diff options
author | Pauli <pauli@openssl.org> | 2021-08-02 16:16:35 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2021-08-05 15:43:59 +1000 |
commit | f7d998a206383b6bab3fad32b28e58d3786fe08a (patch) | |
tree | 68dc70d58777158e20d6c9549c54e8e461b87773 | |
parent | 2cdf7c6a3324f0477d34b2906632e863941d8d6b (diff) |
tls/prov: move the TLS 1.3 KDF code to providers
This function needs to be power up tested as part of the FIPS validation and
thus it needs to be inside the provider boundary. This is realised by
introducing a new KDF "TLS13-KDF" which does the required massaging of
parameters but is otherwise functionally equivalent to HKDF.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/16203)
-rw-r--r-- | include/openssl/core_names.h | 4 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 1 | ||||
-rw-r--r-- | providers/implementations/include/prov/names.h | 1 | ||||
-rw-r--r-- | providers/implementations/kdfs/hkdf.c | 261 | ||||
-rw-r--r-- | ssl/tls13_enc.c | 116 |
5 files changed, 292 insertions, 91 deletions
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index f99497e229..b549dae916 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -190,6 +190,9 @@ extern "C" { #define OSSL_KDF_PARAM_KEY "key" /* octet string */ #define OSSL_KDF_PARAM_SALT "salt" /* octet string */ #define OSSL_KDF_PARAM_PASSWORD "pass" /* octet string */ +#define OSSL_KDF_PARAM_PREFIX "prefix" /* octet string */ +#define OSSL_KDF_PARAM_LABEL "label" /* octet string */ +#define OSSL_KDF_PARAM_DATA "data" /* octet string */ #define OSSL_KDF_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST /* utf8 string */ #define OSSL_KDF_PARAM_CIPHER OSSL_ALG_PARAM_CIPHER /* utf8 string */ #define OSSL_KDF_PARAM_MAC OSSL_ALG_PARAM_MAC /* utf8 string */ @@ -223,6 +226,7 @@ extern "C" { /* Known KDF names */ #define OSSL_KDF_NAME_HKDF "HKDF" +#define OSSL_KDF_NAME_TLS1_3_KDF "TLS13-KDF" #define OSSL_KDF_NAME_PBKDF1 "PBKDF1" #define OSSL_KDF_NAME_PBKDF2 "PBKDF2" #define OSSL_KDF_NAME_SCRYPT "SCRYPT" diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 855bd90919..c80b0dcfa3 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -257,6 +257,7 @@ extern const OSSL_DISPATCH ossl_kdf_scrypt_functions[]; #endif extern const OSSL_DISPATCH ossl_kdf_tls1_prf_functions[]; extern const OSSL_DISPATCH ossl_kdf_hkdf_functions[]; +extern const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_sshkdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_sskdf_functions[]; extern const OSSL_DISPATCH ossl_kdf_x963_kdf_functions[]; diff --git a/providers/implementations/include/prov/names.h b/providers/implementations/include/prov/names.h index 5aec4a0934..b05776e4f6 100644 --- a/providers/implementations/include/prov/names.h +++ b/providers/implementations/include/prov/names.h @@ -249,6 +249,7 @@ */ #define PROV_NAMES_HKDF "HKDF" #define PROV_DESCS_HKDF_SIGN "OpenSSL HKDF via EVP_PKEY implementation" +#define PROV_NAMES_TLS1_3_KDF "TLS13-KDF" #define PROV_NAMES_SSKDF "SSKDF" #define PROV_NAMES_PBKDF1 "PBKDF1" #define PROV_NAMES_PBKDF2 "PBKDF2:1.2.840.113549.1.5.12" diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c index 167b64f0b3..667d5e9619 100644 --- a/providers/implementations/kdfs/hkdf.c +++ b/providers/implementations/kdfs/hkdf.c @@ -23,6 +23,7 @@ #include <openssl/proverr.h> #include "internal/cryptlib.h" #include "internal/numbers.h" +#include "internal/packet.h" #include "crypto/evp.h" #include "prov/provider_ctx.h" #include "prov/providercommon.h" @@ -40,6 +41,9 @@ static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params; static OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params; static OSSL_FUNC_kdf_get_ctx_params_fn kdf_hkdf_get_ctx_params; +static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive; +static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params; +static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params; static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md, const unsigned char *salt, size_t salt_len, @@ -55,6 +59,15 @@ static int HKDF_Expand(const EVP_MD *evp_md, const unsigned char *info, size_t info_len, unsigned char *okm, size_t okm_len); +/* Settable context parameters that are common across HKDF and the TLS KDF */ +#define HKDF_COMMON_SETTABLES \ + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), \ + OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), \ + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), \ + OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), \ + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), \ + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0) + typedef struct { void *provctx; int mode; @@ -63,6 +76,12 @@ typedef struct { size_t salt_len; unsigned char *key; size_t key_len; + unsigned char *prefix; + size_t prefix_len; + unsigned char *label; + size_t label_len; + unsigned char *data; + size_t data_len; unsigned char info[HKDF_MAXBUF]; size_t info_len; } KDF_HKDF; @@ -98,6 +117,9 @@ static void kdf_hkdf_reset(void *vctx) ossl_prov_digest_reset(&ctx->digest); OPENSSL_free(ctx->salt); + OPENSSL_free(ctx->prefix); + OPENSSL_free(ctx->label); + OPENSSL_clear_free(ctx->data, ctx->data_len); OPENSSL_clear_free(ctx->key, ctx->key_len); OPENSSL_cleanse(ctx->info, ctx->info_len); memset(ctx, 0, sizeof(*ctx)); @@ -163,11 +185,10 @@ static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen, } } -static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, const OSSL_PARAM params[]) { - const OSSL_PARAM *p; - KDF_HKDF *ctx = vctx; OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); + const OSSL_PARAM *p; int n; if (params == NULL) @@ -219,6 +240,21 @@ static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 0; } } + + return 1; +} + +static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + KDF_HKDF *ctx = vctx; + + if (params == NULL) + return 1; + + if (!hkdf_common_set_ctx_params(ctx, params)) + return 0; + /* The info fields concatenate, so process them all */ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_INFO)) != NULL) { ctx->info_len = 0; @@ -243,12 +279,7 @@ static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) { static const OSSL_PARAM known_settable_ctx_params[] = { - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_MODE, NULL, 0), - OSSL_PARAM_int(OSSL_KDF_PARAM_MODE, NULL), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), - OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT, NULL, 0), - OSSL_PARAM_octet_string(OSSL_KDF_PARAM_KEY, NULL, 0), + HKDF_COMMON_SETTABLES, OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0), OSSL_PARAM_END }; @@ -496,3 +527,215 @@ static int HKDF_Expand(const EVP_MD *evp_md, HMAC_CTX_free(hmac); return ret; } + +/* + * TLS uses slight variations of the above and for FIPS validation purposes, + * they need to be present here. + * Refer to RFC 8446 section 7 for specific details. + */ + +/* + * Given a |secret|; a |label| of length |labellen|; and |data| of length + * |datalen| (e.g. typically a hash of the handshake messages), derive a new + * secret |outlen| bytes long and store it in the location pointed to be |out|. + * The |data| value may be zero length. Returns 1 on success and 0 on failure. + */ +static int prov_tls13_hkdf_expand(const EVP_MD *md, + const unsigned char *key, size_t keylen, + const unsigned char *prefix, size_t prefixlen, + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen) +{ + size_t hkdflabellen; + unsigned char hkdflabel[HKDF_MAXBUF]; + WPACKET pkt; + + /* + * 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. We've got the maximum the KDF can handle + * which should always be sufficient. + */ + 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, prefix, prefixlen) + || !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)) { + WPACKET_cleanup(&pkt); + return 0; + } + + return HKDF_Expand(md, key, keylen, hkdflabel, hkdflabellen, + out, outlen); +} + +static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx, + const EVP_MD *md, + const unsigned char *prevsecret, + size_t prevsecretlen, + const unsigned char *insecret, + size_t insecretlen, + const unsigned char *prefix, + size_t prefixlen, + const unsigned char *label, + size_t labellen, + unsigned char *out, size_t outlen) +{ + size_t mdlen; + int ret; + unsigned char preextractsec[EVP_MAX_MD_SIZE]; + /* Always filled with zeros */ + static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; + + ret = EVP_MD_get_size(md); + /* Ensure cast to size_t is safe */ + if (ret <= 0) + return 0; + mdlen = (size_t)ret; + + 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) { + EVP_MD_CTX_free(mctx); + return 0; + } + EVP_MD_CTX_free(mctx); + + /* Generate the pre-extract secret */ + if (!prov_tls13_hkdf_expand(md, prevsecret, mdlen, + prefix, prefixlen, label, labellen, + hash, mdlen, preextractsec, mdlen)) + return 0; + prevsecret = preextractsec; + prevsecretlen = mdlen; + } + + ret = HKDF_Extract(libctx, md, prevsecret, prevsecretlen, + insecret, insecretlen, out, outlen); + + if (prevsecret == preextractsec) + OPENSSL_cleanse(preextractsec, mdlen); + return ret; +} + +static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen, + const OSSL_PARAM params[]) +{ + KDF_HKDF *ctx = (KDF_HKDF *)vctx; + const EVP_MD *md; + + if (!ossl_prov_is_running() || !kdf_tls1_3_set_ctx_params(ctx, params)) + return 0; + + md = ossl_prov_digest_md(&ctx->digest); + if (md == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); + return 0; + } + + switch (ctx->mode) { + default: + return 0; + + case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: + return prov_tls13_hkdf_generate_secret(PROV_LIBCTX_OF(ctx->provctx), + md, + ctx->salt, ctx->salt_len, + ctx->key, ctx->key_len, + ctx->prefix, ctx->prefix_len, + ctx->label, ctx->label_len, + key, keylen); + + case EVP_KDF_HKDF_MODE_EXPAND_ONLY: + return prov_tls13_hkdf_expand(md, ctx->key, ctx->key_len, + ctx->prefix, ctx->prefix_len, + ctx->label, ctx->label_len, + ctx->data, ctx->data_len, + key, keylen); + } +} + +static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + const OSSL_PARAM *p; + KDF_HKDF *ctx = vctx; + + if (params == NULL) + return 1; + + if (!hkdf_common_set_ctx_params(ctx, params)) + return 0; + + if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PREFIX)) != NULL) { + OPENSSL_free(ctx->prefix); + ctx->prefix = NULL; + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->prefix, 0, + &ctx->prefix_len)) + return 0; + } + + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_LABEL)) != NULL) { + OPENSSL_free(ctx->label); + ctx->label = NULL; + if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->label, 0, + &ctx->label_len)) + return 0; + } + + OPENSSL_clear_free(ctx->data, ctx->data_len); + ctx->data = NULL; + if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DATA)) != NULL + && !OSSL_PARAM_get_octet_string(p, (void **)&ctx->data, 0, + &ctx->data_len)) + return 0; + return 1; +} + +static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx, + ossl_unused void *provctx) +{ + static const OSSL_PARAM known_settable_ctx_params[] = { + HKDF_COMMON_SETTABLES, + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PREFIX, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_LABEL, NULL, 0), + OSSL_PARAM_octet_string(OSSL_KDF_PARAM_DATA, NULL, 0), + OSSL_PARAM_END + }; + return known_settable_ctx_params; +} + +const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = { + { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_hkdf_new }, + { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_hkdf_free }, + { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_hkdf_reset }, + { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_3_derive }, + { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, + (void(*)(void))kdf_tls1_3_settable_ctx_params }, + { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void(*)(void))kdf_tls1_3_set_ctx_params }, + { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, + (void(*)(void))kdf_hkdf_gettable_ctx_params }, + { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void(*)(void))kdf_hkdf_get_ctx_params }, + { 0, NULL } +}; diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 91c4248117..7f6133f29c 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -18,8 +18,11 @@ #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 @@ -33,29 +36,14 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, 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_KDF *kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF, + 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[5], *p = params; + 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; kctx = EVP_KDF_CTX_new(kdf); EVP_KDF_free(kdf); @@ -76,37 +64,33 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, return 0; } - hashlen = EVP_MD_get_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)) { + if ((ret = EVP_MD_get_size(md)) <= 0) { EVP_KDF_CTX_free(kctx); - WPACKET_cleanup(&pkt); if (fatal) SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); else ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return 0; } + 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_INFO, - hkdflabel, hkdflabellen); + *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) { @@ -178,12 +162,12 @@ 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_KDF *kdf; EVP_KDF_CTX *kctx; - OSSL_PARAM params[5], *p = params; + 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 @@ -191,9 +175,8 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, #else static const char derived_secret_label[] = "derived"; #endif - unsigned char preextractsec[EVP_MAX_MD_SIZE]; - kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_HKDF, s->ctx->propq); + 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) { @@ -210,51 +193,22 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, } 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, ERR_R_INTERNAL_ERROR); - EVP_MD_CTX_free(mctx); - EVP_KDF_CTX_free(kctx); - 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_KDF_CTX_free(kctx); - return 0; - } - - prevsecret = preextractsec; - prevsecretlen = mdlen; - } - *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 *)insecret, - insecretlen); - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, - (unsigned char *)prevsecret, - prevsecretlen); + 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; @@ -263,8 +217,6 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); EVP_KDF_CTX_free(kctx); - if (prevsecret == preextractsec) - OPENSSL_cleanse(preextractsec, mdlen); return ret == 0; } |