Browse 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 10 years ago
parent
commit
2dd3fffe18
2 changed files with 107 additions and 26 deletions
  1. 89
    26
      src/crypto/rsa.c
  2. 18
    0
      src/include/ipxe/crypto.h

+ 89
- 26
src/crypto/rsa.c View File

202
 /**
202
 /**
203
  * Parse RSA integer
203
  * Parse RSA integer
204
  *
204
  *
205
- * @v context		RSA context
206
  * @v integer		Integer to fill in
205
  * @v integer		Integer to fill in
207
  * @v raw		ASN.1 cursor
206
  * @v raw		ASN.1 cursor
208
  * @ret rc		Return status code
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
 			       const struct asn1_cursor *raw ) {
210
 			       const struct asn1_cursor *raw ) {
213
 
211
 
214
 	/* Enter integer */
212
 	/* Enter integer */
223
 	}
221
 	}
224
 
222
 
225
 	/* Fail if cursor or integer are invalid */
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
 		return -EINVAL;
225
 		return -EINVAL;
230
-	}
231
 
226
 
232
 	return 0;
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
  * @ret rc		Return status code
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
 	struct asn1_bit_string bits;
241
 	struct asn1_bit_string bits;
246
-	struct asn1_cursor modulus;
247
-	struct asn1_cursor exponent;
248
 	struct asn1_cursor cursor;
242
 	struct asn1_cursor cursor;
249
 	int is_private;
243
 	int is_private;
250
 	int rc;
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
 	/* Enter subjectPublicKeyInfo/RSAPrivateKey */
246
 	/* Enter subjectPublicKeyInfo/RSAPrivateKey */
247
+	memcpy ( &cursor, raw, sizeof ( cursor ) );
260
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
248
 	asn1_enter ( &cursor, ASN1_SEQUENCE );
261
 
249
 
262
 	/* Determine key format */
250
 	/* Determine key format */
263
 	if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
251
 	if ( asn1_type ( &cursor ) == ASN1_INTEGER ) {
252
+
264
 		/* Private key */
253
 		/* Private key */
265
 		is_private = 1;
254
 		is_private = 1;
266
 
255
 
268
 		asn1_skip_any ( &cursor );
257
 		asn1_skip_any ( &cursor );
269
 
258
 
270
 	} else {
259
 	} else {
260
+
271
 		/* Public key */
261
 		/* Public key */
272
 		is_private = 0;
262
 		is_private = 0;
273
 
263
 
276
 
266
 
277
 		/* Enter subjectPublicKey */
267
 		/* Enter subjectPublicKey */
278
 		if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
268
 		if ( ( rc = asn1_integral_bit_string ( &cursor, &bits ) ) != 0 )
279
-			goto err_parse;
269
+			return rc;
280
 		cursor.data = bits.data;
270
 		cursor.data = bits.data;
281
 		cursor.len = bits.len;
271
 		cursor.len = bits.len;
282
 
272
 
285
 	}
275
 	}
286
 
276
 
287
 	/* Extract modulus */
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
 	asn1_skip_any ( &cursor );
280
 	asn1_skip_any ( &cursor );
291
 
281
 
292
 	/* Skip public exponent, if applicable */
282
 	/* Skip public exponent, if applicable */
294
 		asn1_skip ( &cursor, ASN1_INTEGER );
284
 		asn1_skip ( &cursor, ASN1_INTEGER );
295
 
285
 
296
 	/* Extract publicExponent/privateExponent */
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
 		goto err_parse;
319
 		goto err_parse;
320
+	}
299
 
321
 
300
 	DBGC ( context, "RSA %p modulus:\n", context );
322
 	DBGC ( context, "RSA %p modulus:\n", context );
301
 	DBGC_HDA ( context, 0, modulus.data, modulus.len );
323
 	DBGC_HDA ( context, 0, modulus.data, modulus.len );
628
 	rsa_free ( context );
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
 /** RSA public-key algorithm */
693
 /** RSA public-key algorithm */
632
 struct pubkey_algorithm rsa_algorithm = {
694
 struct pubkey_algorithm rsa_algorithm = {
633
 	.name		= "rsa",
695
 	.name		= "rsa",
639
 	.sign		= rsa_sign,
701
 	.sign		= rsa_sign,
640
 	.verify		= rsa_verify,
702
 	.verify		= rsa_verify,
641
 	.final		= rsa_final,
703
 	.final		= rsa_final,
704
+	.match		= rsa_match,
642
 };
705
 };

+ 18
- 0
src/include/ipxe/crypto.h View File

157
 	 * @v ctx		Context
157
 	 * @v ctx		Context
158
 	 */
158
 	 */
159
 	void ( * final ) ( void *ctx );
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
 static inline void digest_init ( struct digest_algorithm *digest,
172
 static inline void digest_init ( struct digest_algorithm *digest,
245
 	pubkey->final ( ctx );
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
 extern struct digest_algorithm digest_null;
266
 extern struct digest_algorithm digest_null;
249
 extern struct cipher_algorithm cipher_null;
267
 extern struct cipher_algorithm cipher_null;
250
 extern struct pubkey_algorithm pubkey_null;
268
 extern struct pubkey_algorithm pubkey_null;

Loading…
Cancel
Save