sha/asm/keccak1600-armv4.pl: add NEON code path.
[openssl.git] / crypto / dh / dh_pmeth.c
1 /*
2  * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/asn1t.h>
13 #include <openssl/x509.h>
14 #include <openssl/evp.h>
15 #include "dh_locl.h"
16 #include <openssl/bn.h>
17 #include <openssl/dsa.h>
18 #include <openssl/objects.h>
19 #include "internal/evp_int.h"
20
21 /* DH pkey context structure */
22
23 typedef struct {
24     /* Parameter gen parameters */
25     int prime_len;
26     int generator;
27     int use_dsa;
28     int subprime_len;
29     /* message digest used for parameter generation */
30     const EVP_MD *md;
31     int rfc5114_param;
32     /* Keygen callback info */
33     int gentmp[2];
34     /* KDF (if any) to use for DH */
35     char kdf_type;
36     /* OID to use for KDF */
37     ASN1_OBJECT *kdf_oid;
38     /* Message digest to use for key derivation */
39     const EVP_MD *kdf_md;
40     /* User key material */
41     unsigned char *kdf_ukm;
42     size_t kdf_ukmlen;
43     /* KDF output length */
44     size_t kdf_outlen;
45 } DH_PKEY_CTX;
46
47 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
48 {
49     DH_PKEY_CTX *dctx;
50
51     dctx = OPENSSL_zalloc(sizeof(*dctx));
52     if (dctx == NULL)
53         return 0;
54     dctx->prime_len = 1024;
55     dctx->subprime_len = -1;
56     dctx->generator = 2;
57     dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
58
59     ctx->data = dctx;
60     ctx->keygen_info = dctx->gentmp;
61     ctx->keygen_info_count = 2;
62
63     return 1;
64 }
65
66 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
67 {
68     DH_PKEY_CTX *dctx = ctx->data;
69     if (dctx != NULL) {
70         OPENSSL_free(dctx->kdf_ukm);
71         ASN1_OBJECT_free(dctx->kdf_oid);
72         OPENSSL_free(dctx);
73     }
74 }
75
76
77 static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
78 {
79     DH_PKEY_CTX *dctx, *sctx;
80     if (!pkey_dh_init(dst))
81         return 0;
82     sctx = src->data;
83     dctx = dst->data;
84     dctx->prime_len = sctx->prime_len;
85     dctx->subprime_len = sctx->subprime_len;
86     dctx->generator = sctx->generator;
87     dctx->use_dsa = sctx->use_dsa;
88     dctx->md = sctx->md;
89     dctx->rfc5114_param = sctx->rfc5114_param;
90
91     dctx->kdf_type = sctx->kdf_type;
92     dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
93     if (dctx->kdf_oid == NULL)
94         return 0;
95     dctx->kdf_md = sctx->kdf_md;
96     if (sctx->kdf_ukm != NULL) {
97         dctx->kdf_ukm = OPENSSL_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
98         if (dctx->kdf_ukm == NULL)
99           return 0;
100         dctx->kdf_ukmlen = sctx->kdf_ukmlen;
101     }
102     dctx->kdf_outlen = sctx->kdf_outlen;
103     return 1;
104 }
105
106 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
107 {
108     DH_PKEY_CTX *dctx = ctx->data;
109     switch (type) {
110     case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN:
111         if (p1 < 256)
112             return -2;
113         dctx->prime_len = p1;
114         return 1;
115
116     case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
117         if (dctx->use_dsa == 0)
118             return -2;
119         dctx->subprime_len = p1;
120         return 1;
121
122     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
123         if (dctx->use_dsa)
124             return -2;
125         dctx->generator = p1;
126         return 1;
127
128     case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
129 #ifdef OPENSSL_NO_DSA
130         if (p1 != 0)
131             return -2;
132 #else
133         if (p1 < 0 || p1 > 2)
134             return -2;
135 #endif
136         dctx->use_dsa = p1;
137         return 1;
138
139     case EVP_PKEY_CTRL_DH_RFC5114:
140         if (p1 < 1 || p1 > 3)
141             return -2;
142         dctx->rfc5114_param = p1;
143         return 1;
144
145     case EVP_PKEY_CTRL_PEER_KEY:
146         /* Default behaviour is OK */
147         return 1;
148
149     case EVP_PKEY_CTRL_DH_KDF_TYPE:
150         if (p1 == -2)
151             return dctx->kdf_type;
152 #ifdef OPENSSL_NO_CMS
153         if (p1 != EVP_PKEY_DH_KDF_NONE)
154 #else
155         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
156 #endif
157             return -2;
158         dctx->kdf_type = p1;
159         return 1;
160
161     case EVP_PKEY_CTRL_DH_KDF_MD:
162         dctx->kdf_md = p2;
163         return 1;
164
165     case EVP_PKEY_CTRL_GET_DH_KDF_MD:
166         *(const EVP_MD **)p2 = dctx->kdf_md;
167         return 1;
168
169     case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
170         if (p1 <= 0)
171             return -2;
172         dctx->kdf_outlen = (size_t)p1;
173         return 1;
174
175     case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
176         *(int *)p2 = dctx->kdf_outlen;
177         return 1;
178
179     case EVP_PKEY_CTRL_DH_KDF_UKM:
180         OPENSSL_free(dctx->kdf_ukm);
181         dctx->kdf_ukm = p2;
182         if (p2)
183             dctx->kdf_ukmlen = p1;
184         else
185             dctx->kdf_ukmlen = 0;
186         return 1;
187
188     case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
189         *(unsigned char **)p2 = dctx->kdf_ukm;
190         return dctx->kdf_ukmlen;
191
192     case EVP_PKEY_CTRL_DH_KDF_OID:
193         ASN1_OBJECT_free(dctx->kdf_oid);
194         dctx->kdf_oid = p2;
195         return 1;
196
197     case EVP_PKEY_CTRL_GET_DH_KDF_OID:
198         *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
199         return 1;
200
201     default:
202         return -2;
203
204     }
205 }
206
207 static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
208                             const char *type, const char *value)
209 {
210     if (strcmp(type, "dh_paramgen_prime_len") == 0) {
211         int len;
212         len = atoi(value);
213         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
214     }
215     if (strcmp(type, "dh_rfc5114") == 0) {
216         DH_PKEY_CTX *dctx = ctx->data;
217         int len;
218         len = atoi(value);
219         if (len < 0 || len > 3)
220             return -2;
221         dctx->rfc5114_param = len;
222         return 1;
223     }
224     if (strcmp(type, "dh_paramgen_generator") == 0) {
225         int len;
226         len = atoi(value);
227         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
228     }
229     if (strcmp(type, "dh_paramgen_subprime_len") == 0) {
230         int len;
231         len = atoi(value);
232         return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
233     }
234     if (strcmp(type, "dh_paramgen_type") == 0) {
235         int typ;
236         typ = atoi(value);
237         return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
238     }
239     return -2;
240 }
241
242 #ifndef OPENSSL_NO_DSA
243
244 extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
245                                 const EVP_MD *evpmd,
246                                 const unsigned char *seed_in, size_t seed_len,
247                                 unsigned char *seed_out, int *counter_ret,
248                                 unsigned long *h_ret, BN_GENCB *cb);
249
250 extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
251                                  const EVP_MD *evpmd,
252                                  const unsigned char *seed_in,
253                                  size_t seed_len, int idx,
254                                  unsigned char *seed_out, int *counter_ret,
255                                  unsigned long *h_ret, BN_GENCB *cb);
256
257 static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
258 {
259     DSA *ret;
260     int rv = 0;
261     int prime_len = dctx->prime_len;
262     int subprime_len = dctx->subprime_len;
263     const EVP_MD *md = dctx->md;
264     if (dctx->use_dsa > 2)
265         return NULL;
266     ret = DSA_new();
267     if (ret == NULL)
268         return NULL;
269     if (subprime_len == -1) {
270         if (prime_len >= 2048)
271             subprime_len = 256;
272         else
273             subprime_len = 160;
274     }
275     if (md == NULL) {
276         if (prime_len >= 2048)
277             md = EVP_sha256();
278         else
279             md = EVP_sha1();
280     }
281     if (dctx->use_dsa == 1)
282         rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
283                                   NULL, 0, NULL, NULL, NULL, pcb);
284     else if (dctx->use_dsa == 2)
285         rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
286                                    NULL, 0, -1, NULL, NULL, NULL, pcb);
287     if (rv <= 0) {
288         DSA_free(ret);
289         return NULL;
290     }
291     return ret;
292 }
293
294 #endif
295
296 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
297 {
298     DH *dh = NULL;
299     DH_PKEY_CTX *dctx = ctx->data;
300     BN_GENCB *pcb;
301     int ret;
302     if (dctx->rfc5114_param) {
303         switch (dctx->rfc5114_param) {
304         case 1:
305             dh = DH_get_1024_160();
306             break;
307
308         case 2:
309             dh = DH_get_2048_224();
310             break;
311
312         case 3:
313             dh = DH_get_2048_256();
314             break;
315
316         default:
317             return -2;
318         }
319         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
320         return 1;
321     }
322
323     if (ctx->pkey_gencb) {
324         pcb = BN_GENCB_new();
325         if (pcb == NULL)
326             return 0;
327         evp_pkey_set_cb_translate(pcb, ctx);
328     } else
329         pcb = NULL;
330 #ifndef OPENSSL_NO_DSA
331     if (dctx->use_dsa) {
332         DSA *dsa_dh;
333         dsa_dh = dsa_dh_generate(dctx, pcb);
334         BN_GENCB_free(pcb);
335         if (dsa_dh == NULL)
336             return 0;
337         dh = DSA_dup_DH(dsa_dh);
338         DSA_free(dsa_dh);
339         if (!dh)
340             return 0;
341         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
342         return 1;
343     }
344 #endif
345     dh = DH_new();
346     if (dh == NULL) {
347         BN_GENCB_free(pcb);
348         return 0;
349     }
350     ret = DH_generate_parameters_ex(dh,
351                                     dctx->prime_len, dctx->generator, pcb);
352     BN_GENCB_free(pcb);
353     if (ret)
354         EVP_PKEY_assign_DH(pkey, dh);
355     else
356         DH_free(dh);
357     return ret;
358 }
359
360 static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
361 {
362     DH *dh = NULL;
363     if (ctx->pkey == NULL) {
364         DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET);
365         return 0;
366     }
367     dh = DH_new();
368     if (dh == NULL)
369         return 0;
370     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
371     /* Note: if error return, pkey is freed by parent routine */
372     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
373         return 0;
374     return DH_generate_key(pkey->pkey.dh);
375 }
376
377 static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
378                           size_t *keylen)
379 {
380     int ret;
381     DH *dh;
382     DH_PKEY_CTX *dctx = ctx->data;
383     BIGNUM *dhpub;
384     if (!ctx->pkey || !ctx->peerkey) {
385         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
386         return 0;
387     }
388     dh = ctx->pkey->pkey.dh;
389     dhpub = ctx->peerkey->pkey.dh->pub_key;
390     if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
391         if (key == NULL) {
392             *keylen = DH_size(dh);
393             return 1;
394         }
395         ret = DH_compute_key(key, dhpub, dh);
396         if (ret < 0)
397             return ret;
398         *keylen = ret;
399         return 1;
400     }
401 #ifndef OPENSSL_NO_CMS
402     else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
403
404         unsigned char *Z = NULL;
405         size_t Zlen = 0;
406         if (!dctx->kdf_outlen || !dctx->kdf_oid)
407             return 0;
408         if (key == NULL) {
409             *keylen = dctx->kdf_outlen;
410             return 1;
411         }
412         if (*keylen != dctx->kdf_outlen)
413             return 0;
414         ret = 0;
415         Zlen = DH_size(dh);
416         Z = OPENSSL_malloc(Zlen);
417         if (Z == NULL) {
418             goto err;
419         }
420         if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
421             goto err;
422         if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
423                           dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
424             goto err;
425         *keylen = dctx->kdf_outlen;
426         ret = 1;
427  err:
428         OPENSSL_clear_free(Z, Zlen);
429         return ret;
430     }
431 #endif
432     return 0;
433 }
434
435 const EVP_PKEY_METHOD dh_pkey_meth = {
436     EVP_PKEY_DH,
437     0,
438     pkey_dh_init,
439     pkey_dh_copy,
440     pkey_dh_cleanup,
441
442     0,
443     pkey_dh_paramgen,
444
445     0,
446     pkey_dh_keygen,
447
448     0,
449     0,
450
451     0,
452     0,
453
454     0, 0,
455
456     0, 0, 0, 0,
457
458     0, 0,
459
460     0, 0,
461
462     0,
463     pkey_dh_derive,
464
465     pkey_dh_ctrl,
466     pkey_dh_ctrl_str
467 };
468
469 const EVP_PKEY_METHOD dhx_pkey_meth = {
470     EVP_PKEY_DHX,
471     0,
472     pkey_dh_init,
473     pkey_dh_copy,
474     pkey_dh_cleanup,
475
476     0,
477     pkey_dh_paramgen,
478
479     0,
480     pkey_dh_keygen,
481
482     0,
483     0,
484
485     0,
486     0,
487
488     0, 0,
489
490     0, 0, 0, 0,
491
492     0, 0,
493
494     0, 0,
495
496     0,
497     pkey_dh_derive,
498
499     pkey_dh_ctrl,
500     pkey_dh_ctrl_str
501 };