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