Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all-8bit/wolfcrypt/src/dh.c
Line
Count
Source
1
/* dh.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#define WC_FIPS_LL_CRYPTO
23
#define _WC_BUILDING_DH_C
24
25
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
26
27
#ifndef NO_DH
28
29
#if defined(HAVE_FIPS) && \
30
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
31
32
    #ifdef USE_WINDOWS_API
33
        #pragma code_seg(".fipsA$e")
34
        #pragma const_seg(".fipsB$e")
35
    #endif
36
#endif
37
38
#include <wolfssl/wolfcrypt/dh.h>
39
40
#ifdef WOLFSSL_HAVE_SP_DH
41
#include <wolfssl/wolfcrypt/sp.h>
42
#endif
43
44
#ifdef NO_INLINE
45
    #include <wolfssl/wolfcrypt/misc.h>
46
#else
47
    #define WOLFSSL_MISC_INCLUDED
48
    #include <wolfcrypt/src/misc.c>
49
#endif
50
51
#if FIPS_VERSION3_GE(6,0,0)
52
    const unsigned int wolfCrypt_FIPS_dh_ro_sanity[2] =
53
                                                     { 0x1a2b3c4d, 0x00000004 };
54
    int wolfCrypt_FIPS_DH_sanity(void)
55
    {
56
        return 0;
57
    }
58
#endif
59
60
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
61
62
/* Note that the wc_dh_enabled runtime feature-switching facility is neither
63
 * thread-synchronized nor thread-local, and is only allowed during global
64
 * initialization or self-test sequences before application service begins.
65
 */
66
67
static volatile int wc_dh_enabled = WC_DH_INITIAL_RUNTIME_ENABLEMENT;
68
int wc_dh_enable(void) {
69
    if (wc_dh_enabled)
70
        return ALREADY_E;
71
    else {
72
        wc_dh_enabled = 1;
73
        return 0;
74
    }
75
}
76
int wc_dh_disable(void) {
77
    if (wc_dh_enabled) {
78
        wc_dh_enabled = 0;
79
        return 0;
80
    }
81
    else
82
        return ALREADY_E;
83
}
84
int wc_dh_is_enabled(void) {
85
    return wc_dh_enabled;
86
}
87
#endif
88
89
/*
90
Possible DH enable options:
91
 * NO_RSA:              Overall control of DH                 default: on (not defined)
92
 * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
93
                        directly effect this file, but it does speed up DH
94
                        removing the testing. It is not recommended to
95
                        disable the prime checking.           default: off
96
 * WOLFSSL_VALIDATE_DH_KEYGEN: Enable DH key gen consistency checking
97
 *                             (on for FIPS 140-3 or later)   default: off
98
*/
99
100
101
#if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
102
    #include <math.h>
103
330
    #define XPOW(x,y) pow((x),(y))
104
    #define XLOG(x)   log((x))
105
#else
106
    /* user's own math lib */
107
#endif
108
109
#ifdef HAVE_FFDHE_2048
110
static const byte dh_ffdhe2048_p[] = {
111
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
112
    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
113
    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
114
    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
115
    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
116
    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
117
    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
118
    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
119
    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
120
    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
121
    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
122
    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
123
    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
124
    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
125
    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
126
    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
127
    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
128
    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
129
    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
130
    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
131
    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
132
    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
133
    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
134
    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
135
    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
136
    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
137
    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
138
    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
139
    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
140
    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
141
    0x88, 0x6B, 0x42, 0x38, 0x61, 0x28, 0x5C, 0x97,
142
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
143
};
144
static const byte dh_ffdhe2048_g[] = { 0x02 };
145
#ifdef HAVE_FFDHE_Q
146
static const byte dh_ffdhe2048_q[] = {
147
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
148
    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
149
    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
150
    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
151
    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
152
    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
153
    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
154
    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
155
    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
156
    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
157
    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
158
    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
159
    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
160
    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
161
    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
162
    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
163
    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
164
    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
165
    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
166
    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
167
    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
168
    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
169
    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
170
    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
171
    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
172
    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
173
    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
174
    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
175
    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
176
    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
177
    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x94, 0x2E, 0x4B,
178
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
179
};
180
#endif /* HAVE_FFDHE_Q */
181
182
#ifdef HAVE_PUBLIC_FFDHE
183
const DhParams* wc_Dh_ffdhe2048_Get(void)
184
2.04k
{
185
2.04k
    static const DhParams ffdhe2048 = {
186
        #ifdef HAVE_FFDHE_Q
187
            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
188
        #endif /* HAVE_FFDHE_Q */
189
2.04k
        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
190
2.04k
        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
191
2.04k
    };
192
2.04k
    return &ffdhe2048;
193
2.04k
}
194
#endif
195
#endif
196
197
#ifdef HAVE_FFDHE_3072
198
static const byte dh_ffdhe3072_p[] = {
199
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
200
    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
201
    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
202
    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
203
    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
204
    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
205
    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
206
    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
207
    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
208
    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
209
    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
210
    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
211
    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
212
    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
213
    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
214
    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
215
    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
216
    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
217
    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
218
    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
219
    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
220
    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
221
    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
222
    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
223
    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
224
    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
225
    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
226
    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
227
    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
228
    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
229
    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
230
    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
231
    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
232
    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
233
    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
234
    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
235
    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
236
    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
237
    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
238
    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
239
    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
240
    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
241
    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
242
    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
243
    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
244
    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
245
    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0xC6, 0x2E, 0x37,
246
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
247
};
248
static const byte dh_ffdhe3072_g[] = { 0x02 };
249
#ifdef HAVE_FFDHE_Q
250
static const byte dh_ffdhe3072_q[] = {
251
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
252
    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
253
    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
254
    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
255
    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
256
    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
257
    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
258
    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
259
    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
260
    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
261
    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
262
    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
263
    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
264
    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
265
    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
266
    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
267
    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
268
    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
269
    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
270
    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
271
    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
272
    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
273
    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
274
    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
275
    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
276
    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
277
    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
278
    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
279
    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
280
    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
281
    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
282
    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
283
    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
284
    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
285
    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
286
    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
287
    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
288
    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
289
    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
290
    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
291
    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
292
    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
293
    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
294
    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
295
    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
296
    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
297
    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x63, 0x17, 0x1B,
298
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
299
};
300
#endif /* HAVE_FFDHE_Q */
301
302
#ifdef HAVE_PUBLIC_FFDHE
303
const DhParams* wc_Dh_ffdhe3072_Get(void)
304
{
305
    static const DhParams ffdhe3072 = {
306
        #ifdef HAVE_FFDHE_Q
307
            dh_ffdhe3072_q, sizeof(dh_ffdhe3072_q),
308
        #endif /* HAVE_FFDHE_Q */
309
        dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p),
310
        dh_ffdhe3072_g, sizeof(dh_ffdhe3072_g)
311
    };
312
    return &ffdhe3072;
313
}
314
#endif
315
#endif
316
317
#ifdef HAVE_FFDHE_4096
318
static const byte dh_ffdhe4096_p[] = {
319
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
320
    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
321
    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
322
    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
323
    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
324
    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
325
    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
326
    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
327
    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
328
    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
329
    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
330
    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
331
    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
332
    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
333
    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
334
    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
335
    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
336
    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
337
    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
338
    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
339
    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
340
    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
341
    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
342
    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
343
    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
344
    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
345
    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
346
    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
347
    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
348
    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
349
    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
350
    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
351
    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
352
    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
353
    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
354
    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
355
    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
356
    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
357
    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
358
    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
359
    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
360
    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
361
    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
362
    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
363
    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
364
    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
365
    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
366
    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
367
    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
368
    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
369
    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
370
    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
371
    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
372
    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
373
    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
374
    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
375
    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
376
    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
377
    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
378
    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
379
    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
380
    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
381
    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x65, 0x5F, 0x6A,
382
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
383
};
384
static const byte dh_ffdhe4096_g[] = { 0x02 };
385
#ifdef HAVE_FFDHE_Q
386
static const byte dh_ffdhe4096_q[] = {
387
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
388
    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
389
    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
390
    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
391
    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
392
    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
393
    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
394
    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
395
    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
396
    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
397
    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
398
    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
399
    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
400
    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
401
    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
402
    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
403
    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
404
    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
405
    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
406
    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
407
    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
408
    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
409
    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
410
    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
411
    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
412
    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
413
    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
414
    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
415
    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
416
    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
417
    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
418
    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
419
    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
420
    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
421
    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
422
    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
423
    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
424
    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
425
    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
426
    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
427
    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
428
    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
429
    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
430
    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
431
    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
432
    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
433
    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
434
    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
435
    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
436
    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
437
    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
438
    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
439
    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
440
    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
441
    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
442
    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
443
    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
444
    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
445
    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
446
    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
447
    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
448
    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
449
    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x32, 0xAF, 0xB5,
450
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
451
};
452
#endif /* HAVE_FFDHE_Q */
453
454
#ifdef HAVE_PUBLIC_FFDHE
455
const DhParams* wc_Dh_ffdhe4096_Get(void)
456
{
457
    static const DhParams ffdhe4096 = {
458
        #ifdef HAVE_FFDHE_Q
459
            dh_ffdhe4096_q, sizeof(dh_ffdhe4096_q),
460
        #endif /* HAVE_FFDHE_Q */
461
        dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p),
462
        dh_ffdhe4096_g, sizeof(dh_ffdhe4096_g)
463
    };
464
    return &ffdhe4096;
465
}
466
#endif
467
#endif
468
469
#ifdef HAVE_FFDHE_6144
470
static const byte dh_ffdhe6144_p[] = {
471
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
472
    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
473
    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
474
    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
475
    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
476
    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
477
    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
478
    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
479
    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
480
    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
481
    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
482
    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
483
    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
484
    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
485
    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
486
    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
487
    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
488
    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
489
    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
490
    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
491
    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
492
    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
493
    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
494
    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
495
    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
496
    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
497
    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
498
    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
499
    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
500
    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
501
    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
502
    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
503
    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
504
    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
505
    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
506
    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
507
    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
508
    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
509
    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
510
    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
511
    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
512
    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
513
    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
514
    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
515
    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
516
    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
517
    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
518
    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
519
    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
520
    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
521
    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
522
    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
523
    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
524
    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
525
    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
526
    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
527
    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
528
    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
529
    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
530
    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
531
    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
532
    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
533
    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
534
    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
535
    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
536
    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
537
    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
538
    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
539
    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
540
    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
541
    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
542
    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
543
    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
544
    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
545
    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
546
    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
547
    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
548
    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
549
    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
550
    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
551
    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
552
    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
553
    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
554
    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
555
    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
556
    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
557
    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
558
    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
559
    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
560
    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
561
    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
562
    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
563
    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
564
    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
565
    0xA4, 0x0E, 0x32, 0x9C, 0xD0, 0xE4, 0x0E, 0x65,
566
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
567
};
568
static const byte dh_ffdhe6144_g[] = { 0x02 };
569
#ifdef HAVE_FFDHE_Q
570
static const byte dh_ffdhe6144_q[] = {
571
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
572
    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
573
    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
574
    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
575
    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
576
    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
577
    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
578
    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
579
    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
580
    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
581
    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
582
    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
583
    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
584
    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
585
    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
586
    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
587
    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
588
    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
589
    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
590
    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
591
    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
592
    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
593
    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
594
    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
595
    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
596
    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
597
    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
598
    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
599
    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
600
    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
601
    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
602
    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
603
    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
604
    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
605
    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
606
    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
607
    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
608
    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
609
    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
610
    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
611
    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
612
    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
613
    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
614
    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
615
    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
616
    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
617
    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
618
    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
619
    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
620
    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
621
    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
622
    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
623
    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
624
    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
625
    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
626
    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
627
    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
628
    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
629
    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
630
    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
631
    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
632
    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
633
    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
634
    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
635
    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
636
    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
637
    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
638
    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
639
    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
640
    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
641
    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
642
    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
643
    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
644
    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
645
    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
646
    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
647
    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
648
    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
649
    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
650
    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
651
    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
652
    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
653
    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
654
    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
655
    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
656
    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
657
    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
658
    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
659
    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
660
    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
661
    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
662
    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
663
    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
664
    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
665
    0x52, 0x07, 0x19, 0x4E, 0x68, 0x72, 0x07, 0x32,
666
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
667
};
668
#endif /* HAVE_FFDHE_Q */
669
670
#ifdef HAVE_PUBLIC_FFDHE
671
const DhParams* wc_Dh_ffdhe6144_Get(void)
672
{
673
    static const DhParams ffdhe6144 = {
674
        #ifdef HAVE_FFDHE_Q
675
            dh_ffdhe6144_q, sizeof(dh_ffdhe6144_q),
676
        #endif /* HAVE_FFDHE_Q */
677
        dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p),
678
        dh_ffdhe6144_g, sizeof(dh_ffdhe6144_g)
679
    };
680
    return &ffdhe6144;
