|  | @@ -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 |  };
 |