Coverage Report

Created: 2022-08-24 06:37

/src/wolfssl-normal-math/wolfcrypt/src/dh.c
Line
Count
Source (jump to first uncovered line)
1
/* dh.c
2
 *
3
 * Copyright (C) 2006-2022 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
119k
    #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
4.68k
{
155
4.68k
    static const DhParams ffdhe2048 = {
156
        #ifdef HAVE_FFDHE_Q
157
            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
158
        #endif /* HAVE_FFDHE_Q */
159
4.68k
        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
160
4.68k
        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
161
4.68k
    };
162
4.68k
    return &ffdhe2048;
163
4.68k
}
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
69.8k
{
937
69.8k
    int ret = 0;
938
939
69.8k
    if (key == NULL)
940
0
        return BAD_FUNC_ARG;
941
942
69.8k
    key->heap = heap; /* for XMALLOC/XFREE in future */
943
69.8k
    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
69.8k
    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
69.8k
    (void)devId;
958
69.8k
#endif
959
960
69.8k
    key->trustedGroup = 0;
961
962
#ifdef WOLFSSL_KCAPI_DH
963
    key->handle = NULL;
964
#endif
965
966
69.8k
    return ret;
967
69.8k
}
968
969
int wc_InitDhKey(DhKey* key)
970
65.2k
{
971
65.2k
    return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
972
65.2k
}
973
974
975
int wc_FreeDhKey(DhKey* key)
976
17.8k
{
977
17.8k
    if (key) {
978
15.4k
        mp_clear(&key->p);
979
15.4k
        mp_clear(&key->g);
980
15.4k
        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
15.4k
    }
993
17.8k
    return 0;
994
17.8k
}
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
59.6k
    {
1011
        /* assuming discrete log takes about the same time as factoring */
1012
59.6k
        if (n < 5)
1013
177
            return 0;
1014
59.5k
        else
1015
59.5k
            return (word32)(2.4 * XPOW((double)n, 1.0/3.0) *
1016
59.5k
                    XPOW(XLOG((double)n), 2.0/3.0) - 5);
1017
59.6k
    }
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
    #define WOLFSSL_DH_ROUND(x)
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(int modLen, int 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
    byte* cBuf;
1080
0
    int qSz, pSz, cSz, err;
1081
0
#ifdef WOLFSSL_SMALL_STACK
1082
0
    mp_int* tmpQ = NULL;
1083
0
    mp_int* tmpX = NULL;
1084
#else
1085
    mp_int tmpQ[1], tmpX[1];
1086
#endif
1087
1088
    /* Parameters validated in calling functions. */
1089
1090
0
    if (mp_iszero(&key->q) == MP_YES) {
1091
0
        WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
1092
0
        return BAD_FUNC_ARG;
1093
0
    }
1094
1095
0
    qSz = mp_unsigned_bin_size(&key->q);
1096
0
    pSz = mp_unsigned_bin_size(&key->p);
1097
1098
    /* verify (L,N) pair bit lengths */
1099
    /* Trusted primes don't need to be checked. */
1100
0
    if (!key->trustedGroup &&
1101
0
            CheckDhLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) {
1102
0
        WOLFSSL_MSG("DH param sizes do not match SP 800-56A requirements");
1103
0
        return BAD_FUNC_ARG;
1104
0
    }
1105
1106
    /* generate extra 64 bits so that bias from mod function is negligible */
1107
0
    cSz = *privSz + (64 / WOLFSSL_BIT_SIZE);
1108
0
    cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1109
0
    if (cBuf == NULL) {
1110
0
        return MEMORY_E;
1111
0
    }
1112
0
#ifdef WOLFSSL_SMALL_STACK
1113
0
    tmpQ = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1114
0
    if (tmpQ == NULL) {
1115
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1116
0
        return MEMORY_E;
1117
0
    }
1118
0
    tmpX = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1119
0
    if (tmpX == NULL) {
1120
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1121
0
        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1122
0
        return MEMORY_E;
1123
0
    }
1124
0
#endif
1125
1126
1127
0
    if ((err = mp_init_multi(tmpX, tmpQ, NULL, NULL, NULL, NULL))
1128
0
                   != MP_OKAY) {
1129
0
        XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1130
0
#ifdef WOLFSSL_SMALL_STACK
1131
0
        XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1132
0
        XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1133
0
#endif
1134
0
        return err;
1135
0
    }
1136
1137
#ifdef WOLFSSL_CHECK_MEM_ZERO
1138
    wc_MemZero_Add("GeneratePrivateDh186 cBuf", cBuf, cSz);
1139
    mp_memzero_add("GeneratePrivateDh186 tmpX", tmpX);
1140
#endif
1141
0
    do {
1142
        /* generate N+64 bits (c) from RBG into tmpX, making sure positive.
1143
         * Hash_DRBG uses SHA-256 which matches maximum
1144
         * requested_security_strength of (L,N) */
1145
0
        err = wc_RNG_GenerateBlock(rng, cBuf, cSz);
1146
0
        if (err == MP_OKAY)
1147
0
            err = mp_read_unsigned_bin(tmpX, cBuf, cSz);
1148
0
        if (err != MP_OKAY) {
1149
0
            mp_clear(tmpX);
1150
0
            mp_clear(tmpQ);
1151
0
            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1152
0
#ifdef WOLFSSL_SMALL_STACK
1153
0
            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1154
0
            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1155
0
#endif
1156
0
            return err;
1157
0
        }
1158
0
    } while (mp_cmp_d(tmpX, 1) != MP_GT);
1159
1160
0
    ForceZero(cBuf, cSz);
1161
0
    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1162
1163
    /* tmpQ: M = min(2^N,q) - 1 */
1164
0
    if (err == MP_OKAY)
1165
0
        err = mp_2expt(tmpQ, *privSz * 8);
1166
1167
0
    if (err == MP_OKAY) {
1168
0
        if (mp_cmp(tmpQ, &key->q) == MP_GT) {
1169
0
            err = mp_copy(&key->q, tmpQ);
1170
0
        }
1171
0
    }
1172
1173
0
    if (err == MP_OKAY)
1174
0
        err = mp_sub_d(tmpQ, 1, tmpQ);
1175
1176
    /* x = c mod (M), tmpX holds c */
1177
0
    if (err == MP_OKAY)
1178
0
        err = mp_mod(tmpX, tmpQ, tmpX);
1179
1180
    /* x = c mod (M) + 1 */
1181
0
    if (err == MP_OKAY)
1182
0
        err = mp_add_d(tmpX, 1, tmpX);
1183
1184
    /* copy tmpX into priv */
1185
0
    if (err == MP_OKAY) {
1186
0
        pSz = mp_unsigned_bin_size(tmpX);
1187
0
        if (pSz > (int)*privSz) {
1188
0
            WOLFSSL_MSG("DH private key output buffer too small");
1189
0
            err = BAD_FUNC_ARG;
1190
0
        } else {
1191
0
            *privSz = pSz;
1192
0
            err = mp_to_unsigned_bin(tmpX, priv);
1193
0
        }
1194
0
    }
1195
1196
0
    mp_forcezero(tmpX);
1197
0
    mp_clear(tmpQ);
1198
0
#ifdef WOLFSSL_SMALL_STACK
1199
0
    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1200
0
    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1201
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1202
    mp_memzero_check(tmpX);
1203
#endif
1204
1205
0
    return err;
1206
0
}
1207
#endif /* WOLFSSL_NO_DH186 */
1208
#endif /* !WC_NO_RNG */
1209
1210
static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
1211
                             word32* privSz)
1212
64.6k
{
1213
64.6k
#ifndef WC_NO_RNG
1214
64.6k
    int ret = 0;
1215
64.6k
    word32 sz = 0;
1216
1217
64.6k
    if (mp_iseven(&key->p) == MP_YES) {
1218
481
        ret = MP_VAL;
1219
481
    }
1220
64.2k
    else
1221
64.2k
#ifndef WOLFSSL_NO_DH186
1222
64.2k
    if (mp_iszero(&key->q) == MP_NO) {
1223
1224
        /* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair
1225
         * Generation Using Extra Random Bits" */
1226
0
        ret = GeneratePrivateDh186(key, rng, priv, privSz);
1227
1228
0
    }
1229
64.2k
    else
1230
64.2k
#endif
1231
64.2k
    {
1232
1233
64.2k
        sz = mp_unsigned_bin_size(&key->p);
1234
1235
        /* Table of predetermined values from the operation
1236
           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1237
           WOLFSSL_BIT_SIZE + 1
1238
           Sizes in table checked against RFC 3526
1239
         */
1240
64.2k
        WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
1241
64.2k
        switch (sz) {
1242
373
            case 128:  sz = 21; break;
1243
4.05k
            case 256:  sz = 29; break;
1244
50
            case 384:  sz = 34; break;
1245
37
            case 512:  sz = 39; break;
1246
0
            case 640:  sz = 42; break;
1247
0
            case 768:  sz = 46; break;
1248
0
            case 896:  sz = 49; break;
1249
0
            case 1024: sz = 52; break;
1250
59.6k
            default:
1251
59.6k
            #ifndef WOLFSSL_DH_CONST
1252
                /* if using floating points and size of p is not in table */
1253
59.6k
                sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1254
59.6k
                                           WOLFSSL_BIT_SIZE + 1);
1255
59.6k
                break;
1256
            #else
1257
                return BAD_FUNC_ARG;
1258
            #endif
1259
64.2k
        }
1260
1261
64.2k
        if (sz > *privSz)
1262
12
            ret = WC_KEY_SIZE_E;
1263
1264
64.2k
        if (ret == 0)
1265
64.2k
            ret = wc_RNG_GenerateBlock(rng, priv, sz);
1266
1267
64.2k
        if (ret == 0) {
1268
64.1k
            priv[0] |= 0x0C;
1269
64.1k
            *privSz = sz;
1270
64.1k
        }
1271
64.2k
    }
