Coverage Report

Created: 2026-04-01 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math/wolfcrypt/src/dh.c
Line
Count
Source
1
/* dh.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#ifndef NO_DH
25
26
#if defined(HAVE_FIPS) && \
27
    defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
28
29
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
30
    #define FIPS_NO_WRAPPERS
31
32
    #ifdef USE_WINDOWS_API
33
        #pragma code_seg(".fipsA$e")
34
        #pragma const_seg(".fipsB$e")
35
    #endif
36
#endif
37
38
#include <wolfssl/wolfcrypt/dh.h>
39
40
#ifdef WOLFSSL_HAVE_SP_DH
41
#include <wolfssl/wolfcrypt/sp.h>
42
#endif
43
44
#ifdef NO_INLINE
45
    #include <wolfssl/wolfcrypt/misc.h>
46
#else
47
    #define WOLFSSL_MISC_INCLUDED
48
    #include <wolfcrypt/src/misc.c>
49
#endif
50
51
#if FIPS_VERSION3_GE(6,0,0)
52
    const unsigned int wolfCrypt_FIPS_dh_ro_sanity[2] =
53
                                                     { 0x1a2b3c4d, 0x00000004 };
54
    int wolfCrypt_FIPS_DH_sanity(void)
55
    {
56
        return 0;
57
    }
58
#endif
59
60
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && !defined(WOLFSSL_SP_ASM)
61
    /* force off unneeded vector register save/restore. */
62
    #undef SAVE_VECTOR_REGISTERS
63
    #define SAVE_VECTOR_REGISTERS(fail_clause) SAVE_NO_VECTOR_REGISTERS(fail_clause)
64
    #undef RESTORE_VECTOR_REGISTERS
65
    #define RESTORE_VECTOR_REGISTERS() RESTORE_NO_VECTOR_REGISTERS()
66
#endif
67
68
/*
69
Possible DH enable options:
70
 * NO_RSA:              Overall control of DH                 default: on (not defined)
71
 * WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
72
                        directly effect this file, but it does speed up DH
73
                        removing the testing. It is not recommended to
74
                        disable the prime checking.           default: off
75
 * WOLFSSL_VALIDATE_DH_KEYGEN: Enable DH key gen consistency checking
76
 *                             (on for FIPS 140-3 or later)   default: off
77
*/
78
79
80
#if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
81
    #include <math.h>
82
8.67k
    #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.34k
{
164
2.34k
    static const DhParams ffdhe2048 = {
165
        #ifdef HAVE_FFDHE_Q
166
            dh_ffdhe2048_q, sizeof(dh_ffdhe2048_q),
167
        #endif /* HAVE_FFDHE_Q */
168
2.34k
        dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p),
169
2.34k
        dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g)
170
2.34k
    };
171
2.34k
    return &ffdhe2048;
172
2.34k
}
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
12.8k
{
946
12.8k
    int ret = 0;
947
948
12.8k
    if (key == NULL)
949
0
        return BAD_FUNC_ARG;
950
951
12.8k
    key->heap = heap; /* for XMALLOC/XFREE in future */
952
12.8k
    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
12.8k
    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
12.8k
    (void)devId;
967
12.8k
#endif
968
969
12.8k
    key->trustedGroup = 0;
970
971
#ifdef WOLFSSL_KCAPI_DH
972
    key->handle = NULL;
973
#endif
974
975
12.8k
    return ret;
976
12.8k
}
977
978
int wc_InitDhKey(DhKey* key)
979
10.7k
{
980
10.7k
    return wc_InitDhKey_ex(key, NULL, INVALID_DEVID);
981
10.7k
}
982
983
984
int wc_FreeDhKey(DhKey* key)
985
12.3k
{
986
12.3k
    if (key) {
987
11.7k
        mp_clear(&key->p);
988
11.7k
        mp_clear(&key->g);
989
11.7k
        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
11.7k
    }
1002
12.3k
    return 0;
1003
12.3k
}
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
4.50k
    {
1020
        /* assuming discrete log takes about the same time as factoring */
1021
4.50k
        if (n < 5)
1022
171
            return 0;
1023
4.33k
        else
1024
4.33k
            return (word32)((double)2.4 * XPOW((double)n, 1.0/3.0) *
1025
4.33k
                    XPOW(XLOG((double)n), 2.0/3.0) - 5);
1026
4.50k
    }
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
5.08k
    #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_forcezero(tmpX);
1161
0
            mp_clear(tmpQ);
1162
0
            ForceZero(cBuf, cSz);
1163
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1164
0
            XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1165
0
            XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1166
0
            XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1167
0
#endif
1168
0
            return err;
1169
0
        }
1170
0
    } while (mp_cmp_d(tmpX, 1) != MP_GT);
1171
1172
0
    ForceZero(cBuf, cSz);
1173
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1174
0
    XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
1175
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1176
    wc_MemZero_Check(cBuf, cSz);
1177
#endif
1178
1179
    /* tmpQ: M = min(2^N,q) - 1 */
1180
0
    if (err == MP_OKAY)
1181
0
        err = mp_2expt(tmpQ, (int)*privSz * 8);
1182
1183
0
    if (err == MP_OKAY) {
1184
0
        if (mp_cmp(tmpQ, &key->q) == MP_GT) {
1185
0
            err = mp_copy(&key->q, tmpQ);
1186
0
        }
1187
0
    }
1188
1189
0
    if (err == MP_OKAY)
1190
0
        err = mp_sub_d(tmpQ, 1, tmpQ);
1191
1192
    /* x = c mod (M), tmpX holds c */
1193
0
    if (err == MP_OKAY)
1194
0
        err = mp_mod(tmpX, tmpQ, tmpX);
1195
1196
    /* x = c mod (M) + 1 */
1197
0
    if (err == MP_OKAY)
1198
0
        err = mp_add_d(tmpX, 1, tmpX);
1199
1200
    /* copy tmpX into priv */
1201
0
    if (err == MP_OKAY) {
1202
0
        pSz = (word32)mp_unsigned_bin_size(tmpX);
1203
0
        if (pSz > *privSz) {
1204
0
            WOLFSSL_MSG("DH private key output buffer too small");
1205
0
            err = BAD_FUNC_ARG;
1206
0
        } else {
1207
0
            *privSz = pSz;
1208
0
            err = mp_to_unsigned_bin(tmpX, priv);
1209
0
        }
1210
0
    }
1211
1212
0
    mp_forcezero(tmpX);
1213
0
    mp_clear(tmpQ);
1214
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1215
0
    XFREE(tmpQ, key->heap, DYNAMIC_TYPE_DH);
1216
0
    XFREE(tmpX, key->heap, DYNAMIC_TYPE_DH);
1217
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1218
    mp_memzero_check(tmpX);
1219
#endif
1220
1221
0
    return err;
1222
0
}
1223
#endif /* WOLFSSL_NO_DH186 */
1224
#endif /* !WC_NO_RNG */
1225
1226
static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
1227
                             word32* privSz)
1228
5.16k
{
1229
5.16k
#ifndef WC_NO_RNG
1230
5.16k
    int ret = 0;
1231
5.16k
    word32 sz = 0;
1232
1233
5.16k
    if (mp_iseven(&key->p) == MP_YES) {
1234
86
        ret = MP_VAL;
1235
86
    }
1236
5.08k
    else
1237
5.08k
#ifndef WOLFSSL_NO_DH186
1238
5.08k
    if (mp_iszero(&key->q) == MP_NO) {
1239
1240
        /* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair
1241
         * Generation Using Extra Random Bits" */
1242
0
        ret = GeneratePrivateDh186(key, rng, priv, privSz);
1243
1244
0
    }
1245
5.08k
    else
1246
5.08k
#endif
1247
5.08k
    {
1248
1249
5.08k
        sz = (word32)mp_unsigned_bin_size(&key->p);
1250
1251
        /* Table of predetermined values from the operation
1252
           2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1253
           WOLFSSL_BIT_SIZE + 1
1254
           Sizes in table checked against RFC 3526
1255
         */
1256
5.08k
        WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */
1257
5.08k
        switch (sz) {
1258
3
            case 128:  sz = 21; break;
1259
1.33k
            case 256:  sz = 29; break;
1260
35
            case 384:  sz = 34; break;
1261
430
            case 512:  sz = 39; break;
1262
0
            case 640:  sz = 42; break;
1263
0
            case 768:  sz = 46; break;
1264
0
            case 896:  sz = 49; break;
1265
0
            case 1024: sz = 52; break;
1266
3.28k
            default:
1267
3.28k
            #ifndef WOLFSSL_DH_CONST
1268
                /* if using floating points and size of p is not in table */
1269
3.28k
                sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) /
1270
3.28k
                                           WOLFSSL_BIT_SIZE + 1);
1271
3.28k
                break;
1272
            #else
1273
                return BAD_FUNC_ARG;
1274
            #endif
1275
5.08k
        }
1276
1277
5.08k
        if (sz > *privSz)
1278
9
            ret = WC_KEY_SIZE_E;
1279
1280
5.08k
        if (ret == 0)
1281
5.07k
            ret = wc_RNG_GenerateBlock(rng, priv, sz);
1282
1283
5.08k
        if (ret == 0) {
1284
5.04k
            priv[0] |= 0x0C;
1285
5.04k
            *privSz = sz;
1286
5.04k
        }
1287
5.08k
    }
1288
1289
5.16k
    return ret;
1290
#else
1291
    (void)key;
1292
    (void)rng;
1293
    (void)priv;
1294
    (void)privSz;
1295
    return NOT_COMPILED_IN;
1296
#endif /* WC_NO_RNG */
1297
5.16k
}
1298
1299
1300
static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz,
1301
    byte* pub, word32* pubSz)
1302
241
{
1303
241
    int ret = 0;
1304
#ifndef WOLFSSL_SP_MATH
1305
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1306
    mp_int* x;
1307
    mp_int* y;
1308
#else
1309
    mp_int x[1];
1310
    mp_int y[1];
1311
#endif
1312
#endif
1313
1314
241
    if (*pubSz < (word32)mp_unsigned_bin_size(&key->p)) {
1315
6
        return WC_KEY_SIZE_E;
1316
6
    }
1317
1318
235
#ifdef WOLFSSL_HAVE_SP_DH
1319
235
#ifndef WOLFSSL_SP_NO_2048
1320
235
    if (mp_count_bits(&key->p) == 2048)
1321
45
        return sp_DhExp_2048(&key->g, priv, privSz, &key->p, pub, pubSz);
1322
190
#endif
1323
190
#ifndef WOLFSSL_SP_NO_3072
1324
190
    if (mp_count_bits(&key->p) == 3072)
1325
33
        return sp_DhExp_3072(&key->g, priv, privSz, &key->p, pub, pubSz);
1326
157
#endif
1327
157
#ifdef WOLFSSL_SP_4096
1328
157
    if (mp_count_bits(&key->p) == 4096)
1329
4
        return sp_DhExp_4096(&key->g, priv, privSz, &key->p, pub, pubSz);
1330
153
#endif
1331
153
#endif
1332
1333
#if !defined(WOLFSSL_SP_MATH)
1334
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1335
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1336
    if (x == NULL)
1337
        return MEMORY_E;
1338
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1339
    if (y == NULL) {
1340
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1341
        return MEMORY_E;
1342
    }
1343
#endif
1344
    if (mp_init_multi(x, y, 0, 0, 0, 0) != MP_OKAY) {
1345
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1346
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1347
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1348
    #endif
1349
        return MP_INIT_E;
1350
    }
1351
1352
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
1353
        ret = MP_READ_E;
1354
1355
    if (ret == 0 && mp_exptmod(&key->g, x, &key->p, y) != MP_OKAY)
1356
        ret = MP_EXPTMOD_E;
1357
1358
    if (ret == 0 && mp_to_unsigned_bin(y, pub) != MP_OKAY)
1359
        ret = MP_TO_E;
1360
1361
    if (ret == 0)
1362
        *pubSz = (word32)mp_unsigned_bin_size(y);
1363
1364
    mp_clear(y);
1365
    mp_forcezero(x);
1366
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1367
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1368
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1369
#endif
1370
#else
1371
153
    ret = WC_KEY_SIZE_E;
1372
153
#endif
1373
1374
153
    return ret;
1375
157
}
1376
1377
/**
1378
 * Given a DhKey with set params and a priv key, generate the corresponding
1379
 * public key. If fips, does pub key validation.
1380
 * */
