EVP: Add new domparams and key generation functionality
[openssl.git] / crypto / evp / pmeth_gn.c
1 /*
2  * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
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"
22
23 static int gen_init(EVP_PKEY_CTX *ctx, int operation)
24 {
25     int ret = 0;
26
27     if (ctx == NULL)
28         goto not_supported;
29
30     evp_pkey_ctx_free_old_ops(ctx);
31     ctx->operation = operation;
32
33     if (ctx->engine != NULL || ctx->keytype == NULL)
34         goto legacy;
35
36     if (ctx->keymgmt == NULL) {
37         ctx->keymgmt =
38             EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype, ctx->propquery);
39         if (ctx->keymgmt == NULL
40             || ctx->keymgmt->gen_init == NULL) {
41             EVP_KEYMGMT_free(ctx->keymgmt);
42             ctx->keymgmt = NULL;
43             goto legacy;
44         }
45     }
46     if (ctx->keymgmt->gen_init == NULL)
47         goto not_supported;
48
49     switch (operation) {
50     case EVP_PKEY_OP_PARAMGEN:
51         ctx->op.keymgmt.genctx =
52             evp_keymgmt_gen_init(ctx->keymgmt,
53                                  OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
54         break;
55     case EVP_PKEY_OP_KEYGEN:
56         ctx->op.keymgmt.genctx =
57             evp_keymgmt_gen_init(ctx->keymgmt, OSSL_KEYMGMT_SELECT_KEYPAIR);
58         break;
59     }
60
61     if (ctx->op.keymgmt.genctx == NULL)
62         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
63     else
64         ret = 1;
65     goto end;
66
67  legacy:
68 #ifdef FIPS_MODE
69     goto not_supported;
70 #else
71     if (ctx->pmeth == NULL
72         || (operation == EVP_PKEY_OP_PARAMGEN
73             && ctx->pmeth->paramgen == NULL)
74         || (operation == EVP_PKEY_OP_KEYGEN
75             && ctx->pmeth->keygen == NULL))
76         goto not_supported;
77
78     ret = 1;
79     switch (operation) {
80     case EVP_PKEY_OP_PARAMGEN:
81         if (ctx->pmeth->paramgen_init != NULL)
82             ret = ctx->pmeth->paramgen_init(ctx);
83         break;
84     case EVP_PKEY_OP_KEYGEN:
85         if (ctx->pmeth->keygen_init != NULL)
86             ret = ctx->pmeth->keygen_init(ctx);
87         break;
88     }
89 #endif
90
91  end:
92     if (ret <= 0)
93         ctx->operation = EVP_PKEY_OP_UNDEFINED;
94     return ret;
95
96  not_supported:
97     ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
98     ret = -2;
99     goto end;
100 }
101
102 int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
103 {
104     return gen_init(ctx, EVP_PKEY_OP_PARAMGEN);
105 }
106
107 int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
108 {
109     return gen_init(ctx, EVP_PKEY_OP_KEYGEN);
110 }
111
112 static int ossl_callback_to_pkey_gencb(const OSSL_PARAM params[], void *arg)
113 {
114     EVP_PKEY_CTX *ctx = arg;
115     const OSSL_PARAM *param = NULL;
116     int p = -1, n = -1;
117
118     if (ctx->pkey_gencb == NULL)
119         return 1;                /* No callback?  That's fine */
120
121     if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_POTENTIAL))
122         == NULL
123         || !OSSL_PARAM_get_int(param, &p))
124         return 0;
125     if ((param = OSSL_PARAM_locate_const(params, OSSL_GEN_PARAM_ITERATION))
126         == NULL
127         || !OSSL_PARAM_get_int(param, &n))
128         return 0;
129
130     ctx->keygen_info[0] = p;
131     ctx->keygen_info[1] = n;
132
133     return ctx->pkey_gencb(ctx);
134 }
135
136 int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
137 {
138     int ret = 0;
139     OSSL_CALLBACK cb;
140     EVP_PKEY *allocated_pkey = NULL;
141
142     if (ppkey == NULL)
143         return -1;
144
145     if (ctx == NULL)
146         goto not_supported;
147
148     if ((ctx->operation & EVP_PKEY_OP_TYPE_GEN) == 0)
149         goto not_initialized;
150
151     if (*ppkey == NULL)
152         *ppkey = allocated_pkey = EVP_PKEY_new();
153
154     if (*ppkey == NULL) {
155         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
156         return -1;
157     }
158
159     if (ctx->keymgmt == NULL)
160         goto legacy;
161
162     ret = 1;
163     if (ctx->pkey != NULL) {
164         EVP_KEYMGMT *tmp_keymgmt = ctx->keymgmt;
165         void *keydata =
166             evp_pkey_export_to_provider(ctx->pkey, ctx->libctx,
167                                         &tmp_keymgmt, ctx->propquery);
168
169         if (keydata == NULL)
170             goto not_supported;
171         ret = evp_keymgmt_gen_set_template(ctx->keymgmt,
172                                            ctx->op.keymgmt.genctx, keydata);
173     }
174
175     /*
176      * the returned value from evp_keymgmt_util_gen() is cached in *ppkey,
177      * so we so not need to save it, just check it.
178      */
179     ret = ret
180         && (evp_keymgmt_util_gen(*ppkey, ctx->keymgmt, ctx->op.keymgmt.genctx,
181                                  ossl_callback_to_pkey_gencb, ctx)
182             != NULL);
183
184 #ifndef FIPS_MODE
185     /* In case |*ppkey| was originally a legacy key */
186     if (ret)
187         evp_pkey_free_legacy(*ppkey);
188 #endif
189
190     goto end;
191
192  legacy:
193 #ifdef FIPS_MODE
194     goto not_supported;
195 #else
196     switch (ctx->operation) {
197     case EVP_PKEY_OP_PARAMGEN:
198         ret = ctx->pmeth->paramgen(ctx, *ppkey);
199         break;
200     case EVP_PKEY_OP_KEYGEN:
201         ret = ctx->pmeth->keygen(ctx, *ppkey);
202         break;
203     default:
204         goto not_supported;
205     }
206 #endif
207
208  end:
209     if (ret <= 0) {
210         if (allocated_pkey != NULL)
211             *ppkey = NULL;
212         EVP_PKEY_free(allocated_pkey);
213     }
214     return ret;
215
216  not_supported:
217     ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
218     ret = -2;
219     goto end;
220  not_initialized:
221     ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
222     ret = -1;
223     goto end;
224 }
225
226 int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
227 {
228     if (ctx->operation != EVP_PKEY_OP_PARAMGEN) {
229         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
230         return -1;
231     }
232     return EVP_PKEY_gen(ctx, ppkey);
233 }
234
235 int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
236 {
237     if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
238         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATON_NOT_INITIALIZED);
239         return -1;
240     }
241     return EVP_PKEY_gen(ctx, ppkey);
242 }
243
244 void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
245 {
246     ctx->pkey_gencb = cb;
247 }
248
249 EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx)
250 {
251     return ctx->pkey_gencb;
252 }
253
254 /*
255  * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style
256  * callbacks.
257  */
258
259 static int trans_cb(int a, int b, BN_GENCB *gcb)
260 {
261     EVP_PKEY_CTX *ctx = BN_GENCB_get_arg(gcb);
262     ctx->keygen_info[0] = a;
263     ctx->keygen_info[1] = b;
264     return ctx->pkey_gencb(ctx);
265 }
266
267 void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
268 {
269     BN_GENCB_set(cb, trans_cb, ctx);
270 }
271
272 int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
273 {
274     if (idx == -1)
275         return ctx->keygen_info_count;
276     if (idx < 0 || idx > ctx->keygen_info_count)
277         return 0;
278     return ctx->keygen_info[idx];
279 }
280
281 #ifndef FIPS_MODE
282
283 EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
284                                const unsigned char *key, int keylen)
285 {
286     EVP_PKEY_CTX *mac_ctx = NULL;
287     EVP_PKEY *mac_key = NULL;
288     mac_ctx = EVP_PKEY_CTX_new_id(type, e);
289     if (!mac_ctx)
290         return NULL;
291     if (EVP_PKEY_keygen_init(mac_ctx) <= 0)
292         goto merr;
293     if (EVP_PKEY_CTX_set_mac_key(mac_ctx, key, keylen) <= 0)
294         goto merr;
295     if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0)
296         goto merr;
297  merr:
298     EVP_PKEY_CTX_free(mac_ctx);
299     return mac_key;
300 }
301
302 #endif /* FIPS_MODE */
303
304 /*- All methods below can also be used in FIPS_MODE */
305
306 static int fromdata_init(EVP_PKEY_CTX *ctx, int operation)
307 {
308     if (ctx == NULL || ctx->keytype == NULL)
309         goto not_supported;
310
311     evp_pkey_ctx_free_old_ops(ctx);
312     ctx->operation = operation;
313     if (ctx->keymgmt == NULL)
314         ctx->keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ctx->keytype,
315                                          ctx->propquery);
316     if (ctx->keymgmt == NULL)
317         goto not_supported;
318
319     return 1;
320
321  not_supported:
322     ctx->operation = EVP_PKEY_OP_UNDEFINED;
323     ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
324     return -2;
325 }
326
327 int EVP_PKEY_param_fromdata_init(EVP_PKEY_CTX *ctx)
328 {
329     return fromdata_init(ctx, EVP_PKEY_OP_PARAMFROMDATA);
330 }
331
332 int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx)
333 {
334     return fromdata_init(ctx, EVP_PKEY_OP_KEYFROMDATA);
335 }
336
337 int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM params[])
338 {
339     void *keydata = NULL;
340     int selection;
341
342     if (ctx == NULL || (ctx->operation & EVP_PKEY_OP_TYPE_FROMDATA) == 0) {
343         ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
344         return -2;
345     }
346
347     if (ppkey == NULL)
348         return -1;
349
350     if (*ppkey == NULL)
351         *ppkey = EVP_PKEY_new();
352
353     if (*ppkey == NULL) {
354         ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE);
355         return -1;
356     }
357
358     if (ctx->operation == EVP_PKEY_OP_PARAMFROMDATA)
359         selection = OSSL_KEYMGMT_SELECT_ALL_PARAMETERS;
360     else
361         selection = OSSL_KEYMGMT_SELECT_ALL;
362     keydata = evp_keymgmt_util_fromdata(*ppkey, ctx->keymgmt, selection,
363                                         params);
364
365     if (keydata == NULL)
366         return 0;
367     /* keydata is cached in *ppkey, so we need not bother with it further */
368     return 1;
369 }
370
371 /*
372  * TODO(3.0) Re-evaluate the names, it's possible that we find these to be
373  * better:
374  *
375  * EVP_PKEY_param_settable()
376  * EVP_PKEY_param_gettable()
377  */
378 const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx)
379 {
380     /* We call fromdata_init to get ctx->keymgmt populated */
381     if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
382         return evp_keymgmt_import_types(ctx->keymgmt,
383                                         OSSL_KEYMGMT_SELECT_ALL_PARAMETERS);
384     return NULL;
385 }
386
387 const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
388 {
389     /* We call fromdata_init to get ctx->keymgmt populated */
390     if (fromdata_init(ctx, EVP_PKEY_OP_UNDEFINED))
391         return evp_keymgmt_import_types(ctx->keymgmt,
392                                         OSSL_KEYMGMT_SELECT_ALL);
393     return NULL;
394 }