Coverage Report

Created: 2026-05-18 06:53

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