941801df46a7ae8331d9846ee0eeda2f5c6ba37c
[openssl.git] / crypto / dh / dh_pmeth.c
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer. 
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #include <stdio.h>
59 #include "cryptlib.h"
60 #include <openssl/asn1t.h>
61 #include <openssl/x509.h>
62 #include <openssl/evp.h>
63 #include <openssl/dh.h>
64 #include <openssl/bn.h>
65 #ifndef OPENSSL_NO_DSA
66 #include <openssl/dsa.h>
67 #endif
68 #include <openssl/objects.h>
69 #include "evp_locl.h"
70
71 /* DH pkey context structure */
72
73 typedef struct
74         {
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                 {
146                 dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
147                 dctx->kdf_ukmlen = sctx->kdf_ukmlen;
148                 }
149         dctx->kdf_outlen = sctx->kdf_outlen;
150         return 1;
151         }
152
153 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
154         {
155         DH_PKEY_CTX *dctx = ctx->data;
156         if (dctx)
157                 {
158                 if (dctx->kdf_ukm)
159                         OPENSSL_free(dctx->kdf_ukm);
160                 if (dctx->kdf_oid)
161                         ASN1_OBJECT_free(dctx->kdf_oid);
162                 OPENSSL_free(dctx);
163                 }
164         }
165
166 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
167         {
168         DH_PKEY_CTX *dctx = ctx->data;
169         switch (type)
170                 {
171                 case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
172                 if (p1 < 256)
173                         return -2;
174                 dctx->prime_len = p1;
175                 return 1;
176
177                 case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
178                 if (dctx->use_dsa == 0)
179                         return -2;
180                 dctx->subprime_len = p1;
181                 return 1;
182
183                 case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
184                 if (dctx->use_dsa)
185                         return -2;
186                 dctx->generator = p1;
187                 return 1;
188
189                 case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
190 #ifdef OPENSSL_NO_DSA
191                 if (p1 != 0)
192                         return -2;
193 #else
194                 if (p1 < 0 || p1 > 2)
195                         return -2;
196 #endif
197                 dctx->use_dsa = p1;
198                 return 1;
199
200                 case EVP_PKEY_CTRL_DH_RFC5114:
201                 if (p1 < 1 || p1 > 3)
202                         return -2;
203                 dctx->rfc5114_param = p1;
204                 return 1;
205
206                 case EVP_PKEY_CTRL_PEER_KEY:
207                 /* Default behaviour is OK */
208                 return 1;
209
210                 case EVP_PKEY_CTRL_DH_KDF_TYPE:
211                 if (p1 == -2)
212                         return dctx->kdf_type;
213                 if (p1 != EVP_PKEY_DH_KDF_NONE &&
214                     p1 != EVP_PKEY_DH_KDF_X9_42)
215                         return -2;
216                 dctx->kdf_type = p1;
217                 return 1;
218
219                 case EVP_PKEY_CTRL_DH_KDF_MD:
220                 dctx->kdf_md = p2;
221                 return 1;
222
223                 case EVP_PKEY_CTRL_GET_DH_KDF_MD:
224                 *(const EVP_MD **)p2 = dctx->kdf_md;
225                 return 1;
226
227                 case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
228                 if (p1 <= 0)
229                         return -2;
230                 dctx->kdf_outlen = (size_t)p1;
231                 return 1;
232
233                 case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
234                 *(int *)p2 = dctx->kdf_outlen;
235                 return 1;
236
237                 case EVP_PKEY_CTRL_DH_KDF_UKM:
238                 if (dctx->kdf_ukm)
239                         OPENSSL_free(dctx->kdf_ukm);
240                 dctx->kdf_ukm = p2;
241                 if (p2)
242                         dctx->kdf_ukmlen = p1;
243                 else
244                         dctx->kdf_ukmlen = 0;
245                 return 1;
246
247                 case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
248                 *(unsigned char **)p2 = dctx->kdf_ukm;
249                 return dctx->kdf_ukmlen;
250
251                 case EVP_PKEY_CTRL_DH_KDF_OID:
252                 if (dctx->kdf_oid)
253                         ASN1_OBJECT_free(dctx->kdf_oid);
254                 dctx->kdf_oid = p2;
255                 return 1;
256
257                 case EVP_PKEY_CTRL_GET_DH_KDF_OID:
258                 *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
259                 return 1;
260
261                 default:
262                 return -2;
263
264                 }
265         }
266
267
268 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
269                         const char *type, const char *value)
270         {
271         if (!strcmp(type, "dh_paramgen_prime_len"))
272                 {
273                 int len;
274                 len = atoi(value);
275                 return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
276                 }
277         if (!strcmp(type, "dh_rfc5114"))
278                 {
279                 DH_PKEY_CTX *dctx = ctx->data;
280                 int len;
281                 len = atoi(value);
282                 if (len < 0 || len > 3)
283                         return -2;
284                 dctx->rfc5114_param = len;
285                 return 1;
286                 }
287         if (!strcmp(type, "dh_paramgen_generator"))
288                 {
289                 int len;
290                 len = atoi(value);
291                 return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
292                 }
293         if (!strcmp(type, "dh_paramgen_subprime_len"))
294                 {
295                 int len;
296                 len = atoi(value);
297                 return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
298                 }
299         if (!strcmp(type, "dh_paramgen_type"))
300                 {
301                 int typ;
302                 typ = atoi(value);
303                 return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
304                 }
305         return -2;
306         }
307
308 #ifndef OPENSSL_NO_DSA
309
310 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
311         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
312         unsigned char *seed_out,
313         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
314
315 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
316         const EVP_MD *evpmd, const unsigned char *seed_in, size_t seed_len,
317         int idx, unsigned char *seed_out,
318         int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
319
320 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
321         {
322         DSA *ret;
323         int rv = 0;
324         int prime_len = dctx->prime_len;
325         int subprime_len = dctx->subprime_len;
326         const EVP_MD *md = dctx->md;
327         if (dctx->use_dsa > 2)
328                 return NULL;
329         ret = DSA_new();
330         if (!ret)
331                 return NULL;
332         if (subprime_len == -1)
333                 {
334                 if (prime_len >= 2048)
335                         subprime_len = 256;
336                 else
337                         subprime_len = 160;
338                 }
339         if (md == NULL)
340                 {
341                 if (prime_len >= 2048)
342                         md = EVP_sha256();
343                 else
344                         md = EVP_sha1();
345                 }
346         if (dctx->use_dsa == 1)
347                 rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
348                                                 NULL, 0, NULL, NULL, NULL, pcb);
349         else if(dctx->use_dsa == 2)
350                 rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
351                                            NULL, 0, -1, NULL, NULL, NULL, pcb);
352         if (rv <= 0)
353                 {
354                 DSA_free(ret);
355                 return NULL;
356                 }
357         return ret;
358         }
359
360 #endif
361
362 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
363         {
364         DH *dh = NULL;
365         DH_PKEY_CTX *dctx = ctx->data;
366         BN_GENCB *pcb, cb;
367         int ret;
368         if (dctx->rfc5114_param)
369                 {
370                 switch (dctx->rfc5114_param)
371                         {
372                         case 1:
373                         dh = DH_get_1024_160();
374                         break;
375
376                         case 2:
377                         dh = DH_get_2048_224();
378                         break;
379
380                         case 3:
381                         dh = DH_get_2048_256();
382                         break;
383         
384                         default:
385                         return -2;
386                         }
387                 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
388                 return 1;
389                 }
390
391         if (ctx->pkey_gencb)
392                 {
393                 pcb = &cb;
394                 evp_pkey_set_cb_translate(pcb, ctx);
395                 }
396         else
397                 pcb = NULL;
398 #ifndef OPENSSL_NO_DSA
399         if (dctx->use_dsa)
400                 {
401                 DSA *dsa_dh;
402                 dsa_dh = dsa_dh_generate(dctx, pcb);
403                 if (!dsa_dh)
404                         return 0;
405                 dh = DSA_dup_DH(dsa_dh);
406                 DSA_free(dsa_dh);
407                 if (!dh)
408                         return 0;
409                 EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
410                 return 1;
411                 }
412 #endif
413         dh = DH_new();
414         if (!dh)
415                 return 0;
416         ret = DH_generate_parameters_ex(dh,
417                                         dctx->prime_len, dctx->generator, pcb);
418                 
419         if (ret)
420                 EVP_PKEY_assign_DH(pkey, dh);
421         else
422                 DH_free(dh);
423         return ret;
424         }
425
426 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
427         {
428         DH *dh = NULL;
429         if (ctx->pkey == NULL)
430                 {
431                 DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
432                 return 0;
433                 }
434         dh = DH_new();
435         if (!dh)
436                 return 0;
437         EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
438         /* Note: if error return, pkey is freed by parent routine */
439         if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
440                 return 0;
441         return DH_generate_key(pkey->pkey.dh);
442         }
443
444 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
445         {
446         int ret;
447         DH *dh;
448         DH_PKEY_CTX *dctx = ctx->data;
449         BIGNUM *dhpub;
450         if (!ctx->pkey || !ctx->peerkey)
451                 {
452                 DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
453                 return 0;
454                 }
455         dh = ctx->pkey->pkey.dh;
456         dhpub = ctx->peerkey->pkey.dh->pub_key;
457         if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE)
458                 {
459                 if (key == NULL)
460                         {
461                         *keylen = DH_size(dh);
462                         return 1;
463                         }
464                 ret = DH_compute_key(key, dhpub, dh);
465                 if (ret < 0)
466                         return ret;
467                 *keylen = ret;
468                 return 1;
469                 }
470         else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42)
471                 {
472                 unsigned char *Z = NULL;
473                 size_t Zlen = 0;
474                 if (!dctx->kdf_outlen || !dctx->kdf_oid)
475                         return 0;
476                 if (key == NULL)
477                         {
478                         *keylen = dctx->kdf_outlen;
479                         return 1;
480                         }
481                 if (*keylen != dctx->kdf_outlen)
482                         return 0;
483                 ret = 0;
484                 Zlen = DH_size(dh);
485                 Z = OPENSSL_malloc(Zlen);
486                 if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
487                         goto err;
488                 if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
489                                         dctx->kdf_ukm, dctx->kdf_ukmlen,
490                                         dctx->kdf_md))
491                         goto err;
492                 *keylen = dctx->kdf_outlen;
493                 ret = 1;
494                 err:
495                 if (Z)
496                         {
497                         OPENSSL_cleanse(Z, Zlen);
498                         OPENSSL_free(Z);
499                         }
500                 return ret;
501                 }
502         return 1;
503         }
504
505 const EVP_PKEY_METHOD dh_pkey_meth = 
506         {
507         EVP_PKEY_DH,
508         0,
509         pkey_dh_init,
510         pkey_dh_copy,
511         pkey_dh_cleanup,
512
513         0,
514         pkey_dh_paramgen,
515
516         0,
517         pkey_dh_keygen,
518
519         0,
520         0,
521
522         0,
523         0,
524
525         0,0,
526
527         0,0,0,0,
528
529         0,0,
530
531         0,0,
532
533         0,
534         pkey_dh_derive,
535
536         pkey_dh_ctrl,
537         pkey_dh_ctrl_str
538
539         };
540
541 const EVP_PKEY_METHOD dhx_pkey_meth = 
542         {
543         EVP_PKEY_DHX,
544         0,
545         pkey_dh_init,
546         pkey_dh_copy,
547         pkey_dh_cleanup,
548
549         0,
550         pkey_dh_paramgen,
551
552         0,
553         pkey_dh_keygen,
554
555         0,
556         0,
557
558         0,
559         0,
560
561         0,0,
562
563         0,0,0,0,
564
565         0,0,
566
567         0,0,
568
569         0,
570         pkey_dh_derive,
571
572         pkey_dh_ctrl,
573         pkey_dh_ctrl_str
574
575         };