Add FFC param/key generation
[openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2  * Copyright 2006-2018 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 "internal/cryptlib.h"
12 #include <openssl/asn1t.h>
13 #include <openssl/x509.h>
14 #include <openssl/evp.h>
15 #include "dh_local.h"
16 #include <openssl/bn.h>
17 #include <openssl/dsa.h>
18 #include <openssl/objects.h>
19 #include "crypto/evp.h"
20
21 /* DH pkey context structure */
22
23 typedef struct {
24     /* Parameter gen parameters */
25     int prime_len;
26     int generator;
27     int paramgen_type;
28     int subprime_len;
29     int pad;
30     /* message digest used for parameter generation */
31     const EVP_MD *md;
32     int rfc5114_param;
33     int param_nid;
34     /* Keygen callback info */
35     int gentmp[2];
36     /* KDF (if any) to use for DH */
37     char kdf_type;
38     /* OID to use for KDF */
39     ASN1_OBJECT *kdf_oid;
40     /* Message digest to use for key derivation */
41     const EVP_MD *kdf_md;
42     /* User key material */
43     unsigned char *kdf_ukm;
44     size_t kdf_ukmlen;
45     /* KDF output length */
46     size_t kdf_outlen;
47 } DH_PKEY_CTX;
48
49 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
50 {
51     DH_PKEY_CTX *dctx;
52
53     if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
54         DHerr(DH_F_PKEY_DH_INIT, ERR_R_MALLOC_FAILURE);
55         return 0;
56     }
57     dctx->prime_len = 2048;
58     dctx->subprime_len = -1;
59     dctx->generator = 2;
60     dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
61
62     ctx->data = dctx;
63     ctx->keygen_info = dctx->gentmp;
64     ctx->keygen_info_count = 2;
65
66     return 1;
67 }
68
69 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
70 {
71     DH_PKEY_CTX *dctx = ctx->data;
72
73     if (dctx != NULL) {
74         OPENSSL_free(dctx->kdf_ukm);
75         ASN1_OBJECT_free(dctx->kdf_oid);
76         OPENSSL_free(dctx);
77     }
78 }
79
80
81 static int pkey_dh_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
82 {
83     DH_PKEY_CTX *dctx, *sctx;
84
85     if (!pkey_dh_init(dst))
86         return 0;
87     sctx = src->data;
88     dctx = dst->data;
89     dctx->prime_len = sctx->prime_len;
90     dctx->subprime_len = sctx->subprime_len;
91     dctx->generator = sctx->generator;
92     dctx->paramgen_type = sctx->paramgen_type;
93     dctx->pad = sctx->pad;
94     dctx->md = sctx->md;
95     dctx->rfc5114_param = sctx->rfc5114_param;
96     dctx->param_nid = sctx->param_nid;
97
98     dctx->kdf_type = sctx->kdf_type;
99     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
100     if (dctx->kdf_oid == NULL)
101         return 0;
102     dctx->kdf_md = sctx->kdf_md;
103     if (sctx->kdf_ukm != NULL) {
104         dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
105         if (dctx->kdf_ukm == NULL)
106           return 0;
107         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
108     }
109     dctx->kdf_outlen = sctx->kdf_outlen;
110     return 1;
111 }
112
113 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
114 {
115     DH_PKEY_CTX *dctx = ctx->data;
116     switch (type) {
117     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
118         if (p1 < 256)
119             return -2;
120         dctx->prime_len = p1;
121         return 1;
122
123     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
124         if (dctx->paramgen_type == DH_PARAMGEN_TYPE_GENERATOR)
125             return -2;
126         dctx->subprime_len = p1;
127         return 1;
128
129     case EVP_PKEY_CTRL_DH_PAD:
130         dctx->pad = p1;
131         return 1;
132
133     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
134         if (dctx->paramgen_type != DH_PARAMGEN_TYPE_GENERATOR)
135             return -2;
136         dctx->generator = p1;
137         return 1;
138
139     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
140 #ifdef OPENSSL_NO_DSA
141         if (p1 != DH_PARAMGEN_TYPE_GENERATOR)
142             return -2;
143 #else
144         if (p1 < 0 || p1 > 2)
145             return -2;
146 #endif
147         dctx->paramgen_type = p1;
148         return 1;
149
150     case EVP_PKEY_CTRL_DH_RFC5114:
151         if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
152             return -2;
153         dctx->rfc5114_param = p1;
154         return 1;
155
156     case EVP_PKEY_CTRL_DH_NID:
157         if (p1 <= 0 || dctx->rfc5114_param != 0)
158             return -2;
159         dctx->param_nid = p1;
160         return 1;
161
162     case EVP_PKEY_CTRL_PEER_KEY:
163         /* Default behaviour is OK */
164         return 1;
165
166     case EVP_PKEY_CTRL_DH_KDF_TYPE:
167         if (p1 == -2)
168             return dctx->kdf_type;
169 #ifdef OPENSSL_NO_CMS
170         if (p1 != EVP_PKEY_DH_KDF_NONE)
171 #else
172         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
173 #endif
174             return -2;
175         dctx->kdf_type = p1;
176         return 1;
177
178     case EVP_PKEY_CTRL_DH_KDF_MD:
179         dctx->kdf_md = p2;
180         return 1;
181
182     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
183         *(const EVP_MD **)p2 = dctx->kdf_md;
184         return 1;
185
186     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
187         if (p1 <= 0)
188             return -2;
189         dctx->kdf_outlen = (size_t)p1;
190         return 1;
191
192     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
193         *(int *)p2 = dctx->kdf_outlen;
194         return 1;
195
196     case EVP_PKEY_CTRL_DH_KDF_UKM:
197         OPENSSL_free(dctx->kdf_ukm);
198         dctx->kdf_ukm = p2;
199         if (p2)
200             dctx->kdf_ukmlen = p1;
201         else
202             dctx->kdf_ukmlen = 0;
203         return 1;
204
205     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
206         *(unsigned char **)p2 = dctx->kdf_ukm;
207         return dctx->kdf_ukmlen;
208
209     case EVP_PKEY_CTRL_DH_KDF_OID:
210         ASN1_OBJECT_free(dctx->kdf_oid);
211         dctx->kdf_oid = p2;
212         return 1;
213
214     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
215         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
216         return 1;
217
218     default:
219         return -2;
220
221     }
222 }
223
224 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
225                             const char *type, const char *value)
226 {
227     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
228         int len;
229         len = atoi(value);
230         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
231     }
232     if (strcmp(type, "dh_rfc5114") == 0) {
233         DH_PKEY_CTX *dctx = ctx->data;
234         int len;
235         len = atoi(value);
236         if (len < 0 || len > 3)
237             return -2;
238         dctx->rfc5114_param = len;
239         return 1;
240     }
241     if (strcmp(type, "dh_param") == 0) {
242         DH_PKEY_CTX *dctx = ctx->data;
243         int nid = OBJ_sn2nid(value);
244
245         if (nid == NID_undef) {
246             DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
247             return -2;
248         }
249         dctx->param_nid = nid;
250         return 1;
251     }
252     if (strcmp(type, "dh_paramgen_generator") == 0) {
253         int len;
254         len = atoi(value);
255         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
256     }
257     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
258         int len;
259         len = atoi(value);
260         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
261     }
262     if (strcmp(type, "dh_paramgen_type") == 0) {
263         int typ;
264         typ = atoi(value);
265         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
266     }
267     if (strcmp(type, "dh_pad") == 0) {
268         int pad;
269         pad = atoi(value);
270         return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
271     }
272     return -2;
273 }
274
275 static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
276                                BN_GENCB *pcb)
277 {
278     DH *ret;
279     int rv = 0;
280     int res;
281     int prime_len = dctx->prime_len;
282     int subprime_len = dctx->subprime_len;
283     const EVP_MD *md = dctx->md;
284
285     if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
286         return NULL;
287     ret = DH_new();
288     if (ret == NULL)
289         return NULL;
290
291     if (subprime_len == -1) {
292         if (prime_len >= 2048)
293             subprime_len = 256;
294         else
295             subprime_len = 160;
296     }
297     if (md == NULL) {
298         if (prime_len >= 2048)
299             md = EVP_sha256();
300         else
301             md = EVP_sha1();
302     }
303 # ifndef FIPS_MODE
304     if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
305         rv = ffc_params_FIPS186_2_generate(libctx, &ret->params,
306                                            FFC_PARAM_TYPE_DH,
307                                            prime_len, subprime_len, md, &res,
308                                            pcb);
309     else
310 # endif
311     /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
312     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
313         rv = ffc_params_FIPS186_4_generate(libctx, &ret->params,
314                                            FFC_PARAM_TYPE_DH,
315                                            prime_len, subprime_len, md, &res,
316                                            pcb);
317     if (rv <= 0) {
318         DH_free(ret);
319         return NULL;
320     }
321     return ret;
322 }
323
324 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
325                             EVP_PKEY *pkey)
326 {
327     DH *dh = NULL;
328     DH_PKEY_CTX *dctx = ctx->data;
329     BN_GENCB *pcb = NULL;
330     int ret;
331
332     /*
333      * Look for a safe prime group for key establishment. Which uses
334      * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
335      */
336     if (dctx->param_nid != NID_undef) {
337         if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
338             return 0;
339         EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
340         return 1;
341     }
342
343 #ifndef FIPS_MODE
344     if (dctx->rfc5114_param) {
345         switch (dctx->rfc5114_param) {
346         case 1:
347             dh = DH_get_1024_160();
348             break;
349
350         case 2:
351             dh = DH_get_2048_224();
352             break;
353
354         case 3:
355             dh = DH_get_2048_256();
356             break;
357
358         default:
359             return -2;
360         }
361         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
362         return 1;
363     }
364 #endif /* FIPS_MODE */
365
366     if (ctx->pkey_gencb != NULL) {
367         pcb = BN_GENCB_new();
368         if (pcb == NULL)
369             return 0;
370         evp_pkey_set_cb_translate(pcb, ctx);
371     }
372 # ifdef FIPS_MODE
373     dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
374 # endif /* FIPS_MODE */
375     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
376         dh = ffc_params_generate(NULL, dctx, pcb);
377         BN_GENCB_free(pcb);
378         if (dh == NULL)
379             return 0;
380         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
381         return 1;
382     }
383     dh = DH_new();
384     if (dh == NULL) {
385         BN_GENCB_free(pcb);
386         return 0;
387     }
388     ret = DH_generate_parameters_ex(dh,
389                                     dctx->prime_len, dctx->generator, pcb);
390     BN_GENCB_free(pcb);
391     if (ret)
392         EVP_PKEY_assign_DH(pkey, dh);
393     else
394         DH_free(dh);
395     return ret;
396 }
397
398 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
399 {
400     DH_PKEY_CTX *dctx = ctx->data;
401     DH *dh = NULL;
402
403     if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
404         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
405         return 0;
406     }
407     if (dctx->param_nid != NID_undef)
408         dh = DH_new_by_nid(dctx->param_nid);
409     else
410         dh = DH_new();
411     if (dh == NULL)
412         return 0;
413     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
414     /* Note: if error return, pkey is freed by parent routine */
415     if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
416         return 0;
417     return DH_generate_key(pkey->pkey.dh);
418 }
419
420 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
421                           size_t *keylen)
422 {
423     int ret;
424     DH *dh;
425     DH_PKEY_CTX *dctx = ctx->data;
426     BIGNUM *dhpub;
427     if (!ctx->pkey || !ctx->peerkey) {
428         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
429         return 0;
430     }
431     dh = ctx->pkey->pkey.dh;
432     dhpub = ctx->peerkey->pkey.dh->pub_key;
433     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
434         if (key == NULL) {
435             *keylen = DH_size(dh);
436             return 1;
437         }
438         if (dctx->pad)
439             ret = DH_compute_key_padded(key, dhpub, dh);
440         else
441             ret = DH_compute_key(key, dhpub, dh);
442         if (ret < 0)
443             return ret;
444         *keylen = ret;
445         return 1;
446     }
447 #ifndef OPENSSL_NO_CMS
448     else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
449
450         unsigned char *Z = NULL;
451         size_t Zlen = 0;
452         if (!dctx->kdf_outlen || !dctx->kdf_oid)
453             return 0;
454         if (key == NULL) {
455             *keylen = dctx->kdf_outlen;
456             return 1;
457         }
458         if (*keylen != dctx->kdf_outlen)
459             return 0;
460         ret = 0;
461         Zlen = DH_size(dh);
462         Z = OPENSSL_malloc(Zlen);
463         if (Z == NULL) {
464             goto err;
465         }
466         if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
467             goto err;
468         if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
469                           dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
470             goto err;
471         *keylen = dctx->kdf_outlen;
472         ret = 1;
473  err:
474         OPENSSL_clear_free(Z, Zlen);
475         return ret;
476     }
477 #endif
478     return 0;
479 }
480
481 static const EVP_PKEY_METHOD dh_pkey_meth = {
482     EVP_PKEY_DH,
483     0,
484     pkey_dh_init,
485     pkey_dh_copy,
486     pkey_dh_cleanup,
487
488     0,
489     pkey_dh_paramgen,
490
491     0,
492     pkey_dh_keygen,
493
494     0,
495     0,
496
497     0,
498     0,
499
500     0, 0,
501
502     0, 0, 0, 0,
503
504     0, 0,
505
506     0, 0,
507
508     0,
509     pkey_dh_derive,
510
511     pkey_dh_ctrl,
512     pkey_dh_ctrl_str
513 };
514
515 const EVP_PKEY_METHOD *dh_pkey_method(void)
516 {
517     return &dh_pkey_meth;
518 }
519
520 static const EVP_PKEY_METHOD dhx_pkey_meth = {
521     EVP_PKEY_DHX,
522     0,
523     pkey_dh_init,
524     pkey_dh_copy,
525     pkey_dh_cleanup,
526
527     0,
528     pkey_dh_paramgen,
529
530     0,
531     pkey_dh_keygen,
532
533     0,
534     0,
535
536     0,
537     0,
538
539     0, 0,
540
541     0, 0, 0, 0,
542
543     0, 0,
544
545     0, 0,
546
547     0,
548     pkey_dh_derive,
549
550     pkey_dh_ctrl,
551     pkey_dh_ctrl_str
552 };
553
554 const EVP_PKEY_METHOD *dhx_pkey_method(void)
555 {
556     return &dhx_pkey_meth;
557 }