1b0d17251Schristos /*
2*0e2e28bcSchristos * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
3b0d17251Schristos *
4b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
5b0d17251Schristos * this file except in compliance with the License. You can obtain a copy
6b0d17251Schristos * in the file LICENSE in the source distribution or at
7b0d17251Schristos * https://www.openssl.org/source/license.html
8b0d17251Schristos */
9b0d17251Schristos
10b0d17251Schristos #include <openssl/crypto.h>
11b0d17251Schristos #include <openssl/kdf.h>
12b0d17251Schristos #include <openssl/core_dispatch.h>
13b0d17251Schristos #include <openssl/core_names.h>
14b0d17251Schristos #include <openssl/err.h>
15b0d17251Schristos #include <openssl/proverr.h>
16b0d17251Schristos #include <openssl/params.h>
17b0d17251Schristos #include "internal/numbers.h"
18b0d17251Schristos #include "prov/implementations.h"
19b0d17251Schristos #include "prov/provider_ctx.h"
20b0d17251Schristos #include "prov/kdfexchange.h"
21b0d17251Schristos #include "prov/providercommon.h"
22b0d17251Schristos
23b0d17251Schristos static OSSL_FUNC_keyexch_newctx_fn kdf_tls1_prf_newctx;
24b0d17251Schristos static OSSL_FUNC_keyexch_newctx_fn kdf_hkdf_newctx;
25b0d17251Schristos static OSSL_FUNC_keyexch_newctx_fn kdf_scrypt_newctx;
26b0d17251Schristos static OSSL_FUNC_keyexch_init_fn kdf_init;
27b0d17251Schristos static OSSL_FUNC_keyexch_derive_fn kdf_derive;
28b0d17251Schristos static OSSL_FUNC_keyexch_freectx_fn kdf_freectx;
29b0d17251Schristos static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx;
30b0d17251Schristos static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params;
31*0e2e28bcSchristos static OSSL_FUNC_keyexch_get_ctx_params_fn kdf_get_ctx_params;
32b0d17251Schristos static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params;
33b0d17251Schristos static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
34b0d17251Schristos static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params;
35*0e2e28bcSchristos static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params;
36*0e2e28bcSchristos static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
37*0e2e28bcSchristos static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_scrypt_gettable_ctx_params;
38b0d17251Schristos
39b0d17251Schristos typedef struct {
40b0d17251Schristos void *provctx;
41b0d17251Schristos EVP_KDF_CTX *kdfctx;
42b0d17251Schristos KDF_DATA *kdfdata;
43b0d17251Schristos } PROV_KDF_CTX;
44b0d17251Schristos
kdf_newctx(const char * kdfname,void * provctx)45b0d17251Schristos static void *kdf_newctx(const char *kdfname, void *provctx)
46b0d17251Schristos {
47b0d17251Schristos PROV_KDF_CTX *kdfctx;
48b0d17251Schristos EVP_KDF *kdf = NULL;
49b0d17251Schristos
50b0d17251Schristos if (!ossl_prov_is_running())
51b0d17251Schristos return NULL;
52b0d17251Schristos
53b0d17251Schristos kdfctx = OPENSSL_zalloc(sizeof(PROV_KDF_CTX));
54b0d17251Schristos if (kdfctx == NULL)
55b0d17251Schristos return NULL;
56b0d17251Schristos
57b0d17251Schristos kdfctx->provctx = provctx;
58b0d17251Schristos
59b0d17251Schristos kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname, NULL);
60b0d17251Schristos if (kdf == NULL)
61b0d17251Schristos goto err;
62b0d17251Schristos kdfctx->kdfctx = EVP_KDF_CTX_new(kdf);
63b0d17251Schristos EVP_KDF_free(kdf);
64b0d17251Schristos
65b0d17251Schristos if (kdfctx->kdfctx == NULL)
66b0d17251Schristos goto err;
67b0d17251Schristos
68b0d17251Schristos return kdfctx;
69b0d17251Schristos err:
70b0d17251Schristos OPENSSL_free(kdfctx);
71b0d17251Schristos return NULL;
72b0d17251Schristos }
73b0d17251Schristos
74b0d17251Schristos #define KDF_NEWCTX(funcname, kdfname) \
75b0d17251Schristos static void *kdf_##funcname##_newctx(void *provctx) \
76b0d17251Schristos { \
77b0d17251Schristos return kdf_newctx(kdfname, provctx); \
78b0d17251Schristos }
79b0d17251Schristos
80b0d17251Schristos KDF_NEWCTX(tls1_prf, "TLS1-PRF")
81b0d17251Schristos KDF_NEWCTX(hkdf, "HKDF")
82b0d17251Schristos KDF_NEWCTX(scrypt, "SCRYPT")
83b0d17251Schristos
kdf_init(void * vpkdfctx,void * vkdf,const OSSL_PARAM params[])84b0d17251Schristos static int kdf_init(void *vpkdfctx, void *vkdf, const OSSL_PARAM params[])
85b0d17251Schristos {
86b0d17251Schristos PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
87b0d17251Schristos
88b0d17251Schristos if (!ossl_prov_is_running()
89b0d17251Schristos || pkdfctx == NULL
90b0d17251Schristos || vkdf == NULL
91b0d17251Schristos || !ossl_kdf_data_up_ref(vkdf))
92b0d17251Schristos return 0;
93b0d17251Schristos pkdfctx->kdfdata = vkdf;
94b0d17251Schristos
95b0d17251Schristos return kdf_set_ctx_params(pkdfctx, params);
96b0d17251Schristos }
97b0d17251Schristos
kdf_derive(void * vpkdfctx,unsigned char * secret,size_t * secretlen,size_t outlen)98b0d17251Schristos static int kdf_derive(void *vpkdfctx, unsigned char *secret, size_t *secretlen,
99b0d17251Schristos size_t outlen)
100b0d17251Schristos {
101b0d17251Schristos PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
102b0d17251Schristos size_t kdfsize;
103b0d17251Schristos int ret;
104b0d17251Schristos
105b0d17251Schristos if (!ossl_prov_is_running())
106b0d17251Schristos return 0;
107b0d17251Schristos
108b0d17251Schristos kdfsize = EVP_KDF_CTX_get_kdf_size(pkdfctx->kdfctx);
109b0d17251Schristos
110b0d17251Schristos if (secret == NULL) {
111b0d17251Schristos *secretlen = kdfsize;
112b0d17251Schristos return 1;
113b0d17251Schristos }
114b0d17251Schristos
115b0d17251Schristos if (kdfsize != SIZE_MAX) {
116b0d17251Schristos if (outlen < kdfsize) {
117b0d17251Schristos ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
118b0d17251Schristos return 0;
119b0d17251Schristos }
120b0d17251Schristos outlen = kdfsize;
121b0d17251Schristos }
122b0d17251Schristos
123b0d17251Schristos ret = EVP_KDF_derive(pkdfctx->kdfctx, secret, outlen, NULL);
124b0d17251Schristos if (ret <= 0)
125b0d17251Schristos return 0;
126b0d17251Schristos
127b0d17251Schristos *secretlen = outlen;
128b0d17251Schristos return 1;
129b0d17251Schristos }
130b0d17251Schristos
kdf_freectx(void * vpkdfctx)131b0d17251Schristos static void kdf_freectx(void *vpkdfctx)
132b0d17251Schristos {
133b0d17251Schristos PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
134b0d17251Schristos
135b0d17251Schristos EVP_KDF_CTX_free(pkdfctx->kdfctx);
136b0d17251Schristos ossl_kdf_data_free(pkdfctx->kdfdata);
137b0d17251Schristos
138b0d17251Schristos OPENSSL_free(pkdfctx);
139b0d17251Schristos }
140b0d17251Schristos
kdf_dupctx(void * vpkdfctx)141b0d17251Schristos static void *kdf_dupctx(void *vpkdfctx)
142b0d17251Schristos {
143b0d17251Schristos PROV_KDF_CTX *srcctx = (PROV_KDF_CTX *)vpkdfctx;
144b0d17251Schristos PROV_KDF_CTX *dstctx;
145b0d17251Schristos
146b0d17251Schristos if (!ossl_prov_is_running())
147b0d17251Schristos return NULL;
148b0d17251Schristos
149b0d17251Schristos dstctx = OPENSSL_zalloc(sizeof(*srcctx));
150b0d17251Schristos if (dstctx == NULL)
151b0d17251Schristos return NULL;
152b0d17251Schristos
153b0d17251Schristos *dstctx = *srcctx;
154b0d17251Schristos
155b0d17251Schristos dstctx->kdfctx = EVP_KDF_CTX_dup(srcctx->kdfctx);
156b0d17251Schristos if (dstctx->kdfctx == NULL) {
157b0d17251Schristos OPENSSL_free(dstctx);
158b0d17251Schristos return NULL;
159b0d17251Schristos }
160b0d17251Schristos if (!ossl_kdf_data_up_ref(dstctx->kdfdata)) {
161b0d17251Schristos EVP_KDF_CTX_free(dstctx->kdfctx);
162b0d17251Schristos OPENSSL_free(dstctx);
163b0d17251Schristos return NULL;
164b0d17251Schristos }
165b0d17251Schristos
166b0d17251Schristos return dstctx;
167b0d17251Schristos }
168b0d17251Schristos
kdf_set_ctx_params(void * vpkdfctx,const OSSL_PARAM params[])169b0d17251Schristos static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[])
170b0d17251Schristos {
171b0d17251Schristos PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
172b0d17251Schristos
173b0d17251Schristos return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params);
174b0d17251Schristos }
175b0d17251Schristos
kdf_get_ctx_params(void * vpkdfctx,OSSL_PARAM params[])176*0e2e28bcSchristos static int kdf_get_ctx_params(void *vpkdfctx, OSSL_PARAM params[])
177*0e2e28bcSchristos {
178*0e2e28bcSchristos PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
179*0e2e28bcSchristos
180*0e2e28bcSchristos return EVP_KDF_CTX_get_params(pkdfctx->kdfctx, params);
181*0e2e28bcSchristos }
182*0e2e28bcSchristos
kdf_settable_ctx_params(ossl_unused void * vpkdfctx,void * provctx,const char * kdfname)183b0d17251Schristos static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx,
184b0d17251Schristos void *provctx,
185b0d17251Schristos const char *kdfname)
186b0d17251Schristos {
187b0d17251Schristos EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname,
188b0d17251Schristos NULL);
189b0d17251Schristos const OSSL_PARAM *params;
190b0d17251Schristos
191b0d17251Schristos if (kdf == NULL)
192b0d17251Schristos return NULL;
193b0d17251Schristos
194b0d17251Schristos params = EVP_KDF_settable_ctx_params(kdf);
195b0d17251Schristos EVP_KDF_free(kdf);
196b0d17251Schristos
197b0d17251Schristos return params;
198b0d17251Schristos }
199b0d17251Schristos
200b0d17251Schristos #define KDF_SETTABLE_CTX_PARAMS(funcname, kdfname) \
201b0d17251Schristos static const OSSL_PARAM *kdf_##funcname##_settable_ctx_params(void *vpkdfctx, \
202b0d17251Schristos void *provctx) \
203b0d17251Schristos { \
204b0d17251Schristos return kdf_settable_ctx_params(vpkdfctx, provctx, kdfname); \
205b0d17251Schristos }
206b0d17251Schristos
207b0d17251Schristos KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
208b0d17251Schristos KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF")
209b0d17251Schristos KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
210b0d17251Schristos
kdf_gettable_ctx_params(ossl_unused void * vpkdfctx,void * provctx,const char * kdfname)211*0e2e28bcSchristos static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx,
212*0e2e28bcSchristos void *provctx,
213*0e2e28bcSchristos const char *kdfname)
214*0e2e28bcSchristos {
215*0e2e28bcSchristos EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname,
216*0e2e28bcSchristos NULL);
217*0e2e28bcSchristos const OSSL_PARAM *params;
218*0e2e28bcSchristos
219*0e2e28bcSchristos if (kdf == NULL)
220*0e2e28bcSchristos return NULL;
221*0e2e28bcSchristos
222*0e2e28bcSchristos params = EVP_KDF_gettable_ctx_params(kdf);
223*0e2e28bcSchristos EVP_KDF_free(kdf);
224*0e2e28bcSchristos
225*0e2e28bcSchristos return params;
226*0e2e28bcSchristos }
227*0e2e28bcSchristos
228*0e2e28bcSchristos #define KDF_GETTABLE_CTX_PARAMS(funcname, kdfname) \
229*0e2e28bcSchristos static const OSSL_PARAM *kdf_##funcname##_gettable_ctx_params(void *vpkdfctx, \
230*0e2e28bcSchristos void *provctx) \
231*0e2e28bcSchristos { \
232*0e2e28bcSchristos return kdf_gettable_ctx_params(vpkdfctx, provctx, kdfname); \
233*0e2e28bcSchristos }
234*0e2e28bcSchristos
235*0e2e28bcSchristos KDF_GETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
236*0e2e28bcSchristos KDF_GETTABLE_CTX_PARAMS(hkdf, "HKDF")
237*0e2e28bcSchristos KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
238*0e2e28bcSchristos
239b0d17251Schristos #define KDF_KEYEXCH_FUNCTIONS(funcname) \
240b0d17251Schristos const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \
241b0d17251Schristos { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \
242b0d17251Schristos { OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))kdf_init }, \
243b0d17251Schristos { OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))kdf_derive }, \
244b0d17251Schristos { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \
245b0d17251Schristos { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \
246b0d17251Schristos { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \
247*0e2e28bcSchristos { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))kdf_get_ctx_params }, \
248b0d17251Schristos { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \
249b0d17251Schristos (void (*)(void))kdf_##funcname##_settable_ctx_params }, \
250*0e2e28bcSchristos { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \
251*0e2e28bcSchristos (void (*)(void))kdf_##funcname##_gettable_ctx_params }, \
252b0d17251Schristos { 0, NULL } \
253b0d17251Schristos };
254b0d17251Schristos
255b0d17251Schristos KDF_KEYEXCH_FUNCTIONS(tls1_prf)
256b0d17251Schristos KDF_KEYEXCH_FUNCTIONS(hkdf)
257b0d17251Schristos KDF_KEYEXCH_FUNCTIONS(scrypt)
258