1272
1273
64.6k
    return ret;
1274
#else
1275
    (void)key;
1276
    (void)rng;
1277
    (void)priv;
1278
    (void)privSz;
1279
    return NOT_COMPILED_IN;
1280
#endif /* WC_NO_RNG */
1281
64.6k
}
1282
1283
1284
static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
1285
    byte* pub, word32* pubSz)
1286
3.80k
{
1287
3.80k
    int ret = 0;
1288
3.80k
#ifndef WOLFSSL_SP_MATH
1289
3.80k
    word32 binSz = 0;
1290
3.80k
#ifdef WOLFSSL_SMALL_STACK
1291
3.80k
    mp_int* x;
1292
3.80k
    mp_int* y;
1293
#else
1294
    mp_int x[1];
1295
    mp_int y[1];
1296
#endif
1297
3.80k
#endif
1298
1299
#ifdef WOLFSSL_HAVE_SP_DH
1300
#ifndef WOLFSSL_SP_NO_2048
1301
    if (mp_count_bits(&key->p) == 2048)
1302
        return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);
1303
#endif
1304
#ifndef WOLFSSL_SP_NO_3072
1305
    if (mp_count_bits(&key->p) == 3072)
1306
        return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);
1307
#endif
1308
#ifdef WOLFSSL_SP_4096
1309
    if (mp_count_bits(&key->p) == 4096)
1310
        return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);
1311
#endif
1312
#endif
1313
1314
3.80k
#if !defined(WOLFSSL_SP_MATH)
1315
3.80k
#ifdef WOLFSSL_SMALL_STACK
1316
3.80k
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1317
3.80k
    if (x == NULL)
1318
310
        return MEMORY_E;
1319
3.49k
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1320
3.49k
    if (y == NULL) {
1321
12
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1322
12
        return MEMORY_E;
1323
12
    }
1324
3.48k
#endif
1325
3.48k
    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
1326
0
    #ifdef WOLFSSL_SMALL_STACK
1327
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1328
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1329
0
    #endif
1330
0
        return MP_INIT_E;
1331
0
    }
1332
1333
3.48k
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
1334
0
        ret = MP_READ_E;
1335
1336
3.48k
    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
1337
175
        ret = MP_EXPTMOD_E;
1338
1339
3.48k
    if (ret == 0) {
1340
3.31k
        binSz = mp_unsigned_bin_size(y);
1341
3.31k
        if (binSz > *pubSz) {
1342
0
            ret = WC_KEY_SIZE_E;
1343
0
        }
1344
3.31k
    }
1345
1346
3.48k
    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
1347
0
        ret = MP_TO_E;
1348
1349
3.48k
    if (ret == 0)
1350
3.31k
        *pubSz = binSz;
1351
1352
3.48k
    mp_clear(y);
1353
3.48k
    mp_clear(x);
1354
3.48k
#ifdef WOLFSSL_SMALL_STACK
1355
3.48k
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1356
3.48k
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1357
3.48k
#endif
1358
#else
1359
    ret = WC_KEY_SIZE_E;
1360
#endif
1361
1362
3.48k
    return ret;
1363
3.48k
}
1364
1365
static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
1366
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1367
64.6k
{
1368
64.6k
    int ret;
1369
1370
64.6k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
1371
64.6k
        pub == NULL || pubSz == NULL) {
1372
0
        return BAD_FUNC_ARG;
1373
0
    }
1374
1375
64.6k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
1376
1377
64.6k
    ret = GeneratePrivateDh(key, rng, priv, privSz);
1378
1379
64.6k
    if (ret == 0)
1380
64.1k
        ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz);
1381
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1382
    if (ret == 0)
1383
        ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
1384
    if (ret == 0)
1385
        ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz);
1386
#endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
1387
1388
1389
64.6k
    RESTORE_VECTOR_REGISTERS();
1390
1391
64.6k
    return ret;
1392
64.6k
}
1393
#endif /* !WOLFSSL_KCAPI_DH */
1394
1395
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1396
static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
1397
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1398
{
1399
    int ret;
1400
1401
#if defined(HAVE_INTEL_QA)
1402
    word32 pBits;
1403
1404
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
1405
    pBits = mp_unsigned_bin_size(&key->p) * 8;
1406
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
1407
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
1408
        mp_int x;
1409
1410
        ret = mp_init(&x);
1411
        if (ret != MP_OKAY)
1412
            return ret;
1413
1414
        ret = GeneratePrivateDh(key, rng, priv, privSz);
1415
        if (ret == 0)
1416
            ret = mp_read_unsigned_bin(&x, priv, *privSz);
1417
        if (ret == MP_OKAY)
1418
            ret = wc_mp_to_bigint(&x, &x.raw);
1419
        if (ret == MP_OKAY)
1420
            ret = wc_mp_to_bigint(&key->p, &key->p.raw);
1421
        if (ret == MP_OKAY)
1422
            ret = wc_mp_to_bigint(&key->g, &key->g.raw);
1423
        if (ret == MP_OKAY)
1424
            ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
1425
                &x.raw, pub, pubSz);
1426
        mp_clear(&x);
1427
1428
        return ret;
1429
    }
1430
1431
#elif defined(HAVE_CAVIUM)
1432
    /* TODO: Not implemented - use software for now */
1433
1434
#else /* WOLFSSL_ASYNC_CRYPT_TEST */
1435
    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_GEN)) {
1436
        WC_ASYNC_TEST* testDev = &key->asyncDev.test;
1437
        testDev->dhGen.key = key;
1438
        testDev->dhGen.rng = rng;
1439
        testDev->dhGen.priv = priv;
1440
        testDev->dhGen.privSz = privSz;
1441
        testDev->dhGen.pub = pub;
1442
        testDev->dhGen.pubSz = pubSz;
1443
        return WC_PENDING_E;
1444
    }
1445
#endif
1446
1447
    /* otherwise use software DH */
1448
    ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
1449
1450
    return ret;
1451
}
1452
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
1453
1454
1455
/* Check DH Public Key for invalid numbers, optionally allowing
1456
 * the public key to be checked against the large prime (q).
1457
 * If q is NULL, the q value of key is used.
1458
 * Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2.
1459
 *
1460
 * key     DH key group parameters.
1461
 * pub     Public Key.
1462
 * pubSz   Public Key size.
1463
 * prime   Large prime (q), optionally NULL to skip check
1464
 * primeSz Size of large prime
1465
 * partial Do the partial test process. (section 5.6.2.3.2)
1466
 *
1467
 *  returns 0 on success or error code
1468
 */
1469
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
1470
       const byte* prime, word32 primeSz, int partial)
1471
{
1472
    int ret = 0;
1473
#ifdef WOLFSSL_SMALL_STACK
1474
    mp_int* y = NULL;
1475
    mp_int* p = NULL;
1476
    mp_int* q = NULL;
1477
#else
1478
    mp_int y[1];
1479
    mp_int p[1];
1480
    mp_int q[1];
1481
#endif
1482
1483
    if (key == NULL || pub == NULL) {
1484
        return BAD_FUNC_ARG;
1485
    }
1486
1487
#ifdef WOLFSSL_SMALL_STACK
1488
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1489
    if (y == NULL)
1490
        return MEMORY_E;
1491
    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1492
    if (p == NULL) {
1493
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1494
        return MEMORY_E;
1495
    }
1496
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1497
    if (q == NULL) {
1498
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1499
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1500
        return MEMORY_E;
1501
    }
1502
#endif
1503
1504
    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
1505
    #ifdef WOLFSSL_SMALL_STACK
1506
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1507
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1508
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1509
    #endif
1510
        return MP_INIT_E;
1511
    }
1512
1513
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
1514
1515
    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
1516
        ret = MP_READ_E;
1517
    }
1518
1519
    if (ret == 0 && prime != NULL) {
1520
        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1521
            ret = MP_READ_E;
1522
1523
    } else if (mp_iszero(&key->q) == MP_NO) {
1524
        /* use q available in DhKey */
1525
        if (mp_copy(&key->q, q) != MP_OKAY)
1526
            ret = MP_INIT_E;
1527
    }
1528
1529
    /* SP 800-56Ar3, section 5.6.2.3.2 */
1530
    /* pub (y) should not be 0 or 1 */
1531
    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
1532
        ret = MP_CMP_E;
1533
    }
1534
1535
    /* pub (y) shouldn't be greater than or equal to p - 1 */
1536
    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
1537
        ret = MP_INIT_E;
1538
    }
1539
    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
1540
        ret = MP_SUB_E;
1541
    }
1542
    if (ret == 0 && mp_cmp(y, p) == MP_GT) {
1543
        ret = MP_CMP_E;
1544
    }
1545
1546
    if (!partial) {
1547
        if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
1548
1549
            /* restore key->p into p */
1550
            if (mp_copy(&key->p, p) != MP_OKAY)
1551
                ret = MP_INIT_E;
1552
        }
1553
1554
        /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