1381
int wc_DhGeneratePublic(DhKey* key, byte* priv, word32 privSz,
1382
    byte* pub, word32* pubSz)
1383
0
{
1384
0
    int ret = 0;
1385
1386
0
    if (key == NULL || priv == NULL || privSz == 0 ||
1387
0
        pub == NULL || pubSz == NULL) {
1388
0
        return BAD_FUNC_ARG;
1389
0
    }
1390
1391
0
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
1392
1393
0
    ret = GeneratePublicDh(key, priv, privSz, pub, pubSz);
1394
1395
    #if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1396
    if (ret == 0)
1397
        ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
1398
    if (ret == 0)
1399
        ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, privSz);
1400
    #endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
1401
1402
0
    RESTORE_VECTOR_REGISTERS();
1403
1404
0
    return ret;
1405
0
}
1406
1407
static int wc_DhGenerateKeyPair_Sync(DhKey* key, WC_RNG* rng,
1408
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1409
6.46k
{
1410
6.46k
    int ret;
1411
1412
6.46k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
1413
6.46k
        pub == NULL || pubSz == NULL) {
1414
0
        return BAD_FUNC_ARG;
1415
0
    }
1416
1417
6.46k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
1418
1419
6.46k
    ret = GeneratePrivateDh(key, rng, priv, privSz);
1420
1421
6.46k
    if (ret == 0)
1422
6.26k
        ret = GeneratePublicDh(key, priv, *privSz, pub, pubSz);
1423
#if FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_DH_KEYGEN)
1424
    if (ret == 0)
1425
        ret = _ffc_validate_public_key(key, pub, *pubSz, NULL, 0, 0);
1426
    if (ret == 0)
1427
        ret = _ffc_pairwise_consistency_test(key, pub, *pubSz, priv, *privSz);
1428
#endif /* FIPS V5 or later || WOLFSSL_VALIDATE_DH_KEYGEN */
1429
1430
1431
6.46k
    RESTORE_VECTOR_REGISTERS();
1432
1433
6.46k
    return ret;
1434
6.46k
}
1435
#endif /* !WOLFSSL_KCAPI_DH */
1436
1437
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1438
static int wc_DhGenerateKeyPair_Async(DhKey* key, WC_RNG* rng,
1439
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1440
{
1441
    int ret;
1442
1443
#if defined(HAVE_INTEL_QA)
1444
    word32 pBits;
1445
1446
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
1447
    pBits = mp_unsigned_bin_size(&key->p) * 8;
1448
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
1449
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
1450
        mp_int x;
1451
1452
        ret = mp_init(&x);
1453
        if (ret != MP_OKAY)
1454
            return ret;
1455
1456
        ret = GeneratePrivateDh(key, rng, priv, privSz);
1457
        if (ret == 0)
1458
            ret = mp_read_unsigned_bin(&x, priv, *privSz);
1459
        if (ret == MP_OKAY)
1460
            ret = wc_mp_to_bigint(&x, &x.raw);
1461
        if (ret == MP_OKAY)
1462
            ret = wc_mp_to_bigint(&key->p, &key->p.raw);
1463
        if (ret == MP_OKAY)
1464
            ret = wc_mp_to_bigint(&key->g, &key->g.raw);
1465
        if (ret == MP_OKAY)
1466
            ret = IntelQaDhKeyGen(&key->asyncDev, &key->p.raw, &key->g.raw,
1467
                &x.raw, pub, pubSz);
1468
        mp_forcezero(&x);
1469
1470
        return ret;
1471
    }
1472
1473
#elif defined(HAVE_CAVIUM)
1474
    /* TODO: Not implemented - use software for now */
1475
1476
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
1477
    if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_DH_GEN)) {
1478
        WC_ASYNC_SW* sw = &key->asyncDev.sw;
1479
        sw->dhGen.key = key;
1480
        sw->dhGen.rng = rng;
1481
        sw->dhGen.priv = priv;
1482
        sw->dhGen.privSz = privSz;
1483
        sw->dhGen.pub = pub;
1484
        sw->dhGen.pubSz = pubSz;
1485
        return WC_PENDING_E;
1486
    }
1487
#endif
1488
1489
    /* otherwise use software DH */
1490
    ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
1491
1492
    return ret;
1493
}
1494
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_DH */
1495
1496
1497
/* Check DH Public Key for invalid numbers, optionally allowing
1498
 * the public key to be checked against the large prime (q).
1499
 * If q is NULL, the q value of key is used.
1500
 * Check per process in SP 800-56Ar3, section 5.6.2.3.1 or 2.
1501
 *
1502
 * key     DH key group parameters.
1503
 * pub     Public Key.
1504
 * pubSz   Public Key size.
1505
 * prime   Large prime (q), optionally NULL to skip check
1506
 * primeSz Size of large prime
1507
 * partial Do the partial test process. (section 5.6.2.3.2)
1508
 *
1509
 *  returns 0 on success or error code
1510
 */
1511
static int _ffc_validate_public_key(DhKey* key, const byte* pub, word32 pubSz,
1512
       const byte* prime, word32 primeSz, int partial)
1513
{
1514
    int ret = 0;
1515
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1516
    mp_int* y = NULL;
1517
    mp_int* p = NULL;
1518
    mp_int* q = NULL;
1519
#else
1520
    mp_int y[1];
1521
    mp_int p[1];
1522
    mp_int q[1];
1523
#endif
1524
1525
    if (key == NULL || pub == NULL) {
1526
        return BAD_FUNC_ARG;
1527
    }
1528
1529
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1530
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1531
    if (y == NULL)
1532
        return MEMORY_E;
1533
    p = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1534
    if (p == NULL) {
1535
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1536
        return MEMORY_E;
1537
    }
1538
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1539
    if (q == NULL) {
1540
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1541
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1542
        return MEMORY_E;
1543
    }
1544
#endif
1545
1546
    if (mp_init_multi(y, p, q, NULL, NULL, NULL) != MP_OKAY) {
1547
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1548
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1549
        XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1550
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1551
    #endif
1552
        return MP_INIT_E;
1553
    }
1554
1555
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
1556
1557
    if (mp_read_unsigned_bin(y, pub, pubSz) != MP_OKAY) {
1558
        ret = MP_READ_E;
1559
    }
1560
1561
    if (ret == 0 && prime != NULL) {
1562
        if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1563
            ret = MP_READ_E;
1564
1565
    } else if (mp_iszero(&key->q) == MP_NO) {
1566
        /* use q available in DhKey */
1567
        if (mp_copy(&key->q, q) != MP_OKAY)
1568
            ret = MP_INIT_E;
1569
    }
1570
1571
    /* SP 800-56Ar3, section 5.6.2.3.2 */
1572
    /* pub (y) should not be 0 or 1 */
1573
    if (ret == 0 && mp_cmp_d(y, 2) == MP_LT) {
1574
        ret = MP_CMP_E;
1575
    }
1576
1577
    /* pub (y) shouldn't be greater than or equal to p - 1 */
1578
    if (ret == 0 && mp_copy(&key->p, p) != MP_OKAY) {
1579
        ret = MP_INIT_E;
1580
    }
1581
    if (ret == 0 && mp_sub_d(p, 2, p) != MP_OKAY) {
1582
        ret = MP_SUB_E;
1583
    }
1584
    if (ret == 0 && mp_cmp(y, p) == MP_GT) {
1585
        ret = MP_CMP_E;
1586
    }
1587
1588
    if (!partial) {
1589
        if (ret == 0 && (prime != NULL || (mp_iszero(&key->q) == MP_NO) )) {
1590
1591
            /* restore key->p into p */
1592
            if (mp_copy(&key->p, p) != MP_OKAY)
1593
                ret = MP_INIT_E;
1594
        }
1595
1596
        /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */
1597
        if (ret == 0 && prime != NULL) {
1598
#ifdef WOLFSSL_HAVE_SP_DH
1599
#ifndef WOLFSSL_SP_NO_2048
1600
            if (mp_count_bits(&key->p) == 2048) {
1601
                ret = sp_ModExp_2048(y, q, p, y);
1602
                if (ret != 0)
1603
                    ret = MP_EXPTMOD_E;
1604
            }
1605
            else
1606
#endif
1607
#ifndef WOLFSSL_SP_NO_3072
1608
            if (mp_count_bits(&key->p) == 3072) {
1609
                ret = sp_ModExp_3072(y, q, p, y);
1610
                if (ret != 0)
1611
                    ret = MP_EXPTMOD_E;
1612
            }
1613
            else
1614
#endif
1615
#ifdef WOLFSSL_SP_4096
1616
            if (mp_count_bits(&key->p) == 4096) {
1617
                ret = sp_ModExp_4096(y, q, p, y);
1618
                if (ret != 0)
1619
                    ret = MP_EXPTMOD_E;
1620
            }
1621
            else
1622
#endif
1623
#endif
1624
1625
            {
1626
#if !defined(WOLFSSL_SP_MATH)
1627
                /* calculate (y^q) mod(p), store back into y */
1628
                if (mp_exptmod(y, q, p, y) != MP_OKAY)
1629
                    ret = MP_EXPTMOD_E;
1630
#else
1631
                ret = WC_KEY_SIZE_E;
1632
#endif
1633
            }
1634
1635
            /* verify above == 1 */
1636
            if (ret == 0 && mp_cmp_d(y, 1) != MP_EQ)
1637
                ret = MP_CMP_E;
1638
        }
1639
    }
1640
1641
    mp_clear(y);
1642
    mp_clear(p);
1643
    mp_clear(q);
1644
1645
    RESTORE_VECTOR_REGISTERS();
1646
1647
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1648
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1649
    XFREE(p, key->heap, DYNAMIC_TYPE_DH);
1650
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
1651
#endif
1652
1653
    return ret;
1654
}
1655
1656
1657
/* Performs a full public-key validation routine. */
1658
int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz,
1659
                        const byte* prime, word32 primeSz)
