Coverage Report

Created: 2026-07-22 06:50

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