mirror of
https://github.com/ipxe/ipxe
synced 2026-01-21 18:30:56 +03:00
[crypto] Generalise rsa_parse_integer() to asn1_enter_unsigned()
ECDSA signature values and private keys are fixed-length unsigned integers modulo N (the group order of the elliptic curve) and are therefore most naturally represented in ASN.1 using ASN1_OCTET_STRING. Private key representations do use ASN1_OCTET_STRING, but signature values tend to use ASN1_INTEGER, which adds no value but does ensure that the encoding becomes variable-length and requires handling a pointless extra zero byte if the MSB of the unsigned value happens to be set. RSA also makes use of ASN1_INTEGER for modulus and exponent values. Generalise the existing rsa_parse_integer() to asn1_enter_unsigned() to allow this code to be reused for ECDSA. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -372,6 +372,29 @@ int asn1_enter_bits ( struct asn1_cursor *cursor, unsigned int *unused ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter ASN.1 unsigned integer
|
||||
*
|
||||
* @v cursor ASN.1 object cursor
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int asn1_enter_unsigned ( struct asn1_cursor *cursor ) {
|
||||
int rc;
|
||||
|
||||
/* Enter integer */
|
||||
if ( ( rc = asn1_enter ( cursor, ASN1_INTEGER ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Skip initial positive sign byte if applicable */
|
||||
if ( ( cursor->len > 1 ) &&
|
||||
( *( ( uint8_t * ) cursor->data ) == 0x00 ) ) {
|
||||
cursor->data++;
|
||||
cursor->len--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse value of ASN.1 boolean
|
||||
*
|
||||
|
||||
@@ -137,34 +137,6 @@ static int rsa_alloc ( struct rsa_context *context, size_t modulus_len,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RSA integer
|
||||
*
|
||||
* @v integer Integer to fill in
|
||||
* @v raw ASN.1 cursor
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rsa_parse_integer ( struct asn1_cursor *integer,
|
||||
const struct asn1_cursor *raw ) {
|
||||
|
||||
/* Enter integer */
|
||||
memcpy ( integer, raw, sizeof ( *integer ) );
|
||||
asn1_enter ( integer, ASN1_INTEGER );
|
||||
|
||||
/* Skip initial sign byte if applicable */
|
||||
if ( ( integer->len > 1 ) &&
|
||||
( *( ( uint8_t * ) integer->data ) == 0x00 ) ) {
|
||||
integer->data++;
|
||||
integer->len--;
|
||||
}
|
||||
|
||||
/* Fail if cursor or integer are invalid */
|
||||
if ( ! integer->len )
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RSA modulus and exponent
|
||||
*
|
||||
@@ -226,7 +198,8 @@ static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
|
||||
}
|
||||
|
||||
/* Extract modulus */
|
||||
if ( ( rc = rsa_parse_integer ( modulus, &cursor ) ) != 0 )
|
||||
memcpy ( modulus, &cursor, sizeof ( *modulus ) );
|
||||
if ( ( rc = asn1_enter_unsigned ( modulus ) ) != 0 )
|
||||
return rc;
|
||||
asn1_skip_any ( &cursor );
|
||||
|
||||
@@ -235,7 +208,8 @@ static int rsa_parse_mod_exp ( struct asn1_cursor *modulus,
|
||||
asn1_skip ( &cursor, ASN1_INTEGER );
|
||||
|
||||
/* Extract publicExponent/privateExponent */
|
||||
if ( ( rc = rsa_parse_integer ( exponent, &cursor ) ) != 0 )
|
||||
memcpy ( exponent, &cursor, sizeof ( *exponent ) );
|
||||
if ( ( rc = asn1_enter_unsigned ( exponent ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -488,6 +488,7 @@ extern int asn1_skip_any ( struct asn1_cursor *cursor );
|
||||
extern int asn1_shrink_any ( struct asn1_cursor *cursor );
|
||||
extern int asn1_enter_bits ( struct asn1_cursor *cursor,
|
||||
unsigned int *unused );
|
||||
extern int asn1_enter_unsigned ( struct asn1_cursor *cursor );
|
||||
extern int asn1_boolean ( const struct asn1_cursor *cursor );
|
||||
extern int asn1_integer ( const struct asn1_cursor *cursor, int *value );
|
||||
extern int asn1_compare ( const struct asn1_cursor *cursor1,
|
||||
|
||||
Reference in New Issue
Block a user