1660
0
{
1661
0
    return _ffc_validate_public_key(key, pub, pubSz, prime, primeSz, 0);
1662
0
}
1663
1664
1665
/* Check DH Public Key for invalid numbers. Performs a partial public-key
1666
 * validation routine.
1667
 *
1668
 * key   DH key group parameters.
1669
 * pub   Public Key.
1670
 * pubSz Public Key size.
1671
 *
1672
 *  returns 0 on success or error code
1673
 */
1674
int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz)
1675
113
{
1676
113
    return _ffc_validate_public_key(key, pub, pubSz, NULL, 0, 1);
1677
113
}
1678
1679
1680
/**
1681
 * Quick validity check of public key value against prime.
1682
 * Checks are:
1683
 *   - Public key not 0 or 1
1684
 *   - Public key not equal to prime or prime - 1
1685
 *   - Public key not bigger than prime.
1686
 *
1687
 * prime    Big-endian encoding of prime in bytes.
1688
 * primeSz  Size of prime in bytes.
1689
 * pub      Big-endian encoding of public key in bytes.
1690
 * pubSz    Size of public key in bytes.
1691
 */
1692
int wc_DhCheckPubValue(const byte* prime, word32 primeSz, const byte* pub,
1693
                       word32 pubSz)
1694
471
{
1695
471
    int ret = 0;
1696
471
    word32 i;
1697
1698
700
    for (i = 0; i < pubSz && pub[i] == 0; i++) {
1699
229
    }
1700
471
    pubSz -= i;
1701
471
    pub += i;
1702
1703
471
    if (pubSz == 0 || (pubSz == 1 && pub[0] == 1))
1704
9
        ret = MP_VAL;
1705
462
    else if (pubSz == primeSz) {
1706
0
        for (i = 0; i < pubSz-1 && pub[i] == prime[i]; i++) {
1707
0
        }
1708
0
        if (i == pubSz-1 && (pub[i] == prime[i] || pub[i] == prime[i] - 1))
1709
0
            ret = MP_VAL;
1710
0
        else if (pub[i] > prime[i])
1711
0
            ret = MP_VAL;
1712
0
    }
1713
462
    else if (pubSz > primeSz)
1714
0
        ret = MP_VAL;
1715
1716
471
    return ret;
1717
471
}
1718
1719
1720
/* Check DH Private Key for invalid numbers, optionally allowing
1721
 * the private key to be checked against the large prime (q).
1722
 * Check per process in SP 800-56Ar3, section 5.6.2.1.2.
1723
 *
1724
 * key     DH key group parameters.
1725
 * priv    Private Key.
1726
 * privSz  Private Key size.
1727
 * prime   Large prime (q), optionally NULL to skip check
1728
 * primeSz Size of large prime
1729
 *
1730
 *  returns 0 on success or error code
1731
 */
1732
int wc_DhCheckPrivKey_ex(DhKey* key, const byte* priv, word32 privSz,
1733
                         const byte* prime, word32 primeSz)
1734
0
{
1735
0
    int ret = 0;
1736
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1737
0
    mp_int* x = NULL;
1738
0
    mp_int* q = NULL;
1739
#else
1740
    mp_int x[1];
1741
    mp_int q[1];
1742
#endif
1743
1744
0
    if (key == NULL || priv == NULL) {
1745
0
        return BAD_FUNC_ARG;
1746
0
    }
1747
1748
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1749
0
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1750
0
    if (x == NULL)
1751
0
        return MEMORY_E;
1752
0
    q = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1753
0
    if (q == NULL) {
1754
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1755
0
        return MEMORY_E;
1756
0
    }
1757
0
#endif
1758
1759
0
    if (mp_init_multi(x, q, NULL, NULL, NULL, NULL) != MP_OKAY) {
1760
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1761
0
        XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1762
0
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1763
0
    #endif
1764
0
        return MP_INIT_E;
1765
0
    }
1766
1767
0
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY) {
1768
0
        ret = MP_READ_E;
1769
0
    }
1770
1771
0
    if (ret == 0) {
1772
    #ifdef WOLFSSL_CHECK_MEM_ZERO
1773
        mp_memzero_add("wc_DhCheckPrivKey_ex x", x);
1774
    #endif
1775
0
        if (prime != NULL) {
1776
0
            if (mp_read_unsigned_bin(q, prime, primeSz) != MP_OKAY)
1777
0
                ret = MP_READ_E;
1778
0
        }
1779
0
        else if (mp_iszero(&key->q) == MP_NO) {
1780
            /* use q available in DhKey */
1781
0
            if (mp_copy(&key->q, q) != MP_OKAY)
1782
0
                ret = MP_INIT_E;
1783
0
        }
1784
0
    }
1785
1786
    /* priv (x) should not be 0 */
1787
0
    if (ret == 0) {
1788
0
        if (mp_cmp_d(x, 0) == MP_EQ)
1789
0
            ret = MP_CMP_E;
1790
0
    }
1791
1792
0
    if (ret == 0) {
1793
0
        if (mp_iszero(q) == MP_NO) {
1794
            /* priv (x) shouldn't be greater than q - 1 */
1795
0
            if (mp_copy(&key->q, q) != MP_OKAY)
1796
0
                ret = MP_INIT_E;
1797
0
            if (ret == 0) {
1798
0
                if (mp_sub_d(q, 1, q) != MP_OKAY)
1799
0
                    ret = MP_SUB_E;
1800
0
            }
1801
0
            if (ret == 0) {
1802
0
                if (mp_cmp(x, q) == MP_GT)
1803
0
                    ret = DH_CHECK_PRIV_E;
1804
0
            }
1805
0
        }
1806
0
    }
1807
1808
0
    mp_forcezero(x);
1809
0
    mp_clear(q);
1810
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1811
0
    XFREE(q, key->heap, DYNAMIC_TYPE_DH);
1812
0
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
1813
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1814
    mp_memzero_check(x);
1815
#endif
1816
1817
0
    return ret;
1818
0
}
1819
1820
1821
/* Check DH Private Key for invalid numbers
1822
 *
1823
 * key    DH key group parameters.
1824
 * priv   Private Key.
1825
 * privSz Private Key size.
1826
 *
1827
 *  returns 0 on success or error code
1828
 */
1829
int wc_DhCheckPrivKey(DhKey* key, const byte* priv, word32 privSz)
1830
0
{
1831
0
    return wc_DhCheckPrivKey_ex(key, priv, privSz, NULL, 0);
1832
0
}
1833
1834
1835
/* Performs a Pairwise Consistency Test on an FFC key pair. */
1836
/* Check DH Keys for pair-wise consistency per process in
1837
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC. */
1838
static int _ffc_pairwise_consistency_test(DhKey* key,
1839
        const byte* pub, word32 pubSz, const byte* priv, word32 privSz)
1840
0
{
1841
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1842
0
    mp_int* publicKey = NULL;
1843
0
    mp_int* privateKey = NULL;
1844
0
    mp_int* checkKey = NULL;
1845
#else
1846
    mp_int publicKey[1];
1847
    mp_int privateKey[1];
1848
    mp_int checkKey[1];
1849
#endif
1850
0
    int ret = 0;
1851
1852
0
    if (key == NULL || pub == NULL || priv == NULL)
1853
0
        return BAD_FUNC_ARG;
1854
0
    if (mp_iseven(&key->p) == MP_YES)
1855
0
        return MP_VAL;
1856
1857
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1858
0
    publicKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1859
0
    if (publicKey == NULL)
1860
0
        return MEMORY_E;
1861
0
    privateKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1862
0
    if (privateKey == NULL) {
1863
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1864
0
        return MEMORY_E;
1865
0
    }
1866
0
    checkKey = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
1867
0
    if (checkKey == NULL) {
1868
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1869
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1870
0
        return MEMORY_E;
1871
0
    }
1872
0
#endif
1873
1874
0
    if (mp_init_multi(publicKey, privateKey, checkKey,
1875
0
                      NULL, NULL, NULL) != MP_OKAY) {
1876
1877
0
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1878
0
        XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1879
0
        XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1880
0
        XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
1881
0
    #endif
1882
0
        return MP_INIT_E;
1883
0
    }
1884
1885
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
1886
1887
    /* Load the private and public keys into big integers. */
1888
0
    if (mp_read_unsigned_bin(publicKey, pub, pubSz) != MP_OKAY ||
1889
0
        mp_read_unsigned_bin(privateKey, priv, privSz) != MP_OKAY) {
1890
1891
0
        ret = MP_READ_E;
1892
0
    }
1893
#ifdef WOLFSSL_CHECK_MEM_ZERO
1894
    mp_memzero_add("_ffc_pairwise_consistency_test privateKey", privateKey);
1895
#endif
1896
1897
    /* Calculate checkKey = g^privateKey mod p */
1898
0
    if (ret == 0) {
1899
0
#ifdef WOLFSSL_HAVE_SP_DH
1900
0
#ifndef WOLFSSL_SP_NO_2048
1901
0
        if (mp_count_bits(&key->p) == 2048) {
1902
0
            ret = sp_ModExp_2048(&key->g, privateKey, &key->p, checkKey);
1903
0
            if (ret != 0)
1904
0
                ret = MP_EXPTMOD_E;
1905
0
        }
1906
0
        else
1907
0
#endif
1908
0
#ifndef WOLFSSL_SP_NO_3072
1909
0
        if (mp_count_bits(&key->p) == 3072) {
1910
0
            ret = sp_ModExp_3072(&key->g, privateKey, &key->p, checkKey);
1911
0
            if (ret != 0)
1912
0
                ret = MP_EXPTMOD_E;
1913
0
        }
1914
0
        else
1915
0
#endif
1916
0
#ifdef WOLFSSL_SP_4096
1917
0
        if (mp_count_bits(&key->p) == 4096) {
1918
0
            ret = sp_ModExp_4096(&key->g, privateKey, &key->p, checkKey);
1919
0
            if (ret != 0)
1920
0
                ret = MP_EXPTMOD_E;
1921
0
        }
1922
0
        else
1923
0
#endif
1924
0
#endif
1925
0
        {
1926
#if !defined(WOLFSSL_SP_MATH)
1927
            if (mp_exptmod(&key->g, privateKey, &key->p, checkKey) != MP_OKAY)
1928
                ret = MP_EXPTMOD_E;
1929
#else
1930
0
            ret = WC_KEY_SIZE_E;
1931
0
#endif
1932
0
        }
1933
0
    }
1934
1935
    /* Compare the calculated public key to the supplied check value. */
1936
0
    if (ret == 0) {
1937
0
        if (mp_cmp(checkKey, publicKey) != MP_EQ)
1938
0
            ret = MP_CMP_E;
1939
0
    }
1940
1941
0
    mp_forcezero(privateKey);
1942
0
    mp_clear(publicKey);
1943
0
    mp_clear(checkKey);
1944
1945
0
    RESTORE_VECTOR_REGISTERS();
1946
1947
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1948
0
    XFREE(checkKey, key->heap, DYNAMIC_TYPE_DH);
1949
0
    XFREE(privateKey, key->heap, DYNAMIC_TYPE_DH);
1950
0
    XFREE(publicKey, key->heap, DYNAMIC_TYPE_DH);
1951
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
1952
    mp_memzero_check(privateKey);
1953
#endif
1954
1955
0
    return ret;
1956
0
}
1957
1958
1959
/* Check DH Keys for pair-wise consistency per process in
1960
 * SP 800-56Ar3, section 5.6.2.1.4, method (b) for FFC.
1961
 *
1962
 * key    DH key group parameters.
1963
 * pub    Public Key.
1964
 * pubSz  Public Key size.
1965
 * priv   Private Key.
1966
 * privSz Private Key size.
1967
 *
1968
 *  returns 0 on success or error code
1969
 */
