From: Michael Brown Date: Wed, 17 Jun 2026 09:48:18 +0000 (+0100) Subject: [crypto] Use private data field for key exchange algorithms X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=25072c19053fe87993486e411eb85d059856f1fc;p=thirdparty%2Fipxe.git [crypto] Use private data field for key exchange algorithms For historical reasons, TLS versions 1.2 and earlier identify FFDHE groups by specifying the raw group prime and generator (the "dh_p" and "dh_g" fields in ServerDHParams), rather than using a numeric code to identify a named group. This adds complexity to the process of identifying the internal key exchange algorithm. One option would be to extend the definition of struct tls_key_exchange_algorithm to include the identifying values for the field prime and generator, but this is undesirable since the field prime values may be large, and these values are already available (indirectly) in ffdhe.c. Extend our definition of a key exchange algorithm to include an opaque private data field. This allows us to remove the wrapper functions currently created by FFDHE_GROUP() and WEIERSTRASS_CURVE(), and opens up the option of accessing the existing FFDHE field prime and generator values from within the TLS layer. Signed-off-by: Michael Brown --- diff --git a/src/crypto/ffdhe.c b/src/crypto/ffdhe.c index d6f9449be..004170ddb 100644 --- a/src/crypto/ffdhe.c +++ b/src/crypto/ffdhe.c @@ -194,8 +194,8 @@ static struct { * @v shared Shared result to fill in * @ret rc Return status code */ -int ffdhe ( struct ffdhe_group *group, const void *public, const void *private, - void *shared ) { +static int ffdhe ( struct ffdhe_group *group, const void *public, + const void *private, void *shared ) { unsigned int expsize = group->expsize; unsigned int size = group->size; size_t explen = group->explen; @@ -253,6 +253,36 @@ int ffdhe ( struct ffdhe_group *group, const void *public, const void *private, return 0; } +/** + * Calculate public key + * + * @v exchange Key exchange algorithm + * @v private Private key + * @v public Public key to fill in + */ +void ffdhe_public ( struct exchange_algorithm *exchange, const void *private, + void *public ) { + struct ffdhe_group *group = exchange->priv; + + ffdhe ( group, NULL, private, public ); +} + +/** + * Calculate shared secret + * + * @v exchange Key exchange algorithm + * @v private Private key + * @v partner Partner public key + * @v shared Shared secret to fill in + * @ret rc Return status code + */ +int ffdhe_shared ( struct exchange_algorithm *exchange, const void *private, + const void *partner, void *shared ) { + struct ffdhe_group *group = exchange->priv; + + return ffdhe ( group, partner, private, shared ); +} + /* Supported groups */ FFDHE_GROUP ( ffdhe2048, ffdhe2048_algorithm, euler, 2048, 225, 0x61285c97 ); FFDHE_GROUP ( ffdhe3072, ffdhe3072_algorithm, euler, 3072, 275, 0x66c62e37 ); diff --git a/src/crypto/weierstrass.c b/src/crypto/weierstrass.c index ab2df2407..7fa18ca41 100644 --- a/src/crypto/weierstrass.c +++ b/src/crypto/weierstrass.c @@ -1030,12 +1030,13 @@ int weierstrass_add_once ( struct weierstrass_curve *curve, /** * Calculate public key * - * @v curve Weierstrass curve + * @v exchange Key exchange algorithm * @v private Private key * @v public Public key to fill in */ -void weierstrass_public ( struct weierstrass_curve *curve, const void *private, - void *public ) { +void weierstrass_public ( struct exchange_algorithm *exchange, + const void *private, void *public ) { + struct weierstrass_curve *curve = exchange->priv; size_t len = curve->len; weierstrass_uncompressed_t ( len ) *uncompressed = public; int rc; @@ -1052,14 +1053,16 @@ void weierstrass_public ( struct weierstrass_curve *curve, const void *private, /** * Calculate shared secret * - * @v curve Weierstrass curve + * @v exchange Key exchange algorithm * @v private Private key * @v partner Partner public key * @v shared Shared secret to fill in * @ret rc Return status code */ -int weierstrass_shared ( struct weierstrass_curve *curve, const void *private, - const void *partner, void *shared ) { +int weierstrass_shared ( struct exchange_algorithm *exchange, + const void *private, const void *partner, + void *shared ) { + struct weierstrass_curve *curve = exchange->priv; size_t len = curve->len; const weierstrass_uncompressed_t ( len ) *uncompressed = partner; weierstrass_raw_t ( len ) point; diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c index 58382bc89..5eb74b627 100644 --- a/src/crypto/x25519.c +++ b/src/crypto/x25519.c @@ -833,10 +833,12 @@ void x25519_key ( const struct x25519_value *base, /** * Calculate public key * + * @v exchange Key exchange algorithm * @v private Private key * @v public Public key to fill in */ -static void x25519_public ( const void *private, void *public ) { +static void x25519_public ( struct exchange_algorithm *exchange __unused, + const void *private, void *public ) { /* Calculate public key */ x25519_key ( &x25519_generator, private, public ); @@ -845,12 +847,14 @@ static void x25519_public ( const void *private, void *public ) { /** * Calculate shared secret * + * @v exchange Key exchange algorithm * @v private Private key * @v partner Partner public key * @v shared Shared secret to fill in * @ret rc Return status code */ -static int x25519_shared ( const void *private, const void *partner, +static int x25519_shared ( struct exchange_algorithm *exchange __unused, + const void *private, const void *partner, void *shared ) { /* Calculate shared secret */ diff --git a/src/include/ipxe/crypto.h b/src/include/ipxe/crypto.h index ad085533a..e512ae06c 100644 --- a/src/include/ipxe/crypto.h +++ b/src/include/ipxe/crypto.h @@ -187,20 +187,26 @@ struct exchange_algorithm { /** * Calculate public key * + * @v exchange Key exchange algorithm * @v private Private key * @v public Public key to fill in */ - void ( * public ) ( const void *private, void *public ); + void ( * public ) ( struct exchange_algorithm *exchange, + const void *private, void *public ); /** * Calculate shared secret * + * @v exchange Key exchange algorithm * @v private Private key * @v partner Partner public key * @v shared Shared secret to fill in * @ret rc Return status code */ - int ( * shared ) ( const void *private, const void *partner, + int ( * shared ) ( struct exchange_algorithm *exchange, + const void *private, const void *partner, void *shared ); + /** Algorithm private data */ + void *priv; }; /** An elliptic curve */ @@ -350,13 +356,13 @@ pubkey_match ( struct pubkey_algorithm *pubkey, static inline __attribute__ (( always_inline )) void exchange_public ( struct exchange_algorithm *exchange, const void *private, void *public ) { - exchange->public ( private, public ); + exchange->public ( exchange, private, public ); } static inline __attribute__ (( always_inline )) int exchange_shared ( struct exchange_algorithm *exchange, const void *private, const void *partner, void *shared ) { - return exchange->shared ( private, partner, shared ); + return exchange->shared ( exchange, private, partner, shared ); } static inline __attribute__ (( always_inline )) int diff --git a/src/include/ipxe/ffdhe.h b/src/include/ipxe/ffdhe.h index 349680fdf..12e0e3160 100644 --- a/src/include/ipxe/ffdhe.h +++ b/src/include/ipxe/ffdhe.h @@ -33,8 +33,11 @@ struct ffdhe_group { uint32_t lsb32; }; -extern int ffdhe ( struct ffdhe_group *group, const void *public, - const void *private, void *shared ); +extern void ffdhe_public ( struct exchange_algorithm *exchange, + const void *private, void *public ); +extern int ffdhe_shared ( struct exchange_algorithm *exchange, + const void *private, const void *partner, + void *shared ); /** Define a finite field DHE group */ #define FFDHE_GROUP( _name, _exchange, _constant, _bits, _expbits, _lsb ) \ @@ -47,23 +50,14 @@ extern int ffdhe ( struct ffdhe_group *group, const void *public, .expsize = bigint_required_size ( ( _expbits + 7 ) / 8 ), \ .lsb32 = cpu_to_be32 ( _lsb ), \ }; \ - static void _name ## _public ( const void *private, \ - void *public ) { \ - ffdhe ( &_name ## _group, NULL, private, public ); \ - } \ - static int _name ## _shared ( const void *private, \ - const void *partner, \ - void *shared ) { \ - return ffdhe ( &_name ## _group, partner, private, \ - shared ); \ - } \ struct exchange_algorithm _exchange = { \ .name = #_name, \ .privsize = ( ( _expbits + 7 ) / 8 ), \ .pubsize = ( _bits / 8 ), \ .sharedsize = ( _bits / 8 ), \ - .public = _name ## _public, \ - .shared = _name ## _shared, \ + .public = ffdhe_public, \ + .shared = ffdhe_shared, \ + .priv = &_name ## _group, \ } extern struct exchange_algorithm ffdhe2048_algorithm; diff --git a/src/include/ipxe/weierstrass.h b/src/include/ipxe/weierstrass.h index fa2e53cc9..4095b4a77 100644 --- a/src/include/ipxe/weierstrass.h +++ b/src/include/ipxe/weierstrass.h @@ -164,9 +164,9 @@ extern int weierstrass_multiply ( struct weierstrass_curve *curve, extern int weierstrass_add_once ( struct weierstrass_curve *curve, const void *addend, const void *augend, void *result ); -extern void weierstrass_public ( struct weierstrass_curve *curve, +extern void weierstrass_public ( struct exchange_algorithm *exchange, const void *private, void *public ); -extern int weierstrass_shared ( struct weierstrass_curve *curve, +extern int weierstrass_shared ( struct exchange_algorithm *exchange, const void *private, const void *partner, void *shared ); @@ -209,17 +209,6 @@ extern int weierstrass_shared ( struct weierstrass_curve *curve, return weierstrass_add_once ( &_name ## _weierstrass, \ addend, augend, result ); \ } \ - static void _name ## _public ( const void *private, \ - void *public ) { \ - weierstrass_public ( &_name ## _weierstrass, \ - private, public ); \ - } \ - static int _name ## _shared ( const void *private, \ - const void *partner, \ - void *shared ) { \ - return weierstrass_shared ( &_name ## _weierstrass, \ - private, partner, shared ); \ - } \ struct elliptic_curve _curve = { \ .name = #_name, \ .pointsize = sizeof ( weierstrass_raw_t(_len) ), \ @@ -235,8 +224,9 @@ extern int weierstrass_shared ( struct weierstrass_curve *curve, .privsize = (_len), \ .pubsize = sizeof ( weierstrass_uncompressed_t(_len) ), \ .sharedsize = (_len), \ - .public = _name ## _public, \ - .shared = _name ## _shared, \ + .public = weierstrass_public, \ + .shared = weierstrass_shared, \ + .priv = &_name ## _weierstrass, \ } #endif /* _IPXE_WEIERSTRASS_H */