681
}
682
#endif
683
#endif
684
685
#ifdef HAVE_FFDHE_8192
686
static const byte dh_ffdhe8192_p[] = {
687
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
688
    0xAD, 0xF8, 0x54, 0x58, 0xA2, 0xBB, 0x4A, 0x9A,
689
    0xAF, 0xDC, 0x56, 0x20, 0x27, 0x3D, 0x3C, 0xF1,
690
    0xD8, 0xB9, 0xC5, 0x83, 0xCE, 0x2D, 0x36, 0x95,
691
    0xA9, 0xE1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xFB,
692
    0xCC, 0x93, 0x9D, 0xCE, 0x24, 0x9B, 0x3E, 0xF9,
693
    0x7D, 0x2F, 0xE3, 0x63, 0x63, 0x0C, 0x75, 0xD8,
694
    0xF6, 0x81, 0xB2, 0x02, 0xAE, 0xC4, 0x61, 0x7A,
695
    0xD3, 0xDF, 0x1E, 0xD5, 0xD5, 0xFD, 0x65, 0x61,
696
    0x24, 0x33, 0xF5, 0x1F, 0x5F, 0x06, 0x6E, 0xD0,
697
    0x85, 0x63, 0x65, 0x55, 0x3D, 0xED, 0x1A, 0xF3,
698
    0xB5, 0x57, 0x13, 0x5E, 0x7F, 0x57, 0xC9, 0x35,
699
    0x98, 0x4F, 0x0C, 0x70, 0xE0, 0xE6, 0x8B, 0x77,
700
    0xE2, 0xA6, 0x89, 0xDA, 0xF3, 0xEF, 0xE8, 0x72,
701
    0x1D, 0xF1, 0x58, 0xA1, 0x36, 0xAD, 0xE7, 0x35,
702
    0x30, 0xAC, 0xCA, 0x4F, 0x48, 0x3A, 0x79, 0x7A,
703
    0xBC, 0x0A, 0xB1, 0x82, 0xB3, 0x24, 0xFB, 0x61,
704
    0xD1, 0x08, 0xA9, 0x4B, 0xB2, 0xC8, 0xE3, 0xFB,
705
    0xB9, 0x6A, 0xDA, 0xB7, 0x60, 0xD7, 0xF4, 0x68,
706
    0x1D, 0x4F, 0x42, 0xA3, 0xDE, 0x39, 0x4D, 0xF4,
707
    0xAE, 0x56, 0xED, 0xE7, 0x63, 0x72, 0xBB, 0x19,
708
    0x0B, 0x07, 0xA7, 0xC8, 0xEE, 0x0A, 0x6D, 0x70,
709
    0x9E, 0x02, 0xFC, 0xE1, 0xCD, 0xF7, 0xE2, 0xEC,
710
    0xC0, 0x34, 0x04, 0xCD, 0x28, 0x34, 0x2F, 0x61,
711
    0x91, 0x72, 0xFE, 0x9C, 0xE9, 0x85, 0x83, 0xFF,
712
    0x8E, 0x4F, 0x12, 0x32, 0xEE, 0xF2, 0x81, 0x83,
713
    0xC3, 0xFE, 0x3B, 0x1B, 0x4C, 0x6F, 0xAD, 0x73,
714
    0x3B, 0xB5, 0xFC, 0xBC, 0x2E, 0xC2, 0x20, 0x05,
715
    0xC5, 0x8E, 0xF1, 0x83, 0x7D, 0x16, 0x83, 0xB2,
716
    0xC6, 0xF3, 0x4A, 0x26, 0xC1, 0xB2, 0xEF, 0xFA,
717
    0x88, 0x6B, 0x42, 0x38, 0x61, 0x1F, 0xCF, 0xDC,
718
    0xDE, 0x35, 0x5B, 0x3B, 0x65, 0x19, 0x03, 0x5B,
719
    0xBC, 0x34, 0xF4, 0xDE, 0xF9, 0x9C, 0x02, 0x38,
720
    0x61, 0xB4, 0x6F, 0xC9, 0xD6, 0xE6, 0xC9, 0x07,
721
    0x7A, 0xD9, 0x1D, 0x26, 0x91, 0xF7, 0xF7, 0xEE,
722
    0x59, 0x8C, 0xB0, 0xFA, 0xC1, 0x86, 0xD9, 0x1C,
723
    0xAE, 0xFE, 0x13, 0x09, 0x85, 0x13, 0x92, 0x70,
724
    0xB4, 0x13, 0x0C, 0x93, 0xBC, 0x43, 0x79, 0x44,
725
    0xF4, 0xFD, 0x44, 0x52, 0xE2, 0xD7, 0x4D, 0xD3,
726
    0x64, 0xF2, 0xE2, 0x1E, 0x71, 0xF5, 0x4B, 0xFF,
727
    0x5C, 0xAE, 0x82, 0xAB, 0x9C, 0x9D, 0xF6, 0x9E,
728
    0xE8, 0x6D, 0x2B, 0xC5, 0x22, 0x36, 0x3A, 0x0D,
729
    0xAB, 0xC5, 0x21, 0x97, 0x9B, 0x0D, 0xEA, 0xDA,
730
    0x1D, 0xBF, 0x9A, 0x42, 0xD5, 0xC4, 0x48, 0x4E,
731
    0x0A, 0xBC, 0xD0, 0x6B, 0xFA, 0x53, 0xDD, 0xEF,
732
    0x3C, 0x1B, 0x20, 0xEE, 0x3F, 0xD5, 0x9D, 0x7C,
733
    0x25, 0xE4, 0x1D, 0x2B, 0x66, 0x9E, 0x1E, 0xF1,
734
    0x6E, 0x6F, 0x52, 0xC3, 0x16, 0x4D, 0xF4, 0xFB,
735
    0x79, 0x30, 0xE9, 0xE4, 0xE5, 0x88, 0x57, 0xB6,
736
    0xAC, 0x7D, 0x5F, 0x42, 0xD6, 0x9F, 0x6D, 0x18,
737
    0x77, 0x63, 0xCF, 0x1D, 0x55, 0x03, 0x40, 0x04,
738
    0x87, 0xF5, 0x5B, 0xA5, 0x7E, 0x31, 0xCC, 0x7A,
739
    0x71, 0x35, 0xC8, 0x86, 0xEF, 0xB4, 0x31, 0x8A,
740
    0xED, 0x6A, 0x1E, 0x01, 0x2D, 0x9E, 0x68, 0x32,
741
    0xA9, 0x07, 0x60, 0x0A, 0x91, 0x81, 0x30, 0xC4,
742
    0x6D, 0xC7, 0x78, 0xF9, 0x71, 0xAD, 0x00, 0x38,
743
    0x09, 0x29, 0x99, 0xA3, 0x33, 0xCB, 0x8B, 0x7A,
744
    0x1A, 0x1D, 0xB9, 0x3D, 0x71, 0x40, 0x00, 0x3C,
745
    0x2A, 0x4E, 0xCE, 0xA9, 0xF9, 0x8D, 0x0A, 0xCC,
746
    0x0A, 0x82, 0x91, 0xCD, 0xCE, 0xC9, 0x7D, 0xCF,
747
    0x8E, 0xC9, 0xB5, 0x5A, 0x7F, 0x88, 0xA4, 0x6B,
748
    0x4D, 0xB5, 0xA8, 0x51, 0xF4, 0x41, 0x82, 0xE1,
749
    0xC6, 0x8A, 0x00, 0x7E, 0x5E, 0x0D, 0xD9, 0x02,
750
    0x0B, 0xFD, 0x64, 0xB6, 0x45, 0x03, 0x6C, 0x7A,
751
    0x4E, 0x67, 0x7D, 0x2C, 0x38, 0x53, 0x2A, 0x3A,
752
    0x23, 0xBA, 0x44, 0x42, 0xCA, 0xF5, 0x3E, 0xA6,
753
    0x3B, 0xB4, 0x54, 0x32, 0x9B, 0x76, 0x24, 0xC8,
754
    0x91, 0x7B, 0xDD, 0x64, 0xB1, 0xC0, 0xFD, 0x4C,
755
    0xB3, 0x8E, 0x8C, 0x33, 0x4C, 0x70, 0x1C, 0x3A,
756
    0xCD, 0xAD, 0x06, 0x57, 0xFC, 0xCF, 0xEC, 0x71,
757
    0x9B, 0x1F, 0x5C, 0x3E, 0x4E, 0x46, 0x04, 0x1F,
758
    0x38, 0x81, 0x47, 0xFB, 0x4C, 0xFD, 0xB4, 0x77,
759
    0xA5, 0x24, 0x71, 0xF7, 0xA9, 0xA9, 0x69, 0x10,
760
    0xB8, 0x55, 0x32, 0x2E, 0xDB, 0x63, 0x40, 0xD8,
761
    0xA0, 0x0E, 0xF0, 0x92, 0x35, 0x05, 0x11, 0xE3,
762
    0x0A, 0xBE, 0xC1, 0xFF, 0xF9, 0xE3, 0xA2, 0x6E,
763
    0x7F, 0xB2, 0x9F, 0x8C, 0x18, 0x30, 0x23, 0xC3,
764
    0x58, 0x7E, 0x38, 0xDA, 0x00, 0x77, 0xD9, 0xB4,
765
    0x76, 0x3E, 0x4E, 0x4B, 0x94, 0xB2, 0xBB, 0xC1,
766
    0x94, 0xC6, 0x65, 0x1E, 0x77, 0xCA, 0xF9, 0x92,
767
    0xEE, 0xAA, 0xC0, 0x23, 0x2A, 0x28, 0x1B, 0xF6,
768
    0xB3, 0xA7, 0x39, 0xC1, 0x22, 0x61, 0x16, 0x82,
769
    0x0A, 0xE8, 0xDB, 0x58, 0x47, 0xA6, 0x7C, 0xBE,
770
    0xF9, 0xC9, 0x09, 0x1B, 0x46, 0x2D, 0x53, 0x8C,
771
    0xD7, 0x2B, 0x03, 0x74, 0x6A, 0xE7, 0x7F, 0x5E,
772
    0x62, 0x29, 0x2C, 0x31, 0x15, 0x62, 0xA8, 0x46,
773
    0x50, 0x5D, 0xC8, 0x2D, 0xB8, 0x54, 0x33, 0x8A,
774
    0xE4, 0x9F, 0x52, 0x35, 0xC9, 0x5B, 0x91, 0x17,
775
    0x8C, 0xCF, 0x2D, 0xD5, 0xCA, 0xCE, 0xF4, 0x03,
776
    0xEC, 0x9D, 0x18, 0x10, 0xC6, 0x27, 0x2B, 0x04,
777
    0x5B, 0x3B, 0x71, 0xF9, 0xDC, 0x6B, 0x80, 0xD6,
778
    0x3F, 0xDD, 0x4A, 0x8E, 0x9A, 0xDB, 0x1E, 0x69,
779
    0x62, 0xA6, 0x95, 0x26, 0xD4, 0x31, 0x61, 0xC1,
780
    0xA4, 0x1D, 0x57, 0x0D, 0x79, 0x38, 0xDA, 0xD4,
781
    0xA4, 0x0E, 0x32, 0x9C, 0xCF, 0xF4, 0x6A, 0xAA,
782
    0x36, 0xAD, 0x00, 0x4C, 0xF6, 0x00, 0xC8, 0x38,
783
    0x1E, 0x42, 0x5A, 0x31, 0xD9, 0x51, 0xAE, 0x64,
784
    0xFD, 0xB2, 0x3F, 0xCE, 0xC9, 0x50, 0x9D, 0x43,
785
    0x68, 0x7F, 0xEB, 0x69, 0xED, 0xD1, 0xCC, 0x5E,
786
    0x0B, 0x8C, 0xC3, 0xBD, 0xF6, 0x4B, 0x10, 0xEF,
787
    0x86, 0xB6, 0x31, 0x42, 0xA3, 0xAB, 0x88, 0x29,
788
    0x55, 0x5B, 0x2F, 0x74, 0x7C, 0x93, 0x26, 0x65,
789
    0xCB, 0x2C, 0x0F, 0x1C, 0xC0, 0x1B, 0xD7, 0x02,
790
    0x29, 0x38, 0x88, 0x39, 0xD2, 0xAF, 0x05, 0xE4,
791
    0x54, 0x50, 0x4A, 0xC7, 0x8B, 0x75, 0x82, 0x82,
792
    0x28, 0x46, 0xC0, 0xBA, 0x35, 0xC3, 0x5F, 0x5C,
793
    0x59, 0x16, 0x0C, 0xC0, 0x46, 0xFD, 0x82, 0x51,
794
    0x54, 0x1F, 0xC6, 0x8C, 0x9C, 0x86, 0xB0, 0x22,
795
    0xBB, 0x70, 0x99, 0x87, 0x6A, 0x46, 0x0E, 0x74,
796
    0x51, 0xA8, 0xA9, 0x31, 0x09, 0x70, 0x3F, 0xEE,
797
    0x1C, 0x21, 0x7E, 0x6C, 0x38, 0x26, 0xE5, 0x2C,
798
    0x51, 0xAA, 0x69, 0x1E, 0x0E, 0x42, 0x3C, 0xFC,
799
    0x99, 0xE9, 0xE3, 0x16, 0x50, 0xC1, 0x21, 0x7B,
800
    0x62, 0x48, 0x16, 0xCD, 0xAD, 0x9A, 0x95, 0xF9,
801
    0xD5, 0xB8, 0x01, 0x94, 0x88, 0xD9, 0xC0, 0xA0,
802
    0xA1, 0xFE, 0x30, 0x75, 0xA5, 0x77, 0xE2, 0x31,
803
    0x83, 0xF8, 0x1D, 0x4A, 0x3F, 0x2F, 0xA4, 0x57,
804
    0x1E, 0xFC, 0x8C, 0xE0, 0xBA, 0x8A, 0x4F, 0xE8,
805
    0xB6, 0x85, 0x5D, 0xFE, 0x72, 0xB0, 0xA6, 0x6E,
806
    0xDE, 0xD2, 0xFB, 0xAB, 0xFB, 0xE5, 0x8A, 0x30,
807
    0xFA, 0xFA, 0xBE, 0x1C, 0x5D, 0x71, 0xA8, 0x7E,
808
    0x2F, 0x74, 0x1E, 0xF8, 0xC1, 0xFE, 0x86, 0xFE,
809
    0xA6, 0xBB, 0xFD, 0xE5, 0x30, 0x67, 0x7F, 0x0D,
810
    0x97, 0xD1, 0x1D, 0x49, 0xF7, 0xA8, 0x44, 0x3D,
811
    0x08, 0x22, 0xE5, 0x06, 0xA9, 0xF4, 0x61, 0x4E,
812
    0x01, 0x1E, 0x2A, 0x94, 0x83, 0x8F, 0xF8, 0x8C,
813
    0xD6, 0x8C, 0x8B, 0xB7, 0xC5, 0xC6, 0x42, 0x4C,
814
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
815
};
816
static const byte dh_ffdhe8192_g[] = { 0x02 };
817
#ifdef HAVE_FFDHE_Q
818
static const byte dh_ffdhe8192_q[] = {
819
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
820
    0xD6, 0xFC, 0x2A, 0x2C, 0x51, 0x5D, 0xA5, 0x4D,
821
    0x57, 0xEE, 0x2B, 0x10, 0x13, 0x9E, 0x9E, 0x78,
822
    0xEC, 0x5C, 0xE2, 0xC1, 0xE7, 0x16, 0x9B, 0x4A,
823
    0xD4, 0xF0, 0x9B, 0x20, 0x8A, 0x32, 0x19, 0xFD,
824
    0xE6, 0x49, 0xCE, 0xE7, 0x12, 0x4D, 0x9F, 0x7C,
825
    0xBE, 0x97, 0xF1, 0xB1, 0xB1, 0x86, 0x3A, 0xEC,
826
    0x7B, 0x40, 0xD9, 0x01, 0x57, 0x62, 0x30, 0xBD,
827
    0x69, 0xEF, 0x8F, 0x6A, 0xEA, 0xFE, 0xB2, 0xB0,
828
    0x92, 0x19, 0xFA, 0x8F, 0xAF, 0x83, 0x37, 0x68,
829
    0x42, 0xB1, 0xB2, 0xAA, 0x9E, 0xF6, 0x8D, 0x79,
830
    0xDA, 0xAB, 0x89, 0xAF, 0x3F, 0xAB, 0xE4, 0x9A,
831
    0xCC, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xBB,
832
    0xF1, 0x53, 0x44, 0xED, 0x79, 0xF7, 0xF4, 0x39,
833
    0x0E, 0xF8, 0xAC, 0x50, 0x9B, 0x56, 0xF3, 0x9A,
834
    0x98, 0x56, 0x65, 0x27, 0xA4, 0x1D, 0x3C, 0xBD,
835
    0x5E, 0x05, 0x58, 0xC1, 0x59, 0x92, 0x7D, 0xB0,
836
    0xE8, 0x84, 0x54, 0xA5, 0xD9, 0x64, 0x71, 0xFD,
837
    0xDC, 0xB5, 0x6D, 0x5B, 0xB0, 0x6B, 0xFA, 0x34,
838
    0x0E, 0xA7, 0xA1, 0x51, 0xEF, 0x1C, 0xA6, 0xFA,
839
    0x57, 0x2B, 0x76, 0xF3, 0xB1, 0xB9, 0x5D, 0x8C,
840
    0x85, 0x83, 0xD3, 0xE4, 0x77, 0x05, 0x36, 0xB8,
841
    0x4F, 0x01, 0x7E, 0x70, 0xE6, 0xFB, 0xF1, 0x76,
842
    0x60, 0x1A, 0x02, 0x66, 0x94, 0x1A, 0x17, 0xB0,
843
    0xC8, 0xB9, 0x7F, 0x4E, 0x74, 0xC2, 0xC1, 0xFF,
844
    0xC7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xC1,
845
    0xE1, 0xFF, 0x1D, 0x8D, 0xA6, 0x37, 0xD6, 0xB9,
846
    0x9D, 0xDA, 0xFE, 0x5E, 0x17, 0x61, 0x10, 0x02,
847
    0xE2, 0xC7, 0x78, 0xC1, 0xBE, 0x8B, 0x41, 0xD9,
848
    0x63, 0x79, 0xA5, 0x13, 0x60, 0xD9, 0x77, 0xFD,
849
    0x44, 0x35, 0xA1, 0x1C, 0x30, 0x8F, 0xE7, 0xEE,
850
    0x6F, 0x1A, 0xAD, 0x9D, 0xB2, 0x8C, 0x81, 0xAD,
851
    0xDE, 0x1A, 0x7A, 0x6F, 0x7C, 0xCE, 0x01, 0x1C,
852
    0x30, 0xDA, 0x37, 0xE4, 0xEB, 0x73, 0x64, 0x83,
853
    0xBD, 0x6C, 0x8E, 0x93, 0x48, 0xFB, 0xFB, 0xF7,
854
    0x2C, 0xC6, 0x58, 0x7D, 0x60, 0xC3, 0x6C, 0x8E,
855
    0x57, 0x7F, 0x09, 0x84, 0xC2, 0x89, 0xC9, 0x38,
856
    0x5A, 0x09, 0x86, 0x49, 0xDE, 0x21, 0xBC, 0xA2,
857
    0x7A, 0x7E, 0xA2, 0x29, 0x71, 0x6B, 0xA6, 0xE9,
858
    0xB2, 0x79, 0x71, 0x0F, 0x38, 0xFA, 0xA5, 0xFF,
859
    0xAE, 0x57, 0x41, 0x55, 0xCE, 0x4E, 0xFB, 0x4F,
860
    0x74, 0x36, 0x95, 0xE2, 0x91, 0x1B, 0x1D, 0x06,
861
    0xD5, 0xE2, 0x90, 0xCB, 0xCD, 0x86, 0xF5, 0x6D,
862
    0x0E, 0xDF, 0xCD, 0x21, 0x6A, 0xE2, 0x24, 0x27,
863
    0x05, 0x5E, 0x68, 0x35, 0xFD, 0x29, 0xEE, 0xF7,
864
    0x9E, 0x0D, 0x90, 0x77, 0x1F, 0xEA, 0xCE, 0xBE,
865
    0x12, 0xF2, 0x0E, 0x95, 0xB3, 0x4F, 0x0F, 0x78,
866
    0xB7, 0x37, 0xA9, 0x61, 0x8B, 0x26, 0xFA, 0x7D,
867
    0xBC, 0x98, 0x74, 0xF2, 0x72, 0xC4, 0x2B, 0xDB,
868
    0x56, 0x3E, 0xAF, 0xA1, 0x6B, 0x4F, 0xB6, 0x8C,
869
    0x3B, 0xB1, 0xE7, 0x8E, 0xAA, 0x81, 0xA0, 0x02,
870
    0x43, 0xFA, 0xAD, 0xD2, 0xBF, 0x18, 0xE6, 0x3D,
871
    0x38, 0x9A, 0xE4, 0x43, 0x77, 0xDA, 0x18, 0xC5,
872
    0x76, 0xB5, 0x0F, 0x00, 0x96, 0xCF, 0x34, 0x19,
873
    0x54, 0x83, 0xB0, 0x05, 0x48, 0xC0, 0x98, 0x62,
874
    0x36, 0xE3, 0xBC, 0x7C, 0xB8, 0xD6, 0x80, 0x1C,
875
    0x04, 0x94, 0xCC, 0xD1, 0x99, 0xE5, 0xC5, 0xBD,
876
    0x0D, 0x0E, 0xDC, 0x9E, 0xB8, 0xA0, 0x00, 0x1E,
877
    0x15, 0x27, 0x67, 0x54, 0xFC, 0xC6, 0x85, 0x66,
878
    0x05, 0x41, 0x48, 0xE6, 0xE7, 0x64, 0xBE, 0xE7,
879
    0xC7, 0x64, 0xDA, 0xAD, 0x3F, 0xC4, 0x52, 0x35,
880
    0xA6, 0xDA, 0xD4, 0x28, 0xFA, 0x20, 0xC1, 0x70,
881
    0xE3, 0x45, 0x00, 0x3F, 0x2F, 0x06, 0xEC, 0x81,
882
    0x05, 0xFE, 0xB2, 0x5B, 0x22, 0x81, 0xB6, 0x3D,
883
    0x27, 0x33, 0xBE, 0x96, 0x1C, 0x29, 0x95, 0x1D,
884
    0x11, 0xDD, 0x22, 0x21, 0x65, 0x7A, 0x9F, 0x53,
885
    0x1D, 0xDA, 0x2A, 0x19, 0x4D, 0xBB, 0x12, 0x64,
886
    0x48, 0xBD, 0xEE, 0xB2, 0x58, 0xE0, 0x7E, 0xA6,
887
    0x59, 0xC7, 0x46, 0x19, 0xA6, 0x38, 0x0E, 0x1D,
888
    0x66, 0xD6, 0x83, 0x2B, 0xFE, 0x67, 0xF6, 0x38,
889
    0xCD, 0x8F, 0xAE, 0x1F, 0x27, 0x23, 0x02, 0x0F,
890
    0x9C, 0x40, 0xA3, 0xFD, 0xA6, 0x7E, 0xDA, 0x3B,
891
    0xD2, 0x92, 0x38, 0xFB, 0xD4, 0xD4, 0xB4, 0x88,
892
    0x5C, 0x2A, 0x99, 0x17, 0x6D, 0xB1, 0xA0, 0x6C,
893
    0x50, 0x07, 0x78, 0x49, 0x1A, 0x82, 0x88, 0xF1,
894
    0x85, 0x5F, 0x60, 0xFF, 0xFC, 0xF1, 0xD1, 0x37,
895
    0x3F, 0xD9, 0x4F, 0xC6, 0x0C, 0x18, 0x11, 0xE1,
896
    0xAC, 0x3F, 0x1C, 0x6D, 0x00, 0x3B, 0xEC, 0xDA,
897
    0x3B, 0x1F, 0x27, 0x25, 0xCA, 0x59, 0x5D, 0xE0,
898
    0xCA, 0x63, 0x32, 0x8F, 0x3B, 0xE5, 0x7C, 0xC9,
899
    0x77, 0x55, 0x60, 0x11, 0x95, 0x14, 0x0D, 0xFB,
900
    0x59, 0xD3, 0x9C, 0xE0, 0x91, 0x30, 0x8B, 0x41,
901
    0x05, 0x74, 0x6D, 0xAC, 0x23, 0xD3, 0x3E, 0x5F,
902
    0x7C, 0xE4, 0x84, 0x8D, 0xA3, 0x16, 0xA9, 0xC6,
903
    0x6B, 0x95, 0x81, 0xBA, 0x35, 0x73, 0xBF, 0xAF,
904
    0x31, 0x14, 0x96, 0x18, 0x8A, 0xB1, 0x54, 0x23,
905
    0x28, 0x2E, 0xE4, 0x16, 0xDC, 0x2A, 0x19, 0xC5,
906
    0x72, 0x4F, 0xA9, 0x1A, 0xE4, 0xAD, 0xC8, 0x8B,
907
    0xC6, 0x67, 0x96, 0xEA, 0xE5, 0x67, 0x7A, 0x01,
908
    0xF6, 0x4E, 0x8C, 0x08, 0x63, 0x13, 0x95, 0x82,
909
    0x2D, 0x9D, 0xB8, 0xFC, 0xEE, 0x35, 0xC0, 0x6B,
910
    0x1F, 0xEE, 0xA5, 0x47, 0x4D, 0x6D, 0x8F, 0x34,
911
    0xB1, 0x53, 0x4A, 0x93, 0x6A, 0x18, 0xB0, 0xE0,
912
    0xD2, 0x0E, 0xAB, 0x86, 0xBC, 0x9C, 0x6D, 0x6A,
913
    0x52, 0x07, 0x19, 0x4E, 0x67, 0xFA, 0x35, 0x55,
914
    0x1B, 0x56, 0x80, 0x26, 0x7B, 0x00, 0x64, 0x1C,
915
    0x0F, 0x21, 0x2D, 0x18, 0xEC, 0xA8, 0xD7, 0x32,
916
    0x7E, 0xD9, 0x1F, 0xE7, 0x64, 0xA8, 0x4E, 0xA1,
917
    0xB4, 0x3F, 0xF5, 0xB4, 0xF6, 0xE8, 0xE6, 0x2F,
918
    0x05, 0xC6, 0x61, 0xDE, 0xFB, 0x25, 0x88, 0x77,
919
    0xC3, 0x5B, 0x18, 0xA1, 0x51, 0xD5, 0xC4, 0x14,
920
    0xAA, 0xAD, 0x97, 0xBA, 0x3E, 0x49, 0x93, 0x32,
921
    0xE5, 0x96, 0x07, 0x8E, 0x60, 0x0D, 0xEB, 0x81,
922
    0x14, 0x9C, 0x44, 0x1C, 0xE9, 0x57, 0x82, 0xF2,
923
    0x2A, 0x28, 0x25, 0x63, 0xC5, 0xBA, 0xC1, 0x41,
924
    0x14, 0x23, 0x60, 0x5D, 0x1A, 0xE1, 0xAF, 0xAE,
925
    0x2C, 0x8B, 0x06, 0x60, 0x23, 0x7E, 0xC1, 0x28,
926
    0xAA, 0x0F, 0xE3, 0x46, 0x4E, 0x43, 0x58, 0x11,
927
    0x5D, 0xB8, 0x4C, 0xC3, 0xB5, 0x23, 0x07, 0x3A,
928
    0x28, 0xD4, 0x54, 0x98, 0x84, 0xB8, 0x1F, 0xF7,
929
    0x0E, 0x10, 0xBF, 0x36, 0x1C, 0x13, 0x72, 0x96,
930
    0x28, 0xD5, 0x34, 0x8F, 0x07, 0x21, 0x1E, 0x7E,
931
    0x4C, 0xF4, 0xF1, 0x8B, 0x28, 0x60, 0x90, 0xBD,
932
    0xB1, 0x24, 0x0B, 0x66, 0xD6, 0xCD, 0x4A, 0xFC,
933
    0xEA, 0xDC, 0x00, 0xCA, 0x44, 0x6C, 0xE0, 0x50,
934
    0x50, 0xFF, 0x18, 0x3A, 0xD2, 0xBB, 0xF1, 0x18,
935
    0xC1, 0xFC, 0x0E, 0xA5, 0x1F, 0x97, 0xD2, 0x2B,
936
    0x8F, 0x7E, 0x46, 0x70, 0x5D, 0x45, 0x27, 0xF4,
937
    0x5B, 0x42, 0xAE, 0xFF, 0x39, 0x58, 0x53, 0x37,
938
    0x6F, 0x69, 0x7D, 0xD5, 0xFD, 0xF2, 0xC5, 0x18,
939
    0x7D, 0x7D, 0x5F, 0x0E, 0x2E, 0xB8, 0xD4, 0x3F,
940
    0x17, 0xBA, 0x0F, 0x7C, 0x60, 0xFF, 0x43, 0x7F,
941
    0x53, 0x5D, 0xFE, 0xF2, 0x98, 0x33, 0xBF, 0x86,
942
    0xCB, 0xE8, 0x8E, 0xA4, 0xFB, 0xD4, 0x22, 0x1E,
943
    0x84, 0x11, 0x72, 0x83, 0x54, 0xFA, 0x30, 0xA7,
944
    0x00, 0x8F, 0x15, 0x4A, 0x41, 0xC7, 0xFC, 0x46,
945
    0x6B, 0x46, 0x45, 0xDB, 0xE2, 0xE3, 0x21, 0x26,
946
    0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
947
};
948
#endif /* HAVE_FFDHE_Q */
949
950
#ifdef HAVE_PUBLIC_FFDHE
951
const DhParams* wc_Dh_ffdhe8192_Get(void)
952
{
953
    static const DhParams ffdhe8192 = {
954
        #ifdef HAVE_FFDHE_Q
955
            dh_ffdhe8192_q, sizeof(dh_ffdhe8192_q),
956
        #endif /* HAVE_FFDHE_Q */
957
        dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p),
958
        dh_ffdhe8192_g, sizeof(dh_ffdhe8192_g)
959
    };
