]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Use private data field for key exchange algorithms
authorMichael Brown <mcb30@ipxe.org>
Wed, 17 Jun 2026 09:48:18 +0000 (10:48 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 17 Jun 2026 12:38:50 +0000 (13:38 +0100)
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>
src/crypto/ffdhe.c
src/crypto/weierstrass.c
src/crypto/x25519.c
src/include/ipxe/crypto.h
src/include/ipxe/ffdhe.h
src/include/ipxe/weierstrass.h

index d6f9449bef1c19d3fb7588ff8ed177fe771fbda3..004170ddb3de2ac5d3eb3d3b0c840e8467877181 100644 (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 );
index ab2df240794ecd0890f03d1827f9e4849a8d1a0b..7fa18ca41da0747cc9c15c0f2f27e99bdcfd8c3e 100644 (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;
index 58382bc8914745ab055c642f2812d189b68a1df1..5eb74b627366732861b5219682f69fc39ef2bac4 100644 (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 */
index ad085533a3b90056d95d18414f80e5f243be238f..e512ae06ccc1ad05613f353a55c7e5c5547fdcac 100644 (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
index 349680fdfddd94c1dafd21ba1755eea892f35330..12e0e31600c6daf1a8186e8140ca48680fa431a5 100644 (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;
index fa2e53cc982fc2592b161f7154093c913aefcb3e..4095b4a779f9c6fc743ef56bfbfdb4773cc63e02 100644 (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 */