[crypto] Pass signatures for verification as ASN.1 cursors

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-12-01 14:47:51 +00:00
parent c9c0282594
commit 8cd963ab96
9 changed files with 35 additions and 38 deletions

View File

@@ -757,7 +757,7 @@ static int cms_verify_digest ( struct cms_message *cms,
/* Verify digest */ /* Verify digest */
if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out, if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
value->data, value->len ) ) != 0 ) { value ) ) != 0 ) {
DBGC ( cms, "CMS %p/%p signature verification failed: %s\n", DBGC ( cms, "CMS %p/%p signature verification failed: %s\n",
cms, part, strerror ( rc ) ); cms, part, strerror ( rc ) );
return rc; return rc;

View File

@@ -120,8 +120,7 @@ int pubkey_null_sign ( const struct asn1_cursor *key __unused,
int pubkey_null_verify ( const struct asn1_cursor *key __unused, int pubkey_null_verify ( const struct asn1_cursor *key __unused,
struct digest_algorithm *digest __unused, struct digest_algorithm *digest __unused,
const void *value __unused, const void *value __unused,
const void *signature __unused , const struct asn1_cursor *signature __unused ) {
size_t signature_len __unused ) {
return 0; return 0;
} }

View File

@@ -858,8 +858,7 @@ static int ocsp_check_signature ( struct ocsp_check *ocsp,
/* Verify digest */ /* Verify digest */
if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out, if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out,
response->signature.data, &response->signature ) ) != 0 ) {
response->signature.len ) ) != 0 ) {
DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: " DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: "
"%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc )); "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc ));
return rc; return rc;

View File