960
    return &ffdhe8192;
961
}
962
#endif
963
#endif
964
965
int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
966
7.37k
{
967
7.37k
    int ret = 0;
968
969
7.37k
    if (key == NULL)
970
0
        return BAD_FUNC_ARG;
971
972
7.37k
    XMEMSET(key, 0, sizeof(*key));
973
974
7.37k
    key->heap = heap; /* for XMALLOC/XFREE in future */
975
7.37k
    key->trustedGroup = 0;
976
977
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
978
    if (! wc_dh_enabled)
979
        return FIPS_NOT_ALLOWED_E;
980
#endif
981
982
#ifdef WOLFSSL_DH_EXTRA
983
    if (mp_init_multi(&key->p, &key->g, &key->q, &key->pub, &key->priv, NULL) != MP_OKAY)
984
#else
985
7.37k
    if (mp_init_multi(&key->p, &key->g, &key->q, NULL, NULL, NULL) != MP_OKAY)
986
0
#endif
987
0
        return MEMORY_E;
988
989
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
990
    /* handle as async */
991
    ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH,
992
        key->heap, devId);
993
#else
994
7.37k
    (void)devId;
995
7.37k
#endif
996
997
#ifdef WOLFSSL_KCAPI_DH
998
    key->handle = NULL;
999
#endif
1000
1001
#ifdef WC_DH_NONBLOCK
1002
    key->nb = NULL;
1003
#endif
1004
1005
    /* On failure, release MPI allocations, if any. */
1006
7.37k
    if (ret != 0)
1007
0
        (void)wc_FreeDhKey(key);
1008
1009
7.37k
    return ret;
1010
7.37k
}
1011
1012
int wc_InitDhKey(DhKey* key)
1013
5.98k
{
1014
5.98k
    return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
1015
5.98k
}
1016
1017
#ifdef WC_DH_NONBLOCK
1018
int wc_DhSetNonBlock(DhKey* key, DhNb* nb)
1019
{
1020
    if (key == NULL)
1021
        return BAD_FUNC_ARG;
1022
1023
    if (nb != NULL) {
1024
        XMEMSET(nb, 0, sizeof(DhNb));
1025
    }
1026
1027
    /* Pass NULL to disable non-blocking mode. */
1028
    key->nb = nb;
1029
1030
    return 0;
1031
}
1032
#endif
1033
1034
1035
int wc_FreeDhKey(DhKey* key)
1036
8.34k
{
1037
8.34k
    if (key) {
1038
7.62k
        mp_clear(&key->p);
1039
7.62k
        mp_clear(&key->g);
1040
7.62k
        mp_clear(&key->q);
1041
    #ifdef WOLFSSL_DH_EXTRA
1042
        mp_clear(&key->pub);
1043
        mp_forcezero(&key->priv);
1044
    #endif
1045
1046
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1047
        wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_DH);
1048
    #endif
1049
    #ifdef WOLFSSL_KCAPI_DH
1050
        KcapiDh_Free(key);
1051
    #endif
1052
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1053
        /* Deregister any mem-zero entries covering this key (e.g. key->priv
1054
         * registered by wc_DhImportKeyPair) now that its fields are zeroed.
1055
         * Mirrors wc_FreeRsaKey(); mp_forcezero() alone does not remove the
1056
         * registration, so without this the entry leaks into later checks. */
1057
        wc_MemZero_Check(key, sizeof(*key));
1058
    #endif
1059
7.62k
    }
1060
8.34k
    return 0;
1061
8.34k
}
1062
1063
1064
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
1065
       const byte* prime, word32 primeSz, int partial);
1066
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1067
static int _ffc_pairwise_consistency_test(DhKey* key,
1068
        const byte* pub, word32 pubSz, const byte* priv, word32 privSz);
1069
#endif
1070
1071
#ifndef WOLFSSL_KCAPI_DH
1072
1073
#ifndef WC_NO_RNG
1074
/* if defined to not use floating point values do not compile in */
1075
#ifndef WOLFSSL_DH_CONST
1076
    static word32 DiscreteLogWorkFactor(word32 n)
1077
165
    {
1078
        /* assuming discrete log takes about the same time as factoring */
1079
165
        if (n < 5)
1080
0
            return 0;
1081
165
        else
1082
165
            return (word32)((double)2.4 * XPOW((double)n, 1.0/3.0) *
1083
165
                    XPOW(XLOG((double)n), 2.0/3.0) - 5);
1084
165
    }
1085
#endif /* WOLFSSL_DH_CONST*/
1086
1087
1088
/* if not using fixed points use DiscreteLogWorkFactor function for unusual size
1089
   otherwise round up on size needed */
1090
#ifndef WOLFSSL_DH_CONST
1091
1.47k
    #define WOLFSSL_DH_ROUND(x) WC_DO_NOTHING
1092
#else
1093
    #define WOLFSSL_DH_ROUND(x)   \
1094
        do {                      \
1095
            if ((x) % 128) {      \
1096
                (x) &= 0xffffff80;\
1097
                (x) += 128;       \
1098
            }                     \
1099
        }                         \
1100
        while (0)
1101
#endif
1102
1103
1104
#ifndef WOLFSSL_NO_DH186
1105
/* validate that (L,N) match allowed sizes from SP 800-56A, Section 5.5.1.1.
1106
 * modLen - represents L, the size of p in bits
1107
 * divLen - represents N, the size of q in bits
1108
 * return 0 on success, -1 on error */
1109
static int CheckDhLN(word32 modLen, word32 divLen)
1110
0
{
1111
0
    int ret = -1;
1112
1113
0
    switch (modLen) {
1114
        /* FA */
1115
0
        case 1024:
1116
0
            if (divLen == 160)
1117
0
                ret = 0;
1118
0
            break;
1119
        /* FB, FC */
1120
0
        case 2048:
1121
0
            if (divLen == 224 || divLen == 256)
1122
0
                ret = 0;
1123
0
            break;
1124
        /* Per SP 800-56Ar3 Table 2 */
1125
0
        case 3072:
1126
0
            if (divLen == 256)
1127
0
                ret = 0;
1128
0
            break;
1129
0
        default:
1130
0
            break;
1131
0
    }
1132
1133
0
    return ret;
1134
0
}
1135
1136
1137
/* Create DH private key
1138
 *
1139
 * Based on NIST SP 800-56Ar3
1140
 * "5.6.1.1.3 Key Pair Generation Using Extra Random Bits"
1141
 *
1142
 * dh     - pointer to initialized DhKey structure, needs to have dh->q
1143
 * rng    - pointer to initialized WC_RNG structure
1144
 * priv   - output location for generated private key
1145
 * privSz - IN/OUT, size of priv buffer, size of generated private key
1146
 *
1147
 * return 0 on success, negative on error */
1148
static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
1149
                                word32* privSz)
1150
0
{
1151
0
    word32 qSz, pSz, cSz;
1152
0
    int err;
1153
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1154
0
    mp_int* tmpQ = NULL;
1155
0
    mp_int* tmpX = NULL;
1156
0
    byte* cBuf = NULL;
1157
#else
1158
    mp_int tmpQ[1], tmpX[1];
1159
    byte cBuf[DH_MAX_SIZE + 64 / WOLFSSL_BIT_SIZE];
1160
#endif
1161
1162
    /* Pointer parameters validated by the public entry wc_DhGenerateKeyPair. */
1163
1164
0
    if (mp_iszero(&key->q) == MP_YES) {
1165
0
        WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
1166
0
        return BAD_FUNC_ARG;
1167
0
    }
1168
1169
    /* Bound *privSz so cSz (= *privSz + 8) cannot exceed the cBuf capacity.
1170
     * Note: DH_MAX_SIZE is documented as a bit count, but the cBuf declaration
1171
     * above uses it directly as a byte count (cBuf is DH_MAX_SIZE + 8 bytes).
1172
     * This check matches that convention so *privSz (in bytes) is bounded by
1173
     * the actual byte capacity of cBuf. The same bound is applied to the
1174
     * WOLFSSL_SMALL_STACK path to avoid unbounded heap allocation. */
1175
0
    if (*privSz > DH_MAX_SIZE) {
1176
0
        WOLFSSL_MSG("DH private key size exceeds DH_MAX_SIZE");
1177
0
        return WC_KEY_SIZE_E;
1178
0
    }
1179
1180
0
    qSz = (word32)mp_unsigned_bin_size(&key->q);
1181
0
    pSz = (word32)mp_unsigned_bin_size(&key->p);
1182
1183
    /* verify (L,N) pair bit lengths */
1184
    /* Trusted primes don't need to be checked. */
1185
0
    if (!key->trustedGroup &&
1186
0
            CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
1187
0
        WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
1188
0
        return BAD_FUNC_ARG;
1189
0
    }
1190
1191
    /* generate extra 64 bits so that bias from mod function is negligible */
1192
0
    cSz = *privSz + (64 / WOLFSSL_BIT_SIZE);
1193
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1194
0
    cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1195
0
    if (cBuf == NULL) {
1196
0
        return MEMORY_E;
1197
0
    }
1198
0
    tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1199
0
    if (tmpQ == NULL) {
1200
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1201
0
        return MEMORY_E;
1202
0
    }
1203
0
    tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1204
0
    if (tmpX == NULL) {
1205
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1206
0
        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1207
0
        return MEMORY_E;
1208
0
    }
1209
0
#endif
1210
1211
1212
0
    if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))
