c41de925c71a765093a865e6d237be54fb06bb57
[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 "evp_locl.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(DH_PKEY_CTX));
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         if (dctx->kdf_ukm)
157             OPENSSL_free(dctx->kdf_ukm);
158         if (dctx->kdf_oid)
159             ASN1_OBJECT_free(dctx->kdf_oid);
160         OPENSSL_free(dctx);
161     }
162 }
163
164 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
165 {
166     DH_PKEY_CTX *dctx = ctx->data;
167     switch (type) {
168     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
169         if (p1 < 256)
170             return -2;
171         dctx->prime_len = p1;
172         return 1;
173
174     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
175         if (dctx->use_dsa == 0)
176             return -2;
177         dctx->subprime_len = p1;
178         return 1;
179
180     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
181         if (dctx->use_dsa)
182             return -2;
183         dctx->generator = p1;
184         return 1;
185
186     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
187 #ifdef OPENSSL_NO_DSA
188         if (p1 != 0)
189             return -2;
190 #else
191         if (p1 < 0 || p1 > 2)
192             return -2;
193 #endif
194         dctx->use_dsa = p1;
195         return 1;
196
197     case EVP_PKEY_CTRL_DH_RFC5114:
198         if (p1 < 1 || p1 > 3)
199             return -2;
200         dctx->rfc5114_param = p1;
201         return 1;
202
203     case EVP_PKEY_CTRL_PEER_KEY:
204         /* Default behaviour is OK */
205         return 1;
206
207     case EVP_PKEY_CTRL_DH_KDF_TYPE:
208         if (p1 == -2)
209             return dctx->kdf_type;
210         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
211             return -2;
212         dctx->kdf_type = p1;
213         return 1;
214
215     case EVP_PKEY_CTRL_DH_KDF_MD:
216         dctx->kdf_md = p2;
217         return 1;
218
219     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
220         *(const EVP_MD **)p2 = dctx->kdf_md;
221         return 1;
222
223     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
224         if (p1 <= 0)
225             return -2;
226         dctx->kdf_outlen = (size_t)p1;
227         return 1;
228
229     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
230         *(int *)p2 = dctx->kdf_outlen;
231         return 1;
232
233     case EVP_PKEY_CTRL_DH_KDF_UKM:
234         if (dctx->kdf_ukm)
235             OPENSSL_free(dctx->kdf_ukm);
236         dctx->kdf_ukm = p2;
237         if (p2)
238             dctx->kdf_ukmlen = p1;
239         else
240             dctx->kdf_ukmlen = 0;
241         return 1;
242
243     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
244         *(unsigned char **)p2 = dctx->kdf_ukm;
245         return dctx->kdf_ukmlen;
246
247     case EVP_PKEY_CTRL_DH_KDF_OID:
248         if (dctx->kdf_oid)
249             ASN1_OBJECT_free(dctx->kdf_oid);
250         dctx->kdf_oid = p2;
251         return 1;
252
253     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
254         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
255         return 1;
256
257     default:
258         return -2;
259
260     }
261 }
262
263 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
264                             const char *type, const char *value)
265 {
266     if (!strcmp(type, "dh_paramgen_prime_len")) {
267         int len;
268         len = atoi(value);
269         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
270     }
271     if (!strcmp(type, "dh_rfc5114")) {
272         DH_PKEY_CTX *dctx = ctx->data;
273         int len;
274         len = atoi(value);
275         if (len < 0 || len > 3)
276             return -2;
277         dctx->rfc5114_param = len;
278         return 1;
279     }
280     if (!strcmp(type, "dh_paramgen_generator")) {
281         int len;
282         len = atoi(value);
283         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
284     }
285     if (!strcmp(type, "dh_paramgen_subprime_len")) {
286         int len;
287         len = atoi(value);
288         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
289     }
290     if (!strcmp(type, "dh_paramgen_type")) {
291         int typ;
292         typ = atoi(value);
293         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
294     }
295     return -2;
296 }
297
298 #ifndef OPENSSL_NO_DSA
299
300 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
301                                 const EVP_MD *evpmd,
302                                 const unsigned char *seed_in, size_t seed_len,
303                                 unsigned char *seed_out, int *counter_ret,
304                                 unsigned long *h_ret, BN_GENCB *cb);
305
306 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
307                                  const EVP_MD *evpmd,
308                                  const unsigned char *seed_in,
309                                  size_t seed_len, int idx,
310                                  unsigned char *seed_out, int *counter_ret,
311                                  unsigned long *h_ret, BN_GENCB *cb);
312
313 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
314 {
315     DSA *ret;
316     int rv = 0;
317     int prime_len = dctx->prime_len;
318     int subprime_len = dctx->subprime_len;
319     const EVP_MD *md = dctx->md;
320     if (dctx->use_dsa > 2)
321         return NULL;
322     ret = DSA_new();
323     if (!ret)
324         return NULL;
325     if (subprime_len == -1) {
326         if (prime_len >= 2048)
327             subprime_len = 256;
328         else
329             subprime_len = 160;
330     }
331     if (md == NULL) {
332         if (prime_len >= 2048)
333             md = EVP_sha256();
334         else
335             md = EVP_sha1();
336     }
337     if (dctx->use_dsa == 1)
338         rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
339                                   NULL, 0, NULL, NULL, NULL, pcb);
340     else if (dctx->use_dsa == 2)
341         rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
342                                    NULL, 0, -1, NULL, NULL, NULL, pcb);
343     if (rv <= 0) {
344         DSA_free(ret);
345         return NULL;
346     }
347     return ret;
348 }
349
350 #endif
351
352 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
353 {
354     DH *dh = NULL;
355     DH_PKEY_CTX *dctx = ctx->data;
356     BN_GENCB *pcb;
357     int ret;
358     if (dctx->rfc5114_param) {
359         switch (dctx->rfc5114_param) {
360         case 1:
361             dh = DH_get_1024_160();
362             break;
363
364         case 2:
365             dh = DH_get_2048_224();
366             break;
367
368         case 3:
369             dh = DH_get_2048_256();
370             break;
371
372         default:
373             return -2;
374         }
375         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
376         return 1;
377     }
378
379     if (ctx->pkey_gencb) {
380         pcb = BN_GENCB_new();
381         evp_pkey_set_cb_translate(pcb, ctx);
382     } else
383         pcb = NULL;
384 #ifndef OPENSSL_NO_DSA
385     if (dctx->use_dsa) {
386         DSA *dsa_dh;
387         dsa_dh = dsa_dh_generate(dctx, pcb);
388         if (pcb)
389             BN_GENCB_free(pcb);
390         if (!dsa_dh)
391             return 0;
392         dh = DSA_dup_DH(dsa_dh);
393         DSA_free(dsa_dh);
394         if (!dh)
395             return 0;
396         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
397         return 1;
398     }
399 #endif
400     dh = DH_new();
401     if (!dh) {
402         if (pcb)
403             BN_GENCB_free(pcb);
404         return 0;
405     }
406     ret = DH_generate_parameters_ex(dh,
407                                     dctx->prime_len, dctx->generator, pcb);
408     if (pcb)
409         BN_GENCB_free(pcb);
410     if (ret)
411         EVP_PKEY_assign_DH(pkey, dh);
412     else
413         DH_free(dh);
414     return ret;
415 }
416
417 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
418 {
419     DH *dh = NULL;
420     if (ctx->pkey == NULL) {
421         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
422         return 0;
423     }
424     dh = DH_new();
425     if (!dh)
426         return 0;
427     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
428     /* Note: if error return, pkey is freed by parent routine */
429     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
430         return 0;
431     return DH_generate_key(pkey->pkey.dh);
432 }
433
434 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
435                           size_t *keylen)
436 {
437     int ret;
438     DH *dh;
439     DH_PKEY_CTX *dctx = ctx->data;
440     BIGNUM *dhpub;
441     if (!ctx->pkey || !ctx->peerkey) {
442         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
443         return 0;
444     }
445     dh = ctx->pkey->pkey.dh;
446     dhpub = ctx->peerkey->pkey.dh->pub_key;
447     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
448         if (key == NULL) {
449             *keylen = DH_size(dh);
450             return 1;
451         }
452         ret = DH_compute_key(key, dhpub, dh);
453         if (ret < 0)
454             return ret;
455         *keylen = ret;
456         return 1;
457     } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
458         unsigned char *Z = NULL;
459         size_t Zlen = 0;
460         if (!dctx->kdf_outlen || !dctx->kdf_oid)
461             return 0;
462         if (key == NULL) {
463             *keylen = dctx->kdf_outlen;
464             return 1;
465         }
466         if (*keylen != dctx->kdf_outlen)
467             return 0;
468         ret = 0;
469         Zlen = DH_size(dh);
470         Z = OPENSSL_malloc(Zlen);
471         if (DH_compute_key_padded(Z, dhpub, 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         if (Z) {
480             OPENSSL_cleanse(Z, Zlen);
481             OPENSSL_free(Z);
482         }
483         return ret;
484     }
485     return 1;
486 }
487
488 const EVP_PKEY_METHOD dh_pkey_meth = {
489     EVP_PKEY_DH,
490     0,
491     pkey_dh_init,
492     pkey_dh_copy,
493     pkey_dh_cleanup,
494
495     0,
496     pkey_dh_paramgen,
497
498     0,
499     pkey_dh_keygen,
500
501     0,
502     0,
503
504     0,
505     0,
506
507     0, 0,
508
509     0, 0, 0, 0,
510
511     0, 0,
512
513     0, 0,
514
515     0,
516     pkey_dh_derive,
517
518     pkey_dh_ctrl,
519     pkey_dh_ctrl_str
520 };
521
522 const EVP_PKEY_METHOD dhx_pkey_meth = {
523     EVP_PKEY_DHX,
524     0,
525     pkey_dh_init,
526     pkey_dh_copy,
527     pkey_dh_cleanup,
528
529     0,
530     pkey_dh_paramgen,
531
532     0,
533     pkey_dh_keygen,
534
535     0,
536     0,
537
538     0,
539     0,
540
541     0, 0,
542
543     0, 0, 0, 0,
544
545     0, 0,
546
547     0, 0,
548
549     0,
550     pkey_dh_derive,
551
552     pkey_dh_ctrl,
553     pkey_dh_ctrl_str
554 };