[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 <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2026-06-17 10:48:18 +01:00
parent 70d63bec94
commit 25072c1905
6 changed files with 70 additions and 43 deletions
+32 -2
View File
@@ -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 );
+9 -6
View File
@@ -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;
+6 -2
View File
@@ -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 */
+10 -4
View File
@@ -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
+8 -14
View File
@@ -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;
+5 -15
View File
@@ -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 */