1970
int wc_DhCheckKeyPair(DhKey* key, const byte* pub, word32 pubSz,
1971
                      const byte* priv, word32 privSz)
1972
0
{
1973
0
    return _ffc_pairwise_consistency_test(key, pub, pubSz, priv, privSz);
1974
0
}
1975
1976
1977
int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
1978
    byte* priv, word32* privSz, byte* pub, word32* pubSz)
1979
6.53k
{
1980
6.53k
    int ret;
1981
1982
6.53k
    if (key == NULL || rng == NULL || priv == NULL || privSz == NULL ||
1983
6.49k
                                                pub == NULL || pubSz == NULL) {
1984
70
        return BAD_FUNC_ARG;
1985
70
    }
1986
1987
#ifdef WOLFSSL_KCAPI_DH
1988
    (void)priv;
1989
    (void)privSz;
1990
    ret = KcapiDh_MakeKey(key, pub, pubSz);
1991
#else
1992
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
1993
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
1994
        ret = wc_DhGenerateKeyPair_Async(key, rng, priv, privSz, pub, pubSz);
1995
    }
1996
    else
1997
#endif
1998
6.46k
    {
1999
6.46k
        ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
2000
6.46k
    }
2001
6.46k
#endif /* WOLFSSL_KCAPI_DH */
2002
2003
6.46k
    return ret;
2004
6.53k
}
2005
2006
#ifndef WOLFSSL_KCAPI_DH
2007
static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz,
2008
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz, int ct)
2009
222
{
2010
222
    int ret = 0;
2011
222
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2012
222
    mp_int* y = NULL;
2013
#if !defined(WOLFSSL_SP_MATH)
2014
    mp_int* x = NULL;
2015
    mp_int* z = NULL;
2016
#endif
2017
#else
2018
    mp_int y[1];
2019
#if !defined(WOLFSSL_SP_MATH)
2020
    mp_int x[1];
2021
    mp_int z[1];
2022
#endif
2023
#endif
2024
2025
222
    if (mp_iseven(&key->p) == MP_YES) {
2026
13
        return MP_VAL;
2027
13
    }
2028
#ifdef WOLFSSL_VALIDATE_FFC_IMPORT
2029
    if (wc_DhCheckPrivKey(key, priv, privSz) != 0) {
2030
        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPrivKey failed");
2031
        return DH_CHECK_PRIV_E;
2032
    }
2033
2034
    if (wc_DhCheckPubKey(key, otherPub, pubSz) != 0) {
2035
        WOLFSSL_MSG("wc_DhAgree wc_DhCheckPubKey failed");
2036
        return DH_CHECK_PUB_E;
2037
    }
2038
#endif
2039
2040
209
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2041
209
    y = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2042
209
    if (y == NULL)
2043
26
        return MEMORY_E;
2044
#if !defined(WOLFSSL_SP_MATH)
2045
    x = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2046
    if (x == NULL) {
2047
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2048
        return MEMORY_E;
2049
    }
2050
    z = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_DH);
2051
    if (z == NULL) {
2052
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2053
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2054
        return MEMORY_E;
2055
    }
2056
#endif
2057
183
#endif
2058
2059
183
#ifdef WOLFSSL_HAVE_SP_DH
2060
183
    if (0
2061
183
#ifndef WOLFSSL_SP_NO_2048
2062
183
        || mp_count_bits(&key->p) == 2048
2063
92
#endif
2064
92
#ifndef WOLFSSL_SP_NO_3072
2065
92
        || mp_count_bits(&key->p) == 3072
2066
84
#endif
2067
84
#ifdef WOLFSSL_SP_4096
2068
84
        || mp_count_bits(&key->p) == 4096
2069
183
#endif
2070
183
       ) {
2071
143
        int i = (int)*agreeSz - 1;
2072
2073
143
        if (mp_init(y) != MP_OKAY)
2074
0
            ret = MP_INIT_E;
2075
2076
143
        if (ret == 0) {
2077
143
            SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2078
2079
143
            if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2080
2
                ret = MP_READ_E;
2081
2082
143
            if (ret == 0) {
2083
141
            #ifndef WOLFSSL_SP_NO_2048
2084
141
                if (mp_count_bits(&key->p) == 2048) {
2085
89
                    ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree,
2086
89
                                        agreeSz);
2087
89
                }
2088
141
            #endif
2089
141
            #ifndef WOLFSSL_SP_NO_3072
2090
141
                if (mp_count_bits(&key->p) == 3072) {
2091
8
                    ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree,
2092
8
                                        agreeSz);
2093
8
                }
2094
141
            #endif
2095
141
            #ifdef WOLFSSL_SP_4096
2096
141
                if (mp_count_bits(&key->p) == 4096) {
2097
44
                    ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree,
2098
44
                                        agreeSz);
2099
44
                }
2100
141
            #endif
2101
141
            }
2102
2103
143
            mp_clear(y);
2104
2105
143
            RESTORE_VECTOR_REGISTERS();
2106
143
        }
2107
2108
        /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */
2109
143
        if ((ret == 0) &&
2110
128
            ((*agreeSz == 0) || ((*agreeSz == 1) && (agree[0] == 1))))
2111
8
        {
2112
8
            ret = MP_VAL;
2113
8
        }
2114
2115
143
        if ((ret == 0) && ct) {
2116
0
            volatile word16 mask = 0xff;
2117
0
            sword16 o = (sword16)(*agreeSz - 1);
2118
2119
0
            *agreeSz = (word32)(i + 1);
2120
0
            for (; i >= 0 ; i--) {
2121
0
                agree[i] = agree[o] & (byte)mask;
2122
0
                mask = ctMask16LT(0, (int)o);
2123
0
                o = (sword16)(o + (sword16)mask);
2124
0
            }
2125
0
        }
2126
2127
143
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2128
    #if !defined(WOLFSSL_SP_MATH)
2129
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2130
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2131
    #endif
2132
143
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2133
143
    #endif
2134
143
        return ret;
2135
143
    }
2136
40
#endif
2137
2138
#if !defined(WOLFSSL_SP_MATH)
2139
    if (mp_init_multi(x, y, z, 0, 0, 0) != MP_OKAY) {
2140
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2141
        XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2142
        XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2143
        XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2144
    #endif
2145
        return MP_INIT_E;
2146
    }
2147
#if defined(WOLFSSL_SP_MATH_ALL)
2148
    if (ct) {
2149
        /* TFM and Integer implementations keep high words zero.
2150
         * SP math implementation needs all words set to zero as it doesn't
2151
         * ensure unused words are zero. */
2152
        mp_forcezero(x);
2153
    }
2154
#endif
2155
2156
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
2157
2158
    if (mp_read_unsigned_bin(x, priv, privSz) != MP_OKAY)
2159
        ret = MP_READ_E;
2160
#ifdef WOLFSSL_CHECK_MEM_ZERO
2161
    if (ret == 0)
2162
        mp_memzero_add("wc_DhAgree_Sync x", x);
2163
#endif
2164
2165
    if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY)
2166
        ret = MP_READ_E;
2167
2168
    if (ret == 0) {
2169
        if (ct) {
2170
            int bits;
2171
2172
            /* x is mod q but if q not available, use p (> q). */
2173
            if (mp_iszero(&key->q) == MP_NO) {
2174
                bits = mp_count_bits(&key->q);
2175
            }
2176
            else {
2177
                bits = mp_count_bits(&key->p);
2178
            }
2179
            /* Exponentiate to the maximum words of a valid x to ensure a
2180
             * constant time operation. */
2181
            ret = mp_exptmod_ex(y, x, (bits + DIGIT_BIT - 1) / DIGIT_BIT,
2182
                                &key->p, z);
2183
        }
2184
        else {
2185
            ret = mp_exptmod(y, x, &key->p, z);
2186
        }
2187
        if (ret != MP_OKAY)
2188
            ret = MP_EXPTMOD_E;
2189
    }
2190
2191
#ifdef WOLFSSL_CHECK_MEM_ZERO
2192
    if (ret == 0)
2193
        mp_memzero_add("wc_DhAgree_Sync z", z);
2194
#endif
2195
2196
    /* make sure z is not one (SP800-56A, 5.7.1.1) */
2197
    if (ret == 0 && (mp_cmp_d(z, 1) == MP_EQ))
2198
        ret = MP_VAL;
2199
2200
    if (ret == 0) {
2201
        if (ct) {
2202
            /* Put the secret into a buffer in constant time. */
2203
            ret = mp_to_unsigned_bin_len_ct(z, agree, (int)*agreeSz);
2204
        }
2205
        else {
2206
            ret = mp_to_unsigned_bin(z, agree);
2207
            if (ret == MP_OKAY)
2208
                *agreeSz = (word32)mp_unsigned_bin_size(z);
2209
        }
2210
    }
2211
2212
    mp_forcezero(z);
2213
    mp_clear(y);
2214
    mp_forcezero(x);
2215
2216
    RESTORE_VECTOR_REGISTERS();
2217
2218
#else
2219
40
    (void)ct;
2220
40
    ret = WC_KEY_SIZE_E;
2221
40
#endif
2222
2223
40
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
2224
#if !defined(WOLFSSL_SP_MATH)
2225
    XFREE(z, key->heap, DYNAMIC_TYPE_DH);
2226
    XFREE(x, key->heap, DYNAMIC_TYPE_DH);
2227
#endif
2228
40
    XFREE(y, key->heap, DYNAMIC_TYPE_DH);
2229
#elif defined(WOLFSSL_CHECK_MEM_ZERO)
2230
#if !defined(WOLFSSL_SP_MATH)
2231
    mp_memzero_check(x);
2232
    mp_memzero_check(z);
2233
#endif
2234
#endif
2235
2236
40
    return ret;
2237
183
}
2238
2239
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2240
static int wc_DhAgree_Async(DhKey* key, byte* agree, word32* agreeSz,
2241
    const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz)
2242
{
2243
    int ret;
2244
2245
#if defined(HAVE_INTEL_QA)
2246
    word32 pBits;
2247
2248
    /* QAT DH sizes: 768, 1024, 1536, 2048, 3072 and 4096 bits */
2249
    pBits = mp_unsigned_bin_size(&key->p) * 8;
2250
    if (pBits == 768 ||  pBits == 1024 || pBits == 1536 ||
2251
        pBits == 2048 || pBits == 3072 || pBits == 4096) {
2252
        ret = wc_mp_to_bigint(&key->p, &key->p.raw);
2253
        if (ret == MP_OKAY)
2254
            ret = IntelQaDhAgree(&key->asyncDev, &key->p.raw,
2255
                agree, agreeSz, priv, privSz, otherPub, pubSz);
2256
        return ret;
2257
    }
2258
2259
#elif defined(HAVE_CAVIUM)
2260
    /* TODO: Not implemented - use software for now */
2261
2262
#elif defined(WOLFSSL_ASYNC_CRYPT_SW)
2263
    if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_DH_AGREE)) {
2264
        WC_ASYNC_SW* sw = &key->asyncDev.sw;
2265
        sw->dhAgree.key = key;
2266
        sw->dhAgree.agree = agree;
2267
        sw->dhAgree.agreeSz = agreeSz;
2268
        sw->dhAgree.priv = priv;
2269
        sw->dhAgree.privSz = privSz;
2270
        sw->dhAgree.otherPub = otherPub;
2271
        sw->dhAgree.pubSz = pubSz;
2272
        return WC_PENDING_E;
2273
    }
