]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tls] Treat signature algorithm identifiers as opaque 16-bit values
authorMichael Brown <mcb30@ipxe.org>
Thu, 30 Apr 2026 10:56:41 +0000 (11:56 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 30 Apr 2026 12:14:20 +0000 (13:14 +0100)
RFC 5246 defines the signature_algorithm extension values for TLS
version 1.2 as being tuples of {HashAlgorithm, SignatureAlgorithm}
pairs.  RFC 8446 redefines the signature_algorithm extension values
for TLS version 1.3 in a backwards-compatible way as opaque 16-bit
SignatureScheme values, and RFC 8447 updates RFC 5246 to allow these
values to be used with TLS version 1.2.

Redefine our concept of a signature algorithm identifier to remove the
internal structure that no longer exists.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/mishmash/ecdsa_sha224.c
src/crypto/mishmash/ecdsa_sha256.c
src/crypto/mishmash/ecdsa_sha384.c
src/crypto/mishmash/ecdsa_sha512.c
src/crypto/mishmash/rsa_sha1.c
src/crypto/mishmash/rsa_sha224.c
src/crypto/mishmash/rsa_sha256.c
src/crypto/mishmash/rsa_sha384.c
src/crypto/mishmash/rsa_sha512.c
src/include/ipxe/tls.h
src/net/tls.c

index 92aa881cdbe55ae5629a43fa3515b52f912a0f09..fcd9baf22b2e5e4b9d77c24effc31aae35406bab 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/ecdsa.h>
 #include <ipxe/sha256.h>
 #include <ipxe/asn1.h>
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha224_algorithm __asn1_algorithm = {
 /** ECDSA with SHA-224 signature hash algorithm */
 struct tls_signature_hash_algorithm
 tls_ecdsa_sha224 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_ECDSA_ALGORITHM,
-               .hash = TLS_SHA224_ALGORITHM,
-       },
+       .code = htons ( TLS_ECDSA_SHA224_ALGORITHM ),
        .pubkey = &ecdsa_algorithm,
        .digest = &sha224_algorithm,
 };
index 025d6ec7313d08963e29e0619eecccf416470a12..0135f4c570dae6117a47798ecff4ef2e4c6ab494 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/ecdsa.h>
 #include <ipxe/sha256.h>
 #include <ipxe/asn1.h>
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha256_algorithm __asn1_algorithm = {
 /** ECDSA with SHA-256 signature hash algorithm */
 struct tls_signature_hash_algorithm
 tls_ecdsa_sha256 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_ECDSA_ALGORITHM,
-               .hash = TLS_SHA256_ALGORITHM,
-       },
+       .code = htons ( TLS_ECDSA_SHA256_ALGORITHM ),
        .pubkey = &ecdsa_algorithm,
        .digest = &sha256_algorithm,
 };
index d7a0ca5d64ae3148f06f2ea025bf8f428b640567..e6de2b8ef65e382e6d6bcf7d8a63ad32242c4230 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/ecdsa.h>
 #include <ipxe/sha512.h>
 #include <ipxe/asn1.h>
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha384_algorithm __asn1_algorithm = {
 /** ECDSA with SHA-384 signature hash algorithm */
 struct tls_signature_hash_algorithm
 tls_ecdsa_sha384 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_ECDSA_ALGORITHM,
-               .hash = TLS_SHA384_ALGORITHM,
-       },
+       .code = htons ( TLS_ECDSA_SHA384_ALGORITHM ),
        .pubkey = &ecdsa_algorithm,
        .digest = &sha384_algorithm,
 };
index 15391abf21e5861a3272a8b6afe0819990b9a03c..2d97566b2cb2b63bd4ee57e5dcb4014fca0c5ccd 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/ecdsa.h>
 #include <ipxe/sha512.h>
 #include <ipxe/asn1.h>
@@ -43,10 +44,7 @@ struct asn1_algorithm ecdsa_with_sha512_algorithm __asn1_algorithm = {
 /** ECDSA with SHA-512 signature hash algorithm */
 struct tls_signature_hash_algorithm
 tls_ecdsa_sha512 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_ECDSA_ALGORITHM,
-               .hash = TLS_SHA512_ALGORITHM,
-       },
+       .code = htons ( TLS_ECDSA_SHA512_ALGORITHM ),
        .pubkey = &ecdsa_algorithm,
        .digest = &sha512_algorithm,
 };
index 8907ac08a93e5fd07bdd86de85992ab43de8bc33..21991c210b1d7fffd76b5d08f07f4a3dc1fb08e5 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/rsa.h>
 #include <ipxe/sha1.h>
 #include <ipxe/asn1.h>
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha1_prefix __rsa_digestinfo_prefix = {
 
 /** RSA with SHA-1 signature hash algorithm */
 struct tls_signature_hash_algorithm tls_rsa_sha1 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_RSA_ALGORITHM,
-               .hash = TLS_SHA1_ALGORITHM,
-       },
+       .code = htons ( TLS_RSA_SHA1_ALGORITHM ),
        .pubkey = &rsa_algorithm,
        .digest = &sha1_algorithm,
 };
