xref: /netbsd-src/crypto/external/bsd/openssl/dist/providers/implementations/exchange/kdf_exch.c (revision 0e2e28bced52bda3788c857106bde6c44d2df3b8)
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