2274
#endif
2275
2276
    /* otherwise use software DH */
2277
    ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz,
2278
                          0);
2279
2280
    return ret;
2281
}
2282
#endif /* WOLFSSL_ASYNC_CRYPT */
2283
#endif /* !WOLFSSL_KCAPI_DH */
2284
2285
int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv,
2286
            word32 privSz, const byte* otherPub, word32 pubSz)
2287
2.18k
{
2288
2.18k
    int ret = 0;
2289
2290
2.18k
    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
2291
2.12k
                                                            otherPub == NULL) {
2292
103
        return BAD_FUNC_ARG;
2293
103
    }
2294
2295
#ifdef WOLFSSL_KCAPI_DH
2296
    (void)priv;
2297
    (void)privSz;
2298
    ret = KcapiDh_SharedSecret(key, otherPub, pubSz, agree, agreeSz);
2299
#else
2300
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_DH)
2301
    if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_DH) {
2302
        ret = wc_DhAgree_Async(key, agree, agreeSz, priv, privSz, otherPub,
2303
                               pubSz);
2304
    }
2305
    else
2306
#endif
2307
2.08k
    {
2308
2.08k
        ret = wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub,
2309
2.08k
                              pubSz, 0);
2310
2.08k
    }
2311
2.08k
#endif /* WOLFSSL_KCAPI_DH */
2312
2313
2.08k
    return ret;
2314
2.18k
}
2315
2316
int wc_DhAgree_ct(DhKey* key, byte* agree, word32 *agreeSz, const byte* priv,
2317
            word32 privSz, const byte* otherPub, word32 pubSz)
2318
0
{
2319
0
    word32 requested_agreeSz;
2320
2321
0
    if (key == NULL || agree == NULL || agreeSz == NULL || priv == NULL ||
2322
0
                                                            otherPub == NULL) {
2323
0
        return BAD_FUNC_ARG;
2324
0
    }
2325
2326
0
    requested_agreeSz = (word32)mp_unsigned_bin_size(&key->p);
2327
0
    if (requested_agreeSz > *agreeSz) {
2328
0
        return BUFFER_E;
2329
0
    }
2330
0
    *agreeSz = requested_agreeSz;
2331
2332
0
    return wc_DhAgree_Sync(key, agree, agreeSz, priv, privSz, otherPub, pubSz,
2333
0
                           1);
2334
0
}
2335
2336
#ifdef WOLFSSL_DH_EXTRA
2337
WOLFSSL_LOCAL int wc_DhKeyCopy(DhKey* src, DhKey* dst)
2338
{
2339
    int ret;
2340
2341
    if (!src || !dst || src == dst) {
2342
        WOLFSSL_MSG("Parameters not provided or are the same");
2343
        return BAD_FUNC_ARG;
2344
    }
2345
2346
    if ((ret = mp_copy(&src->p, &dst->p)) != MP_OKAY) {
2347
        WOLFSSL_MSG("mp_copy error");
2348
        return ret;
2349
    }
2350
2351
    if ((ret = mp_copy(&src->g, &dst->g)) != MP_OKAY) {
2352
        WOLFSSL_MSG("mp_copy error");
2353
        return ret;
2354
    }
2355
2356
    if ((ret = mp_copy(&src->q, &dst->q)) != MP_OKAY) {
2357
        WOLFSSL_MSG("mp_copy error");
2358
        return ret;
2359
    }
2360
2361
    if ((ret = mp_copy(&src->pub, &dst->pub)) != MP_OKAY) {
2362
        WOLFSSL_MSG("mp_copy error");
2363
        return ret;
2364
    }
2365
2366
    if ((ret = mp_copy(&src->priv, &dst->priv)) != MP_OKAY) {
2367
        WOLFSSL_MSG("mp_copy error");
2368
        return ret;
2369
    }
2370
#ifdef WOLFSSL_CHECK_MEM_ZERO
2371
    mp_memzero_add("wc_DhKeyCopy dst->priv", &dst->priv);
2372
#endif
2373
2374
    dst->heap = src->heap;
2375
2376
    return MP_OKAY;
2377
}
2378
2379
/* Sets private and public key in DhKey if both are available, otherwise sets
2380
    either private or public key, depending on which is available. */
2381
int wc_DhImportKeyPair(DhKey* key, const byte* priv, word32 privSz,
2382
                       const byte* pub, word32 pubSz)
2383
{
2384
    byte havePriv, havePub;
2385
2386
    if (key == NULL) {
2387
        return BAD_FUNC_ARG;
2388
    }
2389
2390
    havePriv = ( (priv != NULL) && (privSz > 0) );
2391
    havePub  = ( (pub  != NULL) && (pubSz  > 0) );
2392
2393
    if (!havePub && !havePriv) {
2394
        WOLFSSL_MSG("No Public or Private Key to Set");
2395
        return BAD_FUNC_ARG;
2396
    }
2397
2398
    /* Set Private Key */
2399
    if (havePriv) {
2400
        /* may have leading 0 */
2401
        if (priv[0] == 0) {
2402
            privSz--; priv++;
2403
        }
2404
        if (mp_init(&key->priv) != MP_OKAY)
2405
            havePriv = 0;
2406
    }
2407
    if (havePriv) {
2408
        if (mp_read_unsigned_bin(&key->priv, priv, privSz) != MP_OKAY) {
2409
            mp_forcezero(&key->priv);
2410
            havePriv = 0;
2411
        } else {
2412
            WOLFSSL_MSG("DH Private Key Set");
2413
        #ifdef WOLFSSL_CHECK_MEM_ZERO
2414
            mp_memzero_add("wc_DhImportKeyPair key->priv", &key->priv);
2415
        #endif
2416
        }
2417
    }
2418
2419
    /* Set Public Key */
2420
    if (havePub) {
2421
        /* may have leading 0 */
2422
        if (pub[0] == 0) {
2423
            pubSz--; pub++;
2424
        }
2425
        if (mp_init(&key->pub) != MP_OKAY)
2426
            havePub = 0;
2427
    }
2428
    if (havePub) {
2429
        if (mp_read_unsigned_bin(&key->pub, pub, pubSz) != MP_OKAY) {
2430
            mp_clear(&key->pub);
2431
            havePub = 0;
2432
            if (havePriv) {
2433
                mp_forcezero(&key->priv);
2434
                havePriv = 0; /* set to 0 to error out with failed read pub */
2435
            }
2436
        } else {
2437
            WOLFSSL_MSG("DH Public Key Set");
2438
        }
2439
    }
2440
2441
    if (havePriv == 0 && havePub == 0) {
2442
        return MEMORY_E;
2443
    }
2444
2445
    return 0;
2446
}
2447
2448
/* Can be used with WOLFSSL_DH_EXTRA when key is loaded with
2449
    wc_DhKeyDecode or wc_DhImportKeyPair */
2450
int wc_DhExportKeyPair(DhKey* key, byte* priv, word32* pPrivSz,
2451
    byte* pub, word32* pPubSz)
2452
{
2453
    int ret = 0;
2454
2455
    if (key == NULL || (priv && pPrivSz == NULL) || (pub && pPubSz == NULL)) {
2456
        return BAD_FUNC_ARG;
2457
    }
2458
2459
    if (priv) {
2460
        word32 privSz = (word32)mp_unsigned_bin_size(&key->priv);
2461
        if (privSz > *pPrivSz) {
2462
            return BUFFER_E;
2463
        }
2464
        *pPrivSz = privSz;
2465
        ret |= mp_to_unsigned_bin(&key->priv, priv);
2466
    }
2467
2468
    if (pub) {
2469
        word32 pubSz = (word32)mp_unsigned_bin_size(&key->pub);
2470
        if (pubSz > *pPubSz) {
2471
            return BUFFER_E;
2472
        }
2473
        *pPubSz = pubSz;
2474
        ret |= mp_to_unsigned_bin(&key->pub,  pub);
2475
    }
2476
2477
    if (ret != 0)
2478
        ret = ASN_DH_KEY_E;
2479
    return ret;
2480
}
2481
2482
#endif /* WOLFSSL_DH_EXTRA */
2483
2484
static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2485
                     word32 gSz, const byte* q, word32 qSz, int trusted,
2486
                     WC_RNG* rng)
2487
9.10k
{
2488
9.10k
    int ret = 0;
2489
9.10k
    mp_int* keyP = NULL;
2490
9.10k
    mp_int* keyG = NULL;
2491
2492
9.10k
    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) {
2493
369
        ret = BAD_FUNC_ARG;
2494
369
    }
2495
2496
9.10k
    SAVE_VECTOR_REGISTERS(return _svr_ret;);
2497
2498
9.10k
    if (ret == 0) {
2499
        /* may have leading 0 */
2500
8.73k
        if (p[0] == 0) {
2501
3.11k
            pSz--; p++;
2502
3.11k
        }
2503
2504
8.73k
        if (g[0] == 0) {
2505
1.52k
            gSz--; g++;
2506
1.52k
        }
2507
2508
8.73k
        if (q != NULL) {
2509
0
            if (q[0] == 0) {
2510
0
                qSz--; q++;
2511
0
            }
2512
0
        }
2513
2514
8.73k
        if (mp_init(&key->p) != MP_OKAY)
2515
0
            ret = MP_INIT_E;
2516
8.73k
    }
2517
2518
9.10k
    if (ret == 0) {
2519
8.73k
        if (mp_read_unsigned_bin(&key->p, p, pSz) != MP_OKAY)
2520
334
            ret = ASN_DH_KEY_E;
2521
8.40k
        else
2522
8.40k
            keyP = &key->p;
2523
8.73k
    }
2524
2525
9.10k
    if (ret == 0 && !trusted) {
2526
695
        int isPrime = 0;
2527
2528
        /* Short-circuit the primality check for p if it is one of the named
2529
         * public moduli (known primes) from RFC 7919.
2530
         */
2531
695
        #ifdef HAVE_FFDHE_2048
2532
695
        if ((pSz == sizeof(dh_ffdhe2048_p)) &&
2533
0
            (XMEMCMP(p, dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p)) == 0))
2534
0
        {
2535
0
            isPrime = 1;
2536
0
        }
2537
695
        else
2538
695
        #endif
2539
        #ifdef HAVE_FFDHE_3072
2540
        if ((pSz == sizeof(dh_ffdhe3072_p)) &&
2541
            (XMEMCMP(p, dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p)) == 0))
2542
        {
2543
            isPrime = 1;
2544
        }
2545
        else
2546
        #endif
2547
        #ifdef HAVE_FFDHE_4096
2548
        if ((pSz == sizeof(dh_ffdhe4096_p)) &&
2549
            (XMEMCMP(p, dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p)) == 0))
2550
        {
2551
            isPrime = 1;
2552
        }
2553
        else
2554
        #endif
2555
        #ifdef HAVE_FFDHE_6144
