dh_pmeth.c revision 348343
1/*
2 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3 * 2006.
4 */
5/* ====================================================================
6 * Copyright (c) 2006-2019 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
74typedef 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
98static 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 = 2048;
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
125static 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
152static 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
164static 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#ifdef OPENSSL_NO_CMS
211        if (p1 != EVP_PKEY_DH_KDF_NONE)
212#else
213        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
214#endif
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
267static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
268                            const char *type, const char *value)
269{
270    if (!strcmp(type, "dh_paramgen_prime_len")) {
271        int len;
272        len = atoi(value);
273        return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
274    }
275    if (!strcmp(type, "dh_rfc5114")) {
276        DH_PKEY_CTX *dctx = ctx->data;
277        int len;
278        len = atoi(value);
279        if (len < 0 || len > 3)
280            return -2;
281        dctx->rfc5114_param = len;
282        return 1;
283    }
284    if (!strcmp(type, "dh_paramgen_generator")) {
285        int len;
286        len = atoi(value);
287        return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
288    }
289    if (!strcmp(type, "dh_paramgen_subprime_len")) {
290        int len;
291        len = atoi(value);
292        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
293    }
294    if (!strcmp(type, "dh_paramgen_type")) {
295        int typ;
296        typ = atoi(value);
297        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
298    }
299    return -2;
300}
301
302#ifndef OPENSSL_NO_DSA
303
304extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
305                                const EVP_MD *evpmd,
306                                const unsigned char *seed_in, size_t seed_len,
307                                unsigned char *seed_out, int *counter_ret,
308                                unsigned long *h_ret, BN_GENCB *cb);
309
310extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
311                                 const EVP_MD *evpmd,
312                                 const unsigned char *seed_in,
313                                 size_t seed_len, int idx,
314                                 unsigned char *seed_out, int *counter_ret,
315                                 unsigned long *h_ret, BN_GENCB *cb);
316
317static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
318{
319    DSA *ret;
320    int rv = 0;
321    int prime_len = dctx->prime_len;
322    int subprime_len = dctx->subprime_len;
323    const EVP_MD *md = dctx->md;
324    if (dctx->use_dsa > 2)
325        return NULL;
326    ret = DSA_new();
327    if (!ret)
328        return NULL;
329    if (subprime_len == -1) {
330        if (prime_len >= 2048)
331            subprime_len = 256;
332        else
333            subprime_len = 160;
334    }
335    if (md == NULL) {
336        if (prime_len >= 2048)
337            md = EVP_sha256();
338        else
339            md = EVP_sha1();
340    }
341    if (dctx->use_dsa == 1)
342        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
343                                  NULL, 0, NULL, NULL, NULL, pcb);
344    else if (dctx->use_dsa == 2)
345        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
346                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
347    if (rv <= 0) {
348        DSA_free(ret);
349        return NULL;
350    }
351    return ret;
352}
353
354#endif
355
356static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
357{
358    DH *dh = NULL;
359    DH_PKEY_CTX *dctx = ctx->data;
360    BN_GENCB *pcb, cb;
361    int ret;
362    if (dctx->rfc5114_param) {
363        switch (dctx->rfc5114_param) {
364        case 1:
365            dh = DH_get_1024_160();
366            break;
367
368        case 2:
369            dh = DH_get_2048_224();
370            break;
371
372        case 3:
373            dh = DH_get_2048_256();
374            break;
375
376        default:
377            return -2;
378        }
379        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
380        return 1;
381    }
382
383    if (ctx->pkey_gencb) {
384        pcb = &cb;
385        evp_pkey_set_cb_translate(pcb, ctx);
386    } else
387        pcb = NULL;
388#ifndef OPENSSL_NO_DSA
389    if (dctx->use_dsa) {
390        DSA *dsa_dh;
391        dsa_dh = dsa_dh_generate(dctx, pcb);
392        if (!dsa_dh)
393            return 0;
394        dh = DSA_dup_DH(dsa_dh);
395        DSA_free(dsa_dh);
396        if (!dh)
397            return 0;
398        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
399        return 1;
400    }
401#endif
402    dh = DH_new();
403    if (!dh)
404        return 0;
405    ret = DH_generate_parameters_ex(dh,
406                                    dctx->prime_len, dctx->generator, pcb);
407
408    if (ret)
409        EVP_PKEY_assign_DH(pkey, dh);
410    else
411        DH_free(dh);
412    return ret;
413}
414
415static 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
432static 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    }
456#ifndef OPENSSL_NO_CMS
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 (!Z) {
472            goto err;
473        }
474        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
475            goto err;
476        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
477                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
478            goto err;
479        *keylen = dctx->kdf_outlen;
480        ret = 1;
481 err:
482        if (Z) {
483            OPENSSL_cleanse(Z, Zlen);
484            OPENSSL_free(Z);
485        }
486        return ret;
487    }
488#endif
489    return 0;
490}
491
492const EVP_PKEY_METHOD dh_pkey_meth = {
493    EVP_PKEY_DH,
494    0,
495    pkey_dh_init,
496    pkey_dh_copy,
497    pkey_dh_cleanup,
498
499    0,
500    pkey_dh_paramgen,
501
502    0,
503    pkey_dh_keygen,
504
505    0,
506    0,
507
508    0,
509    0,
510
511    0, 0,
512
513    0, 0, 0, 0,
514
515    0, 0,
516
517    0, 0,
518
519    0,
520    pkey_dh_derive,
521
522    pkey_dh_ctrl,
523    pkey_dh_ctrl_str
524};
525
526const EVP_PKEY_METHOD dhx_pkey_meth = {
527    EVP_PKEY_DHX,
528    0,
529    pkey_dh_init,
530    pkey_dh_copy,
531    pkey_dh_cleanup,
532
533    0,
534    pkey_dh_paramgen,
535
536    0,
537    pkey_dh_keygen,
538
539    0,
540    0,
541
542    0,
543    0,
544
545    0, 0,
546
547    0, 0, 0, 0,
548
549    0, 0,
550
551    0, 0,
552
553    0,
554    pkey_dh_derive,
555
556    pkey_dh_ctrl,
557    pkey_dh_ctrl_str
558};
559