@@ -591,12 +591,11 @@ static int rsa_sign ( const struct asn1_cursor *key,
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @v signature_len Signature length
* @ret rc Return status code * @ret rc Return status code
*/ */
static int rsa_verify ( const struct asn1_cursor *key, static int rsa_verify ( const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value, struct digest_algorithm *digest, const void *value,
const void *signature, size_t signature_len ) { const struct asn1_cursor *signature ) {
struct rsa_context context; struct rsa_context context;
void *temp; void *temp;
void *expected; void *expected;
@@ -606,17 +605,17 @@ static int rsa_verify ( const struct asn1_cursor *key,
DBGC ( &context, "RSA %p verifying %s digest:\n", DBGC ( &context, "RSA %p verifying %s digest:\n",
&context, digest->name ); &context, digest->name );
DBGC_HDA ( &context, 0, value, digest->digestsize ); DBGC_HDA ( &context, 0, value, digest->digestsize );
DBGC_HDA ( &context, 0, signature, signature_len ); DBGC_HDA ( &context, 0, signature->data, signature->len );
/* Initialise context */ /* Initialise context */
if ( ( rc = rsa_init ( &context, key ) ) != 0 ) if ( ( rc = rsa_init ( &context, key ) ) != 0 )
goto err_init; goto err_init;
/* Sanity check */ /* Sanity check */
if ( signature_len != context.max_len ) { if ( signature->len != context.max_len ) {
DBGC ( &context, "RSA %p signature incorrect length (%zd " DBGC ( &context, "RSA %p signature incorrect length (%zd "
"bytes, should be %zd)\n", "bytes, should be %zd)\n",
&context, signature_len, context.max_len ); &context, signature->len, context.max_len );
rc = -ERANGE; rc = -ERANGE;
goto err_sanity; goto err_sanity;
} }
@@ -626,7 +625,7 @@ static int rsa_verify ( const struct asn1_cursor *key,
*/ */
temp = context.input0; temp = context.input0;
expected = temp; expected = temp;
rsa_cipher ( &context, signature, expected ); rsa_cipher ( &context, signature->data, expected );
DBGC ( &context, "RSA %p deciphered signature:\n", &context ); DBGC ( &context, "RSA %p deciphered signature:\n", &context );
DBGC_HDA ( &context, 0, expected, context.max_len ); DBGC_HDA ( &context, 0, expected, context.max_len );

View File

@@ -1152,8 +1152,7 @@ static int x509_check_signature ( struct x509_certificate *cert,
/* Verify signature using signer's public key */ /* Verify signature using signer's public key */
if ( ( rc = pubkey_verify ( pubkey, &public_key->raw, digest, if ( ( rc = pubkey_verify ( pubkey, &public_key->raw, digest,
digest_out, signature->value.data, digest_out, &signature->value ) ) != 0 ) {
signature->value.len ) ) != 0 ) {
DBGC ( cert, "X509 %p \"%s\" signature verification failed: " DBGC ( cert, "X509 %p \"%s\" signature verification failed: "
"%s\n", cert, x509_name ( cert ), strerror ( rc ) ); "%s\n", cert, x509_name ( cert ), strerror ( rc ) );
goto err_pubkey_verify; goto err_pubkey_verify;

View File

@@ -164,12 +164,11 @@ struct pubkey_algorithm {
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @v signature_len Signature length
* @ret rc Return status code * @ret rc Return status code
*/ */
int ( * verify ) ( const struct asn1_cursor *key, int ( * verify ) ( const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value, struct digest_algorithm *digest, const void *value,
const void *signature, size_t signature_len ); const struct asn1_cursor *signature );
/** Check that public key matches private key /** Check that public key matches private key
* *
* @v private_key Private key * @v private_key Private key
@@ -295,8 +294,8 @@ pubkey_sign ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
static inline __attribute__ (( always_inline )) int static inline __attribute__ (( always_inline )) int
pubkey_verify ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, pubkey_verify ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value, struct digest_algorithm *digest, const void *value,
const void *signature, size_t signature_len ) { const struct asn1_cursor *signature ) {
return pubkey->verify ( key, digest, value, signature, signature_len ); return pubkey->verify ( key, digest, value, signature );
} }
static inline __attribute__ (( always_inline )) int static inline __attribute__ (( always_inline )) int
@@ -336,8 +335,8 @@ extern int pubkey_null_sign ( const struct asn1_cursor *key,
const void *value, void *signature ); const void *value, void *signature );
extern int pubkey_null_verify ( const struct asn1_cursor *key, extern int pubkey_null_verify ( const struct asn1_cursor *key,
struct digest_algorithm *digest, struct digest_algorithm *digest,
const void *value, const void *signature , const void *value,
size_t signature_len ); const struct asn1_cursor *signature );
extern struct digest_algorithm digest_null; extern struct digest_algorithm digest_null;
extern struct cipher_algorithm cipher_null; extern struct cipher_algorithm cipher_null;

View File

@@ -1495,6 +1495,7 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
uint16_t signature_len; uint16_t signature_len;
uint8_t signature[0]; uint8_t signature[0];
} __attribute__ (( packed )) *sig; } __attribute__ (( packed )) *sig;
struct asn1_cursor signature;
const void *data; const void *data;
size_t remaining; size_t remaining;
int rc; int rc;
@@ -1515,6 +1516,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
tls->server.exchange_len ); tls->server.exchange_len );
return -EINVAL_KEY_EXCHANGE; return -EINVAL_KEY_EXCHANGE;
} }
signature.data = sig->signature;
signature.len = ntohs ( sig->signature_len );
/* Identify signature and hash algorithm */ /* Identify signature and hash algorithm */
if ( use_sig_hash ) { if ( use_sig_hash ) {
@@ -1538,8 +1541,6 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
/* Verify signature */ /* Verify signature */
{ {
const void *signature = sig->signature;
size_t signature_len = ntohs ( sig->signature_len );
uint8_t ctx[digest->ctxsize]; uint8_t ctx[digest->ctxsize];
uint8_t hash[digest->digestsize]; uint8_t hash[digest->digestsize];
@@ -1553,9 +1554,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
digest_final ( digest, ctx, hash ); digest_final ( digest, ctx, hash );
/* Verify signature */ /* Verify signature */
if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, digest,
digest, hash, signature, hash, &signature ) ) != 0 ) {
signature_len ) ) != 0 ) {
DBGC ( tls, "TLS %p ServerKeyExchange failed " DBGC ( tls, "TLS %p ServerKeyExchange failed "
"verification\n", tls ); "verification\n", tls );
DBGC_HDA ( tls, 0, tls->server.exchange, DBGC_HDA ( tls, 0, tls->server.exchange,

View File

@@ -99,10 +99,11 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
struct pubkey_algorithm *pubkey = test->pubkey; struct pubkey_algorithm *pubkey = test->pubkey;
struct digest_algorithm *digest = test->digest; struct digest_algorithm *digest = test->digest;
size_t max_len = pubkey_max_len ( pubkey, &test->private ); size_t max_len = pubkey_max_len ( pubkey, &test->private );
uint8_t bad[test->signature_len]; uint8_t bad[test->signature.len];
uint8_t digestctx[digest->ctxsize ]; uint8_t digestctx[digest->ctxsize ];
uint8_t digestout[digest->digestsize]; uint8_t digestout[digest->digestsize];
uint8_t signature[max_len]; uint8_t signature[max_len];
struct asn1_cursor cursor;
int signature_len; int signature_len;
/* Construct digest over plaintext */ /* Construct digest over plaintext */
@@ -114,18 +115,19 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file,
/* Test signing using private key */ /* Test signing using private key */
signature_len = pubkey_sign ( pubkey, &test->private, digest, signature_len = pubkey_sign ( pubkey, &test->private, digest,
digestout, signature ); digestout, signature );
okx ( signature_len == ( ( int ) test->signature_len ), file, line ); okx ( signature_len == ( ( int ) test->signature.len ), file, line );
okx ( memcmp ( signature, test->signature, test->signature_len ) == 0, okx ( memcmp ( signature, test->signature.data,
file, line ); test->signature.len ) == 0, file, line );
/* Test verification using public key */ /* Test verification using public key */
okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
test->signature, test->signature_len ) == 0, &test->signature ) == 0, file, line );
file, line );
/* Test verification failure of modified signature */ /* Test verification failure of modified signature */
memcpy ( bad, test->signature, test->signature_len ); memcpy ( bad, test->signature.data, test->signature.len );
bad[ test->signature_len / 2 ] ^= 0x40; bad[ test->signature.len / 2 ] ^= 0x40;
cursor.data = bad;
cursor.len = test->signature.len;
okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, okx ( pubkey_verify ( pubkey, &test->public, digest, digestout,
bad, sizeof ( bad ) ) != 0, file, line ); &cursor ) != 0, file, line );
} }

View File

@@ -45,9 +45,7 @@ struct pubkey_sign_test {
/** Signature algorithm */ /** Signature algorithm */
struct digest_algorithm *digest; struct digest_algorithm *digest;
/** Signature */ /** Signature */
const void *signature; const struct asn1_cursor signature;
/** Signature length */
size_t signature_len;
}; };
/** Define inline private key data */ /** Define inline private key data */
@@ -129,8 +127,10 @@ struct pubkey_sign_test {
.plaintext = name ## _plaintext, \ .plaintext = name ## _plaintext, \
.plaintext_len = sizeof ( name ## _plaintext ), \ .plaintext_len = sizeof ( name ## _plaintext ), \
.digest = DIGEST, \ .digest = DIGEST, \
.signature = name ## _signature, \ .signature = { \
.signature_len = sizeof ( name ## _signature ), \ .data = name ## _signature, \
.len = sizeof ( name ## _signature ), \
}, \
} }
extern void pubkey_okx ( struct pubkey_test *test, extern void pubkey_okx ( struct pubkey_test *test,