2556
        if ((pSz == sizeof(dh_ffdhe6144_p)) &&
2557
            (XMEMCMP(p, dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p)) == 0))
2558
        {
2559
            isPrime = 1;
2560
        }
2561
        else
2562
        #endif
2563
        #ifdef HAVE_FFDHE_8192
2564
        if ((pSz == sizeof(dh_ffdhe8192_p)) &&
2565
            (XMEMCMP(p, dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p)) == 0))
2566
        {
2567
            isPrime = 1;
2568
        }
2569
        else
2570
        #endif
2571
695
        {
2572
695
            if (rng != NULL)
2573
695
                ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng);
2574
0
            else
2575
0
                ret = mp_prime_is_prime(keyP, 8, &isPrime);
2576
695
        }
2577
2578
695
        if (ret == 0 && isPrime == 0)
2579
339
            ret = DH_CHECK_PUB_E;
2580
695
    }
2581
2582
9.10k
    if (ret == 0 && mp_init(&key->g) != MP_OKAY)
2583
0
        ret = MP_INIT_E;
2584
9.10k
    if (ret == 0) {
2585
8.06k
        if (mp_read_unsigned_bin(&key->g, g, gSz) != MP_OKAY)
2586
54
            ret = ASN_DH_KEY_E;
2587
8.01k
        else
2588
8.01k
            keyG = &key->g;
2589
8.06k
    }
2590
2591
9.10k
    if (ret == 0 && q != NULL) {
2592
0
        if (mp_init(&key->q) != MP_OKAY)
2593
0
            ret = MP_INIT_E;
2594
0
    }
2595
9.10k
    if (ret == 0 && q != NULL) {
2596
0
        if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY)
2597
0
            ret = MP_INIT_E;
2598
0
        else
2599
0
            key->trustedGroup = trusted;
2600
0
    }
2601
2602
9.10k
    if (ret != 0 && key != NULL) {
2603
1.09k
        if (keyG)
2604
0
            mp_clear(keyG);
2605
1.09k
        if (keyP)
2606
393
            mp_clear(keyP);
2607
1.09k
    }
2608
2609
9.10k
    RESTORE_VECTOR_REGISTERS();
2610
2611
9.10k
    return ret;
2612
9.10k
}
2613
2614
2615
int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2616
                   word32 gSz, const byte* q, word32 qSz, int trusted,
2617
                   WC_RNG* rng)
2618
696
{
2619
696
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng);
2620
696
}
2621
2622
2623
int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
2624
                   word32 gSz, const byte* q, word32 qSz)
2625
0
{
2626
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL);
2627
0
}
2628
2629
2630
/* not in asn anymore since no actual asn types used */
2631
int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
2632
                word32 gSz)
2633
8.41k
{
2634
    /* This should not have trusted set. */
2635
8.41k
    return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
2636
8.41k
}
2637
2638
2639
int wc_DhSetNamedKey(DhKey* key, int name)
2640
0
{
2641
0
    const byte* p = NULL;
2642
0
    const byte* g = NULL;
2643
0
    const byte* q = NULL;
2644
0
    word32 pSz = 0, gSz = 0, qSz = 0;
2645
2646
0
    switch (name) {
2647
0
        #ifdef HAVE_FFDHE_2048
2648
0
        case WC_FFDHE_2048:
2649
0
            p = dh_ffdhe2048_p;
2650
0
            pSz = sizeof(dh_ffdhe2048_p);
2651
0
            g = dh_ffdhe2048_g;
2652
0
            gSz = sizeof(dh_ffdhe2048_g);
2653
            #ifdef HAVE_FFDHE_Q
2654
            q = dh_ffdhe2048_q;
2655
            qSz = sizeof(dh_ffdhe2048_q);
2656
            #endif /* HAVE_FFDHE_Q */
2657
0
            break;
2658
0
        #endif /* HAVE_FFDHE_2048 */
2659
        #ifdef HAVE_FFDHE_3072
2660
        case WC_FFDHE_3072:
2661
            p = dh_ffdhe3072_p;
2662
            pSz = sizeof(dh_ffdhe3072_p);
2663
            g = dh_ffdhe3072_g;
2664
            gSz = sizeof(dh_ffdhe3072_g);
2665
            #ifdef HAVE_FFDHE_Q
2666
            q = dh_ffdhe3072_q;
2667
            qSz = sizeof(dh_ffdhe3072_q);
2668
            #endif /* HAVE_FFDHE_Q */
2669
            break;
2670
        #endif /* HAVE_FFDHE_3072 */
2671
        #ifdef HAVE_FFDHE_4096
2672
        case WC_FFDHE_4096:
2673
            p = dh_ffdhe4096_p;
2674
            pSz = sizeof(dh_ffdhe4096_p);
2675
            g = dh_ffdhe4096_g;
2676
            gSz = sizeof(dh_ffdhe4096_g);
2677
            #ifdef HAVE_FFDHE_Q
2678
            q = dh_ffdhe4096_q;
2679
            qSz = sizeof(dh_ffdhe4096_q);
2680
            #endif /* HAVE_FFDHE_Q */
2681
            break;
2682
        #endif /* HAVE_FFDHE_4096 */
2683
        #ifdef HAVE_FFDHE_6144
2684
        case WC_FFDHE_6144:
2685
            p = dh_ffdhe6144_p;
2686
            pSz = sizeof(dh_ffdhe6144_p);
2687
            g = dh_ffdhe6144_g;
2688
            gSz = sizeof(dh_ffdhe6144_g);
2689
            #ifdef HAVE_FFDHE_Q
2690
            q = dh_ffdhe6144_q;
2691
            qSz = sizeof(dh_ffdhe6144_q);
2692
            #endif /* HAVE_FFDHE_Q */
2693
            break;
2694
        #endif /* HAVE_FFDHE_6144 */
2695
        #ifdef HAVE_FFDHE_8192
2696
        case WC_FFDHE_8192:
2697
            p = dh_ffdhe8192_p;
2698
            pSz = sizeof(dh_ffdhe8192_p);
2699
            g = dh_ffdhe8192_g;
2700
            gSz = sizeof(dh_ffdhe8192_g);
2701
            #ifdef HAVE_FFDHE_Q
2702
            q = dh_ffdhe8192_q;
2703
            qSz = sizeof(dh_ffdhe8192_q);
2704
            #endif /* HAVE_FFDHE_Q */
2705
            break;
2706
        #endif /* HAVE_FFDHE_8192 */
2707
0
        default:
2708
0
            break;
2709
0
    }
2710
0
    return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
2711
0
}
2712
2713
2714
word32 wc_DhGetNamedKeyMinSize(int name)
2715
0
{
2716
0
    word32 size;
2717
2718
0
    switch (name) {
2719
0
        #ifdef HAVE_FFDHE_2048
2720
0
        case WC_FFDHE_2048:
2721
0
            size = 29;
2722
0
            break;
2723
0
        #endif /* HAVE_FFDHE_2048 */
2724
        #ifdef HAVE_FFDHE_3072
2725
        case WC_FFDHE_3072:
2726
            size = 34;
2727
            break;
2728
        #endif /* HAVE_FFDHE_3072 */
2729
        #ifdef HAVE_FFDHE_4096
2730
        case WC_FFDHE_4096:
2731
            size = 39;
2732
            break;
2733
        #endif /* HAVE_FFDHE_4096 */
2734
        #ifdef HAVE_FFDHE_6144
2735
        case WC_FFDHE_6144:
2736
            size = 46;
2737
            break;
2738
        #endif /* HAVE_FFDHE_6144 */
2739
        #ifdef HAVE_FFDHE_8192
2740
        case WC_FFDHE_8192:
2741
            size = 52;
2742
            break;
2743
        #endif /* HAVE_FFDHE_8192 */
2744
0
        default:
2745
0
            size = 0;
2746
0
    }
2747
2748
0
    return size;
2749
0
}
2750
2751
2752
/* Returns 1: params match
2753
 *         0: params differ */
2754
int wc_DhCmpNamedKey(int name, int noQ,
2755
        const byte* p, word32 pSz,
2756
        const byte* g, word32 gSz,
2757
        const byte* q, word32 qSz)
