[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-06-19 14:53:03 +01:00
parent 2420211e7f
commit 846686325c
4 changed files with 89 additions and 107 deletions
+15 -4
View File
@@ -104,36 +104,47 @@ struct cipher_algorithm cipher_null = {
.auth = cipher_null_auth, .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, const struct asn1_cursor *plaintext __unused,
struct asn1_builder *ciphertext __unused ) { struct asn1_builder *ciphertext __unused ) {
return -ENOTTY; 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, const struct asn1_cursor *ciphertext __unused,
struct asn1_builder *plaintext __unused ) { struct asn1_builder *plaintext __unused ) {
return -ENOTTY; 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, struct digest_algorithm *digest __unused,
const void *value __unused, const void *value __unused,
struct asn1_builder *signature __unused ) { struct asn1_builder *signature __unused ) {
return -ENOTTY; 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, struct digest_algorithm *digest __unused,
const void *value __unused, const void *value __unused,
const struct asn1_cursor *signature __unused ) { const struct asn1_cursor *signature __unused ) {
return -ENOTTY; 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 = { struct pubkey_algorithm pubkey_null = {
.name = "null", .name = "null",
.encrypt = pubkey_null_encrypt, .encrypt = pubkey_null_encrypt,
.decrypt = pubkey_null_decrypt, .decrypt = pubkey_null_decrypt,
.sign = pubkey_null_sign, .sign = pubkey_null_sign,
.verify = pubkey_null_verify, .verify = pubkey_null_verify,
.match = pubkey_null_match,
}; };
+16 -10
View File
@@ -768,13 +768,15 @@ static int ecdsa_verify_rs ( struct ecdsa_context *ctx ) {
/** /**
* Sign digest value using ECDSA * Sign digest value using ECDSA
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @ret rc Return status code * @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 digest_algorithm *digest, const void *value,
struct asn1_builder *signature ) { struct asn1_builder *signature ) {
struct ecdsa_context ctx; struct ecdsa_context ctx;
@@ -824,13 +826,15 @@ static int ecdsa_sign ( const struct asn1_cursor *key,
/** /**
* Verify signed digest using ECDSA * Verify signed digest using ECDSA
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @ret rc Return status code * @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, struct digest_algorithm *digest, const void *value,
const struct asn1_cursor *signature ) { const struct asn1_cursor *signature ) {
struct ecdsa_context ctx; 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 * Check for matching ECDSA public/private key pair
* *
* @v pubkey Public-key algorithm
* @v private_key Private key * @v private_key Private key
* @v public_key Public key * @v public_key Public key
* @ret rc Return status code * @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 ) { const struct asn1_cursor *public_key ) {
struct elliptic_curve *curve; struct elliptic_curve *curve;
struct ecdsa_key privkey; struct ecdsa_key private;
struct ecdsa_key pubkey; struct ecdsa_key public;
int rc; int rc;
/* Parse keys */ /* Parse keys */
if ( ( rc = ecdsa_parse_key ( &privkey, private_key ) ) != 0 ) if ( ( rc = ecdsa_parse_key ( &private, private_key ) ) != 0 )
return rc; return rc;
if ( ( rc = ecdsa_parse_key ( &pubkey, public_key ) ) != 0 ) if ( ( rc = ecdsa_parse_key ( &public, public_key ) ) != 0 )
return rc; return rc;
/* Compare curves */ /* Compare curves */
if ( privkey.curve != pubkey.curve ) if ( private.curve != public.curve )
return -ENOTTY; return -ENOTTY;
curve = privkey.curve; curve = private.curve;
/* Compare public curve points */ /* 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 -ENOTTY;
return 0; return 0;
+25 -79
View File
@@ -323,12 +323,14 @@ static void rsa_cipher ( struct rsa_context *context,
/** /**
* Encrypt using RSA PKCS#1 * Encrypt using RSA PKCS#1
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v plaintext Plaintext * @v plaintext Plaintext
* @v ciphertext Ciphertext * @v ciphertext Ciphertext
* @ret ciphertext_len Length of ciphertext, or negative error * @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, const struct asn1_cursor *plaintext,
struct asn1_builder *ciphertext ) { struct asn1_builder *ciphertext ) {
struct rsa_context context; struct rsa_context context;
@@ -400,12 +402,14 @@ static int rsa_pkcs1_encrypt ( const struct asn1_cursor *key,
/** /**
* Decrypt using RSA PKCS#1 * Decrypt using RSA PKCS#1
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v ciphertext Ciphertext * @v ciphertext Ciphertext
* @v plaintext Plaintext * @v plaintext Plaintext
* @ret rc Return status code * @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, const struct asn1_cursor *ciphertext,
struct asn1_builder *plaintext ) { struct asn1_builder *plaintext ) {
struct rsa_context context; struct rsa_context context;
@@ -667,16 +671,18 @@ static int rsa_pss_encode ( struct rsa_context *context,
/** /**
* Sign digest value using RSA * Sign digest value using RSA
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @v encode Encoding method
* @ret rc Return status code * @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 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; struct rsa_context context;
int rc; int rc;
@@ -717,17 +723,18 @@ static int rsa_sign ( const struct asn1_cursor *key,
/** /**
* Verify signed digest value using RSA * Verify signed digest value using RSA
* *
* @v pubkey Public-key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @v encoding Encoding method
* @ret rc Return status code * @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, struct digest_algorithm *digest, const void *value,
const struct asn1_cursor *signature, const struct asn1_cursor *signature ) {
rsa_encode_t *encode ) { rsa_encode_t *encode = pubkey->priv;
struct rsa_context context; struct rsa_context context;
void *temp; void *temp;
void *expected; void *expected;
@@ -792,79 +799,16 @@ static int rsa_verify ( const struct asn1_cursor *key,
return rc; 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 * Check for matching RSA public/private key pair
* *
* @v pubkey Public-key algorithm
* @v private_key Private key * @v private_key Private key
* @v public_key Public key * @v public_key Public key
* @ret rc Return status code * @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 ) { const struct asn1_cursor *public_key ) {
struct asn1_cursor private_modulus; struct asn1_cursor private_modulus;
struct asn1_cursor private_exponent; struct asn1_cursor private_exponent;
@@ -892,9 +836,10 @@ struct pubkey_algorithm rsa_algorithm = {
.name = "rsa", .name = "rsa",
.encrypt = rsa_pkcs1_encrypt, .encrypt = rsa_pkcs1_encrypt,
.decrypt = rsa_pkcs1_decrypt, .decrypt = rsa_pkcs1_decrypt,
.sign = rsa_pkcs1_sign, .sign = rsa_sign,
.verify = rsa_pkcs1_verify, .verify = rsa_verify,
.match = rsa_match, .match = rsa_match,
.priv = rsa_pkcs1_encode,
}; };
/** RSA-PSS public-key algorithm */ /** RSA-PSS public-key algorithm */
@@ -902,9 +847,10 @@ struct pubkey_algorithm rsa_pss_algorithm = {
.name = "rsa_pss", .name = "rsa_pss",
.encrypt = pubkey_null_encrypt, .encrypt = pubkey_null_encrypt,
.decrypt = pubkey_null_decrypt, .decrypt = pubkey_null_decrypt,
.sign = rsa_pss_sign, .sign = rsa_sign,
.verify = rsa_pss_verify, .verify = rsa_verify,
.match = rsa_match, .match = rsa_match,
.priv = rsa_pss_encode,
}; };
/* Drag in objects via rsa_algorithm */ /* Drag in objects via rsa_algorithm */
+33 -14
View File
@@ -142,54 +142,66 @@ struct pubkey_algorithm {
const char *name; const char *name;
/** Encrypt /** Encrypt
* *
* @v pubkey Public key algorithm
* @v key Key * @v key Key
* @v plaintext Plaintext * @v plaintext Plaintext
* @v ciphertext Ciphertext * @v ciphertext Ciphertext
* @ret rc Return status code * @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, const struct asn1_cursor *plaintext,
struct asn1_builder *ciphertext ); struct asn1_builder *ciphertext );
/** Decrypt /** Decrypt
* *
* @v pubkey Public key algorithm
* @v key Key * @v key Key
* @v ciphertext Ciphertext * @v ciphertext Ciphertext
* @v plaintext Plaintext * @v plaintext Plaintext
* @ret rc Return status code * @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, const struct asn1_cursor *ciphertext,
struct asn1_builder *plaintext ); struct asn1_builder *plaintext );
/** Sign digest value /** Sign digest value
* *
* @v pubkey Public key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @ret rc Return status code * @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 digest_algorithm *digest, const void *value,
struct asn1_builder *builder ); struct asn1_builder *builder );
/** Verify signed digest value /** Verify signed digest value
* *
* @v pubkey Public key algorithm
* @v key Key * @v key Key
* @v digest Digest algorithm * @v digest Digest algorithm
* @v value Digest value * @v value Digest value
* @v signature Signature * @v signature Signature
* @ret rc Return status code * @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, struct digest_algorithm *digest, const void *value,
const struct asn1_cursor *signature ); const struct asn1_cursor *signature );
/** Check that public key matches private key /** Check that public key matches private key
* *
* @v pubkey Public key algorithm
* @v private_key Private key * @v private_key Private key
* @v public_key Public key * @v public_key Public key
* @ret rc Return status code * @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 ); const struct asn1_cursor *public_key );
/** Algorithm private data */
void *priv;
}; };
/** A key exchange algorithm */ /** 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, pubkey_encrypt ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
const struct asn1_cursor *plaintext, const struct asn1_cursor *plaintext,
struct asn1_builder *ciphertext ) { struct asn1_builder *ciphertext ) {
return pubkey->encrypt ( key, plaintext, ciphertext ); return pubkey->encrypt ( pubkey, key, plaintext, ciphertext );
} }
static inline __attribute__ (( always_inline )) int static inline __attribute__ (( always_inline )) int
pubkey_decrypt ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, pubkey_decrypt ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
const struct asn1_cursor *ciphertext, const struct asn1_cursor *ciphertext,
struct asn1_builder *plaintext ) { struct asn1_builder *plaintext ) {
return pubkey->decrypt ( key, ciphertext, plaintext ); return pubkey->decrypt ( pubkey, key, ciphertext, plaintext );
} }
static inline __attribute__ (( always_inline )) int static inline __attribute__ (( always_inline )) int
pubkey_sign ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key, pubkey_sign ( struct pubkey_algorithm *pubkey, const struct asn1_cursor *key,
struct digest_algorithm *digest, const void *value, struct digest_algorithm *digest, const void *value,
struct asn1_builder *signature ) { 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 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 struct asn1_cursor *signature ) { 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 static inline __attribute__ (( always_inline )) int
pubkey_match ( struct pubkey_algorithm *pubkey, pubkey_match ( struct pubkey_algorithm *pubkey,
const struct asn1_cursor *private_key, const struct asn1_cursor *private_key,
const struct asn1_cursor *public_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 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, extern void cipher_null_auth ( struct cipher_algorithm *cipher, void *ctx,
void *auth ); 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, const struct asn1_cursor *plaintext,
struct asn1_builder *ciphertext ); 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, const struct asn1_cursor *ciphertext,
struct asn1_builder *plaintext ); 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, struct digest_algorithm *digest,
const void *value, const void *value,
struct asn1_builder *signature ); 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, struct digest_algorithm *digest,
const void *value, const void *value,
const struct asn1_cursor *signature ); 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 digest_algorithm digest_null;
extern struct cipher_algorithm cipher_null; extern struct cipher_algorithm cipher_null;