index b676d41f3304bbdf1aea52e7819b79d617937904..ce8f6b65e69fa0f86bfc24fadddfe0b2e2df8e57 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/rsa.h>
 #include <ipxe/sha256.h>
 #include <ipxe/asn1.h>
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha224_prefix __rsa_digestinfo_prefix = {
 
 /** RSA with SHA-224 signature hash algorithm */
 struct tls_signature_hash_algorithm tls_rsa_sha224 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_RSA_ALGORITHM,
-               .hash = TLS_SHA224_ALGORITHM,
-       },
+       .code = htons ( TLS_RSA_SHA224_ALGORITHM ),
        .pubkey = &rsa_algorithm,
        .digest = &sha224_algorithm,
 };
index 8a6a7a5cf4c332f829a5024d3dee9c3de0317f47..f672f0f0f3c100ed9bd98431e88324919d4efe57 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/rsa.h>
 #include <ipxe/sha256.h>
 #include <ipxe/asn1.h>
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha256_prefix __rsa_digestinfo_prefix = {
 
 /** RSA with SHA-256 signature hash algorithm */
 struct tls_signature_hash_algorithm tls_rsa_sha256 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_RSA_ALGORITHM,
-               .hash = TLS_SHA256_ALGORITHM,
-       },
+       .code = htons ( TLS_RSA_SHA256_ALGORITHM ),
        .pubkey = &rsa_algorithm,
        .digest = &sha256_algorithm,
 };
index cc1878bd44c7effa89375c94c0a7a9e4b7afd14a..bb8e06efb9a064d841b7cb9d4c8a61418dcd7fe6 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/rsa.h>
 #include <ipxe/sha512.h>
 #include <ipxe/asn1.h>
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha384_prefix __rsa_digestinfo_prefix = {
 
 /** RSA with SHA-384 signature hash algorithm */
 struct tls_signature_hash_algorithm tls_rsa_sha384 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_RSA_ALGORITHM,
-               .hash = TLS_SHA384_ALGORITHM,
-       },
+       .code = htons ( TLS_RSA_SHA384_ALGORITHM ),
        .pubkey = &rsa_algorithm,
        .digest = &sha384_algorithm,
 };
index 9c995e1c8ed1680372b8e8c1760dd0b1897bc19a..48d1fe2ddc0966d2a0cbf01c96b2c23b7f8b3ed2 100644 (file)
@@ -24,6 +24,7 @@
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 FILE_SECBOOT ( PERMITTED );
 
+#include <byteswap.h>
 #include <ipxe/rsa.h>
 #include <ipxe/sha512.h>
 #include <ipxe/asn1.h>
