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