Remove a TODO(3.0) from EVP_PKEY_derive_set_peer()
[openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2  * Copyright 2006-2021 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         ERR_raise(ERR_LIB_DH, 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         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
176             return -2;
177         dctx->kdf_type = p1;
178         return 1;
179
180     case EVP_PKEY_CTRL_DH_KDF_MD:
181         dctx->kdf_md = p2;
182         return 1;
183
184     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
185         *(const EVP_MD **)p2 = dctx->kdf_md;
186         return 1;
187
188     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
189         if (p1 <= 0)
190             return -2;
191         dctx->kdf_outlen = (size_t)p1;
192         return 1;
193
194     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
195         *(int *)p2 = dctx->kdf_outlen;
196         return 1;
197
198     case EVP_PKEY_CTRL_DH_KDF_UKM:
199         OPENSSL_free(dctx->kdf_ukm);
200         dctx->kdf_ukm = p2;
201         if (p2)
202             dctx->kdf_ukmlen = p1;
203         else
204             dctx->kdf_ukmlen = 0;
205         return 1;
206
207     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
208         *(unsigned char **)p2 = dctx->kdf_ukm;
209         return dctx->kdf_ukmlen;
210
211     case EVP_PKEY_CTRL_DH_KDF_OID:
212         ASN1_OBJECT_free(dctx->kdf_oid);
213         dctx->kdf_oid = p2;
214         return 1;
215
216     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
217         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
218         return 1;
219
220     default:
221         return -2;
222
223     }
224 }
225
226 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
227                             const char *type, const char *value)
228 {
229     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
230         int len;
231         len = atoi(value);
232         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
233     }
234     if (strcmp(type, "dh_rfc5114") == 0) {
235         DH_PKEY_CTX *dctx = ctx->data;
236         int len;
237         len = atoi(value);
238         if (len < 0 || len > 3)
239             return -2;
240         dctx->rfc5114_param = len;
241         return 1;
242     }
243     if (strcmp(type, "dh_param") == 0) {
244         DH_PKEY_CTX *dctx = ctx->data;
245         int nid = OBJ_sn2nid(value);
246
247         if (nid == NID_undef) {
248             ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME);
249             return -2;
250         }
251         dctx->param_nid = nid;
252         return 1;
253     }
254     if (strcmp(type, "dh_paramgen_generator") == 0) {
255         int len;
256         len = atoi(value);
257         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
258     }
259     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
260         int len;
261         len = atoi(value);
262         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
263     }
264     if (strcmp(type, "dh_paramgen_type") == 0) {
265         int typ;
266         typ = atoi(value);
267         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
268     }
269     if (strcmp(type, "dh_pad") == 0) {
270         int pad;
271         pad = atoi(value);
272         return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
273     }
274     return -2;
275 }
276
277 static DH *ffc_params_generate(OSSL_LIB_CTX *libctx, DH_PKEY_CTX *dctx,
278                                BN_GENCB *pcb)
279 {
280     DH *ret;
281     int rv = 0;
282     int res;
283     int prime_len = dctx->prime_len;
284     int subprime_len = dctx->subprime_len;
285
286     if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
287         return NULL;
288     ret = DH_new();
289     if (ret == NULL)
290         return NULL;
291
292     if (subprime_len == -1) {
293         if (prime_len >= 2048)
294             subprime_len = 256;
295         else
296             subprime_len = 160;
297     }
298
299     if (dctx->md != NULL)
300         ossl_ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
301
302 # ifndef FIPS_MODULE
303     if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
304         rv = ossl_ffc_params_FIPS186_2_generate(libctx, &ret->params,
305                                                 FFC_PARAM_TYPE_DH,
306                                                 prime_len, subprime_len, &res,
307                                                 pcb);
308     else
309 # endif
310     /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
311     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
312         rv = ossl_ffc_params_FIPS186_4_generate(libctx, &ret->params,
313                                                 FFC_PARAM_TYPE_DH,
314                                                 prime_len, subprime_len, &res,
315                                                 pcb);
316     if (rv <= 0) {
317         DH_free(ret);
318         return NULL;
319     }
320     return ret;
321 }
322
323 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx,
324                             EVP_PKEY *pkey)
325 {
326     DH *dh = NULL;
327     DH_PKEY_CTX *dctx = ctx->data;
328     BN_GENCB *pcb = NULL;
329     int ret;
330
331     /*
332      * Look for a safe prime group for key establishment. Which uses
333      * either RFC_3526 (modp_XXXX) or RFC_7919 (ffdheXXXX).
334      */
335     if (dctx->param_nid != NID_undef) {
336         if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
337             return 0;
338         EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
339         return 1;
340     }
341
342 #ifndef FIPS_MODULE
343     if (dctx->rfc5114_param) {
344         switch (dctx->rfc5114_param) {
345         case 1:
346             dh = DH_get_1024_160();
347             break;
348
349         case 2:
350             dh = DH_get_2048_224();
351             break;
352
353         case 3:
354             dh = DH_get_2048_256();
355             break;
356
357         default:
358             return -2;
359         }
360         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
361         return 1;
362     }
363 #endif /* FIPS_MODULE */
364
365     if (ctx->pkey_gencb != NULL) {
366         pcb = BN_GENCB_new();
367         if (pcb == NULL)
368             return 0;
369         evp_pkey_set_cb_translate(pcb, ctx);
370     }
371 # ifdef FIPS_MODULE
372     dctx->paramgen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
373 # endif /* FIPS_MODULE */
374     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2) {
375         dh = ffc_params_generate(NULL, dctx, pcb);
376         BN_GENCB_free(pcb);
377         if (dh == NULL)
378             return 0;
379         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380         return 1;
381     }
382     dh = DH_new();
383     if (dh == NULL) {
384         BN_GENCB_free(pcb);
385         return 0;
386     }
387     ret = DH_generate_parameters_ex(dh,
388                                     dctx->prime_len, dctx->generator, pcb);
389     BN_GENCB_free(pcb);
390     if (ret)
391         EVP_PKEY_assign_DH(pkey, dh);
392     else
393         DH_free(dh);
394     return ret;
395 }
396
397 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
398 {
399     DH_PKEY_CTX *dctx = ctx->data;
400     DH *dh = NULL;
401
402     if (ctx->pkey == NULL && dctx->param_nid == NID_undef) {
403         ERR_raise(ERR_LIB_DH, DH_R_NO_PARAMETERS_SET);
404         return 0;
405     }
406     if (dctx->param_nid != NID_undef)
407         dh = DH_new_by_nid(dctx->param_nid);
408     else
409         dh = DH_new();
410     if (dh == NULL)
411         return 0;
412     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
413     /* Note: if error return, pkey is freed by parent routine */
414     if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
415         return 0;
416     return DH_generate_key(pkey->pkey.dh);
417 }
418
419 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
420                           size_t *keylen)
421 {
422     int ret;
423     DH *dh;
424     const DH *dhpub;
425     DH_PKEY_CTX *dctx = ctx->data;
426     BIGNUM *dhpubbn;
427
428     if (ctx->pkey == NULL || ctx->peerkey == NULL) {
429         ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
430         return 0;
431     }
432     dh = ctx->pkey->pkey.dh;
433     dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
434     if (dhpub == NULL) {
435         ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
436         return 0;
437     }
438     dhpubbn = dhpub->pub_key;
439     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
440         if (key == NULL) {
441             *keylen = DH_size(dh);
442             return 1;
443         }
444         if (dctx->pad)
445             ret = DH_compute_key_padded(key, dhpubbn, dh);
446         else
447             ret = DH_compute_key(key, dhpubbn, dh);
448         if (ret < 0)
449             return ret;
450         *keylen = ret;
451         return 1;
452     }
453     else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
454
455         unsigned char *Z = NULL;
456         size_t Zlen = 0;
457         if (!dctx->kdf_outlen || !dctx->kdf_oid)
458             return 0;
459         if (key == NULL) {
460             *keylen = dctx->kdf_outlen;
461             return 1;
462         }
463         if (*keylen != dctx->kdf_outlen)
464             return 0;
465         ret = 0;
466         Zlen = DH_size(dh);
467         Z = OPENSSL_malloc(Zlen);
468         if (Z == NULL) {
469             goto err;
470         }
471         if (DH_compute_key_padded(Z, dhpubbn, dh) <= 0)
472             goto err;
473         if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
474                           dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
475             goto err;
476         *keylen = dctx->kdf_outlen;
477         ret = 1;
478  err:
479         OPENSSL_clear_free(Z, Zlen);
480         return ret;
481     }
482     return 0;
483 }
484
485 static const EVP_PKEY_METHOD dh_pkey_meth = {
486     EVP_PKEY_DH,
487     0,
488     pkey_dh_init,
489     pkey_dh_copy,
490     pkey_dh_cleanup,
491
492     0,
493     pkey_dh_paramgen,
494
495     0,
496     pkey_dh_keygen,
497
498     0,
499     0,
500
501     0,
502     0,
503
504     0, 0,
505
506     0, 0, 0, 0,
507
508     0, 0,
509
510     0, 0,
511
512     0,
513     pkey_dh_derive,
514
515     pkey_dh_ctrl,
516     pkey_dh_ctrl_str
517 };
518
519 const EVP_PKEY_METHOD *ossl_dh_pkey_method(void)
520 {
521     return &dh_pkey_meth;
522 }
523
524 static const EVP_PKEY_METHOD dhx_pkey_meth = {
525     EVP_PKEY_DHX,
526     0,
527     pkey_dh_init,
528     pkey_dh_copy,
529     pkey_dh_cleanup,
530
531     0,
532     pkey_dh_paramgen,
533
534     0,
535     pkey_dh_keygen,
536
537     0,
538     0,
539
540     0,
541     0,
542
543     0, 0,
544
545     0, 0, 0, 0,
546
547     0, 0,
548
549     0, 0,
550
551     0,
552     pkey_dh_derive,
553
554     pkey_dh_ctrl,
555     pkey_dh_ctrl_str
556 };
557
558 const EVP_PKEY_METHOD *ossl_dhx_pkey_method(void)
559 {
560     return &dhx_pkey_meth;
561 }