2758
0
{
2759
0
    const byte* pCmp = NULL;
2760
0
    const byte* qCmp = NULL;
2761
0
    const byte* gCmp = NULL;
2762
0
    word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0;
2763
0
    int cmp = 0, goodName = 1;
2764
2765
0
    switch (name) {
2766
0
        #ifdef HAVE_FFDHE_2048
2767
0
        case WC_FFDHE_2048:
2768
0
            pCmp = dh_ffdhe2048_p;
2769
0
            pCmpSz = sizeof(dh_ffdhe2048_p);
2770
0
            gCmp = dh_ffdhe2048_g;
2771
0
            gCmpSz = sizeof(dh_ffdhe2048_g);
2772
            #ifdef HAVE_FFDHE_Q
2773
            qCmp = dh_ffdhe2048_q;
2774
            qCmpSz = sizeof(dh_ffdhe2048_q);
2775
            #endif /* HAVE_FFDHE_Q */
2776
0
            break;
2777
0
        #endif /* HAVE_FFDHE_2048 */
2778
        #ifdef HAVE_FFDHE_3072
2779
        case WC_FFDHE_3072:
2780
            pCmp = dh_ffdhe3072_p;
2781
            pCmpSz = sizeof(dh_ffdhe3072_p);
2782
            gCmp = dh_ffdhe3072_g;
2783
            gCmpSz = sizeof(dh_ffdhe3072_g);
2784
            #ifdef HAVE_FFDHE_Q
2785
            qCmp = dh_ffdhe3072_q;
2786
            qCmpSz = sizeof(dh_ffdhe3072_q);
2787
            #endif /* HAVE_FFDHE_Q */
2788
            break;
2789
        #endif /* HAVE_FFDHE_3072 */
2790
        #ifdef HAVE_FFDHE_4096
2791
        case WC_FFDHE_4096:
2792
            pCmp = dh_ffdhe4096_p;
2793
            pCmpSz = sizeof(dh_ffdhe4096_p);
2794
            gCmp = dh_ffdhe4096_g;
2795
            gCmpSz = sizeof(dh_ffdhe4096_g);
2796
            #ifdef HAVE_FFDHE_Q
2797
            qCmp = dh_ffdhe4096_q;
2798
            qCmpSz = sizeof(dh_ffdhe4096_q);
2799
            #endif /* HAVE_FFDHE_Q */
2800
            break;
2801
        #endif /* HAVE_FFDHE_4096 */
2802
        #ifdef HAVE_FFDHE_6144
2803
        case WC_FFDHE_6144:
2804
            pCmp = dh_ffdhe6144_p;
2805
            pCmpSz = sizeof(dh_ffdhe6144_p);
2806
            gCmp = dh_ffdhe6144_g;
2807
            gCmpSz = sizeof(dh_ffdhe6144_g);
2808
            #ifdef HAVE_FFDHE_Q
2809
            qCmp = dh_ffdhe6144_q;
2810
            qCmpSz = sizeof(dh_ffdhe6144_q);
2811
            #endif /* HAVE_FFDHE_Q */
2812
            break;
2813
        #endif /* HAVE_FFDHE_6144 */
2814
        #ifdef HAVE_FFDHE_8192
2815
        case WC_FFDHE_8192:
2816
            pCmp = dh_ffdhe8192_p;
2817
            pCmpSz = sizeof(dh_ffdhe8192_p);
2818
            gCmp = dh_ffdhe8192_g;
2819
            gCmpSz = sizeof(dh_ffdhe8192_g);
2820
            #ifdef HAVE_FFDHE_Q
2821
            qCmp = dh_ffdhe8192_q;
2822
            qCmpSz = sizeof(dh_ffdhe8192_q);
2823
            #endif /* HAVE_FFDHE_Q */
2824
            break;
2825
        #endif /* HAVE_FFDHE_8192 */
2826
0
        default:
2827
0
            goodName = 0;
2828
0
    }
2829
2830
0
    if (goodName) {
2831
0
        cmp = (pSz == pCmpSz) && (gSz == gCmpSz) &&
2832
0
            (noQ || ((qCmp != NULL) && (qSz == qCmpSz) &&
2833
0
                     XMEMCMP(q, qCmp, qCmpSz) == 0)) &&
2834
0
            (XMEMCMP(p, pCmp, pCmpSz) == 0) &&
2835
0
            (XMEMCMP(g, gCmp, gCmpSz) == 0);
2836
0
    }
2837
2838
0
    return cmp;
2839
0
}
2840
2841
2842
int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q)
2843
0
{
2844
0
    word32 pSz = 0, gSz = 0, qSz = 0;
2845
2846
0
    switch (name) {
2847
0
        #ifdef HAVE_FFDHE_2048
2848
0
        case WC_FFDHE_2048:
2849
0
            pSz = sizeof(dh_ffdhe2048_p);
2850
0
            gSz = sizeof(dh_ffdhe2048_g);
2851
            #ifdef HAVE_FFDHE_Q
2852
            qSz = sizeof(dh_ffdhe2048_q);
2853
            #endif /* HAVE_FFDHE_Q */
2854
0
            break;
2855
0
        #endif /* HAVE_FFDHE_2048 */
2856
        #ifdef HAVE_FFDHE_3072
2857
        case WC_FFDHE_3072:
2858
            pSz = sizeof(dh_ffdhe3072_p);
2859
            gSz = sizeof(dh_ffdhe3072_g);
2860
            #ifdef HAVE_FFDHE_Q
2861
            qSz = sizeof(dh_ffdhe3072_q);
2862
            #endif /* HAVE_FFDHE_Q */
2863
            break;
2864
        #endif /* HAVE_FFDHE_3072 */
2865
        #ifdef HAVE_FFDHE_4096
2866
        case WC_FFDHE_4096:
2867
            pSz = sizeof(dh_ffdhe4096_p);
2868
            gSz = sizeof(dh_ffdhe4096_g);
2869
            #ifdef HAVE_FFDHE_Q
2870
            qSz = sizeof(dh_ffdhe4096_q);
2871
            #endif /* HAVE_FFDHE_Q */
2872
            break;
2873
        #endif /* HAVE_FFDHE_4096 */
2874
        #ifdef HAVE_FFDHE_6144
2875
        case WC_FFDHE_6144:
2876
            pSz = sizeof(dh_ffdhe6144_p);
2877
            gSz = sizeof(dh_ffdhe6144_g);
2878
            #ifdef HAVE_FFDHE_Q
2879
            qSz = sizeof(dh_ffdhe6144_q);
2880
            #endif /* HAVE_FFDHE_Q */
2881
            break;
2882
        #endif /* HAVE_FFDHE_6144 */
2883
        #ifdef HAVE_FFDHE_8192
2884
        case WC_FFDHE_8192:
2885
            pSz = sizeof(dh_ffdhe8192_p);
2886
            gSz = sizeof(dh_ffdhe8192_g);
2887
            #ifdef HAVE_FFDHE_Q
2888
            qSz = sizeof(dh_ffdhe8192_q);
2889
            #endif /* HAVE_FFDHE_Q */
2890
            break;
2891
        #endif /* HAVE_FFDHE_8192 */
2892
0
        default:
2893
0
            break;
2894
0
    }
2895
2896
0
    if (p != NULL) *p = pSz;
2897
0
    if (g != NULL) *g = gSz;
2898
0
    if (q != NULL) *q = qSz;
2899
2900
0
    return 0;
2901
0
}
2902
2903
2904
int wc_DhCopyNamedKey(int name,
2905
        byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz)
