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