1213
0
                   != MP_OKAY) {
1214
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1215
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1216
0
        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1217
0
        XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1218
0
#endif
1219
0
        return err;
1220
0
    }
1221
1222
#ifdef WOLFSSL_CHECK_MEM_ZERO
1223
    wc_MemZero_Add("GeneratePrivateDh186 cBuf", cBuf, cSz); /* cppcheck-suppress uninitvar */
1224
    mp_memzero_add("GeneratePrivateDh186 tmpX", tmpX);
1225
#endif
1226
0
    do {
1227
        /* generate N+64 bits (c) from RBG into tmpX, making sure positive.
1228
         * Hash_DRBG uses SHA-256 which matches maximum
1229
         * requested_security_strength of (L,N) */
1230
0
        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
1231
0
        if (err == MP_OKAY)
1232
0
            err = mp_read_unsigned_bin(tmpX, cBuf, cSz);
1233
0
        if (err != MP_OKAY) {
1234
0
            mp_forcezero(tmpX);
1235
0
            mp_clear(tmpQ);
1236
0
            ForceZero(cBuf, cSz);
1237
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1238
0
            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1239
0
            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1240
0
            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1241
0
#endif
1242
0
            return err;
1243
0
        }
1244
0
    } while (mp_cmp_d(tmpX, 1) != MP_GT);
1245
1246
0
    ForceZero(cBuf, cSz);
1247
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1248
0
    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1249
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1250
    wc_MemZero_Check(cBuf, cSz);
1251
#endif
1252
1253
    /* tmpQ: M = min(2^N,q) - 1 */
1254
0
    if (err == MP_OKAY)
1255
0
        err = mp_2expt(tmpQ, (int)*privSz * 8);
1256
1257
0
    if (err == MP_OKAY) {
1258
0
        if (mp_cmp(tmpQ, &key->q) == MP_GT) {
1259
0
            err = mp_copy(&key->q, tmpQ);
1260
0
        }
1261
0
    }
1262
1263
0
    if (err == MP_OKAY)
1264
0
        err = mp_sub_d(tmpQ, 1, tmpQ);
1265
1266
    /* x = c mod (M), tmpX holds c */
1267
0
    if (err == MP_OKAY)
1268
0
        err = mp_mod(tmpX, tmpQ, tmpX);
1269
1270
    /* x = c mod (M) + 1 */
1271
0
    if (err == MP_OKAY)
1272
0
        err = mp_add_d(tmpX, 1, tmpX);
1273
1274
    /* copy tmpX into priv */
1275
0
    if (err == MP_OKAY) {
1276
0
        pSz = (word32)mp_unsigned_bin_size(tmpX);
1277
0
        if (pSz > *privSz) {
1278
0
            WOLFSSL_MSG("DH private key output buffer too small");
1279
0
            err = BAD_FUNC_ARG;
1280
0
        } else {
1281
0
            *privSz = pSz;
1282
0
            err = mp_to_unsigned_bin(tmpX, priv);
1283
0
        }
1284
0
    }
1285
1286
0
    mp_forcezero(tmpX);
1287
0
    mp_clear(tmpQ);
1288
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1289
0
    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1290
0
    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1291
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1292
    mp_memzero_check(tmpX);
1293
#endif
1294
1295
0
    return err;
1296
0
}
1297
#endif /* WOLFSSL_NO_DH186 */
1298
#endif /* !WC_NO_RNG */
1299
1300
static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
1301
                             word32* privSz)
1302
1.90k
{
1303
1.90k
#ifndef WC_NO_RNG
1304
1.90k
    int ret = 0;
1305
1.90k
    word32 sz = 0;
1306
1307
    /* reject primes below the minimum allowed size */
1308
1.90k
    if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
1309
421
        WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
1310
421
        return WC_KEY_SIZE_E;
1311
421
    }
1312
1313
1.48k
    if (mp_iseven(&key->p) == MP_YES) {
1314
6
        ret = MP_VAL;
1315
6
    }
1316
1.47k
    else
1317
1.47k
#ifndef WOLFSSL_NO_DH186
1318
1.47k
    if (mp_iszero(&key->q) == MP_NO) {
1319
1320
        /* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair
1321
         * Generation Using Extra Random Bits" */
1322
0
        ret = GeneratePrivateDh186(key, rng, priv, privSz);
1323
1324
0
    }
1325
1.47k
    else
1326
1.47k
#endif
1327
1.47k
    {
1328
1329
1.47k
        sz = (word32)mp_unsigned_bin_size(&key->p);
1330
1331
        /* Table of predetermined values from the operation
1332
           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1333
           WOLFSSL_BIT_SIZE + 1
1334
           Sizes in table checked against RFC 3526
1335
         */
1336
1.47k
        WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
1337
1.47k
        switch (sz) {
1338
3
            case 128:  sz = 21; break;
1339
1.33k
            case 256:  sz = 29; break;
1340
49
            case 384:  sz = 34; break;
1341
59
            case 512:  sz = 39; break;
1342
0
            case 640:  sz = 42; break;
1343
0
            case 768:  sz = 46; break;
1344
0
            case 896:  sz = 49; break;
1345
0
            case 1024: sz = 52; break;
1346
29
            default:
1347
29
            #ifndef WOLFSSL_DH_CONST
1348
                /* if using floating points and size of p is not in table */
1349
29
                sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1350
29
                                           WOLFSSL_BIT_SIZE + 1);
1351
29
                break;
1352
            #else
1353
                return BAD_FUNC_ARG;
1354
            #endif
1355
1.47k
        }
1356
1357
1.47k
        if (sz > *privSz)
1358
1
            ret = WC_KEY_SIZE_E;
1359
1360
1.47k
        if (ret == 0)
1361
1.47k
            ret = wc_RNG_GenerateBlock(rng, priv, sz);
1362
1363
1.47k
        if (ret == 0) {
1364
1.45k
            priv[0] |= 0x0C;
1365
1.45k
            *privSz = sz;
1366
1.45k
        }
1367
1.47k
    }
1368
1369
1.48k
    return ret;
1370
#else
1371
    (void)key;
1372
    (void)rng;
1373
    (void)priv;
1374
    (void)privSz;
1375
    return NOT_COMPILED_IN;
1376
#endif /* WC_NO_RNG */
1377
1.48k
}
1378
1379
1380
static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
1381
    byte* pub, word32* pubSz)
1382
1.40k
{
1383
1.40k
    int ret = 0;
1384
1.40k
#ifndef WOLFSSL_SP_MATH
1385
1.40k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1386
1.40k
    mp_int* x;
1387
1.40k
    mp_int* y;
1388
#else
1389
    mp_int x[1];
1390
    mp_int y[1];
1391
#endif
1392
1.40k
#endif
1393
1394
1.40k
    if (*pubSz < (word32)mp_unsigned_bin_size(&key->p)) {
1395
5
        return WC_KEY_SIZE_E;
1396
5
    }
1397
1398
    /* reject primes below the minimum allowed size */
1399
1.40k
    if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
1400
0
        WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
1401
0
        return WC_KEY_SIZE_E;
1402
0
    }
1403
1404
#ifdef WOLFSSL_HAVE_SP_DH
1405
#ifndef WOLFSSL_SP_NO_2048
1406
    if (mp_count_bits(&key->p) == 2048)
1407
        return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);
1408
#endif
1409
#ifndef WOLFSSL_SP_NO_3072
1410
    if (mp_count_bits(&key->p) == 3072)
1411
        return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);
1412
#endif
1413
#ifdef WOLFSSL_SP_4096
1414
    if (mp_count_bits(&key->p) == 4096)
1415
        return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);
1416
#endif
1417
#endif
1418
1419
1.40k
#if !defined(WOLFSSL_SP_MATH)
1420
1.40k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1421
1.40k
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1422
1.40k
    if (x == NULL)
1423
18
        return MEMORY_E;
1424
1.38k
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1425
1.38k
    if (y == NULL) {
1426
11
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1427
11
        return MEMORY_E;
1428
11
    }
1429
1.37k
#endif
1430
1.37k
    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
1431
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1432
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1433
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1434
0
    #endif
1435
0
        return MP_INIT_E;
1436
0
    }
1437
1438
1.37k
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
1439
0
        ret = MP_READ_E;
1440
1441
1.37k
    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
1442
425
        ret = MP_EXPTMOD_E;
1443
1444
1.37k
    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
1445
3
        ret = MP_TO_E;
1446
1447
1.37k
    if (ret == 0)
1448
944
        *pubSz = (word32)mp_unsigned_bin_size(y);
1449
1450
1.37k
    mp_clear(y);
1451
1.37k
    mp_forcezero(x);
1452
1.37k
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1453
1.37k
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1454
1.37k
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1455
1.37k
#endif
1456
#else
1457
    ret = WC_KEY_SIZE_E;
1458
#endif
1459
1460
1.37k
    return ret;
1461
1.37k
}
1462
1463
/**
1464
 * Given a DhKey with set params and a priv key, generate the corresponding
1465
 * public key. If fips, does pub key validation.
1466
 * */
1467
int wc_DhGeneratePublic(DhKey* key, byte* priv, word32 privSz,
1468
    byte* pub, word32* pubSz)
1469
0
{
1470
0
    int ret = 0;
1471
1472
0
    if (key == NULL || priv == NULL || privSz == 0 ||
1473
0
        pub == NULL || pubSz == NULL) {
1474
0
        return BAD_FUNC_ARG;
1475
0
    }
1476
1477
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
1478
    if (! wc_dh_enabled)
1479
        return FIPS_NOT_ALLOWED_E;
1480
#endif
1481
1482
0
    ret = GeneratePublicDh(key, priv, privSz, pub, pubSz);
1483
1484
    #if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1485
    if (ret == 0)
1486
        ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
1487
    if (ret == 0)
1488
        ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, privSz);
1489
    #endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
1490
1491
0
    return ret;
1492
0
}
1493
1494
static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
1495
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1496
2.33k
{
1497
2.33k
    int ret;
1498
1499
2.33k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
1500
2.33k
        pub == NULL || pubSz == NULL) {
1501
0
        return BAD_FUNC_ARG;
1502
0
    }
1503
1504
2.33k
    ret = GeneratePrivateDh(key, rng, priv, privSz);
1505
1506
2.33k
    if (ret == 0)
1507
1.60k
        ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz);
1508
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1509
    if (ret == 0)
1510
        ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
1511
    if (ret == 0)
1512
        ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz);
1513
#endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
1514
1515
2.33k
    return ret;
1516
2.33k
}
1517
#endif /* !WOLFSSL_KCAPI_DH */
1518
1519
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1520
static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
1521
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1522
{
1523
    int ret;
1524
1525
#if defined(HAVE_INTEL_QA)
1526
    word32 pBits;
1527
1528
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
1529
    pBits = mp_unsigned_bin_size(&key->p) * 8;
1530
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
1531
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
1532
        mp_int x;
1533
1534
        ret = mp_init(&x);
1535
        if (ret != MP_OKAY)
1536
            return ret;
1537
1538
        ret = GeneratePrivateDh(key, rng, priv, privSz);
1539
        if (ret == 0)
1540
            ret = mp_read_unsigned_bin(&x, priv, *privSz);
1541
        if (ret == MP_OKAY)
1542
            ret = wc_mp_to_bigint(&x, &x.raw);
1543
        if (ret == MP_OKAY)
1544
            ret = wc_mp_to_bigint(&key->p, &key->p.raw);
1545
        if (ret == MP_OKAY)
1546
            ret = wc_mp_to_bigint(&key->g, &key->g.raw);
1547
        if (ret == MP_OKAY)
1548
            ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
1549
                &x.raw, pub, pubSz);
1550
        mp_forcezero(&x);
1551
1552
        return ret;
1553
    }
1554
1555
#elif defined(HAVE_CAVIUM)
1556
    /* TODO: Not implemented - use software for now */
1557
1558
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1559
    if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_DH_GEN)) {
1560
        WC_ASYNC_SW* sw = &key->asyncDev.sw;
1561
        sw->dhGen.key = key;
1562
        sw->dhGen.rng = rng;
1563
        sw->dhGen.priv = priv;
1564
        sw->dhGen.privSz = privSz;
1565
        sw->dhGen.pub = pub;
1566
        sw->dhGen.pubSz = pubSz;
1567
        return WC_PENDING_E;
1568
    }
1569
#endif
1570
1571
    /* otherwise use software DH */
1572
    ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
1573
1574
    return ret;
1575
}
1576
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
1577
1578
1579
/* Check DH Public Key for invalid numbers, optionally allowing
1580
 * the public key to be checked against the large prime (q).
1581
 * If q is NULL, the q value of key is used.
1582
 * Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2.
1583
 *
1584
 * key     DH key group parameters.
1585
 * pub     Public Key.
1586
 * pubSz   Public Key size.
1587
 * prime   Large prime (q), optionally NULL to skip check
1588
 * primeSz Size of large prime
1589
 * partial Do the partial test process. (section 5.6.2.3.2)
1590
 *
1591
 *  returns 0 on success or error code
1592
 */
1593
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
1594
       const byte* prime, word32 primeSz, int partial)
1595
100
{
1596
100
    int ret = 0;
1597
100
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1598
100
    mp_int* y = NULL;
1599
100
    mp_int* p = NULL;
1600
100
    mp_int* q = NULL;
1601
#else
1602
    mp_int y[1];
1603
    mp_int p[1];
1604
    mp_int q[1];
1605
#endif
1606
1607
100
    if (key == NULL || pub == NULL) {
1608
0
        return BAD_FUNC_ARG;
1609
0
    }
1610
1611
100
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1612
100
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1613
100
    if (y == NULL)
1614
0
        return MEMORY_E;
1615
100
    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1616
100
    if (p == NULL) {
1617
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1618
0
        return MEMORY_E;
1619
0
    }
1620
100
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1621
100
    if (q == NULL) {
1622
0
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1623
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1624
0
        return MEMORY_E;
1625
0
    }
1626
100
#endif
1627
1628
100
    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
1629
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1630
0
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1631
0
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1632
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1633
0
    #endif
1634
0
        return MP_INIT_E;
1635
0
    }
1636
1637
100
    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
1638
0
        ret = MP_READ_E;
1639
0
    }
1640
1641
100
    if (ret == 0 && prime != NULL) {
1642
0
        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1643
0
            ret = MP_READ_E;
1644
1645
100
    } else if (mp_iszero(&key->q) == MP_NO) {
1646
        /* use q available in DhKey */
1647
0
        if (mp_copy(&key->q, q) != MP_OKAY)
1648
0
            ret = MP_INIT_E;
1649
0
    }
1650
1651
    /* SP 800-56Ar3, section 5.6.2.3.2 */
1652
    /* pub (y) should not be 0 or 1 */
1653
100
    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
1654
0
        ret = MP_CMP_E;
1655
0
    }
1656
1657
    /* pub (y) shouldn't be greater than or equal to p - 1 */
1658
100
    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
1659
0
        ret = MP_INIT_E;
1660
0
    }
1661
100
    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
1662
0
        ret = MP_SUB_E;
1663
0
    }
1664
100
    if (ret == 0 && mp_cmp(y, p) == MP_GT) {
1665
0
        ret = MP_CMP_E;
1666
0
    }
1667
1668
100
    if (!partial) {
1669
100
        if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
1670
1671
            /* restore key->p into p */
1672
0
            if (mp_copy(&key->p, p) != MP_OKAY)
1673
0
                ret = MP_INIT_E;
1674
0
        }
1675
1676
        /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
