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