aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-11-07 18:11:36 +0000
committerMichael Brown <mcb30@ipxe.org>2022-11-08 14:09:18 +0000
commitc453b4c284dbedb5de0663f6b30878b425a7a3e8 (patch)
tree3edacf954d8f3d899d5d666fc6b1c4ba71cbcb9a
parentb6eef1485808093f9dae4fe9d6b685e01a6d65a4 (diff)
downloadipxe-c453b4c284dbedb5de0663f6b30878b425a7a3e8.zip
ipxe-c453b4c284dbedb5de0663f6b30878b425a7a3e8.tar.gz
ipxe-c453b4c284dbedb5de0663f6b30878b425a7a3e8.tar.bz2
[tls] Add MAC length as a cipher suite parameter
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>
-rw-r--r--src/crypto/mishmash/rsa_aes_cbc_sha1.c4
-rw-r--r--src/crypto/mishmash/rsa_aes_cbc_sha256.c4
-rw-r--r--src/include/ipxe/tls.h2
-rw-r--r--src/net/tls.c34
4 files changed, 28 insertions, 16 deletions
diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha1.c b/src/crypto/mishmash/rsa_aes_cbc_sha1.c
index 765ed11..4f399a0 100644
--- a/src/crypto/mishmash/rsa_aes_cbc_sha1.c
+++ b/src/crypto/mishmash/rsa_aes_cbc_sha1.c
@@ -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,
diff --git a/src/crypto/mishmash/rsa_aes_cbc_sha256.c b/src/crypto/mishmash/rsa_aes_cbc_sha256.c
index 1cc7dfe..4b02a77 100644
--- a/src/crypto/mishmash/rsa_aes_cbc_sha256.c
+++ b/src/crypto/mishmash/rsa_aes_cbc_sha256.c
@@ -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,
diff --git a/src/include/ipxe/tls.h b/src/include/ipxe/tls.h
index be192b7..8796fe9 100644
--- a/src/include/ipxe/tls.h
+++ b/src/include/ipxe/tls.h
@@ -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 */
diff --git a/src/net/tls.c b/src/net/tls.c
index a613a08..06d01ae 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -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;
}