2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <openssl/core.h>
13 #include <openssl/core_names.h>
14 #include "internal/cryptlib.h"
15 #include "internal/core.h"
16 #include <openssl/objects.h>
17 #include <openssl/evp.h>
18 #include "crypto/bn.h"
19 #include "crypto/asn1.h"
20 #include "crypto/evp.h"
21 #include "evp_local.h"
23 static int gen_init(EVP_PKEY_CTX
*ctx
, int operation
)
30 evp_pkey_ctx_free_old_ops(ctx
);
31 ctx
->operation
= operation
;
33 if (ctx
->keymgmt
== NULL
|| ctx
->keymgmt
->gen_init
== NULL
)
37 case EVP_PKEY_OP_PARAMGEN
:
38 ctx
->op
.keymgmt
.genctx
=
39 evp_keymgmt_gen_init(ctx
->keymgmt
,
40 OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
);
42 case EVP_PKEY_OP_KEYGEN
:
43 ctx
->op
.keymgmt
.genctx
=
44 evp_keymgmt_gen_init(ctx
->keymgmt
, OSSL_KEYMGMT_SELECT_KEYPAIR
);
48 if (ctx
->op
.keymgmt
.genctx
== NULL
)
49 ERR_raise(ERR_LIB_EVP
, EVP_R_INITIALIZATION_ERROR
);
58 if (ctx
->pmeth
== NULL
59 || (operation
== EVP_PKEY_OP_PARAMGEN
60 && ctx
->pmeth
->paramgen
== NULL
)
61 || (operation
== EVP_PKEY_OP_KEYGEN
62 && ctx
->pmeth
->keygen
== NULL
))
67 case EVP_PKEY_OP_PARAMGEN
:
68 if (ctx
->pmeth
->paramgen_init
!= NULL
)
69 ret
= ctx
->pmeth
->paramgen_init(ctx
);
71 case EVP_PKEY_OP_KEYGEN
:
72 if (ctx
->pmeth
->keygen_init
!= NULL
)
73 ret
= ctx
->pmeth
->keygen_init(ctx
);
79 if (ret
<= 0 && ctx
!= NULL
) {
80 evp_pkey_ctx_free_old_ops(ctx
);
81 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
86 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
91 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX
*ctx
)
93 return gen_init(ctx
, EVP_PKEY_OP_PARAMGEN
);
96 int EVP_PKEY_keygen_init(EVP_PKEY_CTX
*ctx
)
98 return gen_init(ctx
, EVP_PKEY_OP_KEYGEN
);
101 static int ossl_callback_to_pkey_gencb(const OSSL_PARAM params
[], void *arg
)
103 EVP_PKEY_CTX
*ctx
= arg
;
104 const OSSL_PARAM
*param
= NULL
;
107 if (ctx
->pkey_gencb
== NULL
)
108 return 1; /* No callback? That's fine */
110 if ((param
= OSSL_PARAM_locate_const(params
, OSSL_GEN_PARAM_POTENTIAL
))
112 || !OSSL_PARAM_get_int(param
, &p
))
114 if ((param
= OSSL_PARAM_locate_const(params
, OSSL_GEN_PARAM_ITERATION
))
116 || !OSSL_PARAM_get_int(param
, &n
))
119 ctx
->keygen_info
[0] = p
;
120 ctx
->keygen_info
[1] = n
;
122 return ctx
->pkey_gencb(ctx
);
125 int EVP_PKEY_gen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
**ppkey
)
129 EVP_PKEY
*allocated_pkey
= NULL
;
130 /* Legacy compatible keygen callback info, only used with provider impls */
139 if ((ctx
->operation
& EVP_PKEY_OP_TYPE_GEN
) == 0)
140 goto not_initialized
;
143 *ppkey
= allocated_pkey
= EVP_PKEY_new();
145 if (*ppkey
== NULL
) {
146 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
150 if (ctx
->op
.keymgmt
.genctx
== NULL
)
154 * Asssigning gentmp to ctx->keygen_info is something our legacy
155 * implementations do. Because the provider implementations aren't
156 * allowed to reach into our EVP_PKEY_CTX, we need to provide similar
157 * space for backward compatibility. It's ok that we attach a local
158 * variable, as it should only be useful in the calls down from here.
159 * This is cleared as soon as it isn't useful any more, i.e. directly
160 * after the evp_keymgmt_util_gen() call.
162 ctx
->keygen_info
= gentmp
;
163 ctx
->keygen_info_count
= 2;
166 if (ctx
->pkey
!= NULL
) {
167 EVP_KEYMGMT
*tmp_keymgmt
= ctx
->keymgmt
;
169 evp_pkey_export_to_provider(ctx
->pkey
, ctx
->libctx
,
170 &tmp_keymgmt
, ctx
->propquery
);
172 if (tmp_keymgmt
== NULL
)
175 * It's ok if keydata is NULL here. The backend is expected to deal
176 * with that as it sees fit.
178 ret
= evp_keymgmt_gen_set_template(ctx
->keymgmt
,
179 ctx
->op
.keymgmt
.genctx
, keydata
);
183 * the returned value from evp_keymgmt_util_gen() is cached in *ppkey,
184 * so we so not need to save it, just check it.
187 && (evp_keymgmt_util_gen(*ppkey
, ctx
->keymgmt
, ctx
->op
.keymgmt
.genctx
,
188 ossl_callback_to_pkey_gencb
, ctx
)
191 ctx
->keygen_info
= NULL
;
194 /* In case |*ppkey| was originally a legacy key */
196 evp_pkey_free_legacy(*ppkey
);
200 * Because we still have legacy keys, and evp_pkey_downgrade()
201 * TODO remove this #legacy internal keys are gone
203 (*ppkey
)->type
= ctx
->legacy_keytype
;
211 if (ctx
->pkey
&& !evp_pkey_downgrade(ctx
->pkey
))
213 switch (ctx
->operation
) {
214 case EVP_PKEY_OP_PARAMGEN
:
215 ret
= ctx
->pmeth
->paramgen(ctx
, *ppkey
);
217 case EVP_PKEY_OP_KEYGEN
:
218 ret
= ctx
->pmeth
->keygen(ctx
, *ppkey
);
227 if (allocated_pkey
!= NULL
)
229 EVP_PKEY_free(allocated_pkey
);
234 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
238 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATON_NOT_INITIALIZED
);
243 ERR_raise(ERR_LIB_EVP
, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS
);
249 int EVP_PKEY_paramgen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
**ppkey
)
251 if (ctx
->operation
!= EVP_PKEY_OP_PARAMGEN
) {
252 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATON_NOT_INITIALIZED
);
255 return EVP_PKEY_gen(ctx
, ppkey
);
258 int EVP_PKEY_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
**ppkey
)
260 if (ctx
->operation
!= EVP_PKEY_OP_KEYGEN
) {
261 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATON_NOT_INITIALIZED
);
264 return EVP_PKEY_gen(ctx
, ppkey
);
267 void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX
*ctx
, EVP_PKEY_gen_cb
*cb
)
269 ctx
->pkey_gencb
= cb
;
272 EVP_PKEY_gen_cb
*EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX
*ctx
)
274 return ctx
->pkey_gencb
;
278 * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
282 static int trans_cb(int a
, int b
, BN_GENCB
*gcb
)
284 EVP_PKEY_CTX
*ctx
= BN_GENCB_get_arg(gcb
);
285 ctx
->keygen_info
[0] = a
;
286 ctx
->keygen_info
[1] = b
;
287 return ctx
->pkey_gencb(ctx
);
290 void evp_pkey_set_cb_translate(BN_GENCB
*cb
, EVP_PKEY_CTX
*ctx
)
292 BN_GENCB_set(cb
, trans_cb
, ctx
);
295 int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX
*ctx
, int idx
)
298 return ctx
->keygen_info_count
;
299 if (idx
< 0 || idx
> ctx
->keygen_info_count
)
301 return ctx
->keygen_info
[idx
];
306 EVP_PKEY
*EVP_PKEY_new_mac_key(int type
, ENGINE
*e
,
307 const unsigned char *key
, int keylen
)
309 EVP_PKEY_CTX
*mac_ctx
= NULL
;
310 EVP_PKEY
*mac_key
= NULL
;
311 mac_ctx
= EVP_PKEY_CTX_new_id(type
, e
);
314 if (EVP_PKEY_keygen_init(mac_ctx
) <= 0)
316 if (EVP_PKEY_CTX_set_mac_key(mac_ctx
, key
, keylen
) <= 0)
318 if (EVP_PKEY_keygen(mac_ctx
, &mac_key
) <= 0)
321 EVP_PKEY_CTX_free(mac_ctx
);
325 #endif /* FIPS_MODULE */
327 /*- All methods below can also be used in FIPS_MODULE */
329 static int fromdata_init(EVP_PKEY_CTX
*ctx
, int operation
)
331 if (ctx
== NULL
|| ctx
->keytype
== NULL
)
334 evp_pkey_ctx_free_old_ops(ctx
);
335 if (ctx
->keymgmt
== NULL
)
338 ctx
->operation
= operation
;
343 ctx
->operation
= EVP_PKEY_OP_UNDEFINED
;
344 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
348 int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX
*ctx
)
350 return fromdata_init(ctx
, EVP_PKEY_OP_PARAMFROMDATA
);
353 int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX
*ctx
)
355 return fromdata_init(ctx
, EVP_PKEY_OP_KEYFROMDATA
);
358 int EVP_PKEY_fromdata(EVP_PKEY_CTX
*ctx
, EVP_PKEY
**ppkey
, OSSL_PARAM params
[])
360 void *keydata
= NULL
;
363 if (ctx
== NULL
|| (ctx
->operation
& EVP_PKEY_OP_TYPE_FROMDATA
) == 0) {
364 ERR_raise(ERR_LIB_EVP
, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
);
372 *ppkey
= EVP_PKEY_new();
374 if (*ppkey
== NULL
) {
375 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);
379 if (ctx
->operation
== EVP_PKEY_OP_PARAMFROMDATA
)
380 selection
= OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
;
382 selection
= OSSL_KEYMGMT_SELECT_ALL
;
383 keydata
= evp_keymgmt_util_fromdata(*ppkey
, ctx
->keymgmt
, selection
,
388 /* keydata is cached in *ppkey, so we need not bother with it further */
393 * TODO(3.0) Re-evaluate the names, it's possible that we find these to be
396 * EVP_PKEY_param_settable()
397 * EVP_PKEY_param_gettable()
399 const OSSL_PARAM
*EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX
*ctx
)
401 /* We call fromdata_init to get ctx->keymgmt populated */
402 if (fromdata_init(ctx
, EVP_PKEY_OP_UNDEFINED
))
403 return evp_keymgmt_import_types(ctx
->keymgmt
,
404 OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
);
408 const OSSL_PARAM
*EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX
*ctx
)
410 /* We call fromdata_init to get ctx->keymgmt populated */
411 if (fromdata_init(ctx
, EVP_PKEY_OP_UNDEFINED
))
412 return evp_keymgmt_import_types(ctx
->keymgmt
,
413 OSSL_KEYMGMT_SELECT_ALL
);