]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Allow construction of shared public key to return an error
authorMichael Brown <mcb30@ipxe.org>
Thu, 25 Jun 2026 09:04:56 +0000 (10:04 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 25 Jun 2026 11:13:26 +0000 (12:13 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/elliptic.c
src/crypto/ffdhe.c
src/crypto/x25519.c
src/include/ipxe/crypto.h
src/include/ipxe/elliptic.h
src/include/ipxe/ffdhe.h
src/net/tls.c
src/tests/exchange_test.c

index 75b8ba0689c2e05ab4dc23353223f3b4ab6a265c..8c07b7ab2fb4d2a9ea94919067ad030936e3d7c4 100644 (file)
@@ -42,8 +42,9 @@ FILE_SECBOOT ( PERMITTED );
  * @v exchange         Key exchange algorithm
  * @v private          Private key
  * @v public           Public key to fill in
+ * @ret rc             Return status code
  */
-void elliptic_share ( struct exchange_algorithm *exchange, const void *private,
+int elliptic_share ( struct exchange_algorithm *exchange, const void *private,
                      void *public ) {
        struct elliptic_curve *curve = exchange->priv;
        size_t len = exchange->sharedsize;
@@ -57,10 +58,14 @@ void elliptic_share ( struct exchange_algorithm *exchange, const void *private,
 
        /* Calculate public key */
        result->format = ELLIPTIC_FORMAT_UNCOMPRESSED;
-       rc = elliptic_multiply ( curve, curve->base, private, &result->xy );
+       if ( ( rc = elliptic_multiply ( curve, curve->base, private,
+                                       &result->xy ) ) != 0 ) {
+               /* Can never fail when using the curve's own base point */
+               assert ( 0 );
+               return rc;
+       }
 
-       /* Can never fail when using the curve's own base point */
-       assert ( rc == 0 );
+       return rc;
 }
 
 /**
index 46259f2eb538d5e538104cc3abe160d4ec3c86da..c47b03d4a1c5565df2bc194acc02c5531bfda1e4 100644 (file)
@@ -264,12 +264,13 @@ static int ffdhe ( struct ffdhe_group *group, const void *public,
  * @v exchange         Key exchange algorithm
  * @v private          Private key
  * @v public           Public key to fill in
+ * @ret rc             Return status code
  */
-void ffdhe_share ( struct exchange_algorithm *exchange, const void *private,
-                  void *public ) {
+int ffdhe_share ( struct exchange_algorithm *exchange, const void *private,
+                 void *public ) {
        struct ffdhe_group *group = exchange->priv;
 
-       ffdhe ( group, NULL, private, public );
+       return ffdhe ( group, NULL, private, public );
 }
 
 /**
index c52f0f1e8c71dfa4dc430ef31d1684370b059694..f4bf59a852e9461a83937bb0526b42203a116b04 100644 (file)
@@ -836,12 +836,15 @@ void x25519_key ( const struct x25519_value *base,
  * @v exchange         Key exchange algorithm
  * @v private          Private key
  * @v public           Public key to fill in
+ * @ret rc             Return status code
  */
-static void x25519_share ( struct exchange_algorithm *exchange __unused,
-                          const void *private, void *public ) {
+static int x25519_share ( struct exchange_algorithm *exchange __unused,
+                         const void *private, void *public ) {
 
        /* Calculate public key */
        x25519_key ( &x25519_generator, private, public );
+
+       return 0;
 }
 
 /**
index 2ee3794c7c348eeffd4197183e50007300b49ffc..72f4b73763adf853d8c092de0e06a31770638fbe 100644 (file)
@@ -220,9 +220,10 @@ struct exchange_algorithm {
         * @v exchange          Key exchange algorithm
         * @v private           Private key
         * @v public            Public key to fill in
+        * @ret rc              Return status code
         */
-       void ( * share ) ( struct exchange_algorithm *exchange,
-                          const void *private, void *public );
+       int ( * share ) ( struct exchange_algorithm *exchange,
+                         const void *private, void *public );
        /**
         * Agree shared secret
         *
@@ -390,10 +391,10 @@ pubkey_match ( struct pubkey_algorithm *pubkey,
        return pubkey->match ( pubkey, private_key, public_key );
 }
 
-static inline __attribute__ (( always_inline )) void
+static inline __attribute__ (( always_inline )) int
 exchange_share ( struct exchange_algorithm *exchange, const void *private,
                 void *public ) {
-       exchange->share ( exchange, private, public );
+       return exchange->share ( exchange, private, public );
 }
 
 static inline __attribute__ (( always_inline )) int
index ff316510173cdcbb607d047448ec436d87228497..8989afa159e6e50fdf236c0d64a740072b5195b7 100644 (file)
@@ -29,8 +29,8 @@ FILE_SECBOOT ( PERMITTED );
 /** Format byte for uncompressed curve point representation */
 #define ELLIPTIC_FORMAT_UNCOMPRESSED 0x04
 
-extern void elliptic_share ( struct exchange_algorithm *exchange,
-                            const void *private, void *public );
+extern int elliptic_share ( struct exchange_algorithm *exchange,
+                           const void *private, void *public );
 extern int elliptic_agree ( struct exchange_algorithm *exchange,
                            const void *private, const void *partner,
                            void *shared );
index aa76b6b8fdadedeb9896a2077bfd801369a8b7ee..be8983b0657bb95f47717e26042cc0f317cab609 100644 (file)
@@ -33,8 +33,8 @@ struct ffdhe_group {
        uint32_t lsb32;
 };
 
-extern void ffdhe_share ( struct exchange_algorithm *exchange,
-                         const void *private, void *public );
+extern int ffdhe_share ( struct exchange_algorithm *exchange,
+                        const void *private, void *public );
 extern int ffdhe_agree ( struct exchange_algorithm *exchange,
                         const void *private, const void *partner,
                         void *shared );
index 097e72ee022bf15683524f50d22edb719445bbb9..66bf19c72e116c34ba1dd1cef69e9d25db29767a 100644 (file)
@@ -1820,7 +1820,10 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
                          htonl ( sizeof ( key_xchg ) -
                                  sizeof ( key_xchg.type_length ) ) );
                key_xchg.public_len = sizeof ( key_xchg.public );
-               exchange_share ( exchange, private, key_xchg.public );
+               if ( ( rc = exchange_share ( exchange, private,
+                                            key_xchg.public ) ) != 0 ) {
+                       return rc;
+               }
 
                /* Transmit Client Key Exchange record */
                if ( ( rc = tls_send_handshake ( tls, &key_xchg,
index d3b1e9306a2848388a1963b44a08363d0fa71eb2..3477c8930956b46d784f2d2d2da301239387b849 100644 (file)
@@ -67,7 +67,8 @@ void exchange_okx ( struct exchange_test *test, const char *file,
        /* Verify calculation of public key */
        DBGC ( test, "KEX %s private key:\n", exchange->name );
        DBGC_HDA ( test, 0, test->private, exchange->privsize );
-       exchange_share ( exchange, test->private, actual->public );
+       okx ( exchange_share ( exchange, test->private, actual->public ) == 0,
+             file, line );
        DBGC ( test, "KEX %s public key:\n", exchange->name );
        DBGC_HDA ( test, 0, actual->public, exchange->pubsize );
        okx ( memcmp ( actual->public, test->public, exchange->pubsize ) == 0,