1677
100
        if (ret == 0 && mp_iszero(q) == MP_NO) {
1678
#ifdef WOLFSSL_HAVE_SP_DH
1679
#ifndef WOLFSSL_SP_NO_2048
1680
            if (mp_count_bits(&key->p) == 2048) {
1681
                ret = sp_ModExp_2048(y, q, p, y);
1682
                if (ret != 0)
1683
                    ret = MP_EXPTMOD_E;
1684
            }
1685
            else
1686
#endif
1687
#ifndef WOLFSSL_SP_NO_3072
1688
            if (mp_count_bits(&key->p) == 3072) {
1689
                ret = sp_ModExp_3072(y, q, p, y);
1690
                if (ret != 0)
1691
                    ret = MP_EXPTMOD_E;
1692
            }
1693
            else
1694
#endif
1695
#ifdef WOLFSSL_SP_4096
1696
            if (mp_count_bits(&key->p) == 4096) {
1697
                ret = sp_ModExp_4096(y, q, p, y);
1698
                if (ret != 0)
1699
                    ret = MP_EXPTMOD_E;
1700
            }
1701
            else
1702
#endif
1703
#endif
1704
1705
0
            {
1706
0
#if !defined(WOLFSSL_SP_MATH)
1707
                /* calculate (y^q) mod(p), store back into y */
1708
0
                if (mp_exptmod(y, q, p, y) != MP_OKAY)
1709
0
                    ret = MP_EXPTMOD_E;
1710
#else
1711
                ret = WC_KEY_SIZE_E;
1712
#endif
1713
0
            }
1714
1715
            /* verify above == 1 */
1716
0
            if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
1717
0
                ret = MP_CMP_E;
1718
0
        }
1719
100
    }
1720
1721
100
    mp_clear(y);
1722
100
    mp_clear(p);
1723
100
    mp_clear(q);
1724
1725
100
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1726
100
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1727
100
    XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1728
100
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1729
100
#endif
1730
1731
100
    return ret;
1732
100
}
1733
1734
1735
/* Performs a full public-key validation routine. */
1736
int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
1737
                        const byte* prime, word32 primeSz)
1738
344
{
1739
344
    return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0);
1740
344
}
1741
1742
1743
/* Check DH Public Key for invalid numbers. Performs a partial public-key
1744
 * validation routine.
1745
 *
1746
 * key   DH key group parameters.
1747
 * pub   Public Key.
1748
 * pubSz Public Key size.
1749
 *
1750
 *  returns 0 on success or error code
1751
 */
1752
int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
1753
0
{
1754
0
    return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1);
1755
0
}
1756
1757
1758
/**
1759
 * Quick validity check of public key value against prime.
1760
 * Checks are:
1761
 *   - Public key not 0 or 1
1762
 *   - Public key not equal to prime or prime - 1
1763
 *   - Public key not bigger than prime.
1764
 *
1765
 * prime    Big-endian encoding of prime in bytes.
1766
 * primeSz  Size of prime in bytes.
1767
 * pub      Big-endian encoding of public key in bytes.
1768
 * pubSz    Size of public key in bytes.
1769
 */
1770
int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,
1771
                       word32 pubSz)
1772
104
{
1773
104
    int ret = 0;
1774
104
    word32 i;
1775
1776
104
    if (prime == NULL || pub == NULL)
1777
0
        return BAD_FUNC_ARG;
1778
1779
166
    for (i = 0; i < pubSz && pub[i] == 0; i++) {
1780
62
    }
1781
104
    pubSz -= i;
1782
104
    pub += i;
1783
1784
104
    if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))
1785
4
        ret = MP_VAL;
1786
100
    else if (pubSz == primeSz) {
1787
0
        for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {
1788
0
        }
1789
0
        if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))
1790
0
            ret = MP_VAL;
1791
0
        else if (pub[i] > prime[i])
1792
0
            ret = MP_VAL;
1793
0
    }
1794
100
    else if (pubSz > primeSz)
1795
0
        ret = MP_VAL;
1796
1797
104
    return ret;
1798
104
}
1799
1800
1801
/* Check DH Private Key for invalid numbers, optionally allowing
1802
 * the private key to be checked against the large prime (q).
1803
 * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
1804
 *
1805
 * key     DH key group parameters.
1806
 * priv    Private Key.
1807
 * privSz  Private Key size.
1808
 * prime   Large prime (q), optionally NULL to skip check
1809
 * primeSz Size of large prime
1810
 *
1811
 *  returns 0 on success or error code
1812
 */
1813
int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
1814
                         const byte* prime, word32 primeSz)
1815
0
{
1816
0
    int ret = 0;
1817
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1818
0
    mp_int* x = NULL;
1819
0
    mp_int* q = NULL;
1820
#else
1821
    mp_int x[1];
1822
    mp_int q[1];
1823
#endif
1824
1825
0
    if (key == NULL || priv == NULL) {
1826
0
        return BAD_FUNC_ARG;
1827
0
    }
1828
1829
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1830
0
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1831
0
    if (x == NULL)
1832
0
        return MEMORY_E;
1833
0
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1834
0
    if (q == NULL) {
1835
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1836
0
        return MEMORY_E;
1837
0
    }
1838
0
#endif
1839
1840
0
    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
1841
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1842
0
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1843
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1844
0
    #endif
1845
0
        return MP_INIT_E;
1846
0
    }
1847
1848
0
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
1849
0
        ret = MP_READ_E;
1850
0
    }
1851
1852
0
    if (ret == 0) {
1853
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1854
        mp_memzero_add("wc_DhCheckPrivKey_ex x", x);
1855
    #endif
1856
0
        if (prime != NULL) {
1857
0
            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1858
0
                ret = MP_READ_E;
1859
0
        }
1860
0
        else if (mp_iszero(&key->q) == MP_NO) {
1861
            /* use q available in DhKey */
1862
0
            if (mp_copy(&key->q, q) != MP_OKAY)
1863
0
                ret = MP_INIT_E;
1864
0
        }
1865
0
    }
1866
1867
    /* priv (x) should not be 0 */
1868
0
    if (ret == 0) {
1869
0
        if (mp_cmp_d(x, 0) == MP_EQ)
1870
0
            ret = MP_CMP_E;
1871
0
    }
1872
1873
0
    if (ret == 0) {
1874
0
        if (mp_iszero(q) == MP_NO) {
1875
            /* priv (x) shouldn't be greater than q - 1 */
1876
            /* q already holds the supplied prime or key->q; do not clobber it */
1877
0
            if (mp_sub_d(q, 1, q) != MP_OKAY)
1878
0
                ret = MP_SUB_E;
1879
0
            if (ret == 0) {
1880
0
                if (mp_cmp(x, q) == MP_GT)
1881
0
                    ret = DH_CHECK_PRIV_E;
1882
0
            }
1883
0
        }
1884
0
    }
1885
1886
0
    mp_forcezero(x);
1887
0
    mp_clear(q);
1888
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1889
0
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1890
0
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1891
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1892
    mp_memzero_check(x);
1893
#endif
1894
1895
0
    return ret;
1896
0
}
1897
1898
1899
/* Check DH Private Key for invalid numbers
1900
 *
1901
 * key    DH key group parameters.
1902
 * priv   Private Key.
1903
 * privSz Private Key size.
1904
 *
1905
 *  returns 0 on success or error code
1906
 */
1907
int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
1908
0
{
1909
0
    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
1910
0
}
1911
1912
1913
/* Performs a Pairwise Consistency Test on an FFC key pair. */
1914
/* Check DH Keys for pair-wise consistency per process in
1915
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. */
1916
static int _ffc_pairwise_consistency_test(DhKey* key,
1917
        const byte* pub, word32 pubSz, const byte* priv, word32 privSz)
1918
0
{
1919
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1920
0
    mp_int* publicKey = NULL;
1921
0
    mp_int* privateKey = NULL;
1922
0
    mp_int* checkKey = NULL;
1923
#else
1924
    mp_int publicKey[1];
1925
    mp_int privateKey[1];
1926
    mp_int checkKey[1];
1927
#endif
1928
0
    int ret = 0;
1929
1930
0
    if (key == NULL || pub == NULL || priv == NULL)
1931
0
        return BAD_FUNC_ARG;
1932
0
    if (mp_iseven(&key->p) == MP_YES)
1933
0
        return MP_VAL;
1934
1935
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1936
0
    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1937
0
    if (publicKey == NULL)
1938
0
        return MEMORY_E;
1939
0
    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1940
0
    if (privateKey == NULL) {
1941
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1942
0
        return MEMORY_E;
1943
0
    }
1944
0
    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1945
0
    if (checkKey == NULL) {
1946
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1947
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1948
0
        return MEMORY_E;
1949
0
    }
1950
0
#endif
1951
1952
0
    if (mp_init_multi(publicKey, privateKey, checkKey,
1953
0
                      NULL, NULL, NULL) != MP_OKAY) {
1954
1955
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1956
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1957
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1958
0
        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
1959
0
    #endif
1960
0
        return MP_INIT_E;
1961
0
    }
1962
1963
    /* Load the private and public keys into big integers. */
1964
0
    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
1965
0
        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
1966
1967
0
        ret = MP_READ_E;
1968
0
    }
1969
#ifdef WOLFSSL_CHECK_MEM_ZERO
1970
    mp_memzero_add("_ffc_pairwise_consistency_test privateKey", privateKey);
1971
#endif
1972
1973
    /* Calculate checkKey = g^privateKey mod p */
1974
0
    if (ret == 0) {
1975
#ifdef WOLFSSL_HAVE_SP_DH
1976
#ifndef WOLFSSL_SP_NO_2048
1977
        if (mp_count_bits(&key->p) == 2048) {
1978
            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
1979
            if (ret != 0)
1980
                ret = MP_EXPTMOD_E;
1981
        }
1982
        else
1983
#endif
1984
#ifndef WOLFSSL_SP_NO_3072
1985
        if (mp_count_bits(&key->p) == 3072) {
1986
            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
1987
            if (ret != 0)
1988
                ret = MP_EXPTMOD_E;
1989
        }
1990
        else
1991
#endif
1992
#ifdef WOLFSSL_SP_4096
1993
        if (mp_count_bits(&key->p) == 4096) {
1994
            ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
1995
            if (ret != 0)
1996
                ret = MP_EXPTMOD_E;
1997
        }
1998
        else
1999
#endif
2000
#endif
2001
0
        {
2002
0
#if !defined(WOLFSSL_SP_MATH)
2003
0
            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
2004
0
                ret = MP_EXPTMOD_E;
2005
#else
2006
            ret = WC_KEY_SIZE_E;
2007
#endif
2008
0
        }
2009
0
    }
2010
2011
    /* Compare the calculated public key to the supplied check value. */
2012
0
    if (ret == 0) {
2013
0
        if (mp_cmp(checkKey, publicKey) != MP_EQ)
2014
0
            ret = MP_CMP_E;
2015
0
    }
2016
2017
0
    mp_forcezero(privateKey);
2018
0
    mp_clear(publicKey);
2019
0
    mp_clear(checkKey);
2020
2021
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2022
0
    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
2023
0
    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
2024
0
    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
2025
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
2026
    mp_memzero_check(privateKey);
2027
#endif
2028
2029
0
    return ret;
2030
0
}
2031
2032
2033
/* Check DH Keys for pair-wise consistency per process in
2034
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
2035
 *
2036
 * key    DH key group parameters.
2037
 * pub    Public Key.
2038
 * pubSz  Public Key size.
2039
 * priv   Private Key.
2040
 * privSz Private Key size.
2041
 *
2042
 *  returns 0 on success or error code
2043
 */
2044
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
2045
                      const byte* priv, word32 privSz)
2046
0
{
2047
0
    return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz);
2048
0
}
2049
2050
2051
int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
2052
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
2053
2.38k
{
2054
2.38k
    int ret;
2055
2056
2.38k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
2057
2.35k
                                                pub == NULL || pubSz == NULL) {
2058
51
        return BAD_FUNC_ARG;
2059
51
    }
2060
2061
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
2062
    if (! wc_dh_enabled)
2063
        return FIPS_NOT_ALLOWED_E;
2064
#endif
2065
2066
#ifdef WOLFSSL_KCAPI_DH
2067
    (void)priv;
2068
    (void)privSz;
2069
    ret = KcapiDh_MakeKey(key, pub, pubSz);
2070
#else
2071
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2072
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
2073
        ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
2074
    }
2075
    else
2076
#endif
2077
2.33k
    {
2078
2.33k
        ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
2079
2.33k
    }
2080
2.33k
#endif /* WOLFSSL_KCAPI_DH */
2081
2082
2.33k
    return ret;
2083
2.38k
}
2084
2085
#ifndef WOLFSSL_KCAPI_DH
2086
static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
2087
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz, int ct)
2088
205
{
2089
205
    int ret = 0;
2090
205
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2091
205
    mp_int* y = NULL;
2092
205
#if !defined(WOLFSSL_SP_MATH)
2093
205
    mp_int* x = NULL;
2094
205
    mp_int* z = NULL;
2095
205
#endif
2096
#else
2097
    mp_int y[1];
2098
#if !defined(WOLFSSL_SP_MATH)
2099
    mp_int x[1];
2100
    mp_int z[1];
2101
#endif
2102
#endif
2103
2104
    /* reject primes below the minimum allowed size */
2105
205
    if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
2106
105
        WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
2107
105
        return WC_KEY_SIZE_E;
2108
105
    }
2109
2110
100
    if (mp_iseven(&key->p) == MP_YES) {
2111
0
        return MP_VAL;
2112
0
    }
2113
2114
    /* Non-blocking re-entry: the same wc_DhAgree call repeats until the
2115
     * SP state machine completes, so cache the per-op key validation
2116
     * results instead of re-running them each yield. The cache is
2117
     * scoped to non-blocking, non-const-time callers only. */
2118
#ifdef WC_DH_NONBLOCK
2119
    if (key->nb == NULL || ct || !key->nb->pubKeyValidated)
2120
#endif
2121
100
    {
2122
#ifdef WOLFSSL_VALIDATE_FFC_IMPORT
2123
        if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
2124
            WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
2125
            return DH_CHECK_PRIV_E;
2126
        }
2127
#endif
2128
        /* Always validate peer public key (2 <= y <= p-2) per SP 800-56A */
2129
100
        if (wc_DhCheckPubKey_ex(key, otherPub, pubSz, NULL, 0) != 0) {
2130
0
            WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
2131
0
            return DH_CHECK_PUB_E;
2132
0
        }
2133
#ifdef WC_DH_NONBLOCK
2134
        if (key->nb != NULL && !ct) {
2135
            key->nb->pubKeyValidated = 1;
2136
        }
2137
#endif
2138
100
    }
2139
2140
#if defined(WC_DH_NONBLOCK) && defined(WOLFSSL_HAVE_SP_DH) && \
2141
    defined(WOLFSSL_SP_NONBLOCK) && defined(WOLFSSL_SP_SMALL) && \
2142
    !defined(WOLFSSL_SP_FAST_MODEXP)
2143
    /* Non-blocking dispatch bypasses the mp_int dance entirely - the SP
2144
     * wrapper takes byte buffers and persists across yields. The constant-
2145
     * time fold-back (ct branch) is intentionally not applied here; nb
2146
     * callers should use the standard wc_DhAgree(). */
2147
    if (key->nb != NULL && !ct) {
2148
        int nb_ret = MP_OKAY;
2149
        int dispatched = 0;
2150
    #ifndef WOLFSSL_SP_NO_2048
2151
        if (mp_count_bits(&key->p) == 2048) {
2152
            nb_ret = sp_DhExp_2048_nb(&key->nb->sp_ctx, otherPub, pubSz,
2153
                         priv, privSz, &key->p, agree, agreeSz);
2154
            dispatched = 1;
2155
        }
2156
    #endif
2157
    #ifndef WOLFSSL_SP_NO_3072
2158
        if (!dispatched && mp_count_bits(&key->p) == 3072) {
2159
            nb_ret = sp_DhExp_3072_nb(&key->nb->sp_ctx, otherPub, pubSz,
2160
                         priv, privSz, &key->p, agree, agreeSz);
2161
            dispatched = 1;
2162
        }
2163
    #endif
2164
    #ifdef WOLFSSL_SP_4096
2165
        if (!dispatched && mp_count_bits(&key->p) == 4096) {
2166
            nb_ret = sp_DhExp_4096_nb(&key->nb->sp_ctx, otherPub, pubSz,
2167
                         priv, privSz, &key->p, agree, agreeSz);
2168
            dispatched = 1;
2169
        }
2170
    #endif
2171
        if (dispatched) {
2172
            /* Op finished (or hit a hard error) - clear the cached
2173
             * validation so the next op on this DhNb re-runs the
2174
             * SP 800-56A peer-key check. MP_WOULDBLOCK keeps it. */
2175
            if (nb_ret != WC_NO_ERR_TRACE(MP_WOULDBLOCK)) {
2176
                key->nb->pubKeyValidated = 0;
2177
            }
2178
            return nb_ret;
2179
        }
2180
        /* size not nb-supported - the blocking path below completes in
2181
         * one call, so the cached validation is single-use. Clear it
2182
         * here so the next agree on this DhNb re-validates. */
2183
        key->nb->pubKeyValidated = 0;
2184
        /* fall through to blocking path */
2185
    }
2186
#endif
2187
2188
100
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2189
100
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2190
100
    if (y == NULL)
2191
0
        return MEMORY_E;
2192
100
#if !defined(WOLFSSL_SP_MATH)
2193
100
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2194
100
    if (x == NULL) {
2195
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2196
0
        return MEMORY_E;
2197
0
    }
2198
100
    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2199
100
    if (z == NULL) {
2200
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2201
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2202
0
        return MEMORY_E;
2203
0
    }
