Parcourir la source

[crypto] Add pubkey_match() to check for matching public/private key pairs

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown il y a 10 ans
Parent
révision
2dd3fffe18
2 fichiers modifiés avec 107 ajouts et 26 suppressions
  1. 89
    26
      src/crypto/rsa.c
  2. 18
    0
      src/include/ipxe/crypto.h

+ 89
- 26
src/crypto/rsa.c Voir le fichier

@@ -202,13 +202,11 @@ static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
202 202
 /**
203 203
  * Parse RSA integer
204 204
  *
205
- * @v context		RSA context
206 205
  * @v integer		Integer to fill in
207 206
  * @v raw		ASN.1 cursor
208 207
  * @ret rc		Return status code
209 208
  */
210
-static int rsa_parse_integer ( struct rsa_context *context,
211
-			       struct asn1_cursor *integer,
209
+static int rsa_parse_integer ( struct asn1_cursor *integer,
212 210
 			       const struct asn1_cursor *raw ) {
213 211
 
214 212
 	/* Enter integer */
@@ -223,44 +221,35 @@ static int rsa_parse_integer ( struct rsa_context *context,
223 221
 	}
224 222
 
225 223
 	/* Fail if cursor or integer are invalid */
226
-	if ( ! integer->len ) {
227
-		DBGC ( context, "RSA %p invalid integer:\n", context );
228
-		DBGC_HDA ( context, 0, raw->data, raw->len );
224
+	if ( ! integer->len )
229 225
 		return -EINVAL;
230
-	}
231 226
 
232 227
 	return 0;
233 228
 }
234 229
 
235 230
 /**
236
- * Initialise RSA cipher
231
+ * Parse RSA modulus and exponent
237 232
  *
238
- * @v ctx		RSA context
239
- * @v key		Key
240
- * @v key_len		Length of key
233
+ * @v modulus		Modulus to fill in
234
+ * @v exponent		Exponent to fill in
235
+ * @v raw		ASN.1 cursor
241 236
  * @ret rc		Return status code
242 237
  */
243
-static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
244
-	struct rsa_context *context = ctx;
238
+static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
239
+			       struct asn1_cursor *exponent,
240
+			       const struct asn1_cursor *raw ) {
245 241
 	struct asn1_bit_string bits;
246
-	struct asn1_cursor modulus;
247
-	struct asn1_cursor exponent;
248 242
 	struct asn1_cursor cursor;
249 243
 	int is_private;
250 244
 	int rc;
251 245
 
252
-	/* Initialise context */
253
-	memset ( context, 0, sizeof ( *context ) );
254
-
255
-	/* Initialise cursor */
256
-	cursor.data = key;
257
-	cursor.len = key_len;
258
-
259 246
 	/* Enter subjectPublicKeyInfo/RSAPrivateKey */
247
+	memcpy ( &cursor, raw, sizeof ( cursor ) );
260 248
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
261 249
 
262 250
 	/* Determine key format */
263 251
 	if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
252
+
264 253
 		/* Private key */
265 254
 		is_private = 1;
266 255
 
@@ -268,6 +257,7 @@ static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
268 257
 		asn1_skip_any ( &cursor );
269 258
 
270 259
 	} else {
260
+
271 261
 		/* Public key */
272 262
 		is_private = 0;
273 263
 
@@ -276,7 +266,7 @@ static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
276 266
 
277 267
 		/* Enter subjectPublicKey */
278 268
 		if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
279
-			goto err_parse;
269
+			return rc;
280 270
 		cursor.data = bits.data;
281 271
 		cursor.len = bits.len;
282 272
 
@@ -285,8 +275,8 @@ static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
285 275
 	}
286 276
 
287 277
 	/* Extract modulus */
288
-	if ( ( rc = rsa_parse_integer ( context, &modulus, &cursor ) ) != 0 )
289
-		goto err_parse;
278
+	if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
279
+		return rc;
290 280
 	asn1_skip_any ( &cursor );
291 281
 
292 282
 	/* Skip public exponent, if applicable */
@@ -294,8 +284,40 @@ static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
294 284
 		asn1_skip ( &cursor, ASN1_INTEGER );
295 285
 
296 286
 	/* Extract publicExponent/privateExponent */
