]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/pkey_kdf.c
EVP configuration section: add 'default_properties' command
[thirdparty/openssl.git] / crypto / evp / pkey_kdf.c
CommitLineData
5a285add
DM
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>
cee719c2 15#include "internal/numbers.h"
5a285add
DM
16#include "internal/evp_int.h"
17
18static int pkey_kdf_init(EVP_PKEY_CTX *ctx)
19{
20 EVP_KDF_CTX *kctx;
21
22 kctx = EVP_KDF_CTX_new_id(ctx->pmeth->pkey_id);
23 if (kctx == NULL)
24 return 0;
25
26 ctx->data = kctx;
27 return 1;
28}
29
30static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx)
31{
32 EVP_KDF_CTX *kctx = ctx->data;
33
34 EVP_KDF_CTX_free(kctx);
35}
36
37static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
38{
39 EVP_KDF_CTX *kctx = ctx->data;
40 uint64_t u64_value;
41 int cmd;
42 int ret;
43
44 switch (type) {
45 case EVP_PKEY_CTRL_PASS:
46 cmd = EVP_KDF_CTRL_SET_PASS;
47 break;
48 case EVP_PKEY_CTRL_HKDF_SALT:
49 case EVP_PKEY_CTRL_SCRYPT_SALT:
50 cmd = EVP_KDF_CTRL_SET_SALT;
51 break;
52 case EVP_PKEY_CTRL_TLS_MD:
53 case EVP_PKEY_CTRL_HKDF_MD:
54 cmd = EVP_KDF_CTRL_SET_MD;
55 break;
56 case EVP_PKEY_CTRL_TLS_SECRET:
57 cmd = EVP_KDF_CTRL_SET_TLS_SECRET;
58 ret = EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_RESET_TLS_SEED);
59 if (ret < 1)
60 return ret;
61 break;
62 case EVP_PKEY_CTRL_TLS_SEED:
63 cmd = EVP_KDF_CTRL_ADD_TLS_SEED;
64 break;
65 case EVP_PKEY_CTRL_HKDF_KEY:
66 cmd = EVP_KDF_CTRL_SET_KEY;
67 break;
68 case EVP_PKEY_CTRL_HKDF_INFO:
69 cmd = EVP_KDF_CTRL_ADD_HKDF_INFO;
70 break;
71 case EVP_PKEY_CTRL_HKDF_MODE:
72 cmd = EVP_KDF_CTRL_SET_HKDF_MODE;
73 break;
74 case EVP_PKEY_CTRL_SCRYPT_N:
75 cmd = EVP_KDF_CTRL_SET_SCRYPT_N;
76 break;
77 case EVP_PKEY_CTRL_SCRYPT_R:
78 cmd = EVP_KDF_CTRL_SET_SCRYPT_R;
79 break;
80 case EVP_PKEY_CTRL_SCRYPT_P:
81 cmd = EVP_KDF_CTRL_SET_SCRYPT_P;
82 break;
83 case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES:
84 cmd = EVP_KDF_CTRL_SET_MAXMEM_BYTES;
85 break;
86 default:
87 return -2;
88 }
89
90 switch (cmd) {
91 case EVP_KDF_CTRL_SET_PASS:
92 case EVP_KDF_CTRL_SET_SALT:
93 case EVP_KDF_CTRL_SET_KEY:
94 case EVP_KDF_CTRL_SET_TLS_SECRET:
95 case EVP_KDF_CTRL_ADD_TLS_SEED:
96 case EVP_KDF_CTRL_ADD_HKDF_INFO:
97 return EVP_KDF_ctrl(kctx, cmd, (const unsigned char *)p2, (size_t)p1);
98
99 case EVP_KDF_CTRL_SET_MD:
100 return EVP_KDF_ctrl(kctx, cmd, (const EVP_MD *)p2);
101
102 case EVP_KDF_CTRL_SET_HKDF_MODE:
103 return EVP_KDF_ctrl(kctx, cmd, (int)p1);
104
105 case EVP_KDF_CTRL_SET_SCRYPT_R:
106 case EVP_KDF_CTRL_SET_SCRYPT_P:
107 u64_value = *(uint64_t *)p2;
108 if (u64_value > UINT32_MAX) {
109 EVPerr(EVP_F_PKEY_KDF_CTRL, EVP_R_PARAMETER_TOO_LARGE);
110 return 0;
111 }
112
113 return EVP_KDF_ctrl(kctx, cmd, (uint32_t)u64_value);
114
115 case EVP_KDF_CTRL_SET_SCRYPT_N:
116 case EVP_KDF_CTRL_SET_MAXMEM_BYTES:
117 return EVP_KDF_ctrl(kctx, cmd, *(uint64_t *)p2);
118
119 default:
120 return 0;
121 }
122}
123
124static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
125 const char *value)
126{
127 EVP_KDF_CTX *kctx = ctx->data;
128
129 if (strcmp(type, "md") == 0)
130 return EVP_KDF_ctrl_str(kctx, "digest", value);
131 return EVP_KDF_ctrl_str(kctx, type, value);
132}
133
134static int pkey_kdf_derive_init(EVP_PKEY_CTX *ctx)
135{
136 EVP_KDF_CTX *kctx = ctx->data;
137
138 EVP_KDF_reset(kctx);
139 return 1;
140}
141
142/*
143 * For fixed-output algorithms the keylen parameter is an "out" parameter
144 * otherwise it is an "in" parameter.
145 */
146static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
147 size_t *keylen)
148{
149 EVP_KDF_CTX *kctx = ctx->data;
150 size_t outlen = EVP_KDF_size(kctx);
151
152 if (outlen == 0 || outlen == SIZE_MAX) {
153 /* Variable-output algorithm */
154 if (key == NULL)
155 return 0;
156 } else {
157 /* Fixed-output algorithm */
158 *keylen = outlen;
159 if (key == NULL)
160 return 1;
161 }
162 return EVP_KDF_derive(kctx, key, *keylen);
163}
164
165#ifndef OPENSSL_NO_SCRYPT
166const EVP_PKEY_METHOD scrypt_pkey_meth = {
167 EVP_PKEY_SCRYPT,
168 0,
169 pkey_kdf_init,
170 0,
171 pkey_kdf_cleanup,
172
173 0, 0,
174 0, 0,
175
176 0,
177 0,
178
179 0,
180 0,
181
182 0, 0,
183
184 0, 0, 0, 0,
185
186 0, 0,
187
188 0, 0,
189
190 pkey_kdf_derive_init,
191 pkey_kdf_derive,
192 pkey_kdf_ctrl,
193 pkey_kdf_ctrl_str
194};
195#endif
196
197const EVP_PKEY_METHOD tls1_prf_pkey_meth = {
198 EVP_PKEY_TLS1_PRF,
199 0,
200 pkey_kdf_init,
201 0,
202 pkey_kdf_cleanup,
203
204 0, 0,
205 0, 0,
206
207 0,
208 0,
209
210 0,
211 0,
212
213 0, 0,
214
215 0, 0, 0, 0,
216
217 0, 0,
218
219 0, 0,
220
221 pkey_kdf_derive_init,
222 pkey_kdf_derive,
223 pkey_kdf_ctrl,
224 pkey_kdf_ctrl_str
225};
226
227const EVP_PKEY_METHOD hkdf_pkey_meth = {
228 EVP_PKEY_HKDF,
229 0,
230 pkey_kdf_init,
231 0,
232 pkey_kdf_cleanup,
233
234 0, 0,
235 0, 0,
236
237 0,
238 0,
239
240 0,
241 0,
242
243 0, 0,
244
245 0, 0, 0, 0,
246
247 0, 0,
248
249 0, 0,
250
251 pkey_kdf_derive_init,
252 pkey_kdf_derive,
253 pkey_kdf_ctrl,
254 pkey_kdf_ctrl_str
255};
256