]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/evp/pkey_kdf.c
Fix users of KDFs to use params not ctls
[thirdparty/openssl.git] / crypto / evp / pkey_kdf.c
1 /*
2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
4 *
5 * Licensed under the Apache License 2.0 (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11 #include <string.h>
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include <openssl/kdf.h>
15 #include <openssl/core.h>
16 #include <openssl/core_names.h>
17 #include <openssl/params.h>
18 #include "internal/numbers.h"
19 #include "internal/evp_int.h"
20
21 #define MAX_PARAM 20
22
23 typedef struct {
24 EVP_KDF_CTX *kctx;
25 /* TODO(3.0): come up with a better way to do this */
26 OSSL_PARAM params[MAX_PARAM];
27 int palloc[MAX_PARAM];
28 uint64_t uint64s[MAX_PARAM];
29 int ints[MAX_PARAM];
30 int pidx;
31 } EVP_PKEY_KDF_CTX;
32
33 static void pkey_kdf_free_param_data(EVP_PKEY_KDF_CTX *pkctx)
34 {
35 int i;
36
37 for (i = 0; i < pkctx->pidx; i++)
38 if (pkctx->palloc[i])
39 OPENSSL_free(pkctx->params[i].data);
40 pkctx->pidx = 0;
41 }
42
43 static int pkey_kdf_init(EVP_PKEY_CTX *ctx)
44 {
45 EVP_PKEY_KDF_CTX *pkctx;
46 EVP_KDF_CTX *kctx;
47 const char *kdf_name = OBJ_nid2sn(ctx->pmeth->pkey_id);
48 EVP_KDF *kdf;
49
50 pkctx = OPENSSL_zalloc(sizeof(*pkctx));
51 if (pkctx == NULL)
52 return 0;
53
54 kdf = EVP_KDF_fetch(NULL, kdf_name, NULL);
55 kctx = EVP_KDF_CTX_new(kdf);
56 EVP_KDF_free(kdf);
57 if (kctx == NULL) {
58 OPENSSL_free(pkctx);
59 return 0;
60 }
61
62 pkctx->kctx = kctx;
63 ctx->data = pkctx;
64 return 1;
65 }
66
67 static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx)
68 {
69 EVP_PKEY_KDF_CTX *pkctx = ctx->data;
70
71 EVP_KDF_CTX_free(pkctx->kctx);
72 pkey_kdf_free_param_data(pkctx);
73 OPENSSL_free(pkctx);
74 }
75
76 static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
77 {
78 EVP_PKEY_KDF_CTX *pkctx = ctx->data;
79 enum { T_OCTET_STRING, T_UINT64, T_DIGEST, T_INT } cmd;
80 const char *name, *mdname;
81 OSSL_PARAM *p = pkctx->params + pkctx->pidx;
82
83 switch (type) {
84 case EVP_PKEY_CTRL_PASS:
85 cmd = T_OCTET_STRING;
86 name = OSSL_KDF_PARAM_PASSWORD;
87 break;
88 case EVP_PKEY_CTRL_HKDF_SALT:
89 case EVP_PKEY_CTRL_SCRYPT_SALT:
90 cmd = T_OCTET_STRING;
91 name = OSSL_KDF_PARAM_SALT;
92 break;
93 case EVP_PKEY_CTRL_TLS_MD:
94 case EVP_PKEY_CTRL_HKDF_MD:
95 cmd = T_DIGEST;
96 name = OSSL_KDF_PARAM_DIGEST;
97 break;
98 case EVP_PKEY_CTRL_TLS_SECRET:
99 cmd = T_OCTET_STRING;
100 name = OSSL_KDF_PARAM_SECRET;
101 break;
102 case EVP_PKEY_CTRL_TLS_SEED:
103 cmd = T_OCTET_STRING;
104 name = OSSL_KDF_PARAM_SEED;
105 break;
106 case EVP_PKEY_CTRL_HKDF_KEY:
107 cmd = T_OCTET_STRING;
108 name = OSSL_KDF_PARAM_KEY;
109 break;
110 case EVP_PKEY_CTRL_HKDF_INFO:
111 cmd = T_OCTET_STRING;
112 name = OSSL_KDF_PARAM_INFO;
113 break;
114 case EVP_PKEY_CTRL_HKDF_MODE:
115 cmd = T_INT;
116 name = OSSL_KDF_PARAM_MODE;
117 break;
118 case EVP_PKEY_CTRL_SCRYPT_N:
119 cmd = T_UINT64;
120 name = OSSL_KDF_PARAM_SCRYPT_N;
121 break;
122 case EVP_PKEY_CTRL_SCRYPT_R:
123 cmd = T_UINT64; /* Range checking occurs on the provider side */
124 name = OSSL_KDF_PARAM_SCRYPT_R;
125 break;
126 case EVP_PKEY_CTRL_SCRYPT_P:
127 cmd = T_UINT64; /* Range checking occurs on the provider side */
128 name = OSSL_KDF_PARAM_SCRYPT_P;
129 break;
130 case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
131 cmd = T_UINT64;
132 name = OSSL_KDF_PARAM_SCRYPT_MAXMEM;
133 break;
134 default:
135 return -2;
136 }
137
138 switch (cmd) {
139 case T_OCTET_STRING:
140 *p = OSSL_PARAM_construct_octet_string(name, (unsigned char *)p2,
141 (size_t)p1);
142 break;
143
144 case T_DIGEST:
145 mdname = EVP_MD_name((const EVP_MD *)p2);
146 *p = OSSL_PARAM_construct_utf8_string(name, (char *)mdname,
147 strlen(mdname) + 1);
148 break;
149
150 /*
151 * These are special because the helper macros pass a pointer to the
152 * stack, so a local copy is required.
153 */
154 case T_INT:
155 pkctx->ints[pkctx->pidx] = *(int *)p2;
156 *p = OSSL_PARAM_construct_int(name, pkctx->ints + pkctx->pidx);
157 break;
158
159 case T_UINT64:
160 pkctx->uint64s[pkctx->pidx] = *(uint64_t *)p2;
161 *p = OSSL_PARAM_construct_uint64(name, pkctx->uint64s + pkctx->pidx);
162 break;
163 }
164 pkctx->palloc[pkctx->pidx++] = 0;
165 return 1;
166 }
167
168 static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
169 const char *value)
170 {
171 EVP_PKEY_KDF_CTX *pkctx = ctx->data;
172 EVP_KDF_CTX *kctx = pkctx->kctx;
173 const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx);
174 const OSSL_PARAM *defs = EVP_KDF_CTX_settable_params(kdf);
175 OSSL_PARAM *p = pkctx->params + pkctx->pidx;
176
177 /* Deal with ctrl name aliasing */
178 if (strcmp(type, "md") == 0)
179 type = OSSL_KDF_PARAM_DIGEST;
180 /* scrypt uses 'N', params uses 'n' */
181 if (strcmp(type, "N") == 0)
182 type = OSSL_KDF_PARAM_SCRYPT_N;
183
184 if (!OSSL_PARAM_allocate_from_text(p, defs, type, value, strlen(value)))
185 return 0;
186 pkctx->palloc[pkctx->pidx++] = 1;
187 return 1;
188 }
189
190 static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx)
191 {
192 EVP_PKEY_KDF_CTX *pkctx = ctx->data;
193
194 pkey_kdf_free_param_data(pkctx);
195 EVP_KDF_reset(pkctx->kctx);
196 return 1;
197 }
198
199 /*
200 * For fixed-output algorithms the keylen parameter is an "out" parameter
201 * otherwise it is an "in" parameter.
202 */
203 static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
204 size_t *keylen)
205 {
206 EVP_PKEY_KDF_CTX *pkctx = ctx->data;
207 EVP_KDF_CTX *kctx = pkctx->kctx;
208 size_t outlen = EVP_KDF_size(kctx);
209 int r;
210
211 if (pkctx->pidx > 0) {
212 pkctx->params[pkctx->pidx] = OSSL_PARAM_construct_end();
213 r = EVP_KDF_CTX_set_params(kctx, pkctx->params);
214 pkey_kdf_free_param_data(pkctx);
215 if (!r)
216 return 0;
217 }
218 if (outlen == 0 || outlen == SIZE_MAX) {
219 /* Variable-output algorithm */
220 if (key == NULL)
221 return 0;
222 } else {
223 /* Fixed-output algorithm */
224 *keylen = outlen;
225 if (key == NULL)
226 return 1;
227 }
228 return EVP_KDF_derive(kctx, key, *keylen);
229 }
230
231 #ifndef OPENSSL_NO_SCRYPT
232 const EVP_PKEY_METHOD scrypt_pkey_meth = {
233 EVP_PKEY_SCRYPT,
234 0,
235 pkey_kdf_init,
236 0,
237 pkey_kdf_cleanup,
238
239 0, 0,
240 0, 0,
241
242 0,
243 0,
244
245 0,
246 0,
247
248 0, 0,
249
250 0, 0, 0, 0,
251
252 0, 0,
253
254 0, 0,
255
256 pkey_kdf_derive_init,
257 pkey_kdf_derive,
258 pkey_kdf_ctrl,
259 pkey_kdf_ctrl_str
260 };
261 #endif
262
263 const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
264 EVP_PKEY_TLS1_PRF,
265 0,
266 pkey_kdf_init,
267 0,
268 pkey_kdf_cleanup,
269
270 0, 0,
271 0, 0,
272
273 0,
274 0,
275
276 0,
277 0,
278
279 0, 0,
280
281 0, 0, 0, 0,
282
283 0, 0,
284
285 0, 0,
286
287 pkey_kdf_derive_init,
288 pkey_kdf_derive,
289 pkey_kdf_ctrl,
290 pkey_kdf_ctrl_str
291 };
292
293 const EVP_PKEY_METHOD hkdf_pkey_meth = {
294 EVP_PKEY_HKDF,
295 0,
296 pkey_kdf_init,
297 0,
298 pkey_kdf_cleanup,
299
300 0, 0,
301 0, 0,
302
303 0,
304 0,
305
306 0,
307 0,
308
309 0, 0,
310
311 0, 0, 0, 0,
312
313 0, 0,
314
315 0, 0,
316
317 pkey_kdf_derive_init,
318 pkey_kdf_derive,
319 pkey_kdf_ctrl,
320 pkey_kdf_ctrl_str
321 };
322