Coverage Report

Created: 2025-11-16 07:15

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