From: Michael Brown Date: Fri, 19 Jun 2026 13:53:03 +0000 (+0100) Subject: [crypto] Use private data field for public-key algorithms X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;ds=inline;p=thirdparty%2Fipxe.git [crypto] Use private data field for public-key algorithms Following the example of commit 25072c1 ("[crypto] Use private data field for key exchange algorithms"), extend the definition of a public-key algorithm to include an opaque private data field, and use this to eliminate the wrapper functions for PKCS#1 and RSA-PSS. Signed-off-by: Michael Brown --- diff --git a/src/crypto/crypto_null.c b/src/crypto/crypto_null.c index a8d4519f8..d0f6a1a99 100644 --- a/src/crypto/crypto_null.c +++ b/src/crypto/crypto_null.c @@ -104,36 +104,47 @@ struct cipher_algorithm cipher_null = { .auth = cipher_null_auth, }; -int pubkey_null_encrypt ( const struct asn1_cursor *key __unused, +int pubkey_null_encrypt ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key __unused, const struct asn1_cursor *plaintext __unused, struct asn1_builder *ciphertext __unused ) { return -ENOTTY; } -int pubkey_null_decrypt ( const struct asn1_cursor *key __unused, +int pubkey_null_decrypt ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key __unused, const struct asn1_cursor *ciphertext __unused, struct asn1_builder *plaintext __unused ) { return -ENOTTY; } -int pubkey_null_sign ( const struct asn1_cursor *key __unused, +int pubkey_null_sign ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key __unused, struct digest_algorithm *digest __unused, const void *value __unused, struct asn1_builder *signature __unused ) { return -ENOTTY; } -int pubkey_null_verify ( const struct asn1_cursor *key __unused, +int pubkey_null_verify ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key __unused, struct digest_algorithm *digest __unused, const void *value __unused, const struct asn1_cursor *signature __unused ) { return -ENOTTY; } +int pubkey_null_match ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *private_key __unused, + const struct asn1_cursor *public_key __unused ) { + return -ENOTTY; +} + struct pubkey_algorithm pubkey_null = { .name = "null", .encrypt = pubkey_null_encrypt, .decrypt = pubkey_null_decrypt, .sign = pubkey_null_sign, .verify = pubkey_null_verify, + .match = pubkey_null_match, }; diff --git a/src/crypto/ecdsa.c b/src/crypto/ecdsa.c index 5be4b4b21..364d8d66e 100644 --- a/src/crypto/ecdsa.c +++ b/src/crypto/ecdsa.c @@ -768,13 +768,15 @@ static int ecdsa_verify_rs ( struct ecdsa_context *ctx ) { /** * Sign digest value using ECDSA * + * @v pubkey Public-key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature * @ret rc Return status code */ -static int ecdsa_sign ( const struct asn1_cursor *key, +static int ecdsa_sign ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature ) { struct ecdsa_context ctx; @@ -824,13 +826,15 @@ static int ecdsa_sign ( const struct asn1_cursor *key, /** * Verify signed digest using ECDSA * + * @v pubkey Public-key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature * @ret rc Return status code */ -static int ecdsa_verify ( const struct asn1_cursor *key, +static int ecdsa_verify ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature ) { struct ecdsa_context ctx; @@ -872,30 +876,32 @@ static int ecdsa_verify ( const struct asn1_cursor *key, /** * Check for matching ECDSA public/private key pair * + * @v pubkey Public-key algorithm * @v private_key Private key * @v public_key Public key * @ret rc Return status code */ -static int ecdsa_match ( const struct asn1_cursor *private_key, +static int ecdsa_match ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *private_key, const struct asn1_cursor *public_key ) { struct elliptic_curve *curve; - struct ecdsa_key privkey; - struct ecdsa_key pubkey; + struct ecdsa_key private; + struct ecdsa_key public; int rc; /* Parse keys */ - if ( ( rc = ecdsa_parse_key ( &privkey, private_key ) ) != 0 ) + if ( ( rc = ecdsa_parse_key ( &private, private_key ) ) != 0 ) return rc; - if ( ( rc = ecdsa_parse_key ( &pubkey, public_key ) ) != 0 ) + if ( ( rc = ecdsa_parse_key ( &public, public_key ) ) != 0 ) return rc; /* Compare curves */ - if ( privkey.curve != pubkey.curve ) + if ( private.curve != public.curve ) return -ENOTTY; - curve = privkey.curve; + curve = private.curve; /* Compare public curve points */ - if ( memcmp ( privkey.public, pubkey.public, curve->pointsize ) != 0 ) + if ( memcmp ( private.public, public.public, curve->pointsize ) != 0 ) return -ENOTTY; return 0; diff --git a/src/crypto/rsa.c b/src/crypto/rsa.c index e62eb02a4..9454b29ba 100644 --- a/src/crypto/rsa.c +++ b/src/crypto/rsa.c @@ -323,12 +323,14 @@ static void rsa_cipher ( struct rsa_context *context, /** * Encrypt using RSA PKCS#1 * + * @v pubkey Public-key algorithm * @v key Key * @v plaintext Plaintext * @v ciphertext Ciphertext * @ret ciphertext_len Length of ciphertext, or negative error */ -static int rsa_pkcs1_encrypt ( const struct asn1_cursor *key, +static int rsa_pkcs1_encrypt ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext ) { struct rsa_context context; @@ -400,12 +402,14 @@ static int rsa_pkcs1_encrypt ( const struct asn1_cursor *key, /** * Decrypt using RSA PKCS#1 * + * @v pubkey Public-key algorithm * @v key Key * @v ciphertext Ciphertext * @v plaintext Plaintext * @ret rc Return status code */ -static int rsa_pkcs1_decrypt ( const struct asn1_cursor *key, +static int rsa_pkcs1_decrypt ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext ) { struct rsa_context context; @@ -667,16 +671,18 @@ static int rsa_pss_encode ( struct rsa_context *context, /** * Sign digest value using RSA * + * @v pubkey Public-key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature - * @v encode Encoding method * @ret rc Return status code */ -static int rsa_sign ( const struct asn1_cursor *key, +static int rsa_sign ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, - struct asn1_builder *signature, rsa_encode_t *encode ) { + struct asn1_builder *signature ) { + rsa_encode_t *encode = pubkey->priv; struct rsa_context context; int rc; @@ -717,17 +723,18 @@ static int rsa_sign ( const struct asn1_cursor *key, /** * Verify signed digest value using RSA * + * @v pubkey Public-key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature - * @v encoding Encoding method * @ret rc Return status code */ -static int rsa_verify ( const struct asn1_cursor *key, +static int rsa_verify ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, - const struct asn1_cursor *signature, - rsa_encode_t *encode ) { + const struct asn1_cursor *signature ) { + rsa_encode_t *encode = pubkey->priv; struct rsa_context context; void *temp; void *expected; @@ -792,79 +799,16 @@ static int rsa_verify ( const struct asn1_cursor *key, return rc; } -/** - * Sign digest value using RSA PKCS#1 - * - * @v key Key - * @v digest Digest algorithm - * @v value Digest value - * @v signature Signature - * @ret rc Return status code - */ -static int rsa_pkcs1_sign ( const struct asn1_cursor *key, - struct digest_algorithm *digest, const void *value, - struct asn1_builder *signature ) { - - return rsa_sign ( key, digest, value, signature, rsa_pkcs1_encode ); -} - -/** - * Verify signed digest value using RSA PKCS#1 - * - * @v key Key - * @v digest Digest algorithm - * @v value Digest value - * @v signature Signature - * @ret rc Return status code - */ -static int rsa_pkcs1_verify ( const struct asn1_cursor *key, - struct digest_algorithm *digest, - const void *value, - const struct asn1_cursor *signature ) { - - return rsa_verify ( key, digest, value, signature, rsa_pkcs1_encode ); -} - -/** - * Sign digest value using RSA PSS - * - * @v key Key - * @v digest Digest algorithm - * @v value Digest value - * @v signature Signature - * @ret rc Return status code - */ -static int rsa_pss_sign ( const struct asn1_cursor *key, - struct digest_algorithm *digest, const void *value, - struct asn1_builder *signature ) { - - return rsa_sign ( key, digest, value, signature, rsa_pss_encode ); -} - -/** - * Verify signed digest value using RSA PSS - * - * @v key Key - * @v digest Digest algorithm - * @v value Digest value - * @v signature Signature - * @ret rc Return status code - */ -static int rsa_pss_verify ( const struct asn1_cursor *key, - struct digest_algorithm *digest, const void *value, - const struct asn1_cursor *signature ) { - - return rsa_verify ( key, digest, value, signature, rsa_pss_encode ); -} - /** * Check for matching RSA public/private key pair * + * @v pubkey Public-key algorithm * @v private_key Private key * @v public_key Public key * @ret rc Return status code */ -static int rsa_match ( const struct asn1_cursor *private_key, +static int rsa_match ( struct pubkey_algorithm *pubkey __unused, + const struct asn1_cursor *private_key, const struct asn1_cursor *public_key ) { struct asn1_cursor private_modulus; struct asn1_cursor private_exponent; @@ -892,9 +836,10 @@ struct pubkey_algorithm rsa_algorithm = { .name = "rsa", .encrypt = rsa_pkcs1_encrypt, .decrypt = rsa_pkcs1_decrypt, - .sign = rsa_pkcs1_sign, - .verify = rsa_pkcs1_verify, + .sign = rsa_sign, + .verify = rsa_verify, .match = rsa_match, + .priv = rsa_pkcs1_encode, }; /** RSA-PSS public-key algorithm */ @@ -902,9 +847,10 @@ struct pubkey_algorithm rsa_pss_algorithm = { .name = "rsa_pss", .encrypt = pubkey_null_encrypt, .decrypt = pubkey_null_decrypt, - .sign = rsa_pss_sign, - .verify = rsa_pss_verify, + .sign = rsa_sign, + .verify = rsa_verify, .match = rsa_match, + .priv = rsa_pss_encode, }; /* Drag in objects via rsa_algorithm */ diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index d2e0d18db..2ee3794c7 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -142,54 +142,66 @@ struct pubkey_algorithm { const char *name; /** Encrypt * + * @v pubkey Public key algorithm * @v key Key * @v plaintext Plaintext * @v ciphertext Ciphertext * @ret rc Return status code */ - int ( * encrypt ) ( const struct asn1_cursor *key, + int ( * encrypt ) ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext ); /** Decrypt * + * @v pubkey Public key algorithm * @v key Key * @v ciphertext Ciphertext * @v plaintext Plaintext * @ret rc Return status code */ - int ( * decrypt ) ( const struct asn1_cursor *key, + int ( * decrypt ) ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext ); /** Sign digest value * + * @v pubkey Public key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature * @ret rc Return status code */ - int ( * sign ) ( const struct asn1_cursor *key, + int ( * sign ) ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *builder ); /** Verify signed digest value * + * @v pubkey Public key algorithm * @v key Key * @v digest Digest algorithm * @v value Digest value * @v signature Signature * @ret rc Return status code */ - int ( * verify ) ( const struct asn1_cursor *key, + int ( * verify ) ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature ); /** Check that public key matches private key * + * @v pubkey Public key algorithm * @v private_key Private key * @v public_key Public key * @ret rc Return status code */ - int ( * match ) ( const struct asn1_cursor *private_key, + int ( * match ) ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *private_key, const struct asn1_cursor *public_key ); + /** Algorithm private data */ + void *priv; }; /** A key exchange algorithm */ @@ -347,35 +359,35 @@ static inline __attribute__ (( always_inline )) int pubkey_encrypt ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext ) { - return pubkey->encrypt ( key, plaintext, ciphertext ); + return pubkey->encrypt ( pubkey, key, plaintext, ciphertext ); } static inline __attribute__ (( always_inline )) int pubkey_decrypt ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext ) { - return pubkey->decrypt ( key, ciphertext, plaintext ); + return pubkey->decrypt ( pubkey, key, ciphertext, plaintext ); } static inline __attribute__ (( always_inline )) int pubkey_sign ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature ) { - return pubkey->sign ( key, digest, value, signature ); + return pubkey->sign ( pubkey, key, digest, value, signature ); } 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 struct asn1_cursor *signature ) { - return pubkey->verify ( key, digest, value, signature ); + return pubkey->verify ( pubkey, key, digest, value, signature ); } static inline __attribute__ (( always_inline )) int pubkey_match ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *private_key, const struct asn1_cursor *public_key ) { - return pubkey->match ( private_key, public_key ); + return pubkey->match ( pubkey, private_key, public_key ); } static inline __attribute__ (( always_inline )) void @@ -424,20 +436,27 @@ extern void cipher_null_decrypt ( struct cipher_algorithm *cipher, void *ctx, extern void cipher_null_auth ( struct cipher_algorithm *cipher, void *ctx, void *auth ); -extern int pubkey_null_encrypt ( const struct asn1_cursor *key, +extern int pubkey_null_encrypt ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, const struct asn1_cursor *plaintext, struct asn1_builder *ciphertext ); -extern int pubkey_null_decrypt ( const struct asn1_cursor *key, +extern int pubkey_null_decrypt ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, const struct asn1_cursor *ciphertext, struct asn1_builder *plaintext ); -extern int pubkey_null_sign ( const struct asn1_cursor *key, +extern int pubkey_null_sign ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, struct asn1_builder *signature ); -extern int pubkey_null_verify ( const struct asn1_cursor *key, +extern int pubkey_null_verify ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *key, struct digest_algorithm *digest, const void *value, const struct asn1_cursor *signature ); +extern int pubkey_null_match ( struct pubkey_algorithm *pubkey, + const struct asn1_cursor *private_key, + const struct asn1_cursor *public_key ); extern struct digest_algorithm digest_null; extern struct cipher_algorithm cipher_null;