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