2906
0
{
2907
0
    const byte* pC = NULL;
2908
0
    const byte* gC = NULL;
2909
0
    const byte* qC = NULL;
2910
0
    word32 pCSz = 0, gCSz = 0, qCSz = 0;
2911
2912
0
    switch (name) {
2913
0
        #ifdef HAVE_FFDHE_2048
2914
0
        case WC_FFDHE_2048:
2915
0
            pC = dh_ffdhe2048_p;
2916
0
            pCSz = sizeof(dh_ffdhe2048_p);
2917
0
            gC = dh_ffdhe2048_g;
2918
0
            gCSz = sizeof(dh_ffdhe2048_g);
2919
            #ifdef HAVE_FFDHE_Q
2920
            qC = dh_ffdhe2048_q;
2921
            qCSz = sizeof(dh_ffdhe2048_q);
2922
            #endif /* HAVE_FFDHE_Q */
2923
0
            break;
2924
0
        #endif /* HAVE_FFDHE_2048 */
2925
        #ifdef HAVE_FFDHE_3072
2926
        case WC_FFDHE_3072:
2927
            pC = dh_ffdhe3072_p;
2928
            pCSz = sizeof(dh_ffdhe3072_p);
2929
            gC = dh_ffdhe3072_g;
2930
            gCSz = sizeof(dh_ffdhe3072_g);
2931
            #ifdef HAVE_FFDHE_Q
2932
            qC = dh_ffdhe3072_q;
2933
            qCSz = sizeof(dh_ffdhe3072_q);
2934
            #endif /* HAVE_FFDHE_Q */
2935
            break;
2936
        #endif /* HAVE_FFDHE_3072 */
2937
        #ifdef HAVE_FFDHE_4096
2938
        case WC_FFDHE_4096:
2939
            pC = dh_ffdhe4096_p;
2940
            pCSz = sizeof(dh_ffdhe4096_p);
2941
            gC = dh_ffdhe4096_g;
2942
            gCSz = sizeof(dh_ffdhe4096_g);
2943
            #ifdef HAVE_FFDHE_Q
2944
            qC = dh_ffdhe4096_q;
2945
            qCSz = sizeof(dh_ffdhe4096_q);
2946
            #endif /* HAVE_FFDHE_Q */
2947
            break;
2948
        #endif /* HAVE_FFDHE_4096 */
2949
        #ifdef HAVE_FFDHE_6144
2950
        case WC_FFDHE_6144:
2951
            pC = dh_ffdhe6144_p;
2952
            pCSz = sizeof(dh_ffdhe6144_p);
2953
            gC = dh_ffdhe6144_g;
2954
            gCSz = sizeof(dh_ffdhe6144_g);
2955
            #ifdef HAVE_FFDHE_Q
2956
            qC = dh_ffdhe6144_q;
2957
            qCSz = sizeof(dh_ffdhe6144_q);
2958
            #endif /* HAVE_FFDHE_Q */
2959
            break;
2960
        #endif /* HAVE_FFDHE_6144 */
2961
        #ifdef HAVE_FFDHE_8192
2962
        case WC_FFDHE_8192:
2963
            pC = dh_ffdhe8192_p;
2964
            pCSz = sizeof(dh_ffdhe8192_p);
2965
            gC = dh_ffdhe8192_g;
2966
            gCSz = sizeof(dh_ffdhe8192_g);
2967
            #ifdef HAVE_FFDHE_Q
2968
            qC = dh_ffdhe8192_q;
2969
            qCSz = sizeof(dh_ffdhe8192_q);
2970
            #endif /* HAVE_FFDHE_Q */
2971
            break;
2972
        #endif /* HAVE_FFDHE_8192 */
2973
0
        default:
2974
0
            break;
2975
0
    }
2976
2977
0
    if (p != NULL && pC != NULL)
2978
0
        XMEMCPY(p, pC, pCSz);
2979
0
    if (pSz != NULL)
2980
0
        *pSz = pCSz;
2981
0
    if (g != NULL && gC != NULL)
2982
0
        XMEMCPY(g, gC, gCSz);
2983
0
    if (gSz != NULL)
2984
0
        *gSz = gCSz;
2985
0
    if (q != NULL && qC != NULL)
2986
0
        XMEMCPY(q, qC, qCSz);
2987
0
    if (qSz != NULL)
2988
0
        *qSz = qCSz;
2989
2990
0
    return 0;
2991
0
}
2992
2993
2994
#ifdef WOLFSSL_KEY_GEN
2995
2996
/* modulus_size in bits */
2997
int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh)
2998
0
{
2999
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3000
0
    mp_int *tmp = NULL, *tmp2 = NULL;
3001
#else
3002
    mp_int tmp[1], tmp2[2];
3003
#endif
3004
0
    word32  groupSz = 0, bufSz = 0,
3005
0
            primeCheckCount = 0;
3006
0
    int     primeCheck = MP_NO,
3007
0
            ret = 0;
3008
#ifdef WOLFSSL_NO_MALLOC
3009
    unsigned char buf[DH_MAX_SIZE / WOLFSSL_BIT_SIZE];
3010
#else
3011
0
    unsigned char *buf = NULL;
3012
0
#endif
3013
3014
#if !defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_NO_MALLOC)
3015
    XMEMSET(tmp, 0, sizeof(tmp));
3016
    XMEMSET(tmp2, 0, sizeof(tmp2));
3017
#endif
3018
3019
0
    if (rng == NULL || dh == NULL)
3020
0
        ret = BAD_FUNC_ARG;
3021
3022
    /* set group size in bytes from modulus size
3023
     * FIPS 186-4 defines valid values (1024, 160) (2048, 256) (3072, 256)
3024
     */
3025
0
    if (ret == 0) {
3026
0
        switch (modSz) {
3027
0
            case 1024:
3028
0
                groupSz = 20;
3029
0
                break;
3030
0
            case 2048:
3031
0
            case 3072:
3032
0
                groupSz = 32;
3033
0
                break;
3034
0
            default:
3035
        #if !defined(HAVE_FIPS) && defined(WOLFSSL_NO_DH186)
3036
                /* in non fips mode attempt to match strength of group size with
3037
                 * mod size */
3038
                if (modSz < 2048)
3039
                    groupSz = 20;
3040
                else
3041
                    groupSz = 32;
3042
        #else
3043
0
                ret = BAD_FUNC_ARG;
3044
0
        #endif
3045
0
                break;
3046
0
        }
3047
0
    }
3048
3049
0
    if (ret == 0) {
3050
        /* modulus size in bytes */
3051
0
        modSz /= WOLFSSL_BIT_SIZE;
3052
3053
0
        if ((word32)modSz < groupSz) {
3054
0
            WOLFSSL_MSG("DH modSz was too small");
3055
0
            ret = BAD_FUNC_ARG;
3056
0
        }
3057
0
    }
3058
3059
0
    if (ret == 0) {
3060
0
        bufSz = (word32)modSz - groupSz;
3061
3062
#ifdef WOLFSSL_NO_MALLOC
3063
        if (bufSz > sizeof(buf))
3064
            ret = MEMORY_E;
3065
#else
3066
        /* allocate ram */
3067
0
        buf = (unsigned char *)XMALLOC(bufSz,
3068
0
                                       dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
3069
0
        if (buf == NULL)
3070
0
            ret = MEMORY_E;
3071
0
#endif
3072
0
    }
3073
3074
    /* make a random string that will be multiplied against q */
3075
0
    if (ret == 0)
3076
0
        ret = wc_RNG_GenerateBlock(rng, buf, bufSz);
3077
3078
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3079
0
    if (ret == 0) {
3080
0
        if ((tmp = (mp_int *)XMALLOC(sizeof(*tmp), NULL,
3081
0
                DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) {
3082
0
            ret = MEMORY_E;
3083
0
        }
3084
0
        else {
3085
0
            XMEMSET(tmp, 0, sizeof(*tmp));
3086
0
        }
3087
0
    }
3088
0
    if (ret == 0) {
3089
0
        if ((tmp2 = (mp_int *)XMALLOC(sizeof(*tmp2), NULL,
3090
0
                DYNAMIC_TYPE_WOLF_BIGINT)) == NULL) {
3091
0
            ret = MEMORY_E;
3092
0
        }
3093
0
        else {
3094
0
            XMEMSET(tmp2, 0, sizeof(*tmp2));
3095
0
        }
3096
0
    }
3097
0
#endif
3098
3099
0
    SAVE_VECTOR_REGISTERS(ret = _svr_ret;);
3100
3101
0
    if (ret == 0) {
3102
        /* force magnitude */
3103
0
        buf[0] |= 0xC0;
3104
        /* force even */
3105
0
        buf[bufSz - 1] &= 0xfe;
3106
3107
0
        if (mp_init_multi(tmp, tmp2, &dh->p, &dh->q, &dh->g, 0)
3108
0
                != MP_OKAY) {
3109
0
            ret = MP_INIT_E;
3110
0
        }
3111
0
    }
3112
3113
0
    if (ret == 0) {
3114
0
        if (mp_read_unsigned_bin(tmp2, buf, bufSz) != MP_OKAY)
3115
0
            ret = MP_READ_E;
3116
0
    }
3117
3118
    /* make our prime q */
3119
0
    if (ret == 0) {
3120
0
        if (mp_rand_prime(&dh->q, (int)groupSz, rng, NULL) != MP_OKAY)
3121
0
            ret = PRIME_GEN_E;
3122
0
    }
3123
3124
    /* p = random * q */
3125
0
    if (ret == 0) {
3126
0
        if (mp_mul(&dh->q, tmp2, &dh->p) != MP_OKAY)
3127
0
            ret = MP_MUL_E;
3128
0
    }
3129
3130
    /* p = random * q + 1, so q is a prime divisor of p-1 */
3131
0
    if (ret == 0) {
3132
0
        if (mp_add_d(&dh->p, 1, &dh->p) != MP_OKAY)
3133
0
            ret = MP_ADD_E;
3134
0
    }
3135
3136
    /* tmp = 2q  */
3137
0
    if (ret == 0) {
3138
0
        if (mp_add(&dh->q, &dh->q, tmp) != MP_OKAY)
3139
0
            ret = MP_ADD_E;
3140
0
    }
3141
3142
    /* loop until p is prime */
3143
0
    if (ret == 0) {
3144
0
        for (;;) {
3145
0
            if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY)
3146
0
                ret = PRIME_GEN_E;
3147
3148
0
            if (primeCheck != MP_YES) {
3149
                /* p += 2q */
3150
0
                if (mp_add(tmp, &dh->p, &dh->p) != MP_OKAY)
3151
0
                    ret = MP_ADD_E;
3152
0
                else
3153
0
                    primeCheckCount++;
3154
0
            }
3155
3156
0
            if (ret != 0 || primeCheck == MP_YES)
3157
0
                break;
3158
3159
            /* linuxkm: release the kernel for a moment before iterating. */
3160
0
            RESTORE_VECTOR_REGISTERS();
3161
0
            SAVE_VECTOR_REGISTERS(ret = _svr_ret; break;);
3162
0
        };
3163
0
    }
3164
3165
    /* tmp2 += (2*loop_check_prime)
3166
     * to have p = (q * tmp2) + 1 prime
3167
     */
3168
0
    if ((ret == 0) && (primeCheckCount)) {
3169
0
        if (mp_add_d(tmp2, 2 * primeCheckCount, tmp2) != MP_OKAY)
3170
0
            ret = MP_ADD_E;
3171
0
    }
3172
3173
    /* find a value g for which g^tmp2 != 1 */
3174
0
    if ((ret == 0) && (mp_set(&dh->g, 1) != MP_OKAY))
3175
0
        ret = MP_ZERO_E;
3176
3177
0
    if (ret == 0) {
3178
0
        do {
3179
0
            if (mp_add_d(&dh->g, 1, &dh->g) != MP_OKAY)
3180
0
                ret = MP_ADD_E;
3181
0
            else if (mp_exptmod(&dh->g, tmp2, &dh->p, tmp) != MP_OKAY)
3182
0
                ret = MP_EXPTMOD_E;
3183
0
        } while (ret == 0 && mp_cmp_d(tmp, 1) == MP_EQ);
3184
0
    }
3185
3186
0
    if (ret == 0) {
3187
        /* at this point tmp generates a group of order q mod p */
3188
0
#ifndef USE_FAST_MATH
3189
        /* Exchanging is quick when the data pointer can be copied. */
3190
0
        mp_exch(tmp, &dh->g);
3191
#else
3192
        mp_copy(tmp, &dh->g);
3193
#endif
3194
0
    }
3195
3196
    /* clear the parameters if there was an error */
3197
0
    if ((ret != 0) && (dh != NULL)) {
3198
0
        mp_clear(&dh->q);
3199
0
        mp_clear(&dh->p);
3200
0
        mp_clear(&dh->g);
3201
0
    }
3202
3203
0
    RESTORE_VECTOR_REGISTERS();
3204
3205
0
#ifndef WOLFSSL_NO_MALLOC
3206
0
    if (buf != NULL)
3207
0
#endif
3208
0
    {
3209
0
        ForceZero(buf, bufSz);
3210
0
#ifndef WOLFSSL_NO_MALLOC
3211
0
        if (dh != NULL) {
3212
0
            XFREE(buf, dh->heap, DYNAMIC_TYPE_TMP_BUFFER);
3213
0
        }
3214
0
#endif
3215
0
    }
3216
3217
0
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
3218
0
    if (tmp != NULL) {
3219
0
        mp_clear(tmp);
3220
0
        XFREE(tmp, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3221
0
    }
3222
0
    if (tmp2 != NULL) {
3223
0
        mp_clear(tmp2);
3224
0
        XFREE(tmp2, NULL, DYNAMIC_TYPE_WOLF_BIGINT);
3225
0
    }
3226
#else
3227
    mp_clear(tmp);
3228
    mp_clear(tmp2);
3229
#endif
3230
3231
0
    return ret;
3232
0
}
3233
3234
#endif /* WOLFSSL_KEY_GEN */
3235
3236
/* Export raw DH parameters from DhKey structure
3237
 *
3238
 * dh   - pointer to initialized DhKey structure
3239
 * p    - output location for DH (p) parameter
3240
 * pSz  - [IN/OUT] size of output buffer for p, size of p
3241
 * q    - output location for DH (q) parameter
3242
 * qSz  - [IN/OUT] size of output buffer for q, size of q
3243
 * g    - output location for DH (g) parameter
3244
 * gSz  - [IN/OUT] size of output buffer for g, size of g
3245
 *
3246
 * If p, q, and g pointers are all passed in as NULL, the function
3247
 * will set pSz, qSz, and gSz to the required output buffer sizes for p,
3248
 * q, and g. In this case, the function will return LENGTH_ONLY_E.
3249
 *
3250
 * returns 0 on success, negative upon failure
3251
 */
3252
int wc_DhExportParamsRaw(DhKey* dh, byte* p, word32* pSz,
3253
                         byte* q, word32* qSz, byte* g, word32* gSz)
3254
0
{
3255
0
    int ret = 0;
3256
0
    word32 pLen = 0, qLen = 0, gLen = 0;
3257
3258
0
    if (dh == NULL || pSz == NULL || qSz == NULL || gSz == NULL)
3259
0
        ret = BAD_FUNC_ARG;
3260
3261
    /* get required output buffer sizes */
3262
0
    if (ret == 0) {
3263
0
        pLen = (word32)mp_unsigned_bin_size(&dh->p);
3264
0
        qLen = (word32)mp_unsigned_bin_size(&dh->q);
3265
0
        gLen = (word32)mp_unsigned_bin_size(&dh->g);
3266
3267
        /* return buffer sizes and LENGTH_ONLY_E if buffers are NULL */
3268
0
        if (p == NULL && q == NULL && g == NULL) {
3269
0
            *pSz = pLen;
3270
0
            *qSz = qLen;
3271
0
            *gSz = gLen;
3272
0
            ret = WC_NO_ERR_TRACE(LENGTH_ONLY_E);
3273
0
        }
3274
0
    }
3275
3276
0
    if (ret == 0) {
3277
0
        if (p == NULL || q == NULL || g == NULL)
3278
0
            ret = BAD_FUNC_ARG;
3279
0
    }
3280
3281
    /* export p */
3282
0
    if (ret == 0) {
3283
0
        if (*pSz < pLen) {
3284
0
            WOLFSSL_MSG("Output buffer for DH p parameter too small, "
3285
0
                        "required size placed into pSz");
3286
0
            *pSz = pLen;
3287
0
            ret = BUFFER_E;
3288
0
        }
3289
0
    }
3290
3291
0
    if (ret == 0) {
3292
0
        *pSz = pLen;
3293
0
        if (mp_to_unsigned_bin(&dh->p, p) != MP_OKAY)
3294
0
            ret = MP_TO_E;
3295
0
    }
3296
3297
    /* export q */
3298
0
    if (ret == 0) {
3299
0
        if (*qSz < qLen) {
3300
0
            WOLFSSL_MSG("Output buffer for DH q parameter too small, "
3301
0
                        "required size placed into qSz");
3302
0
            *qSz = qLen;
3303
0
            ret = BUFFER_E;
3304
0
        }
3305
0
    }
3306
3307
0
    if (ret == 0) {
3308
0
        *qSz = qLen;
3309
0
        if (mp_to_unsigned_bin(&dh->q, q) != MP_OKAY)
3310
0
            ret = MP_TO_E;
3311
0
    }
3312
3313
    /* export g */
3314
0
    if (ret == 0) {
3315
0
        if (*gSz < gLen) {
3316
0
            WOLFSSL_MSG("Output buffer for DH g parameter too small, "
3317
0
                        "required size placed into gSz");
3318
0
            *gSz = gLen;
3319
0
            ret = BUFFER_E;
3320
0
        }
3321
0
    }
3322
3323
0
    if (ret == 0) {
3324
0
        *gSz = gLen;
3325
0
        if (mp_to_unsigned_bin(&dh->g, g) != MP_OKAY)
3326
0
            ret = MP_TO_E;
3327
0
    }
3328
3329
0
    return ret;
3330
0
}
3331
3332
#endif /* NO_DH */