1/*
2 * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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 <openssl/evp.h>
11#include <openssl/core_names.h>
12#include <openssl/param_build.h>
13
14#include "predefined_dhparams.h"
15
16#ifndef OPENSSL_NO_DH
17
18static EVP_PKEY *get_dh_from_pg_bn(OSSL_LIB_CTX *libctx, const char *type,
19                                   BIGNUM *p, BIGNUM *g, BIGNUM *q)
20{
21    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(libctx, type, NULL);
22    OSSL_PARAM_BLD *tmpl = NULL;
23    OSSL_PARAM *params = NULL;
24    EVP_PKEY *dhpkey = NULL;
25
26    if (pctx == NULL || EVP_PKEY_fromdata_init(pctx) <= 0)
27        goto err;
28
29    if ((tmpl = OSSL_PARAM_BLD_new()) == NULL
30            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
31            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)
32            || (q != NULL
33                && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)))
34        goto err;
35
36    params = OSSL_PARAM_BLD_to_param(tmpl);
37    if (params == NULL
38        || EVP_PKEY_fromdata(pctx, &dhpkey, EVP_PKEY_KEY_PARAMETERS, params) <= 0)
39        goto err;
40
41 err:
42    EVP_PKEY_CTX_free(pctx);
43    OSSL_PARAM_free(params);
44    OSSL_PARAM_BLD_free(tmpl);
45    return dhpkey;
46}
47
48static EVP_PKEY *get_dh_from_pg(OSSL_LIB_CTX *libctx, const char *type,
49                                unsigned char *pdata, size_t plen,
50                                unsigned char *gdata, size_t glen,
51                                unsigned char *qdata, size_t qlen)
52{
53    EVP_PKEY *dhpkey = NULL;
54    BIGNUM *p = NULL, *g = NULL, *q = NULL;
55
56    p = BN_bin2bn(pdata, plen, NULL);
57    g = BN_bin2bn(gdata, glen, NULL);
58    if (p == NULL || g == NULL)
59        goto err;
60    if (qdata != NULL && (q = BN_bin2bn(qdata, qlen, NULL)) == NULL)
61        goto err;
62
63    dhpkey = get_dh_from_pg_bn(libctx, type, p, g, q);
64
65 err:
66    BN_free(p);
67    BN_free(g);
68    BN_free(q);
69    return dhpkey;
70}
71
72EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx)
73{
74    static unsigned char dh512_p[] = {
75        0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0, 0xC6,
76        0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04, 0xB0,
77        0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9, 0x5F,
78        0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33, 0xB8,
79        0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21, 0x33,
80        0x02, 0xC5, 0xAE, 0x23,
81    };
82    static unsigned char dh512_g[] = {
83        0x02,
84    };
85
86    return get_dh_from_pg(libctx, "DH", dh512_p, sizeof(dh512_p),
87                          dh512_g, sizeof(dh512_g), NULL, 0);
88}
89
90EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx)
91{
92    static unsigned char dhx512_p[] = {
93        0x00, 0xe8, 0x1a, 0xb7, 0x9a, 0x02, 0x65, 0x64, 0x94, 0x7b, 0xba, 0x09,
94        0x1c, 0x12, 0x27, 0x1e, 0xea, 0x89, 0x32, 0x64, 0x78, 0xf8, 0x1c, 0x78,
95        0x8e, 0x96, 0xc3, 0xc6, 0x9f, 0x41, 0x05, 0x41, 0x65, 0xae, 0xe3, 0x05,
96        0xea, 0x66, 0x21, 0xf7, 0x38, 0xb7, 0x2b, 0x32, 0x40, 0x5a, 0x14, 0x86,
97        0x51, 0x94, 0xb1, 0xcf, 0x01, 0xe3, 0x27, 0x28, 0xf6, 0x75, 0xa3, 0x15,
98        0xbb, 0x12, 0x4d, 0x99, 0xe7,
99    };
100    static unsigned char dhx512_g[] = {
101        0x00, 0x91, 0xc1, 0x43, 0x6d, 0x0d, 0xb0, 0xa4, 0xde, 0x41, 0xb7, 0x93,
102        0xad, 0x51, 0x94, 0x1b, 0x43, 0xd8, 0x42, 0xf1, 0x5e, 0x46, 0x83, 0x5d,
103        0xf1, 0xd1, 0xf0, 0x41, 0x10, 0xd1, 0x1c, 0x5e, 0xad, 0x9b, 0x68, 0xb1,
104        0x6f, 0xf5, 0x8e, 0xaa, 0x6d, 0x71, 0x88, 0x37, 0xdf, 0x05, 0xf7, 0x6e,
105        0x7a, 0xb4, 0x25, 0x10, 0x6c, 0x7f, 0x38, 0xb4, 0xc8, 0xfc, 0xcc, 0x0c,
106        0x6a, 0x02, 0x08, 0x61, 0xf6,
107    };
108    static unsigned char dhx512_q[] = {
109        0x00, 0xdd, 0xf6, 0x35, 0xad, 0xfa, 0x70, 0xc7, 0xe7, 0xa8, 0xf0, 0xe3,
110        0xda, 0x79, 0x34, 0x3f, 0x5b, 0xcf, 0x73, 0x82, 0x91,
111    };
112
113    return get_dh_from_pg(libctx, "X9.42 DH",
114                          dhx512_p, sizeof(dhx512_p),
115                          dhx512_g, sizeof(dhx512_g),
116                          dhx512_q, sizeof(dhx512_q));
117}
118
119EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx)
120{
121    static unsigned char dh1024_p[] = {
122        0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00,
123        0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19,
124        0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2,
125        0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55,
126        0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC,
127        0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97,
128        0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D,
129        0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB,
130        0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6,
131        0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E,
132        0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39,
133    };
134    static unsigned char dh1024_g[] = {
135        0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05,
136        0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3,
137        0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9,
138        0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C,
139        0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65,
140        0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60,
141        0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6,
142        0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7,
143        0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1,
144        0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60,
145        0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
146    };
147
148    return get_dh_from_pg(libctx, "DH", dh1024_p, sizeof(dh1024_p),
149                          dh1024_g, sizeof(dh1024_g), NULL, 0);
150}
151
152EVP_PKEY *get_dh2048(OSSL_LIB_CTX *libctx)
153{
154    BIGNUM *p = NULL, *g = NULL;
155    EVP_PKEY *dhpkey = NULL;
156
157    g = BN_new();
158    if (g == NULL || !BN_set_word(g, 2))
159        goto err;
160
161    p = BN_get_rfc3526_prime_2048(NULL);
162    if (p == NULL)
163        goto err;
164
165    dhpkey = get_dh_from_pg_bn(libctx, "DH", p, g, NULL);
166
167 err:
168    BN_free(p);
169    BN_free(g);
170    return dhpkey;
171}
172
173EVP_PKEY *get_dh4096(OSSL_LIB_CTX *libctx)
174{
175    BIGNUM *p = NULL, *g = NULL;
176    EVP_PKEY *dhpkey = NULL;
177
178    g = BN_new();
179    if (g == NULL || !BN_set_word(g, 2))
180        goto err;
181
182    p = BN_get_rfc3526_prime_4096(NULL);
183    if (p == NULL)
184        goto err;
185
186    dhpkey = get_dh_from_pg_bn(libctx, "DH", p, g, NULL);
187
188 err:
189    BN_free(p);
190    BN_free(g);
191    return dhpkey;
192}
193
194#endif
195