1555
        if (ret == 0 && prime != NULL) {
1556
#ifdef WOLFSSL_HAVE_SP_DH
1557
#ifndef WOLFSSL_SP_NO_2048
1558
            if (mp_count_bits(&key->p) == 2048) {
1559
                ret = sp_ModExp_2048(y, q, p, y);
1560
                if (ret != 0)
1561
                    ret = MP_EXPTMOD_E;
1562
            }
1563
            else
1564
#endif
1565
#ifndef WOLFSSL_SP_NO_3072
1566
            if (mp_count_bits(&key->p) == 3072) {
1567
                ret = sp_ModExp_3072(y, q, p, y);
1568
                if (ret != 0)
1569
                    ret = MP_EXPTMOD_E;
1570
            }
1571
            else
1572
#endif
1573
#ifdef WOLFSSL_SP_4096
1574
            if (mp_count_bits(&key->p) == 4096) {
1575
                ret = sp_ModExp_4096(y, q, p, y);
1576
                if (ret != 0)
1577
                    ret = MP_EXPTMOD_E;
1578
            }
1579
            else
1580
#endif
1581
#endif
1582
1583
            {
1584
#if !defined(WOLFSSL_SP_MATH)
1585
                /* calculate (y^q) mod(p), store back into y */
1586
                if (mp_exptmod(y, q, p, y) != MP_OKAY)
1587
                    ret = MP_EXPTMOD_E;
1588
#else
1589
                ret = WC_KEY_SIZE_E;
1590
#endif
1591
            }
1592
1593
            /* verify above == 1 */
1594
            if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
1595
                ret = MP_CMP_E;
1596
        }
1597
    }
1598
1599
    mp_clear(y);
1600
    mp_clear(p);
1601
    mp_clear(q);
1602
1603
    RESTORE_VECTOR_REGISTERS();
1604
1605
#ifdef WOLFSSL_SMALL_STACK
1606
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1607
    XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1608
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1609
#endif
1610
1611
    return ret;
1612
}
1613
1614
1615
/* Performs a full public-key validation routine. */
1616
int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
1617
                        const byte* prime, word32 primeSz)
1618
0
{
1619
0
    return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0);
1620
0
}
1621
1622
1623
/* Check DH Public Key for invalid numbers. Performs a partial public-key
1624
 * validation routine.
1625
 *
1626
 * key   DH key group parameters.
1627
 * pub   Public Key.
1628
 * pubSz Public Key size.
1629
 *
1630
 *  returns 0 on success or error code
1631
 */
1632
int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
1633
187
{
1634
187
    return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1);
1635
187
}
1636
1637
1638
/**
1639
 * Quick validity check of public key value against prime.
1640
 * Checks are:
1641
 *   - Public key not 0 or 1
1642
 *   - Public key not equal to prime or prime - 1
1643
 *   - Public key not bigger than prime.
1644
 *
1645
 * prime    Big-endian encoding of prime in bytes.
1646
 * primeSz  Size of prime in bytes.
1647
 * pub      Big-endian encoding of public key in bytes.
1648
 * pubSz    Size of public key in bytes.
1649
 */
1650
int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,
1651
                       word32 pubSz)
1652
858
{
1653
858
    int ret = 0;
1654
858
    word32 i;
1655
1656
1.64k
    for (i = 0; i < pubSz && pub[i] == 0; i++) {
1657
784
    }
1658
858
    pubSz -= i;
1659
858
    pub += i;
1660
1661
858
    if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))
1662
608
        ret = MP_VAL;
1663
250
    else if (pubSz == primeSz) {
1664
269
        for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {
1665
256
        }
1666
13
        if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))
1667
0
            ret = MP_VAL;
1668
13
        else if (pub[i] > prime[i])
1669
5
            ret = MP_VAL;
1670
13
    }
1671
237
    else if (pubSz > primeSz)
1672
13
        ret = MP_VAL;
1673
1674
858
    return ret;
1675
858
}
1676
1677
1678
/* Check DH Private Key for invalid numbers, optionally allowing
1679
 * the private key to be checked against the large prime (q).
1680
 * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
1681
 *
1682
 * key     DH key group parameters.
1683
 * priv    Private Key.
1684
 * privSz  Private Key size.
1685
 * prime   Large prime (q), optionally NULL to skip check
1686
 * primeSz Size of large prime
1687
 *
1688
 *  returns 0 on success or error code
1689
 */
1690
int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
1691
                         const byte* prime, word32 primeSz)
1692
0
{
1693
0
    int ret = 0;
1694
0
#ifdef WOLFSSL_SMALL_STACK
1695
0
    mp_int* x = NULL;
1696
0
    mp_int* q = NULL;
1697
#else
1698
    mp_int x[1];
1699
    mp_int q[1];
1700
#endif
1701
1702
0
    if (key == NULL || priv == NULL) {
1703
0
        return BAD_FUNC_ARG;
1704
0
    }
1705
1706
0
#ifdef WOLFSSL_SMALL_STACK
1707
0
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1708
0
    if (x == NULL)
1709
0
        return MEMORY_E;
1710
0
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1711
0
    if (q == NULL) {
1712
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1713
0
        return MEMORY_E;
1714
0
    }
1715
0
#endif
1716
1717
0
    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
1718
0
    #ifdef WOLFSSL_SMALL_STACK
1719
0
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1720
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1721
0
    #endif
1722
0
        return MP_INIT_E;
1723
0
    }
1724
1725
0
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
1726
0
        ret = MP_READ_E;
1727
0
    }
1728
1729
0
    if (ret == 0) {
1730
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1731
        mp_memzero_add("wc_DhCheckPrivKey_ex x", x);
1732
    #endif
1733
0
        if (prime != NULL) {
1734
0
            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1735
0
                ret = MP_READ_E;
1736
0
        }
1737
0
        else if (mp_iszero(&key->q) == MP_NO) {
1738
            /* use q available in DhKey */
1739
0
            if (mp_copy(&key->q, q) != MP_OKAY)
1740
0
                ret = MP_INIT_E;
1741
0
        }
1742
0
    }
1743
1744
    /* priv (x) should not be 0 */
1745
0
    if (ret == 0) {
1746
0
        if (mp_cmp_d(x, 0) == MP_EQ)
1747
0
            ret = MP_CMP_E;
1748
0
    }
1749
1750
0
    if (ret == 0) {
1751
0
        if (mp_iszero(q) == MP_NO) {
1752
            /* priv (x) shouldn't be greater than q - 1 */
1753
0
            if (mp_copy(&key->q, q) != MP_OKAY)
1754
0
                ret = MP_INIT_E;
1755
0
            if (ret == 0) {
1756
0
                if (mp_sub_d(q, 1, q) != MP_OKAY)
1757
0
                    ret = MP_SUB_E;
1758
0
            }
1759
0
            if (ret == 0) {
1760
0
                if (mp_cmp(x, q) == MP_GT)
1761
0
                    ret = DH_CHECK_PRIV_E;
1762
0
            }
1763
0
        }
1764
0
    }
1765
1766
0
    mp_forcezero(x);
1767
0
    mp_clear(q);
1768
0
#ifdef WOLFSSL_SMALL_STACK
1769
0
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1770
0
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1771
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1772
    mp_memzero_check(x);
1773
#endif
1774
1775
0
    return ret;
1776
0
}
1777
1778
1779
/* Check DH Private Key for invalid numbers
1780
 *
1781
 * key    DH key group parameters.
1782
 * priv   Private Key.
1783
 * privSz Private Key size.
1784
 *
1785
 *  returns 0 on success or error code
1786
 */
1787
int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
1788
0
{
1789
0
    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
1790
0
}
1791
1792
1793
/* Performs a Pairwise Consistency Test on an FFC key pair. */
1794
/* Check DH Keys for pair-wise consistency per process in
1795
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. */
1796
static int _ffc_pairwise_consistency_test(DhKey* key,
1797
        const byte* pub, word32 pubSz, const byte* priv, word32 privSz)
1798
0
{
1799
0
#ifdef WOLFSSL_SMALL_STACK
1800
0
    mp_int* publicKey = NULL;
1801
0
    mp_int* privateKey = NULL;
1802
0
    mp_int* checkKey = NULL;
1803
#else
1804
    mp_int publicKey[1];
1805
    mp_int privateKey[1];
1806
    mp_int checkKey[1];
1807
#endif
1808
0
    int ret = 0;
1809
1810
0
    if (key == NULL || pub == NULL || priv == NULL)
1811
0
        return BAD_FUNC_ARG;
1812
0
    if (mp_iseven(&key->p) == MP_YES)
1813
0
        return MP_VAL;
1814
1815
0
#ifdef WOLFSSL_SMALL_STACK
1816
0
    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1817
0
    if (publicKey == NULL)
1818
0
        return MEMORY_E;
1819
0
    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1820
0
    if (privateKey == NULL) {
1821
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1822
0
        return MEMORY_E;
1823
0
    }
1824
0
    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1825
0
    if (checkKey == NULL) {
1826
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1827
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1828
0
        return MEMORY_E;
1829
0
    }
1830
0
#endif
1831
1832
0
    if (mp_init_multi(publicKey, privateKey, checkKey,
1833
0
                      NULL, NULL, NULL) != MP_OKAY) {
1834
1835
0
    #ifdef WOLFSSL_SMALL_STACK
1836
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1837
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1838
0
        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
1839
0
    #endif
1840
0
        return MP_INIT_E;
1841
0
    }
1842
1843
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
1844
1845
    /* Load the private and public keys into big integers. */
1846
0
    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
1847
0
        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
1848
1849
0
        ret = MP_READ_E;
1850
0
    }
1851
#ifdef WOLFSSL_CHECK_MEM_ZERO
1852
    mp_memzero_add("_ffc_pairwise_consistency_test privateKey", privateKey);
1853
#endif
1854
1855
    /* Calculate checkKey = g^privateKey mod p */