2204
100
#endif
2205
100
#endif
2206
2207
#ifdef WOLFSSL_HAVE_SP_DH
2208
    if (0
2209
#ifndef WOLFSSL_SP_NO_2048
2210
        || mp_count_bits(&key->p) == 2048
2211
#endif
2212
#ifndef WOLFSSL_SP_NO_3072
2213
        || mp_count_bits(&key->p) == 3072
2214
#endif
2215
#ifdef WOLFSSL_SP_4096
2216
        || mp_count_bits(&key->p) == 4096
2217
#endif
2218
       ) {
2219
        int i = (int)*agreeSz - 1;
2220
2221
        if (mp_init(y) != MP_OKAY)
2222
            ret = MP_INIT_E;
2223
2224
        if (ret == 0) {
2225
            if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2226
                ret = MP_READ_E;
2227
2228
            if (ret == 0) {
2229
            #ifndef WOLFSSL_SP_NO_2048
2230
                if (mp_count_bits(&key->p) == 2048) {
2231
                    ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree,
2232
                                        agreeSz);
2233
                }
2234
            #endif
2235
            #ifndef WOLFSSL_SP_NO_3072
2236
                if (mp_count_bits(&key->p) == 3072) {
2237
                    ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree,
2238
                                        agreeSz);
2239
                }
2240
            #endif
2241
            #ifdef WOLFSSL_SP_4096
2242
                if (mp_count_bits(&key->p) == 4096) {
2243
                    ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree,
2244
                                        agreeSz);
2245
                }
2246
            #endif
2247
            }
2248
2249
            mp_clear(y);
2250
        }
2251
2252
        /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */
2253
        if ((ret == 0) &&
2254
            ((*agreeSz == 0) || ((*agreeSz == 1) && (agree[0] == 1))))
2255
        {
2256
            ret = MP_VAL;
2257
        }
2258
2259
        if ((ret == 0) && ct) {
2260
            volatile word16 mask = 0xff;
2261
            sword16 o = (sword16)(*agreeSz - 1);
2262
2263
            *agreeSz = (word32)(i + 1);
2264
            for (; i >= 0 ; i--) {
2265
                agree[i] = agree[o] & (byte)mask;
2266
                mask = ctMask16LT(0, (int)o);
2267
                o = (sword16)(o + (sword16)mask);
2268
            }
2269
        }
2270
2271
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2272
    #if !defined(WOLFSSL_SP_MATH)
2273
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2274
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2275
    #endif
2276
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2277
    #endif
2278
        return ret;
2279
    }
2280
#endif
2281
2282
100
#if !defined(WOLFSSL_SP_MATH)
2283
100
    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
2284
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2285
0
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2286
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2287
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2288
0
    #endif
2289
0
        return MP_INIT_E;
2290
0
    }
2291
100
#if defined(WOLFSSL_SP_MATH_ALL)
2292
100
    if (ct) {
2293
        /* TFM and Integer implementations keep high words zero.
2294
         * SP math implementation needs all words set to zero as it doesn't
2295
         * ensure unused words are zero. */
2296
0
        mp_forcezero(x);
2297
0
    }
2298
100
#endif
2299
2300
100
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
2301
0
        ret = MP_READ_E;
2302
#ifdef WOLFSSL_CHECK_MEM_ZERO
2303
    if (ret == 0)
2304
        mp_memzero_add("wc_DhAgree_Sync x", x);
2305
#endif
2306
2307
100
    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2308
0
        ret = MP_READ_E;
2309
2310
100
    if (ret == 0) {
2311
100
        if (ct) {
2312
0
            int bits;
2313
2314
            /* x is mod q but if q not available, use p (> q). */
2315
0
            if (mp_iszero(&key->q) == MP_NO) {
2316
0
                bits = mp_count_bits(&key->q);
2317
0
            }
2318
0
            else {
2319
0
                bits = mp_count_bits(&key->p);
2320
0
            }
2321
            /* Exponentiate to the maximum words of a valid x to ensure a
2322
             * constant time operation. */
2323
0
            ret = mp_exptmod_ex(y, x, (bits + DIGIT_BIT - 1) / DIGIT_BIT,
2324
0
                                &key->p, z);
2325
0
        }
2326
100
        else {
2327
100
            ret = mp_exptmod(y, x, &key->p, z);
2328
100
        }
2329
100
        if (ret != MP_OKAY)
2330
0
            ret = MP_EXPTMOD_E;
2331
100
    }
2332
2333
#ifdef WOLFSSL_CHECK_MEM_ZERO
2334
    if (ret == 0)
2335
        mp_memzero_add("wc_DhAgree_Sync z", z);
2336
#endif
2337
2338
    /* make sure z is not one (SP800-56A, 5.7.1.1) */
2339
100
    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
2340
0
        ret = MP_VAL;
2341
2342
100
    if (ret == 0) {
2343
100
        if (ct) {
2344
            /* Put the secret into a buffer in constant time. */
2345
0
            ret = mp_to_unsigned_bin_len_ct(z, agree, (int)*agreeSz);
2346
0
        }
2347
100
        else {
2348
100
            ret = mp_to_unsigned_bin(z, agree);
2349
100
            if (ret == MP_OKAY)
2350
100
                *agreeSz = (word32)mp_unsigned_bin_size(z);
2351
100
        }
2352
100
    }
2353
2354
100
    mp_forcezero(z);
2355
100
    mp_clear(y);
2356
100
    mp_forcezero(x);
2357
2358
#else
2359
    (void)ct;
2360
    ret = WC_KEY_SIZE_E;
2361
#endif
2362
2363
100
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2364
100
#if !defined(WOLFSSL_SP_MATH)
2365
100
    XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2366
100
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2367
100
#endif
2368
100
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2369
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
2370
#if !defined(WOLFSSL_SP_MATH)
2371
    mp_memzero_check(x);
2372
    mp_memzero_check(z);
2373
#endif
2374
#endif
2375
2376
100
    return ret;
2377
100
}
2378
2379
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2380
static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
2381
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
2382
{
2383
    int ret;
2384
2385
#if defined(HAVE_INTEL_QA)
2386
    word32 pBits;
2387
2388
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
2389
    pBits = mp_unsigned_bin_size(&key->p) * 8;
2390
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
2391
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
2392
        ret = wc_mp_to_bigint(&key->p, &key->p.raw);
2393
        if (ret == MP_OKAY)
2394
            ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
2395
                agree, agreeSz, priv, privSz, otherPub, pubSz);
2396
        return ret;
2397
    }
2398
2399
#elif defined(HAVE_CAVIUM)
2400
    /* TODO: Not implemented - use software for now */
2401
2402
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
2403
    if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_DH_AGREE)) {
2404
        WC_ASYNC_SW* sw = &key->asyncDev.sw;
2405
        sw->dhAgree.key = key;
2406
        sw->dhAgree.agree = agree;
2407
        sw->dhAgree.agreeSz = agreeSz;
2408
        sw->dhAgree.priv = priv;
2409
        sw->dhAgree.privSz = privSz;
2410
        sw->dhAgree.otherPub = otherPub;
2411
        sw->dhAgree.pubSz = pubSz;
2412
        return WC_PENDING_E;
2413
    }
2414
#endif
2415
2416
    /* otherwise use software DH */
2417
    ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz,
2418
                          0);
2419
2420
    return ret;
2421
}
2422
#endif /* WOLFSSL_ASYNC_CRYPT */
2423
#endif /* !WOLFSSL_KCAPI_DH */
2424
2425
int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
2426
            word32 privSz, const byte* otherPub, word32 pubSz)
2427
638
{
2428
638
    int ret = 0;
2429
2430
638
    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
2431
603
                                                            otherPub == NULL) {
2432
47
        return BAD_FUNC_ARG;
2433
47
    }
2434
2435
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
2436
    if (! wc_dh_enabled)
2437
        return FIPS_NOT_ALLOWED_E;
2438
#endif
2439
2440
#ifdef WOLFSSL_KCAPI_DH
2441
    (void)priv;
2442
    (void)privSz;
2443
    if (mp_count_bits(&key->p) < DH_MIN_SIZE) {
2444
        WOLFSSL_MSG("DH prime smaller than DH_MIN_SIZE");
2445
        return WC_KEY_SIZE_E;
2446
    }
2447
    ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
2448
#else
2449
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2450
    /* Async marker takes precedence: when wolfAsync_DoSw (wolfcrypt/src/
2451
     * async.c) re-enters the compute path, wc_DhAgree_Async dispatches
2452
     * to the SP nonblock wrapper if key->nb is attached, and per-yield
2453
     * FP_WOULDBLOCK (alias of MP_WOULDBLOCK) is translated to
2454
     * WC_PENDING_E by wolfAsync_DoSw so the TLS event loop drives it. */
2455
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
2456
        ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub,
2457
                               pubSz);
2458
    }
2459
    else
2460
#endif
2461
591
    {
2462
        /* wc_DhAgree_Sync handles key->nb internally; no separate dispatch
2463
         * needed here. wc_DhAgree_ct (constant-time fold-back) bypasses
2464
         * this function entirely so passing ct=0 is correct. */
2465
591
        ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub,
2466
591
                              pubSz, 0);
2467
591
    }
2468
591
#endif /* WOLFSSL_KCAPI_DH */
2469
2470
591
    return ret;
2471
638
}
2472
2473
int wc_DhAgree_ct(DhKey* key, byte* agree, word32 *agreeSz, const byte* priv,
2474
            word32 privSz, const byte* otherPub, word32 pubSz)
2475
0
{
2476
0
    word32 requested_agreeSz;
2477
2478
0
    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
2479
0
                                                            otherPub == NULL) {
2480
0
        return BAD_FUNC_ARG;
2481
0
    }
2482
2483
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
2484
    if (! wc_dh_enabled)
2485
        return FIPS_NOT_ALLOWED_E;
2486
#endif
2487
2488
0
    requested_agreeSz = (word32)mp_unsigned_bin_size(&key->p);
2489
0
    if (requested_agreeSz > *agreeSz) {
2490
0
        return BUFFER_E;
2491
0
    }
2492
0
    *agreeSz = requested_agreeSz;
2493
2494
0
    return wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz,
2495
0
                           1);
2496
0
}
2497
2498
#ifdef WOLFSSL_DH_EXTRA
2499
WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst)
2500
{
2501
    int ret;
2502
2503
    if (!src || !dst || src == dst) {
2504
        WOLFSSL_MSG("Parameters not provided or are the same");
2505
        return BAD_FUNC_ARG;
2506
    }
2507
2508
    if ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) {
2509
        WOLFSSL_MSG("mp_copy error");
2510
        return ret;
2511
    }
2512
2513
    if ((ret = mp_copy(&src->g, &dst->g)) != MP_OKAY) {
2514
        WOLFSSL_MSG("mp_copy error");
2515
        return ret;
2516
    }
2517
2518
    if ((ret = mp_copy(&src->q, &dst->q)) != MP_OKAY) {
2519
        WOLFSSL_MSG("mp_copy error");
2520
        return ret;
2521
    }
2522
2523
    if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) {
2524
        WOLFSSL_MSG("mp_copy error");
2525
        return ret;
2526
    }
2527
2528
    if ((ret = mp_copy(&src->priv, &dst->priv)) != MP_OKAY) {
2529
        WOLFSSL_MSG("mp_copy error");
2530
        return ret;
2531
    }
2532
#ifdef WOLFSSL_CHECK_MEM_ZERO
2533
    mp_memzero_add("wc_DhKeyCopy dst->priv", &dst->priv);
2534
#endif
2535
2536
    dst->heap = src->heap;
2537
2538
    return MP_OKAY;
2539
}
2540
2541
/* Sets private and public key in DhKey if both are available, otherwise sets
2542
    either private or public key, depending on which is available. */
2543
int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,
2544
                       const byte* pub, word32 pubSz)
2545
{
2546
    byte havePriv, havePub;
2547
2548
    if (key == NULL) {
2549
        return BAD_FUNC_ARG;
2550
    }
2551
2552
    havePriv = ( (priv != NULL) && (privSz > 0) );
2553
    havePub  = ( (pub  != NULL) && (pubSz  > 0) );
2554
2555
    if (!havePub && !havePriv) {
2556
        WOLFSSL_MSG("No Public or Private Key to Set");
2557
        return BAD_FUNC_ARG;
2558
    }
2559
2560
    /* Set Private Key */
2561
    if (havePriv) {
2562
        /* may have leading 0 */
2563
        if (priv[0] == 0) {
2564
            privSz--; priv++;
2565
        }
2566
        if (mp_init(&key->priv) != MP_OKAY)
2567
            havePriv = 0;
2568
    }
2569
    if (havePriv) {
2570
        if (mp_read_unsigned_bin(&key->priv, priv, privSz) != MP_OKAY) {
2571
            mp_forcezero(&key->priv);
2572
            havePriv = 0;
2573
        } else {
2574
            WOLFSSL_MSG("DH Private Key Set");
2575
        #ifdef WOLFSSL_CHECK_MEM_ZERO
2576
            mp_memzero_add("wc_DhImportKeyPair key->priv", &key->priv);
2577
        #endif
2578
        }
2579
    }
2580
2581
    /* Set Public Key */
2582
    if (havePub) {
2583
        /* may have leading 0 */
2584
        if (pub[0] == 0) {
2585
            pubSz--; pub++;
2586
        }
2587
        if (mp_init(&key->pub) != MP_OKAY)
2588
            havePub = 0;
2589
    }
2590
    if (havePub) {
2591
        if (mp_read_unsigned_bin(&key->pub, pub, pubSz) != MP_OKAY) {
2592
            mp_clear(&key->pub);
2593
            havePub = 0;
2594
            if (havePriv) {
2595
                mp_forcezero(&key->priv);
2596
                havePriv = 0; /* set to 0 to error out with failed read pub */
2597
            }
2598
        } else {
2599
            WOLFSSL_MSG("DH Public Key Set");
2600
        }
2601
    }
2602
2603
    if (havePriv == 0 && havePub == 0) {
2604
        return MEMORY_E;
2605
    }
2606
2607
    return 0;
2608
}
2609
2610
/* Can be used with WOLFSSL_DH_EXTRA when key is loaded with
2611
    wc_DhKeyDecode or wc_DhImportKeyPair */
2612
int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz,
2613
    byte* pub, word32* pPubSz)
2614
{
2615
    int ret = 0;
2616
2617
    if (key == NULL || (priv && pPrivSz == NULL) || (pub && pPubSz == NULL)) {
2618
        return BAD_FUNC_ARG;
2619
    }
2620
2621
    if (priv) {
2622
        word32 privSz = (word32)mp_unsigned_bin_size(&key->priv);
2623
        if (privSz > *pPrivSz) {
2624
            return BUFFER_E;
2625
        }
2626
        *pPrivSz = privSz;
2627
        ret |= mp_to_unsigned_bin(&key->priv, priv);
2628
    }
2629
2630
    if (pub) {
2631
        word32 pubSz = (word32)mp_unsigned_bin_size(&key->pub);
2632
        if (pubSz > *pPubSz) {
2633
            return BUFFER_E;
2634
        }
2635
        *pPubSz = pubSz;
2636
        ret |= mp_to_unsigned_bin(&key->pub,  pub);
2637
    }
2638
2639
    if (ret != 0)
2640
        ret = ASN_DH_KEY_E;
2641
    return ret;
2642
}
2643
2644
#endif /* WOLFSSL_DH_EXTRA */
2645
2646
static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2647
                     word32 gSz, const byte* q, word32 qSz, int trusted,
2648
                     WC_RNG* rng)
2649
3.62k
{
2650
3.62k
    int ret = 0;
2651
3.62k
    mp_int* keyP = NULL;
2652
3.62k
    mp_int* keyG = NULL;
2653
2654
3.62k
    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
2655
202
        ret = BAD_FUNC_ARG;
2656
202
    }
2657
2658
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
2659
    if ((ret == 0) && (! wc_dh_enabled))
2660
        ret = FIPS_NOT_ALLOWED_E;
2661
#endif
2662
2663
3.62k
    if (ret == 0) {
2664
        /* may have leading 0 */
2665
3.41k
        if (p[0] == 0) {
2666
764
            pSz--; p++;
2667
764
        }
2668
2669
3.41k
        if (g[0] == 0) {
2670
498
            gSz--; g++;
2671
498
        }
2672
2673
3.41k
        if (q != NULL) {
2674
0
            if (q[0] == 0) {
2675
0
                qSz--; q++;
2676
0
            }
2677
0
        }
2678
2679
3.41k
        if (mp_init(&key->p) != MP_OKAY)
2680
0
            ret = MP_INIT_E;
2681
3.41k
    }
2682
2683
3.62k
    if (ret == 0) {
2684
3.41k
        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
2685
228
            ret = ASN_DH_KEY_E;
2686
3.19k
        else
2687
3.19k
            keyP = &key->p;
2688
3.41k
    }
