Coverage Report

Created: 2025-04-11 06:45

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