]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[tls] Add MAC length as a cipher suite parameter
authorMichael Brown <mcb30@ipxe.org>
Mon, 7 Nov 2022 18:11:36 +0000 (18:11 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 8 Nov 2022 14:09:18 +0000 (14:09 +0000)
TLS stream and block ciphers use a MAC with a length equal to the
output length of the digest algorithm in use.  For AEAD ciphers there
is no MAC, with the equivalent functionality provided by the cipher
algorithm's authentication tag.

Allow for the existence of AEAD cipher suites by making the MAC length
a parameter of the cipher suite.

Assume that the MAC key length is equal to the MAC length, since this
is true for all currently supported cipher suites.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/crypto/mishmash/rsa_aes_cbc_sha1.c
src/crypto/mishmash/rsa_aes_cbc_sha256.c
src/include/ipxe/tls.h
src/net/tls.c

index 765ed1138188f3badf1ceaa5335927a03e43f887..4f399a036bdc506ca4e6d012d1ffbeabf0b26e2a 100644 (file)
@@ -36,6 +36,7 @@ tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 03 ) = {
        .key_len = ( 128 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA1_DIGEST_SIZE,
        .exchange = &tls_dhe_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -49,6 +50,7 @@ tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 04 ) = {
        .key_len = ( 256 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA1_DIGEST_SIZE,
        .exchange = &tls_dhe_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -62,6 +64,7 @@ tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 13 ) = {
        .key_len = ( 128 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA1_DIGEST_SIZE,
        .exchange = &tls_pubkey_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -75,6 +78,7 @@ tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 14 ) = {
        .key_len = ( 256 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA1_DIGEST_SIZE,
        .exchange = &tls_pubkey_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
index 1cc7dfe27b96f4a272ea5ff4682310e3e27179bf..4b02a77438144cf6e00e5bb9b4e2ae1a03bb7f0d 100644 (file)
@@ -36,6 +36,7 @@ tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 01 ) = {
        .key_len = ( 128 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA256_DIGEST_SIZE,
        .exchange = &tls_dhe_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -49,6 +50,7 @@ tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 02 ) = {
        .key_len = ( 256 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA256_DIGEST_SIZE,
        .exchange = &tls_dhe_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -62,6 +64,7 @@ tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 11 ) = {
        .key_len = ( 128 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA256_DIGEST_SIZE,
        .exchange = &tls_pubkey_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
@@ -75,6 +78,7 @@ tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 12 ) = {
        .key_len = ( 256 / 8 ),
        .fixed_iv_len = 0,
        .record_iv_len = AES_BLOCKSIZE,
+       .mac_len = SHA256_DIGEST_SIZE,
        .exchange = &tls_pubkey_exchange_algorithm,
        .pubkey = &rsa_algorithm,
        .cipher = &aes_cbc_algorithm,
index be192b7efe5def3afd0b8a6f7aff7942b5267624..8796fe931d8d5cd70410291cc695ca24c1ca6185 100644 (file)
@@ -185,6 +185,8 @@ struct tls_cipher_suite {
        uint8_t fixed_iv_len;
        /** Record initialisation vector length */
        uint8_t record_iv_len;
+       /** MAC length */
+       uint8_t mac_len;
 };
 
 /** TLS cipher suite table */
index a613a08ed5546416b181bb296321b06fea521dcc..06d01aeb3a1beff34d6fde3e6180f70627e9b30d 100644 (file)
@@ -662,7 +662,7 @@ static void tls_generate_master_secret ( struct tls_connection *tls,
 static int tls_generate_keys ( struct tls_connection *tls ) {
        struct tls_cipherspec *tx_cipherspec = &tls->tx_cipherspec_pending;
        struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending;
-       size_t hash_size = tx_cipherspec->suite->digest->digestsize;
+       size_t hash_size = tx_cipherspec->suite->mac_len;
        size_t key_size = tx_cipherspec->suite->key_len;
        size_t iv_size = tx_cipherspec->suite->fixed_iv_len;
        size_t total = ( 2 * ( hash_size + key_size + iv_size ) );
@@ -799,7 +799,6 @@ static int tls_set_cipher ( struct tls_connection *tls,
                            struct tls_cipher_suite *suite ) {
        struct pubkey_algorithm *pubkey = suite->pubkey;
        struct cipher_algorithm *cipher = suite->cipher;
-       struct digest_algorithm *digest = suite->digest;
        size_t total;
        void *dynamic;
 
@@ -807,7 +806,7 @@ static int tls_set_cipher ( struct tls_connection *tls,
        tls_clear_cipher ( tls, cipherspec );
 
        /* Allocate dynamic storage */
-       total = ( pubkey->ctxsize + cipher->ctxsize + digest->digestsize +
+       total = ( pubkey->ctxsize + cipher->ctxsize + suite->mac_len +
                  suite->fixed_iv_len );
        dynamic = zalloc ( total );
        if ( ! dynamic ) {
@@ -820,7 +819,7 @@ static int tls_set_cipher ( struct tls_connection *tls,
        cipherspec->dynamic = dynamic;
        cipherspec->pubkey_ctx = dynamic;       dynamic += pubkey->ctxsize;
        cipherspec->cipher_ctx = dynamic;       dynamic += cipher->ctxsize;
-       cipherspec->mac_secret = dynamic;       dynamic += digest->digestsize;
+       cipherspec->mac_secret = dynamic;       dynamic += suite->mac_len;
        cipherspec->fixed_iv = dynamic;         dynamic += suite->fixed_iv_len;
        assert ( ( cipherspec->dynamic + total ) == dynamic );
 
@@ -2525,9 +2524,10 @@ static int tls_new_record ( struct tls_connection *tls, unsigned int type,
  */
 static void tls_hmac_init ( struct tls_cipherspec *cipherspec, void *ctx,
                            struct tls_auth_header *authhdr ) {
-       struct digest_algorithm *digest = cipherspec->suite->digest;
+       struct tls_cipher_suite *suite = cipherspec->suite;
+       struct digest_algorithm *digest = suite->digest;
 
-       hmac_init ( digest, ctx, cipherspec->mac_secret, digest->digestsize );
+       hmac_init ( digest, ctx, cipherspec->mac_secret, suite->mac_len );
        hmac_update ( digest, ctx, authhdr, sizeof ( *authhdr ) );
 }
 
@@ -2593,7 +2593,7 @@ static void tls_hmac ( struct tls_cipherspec *cipherspec,
 static void * __malloc
 tls_assemble_stream ( struct tls_connection *tls, const void *data, size_t len,
                      void *digest, size_t *plaintext_len ) {
-       size_t mac_len = tls->tx_cipherspec.suite->digest->digestsize;
+       size_t mac_len = tls->tx_cipherspec.suite->mac_len;
        void *plaintext;
        void *content;
        void *mac;
@@ -2629,7 +2629,7 @@ static void * tls_assemble_block ( struct tls_connection *tls,
                                   const void *data, size_t len,
                                   void *digest, size_t *plaintext_len ) {
        size_t blocksize = tls->tx_cipherspec.suite->cipher->blocksize;
-       size_t mac_len = tls->tx_cipherspec.suite->digest->digestsize;
+       size_t mac_len = tls->tx_cipherspec.suite->mac_len;
        size_t iv_len = blocksize;
        size_t padding_len;
        void *plaintext;
@@ -2675,15 +2675,16 @@ static void * tls_assemble_block ( struct tls_connection *tls,
 static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
                                const void *data, size_t len ) {
        struct tls_cipherspec *cipherspec = &tls->tx_cipherspec;
-       struct cipher_algorithm *cipher = cipherspec->suite->cipher;
+       struct tls_cipher_suite *suite = cipherspec->suite;
+       struct cipher_algorithm *cipher = suite->cipher;
+       struct digest_algorithm *digest = suite->digest;
        struct tls_auth_header authhdr;
        struct tls_header *tlshdr;
        void *plaintext = NULL;
        size_t plaintext_len;
        struct io_buffer *ciphertext = NULL;
        size_t ciphertext_len;
-       size_t mac_len = cipherspec->suite->digest->digestsize;
-       uint8_t mac[mac_len];
+       uint8_t mac[digest->digestsize];
        int rc;
 
        /* Construct header */
@@ -2762,7 +2763,7 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
  */
 static int tls_split_stream ( struct tls_connection *tls,
                              struct list_head *rx_data, void **mac ) {
-       size_t mac_len = tls->rx_cipherspec.suite->digest->digestsize;
+       size_t mac_len = tls->rx_cipherspec.suite->mac_len;
        struct io_buffer *iobuf;
 
        /* Extract MAC */
@@ -2789,7 +2790,7 @@ static int tls_split_stream ( struct tls_connection *tls,
  */
 static int tls_split_block ( struct tls_connection *tls,
                             struct list_head *rx_data, void **mac ) {
-       size_t mac_len = tls->rx_cipherspec.suite->digest->digestsize;
+       size_t mac_len = tls->rx_cipherspec.suite->mac_len;
        size_t iv_len = tls->rx_cipherspec.suite->cipher->blocksize;
        struct io_buffer *iobuf;
        uint8_t *padding_final;
@@ -2850,8 +2851,9 @@ static int tls_new_ciphertext ( struct tls_connection *tls,
                                struct tls_header *tlshdr,
                                struct list_head *rx_data ) {
        struct tls_cipherspec *cipherspec = &tls->rx_cipherspec;
-       struct cipher_algorithm *cipher = cipherspec->suite->cipher;
-       struct digest_algorithm *digest = cipherspec->suite->digest;
+       struct tls_cipher_suite *suite = cipherspec->suite;
+       struct cipher_algorithm *cipher = suite->cipher;
+       struct digest_algorithm *digest = suite->digest;
        struct tls_auth_header authhdr;
        uint8_t ctx[ hmac_ctxsize ( digest ) ];
        uint8_t verify_mac[digest->digestsize];
@@ -2893,7 +2895,7 @@ static int tls_new_ciphertext ( struct tls_connection *tls,
                                  iob_len ( iobuf ) );
        }
        tls_hmac_final ( cipherspec, ctx, verify_mac );
-       if ( memcmp ( mac, verify_mac, sizeof ( verify_mac ) ) != 0 ) {
+       if ( memcmp ( mac, verify_mac, suite->mac_len ) != 0 ) {
                DBGC ( tls, "TLS %p failed MAC verification\n", tls );
                return -EINVAL_MAC;
        }