297
-	if ( ( rc = rsa_parse_integer ( context, &exponent, &cursor ) ) != 0 )
287
+	if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
288
+		return rc;
289
+
290
+	return 0;
291
+}
292
+
293
+/**
294
+ * Initialise RSA cipher
295
+ *
296
+ * @v ctx		RSA context
297
+ * @v key		Key
298
+ * @v key_len		Length of key
299
+ * @ret rc		Return status code
300
+ */
301
+static int rsa_init ( void *ctx, const void *key, size_t key_len ) {
302
+	struct rsa_context *context = ctx;
303
+	struct asn1_cursor modulus;
304
+	struct asn1_cursor exponent;
305
+	struct asn1_cursor cursor;
306
+	int rc;
307
+
308
+	/* Initialise context */
309
+	memset ( context, 0, sizeof ( *context ) );
310
+
311
+	/* Initialise cursor */
312
+	cursor.data = key;
313
+	cursor.len = key_len;
314
+
315
+	/* Parse modulus and exponent */
316
+	if ( ( rc = rsa_parse_mod_exp ( &modulus, &exponent, &cursor ) ) != 0 ){
317
+		DBGC ( context, "RSA %p invalid modulus/exponent:\n", context );
318
+		DBGC_HDA ( context, 0, cursor.data, cursor.len );
298 319
 		goto err_parse;
320
+	}
299 321
 
300 322
 	DBGC ( context, "RSA %p modulus:\n", context );
301 323
 	DBGC_HDA ( context, 0, modulus.data, modulus.len );
@@ -628,6 +650,46 @@ static void rsa_final ( void *ctx ) {
628 650
 	rsa_free ( context );
629 651
 }
630 652
 
653
+/**
654
+ * Check for matching RSA public/private key pair
655
+ *
656
+ * @v private_key	Private key
657
+ * @v private_key_len	Private key length
658
+ * @v public_key	Public key
659
+ * @v public_key_len	Public key length
660
+ * @ret rc		Return status code
661
+ */
662
+static int rsa_match ( const void *private_key, size_t private_key_len,
663
+		       const void *public_key, size_t public_key_len ) {
664
+	struct asn1_cursor private_modulus;
665
+	struct asn1_cursor private_exponent;
666
+	struct asn1_cursor private_cursor;
667
+	struct asn1_cursor public_modulus;
668
+	struct asn1_cursor public_exponent;
669
+	struct asn1_cursor public_cursor;
670
+	int rc;
671
+
672
+	/* Initialise cursors */
673
+	private_cursor.data = private_key;
674
+	private_cursor.len = private_key_len;
675
+	public_cursor.data = public_key;
676
+	public_cursor.len = public_key_len;
677
+
678
+	/* Parse moduli and exponents */
679
+	if ( ( rc = rsa_parse_mod_exp ( &private_modulus, &private_exponent,
680
+					&private_cursor ) ) != 0 )
681
+		return rc;
682
+	if ( ( rc = rsa_parse_mod_exp ( &public_modulus, &public_exponent,
683
+					&public_cursor ) ) != 0 )
684
+		return rc;
685
+
686
+	/* Compare moduli */
687
+	if ( asn1_compare ( &private_modulus, &public_modulus ) != 0 )
688
+		return -ENOTTY;
689
+
690
+	return 0;
691
+}
692
+
631 693
 /** RSA public-key algorithm */
632 694
 struct pubkey_algorithm rsa_algorithm = {
633 695
 	.name		= "rsa",
@@ -639,4 +701,5 @@ struct pubkey_algorithm rsa_algorithm = {
639 701
 	.sign		= rsa_sign,
640 702
 	.verify		= rsa_verify,
641 703
 	.final		= rsa_final,
704
+	.match		= rsa_match,
642 705
 };

+ 18
- 0
src/include/ipxe/crypto.h Voir le fichier

@@ -157,6 +157,16 @@ struct pubkey_algorithm {
157 157
 	 * @v ctx		Context
158 158
 	 */
159 159
 	void ( * final ) ( void *ctx );
160
+	/** Check that public key matches private key
161
+	 *
162
+	 * @v private_key	Private key
163
+	 * @v private_key_len	Private key length
164
+	 * @v public_key	Public key
165
+	 * @v public_key_len	Public key length
166
+	 * @ret rc		Return status code
167
+	 */
168
+	int ( * match ) ( const void *private_key, size_t private_key_len,
169
+			  const void *public_key, size_t public_key_len );
160 170
 };
161 171
 
162 172
 static inline void digest_init ( struct digest_algorithm *digest,
@@ -245,6 +255,14 @@ static inline void pubkey_final ( struct pubkey_algorithm *pubkey, void *ctx ) {
245 255
 	pubkey->final ( ctx );
246 256
 }
247 257
 
258
+static inline int pubkey_match ( struct pubkey_algorithm *pubkey,
259
+				 const void *private_key,
260
+				 size_t private_key_len, const void *public_key,
261
+				 size_t public_key_len ) {
262
+	return pubkey->match ( private_key, private_key_len, public_key,
263
+			       public_key_len );
264
+}
265
+
248 266
 extern struct digest_algorithm digest_null;
249 267
 extern struct cipher_algorithm cipher_null;
250 268
 extern struct pubkey_algorithm pubkey_null;

Chargement…
Annuler
Enregistrer