summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2020-01-16 13:14:27 +0100
committerMatt Caswell <matt@openssl.org>2020-02-06 12:59:07 +0100
commitc8f6c28a938fc887ee3d2337f09db453e7fb0369 (patch)
tree80fab6c444adfb668fa03edc2297b729757b53c9
parentParams: change UTF8 construct calls to avoid explicit strlen(3) calls. (diff)
downloadopenssl-c8f6c28a938fc887ee3d2337f09db453e7fb0369.tar.xz
openssl-c8f6c28a938fc887ee3d2337f09db453e7fb0369.zip
Explicitly fetch ciphers and digests in libssl
We modify libssl to use explicitly fetched ciphers, digests and other algorithms as required based on the configured library context and property query string for the SSL_CTX that is being used. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/10854)
-rw-r--r--ssl/s3_enc.c7
-rw-r--r--ssl/s3_lib.c11
-rw-r--r--ssl/ssl_ciph.c175
-rw-r--r--ssl/ssl_init.c5
-rw-r--r--ssl/ssl_lib.c111
-rw-r--r--ssl/ssl_local.h59
-rw-r--r--ssl/ssl_txt.c2
-rw-r--r--ssl/statem/extensions_clnt.c6
-rw-r--r--ssl/statem/extensions_srvr.c5
-rw-r--r--ssl/statem/statem_clnt.c6
-rw-r--r--ssl/statem/statem_lib.c4
-rw-r--r--ssl/statem/statem_srvr.c2
-rw-r--r--ssl/t1_enc.c6
-rw-r--r--ssl/t1_lib.c25
-rw-r--r--ssl/tls13_enc.c71
-rw-r--r--test/tls13secretstest.c17
16 files changed, 337 insertions, 175 deletions
diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c
index ea0fb750f1..76bea32dbd 100644
--- a/ssl/s3_enc.c
+++ b/ssl/s3_enc.c
@@ -86,7 +86,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
err:
EVP_MD_CTX_free(m5);
EVP_MD_CTX_free(s1);
- EVP_MD_free(md5);
+ ssl_evp_md_free(md5);
return ret;
}
@@ -257,13 +257,16 @@ int ssl3_setup_key_block(SSL *s)
if (s->s3.tmp.key_block_length != 0)
return 1;
- if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) {
+ if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, NULL, NULL, &comp,
+ 0)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_SETUP_KEY_BLOCK,
SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0;
}
+ 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;
#ifdef OPENSSL_NO_COMP
s->s3.tmp.new_compression = NULL;
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index a1a61cf328..f5e313b21f 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -3317,6 +3317,9 @@ void ssl3_free(SSL *s)
s->s3.tmp.pkey = NULL;
#endif
+ ssl_evp_cipher_free(s->s3.tmp.new_sym_enc);
+ ssl_evp_md_free(s->s3.tmp.new_hash);
+
OPENSSL_free(s->s3.tmp.ctype);
sk_X509_NAME_pop_free(s->s3.tmp.peer_ca_names, X509_NAME_free);
OPENSSL_free(s->s3.tmp.ciphers_raw);
@@ -4136,7 +4139,6 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
STACK_OF(SSL_CIPHER) *prio, *allow;
int i, ii, ok, prefer_sha256 = 0;
unsigned long alg_k = 0, alg_a = 0, mask_k = 0, mask_a = 0;
- const EVP_MD *mdsha256 = EVP_sha256();
#ifndef OPENSSL_NO_CHACHA
STACK_OF(SSL_CIPHER) *prio_chacha = NULL;
#endif
@@ -4310,7 +4312,12 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
if (prefer_sha256) {
const SSL_CIPHER *tmp = sk_SSL_CIPHER_value(allow, ii);
- if (ssl_md(tmp->algorithm2) == mdsha256) {
+ /*
+ * TODO: When there are no more legacy digests we can just use
+ * OSSL_DIGEST_NAME_SHA2_256 instead of calling OBJ_nid2sn
+ */
+ if (EVP_MD_is_a(ssl_md(s->ctx, tmp->algorithm2),
+ OBJ_nid2sn(NID_sha256))) {
ret = tmp;
break;
}
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index f9fbc5954f..64c791636a 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -22,30 +22,6 @@
#include "internal/thread_once.h"
#include "internal/cryptlib.h"
-#define SSL_ENC_DES_IDX 0
-#define SSL_ENC_3DES_IDX 1
-#define SSL_ENC_RC4_IDX 2
-#define SSL_ENC_RC2_IDX 3
-#define SSL_ENC_IDEA_IDX 4
-#define SSL_ENC_NULL_IDX 5
-#define SSL_ENC_AES128_IDX 6
-#define SSL_ENC_AES256_IDX 7
-#define SSL_ENC_CAMELLIA128_IDX 8
-#define SSL_ENC_CAMELLIA256_IDX 9
-#define SSL_ENC_GOST89_IDX 10
-#define SSL_ENC_SEED_IDX 11
-#define SSL_ENC_AES128GCM_IDX 12
-#define SSL_ENC_AES256GCM_IDX 13
-#define SSL_ENC_AES128CCM_IDX 14
-#define SSL_ENC_AES256CCM_IDX 15
-#define SSL_ENC_AES128CCM8_IDX 16
-#define SSL_ENC_AES256CCM8_IDX 17
-#define SSL_ENC_GOST8912_IDX 18
-#define SSL_ENC_CHACHA_IDX 19
-#define SSL_ENC_ARIA128GCM_IDX 20
-#define SSL_ENC_ARIA256GCM_IDX 21
-#define SSL_ENC_NUM_IDX 22
-
/* NB: make sure indices in these tables match values above */
typedef struct {
@@ -79,8 +55,6 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
{SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */
};
-static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
-
#define SSL_COMP_NULL_IDX 0
#define SSL_COMP_ZLIB_IDX 1
#define SSL_COMP_NUM_IDX 2
@@ -91,13 +65,6 @@ static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT;
#endif
-/*
- * Constant SSL_MAX_DIGEST equal to size of digests array should be defined
- * in the ssl_local.h
- */
-
-#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
-
/* NB: make sure indices in this table matches values above */
static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
{SSL_MD5, NID_md5}, /* SSL_MD_MD5_IDX 0 */
@@ -114,10 +81,6 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
{0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */
};
-static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
/* *INDENT-OFF* */
static const ssl_cipher_table ssl_cipher_table_kx[] = {
{SSL_kRSA, NID_kx_rsa},
@@ -176,8 +139,6 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
NID_undef, NID_undef, NID_undef
};
-static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
-
#define CIPHER_ADD 1
#define CIPHER_KILL 2
#define CIPHER_DEL 3
@@ -355,41 +316,37 @@ static uint32_t disabled_mac_mask;
static uint32_t disabled_mkey_mask;
static uint32_t disabled_auth_mask;
-int ssl_load_ciphers(void)
+int ssl_load_ciphers(SSL_CTX *ctx)
{
size_t i;
const ssl_cipher_table *t;
disabled_enc_mask = 0;
- ssl_sort_cipher_list();
for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) {
- if (t->nid == NID_undef) {
- ssl_cipher_methods[i] = NULL;
- } else {
- const EVP_CIPHER *cipher = EVP_get_cipherbynid(t->nid);
- ssl_cipher_methods[i] = cipher;
+ if (t->nid != NID_undef) {
+ const EVP_CIPHER *cipher
+ = ssl_evp_cipher_fetch(ctx->libctx, t->nid, ctx->propq);
+
+ ctx->ssl_cipher_methods[i] = cipher;
if (cipher == NULL)
disabled_enc_mask |= t->mask;
}
}
disabled_mac_mask = 0;
for (i = 0, t = ssl_cipher_table_mac; i < SSL_MD_NUM_IDX; i++, t++) {
- const EVP_MD *md = EVP_get_digestbynid(t->nid);
- ssl_digest_methods[i] = md;
+ const EVP_MD *md
+ = ssl_evp_md_fetch(ctx->libctx, t->nid, ctx->propq);
+
+ ctx->ssl_digest_methods[i] = md;
if (md == NULL) {
disabled_mac_mask |= t->mask;
} else {
int tmpsize = EVP_MD_size(md);
if (!ossl_assert(tmpsize >= 0))
return 0;
- ssl_mac_secret_size[i] = tmpsize;
+ ctx->ssl_mac_secret_size[i] = tmpsize;
}
}
- /* Make sure we can access MD5 and SHA1 */
- if (!ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL))
- return 0;
- if (!ossl_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL))
- return 0;
disabled_mkey_mask = 0;
disabled_auth_mask = 0;
@@ -422,14 +379,14 @@ int ssl_load_ciphers(void)
*/
ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX])
- ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
+ ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
else
disabled_mac_mask |= SSL_GOST89MAC;
ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] =
get_optional_pkey_id("gost-mac-12");
if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX])
- ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
+ ctx->ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
else
disabled_mac_mask |= SSL_GOST89MAC12;
@@ -482,9 +439,10 @@ static int load_builtin_compressions(void)
}
#endif
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
- const EVP_MD **md, int *mac_pkey_type,
- size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
+int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
+ const EVP_CIPHER **enc, const EVP_MD **md,
+ int *mac_pkey_type, size_t *mac_secret_size,
+ SSL_COMP **comp, int use_etm)
{
int i;
const SSL_CIPHER *c;
@@ -521,10 +479,18 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
if (i == -1) {
*enc = NULL;
} else {
- if (i == SSL_ENC_NULL_IDX)
- *enc = EVP_enc_null();
- else
- *enc = ssl_cipher_methods[i];
+ if (i == SSL_ENC_NULL_IDX) {
+ /*
+ * We assume we don't care about this coming from an ENGINE so
+ * just do a normal EVP_CIPHER_fetch instead of
+ * ssl_evp_cipher_fetch()
+ */
+ *enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq);
+ } else {
+ if (!ssl_evp_cipher_up_ref(ctx->ssl_cipher_methods[i]))
+ return 0;
+ *enc = ctx->ssl_cipher_methods[i];
+ }
}
i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
@@ -537,67 +503,80 @@ int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
if (c->algorithm_mac == SSL_AEAD)
mac_pkey_type = NULL;
} else {
- *md = ssl_digest_methods[i];
+ if (!ssl_evp_md_up_ref(ctx->ssl_digest_methods[i])) {
+ ssl_evp_cipher_free(*enc);
+ return 0;
+ }
+ *md = ctx->ssl_digest_methods[i];
if (mac_pkey_type != NULL)
*mac_pkey_type = ssl_mac_pkey_id[i];
if (mac_secret_size != NULL)
- *mac_secret_size = ssl_mac_secret_size[i];
+ *mac_secret_size = ctx->ssl_mac_secret_size[i];
}
if ((*enc != NULL) &&
(*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
&& (!mac_pkey_type || *mac_pkey_type != NID_undef)) {
- const EVP_CIPHER *evp;
+ const EVP_CIPHER *evp = NULL;
- if (use_etm)
+ if (use_etm
+ || s->ssl_version >> 8 != TLS1_VERSION_MAJOR
+ || s->ssl_version < TLS1_VERSION)
return 1;
- if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR ||
- s->ssl_version < TLS1_VERSION)
- return 1;
-
- if (c->algorithm_enc == SSL_RC4 &&
- c->algorithm_mac == SSL_MD5 &&
- (evp = EVP_get_cipherbyname("RC4-HMAC-MD5")))
- *enc = evp, *md = NULL;
- else if (c->algorithm_enc == SSL_AES128 &&
- c->algorithm_mac == SSL_SHA1 &&
- (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
- *enc = evp, *md = NULL;
- else if (c->algorithm_enc == SSL_AES256 &&
- c->algorithm_mac == SSL_SHA1 &&
- (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
- *enc = evp, *md = NULL;
- else if (c->algorithm_enc == SSL_AES128 &&
- c->algorithm_mac == SSL_SHA256 &&
- (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256")))
- *enc = evp, *md = NULL;
- else if (c->algorithm_enc == SSL_AES256 &&
- c->algorithm_mac == SSL_SHA256 &&
- (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256")))
- *enc = evp, *md = NULL;
+ if (c->algorithm_enc == SSL_RC4
+ && c->algorithm_mac == SSL_MD5)
+ evp = ssl_evp_cipher_fetch(ctx->libctx, NID_rc4_hmac_md5,
+ ctx->propq);
+ else if (c->algorithm_enc == SSL_AES128
+ && c->algorithm_mac == SSL_SHA1)
+ evp = ssl_evp_cipher_fetch(ctx->libctx,
+ NID_aes_128_cbc_hmac_sha1,
+ ctx->propq);
+ else if (c->algorithm_enc == SSL_AES256
+ && c->algorithm_mac == SSL_SHA1)
+ evp = ssl_evp_cipher_fetch(ctx->libctx,
+ NID_aes_256_cbc_hmac_sha1,
+ ctx->propq);
+ else if (c->algorithm_enc == SSL_AES128
+ && c->algorithm_mac == SSL_SHA256)
+ evp = ssl_evp_cipher_fetch(ctx->libctx,
+ NID_aes_128_cbc_hmac_sha256,
+ ctx->propq);
+ else if (c->algorithm_enc == SSL_AES256
+ && c->algorithm_mac == SSL_SHA256)
+ evp = ssl_evp_cipher_fetch(ctx->libctx,
+ NID_aes_256_cbc_hmac_sha256,
+ ctx->propq);
+
+ if (evp != NULL) {
+ ssl_evp_cipher_free(*enc);
+ ssl_evp_md_free(*md);
+ *enc = evp;
+ *md = NULL;
+ }
return 1;
- } else {
- return 0;
}
+
+ return 0;
}
-const EVP_MD *ssl_md(int idx)
+const EVP_MD *ssl_md(SSL_CTX *ctx, int idx)
{
idx &= SSL_HANDSHAKE_MAC_MASK;
if (idx < 0 || idx >= SSL_MD_NUM_IDX)
return NULL;
- return ssl_digest_methods[idx];
+ return ctx->ssl_digest_methods[idx];
}
const EVP_MD *ssl_handshake_md(SSL *s)
{
- return ssl_md(ssl_get_algorithm2(s));
+ return ssl_md(s->ctx, ssl_get_algorithm2(s));
}
const EVP_MD *ssl_prf_md(SSL *s)
{
- return ssl_md(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
+ return ssl_md(s->ctx, ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
}
#define ITEM_SEP(a) \
@@ -2094,7 +2073,7 @@ const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c)
if (idx < 0 || idx >= SSL_MD_NUM_IDX)
return NULL;
- return ssl_digest_methods[idx];
+ return EVP_get_digestbynid(ssl_cipher_table_mac[idx].nid);
}
int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c
index 3e85426112..2ccbda7fa3 100644
--- a/ssl/ssl_init.c
+++ b/ssl/ssl_init.c
@@ -94,10 +94,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base)
*/
SSL_COMP_get_compression_methods();
#endif
- /* initialize cipher/digest methods table */
- if (!ssl_load_ciphers())
- return 0;
-
+ ssl_sort_cipher_list();
OSSL_TRACE(INIT,"ossl_init_ssl_base: SSL_add_ssl_module()\n");
/*
* We ignore an error return here. Not much we can do - but not that bad
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b5239d6eb2..977b599055 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -3146,6 +3146,10 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq,
goto err;
#endif
+ /* initialize cipher/digest methods table */
+ if (!ssl_load_ciphers(ret))
+ return 0;
+
if (!SSL_CTX_set_ciphersuites(ret, OSSL_default_ciphersuites()))
goto err;
@@ -3162,14 +3166,12 @@ SSL_CTX *SSL_CTX_new_with_libctx(OPENSSL_CTX *libctx, const char *propq,
if (ret->param == NULL)
goto err;
- if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) {
- SSLerr(0, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
- goto err2;
- }
- if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) {
- SSLerr(0, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
- goto err2;
- }
+ /*
+ * If these aren't available from the provider we'll get NULL returns.
+ * That's fine but will cause errors later if SSLv3 is negotiated
+ */
+ ret->md5 = ssl_evp_md_fetch(libctx, NID_md5, propq);
+ ret->sha1 = ssl_evp_md_fetch(libctx, NID_sha1, propq);
if ((ret->ca_names = sk_X509_NAME_new_null()) == NULL)
goto err;
@@ -3359,6 +3361,14 @@ void SSL_CTX_free(SSL_CTX *a)
OPENSSL_free(a->ext.alpn);
OPENSSL_secure_free(a->ext.secure);
+ ssl_evp_md_free(a->md5);
+ ssl_evp_md_free(a->sha1);
+
+ for (i = 0; i < SSL_ENC_NUM_IDX; i++)
+ ssl_evp_cipher_free(a->ssl_cipher_methods[i]);
+ for (i = 0; i < SSL_MD_NUM_IDX; i++)
+ ssl_evp_md_free(a->ssl_digest_methods[i]);
+
CRYPTO_THREAD_lock_free(a->lock);
OPENSSL_free(a->propq);
@@ -5833,3 +5843,88 @@ void SSL_set_allow_early_data_cb(SSL *s,
s->allow_early_data_cb = cb;
s->allow_early_data_cb_data = arg;
}
+
+const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties)
+{
+ /*
+ * If there is an Engine available for this cipher we use the "implicit"
+ * form to ensure we use that engine later.
+ */
+ if (ENGINE_get_cipher_engine(nid) != NULL)
+ return EVP_get_cipherbynid(nid);
+
+ /* Otherwise we do an explicit fetch */
+ return EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+
+int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher)
+{
+ /* Don't up-ref an implicit EVP_CIPHER */
+ if (EVP_CIPHER_provider(cipher) == NULL)
+ return 1;
+
+ /*
+ * The cipher was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ return EVP_CIPHER_up_ref((EVP_CIPHER *)cipher);
+}
+
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
+{
+ if (cipher == NULL)
+ return;
+
+ if (EVP_CIPHER_provider(cipher) != NULL) {
+ /*
+ * The cipher was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ EVP_CIPHER_free((EVP_CIPHER *)cipher);
+ }
+}
+
+const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties)
+{
+ /*
+ * If there is an Engine available for this digest we use the "implicit"
+ * form to ensure we use that engine later.
+ */
+ if (ENGINE_get_digest_engine(nid) != NULL)
+ return EVP_get_digestbynid(nid);
+
+ /* Otherwise we do an explicit fetch */
+ return EVP_MD_fetch(libctx, OBJ_nid2sn(nid), properties);
+}
+
+int ssl_evp_md_up_ref(const EVP_MD *md)
+{
+ /* Don't up-ref an implicit EVP_MD */
+ if (EVP_MD_provider(md) == NULL)
+ return 1;
+
+ /*
+ * The digest was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ return EVP_MD_up_ref((EVP_MD *)md);
+}
+
+void ssl_evp_md_free(const EVP_MD *md)
+{
+ if (md == NULL)
+ return;
+
+ if (EVP_MD_provider(md) != NULL) {
+ /*
+ * The digest was explicitly fetched and therefore it is safe to cast
+ * away the const
+ */
+ EVP_MD_free((EVP_MD *)md);
+ }
+}
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index 680afa070a..eefc4ea31d 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -276,6 +276,8 @@
# define SSL_MD_SHA512_IDX 11
# define SSL_MAX_DIGEST 12
+#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
+
/* Bits for algorithm2 (handshake digests and other extra flags) */
/* Bits 0-7 are handshake MAC */
@@ -389,6 +391,30 @@
# define SSL_PKEY_ED448 8
# define SSL_PKEY_NUM 9
+# define SSL_ENC_DES_IDX 0
+# define SSL_ENC_3DES_IDX 1
+# define SSL_ENC_RC4_IDX 2
+# define SSL_ENC_RC2_IDX 3
+# define SSL_ENC_IDEA_IDX 4
+# define SSL_ENC_NULL_IDX 5
+# define SSL_ENC_AES128_IDX 6
+# define SSL_ENC_AES256_IDX 7
+# define SSL_ENC_CAMELLIA128_IDX 8
+# define SSL_ENC_CAMELLIA256_IDX 9
+# define SSL_ENC_GOST89_IDX 10
+# define SSL_ENC_SEED_IDX 11
+# define SSL_ENC_AES128GCM_IDX 12
+# define SSL_ENC_AES256GCM_IDX 13
+# define SSL_ENC_AES128CCM_IDX 14
+# define SSL_ENC_AES256CCM_IDX 15
+# define SSL_ENC_AES128CCM8_IDX 16
+# define SSL_ENC_AES256CCM8_IDX 17
+# define SSL_ENC_GOST8912_IDX 18
+# define SSL_ENC_CHACHA_IDX 19
+# define SSL_ENC_ARIA128GCM_IDX 20
+# define SSL_ENC_ARIA256GCM_IDX 21
+# define SSL_ENC_NUM_IDX 22
+
/*-
* SSL_kRSA <- RSA_ENC
* SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
@@ -865,7 +891,7 @@ struct ssl_ctx_st {
CRYPTO_EX_DATA ex_data;
const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */
- const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */
+ const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3-sha1' */
STACK_OF(X509) *extra_certs;
STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
@@ -1109,6 +1135,10 @@ struct ssl_ctx_st {
void *async_cb_arg;
char *propq;
+
+ const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
+ const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX];
+ size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
};
typedef struct cert_pkey_st CERT_PKEY;
@@ -2333,10 +2363,10 @@ __owur int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites,
STACK_OF(SSL_CIPHER) **scsvs, int sslv2format,
int fatal);
void ssl_update_cache(SSL *s, int mode);
-__owur int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
- const EVP_MD **md, int *mac_pkey_type,
- size_t *mac_secret_size, SSL_COMP **comp,
- int use_etm);
+__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s,
+ const EVP_CIPHER **enc, const EVP_MD **md,
+ int *mac_pkey_type, size_t *mac_secret_size,
+ SSL_COMP **comp, int use_etm);
__owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
size_t *int_overhead, size_t *blocksize,
size_t *ext_overhead);
@@ -2376,7 +2406,7 @@ void ssl_set_masks(SSL *s);
__owur STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
__owur int ssl_x509err2alert(int type);
void ssl_sort_cipher_list(void);
-int ssl_load_ciphers(void);
+int ssl_load_ciphers(SSL_CTX *ctx);
__owur int ssl_fill_hello_random(SSL *s, int server, unsigned char *field,
size_t len, DOWNGRADE dgrd);
__owur int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
@@ -2631,7 +2661,8 @@ __owur int tls1_save_u16(PACKET *pkt, uint16_t **pdest, size_t *pdestlen);
__owur int tls1_save_sigalgs(SSL *s, PACKET *pkt, int cert);
__owur int tls1_process_sigalgs(SSL *s);
__owur int tls1_set_peer_legacy_sigalg(SSL *s, const EVP_PKEY *pkey);
-__owur int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd);
+__owur int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu,
+ const EVP_MD **pmd);
__owur size_t tls12_get_psigalgs(SSL *s, int sent, const uint16_t **psigs);
# ifndef OPENSSL_NO_EC
__owur int tls_check_sigalg_curve(const SSL *s, int curve);
@@ -2642,7 +2673,7 @@ __owur int ssl_cipher_disabled(const SSL *s, const SSL_CIPHER *c, int op, int ec
__owur int ssl_handshake_hash(SSL *s, unsigned char *out, size_t outlen,
size_t *hashlen);
-__owur const EVP_MD *ssl_md(int idx);
+__owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx);
__owur const EVP_MD *ssl_handshake_md(SSL *s);
__owur const EVP_MD *ssl_prf_md(SSL *s);
@@ -2720,6 +2751,18 @@ void ssl_comp_free_compression_methods_int(void);
/* ssl_mcnf.c */
void ssl_ctx_system_config(SSL_CTX *ctx);
+const EVP_CIPHER *ssl_evp_cipher_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties);
+int ssl_evp_cipher_up_ref(const EVP_CIPHER *cipher);
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher);
+const EVP_MD *ssl_evp_md_fetch(OPENSSL_CTX *libctx,
+ int nid,
+ const char *properties);
+int ssl_evp_md_up_ref(const EVP_MD *md);
+void ssl_evp_md_free(const EVP_MD *md);
+
+
# else /* OPENSSL_UNIT_TEST */
# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c
index bc3fcfbd1d..09d00bacbe 100644
--- a/ssl/ssl_txt.c
+++ b/ssl/ssl_txt.c
@@ -117,7 +117,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
if (x->compress_meth != 0) {
SSL_COMP *comp = NULL;
- if (!ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp, 0))
+ if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0))
goto err;
if (comp == NULL) {
if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= 0)
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
index 75fecdeaa6..776473e659 100644
--- a/ssl/statem/extensions_clnt.c
+++ b/ssl/statem/extensions_clnt.c
@@ -981,7 +981,7 @@ EXT_RETURN tls_construct_ctos_padding(SSL *s, WPACKET *pkt,
if (s->session->ssl_version == TLS1_3_VERSION
&& s->session->ext.ticklen != 0
&& s->session->cipher != NULL) {
- const EVP_MD *md = ssl_md(s->session->cipher->algorithm2);
+ const EVP_MD *md = ssl_md(s->ctx, s->session->cipher->algorithm2);
if (md != NULL) {
/*
@@ -1059,7 +1059,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
ERR_R_INTERNAL_ERROR);
return EXT_RETURN_FAIL;
}
- mdres = ssl_md(s->session->cipher->algorithm2);
+ mdres = ssl_md(s->ctx, s->session->cipher->algorithm2);
if (mdres == NULL) {
/*
* Don't recognize this cipher so we can't use the session.
@@ -1132,7 +1132,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context,
return EXT_RETURN_NOT_SENT;
if (s->psksession != NULL) {
- mdpsk = ssl_md(s->psksession->cipher->algorithm2);
+ mdpsk = ssl_md(s->ctx, s->psksession->cipher->algorithm2);
if (mdpsk == NULL) {
/*
* Don't recognize this cipher so we can't use the session.
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
index a2a4ae8a6e..999e1cd832 100644
--- a/ssl/statem/extensions_srvr.c
+++ b/ssl/statem/extensions_srvr.c
@@ -1238,8 +1238,9 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
}
}
- md = ssl_md(sess->cipher->algorithm2);
- if (md != ssl_md(s->s3.tmp.new_cipher->algorithm2)) {
+ md = ssl_md(s->ctx, sess->cipher->algorithm2);
+ if (!EVP_MD_is_a(md,
+ EVP_MD_name(ssl_md(s->ctx, s->s3.tmp.new_cipher->algorithm2)))) {
/* The ciphersuite is not compatible with this session. */
SSL_SESSION_free(sess);
sess = NULL;
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index ef53fe7872..e524e62b93 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -1376,8 +1376,8 @@ static int set_client_ciphersuite(SSL *s, const unsigned char *cipherchars)
* In TLSv1.3 it is valid for the server to select a different
* ciphersuite as long as the hash is the same.
*/
- if (ssl_md(c->algorithm2)
- != ssl_md(s->session->cipher->algorithm2)) {
+ if (ssl_md(s->ctx, c->algorithm2)
+ != ssl_md(s->ctx, s->session->cipher->algorithm2)) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER,
SSL_F_SET_CLIENT_CIPHERSUITE,
SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED);
@@ -2337,7 +2337,7 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
goto err;
}
- if (!tls1_lookup_md(s->s3.tmp.peer_sigalg, &md)) {
+ if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c
index c478bb47aa..c5956ea37c 100644
--- a/ssl/statem/statem_lib.c
+++ b/ssl/statem/statem_lib.c
@@ -247,7 +247,7 @@ int tls_construct_cert_verify(SSL *s, WPACKET *pkt)
}
pkey = s->s3.tmp.cert->privatekey;
- if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
+ if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CERT_VERIFY,
ERR_R_INTERNAL_ERROR);
goto err;
@@ -420,7 +420,7 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
goto err;
}
- if (!tls1_lookup_md(s->s3.tmp.peer_sigalg, &md)) {
+ if (!tls1_lookup_md(s->ctx, s->s3.tmp.peer_sigalg, &md)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CERT_VERIFY,
ERR_R_INTERNAL_ERROR);
goto err;
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 50eaf69da4..256575f1a0 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2763,7 +2763,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
unsigned char *sigbytes1, *sigbytes2, *tbs;
size_t siglen = 0, tbslen;
- if (pkey == NULL || !tls1_lookup_md(lu, &md)) {
+ if (pkey == NULL || !tls1_lookup_md(s->ctx, lu, &md)) {
/* Should never happen */
SSLfatal(s, SSL_AD_INTERNAL_ERROR,
SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 59bf789af0..6ce5235882 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -538,14 +538,16 @@ int tls1_setup_key_block(SSL *s)
if (s->s3.tmp.key_block_length != 0)
return 1;
- if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type, &mac_secret_size,
- &comp, s->ext.use_etm)) {
+ if (!ssl_cipher_get_evp(s->ctx, s->session, &c, &hash, &mac_type,
+ &mac_secret_size, &comp, s->ext.use_etm)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_SETUP_KEY_BLOCK,
SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0;
}
+ 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;
s->s3.tmp.new_mac_pkey_type = mac_type;
s->s3.tmp.new_mac_secret_size = mac_secret_size;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index fa2d6e0154..103a8f18bb 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -893,7 +893,7 @@ static const SIGALG_LOOKUP *tls1_lookup_sigalg(uint16_t sigalg)
return NULL;
}
/* Lookup hash: return 0 if invalid or not enabled */
-int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
+int tls1_lookup_md(SSL_CTX *ctx, const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
{
const EVP_MD *md;
if (lu == NULL)
@@ -902,7 +902,7 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
if (lu->hash == NID_undef) {
md = NULL;
} else {
- md = ssl_md(lu->hash_idx);
+ md = ssl_md(ctx, lu->hash_idx);
if (md == NULL)
return 0;
}
@@ -919,13 +919,14 @@ int tls1_lookup_md(const SIGALG_LOOKUP *lu, const EVP_MD **pmd)
* with a 128 byte (1024 bit) key.
*/
#define RSA_PSS_MINIMUM_KEY_SIZE(md) (2 * EVP_MD_size(md) + 2)
-static int rsa_pss_check_min_key_size(const RSA *rsa, const SIGALG_LOOKUP *lu)
+static int rsa_pss_check_min_key_size(SSL_CTX *ctx, const RSA *rsa,
+ const SIGALG_LOOKUP *lu)
{
const EVP_MD *md;
if (rsa == NULL)
return 0;
- if (!tls1_lookup_md(lu, &md) || md == NULL)
+ if (!tls1_lookup_md(ctx, lu, &md) || md == NULL)
return 0;
if (RSA_size(rsa) < RSA_PSS_MINIMUM_KEY_SIZE(md))
return 0;
@@ -978,7 +979,7 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx)
if (SSL_USE_SIGALGS(s) || idx != SSL_PKEY_RSA) {
const SIGALG_LOOKUP *lu = tls1_lookup_sigalg(tls_default_sigalg[idx]);
- if (!tls1_lookup_md(lu, NULL))
+ if (!tls1_lookup_md(s->ctx, lu, NULL))
return NULL;
if (!tls12_sigalg_allowed(s, SSL_SECOP_SIGALG_SUPPORTED, lu))
return NULL;
@@ -1183,7 +1184,7 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey)
SSL_R_WRONG_SIGNATURE_TYPE);
return 0;
}
- if (!tls1_lookup_md(lu, &md)) {
+ if (!tls1_lookup_md(s->ctx, lu, &md)) {
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS12_CHECK_PEER_SIGALG,
SSL_R_UNKNOWN_DIGEST);
return 0;
@@ -1670,7 +1671,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
int secbits;
/* See if sigalgs is recognised and if hash is enabled */
- if (!tls1_lookup_md(lu, NULL))
+ if (!tls1_lookup_md(s->ctx, lu, NULL))
return 0;
/* DSA is not allowed in TLS 1.3 */
if (SSL_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA)
@@ -1728,7 +1729,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu)
if (lu->hash == NID_undef)
return 1;
/* Security bits: half digest bits */
- secbits = EVP_MD_size(ssl_md(lu->hash_idx)) * 4;
+ secbits = EVP_MD_size(ssl_md(s->ctx, lu->hash_idx)) * 4;
/* Finally see if security callback allows it */
sigalgstr[0] = (lu->sigalg >> 8) & 0xff;
sigalgstr[1] = lu->sigalg & 0xff;
@@ -2777,7 +2778,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
|| lu->sig == EVP_PKEY_RSA)
continue;
/* Check that we have a cert, and signature_algorithms_cert */
- if (!tls1_lookup_md(lu, NULL))
+ if (!tls1_lookup_md(s->ctx, lu, NULL))
continue;
if ((pkey == NULL && !has_usable_cert(s, lu, -1))
|| (pkey != NULL && !is_cert_usable(s, lu, x, pkey)))
@@ -2799,7 +2800,7 @@ static const SIGALG_LOOKUP *find_sig_alg(SSL *s, X509 *x, EVP_PKEY *pkey)
#endif
} else if (lu->sig == EVP_PKEY_RSA_PSS) {
/* validate that key is large enough for the signature algorithm */
- if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(tmppkey), lu))
+ if (!rsa_pss_check_min_key_size(s->ctx, EVP_PKEY_get0(tmppkey), lu))
continue;
}
break;
@@ -2885,7 +2886,9 @@ int tls_choose_sigalg(SSL *s, int fatalerrs)
/* validate that key is large enough for the signature algorithm */
EVP_PKEY *pkey = s->cert->pkeys[sig_idx].privatekey;
- if (!rsa_pss_check_min_key_size(EVP_PKEY_get0(pkey), lu))
+ if (!rsa_pss_check_min_key_size(s->ctx,
+ EVP_PKEY_get0(pkey),
+ lu))
continue;
}
#ifndef OPENSSL_NO_EC
diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c
index 181f3920a1..9ca63b7550 100644
--- a/ssl/tls13_enc.c
+++ b/ssl/tls13_enc.c
@@ -36,7 +36,8 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret,
#else
static const unsigned char label_prefix[] = "tls13 ";
#endif
- EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
+ EVP_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF,
+ s->ctx->propq);
EVP_KDF_CTX *kctx;
OSSL_PARAM params[5], *p = params;
int mode = EVP_PKEY_HKDEF_MODE_EXPAND_ONLY;
@@ -194,7 +195,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md,
#endif
unsigned char preextractsec[EVP_MAX_MD_SIZE];
- kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL);
+ kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF, s->ctx->propq);
kctx = EVP_KDF_CTX_new(kdf);
EVP_KDF_free(kdf);
if (kctx == NULL) {
@@ -311,11 +312,27 @@ int tls13_generate_master_secret(SSL *s, unsigned char *out,
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_name(ssl_handshake_md(s));
+ EVP_MAC *hmac = EVP_MAC_fetch(s->ctx->libctx, "HMAC", s->ctx->propq);
unsigned char hash[EVP_MAX_MD_SIZE];
+ unsigned char finsecret[EVP_MAX_MD_SIZE];
size_t hashlen, ret = 0;
- EVP_PKEY *key = NULL;
- EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ EVP_MAC_CTX *ctx = NULL;
+ OSSL_PARAM params[4], *p = params;
+
+ if (hmac == NULL) {
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ /* Safe to cast away const here since we're not "getting" any data */
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST,
+ (char *)mdname, 0);
+ if (s->ctx->propq != NULL)
+ *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_PROPERTIES,
+ (char *)s->ctx->propq,
+ 0);
if (!ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) {
/* SSLfatal() already called */
@@ -323,29 +340,31 @@ 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);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+ s->server_finished_secret,
+ hashlen);
} else if (SSL_IS_FIRST_HANDSHAKE(s)) {
- key = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, NULL,
- s->client_finished_secret, hashlen);
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY,
+ s->client_finished_secret,
+ hashlen);
} else {
- unsigned char finsecret[EVP_MAX_MD_SIZE];
-
if (!tls13_derive_finishedkey(s, ssl_handshake_md(s),
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));
+ *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, finsecret,
+ hashlen);
}
+ *p++ = OSSL_PARAM_construct_end();
- 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) {
+ ctx = EVP_MAC_CTX_new(hmac);
+ if (ctx == NULL
+ || !EVP_MAC_CTX_set_params(ctx, params)
+ || !EVP_MAC_init(ctx)
+ || !EVP_MAC_update(ctx, hash, hashlen)
+ /* outsize as per sizeof(peer_finish_md) */
+ || !EVP_MAC_final(ctx, out, &hashlen, EVP_MAX_MD_SIZE * 2)) {
SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_FINAL_FINISH_MAC,
ERR_R_INTERNAL_ERROR);
goto err;
@@ -353,8 +372,9 @@ size_t tls13_final_finish_mac(SSL *s, const char *str, size_t slen,
ret = hashlen;
err:
- EVP_PKEY_free(key);
- EVP_MD_CTX_free(ctx);
+ OPENSSL_cleanse(finsecret, sizeof(finsecret));
+ EVP_MAC_CTX_free(ctx);
+ EVP_MAC_free(hmac);
return ret;
}
@@ -368,13 +388,16 @@ int tls13_setup_key_block(SSL *s)
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)) {
+ if (!ssl_cipher_get_evp(s->ctx, 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);
return 0;
}
+ 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;
@@ -577,7 +600,7 @@ int tls13_change_cipher_state(SSL *s, int which)
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)) {
@@ -862,7 +885,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
diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c
index def78b9920..5d614768f8 100644
--- a/test/tls13secretstest.c
+++ b/test/tls13secretstest.c
@@ -165,9 +165,10 @@ void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl)
{
}
-int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
- const EVP_MD **md, int *mac_pkey_type,
- size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
+int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s,
+ const EVP_CIPHER **enc, const EVP_MD **md,
+ int *mac_pkey_type, size_t *mac_secret_size,
+ SSL_COMP **comp, int use_etm)
{
return 0;
@@ -186,7 +187,7 @@ int ssl_log_secret(SSL *ssl,
return 1;
}
-const EVP_MD *ssl_md(int idx)
+const EVP_MD *ssl_md(SSL_CTX *ctx, int idx)
{
return EVP_sha256();
}
@@ -206,6 +207,14 @@ int ossl_statem_export_early_allowed(SSL *s)
return 1;
}
+void ssl_evp_cipher_free(const EVP_CIPHER *cipher)
+{
+}
+
+void ssl_evp_md_free(const EVP_MD *md)
+{
+}
+
/* End of mocked out code */
static int test_secret(SSL *s, unsigned char *prk,