1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * Refer to "The TLS Protocol Version 1.0" Section 5 12e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc2246#section-5) and 13e1051a39Sopenharmony_ci * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5 14e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc5246#section-5). 15e1051a39Sopenharmony_ci * 16e1051a39Sopenharmony_ci * For TLS v1.0 and TLS v1.1 the TLS PRF algorithm is given by: 17e1051a39Sopenharmony_ci * 18e1051a39Sopenharmony_ci * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR 19e1051a39Sopenharmony_ci * P_SHA-1(S2, label + seed) 20e1051a39Sopenharmony_ci * 21e1051a39Sopenharmony_ci * where P_MD5 and P_SHA-1 are defined by P_<hash>, below, and S1 and S2 are 22e1051a39Sopenharmony_ci * two halves of the secret (with the possibility of one shared byte, in the 23e1051a39Sopenharmony_ci * case where the length of the original secret is odd). S1 is taken from the 24e1051a39Sopenharmony_ci * first half of the secret, S2 from the second half. 25e1051a39Sopenharmony_ci * 26e1051a39Sopenharmony_ci * For TLS v1.2 the TLS PRF algorithm is given by: 27e1051a39Sopenharmony_ci * 28e1051a39Sopenharmony_ci * PRF(secret, label, seed) = P_<hash>(secret, label + seed) 29e1051a39Sopenharmony_ci * 30e1051a39Sopenharmony_ci * where hash is SHA-256 for all cipher suites defined in RFC 5246 as well as 31e1051a39Sopenharmony_ci * those published prior to TLS v1.2 while the TLS v1.2 protocol is in effect, 32e1051a39Sopenharmony_ci * unless defined otherwise by the cipher suite. 33e1051a39Sopenharmony_ci * 34e1051a39Sopenharmony_ci * P_<hash> is an expansion function that uses a single hash function to expand 35e1051a39Sopenharmony_ci * a secret and seed into an arbitrary quantity of output: 36e1051a39Sopenharmony_ci * 37e1051a39Sopenharmony_ci * P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) + 38e1051a39Sopenharmony_ci * HMAC_<hash>(secret, A(2) + seed) + 39e1051a39Sopenharmony_ci * HMAC_<hash>(secret, A(3) + seed) + ... 40e1051a39Sopenharmony_ci * 41e1051a39Sopenharmony_ci * where + indicates concatenation. P_<hash> can be iterated as many times as 42e1051a39Sopenharmony_ci * is necessary to produce the required quantity of data. 43e1051a39Sopenharmony_ci * 44e1051a39Sopenharmony_ci * A(i) is defined as: 45e1051a39Sopenharmony_ci * A(0) = seed 46e1051a39Sopenharmony_ci * A(i) = HMAC_<hash>(secret, A(i-1)) 47e1051a39Sopenharmony_ci */ 48e1051a39Sopenharmony_ci#include <stdio.h> 49e1051a39Sopenharmony_ci#include <stdarg.h> 50e1051a39Sopenharmony_ci#include <string.h> 51e1051a39Sopenharmony_ci#include <openssl/evp.h> 52e1051a39Sopenharmony_ci#include <openssl/kdf.h> 53e1051a39Sopenharmony_ci#include <openssl/core_names.h> 54e1051a39Sopenharmony_ci#include <openssl/params.h> 55e1051a39Sopenharmony_ci#include <openssl/proverr.h> 56e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 57e1051a39Sopenharmony_ci#include "internal/numbers.h" 58e1051a39Sopenharmony_ci#include "crypto/evp.h" 59e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 60e1051a39Sopenharmony_ci#include "prov/providercommon.h" 61e1051a39Sopenharmony_ci#include "prov/implementations.h" 62e1051a39Sopenharmony_ci#include "prov/provider_util.h" 63e1051a39Sopenharmony_ci#include "e_os.h" 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_newctx_fn kdf_tls1_prf_new; 66e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_freectx_fn kdf_tls1_prf_free; 67e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_reset_fn kdf_tls1_prf_reset; 68e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_derive_fn kdf_tls1_prf_derive; 69e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params; 70e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_prf_set_ctx_params; 71e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params; 72e1051a39Sopenharmony_cistatic OSSL_FUNC_kdf_get_ctx_params_fn kdf_tls1_prf_get_ctx_params; 73e1051a39Sopenharmony_ci 74e1051a39Sopenharmony_cistatic int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, 75e1051a39Sopenharmony_ci const unsigned char *sec, size_t slen, 76e1051a39Sopenharmony_ci const unsigned char *seed, size_t seed_len, 77e1051a39Sopenharmony_ci unsigned char *out, size_t olen); 78e1051a39Sopenharmony_ci 79e1051a39Sopenharmony_ci#define TLS1_PRF_MAXBUF 1024 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci/* TLS KDF kdf context structure */ 82e1051a39Sopenharmony_citypedef struct { 83e1051a39Sopenharmony_ci void *provctx; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci /* MAC context for the main digest */ 86e1051a39Sopenharmony_ci EVP_MAC_CTX *P_hash; 87e1051a39Sopenharmony_ci /* MAC context for SHA1 for the MD5/SHA-1 combined PRF */ 88e1051a39Sopenharmony_ci EVP_MAC_CTX *P_sha1; 89e1051a39Sopenharmony_ci 90e1051a39Sopenharmony_ci /* Secret value to use for PRF */ 91e1051a39Sopenharmony_ci unsigned char *sec; 92e1051a39Sopenharmony_ci size_t seclen; 93e1051a39Sopenharmony_ci /* Buffer of concatenated seed data */ 94e1051a39Sopenharmony_ci unsigned char seed[TLS1_PRF_MAXBUF]; 95e1051a39Sopenharmony_ci size_t seedlen; 96e1051a39Sopenharmony_ci} TLS1_PRF; 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_cistatic void *kdf_tls1_prf_new(void *provctx) 99e1051a39Sopenharmony_ci{ 100e1051a39Sopenharmony_ci TLS1_PRF *ctx; 101e1051a39Sopenharmony_ci 102e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 103e1051a39Sopenharmony_ci return NULL; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 106e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 107e1051a39Sopenharmony_ci return NULL; 108e1051a39Sopenharmony_ci } 109e1051a39Sopenharmony_ci ctx->provctx = provctx; 110e1051a39Sopenharmony_ci return ctx; 111e1051a39Sopenharmony_ci} 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_cistatic void kdf_tls1_prf_free(void *vctx) 114e1051a39Sopenharmony_ci{ 115e1051a39Sopenharmony_ci TLS1_PRF *ctx = (TLS1_PRF *)vctx; 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci if (ctx != NULL) { 118e1051a39Sopenharmony_ci kdf_tls1_prf_reset(ctx); 119e1051a39Sopenharmony_ci OPENSSL_free(ctx); 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci} 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_cistatic void kdf_tls1_prf_reset(void *vctx) 124e1051a39Sopenharmony_ci{ 125e1051a39Sopenharmony_ci TLS1_PRF *ctx = (TLS1_PRF *)vctx; 126e1051a39Sopenharmony_ci void *provctx = ctx->provctx; 127e1051a39Sopenharmony_ci 128e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx->P_hash); 129e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx->P_sha1); 130e1051a39Sopenharmony_ci OPENSSL_clear_free(ctx->sec, ctx->seclen); 131e1051a39Sopenharmony_ci OPENSSL_cleanse(ctx->seed, ctx->seedlen); 132e1051a39Sopenharmony_ci memset(ctx, 0, sizeof(*ctx)); 133e1051a39Sopenharmony_ci ctx->provctx = provctx; 134e1051a39Sopenharmony_ci} 135e1051a39Sopenharmony_ci 136e1051a39Sopenharmony_cistatic int kdf_tls1_prf_derive(void *vctx, unsigned char *key, size_t keylen, 137e1051a39Sopenharmony_ci const OSSL_PARAM params[]) 138e1051a39Sopenharmony_ci{ 139e1051a39Sopenharmony_ci TLS1_PRF *ctx = (TLS1_PRF *)vctx; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || !kdf_tls1_prf_set_ctx_params(ctx, params)) 142e1051a39Sopenharmony_ci return 0; 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci if (ctx->P_hash == NULL) { 145e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); 146e1051a39Sopenharmony_ci return 0; 147e1051a39Sopenharmony_ci } 148e1051a39Sopenharmony_ci if (ctx->sec == NULL) { 149e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SECRET); 150e1051a39Sopenharmony_ci return 0; 151e1051a39Sopenharmony_ci } 152e1051a39Sopenharmony_ci if (ctx->seedlen == 0) { 153e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_SEED); 154e1051a39Sopenharmony_ci return 0; 155e1051a39Sopenharmony_ci } 156e1051a39Sopenharmony_ci if (keylen == 0) { 157e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); 158e1051a39Sopenharmony_ci return 0; 159e1051a39Sopenharmony_ci } 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ci return tls1_prf_alg(ctx->P_hash, ctx->P_sha1, 162e1051a39Sopenharmony_ci ctx->sec, ctx->seclen, 163e1051a39Sopenharmony_ci ctx->seed, ctx->seedlen, 164e1051a39Sopenharmony_ci key, keylen); 165e1051a39Sopenharmony_ci} 166e1051a39Sopenharmony_ci 167e1051a39Sopenharmony_cistatic int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) 168e1051a39Sopenharmony_ci{ 169e1051a39Sopenharmony_ci const OSSL_PARAM *p; 170e1051a39Sopenharmony_ci TLS1_PRF *ctx = vctx; 171e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ci if (params == NULL) 174e1051a39Sopenharmony_ci return 1; 175e1051a39Sopenharmony_ci 176e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_DIGEST)) != NULL) { 177e1051a39Sopenharmony_ci if (OPENSSL_strcasecmp(p->data, SN_md5_sha1) == 0) { 178e1051a39Sopenharmony_ci if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params, 179e1051a39Sopenharmony_ci OSSL_MAC_NAME_HMAC, 180e1051a39Sopenharmony_ci NULL, SN_md5, libctx) 181e1051a39Sopenharmony_ci || !ossl_prov_macctx_load_from_params(&ctx->P_sha1, params, 182e1051a39Sopenharmony_ci OSSL_MAC_NAME_HMAC, 183e1051a39Sopenharmony_ci NULL, SN_sha1, libctx)) 184e1051a39Sopenharmony_ci return 0; 185e1051a39Sopenharmony_ci } else { 186e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx->P_sha1); 187e1051a39Sopenharmony_ci if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params, 188e1051a39Sopenharmony_ci OSSL_MAC_NAME_HMAC, 189e1051a39Sopenharmony_ci NULL, NULL, libctx)) 190e1051a39Sopenharmony_ci return 0; 191e1051a39Sopenharmony_ci } 192e1051a39Sopenharmony_ci } 193e1051a39Sopenharmony_ci 194e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SECRET)) != NULL) { 195e1051a39Sopenharmony_ci OPENSSL_clear_free(ctx->sec, ctx->seclen); 196e1051a39Sopenharmony_ci ctx->sec = NULL; 197e1051a39Sopenharmony_ci if (!OSSL_PARAM_get_octet_string(p, (void **)&ctx->sec, 0, &ctx->seclen)) 198e1051a39Sopenharmony_ci return 0; 199e1051a39Sopenharmony_ci } 200e1051a39Sopenharmony_ci /* The seed fields concatenate, so process them all */ 201e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SEED)) != NULL) { 202e1051a39Sopenharmony_ci for (; p != NULL; p = OSSL_PARAM_locate_const(p + 1, 203e1051a39Sopenharmony_ci OSSL_KDF_PARAM_SEED)) { 204e1051a39Sopenharmony_ci const void *q = ctx->seed + ctx->seedlen; 205e1051a39Sopenharmony_ci size_t sz = 0; 206e1051a39Sopenharmony_ci 207e1051a39Sopenharmony_ci if (p->data_size != 0 208e1051a39Sopenharmony_ci && p->data != NULL 209e1051a39Sopenharmony_ci && !OSSL_PARAM_get_octet_string(p, (void **)&q, 210e1051a39Sopenharmony_ci TLS1_PRF_MAXBUF - ctx->seedlen, 211e1051a39Sopenharmony_ci &sz)) 212e1051a39Sopenharmony_ci return 0; 213e1051a39Sopenharmony_ci ctx->seedlen += sz; 214e1051a39Sopenharmony_ci } 215e1051a39Sopenharmony_ci } 216e1051a39Sopenharmony_ci return 1; 217e1051a39Sopenharmony_ci} 218e1051a39Sopenharmony_ci 219e1051a39Sopenharmony_cistatic const OSSL_PARAM *kdf_tls1_prf_settable_ctx_params( 220e1051a39Sopenharmony_ci ossl_unused void *ctx, ossl_unused void *provctx) 221e1051a39Sopenharmony_ci{ 222e1051a39Sopenharmony_ci static const OSSL_PARAM known_settable_ctx_params[] = { 223e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0), 224e1051a39Sopenharmony_ci OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST, NULL, 0), 225e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SECRET, NULL, 0), 226e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SEED, NULL, 0), 227e1051a39Sopenharmony_ci OSSL_PARAM_END 228e1051a39Sopenharmony_ci }; 229e1051a39Sopenharmony_ci return known_settable_ctx_params; 230e1051a39Sopenharmony_ci} 231e1051a39Sopenharmony_ci 232e1051a39Sopenharmony_cistatic int kdf_tls1_prf_get_ctx_params(void *vctx, OSSL_PARAM params[]) 233e1051a39Sopenharmony_ci{ 234e1051a39Sopenharmony_ci OSSL_PARAM *p; 235e1051a39Sopenharmony_ci 236e1051a39Sopenharmony_ci if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE)) != NULL) 237e1051a39Sopenharmony_ci return OSSL_PARAM_set_size_t(p, SIZE_MAX); 238e1051a39Sopenharmony_ci return -2; 239e1051a39Sopenharmony_ci} 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_cistatic const OSSL_PARAM *kdf_tls1_prf_gettable_ctx_params( 242e1051a39Sopenharmony_ci ossl_unused void *ctx, ossl_unused void *provctx) 243e1051a39Sopenharmony_ci{ 244e1051a39Sopenharmony_ci static const OSSL_PARAM known_gettable_ctx_params[] = { 245e1051a39Sopenharmony_ci OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), 246e1051a39Sopenharmony_ci OSSL_PARAM_END 247e1051a39Sopenharmony_ci }; 248e1051a39Sopenharmony_ci return known_gettable_ctx_params; 249e1051a39Sopenharmony_ci} 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_kdf_tls1_prf_functions[] = { 252e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_NEWCTX, (void(*)(void))kdf_tls1_prf_new }, 253e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_FREECTX, (void(*)(void))kdf_tls1_prf_free }, 254e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_RESET, (void(*)(void))kdf_tls1_prf_reset }, 255e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_DERIVE, (void(*)(void))kdf_tls1_prf_derive }, 256e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, 257e1051a39Sopenharmony_ci (void(*)(void))kdf_tls1_prf_settable_ctx_params }, 258e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_SET_CTX_PARAMS, 259e1051a39Sopenharmony_ci (void(*)(void))kdf_tls1_prf_set_ctx_params }, 260e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, 261e1051a39Sopenharmony_ci (void(*)(void))kdf_tls1_prf_gettable_ctx_params }, 262e1051a39Sopenharmony_ci { OSSL_FUNC_KDF_GET_CTX_PARAMS, 263e1051a39Sopenharmony_ci (void(*)(void))kdf_tls1_prf_get_ctx_params }, 264e1051a39Sopenharmony_ci { 0, NULL } 265e1051a39Sopenharmony_ci}; 266e1051a39Sopenharmony_ci 267e1051a39Sopenharmony_ci/* 268e1051a39Sopenharmony_ci * Refer to "The TLS Protocol Version 1.0" Section 5 269e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc2246#section-5) and 270e1051a39Sopenharmony_ci * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5 271e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc5246#section-5). 272e1051a39Sopenharmony_ci * 273e1051a39Sopenharmony_ci * P_<hash> is an expansion function that uses a single hash function to expand 274e1051a39Sopenharmony_ci * a secret and seed into an arbitrary quantity of output: 275e1051a39Sopenharmony_ci * 276e1051a39Sopenharmony_ci * P_<hash>(secret, seed) = HMAC_<hash>(secret, A(1) + seed) + 277e1051a39Sopenharmony_ci * HMAC_<hash>(secret, A(2) + seed) + 278e1051a39Sopenharmony_ci * HMAC_<hash>(secret, A(3) + seed) + ... 279e1051a39Sopenharmony_ci * 280e1051a39Sopenharmony_ci * where + indicates concatenation. P_<hash> can be iterated as many times as 281e1051a39Sopenharmony_ci * is necessary to produce the required quantity of data. 282e1051a39Sopenharmony_ci * 283e1051a39Sopenharmony_ci * A(i) is defined as: 284e1051a39Sopenharmony_ci * A(0) = seed 285e1051a39Sopenharmony_ci * A(i) = HMAC_<hash>(secret, A(i-1)) 286e1051a39Sopenharmony_ci */ 287e1051a39Sopenharmony_cistatic int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init, 288e1051a39Sopenharmony_ci const unsigned char *sec, size_t sec_len, 289e1051a39Sopenharmony_ci const unsigned char *seed, size_t seed_len, 290e1051a39Sopenharmony_ci unsigned char *out, size_t olen) 291e1051a39Sopenharmony_ci{ 292e1051a39Sopenharmony_ci size_t chunk; 293e1051a39Sopenharmony_ci EVP_MAC_CTX *ctx = NULL, *ctx_Ai = NULL; 294e1051a39Sopenharmony_ci unsigned char Ai[EVP_MAX_MD_SIZE]; 295e1051a39Sopenharmony_ci size_t Ai_len; 296e1051a39Sopenharmony_ci int ret = 0; 297e1051a39Sopenharmony_ci 298e1051a39Sopenharmony_ci if (!EVP_MAC_init(ctx_init, sec, sec_len, NULL)) 299e1051a39Sopenharmony_ci goto err; 300e1051a39Sopenharmony_ci chunk = EVP_MAC_CTX_get_mac_size(ctx_init); 301e1051a39Sopenharmony_ci if (chunk == 0) 302e1051a39Sopenharmony_ci goto err; 303e1051a39Sopenharmony_ci /* A(0) = seed */ 304e1051a39Sopenharmony_ci ctx_Ai = EVP_MAC_CTX_dup(ctx_init); 305e1051a39Sopenharmony_ci if (ctx_Ai == NULL) 306e1051a39Sopenharmony_ci goto err; 307e1051a39Sopenharmony_ci if (seed != NULL && !EVP_MAC_update(ctx_Ai, seed, seed_len)) 308e1051a39Sopenharmony_ci goto err; 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci for (;;) { 311e1051a39Sopenharmony_ci /* calc: A(i) = HMAC_<hash>(secret, A(i-1)) */ 312e1051a39Sopenharmony_ci if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai))) 313e1051a39Sopenharmony_ci goto err; 314e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx_Ai); 315e1051a39Sopenharmony_ci ctx_Ai = NULL; 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ci /* calc next chunk: HMAC_<hash>(secret, A(i) + seed) */ 318e1051a39Sopenharmony_ci ctx = EVP_MAC_CTX_dup(ctx_init); 319e1051a39Sopenharmony_ci if (ctx == NULL) 320e1051a39Sopenharmony_ci goto err; 321e1051a39Sopenharmony_ci if (!EVP_MAC_update(ctx, Ai, Ai_len)) 322e1051a39Sopenharmony_ci goto err; 323e1051a39Sopenharmony_ci /* save state for calculating next A(i) value */ 324e1051a39Sopenharmony_ci if (olen > chunk) { 325e1051a39Sopenharmony_ci ctx_Ai = EVP_MAC_CTX_dup(ctx); 326e1051a39Sopenharmony_ci if (ctx_Ai == NULL) 327e1051a39Sopenharmony_ci goto err; 328e1051a39Sopenharmony_ci } 329e1051a39Sopenharmony_ci if (seed != NULL && !EVP_MAC_update(ctx, seed, seed_len)) 330e1051a39Sopenharmony_ci goto err; 331e1051a39Sopenharmony_ci if (olen <= chunk) { 332e1051a39Sopenharmony_ci /* last chunk - use Ai as temp bounce buffer */ 333e1051a39Sopenharmony_ci if (!EVP_MAC_final(ctx, Ai, &Ai_len, sizeof(Ai))) 334e1051a39Sopenharmony_ci goto err; 335e1051a39Sopenharmony_ci memcpy(out, Ai, olen); 336e1051a39Sopenharmony_ci break; 337e1051a39Sopenharmony_ci } 338e1051a39Sopenharmony_ci if (!EVP_MAC_final(ctx, out, NULL, olen)) 339e1051a39Sopenharmony_ci goto err; 340e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx); 341e1051a39Sopenharmony_ci ctx = NULL; 342e1051a39Sopenharmony_ci out += chunk; 343e1051a39Sopenharmony_ci olen -= chunk; 344e1051a39Sopenharmony_ci } 345e1051a39Sopenharmony_ci ret = 1; 346e1051a39Sopenharmony_ci err: 347e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx); 348e1051a39Sopenharmony_ci EVP_MAC_CTX_free(ctx_Ai); 349e1051a39Sopenharmony_ci OPENSSL_cleanse(Ai, sizeof(Ai)); 350e1051a39Sopenharmony_ci return ret; 351e1051a39Sopenharmony_ci} 352e1051a39Sopenharmony_ci 353e1051a39Sopenharmony_ci/* 354e1051a39Sopenharmony_ci * Refer to "The TLS Protocol Version 1.0" Section 5 355e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc2246#section-5) and 356e1051a39Sopenharmony_ci * "The Transport Layer Security (TLS) Protocol Version 1.2" Section 5 357e1051a39Sopenharmony_ci * (https://tools.ietf.org/html/rfc5246#section-5). 358e1051a39Sopenharmony_ci * 359e1051a39Sopenharmony_ci * For TLS v1.0 and TLS v1.1: 360e1051a39Sopenharmony_ci * 361e1051a39Sopenharmony_ci * PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR 362e1051a39Sopenharmony_ci * P_SHA-1(S2, label + seed) 363e1051a39Sopenharmony_ci * 364e1051a39Sopenharmony_ci * S1 is taken from the first half of the secret, S2 from the second half. 365e1051a39Sopenharmony_ci * 366e1051a39Sopenharmony_ci * L_S = length in bytes of secret; 367e1051a39Sopenharmony_ci * L_S1 = L_S2 = ceil(L_S / 2); 368e1051a39Sopenharmony_ci * 369e1051a39Sopenharmony_ci * For TLS v1.2: 370e1051a39Sopenharmony_ci * 371e1051a39Sopenharmony_ci * PRF(secret, label, seed) = P_<hash>(secret, label + seed) 372e1051a39Sopenharmony_ci */ 373e1051a39Sopenharmony_cistatic int tls1_prf_alg(EVP_MAC_CTX *mdctx, EVP_MAC_CTX *sha1ctx, 374e1051a39Sopenharmony_ci const unsigned char *sec, size_t slen, 375e1051a39Sopenharmony_ci const unsigned char *seed, size_t seed_len, 376e1051a39Sopenharmony_ci unsigned char *out, size_t olen) 377e1051a39Sopenharmony_ci{ 378e1051a39Sopenharmony_ci if (sha1ctx != NULL) { 379e1051a39Sopenharmony_ci /* TLS v1.0 and TLS v1.1 */ 380e1051a39Sopenharmony_ci size_t i; 381e1051a39Sopenharmony_ci unsigned char *tmp; 382e1051a39Sopenharmony_ci /* calc: L_S1 = L_S2 = ceil(L_S / 2) */ 383e1051a39Sopenharmony_ci size_t L_S1 = (slen + 1) / 2; 384e1051a39Sopenharmony_ci size_t L_S2 = L_S1; 385e1051a39Sopenharmony_ci 386e1051a39Sopenharmony_ci if (!tls1_prf_P_hash(mdctx, sec, L_S1, 387e1051a39Sopenharmony_ci seed, seed_len, out, olen)) 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci 390e1051a39Sopenharmony_ci if ((tmp = OPENSSL_malloc(olen)) == NULL) { 391e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 392e1051a39Sopenharmony_ci return 0; 393e1051a39Sopenharmony_ci } 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci if (!tls1_prf_P_hash(sha1ctx, sec + slen - L_S2, L_S2, 396e1051a39Sopenharmony_ci seed, seed_len, tmp, olen)) { 397e1051a39Sopenharmony_ci OPENSSL_clear_free(tmp, olen); 398e1051a39Sopenharmony_ci return 0; 399e1051a39Sopenharmony_ci } 400e1051a39Sopenharmony_ci for (i = 0; i < olen; i++) 401e1051a39Sopenharmony_ci out[i] ^= tmp[i]; 402e1051a39Sopenharmony_ci OPENSSL_clear_free(tmp, olen); 403e1051a39Sopenharmony_ci return 1; 404e1051a39Sopenharmony_ci } 405e1051a39Sopenharmony_ci 406e1051a39Sopenharmony_ci /* TLS v1.2 */ 407e1051a39Sopenharmony_ci if (!tls1_prf_P_hash(mdctx, sec, slen, seed, seed_len, out, olen)) 408e1051a39Sopenharmony_ci return 0; 409e1051a39Sopenharmony_ci 410e1051a39Sopenharmony_ci return 1; 411e1051a39Sopenharmony_ci} 412