1 /****************************************************************************
2 * *
3 * cryptlib SSHv2/SSL/TLS DH Public Parameters *
4 * Copyright Peter Gutmann 1998-2013 *
5 * *
6 ****************************************************************************/
7
8 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
9 #if defined( INC_ALL )
10 #include "crypt.h"
11 #include "context.h"
12 #else
13 #include "crypt.h"
14 #include "context/context.h"
15 #endif /* Compiler-specific includes */
16
17 /* Define the following to convert from the fixed-format DH and ECC domain
18 parameters to pre-encoded the bignum format. This will also require
19 adding the following to the keygen function in the DH/ECDH code:
20
21 loadDHparams( contextInfoPtr, bitsToBytes( 1536 ) );
22 loadDHparams( contextInfoPtr, bitsToBytes( 2048 ) );
23 loadDHparams( contextInfoPtr, bitsToBytes( 3072 ) );
24
25 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_P256 );
26 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_BRAINPOOL_P256 );
27 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_P384 );
28 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_BRAINPOOL_P384 );
29 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_P521 );
30 loadECCparams( contextInfoPtr, CRYPT_ECCCURVE_BRAINPOOL_P512 ); */
31
32 /* #define CREATE_BIGNUM_VALUES */
33
34 #if defined( USE_SSH ) || defined( USE_SSL )
35
36 /****************************************************************************
37 * *
38 * DH Domain Parameters *
39 * *
40 ****************************************************************************/
41
42 /* Predefined DH values from RFC 2409 and RFC 3526. These have been
43 independently verified by Henrick Hellstr�m <henrick@streamsec.se> to
44 check that:
45
46 a: The numbers match the numbers in the RFCs.
47 b: The numbers are safe primes (using both Miller-Rabin tests and Lucas
48 tests on q = (p-1)/2, and then the Pocklington Criterion on p).
49 c: The small constant k is indeed the least positive integer such that
50 the number is a safe prime.
51
52 Safely converting these to pre-encoded bignum values is a multi-stage
53 process, first we encode the original values as SSL-format values, which
54 is the closest format to the original spec and one for which we can
55 use SHA-1 hashes to verify the primes.
56
57 Then we read them into a bignum and print the result. This finally
58 allows us to use the values as pre-generated bignums. To enable the
59 code for this process, define the following value */
60
61 #ifdef CREATE_BIGNUM_VALUES
62
63 #ifdef USE_DH1024
64
65 /* 1024-bit DH parameters from RFC 2409 */
66
67 static const BYTE FAR_BSS dh1024SSL[] = {
68 0x00, 0x80, /* p */
69 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
70 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
71 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
72 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
73 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
74 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
75 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
76 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
77 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
78 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
79 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
80 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
81 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
82 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
83 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
84 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
85 0x00, 0x01, /* g */
86 0x02
87 };
88 #endif /* USE_DH1024 */
89
90 /* 1536-, 2048- and 3072-bit parameters from RFC 3526. There is also a
91 4096-bit value given in the RFC, but using that, and the even larger
92 values of 6144 and 8192 bits, is just silly. See also the comment on
93 defences against clients that request stupid key sizes in processDHE()
94 in ssh2_svr.c */
95
96 static const BYTE FAR_BSS dh1536SSL[] = {
97 0x00, 0xC0, /* p */
98 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
99 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
100 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
101 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
102 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
103 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
104 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
105 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
106 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
107 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
108 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
109 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
110 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
111 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
112 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
113 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
114 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
115 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
116 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
117 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
118 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
119 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
120 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27,
121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
122 0x00, 0x01, /* g */
123 0x02
124 };
125
126 static const BYTE FAR_BSS dh2048SSL[] = {
127 0x01, 0x00, /* p */
128 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
129 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
130 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
131 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
132 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
133 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
134 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
135 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
136 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
137 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
138 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
139 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
140 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
141 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
142 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
143 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
144 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
145 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
146 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
147 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
148 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
149 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
150 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
151 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
152 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
153 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
154 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
155 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
156 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
157 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
158 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68,
159 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
160 0x00, 0x01, /* g */
161 0x02
162 };
163
164 static const BYTE FAR_BSS dh3072SSL[] = {
165 0x01, 0x80, /* p */
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
168 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
169 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
170 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22,
171 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
172 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B,
173 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
174 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
175 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
176 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B,
177 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
178 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5,
179 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
180 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
181 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
182 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A,
183 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
184 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96,
185 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
186 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
187 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
188 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C,
189 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
190 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03,
191 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
192 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
193 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
194 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5,
195 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
196 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D,
197 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
198 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
199 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
200 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D,
201 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
202 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7,
203 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
204 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
205 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
206 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64,
207 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
208 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C,
209 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
210 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
211 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
212 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA,
213 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
214 0x00, 0x01, /* g */
215 0x02
216 };
217
218 /* Checksum values for the DH data */
219
220 #ifdef USE_DH1024
221 static int dh1024checksum;
222 #endif /* USE_DH1024 */
223
224 static int dh1536checksum, dh2048checksum, dh3072checksum;
225
226 /* Check that the stored DH key data is valid */
227
228 CHECK_RETVAL \
checkDHdata(void)229 static int checkDHdata( void )
230 {
231 HASHFUNCTION_ATOMIC hashFunctionAtomic;
232 BYTE hashValue[ 20 + 8 ];
233
234 getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &hashFunctionAtomic, NULL );
235
236 /* Generate/check the SHA-1 values for the primes. This doesn't cover
237 all of the data, but is needed to bootstrap the full check because
238 only the hashes of the primes have been published */
239 #if 0
240 hashFunctionAtomic( hashValue, 20, dh1024SSL + 2, sizeof( dh1024SSL ) - 5 );
241 hashFunctionAtomic( hashValue, 20, dh1536SSL + 2, sizeof( dh1536SSL ) - 5 );
242 hashFunctionAtomic( hashValue, 20, dh2048SSL + 2, sizeof( dh2048SSL ) - 5 );
243 hashFunctionAtomic( hashValue, 20, dh3072SSL + 2, sizeof( dh3072SSL ) - 5 );
244 #endif /* 0 */
245
246 /* Check the SHA-1 values for the DH data */
247 #ifndef CONFIG_FUZZ
248 #ifdef USE_DH1024
249 hashFunctionAtomic( hashValue, 20, dh1024SSL, sizeof( dh1024SSL ) );
250 if( memcmp( hashValue, \
251 "\x46\xF4\x47\xC3\x69\x00\x6F\x22\x91\x0E\x24\xF5\x73\x68\xE6\xF7", 16 ) )
252 retIntError();
253 #endif /* USE_DH1024 */
254 hashFunctionAtomic( hashValue, 20, dh1536SSL, sizeof( dh1536SSL ) );
255 if( memcmp( hashValue, \
256 "\xA3\xEC\x2F\x85\xC7\xD3\x74\xD2\x56\x53\x22\xED\x53\x87\x6F\xDC", 16 ) )
257 retIntError();
258 hashFunctionAtomic( hashValue, 20, dh2048SSL, sizeof( dh2048SSL ) );
259 if( memcmp( hashValue, \
260 "\x0E\x8E\x49\x9F\xD9\x18\x02\xCB\x5D\x42\x03\xA5\xE1\x67\x51\xDB", 16 ) )
261 retIntError();
262 hashFunctionAtomic( hashValue, 20, dh3072SSL, sizeof( dh3072SSL ) );
263 if( memcmp( hashValue, \
264 "\x8F\x4A\x19\xEF\x85\x1D\x91\xEA\x18\xE8\xB8\xB9\x9F\xF0\xFD\xF8", 16 ) )
265 retIntError();
266 #endif /* !CONFIG_FUZZ */
267
268 /* Now that we've verified that the DH data is valid, calculate a
269 checksum for each value to allow it to be quickly checked before it's
270 loaded into a context */
271 #ifdef USE_DH1024
272 dh1024checksum = checksumData( dh1024SSL, sizeof( dh1024SSL ) );
273 #endif /* USE_DH1024 */
274 dh1536checksum = checksumData( dh1536SSL, sizeof( dh1536SSL ) );
275 dh2048checksum = checksumData( dh2048SSL, sizeof( dh2048SSL ) );
276 dh3072checksum = checksumData( dh3072SSL, sizeof( dh3072SSL ) );
277
278 return( CRYPT_OK );
279 }
280
281 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
loadDHparamsFixed(INOUT CONTEXT_INFO * contextInfoPtr,IN_LENGTH_PKC const int keySize)282 static int loadDHparamsFixed( INOUT CONTEXT_INFO *contextInfoPtr,
283 IN_LENGTH_PKC const int keySize )
284 {
285 MESSAGE_DATA msgData;
286 const void *keyData;
287 int keyDataLength, keyDataChecksum;
288
289 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
290
291 REQUIRES( keySize >= MIN_PKCSIZE && keySize <= CRYPT_MAX_PKCSIZE );
292
293 switch( keySize )
294 {
295 #ifdef USE_DH1024
296 case bitsToBytes( 1024 ):
297 keyData = dh1024SSL;
298 keyDataLength = sizeof( dh1024SSL );
299 keyDataChecksum = dh1024checksum;
300 break;
301 #endif /* USE_DH1024 */
302
303 case bitsToBytes( 1536 ):
304 keyData = dh1536SSL;
305 keyDataLength = sizeof( dh1536SSL );
306 keyDataChecksum = dh1536checksum;
307 break;
308
309 case bitsToBytes( 2048 ):
310 keyData = dh2048SSL;
311 keyDataLength = sizeof( dh2048SSL );
312 keyDataChecksum = dh2048checksum;
313 break;
314
315 case bitsToBytes( 3072 ):
316 default: /* Hier ist der mast zu ende */
317 keyData = dh3072SSL;
318 keyDataLength = sizeof( dh3072SSL );
319 keyDataChecksum = dh3072checksum;
320 break;
321 }
322
323 /* Make sure that the key data hasn't been corrupted */
324 if( keyDataChecksum != checksumData( keyData, keyDataLength ) )
325 {
326 DEBUG_DIAG(( "Fixed DH value for %d-bit key has been corrupted",
327 bytesToBits( keySize ) ));
328 retIntError();
329 }
330
331 /* Load the fixed DH key into the context */
332 setMessageData( &msgData, ( MESSAGE_CAST ) keyData, keyDataLength );
333 return( krnlSendMessage( contextInfoPtr->objectHandle,
334 IMESSAGE_SETATTRIBUTE_S, &msgData,
335 CRYPT_IATTRIBUTE_KEY_SSL ) );
336 }
337 #endif /* CREATE_BIGNUM_VALUES */
338
339 /* DH values as pre-encoded bignums, allowing them to be used directly */
340
341 #if BN_BITS2 == 64
342
343 static const DH_DOMAINPARAMS dh1536params = {
344 /* p */
345 { BIGNUM_ALLOC_WORDS, 24, FALSE, BN_FLG_STATIC_DATA, {
346 0xFFFFFFFFFFFFFFFFULL, 0xF1746C08CA237327ULL,
347 0x670C354E4ABC9804ULL, 0x9ED529077096966DULL,
348 0x1C62F356208552BBULL, 0x83655D23DCA3AD96ULL,
349 0x69163FA8FD24CF5FULL, 0x98DA48361C55D39AULL,
350 0xC2007CB8A163BF05ULL, 0x49286651ECE45B3DULL,
351 0xAE9F24117C4B1FE6ULL, 0xEE386BFB5A899FA5ULL,
352 0x0BFF5CB6F406B7EDULL, 0xF44C42E9A637ED6BULL,
353 0xE485B576625E7EC6ULL, 0x4FE1356D6D51C245ULL,
354 0x302B0A6DF25F1437ULL, 0xEF9519B3CD3A431BULL,
355 0x514A08798E3404DDULL, 0x020BBEA63B139B22ULL,
356 0x29024E088A67CC74ULL, 0xC4C6628B80DC1CD1ULL,
357 0xC90FDAA22168C234ULL, 0xFFFFFFFFFFFFFFFFULL } },
358 /* g */
359 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
360 0x0000000000000002ULL } },
361 /* Checksums */
362 0x9472AA5034F03DC6ULL, 0x28C47BE7F867ED54ULL
363 };
364
365 static const DH_DOMAINPARAMS dh2048params = {
366 /* p */
367 { BIGNUM_ALLOC_WORDS, 32, FALSE, BN_FLG_STATIC_DATA, {
368 0xFFFFFFFFFFFFFFFFULL, 0x15728E5A8AACAA68ULL,
369 0x15D2261898FA0510ULL, 0x3995497CEA956AE5ULL,
370 0xDE2BCBF695581718ULL, 0xB5C55DF06F4C52C9ULL,
371 0x9B2783A2EC07A28FULL, 0xE39E772C180E8603ULL,
372 0x32905E462E36CE3BULL, 0xF1746C08CA18217CULL,
373 0x670C354E4ABC9804ULL, 0x9ED529077096966DULL,
374 0x1C62F356208552BBULL, 0x83655D23DCA3AD96ULL,
375 0x69163FA8FD24CF5FULL, 0x98DA48361C55D39AULL,
376 0xC2007CB8A163BF05ULL, 0x49286651ECE45B3DULL,
377 0xAE9F24117C4B1FE6ULL, 0xEE386BFB5A899FA5ULL,
378 0x0BFF5CB6F406B7EDULL, 0xF44C42E9A637ED6BULL,
379 0xE485B576625E7EC6ULL, 0x4FE1356D6D51C245ULL,
380 0x302B0A6DF25F1437ULL, 0xEF9519B3CD3A431BULL,
381 0x514A08798E3404DDULL, 0x020BBEA63B139B22ULL,
382 0x29024E088A67CC74ULL, 0xC4C6628B80DC1CD1ULL,
383 0xC90FDAA22168C234ULL, 0xFFFFFFFFFFFFFFFFULL } },
384 /* g */
385 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
386 0x0000000000000002ULL } },
387 /* Checksums */
388 0x405BD3182D6B262CULL, 0x28C47BE7F867ED54ULL
389 };
390
391 static const DH_DOMAINPARAMS dh3072params = {
392 /* p */
393 { BIGNUM_ALLOC_WORDS, 48, FALSE, BN_FLG_STATIC_DATA, {
394 0xFFFFFFFFFFFFFFFFULL, 0x4B82D120A93AD2CAULL,
395 0x43DB5BFCE0FD108EULL, 0x08E24FA074E5AB31ULL,
396 0x770988C0BAD946E2ULL, 0xBBE117577A615D6CULL,
397 0x521F2B18177B200CULL, 0xD87602733EC86A64ULL,
398 0xF12FFA06D98A0864ULL, 0xCEE3D2261AD2EE6BULL,
399 0x1E8C94E04A25619DULL, 0xABF5AE8CDB0933D7ULL,
400 0xB3970F85A6E1E4C7ULL, 0x8AEA71575D060C7DULL,
401 0xECFB850458DBEF0AULL, 0xA85521ABDF1CBA64ULL,
402 0xAD33170D04507A33ULL, 0x15728E5A8AAAC42DULL,
403 0x15D2261898FA0510ULL, 0x3995497CEA956AE5ULL,
404 0xDE2BCBF695581718ULL, 0xB5C55DF06F4C52C9ULL,
405 0x9B2783A2EC07A28FULL, 0xE39E772C180E8603ULL,
406 0x32905E462E36CE3BULL, 0xF1746C08CA18217CULL,
407 0x670C354E4ABC9804ULL, 0x9ED529077096966DULL,
408 0x1C62F356208552BBULL, 0x83655D23DCA3AD96ULL,
409 0x69163FA8FD24CF5FULL, 0x98DA48361C55D39AULL,
410 0xC2007CB8A163BF05ULL, 0x49286651ECE45B3DULL,
411 0xAE9F24117C4B1FE6ULL, 0xEE386BFB5A899FA5ULL,
412 0x0BFF5CB6F406B7EDULL, 0xF44C42E9A637ED6BULL,
413 0xE485B576625E7EC6ULL, 0x4FE1356D6D51C245ULL,
414 0x302B0A6DF25F1437ULL, 0xEF9519B3CD3A431BULL,
415 0x514A08798E3404DDULL, 0x020BBEA63B139B22ULL,
416 0x29024E088A67CC74ULL, 0xC4C6628B80DC1CD1ULL,
417 0xC90FDAA22168C234ULL, 0xFFFFFFFFFFFFFFFFULL } },
418 /* g */
419 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
420 0x0000000000000002ULL } },
421 /* Checksums */
422 0x576642F5C4CD8D96ULL, 0x28C47BE7F867ED54ULL
423 };
424
425 #else
426
427 static const DH_DOMAINPARAMS dh1536params = {
428 /* p */
429 { BIGNUM_ALLOC_WORDS, 48, FALSE, BN_FLG_STATIC_DATA, {
430 0xFFFFFFFF, 0xFFFFFFFF, 0xCA237327, 0xF1746C08,
431 0x4ABC9804, 0x670C354E, 0x7096966D, 0x9ED52907,
432 0x208552BB, 0x1C62F356, 0xDCA3AD96, 0x83655D23,
433 0xFD24CF5F, 0x69163FA8, 0x1C55D39A, 0x98DA4836,
434 0xA163BF05, 0xC2007CB8, 0xECE45B3D, 0x49286651,
435 0x7C4B1FE6, 0xAE9F2411, 0x5A899FA5, 0xEE386BFB,
436 0xF406B7ED, 0x0BFF5CB6, 0xA637ED6B, 0xF44C42E9,
437 0x625E7EC6, 0xE485B576, 0x6D51C245, 0x4FE1356D,
438 0xF25F1437, 0x302B0A6D, 0xCD3A431B, 0xEF9519B3,
439 0x8E3404DD, 0x514A0879, 0x3B139B22, 0x020BBEA6,
440 0x8A67CC74, 0x29024E08, 0x80DC1CD1, 0xC4C6628B,
441 0x2168C234, 0xC90FDAA2, 0xFFFFFFFF, 0xFFFFFFFF } },
442 /* g */
443 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA,
444 { 2 } },
445 /* Checksums */
446 0x7A168323, 0x847050E5
447 };
448
449 static const DH_DOMAINPARAMS dh2048params = {
450 /* p */
451 { BIGNUM_ALLOC_WORDS, 64, FALSE, BN_FLG_STATIC_DATA, {
452 0xFFFFFFFF, 0xFFFFFFFF, 0x8AACAA68, 0x15728E5A,
453 0x98FA0510, 0x15D22618, 0xEA956AE5, 0x3995497C,
454 0x95581718, 0xDE2BCBF6, 0x6F4C52C9, 0xB5C55DF0,
455 0xEC07A28F, 0x9B2783A2, 0x180E8603, 0xE39E772C,
456 0x2E36CE3B, 0x32905E46, 0xCA18217C, 0xF1746C08,
457 0x4ABC9804, 0x670C354E, 0x7096966D, 0x9ED52907,
458 0x208552BB, 0x1C62F356, 0xDCA3AD96, 0x83655D23,
459 0xFD24CF5F, 0x69163FA8, 0x1C55D39A, 0x98DA4836,
460 0xA163BF05, 0xC2007CB8, 0xECE45B3D, 0x49286651,
461 0x7C4B1FE6, 0xAE9F2411, 0x5A899FA5, 0xEE386BFB,
462 0xF406B7ED, 0x0BFF5CB6, 0xA637ED6B, 0xF44C42E9,
463 0x625E7EC6, 0xE485B576, 0x6D51C245, 0x4FE1356D,
464 0xF25F1437, 0x302B0A6D, 0xCD3A431B, 0xEF9519B3,
465 0x8E3404DD, 0x514A0879, 0x3B139B22, 0x020BBEA6,
466 0x8A67CC74, 0x29024E08, 0x80DC1CD1, 0xC4C6628B,
467 0x2168C234, 0xC90FDAA2, 0xFFFFFFFF, 0xFFFFFFFF } },
468 /* g */
469 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA,
470 { 2 } },
471 /* Checksums */
472 0x82C18653, 0x847050E5
473 };
474
475 static const DH_DOMAINPARAMS dh3072params = {
476 /* p */
477 { BIGNUM_ALLOC_WORDS, 96, FALSE, BN_FLG_STATIC_DATA, {
478 0xFFFFFFFF, 0xFFFFFFFF, 0xA93AD2CA, 0x4B82D120,
479 0xE0FD108E, 0x43DB5BFC, 0x74E5AB31, 0x08E24FA0,
480 0xBAD946E2, 0x770988C0, 0x7A615D6C, 0xBBE11757,
481 0x177B200C, 0x521F2B18, 0x3EC86A64, 0xD8760273,
482 0xD98A0864, 0xF12FFA06, 0x1AD2EE6B, 0xCEE3D226,
483 0x4A25619D, 0x1E8C94E0, 0xDB0933D7, 0xABF5AE8C,
484 0xA6E1E4C7, 0xB3970F85, 0x5D060C7D, 0x8AEA7157,
485 0x58DBEF0A, 0xECFB8504, 0xDF1CBA64, 0xA85521AB,
486 0x04507A33, 0xAD33170D, 0x8AAAC42D, 0x15728E5A,
487 0x98FA0510, 0x15D22618, 0xEA956AE5, 0x3995497C,
488 0x95581718, 0xDE2BCBF6, 0x6F4C52C9, 0xB5C55DF0,
489 0xEC07A28F, 0x9B2783A2, 0x180E8603, 0xE39E772C,
490 0x2E36CE3B, 0x32905E46, 0xCA18217C, 0xF1746C08,
491 0x4ABC9804, 0x670C354E, 0x7096966D, 0x9ED52907,
492 0x208552BB, 0x1C62F356, 0xDCA3AD96, 0x83655D23,
493 0xFD24CF5F, 0x69163FA8, 0x1C55D39A, 0x98DA4836,
494 0xA163BF05, 0xC2007CB8, 0xECE45B3D, 0x49286651,
495 0x7C4B1FE6, 0xAE9F2411, 0x5A899FA5, 0xEE386BFB,
496 0xF406B7ED, 0x0BFF5CB6, 0xA637ED6B, 0xF44C42E9,
497 0x625E7EC6, 0xE485B576, 0x6D51C245, 0x4FE1356D,
498 0xF25F1437, 0x302B0A6D, 0xCD3A431B, 0xEF9519B3,
499 0x8E3404DD, 0x514A0879, 0x3B139B22, 0x020BBEA6,
500 0x8A67CC74, 0x29024E08, 0x80DC1CD1, 0xC4C6628B,
501 0x2168C234, 0xC90FDAA2, 0xFFFFFFFF, 0xFFFFFFFF } },
502 /* g */
503 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA,
504 { 2 } },
505 /* Checksums */
506 0xFB7DF2C8, 0x847050E5
507 };
508
509 #endif /* 64- vs 32-bit */
510
511 /****************************************************************************
512 * *
513 * DH Access Functions *
514 * *
515 ****************************************************************************/
516
517 /* Load a fixed DH key of the appropriate size */
518
519 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
loadDHparams(INOUT CONTEXT_INFO * contextInfoPtr,IN_LENGTH_PKC const int requestedKeySize)520 int loadDHparams( INOUT CONTEXT_INFO *contextInfoPtr,
521 IN_LENGTH_PKC const int requestedKeySize )
522 {
523 PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
524 const DH_DOMAINPARAMS *domainParams;
525 #ifdef CREATE_BIGNUM_VALUES
526 int status;
527 #endif /* CREATE_BIGNUM_VALUES */
528
529 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
530
531 REQUIRES( requestedKeySize >= MIN_PKCSIZE && \
532 requestedKeySize <= CRYPT_MAX_PKCSIZE );
533
534 /* Convert the fixed-format bignums to encoded BIGNUMs */
535 #ifdef CREATE_BIGNUM_VALUES
536 checkDHdata();
537 status = loadDHparamsFixed( contextInfoPtr, requestedKeySize );
538 if( cryptStatusError( status ) )
539 return( status );
540 printBignum( &pkcInfo->dlpParam_p, "p" );
541 printBignum( &pkcInfo->dlpParam_g, "g" );
542 DEBUG_PRINT(( "\t/* Checksums */\n\t" ));
543 printBignumChecksum( &pkcInfo->dlpParam_p );
544 printBignumChecksum( &pkcInfo->dlpParam_g );
545 DEBUG_PRINT(( "\n" ));
546 #endif /* CREATE_BIGNUM_VALUES */
547
548 /* Get the built-in DH key value that corresponds best to the client's
549 requested key size. We allow for a bit of slop to avoid having
550 something like a 2049-bit requested key size lead to the use of a
551 3072-bit key value.
552
553 In theory for protocols that support the use of arbitrary DH
554 parameters we should probably generate a new DH key each time:
555
556 status = krnlSendMessage( iDHContext, IMESSAGE_SETATTRIBUTE,
557 ( MESSAGE_CAST ) &requestedKeySize,
558 CRYPT_CTXINFO_KEYSIZE );
559 if( cryptStatusOK( status ) )
560 status = krnlSendMessage( iDHContext, IMESSAGE_CTX_GENKEY,
561 NULL, FALSE );
562
563 however because the handshake is set up so that the client (rather
564 than the server) chooses the key size we can't actually perform the
565 generation until we're in the middle of the handshake. This means
566 that the server will grind to a halt during each handshake as it
567 generates a new key of whatever size takes the client's fancy (it
568 also leads to a nice potential DoS attack on the server). To avoid
569 this problem we use fixed keys of various common sizes.
570
571 As late as 2014 Java still can't handle DH keys over 1024 bits (it
572 only allows keys ranging from 512-1024 bits):
573
574 java.security.InvalidAlgorithmParameterException: Prime size must be
575 multiple of 64, and can only range from 512 to 1024 (inclusive)
576
577 so if you need to talk to a system built in Java you need to first
578 enable the use of unsound 1024-bit keys using USE_DH1024 and then
579 hardcode the key size to 1024 bits, the largest size that Java will
580 allow */
581 domainParams = ( requestedKeySize < 192 + 8 ) ? &dh1536params : \
582 ( requestedKeySize < 256 + 8 ) ? &dh2048params : \
583 &dh3072params;
584
585 /* Make sure that the domain parameters are in order */
586 if( !checksumDomainParameters( domainParams, FALSE ) )
587 {
588 DEBUG_DIAG(( "Fixed DH value for requested %d-bit key has been "
589 "corrupted", requestedKeySize ));
590 retIntError();
591 }
592
593 pkcInfo->domainParams = domainParams;
594
595 ENSURES( sanityCheckPKCInfo( pkcInfo ) );
596
597 return( CRYPT_OK );
598 }
599 #endif /* USE_SSH || USE_SSL */
600
601 /****************************************************************************
602 * *
603 * ECC Domain Parameters *
604 * *
605 ****************************************************************************/
606
607 #if defined( USE_ECDH ) || defined( USE_ECDSA )
608
609 /* We always use pre-generated parameters both because it's unlikely that
610 anyone will ever decide to generate nonstandard parameters when standard
611 ones are available (or at least no sane person would, no doubt every
612 little standards committee wanting to make their mark will feel the need
613 to have their own personal incompatible parameters). In addition using
614 externally-generated parameters can (as for DSA) lead to problems with
615 maliciously-generated values (see "CM-Curves with good Cryptography
616 Properties", Neal Koblitz, Proceedings of Crypto'91, p.279), and finally
617 (also like DSA) it can lead to problems with parameter-substitution
618 attacks (see "Digital Signature Schemes with Domain Parameters", Serge
619 Vaudenay, Proceedings of ACISP'04, p.188) */
620
621 #ifdef CREATE_BIGNUM_VALUES
622
623 typedef struct {
624 CRYPT_ECCCURVE_TYPE paramType;
625 const int curveSizeBits;
626 const BYTE *p, *a, *b, *gx, *gy, *n, *h;
627 const BYTE *hashValue;
628 } ECC_DOMAIN_PARAMS;
629
630 static const ECC_DOMAIN_PARAMS domainParamTbl[] = {
631 /* NIST P-256, X9.62 p256r1, SECG p256r1 */
632 { CRYPT_ECCCURVE_P256, 256,
633 MKDATA( "\xFF\xFF\xFF\xFF\x00\x00\x00\x01" \
634 "\x00\x00\x00\x00\x00\x00\x00\x00" \
635 "\x00\x00\x00\x00\xFF\xFF\xFF\xFF" \
636 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ),
637 MKDATA( "\xFF\xFF\xFF\xFF\x00\x00\x00\x01" \
638 "\x00\x00\x00\x00\x00\x00\x00\x00" \
639 "\x00\x00\x00\x00\xFF\xFF\xFF\xFF" \
640 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC" ),
641 MKDATA( "\x5A\xC6\x35\xD8\xAA\x3A\x93\xE7" \
642 "\xB3\xEB\xBD\x55\x76\x98\x86\xBC" \
643 "\x65\x1D\x06\xB0\xCC\x53\xB0\xF6" \
644 "\x3B\xCE\x3C\x3E\x27\xD2\x60\x4B" ),
645 MKDATA( "\x6B\x17\xD1\xF2\xE1\x2C\x42\x47" \
646 "\xF8\xBC\xE6\xE5\x63\xA4\x40\xF2" \
647 "\x77\x03\x7D\x81\x2D\xEB\x33\xA0" \
648 "\xF4\xA1\x39\x45\xD8\x98\xC2\x96" ),
649 MKDATA( "\x4F\xE3\x42\xE2\xFE\x1A\x7F\x9B" \
650 "\x8E\xE7\xEB\x4A\x7C\x0F\x9E\x16" \
651 "\x2B\xCE\x33\x57\x6B\x31\x5E\xCE" \
652 "\xCB\xB6\x40\x68\x37\xBF\x51\xF5" ),
653 MKDATA( "\xFF\xFF\xFF\xFF\x00\x00\x00\x00" \
654 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
655 "\xBC\xE6\xFA\xAD\xA7\x17\x9E\x84" \
656 "\xF3\xB9\xCA\xC2\xFC\x63\x25\x51" ),
657 MKDATA( "\x01" ),
658 MKDATA( "\x40\x31\x2F\x8C\x04\xBB\x5E\x5C" \
659 "\x0F\x12\x32\x75\x91\xE8\x71\x65" ) },
660
661 /* Brainpool p256r1 */
662 { CRYPT_ECCCURVE_BRAINPOOL_P256, 256,
663 MKDATA( "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC" \
664 "\x3E\x66\x0A\x90\x9D\x83\x8D\x72" \
665 "\x6E\x3B\xF6\x23\xD5\x26\x20\x28" \
666 "\x20\x13\x48\x1D\x1F\x6E\x53\x77" ),
667 MKDATA( "\x7D\x5A\x09\x75\xFC\x2C\x30\x57" \
668 "\xEE\xF6\x75\x30\x41\x7A\xFF\xE7" \
669 "\xFB\x80\x55\xC1\x26\xDC\x5C\x6C" \
670 "\xE9\x4A\x4B\x44\xF3\x30\xB5\xD9" ),
671 MKDATA( "\x26\xDC\x5C\x6C\xE9\x4A\x4B\x44" \
672 "\xF3\x30\xB5\xD9\xBB\xD7\x7C\xBF" \
673 "\x95\x84\x16\x29\x5C\xF7\xE1\xCE" \
674 "\x6B\xCC\xDC\x18\xFF\x8C\x07\xB6" ),
675 MKDATA( "\x8B\xD2\xAE\xB9\xCB\x7E\x57\xCB" \
676 "\x2C\x4B\x48\x2F\xFC\x81\xB7\xAF" \
677 "\xB9\xDE\x27\xE1\xE3\xBD\x23\xC2" \
678 "\x3A\x44\x53\xBD\x9A\xCE\x32\x62" ),
679 MKDATA( "\x54\x7E\xF8\x35\xC3\xDA\xC4\xFD" \
680 "\x97\xF8\x46\x1A\x14\x61\x1D\xC9" \
681 "\xC2\x77\x45\x13\x2D\xED\x8E\x54" \
682 "\x5C\x1D\x54\xC7\x2F\x04\x69\x97" ),
683 MKDATA( "\xA9\xFB\x57\xDB\xA1\xEE\xA9\xBC" \
684 "\x3E\x66\x0A\x90\x9D\x83\x8D\x71" \
685 "\x8C\x39\x7A\xA3\xB5\x61\xA6\xF7" \
686 "\x90\x1E\x0E\x82\x97\x48\x56\xA7" ),
687 MKDATA( "\x01" ),
688 MKDATA( "\x3F\xBF\x15\xA2\x89\x27\x68\x83" \
689 "\x67\xAC\x82\x26\x48\xFA\x44\x8E" ) },
690
691 /* NIST P-384, SECG p384r1 */
692 { CRYPT_ECCCURVE_P384, 384,
693 MKDATA( "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
694 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
695 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
696 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE" \
697 "\xFF\xFF\xFF\xFF\x00\x00\x00\x00" \
698 "\x00\x00\x00\x00\xFF\xFF\xFF\xFF" ),
699 MKDATA( "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
700 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
701 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
702 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE" \
703 "\xFF\xFF\xFF\xFF\x00\x00\x00\x00" \
704 "\x00\x00\x00\x00\xFF\xFF\xFF\xFC" ),
705 MKDATA( "\xB3\x31\x2F\xA7\xE2\x3E\xE7\xE4" \
706 "\x98\x8E\x05\x6B\xE3\xF8\x2D\x19" \
707 "\x18\x1D\x9C\x6E\xFE\x81\x41\x12" \
708 "\x03\x14\x08\x8F\x50\x13\x87\x5A" \
709 "\xC6\x56\x39\x8D\x8A\x2E\xD1\x9D" \
710 "\x2A\x85\xC8\xED\xD3\xEC\x2A\xEF" ),
711 MKDATA( "\xAA\x87\xCA\x22\xBE\x8B\x05\x37" \
712 "\x8E\xB1\xC7\x1E\xF3\x20\xAD\x74" \
713 "\x6E\x1D\x3B\x62\x8B\xA7\x9B\x98" \
714 "\x59\xF7\x41\xE0\x82\x54\x2A\x38" \
715 "\x55\x02\xF2\x5D\xBF\x55\x29\x6C" \
716 "\x3A\x54\x5E\x38\x72\x76\x0A\xB7" ),
717 MKDATA( "\x36\x17\xDE\x4A\x96\x26\x2C\x6F" \
718 "\x5D\x9E\x98\xBF\x92\x92\xDC\x29" \
719 "\xF8\xF4\x1D\xBD\x28\x9A\x14\x7C" \
720 "\xE9\xDA\x31\x13\xB5\xF0\xB8\xC0" \
721 "\x0A\x60\xB1\xCE\x1D\x7E\x81\x9D" \
722 "\x7A\x43\x1D\x7C\x90\xEA\x0E\x5F" ),
723 MKDATA( "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
724 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
725 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
726 "\xC7\x63\x4D\x81\xF4\x37\x2D\xDF" \
727 "\x58\x1A\x0D\xB2\x48\xB0\xA7\x7A" \
728 "\xEC\xEC\x19\x6A\xCC\xC5\x29\x73" ),
729 MKDATA( "\x01" ),
730 MKDATA( "\xC2\xDF\x12\x1E\x86\x76\xF9\x5A" \
731 "\x6C\xD9\xA9\x3C\x18\xA3\xA8\x79" ) },
732
733 /* Brainpool p384r1 */
734 { CRYPT_ECCCURVE_BRAINPOOL_P384, 384,
735 MKDATA( "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28" \
736 "\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF" \
737 "\x15\x2F\x71\x09\xED\x54\x56\xB4" \
738 "\x12\xB1\xDA\x19\x7F\xB7\x11\x23" \
739 "\xAC\xD3\xA7\x29\x90\x1D\x1A\x71" \
740 "\x87\x47\x00\x13\x31\x07\xEC\x53" ),
741 MKDATA( "\x7B\xC3\x82\xC6\x3D\x8C\x15\x0C" \
742 "\x3C\x72\x08\x0A\xCE\x05\xAF\xA0" \
743 "\xC2\xBE\xA2\x8E\x4F\xB2\x27\x87" \
744 "\x13\x91\x65\xEF\xBA\x91\xF9\x0F" \
745 "\x8A\xA5\x81\x4A\x50\x3A\xD4\xEB" \
746 "\x04\xA8\xC7\xDD\x22\xCE\x28\x26" ),
747 MKDATA( "\x04\xA8\xC7\xDD\x22\xCE\x28\x26" \
748 "\x8B\x39\xB5\x54\x16\xF0\x44\x7C" \
749 "\x2F\xB7\x7D\xE1\x07\xDC\xD2\xA6" \
750 "\x2E\x88\x0E\xA5\x3E\xEB\x62\xD5" \
751 "\x7C\xB4\x39\x02\x95\xDB\xC9\x94" \
752 "\x3A\xB7\x86\x96\xFA\x50\x4C\x11" ),
753 MKDATA( "\x1D\x1C\x64\xF0\x68\xCF\x45\xFF" \
754 "\xA2\xA6\x3A\x81\xB7\xC1\x3F\x6B" \
755 "\x88\x47\xA3\xE7\x7E\xF1\x4F\xE3" \
756 "\xDB\x7F\xCA\xFE\x0C\xBD\x10\xE8" \
757 "\xE8\x26\xE0\x34\x36\xD6\x46\xAA" \
758 "\xEF\x87\xB2\xE2\x47\xD4\xAF\x1E" ),
759 MKDATA( "\x8A\xBE\x1D\x75\x20\xF9\xC2\xA4" \
760 "\x5C\xB1\xEB\x8E\x95\xCF\xD5\x52" \
761 "\x62\xB7\x0B\x29\xFE\xEC\x58\x64" \
762 "\xE1\x9C\x05\x4F\xF9\x91\x29\x28" \
763 "\x0E\x46\x46\x21\x77\x91\x81\x11" \
764 "\x42\x82\x03\x41\x26\x3C\x53\x15" ),
765 MKDATA( "\x8C\xB9\x1E\x82\xA3\x38\x6D\x28" \
766 "\x0F\x5D\x6F\x7E\x50\xE6\x41\xDF" \
767 "\x15\x2F\x71\x09\xED\x54\x56\xB3" \
768 "\x1F\x16\x6E\x6C\xAC\x04\x25\xA7" \
769 "\xCF\x3A\xB6\xAF\x6B\x7F\xC3\x10" \
770 "\x3B\x88\x32\x02\xE9\x04\x65\x65" ),
771 MKDATA( "\x01" ),
772 MKDATA( "\x04\xDE\xA5\xE1\x39\x3B\xE0\xB5" \
773 "\x6F\x2C\x0B\xC7\xAF\x9E\xF9\x07" ) },
774
775 /* NIST P-521, SECG p521r1 */
776 { CRYPT_ECCCURVE_P521, 521,
777 MKDATA( "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
778 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
779 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
780 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
781 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
782 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
783 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
784 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
785 "\xFF\xFF" ),
786 MKDATA( "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
787 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
788 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
789 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
790 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
791 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
792 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
793 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
794 "\xFF\xFC" ),
795 MKDATA( "\x00\x51\x95\x3E\xB9\x61\x8E\x1C" \
796 "\x9A\x1F\x92\x9A\x21\xA0\xB6\x85" \
797 "\x40\xEE\xA2\xDA\x72\x5B\x99\xB3" \
798 "\x15\xF3\xB8\xB4\x89\x91\x8E\xF1" \
799 "\x09\xE1\x56\x19\x39\x51\xEC\x7E" \
800 "\x93\x7B\x16\x52\xC0\xBD\x3B\xB1" \
801 "\xBF\x07\x35\x73\xDF\x88\x3D\x2C" \
802 "\x34\xF1\xEF\x45\x1F\xD4\x6B\x50" \
803 "\x3F\x00" ),
804 MKDATA( "\x00\xC6\x85\x8E\x06\xB7\x04\x04" \
805 "\xE9\xCD\x9E\x3E\xCB\x66\x23\x95" \
806 "\xB4\x42\x9C\x64\x81\x39\x05\x3F" \
807 "\xB5\x21\xF8\x28\xAF\x60\x6B\x4D" \
808 "\x3D\xBA\xA1\x4B\x5E\x77\xEF\xE7" \
809 "\x59\x28\xFE\x1D\xC1\x27\xA2\xFF" \
810 "\xA8\xDE\x33\x48\xB3\xC1\x85\x6A" \
811 "\x42\x9B\xF9\x7E\x7E\x31\xC2\xE5" \
812 "\xBD\x66" ),
813 MKDATA( "\x01\x18\x39\x29\x6A\x78\x9A\x3B" \
814 "\xC0\x04\x5C\x8A\x5F\xB4\x2C\x7D" \
815 "\x1B\xD9\x98\xF5\x44\x49\x57\x9B" \
816 "\x44\x68\x17\xAF\xBD\x17\x27\x3E" \
817 "\x66\x2C\x97\xEE\x72\x99\x5E\xF4" \
818 "\x26\x40\xC5\x50\xB9\x01\x3F\xAD" \
819 "\x07\x61\x35\x3C\x70\x86\xA2\x72" \
820 "\xC2\x40\x88\xBE\x94\x76\x9F\xD1" \
821 "\x66\x50" ),
822 MKDATA( "\x01\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
823 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
824 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
825 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" \
826 "\xFF\xFA\x51\x86\x87\x83\xBF\x2F" \
827 "\x96\x6B\x7F\xCC\x01\x48\xF7\x09" \
828 "\xA5\xD0\x3B\xB5\xC9\xB8\x89\x9C" \
829 "\x47\xAE\xBB\x6F\xB7\x1E\x91\x38" \
830 "\x64\x09" ),
831 MKDATA( "\x01" ),
832 MKDATA( "\xC4\x0E\xC4\xCC\x78\x19\x0A\xA6" \
833 "\x8C\x7E\xA0\xB1\x14\xA4\xBC\x23" ) },
834
835 /* Brainpool p512r1 */
836 { CRYPT_ECCCURVE_BRAINPOOL_P512, 512,
837 MKDATA( "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B" \
838 "\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07" \
839 "\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E" \
840 "\xD6\x63\x9C\xCA\x70\x33\x08\x71" \
841 "\x7D\x4D\x9B\x00\x9B\xC6\x68\x42" \
842 "\xAE\xCD\xA1\x2A\xE6\xA3\x80\xE6" \
843 "\x28\x81\xFF\x2F\x2D\x82\xC6\x85" \
844 "\x28\xAA\x60\x56\x58\x3A\x48\xF3" ),
845 MKDATA( "\x78\x30\xA3\x31\x8B\x60\x3B\x89" \
846 "\xE2\x32\x71\x45\xAC\x23\x4C\xC5" \
847 "\x94\xCB\xDD\x8D\x3D\xF9\x16\x10" \
848 "\xA8\x34\x41\xCA\xEA\x98\x63\xBC" \
849 "\x2D\xED\x5D\x5A\xA8\x25\x3A\xA1" \
850 "\x0A\x2E\xF1\xC9\x8B\x9A\xC8\xB5" \
851 "\x7F\x11\x17\xA7\x2B\xF2\xC7\xB9" \
852 "\xE7\xC1\xAC\x4D\x77\xFC\x94\xCA" ),
853 MKDATA( "\x3D\xF9\x16\x10\xA8\x34\x41\xCA" \
854 "\xEA\x98\x63\xBC\x2D\xED\x5D\x5A" \
855 "\xA8\x25\x3A\xA1\x0A\x2E\xF1\xC9" \
856 "\x8B\x9A\xC8\xB5\x7F\x11\x17\xA7" \
857 "\x2B\xF2\xC7\xB9\xE7\xC1\xAC\x4D" \
858 "\x77\xFC\x94\xCA\xDC\x08\x3E\x67" \
859 "\x98\x40\x50\xB7\x5E\xBA\xE5\xDD" \
860 "\x28\x09\xBD\x63\x80\x16\xF7\x23" ),
861 MKDATA( "\x81\xAE\xE4\xBD\xD8\x2E\xD9\x64" \
862 "\x5A\x21\x32\x2E\x9C\x4C\x6A\x93" \
863 "\x85\xED\x9F\x70\xB5\xD9\x16\xC1" \
864 "\xB4\x3B\x62\xEE\xF4\xD0\x09\x8E" \
865 "\xFF\x3B\x1F\x78\xE2\xD0\xD4\x8D" \
866 "\x50\xD1\x68\x7B\x93\xB9\x7D\x5F" \
867 "\x7C\x6D\x50\x47\x40\x6A\x5E\x68" \
868 "\x8B\x35\x22\x09\xBC\xB9\xF8\x22" ),
869 MKDATA( "\x7D\xDE\x38\x5D\x56\x63\x32\xEC" \
870 "\xC0\xEA\xBF\xA9\xCF\x78\x22\xFD" \
871 "\xF2\x09\xF7\x00\x24\xA5\x7B\x1A" \
872 "\xA0\x00\xC5\x5B\x88\x1F\x81\x11" \
873 "\xB2\xDC\xDE\x49\x4A\x5F\x48\x5E" \
874 "\x5B\xCA\x4B\xD8\x8A\x27\x63\xAE" \
875 "\xD1\xCA\x2B\x2F\xA8\xF0\x54\x06" \
876 "\x78\xCD\x1E\x0F\x3A\xD8\x08\x92" ),
877 MKDATA( "\xAA\xDD\x9D\xB8\xDB\xE9\xC4\x8B" \
878 "\x3F\xD4\xE6\xAE\x33\xC9\xFC\x07" \
879 "\xCB\x30\x8D\xB3\xB3\xC9\xD2\x0E" \
880 "\xD6\x63\x9C\xCA\x70\x33\x08\x70" \
881 "\x55\x3E\x5C\x41\x4C\xA9\x26\x19" \
882 "\x41\x86\x61\x19\x7F\xAC\x10\x47" \
883 "\x1D\xB1\xD3\x81\x08\x5D\xDA\xDD" \
884 "\xB5\x87\x96\x82\x9C\xA9\x00\x69" ),
885 MKDATA( "\x01" ),
886 MKDATA( "\x2C\x2A\xE4\xF6\x05\xB6\xAF\xB5"
887 "\x78\xC5\x90\x1E\x45\x9F\x4B\x5C" ) },
888
889 /* End-of-list marker */
890 { CRYPT_ECCCURVE_NONE, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
891 { CRYPT_ECCCURVE_NONE, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
892 };
893
894 /* Checksum values for the ECC data */
895
896 static BOOLEAN eccChecksumsSet = FALSE;
897 static int eccChecksums[ 8 + 8 ];
898
899 /* Check that the DH key data is valid */
900
901 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \
902 static BOOLEAN hashECCparams( const ECC_DOMAIN_PARAMS *eccParams,
903 IN_BUFFER( 20 ) const void *hashValue )
904 {
905 HASHFUNCTION hashFunction;
906 HASHINFO hashInfo;
907 BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
908 const int curveSize = bitsToBytes( eccParams->curveSizeBits );
909 int hashSize;
910
911 assert( isReadPtr( eccParams, sizeof( ECC_DOMAIN_PARAMS ) ) );
912
913 getHashParameters( CRYPT_ALGO_SHA1, 0, &hashFunction, &hashSize );
914 hashFunction( hashInfo, NULL, 0, eccParams->p, curveSize, HASH_STATE_START );
915 hashFunction( hashInfo, NULL, 0, eccParams->a, curveSize, HASH_STATE_CONTINUE );
916 hashFunction( hashInfo, NULL, 0, eccParams->b, curveSize, HASH_STATE_CONTINUE );
917 hashFunction( hashInfo, NULL, 0, eccParams->gx, curveSize, HASH_STATE_CONTINUE );
918 hashFunction( hashInfo, NULL, 0, eccParams->gy, curveSize, HASH_STATE_CONTINUE );
919 hashFunction( hashInfo, NULL, 0, eccParams->n, curveSize, HASH_STATE_CONTINUE );
920 hashFunction( hashInfo, hash, CRYPT_MAX_HASHSIZE, eccParams->h, 1, HASH_STATE_END );
921
922 return( !memcmp( hash, hashValue, 16 ) ? TRUE : FALSE );
923 }
924
925 CHECK_RETVAL \
initCheckECCdata(void)926 static int initCheckECCdata( void )
927 {
928 int i;
929
930 /* Check the SHA-1 values for the ECC data and set up the corresponding
931 checksums for the overall ECC parameters */
932 for( i = 0; domainParamTbl[ i ].paramType != CRYPT_ECCCURVE_NONE && \
933 i < FAILSAFE_ARRAYSIZE( domainParamTbl, ECC_DOMAIN_PARAMS );
934 i++ )
935 {
936 const ECC_DOMAIN_PARAMS *eccParams = &domainParamTbl[ i ];
937
938 if( eccParams->paramType <= CRYPT_ECCCURVE_NONE || \
939 eccParams->paramType >= CRYPT_ECCCURVE_LAST || \
940 eccParams->curveSizeBits < 192 || \
941 eccParams->curveSizeBits > 521 )
942 retIntError();
943 if( !hashECCparams( eccParams, eccParams->hashValue ) )
944 retIntError();
945 eccChecksums[ i ] = checksumData( eccParams,
946 sizeof( ECC_DOMAIN_PARAMS ) );
947 }
948 eccChecksumsSet = TRUE;
949
950 return( CRYPT_OK );
951 }
952
953 /* Initialise the bignums for the domain parameter values { p, a, b, gx, gy,
954 n }. Note that although the cofactor h is given for the standard named
955 curves it's not used for any ECC operations so we don't bother allocating
956 a bignum to it */
957
958 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
loadECCparamsFixed(INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (CRYPT_ECCCURVE)const CRYPT_ECCCURVE_TYPE curveType)959 int loadECCparamsFixed( INOUT CONTEXT_INFO *contextInfoPtr,
960 IN_ENUM( CRYPT_ECCCURVE ) \
961 const CRYPT_ECCCURVE_TYPE curveType )
962 {
963 PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
964 const ECC_DOMAIN_PARAMS *eccParams = NULL;
965 BIGNUM bignums[ 7 ];
966 int curveSize, checksum DUMMY_INIT, i, bnStatus = BN_STATUS, status;
967
968 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
969
970 REQUIRES( sanityCheckPKCInfo( pkcInfo ) );
971 REQUIRES( curveType > CRYPT_ECCCURVE_NONE && \
972 curveType < CRYPT_ECCCURVE_LAST );
973
974 /* Set up the ECC parameter checksums if required */
975 if( !eccChecksumsSet )
976 {
977 status = initCheckECCdata();
978 if( cryptStatusError( status ) )
979 return( status );
980 eccChecksumsSet = TRUE;
981 }
982
983 /* Find the parameter info for this curve */
984 for( i = 0; domainParamTbl[ i ].paramType != CRYPT_ECCCURVE_NONE && \
985 i < FAILSAFE_ARRAYSIZE( domainParamTbl, ECC_DOMAIN_PARAMS );
986 i++ )
987 {
988 if( domainParamTbl[ i ].paramType == curveType )
989 {
990 eccParams = &domainParamTbl[ i ];
991 checksum = eccChecksums[ i ];
992 break;
993 }
994 }
995 ENSURES( i < FAILSAFE_ARRAYSIZE( domainParamTbl, ECC_DOMAIN_PARAMS ) );
996 ENSURES( eccParams != NULL );
997 if( checksum != checksumData( eccParams, sizeof( ECC_DOMAIN_PARAMS ) ) )
998 retIntError();
999
1000 /* For the named curve the key size is defined by exective fiat based
1001 on the curve type rather than being taken from the public-key value
1002 (which in this case is the magnitude of the point Q on the curve), so
1003 we set it explicitly based on the curve type */
1004 pkcInfo->curveType = curveType;
1005 pkcInfo->keySizeBits = eccParams->curveSizeBits;
1006 curveSize = bitsToBytes( eccParams->curveSizeBits );
1007
1008 /* Load the parameters into the context bignums */
1009 for( i = 0; i < 7; i++ )
1010 BN_init( &bignums[ i ] );
1011 CKPTR( BN_bin2bn( eccParams->p, curveSize, &bignums[ 0 ] ) );
1012 CKPTR( BN_bin2bn( eccParams->a, curveSize, &bignums[ 1 ] ) );
1013 CKPTR( BN_bin2bn( eccParams->b, curveSize, &bignums[ 2 ] ) );
1014 CKPTR( BN_bin2bn( eccParams->gx, curveSize, &bignums[ 3 ] ) );
1015 CKPTR( BN_bin2bn( eccParams->gy, curveSize, &bignums[ 4 ] ) );
1016 CKPTR( BN_bin2bn( eccParams->n, curveSize, &bignums[ 5 ] ) );
1017 CKPTR( BN_bin2bn( eccParams->h, 1, &bignums[ 6 ] ) );
1018 if( bnStatusError( bnStatus ) )
1019 return( getBnStatus( bnStatus ) );
1020
1021 printBignum( &bignums[ 0 ], "p" );
1022 printBignum( &bignums[ 1 ], "a" );
1023 printBignum( &bignums[ 2 ], "b" );
1024 printBignum( &bignums[ 3 ], "gx" );
1025 printBignum( &bignums[ 4 ], "gy" );
1026 printBignum( &bignums[ 5 ], "n" );
1027 printBignum( &bignums[ 6 ], "h" );
1028 DEBUG_PRINT(( "\t/* Checksums */\n\t" ));
1029 printBignumChecksum( &bignums[ 0 ] );
1030 printBignumChecksum( &bignums[ 1 ] );
1031 #if BN_BITS2 == 64
1032 DEBUG_PRINT( ( "\n\t" ) );
1033 #endif /* 64- vs 32-bit */
1034 printBignumChecksum( &bignums[ 2 ] );
1035 printBignumChecksum( &bignums[ 3 ] );
1036 DEBUG_PRINT(( "\n\t" ));
1037 printBignumChecksum( &bignums[ 4 ] );
1038 printBignumChecksum( &bignums[ 5 ] );
1039 #if BN_BITS2 == 64
1040 DEBUG_PRINT( ( "\n\t" ) );
1041 #endif /* 64- vs 32-bit */
1042 printBignumChecksum( &bignums[ 6 ] );
1043 DEBUG_PRINT(( "\n" ));
1044
1045 ENSURES( sanityCheckPKCInfo( pkcInfo ) );
1046
1047 return( CRYPT_OK );
1048 }
1049 #endif /* CREATE_BIGNUM_VALUES */
1050
1051 /* ECC values as pre-encoded bignums, allowing them to be used directly */
1052
1053 #if BN_BITS2 == 64
1054
1055 /* NIST P-256, X9.62 p256r1, SECG p256r1, CRYPT_ECCCURVE_P256 */
1056
1057 static const ECC_DOMAINPARAMS p256params = {
1058 /* p */
1059 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1060 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL,
1061 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL } },
1062 /* a */
1063 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1064 0xFFFFFFFFFFFFFFFCULL, 0x00000000FFFFFFFFULL,
1065 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL } },
1066 /* b */
1067 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1068 0x3BCE3C3E27D2604BULL, 0x651D06B0CC53B0F6ULL,
1069 0xB3EBBD55769886BCULL, 0x5AC635D8AA3A93E7ULL } },
1070 /* gx */
1071 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1072 0xF4A13945D898C296ULL, 0x77037D812DEB33A0ULL,
1073 0xF8BCE6E563A440F2ULL, 0x6B17D1F2E12C4247ULL } },
1074 /* gy */
1075 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1076 0xCBB6406837BF51F5ULL, 0x2BCE33576B315ECEULL,
1077 0x8EE7EB4A7C0F9E16ULL, 0x4FE342E2FE1A7F9BULL } },
1078 /* n */
1079 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1080 0xF3B9CAC2FC632551ULL, 0xBCE6FAADA7179E84ULL,
1081 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFF00000000ULL } },
1082 /* h */
1083 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1084 0x0000000000000001ULL } },
1085 /* Checksums */
1086 0xA72822FA39201D4CULL, 0x77FB7550AD79DEE0ULL,
1087 0x4E550413B3F54BB8ULL, 0xE5D81ACCD382A875ULL,
1088 0xA2C6307087289DE6ULL, 0xBB9E6DDEC3E0E95AULL,
1089 0x26402E6EE1F4833EULL
1090 };
1091
1092 /* Brainpool p256r1, CRYPT_ECCCURVE_BRAINPOOL_P256 */
1093
1094 static const ECC_DOMAINPARAMS brainpool256params = {
1095 /* p */
1096 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1097 0x2013481D1F6E5377ULL, 0x6E3BF623D5262028ULL,
1098 0x3E660A909D838D72ULL, 0xA9FB57DBA1EEA9BCULL } },
1099 /* a */
1100 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1101 0xE94A4B44F330B5D9ULL, 0xFB8055C126DC5C6CULL,
1102 0xEEF67530417AFFE7ULL, 0x7D5A0975FC2C3057ULL } },
1103 /* b */
1104 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1105 0x6BCCDC18FF8C07B6ULL, 0x958416295CF7E1CEULL,
1106 0xF330B5D9BBD77CBFULL, 0x26DC5C6CE94A4B44ULL } },
1107 /* gx */
1108 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1109 0x3A4453BD9ACE3262ULL, 0xB9DE27E1E3BD23C2ULL,
1110 0x2C4B482FFC81B7AFULL, 0x8BD2AEB9CB7E57CBULL } },
1111 /* gy */
1112 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1113 0x5C1D54C72F046997ULL, 0xC27745132DED8E54ULL,
1114 0x97F8461A14611DC9ULL, 0x547EF835C3DAC4FDULL } },
1115 /* n */
1116 { BIGNUM_ALLOC_WORDS, 4, FALSE, BN_FLG_STATIC_DATA, {
1117 0x901E0E82974856A7ULL, 0x8C397AA3B561A6F7ULL,
1118 0x3E660A909D838D71ULL, 0xA9FB57DBA1EEA9BCULL } },
1119 /* h */
1120 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1121 0x0000000000000001ULL } },
1122 /* Checksums */
1123 0x8C58020DDBF6A665ULL, 0x50890F90EEF60A86ULL,
1124 0xEA0C456931CC1EEFULL, 0x70E10A10445E70FAULL,
1125 0xAD55C5C5D51EC478ULL, 0x2AB6E0C318795E4FULL,
1126 0x26402E6EE1F4833EULL
1127 };
1128
1129 /* NIST P-384, SECG p384r1, CRYPT_ECCCURVE_P384 */
1130
1131 static const ECC_DOMAINPARAMS p384params = {
1132 /* p */
1133 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1134 0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL,
1135 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL,
1136 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL } },
1137 /* a */
1138 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1139 0x00000000FFFFFFFCULL, 0xFFFFFFFF00000000ULL,
1140 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL,
1141 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL } },
1142 /* b */
1143 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1144 0x2A85C8EDD3EC2AEFULL, 0xC656398D8A2ED19DULL,
1145 0x0314088F5013875AULL, 0x181D9C6EFE814112ULL,
1146 0x988E056BE3F82D19ULL, 0xB3312FA7E23EE7E4ULL } },
1147 /* gx */
1148 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1149 0x3A545E3872760AB7ULL, 0x5502F25DBF55296CULL,
1150 0x59F741E082542A38ULL, 0x6E1D3B628BA79B98ULL,
1151 0x8EB1C71EF320AD74ULL, 0xAA87CA22BE8B0537ULL } },
1152 /* gy */
1153 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1154 0x7A431D7C90EA0E5FULL, 0x0A60B1CE1D7E819DULL,
1155 0xE9DA3113B5F0B8C0ULL, 0xF8F41DBD289A147CULL,
1156 0x5D9E98BF9292DC29ULL, 0x3617DE4A96262C6FULL } },
1157 /* n */
1158 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1159 0xECEC196ACCC52973ULL, 0x581A0DB248B0A77AULL,
1160 0xC7634D81F4372DDFULL, 0xFFFFFFFFFFFFFFFFULL,
1161 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL } },
1162 /* h */
1163 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1164 0x0000000000000001ULL } },
1165 /* Checksums */
1166 0x9A9A47599E9FA193ULL, 0x8A54B4DE8DBA0429ULL,
1167 0xFB1CEA2E3FFD90F0ULL, 0x14A04AC2065B13E6ULL,
1168 0xBC63FBAFCEB8C35DULL, 0xA679E5A399BA581CULL,
1169 0x26402E6EE1F4833EULL
1170 };
1171
1172 /* Brainpool p384r1, CRYPT_ECCCURVE_BRAINPOOL_P384 */
1173
1174 static const ECC_DOMAINPARAMS brainpool384params = {
1175 /* p */
1176 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1177 0x874700133107EC53ULL, 0xACD3A729901D1A71ULL,
1178 0x12B1DA197FB71123ULL, 0x152F7109ED5456B4ULL,
1179 0x0F5D6F7E50E641DFULL, 0x8CB91E82A3386D28ULL } },
1180 /* a */
1181 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1182 0x04A8C7DD22CE2826ULL, 0x8AA5814A503AD4EBULL,
1183 0x139165EFBA91F90FULL, 0xC2BEA28E4FB22787ULL,
1184 0x3C72080ACE05AFA0ULL, 0x7BC382C63D8C150CULL } },
1185 /* b */
1186 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1187 0x3AB78696FA504C11ULL, 0x7CB4390295DBC994ULL,
1188 0x2E880EA53EEB62D5ULL, 0x2FB77DE107DCD2A6ULL,
1189 0x8B39B55416F0447CULL, 0x04A8C7DD22CE2826ULL } },
1190 /* gx */
1191 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1192 0xEF87B2E247D4AF1EULL, 0xE826E03436D646AAULL,
1193 0xDB7FCAFE0CBD10E8ULL, 0x8847A3E77EF14FE3ULL,
1194 0xA2A63A81B7C13F6BULL, 0x1D1C64F068CF45FFULL } },
1195 /* gy */
1196 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1197 0x42820341263C5315ULL, 0x0E46462177918111ULL,
1198 0xE19C054FF9912928ULL, 0x62B70B29FEEC5864ULL,
1199 0x5CB1EB8E95CFD552ULL, 0x8ABE1D7520F9C2A4ULL } },
1200 /* n */
1201 { BIGNUM_ALLOC_WORDS, 6, FALSE, BN_FLG_STATIC_DATA, {
1202 0x3B883202E9046565ULL, 0xCF3AB6AF6B7FC310ULL,
1203 0x1F166E6CAC0425A7ULL, 0x152F7109ED5456B3ULL,
1204 0x0F5D6F7E50E641DFULL, 0x8CB91E82A3386D28ULL } },
1205 /* h */
1206 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1207 0x0000000000000001ULL } },
1208 /* Checksums */
1209 0x6A9E0847ABC8E154ULL, 0x61C83241A722DD92ULL,
1210 0xD325B1754DE15E11ULL, 0x350A61B48CD1B7F9ULL,
1211 0xFAB31A42AC6B58C9ULL, 0xE36D9145DA891AF4ULL,
1212 0x26402E6EE1F4833EULL
1213 };
1214
1215 /* NIST P-521, SECG p521r1, CRYPT_ECCCURVE_P521 */
1216
1217 static const ECC_DOMAINPARAMS p521params = {
1218 /* p */
1219 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1220 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1221 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1222 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1223 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1224 0x00000000000001FFULL } },
1225 /* a */
1226 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1227 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL,
1228 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1229 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1230 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1231 0x00000000000001FFULL } },
1232 /* b */
1233 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1234 0xEF451FD46B503F00ULL, 0x3573DF883D2C34F1ULL,
1235 0x1652C0BD3BB1BF07ULL, 0x56193951EC7E937BULL,
1236 0xB8B489918EF109E1ULL, 0xA2DA725B99B315F3ULL,
1237 0x929A21A0B68540EEULL, 0x953EB9618E1C9A1FULL,
1238 0x0000000000000051ULL } },
1239 /* gx */
1240 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1241 0xF97E7E31C2E5BD66ULL, 0x3348B3C1856A429BULL,
1242 0xFE1DC127A2FFA8DEULL, 0xA14B5E77EFE75928ULL,
1243 0xF828AF606B4D3DBAULL, 0x9C648139053FB521ULL,
1244 0x9E3ECB662395B442ULL, 0x858E06B70404E9CDULL,
1245 0x00000000000000C6ULL } },
1246 /* gy */
1247 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1248 0x88BE94769FD16650ULL, 0x353C7086A272C240ULL,
1249 0xC550B9013FAD0761ULL, 0x97EE72995EF42640ULL,
1250 0x17AFBD17273E662CULL, 0x98F54449579B4468ULL,
1251 0x5C8A5FB42C7D1BD9ULL, 0x39296A789A3BC004ULL,
1252 0x0000000000000118ULL } },
1253 /* n */
1254 { BIGNUM_ALLOC_WORDS, 9, FALSE, BN_FLG_STATIC_DATA, {
1255 0xBB6FB71E91386409ULL, 0x3BB5C9B8899C47AEULL,
1256 0x7FCC0148F709A5D0ULL, 0x51868783BF2F966BULL,
1257 0xFFFFFFFFFFFFFFFAULL, 0xFFFFFFFFFFFFFFFFULL,
1258 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL,
1259 0x00000000000001FFULL } },
1260 /* h */
1261 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1262 0x0000000000000001ULL } },
1263 /* Checksums */
1264 0xDA99C55253FF5436ULL, 0x2847E17D2F34D05BULL,
1265 0x11D14F0DFE0C6BF1ULL, 0x5F95A0E0F9B321C8ULL,
1266 0x2EEA29DDC3441128ULL, 0x2595D584A94B217DULL,
1267 0x26402E6EE1F4833EULL
1268 };
1269
1270 /* Brainpool p512r1, CRYPT_ECCCURVE_BRAINPOOL_P512 */
1271
1272 static const ECC_DOMAINPARAMS brainpool512params = {
1273 /* p */
1274 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1275 0x28AA6056583A48F3ULL, 0x2881FF2F2D82C685ULL,
1276 0xAECDA12AE6A380E6ULL, 0x7D4D9B009BC66842ULL,
1277 0xD6639CCA70330871ULL, 0xCB308DB3B3C9D20EULL,
1278 0x3FD4E6AE33C9FC07ULL, 0xAADD9DB8DBE9C48BULL } },
1279 /* a */
1280 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1281 0xE7C1AC4D77FC94CAULL, 0x7F1117A72BF2C7B9ULL,
1282 0x0A2EF1C98B9AC8B5ULL, 0x2DED5D5AA8253AA1ULL,
1283 0xA83441CAEA9863BCULL, 0x94CBDD8D3DF91610ULL,
1284 0xE2327145AC234CC5ULL, 0x7830A3318B603B89ULL } },
1285 /* b */
1286 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1287 0x2809BD638016F723ULL, 0x984050B75EBAE5DDULL,
1288 0x77FC94CADC083E67ULL, 0x2BF2C7B9E7C1AC4DULL,
1289 0x8B9AC8B57F1117A7ULL, 0xA8253AA10A2EF1C9ULL,
1290 0xEA9863BC2DED5D5AULL, 0x3DF91610A83441CAULL } },
1291 /* gx */
1292 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1293 0x8B352209BCB9F822ULL, 0x7C6D5047406A5E68ULL,
1294 0x50D1687B93B97D5FULL, 0xFF3B1F78E2D0D48DULL,
1295 0xB43B62EEF4D0098EULL, 0x85ED9F70B5D916C1ULL,
1296 0x5A21322E9C4C6A93ULL, 0x81AEE4BDD82ED964ULL } },
1297 /* gy */
1298 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1299 0x78CD1E0F3AD80892ULL, 0xD1CA2B2FA8F05406ULL,
1300 0x5BCA4BD88A2763AEULL, 0xB2DCDE494A5F485EULL,
1301 0xA000C55B881F8111ULL, 0xF209F70024A57B1AULL,
1302 0xC0EABFA9CF7822FDULL, 0x7DDE385D566332ECULL } },
1303 /* n */
1304 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1305 0xB58796829CA90069ULL, 0x1DB1D381085DDADDULL,
1306 0x418661197FAC1047ULL, 0x553E5C414CA92619ULL,
1307 0xD6639CCA70330870ULL, 0xCB308DB3B3C9D20EULL,
1308 0x3FD4E6AE33C9FC07ULL, 0xAADD9DB8DBE9C48BULL } },
1309 /* h */
1310 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1311 0x0000000000000001ULL } },
1312 /* Checksums */
1313 0xC1DA14200D9335A0ULL, 0x0576ECE4ABA7F09BULL,
1314 0x4319F6256D8AAFCFULL, 0x1042D928E89F3778ULL,
1315 0x0A26038C333433C3ULL, 0x1B30D8586B566AFDULL,
1316 0x26402E6EE1F4833EULL
1317 };
1318
1319 #else
1320
1321 /* NIST P-256, X9.62 p256r1, SECG p256r1, CRYPT_ECCCURVE_P256 */
1322
1323 static const ECC_DOMAINPARAMS p256params = {
1324 /* p */
1325 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1326 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
1327 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF } },
1328 /* a */
1329 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1330 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
1331 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF } },
1332 /* b */
1333 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1334 0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0,
1335 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8 } },
1336 /* gx */
1337 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1338 0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81,
1339 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2 } },
1340 /* gy */
1341 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1342 0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357,
1343 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2 } },
1344 /* n */
1345 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1346 0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD,
1347 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF } },
1348 /* h */
1349 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1350 0x00000001 } },
1351 /* Checksums */
1352 0xF3897EFA, 0xA860F782, 0x3994862C, 0x1E8D2321,
1353 0x15B99322, 0x4943FE0A, 0x75E7E997
1354 };
1355
1356 /* Brainpool p256r1, CRYPT_ECCCURVE_BRAINPOOL_P256 */
1357
1358 static const ECC_DOMAINPARAMS brainpool256params = {
1359 /* p */
1360 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1361 0x1F6E5377, 0x2013481D, 0xD5262028, 0x6E3BF623,
1362 0x9D838D72, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB } },
1363 /* a */
1364 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1365 0xF330B5D9, 0xE94A4B44, 0x26DC5C6C, 0xFB8055C1,
1366 0x417AFFE7, 0xEEF67530, 0xFC2C3057, 0x7D5A0975 } },
1367 /* b */
1368 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1369 0xFF8C07B6, 0x6BCCDC18, 0x5CF7E1CE, 0x95841629,
1370 0xBBD77CBF, 0xF330B5D9, 0xE94A4B44, 0x26DC5C6C } },
1371 /* gx */
1372 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1373 0x9ACE3262, 0x3A4453BD, 0xE3BD23C2, 0xB9DE27E1,
1374 0xFC81B7AF, 0x2C4B482F, 0xCB7E57CB, 0x8BD2AEB9 } },
1375 /* gy */
1376 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1377 0x2F046997, 0x5C1D54C7, 0x2DED8E54, 0xC2774513,
1378 0x14611DC9, 0x97F8461A, 0xC3DAC4FD, 0x547EF835 } },
1379 /* n */
1380 { BIGNUM_ALLOC_WORDS, 8, FALSE, BN_FLG_STATIC_DATA, {
1381 0x974856A7, 0x901E0E82, 0xB561A6F7, 0x8C397AA3,
1382 0x9D838D71, 0x3E660A90, 0xA1EEA9BC, 0xA9FB57DB } },
1383 /* h */
1384 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1385 0x00000001 } },
1386 /* Checksums */
1387 0x3498DCF4, 0x3BCBEBC2, 0x69495E03, 0x2AD8069D,
1388 0x11DAF3CF, 0xCA928D15, 0x75E7E997
1389 };
1390
1391 /* NIST P-384, SECG p384r1, CRYPT_ECCCURVE_P384 */
1392
1393 static const ECC_DOMAINPARAMS p384params = {
1394 /* p */
1395 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1396 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF,
1397 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1398 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } },
1399 /* a */
1400 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1401 0xFFFFFFFC, 0x00000000, 0x00000000, 0xFFFFFFFF,
1402 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1403 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } },
1404 /* b */
1405 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1406 0xD3EC2AEF, 0x2A85C8ED, 0x8A2ED19D, 0xC656398D,
1407 0x5013875A, 0x0314088F, 0xFE814112, 0x181D9C6E,
1408 0xE3F82D19, 0x988E056B, 0xE23EE7E4, 0xB3312FA7 } },
1409 /* gx */
1410 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1411 0x72760AB7, 0x3A545E38, 0xBF55296C, 0x5502F25D,
1412 0x82542A38, 0x59F741E0, 0x8BA79B98, 0x6E1D3B62,
1413 0xF320AD74, 0x8EB1C71E, 0xBE8B0537, 0xAA87CA22 } },
1414 /* gy */
1415 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1416 0x90EA0E5F, 0x7A431D7C, 0x1D7E819D, 0x0A60B1CE,
1417 0xB5F0B8C0, 0xE9DA3113, 0x289A147C, 0xF8F41DBD,
1418 0x9292DC29, 0x5D9E98BF, 0x96262C6F, 0x3617DE4A } },
1419 /* n */
1420 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1421 0xCCC52973, 0xECEC196A, 0x48B0A77A, 0x581A0DB2,
1422 0xF4372DDF, 0xC7634D81, 0xFFFFFFFF, 0xFFFFFFFF,
1423 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } },
1424 /* h */
1425 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1426 0x00000001 } },
1427 /* Checksums */
1428 0x7D715AAC, 0x1FC7CA5A, 0x114D671D, 0x9173FBBF,
1429 0x26E973C0, 0x8D05F26F, 0x75E7E997
1430 };
1431
1432 /* Brainpool p384r1, CRYPT_ECCCURVE_BRAINPOOL_P384 */
1433
1434 static const ECC_DOMAINPARAMS brainpool384params = {
1435 /* p */
1436 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1437 0x3107EC53, 0x87470013, 0x901D1A71, 0xACD3A729,
1438 0x7FB71123, 0x12B1DA19, 0xED5456B4, 0x152F7109,
1439 0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82 } },
1440 /* a */
1441 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1442 0x22CE2826, 0x04A8C7DD, 0x503AD4EB, 0x8AA5814A,
1443 0xBA91F90F, 0x139165EF, 0x4FB22787, 0xC2BEA28E,
1444 0xCE05AFA0, 0x3C72080A, 0x3D8C150C, 0x7BC382C6 } },
1445 /* b */
1446 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1447 0xFA504C11, 0x3AB78696, 0x95DBC994, 0x7CB43902,
1448 0x3EEB62D5, 0x2E880EA5, 0x07DCD2A6, 0x2FB77DE1,
1449 0x16F0447C, 0x8B39B554, 0x22CE2826, 0x04A8C7DD } },
1450 /* gx */
1451 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1452 0x47D4AF1E, 0xEF87B2E2, 0x36D646AA, 0xE826E034,
1453 0x0CBD10E8, 0xDB7FCAFE, 0x7EF14FE3, 0x8847A3E7,
1454 0xB7C13F6B, 0xA2A63A81, 0x68CF45FF, 0x1D1C64F0 } },
1455 /* gy */
1456 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1457 0x263C5315, 0x42820341, 0x77918111, 0x0E464621,
1458 0xF9912928, 0xE19C054F, 0xFEEC5864, 0x62B70B29,
1459 0x95CFD552, 0x5CB1EB8E, 0x20F9C2A4, 0x8ABE1D75 } },
1460 /* n */
1461 { BIGNUM_ALLOC_WORDS, 12, FALSE, BN_FLG_STATIC_DATA, {
1462 0xE9046565, 0x3B883202, 0x6B7FC310, 0xCF3AB6AF,
1463 0xAC0425A7, 0x1F166E6C, 0xED5456B3, 0x152F7109,
1464 0x50E641DF, 0x0F5D6F7E, 0xA3386D28, 0x8CB91E82 } },
1465 /* h */
1466 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1467 0x00000001 } },
1468 /* Checksums */
1469 0xA104D6F2, 0x0154CB82, 0xF8B07960, 0xACC086CC,
1470 0x7F4924D6, 0x0B03676F, 0x75E7E997
1471 };
1472
1473 /* NIST P-521, SECG p521r1, CRYPT_ECCCURVE_P521 */
1474
1475 static const ECC_DOMAINPARAMS p521params = {
1476 /* p */
1477 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1478 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1479 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1480 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1481 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1482 0x000001FF } },
1483 /* a */
1484 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1485 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1486 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1487 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1488 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1489 0x000001FF } },
1490 /* b */
1491 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1492 0x6B503F00, 0xEF451FD4, 0x3D2C34F1, 0x3573DF88,
1493 0x3BB1BF07, 0x1652C0BD, 0xEC7E937B, 0x56193951,
1494 0x8EF109E1, 0xB8B48991, 0x99B315F3, 0xA2DA725B,
1495 0xB68540EE, 0x929A21A0, 0x8E1C9A1F, 0x953EB961,
1496 0x00000051 } },
1497 /* gx */
1498 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1499 0xC2E5BD66, 0xF97E7E31, 0x856A429B, 0x3348B3C1,
1500 0xA2FFA8DE, 0xFE1DC127, 0xEFE75928, 0xA14B5E77,
1501 0x6B4D3DBA, 0xF828AF60, 0x053FB521, 0x9C648139,
1502 0x2395B442, 0x9E3ECB66, 0x0404E9CD, 0x858E06B7,
1503 0x000000C6 } },
1504 /* gy */
1505 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1506 0x9FD16650, 0x88BE9476, 0xA272C240, 0x353C7086,
1507 0x3FAD0761, 0xC550B901, 0x5EF42640, 0x97EE7299,
1508 0x273E662C, 0x17AFBD17, 0x579B4468, 0x98F54449,
1509 0x2C7D1BD9, 0x5C8A5FB4, 0x9A3BC004, 0x39296A78,
1510 0x00000118 } },
1511 /* n */
1512 { BIGNUM_ALLOC_WORDS, 17, FALSE, BN_FLG_STATIC_DATA, {
1513 0x91386409, 0xBB6FB71E, 0x899C47AE, 0x3BB5C9B8,
1514 0xF709A5D0, 0x7FCC0148, 0xBF2F966B, 0x51868783,
1515 0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1516 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
1517 0x000001FF } },
1518 /* h */
1519 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1520 0x00000001 } },
1521 /* Checksums */
1522 0xF0CB48FC, 0xC89C4882, 0xB1A12B3C, 0x22B097CC,
1523 0xEE2FFB2E, 0xA2E7127F, 0x75E7E997
1524 };
1525
1526 /* Brainpool p512r1, CRYPT_ECCCURVE_BRAINPOOL_P512 */
1527
1528 static const ECC_DOMAINPARAMS brainpool512params = {
1529 /* p */
1530 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1531 0x583A48F3, 0x28AA6056, 0x2D82C685, 0x2881FF2F,
1532 0xE6A380E6, 0xAECDA12A, 0x9BC66842, 0x7D4D9B00,
1533 0x70330871, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3,
1534 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8 } },
1535 /* a */
1536 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1537 0x77FC94CA, 0xE7C1AC4D, 0x2BF2C7B9, 0x7F1117A7,
1538 0x8B9AC8B5, 0x0A2EF1C9, 0xA8253AA1, 0x2DED5D5A,
1539 0xEA9863BC, 0xA83441CA, 0x3DF91610, 0x94CBDD8D,
1540 0xAC234CC5, 0xE2327145, 0x8B603B89, 0x7830A331 } },
1541 /* b */
1542 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1543 0x8016F723, 0x2809BD63, 0x5EBAE5DD, 0x984050B7,
1544 0xDC083E67, 0x77FC94CA, 0xE7C1AC4D, 0x2BF2C7B9,
1545 0x7F1117A7, 0x8B9AC8B5, 0x0A2EF1C9, 0xA8253AA1,
1546 0x2DED5D5A, 0xEA9863BC, 0xA83441CA, 0x3DF91610 } },
1547 /* gx */
1548 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1549 0xBCB9F822, 0x8B352209, 0x406A5E68, 0x7C6D5047,
1550 0x93B97D5F, 0x50D1687B, 0xE2D0D48D, 0xFF3B1F78,
1551 0xF4D0098E, 0xB43B62EE, 0xB5D916C1, 0x85ED9F70,
1552 0x9C4C6A93, 0x5A21322E, 0xD82ED964, 0x81AEE4BD } },
1553 /* gy */
1554 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1555 0x3AD80892, 0x78CD1E0F, 0xA8F05406, 0xD1CA2B2F,
1556 0x8A2763AE, 0x5BCA4BD8, 0x4A5F485E, 0xB2DCDE49,
1557 0x881F8111, 0xA000C55B, 0x24A57B1A, 0xF209F700,
1558 0xCF7822FD, 0xC0EABFA9, 0x566332EC, 0x7DDE385D } },
1559 /* n */
1560 { BIGNUM_ALLOC_WORDS, 16, FALSE, BN_FLG_STATIC_DATA, {
1561 0x9CA90069, 0xB5879682, 0x085DDADD, 0x1DB1D381,
1562 0x7FAC1047, 0x41866119, 0x4CA92619, 0x553E5C41,
1563 0x70330870, 0xD6639CCA, 0xB3C9D20E, 0xCB308DB3,
1564 0x33C9FC07, 0x3FD4E6AE, 0xDBE9C48B, 0xAADD9DB8 } },
1565 /* h */
1566 { BIGNUM_ALLOC_WORDS, 1, FALSE, BN_FLG_STATIC_DATA, {
1567 0x00000001 } },
1568 /* Checksums */
1569 0x8A2C6186, 0x8FBBE214, 0x60D7593D, 0x02F580D8,
1570 0xD6823856, 0xBD31D0D9, 0x75E7E997
1571 };
1572 #endif /* 64- vs 32-bit */
1573
1574 /****************************************************************************
1575 * *
1576 * ECC Access Functions *
1577 * *
1578 ****************************************************************************/
1579
1580 /* Initialise the bignums for the domain parameter values { p, a, b, gx, gy,
1581 n }. Note that although the cofactor h is given for the standard named
1582 curves it's not used for any ECC operations, so we could quite easily
1583 omit it */
1584
1585 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
loadECCparams(INOUT CONTEXT_INFO * contextInfoPtr,IN_ENUM (CRYPT_ECCCURVE)const CRYPT_ECCCURVE_TYPE curveType)1586 int loadECCparams( INOUT CONTEXT_INFO *contextInfoPtr,
1587 IN_ENUM( CRYPT_ECCCURVE ) \
1588 const CRYPT_ECCCURVE_TYPE curveType )
1589 {
1590 PKC_INFO *pkcInfo = contextInfoPtr->ctxPKC;
1591 const ECC_DOMAINPARAMS *domainParams;
1592 int curveSizeBits, status;
1593
1594 assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
1595
1596 REQUIRES( sanityCheckPKCInfo( pkcInfo ) );
1597 REQUIRES( curveType > CRYPT_ECCCURVE_NONE && \
1598 curveType < CRYPT_ECCCURVE_LAST );
1599
1600 /* Convert the fixed-format bignums to encoded BIGNUMs */
1601 #ifdef CREATE_BIGNUM_VALUES
1602 status = loadECCparamsFixed( contextInfoPtr, curveType );
1603 if( cryptStatusError( status ) )
1604 return( status );
1605 #endif /* CREATE_BIGNUM_VALUES */
1606
1607 /* Get the requested domain parameters */
1608 switch( curveType )
1609 {
1610 case CRYPT_ECCCURVE_P256:
1611 domainParams = &p256params;
1612 break;
1613
1614 case CRYPT_ECCCURVE_BRAINPOOL_P256:
1615 domainParams = &brainpool256params;
1616 break;
1617
1618 case CRYPT_ECCCURVE_P384:
1619 domainParams = &p384params;
1620 break;
1621
1622 case CRYPT_ECCCURVE_BRAINPOOL_P384:
1623 domainParams = &brainpool384params;
1624 break;
1625
1626 case CRYPT_ECCCURVE_P521:
1627 domainParams = &p521params;
1628 break;
1629
1630 case CRYPT_ECCCURVE_BRAINPOOL_P512:
1631 domainParams = &brainpool512params;
1632 break;
1633
1634 default:
1635 retIntError();
1636 }
1637
1638 /* For the named curve the key size is defined by exective fiat based
1639 on the curve type rather than being taken from the public-key value
1640 (which in this case is the magnitude of the point Q on the curve), so
1641 we set it explicitly based on the curve type */
1642 status = getECCFieldSize( curveType, &curveSizeBits, TRUE );
1643 if( cryptStatusError( status ) )
1644 return( status );
1645 pkcInfo->curveType = curveType;
1646 pkcInfo->keySizeBits = curveSizeBits;
1647
1648 /* Make sure that the domain parameters are in order */
1649 if( !checksumDomainParameters( domainParams, TRUE ) )
1650 {
1651 DEBUG_DIAG(( "ECC domain parameters for curve ID %d key has been "
1652 "corrupted", curveType ));
1653 retIntError();
1654 }
1655
1656 pkcInfo->domainParams = domainParams;
1657
1658 ENSURES( sanityCheckPKCInfo( pkcInfo ) );
1659
1660 return( CRYPT_OK );
1661 }
1662 #endif /* USE_ECDH || USE_ECDSA */
1663