From a5ef2b157731e3bd2f9c0dbba4caf361195fa5c8 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 1 Apr 2020 22:43:37 +0300 Subject: [PATCH 82/87] ssl: fix CMAC support For CMAC EVP_MD_CTX_md is NULL. Thus tls1_mac() will not be called. Store read/write mac_size in the context to make it work. Signed-off-by: Dmitry Baryshkov --- src/lib/libssl/ssl.h | 1 + src/lib/libssl/ssl_lib.c | 2 ++ src/lib/libssl/ssl_locl.h | 1 + src/lib/libssl/ssl_pkt.c | 11 ++++------- src/lib/libssl/t1_enc.c | 23 ++++++++++++----------- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/lib/libssl/ssl.h b/src/lib/libssl/ssl.h index b11216b1e..1f9095feb 100644 --- a/src/lib/libssl/ssl.h +++ b/src/lib/libssl/ssl.h @@ -872,6 +872,7 @@ struct ssl_st { */ EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ EVP_MD_CTX *read_hash; /* used for mac generation */ + int read_mac_size; struct ssl_internal_st *internal; }; diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 5495a74ad..c989d802c 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c @@ -2538,6 +2538,7 @@ ssl_clear_cipher_read_state(SSL *s) s->enc_read_ctx = NULL; EVP_MD_CTX_free(s->read_hash); s->read_hash = NULL; + s->read_mac_size = 0; if (s->internal->aead_read_ctx != NULL) { EVP_AEAD_CTX_cleanup(&s->internal->aead_read_ctx->ctx); @@ -2553,6 +2554,7 @@ ssl_clear_cipher_write_state(SSL *s) s->internal->enc_write_ctx = NULL; EVP_MD_CTX_free(s->internal->write_hash); s->internal->write_hash = NULL; + s->internal->write_mac_size = 0; if (s->internal->aead_write_ctx != NULL) { EVP_AEAD_CTX_cleanup(&s->internal->aead_write_ctx->ctx); diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index f522abf96..858010b87 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h @@ -737,6 +737,7 @@ typedef struct ssl_internal_st { EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ EVP_MD_CTX *write_hash; /* used for mac generation */ + int write_mac_size; /* session info */ diff --git a/src/lib/libssl/ssl_pkt.c b/src/lib/libssl/ssl_pkt.c index d4aebebe9..23a5509c3 100644 --- a/src/lib/libssl/ssl_pkt.c +++ b/src/lib/libssl/ssl_pkt.c @@ -443,12 +443,12 @@ ssl3_get_record(SSL *s) /* r->length is now the compressed data plus mac */ if ((sess != NULL) && (s->enc_read_ctx != NULL) && - (EVP_MD_CTX_md(s->read_hash) != NULL)) { + (s->read_mac_size != 0)) { /* s->read_hash != NULL => mac_size != -1 */ unsigned char *mac = NULL; unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); + mac_size = s->read_mac_size; OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); orig_len = rr->length + rr->padding_length; @@ -628,13 +628,10 @@ ssl3_create_record(SSL *s, unsigned char *p, int type, const unsigned char *buf, memset(&cbb, 0, sizeof(cbb)); - if ((sess == NULL) || (s->internal->enc_write_ctx == NULL) || - (EVP_MD_CTX_md(s->internal->write_hash) == NULL)) { + if ((sess == NULL) || (s->internal->enc_write_ctx == NULL)) { mac_size = 0; } else { - mac_size = EVP_MD_CTX_size(s->internal->write_hash); - if (mac_size < 0) - goto err; + mac_size = s->internal->write_mac_size; } /* diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 7e9422b51..363447b52 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c @@ -407,6 +407,7 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, const EVP_CIPHER *cipher; EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; + int mac_size; const EVP_MD *mac; const EVP_CIPHER *mac_cipher; int mac_type; @@ -459,14 +460,20 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, if (mac_type == EVP_PKEY_CMAC) { mac_key = EVP_PKEY_new_CMAC_key(NULL, mac_secret, mac_secret_size, mac_cipher); + mac_size = EVP_CIPHER_block_size(mac_cipher); } else { mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, mac_secret_size); + mac_size = EVP_MD_size(mac); } if (mac_key == NULL) goto err; EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); EVP_PKEY_free(mac_key); + if (is_read) + s->read_mac_size = mac_size; + else + s->internal->write_mac_size = mac_size; if (S3I(s)->hs.new_cipher->algorithm_enc == SSL_eGOST2814789CNT) { int nid; @@ -846,10 +853,7 @@ tls1_enc(SSL *s, int send) } if (send) { - if (EVP_MD_CTX_md(s->internal->write_hash)) { - int n = EVP_MD_CTX_size(s->internal->write_hash); - OPENSSL_assert(n >= 0); - } + OPENSSL_assert(s->internal->write_mac_size >= 0); ds = s->internal->enc_write_ctx; if (s->internal->enc_write_ctx == NULL) enc = NULL; @@ -874,10 +878,7 @@ tls1_enc(SSL *s, int send) } } } else { - if (EVP_MD_CTX_md(s->read_hash)) { - int n = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(n >= 0); - } + OPENSSL_assert(s->read_mac_size >= 0); ds = s->enc_read_ctx; if (s->enc_read_ctx == NULL) enc = NULL; @@ -917,8 +918,7 @@ tls1_enc(SSL *s, int send) return -1; /* AEAD can fail to verify MAC */ ret = 1; - if (EVP_MD_CTX_md(s->read_hash) != NULL) - mac_size = EVP_MD_CTX_size(s->read_hash); + mac_size = s->read_mac_size; if ((bs != 1) && !send) ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); } @@ -970,13 +970,14 @@ tls1_mac(SSL *ssl, unsigned char *md, int send) rec = &(ssl->s3->internal->wrec); seq = &(ssl->s3->internal->write_sequence[0]); hash = ssl->internal->write_hash; + t = ssl->internal->write_mac_size; } else { rec = &(ssl->s3->internal->rrec); seq = &(ssl->s3->internal->read_sequence[0]); hash = ssl->read_hash; + t = ssl->read_mac_size; } - t = EVP_MD_CTX_size(hash); OPENSSL_assert(t >= 0); md_size = t; -- 2.17.1