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