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;