From 8cd963ab9657d3b14ad36a37a73522fc91415c90 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 1 Dec 2025 14:47:51 +0000 Subject: [PATCH] [crypto] Pass signatures for verification as ASN.1 cursors Signed-off-by: Michael Brown --- src/crypto/cms.c | 2 +- src/crypto/crypto_null.c | 3 +-- src/crypto/ocsp.c | 3 +-- src/crypto/rsa.c | 11 +++++------ src/crypto/x509.c | 3 +-- src/include/ipxe/crypto.h | 11 +++++------ src/net/tls.c | 10 +++++----- src/tests/pubkey_test.c | 20 +++++++++++--------- src/tests/pubkey_test.h | 10 +++++----- 9 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/crypto/cms.c b/src/crypto/cms.c index e3571f330..a3c03a9b4 100644 --- a/src/crypto/cms.c +++ b/src/crypto/cms.c @@ -757,7 +757,7 @@ static int cms_verify_digest ( struct cms_message *cms, /* Verify digest */ 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", cms, part, strerror ( rc ) ); return rc; diff --git a/src/crypto/crypto_null.c b/src/crypto/crypto_null.c index d5863f958..ca4e1b134 100644 --- a/src/crypto/crypto_null.c +++ b/src/crypto/crypto_null.c @@ -120,8 +120,7 @@ int pubkey_null_sign ( const struct asn1_cursor *key __unused, int pubkey_null_verify ( const struct asn1_cursor *key __unused, struct digest_algorithm *digest __unused, const void *value __unused, - const void *signature __unused , - size_t signature_len __unused ) { + const struct asn1_cursor *signature __unused ) { return 0; } diff --git a/src/crypto/ocsp.c b/src/crypto/ocsp.c index ae70f320c..1712d614e 100644 --- a/src/crypto/ocsp.c +++ b/src/crypto/ocsp.c @@ -858,8 +858,7 @@ static int ocsp_check_signature ( struct ocsp_check *ocsp, /* Verify digest */ if ( ( rc = pubkey_verify ( pubkey, key, digest, digest_out, - response->signature.data, - response->signature.len ) ) != 0 ) { + &response->signature ) ) != 0 ) { DBGC ( ocsp, "OCSP %p \"%s\" signature verification failed: " "%s\n", ocsp, x509_name ( ocsp->cert ), strerror ( rc )); return rc; diff --git a/src/crypto/rsa.c b/src/crypto/rsa.c index f9041eede..b93437518 100644 --- a/src/crypto/rsa.c +++ b/src/crypto/rsa.c @@ -591,12 +591,11 @@ static int rsa_sign ( const struct asn1_cursor *key, * @v digest Digest algorithm * @v value Digest value * @v signature Signature - * @v signature_len Signature length * @ret rc Return status code */ static int rsa_verify ( const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, - const void *signature, size_t signature_len ) { + const struct asn1_cursor *signature ) { struct rsa_context context; void *temp; void *expected; @@ -606,17 +605,17 @@ static int rsa_verify ( const struct asn1_cursor *key, DBGC ( &context, "RSA %p verifying %s digest:\n", &context, digest->name ); DBGC_HDA ( &context, 0, value, digest->digestsize ); - DBGC_HDA ( &context, 0, signature, signature_len ); + DBGC_HDA ( &context, 0, signature->data, signature->len ); /* Initialise context */ if ( ( rc = rsa_init ( &context, key ) ) != 0 ) goto err_init; /* Sanity check */ - if ( signature_len != context.max_len ) { + if ( signature->len != context.max_len ) { DBGC ( &context, "RSA %p signature incorrect length (%zd " "bytes, should be %zd)\n", - &context, signature_len, context.max_len ); + &context, signature->len, context.max_len ); rc = -ERANGE; goto err_sanity; } @@ -626,7 +625,7 @@ static int rsa_verify ( const struct asn1_cursor *key, */ temp = context.input0; expected = temp; - rsa_cipher ( &context, signature, expected ); + rsa_cipher ( &context, signature->data, expected ); DBGC ( &context, "RSA %p deciphered signature:\n", &context ); DBGC_HDA ( &context, 0, expected, context.max_len ); diff --git a/src/crypto/x509.c b/src/crypto/x509.c index 0b01171b6..5d39a1dd8 100644 --- a/src/crypto/x509.c +++ b/src/crypto/x509.c @@ -1152,8 +1152,7 @@ static int x509_check_signature ( struct x509_certificate *cert, /* Verify signature using signer's public key */ if ( ( rc = pubkey_verify ( pubkey, &public_key->raw, digest, - digest_out, signature->value.data, - signature->value.len ) ) != 0 ) { + digest_out, &signature->value ) ) != 0 ) { DBGC ( cert, "X509 %p \"%s\" signature verification failed: " "%s\n", cert, x509_name ( cert ), strerror ( rc ) ); goto err_pubkey_verify; diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index 4bd543ae2..5b87d1a47 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -164,12 +164,11 @@ struct pubkey_algorithm { * @v digest Digest algorithm * @v value Digest value * @v signature Signature - * @v signature_len Signature length * @ret rc Return status code */ int ( * verify ) ( const struct asn1_cursor *key, 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 * * @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 pubkey_verify ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, - const void *signature, size_t signature_len ) { - return pubkey->verify ( key, digest, value, signature, signature_len ); + const struct asn1_cursor *signature ) { + return pubkey->verify ( key, digest, value, signature ); } 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 ); extern int pubkey_null_verify ( const struct asn1_cursor *key, struct digest_algorithm *digest, - const void *value, const void *signature , - size_t signature_len ); + const void *value, + const struct asn1_cursor *signature ); extern struct digest_algorithm digest_null; extern struct cipher_algorithm cipher_null; diff --git a/src/net/tls.c b/src/net/tls.c index 1d5a6c6d8..1bcb5c027 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -1495,6 +1495,7 @@ static int tls_verify_dh_params ( struct tls_connection *tls, uint16_t signature_len; uint8_t signature[0]; } __attribute__ (( packed )) *sig; + struct asn1_cursor signature; const void *data; size_t remaining; int rc; @@ -1515,6 +1516,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls, tls->server.exchange_len ); return -EINVAL_KEY_EXCHANGE; } + signature.data = sig->signature; + signature.len = ntohs ( sig->signature_len ); /* Identify signature and hash algorithm */ if ( use_sig_hash ) { @@ -1538,8 +1541,6 @@ static int tls_verify_dh_params ( struct tls_connection *tls, /* Verify signature */ { - const void *signature = sig->signature; - size_t signature_len = ntohs ( sig->signature_len ); uint8_t ctx[digest->ctxsize]; uint8_t hash[digest->digestsize]; @@ -1553,9 +1554,8 @@ static int tls_verify_dh_params ( struct tls_connection *tls, digest_final ( digest, ctx, hash ); /* Verify signature */ - if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, - digest, hash, signature, - signature_len ) ) != 0 ) { + if ( ( rc = pubkey_verify ( pubkey, &tls->server.key, digest, + hash, &signature ) ) != 0 ) { DBGC ( tls, "TLS %p ServerKeyExchange failed " "verification\n", tls ); DBGC_HDA ( tls, 0, tls->server.exchange, diff --git a/src/tests/pubkey_test.c b/src/tests/pubkey_test.c index ff318bfb7..2e0eeb116 100644 --- a/src/tests/pubkey_test.c +++ b/src/tests/pubkey_test.c @@ -99,10 +99,11 @@ void pubkey_sign_okx ( struct pubkey_sign_test *test, const char *file, struct pubkey_algorithm *pubkey = test->pubkey; struct digest_algorithm *digest = test->digest; 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 digestout[digest->digestsize]; uint8_t signature[max_len]; + struct asn1_cursor cursor; int signature_len; /* 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 */ signature_len = pubkey_sign ( pubkey, &test->private, digest, digestout, signature ); - okx ( signature_len == ( ( int ) test->signature_len ), file, line ); - okx ( memcmp ( signature, test->signature, test->signature_len ) == 0, - file, line ); + okx ( signature_len == ( ( int ) test->signature.len ), file, line ); + okx ( memcmp ( signature, test->signature.data, + test->signature.len ) == 0, file, line ); /* Test verification using public key */ okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, - test->signature, test->signature_len ) == 0, - file, line ); + &test->signature ) == 0, file, line ); /* Test verification failure of modified signature */ - memcpy ( bad, test->signature, test->signature_len ); - bad[ test->signature_len / 2 ] ^= 0x40; + memcpy ( bad, test->signature.data, test->signature.len ); + bad[ test->signature.len / 2 ] ^= 0x40; + cursor.data = bad; + cursor.len = test->signature.len; okx ( pubkey_verify ( pubkey, &test->public, digest, digestout, - bad, sizeof ( bad ) ) != 0, file, line ); + &cursor ) != 0, file, line ); } diff --git a/src/tests/pubkey_test.h b/src/tests/pubkey_test.h index 20bb94355..1bb6caf51 100644 --- a/src/tests/pubkey_test.h +++ b/src/tests/pubkey_test.h @@ -45,9 +45,7 @@ struct pubkey_sign_test { /** Signature algorithm */ struct digest_algorithm *digest; /** Signature */ - const void *signature; - /** Signature length */ - size_t signature_len; + const struct asn1_cursor signature; }; /** Define inline private key data */ @@ -129,8 +127,10 @@ struct pubkey_sign_test { .plaintext = name ## _plaintext, \ .plaintext_len = sizeof ( name ## _plaintext ), \ .digest = DIGEST, \ - .signature = name ## _signature, \ - .signature_len = sizeof ( name ## _signature ), \ + .signature = { \ + .data = name ## _signature, \ + .len = sizeof ( name ## _signature ), \ + }, \ } extern void pubkey_okx ( struct pubkey_test *test,