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