1e1036491e375fe62dc3fe3730508027d78e3c3e
[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 "cryptlib.h"
61 #include <openssl/asn1t.h>
62 #include <openssl/x509.h>
63 #include <openssl/evp.h>
64 #include <openssl/dh.h>
65 #include <openssl/bn.h>
66 #ifndef OPENSSL_NO_DSA
67 # include <openssl/dsa.h>
68 #endif
69 #include <openssl/objects.h>
70 #include "internal/evp_int.h"
71
72 /* DH pkey context structure */
73
74 typedef struct {
75     /* Parameter gen parameters */
76     int prime_len;
77     int generator;
78     int use_dsa;
79     int subprime_len;
80     /* message digest used for parameter generation */
81     const EVP_MD *md;
82     int rfc5114_param;
83     /* Keygen callback info */
84     int gentmp[2];
85     /* KDF (if any) to use for DH */
86     char kdf_type;
87     /* OID to use for KDF */
88     ASN1_OBJECT *kdf_oid;
89     /* Message digest to use for key derivation */
90     const EVP_MD *kdf_md;
91     /* User key material */
92     unsigned char *kdf_ukm;
93     size_t kdf_ukmlen;
94     /* KDF output length */
95     size_t kdf_outlen;
96 } DH_PKEY_CTX;
97
98 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
99 {
100     DH_PKEY_CTX *dctx;
101     dctx = OPENSSL_malloc(sizeof(*dctx));
102     if (!dctx)
103         return 0;
104     dctx->prime_len = 1024;
105     dctx->subprime_len = -1;
106     dctx->generator = 2;
107     dctx->use_dsa = 0;
108     dctx->md = NULL;
109     dctx->rfc5114_param = 0;
110
111     dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
112     dctx->kdf_oid = NULL;
113     dctx->kdf_md = NULL;
114     dctx->kdf_ukm = NULL;
115     dctx->kdf_ukmlen = 0;
116     dctx->kdf_outlen = 0;
117
118     ctx->data = dctx;
119     ctx->keygen_info = dctx->gentmp;
120     ctx->keygen_info_count = 2;
121
122     return 1;
123 }
124
125 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
126 {
127     DH_PKEY_CTX *dctx, *sctx;
128     if (!pkey_dh_init(dst))
129         return 0;
130     sctx = src->data;
131     dctx = dst->data;
132     dctx->prime_len = sctx->prime_len;
133     dctx->subprime_len = sctx->subprime_len;
134     dctx->generator = sctx->generator;
135     dctx->use_dsa = sctx->use_dsa;
136     dctx->md = sctx->md;
137     dctx->rfc5114_param = sctx->rfc5114_param;
138
139     dctx->kdf_type = sctx->kdf_type;
140     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
141     if (!dctx->kdf_oid)
142         return 0;
143     dctx->kdf_md = sctx->kdf_md;
144     if (dctx->kdf_ukm) {
145         dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
146         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
147     }
148     dctx->kdf_outlen = sctx->kdf_outlen;
149     return 1;
150 }
151
152 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
153 {
154     DH_PKEY_CTX *dctx = ctx->data;
155     if (dctx) {
156         OPENSSL_free(dctx->kdf_ukm);
157         ASN1_OBJECT_free(dctx->kdf_oid);
158         OPENSSL_free(dctx);
159     }
160 }
161
162 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
163 {
164     DH_PKEY_CTX *dctx = ctx->data;
165     switch (type) {
166     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
167         if (p1 < 256)
168             return -2;
169         dctx->prime_len = p1;
170         return 1;
171
172     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
173         if (dctx->use_dsa == 0)
174             return -2;
175         dctx->subprime_len = p1;
176         return 1;
177
178     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
179         if (dctx->use_dsa)
180             return -2;
181         dctx->generator = p1;
182         return 1;
183
184     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
185 #ifdef OPENSSL_NO_DSA
186         if (p1 != 0)
187             return -2;
188 #else
189         if (p1 < 0 || p1 > 2)
190             return -2;
191 #endif
192         dctx->use_dsa = p1;
193         return 1;
194
195     case EVP_PKEY_CTRL_DH_RFC5114:
196         if (p1 < 1 || p1 > 3)
197             return -2;
198         dctx->rfc5114_param = p1;
199         return 1;
200
201     case EVP_PKEY_CTRL_PEER_KEY:
202         /* Default behaviour is OK */
203         return 1;
204
205     case EVP_PKEY_CTRL_DH_KDF_TYPE:
206         if (p1 == -2)
207             return dctx->kdf_type;
208         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
209             return -2;
210         dctx->kdf_type = p1;
211         return 1;
212
213     case EVP_PKEY_CTRL_DH_KDF_MD:
214         dctx->kdf_md = p2;
215         return 1;
216
217     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
218         *(const EVP_MD **)p2 = dctx->kdf_md;
219         return 1;
220
221     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
222         if (p1 <= 0)
223             return -2;
224         dctx->kdf_outlen = (size_t)p1;
225         return 1;
226
227     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
228         *(int *)p2 = dctx->kdf_outlen;
229         return 1;
230
231     case EVP_PKEY_CTRL_DH_KDF_UKM:
232         OPENSSL_free(dctx->kdf_ukm);
233         dctx->kdf_ukm = p2;
234         if (p2)
235             dctx->kdf_ukmlen = p1;
236         else
237             dctx->kdf_ukmlen = 0;
238         return 1;
239
240     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
241         *(unsigned char **)p2 = dctx->kdf_ukm;
242         return dctx->kdf_ukmlen;
243
244     case EVP_PKEY_CTRL_DH_KDF_OID:
245         ASN1_OBJECT_free(dctx->kdf_oid);
246         dctx->kdf_oid = p2;
247         return 1;
248
249     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
250         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
251         return 1;
252
253     default:
254         return -2;
255
256     }
257 }
258
259 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
260                             const char *type, const char *value)
261 {
262     if (!strcmp(type, "dh_paramgen_prime_len")) {
263         int len;
264         len = atoi(value);
265         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
266     }
267     if (!strcmp(type, "dh_rfc5114")) {
268         DH_PKEY_CTX *dctx = ctx->data;
269         int len;
270         len = atoi(value);
271         if (len < 0 || len > 3)
272             return -2;
273         dctx->rfc5114_param = len;
274         return 1;
275     }
276     if (!strcmp(type, "dh_paramgen_generator")) {
277         int len;
278         len = atoi(value);
279         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
280     }
281     if (!strcmp(type, "dh_paramgen_subprime_len")) {
282         int len;
283         len = atoi(value);
284         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
285     }
286     if (!strcmp(type, "dh_paramgen_type")) {
287         int typ;
288         typ = atoi(value);
289         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
290     }
291     return -2;
292 }
293
294 #ifndef OPENSSL_NO_DSA
295
296 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
297                                 const EVP_MD *evpmd,
298                                 const unsigned char *seed_in, size_t seed_len,
299                                 unsigned char *seed_out, int *counter_ret,
300                                 unsigned long *h_ret, BN_GENCB *cb);
301
302 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
303                                  const EVP_MD *evpmd,
304                                  const unsigned char *seed_in,
305                                  size_t seed_len, int idx,
306                                  unsigned char *seed_out, int *counter_ret,
307                                  unsigned long *h_ret, BN_GENCB *cb);
308
309 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
310 {
311     DSA *ret;
312     int rv = 0;
313     int prime_len = dctx->prime_len;
314     int subprime_len = dctx->subprime_len;
315     const EVP_MD *md = dctx->md;
316     if (dctx->use_dsa > 2)
317         return NULL;
318     ret = DSA_new();
319     if (!ret)
320         return NULL;
321     if (subprime_len == -1) {
322         if (prime_len >= 2048)
323             subprime_len = 256;
324         else
325             subprime_len = 160;
326     }
327     if (md == NULL) {
328         if (prime_len >= 2048)
329             md = EVP_sha256();
330         else
331             md = EVP_sha1();
332     }
333     if (dctx->use_dsa == 1)
334         rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
335                                   NULL, 0, NULL, NULL, NULL, pcb);
336     else if (dctx->use_dsa == 2)
337         rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
338                                    NULL, 0, -1, NULL, NULL, NULL, pcb);
339     if (rv <= 0) {
340         DSA_free(ret);
341         return NULL;
342     }
343     return ret;
344 }
345
346 #endif
347
348 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
349 {
350     DH *dh = NULL;
351     DH_PKEY_CTX *dctx = ctx->data;
352     BN_GENCB *pcb;
353     int ret;
354     if (dctx->rfc5114_param) {
355         switch (dctx->rfc5114_param) {
356         case 1:
357             dh = DH_get_1024_160();
358             break;
359
360         case 2:
361             dh = DH_get_2048_224();
362             break;
363
364         case 3:
365             dh = DH_get_2048_256();
366             break;
367
368         default:
369             return -2;
370         }
371         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
372         return 1;
373     }
374
375     if (ctx->pkey_gencb) {
376         pcb = BN_GENCB_new();
377         evp_pkey_set_cb_translate(pcb, ctx);
378     } else
379         pcb = NULL;
380 #ifndef OPENSSL_NO_DSA
381     if (dctx->use_dsa) {
382         DSA *dsa_dh;
383         dsa_dh = dsa_dh_generate(dctx, pcb);
384         BN_GENCB_free(pcb);
385         if (!dsa_dh)
386             return 0;
387         dh = DSA_dup_DH(dsa_dh);
388         DSA_free(dsa_dh);
389         if (!dh)
390             return 0;
391         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
392         return 1;
393     }
394 #endif
395     dh = DH_new();
396     if (!dh) {
397         BN_GENCB_free(pcb);
398         return 0;
399     }
400     ret = DH_generate_parameters_ex(dh,
401                                     dctx->prime_len, dctx->generator, pcb);
402     BN_GENCB_free(pcb);
403     if (ret)
404         EVP_PKEY_assign_DH(pkey, dh);
405     else
406         DH_free(dh);
407     return ret;
408 }
409
410 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
411 {
412     DH *dh = NULL;
413     if (ctx->pkey == NULL) {
414         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
415         return 0;
416     }
417     dh = DH_new();
418     if (!dh)
419         return 0;
420     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
421     /* Note: if error return, pkey is freed by parent routine */
422     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
423         return 0;
424     return DH_generate_key(pkey->pkey.dh);
425 }
426
427 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
428                           size_t *keylen)
429 {
430     int ret;
431     DH *dh;
432     DH_PKEY_CTX *dctx = ctx->data;
433     BIGNUM *dhpub;
434     if (!ctx->pkey || !ctx->peerkey) {
435         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
436         return 0;
437     }
438     dh = ctx->pkey->pkey.dh;
439     dhpub = ctx->peerkey->pkey.dh->pub_key;
440     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
441         if (key == NULL) {
442             *keylen = DH_size(dh);
443             return 1;
444         }
445         ret = DH_compute_key(key, dhpub, dh);
446         if (ret < 0)
447             return ret;
448         *keylen = ret;
449         return 1;
450     } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
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) {
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     return 1;
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 };