From d549ac36b23762900f5e07cc5afa41e1169141ac Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 1 Apr 2020 17:21:43 +0300 Subject: [PATCH 79/87] ssl: support selecting CMAC for CTR-OMAC ciphersuites CTR-OMAC ciphersuites use CMAC instead of HMAC to generate record MACs. Make ssl_cipher_get_evp() return either MD (for HMAC) or a cipher (for CMAC). Signed-off-by: Dmitry Baryshkov --- src/lib/libssl/ssl_ciph.c | 20 ++++++++++++++++++-- src/lib/libssl/ssl_locl.h | 3 ++- src/lib/libssl/t1_enc.c | 18 ++++++++++++++---- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/lib/libssl/ssl_ciph.c b/src/lib/libssl/ssl_ciph.c index a3e0d396b..0f1995c20 100644 --- a/src/lib/libssl/ssl_ciph.c +++ b/src/lib/libssl/ssl_ciph.c @@ -448,10 +448,11 @@ static const SSL_CIPHER cipher_aliases[] = { int ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size) + const EVP_MD **md, const EVP_CIPHER **mac_ciph, int *mac_pkey_type, int *mac_secret_size) { *enc = NULL; *md = NULL; + *mac_ciph = NULL; *mac_pkey_type = NID_undef; *mac_secret_size = 0; @@ -490,6 +491,12 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc, case SSL_eGOST2814789CNT: *enc = EVP_gost2814789_cnt(); break; + case SSL_KUZNYECHIK_CTR_ACPKM: + *enc = EVP_kuznyechik_ctr_acpkm(); + break; + case SSL_MAGMA_CTR_ACPKM: + *enc = EVP_magma_ctr_acpkm(); + break; } switch (ss->cipher->algorithm_mac) { @@ -514,9 +521,15 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc, case SSL_STREEBOG256: *md = EVP_streebog256(); break; + case SSL_MAGMA_OMAC: + *mac_ciph = EVP_magma_cbc(); + break; + case SSL_KUZNYECHIK_OMAC: + *mac_ciph = EVP_kuznyechik_cbc(); + break; } - if (*enc == NULL || *md == NULL) + if (*enc == NULL || (*md == NULL && *mac_ciph == NULL)) return 0; /* @@ -531,6 +544,9 @@ ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc, if (ss->cipher->algorithm_mac == SSL_GOST89MAC) { *mac_pkey_type = EVP_PKEY_GOSTIMIT; *mac_secret_size = 32; /* XXX */ + } else if (*mac_ciph) { + *mac_pkey_type = EVP_PKEY_CMAC; + *mac_secret_size = EVP_CIPHER_key_length(*mac_ciph); } else { *mac_pkey_type = EVP_PKEY_HMAC; *mac_secret_size = EVP_MD_size(*md); diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index b07be5ab2..87eb05999 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h @@ -901,6 +901,7 @@ typedef struct ssl3_state_internal_st { const EVP_CIPHER *new_sym_enc; const EVP_AEAD *new_aead; const EVP_MD *new_hash; + const EVP_CIPHER *new_hash_cipher; int new_mac_pkey_type; int cert_request; } tmp; @@ -1146,7 +1147,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, const char *rule_str); void ssl_update_cache(SSL *s, int mode); int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size); + const EVP_MD **md, const EVP_CIPHER **mac_ciph, int *mac_pkey_type, int *mac_secret_size); int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead); int ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md); diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 2893e1d4d..736670259 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c @@ -408,10 +408,12 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, EVP_MD_CTX *mac_ctx; EVP_PKEY *mac_key; const EVP_MD *mac; + const EVP_CIPHER *mac_cipher; int mac_type; cipher = S3I(s)->tmp.new_sym_enc; mac = S3I(s)->tmp.new_hash; + mac_cipher = S3I(s)->tmp.new_hash_cipher; mac_type = S3I(s)->tmp.new_mac_pkey_type; if (is_read) { @@ -454,8 +456,14 @@ tls1_change_cipher_state_cipher(SSL *s, char is_read, EVP_CipherInit_ex(cipher_ctx, cipher, NULL, key, iv, !is_read); - if ((mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, - mac_secret_size)) == NULL) + if (mac_type == EVP_PKEY_CMAC) { + mac_key = EVP_PKEY_new_CMAC_key(NULL, mac_secret, + mac_secret_size, mac_cipher); + } else { + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, mac_secret, + mac_secret_size); + } + if (mac_key == NULL) goto err; EVP_DigestSignInit(mac_ctx, NULL, mac, NULL, mac_key); EVP_PKEY_free(mac_key); @@ -587,6 +595,7 @@ tls1_setup_key_block(SSL *s) const EVP_CIPHER *cipher = NULL; const EVP_AEAD *aead = NULL; const EVP_MD *mac = NULL; + const EVP_CIPHER *mac_cipher = NULL; int ret = 0; if (S3I(s)->hs.key_block_len != 0) @@ -601,8 +610,8 @@ tls1_setup_key_block(SSL *s) key_len = EVP_AEAD_key_length(aead); iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher); } else { - if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_type, - &mac_secret_size)) { + if (!ssl_cipher_get_evp(s->session, &cipher, &mac, &mac_cipher, + &mac_type, &mac_secret_size)) { SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return (0); } @@ -613,6 +622,7 @@ tls1_setup_key_block(SSL *s) S3I(s)->tmp.new_aead = aead; S3I(s)->tmp.new_sym_enc = cipher; S3I(s)->tmp.new_hash = mac; + S3I(s)->tmp.new_hash_cipher = mac_cipher; S3I(s)->tmp.new_mac_pkey_type = mac_type; S3I(s)->tmp.new_mac_secret_size = mac_secret_size; -- 2.17.1