diff options
-rw-r--r-- | src/crypto/mishmash/rsa_aes_cbc_sha1.c | 8 | ||||
-rw-r--r-- | src/crypto/mishmash/rsa_aes_cbc_sha256.c | 8 | ||||
-rw-r--r-- | src/include/ipxe/tls.h | 10 | ||||
-rw-r--r-- | src/net/tls.c | 27 |
4 files changed, 48 insertions, 5 deletions
diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha1.c b/src/crypto/mishmash/rsa_aes_cbc_sha1.c index b054a01c7..765ed1138 100644 --- a/src/crypto/mishmash/rsa_aes_cbc_sha1.c +++ b/src/crypto/mishmash/rsa_aes_cbc_sha1.c @@ -34,6 +34,8 @@ struct tls_cipher_suite tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 03 ) = { .code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA ), .key_len = ( 128 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -45,6 +47,8 @@ struct tls_cipher_suite tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 04 ) = { .code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA ), .key_len = ( 256 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -56,6 +60,8 @@ struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 13 ) = { .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ), .key_len = ( 128 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -67,6 +73,8 @@ struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 14 ) = { .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ), .key_len = ( 256 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha256.c b/src/crypto/mishmash/rsa_aes_cbc_sha256.c index b003523d5..1cc7dfe27 100644 --- a/src/crypto/mishmash/rsa_aes_cbc_sha256.c +++ b/src/crypto/mishmash/rsa_aes_cbc_sha256.c @@ -34,6 +34,8 @@ struct tls_cipher_suite tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 01 ) = { .code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ), .key_len = ( 128 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -45,6 +47,8 @@ struct tls_cipher_suite tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 02 ) = { .code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ), .key_len = ( 256 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_dhe_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -56,6 +60,8 @@ struct tls_cipher_suite tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 11 ) = { .code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ), .key_len = ( 128 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, @@ -67,6 +73,8 @@ struct tls_cipher_suite tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 12 ) = { .code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ), .key_len = ( 256 / 8 ), + .fixed_iv_len = 0, + .record_iv_len = AES_BLOCKSIZE, .exchange = &tls_pubkey_exchange_algorithm, .pubkey = &rsa_algorithm, .cipher = &aes_cbc_algorithm, diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h index 0b34dee7c..8bb1ccceb 100644 --- a/src/include/ipxe/tls.h +++ b/src/include/ipxe/tls.h @@ -169,10 +169,14 @@ struct tls_cipher_suite { struct cipher_algorithm *cipher; /** MAC digest algorithm */ struct digest_algorithm *digest; - /** Key length */ - uint16_t key_len; /** Numeric code (in network-endian order) */ uint16_t code; + /** Key length */ + uint8_t key_len; + /** Fixed initialisation vector length */ + uint8_t fixed_iv_len; + /** Record initialisation vector length */ + uint8_t record_iv_len; }; /** TLS cipher suite table */ @@ -195,6 +199,8 @@ struct tls_cipherspec { void *cipher_ctx; /** MAC secret */ void *mac_secret; + /** Fixed initialisation vector */ + void *fixed_iv; }; /** A TLS signature and hash algorithm identifier */ diff --git a/src/net/tls.c b/src/net/tls.c index 9ad8448cf..f4f8d930d 100644 --- a/src/net/tls.c +++ b/src/net/tls.c @@ -664,7 +664,8 @@ static int tls_generate_keys ( struct tls_connection *tls ) { struct tls_cipherspec *rx_cipherspec = &tls->rx_cipherspec_pending; size_t hash_size = tx_cipherspec->suite->digest->digestsize; size_t key_size = tx_cipherspec->suite->key_len; - size_t total = ( 2 * ( hash_size + key_size ) ); + size_t iv_size = tx_cipherspec->suite->fixed_iv_len; + size_t total = ( 2 * ( hash_size + key_size + iv_size ) ); uint8_t key_block[total]; uint8_t *key; int rc; @@ -714,6 +715,18 @@ static int tls_generate_keys ( struct tls_connection *tls ) { DBGC_HD ( tls, key, key_size ); key += key_size; + /* TX initialisation vector */ + memcpy ( tx_cipherspec->fixed_iv, key, iv_size ); + DBGC ( tls, "TLS %p TX IV:\n", tls ); + DBGC_HD ( tls, key, iv_size ); + key += iv_size; + + /* RX initialisation vector */ + memcpy ( rx_cipherspec->fixed_iv, key, iv_size ); + DBGC ( tls, "TLS %p RX IV:\n", tls ); + DBGC_HD ( tls, key, iv_size ); + key += iv_size; + assert ( ( key_block + total ) == key ); return 0; @@ -792,9 +805,10 @@ static int tls_set_cipher ( struct tls_connection *tls, /* Clear out old cipher contents, if any */ tls_clear_cipher ( tls, cipherspec ); - + /* Allocate dynamic storage */ - total = ( pubkey->ctxsize + cipher->ctxsize + digest->digestsize ); + total = ( pubkey->ctxsize + cipher->ctxsize + digest->digestsize + + suite->fixed_iv_len ); dynamic = zalloc ( total ); if ( ! dynamic ) { DBGC ( tls, "TLS %p could not allocate %zd bytes for crypto " @@ -807,6 +821,7 @@ static int tls_set_cipher ( struct tls_connection *tls, cipherspec->pubkey_ctx = dynamic; dynamic += pubkey->ctxsize; cipherspec->cipher_ctx = dynamic; dynamic += cipher->ctxsize; cipherspec->mac_secret = dynamic; dynamic += digest->digestsize; + cipherspec->fixed_iv = dynamic; dynamic += suite->fixed_iv_len; assert ( ( cipherspec->dynamic + total ) == dynamic ); /* Store parameters */ @@ -2627,6 +2642,9 @@ static void * tls_assemble_block ( struct tls_connection *tls, void *mac; void *padding; + /* Sanity check */ + assert ( iv_len == tls->tx_cipherspec.suite->record_iv_len ); + /* Calculate block-ciphered struct length */ padding_len = ( ( blocksize - 1 ) & -( iv_len + len + mac_len + 1 ) ); *plaintext_len = ( iv_len + len + mac_len + padding_len + 1 ); @@ -2781,6 +2799,9 @@ static int tls_split_block ( struct tls_connection *tls, uint8_t *padding; size_t padding_len; + /* Sanity check */ + assert ( iv_len == tls->rx_cipherspec.suite->record_iv_len ); + /* Extract initialisation vector */ iobuf = list_first_entry ( rx_data, struct io_buffer, list ); if ( iob_len ( iobuf ) < iv_len ) { |