1856
0
    if (ret == 0) {
1857
#ifdef WOLFSSL_HAVE_SP_DH
1858
#ifndef WOLFSSL_SP_NO_2048
1859
        if (mp_count_bits(&key->p) == 2048) {
1860
            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
1861
            if (ret != 0)
1862
                ret = MP_EXPTMOD_E;
1863
        }
1864
        else
1865
#endif
1866
#ifndef WOLFSSL_SP_NO_3072
1867
        if (mp_count_bits(&key->p) == 3072) {
1868
            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
1869
            if (ret != 0)
1870
                ret = MP_EXPTMOD_E;
1871
        }
1872
        else
1873
#endif
1874
#ifdef WOLFSSL_SP_4096
1875
        if (mp_count_bits(&key->p) == 4096) {
1876
            ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
1877
            if (ret != 0)
1878
                ret = MP_EXPTMOD_E;
1879
        }
1880
        else
1881
#endif
1882
#endif
1883
0
        {
1884
0
#if !defined(WOLFSSL_SP_MATH)
1885
0
            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
1886
0
                ret = MP_EXPTMOD_E;
1887
#else
1888
            ret = WC_KEY_SIZE_E;
1889
#endif
1890
0
        }
1891
0
    }
1892
1893
    /* Compare the calculated public key to the supplied check value. */
1894
0
    if (ret == 0) {
1895
0
        if (mp_cmp(checkKey, publicKey) != MP_EQ)
1896
0
            ret = MP_CMP_E;
1897
0
    }
1898
1899
0
    mp_forcezero(privateKey);
1900
0
    mp_clear(publicKey);
1901
0
    mp_clear(checkKey);
1902
1903
0
    RESTORE_VECTOR_REGISTERS();
1904
1905
0
#ifdef WOLFSSL_SMALL_STACK
1906
0
    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
1907
0
    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1908
0
    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1909
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1910
    mp_memzero_check(privateKey);
1911
#endif
1912
1913
0
    return ret;
1914
0
}
1915
1916
1917
/* Check DH Keys for pair-wise consistency per process in
1918
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
1919
 *
1920
 * key    DH key group parameters.
1921
 * pub    Public Key.
1922
 * pubSz  Public Key size.
1923
 * priv   Private Key.
1924
 * privSz Private Key size.
1925
 *
1926
 *  returns 0 on success or error code
1927
 */
1928
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
1929
                      const byte* priv, word32 privSz)
1930
0
{
1931
0
    return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz);
1932
0
}
1933
1934
1935
int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
1936
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1937
64.6k
{
1938
64.6k
    int ret;
1939
1940
64.6k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
1941
64.6k
                                                pub == NULL || pubSz == NULL) {
1942
0
        return BAD_FUNC_ARG;
1943
0
    }
1944
1945
#ifdef WOLFSSL_KCAPI_DH
1946
    (void)priv;
1947
    (void)privSz;
1948
    ret = KcapiDh_MakeKey(key, pub, pubSz);
1949
#else
1950
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1951
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
1952
        ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
1953
    }
1954
    else
1955
#endif
1956
64.6k
    {
1957
64.6k
        ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
1958
64.6k
    }
1959
64.6k
#endif /* WOLFSSL_KCAPI_DH */
1960
1961
64.6k
    return ret;
1962
64.6k
}
1963
1964
#ifndef WOLFSSL_KCAPI_DH
1965
static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
1966
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
1967
1.05k
{
1968
1.05k
    int ret = 0;
1969
1.05k
#ifdef WOLFSSL_SMALL_STACK
1970
1.05k
    mp_int* y = NULL;
1971
1.05k
#if !defined(WOLFSSL_SP_MATH)
1972
1.05k
    mp_int* x = NULL;
1973
1.05k
    mp_int* z = NULL;
1974
1.05k
#endif
1975
#else
1976
    mp_int y[1];
1977
#if !defined(WOLFSSL_SP_MATH)
1978
    mp_int x[1];
1979
    mp_int z[1];
1980
#endif
1981
#endif
1982
1983
1.05k
    if (mp_iseven(&key->p) == MP_YES) {
1984
77
        return MP_VAL;
1985
77
    }
1986
#ifdef WOLFSSL_VALIDATE_FFC_IMPORT
1987
    if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
1988
        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
1989
        return DH_CHECK_PRIV_E;
1990
    }
1991
1992
    if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
1993
        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
1994
        return DH_CHECK_PUB_E;
1995
    }
1996
#endif
1997
1998
979
#ifdef WOLFSSL_SMALL_STACK
1999
979
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2000
979
    if (y == NULL)
2001
276
        return MEMORY_E;
2002
703
#if !defined(WOLFSSL_SP_MATH)
2003
703
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2004
703
    if (x == NULL) {
2005
12
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2006
12
        return MEMORY_E;
2007
12
    }
2008
691
    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2009
691
    if (z == NULL) {
2010
12
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2011
12
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2012
12
        return MEMORY_E;
2013
12
    }
2014
679
#endif
2015
679
#endif
2016
2017
#ifdef WOLFSSL_HAVE_SP_DH
2018
#ifndef WOLFSSL_SP_NO_2048
2019
    if (mp_count_bits(&key->p) == 2048) {
2020
        if (mp_init(y) != MP_OKAY)
2021
            return MP_INIT_E;
2022
2023
        SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2024
2025
        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2026
            ret = MP_READ_E;
2027
2028
        if (ret == 0)
2029
            ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz);
2030
2031
        mp_clear(y);
2032
2033
        RESTORE_VECTOR_REGISTERS();
2034
2035
    #ifdef WOLFSSL_SMALL_STACK
2036
    #if !defined(WOLFSSL_SP_MATH)
2037
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2038
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2039
    #endif
2040
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2041
    #endif
2042
        return ret;
2043
    }
2044
#endif
2045
#ifndef WOLFSSL_SP_NO_3072
2046
    if (mp_count_bits(&key->p) == 3072) {
2047
        if (mp_init(y) != MP_OKAY)
2048
            return MP_INIT_E;
2049
2050
        SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2051
2052
        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2053
            ret = MP_READ_E;
2054
2055
        if (ret == 0)
2056
            ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz);
2057
2058
        mp_clear(y);
2059
2060
        RESTORE_VECTOR_REGISTERS();
2061
2062
    #ifdef WOLFSSL_SMALL_STACK
2063
    #if !defined(WOLFSSL_SP_MATH)
2064
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2065
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2066
    #endif
2067
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2068
    #endif
2069
        return ret;
2070
    }
2071
#endif
2072
#ifdef WOLFSSL_SP_4096
2073
    if (mp_count_bits(&key->p) == 4096) {
2074
        if (mp_init(y) != MP_OKAY)
2075
            return MP_INIT_E;
2076
2077
        SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2078
2079
        if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2080
            ret = MP_READ_E;
2081
2082
        if (ret == 0)
2083
            ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz);
2084
2085
        mp_clear(y);
2086
2087
        RESTORE_VECTOR_REGISTERS();
2088
2089
    #ifdef WOLFSSL_SMALL_STACK
2090
    #if !defined(WOLFSSL_SP_MATH)
2091
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2092
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2093
    #endif
2094
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2095
    #endif
2096
        return ret;
2097
    }
2098
#endif
2099
#endif
2100
2101
679
#if !defined(WOLFSSL_SP_MATH)
2102
679
    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
2103
0
    #ifdef WOLFSSL_SMALL_STACK
2104
0
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2105
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2106
0
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2107
0
    #endif
2108
0
        return MP_INIT_E;
2109
0
    }
2110
2111
679
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2112
2113
679
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
2114
19
        ret = MP_READ_E;
2115
#ifdef WOLFSSL_CHECK_MEM_ZERO
2116
    if (ret == 0)
2117
        mp_memzero_add("wc_DhAgree_Sync x", x);
2118
#endif
2119
2120
679
    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2121
14
        ret = MP_READ_E;
2122
2123
679
    if (ret == 0 && mp_exptmod(y, x, &key->p, z) != MP_OKAY)
2124
15
        ret = MP_EXPTMOD_E;
2125
#ifdef WOLFSSL_CHECK_MEM_ZERO
2126
    if (ret == 0)
2127
        mp_memzero_add("wc_DhAgree_Sync z", z);
2128
#endif
2129
2130
    /* make sure z is not one (SP800-56A, 5.7.1.1) */
2131
679
    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
2132
88
        ret = MP_VAL;
2133
2134
679
    if (ret == 0 && mp_to_unsigned_bin(z, agree) != MP_OKAY)
2135
0
        ret = MP_TO_E;
2136
2137
679
    if (ret == 0)
2138
543
        *agreeSz = mp_unsigned_bin_size(z);
2139
2140
679
    mp_forcezero(z);
2141
679
    mp_clear(y);
2142
679
    mp_forcezero(x);
2143
2144
679
    RESTORE_VECTOR_REGISTERS();
2145
2146
#else
2147
    ret = WC_KEY_SIZE_E;
2148
#endif
2149
2150
679
#ifdef WOLFSSL_SMALL_STACK
2151
679
#if !defined(WOLFSSL_SP_MATH)
2152
679
    XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2153
679
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2154
679
#endif
2155
679
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2156
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
2157
    mp_memzero_check(x);
2158
    mp_memzero_check(z);
2159
#endif
2160
2161
679
    return ret;
2162
679
}
2163
2164
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2165
static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
2166
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
2167
{
2168
    int ret;
2169
2170
#if defined(HAVE_INTEL_QA)
2171
    word32 pBits;
2172
2173
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
2174
    pBits = mp_unsigned_bin_size(&key->p) * 8;
2175
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
2176
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
2177
        ret = wc_mp_to_bigint(&key->p, &key->p.raw);
2178
        if (ret == MP_OKAY)
2179
            ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
2180
                agree, agreeSz, priv, privSz, otherPub, pubSz);
2181
        return ret;
2182
    }
2183
2184
#elif defined(HAVE_CAVIUM)
2185
    /* TODO: Not implemented - use software for now */