2689
2690
3.62k
    if (ret == 0 && !trusted) {
2691
0
        int isPrime = 0;
2692
2693
        /* Short-circuit the primality check for p if it is one of the named
2694
         * public moduli (known primes) from RFC 7919.
2695
         */
2696
0
        #ifdef HAVE_FFDHE_2048
2697
0
        if ((pSz == sizeof(dh_ffdhe2048_p)) &&
2698
0
            (XMEMCMP(p, dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p)) == 0))
2699
0
        {
2700
0
            isPrime = 1;
2701
0
        }
2702
0
        else
2703
0
        #endif
2704
        #ifdef HAVE_FFDHE_3072
2705
        if ((pSz == sizeof(dh_ffdhe3072_p)) &&
2706
            (XMEMCMP(p, dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p)) == 0))
2707
        {
2708
            isPrime = 1;
2709
        }
2710
        else
2711
        #endif
2712
        #ifdef HAVE_FFDHE_4096
2713
        if ((pSz == sizeof(dh_ffdhe4096_p)) &&
2714
            (XMEMCMP(p, dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p)) == 0))
2715
        {
2716
            isPrime = 1;
2717
        }
2718
        else
2719
        #endif
2720
        #ifdef HAVE_FFDHE_6144
2721
        if ((pSz == sizeof(dh_ffdhe6144_p)) &&
2722
            (XMEMCMP(p, dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p)) == 0))
2723
        {
2724
            isPrime = 1;
2725
        }
2726
        else
2727
        #endif
2728
        #ifdef HAVE_FFDHE_8192
2729
        if ((pSz == sizeof(dh_ffdhe8192_p)) &&
2730
            (XMEMCMP(p, dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p)) == 0))
2731
        {
2732
            isPrime = 1;
2733
        }
2734
        else
2735
        #endif
2736
0
        {
2737
0
#ifndef WC_NO_RNG
2738
0
            WC_RNG* checkRng = rng;
2739
0
            WC_RNG* tmpRng = NULL;
2740
2741
            /* A fixed-base Miller-Rabin test can be fooled by a crafted
2742
             * composite, so use random witnesses when an RNG is available.
2743
             * Create a temporary RNG when the caller did not supply one. */
2744
0
            if (checkRng == NULL) {
2745
0
                if (wc_rng_new_ex(&tmpRng, NULL, 0, key->heap,
2746
0
                        INVALID_DEVID) == 0) {
2747
0
                    checkRng = tmpRng;
2748
0
                }
2749
0
            }
2750
2751
0
            if (checkRng != NULL) {
2752
0
                ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, checkRng);
2753
0
            }
2754
0
            else {
2755
                /* Fall back to the deterministic test rather than failing the
2756
                 * parameter load. This is the weaker check: a composite
2757
                 * crafted against the fixed bases is accepted as prime. */
2758
0
                WOLFSSL_MSG("DH: no RNG, primality test uses fixed bases");
2759
0
                ret = mp_prime_is_prime(keyP, 8, &isPrime);
2760
0
            }
2761
2762
            /* Safe on NULL and zeroizes the RNG state before freeing. */
2763
0
            wc_rng_free(tmpRng);
2764
#else
2765
            (void)rng;
2766
            ret = mp_prime_is_prime(keyP, 8, &isPrime);
2767
#endif
2768
0
        }
2769
2770
0
        if (ret == 0 && isPrime == 0)
2771
0
            ret = DH_CHECK_PUB_E;
2772
0
    }
2773
2774
3.62k
    if (ret == 0 && mp_init(&key->g) != MP_OKAY)
2775
0
        ret = MP_INIT_E;
2776
3.62k
    if (ret == 0) {
2777
3.19k
        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
2778
36
            ret = ASN_DH_KEY_E;
2779
3.15k
        else
2780
3.15k
            keyG = &key->g;
2781
3.19k
    }
2782
2783
3.62k
    if (ret == 0 && q != NULL) {
2784
0
        if (mp_init(&key->q) != MP_OKAY)
2785
0
            ret = MP_INIT_E;
2786
0
    }
2787
3.62k
    if (ret == 0 && q != NULL) {
2788
0
        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
2789
0
            ret = MP_INIT_E;
2790
0
        else
2791
0
            key->trustedGroup = trusted;
2792
0
    }
2793
2794
3.62k
    if (ret != 0 && key != NULL) {
2795
466
        if (keyG)
2796
0
            mp_clear(keyG);
2797
466
        if (keyP)
2798
36
            mp_clear(keyP);
2799
466
    }
2800
2801
3.62k
    return ret;
2802
3.62k
}
2803
2804
2805
int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2806
                   word32 gSz, const byte* q, word32 qSz, int trusted,
2807
                   WC_RNG* rng)
2808
0
{
2809
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
2810
0
}
2811
2812
2813
int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
2814
                   word32 gSz, const byte* q, word32 qSz)
2815
0
{
2816
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL);
2817
0
}
2818
2819
2820
/* not in asn anymore since no actual asn types used */
2821
int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2822
                word32 gSz)
2823
3.62k
{
2824
    /* This should not have trusted set. */
2825
3.62k
    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
2826
3.62k
}
2827
2828
2829
int wc_DhSetNamedKey(DhKey* key, int name)
2830
0
{
2831
0
    const byte* p = NULL;
2832
0
    const byte* g = NULL;
2833
0
    const byte* q = NULL;
2834
0
    word32 pSz = 0, gSz = 0, qSz = 0;
2835
2836
0
    switch (name) {
2837
0
        #ifdef HAVE_FFDHE_2048
2838
0
        case WC_FFDHE_2048:
2839
0
            p = dh_ffdhe2048_p;
2840
0
            pSz = sizeof(dh_ffdhe2048_p);
2841
0
            g = dh_ffdhe2048_g;
2842
0
            gSz = sizeof(dh_ffdhe2048_g);
2843
            #ifdef HAVE_FFDHE_Q
2844
            q = dh_ffdhe2048_q;
2845
            qSz = sizeof(dh_ffdhe2048_q);
2846
            #endif /* HAVE_FFDHE_Q */
2847
0
            break;
2848
0
        #endif /* HAVE_FFDHE_2048 */
2849
        #ifdef HAVE_FFDHE_3072
2850
        case WC_FFDHE_3072:
2851
            p = dh_ffdhe3072_p;
2852
            pSz = sizeof(dh_ffdhe3072_p);
2853
            g = dh_ffdhe3072_g;
2854
            gSz = sizeof(dh_ffdhe3072_g);
2855
            #ifdef HAVE_FFDHE_Q
2856
            q = dh_ffdhe3072_q;
2857
            qSz = sizeof(dh_ffdhe3072_q);
2858
            #endif /* HAVE_FFDHE_Q */
2859
            break;
2860
        #endif /* HAVE_FFDHE_3072 */
2861
        #ifdef HAVE_FFDHE_4096
2862
        case WC_FFDHE_4096:
2863
            p = dh_ffdhe4096_p;
2864
            pSz = sizeof(dh_ffdhe4096_p);
2865
            g = dh_ffdhe4096_g;
2866
            gSz = sizeof(dh_ffdhe4096_g);
2867
            #ifdef HAVE_FFDHE_Q
2868
            q = dh_ffdhe4096_q;
2869
            qSz = sizeof(dh_ffdhe4096_q);
2870
            #endif /* HAVE_FFDHE_Q */
2871
            break;
2872
        #endif /* HAVE_FFDHE_4096 */
2873
        #ifdef HAVE_FFDHE_6144
2874
        case WC_FFDHE_6144:
2875
            p = dh_ffdhe6144_p;
2876
            pSz = sizeof(dh_ffdhe6144_p);
2877
            g = dh_ffdhe6144_g;
2878
            gSz = sizeof(dh_ffdhe6144_g);
2879
            #ifdef HAVE_FFDHE_Q
2880
            q = dh_ffdhe6144_q;
2881
            qSz = sizeof(dh_ffdhe6144_q);
2882
            #endif /* HAVE_FFDHE_Q */
2883
            break;
2884
        #endif /* HAVE_FFDHE_6144 */
2885
        #ifdef HAVE_FFDHE_8192
2886
        case WC_FFDHE_8192:
2887
            p = dh_ffdhe8192_p;
2888
            pSz = sizeof(dh_ffdhe8192_p);
2889
            g = dh_ffdhe8192_g;
2890
            gSz = sizeof(dh_ffdhe8192_g);
2891
            #ifdef HAVE_FFDHE_Q
2892
            q = dh_ffdhe8192_q;
2893
            qSz = sizeof(dh_ffdhe8192_q);
2894
            #endif /* HAVE_FFDHE_Q */
2895
            break;
2896
        #endif /* HAVE_FFDHE_8192 */
2897
0
        default:
2898
0
            break;
2899
0
    }
2900
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
2901
0
}
2902
2903
2904
word32 wc_DhGetNamedKeyMinSize(int name)
2905
0
{
2906
0
    word32 size;
2907
2908
0
    switch (name) {
2909
0
        #ifdef HAVE_FFDHE_2048
2910
0
        case WC_FFDHE_2048:
2911
0
            size = 29;
2912
0
            break;
2913
0
        #endif /* HAVE_FFDHE_2048 */
2914
        #ifdef HAVE_FFDHE_3072
2915
        case WC_FFDHE_3072:
2916
            size = 34;
2917
            break;
2918
        #endif /* HAVE_FFDHE_3072 */
2919
        #ifdef HAVE_FFDHE_4096
2920
        case WC_FFDHE_4096:
2921
            size = 39;
2922
            break;
2923
        #endif /* HAVE_FFDHE_4096 */
2924
        #ifdef HAVE_FFDHE_6144
2925
        case WC_FFDHE_6144:
2926
            size = 46;
2927
            break;
2928
        #endif /* HAVE_FFDHE_6144 */
2929
        #ifdef HAVE_FFDHE_8192
2930
        case WC_FFDHE_8192:
2931
            size = 52;
2932
            break;
2933
        #endif /* HAVE_FFDHE_8192 */
2934
0
        default:
2935
0
            size = 0;
2936
0
    }
2937
2938
0
    return size;
2939
0
}
2940
2941
2942
/* Returns 1: params match
2943
 *         0: params differ */
2944
int wc_DhCmpNamedKey(int name, int noQ,
2945
        const byte* p, word32 pSz,
2946
        const byte* g, word32 gSz,
2947
        const byte* q, word32 qSz)
2948
0
{
2949
0
    const byte* pCmp = NULL;
2950
0
    const byte* qCmp = NULL;
2951
0
    const byte* gCmp = NULL;
2952
0
    word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0;
2953
0
    int cmp = 0, goodName = 1;
2954
2955
0
    switch (name) {
2956
0
        #ifdef HAVE_FFDHE_2048
2957
0
        case WC_FFDHE_2048:
2958
0
            pCmp = dh_ffdhe2048_p;
2959
0
            pCmpSz = sizeof(dh_ffdhe2048_p);
2960
0
            gCmp = dh_ffdhe2048_g;
2961
0
            gCmpSz = sizeof(dh_ffdhe2048_g);
2962
            #ifdef HAVE_FFDHE_Q
2963
            qCmp = dh_ffdhe2048_q;
2964
            qCmpSz = sizeof(dh_ffdhe2048_q);
2965
            #endif /* HAVE_FFDHE_Q */
2966
0
            break;
2967
0
        #endif /* HAVE_FFDHE_2048 */
2968
        #ifdef HAVE_FFDHE_3072
2969
        case WC_FFDHE_3072:
2970
            pCmp = dh_ffdhe3072_p;
2971
            pCmpSz = sizeof(dh_ffdhe3072_p);
2972
            gCmp = dh_ffdhe3072_g;
2973
            gCmpSz = sizeof(dh_ffdhe3072_g);
2974
            #ifdef HAVE_FFDHE_Q
2975
            qCmp = dh_ffdhe3072_q;
2976
            qCmpSz = sizeof(dh_ffdhe3072_q);
2977
            #endif /* HAVE_FFDHE_Q */
2978
            break;
2979
        #endif /* HAVE_FFDHE_3072 */
2980
        #ifdef HAVE_FFDHE_4096
2981
        case WC_FFDHE_4096:
2982
            pCmp = dh_ffdhe4096_p;
2983
            pCmpSz = sizeof(dh_ffdhe4096_p);
2984
            gCmp = dh_ffdhe4096_g;
2985
            gCmpSz = sizeof(dh_ffdhe4096_g);
2986
            #ifdef HAVE_FFDHE_Q
2987
            qCmp = dh_ffdhe4096_q;
2988
            qCmpSz = sizeof(dh_ffdhe4096_q);
2989
            #endif /* HAVE_FFDHE_Q */
2990
            break;
2991
        #endif /* HAVE_FFDHE_4096 */
2992
        #ifdef HAVE_FFDHE_6144
2993
        case WC_FFDHE_6144:
2994
            pCmp = dh_ffdhe6144_p;
2995
            pCmpSz = sizeof(dh_ffdhe6144_p);
2996
            gCmp = dh_ffdhe6144_g;
2997
            gCmpSz = sizeof(dh_ffdhe6144_g);
2998
            #ifdef HAVE_FFDHE_Q
2999
            qCmp = dh_ffdhe6144_q;
3000
            qCmpSz = sizeof(dh_ffdhe6144_q);
3001
            #endif /* HAVE_FFDHE_Q */
3002
            break;
3003
        #endif /* HAVE_FFDHE_6144 */
3004
        #ifdef HAVE_FFDHE_8192
3005
        case WC_FFDHE_8192:
3006
            pCmp = dh_ffdhe8192_p;
3007
            pCmpSz = sizeof(dh_ffdhe8192_p);
3008
            gCmp = dh_ffdhe8192_g;
3009
            gCmpSz = sizeof(dh_ffdhe8192_g);
3010
            #ifdef HAVE_FFDHE_Q
3011
            qCmp = dh_ffdhe8192_q;
3012
            qCmpSz = sizeof(dh_ffdhe8192_q);
3013
            #endif /* HAVE_FFDHE_Q */
3014
            break;
3015
        #endif /* HAVE_FFDHE_8192 */
3016
0
        default:
3017
0
            goodName = 0;
3018
0
    }
3019
3020
0
    if (goodName) {
3021
0
        cmp = (pSz == pCmpSz) && (gSz == gCmpSz) &&
3022
0
            (noQ || ((qCmp != NULL) && (qSz == qCmpSz) &&
3023
0
                     XMEMCMP(q, qCmp, qCmpSz) == 0)) &&
3024
0
            (XMEMCMP(p, pCmp, pCmpSz) == 0) &&
3025
0
            (XMEMCMP(g, gCmp, gCmpSz) == 0);
3026
0
    }
3027
3028
0
    return cmp;
3029
0
}
3030
3031
3032
int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q)
3033
0
{
3034
0
    word32 pSz = 0, gSz = 0, qSz = 0;
3035
3036
0
    switch (name) {
3037
0
        #ifdef HAVE_FFDHE_2048
3038
0
        case WC_FFDHE_2048:
3039
0
            pSz = sizeof(dh_ffdhe2048_p);
3040
0
            gSz = sizeof(dh_ffdhe2048_g);
3041
            #ifdef HAVE_FFDHE_Q
3042
            qSz = sizeof(dh_ffdhe2048_q);
3043
            #endif /* HAVE_FFDHE_Q */
3044
0
            break;
3045
0
        #endif /* HAVE_FFDHE_2048 */
3046
        #ifdef HAVE_FFDHE_3072
3047
        case WC_FFDHE_3072:
3048
            pSz = sizeof(dh_ffdhe3072_p);
3049
            gSz = sizeof(dh_ffdhe3072_g);
3050
            #ifdef HAVE_FFDHE_Q
3051
            qSz = sizeof(dh_ffdhe3072_q);
3052
            #endif /* HAVE_FFDHE_Q */
3053
            break;
3054
        #endif /* HAVE_FFDHE_3072 */
3055
        #ifdef HAVE_FFDHE_4096
3056
        case WC_FFDHE_4096:
3057
            pSz = sizeof(dh_ffdhe4096_p);
3058
            gSz = sizeof(dh_ffdhe4096_g);
3059
            #ifdef HAVE_FFDHE_Q
3060
            qSz = sizeof(dh_ffdhe4096_q);
3061
            #endif /* HAVE_FFDHE_Q */
3062
            break;
3063
        #endif /* HAVE_FFDHE_4096 */
3064
        #ifdef HAVE_FFDHE_6144
3065
        case WC_FFDHE_6144:
3066
            pSz = sizeof(dh_ffdhe6144_p);
3067
            gSz = sizeof(dh_ffdhe6144_g);
3068
            #ifdef HAVE_FFDHE_Q
3069
            qSz = sizeof(dh_ffdhe6144_q);
3070
            #endif /* HAVE_FFDHE_Q */
3071
            break;
3072
        #endif /* HAVE_FFDHE_6144 */
3073
        #ifdef HAVE_FFDHE_8192
3074
        case WC_FFDHE_8192:
3075
            pSz = sizeof(dh_ffdhe8192_p);
3076
            gSz = sizeof(dh_ffdhe8192_g);
3077
            #ifdef HAVE_FFDHE_Q
3078
            qSz = sizeof(dh_ffdhe8192_q);
3079
            #endif /* HAVE_FFDHE_Q */
3080
            break;
3081
        #endif /* HAVE_FFDHE_8192 */
3082
0
        default:
3083
0
            break;
3084
0
    }
3085
3086
0
    if (p != NULL) *p = pSz;
3087
0
    if (g != NULL) *g = gSz;
3088
0
    if (q != NULL) *q = qSz;
3089
3090
0
    return 0;
3091
0
}
3092
3093
3094
int wc_DhCopyNamedKey(int name,
3095
        byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz)
