libressl/0079-ssl-support-selecting-CMAC-for-CTR-OMAC-ciphersuites.patch

159 lines
5.3 KiB
Diff
Raw Permalink Normal View History

From d549ac36b23762900f5e07cc5afa41e1169141ac Mon Sep 17 00:00:00 2001
From: Dmitry Baryshkov <dbaryshkov@gmail.com>
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 <dbaryshkov@gmail.com>
---
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