2186
2187
#else /* WOLFSSL_ASYNC_CRYPT_TEST */
2188
    if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_DH_AGREE)) {
2189
        WC_ASYNC_TEST* testDev = &key->asyncDev.test;
2190
        testDev->dhAgree.key = key;
2191
        testDev->dhAgree.agree = agree;
2192
        testDev->dhAgree.agreeSz = agreeSz;
2193
        testDev->dhAgree.priv = priv;
2194
        testDev->dhAgree.privSz = privSz;
2195
        testDev->dhAgree.otherPub = otherPub;
2196
        testDev->dhAgree.pubSz = pubSz;
2197
        return WC_PENDING_E;
2198
    }
2199
#endif
2200
2201
    /* otherwise use software DH */
2202
    ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
2203
2204
    return ret;
2205
}
2206
#endif /* WOLFSSL_ASYNC_CRYPT */
2207
#endif /* !WOLFSSL_KCAPI_DH */
2208
2209
int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
2210
            word32 privSz, const byte* otherPub, word32 pubSz)
2211
3.33k
{
2212
3.33k
    int ret = 0;
2213
2214
3.33k
    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
2215
3.33k
                                                            otherPub == NULL) {
2216
26
        return BAD_FUNC_ARG;
2217
26
    }
2218
2219
#ifdef WOLFSSL_KCAPI_DH
2220
    (void)priv;
2221
    (void)privSz;
2222
    ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
2223
#else
2224
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2225
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
2226
        ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
2227
    }
2228
    else
2229
#endif
2230
3.31k
    {
2231
3.31k
        ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz);
2232
3.31k
    }
2233
3.31k
#endif /* WOLFSSL_KCAPI_DH */
2234
2235
3.31k
    return ret;
2236
3.33k
}
2237
2238
#ifdef WOLFSSL_DH_EXTRA
2239
WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst)
2240
{
2241
    int ret;
2242
2243
    if (!src || !dst || src == dst) {
2244
        WOLFSSL_MSG("Parameters not provided or are the same");
2245
        return BAD_FUNC_ARG;
2246
    }
2247
2248
    if ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) {
2249
        WOLFSSL_MSG("mp_copy error");
2250
        return ret;
2251
    }
2252
2253
    if ((ret = mp_copy(&src->g, &dst->g)) != MP_OKAY) {
2254
        WOLFSSL_MSG("mp_copy error");
2255
        return ret;
2256
    }
2257
2258
    if ((ret = mp_copy(&src->q, &dst->q)) != MP_OKAY) {
2259
        WOLFSSL_MSG("mp_copy error");
2260
        return ret;
2261
    }
2262
2263
    if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) {
2264
        WOLFSSL_MSG("mp_copy error");
2265
        return ret;
2266
    }
2267
2268
    if ((ret = mp_copy(&src->priv, &dst->priv)) != MP_OKAY) {
2269
        WOLFSSL_MSG("mp_copy error");
2270
        return ret;
2271
    }
2272
#ifdef WOLFSSL_CHECK_MEM_ZERO
2273
    mp_memzero_add("wc_DhKeyCopy dst->priv", &dst->priv);
2274
#endif
2275
2276
    dst->heap = src->heap;
2277
2278
    return MP_OKAY;
2279
}
2280
2281
/* Sets private and public key in DhKey if both are available, otherwise sets
2282
    either private or public key, depending on which is available. */
2283
int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,
2284
                       const byte* pub, word32 pubSz)
2285
{
2286
    byte havePriv, havePub;
2287
2288
    if (key == NULL) {
2289
        return BAD_FUNC_ARG;
2290
    }
2291
2292
    havePriv = ( (priv != NULL) && (privSz > 0) );
2293
    havePub  = ( (pub  != NULL) && (pubSz  > 0) );
2294
2295
    if (!havePub && !havePriv) {
2296
        WOLFSSL_MSG("No Public or Private Key to Set");
2297
        return BAD_FUNC_ARG;
2298
    }
2299
2300
    /* Set Private Key */
2301
    if (havePriv) {
2302
        /* may have leading 0 */
2303
        if (priv[0] == 0) {
2304
            privSz--; priv++;
2305
        }
2306
        if (mp_init(&key->priv) != MP_OKAY)
2307
            havePriv = 0;
2308
    }
2309
    if (havePriv) {
2310
        if (mp_read_unsigned_bin(&key->priv, priv, privSz) != MP_OKAY) {
2311
            mp_clear(&key->priv);
2312
            havePriv = 0;
2313
        } else {
2314
            WOLFSSL_MSG("DH Private Key Set");
2315
        #ifdef WOLFSSL_CHECK_MEM_ZERO
2316
            mp_memzero_add("wc_DhImportKeyPair key->priv", &key->priv);
2317
        #endif
2318
        }
2319
    }
2320
2321
    /* Set Public Key */
2322
    if (havePub) {
2323
        /* may have leading 0 */
2324
        if (pub[0] == 0) {
2325
            pubSz--; pub++;
2326
        }
2327
        if (mp_init(&key->pub) != MP_OKAY)
2328
            havePub = 0;
2329
    }
2330
    if (havePub) {
2331
        if (mp_read_unsigned_bin(&key->pub, pub, pubSz) != MP_OKAY) {
2332
            mp_clear(&key->pub);
2333
            havePub = 0;
2334
            if (havePriv) {
2335
                mp_forcezero(&key->priv);
2336
                havePriv = 0; /* set to 0 to error out with failed read pub */
2337
            }
2338
        } else {
2339
            WOLFSSL_MSG("DH Public Key Set");
2340
        }
2341
    }
2342
2343
    if (havePriv == 0 && havePub == 0) {
2344
        return MEMORY_E;
2345
    }
2346
2347
    return 0;
2348
}
2349
2350
/* Can be used with WOLFSSL_DH_EXTRA when key is loaded with
2351
    wc_DhKeyDecode or wc_DhImportKeyPair */
2352
int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz,
2353
    byte* pub, word32* pPubSz)
2354
{
2355
    int ret = 0;
2356
    word32 pubSz, privSz;
2357
2358
    if (key == NULL || (priv && pPrivSz == NULL) || (pub && pPubSz == NULL)) {
2359
        return BAD_FUNC_ARG;
2360
    }
2361
2362
    if (priv) {
2363
        privSz = mp_unsigned_bin_size(&key->priv);
2364
        if (privSz > *pPrivSz) {
2365
            return BUFFER_E;
2366
        }
2367
        *pPrivSz = privSz;
2368
        ret |= mp_to_unsigned_bin(&key->priv, priv);
2369
    }
2370
2371
    if (pub) {
2372
        pubSz = mp_unsigned_bin_size(&key->pub);
2373
        if (pubSz > *pPubSz) {
2374
            return BUFFER_E;
2375
        }
2376
        *pPubSz = pubSz;
2377
        ret |= mp_to_unsigned_bin(&key->pub,  pub);
2378
    }
2379
2380
    if (ret != 0)
2381
        ret = ASN_DH_KEY_E;
2382
    return ret;
2383
}
2384
2385
#endif /* WOLFSSL_DH_EXTRA */
2386
2387
static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2388
                   word32 gSz, const byte* q, word32 qSz, int trusted,
2389
                   WC_RNG* rng)
2390
67.8k
{
2391
67.8k
    int ret = 0;
2392
67.8k
    mp_int* keyP = NULL;
2393
67.8k
    mp_int* keyG = NULL;
2394
2395
67.8k
    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
2396
19
        ret = BAD_FUNC_ARG;
2397
19
    }
2398
2399
67.8k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
2400
2401
67.8k
    if (ret == 0) {
2402
        /* may have leading 0 */
2403
67.8k
        if (p[0] == 0) {
2404
10.7k
            pSz--; p++;
2405
10.7k
        }
2406
2407
67.8k
        if (g[0] == 0) {
2408
33.7k
            gSz--; g++;
2409
33.7k
        }
2410
2411
67.8k
        if (q != NULL) {
2412
0
            if (q[0] == 0) {
2413
0
                qSz--; q++;
2414
0
            }
2415
0
        }
2416
2417
67.8k
        if (mp_init(&key->p) != MP_OKAY)
2418
0
            ret = MP_INIT_E;
2419
67.8k
    }
2420
2421
67.8k
    if (ret == 0) {
2422
67.8k
        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
2423
316
            ret = ASN_DH_KEY_E;
2424
67.5k
        else
2425
67.5k
            keyP = &key->p;
2426
67.8k
    }
2427
2428
67.8k
    if (ret == 0 && !trusted) {
2429
1.16k
        int isPrime = 0;
2430
1.16k
        if (rng != NULL)
2431
1.16k
            ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);
2432
0
        else
2433
0
            ret = mp_prime_is_prime(keyP, 8, &isPrime);
2434
2435
1.16k
        if (ret == 0 && isPrime == 0)
2436
569
            ret = DH_CHECK_PUB_E;
2437
1.16k
    }
2438
2439
67.8k
    if (ret == 0 && mp_init(&key->g) != MP_OKAY)
2440
0
        ret = MP_INIT_E;
2441
67.8k
    if (ret == 0) {
2442
66.9k
        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
2443
38
            ret = ASN_DH_KEY_E;
2444
66.8k
        else
2445
66.8k
            keyG = &key->g;
2446
66.9k
    }
2447
2448
67.8k
    if (ret == 0 && q != NULL) {
2449
0
        if (mp_init(&key->q) != MP_OKAY)
2450
0
            ret = MP_INIT_E;
2451
0
    }
2452
67.8k
    if (ret == 0 && q != NULL) {
2453
0
        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
2454
0
            ret = MP_INIT_E;
2455
0
        else
2456
0
            key->trustedGroup = trusted;
2457
0
    }
