354ca0c5bb6f4a0b525ae319bcb7524634aa207c
[openssl.git] / providers / implementations / keymgmt / ec_kmgmt.c
1 /*
2  * Copyright 2020 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 /*
11  * ECDH/ECDSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <openssl/core_numbers.h>
17 #include <openssl/core_names.h>
18 #include <openssl/bn.h>
19 #include <openssl/objects.h>
20 #include <openssl/params.h>
21 #include "crypto/bn.h"
22 #include "crypto/ec.h"
23 #include "internal/param_build.h"
24 #include "prov/implementations.h"
25 #include "prov/providercommon.h"
26 #include "prov/provider_ctx.h"
27
28 static OSSL_OP_keymgmt_new_fn ec_newdata;
29 static OSSL_OP_keymgmt_free_fn ec_freedata;
30 static OSSL_OP_keymgmt_get_params_fn ec_get_params;
31 static OSSL_OP_keymgmt_gettable_params_fn ec_gettable_params;
32 static OSSL_OP_keymgmt_set_params_fn ec_set_params;
33 static OSSL_OP_keymgmt_settable_params_fn ec_settable_params;
34 static OSSL_OP_keymgmt_has_fn ec_has;
35 static OSSL_OP_keymgmt_match_fn ec_match;
36 static OSSL_OP_keymgmt_validate_fn ec_validate;
37 static OSSL_OP_keymgmt_import_fn ec_import;
38 static OSSL_OP_keymgmt_import_types_fn ec_import_types;
39 static OSSL_OP_keymgmt_export_fn ec_export;
40 static OSSL_OP_keymgmt_export_types_fn ec_export_types;
41 static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name;
42
43 #define EC_POSSIBLE_SELECTIONS                 \
44     (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
45
46 static
47 const char *ec_query_operation_name(int operation_id)
48 {
49     switch (operation_id) {
50     case OSSL_OP_KEYEXCH:
51         return "ECDH";
52     case OSSL_OP_SIGNATURE:
53         return "ECDSA";
54     }
55     return NULL;
56 }
57
58 static ossl_inline
59 int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
60 {
61     const EC_GROUP *ecg;
62     int curve_nid;
63
64     if (ec == NULL)
65         return 0;
66
67     ecg = EC_KEY_get0_group(ec);
68     if (ecg == NULL)
69         return 0;
70
71     curve_nid = EC_GROUP_get_curve_name(ecg);
72
73     if (curve_nid == NID_undef) {
74         /* explicit parameters */
75
76         /*
77          * TODO(3.0): should we support explicit parameters curves?
78          */
79         return 0;
80     } else {
81         /* named curve */
82         const char *curve_name = NULL;
83
84         if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
85             return 0;
86
87         if (!ossl_param_bld_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME,
88                                              curve_name, 0))
89             return 0;
90     }
91
92     return 1;
93 }
94
95 /*
96  * Callers of key_to_params MUST make sure that domparams_to_params is also
97  * called!
98  *
99  * This function only exports the bare keypair, domain parameters and other
100  * parameters are exported separately.
101  */
102 static ossl_inline
103 int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private)
104 {
105     const BIGNUM *priv_key = NULL;
106     const EC_POINT *pub_point = NULL;
107     const EC_GROUP *ecg = NULL;
108     unsigned char *pub_key = NULL;
109     size_t pub_key_len = 0;
110     int ret = 0;
111
112     if (eckey == NULL)
113         return 0;
114
115     ecg = EC_KEY_get0_group(eckey);
116     priv_key = EC_KEY_get0_private_key(eckey);
117     pub_point = EC_KEY_get0_public_key(eckey);
118
119     /* group and public_key must be present, priv_key is optional */
120     if (ecg == NULL || pub_point == NULL)
121         return 0;
122     if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
123                                           POINT_CONVERSION_COMPRESSED,
124                                           &pub_key, NULL)) == 0)
125         return 0;
126
127     if (!ossl_param_bld_push_octet_string(tmpl,
128                                           OSSL_PKEY_PARAM_PUB_KEY,
129                                           pub_key, pub_key_len))
130         goto err;
131
132     if (priv_key != NULL && include_private) {
133         size_t sz;
134         int ecbits;
135
136         /*
137          * Key import/export should never leak the bit length of the secret
138          * scalar in the key.
139          *
140          * For this reason, on export we use padded BIGNUMs with fixed length.
141          *
142          * When importing we also should make sure that, even if short lived,
143          * the newly created BIGNUM is marked with the BN_FLG_CONSTTIME flag as
144          * soon as possible, so that any processing of this BIGNUM might opt for
145          * constant time implementations in the backend.
146          *
147          * Setting the BN_FLG_CONSTTIME flag alone is never enough, we also have
148          * to preallocate the BIGNUM internal buffer to a fixed public size big
149          * enough that operations performed during the processing never trigger
150          * a realloc which would leak the size of the scalar through memory
151          * accesses.
152          *
153          * Fixed Length
154          * ------------
155          *
156          * The order of the large prime subgroup of the curve is our choice for
157          * a fixed public size, as that is generally the upper bound for
158          * generating a private key in EC cryptosystems and should fit all valid
159          * secret scalars.
160          *
161          * For padding on export we just use the bit length of the order
162          * converted to bytes (rounding up).
163          *
164          * For preallocating the BIGNUM storage we look at the number of "words"
165          * required for the internal representation of the order, and we
166          * preallocate 2 extra "words" in case any of the subsequent processing
167          * might temporarily overflow the order length.
168          */
169         ecbits = EC_GROUP_order_bits(ecg);
170         if (ecbits <= 0)
171             goto err;
172         sz = (ecbits + 7 ) / 8;
173         if (!ossl_param_bld_push_BN_pad(tmpl,
174                                         OSSL_PKEY_PARAM_PRIV_KEY,
175                                         priv_key, sz))
176             goto err;
177     }
178
179     ret = 1;
180
181  err:
182     OPENSSL_free(pub_key);
183     return ret;
184 }
185
186 static ossl_inline
187 int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
188 {
189     int ecdh_cofactor_mode = 0;
190
191     if (ec == NULL)
192         return 0;
193
194     ecdh_cofactor_mode =
195         (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
196     if (!ossl_param_bld_push_int(tmpl,
197                 OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
198                 ecdh_cofactor_mode))
199         return 0;
200
201     return 1;
202 }
203
204 static
205 void *ec_newdata(void *provctx)
206 {
207     return EC_KEY_new_ex(PROV_LIBRARY_CONTEXT_OF(provctx));
208 }
209
210 static
211 void ec_freedata(void *keydata)
212 {
213     EC_KEY_free(keydata);
214 }
215
216 static
217 int ec_has(void *keydata, int selection)
218 {
219     EC_KEY *ec = keydata;
220     int ok = 0;
221
222     if (ec != NULL) {
223         if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
224             ok = 1;
225
226         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
227             ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
228         if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
229             ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
230         if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
231             ok = ok && (EC_KEY_get0_group(ec) != NULL);
232         /*
233          * We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be
234          * available, so no extra check is needed other than the previous one
235          * against EC_POSSIBLE_SELECTIONS.
236          */
237     }
238     return ok;
239 }
240
241 static int ec_match(const void *keydata1, const void *keydata2, int selection)
242 {
243     const EC_KEY *ec1 = keydata1;
244     const EC_KEY *ec2 = keydata2;
245     const EC_GROUP *group_a = EC_KEY_get0_group(ec1);
246     const EC_GROUP *group_b = EC_KEY_get0_group(ec2);
247     int ok = 1;
248
249     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
250         ok = ok && group_a != NULL && group_b != NULL
251             && EC_GROUP_cmp(group_a, group_b, NULL) == 0;
252     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
253         const BIGNUM *pa = EC_KEY_get0_private_key(ec1);
254         const BIGNUM *pb = EC_KEY_get0_private_key(ec2);
255
256         ok = ok && BN_cmp(pa, pb) == 0;
257     }
258     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
259         const EC_POINT *pa = EC_KEY_get0_public_key(ec1);
260         const EC_POINT *pb = EC_KEY_get0_public_key(ec2);
261
262         ok = ok && EC_POINT_cmp(group_b, pa, pb, NULL);
263     }
264     return ok;
265 }
266
267 static
268 int ec_import(void *keydata, int selection, const OSSL_PARAM params[])
269 {
270     EC_KEY *ec = keydata;
271     int ok = 1;
272
273     if (ec == NULL)
274         return 0;
275
276     /*
277      * In this implementation, we can export/import only keydata in the
278      * following combinations:
279      *   - domain parameters only
280      *   - public key with associated domain parameters (+optional other params)
281      *   - private key with associated public key and domain parameters
282      *         (+optional other params)
283      *
284      * This means:
285      *   - domain parameters must always be requested
286      *   - private key must be requested alongside public key
287      *   - other parameters must be requested only alongside a key
288      */
289     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
290         return 0;
291     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
292             && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
293         return 0;
294     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
295             && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
296         return 0;
297
298     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
299         ok = ok && ec_key_domparams_fromdata(ec, params);
300     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
301         int include_private =
302             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
303
304         ok = ok && ec_key_fromdata(ec, params, include_private);
305     }
306     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
307         ok = ok && ec_key_otherparams_fromdata(ec, params);
308
309     return ok;
310 }
311
312 static
313 int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
314               void *cbarg)
315 {
316     EC_KEY *ec = keydata;
317     OSSL_PARAM_BLD tmpl;
318     OSSL_PARAM *params = NULL;
319     int ok = 1;
320
321     if (ec == NULL)
322         return 0;
323
324     /*
325      * In this implementation, we can export/import only keydata in the
326      * following combinations:
327      *   - domain parameters only
328      *   - public key with associated domain parameters (+optional other params)
329      *   - private key with associated public key and domain parameters
330      *         (+optional other params)
331      *
332      * This means:
333      *   - domain parameters must always be requested
334      *   - private key must be requested alongside public key
335      *   - other parameters must be requested only alongside a key
336      */
337     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0)
338         return 0;
339     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
340             && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
341         return 0;
342     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
343             && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
344         return 0;
345
346     ossl_param_bld_init(&tmpl);
347
348     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
349         ok = ok && domparams_to_params(ec, &tmpl);
350     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
351         int include_private =
352             selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
353
354         ok = ok && key_to_params(ec, &tmpl, include_private);
355     }
356     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
357         ok = ok && otherparams_to_params(ec, &tmpl);
358
359     if (!ok
360         || (params = ossl_param_bld_to_param(&tmpl)) == NULL)
361         return 0;
362
363     ok = param_cb(params, cbarg);
364     ossl_param_bld_free(params);
365     return ok;
366 }
367
368 /* IMEXPORT = IMPORT + EXPORT */
369
370 # define EC_IMEXPORTABLE_DOM_PARAMETERS                          \
371     OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_NAME, NULL, 0)
372 # define EC_IMEXPORTABLE_PUBLIC_KEY                              \
373     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
374 # define EC_IMEXPORTABLE_PRIVATE_KEY                             \
375     OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
376 # define EC_IMEXPORTABLE_OTHER_PARAMETERS                        \
377     OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL)
378
379 /*
380  * Include all the possible combinations of OSSL_PARAM arrays for
381  * ec_imexport_types().
382  *
383  * They are in a separate file as it is ~100 lines of unreadable and
384  * uninteresting machine generated stuff.
385  *
386  * TODO(3.0): the generated list looks quite ugly, as to cover all possible
387  * combinations of the bits in `selection`, it also includes combinations that
388  * are not really useful: we might want to consider alternatives to this
389  * solution.
390  */
391 #include "ec_kmgmt_imexport.inc"
392
393 static ossl_inline
394 const OSSL_PARAM *ec_imexport_types(int selection)
395 {
396     int type_select = 0;
397
398     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
399         type_select += 1;
400     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
401         type_select += 2;
402     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
403         type_select += 4;
404     if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
405         type_select += 8;
406     return ec_types[type_select];
407 }
408
409 static
410 const OSSL_PARAM *ec_import_types(int selection)
411 {
412     return ec_imexport_types(selection);
413 }
414
415 static
416 const OSSL_PARAM *ec_export_types(int selection)
417 {
418     return ec_imexport_types(selection);
419 }
420
421 static
422 int ec_get_params(void *key, OSSL_PARAM params[])
423 {
424     EC_KEY *eck = key;
425     const EC_GROUP *ecg = NULL;
426     OSSL_PARAM *p;
427
428     ecg = EC_KEY_get0_group(eck);
429     if (ecg == NULL)
430         return 0;
431
432     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
433         && !OSSL_PARAM_set_int(p, ECDSA_size(eck)))
434         return 0;
435     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
436         && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg)))
437         return 0;
438     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL) {
439         int ecbits, sec_bits;
440
441         ecbits = EC_GROUP_order_bits(ecg);
442
443         /*
444          * The following estimates are based on the values published
445          * in Table 2 of "NIST Special Publication 800-57 Part 1 Revision 4"
446          * at http://dx.doi.org/10.6028/NIST.SP.800-57pt1r4 .
447          *
448          * Note that the above reference explicitly categorizes algorithms in a
449          * discrete set of values {80, 112, 128, 192, 256}, and that it is
450          * relevant only for NIST approved Elliptic Curves, while OpenSSL
451          * applies the same logic also to other curves.
452          *
453          * Classifications produced by other standardazing bodies might differ,
454          * so the results provided for "bits of security" by this provider are
455          * to be considered merely indicative, and it is the users'
456          * responsibility to compare these values against the normative
457          * references that may be relevant for their intent and purposes.
458          */
459         if (ecbits >= 512)
460             sec_bits = 256;
461         else if (ecbits >= 384)
462             sec_bits = 192;
463         else if (ecbits >= 256)
464             sec_bits = 128;
465         else if (ecbits >= 224)
466             sec_bits = 112;
467         else if (ecbits >= 160)
468             sec_bits = 80;
469         else
470             sec_bits = ecbits / 2;
471
472         if (!OSSL_PARAM_set_int(p, sec_bits))
473             return 0;
474     }
475
476     p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
477     if (p != NULL) {
478         int ecdh_cofactor_mode = 0;
479
480         ecdh_cofactor_mode =
481             (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
482
483         if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
484             return 0;
485     }
486
487     return 1;
488 }
489
490 static const OSSL_PARAM ec_known_gettable_params[] = {
491     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
492     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
493     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
494     OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
495     OSSL_PARAM_END
496 };
497
498 static
499 const OSSL_PARAM *ec_gettable_params(void)
500 {
501     return ec_known_gettable_params;
502 }
503
504 static const OSSL_PARAM ec_known_settable_params[] = {
505     OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
506     OSSL_PARAM_END
507 };
508
509 static
510 const OSSL_PARAM *ec_settable_params(void)
511 {
512     return ec_known_settable_params;
513 }
514
515 static
516 int ec_set_params(void *key, const OSSL_PARAM params[])
517 {
518     EC_KEY *eck = key;
519     const OSSL_PARAM *p;
520
521     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH);
522     if (p != NULL && !ec_set_param_ecdh_cofactor_mode(eck, p))
523         return 0;
524
525     return 1;
526 }
527
528 static
529 int ec_validate(void *keydata, int selection)
530 {
531     EC_KEY *eck = keydata;
532     int ok = 0;
533     BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(eck));
534
535     if (ctx == NULL)
536         return 0;
537
538     if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
539         ok = 1;
540
541     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
542         ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
543
544     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
545         ok = ok && ec_key_public_check(eck, ctx);
546
547     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
548         ok = ok && ec_key_private_check(eck);
549
550     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
551         ok = ok && ec_key_pairwise_check(eck, ctx);
552
553     BN_CTX_free(ctx);
554     return ok;
555 }
556
557 const OSSL_DISPATCH ec_keymgmt_functions[] = {
558     { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata },
559     { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata },
560     { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))ec_get_params },
561     { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))ec_gettable_params },
562     { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))ec_set_params },
563     { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))ec_settable_params },
564     { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has },
565     { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match },
566     { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))ec_validate },
567     { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ec_import },
568     { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types },
569     { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export },
570     { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types },
571     { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME,
572         (void (*)(void))ec_query_operation_name },
573     { 0, NULL }
574 };