• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006-2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 use_dsa;
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 
pkey_dh_init(EVP_PKEY_CTX * ctx)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 
pkey_dh_cleanup(EVP_PKEY_CTX * ctx)69 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
70 {
71     DH_PKEY_CTX *dctx = ctx->data;
72     if (dctx != NULL) {
73         OPENSSL_free(dctx->kdf_ukm);
74         ASN1_OBJECT_free(dctx->kdf_oid);
75         OPENSSL_free(dctx);
76     }
77 }
78 
79 
pkey_dh_copy(EVP_PKEY_CTX * dst,EVP_PKEY_CTX * src)80 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
81 {
82     DH_PKEY_CTX *dctx, *sctx;
83     if (!pkey_dh_init(dst))
84         return 0;
85     sctx = src->data;
86     dctx = dst->data;
87     dctx->prime_len = sctx->prime_len;
88     dctx->subprime_len = sctx->subprime_len;
89     dctx->generator = sctx->generator;
90     dctx->use_dsa = sctx->use_dsa;
91     dctx->pad = sctx->pad;
92     dctx->md = sctx->md;
93     dctx->rfc5114_param = sctx->rfc5114_param;
94     dctx->param_nid = sctx->param_nid;
95 
96     dctx->kdf_type = sctx->kdf_type;
97     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
98     if (dctx->kdf_oid == NULL)
99         return 0;
100     dctx->kdf_md = sctx->kdf_md;
101     if (sctx->kdf_ukm != NULL) {
102         dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
103         if (dctx->kdf_ukm == NULL)
104           return 0;
105         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
106     }
107     dctx->kdf_outlen = sctx->kdf_outlen;
108     return 1;
109 }
110 
pkey_dh_ctrl(EVP_PKEY_CTX * ctx,int type,int p1,void * p2)111 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
112 {
113     DH_PKEY_CTX *dctx = ctx->data;
114     switch (type) {
115     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
116         if (p1 < 256)
117             return -2;
118         dctx->prime_len = p1;
119         return 1;
120 
121     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
122         if (dctx->use_dsa == 0)
123             return -2;
124         dctx->subprime_len = p1;
125         return 1;
126 
127     case EVP_PKEY_CTRL_DH_PAD:
128         dctx->pad = p1;
129         return 1;
130 
131     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
132         if (dctx->use_dsa)
133             return -2;
134         dctx->generator = p1;
135         return 1;
136 
137     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
138 #ifdef OPENSSL_NO_DSA
139         if (p1 != 0)
140             return -2;
141 #else
142         if (p1 < 0 || p1 > 2)
143             return -2;
144 #endif
145         dctx->use_dsa = p1;
146         return 1;
147 
148     case EVP_PKEY_CTRL_DH_RFC5114:
149         if (p1 < 1 || p1 > 3 || dctx->param_nid != NID_undef)
150             return -2;
151         dctx->rfc5114_param = p1;
152         return 1;
153 
154     case EVP_PKEY_CTRL_DH_NID:
155         if (p1 <= 0 || dctx->rfc5114_param != 0)
156             return -2;
157         dctx->param_nid = p1;
158         return 1;
159 
160     case EVP_PKEY_CTRL_PEER_KEY:
161         /* Default behaviour is OK */
162         return 1;
163 
164     case EVP_PKEY_CTRL_DH_KDF_TYPE:
165         if (p1 == -2)
166             return dctx->kdf_type;
167 #ifdef OPENSSL_NO_CMS
168         if (p1 != EVP_PKEY_DH_KDF_NONE)
169 #else
170         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
171 #endif
172             return -2;
173         dctx->kdf_type = p1;
174         return 1;
175 
176     case EVP_PKEY_CTRL_DH_KDF_MD:
177         dctx->kdf_md = p2;
178         return 1;
179 
180     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
181         *(const EVP_MD **)p2 = dctx->kdf_md;
182         return 1;
183 
184     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
185         if (p1 <= 0)
186             return -2;
187         dctx->kdf_outlen = (size_t)p1;
188         return 1;
189 
190     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
191         *(int *)p2 = dctx->kdf_outlen;
192         return 1;
193 
194     case EVP_PKEY_CTRL_DH_KDF_UKM:
195         OPENSSL_free(dctx->kdf_ukm);
196         dctx->kdf_ukm = p2;
197         if (p2)
198             dctx->kdf_ukmlen = p1;
199         else
200             dctx->kdf_ukmlen = 0;
201         return 1;
202 
203     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
204         *(unsigned char **)p2 = dctx->kdf_ukm;
205         return dctx->kdf_ukmlen;
206 
207     case EVP_PKEY_CTRL_DH_KDF_OID:
208         ASN1_OBJECT_free(dctx->kdf_oid);
209         dctx->kdf_oid = p2;
210         return 1;
211 
212     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
213         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
214         return 1;
215 
216     default:
217         return -2;
218 
219     }
220 }
221 
pkey_dh_ctrl_str(EVP_PKEY_CTX * ctx,const char * type,const char * value)222 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
223                             const char *type, const char *value)
224 {
225     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
226         int len;
227         len = atoi(value);
228         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
229     }
230     if (strcmp(type, "dh_rfc5114") == 0) {
231         DH_PKEY_CTX *dctx = ctx->data;
232         int len;
233         len = atoi(value);
234         if (len < 0 || len > 3)
235             return -2;
236         dctx->rfc5114_param = len;
237         return 1;
238     }
239     if (strcmp(type, "dh_param") == 0) {
240         DH_PKEY_CTX *dctx = ctx->data;
241         int nid = OBJ_sn2nid(value);
242 
243         if (nid == NID_undef) {
244             DHerr(DH_F_PKEY_DH_CTRL_STR, DH_R_INVALID_PARAMETER_NAME);
245             return -2;
246         }
247         dctx->param_nid = nid;
248         return 1;
249     }
250     if (strcmp(type, "dh_paramgen_generator") == 0) {
251         int len;
252         len = atoi(value);
253         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
254     }
255     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
256         int len;
257         len = atoi(value);
258         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
259     }
260     if (strcmp(type, "dh_paramgen_type") == 0) {
261         int typ;
262         typ = atoi(value);
263         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
264     }
265     if (strcmp(type, "dh_pad") == 0) {
266         int pad;
267         pad = atoi(value);
268         return EVP_PKEY_CTX_set_dh_pad(ctx, pad);
269     }
270     return -2;
271 }
272 
273 #ifndef OPENSSL_NO_DSA
274 
275 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
276                                 const EVP_MD *evpmd,
277                                 const unsigned char *seed_in, size_t seed_len,
278                                 unsigned char *seed_out, int *counter_ret,
279                                 unsigned long *h_ret, BN_GENCB *cb);
280 
281 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
282                                  const EVP_MD *evpmd,
283                                  const unsigned char *seed_in,
284                                  size_t seed_len, int idx,
285                                  unsigned char *seed_out, int *counter_ret,
286                                  unsigned long *h_ret, BN_GENCB *cb);
287 
dsa_dh_generate(DH_PKEY_CTX * dctx,BN_GENCB * pcb)288 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
289 {
290     DSA *ret;
291     int rv = 0;
292     int prime_len = dctx->prime_len;
293     int subprime_len = dctx->subprime_len;
294     const EVP_MD *md = dctx->md;
295     if (dctx->use_dsa > 2)
296         return NULL;
297     ret = DSA_new();
298     if (ret == NULL)
299         return NULL;
300     if (subprime_len == -1) {
301         if (prime_len >= 2048)
302             subprime_len = 256;
303         else
304             subprime_len = 160;
305     }
306     if (md == NULL) {
307         if (prime_len >= 2048)
308             md = EVP_sha256();
309         else
310             md = EVP_sha1();
311     }
312     if (dctx->use_dsa == 1)
313         rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
314                                   NULL, 0, NULL, NULL, NULL, pcb);
315     else if (dctx->use_dsa == 2)
316         rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
317                                    NULL, 0, -1, NULL, NULL, NULL, pcb);
318     if (rv <= 0) {
319         DSA_free(ret);
320         return NULL;
321     }
322     return ret;
323 }
324 
325 #endif
326 
pkey_dh_paramgen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)327 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
328 {
329     DH *dh = NULL;
330     DH_PKEY_CTX *dctx = ctx->data;
331     BN_GENCB *pcb;
332     int ret;
333     if (dctx->rfc5114_param) {
334         switch (dctx->rfc5114_param) {
335         case 1:
336             dh = DH_get_1024_160();
337             break;
338 
339         case 2:
340             dh = DH_get_2048_224();
341             break;
342 
343         case 3:
344             dh = DH_get_2048_256();
345             break;
346 
347         default:
348             return -2;
349         }
350         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
351         return 1;
352     }
353 
354     if (dctx->param_nid != 0) {
355         if ((dh = DH_new_by_nid(dctx->param_nid)) == NULL)
356             return 0;
357         EVP_PKEY_assign(pkey, EVP_PKEY_DH, dh);
358         return 1;
359     }
360 
361     if (ctx->pkey_gencb) {
362         pcb = BN_GENCB_new();
363         if (pcb == NULL)
364             return 0;
365         evp_pkey_set_cb_translate(pcb, ctx);
366     } else
367         pcb = NULL;
368 #ifndef OPENSSL_NO_DSA
369     if (dctx->use_dsa) {
370         DSA *dsa_dh;
371         dsa_dh = dsa_dh_generate(dctx, pcb);
372         BN_GENCB_free(pcb);
373         if (dsa_dh == NULL)
374             return 0;
375         dh = DSA_dup_DH(dsa_dh);
376         DSA_free(dsa_dh);
377         if (!dh)
378             return 0;
379         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380         return 1;
381     }
382 #endif
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 
pkey_dh_keygen(EVP_PKEY_CTX * ctx,EVP_PKEY * pkey)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 == 0) {
404         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
405         return 0;
406     }
407     if (dctx->param_nid != 0)
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 
pkey_dh_derive(EVP_PKEY_CTX * ctx,unsigned char * key,size_t * keylen)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 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 dhx_pkey_meth = {
516     EVP_PKEY_DHX,
517     0,
518     pkey_dh_init,
519     pkey_dh_copy,
520     pkey_dh_cleanup,
521 
522     0,
523     pkey_dh_paramgen,
524 
525     0,
526     pkey_dh_keygen,
527 
528     0,
529     0,
530 
531     0,
532     0,
533 
534     0, 0,
535 
536     0, 0, 0, 0,
537 
538     0, 0,
539 
540     0, 0,
541 
542     0,
543     pkey_dh_derive,
544 
545     pkey_dh_ctrl,
546     pkey_dh_ctrl_str
547 };
548