2458
2459
67.8k
    if (ret != 0 && key != NULL) {
2460
942
        if (keyG)
2461
0
            mp_clear(keyG);
2462
942
        if (keyP)
2463
607
            mp_clear(keyP);
2464
942
    }
2465
2466
67.8k
    RESTORE_VECTOR_REGISTERS();
2467
2468
67.8k
    return ret;
2469
67.8k
}
2470
2471
2472
int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2473
                   word32 gSz, const byte* q, word32 qSz, int trusted,
2474
                   WC_RNG* rng)
2475
1.16k
{
2476
1.16k
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
2477
1.16k
}
2478
2479
2480
int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
2481
                   word32 gSz, const byte* q, word32 qSz)
2482
0
{
2483
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL);
2484
0
}
2485
2486
2487
/* not in asn anymore since no actual asn types used */
2488
int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2489
                word32 gSz)
2490
66.6k
{
2491
    /* This should not have trusted set. */
2492
66.6k
    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
2493
66.6k
}
2494
2495
2496
int wc_DhSetNamedKey(DhKey* key, int name)
2497
0
{
2498
0
    const byte* p = NULL;
2499
0
    const byte* g = NULL;
2500
0
    const byte* q = NULL;
2501
0
    word32 pSz = 0, gSz = 0, qSz = 0;
2502
2503
0
    switch (name) {
2504
0
        #ifdef HAVE_FFDHE_2048
2505
0
        case WC_FFDHE_2048:
2506
0
            p = dh_ffdhe2048_p;
2507
0
            pSz = sizeof(dh_ffdhe2048_p);
2508
0
            g = dh_ffdhe2048_g;
2509
0
            gSz = sizeof(dh_ffdhe2048_g);
2510
            #ifdef HAVE_FFDHE_Q
2511
            q = dh_ffdhe2048_q;
2512
            qSz = sizeof(dh_ffdhe2048_q);
2513
            #endif /* HAVE_FFDHE_Q */
2514
0
            break;
2515
0
        #endif /* HAVE_FFDHE_2048 */
2516
        #ifdef HAVE_FFDHE_3072
2517
        case WC_FFDHE_3072:
2518
            p = dh_ffdhe3072_p;
2519
            pSz = sizeof(dh_ffdhe3072_p);
2520
            g = dh_ffdhe3072_g;
2521
            gSz = sizeof(dh_ffdhe3072_g);
2522
            #ifdef HAVE_FFDHE_Q
2523
            q = dh_ffdhe3072_q;
2524
            qSz = sizeof(dh_ffdhe3072_q);
2525
            #endif /* HAVE_FFDHE_Q */
2526
            break;
2527
        #endif /* HAVE_FFDHE_3072 */
2528
        #ifdef HAVE_FFDHE_4096
2529
        case WC_FFDHE_4096:
2530
            p = dh_ffdhe4096_p;
2531
            pSz = sizeof(dh_ffdhe4096_p);
2532
            g = dh_ffdhe4096_g;
2533
            gSz = sizeof(dh_ffdhe4096_g);
2534
            #ifdef HAVE_FFDHE_Q
2535
            q = dh_ffdhe4096_q;
2536
            qSz = sizeof(dh_ffdhe4096_q);
2537
            #endif /* HAVE_FFDHE_Q */
2538
            break;
2539
        #endif /* HAVE_FFDHE_4096 */
2540
        #ifdef HAVE_FFDHE_6144
2541
        case WC_FFDHE_6144:
2542
            p = dh_ffdhe6144_p;
2543
            pSz = sizeof(dh_ffdhe6144_p);
2544
            g = dh_ffdhe6144_g;
2545
            gSz = sizeof(dh_ffdhe6144_g);
2546
            #ifdef HAVE_FFDHE_Q
2547
            q = dh_ffdhe6144_q;
2548
            qSz = sizeof(dh_ffdhe6144_q);
2549
            #endif /* HAVE_FFDHE_Q */
2550
            break;
2551
        #endif /* HAVE_FFDHE_6144 */
2552
        #ifdef HAVE_FFDHE_8192
2553
        case WC_FFDHE_8192:
2554
            p = dh_ffdhe8192_p;
2555
            pSz = sizeof(dh_ffdhe8192_p);
2556
            g = dh_ffdhe8192_g;
2557
            gSz = sizeof(dh_ffdhe8192_g);
2558
            #ifdef HAVE_FFDHE_Q
2559
            q = dh_ffdhe8192_q;
2560
            qSz = sizeof(dh_ffdhe8192_q);
2561
            #endif /* HAVE_FFDHE_Q */
2562
            break;
2563
        #endif /* HAVE_FFDHE_8192 */
2564
0
        default:
2565
0
            break;
2566
0
    }
2567
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
2568
0
}
2569
2570
2571
word32 wc_DhGetNamedKeyMinSize(int name)
2572
0
{
2573
0
    int size;
2574
2575
0
    switch (name) {
2576
0
        #ifdef HAVE_FFDHE_2048
2577
0
        case WC_FFDHE_2048:
2578
0
            size = 29;
2579
0
            break;
2580
0
        #endif /* HAVE_FFDHE_2048 */
2581
        #ifdef HAVE_FFDHE_3072
2582
        case WC_FFDHE_3072:
2583
            size = 34;
2584
            break;
2585
        #endif /* HAVE_FFDHE_3072 */
2586
        #ifdef HAVE_FFDHE_4096
2587
        case WC_FFDHE_4096:
2588
            size = 39;
2589
            break;
2590
        #endif /* HAVE_FFDHE_4096 */
2591
        #ifdef HAVE_FFDHE_6144
2592
        case WC_FFDHE_6144:
2593
            size = 46;
2594
            break;
2595
        #endif /* HAVE_FFDHE_6144 */
2596
        #ifdef HAVE_FFDHE_8192
2597
        case WC_FFDHE_8192:
2598
            size = 52;
2599
            break;
2600
        #endif /* HAVE_FFDHE_8192 */
2601
0
        default:
2602
0
            size = 0;
2603
0
    }
2604
2605
0
    return size;
2606
0
}
2607
2608
2609
/* Returns 1: params match
2610
 *         0: params differ */
2611
int wc_DhCmpNamedKey(int name, int noQ,
2612
        const byte* p, word32 pSz,
2613
        const byte* g, word32 gSz,
2614
        const byte* q, word32 qSz)
