[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:
Michael Brown
2025-12-11 15:02:28 +00:00
parent c7f129fede
commit fb1188936c
3 changed files with 28 additions and 30 deletions

View File

@@ -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
*

View File

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

View File

@@ -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,