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