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
,
194 * These are special because the helper macros pass a pointer to the
195 * stack, so a local copy is required.
198 params
[0] = OSSL_PARAM_construct_int(name
, &p1
);
202 params
[0] = OSSL_PARAM_construct_uint64(name
, (uint64_t *)p2
);
206 return EVP_KDF_CTX_set_params(kctx
, params
);
209 static int pkey_kdf_ctrl_str(EVP_PKEY_CTX
*ctx
, const char *type
,
212 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
213 EVP_KDF_CTX
*kctx
= pkctx
->kctx
;
214 const EVP_KDF
*kdf
= EVP_KDF_CTX_kdf(kctx
);
215 BUF_MEM
**collector
= NULL
;
216 const OSSL_PARAM
*defs
= EVP_KDF_settable_ctx_params(kdf
);
217 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
220 /* Deal with ctrl name aliasing */
221 if (strcmp(type
, "md") == 0)
222 type
= OSSL_KDF_PARAM_DIGEST
;
223 /* scrypt uses 'N', params uses 'n' */
224 if (strcmp(type
, "N") == 0)
225 type
= OSSL_KDF_PARAM_SCRYPT_N
;
227 if (!OSSL_PARAM_allocate_from_text(¶ms
[0], defs
, type
,
228 value
, strlen(value
)))
232 * We do the same special casing of seed and info here as in
235 if (strcmp(params
[0].key
, OSSL_KDF_PARAM_SEED
) == 0)
236 collector
= &pkctx
->collected_seed
;
237 else if (strcmp(params
[0].key
, OSSL_KDF_PARAM_INFO
) == 0)
238 collector
= &pkctx
->collected_info
;
240 if (collector
!= NULL
)
241 ok
= collect(collector
, params
[0].data
, params
[0].data_size
);
243 ok
= EVP_KDF_CTX_set_params(kctx
, params
);
244 OPENSSL_free(params
[0].data
);
248 static int pkey_kdf_derive_init(EVP_PKEY_CTX
*ctx
)
250 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
252 pkey_kdf_free_collected(pkctx
);
253 if (pkctx
->kctx
!= NULL
)
254 EVP_KDF_reset(pkctx
->kctx
);
259 * For fixed-output algorithms the keylen parameter is an "out" parameter
260 * otherwise it is an "in" parameter.
262 static int pkey_kdf_derive(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
265 EVP_PKEY_KDF_CTX
*pkctx
= ctx
->data
;
266 EVP_KDF_CTX
*kctx
= pkctx
->kctx
;
267 size_t outlen
= EVP_KDF_size(kctx
);
270 if (pkctx
->collected_seed
!= NULL
) {
271 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
274 OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED
,
275 pkctx
->collected_seed
->data
,
276 pkctx
->collected_seed
->length
);
278 r
= EVP_KDF_CTX_set_params(kctx
, params
);
279 pkey_kdf_free_collected(pkctx
);
283 if (pkctx
->collected_info
!= NULL
) {
284 OSSL_PARAM params
[] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
287 OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO
,
288 pkctx
->collected_info
->data
,
289 pkctx
->collected_info
->length
);
291 r
= EVP_KDF_CTX_set_params(kctx
, params
);
292 pkey_kdf_free_collected(pkctx
);
296 if (outlen
== 0 || outlen
== SIZE_MAX
) {
297 /* Variable-output algorithm */
301 /* Fixed-output algorithm */
306 return EVP_KDF_derive(kctx
, key
, *keylen
);
309 #ifndef OPENSSL_NO_SCRYPT
310 static const EVP_PKEY_METHOD scrypt_pkey_meth
= {
334 pkey_kdf_derive_init
,
340 const EVP_PKEY_METHOD
*scrypt_pkey_method(void)
342 return &scrypt_pkey_meth
;
346 static const EVP_PKEY_METHOD tls1_prf_pkey_meth
= {
370 pkey_kdf_derive_init
,
376 const EVP_PKEY_METHOD
*tls1_prf_pkey_method(void)
378 return &tls1_prf_pkey_meth
;
381 static const EVP_PKEY_METHOD hkdf_pkey_meth
= {
405 pkey_kdf_derive_init
,
411 const EVP_PKEY_METHOD
*hkdf_pkey_method(void)
413 return &hkdf_pkey_meth
;