2 * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
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
12 #include <openssl/evp.h>
13 #include <openssl/err.h>
14 #include <openssl/buffer.h>
15 #include <openssl/kdf.h>
16 #include <openssl/core.h>
17 #include <openssl/core_names.h>
18 #include <openssl/params.h>
19 #include "internal/numbers.h"
20 #include "crypto/evp.h"
27 * EVP_PKEY implementations collect bits of certain data
29 BUF_MEM
*collected_seed
;
30 BUF_MEM
*collected_info
;
33 static void pkey_kdf_free_collected(EVP_PKEY_KDF_CTX
*pkctx
)
35 BUF_MEM_free(pkctx
->collected_seed
);
36 pkctx
->collected_seed
= NULL
;
37 BUF_MEM_free(pkctx
->collected_info
);
38 pkctx
->collected_info
= NULL
;
41 static int pkey_kdf_init(EVP_PKEY_CTX
*ctx
)
43 EVP_PKEY_KDF_CTX
*pkctx
;
45 const char *kdf_name
= OBJ_nid2sn(ctx
->pmeth
->pkey_id
);
48 pkctx
= OPENSSL_zalloc(sizeof(*pkctx
));
52 kdf
= EVP_KDF_fetch(NULL
, kdf_name
, NULL
);
53 kctx
= EVP_KDF_CTX_new(kdf
);
65 static void pkey_kdf_cleanup(EVP_PKEY_CTX
*ctx
)
67 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
69 EVP_KDF_CTX_free(pkctx
->kctx
);
70 pkey_kdf_free_collected(pkctx
);
74 static int collect(BUF_MEM
**collector
, void *data
, size_t datalen
)
78 if (*collector
== NULL
)
79 *collector
= BUF_MEM_new();
80 if (*collector
== NULL
) {
81 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
85 if (data
!= NULL
&& datalen
> 0) {
86 i
= (*collector
)->length
; /* BUF_MEM_grow() changes it! */
88 if (!BUF_MEM_grow(*collector
, i
+ datalen
))
90 memcpy((*collector
)->data
+ i
, data
, datalen
);
95 static int pkey_kdf_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
97 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
98 EVP_KDF_CTX
*kctx
= pkctx
->kctx
;
99 enum { T_OCTET_STRING
, T_UINT64
, T_DIGEST
, T_INT
} cmd
;
100 const char *name
, *mdname
;
101 BUF_MEM
**collector
= NULL
;
102 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
105 case EVP_PKEY_CTRL_PASS
:
106 cmd
= T_OCTET_STRING
;
107 name
= OSSL_KDF_PARAM_PASSWORD
;
109 case EVP_PKEY_CTRL_HKDF_SALT
:
110 case EVP_PKEY_CTRL_SCRYPT_SALT
:
111 cmd
= T_OCTET_STRING
;
112 name
= OSSL_KDF_PARAM_SALT
;
114 case EVP_PKEY_CTRL_TLS_MD
:
115 case EVP_PKEY_CTRL_HKDF_MD
:
117 name
= OSSL_KDF_PARAM_DIGEST
;
119 case EVP_PKEY_CTRL_TLS_SECRET
:
120 cmd
= T_OCTET_STRING
;
121 name
= OSSL_KDF_PARAM_SECRET
;
123 * Perform the semantics described in
124 * EVP_PKEY_CTX_add1_tls1_prf_seed(3)
126 if (ctx
->pmeth
->pkey_id
== NID_tls1_prf
) {
127 BUF_MEM_free(pkctx
->collected_seed
);
128 pkctx
->collected_seed
= NULL
;
131 case EVP_PKEY_CTRL_TLS_SEED
:
132 cmd
= T_OCTET_STRING
;
133 name
= OSSL_KDF_PARAM_SEED
;
134 collector
= &pkctx
->collected_seed
;
136 case EVP_PKEY_CTRL_HKDF_KEY
:
137 cmd
= T_OCTET_STRING
;
138 name
= OSSL_KDF_PARAM_KEY
;
140 case EVP_PKEY_CTRL_HKDF_INFO
:
141 cmd
= T_OCTET_STRING
;
142 name
= OSSL_KDF_PARAM_INFO
;
143 collector
= &pkctx
->collected_info
;
145 case EVP_PKEY_CTRL_HKDF_MODE
:
147 name
= OSSL_KDF_PARAM_MODE
;
149 case EVP_PKEY_CTRL_SCRYPT_N
:
151 name
= OSSL_KDF_PARAM_SCRYPT_N
;
153 case EVP_PKEY_CTRL_SCRYPT_R
:
154 cmd
= T_UINT64
; /* Range checking occurs on the provider side */
155 name
= OSSL_KDF_PARAM_SCRYPT_R
;
157 case EVP_PKEY_CTRL_SCRYPT_P
:
158 cmd
= T_UINT64
; /* Range checking occurs on the provider side */
159 name
= OSSL_KDF_PARAM_SCRYPT_P
;
161 case EVP_PKEY_CTRL_SCRYPT_MAXMEM_BYTES
:
163 name
= OSSL_KDF_PARAM_SCRYPT_MAXMEM
;
169 if (collector
!= NULL
) {
172 return collect(collector
, p2
, p1
);
174 OPENSSL_assert("You shouldn't be here");
183 OSSL_PARAM_construct_octet_string(name
, (unsigned char *)p2
,
188 mdname
= EVP_MD_name((const EVP_MD
*)p2
);
189 params
[0] = OSSL_PARAM_construct_utf8_string(name
, (char *)mdname
, 0);
193 * These are special because the helper macros pass a pointer to the
194 * stack, so a local copy is required.
197 params
[0] = OSSL_PARAM_construct_int(name
, &p1
);
201 params
[0] = OSSL_PARAM_construct_uint64(name
, (uint64_t *)p2
);
205 return EVP_KDF_CTX_set_params(kctx
, params
);
208 static int pkey_kdf_ctrl_str(EVP_PKEY_CTX
*ctx
, const char *type
,
211 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
212 EVP_KDF_CTX
*kctx
= pkctx
->kctx
;
213 const EVP_KDF
*kdf
= EVP_KDF_CTX_kdf(kctx
);
214 BUF_MEM
**collector
= NULL
;
215 const OSSL_PARAM
*defs
= EVP_KDF_settable_ctx_params(kdf
);
216 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
219 /* Deal with ctrl name aliasing */
220 if (strcmp(type
, "md") == 0)
221 type
= OSSL_KDF_PARAM_DIGEST
;
222 /* scrypt uses 'N', params uses 'n' */
223 if (strcmp(type
, "N") == 0)
224 type
= OSSL_KDF_PARAM_SCRYPT_N
;
226 if (!OSSL_PARAM_allocate_from_text(¶ms
[0], defs
, type
,
227 value
, strlen(value
), NULL
))
231 * We do the same special casing of seed and info here as in
234 if (strcmp(params
[0].key
, OSSL_KDF_PARAM_SEED
) == 0)
235 collector
= &pkctx
->collected_seed
;
236 else if (strcmp(params
[0].key
, OSSL_KDF_PARAM_INFO
) == 0)
237 collector
= &pkctx
->collected_info
;
239 if (collector
!= NULL
)
240 ok
= collect(collector
, params
[0].data
, params
[0].data_size
);
242 ok
= EVP_KDF_CTX_set_params(kctx
, params
);
243 OPENSSL_free(params
[0].data
);
247 static int pkey_kdf_derive_init(EVP_PKEY_CTX
*ctx
)
249 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
251 pkey_kdf_free_collected(pkctx
);
252 if (pkctx
->kctx
!= NULL
)
253 EVP_KDF_reset(pkctx
->kctx
);
258 * For fixed-output algorithms the keylen parameter is an "out" parameter
259 * otherwise it is an "in" parameter.
261 static int pkey_kdf_derive(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
264 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
265 EVP_KDF_CTX
*kctx
= pkctx
->kctx
;
266 size_t outlen
= EVP_KDF_size(kctx
);
269 if (pkctx
->collected_seed
!= NULL
) {
270 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
273 OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED
,
274 pkctx
->collected_seed
->data
,
275 pkctx
->collected_seed
->length
);
277 r
= EVP_KDF_CTX_set_params(kctx
, params
);
278 pkey_kdf_free_collected(pkctx
);
282 if (pkctx
->collected_info
!= NULL
) {
283 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
286 OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO
,
287 pkctx
->collected_info
->data
,
288 pkctx
->collected_info
->length
);
290 r
= EVP_KDF_CTX_set_params(kctx
, params
);
291 pkey_kdf_free_collected(pkctx
);
295 if (outlen
== 0 || outlen
== SIZE_MAX
) {
296 /* Variable-output algorithm */
300 /* Fixed-output algorithm */
305 return EVP_KDF_derive(kctx
, key
, *keylen
);
308 #ifndef OPENSSL_NO_SCRYPT
309 static const EVP_PKEY_METHOD scrypt_pkey_meth
= {
333 pkey_kdf_derive_init
,
339 const EVP_PKEY_METHOD
*scrypt_pkey_method(void)
341 return &scrypt_pkey_meth
;
345 static const EVP_PKEY_METHOD tls1_prf_pkey_meth
= {
369 pkey_kdf_derive_init
,
375 const EVP_PKEY_METHOD
*tls1_prf_pkey_method(void)
377 return &tls1_prf_pkey_meth
;
380 static const EVP_PKEY_METHOD hkdf_pkey_meth
= {
404 pkey_kdf_derive_init
,
410 const EVP_PKEY_METHOD
*hkdf_pkey_method(void)
412 return &hkdf_pkey_meth
;