2615
0
{
2616
0
    const byte* pCmp = NULL;
2617
0
    const byte* qCmp = NULL;
2618
0
    const byte* gCmp = NULL;
2619
0
    word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0;
2620
0
    int cmp = 0, goodName = 1;
2621
2622
0
    switch (name) {
2623
0
        #ifdef HAVE_FFDHE_2048
2624
0
        case WC_FFDHE_2048:
2625
0
            pCmp = dh_ffdhe2048_p;
2626
0
            pCmpSz = sizeof(dh_ffdhe2048_p);
2627
0
            gCmp = dh_ffdhe2048_g;
2628
0
            gCmpSz = sizeof(dh_ffdhe2048_g);
2629
            #ifdef HAVE_FFDHE_Q
2630
            qCmp = dh_ffdhe2048_q;
2631
            qCmpSz = sizeof(dh_ffdhe2048_q);
2632
            #endif /* HAVE_FFDHE_Q */
2633
0
            break;
2634
0
        #endif /* HAVE_FFDHE_2048 */
2635
        #ifdef HAVE_FFDHE_3072
2636
        case WC_FFDHE_3072:
2637
            pCmp = dh_ffdhe3072_p;
2638
            pCmpSz = sizeof(dh_ffdhe3072_p);
2639
            gCmp = dh_ffdhe3072_g;
2640
            gCmpSz = sizeof(dh_ffdhe3072_g);
2641
            #ifdef HAVE_FFDHE_Q
2642
            qCmp = dh_ffdhe3072_q;
2643
            qCmpSz = sizeof(dh_ffdhe3072_q);
2644
            #endif /* HAVE_FFDHE_Q */
2645
            break;
2646
        #endif /* HAVE_FFDHE_3072 */
2647
        #ifdef HAVE_FFDHE_4096
2648
        case WC_FFDHE_4096:
2649
            pCmp = dh_ffdhe4096_p;
2650
            pCmpSz = sizeof(dh_ffdhe4096_p);
2651
            gCmp = dh_ffdhe4096_g;
2652
            gCmpSz = sizeof(dh_ffdhe4096_g);
2653
            #ifdef HAVE_FFDHE_Q
2654
            qCmp = dh_ffdhe4096_q;
2655
            qCmpSz = sizeof(dh_ffdhe4096_q);
2656
            #endif /* HAVE_FFDHE_Q */
2657
            break;
2658
        #endif /* HAVE_FFDHE_4096 */
2659
        #ifdef HAVE_FFDHE_6144
2660
        case WC_FFDHE_6144:
2661
            pCmp = dh_ffdhe6144_p;
2662
            pCmpSz = sizeof(dh_ffdhe6144_p);
2663
            gCmp = dh_ffdhe6144_g;
2664
            gCmpSz = sizeof(dh_ffdhe6144_g);
2665
            #ifdef HAVE_FFDHE_Q
2666
            qCmp = dh_ffdhe6144_q;
2667
            qCmpSz = sizeof(dh_ffdhe6144_q);
2668
            #endif /* HAVE_FFDHE_Q */
2669
            break;
2670
        #endif /* HAVE_FFDHE_6144 */
2671
        #ifdef HAVE_FFDHE_8192
2672
        case WC_FFDHE_8192:
2673
            pCmp = dh_ffdhe8192_p;
2674
            pCmpSz = sizeof(dh_ffdhe8192_p);
2675
            gCmp = dh_ffdhe8192_g;
2676
            gCmpSz = sizeof(dh_ffdhe8192_g);
2677
            #ifdef HAVE_FFDHE_Q
2678
            qCmp = dh_ffdhe8192_q;
2679
            qCmpSz = sizeof(dh_ffdhe8192_q);
2680
            #endif /* HAVE_FFDHE_Q */
2681
            break;
2682
        #endif /* HAVE_FFDHE_8192 */
2683
0
        default:
2684
0
            goodName = 0;
2685
0
    }
2686
2687
0
    cmp = goodName && (pSz == pCmpSz) && (gSz == gCmpSz) &&
2688
0
        (noQ || ((qCmp != NULL) && (qSz == qCmpSz) &&
2689
0
                 XMEMCMP(q, qCmp, qCmpSz) == 0)) &&
2690
0
        (XMEMCMP(p, pCmp, pCmpSz) == 0) &&
2691
0
        (XMEMCMP(g, gCmp, gCmpSz) == 0);
2692
2693
0
    return cmp;
2694
0
}
2695
2696
2697
int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q)
2698
0
{
2699
0
    word32 pSz = 0, gSz = 0, qSz = 0;
2700
2701
0
    switch (name) {
2702
0
        #ifdef HAVE_FFDHE_2048
2703
0
        case WC_FFDHE_2048:
2704
0
            pSz = sizeof(dh_ffdhe2048_p);
2705
0
            gSz = sizeof(dh_ffdhe2048_g);
2706
            #ifdef HAVE_FFDHE_Q
2707
            qSz = sizeof(dh_ffdhe2048_q);
2708
            #endif /* HAVE_FFDHE_Q */
2709
0
            break;
2710
0
        #endif /* HAVE_FFDHE_2048 */
2711
        #ifdef HAVE_FFDHE_3072
2712
        case WC_FFDHE_3072:
2713
            pSz = sizeof(dh_ffdhe3072_p);
2714
            gSz = sizeof(dh_ffdhe3072_g);
2715
            #ifdef HAVE_FFDHE_Q
2716
            qSz = sizeof(dh_ffdhe3072_q);
2717
            #endif /* HAVE_FFDHE_Q */
2718
            break;
2719
        #endif /* HAVE_FFDHE_3072 */
2720
        #ifdef HAVE_FFDHE_4096
2721
        case WC_FFDHE_4096:
2722
            pSz = sizeof(dh_ffdhe4096_p);
2723
            gSz = sizeof(dh_ffdhe4096_g);
2724
            #ifdef HAVE_FFDHE_Q
2725
            qSz = sizeof(dh_ffdhe4096_q);
2726
            #endif /* HAVE_FFDHE_Q */
2727
            break;
2728
        #endif /* HAVE_FFDHE_4096 */
2729
        #ifdef HAVE_FFDHE_6144
2730
        case WC_FFDHE_6144:
2731
            pSz = sizeof(dh_ffdhe6144_p);
2732
            gSz = sizeof(dh_ffdhe6144_g);
2733
            #ifdef HAVE_FFDHE_Q
2734
            qSz = sizeof(dh_ffdhe6144_q);
2735
            #endif /* HAVE_FFDHE_Q */
2736
            break;
2737
        #endif /* HAVE_FFDHE_6144 */
2738
        #ifdef HAVE_FFDHE_8192
2739
        case WC_FFDHE_8192:
2740
            pSz = sizeof(dh_ffdhe8192_p);
2741
            gSz = sizeof(dh_ffdhe8192_g);
2742
            #ifdef HAVE_FFDHE_Q
2743
            qSz = sizeof(dh_ffdhe8192_q);
2744
            #endif /* HAVE_FFDHE_Q */
2745
            break;
2746
        #endif /* HAVE_FFDHE_8192 */
2747
0
        default:
2748
0
            break;
2749
0
    }
2750
2751
0
    if (p != NULL) *p = pSz;
2752
0
    if (g != NULL) *g = gSz;
2753
0
    if (q != NULL) *q = qSz;
2754
2755
0
    return 0;
2756
0
}
2757
2758
2759
int wc_DhCopyNamedKey(int name,
2760
        byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz)
2761
0
{
2762
0
    const byte* pC = NULL;
2763
0
    const byte* gC = NULL;
2764
0
    const byte* qC = NULL;
2765
0
    word32 pCSz = 0, gCSz = 0, qCSz = 0;
2766
2767
0
    switch (name) {
2768
0
        #ifdef HAVE_FFDHE_2048
2769
0
        case WC_FFDHE_2048:
2770
0
            pC = dh_ffdhe2048_p;
2771
0
            pCSz = sizeof(dh_ffdhe2048_p);
2772
0
            gC = dh_ffdhe2048_g;
2773
0
            gCSz = sizeof(dh_ffdhe2048_g);
2774
            #ifdef HAVE_FFDHE_Q
2775
            qC = dh_ffdhe2048_q;
2776
            qCSz = sizeof(dh_ffdhe2048_q);
2777
            #endif /* HAVE_FFDHE_Q */
2778
0
            break;
2779
0
        #endif /* HAVE_FFDHE_2048 */
2780
        #ifdef HAVE_FFDHE_3072
2781
        case WC_FFDHE_3072:
2782
            pC = dh_ffdhe3072_p;
2783
            pCSz = sizeof(dh_ffdhe3072_p);
2784
            gC = dh_ffdhe3072_g;
2785
            gCSz = sizeof(dh_ffdhe3072_g);
2786
            #ifdef HAVE_FFDHE_Q
2787
            qC = dh_ffdhe3072_q;
2788
            qCSz = sizeof(dh_ffdhe3072_q);
2789
            #endif /* HAVE_FFDHE_Q */
2790
            break;
2791
        #endif /* HAVE_FFDHE_3072 */
2792
        #ifdef HAVE_FFDHE_4096
2793
        case WC_FFDHE_4096:
2794
            pC = dh_ffdhe4096_p;
2795
            pCSz = sizeof(dh_ffdhe4096_p);
2796
            gC = dh_ffdhe4096_g;
2797
            gCSz = sizeof(dh_ffdhe4096_g);
2798
            #ifdef HAVE_FFDHE_Q
2799
            qC = dh_ffdhe4096_q;
2800
            qCSz = sizeof(dh_ffdhe4096_q);
2801
            #endif /* HAVE_FFDHE_Q */
2802
            break;
2803
        #endif /* HAVE_FFDHE_4096 */
2804
        #ifdef HAVE_FFDHE_6144
2805
        case WC_FFDHE_6144:
2806
            pC = dh_ffdhe6144_p;
2807
            pCSz = sizeof(dh_ffdhe6144_p);
2808
            gC = dh_ffdhe6144_g;
2809
            gCSz = sizeof(dh_ffdhe6144_g);
2810
            #ifdef HAVE_FFDHE_Q
2811
            qC = dh_ffdhe6144_q;
2812
            qCSz = sizeof(dh_ffdhe6144_q);
2813
            #endif /* HAVE_FFDHE_Q */
2814
            break;
2815
        #endif /* HAVE_FFDHE_6144 */
2816
        #ifdef HAVE_FFDHE_8192
2817
        case WC_FFDHE_8192:
2818
            pC = dh_ffdhe8192_p;
2819
            pCSz = sizeof(dh_ffdhe8192_p);
2820
            gC = dh_ffdhe8192_g;
2821
            gCSz = sizeof(dh_ffdhe8192_g);
2822
            #ifdef HAVE_FFDHE_Q
2823
            qC = dh_ffdhe8192_q;
2824
            qCSz = sizeof(dh_ffdhe8192_q);
2825
            #endif /* HAVE_FFDHE_Q */
2826
            break;
2827
        #endif /* HAVE_FFDHE_8192 */
2828
0
        default:
2829
0
            break;
2830
0
    }
2831
2832
0
    if (p != NULL && pC != NULL)
2833
0
        XMEMCPY(p, pC, pCSz);
2834
0
    if (pSz != NULL)
2835
0
        *pSz = pCSz;
2836
0
    if (g != NULL && gC != NULL)
2837
0
        XMEMCPY(g, gC, gCSz);
2838
0
    if (gSz != NULL)
2839
0
        *gSz = gCSz;
2840
0
    if (q != NULL && qC != NULL)
2841
0
        XMEMCPY(q, qC, qCSz);
2842
0
    if (qSz != NULL)
2843
0
        *qSz = qCSz;
2844
2845
0
    return 0;
2846
0
}
2847
2848
2849
#ifdef WOLFSSL_KEY_GEN
2850
2851
/* modulus_size in bits */
2852
int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
2853
0
{
2854
0
#ifdef WOLFSSL_SMALL_STACK
2855
0
    mp_int *tmp = NULL, *tmp2 = NULL;
2856
#else
2857
    mp_int tmp[1], tmp2[2];
2858
#endif
2859
0
    int     groupSz = 0, bufSz = 0,
2860
0
            primeCheckCount = 0,
2861
0
            primeCheck = MP_NO,
2862
0
            ret = 0;
2863
0
    unsigned char *buf = NULL;
2864
2865
0
    if (rng == NULL || dh == NULL)
2866
0
        ret = BAD_FUNC_ARG;
2867
2868
    /* set group size in bytes from modulus size
2869
     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
2870
     */
2871
0
    if (ret == 0) {
2872
0
        switch (modSz) {
2873
0
            case 1024:
2874
0
                groupSz = 20;
2875
0
                break;
2876
0
            case 2048:
2877
0
            case 3072:
2878
0
                groupSz = 32;
2879
0
                break;
2880
0
            default:
2881
        #if !defined(HAVE_FIPS) && defined(WOLFSSL_NO_DH186)
2882
                /* in non fips mode attempt to match strength of group size with
2883
                 * mod size */
2884
                if (modSz < 2048)
2885
                    groupSz = 20;
2886
                else
2887
                    groupSz = 32;
2888
        #else
2889
0
                ret = BAD_FUNC_ARG;
2890
0
        #endif
2891
0
                break;
2892
0
        }
2893
0
    }
2894
2895
0
    if (ret == 0) {
2896
        /* modulus size in bytes */
2897
0
        modSz /= WOLFSSL_BIT_SIZE;
2898
0
        bufSz = modSz - groupSz;
2899
2900
        /* allocate ram */
2901
0
        buf = (unsigned char *)XMALLOC(bufSz,
2902
0
                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
2903
0
        if (buf == NULL)
2904
0
            ret = MEMORY_E;
2905
0
    }
2906
2907
    /* make a random string that will be multiplied against q */
2908
0
    if (ret == 0)
2909
0
        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
2910
2911
0
#ifdef WOLFSSL_SMALL_STACK
2912
0
    if (ret == 0) {
2913
0
        if (((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) ||
2914
0
            ((tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL, DYNAMIC_TYPE_WOLF_BIGINT)) == NULL))
2915
0
            ret = MEMORY_E;
2916
0
    }
2917
0
#endif
2918
2919
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2920
2921
0
    if (ret == 0) {
2922
        /* force magnitude */
2923
0
        buf[0] |= 0xC0;
2924
        /* force even */
2925
0
        buf[bufSz - 1] &= ~1;
2926
2927
0
        if (mp_init_multi(tmp, tmp2, &dh->p, &dh->q, &dh->g, 0)
2928
0
                != MP_OKAY) {
2929
0
            ret = MP_INIT_E;
2930
0
        }
2931
0
    }
2932
2933
0
    if (ret == 0) {
2934
0
        if (mp_read_unsigned_bin(tmp2, buf, bufSz) != MP_OKAY)
2935
0
            ret = MP_READ_E;
2936
0
    }
2937
2938
    /* make our prime q */
2939
0
    if (ret == 0) {
2940
0
        if (mp_rand_prime(&dh->q, groupSz, rng, NULL) != MP_OKAY)
2941
0
            ret = PRIME_GEN_E;
2942
0
    }
2943
2944
    /* p = random * q */
2945
0
    if (ret == 0) {
2946
0
        if (mp_mul(&dh->q, tmp2, &dh->p) != MP_OKAY)
2947
0
            ret = MP_MUL_E;
2948
0
    }
2949
2950
    /* p = random * q + 1, so q is a prime divisor of p-1 */
2951
0
    if (ret == 0) {
2952
0
        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
2953
0
            ret = MP_ADD_E;
2954
0
    }
2955
2956
    /* tmp = 2q  */
2957
0
    if (ret == 0) {
2958
0
        if (mp_add(&dh->q, &dh->q, tmp) != MP_OKAY)
2959
0
            ret = MP_ADD_E;
2960
0
    }
2961
2962
    /* loop until p is prime */
2963
0
    if (ret == 0) {
2964
0
        do {
2965
0
            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
2966
0
                ret = PRIME_GEN_E;
2967
2968
0
            if (primeCheck != MP_YES) {
2969
                /* p += 2q */
2970
0
                if (mp_add(tmp, &dh->p, &dh->p) != MP_OKAY)
2971
0
                    ret = MP_ADD_E;
2972
0
                else
2973
0
                    primeCheckCount++;
2974
0
            }
2975
0
        } while (ret == 0 && primeCheck == MP_NO);
2976
0
    }
2977
2978
    /* tmp2 += (2*loop_check_prime)
2979
     * to have p = (q * tmp2) + 1 prime
2980
     */
2981
0
    if ((ret == 0) && (primeCheckCount)) {
2982
0
        if (mp_add_d(tmp2, 2 * primeCheckCount, tmp2) != MP_OKAY)
2983
0
            ret = MP_ADD_E;
2984
0
    }
2985
2986
    /* find a value g for which g^tmp2 != 1 */
2987
0
    if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))
