Fix set0 reuse test
[openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3  * 2006.
4  */
5 /* ====================================================================
6  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  *
20  * 3. All advertising materials mentioning features or use of this
21  *    software must display the following acknowledgment:
22  *    "This product includes software developed by the OpenSSL Project
23  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24  *
25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26  *    endorse or promote products derived from this software without
27  *    prior written permission. For written permission, please contact
28  *    licensing@OpenSSL.org.
29  *
30  * 5. Products derived from this software may not be called "OpenSSL"
31  *    nor may "OpenSSL" appear in their names without prior written
32  *    permission of the OpenSSL Project.
33  *
34  * 6. Redistributions of any form whatsoever must retain the following
35  *    acknowledgment:
36  *    "This product includes software developed by the OpenSSL Project
37  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50  * OF THE POSSIBILITY OF SUCH DAMAGE.
51  * ====================================================================
52  *
53  * This product includes cryptographic software written by Eric Young
54  * (eay@cryptsoft.com).  This product includes software written by Tim
55  * Hudson (tjh@cryptsoft.com).
56  *
57  */
58
59 #include <stdio.h>
60 #include "internal/cryptlib.h"
61 #include <openssl/asn1t.h>
62 #include <openssl/x509.h>
63 #include <openssl/evp.h>
64 #include "dh_locl.h"
65 #include <openssl/bn.h>
66 #include <openssl/dsa.h>
67 #include <openssl/objects.h>
68 #include "internal/evp_int.h"
69
70 /* DH pkey context structure */
71
72 typedef struct {
73     /* Parameter gen parameters */
74     int prime_len;
75     int generator;
76     int use_dsa;
77     int subprime_len;
78     /* message digest used for parameter generation */
79     const EVP_MD *md;
80     int rfc5114_param;
81     /* Keygen callback info */
82     int gentmp[2];
83     /* KDF (if any) to use for DH */
84     char kdf_type;
85     /* OID to use for KDF */
86     ASN1_OBJECT *kdf_oid;
87     /* Message digest to use for key derivation */
88     const EVP_MD *kdf_md;
89     /* User key material */
90     unsigned char *kdf_ukm;
91     size_t kdf_ukmlen;
92     /* KDF output length */
93     size_t kdf_outlen;
94 } DH_PKEY_CTX;
95
96 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
97 {
98     DH_PKEY_CTX *dctx;
99
100     dctx = OPENSSL_zalloc(sizeof(*dctx));
101     if (dctx == NULL)
102         return 0;
103     dctx->prime_len = 1024;
104     dctx->subprime_len = -1;
105     dctx->generator = 2;
106     dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
107
108     ctx->data = dctx;
109     ctx->keygen_info = dctx->gentmp;
110     ctx->keygen_info_count = 2;
111
112     return 1;
113 }
114
115 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
116 {
117     DH_PKEY_CTX *dctx, *sctx;
118     if (!pkey_dh_init(dst))
119         return 0;
120     sctx = src->data;
121     dctx = dst->data;
122     dctx->prime_len = sctx->prime_len;
123     dctx->subprime_len = sctx->subprime_len;
124     dctx->generator = sctx->generator;
125     dctx->use_dsa = sctx->use_dsa;
126     dctx->md = sctx->md;
127     dctx->rfc5114_param = sctx->rfc5114_param;
128
129     dctx->kdf_type = sctx->kdf_type;
130     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
131     if (!dctx->kdf_oid)
132         return 0;
133     dctx->kdf_md = sctx->kdf_md;
134     if (dctx->kdf_ukm) {
135         dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
136         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
137     }
138     dctx->kdf_outlen = sctx->kdf_outlen;
139     return 1;
140 }
141
142 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
143 {
144     DH_PKEY_CTX *dctx = ctx->data;
145     if (dctx) {
146         OPENSSL_free(dctx->kdf_ukm);
147         ASN1_OBJECT_free(dctx->kdf_oid);
148         OPENSSL_free(dctx);
149     }
150 }
151
152 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
153 {
154     DH_PKEY_CTX *dctx = ctx->data;
155     switch (type) {
156     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
157         if (p1 < 256)
158             return -2;
159         dctx->prime_len = p1;
160         return 1;
161
162     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
163         if (dctx->use_dsa == 0)
164             return -2;
165         dctx->subprime_len = p1;
166         return 1;
167
168     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
169         if (dctx->use_dsa)
170             return -2;
171         dctx->generator = p1;
172         return 1;
173
174     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
175 #ifdef OPENSSL_NO_DSA
176         if (p1 != 0)
177             return -2;
178 #else
179         if (p1 < 0 || p1 > 2)
180             return -2;
181 #endif
182         dctx->use_dsa = p1;
183         return 1;
184
185     case EVP_PKEY_CTRL_DH_RFC5114:
186         if (p1 < 1 || p1 > 3)
187             return -2;
188         dctx->rfc5114_param = p1;
189         return 1;
190
191     case EVP_PKEY_CTRL_PEER_KEY:
192         /* Default behaviour is OK */
193         return 1;
194
195     case EVP_PKEY_CTRL_DH_KDF_TYPE:
196         if (p1 == -2)
197             return dctx->kdf_type;
198 #ifdef OPENSSL_NO_CMS
199         if (p1 != EVP_PKEY_DH_KDF_NONE)
200 #else
201         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
202 #endif
203             return -2;
204         dctx->kdf_type = p1;
205         return 1;
206
207     case EVP_PKEY_CTRL_DH_KDF_MD:
208         dctx->kdf_md = p2;
209         return 1;
210
211     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
212         *(const EVP_MD **)p2 = dctx->kdf_md;
213         return 1;
214
215     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
216         if (p1 <= 0)
217             return -2;
218         dctx->kdf_outlen = (size_t)p1;
219         return 1;
220
221     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
222         *(int *)p2 = dctx->kdf_outlen;
223         return 1;
224
225     case EVP_PKEY_CTRL_DH_KDF_UKM:
226         OPENSSL_free(dctx->kdf_ukm);
227         dctx->kdf_ukm = p2;
228         if (p2)
229             dctx->kdf_ukmlen = p1;
230         else
231             dctx->kdf_ukmlen = 0;
232         return 1;
233
234     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
235         *(unsigned char **)p2 = dctx->kdf_ukm;
236         return dctx->kdf_ukmlen;
237
238     case EVP_PKEY_CTRL_DH_KDF_OID:
239         ASN1_OBJECT_free(dctx->kdf_oid);
240         dctx->kdf_oid = p2;
241         return 1;
242
243     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
244         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
245         return 1;
246
247     default:
248         return -2;
249
250     }
251 }
252
253 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
254                             const char *type, const char *value)
255 {
256     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
257         int len;
258         len = atoi(value);
259         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
260     }
261     if (strcmp(type, "dh_rfc5114") == 0) {
262         DH_PKEY_CTX *dctx = ctx->data;
263         int len;
264         len = atoi(value);
265         if (len < 0 || len > 3)
266             return -2;
267         dctx->rfc5114_param = len;
268         return 1;
269     }
270     if (strcmp(type, "dh_paramgen_generator") == 0) {
271         int len;
272         len = atoi(value);
273         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
274     }
275     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
276         int len;
277         len = atoi(value);
278         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
279     }
280     if (strcmp(type, "dh_paramgen_type") == 0) {
281         int typ;
282         typ = atoi(value);
283         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
284     }
285     return -2;
286 }
287
288 #ifndef OPENSSL_NO_DSA
289
290 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
291                                 const EVP_MD *evpmd,
292                                 const unsigned char *seed_in, size_t seed_len,
293                                 unsigned char *seed_out, int *counter_ret,
294                                 unsigned long *h_ret, BN_GENCB *cb);
295
296 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
297                                  const EVP_MD *evpmd,
298                                  const unsigned char *seed_in,
299                                  size_t seed_len, int idx,
300                                  unsigned char *seed_out, int *counter_ret,
301                                  unsigned long *h_ret, BN_GENCB *cb);
302
303 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
304 {
305     DSA *ret;
306     int rv = 0;
307     int prime_len = dctx->prime_len;
308     int subprime_len = dctx->subprime_len;
309     const EVP_MD *md = dctx->md;
310     if (dctx->use_dsa > 2)
311         return NULL;
312     ret = DSA_new();
313     if (ret == NULL)
314         return NULL;
315     if (subprime_len == -1) {
316         if (prime_len >= 2048)
317             subprime_len = 256;
318         else
319             subprime_len = 160;
320     }
321     if (md == NULL) {
322         if (prime_len >= 2048)
323             md = EVP_sha256();
324         else
325             md = EVP_sha1();
326     }
327     if (dctx->use_dsa == 1)
328         rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
329                                   NULL, 0, NULL, NULL, NULL, pcb);
330     else if (dctx->use_dsa == 2)
331         rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
332                                    NULL, 0, -1, NULL, NULL, NULL, pcb);
333     if (rv <= 0) {
334         DSA_free(ret);
335         return NULL;
336     }
337     return ret;
338 }
339
340 #endif
341
342 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
343 {
344     DH *dh = NULL;
345     DH_PKEY_CTX *dctx = ctx->data;
346     BN_GENCB *pcb;
347     int ret;
348     if (dctx->rfc5114_param) {
349         switch (dctx->rfc5114_param) {
350         case 1:
351             dh = DH_get_1024_160();
352             break;
353
354         case 2:
355             dh = DH_get_2048_224();
356             break;
357
358         case 3:
359             dh = DH_get_2048_256();
360             break;
361
362         default:
363             return -2;
364         }
365         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
366         return 1;
367     }
368
369     if (ctx->pkey_gencb) {
370         pcb = BN_GENCB_new();
371         if (pcb == NULL)
372             return 0;
373         evp_pkey_set_cb_translate(pcb, ctx);
374     } else
375         pcb = NULL;
376 #ifndef OPENSSL_NO_DSA
377     if (dctx->use_dsa) {
378         DSA *dsa_dh;
379         dsa_dh = dsa_dh_generate(dctx, pcb);
380         BN_GENCB_free(pcb);
381         if (dsa_dh == NULL)
382             return 0;
383         dh = DSA_dup_DH(dsa_dh);
384         DSA_free(dsa_dh);
385         if (!dh)
386             return 0;
387         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
388         return 1;
389     }
390 #endif
391     dh = DH_new();
392     if (dh == NULL) {
393         BN_GENCB_free(pcb);
394         return 0;
395     }
396     ret = DH_generate_parameters_ex(dh,
397                                     dctx->prime_len, dctx->generator, pcb);
398     BN_GENCB_free(pcb);
399     if (ret)
400         EVP_PKEY_assign_DH(pkey, dh);
401     else
402         DH_free(dh);
403     return ret;
404 }
405
406 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
407 {
408     DH *dh = NULL;
409     if (ctx->pkey == NULL) {
410         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
411         return 0;
412     }
413     dh = DH_new();
414     if (dh == NULL)
415         return 0;
416     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
417     /* Note: if error return, pkey is freed by parent routine */
418     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
419         return 0;
420     return DH_generate_key(pkey->pkey.dh);
421 }
422
423 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
424                           size_t *keylen)
425 {
426     int ret;
427     DH *dh;
428     DH_PKEY_CTX *dctx = ctx->data;
429     BIGNUM *dhpub;
430     if (!ctx->pkey || !ctx->peerkey) {
431         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
432         return 0;
433     }
434     dh = ctx->pkey->pkey.dh;
435     dhpub = ctx->peerkey->pkey.dh->pub_key;
436     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
437         if (key == NULL) {
438             *keylen = DH_size(dh);
439             return 1;
440         }
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 };