@@ -54,10 +55,7 @@ struct rsa_digestinfo_prefix rsa_sha512_prefix __rsa_digestinfo_prefix = {
 
 /** RSA with SHA-512 signature hash algorithm */
 struct tls_signature_hash_algorithm tls_rsa_sha512 __tls_sig_hash_algorithm = {
-       .code = {
-               .signature = TLS_RSA_ALGORITHM,
-               .hash = TLS_SHA512_ALGORITHM,
-       },
+       .code = htons ( TLS_RSA_SHA512_ALGORITHM ),
        .pubkey = &rsa_algorithm,
        .digest = &sha512_algorithm,
 };
index 4e5e25755b2c498b1b4d06dda96f5e23cbb8dd2f..7e4662c0d5df8afa505b39315d825a3fc03b1b23 100644 (file)
@@ -113,17 +113,16 @@ struct tls_header {
 #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xc02f
 #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xc030
 
-/* TLS hash algorithm identifiers */
-#define TLS_MD5_ALGORITHM 1
-#define TLS_SHA1_ALGORITHM 2
-#define TLS_SHA224_ALGORITHM 3
-#define TLS_SHA256_ALGORITHM 4
-#define TLS_SHA384_ALGORITHM 5
-#define TLS_SHA512_ALGORITHM 6
-
-/* TLS signature algorithm identifiers */
-#define TLS_RSA_ALGORITHM 1
-#define TLS_ECDSA_ALGORITHM 3
+/* TLS signature hash algorithm identifiers */
+#define TLS_RSA_SHA1_ALGORITHM 0x0201
+#define TLS_RSA_SHA224_ALGORITHM 0x0301
+#define TLS_ECDSA_SHA224_ALGORITHM 0x0303
+#define TLS_RSA_SHA256_ALGORITHM 0x0401
+#define TLS_ECDSA_SHA256_ALGORITHM 0x0403
+#define TLS_RSA_SHA384_ALGORITHM 0x0501
+#define TLS_ECDSA_SHA384_ALGORITHM 0x0503
+#define TLS_RSA_SHA512_ALGORITHM 0x0601
+#define TLS_ECDSA_SHA512_ALGORITHM 0x0603
 
 /* TLS server name extension */
 #define TLS_SERVER_NAME 0
@@ -279,22 +278,14 @@ struct tls_cipherspec_pair {
        struct tls_cipherspec pending;
 };
 
-/** A TLS signature and hash algorithm identifier */
-struct tls_signature_hash_id {
-       /** Hash algorithm */
-       uint8_t hash;
-       /** Signature algorithm */
-       uint8_t signature;
-} __attribute__ (( packed ));
-
 /** A TLS signature algorithm */
 struct tls_signature_hash_algorithm {
        /** Digest algorithm */
        struct digest_algorithm *digest;
        /** Public-key algorithm */
        struct pubkey_algorithm *pubkey;
-       /** Numeric code */
-       struct tls_signature_hash_id code;
+       /** Numeric code (in network-endian order) */
+       uint16_t code;
 };
 
 /** TLS signature hash algorithm table
index c1182bbcd7cc81cee73a0dea1bcab75920de9c7b..8ca3a0fcba070e052f2f177a8c422d5b1ea07ec5 100644 (file)
@@ -1033,38 +1033,19 @@ tls_signature_hash_algorithm ( struct pubkey_algorithm *pubkey,
 }
 
 /**
- * Find TLS signature algorithm
- *
- * @v code             Signature and hash algorithm identifier
- * @ret pubkey         Public key algorithm, or NULL
- */
-static struct pubkey_algorithm *
-tls_signature_hash_pubkey ( struct tls_signature_hash_id code ) {
-       struct tls_signature_hash_algorithm *sig_hash;
-
-       /* Identify signature and hash algorithm */
-       for_each_table_entry ( sig_hash, TLS_SIG_HASH_ALGORITHMS ) {
-               if ( sig_hash->code.signature == code.signature )
-                       return sig_hash->pubkey;
-       }
-
-       return NULL;
-}
-
-/**
- * Find TLS hash algorithm
+ * Find TLS signature and hash algorithm
  *
  * @v code             Signature and hash algorithm identifier
- * @ret digest         Digest algorithm, or NULL
+ * @ret sig_hash       Signature and hash algorithm, or NULL
  */
-static struct digest_algorithm *
-tls_signature_hash_digest ( struct tls_signature_hash_id code ) {
+static struct tls_signature_hash_algorithm *
+tls_find_signature_hash ( unsigned int code ) {
        struct tls_signature_hash_algorithm *sig_hash;
 
        /* Identify signature and hash algorithm */
        for_each_table_entry ( sig_hash, TLS_SIG_HASH_ALGORITHMS ) {
-               if ( sig_hash->code.hash == code.hash )
-                       return sig_hash->digest;
+               if ( sig_hash->code == code )
+                       return sig_hash;
        }
 
        return NULL;
@@ -1199,8 +1180,7 @@ static int tls_client_hello ( struct tls_connection *tls,
                uint16_t len;
                struct {
                        uint16_t len;
-                       struct tls_signature_hash_id
-                               code[TLS_NUM_SIG_HASH_ALGORITHMS];
+                       uint16_t code[TLS_NUM_SIG_HASH_ALGORITHMS];
                } __attribute__ (( packed )) data;
        } __attribute__ (( packed )) *signature_algorithms_ext;
        struct {
@@ -1502,11 +1482,12 @@ struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm = {
 static int tls_verify_dh_params ( struct tls_connection *tls,
                                  size_t param_len ) {
        struct tls_cipherspec *cipherspec = &tls->tx.cipherspec.pending;
+       struct tls_signature_hash_algorithm *sig_hash;
        struct pubkey_algorithm *pubkey;
        struct digest_algorithm *digest;
        int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
        const struct {
-               struct tls_signature_hash_id sig_hash[use_sig_hash];
+               uint16_t sig_hash[use_sig_hash];
                uint16_t signature_len;
                uint8_t signature[0];
        } __attribute__ (( packed )) *sig;
@@ -1536,13 +1517,16 @@ static int tls_verify_dh_params ( struct tls_connection *tls,
 
        /* Identify signature and hash algorithm */
        if ( use_sig_hash ) {
-               pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
-               digest = tls_signature_hash_digest ( sig->sig_hash[0] );
-               if ( ( ! pubkey ) || ( ! digest ) ) {
-                       DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
-                              "signature and hash algorithm\n", tls );
+               sig_hash = tls_find_signature_hash ( sig->sig_hash[0] );
+               if ( ! sig_hash ) {
+                       DBGC ( tls, "TLS %p unsupported signature hash "
+                              "%#04x\n", tls, sig->sig_hash[0] );
                        return -ENOTSUP_SIG_HASH;
                }
+               pubkey = sig_hash->pubkey;
+               digest = sig_hash->digest;
+               DBGC ( tls, "TLS %p using signature hash %s-%s\n",
+                      tls, pubkey->name, digest->name );
                if ( pubkey != cipherspec->suite->pubkey ) {
                        DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
                               "signature algorithm %s (expected %s)\n", tls,
@@ -1910,7 +1894,7 @@ static int tls_send_certificate_verify ( struct tls_connection *tls ) {
                int use_sig_hash = ( ( sig_hash == NULL ) ? 0 : 1 );
                struct {
                        uint32_t type_length;
-                       struct tls_signature_hash_id sig_hash[use_sig_hash];
+                       uint16_t sig_hash[use_sig_hash];
                        uint16_t signature_len;
                } __attribute__ (( packed )) header;