aboutsummaryrefslogtreecommitdiff
path: root/crypto/openssl/ssl/tls13_enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/openssl/ssl/tls13_enc.c')
-rw-r--r--crypto/openssl/ssl/tls13_enc.c382
1 files changed, 184 insertions, 198 deletions
diff --git a/crypto/openssl/ssl/tls13_enc.c b/crypto/openssl/ssl/tls13_enc.c
index 109227e55666..39a27d926ce7 100644
--- a/crypto/openssl/ssl/tls13_enc.c
+++ b/crypto/openssl/ssl/tls13_enc.c
@@ -1,7 +1,7 @@
/*
- * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
@@ -14,11 +14,15 @@
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/kdf.h>
+#include <openssl/core_names.h>
#define TLS13_MAX_LABEL_LEN 249
-/* Always filled with zeros */
-static const unsigned char default_zeros[EVP_MAX_MD_SIZE];
+#ifdef CHARSET_EBCDIC
+static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 };
+#else
+static const unsigned char label_prefix[] = "tls13 ";
+#endif
/*
* Given a |secret|; a |label| of length |labellen|; and |data| of length
@@ -28,84 +32,72 @@ static const unsigned char default_zeros[EVP_MAX_MD_SIZE];
* |fatal| is set. Returns 1 on success 0 on failure.
*/
int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
- const unsigned char *label, size_t labellen,
- const unsigned char *data, size_t datalen,
- unsigned char *out, size_t outlen, int fatal)
+ const unsigned char *label, size_t labellen,
+ const unsigned char *data, size_t datalen,
+ unsigned char *out, size_t outlen, int fatal)
{
-#ifdef CHARSET_EBCDIC
- static const unsigned char label_prefix[] = { 0x74, 0x6C, 0x73, 0x31, 0x33, 0x20, 0x00 };
-#else
- static const unsigned char label_prefix[] = "tls13 ";
-#endif
- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+ EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF,
+ s->ctx->propq);
+ EVP_KDF_CTX *kctx;
+ OSSL_PARAM params[7], *p = params;
+ int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
+ const char *mdname = EVP_MD_get0_name(md);
int ret;
- size_t hkdflabellen;
size_t hashlen;
- /*
- * 2 bytes for length of derived secret + 1 byte for length of combined
- * prefix and label + bytes for the label itself + 1 byte length of hash
- * + bytes for the hash itself
- */
- unsigned char hkdflabel[sizeof(uint16_t) + sizeof(uint8_t)
- + (sizeof(label_prefix) - 1) + TLS13_MAX_LABEL_LEN
- + 1 + EVP_MAX_MD_SIZE];
- WPACKET pkt;
- if (pctx == NULL)
+ kctx = EVP_KDF_CTX_new(kdf);
+ EVP_KDF_free(kdf);
+ if (kctx == NULL)
return 0;
if (labellen > TLS13_MAX_LABEL_LEN) {
if (fatal) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
} else {
/*
* Probably we have been called from SSL_export_keying_material(),
* or SSL_export_keying_material_early().
*/
- SSLerr(SSL_F_TLS13_HKDF_EXPAND, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
+ ERR_raise(ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
}
- EVP_PKEY_CTX_free(pctx);
+ EVP_KDF_CTX_free(kctx);
return 0;
}
- hashlen = EVP_MD_size(md);
-
- if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0)
- || !WPACKET_put_bytes_u16(&pkt, outlen)
- || !WPACKET_start_sub_packet_u8(&pkt)
- || !WPACKET_memcpy(&pkt, label_prefix, sizeof(label_prefix) - 1)
- || !WPACKET_memcpy(&pkt, label, labellen)
- || !WPACKET_close(&pkt)
- || !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen)
- || !WPACKET_get_total_written(&pkt, &hkdflabellen)
- || !WPACKET_finish(&pkt)) {
- EVP_PKEY_CTX_free(pctx);
- WPACKET_cleanup(&pkt);
+ if ((ret = EVP_MD_get_size(md)) <= 0) {
+ EVP_KDF_CTX_free(kctx);
if (fatal)
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
else
- SSLerr(SSL_F_TLS13_HKDF_EXPAND, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
-
- ret = EVP_PKEY_derive_init(pctx) <= 0
- || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXPAND_ONLY)
- <= 0
- || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0
- || EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, hashlen) <= 0
- || EVP_PKEY_CTX_add1_hkdf_info(pctx, hkdflabel, hkdflabellen) <= 0
- || EVP_PKEY_derive(pctx, out, &outlen) <= 0;
-
- EVP_PKEY_CTX_free(pctx);
+ hashlen = (size_t)ret;
+
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ (char *)mdname, 0);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ (unsigned char *)secret, hashlen);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
+ (unsigned char *)label_prefix,
+ sizeof(label_prefix) - 1);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
+ (unsigned char *)label, labellen);
+ if (data != NULL)
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_DATA,
+ (unsigned char *)data,
+ datalen);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = EVP_KDF_derive(kctx, out, outlen, params) <= 0;
+ EVP_KDF_CTX_free(kctx);
if (ret != 0) {
if (fatal)
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
else
- SSLerr(SSL_F_TLS13_HKDF_EXPAND, ERR_R_INTERNAL_ERROR);
+ ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
}
return ret == 0;
@@ -170,86 +162,61 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
size_t insecretlen,
unsigned char *outsecret)
{
- size_t mdlen, prevsecretlen;
+ size_t mdlen;
int mdleni;
int ret;
- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
+ EVP_KDF *kdf;
+ EVP_KDF_CTX *kctx;
+ OSSL_PARAM params[7], *p = params;
+ int mode = EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY;
+ const char *mdname = EVP_MD_get0_name(md);
#ifdef CHARSET_EBCDIC
static const char derived_secret_label[] = { 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64, 0x00 };
#else
static const char derived_secret_label[] = "derived";
#endif
- unsigned char preextractsec[EVP_MAX_MD_SIZE];
- if (pctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
- ERR_R_INTERNAL_ERROR);
+ kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, s->ctx->propq);
+ kctx = EVP_KDF_CTX_new(kdf);
+ EVP_KDF_free(kdf);
+ if (kctx == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
return 0;
}
- mdleni = EVP_MD_size(md);
+ mdleni = EVP_MD_get_size(md);
/* Ensure cast to size_t is safe */
if (!ossl_assert(mdleni >= 0)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ EVP_KDF_CTX_free(kctx);
return 0;
}
mdlen = (size_t)mdleni;
- if (insecret == NULL) {
- insecret = default_zeros;
- insecretlen = mdlen;
- }
- if (prevsecret == NULL) {
- prevsecret = default_zeros;
- prevsecretlen = 0;
- } else {
- EVP_MD_CTX *mctx = EVP_MD_CTX_new();
- unsigned char hash[EVP_MAX_MD_SIZE];
-
- /* The pre-extract derive step uses a hash of no messages */
- if (mctx == NULL
- || EVP_DigestInit_ex(mctx, md, NULL) <= 0
- || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
- ERR_R_INTERNAL_ERROR);
- EVP_MD_CTX_free(mctx);
- EVP_PKEY_CTX_free(pctx);
- return 0;
- }
- EVP_MD_CTX_free(mctx);
-
- /* Generate the pre-extract secret */
- if (!tls13_hkdf_expand(s, md, prevsecret,
- (unsigned char *)derived_secret_label,
- sizeof(derived_secret_label) - 1, hash, mdlen,
- preextractsec, mdlen, 1)) {
- /* SSLfatal() already called */
- EVP_PKEY_CTX_free(pctx);
- return 0;
- }
-
- prevsecret = preextractsec;
- prevsecretlen = mdlen;
- }
-
- ret = EVP_PKEY_derive_init(pctx) <= 0
- || EVP_PKEY_CTX_hkdf_mode(pctx, EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY)
- <= 0
- || EVP_PKEY_CTX_set_hkdf_md(pctx, md) <= 0
- || EVP_PKEY_CTX_set1_hkdf_key(pctx, insecret, insecretlen) <= 0
- || EVP_PKEY_CTX_set1_hkdf_salt(pctx, prevsecret, prevsecretlen)
- <= 0
- || EVP_PKEY_derive(pctx, outsecret, &mdlen)
- <= 0;
+ *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode);
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
+ (char *)mdname, 0);
+ if (insecret != NULL)
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+ (unsigned char *)insecret,
+ insecretlen);
+ if (prevsecret != NULL)
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
+ (unsigned char *)prevsecret, mdlen);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX,
+ (unsigned char *)label_prefix,
+ sizeof(label_prefix) - 1);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL,
+ (unsigned char *)derived_secret_label,
+ sizeof(derived_secret_label) - 1);
+ *p++ = OSSL_PARAM_construct_end();
+
+ ret = EVP_KDF_derive(kctx, outsecret, mdlen, params) <= 0;
if (ret != 0)
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
- EVP_PKEY_CTX_free(pctx);
- if (prevsecret == preextractsec)
- OPENSSL_cleanse(preextractsec, mdlen);
+ EVP_KDF_CTX_free(kctx);
return ret == 0;
}
@@ -278,7 +245,7 @@ int tls13_generate_master_secret(SSL *s, unsigned char *out,
{
const EVP_MD *md = ssl_handshake_md(s);
- *secret_size = EVP_MD_size(md);
+ *secret_size = EVP_MD_get_size(md);
/* Calls SSLfatal() if required */
return tls13_generate_secret(s, md, prev, NULL, 0, out);
}
@@ -291,10 +258,22 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
unsigned char *out)
{
const EVP_MD *md = ssl_handshake_md(s);
+ const char *mdname = EVP_MD_get0_name(md);
unsigned char hash[EVP_MAX_MD_SIZE];
- size_t hashlen, ret = 0;
- EVP_PKEY *key = NULL;
- EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ unsigned char finsecret[EVP_MAX_MD_SIZE];
+ unsigned char *key = NULL;
+ size_t len = 0, hashlen;
+ OSSL_PARAM params[2], *p = params;
+
+ if (md == NULL)
+ return 0;
+
+ /* Safe to cast away const here since we're not "getting" any data */
+ if (s->ctx->propq != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
+ (char *)s->ctx->propq,
+ 0);
+ *p = OSSL_PARAM_construct_end();
if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
/* SSLfatal() already called */
@@ -302,39 +281,28 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
}
if (str == s->method->ssl3_enc->server_finished_label) {
- key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
- s->server_finished_secret, hashlen);
+ key = s->server_finished_secret;
} else if (SSL_IS_FIRST_HANDSHAKE(s)) {
- key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
- s->client_finished_secret, hashlen);
+ key = s->client_finished_secret;
} else {
- unsigned char finsecret[EVP_MAX_MD_SIZE];
-
- if (!tls13_derive_finishedkey(s, ssl_handshake_md(s),
+ if (!tls13_derive_finishedkey(s, md,
s->client_app_traffic_secret,
finsecret, hashlen))
goto err;
-
- key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL, finsecret,
- hashlen);
- OPENSSL_cleanse(finsecret, sizeof(finsecret));
+ key = finsecret;
}
- if (key == NULL
- || ctx == NULL
- || EVP_DigestSignInit(ctx, NULL, md, NULL, key) <= 0
- || EVP_DigestSignUpdate(ctx, hash, hashlen) <= 0
- || EVP_DigestSignFinal(ctx, out, &hashlen) <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
- ERR_R_INTERNAL_ERROR);
+ if (!EVP_Q_mac(s->ctx->libctx, "HMAC", s->ctx->propq, mdname,
+ params, key, hashlen, hash, hashlen,
+ /* outsize as per sizeof(peer_finish_md) */
+ out, EVP_MAX_MD_SIZE * 2, &len)) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
- ret = hashlen;
err:
- EVP_PKEY_free(key);
- EVP_MD_CTX_free(ctx);
- return ret;
+ OPENSSL_cleanse(finsecret, sizeof(finsecret));
+ return len;
}
/*
@@ -346,15 +314,18 @@ int tls13_setup_key_block(SSL *s)
const EVP_CIPHER *c;
const EVP_MD *hash;
- s->session->cipher = s->s3->tmp.new_cipher;
- if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, NULL, 0)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_SETUP_KEY_BLOCK,
- SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+ s->session->cipher = s->s3.tmp.new_cipher;
+ if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, NULL,
+ 0)) {
+ /* Error is already recorded */
+ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
return 0;
}
- s->s3->tmp.new_sym_enc = c;
- s->s3->tmp.new_hash = hash;
+ ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
+ s->s3.tmp.new_sym_enc = c;
+ ssl_evp_md_free(s->s3.tmp.new_hash);
+ s->s3.tmp.new_hash = hash;
return 1;
}
@@ -369,13 +340,12 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
EVP_CIPHER_CTX *ciph_ctx)
{
size_t ivlen, keylen, taglen;
- int hashleni = EVP_MD_size(md);
+ int hashleni = EVP_MD_get_size(md);
size_t hashlen;
/* Ensure cast to size_t is safe */
if (!ossl_assert(hashleni >= 0)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
- ERR_R_EVP_LIB);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
hashlen = (size_t)hashleni;
@@ -386,14 +356,13 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
return 0;
}
- /* TODO(size_t): convert me */
- keylen = EVP_CIPHER_key_length(ciph);
- if (EVP_CIPHER_mode(ciph) == EVP_CIPH_CCM_MODE) {
+ keylen = EVP_CIPHER_get_key_length(ciph);
+ if (EVP_CIPHER_get_mode(ciph) == EVP_CIPH_CCM_MODE) {
uint32_t algenc;
ivlen = EVP_CCM_TLS_IV_LEN;
- if (s->s3->tmp.new_cipher != NULL) {
- algenc = s->s3->tmp.new_cipher->algorithm_enc;
+ if (s->s3.tmp.new_cipher != NULL) {
+ algenc = s->s3.tmp.new_cipher->algorithm_enc;
} else if (s->session->cipher != NULL) {
/* We've not selected a cipher yet - we must be doing early data */
algenc = s->session->cipher->algorithm_enc;
@@ -401,8 +370,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
/* We must be doing early data with out-of-band PSK */
algenc = s->psksession->cipher->algorithm_enc;
} else {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
- ERR_R_EVP_LIB);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8))
@@ -410,7 +378,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
else
taglen = EVP_CCM_TLS_TAG_LEN;
} else {
- ivlen = EVP_CIPHER_iv_length(ciph);
+ ivlen = EVP_CIPHER_get_iv_length(ciph);
taglen = 0;
}
@@ -421,12 +389,11 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md,
}
if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0
- || !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL)
- || (taglen != 0 && !EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
- taglen, NULL))
+ || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0
+ || (taglen != 0 && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG,
+ taglen, NULL) <= 0)
|| EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV,
- ERR_R_EVP_LIB);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_EVP_LIB);
return 0;
}
@@ -481,8 +448,7 @@ int tls13_change_cipher_state(SSL *s, int which)
} else {
s->enc_read_ctx = EVP_CIPHER_CTX_new();
if (s->enc_read_ctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -497,8 +463,7 @@ int tls13_change_cipher_state(SSL *s, int which)
} else {
s->enc_write_ctx = EVP_CIPHER_CTX_new();
if (s->enc_write_ctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -522,11 +487,9 @@ int tls13_change_cipher_state(SSL *s, int which)
labellen = sizeof(client_early_traffic) - 1;
log_label = CLIENT_EARLY_LABEL;
- handlen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ handlen = BIO_get_mem_data(s->s3.handshake_buffer, &hdata);
if (handlen <= 0) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE,
- SSL_R_BAD_HANDSHAKE_LENGTH);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_HANDSHAKE_LENGTH);
goto err;
}
@@ -541,16 +504,13 @@ int tls13_change_cipher_state(SSL *s, int which)
if (!ossl_assert(s->psksession != NULL
&& s->max_early_data ==
s->psksession->ext.max_early_data)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
sslcipher = SSL_SESSION_get0_cipher(s->psksession);
}
if (sslcipher == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, SSL_R_BAD_PSK);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK);
goto err;
}
@@ -561,17 +521,26 @@ int tls13_change_cipher_state(SSL *s, int which)
*/
mdctx = EVP_MD_CTX_new();
if (mdctx == NULL) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /*
+ * This ups the ref count on cipher so we better make sure we free
+ * it again
+ */
+ if (!ssl_cipher_get_evp_cipher(s->ctx, sslcipher, &cipher)) {
+ /* Error is already recorded */
+ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR);
+ EVP_MD_CTX_free(mdctx);
goto err;
}
- cipher = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(sslcipher));
- md = ssl_md(sslcipher->algorithm2);
+
+ md = ssl_md(s->ctx, sslcipher->algorithm2);
if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)
|| !EVP_DigestUpdate(mdctx, hdata, handlen)
|| !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
EVP_MD_CTX_free(mdctx);
goto err;
}
@@ -584,8 +553,7 @@ int tls13_change_cipher_state(SSL *s, int which)
hashval, hashlen,
s->early_exporter_master_secret, hashlen,
1)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR,
- SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -597,7 +565,7 @@ int tls13_change_cipher_state(SSL *s, int which)
} else if (which & SSL3_CC_HANDSHAKE) {
insecret = s->handshake_secret;
finsecret = s->client_finished_secret;
- finsecretlen = EVP_MD_size(ssl_handshake_md(s));
+ finsecretlen = EVP_MD_get_size(ssl_handshake_md(s));
label = client_handshake_traffic;
labellen = sizeof(client_handshake_traffic) - 1;
log_label = CLIENT_HANDSHAKE_LABEL;
@@ -629,7 +597,7 @@ int tls13_change_cipher_state(SSL *s, int which)
if (which & SSL3_CC_HANDSHAKE) {
insecret = s->handshake_secret;
finsecret = s->server_finished_secret;
- finsecretlen = EVP_MD_size(ssl_handshake_md(s));
+ finsecretlen = EVP_MD_get_size(ssl_handshake_md(s));
label = server_handshake_traffic;
labellen = sizeof(server_handshake_traffic) - 1;
log_label = SERVER_HANDSHAKE_LABEL;
@@ -643,7 +611,7 @@ int tls13_change_cipher_state(SSL *s, int which)
if (!(which & SSL3_CC_EARLY)) {
md = ssl_handshake_md(s);
- cipher = s->s3->tmp.new_sym_enc;
+ cipher = s->s3.tmp.new_sym_enc;
if (!ssl3_digest_cached_records(s, 1)
|| !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) {
/* SSLfatal() already called */;
@@ -747,8 +715,7 @@ int tls13_change_cipher_state(SSL *s, int which)
bio = s->rbio;
if (!ossl_assert(bio != NULL)) {
- SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE,
- ERR_R_INTERNAL_ERROR);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -778,6 +745,10 @@ skip_ktls:
#endif
ret = 1;
err:
+ if ((which & SSL3_CC_EARLY) != 0) {
+ /* We up-refed this so now we need to down ref */
+ ssl_evp_cipher_free(cipher);
+ }
OPENSSL_cleanse(key, sizeof(key));
OPENSSL_cleanse(secret, sizeof(secret));
return ret;
@@ -791,12 +762,19 @@ int tls13_update_key(SSL *s, int sending)
static const unsigned char application_traffic[] = "traffic upd";
#endif
const EVP_MD *md = ssl_handshake_md(s);
- size_t hashlen = EVP_MD_size(md);
+ size_t hashlen;
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char *insecret, *iv;
unsigned char secret[EVP_MAX_MD_SIZE];
+ char *log_label;
EVP_CIPHER_CTX *ciph_ctx;
- int ret = 0;
+ int ret = 0, l;
+
+ if ((l = EVP_MD_get_size(md)) <= 0) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ hashlen = (size_t)l;
if (s->server == sending)
insecret = s->server_app_traffic_secret;
@@ -814,8 +792,8 @@ int tls13_update_key(SSL *s, int sending)
RECORD_LAYER_reset_read_sequence(&s->rlayer);
}
- if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s),
- s->s3->tmp.new_sym_enc, insecret, NULL,
+ if (!derive_secret_key_and_iv(s, sending, md,
+ s->s3.tmp.new_sym_enc, insecret, NULL,
application_traffic,
sizeof(application_traffic) - 1, secret, key,
iv, ciph_ctx)) {
@@ -825,6 +803,13 @@ int tls13_update_key(SSL *s, int sending)
memcpy(insecret, secret, hashlen);
+ /* Call Key log on successful traffic secret update */
+ log_label = s->server == sending ? SERVER_APPLICATION_N_LABEL : CLIENT_APPLICATION_N_LABEL;
+ if (!ssl_log_secret(s, log_label, secret, hashlen)) {
+ /* SSLfatal() already called */
+ goto err;
+ }
+
s->statem.enc_write_state = ENC_WRITE_STATE_VALID;
ret = 1;
err:
@@ -859,7 +844,7 @@ int tls13_export_keying_material(SSL *s, unsigned char *out, size_t olen,
unsigned int hashsize, datalen;
int ret = 0;
- if (ctx == NULL || !ossl_statem_export_allowed(s))
+ if (ctx == NULL || md == NULL || !ossl_statem_export_allowed(s))
goto err;
if (!use_context)
@@ -911,7 +896,7 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
else
sslcipher = SSL_SESSION_get0_cipher(s->session);
- md = ssl_md(sslcipher->algorithm2);
+ md = ssl_md(s->ctx, sslcipher->algorithm2);
/*
* Calculate the hash value and store it in |data|. The reason why
@@ -928,7 +913,8 @@ int tls13_export_keying_material_early(SSL *s, unsigned char *out, size_t olen,
*
* Here Transcript-Hash is the cipher suite hash algorithm.
*/
- if (EVP_DigestInit_ex(ctx, md, NULL) <= 0
+ if (md == NULL
+ || EVP_DigestInit_ex(ctx, md, NULL) <= 0
|| EVP_DigestUpdate(ctx, context, contextlen) <= 0
|| EVP_DigestFinal_ex(ctx, hash, &hashsize) <= 0
|| EVP_DigestInit_ex(ctx, md, NULL) <= 0