]>
| Commit | Line | Data |
|---|---|---|
| d2e9e320 | 1 | /* |
| e6633241 | 2 | * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. |
| aacfb134 | 3 | * |
| 7bb803e8 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
| d2e9e320 RS |
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 | |
| aacfb134 AG |
8 | */ |
| 9 | ||
| dbde4726 P |
10 | /* |
| 11 | * HMAC low level APIs are deprecated for public use, but still ok for internal | |
| 12 | * use. | |
| 13 | */ | |
| 14 | #include "internal/deprecated.h" | |
| 15 | ||
| aacfb134 | 16 | #include <stdlib.h> |
| 5a285add | 17 | #include <stdarg.h> |
| aacfb134 AG |
18 | #include <string.h> |
| 19 | #include <openssl/hmac.h> | |
| aacfb134 | 20 | #include <openssl/evp.h> |
| 5a285add | 21 | #include <openssl/kdf.h> |
| e3405a4a | 22 | #include <openssl/core_names.h> |
| 2741128e | 23 | #include <openssl/proverr.h> |
| aacfb134 | 24 | #include "internal/cryptlib.h" |
| cee719c2 | 25 | #include "internal/numbers.h" |
| f7d998a2 | 26 | #include "internal/packet.h" |
| 25f2138b | 27 | #include "crypto/evp.h" |
| ddd21319 | 28 | #include "prov/provider_ctx.h" |
| 2b9e4e95 | 29 | #include "prov/providercommon.h" |
| af3e7e1b | 30 | #include "prov/implementations.h" |
| ddd21319 | 31 | #include "prov/provider_util.h" |
| 6d47e819 | 32 | #include "prov/securitycheck.h" |
| d5f9166b | 33 | #include "internal/e_os.h" |
| 345b42be | 34 | #include "internal/params.h" |
| 5b800192 | 35 | #include "internal/sizes.h" |
| aacfb134 | 36 | |
| 20c2876f | 37 | #define HKDF_MAXBUF 2048 |
| 2fab90bb BB |
38 | #define HKDF_MAXINFO (32 * 1024) |
| 39 | #define HKDF_MAX_INFOS 5 | |
| aacfb134 | 40 | |
| 363b1e5d | 41 | static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_new; |
| 95bd5ff6 | 42 | static OSSL_FUNC_kdf_dupctx_fn kdf_hkdf_dup; |
| 363b1e5d DMSP |
43 | static OSSL_FUNC_kdf_freectx_fn kdf_hkdf_free; |
| 44 | static OSSL_FUNC_kdf_reset_fn kdf_hkdf_reset; | |
| 45 | static OSSL_FUNC_kdf_derive_fn kdf_hkdf_derive; | |
| 46 | static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_settable_ctx_params; | |
| 47 | static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_set_ctx_params; | |
| dc294270 P |
48 | static OSSL_FUNC_kdf_gettable_ctx_params_fn hkdf_gettable_ctx_params; |
| 49 | static OSSL_FUNC_kdf_get_ctx_params_fn hkdf_common_get_ctx_params; | |
| f7d998a2 P |
50 | static OSSL_FUNC_kdf_derive_fn kdf_tls1_3_derive; |
| 51 | static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_tls1_3_settable_ctx_params; | |
| 52 | static OSSL_FUNC_kdf_set_ctx_params_fn kdf_tls1_3_set_ctx_params; | |
| d1a8d5a8 DVG |
53 | static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha256_new; |
| 54 | static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha384_new; | |
| 55 | static OSSL_FUNC_kdf_newctx_fn kdf_hkdf_sha512_new; | |
| df981828 P |
56 | static OSSL_FUNC_kdf_settable_ctx_params_fn kdf_hkdf_fixed_digest_settable_ctx_params; |
| 57 | static OSSL_FUNC_kdf_set_ctx_params_fn kdf_hkdf_fixed_digest_set_ctx_params; | |
| d1a8d5a8 DVG |
58 | |
| 59 | static void *kdf_hkdf_fixed_digest_new(void *provctx, const char *digest); | |
| c6a1d8ea | 60 | static void kdf_hkdf_reset_ex(void *vctx, int on_free); |
| e3405a4a | 61 | |
| 0a8a6afd | 62 | static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md, |
| 2fab90bb BB |
63 | const unsigned char *salt, size_t salt_len, |
| 64 | const unsigned char *key, size_t key_len, | |
| 65 | const unsigned char *info, size_t info_len, | |
| 66 | unsigned char *okm, size_t okm_len); | |
| 0a8a6afd | 67 | static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md, |
| 2fab90bb BB |
68 | const unsigned char *salt, size_t salt_len, |
| 69 | const unsigned char *ikm, size_t ikm_len, | |
| 70 | unsigned char *prk, size_t prk_len); | |
| 5a285add | 71 | static int HKDF_Expand(const EVP_MD *evp_md, |
| 2fab90bb BB |
72 | const unsigned char *prk, size_t prk_len, |
| 73 | const unsigned char *info, size_t info_len, | |
| 74 | unsigned char *okm, size_t okm_len); | |
| 5a285add | 75 | |
| e3405a4a P |
76 | typedef struct { |
| 77 | void *provctx; | |
| d2139cf8 | 78 | int mode; |
| 86f17ed6 | 79 | PROV_DIGEST digest; |
| aacfb134 AG |
80 | unsigned char *salt; |
| 81 | size_t salt_len; | |
| 82 | unsigned char *key; | |
| 83 | size_t key_len; | |
| f7d998a2 P |
84 | unsigned char *prefix; |
| 85 | size_t prefix_len; | |
| 86 | unsigned char *label; | |
| 87 | size_t label_len; | |
| 88 | unsigned char *data; | |
| 89 | size_t data_len; | |
| e8115bd1 | 90 | unsigned char *info; |
| aacfb134 | 91 | size_t info_len; |
| c6a1d8ea | 92 | int fixed_digest; |
| 6d47e819 | 93 | OSSL_FIPS_IND_DECLARE |
| e3405a4a | 94 | } KDF_HKDF; |
| aacfb134 | 95 | |
| e3405a4a | 96 | static void *kdf_hkdf_new(void *provctx) |
| aacfb134 | 97 | { |
| e3405a4a | 98 | KDF_HKDF *ctx; |
| aacfb134 | 99 | |
| 2b9e4e95 P |
100 | if (!ossl_prov_is_running()) |
| 101 | return NULL; | |
| 102 | ||
| 6d47e819 | 103 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL) { |
| e3405a4a | 104 | ctx->provctx = provctx; |
| 6d47e819 | 105 | OSSL_FIPS_IND_INIT(ctx) |
| 106 | } | |
| e3405a4a | 107 | return ctx; |
| 5a285add | 108 | } |
| aacfb134 | 109 | |
| e3405a4a | 110 | static void kdf_hkdf_free(void *vctx) |
| 5a285add | 111 | { |
| e3405a4a | 112 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
| aacfb134 | 113 | |
| 3c659415 | 114 | if (ctx != NULL) { |
| c6a1d8ea | 115 | kdf_hkdf_reset_ex(vctx, 1); |
| 3c659415 P |
116 | OPENSSL_free(ctx); |
| 117 | } | |
| aacfb134 AG |
118 | } |
| 119 | ||
| e3405a4a | 120 | static void kdf_hkdf_reset(void *vctx) |
| c6a1d8ea DVG |
121 | { |
| 122 | kdf_hkdf_reset_ex(vctx, 0); | |
| 123 | } | |
| 124 | ||
| 125 | static void kdf_hkdf_reset_ex(void *vctx, int on_free) | |
| aacfb134 | 126 | { |
| e3405a4a | 127 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
| 0577959c | 128 | void *provctx = ctx->provctx; |
| c6a1d8ea DVG |
129 | int preserve_digest = on_free ? 0 : ctx->fixed_digest; |
| 130 | PROV_DIGEST save_prov_digest = { 0 }; | |
| 131 | ||
| 132 | /* For fixed digests just save and restore the PROV_DIGEST object */ | |
| 133 | if (preserve_digest) | |
| 134 | save_prov_digest = ctx->digest; | |
| 135 | else | |
| 136 | ossl_prov_digest_reset(&ctx->digest); | |
| db1d8c90 | 137 | #ifdef OPENSSL_PEDANTIC_ZEROIZATION |
| fa338aa7 DJL |
138 | OPENSSL_clear_free(ctx->salt, ctx->salt_len); |
| 139 | #else | |
| e3405a4a | 140 | OPENSSL_free(ctx->salt); |
| fa338aa7 | 141 | #endif |
| f7d998a2 P |
142 | OPENSSL_free(ctx->prefix); |
| 143 | OPENSSL_free(ctx->label); | |
| 144 | OPENSSL_clear_free(ctx->data, ctx->data_len); | |
| e3405a4a | 145 | OPENSSL_clear_free(ctx->key, ctx->key_len); |
| e8115bd1 | 146 | OPENSSL_clear_free(ctx->info, ctx->info_len); |
| e3405a4a | 147 | memset(ctx, 0, sizeof(*ctx)); |
| 0577959c | 148 | ctx->provctx = provctx; |
| c6a1d8ea DVG |
149 | if (preserve_digest) { |
| 150 | ctx->fixed_digest = preserve_digest; | |
| 151 | ctx->digest = save_prov_digest; | |
| 152 | } | |
| aacfb134 AG |
153 | } |
| 154 | ||
| 95bd5ff6 P |
155 | static void *kdf_hkdf_dup(void *vctx) |
| 156 | { | |
| 157 | const KDF_HKDF *src = (const KDF_HKDF *)vctx; | |
| 158 | KDF_HKDF *dest; | |
| 159 | ||
| 160 | dest = kdf_hkdf_new(src->provctx); | |
| 161 | if (dest != NULL) { | |
| 162 | if (!ossl_prov_memdup(src->salt, src->salt_len, &dest->salt, | |
| 2fab90bb BB |
163 | &dest->salt_len) |
| 164 | || !ossl_prov_memdup(src->key, src->key_len, | |
| 165 | &dest->key, &dest->key_len) | |
| 166 | || !ossl_prov_memdup(src->prefix, src->prefix_len, | |
| 167 | &dest->prefix, &dest->prefix_len) | |
| 168 | || !ossl_prov_memdup(src->label, src->label_len, | |
| 169 | &dest->label, &dest->label_len) | |
| 170 | || !ossl_prov_memdup(src->data, src->data_len, | |
| 171 | &dest->data, &dest->data_len) | |
| 172 | || !ossl_prov_memdup(src->info, src->info_len, | |
| 173 | &dest->info, &dest->info_len) | |
| 174 | || !ossl_prov_digest_copy(&dest->digest, &src->digest)) | |
| 95bd5ff6 | 175 | goto err; |
| 95bd5ff6 | 176 | dest->mode = src->mode; |
| c6a1d8ea | 177 | dest->fixed_digest = src->fixed_digest; |
| 6d47e819 | 178 | OSSL_FIPS_IND_COPY(dest, src) |
| 95bd5ff6 P |
179 | } |
| 180 | return dest; | |
| 181 | ||
| 2fab90bb | 182 | err: |
| 95bd5ff6 P |
183 | kdf_hkdf_free(dest); |
| 184 | return NULL; | |
| 185 | } | |
| 186 | ||
| e3405a4a | 187 | static size_t kdf_hkdf_size(KDF_HKDF *ctx) |
| ca55d70b | 188 | { |
| 97cc9c9b | 189 | int sz; |
| 86f17ed6 | 190 | const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); |
| 97cc9c9b | 191 | |
| e3405a4a | 192 | if (ctx->mode != EVP_KDF_HKDF_MODE_EXTRACT_ONLY) |
| 5a285add | 193 | return SIZE_MAX; |
| ca55d70b | 194 | |
| 86f17ed6 | 195 | if (md == NULL) { |
| e3405a4a | 196 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); |
| 5a285add DM |
197 | return 0; |
| 198 | } | |
| ed576acd | 199 | sz = EVP_MD_get_size(md); |
| 14c45338 | 200 | if (sz <= 0) |
| 97cc9c9b SL |
201 | return 0; |
| 202 | ||
| 203 | return sz; | |
| ca55d70b MC |
204 | } |
| 205 | ||
| 1b838621 | 206 | #ifdef FIPS_MODULE |
| 207 | static int fips_hkdf_key_check_passed(KDF_HKDF *ctx) | |
| 208 | { | |
| 209 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); | |
| 210 | int key_approved = ossl_kdf_check_key_size(ctx->key_len); | |
| 211 | ||
| 212 | if (!key_approved) { | |
| 213 | if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, | |
| 2fab90bb BB |
214 | libctx, "HKDF", "Key size", |
| 215 | ossl_fips_config_hkdf_key_check)) { | |
| 1b838621 | 216 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); |
| 217 | return 0; | |
| 218 | } | |
| 219 | } | |
| 220 | return 1; | |
| 221 | } | |
| 222 | #endif | |
| 223 | ||
| 3469b388 | 224 | static int kdf_hkdf_derive(void *vctx, unsigned char *key, size_t keylen, |
| 2fab90bb | 225 | const OSSL_PARAM params[]) |
| aacfb134 | 226 | { |
| e3405a4a | 227 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
| 0a8a6afd | 228 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); |
| 2b9e4e95 P |
229 | const EVP_MD *md; |
| 230 | ||
| 3469b388 | 231 | if (!ossl_prov_is_running() || !kdf_hkdf_set_ctx_params(ctx, params)) |
| 2b9e4e95 | 232 | return 0; |
| e3405a4a | 233 | |
| 2b9e4e95 | 234 | md = ossl_prov_digest_md(&ctx->digest); |
| 86f17ed6 | 235 | if (md == NULL) { |
| e3405a4a | 236 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); |
| f55129c7 JB |
237 | return 0; |
| 238 | } | |
| e3405a4a P |
239 | if (ctx->key == NULL) { |
| 240 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); | |
| aacfb134 | 241 | return 0; |
| e65f6509 | 242 | } |
| 1cae59d1 JS |
243 | if (keylen == 0) { |
| 244 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); | |
| 245 | return 0; | |
| 246 | } | |
| aacfb134 | 247 | |
| e3405a4a | 248 | switch (ctx->mode) { |
| 5a285add | 249 | case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: |
| 9d300aa2 | 250 | default: |
| 0a8a6afd | 251 | return HKDF(libctx, md, ctx->salt, ctx->salt_len, |
| 2fab90bb | 252 | ctx->key, ctx->key_len, ctx->info, ctx->info_len, key, keylen); |
| d2139cf8 | 253 | |
| 5a285add | 254 | case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: |
| 0a8a6afd | 255 | return HKDF_Extract(libctx, md, ctx->salt, ctx->salt_len, |
| 2fab90bb | 256 | ctx->key, ctx->key_len, key, keylen); |
| d2139cf8 | 257 | |
| 5a285add | 258 | case EVP_KDF_HKDF_MODE_EXPAND_ONLY: |
| 86f17ed6 | 259 | return HKDF_Expand(md, ctx->key, ctx->key_len, ctx->info, |
| 2fab90bb | 260 | ctx->info_len, key, keylen); |
| aacfb134 | 261 | } |
| aacfb134 AG |
262 | } |
| 263 | ||
| dc294270 P |
264 | struct hkdf_all_set_ctx_params_st { |
| 265 | OSSL_PARAM *mode; | |
| 266 | OSSL_PARAM *propq; | |
| dc294270 P |
267 | OSSL_PARAM *digest; |
| 268 | OSSL_PARAM *key; | |
| 269 | OSSL_PARAM *salt; | |
| 004077be | 270 | #ifdef FIPS_MODULE |
| dc294270 P |
271 | OSSL_PARAM *ind_k; |
| 272 | OSSL_PARAM *ind_d; | |
| 004077be | 273 | #endif |
| dc294270 P |
274 | OSSL_PARAM *prefix; |
| 275 | OSSL_PARAM *label; | |
| 276 | OSSL_PARAM *data; | |
| df981828 | 277 | OSSL_PARAM *info[HKDF_MAX_INFOS]; |
| dc294270 P |
278 | int num_info; |
| 279 | }; | |
| 280 | ||
| 971e589a SS |
281 | #define hkdf_set_ctx_params_st hkdf_all_set_ctx_params_st |
| 282 | #define hkdf_fixed_digest_set_ctx_params_st hkdf_all_set_ctx_params_st | |
| 283 | #define kdf_tls1_3_set_ctx_params_st hkdf_all_set_ctx_params_st | |
| 284 | ||
| 285 | #include "providers/implementations/kdfs/hkdf.inc" | |
| 286 | ||
| 2fab90bb | 287 | static int hkdf_common_set_ctx_params(KDF_HKDF *ctx, struct hkdf_all_set_ctx_params_st *p) |
| e3405a4a | 288 | { |
| 0a8a6afd | 289 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); |
| e3405a4a | 290 | int n; |
| 86f17ed6 | 291 | |
| dc294270 | 292 | if (p->digest != NULL) { |
| 14e46600 | 293 | const EVP_MD *md = NULL; |
| 294 | ||
| 8c7e974b | 295 | if (!ossl_prov_digest_load(&ctx->digest, p->digest, p->propq, libctx)) |
| 14e46600 | 296 | return 0; |
| 297 | ||
| 298 | md = ossl_prov_digest_md(&ctx->digest); | |
| 14c45338 | 299 | if (EVP_MD_xof(md)) { |
| 14e46600 | 300 | ERR_raise(ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED); |
| 301 | return 0; | |
| 302 | } | |
| 303 | } | |
| e3405a4a | 304 | |
| dc294270 P |
305 | if (p->mode != NULL) { |
| 306 | if (p->mode->data_type == OSSL_PARAM_UTF8_STRING) { | |
| 307 | if (OPENSSL_strcasecmp(p->mode->data, "EXTRACT_AND_EXPAND") == 0) { | |
| e3405a4a | 308 | ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND; |
| dc294270 | 309 | } else if (OPENSSL_strcasecmp(p->mode->data, "EXTRACT_ONLY") == 0) { |
| e3405a4a | 310 | ctx->mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY; |
| dc294270 | 311 | } else if (OPENSSL_strcasecmp(p->mode->data, "EXPAND_ONLY") == 0) { |
| e3405a4a P |
312 | ctx->mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY; |
| 313 | } else { | |
| 314 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
| 315 | return 0; | |
| 316 | } | |
| dc294270 | 317 | } else if (OSSL_PARAM_get_int(p->mode, &n)) { |
| e3405a4a P |
318 | if (n != EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND |
| 319 | && n != EVP_KDF_HKDF_MODE_EXTRACT_ONLY | |
| 320 | && n != EVP_KDF_HKDF_MODE_EXPAND_ONLY) { | |
| 321 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
| 322 | return 0; | |
| 323 | } | |
| 324 | ctx->mode = n; | |
| 325 | } else { | |
| 326 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
| 327 | return 0; | |
| 328 | } | |
| 329 | } | |
| 330 | ||
| dc294270 | 331 | if (p->key != NULL) { |
| e3405a4a P |
332 | OPENSSL_clear_free(ctx->key, ctx->key_len); |
| 333 | ctx->key = NULL; | |
| dc294270 | 334 | if (!OSSL_PARAM_get_octet_string(p->key, (void **)&ctx->key, 0, |
| 2fab90bb | 335 | &ctx->key_len)) |
| e3405a4a P |
336 | return 0; |
| 337 | } | |
| 338 | ||
| dc294270 | 339 | if (p->salt != NULL) { |
| 12eb6c58 P |
340 | OPENSSL_free(ctx->salt); |
| 341 | ctx->salt = NULL; | |
| dc294270 | 342 | if (!OSSL_PARAM_get_octet_string(p->salt, (void **)&ctx->salt, 0, |
| 2fab90bb | 343 | &ctx->salt_len)) |
| 12eb6c58 | 344 | return 0; |
| e3405a4a | 345 | } |
| f7d998a2 | 346 | |
| df981828 P |
347 | /* Only relevant for HKDF not to the TLS 1.3 KDF */ |
| 348 | if (ossl_param_get1_concat_octet_string(p->num_info, p->info, | |
| 2fab90bb BB |
349 | &ctx->info, &ctx->info_len) |
| 350 | == 0) | |
| df981828 P |
351 | return 0; |
| 352 | ||
| f7d998a2 P |
353 | return 1; |
| 354 | } | |
| 355 | ||
| 356 | static int kdf_hkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | |
| 357 | { | |
| dc294270 | 358 | struct hkdf_all_set_ctx_params_st p; |
| f7d998a2 P |
359 | KDF_HKDF *ctx = vctx; |
| 360 | ||
| dc294270 P |
361 | if (ctx == NULL || !hkdf_set_ctx_params_decoder(params, &p)) |
| 362 | return 0; | |
| f7d998a2 | 363 | |
| df981828 | 364 | if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_k)) |
| 1b838621 | 365 | return 0; |
| 366 | ||
| dc294270 | 367 | if (!hkdf_common_set_ctx_params(ctx, &p)) |
| f7d998a2 P |
368 | return 0; |
| 369 | ||
| 81bb8848 | 370 | #ifdef FIPS_MODULE |
| dc294270 | 371 | if (p.key != NULL) |
| 81bb8848 | 372 | if (!fips_hkdf_key_check_passed(ctx)) |
| 373 | return 0; | |
| 374 | #endif | |
| 375 | ||
| e3405a4a P |
376 | return 1; |
| 377 | } | |
| 378 | ||
| 1e8e5c60 | 379 | static const OSSL_PARAM *kdf_hkdf_settable_ctx_params(ossl_unused void *ctx, |
| 2fab90bb | 380 | ossl_unused void *provctx) |
| e3405a4a | 381 | { |
| dc294270 P |
382 | return hkdf_set_ctx_params_list; |
| 383 | } | |
| 384 | ||
| dc294270 | 385 | static const OSSL_PARAM *hkdf_gettable_ctx_params(ossl_unused void *ctx, |
| 2fab90bb | 386 | ossl_unused void *provctx) |
| dc294270 P |
387 | { |
| 388 | return hkdf_get_ctx_params_list; | |
| e3405a4a P |
389 | } |
| 390 | ||
| dc294270 | 391 | static int hkdf_common_get_ctx_params(void *vctx, OSSL_PARAM params[]) |
| e3405a4a | 392 | { |
| dc294270 P |
393 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; |
| 394 | struct hkdf_get_ctx_params_st p; | |
| e3405a4a | 395 | |
| dc294270 P |
396 | if (ctx == NULL || !hkdf_get_ctx_params_decoder(params, &p)) |
| 397 | return 0; | |
| 14e46600 | 398 | |
| dc294270 | 399 | if (p.size != NULL) { |
| 9d300aa2 SL |
400 | size_t sz = kdf_hkdf_size(ctx); |
| 401 | ||
| 402 | if (sz == 0) | |
| 403 | return 0; | |
| dc294270 | 404 | if (!OSSL_PARAM_set_size_t(p.size, sz)) |
| 6d47e819 | 405 | return 0; |
| 9d300aa2 | 406 | } |
| 14e46600 | 407 | |
| dc294270 | 408 | if (p.digest != NULL) { |
| 5b800192 DVG |
409 | const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); |
| 410 | ||
| 411 | if (md == NULL) | |
| 412 | return 0; | |
| dc294270 | 413 | else if (!OSSL_PARAM_set_utf8_string(p.digest, EVP_MD_get0_name(md))) |
| 5b800192 DVG |
414 | return 0; |
| 415 | } | |
| 416 | ||
| 417 | /* OSSL_KDF_PARAM_MODE has multiple parameter types, so look for all instances */ | |
| dc294270 P |
418 | if (p.mode != NULL) { |
| 419 | if (p.mode->data_type == OSSL_PARAM_UTF8_STRING) { | |
| 5b800192 DVG |
420 | switch (ctx->mode) { |
| 421 | case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND: | |
| dc294270 | 422 | if (!OSSL_PARAM_set_utf8_string(p.mode, "EXTRACT_AND_EXPAND")) |
| 5b800192 DVG |
423 | return 0; |
| 424 | break; | |
| 425 | case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: | |
| dc294270 | 426 | if (!OSSL_PARAM_set_utf8_string(p.mode, "EXTRACT_ONLY")) |
| 5b800192 DVG |
427 | return 0; |
| 428 | break; | |
| 429 | case EVP_KDF_HKDF_MODE_EXPAND_ONLY: | |
| dc294270 | 430 | if (!OSSL_PARAM_set_utf8_string(p.mode, "EXPAND_ONLY")) |
| 5b800192 DVG |
431 | return 0; |
| 432 | break; | |
| 433 | default: | |
| 434 | return 0; | |
| 435 | } | |
| c33bce64 | 436 | } else { |
| dc294270 | 437 | if (!OSSL_PARAM_set_int(p.mode, ctx->mode)) |
| 5b800192 DVG |
438 | return 0; |
| 439 | } | |
| 5b800192 DVG |
440 | } |
| 441 | ||
| dc294270 | 442 | if (p.salt != NULL) { |
| 5b800192 | 443 | if (ctx->salt == NULL || ctx->salt_len == 0) |
| dc294270 P |
444 | p.salt->return_size = 0; |
| 445 | else if (!OSSL_PARAM_set_octet_string(p.salt, ctx->salt, ctx->salt_len)) | |
| 5b800192 DVG |
446 | return 0; |
| 447 | } | |
| 448 | ||
| dc294270 | 449 | if (p.info != NULL) { |
| 6d47e819 | 450 | if (ctx->info == NULL || ctx->info_len == 0) |
| dc294270 P |
451 | p.info->return_size = 0; |
| 452 | else if (!OSSL_PARAM_set_octet_string(p.info, ctx->info, ctx->info_len)) | |
| 6d47e819 | 453 | return 0; |
| 6b566687 | 454 | } |
| 14e46600 | 455 | |
| dc294270 | 456 | if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(ctx, p.ind)) |
| 1b838621 | 457 | return 0; |
| 458 | ||
| 6d47e819 | 459 | return 1; |
| e3405a4a P |
460 | } |
| 461 | ||
| 1be63951 | 462 | const OSSL_DISPATCH ossl_kdf_hkdf_functions[] = { |
| 2fab90bb BB |
463 | { OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_hkdf_new }, |
| 464 | { OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_hkdf_dup }, | |
| 465 | { OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_hkdf_free }, | |
| 466 | { OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_hkdf_reset }, | |
| 467 | { OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_hkdf_derive }, | |
| e3405a4a | 468 | { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, |
| 2fab90bb BB |
469 | (void (*)(void))kdf_hkdf_settable_ctx_params }, |
| 470 | { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_hkdf_set_ctx_params }, | |
| e3405a4a | 471 | { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, |
| 2fab90bb BB |
472 | (void (*)(void))hkdf_gettable_ctx_params }, |
| 473 | { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))hkdf_common_get_ctx_params }, | |
| 1e6bd31e | 474 | OSSL_DISPATCH_END |
| aacfb134 AG |
475 | }; |
| 476 | ||
| d1a8d5a8 DVG |
477 | static void *kdf_hkdf_fixed_digest_new(void *provctx, const char *digest) |
| 478 | { | |
| 479 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); | |
| 480 | KDF_HKDF *ctx; | |
| ce3714c4 | 481 | OSSL_PARAM param; |
| d1a8d5a8 DVG |
482 | |
| 483 | ctx = kdf_hkdf_new(provctx); | |
| 484 | if (ctx == NULL) | |
| 485 | return NULL; | |
| 486 | ||
| ce3714c4 | 487 | param = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_DIGEST, |
| 2fab90bb | 488 | (char *)digest, 0); |
| 8c7e974b | 489 | if (!ossl_prov_digest_load(&ctx->digest, ¶m, NULL, libctx)) { |
| d1a8d5a8 DVG |
490 | kdf_hkdf_free(ctx); |
| 491 | return NULL; | |
| 492 | } | |
| 493 | ||
| c6a1d8ea DVG |
494 | /* Now the digest can no longer be changed */ |
| 495 | ctx->fixed_digest = 1; | |
| 496 | ||
| d1a8d5a8 DVG |
497 | return ctx; |
| 498 | } | |
| 499 | ||
| df981828 P |
500 | static int kdf_hkdf_fixed_digest_set_ctx_params(void *vctx, const OSSL_PARAM params[]) |
| 501 | { | |
| 502 | struct hkdf_all_set_ctx_params_st p; | |
| 503 | KDF_HKDF *ctx = vctx; | |
| 504 | ||
| 505 | if (ctx == NULL || !hkdf_fixed_digest_set_ctx_params_decoder(params, &p)) | |
| 506 | return 0; | |
| 507 | ||
| df981828 P |
508 | if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_k)) |
| 509 | return 0; | |
| 510 | ||
| 511 | if (!hkdf_common_set_ctx_params(ctx, &p)) | |
| 512 | return 0; | |
| 513 | ||
| 514 | #ifdef FIPS_MODULE | |
| 515 | if (p.key != NULL) | |
| 516 | if (!fips_hkdf_key_check_passed(ctx)) | |
| 517 | return 0; | |
| 518 | #endif | |
| 519 | ||
| 520 | return 1; | |
| 521 | } | |
| 522 | ||
| 2fab90bb | 523 | static const OSSL_PARAM *kdf_hkdf_fixed_digest_settable_ctx_params(ossl_unused void *ctx, ossl_unused void *provctx) |
| df981828 P |
524 | { |
| 525 | return hkdf_fixed_digest_set_ctx_params_list; | |
| 526 | } | |
| 527 | ||
| 2fab90bb BB |
528 | #define KDF_HKDF_FIXED_DIGEST_NEW(hashname, hashstring) \ |
| 529 | static void *kdf_hkdf_##hashname##_new(void *provctx) \ | |
| 530 | { \ | |
| d1a8d5a8 DVG |
531 | return kdf_hkdf_fixed_digest_new(provctx, hashstring); \ |
| 532 | } | |
| 533 | ||
| 534 | KDF_HKDF_FIXED_DIGEST_NEW(sha256, "SHA256") | |
| 535 | KDF_HKDF_FIXED_DIGEST_NEW(sha384, "SHA384") | |
| 536 | KDF_HKDF_FIXED_DIGEST_NEW(sha512, "SHA512") | |
| 537 | ||
| 2fab90bb BB |
538 | #define MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(hashname) \ |
| 539 | const OSSL_DISPATCH ossl_kdf_hkdf_##hashname##_functions[] = { \ | |
| 540 | { OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_hkdf_##hashname##_new }, \ | |
| 541 | { OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_hkdf_dup }, \ | |
| 542 | { OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_hkdf_free }, \ | |
| 543 | { OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_hkdf_reset }, \ | |
| 544 | { OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_hkdf_derive }, \ | |
| 545 | { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, (void (*)(void))kdf_hkdf_fixed_digest_settable_ctx_params }, \ | |
| 546 | { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_hkdf_fixed_digest_set_ctx_params }, \ | |
| 547 | { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, (void (*)(void))hkdf_gettable_ctx_params }, \ | |
| 548 | { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))hkdf_common_get_ctx_params }, \ | |
| 549 | OSSL_DISPATCH_END \ | |
| d1a8d5a8 DVG |
550 | }; |
| 551 | ||
| 552 | MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha256) | |
| 553 | MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha384) | |
| 554 | MAKE_KDF_HKDF_FIXED_DIGEST_FUNCTIONS(sha512) | |
| 555 | ||
| e7018588 DM |
556 | /* |
| 557 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
| 558 | * Section 2 (https://tools.ietf.org/html/rfc5869#section-2) and | |
| 559 | * "Cryptographic Extraction and Key Derivation: The HKDF Scheme" | |
| 560 | * Section 4.2 (https://eprint.iacr.org/2010/264.pdf). | |
| 561 | * | |
| 562 | * From the paper: | |
| 563 | * The scheme HKDF is specified as: | |
| 564 | * HKDF(XTS, SKM, CTXinfo, L) = K(1) | K(2) | ... | K(t) | |
| 565 | * | |
| 566 | * where: | |
| 567 | * SKM is source key material | |
| 568 | * XTS is extractor salt (which may be null or constant) | |
| 569 | * CTXinfo is context information (may be null) | |
| 570 | * L is the number of key bits to be produced by KDF | |
| 571 | * k is the output length in bits of the hash function used with HMAC | |
| 572 | * t = ceil(L/k) | |
| 573 | * the value K(t) is truncated to its first d = L mod k bits. | |
| 574 | * | |
| 575 | * From RFC 5869: | |
| 576 | * 2.2. Step 1: Extract | |
| 577 | * HKDF-Extract(salt, IKM) -> PRK | |
| 578 | * 2.3. Step 2: Expand | |
| 579 | * HKDF-Expand(PRK, info, L) -> OKM | |
| 580 | */ | |
| 0a8a6afd | 581 | static int HKDF(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md, |
| 2fab90bb BB |
582 | const unsigned char *salt, size_t salt_len, |
| 583 | const unsigned char *ikm, size_t ikm_len, | |
| 584 | const unsigned char *info, size_t info_len, | |
| 585 | unsigned char *okm, size_t okm_len) | |
| aacfb134 AG |
586 | { |
| 587 | unsigned char prk[EVP_MAX_MD_SIZE]; | |
| 97cc9c9b SL |
588 | int ret, sz; |
| 589 | size_t prk_len; | |
| 590 | ||
| ed576acd | 591 | sz = EVP_MD_get_size(evp_md); |
| 14c45338 | 592 | if (sz <= 0) |
| 97cc9c9b SL |
593 | return 0; |
| 594 | prk_len = (size_t)sz; | |
| aacfb134 | 595 | |
| e7018588 | 596 | /* Step 1: HKDF-Extract(salt, IKM) -> PRK */ |
| 0a8a6afd | 597 | if (!HKDF_Extract(libctx, evp_md, |
| 2fab90bb | 598 | salt, salt_len, ikm, ikm_len, prk, prk_len)) |
| 5a285add | 599 | return 0; |
| aacfb134 | 600 | |
| e7018588 | 601 | /* Step 2: HKDF-Expand(PRK, info, L) -> OKM */ |
| d2139cf8 MC |
602 | ret = HKDF_Expand(evp_md, prk, prk_len, info, info_len, okm, okm_len); |
| 603 | OPENSSL_cleanse(prk, sizeof(prk)); | |
| 604 | ||
| 605 | return ret; | |
| aacfb134 AG |
606 | } |
| 607 | ||
| e7018588 DM |
608 | /* |
| 609 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
| 610 | * Section 2.2 (https://tools.ietf.org/html/rfc5869#section-2.2). | |
| 611 | * | |
| 612 | * 2.2. Step 1: Extract | |
| 613 | * | |
| 614 | * HKDF-Extract(salt, IKM) -> PRK | |
| 615 | * | |
| 616 | * Options: | |
| 617 | * Hash a hash function; HashLen denotes the length of the | |
| 618 | * hash function output in octets | |
| 619 | * | |
| 620 | * Inputs: | |
| 621 | * salt optional salt value (a non-secret random value); | |
| 622 | * if not provided, it is set to a string of HashLen zeros. | |
| 623 | * IKM input keying material | |
| 624 | * | |
| 625 | * Output: | |
| 626 | * PRK a pseudorandom key (of HashLen octets) | |
| 627 | * | |
| 628 | * The output PRK is calculated as follows: | |
| 629 | * | |
| 630 | * PRK = HMAC-Hash(salt, IKM) | |
| 631 | */ | |
| 0a8a6afd | 632 | static int HKDF_Extract(OSSL_LIB_CTX *libctx, const EVP_MD *evp_md, |
| 2fab90bb BB |
633 | const unsigned char *salt, size_t salt_len, |
| 634 | const unsigned char *ikm, size_t ikm_len, | |
| 635 | unsigned char *prk, size_t prk_len) | |
| aacfb134 | 636 | { |
| ed576acd | 637 | int sz = EVP_MD_get_size(evp_md); |
| 97cc9c9b | 638 | |
| 14c45338 | 639 | if (sz <= 0) |
| 97cc9c9b SL |
640 | return 0; |
| 641 | if (prk_len != (size_t)sz) { | |
| e3405a4a | 642 | ERR_raise(ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE); |
| 5a285add DM |
643 | return 0; |
| 644 | } | |
| e7018588 | 645 | /* calc: PRK = HMAC-Hash(salt, IKM) */ |
| 2fab90bb BB |
646 | return EVP_Q_mac(libctx, "HMAC", NULL, EVP_MD_get0_name(evp_md), NULL, salt, |
| 647 | salt_len, ikm, ikm_len, prk, EVP_MD_get_size(evp_md), NULL) | |
| ea396c70 | 648 | != NULL; |
| aacfb134 AG |
649 | } |
| 650 | ||
| e7018588 DM |
651 | /* |
| 652 | * Refer to "HMAC-based Extract-and-Expand Key Derivation Function (HKDF)" | |
| 653 | * Section 2.3 (https://tools.ietf.org/html/rfc5869#section-2.3). | |
| 654 | * | |
| 655 | * 2.3. Step 2: Expand | |
| 656 | * | |
| 657 | * HKDF-Expand(PRK, info, L) -> OKM | |
| 658 | * | |
| 659 | * Options: | |
| 660 | * Hash a hash function; HashLen denotes the length of the | |
| 661 | * hash function output in octets | |
| 662 | * | |
| 663 | * Inputs: | |
| 664 | * PRK a pseudorandom key of at least HashLen octets | |
| 665 | * (usually, the output from the extract step) | |
| 666 | * info optional context and application specific information | |
| 667 | * (can be a zero-length string) | |
| 668 | * L length of output keying material in octets | |
| 669 | * (<= 255*HashLen) | |
| 670 | * | |
| 671 | * Output: | |
| 672 | * OKM output keying material (of L octets) | |
| 673 | * | |
| 674 | * The output OKM is calculated as follows: | |
| 675 | * | |
| 676 | * N = ceil(L/HashLen) | |
| 677 | * T = T(1) | T(2) | T(3) | ... | T(N) | |
| 678 | * OKM = first L octets of T | |
| 679 | * | |
| 680 | * where: | |
| 681 | * T(0) = empty string (zero length) | |
| 682 | * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01) | |
| 683 | * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02) | |
| 684 | * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03) | |
| 685 | * ... | |
| 686 | * | |
| 687 | * (where the constant concatenated to the end of each T(n) is a | |
| 688 | * single octet.) | |
| 689 | */ | |
| 5a285add | 690 | static int HKDF_Expand(const EVP_MD *evp_md, |
| 2fab90bb BB |
691 | const unsigned char *prk, size_t prk_len, |
| 692 | const unsigned char *info, size_t info_len, | |
| 693 | unsigned char *okm, size_t okm_len) | |
| aacfb134 AG |
694 | { |
| 695 | HMAC_CTX *hmac; | |
| 97cc9c9b | 696 | int ret = 0, sz; |
| aacfb134 | 697 | unsigned int i; |
| aacfb134 | 698 | unsigned char prev[EVP_MAX_MD_SIZE]; |
| 97cc9c9b SL |
699 | size_t done_len = 0, dig_len, n; |
| 700 | ||
| ed576acd | 701 | sz = EVP_MD_get_size(evp_md); |
| 97cc9c9b SL |
702 | if (sz <= 0) |
| 703 | return 0; | |
| 704 | dig_len = (size_t)sz; | |
| 5a285add | 705 | |
| e7018588 DM |
706 | /* calc: N = ceil(L/HashLen) */ |
| 707 | n = okm_len / dig_len; | |
| aacfb134 AG |
708 | if (okm_len % dig_len) |
| 709 | n++; | |
| 710 | ||
| d2139cf8 | 711 | if (n > 255 || okm == NULL) |
| 5a285add | 712 | return 0; |
| aacfb134 AG |
713 | |
| 714 | if ((hmac = HMAC_CTX_new()) == NULL) | |
| 5a285add | 715 | return 0; |
| aacfb134 | 716 | |
| 6f9683d6 | 717 | if (!HMAC_Init_ex(hmac, prk, (int)prk_len, evp_md, NULL)) |
| aacfb134 AG |
718 | goto err; |
| 719 | ||
| 720 | for (i = 1; i <= n; i++) { | |
| 721 | size_t copy_len; | |
| 722 | const unsigned char ctr = i; | |
| 723 | ||
| e7018588 | 724 | /* calc: T(i) = HMAC-Hash(PRK, T(i - 1) | info | i) */ |
| aacfb134 AG |
725 | if (i > 1) { |
| 726 | if (!HMAC_Init_ex(hmac, NULL, 0, NULL, NULL)) | |
| 727 | goto err; | |
| 728 | ||
| 729 | if (!HMAC_Update(hmac, prev, dig_len)) | |
| 730 | goto err; | |
| 731 | } | |
| 732 | ||
| 733 | if (!HMAC_Update(hmac, info, info_len)) | |
| 734 | goto err; | |
| 735 | ||
| 736 | if (!HMAC_Update(hmac, &ctr, 1)) | |
| 737 | goto err; | |
| 738 | ||
| 739 | if (!HMAC_Final(hmac, prev, NULL)) | |
| 740 | goto err; | |
| 741 | ||
| 2fab90bb | 742 | copy_len = (dig_len > okm_len - done_len) ? okm_len - done_len : dig_len; |
| aacfb134 AG |
743 | |
| 744 | memcpy(okm + done_len, prev, copy_len); | |
| 745 | ||
| 746 | done_len += copy_len; | |
| 747 | } | |
| 5a285add | 748 | ret = 1; |
| aacfb134 | 749 | |
| 2fab90bb | 750 | err: |
| 64ed55ab | 751 | OPENSSL_cleanse(prev, sizeof(prev)); |
| aacfb134 | 752 | HMAC_CTX_free(hmac); |
| 64ed55ab | 753 | return ret; |
| aacfb134 | 754 | } |
| f7d998a2 P |
755 | |
| 756 | /* | |
| 757 | * TLS uses slight variations of the above and for FIPS validation purposes, | |
| 758 | * they need to be present here. | |
| 759 | * Refer to RFC 8446 section 7 for specific details. | |
| 760 | */ | |
| 761 | ||
| 762 | /* | |
| 763 | * Given a |secret|; a |label| of length |labellen|; and |data| of length | |
| 764 | * |datalen| (e.g. typically a hash of the handshake messages), derive a new | |
| 765 | * secret |outlen| bytes long and store it in the location pointed to be |out|. | |
| 766 | * The |data| value may be zero length. Returns 1 on success and 0 on failure. | |
| 767 | */ | |
| 768 | static int prov_tls13_hkdf_expand(const EVP_MD *md, | |
| 2fab90bb BB |
769 | const unsigned char *key, size_t keylen, |
| 770 | const unsigned char *prefix, size_t prefixlen, | |
| 771 | const unsigned char *label, size_t labellen, | |
| 772 | const unsigned char *data, size_t datalen, | |
| 773 | unsigned char *out, size_t outlen) | |
| f7d998a2 P |
774 | { |
| 775 | size_t hkdflabellen; | |
| 776 | unsigned char hkdflabel[HKDF_MAXBUF]; | |
| 777 | WPACKET pkt; | |
| 778 | ||
| 779 | /* | |
| 780 | * 2 bytes for length of derived secret + 1 byte for length of combined | |
| 781 | * prefix and label + bytes for the label itself + 1 byte length of hash | |
| 782 | * + bytes for the hash itself. We've got the maximum the KDF can handle | |
| 783 | * which should always be sufficient. | |
| 784 | */ | |
| 785 | if (!WPACKET_init_static_len(&pkt, hkdflabel, sizeof(hkdflabel), 0) | |
| 2fab90bb BB |
786 | || !WPACKET_put_bytes_u16(&pkt, outlen) |
| 787 | || !WPACKET_start_sub_packet_u8(&pkt) | |
| 788 | || !WPACKET_memcpy(&pkt, prefix, prefixlen) | |
| 789 | || !WPACKET_memcpy(&pkt, label, labellen) | |
| 790 | || !WPACKET_close(&pkt) | |
| 791 | || !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen) | |
| 792 | || !WPACKET_get_total_written(&pkt, &hkdflabellen) | |
| 793 | || !WPACKET_finish(&pkt)) { | |
| f7d998a2 P |
794 | WPACKET_cleanup(&pkt); |
| 795 | return 0; | |
| 796 | } | |
| 797 | ||
| 798 | return HKDF_Expand(md, key, keylen, hkdflabel, hkdflabellen, | |
| 2fab90bb | 799 | out, outlen); |
| f7d998a2 P |
800 | } |
| 801 | ||
| 802 | static int prov_tls13_hkdf_generate_secret(OSSL_LIB_CTX *libctx, | |
| 2fab90bb BB |
803 | const EVP_MD *md, |
| 804 | const unsigned char *prevsecret, | |
| 805 | size_t prevsecretlen, | |
| 806 | const unsigned char *insecret, | |
| 807 | size_t insecretlen, | |
| 808 | const unsigned char *prefix, | |
| 809 | size_t prefixlen, | |
| 810 | const unsigned char *label, | |
| 811 | size_t labellen, | |
| 812 | unsigned char *out, size_t outlen) | |
| f7d998a2 P |
813 | { |
| 814 | size_t mdlen; | |
| 815 | int ret; | |
| 816 | unsigned char preextractsec[EVP_MAX_MD_SIZE]; | |
| 817 | /* Always filled with zeros */ | |
| 818 | static const unsigned char default_zeros[EVP_MAX_MD_SIZE]; | |
| 819 | ||
| 820 | ret = EVP_MD_get_size(md); | |
| 821 | /* Ensure cast to size_t is safe */ | |
| 822 | if (ret <= 0) | |
| 823 | return 0; | |
| 824 | mdlen = (size_t)ret; | |
| 825 | ||
| 826 | if (insecret == NULL) { | |
| 827 | insecret = default_zeros; | |
| 828 | insecretlen = mdlen; | |
| 829 | } | |
| 830 | if (prevsecret == NULL) { | |
| 831 | prevsecret = default_zeros; | |
| 15d6114d | 832 | prevsecretlen = mdlen; |
| f7d998a2 P |
833 | } else { |
| 834 | EVP_MD_CTX *mctx = EVP_MD_CTX_new(); | |
| 835 | unsigned char hash[EVP_MAX_MD_SIZE]; | |
| 836 | ||
| 837 | /* The pre-extract derive step uses a hash of no messages */ | |
| 838 | if (mctx == NULL | |
| 2fab90bb BB |
839 | || EVP_DigestInit_ex(mctx, md, NULL) <= 0 |
| 840 | || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) { | |
| f7d998a2 P |
841 | EVP_MD_CTX_free(mctx); |
| 842 | return 0; | |
| 843 | } | |
| 844 | EVP_MD_CTX_free(mctx); | |
| 845 | ||
| 846 | /* Generate the pre-extract secret */ | |
| 5c91f70b | 847 | if (!prov_tls13_hkdf_expand(md, prevsecret, prevsecretlen, |
| 2fab90bb BB |
848 | prefix, prefixlen, label, labellen, |
| 849 | hash, mdlen, preextractsec, mdlen)) | |
| f7d998a2 P |
850 | return 0; |
| 851 | prevsecret = preextractsec; | |
| 852 | prevsecretlen = mdlen; | |
| 853 | } | |
| 854 | ||
| 855 | ret = HKDF_Extract(libctx, md, prevsecret, prevsecretlen, | |
| 2fab90bb | 856 | insecret, insecretlen, out, outlen); |
| f7d998a2 P |
857 | |
| 858 | if (prevsecret == preextractsec) | |
| 859 | OPENSSL_cleanse(preextractsec, mdlen); | |
| 860 | return ret; | |
| 861 | } | |
| 862 | ||
| 6d47e819 | 863 | #ifdef FIPS_MODULE |
| 14e46600 | 864 | static int fips_tls1_3_digest_check_passed(KDF_HKDF *ctx, const EVP_MD *md) |
| 6d47e819 | 865 | { |
| 866 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); | |
| 6d47e819 | 867 | /* |
| 868 | * Perform digest check | |
| 869 | * | |
| 870 | * According to RFC 8446 appendix B.4, the valid hash functions are | |
| 871 | * specified in FIPS 180-4. However, it only lists SHA2-256 and SHA2-384 in | |
| 872 | * the table. ACVP also only lists the same set of hash functions. | |
| 873 | */ | |
| 874 | int digest_unapproved = !EVP_MD_is_a(md, SN_sha256) | |
| 875 | && !EVP_MD_is_a(md, SN_sha384); | |
| 876 | ||
| 877 | if (digest_unapproved) { | |
| 878 | if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, | |
| 2fab90bb BB |
879 | libctx, "TLS13 KDF", "Digest", |
| 880 | ossl_fips_config_tls13_kdf_digest_check)) { | |
| 6d47e819 | 881 | ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); |
| 882 | return 0; | |
| 883 | } | |
| 884 | } | |
| 885 | return 1; | |
| 886 | } | |
| 1b838621 | 887 | |
| 888 | /* | |
| 889 | * Calculate the correct length of the secret key. | |
| 890 | * | |
| 891 | * RFC 8446: | |
| 892 | * If a given secret is not available, then the 0-value consisting of a | |
| 893 | * string of Hash.length bytes set to zeros is used. | |
| 894 | */ | |
| 895 | static size_t fips_tls1_3_key_size(KDF_HKDF *ctx) | |
| 896 | { | |
| 897 | const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); | |
| 898 | size_t key_size = 0; | |
| 899 | ||
| 900 | if (ctx->key != NULL) | |
| 901 | key_size = ctx->key_len; | |
| 902 | else if (md != NULL) | |
| 903 | key_size = EVP_MD_size(md); | |
| 904 | ||
| 905 | return key_size; | |
| 906 | } | |
| 907 | ||
| 908 | static int fips_tls1_3_key_check_passed(KDF_HKDF *ctx) | |
| 909 | { | |
| 910 | OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); | |
| 911 | int key_approved = ossl_kdf_check_key_size(fips_tls1_3_key_size(ctx)); | |
| 912 | ||
| 913 | if (!key_approved) { | |
| 914 | if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE1, | |
| 2fab90bb BB |
915 | libctx, "TLS13 KDF", "Key size", |
| 916 | ossl_fips_config_tls13_kdf_key_check)) { | |
| 1b838621 | 917 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); |
| 918 | return 0; | |
| 919 | } | |
| 920 | } | |
| 921 | return 1; | |
| 922 | } | |
| 6d47e819 | 923 | #endif |
| 924 | ||
| f7d998a2 | 925 | static int kdf_tls1_3_derive(void *vctx, unsigned char *key, size_t keylen, |
| 2fab90bb | 926 | const OSSL_PARAM params[]) |
| f7d998a2 P |
927 | { |
| 928 | KDF_HKDF *ctx = (KDF_HKDF *)vctx; | |
| 929 | const EVP_MD *md; | |
| 930 | ||
| 931 | if (!ossl_prov_is_running() || !kdf_tls1_3_set_ctx_params(ctx, params)) | |
| 932 | return 0; | |
| 933 | ||
| 934 | md = ossl_prov_digest_md(&ctx->digest); | |
| 935 | if (md == NULL) { | |
| 936 | ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST); | |
| 937 | return 0; | |
| 938 | } | |
| 939 | ||
| 940 | switch (ctx->mode) { | |
| 941 | default: | |
| 942 | return 0; | |
| 943 | ||
| 944 | case EVP_KDF_HKDF_MODE_EXTRACT_ONLY: | |
| 945 | return prov_tls13_hkdf_generate_secret(PROV_LIBCTX_OF(ctx->provctx), | |
| 2fab90bb BB |
946 | md, |
| 947 | ctx->salt, ctx->salt_len, | |
| 948 | ctx->key, ctx->key_len, | |
| 949 | ctx->prefix, ctx->prefix_len, | |
| 950 | ctx->label, ctx->label_len, | |
| 951 | key, keylen); | |
| f7d998a2 P |
952 | |
| 953 | case EVP_KDF_HKDF_MODE_EXPAND_ONLY: | |
| 954 | return prov_tls13_hkdf_expand(md, ctx->key, ctx->key_len, | |
| 2fab90bb BB |
955 | ctx->prefix, ctx->prefix_len, |
| 956 | ctx->label, ctx->label_len, | |
| 957 | ctx->data, ctx->data_len, | |
| 958 | key, keylen); | |
| f7d998a2 P |
959 | } |
| 960 | } | |
| 961 | ||
| 962 | static int kdf_tls1_3_set_ctx_params(void *vctx, const OSSL_PARAM params[]) | |
| 963 | { | |
| dc294270 | 964 | struct hkdf_all_set_ctx_params_st p; |
| f7d998a2 P |
965 | KDF_HKDF *ctx = vctx; |
| 966 | ||
| dc294270 P |
967 | if (ctx == NULL || !kdf_tls1_3_set_ctx_params_decoder(params, &p)) |
| 968 | return 0; | |
| f7d998a2 | 969 | |
| dc294270 | 970 | if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_d)) |
| 6d47e819 | 971 | return 0; |
| dc294270 | 972 | if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE1, p.ind_k)) |
| 1b838621 | 973 | return 0; |
| 6d47e819 | 974 | |
| dc294270 | 975 | if (!hkdf_common_set_ctx_params(ctx, &p)) |
| f7d998a2 P |
976 | return 0; |
| 977 | ||
| 978 | if (ctx->mode == EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND) { | |
| 979 | ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MODE); | |
| 980 | return 0; | |
| 981 | } | |
| 982 | ||
| dc294270 | 983 | if (p.prefix != NULL) { |
| f7d998a2 P |
984 | OPENSSL_free(ctx->prefix); |
| 985 | ctx->prefix = NULL; | |
| dc294270 | 986 | if (!OSSL_PARAM_get_octet_string(p.prefix, (void **)&ctx->prefix, 0, |
| 2fab90bb | 987 | &ctx->prefix_len)) |
| f7d998a2 P |
988 | return 0; |
| 989 | } | |
| 990 | ||
| dc294270 | 991 | if (p.label != NULL) { |
| f7d998a2 P |
992 | OPENSSL_free(ctx->label); |
| 993 | ctx->label = NULL; | |
| dc294270 | 994 | if (!OSSL_PARAM_get_octet_string(p.label, (void **)&ctx->label, 0, |
| 2fab90bb | 995 | &ctx->label_len)) |
| f7d998a2 P |
996 | return 0; |
| 997 | } | |
| 998 | ||
| dc294270 P |
999 | if (p.data != NULL) { |
| 1000 | OPENSSL_clear_free(ctx->data, ctx->data_len); | |
| 1001 | ctx->data = NULL; | |
| 1002 | if (!OSSL_PARAM_get_octet_string(p.data, (void **)&ctx->data, 0, | |
| 2fab90bb | 1003 | &ctx->data_len)) |
| dc294270 P |
1004 | return 0; |
| 1005 | } | |
| 14e46600 | 1006 | |
| 1007 | #ifdef FIPS_MODULE | |
| dc294270 | 1008 | if (p.digest != NULL) { |
| 14e46600 | 1009 | const EVP_MD *md = ossl_prov_digest_md(&ctx->digest); |
| 1010 | ||
| 1011 | if (!fips_tls1_3_digest_check_passed(ctx, md)) | |
| 1012 | return 0; | |
| 1013 | } | |
| 81bb8848 | 1014 | |
| dc294270 | 1015 | if (p.key != NULL) |
| 81bb8848 | 1016 | if (!fips_tls1_3_key_check_passed(ctx)) |
| 1017 | return 0; | |
| 14e46600 | 1018 | #endif |
| 1019 | ||
| f7d998a2 P |
1020 | return 1; |
| 1021 | } | |
| 1022 | ||
| 1023 | static const OSSL_PARAM *kdf_tls1_3_settable_ctx_params(ossl_unused void *ctx, | |
| 2fab90bb | 1024 | ossl_unused void *provctx) |
| f7d998a2 | 1025 | { |
| dc294270 | 1026 | return kdf_tls1_3_set_ctx_params_list; |
| 14e46600 | 1027 | } |
| 1028 | ||
| f7d998a2 | 1029 | const OSSL_DISPATCH ossl_kdf_tls1_3_kdf_functions[] = { |
| 2fab90bb BB |
1030 | { OSSL_FUNC_KDF_NEWCTX, (void (*)(void))kdf_hkdf_new }, |
| 1031 | { OSSL_FUNC_KDF_DUPCTX, (void (*)(void))kdf_hkdf_dup }, | |
| 1032 | { OSSL_FUNC_KDF_FREECTX, (void (*)(void))kdf_hkdf_free }, | |
| 1033 | { OSSL_FUNC_KDF_RESET, (void (*)(void))kdf_hkdf_reset }, | |
| 1034 | { OSSL_FUNC_KDF_DERIVE, (void (*)(void))kdf_tls1_3_derive }, | |
| f7d998a2 | 1035 | { OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS, |
| 2fab90bb BB |
1036 | (void (*)(void))kdf_tls1_3_settable_ctx_params }, |
| 1037 | { OSSL_FUNC_KDF_SET_CTX_PARAMS, (void (*)(void))kdf_tls1_3_set_ctx_params }, | |
| f7d998a2 | 1038 | { OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS, |
| 2fab90bb BB |
1039 | (void (*)(void))hkdf_gettable_ctx_params }, |
| 1040 | { OSSL_FUNC_KDF_GET_CTX_PARAMS, (void (*)(void))hkdf_common_get_ctx_params }, | |
| 1e6bd31e | 1041 | OSSL_DISPATCH_END |
| f7d998a2 | 1042 | }; |