3096
0
{
3097
0
    const byte* pC = NULL;
3098
0
    const byte* gC = NULL;
3099
0
    const byte* qC = NULL;
3100
0
    word32 pCSz = 0, gCSz = 0, qCSz = 0;
3101
3102
0
    switch (name) {
3103
0
        #ifdef HAVE_FFDHE_2048
3104
0
        case WC_FFDHE_2048:
3105
0
            pC = dh_ffdhe2048_p;
3106
0
            pCSz = sizeof(dh_ffdhe2048_p);
3107
0
            gC = dh_ffdhe2048_g;
3108
0
            gCSz = sizeof(dh_ffdhe2048_g);
3109
            #ifdef HAVE_FFDHE_Q
3110
            qC = dh_ffdhe2048_q;
3111
            qCSz = sizeof(dh_ffdhe2048_q);
3112
            #endif /* HAVE_FFDHE_Q */
3113
0
            break;
3114
0
        #endif /* HAVE_FFDHE_2048 */
3115
        #ifdef HAVE_FFDHE_3072
3116
        case WC_FFDHE_3072:
3117
            pC = dh_ffdhe3072_p;
3118
            pCSz = sizeof(dh_ffdhe3072_p);
3119
            gC = dh_ffdhe3072_g;
3120
            gCSz = sizeof(dh_ffdhe3072_g);
3121
            #ifdef HAVE_FFDHE_Q
3122
            qC = dh_ffdhe3072_q;
3123
            qCSz = sizeof(dh_ffdhe3072_q);
3124
            #endif /* HAVE_FFDHE_Q */
3125
            break;
3126
        #endif /* HAVE_FFDHE_3072 */
3127
        #ifdef HAVE_FFDHE_4096
3128
        case WC_FFDHE_4096:
3129
            pC = dh_ffdhe4096_p;
3130
            pCSz = sizeof(dh_ffdhe4096_p);
3131
            gC = dh_ffdhe4096_g;
3132
            gCSz = sizeof(dh_ffdhe4096_g);
3133
            #ifdef HAVE_FFDHE_Q
3134
            qC = dh_ffdhe4096_q;
3135
            qCSz = sizeof(dh_ffdhe4096_q);
3136
            #endif /* HAVE_FFDHE_Q */
3137
            break;
3138
        #endif /* HAVE_FFDHE_4096 */
3139
        #ifdef HAVE_FFDHE_6144
3140
        case WC_FFDHE_6144:
3141
            pC = dh_ffdhe6144_p;
3142
            pCSz = sizeof(dh_ffdhe6144_p);
3143
            gC = dh_ffdhe6144_g;
3144
            gCSz = sizeof(dh_ffdhe6144_g);
3145
            #ifdef HAVE_FFDHE_Q
3146
            qC = dh_ffdhe6144_q;
3147
            qCSz = sizeof(dh_ffdhe6144_q);
3148
            #endif /* HAVE_FFDHE_Q */
3149
            break;
3150
        #endif /* HAVE_FFDHE_6144 */
3151
        #ifdef HAVE_FFDHE_8192
3152
        case WC_FFDHE_8192:
3153
            pC = dh_ffdhe8192_p;
3154
            pCSz = sizeof(dh_ffdhe8192_p);
3155
            gC = dh_ffdhe8192_g;
3156
            gCSz = sizeof(dh_ffdhe8192_g);
3157
            #ifdef HAVE_FFDHE_Q
3158
            qC = dh_ffdhe8192_q;
3159
            qCSz = sizeof(dh_ffdhe8192_q);
3160
            #endif /* HAVE_FFDHE_Q */
3161
            break;
3162
        #endif /* HAVE_FFDHE_8192 */
3163
0
        default:
3164
0
            break;
3165
0
    }
3166
3167
0
    if (p != NULL && pC != NULL)
3168
0
        XMEMCPY(p, pC, pCSz);
3169
0
    if (pSz != NULL)
3170
0
        *pSz = pCSz;
3171
0
    if (g != NULL && gC != NULL)
3172
0
        XMEMCPY(g, gC, gCSz);
3173
0
    if (gSz != NULL)
3174
0
        *gSz = gCSz;
3175
0
    if (q != NULL && qC != NULL)
3176
0
        XMEMCPY(q, qC, qCSz);
3177
0
    if (qSz != NULL)
3178
0
        *qSz = qCSz;
3179
3180
0
    return 0;
3181
0
}
3182
3183
3184
#ifdef WOLFSSL_KEY_GEN
3185
3186
/* modulus_size in bits */
3187
int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
3188
0
{
3189
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3190
0
    mp_int *tmp = NULL, *tmp2 = NULL;
3191
#else
3192
    mp_int tmp[1], tmp2[2];
3193
#endif
3194
0
    word32  groupSz = 0, bufSz = 0,
3195
0
            primeCheckCount = 0;
3196
0
    int     primeCheck = MP_NO,
3197
0
            ret = 0;
3198
#ifdef WOLFSSL_NO_MALLOC
3199
    unsigned char buf[DH_MAX_SIZE / WOLFSSL_BIT_SIZE];
3200
#else
3201
0
    unsigned char *buf = NULL;
3202
0
#endif
3203
3204
#if !defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_NO_MALLOC)
3205
    XMEMSET(tmp, 0, sizeof(tmp));
3206
    XMEMSET(tmp2, 0, sizeof(tmp2));
3207
#endif
3208
3209
0
    if (rng == NULL || dh == NULL)
3210
0
        ret = BAD_FUNC_ARG;
3211
3212
#ifdef WC_DH_INITIAL_RUNTIME_ENABLEMENT
3213
    if (! wc_dh_enabled)
3214
        return FIPS_NOT_ALLOWED_E;
3215
#endif
3216
3217
    /* set group size in bytes from modulus size
3218
     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
3219
     */
3220
0
    if (ret == 0) {
3221
0
        switch (modSz) {
3222
0
            case 1024:
3223
0
                groupSz = 20;
3224
0
                break;
3225
0
            case 2048:
3226
0
            case 3072:
3227
0
                groupSz = 32;
3228
0
                break;
3229
0
            default:
3230
        #if !defined(HAVE_FIPS) && defined(WOLFSSL_NO_DH186)
3231
                /* in non fips mode attempt to match strength of group size with
3232
                 * mod size */
3233
                if (modSz < 2048)
3234
                    groupSz = 20;
3235
                else
3236
                    groupSz = 32;
3237
        #else
3238
0
                ret = BAD_FUNC_ARG;
3239
0
        #endif
3240
0
                break;
3241
0
        }
3242
0
    }
3243
3244
0
    if (ret == 0) {
3245
        /* modulus size in bytes */
3246
0
        modSz /= WOLFSSL_BIT_SIZE;
3247
3248
0
        if ((word32)modSz < groupSz) {
3249
0
            WOLFSSL_MSG("DH modSz was too small");
3250
0
            ret = BAD_FUNC_ARG;
3251
0
        }
3252
0
    }
3253
3254
0
    if (ret == 0) {
3255
0
        bufSz = (word32)modSz - groupSz;
3256
3257
#ifdef WOLFSSL_NO_MALLOC
3258
        if (bufSz > sizeof(buf))
3259
            ret = MEMORY_E;
3260
#else
3261
        /* allocate ram */
3262
0
        buf = (unsigned char *)XMALLOC(bufSz,
3263
0
                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
3264
0
        if (buf == NULL)
3265
0
            ret = MEMORY_E;
3266
0
#endif
3267
0
    }
3268
3269
    /* make a random string that will be multiplied against q */
3270
0
    if (ret == 0)
3271
0
        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
3272
3273
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3274
0
    if (ret == 0) {
3275
0
        if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL,
3276
0
                DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) {
3277
0
            ret = MEMORY_E;
3278
0
        }
3279
0
        else {
3280
0
            XMEMSET(tmp, 0, sizeof(*tmp));
3281
0
        }
3282
0
    }
3283
0
    if (ret == 0) {
3284
0
        if ((tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL,
3285
0
                DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) {
3286
0
            ret = MEMORY_E;
3287
0
        }
3288
0
        else {
3289
0
            XMEMSET(tmp2, 0, sizeof(*tmp2));
3290
0
        }
3291
0
    }
3292
0
#endif
3293
3294
0
    if (ret == 0) {
3295
        /* force magnitude */
3296
0
        buf[0] |= 0xC0;
3297
        /* force even */
3298
0
        buf[bufSz - 1] &= 0xfe;
3299
3300
0
        if (mp_init_multi(tmp, tmp2, &dh->p, &dh->q, &dh->g, 0)
3301
0
                != MP_OKAY) {
3302
0
            ret = MP_INIT_E;
3303
0
        }
3304
0
    }
3305
3306
0
    if (ret == 0) {
3307
0
        if (mp_read_unsigned_bin(tmp2, buf, bufSz) != MP_OKAY)
3308
0
            ret = MP_READ_E;
3309
0
    }
3310
3311
    /* make our prime q */
3312
0
    if (ret == 0) {
3313
0
        if (mp_rand_prime(&dh->q, (int)groupSz, rng, NULL) != MP_OKAY)
3314
0
            ret = PRIME_GEN_E;
3315
0
    }
3316
3317
    /* p = random * q */
3318
0
    if (ret == 0) {
3319
0
        if (mp_mul(&dh->q, tmp2, &dh->p) != MP_OKAY)
3320
0
            ret = MP_MUL_E;
3321
0
    }
3322
3323
    /* p = random * q + 1, so q is a prime divisor of p-1 */
3324
0
    if (ret == 0) {
3325
0
        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
3326
0
            ret = MP_ADD_E;
3327
0
    }
3328
3329
    /* tmp = 2q  */
3330
0
    if (ret == 0) {
3331
0
        if (mp_add(&dh->q, &dh->q, tmp) != MP_OKAY)
3332
0
            ret = MP_ADD_E;
3333
0
    }
3334
3335
    /* loop until p is prime */
3336
0
    if (ret == 0) {
3337
0
        for (;;) {
3338
0
            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
3339
0
                ret = PRIME_GEN_E;
3340
3341
0
            if (primeCheck != MP_YES) {
3342
                /* p += 2q */
3343
0
                if (mp_add(tmp, &dh->p, &dh->p) != MP_OKAY)
3344
0
                    ret = MP_ADD_E;
3345
0
                else
3346
0
                    primeCheckCount++;
3347
0
            }
3348
3349
0
            if (ret != 0 || primeCheck == MP_YES)
3350
0
                break;
3351
3352
0
            ret = WC_CHECK_FOR_INTR_SIGNALS();
3353
0
            if (ret != 0)
3354
0
                break;
3355
0
            WC_RELAX_LONG_LOOP();
3356
0
        };
3357
0
    }
3358
3359
    /* tmp2 += (2*loop_check_prime)
3360
     * to have p = (q * tmp2) + 1 prime
3361
     */
3362
0
    if ((ret == 0) && (primeCheckCount)) {
3363
0
        if (mp_add_d(tmp2, 2 * primeCheckCount, tmp2) != MP_OKAY)
3364
0
            ret = MP_ADD_E;
3365
0
    }
3366
3367
    /* find a value g for which g^tmp2 != 1 */
3368
0
    if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))
3369
0
        ret = MP_ZERO_E;
3370
3371
0
    if (ret == 0) {
3372
0
        do {
3373
0
            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
3374
0
                ret = MP_ADD_E;
3375
0
            else if (mp_exptmod(&dh->g, tmp2, &dh->p, tmp) != MP_OKAY)
3376
0
                ret = MP_EXPTMOD_E;
3377
0
        } while (ret == 0 && mp_cmp_d(tmp, 1) == MP_EQ);
3378
0
    }
3379
3380
0
    if (ret == 0) {
3381
        /* at this point tmp generates a group of order q mod p */
3382
0
#ifndef USE_FAST_MATH
3383
        /* Exchanging is quick when the data pointer can be copied. */
3384
0
        mp_exch(tmp, &dh->g);
3385
#else
3386
        mp_copy(tmp, &dh->g);
3387
#endif
3388
0
    }
3389
3390
    /* clear the parameters if there was an error */
3391
0
    if ((ret != 0) && (dh != NULL)) {
3392
0
        mp_clear(&dh->q);
3393
0
        mp_clear(&dh->p);
3394
0
        mp_clear(&dh->g);
3395
0
    }
3396
3397
0
#ifndef WOLFSSL_NO_MALLOC
3398
0
    if (buf != NULL)
3399
0
#endif
3400
0
    {
3401
0
        ForceZero(buf, bufSz);
3402
0
#ifndef WOLFSSL_NO_MALLOC
3403
0
        if (dh != NULL) {
3404
0
            XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
3405
0
        }
3406
0
#endif
3407
0
    }
3408
3409
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3410
0
    if (tmp != NULL) {
3411
0
        mp_clear(tmp);
3412
0
        XFREE(tmp, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3413
0
    }
3414
0
    if (tmp2 != NULL) {
3415
0
        mp_clear(tmp2);
3416
0
        XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3417
0
    }
3418
#else
3419
    mp_clear(tmp);
3420
    mp_clear(tmp2);
3421
#endif
3422
3423
0
    return ret;
3424
0
}
3425
3426
#endif /* WOLFSSL_KEY_GEN */
3427
3428
/* Export raw DH parameters from DhKey structure
3429
 *
3430
 * dh   - pointer to initialized DhKey structure
3431
 * p    - output location for DH (p) parameter
3432
 * pSz  - [IN/OUT] size of output buffer for p, size of p
3433
 * q    - output location for DH (q) parameter
3434
 * qSz  - [IN/OUT] size of output buffer for q, size of q
3435
 * g    - output location for DH (g) parameter
3436
 * gSz  - [IN/OUT] size of output buffer for g, size of g
3437
 *
3438
 * If p, q, and g pointers are all passed in as NULL, the function
3439
 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
3440
 * q, and g. In this case, the function will return LENGTH_ONLY_E.
3441
 *
3442
 * returns 0 on success, negative upon failure
3443
 */
3444
int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
3445
                         byte* q, word32* qSz, byte* g, word32* gSz)
3446
0
{
3447
0
    int ret = 0;
3448
0
    word32 pLen = 0, qLen = 0, gLen = 0;
3449
3450
0
    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
3451
0
        ret = BAD_FUNC_ARG;
3452
3453
    /* get required output buffer sizes */
3454
0
    if (ret == 0) {
3455
0
        pLen = (word32)mp_unsigned_bin_size(&dh->p);
3456
0
        qLen = (word32)mp_unsigned_bin_size(&dh->q);
3457
0
        gLen = (word32)mp_unsigned_bin_size(&dh->g);
3458
3459
        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
3460
0
        if (p == NULL && q == NULL && g == NULL) {
3461
0
            *pSz = pLen;
3462
0
            *qSz = qLen;
3463
0
            *gSz = gLen;
3464
0
            ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
3465
0
        }
3466
0
    }
3467
3468
0
    if (ret == 0) {
3469
0
        if (p == NULL || q == NULL || g == NULL)
3470
0
            ret = BAD_FUNC_ARG;
3471
0
    }
3472
3473
    /* export p */
3474
0
    if (ret == 0) {
3475
0
        if (*pSz < pLen) {
3476
0
            WOLFSSL_MSG("Output buffer for DH p parameter too small, "
3477
0
                        "required size placed into pSz");
3478
0
            *pSz = pLen;
3479
0
            ret = BUFFER_E;
3480
0
        }
3481
0
    }
3482
3483
0
    if (ret == 0) {
3484
0
        *pSz = pLen;
3485
0
        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
3486
0
            ret = MP_TO_E;
3487
0
    }
3488
3489
    /* export q */
3490
0
    if (ret == 0) {
3491
0
        if (*qSz < qLen) {
3492
0
            WOLFSSL_MSG("Output buffer for DH q parameter too small, "
3493
0
                        "required size placed into qSz");
3494
0
            *qSz = qLen;
3495
0
            ret = BUFFER_E;
3496
0
        }
3497
0
    }
3498
3499
0
    if (ret == 0) {
3500
0
        *qSz = qLen;
3501
0
        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
3502
0
            ret = MP_TO_E;
3503
0
    }
3504
3505
    /* export g */
3506
0
    if (ret == 0) {
3507
0
        if (*gSz < gLen) {
3508
0
            WOLFSSL_MSG("Output buffer for DH g parameter too small, "
3509
0
                        "required size placed into gSz");
3510
0
            *gSz = gLen;
3511
0
            ret = BUFFER_E;
3512
0
        }
3513
0
    }
3514
3515
0
    if (ret == 0) {
3516
0
        *gSz = gLen;
3517
0
        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
3518
0
            ret = MP_TO_E;
3519
0
    }
3520
3521
0
    return ret;
3522
0
}
3523
3524
#endif /* NO_DH */