2988
0
        ret = MP_ZERO_E;
2989
2990
0
    if (ret == 0) {
2991
0
        do {
2992
0
            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
2993
0
                ret = MP_ADD_E;
2994
0
            else if (mp_exptmod(&dh->g, tmp2, &dh->p, tmp) != MP_OKAY)
2995
0
                ret = MP_EXPTMOD_E;
2996
0
        } while (ret == 0 && mp_cmp_d(tmp, 1) == MP_EQ);
2997
0
    }
2998
2999
0
    if (ret == 0) {
3000
        /* at this point tmp generates a group of order q mod p */
3001
0
#ifndef USE_FAST_MATH
3002
        /* Exchanging is quick when the data pointer can be copied. */
3003
0
        mp_exch(tmp, &dh->g);
3004
#else
3005
        mp_copy(tmp, &dh->g);
3006
#endif
3007
0
    }
3008
3009
    /* clear the parameters if there was an error */
3010
0
    if ((ret != 0) && (dh != NULL)) {
3011
0
        mp_clear(&dh->q);
3012
0
        mp_clear(&dh->p);
3013
0
        mp_clear(&dh->g);
3014
0
    }
3015
3016
0
    RESTORE_VECTOR_REGISTERS();
3017
3018
0
    if (buf != NULL) {
3019
0
        ForceZero(buf, bufSz);
3020
0
        if (dh != NULL) {
3021
0
            XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
3022
0
        }
3023
0
    }
3024
3025
0
#ifdef WOLFSSL_SMALL_STACK
3026
0
    if (tmp != NULL) {
3027
0
        mp_clear(tmp);
3028
0
        XFREE(tmp, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3029
0
    }
3030
0
    if (tmp2 != NULL) {
3031
0
        mp_clear(tmp2);
3032
0
        XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3033
0
    }
3034
#else
3035
    mp_clear(tmp);
3036
    mp_clear(tmp2);
3037
#endif
3038
3039
0
    return ret;
3040
0
}
3041
3042
3043
/* Export raw DH parameters from DhKey structure
3044
 *
3045
 * dh   - pointer to initialized DhKey structure
3046
 * p    - output location for DH (p) parameter
3047
 * pSz  - [IN/OUT] size of output buffer for p, size of p
3048
 * q    - output location for DH (q) parameter
3049
 * qSz  - [IN/OUT] size of output buffer for q, size of q
3050
 * g    - output location for DH (g) parameter
3051
 * gSz  - [IN/OUT] size of output buffer for g, size of g
3052
 *
3053
 * If p, q, and g pointers are all passed in as NULL, the function
3054
 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
3055
 * q, and g. In this case, the function will return LENGTH_ONLY_E.
3056
 *
3057
 * returns 0 on success, negative upon failure
3058
 */
3059
int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
3060
                         byte* q, word32* qSz, byte* g, word32* gSz)
3061
0
{
3062
0
    int ret = 0;
3063
0
    word32 pLen = 0, qLen = 0, gLen = 0;
3064
3065
0
    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
3066
0
        ret = BAD_FUNC_ARG;
3067
3068
    /* get required output buffer sizes */
3069
0
    if (ret == 0) {
3070
0
        pLen = mp_unsigned_bin_size(&dh->p);
3071
0
        qLen = mp_unsigned_bin_size(&dh->q);
3072
0
        gLen = mp_unsigned_bin_size(&dh->g);
3073
3074
        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
3075
0
        if (p == NULL && q == NULL && g == NULL) {
3076
0
            *pSz = pLen;
3077
0
            *qSz = qLen;
3078
0
            *gSz = gLen;
3079
0
            ret = LENGTH_ONLY_E;
3080
0
        }
3081
0
    }
3082
3083
0
    if (ret == 0) {
3084
0
        if (p == NULL || q == NULL || g == NULL)
3085
0
            ret = BAD_FUNC_ARG;
3086
0
    }
3087
3088
    /* export p */
3089
0
    if (ret == 0) {
3090
0
        if (*pSz < pLen) {
3091
0
            WOLFSSL_MSG("Output buffer for DH p parameter too small, "
3092
0
                        "required size placed into pSz");
3093
0
            *pSz = pLen;
3094
0
            ret = BUFFER_E;
3095
0
        }
3096
0
    }
3097
3098
0
    if (ret == 0) {
3099
0
        *pSz = pLen;
3100
0
        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
3101
0
            ret = MP_TO_E;
3102
0
    }
3103
3104
    /* export q */
3105
0
    if (ret == 0) {
3106
0
        if (*qSz < qLen) {
3107
0
            WOLFSSL_MSG("Output buffer for DH q parameter too small, "
3108
0
                        "required size placed into qSz");
3109
0
            *qSz = qLen;
3110
0
            ret = BUFFER_E;
3111
0
        }
3112
0
    }
3113
3114
0
    if (ret == 0) {
3115
0
        *qSz = qLen;
3116
0
        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
3117
0
            ret = MP_TO_E;
3118
0
    }
3119
3120
    /* export g */
3121
0
    if (ret == 0) {
3122
0
        if (*gSz < gLen) {
3123
0
            WOLFSSL_MSG("Output buffer for DH g parameter too small, "
3124
0
                        "required size placed into gSz");
3125
0
            *gSz = gLen;
3126
0
            ret = BUFFER_E;
3127
0
        }
3128
0
    }
3129
3130
0
    if (ret == 0) {
3131
0
        *gSz = gLen;
3132
0
        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
3133
0
            ret = MP_TO_E;
3134
0
    }
3135
3136
0
    return ret;
3137
0
}
3138
3139
#endif /* WOLFSSL_KEY_GEN */
3140
3141
#endif /* NO_DH */