1 /****************************************************************************
2 *																			*
3 *					cryptlib SSL v3/TLS Cipher Suites						*
4 *					Copyright Peter Gutmann 1998-2014						*
5 *																			*
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9   #include "crypt.h"
10   #include "session.h"
11   #include "ssl.h"
12 #else
13   #include "crypt.h"
14   #include "session/session.h"
15   #include "session/ssl.h"
16 #endif /* Compiler-specific includes */
17 
18 #ifdef USE_SSL
19 
20 /****************************************************************************
21 *																			*
22 *							Cipher Suite Definitions						*
23 *																			*
24 ****************************************************************************/
25 
26 /* The monster list of cryptlib's SSL/TLS cipher suites (the full list is
27    much, much longer than this).  There are a pile of DH cipher suites, in
28    practice only DHE is used, DH requires the use of X9.42 DH certificates
29    (there aren't any) and DH_anon uses unauthenticated DH which implementers
30    seem to have an objection to even though it's not much different in
31    effect from the way RSA cipher suites are used in practice.
32 
33    To keep things simple for the caller we only allow RSA auth for DH key
34    agreement and not DSA, since the former also automatically works for the
35    far more common RSA key exchange that's usually used for key setup.
36    Similarly we only allow ECDSA for ECDH, since anyone who wants to make
37    the ECC fashion statement isn't going to then fall back to RSA for the
38    server authentication.
39 
40    We prefer AES-128 to AES-256 since -256 has a weaker key schedule than
41    -128, so if anyone's going to attack it they'll go for the key schedule
42    rather than the (mostly irrelevant) -128 vs. -256.
43 
44    In some piece of SuiteB bizarritude a number of suites that have a
45    xxx_WITH_AES_128_xxx_SHA256 only have a xxx_WITH_AES_256_xxx_SHA384
46    equivalent but no xxx_WITH_AES_256_xxx_SHA256, which is why there are a
47    number of suites with apparently-mismatched AES-128 only options.
48 
49    The number of suites and different configuration options are sufficiently
50    complex that we can't use a fixed table for them but have to dynamically
51    build them up at runtime from the following sub-tables */
52 
53 #define MAX_CIPHERSUITE_TBLSIZE		64
54 
55 static const CIPHERSUITE_INFO cipherSuiteDH[] = {
56 	/* AES with DH */
57 	{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
58 	  DESCRIPTION( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256" )
59 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
60 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, SHA2MAC_SIZE,
61 	  CIPHERSUITE_FLAG_DH | CIPHERSUITE_FLAG_TLS12 },
62 	{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
63 	  DESCRIPTION( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256" )
64 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
65 	  CRYPT_ALGO_HMAC_SHA2, 0, 32, SHA2MAC_SIZE,
66 	  CIPHERSUITE_FLAG_DH | CIPHERSUITE_FLAG_TLS12 },
67 	{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
68 	  DESCRIPTION( "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" )
69 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
70 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
71 	  CIPHERSUITE_FLAG_DH },
72 	{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
73 	  DESCRIPTION( "TLS_DHE_RSA_WITH_AES_256_CBC_SHA" )
74 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
75 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE, CIPHERSUITE_FLAG_DH },
76 
77 	/* 3DES with DH */
78 	{ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
79 	  DESCRIPTION( "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA" )
80 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_3DES,
81 	  CRYPT_ALGO_HMAC_SHA1, 0, 24, SHA1MAC_SIZE,
82 	  CIPHERSUITE_FLAG_DH },
83 
84 	/* End-of-list marker */
85 	{ SSL_NULL_WITH_NULL,
86 	  DESCRIPTION( "End-of-list marker" )
87 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
88 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE },
89 	{ SSL_NULL_WITH_NULL,
90 	  DESCRIPTION( "End-of-list marker" )
91 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
92 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE }
93 	};
94 
95 #if defined( USE_ECDSA ) && defined( USE_ECDH )
96 
97 static const CIPHERSUITE_INFO cipherSuiteECC[] = {
98 	/* ECDH with ECDSA */
99 	{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
100 	  DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" )
101 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
102 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, SHA2MAC_SIZE,
103 	  CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_TLS12 },
104 /*	{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
105 	  DESCRIPTION( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" )
106 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
107 	  CRYPT_ALGO_HMAC_SHA2, 0, 32, SHA2MAC_SIZE,
108 	  CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_TLS12 }, */
109 	{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
110 	  DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" )
111 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
112 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
113 	  CIPHERSUITE_FLAG_ECC },
114 	{ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
115 	  DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" )
116 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
117 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE,
118 	  CIPHERSUITE_FLAG_ECC },
119 	{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
120 	  DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" )
121 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_3DES,
122 	  CRYPT_ALGO_HMAC_SHA1, 0, 24, SHA1MAC_SIZE,
123 	  CIPHERSUITE_FLAG_ECC },
124 
125 	/* ECDH with RSA */
126 /*	{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
127 	  DESCRIPTION( "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" )
128 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
129 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
130 	  CIPHERSUITE_FLAG_ECC },
131 	{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
132 	  DESCRIPTION( "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" )
133 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
134 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE,
135 	  CIPHERSUITE_FLAG_ECC }, */
136 
137 	/* End-of-list marker */
138 	{ SSL_NULL_WITH_NULL,
139 	  DESCRIPTION( "End-of-list marker" )
140 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
141 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE },
142 	{ SSL_NULL_WITH_NULL,
143 	  DESCRIPTION( "End-of-list marker" )
144 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
145 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE }
146 	};
147 #endif /* USE_ECDSA && USE_ECDH */
148 
149 #ifdef USE_GCM
150 
151 static const CIPHERSUITE_INFO cipherSuiteGCM[] = {
152 	/* ECDH with ECDSA and AES-GCM */
153 	{ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
154 	  DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" )
155 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
156 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, GCMICV_SIZE,
157 	  CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12 },
158 /*	{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
159 	  DESCRIPTION( "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" )
160 	  CRYPT_ALGO_ECDH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
161 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, GCMICV_SIZE,
162 	  CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12 }, */
163 
164 	/* AES-GCM with DH */
165 	{ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
166 	  DESCRIPTION( "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" )
167 	  CRYPT_ALGO_DH, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
168 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, GCMICV_SIZE,
169 	  CIPHERSUITE_FLAG_DH | CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12 },
170 
171 	/* AES-GCM with RSA */
172 	{ TLS_RSA_WITH_AES_128_GCM_SHA256,
173 	  DESCRIPTION( "TLS_RSA_WITH_AES_128_GCM_SHA256" )
174 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
175 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, GCMICV_SIZE,
176 	  CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12 },
177 
178 	/* End-of-list marker */
179 	{ SSL_NULL_WITH_NULL,
180 	  DESCRIPTION( "End-of-list marker" )
181 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
182 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE },
183 	{ SSL_NULL_WITH_NULL,
184 	  DESCRIPTION( "End-of-list marker" )
185 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
186 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE }
187 	};
188 #endif /* USE_GCM */
189 
190 static const CIPHERSUITE_INFO cipherSuitePSK[] = {
191 	/* PSK with PFS */
192 	{ TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
193 	  DESCRIPTION( "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" )
194 	  CRYPT_ALGO_DH, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
195 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, SHA2MAC_SIZE,
196 	  CIPHERSUITE_FLAG_PSK | CIPHERSUITE_FLAG_DH | CIPHERSUITE_FLAG_TLS12 },
197 	{ TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
198 	  DESCRIPTION( "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" )
199 	  CRYPT_ALGO_DH, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
200 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
201 	  CIPHERSUITE_FLAG_PSK | CIPHERSUITE_FLAG_DH },
202 	{ TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
203 	  DESCRIPTION( "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" )
204 	  CRYPT_ALGO_DH, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
205 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE,
206 	  CIPHERSUITE_FLAG_PSK | CIPHERSUITE_FLAG_DH },
207 	{ TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
208 	  DESCRIPTION( "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" )
209 	  CRYPT_ALGO_DH, CRYPT_ALGO_NONE, CRYPT_ALGO_3DES,
210 	  CRYPT_ALGO_HMAC_SHA1, 0, 24, SHA1MAC_SIZE,
211 	  CIPHERSUITE_FLAG_PSK | CIPHERSUITE_FLAG_DH },
212 
213 	/* PSK without PFS */
214 	{ TLS_PSK_WITH_AES_128_CBC_SHA256,
215 	  DESCRIPTION( "TLS_PSK_WITH_AES_128_CBC_SHA256" )
216 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
217 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, SHA2MAC_SIZE,
218 	  CIPHERSUITE_FLAG_PSK | CIPHERSUITE_FLAG_TLS12 },
219 	{ TLS_PSK_WITH_AES_128_CBC_SHA,
220 	  DESCRIPTION( "TLS_PSK_WITH_AES_128_CBC_SHA" )
221 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
222 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
223 	  CIPHERSUITE_FLAG_PSK },
224 	{ TLS_PSK_WITH_AES_256_CBC_SHA,
225 	  DESCRIPTION( "TLS_PSK_WITH_AES_256_CBC_SHA" )
226 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_AES,
227 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE,
228 	  CIPHERSUITE_FLAG_PSK },
229 	{ TLS_PSK_WITH_3DES_EDE_CBC_SHA,
230 	  DESCRIPTION( "TLS_PSK_WITH_3DES_EDE_CBC_SHA" )
231 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_3DES,
232 	  CRYPT_ALGO_HMAC_SHA1, 0, 24, SHA1MAC_SIZE,
233 	  CIPHERSUITE_FLAG_PSK },
234 
235 	/* End-of-list marker */
236 	{ SSL_NULL_WITH_NULL,
237 	  DESCRIPTION( "End-of-list marker" )
238 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
239 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE },
240 	{ SSL_NULL_WITH_NULL,
241 	  DESCRIPTION( "End-of-list marker" )
242 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
243 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE }
244 	};
245 
246 static const CIPHERSUITE_INFO cipherSuiteRSA[] = {
247 	/* AES with RSA */
248 	{ TLS_RSA_WITH_AES_128_CBC_SHA256,
249 	  DESCRIPTION( "TLS_RSA_WITH_AES_128_CBC_SHA256" )
250 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
251 	  CRYPT_ALGO_HMAC_SHA2, 0, 16, SHA2MAC_SIZE,
252 	  CIPHERSUITE_FLAG_TLS12 },
253 	{ TLS_RSA_WITH_AES_256_CBC_SHA256,
254 	  DESCRIPTION( "TLS_RSA_WITH_AES_256_CBC_SHA256" )
255 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
256 	  CRYPT_ALGO_HMAC_SHA2, 0, 32, SHA2MAC_SIZE,
257 	  CIPHERSUITE_FLAG_TLS12 },
258 	{ TLS_RSA_WITH_AES_128_CBC_SHA,
259 	  DESCRIPTION( "TLS_RSA_WITH_AES_128_CBC_SHA" )
260 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
261 	  CRYPT_ALGO_HMAC_SHA1, 0, 16, SHA1MAC_SIZE,
262 	  CIPHERSUITE_FLAG_NONE },
263 	{ TLS_RSA_WITH_AES_256_CBC_SHA,
264 	  DESCRIPTION( "TLS_RSA_WITH_AES_256_CBC_SHA" )
265 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_AES,
266 	  CRYPT_ALGO_HMAC_SHA1, 0, 32, SHA1MAC_SIZE,
267 	  CIPHERSUITE_FLAG_NONE },
268 
269 	/* 3DES with RSA */
270 	{ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
271 	  DESCRIPTION( "SSL_RSA_WITH_3DES_EDE_CBC_SHA" )
272 	  CRYPT_ALGO_RSA, CRYPT_ALGO_RSA, CRYPT_ALGO_3DES,
273 	  CRYPT_ALGO_HMAC_SHA1, 0, 24, SHA1MAC_SIZE,
274 	  CIPHERSUITE_FLAG_NONE },
275 
276 	/* End-of-list marker */
277 	{ SSL_NULL_WITH_NULL,
278 	  DESCRIPTION( "End-of-list marker" )
279 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
280 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE },
281 	{ SSL_NULL_WITH_NULL,
282 	  DESCRIPTION( "End-of-list marker" )
283 	  CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
284 	  CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE }
285 	};
286 
287 /* Tables defining the arrangement of the above sets of suites into a
288    single monster list.  The order of adding suites is as follows:
289 
290 	[ Optional special-case suites, for testing or custom configurations ].
291 	PSK suites, since they provide proper mutual authentication.
292 	ECC suites if PREFER_ECC is defined, since anyone wanting to make this
293 			particular fashion statement probably wants to actually use the
294 			suites rather than having them ignored as the 25th-ranked
295 			option.  (GCM with ECC is a variant of this, this is even more
296 			of a fashion statement and really only makes sense with ECC).
297 	DH suites.
298 	RSA suites with strong ciphers.
299 	Misc RSA suites with also-ran ciphers */
300 
301 typedef struct {
302 	const CIPHERSUITE_INFO *cipherSuites;
303 	const int cipherSuiteCount;
304 	} CIPHERSUITES_LIST;
305 
306 static const CIPHERSUITES_LIST cipherSuitesList[] = {
307 	{ cipherSuitePSK, FAILSAFE_ARRAYSIZE( cipherSuitePSK, CIPHERSUITE_INFO ) },
308 #ifdef PREFER_ECC
309   #ifdef USE_GCM
310 	{ cipherSuiteGCM, FAILSAFE_ARRAYSIZE( cipherSuiteGCM, CIPHERSUITE_INFO ) },
311   #endif /* USE_GCM */
312   #if defined( USE_ECDSA ) && defined( USE_ECDH )
313 	{ cipherSuiteECC, FAILSAFE_ARRAYSIZE( cipherSuiteECC, CIPHERSUITE_INFO ) },
314   #endif /* USE_ECDSA && USE_ECDH */
315 #endif /* PREFER_ECC */
316 	{ cipherSuiteDH, FAILSAFE_ARRAYSIZE( cipherSuiteDH, CIPHERSUITE_INFO ) },
317 	{ cipherSuiteRSA, FAILSAFE_ARRAYSIZE( cipherSuiteRSA, CIPHERSUITE_INFO ) },
318 #ifndef PREFER_ECC
319   #ifdef USE_GCM
320 	{ cipherSuiteGCM, FAILSAFE_ARRAYSIZE( cipherSuiteGCM, CIPHERSUITE_INFO ) },
321   #endif /* USE_GCM */
322   #if defined( USE_ECDSA ) && defined( USE_ECDH )
323 	{ cipherSuiteECC, FAILSAFE_ARRAYSIZE( cipherSuiteECC, CIPHERSUITE_INFO ) },
324   #endif /* USE_ECDSA && USE_ECDH */
325 #endif /* !PREFER_ECC */
326 	{ NULL, 0 }, { NULL, 0 }
327 	};
328 
329 /****************************************************************************
330 *																			*
331 *						Cipher Suite Definitions for Suite B				*
332 *																			*
333 ****************************************************************************/
334 
335 /* If we're running in a Suite B configuration then we don't bother with any
336    of the standard cipher suites but only provide Suite B suites */
337 
338 #if defined( CONFIG_SUITEB )
339 
340 #if defined( _MSC_VER ) || defined( __GNUC__ )
341   #pragma message( "  Building with custom suite: Suite B" )
342   #if defined( CONFIG_SUITEB_TESTS )
343 	#pragma message( "  Building with custom suite: Suite B test suites" )
344   #endif /* Suite B special test suites */
345 #endif /* VC++ */
346 
347 /* 256-bit Suite B suites */
348 
349 static const CIPHERSUITE_INFO suiteBP384GCM = {
350 	TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
351 	DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" )
352 	CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
353 	CRYPT_ALGO_HMAC_SHA2, bitsToBytes( 384 ), 32, GCMICV_SIZE,
354 	CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12
355 	};
356 
357 /* 128-bit Suite B suites */
358 
359 static const CIPHERSUITE_INFO suiteBP256GCM = {
360 	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
361 	DESCRIPTION( "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" )
362 	CRYPT_ALGO_ECDH, CRYPT_ALGO_ECDSA, CRYPT_ALGO_AES,
363 	CRYPT_ALGO_HMAC_SHA2, 0, 16, GCMICV_SIZE,
364 	CIPHERSUITE_FLAG_ECC | CIPHERSUITE_FLAG_GCM | CIPHERSUITE_FLAG_TLS12
365 	};
366 
367 /* End-of-list marker */
368 
369 static const CIPHERSUITE_INFO suiteBEOL = {
370 	SSL_NULL_WITH_NULL,
371 	DESCRIPTION( "End-of-list marker" )
372 	CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
373 	CRYPT_ALGO_NONE, 0, 0, 0, CIPHERSUITE_FLAG_NONE
374 	};
375 
376 /* Since the only suites that we're enabling are the Suite B ones, we
377    override the default getCipherSuiteInfo() with our own one */
378 
379 CHECK_RETVAL \
getSuiteBCipherSuiteInfo(OUT const CIPHERSUITE_INFO *** cipherSuiteInfoPtrPtrPtr,OUT_INT_Z int * noSuiteEntries,const BOOLEAN isServer,IN_FLAGS_Z (SSL)const int suiteBinfo)380 int getSuiteBCipherSuiteInfo( OUT const CIPHERSUITE_INFO ***cipherSuiteInfoPtrPtrPtr,
381 							  OUT_INT_Z int *noSuiteEntries,
382 							  const BOOLEAN isServer,
383 							  IN_FLAGS_Z( SSL ) const int suiteBinfo )
384 	{
385 	static const CIPHERSUITE_INFO *cipherSuite192InfoTbl[] = \
386 		{ &suiteBP384GCM, &suiteBEOL, &suiteBEOL };
387 	static const CIPHERSUITE_INFO *cipherSuite128InfoTbl[] = \
388 		{ &suiteBP256GCM, &suiteBP384GCM, &suiteBEOL, &suiteBEOL };
389 	BOOLEAN is128bitLevel = ( ( suiteBinfo & SSL_PFLAG_SUITEB ) == \
390 									SSL_PFLAG_SUITEB_128 ) ? TRUE : FALSE;
391 
392 	assert( isReadPtr( cipherSuiteInfoPtrPtrPtr, \
393 					   sizeof( CIPHERSUITE_INFO ** ) ) );
394 	assert( isWritePtr( noSuiteEntries, sizeof( int ) ) );
395 
396 	REQUIRES( suiteBinfo >= SSL_PFLAG_NONE && suiteBinfo < SSL_PFLAG_MAX );
397 
398 	/* Depending on the security level that we're configured for we either
399 	   prefer the 128-bit suites or the 192-bit suites */
400 	if( is128bitLevel )
401 		{
402 		*cipherSuiteInfoPtrPtrPtr = ( const CIPHERSUITE_INFO ** ) \
403 									cipherSuite128InfoTbl;	/* For gcc */
404 		*noSuiteEntries = FAILSAFE_ARRAYSIZE( cipherSuite128InfoTbl, \
405 											  CIPHERSUITE_INFO * );
406 		}
407 	else
408 		{
409 		*cipherSuiteInfoPtrPtrPtr = ( const CIPHERSUITE_INFO ** ) \
410 									cipherSuite192InfoTbl;	/* For gcc */
411 		*noSuiteEntries = FAILSAFE_ARRAYSIZE( cipherSuite192InfoTbl, \
412 											  CIPHERSUITE_INFO * );
413 		}
414 	return( CRYPT_OK );
415 	}
416 
417 /* Remap the usual getCipherSuiteInfo() into an alternative name that
418    doesn't clash with the Suite B replacement */
419 
420 #undef getCipherSuiteInfo
421 #define	getCipherSuiteInfo	getCipherSuiteInfoOriginal
422 
423 #endif /* CONFIG_SUITEB */
424 
425 /****************************************************************************
426 *																			*
427 *							Cipher Suite Functions							*
428 *																			*
429 ****************************************************************************/
430 
431 /* Build the single unified list of ciphers suites in preferred-algorithm
432    order */
433 
434 CHECK_RETVAL \
435 static int addCipherSuiteInfo( INOUT CIPHERSUITE_INFO **cipherSuiteTbl,
436 							   IN_RANGE( 0, MAX_CIPHERSUITE_TBLSIZE ) \
437 									const int cipherSuiteTblCount,
438 							   OUT_RANGE( 0, MAX_CIPHERSUITE_TBLSIZE ) \
439 									int *newCipherSuiteTblCount,
440 							   const CIPHERSUITE_INFO *cipherSuites,
441 							   IN_RANGE( 0, MAX_CIPHERSUITE_TBLSIZE / 2 ) \
442 									const int cipherSuitesCount )
443 	{
444 	int srcIndex, destIndex;
445 
446 	assert( isReadPtr( cipherSuiteTbl, \
447 					   sizeof( CIPHERSUITE_INFO * ) * MAX_CIPHERSUITE_TBLSIZE ) );
448 	assert( isWritePtr( newCipherSuiteTblCount, sizeof( int ) ) );
449 	assert( isReadPtr( cipherSuites,
450 					   sizeof( CIPHERSUITE_INFO * ) * 2 ) );
451 
452 	REQUIRES( cipherSuiteTblCount >= 0 && \
453 			  cipherSuiteTblCount < MAX_CIPHERSUITE_TBLSIZE );
454 	REQUIRES( cipherSuitesCount >= 0 && \
455 			  cipherSuitesCount < MAX_CIPHERSUITE_TBLSIZE / 2 );
456 
457 	/* Clear return value.  Unlike standard practice this doesn't set it to
458 	   zero but to the existing count, making the call a no-op */
459 	*newCipherSuiteTblCount = cipherSuiteTblCount;
460 
461 	/* Add any new suites to the existing table */
462 	for( srcIndex = 0, destIndex = cipherSuiteTblCount;
463 		 cipherSuites[ srcIndex ].cipherSuite != SSL_NULL_WITH_NULL && \
464 			srcIndex < cipherSuitesCount && destIndex < MAX_CIPHERSUITE_TBLSIZE;
465 		 srcIndex++, destIndex++ )
466 		{
467 		cipherSuiteTbl[ destIndex ] = ( CIPHERSUITE_INFO * ) \
468 									  &cipherSuites[ srcIndex ];
469 		}
470 	ENSURES( srcIndex < cipherSuitesCount );
471 	ENSURES( destIndex < MAX_CIPHERSUITE_TBLSIZE );
472 
473 	*newCipherSuiteTblCount = destIndex;
474 
475 	return( CRYPT_OK );
476 	}
477 
478 CHECK_RETVAL \
getCipherSuiteInfo(OUT const CIPHERSUITE_INFO *** cipherSuiteInfoPtrPtrPtr,OUT_INT_Z int * noSuiteEntries)479 int getCipherSuiteInfo( OUT const CIPHERSUITE_INFO ***cipherSuiteInfoPtrPtrPtr,
480 						OUT_INT_Z int *noSuiteEntries )
481 	{
482 	static CIPHERSUITE_INFO *cipherSuiteInfoTbl[ MAX_CIPHERSUITE_TBLSIZE + 8 ];
483 	static BOOLEAN cipherSuitInfoInited = FALSE;
484 	static int cipherSuiteCount = 0;
485 	int status;
486 
487 	assert( isReadPtr( cipherSuiteInfoPtrPtrPtr, \
488 					   sizeof( CIPHERSUITE_INFO ** ) ) );
489 	assert( isWritePtr( noSuiteEntries, sizeof( int ) ) );
490 
491 	/* Dynamically set up the monster table of cipher suites.  Note that
492 	   this isn't thread-safe, but since it performs the setup in a
493 	   completely deterministic manner it doesn't matter if the extremely
494 	   unlikely situation of two threads initialising the array at the same
495 	   time occurs, since they're initialising it identically */
496 	if( !cipherSuitInfoInited )
497 		{
498 		static const CIPHERSUITE_INFO endOfList = {
499 			SSL_NULL_WITH_NULL,
500 			DESCRIPTION( "End-of-list marker" )
501 			CRYPT_ALGO_NONE, CRYPT_ALGO_NONE, CRYPT_ALGO_NONE,
502 			CRYPT_ALGO_NONE, 0, 0, CIPHERSUITE_FLAG_NONE };
503 		int i;
504 
505 		/* Build the unified list of cipher suites */
506 		for( i = 0;
507 			 cipherSuitesList[ i ].cipherSuites != NULL && \
508 				i < FAILSAFE_ARRAYSIZE( cipherSuitesList, CIPHERSUITES_LIST );
509 			 i++ )
510 			{
511 			status = addCipherSuiteInfo( cipherSuiteInfoTbl, cipherSuiteCount,
512 						&cipherSuiteCount, cipherSuitesList[ i ].cipherSuites,
513 						cipherSuitesList[ i ].cipherSuiteCount );
514 			if( cryptStatusError( status ) )
515 				return( status );
516 			}
517 		ENSURES( i < FAILSAFE_ARRAYSIZE( cipherSuitesList, CIPHERSUITES_LIST ) );
518 
519 		/* Add the end-of-list marker suites.  Note that we don't increment
520 		   the suite count when the second one is added to match the
521 		   behaviour of FAILSAFE_ARRAYSIZE() */
522 		REQUIRES( cipherSuiteCount + 2 < MAX_CIPHERSUITE_TBLSIZE );
523 		cipherSuiteInfoTbl[ cipherSuiteCount++ ] = \
524 								( CIPHERSUITE_INFO * ) &endOfList;
525 		cipherSuiteInfoTbl[ cipherSuiteCount ] = \
526 								( CIPHERSUITE_INFO * ) &endOfList;
527 
528 		cipherSuitInfoInited = TRUE;
529 		}
530 
531 	*cipherSuiteInfoPtrPtrPtr = ( const CIPHERSUITE_INFO ** ) \
532 								cipherSuiteInfoTbl;	/* For gcc */
533 	*noSuiteEntries = cipherSuiteCount;
534 
535 	return( CRYPT_OK );
536 	}
537 #endif /* USE_SSL */
538