blob: 4894239f1a1ec19b77036dfa171507f68574d1f9 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110/* ====================================================================
111 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112 * ECC cipher suite support in OpenSSL originally developed by
113 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
114 */
115/* ====================================================================
116 * Copyright 2005 Nokia. All rights reserved.
117 *
118 * The portions of the attached software ("Contribution") is developed by
119 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
120 * license.
121 *
122 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
123 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
124 * support (see RFC 4279) to OpenSSL.
125 *
126 * No patent licenses or other rights except those expressly stated in
127 * the OpenSSL open source license shall be deemed granted or received
128 * expressly, by implication, estoppel, or otherwise.
129 *
130 * No assurances are provided by Nokia that the Contribution does not
131 * infringe the patent or other intellectual property rights of any third
132 * party or that the license provides you with all the necessary rights
133 * to make use of the Contribution.
134 *
135 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
136 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
137 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
138 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
139 * OTHERWISE. */
140
Adam Langley95c29f32014-06-20 12:00:00 -0700141#include <assert.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400142#include <stdio.h>
143#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700144
David Benjamin71f07942015-04-08 02:36:59 -0400145#include <openssl/buf.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400146#include <openssl/err.h>
David Benjaminea72bd02014-12-21 21:27:41 -0500147#include <openssl/md5.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700148#include <openssl/mem.h>
David Benjaminea72bd02014-12-21 21:27:41 -0500149#include <openssl/sha.h>
David Benjamin71f07942015-04-08 02:36:59 -0400150#include <openssl/stack.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700151
David Benjamin2ee94aa2015-04-07 22:38:30 -0400152#include "internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -0700153
Adam Langley95c29f32014-06-20 12:00:00 -0700154
David Benjamina1c90a52015-05-30 17:03:14 -0400155/* kCiphers is an array of all supported ciphers, sorted by id. */
156const SSL_CIPHER kCiphers[] = {
157 /* The RSA ciphers */
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700158 /* Cipher 02 */
159 {
160 SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA, SSL_aRSA,
161 SSL_eNULL, SSL_SHA1, SSL_SSLV3, SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT, 0, 0,
162 },
163
David Benjamina1c90a52015-05-30 17:03:14 -0400164 /* Cipher 04 */
165 {
166 SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
167 SSL_RC4, SSL_MD5, SSL_SSLV3, SSL_MEDIUM,
168 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
169 },
170
171 /* Cipher 05 */
172 {
173 SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA,
174 SSL_RC4, SSL_SHA1, SSL_SSLV3, SSL_MEDIUM,
175 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
176 },
177
178 /* Cipher 0A */
179 {
180 SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA,
181 SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, SSL_HIGH | SSL_FIPS,
182 SSL_HANDSHAKE_MAC_DEFAULT, 112, 168,
183 },
184
185
186 /* New AES ciphersuites */
187
188 /* Cipher 2F */
189 {
190 TLS1_TXT_RSA_WITH_AES_128_SHA, TLS1_CK_RSA_WITH_AES_128_SHA, SSL_kRSA,
191 SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
192 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
193 },
194
195 /* Cipher 33 */
196 {
197 TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
198 SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
199 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
200 },
201
202 /* Cipher 35 */
203 {
204 TLS1_TXT_RSA_WITH_AES_256_SHA, TLS1_CK_RSA_WITH_AES_256_SHA, SSL_kRSA,
205 SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
206 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
207 },
208
209 /* Cipher 39 */
210 {
211 TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
212 SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
213 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
214 },
215
216
217 /* TLS v1.2 ciphersuites */
218
219 /* Cipher 3C */
220 {
221 TLS1_TXT_RSA_WITH_AES_128_SHA256, TLS1_CK_RSA_WITH_AES_128_SHA256,
222 SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256, SSL_TLSV1_2,
223 SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 128, 128,
224 },
225
226 /* Cipher 3D */
227 {
228 TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256,
229 SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256, SSL_TLSV1_2,
230 SSL_HIGH | SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256, 256, 256,
231 },
232
233 /* Cipher 67 */
234 {
235 TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
236 TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128,
237 SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
238 SSL_HANDSHAKE_MAC_SHA256, 128, 128,
239 },
240
241 /* Cipher 6B */
242 {
243 TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
244 TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES256,
245 SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
246 SSL_HANDSHAKE_MAC_SHA256, 256, 256,
247 },
248
Adam Langley85bc5602015-06-09 09:54:04 -0700249 /* PSK cipher suites. */
250
David Benjamina1c90a52015-05-30 17:03:14 -0400251 /* Cipher 8A */
252 {
253 TLS1_TXT_PSK_WITH_RC4_128_SHA, TLS1_CK_PSK_WITH_RC4_128_SHA, SSL_kPSK,
254 SSL_aPSK, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
255 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
256 },
257
258 /* Cipher 8C */
259 {
260 TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
261 SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
262 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
263 },
264
265 /* Cipher 8D */
266 {
267 TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
268 SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
269 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
270 },
271
David Benjamina1c90a52015-05-30 17:03:14 -0400272 /* GCM ciphersuites from RFC5288 */
273
274 /* Cipher 9C */
275 {
276 TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
277 TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM,
278 SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400279 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400280 128, 128,
281 },
282
283 /* Cipher 9D */
284 {
285 TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
286 TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM,
287 SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400288 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400289 256, 256,
290 },
291
292 /* Cipher 9E */
293 {
294 TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
295 TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM,
296 SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400297 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400298 128, 128,
299 },
300
301 /* Cipher 9F */
302 {
303 TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
304 TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM,
305 SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400306 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400307 256, 256,
308 },
309
310 /* Cipher C007 */
311 {
312 TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
313 TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_kECDHE, SSL_aECDSA, SSL_RC4,
314 SSL_SHA1, SSL_TLSV1, SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT, 128,
315 128,
316 },
317
318 /* Cipher C009 */
319 {
320 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
321 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
322 SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
323 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
324 },
325
326 /* Cipher C00A */
327 {
328 TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
329 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aECDSA,
330 SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
331 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
332 },
333
334 /* Cipher C011 */
335 {
336 TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
337 SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1, SSL_TLSV1, SSL_MEDIUM,
338 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
339 },
340
341 /* Cipher C013 */
342 {
343 TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
344 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES128,
345 SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
346 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
347 },
348
349 /* Cipher C014 */
350 {
351 TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
352 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_kECDHE, SSL_aRSA, SSL_AES256,
353 SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
354 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
355 },
356
357
358 /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
359
360 /* Cipher C023 */
361 {
362 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
363 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aECDSA,
364 SSL_AES128, SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
365 SSL_HANDSHAKE_MAC_SHA256, 128, 128,
366 },
367
368 /* Cipher C024 */
369 {
370 TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
371 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aECDSA,
372 SSL_AES256, SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
373 SSL_HANDSHAKE_MAC_SHA384, 256, 256,
374 },
375
376 /* Cipher C027 */
377 {
378 TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
379 TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, SSL_kECDHE, SSL_aRSA, SSL_AES128,
380 SSL_SHA256, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
381 SSL_HANDSHAKE_MAC_SHA256, 128, 128,
382 },
383
384 /* Cipher C028 */
385 {
386 TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
387 TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, SSL_kECDHE, SSL_aRSA, SSL_AES256,
388 SSL_SHA384, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
389 SSL_HANDSHAKE_MAC_SHA384, 256, 256,
390 },
391
392
393 /* GCM based TLS v1.2 ciphersuites from RFC5289 */
394
395 /* Cipher C02B */
396 {
397 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
398 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA,
399 SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400400 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400401 128, 128,
402 },
403
404 /* Cipher C02C */
405 {
406 TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
407 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA,
408 SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400409 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400410 256, 256,
411 },
412
413 /* Cipher C02F */
414 {
415 TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
416 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA,
417 SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400418 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400419 128, 128,
420 },
421
422 /* Cipher C030 */
423 {
424 TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
425 TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA,
426 SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
David Benjaminb2a985b2015-06-21 15:13:57 -0400427 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400428 256, 256,
429 },
430
Adam Langley85bc5602015-06-09 09:54:04 -0700431 /* ECDHE-PSK cipher suites. */
432
433 /* Cipher C035 */
434 {
435 TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA,
436 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
437 SSL_kECDHE, SSL_aPSK, SSL_AES128, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
438 SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
439 },
440
441 /* Cipher C036 */
442 {
443 TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA,
444 TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA,
445 SSL_kECDHE, SSL_aPSK, SSL_AES256, SSL_SHA1, SSL_TLSV1, SSL_HIGH | SSL_FIPS,
446 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
447 },
448
449 /* ChaCha20-Poly1305 cipher suites. */
450
David Benjamina1c90a52015-05-30 17:03:14 -0400451 {
452 TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
453 TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
454 SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
455 SSL_HANDSHAKE_MAC_SHA256,
David Benjaminbe8a8692015-08-21 13:51:56 -0400456 256, 256,
David Benjamina1c90a52015-05-30 17:03:14 -0400457 },
458
459 {
460 TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
461 TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
462 SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
463 SSL_HANDSHAKE_MAC_SHA256,
David Benjaminbe8a8692015-08-21 13:51:56 -0400464 256, 256,
David Benjamina1c90a52015-05-30 17:03:14 -0400465 },
David Benjamina1c90a52015-05-30 17:03:14 -0400466};
467
468static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
469
Adam Langleyfcf25832014-12-18 17:42:32 -0800470#define CIPHER_ADD 1
471#define CIPHER_KILL 2
472#define CIPHER_DEL 3
473#define CIPHER_ORD 4
474#define CIPHER_SPECIAL 5
Adam Langley95c29f32014-06-20 12:00:00 -0700475
Adam Langleyfcf25832014-12-18 17:42:32 -0800476typedef struct cipher_order_st {
477 const SSL_CIPHER *cipher;
478 int active;
Adam Langleyfcf25832014-12-18 17:42:32 -0800479 int in_group;
480 struct cipher_order_st *next, *prev;
481} CIPHER_ORDER;
Adam Langley95c29f32014-06-20 12:00:00 -0700482
David Benjamin0344daf2015-04-08 02:08:01 -0400483typedef struct cipher_alias_st {
484 /* name is the name of the cipher alias. */
485 const char *name;
486
487 /* The following fields are bitmasks for the corresponding fields on
488 * |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the
489 * bit corresponding to the cipher's value is set to 1. If any bitmask is
490 * all zeroes, the alias matches nothing. Use |~0u| for the default value. */
491 uint32_t algorithm_mkey;
492 uint32_t algorithm_auth;
493 uint32_t algorithm_enc;
494 uint32_t algorithm_mac;
495 uint32_t algorithm_ssl;
496 uint32_t algo_strength;
497} CIPHER_ALIAS;
498
David Benjamina1c90a52015-05-30 17:03:14 -0400499static const CIPHER_ALIAS kCipherAliases[] = {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700500 /* "ALL" doesn't include eNULL (must be specifically enabled) */
501 {SSL_TXT_ALL, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700502
David Benjamina1c90a52015-05-30 17:03:14 -0400503 /* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
Adam Langley95c29f32014-06-20 12:00:00 -0700504
David Benjamina1c90a52015-05-30 17:03:14 -0400505 /* key exchange aliases
506 * (some of those using only a single bit here combine
507 * multiple key exchange algs according to the RFCs,
508 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
509 {SSL_TXT_kRSA, SSL_kRSA, ~0u, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700510
David Benjamina1c90a52015-05-30 17:03:14 -0400511 {SSL_TXT_kDHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
512 {SSL_TXT_kEDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
513 {SSL_TXT_DH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700514
David Benjamina1c90a52015-05-30 17:03:14 -0400515 {SSL_TXT_kECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
516 {SSL_TXT_kEECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
517 {SSL_TXT_ECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700518
David Benjamina1c90a52015-05-30 17:03:14 -0400519 {SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700520
David Benjamina1c90a52015-05-30 17:03:14 -0400521 /* server authentication aliases */
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700522 {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
David Benjamina1c90a52015-05-30 17:03:14 -0400523 {SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
524 {SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
525 {SSL_TXT_aPSK, ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700526
David Benjamina1c90a52015-05-30 17:03:14 -0400527 /* aliases combining key exchange and server authentication */
528 {SSL_TXT_DHE, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
529 {SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
530 {SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
531 {SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700532 {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
David Benjamina1c90a52015-05-30 17:03:14 -0400533 {SSL_TXT_PSK, SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700534
David Benjamina1c90a52015-05-30 17:03:14 -0400535 /* symmetric encryption aliases */
536 {SSL_TXT_3DES, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u},
537 {SSL_TXT_RC4, ~0u, ~0u, SSL_RC4, ~0u, ~0u, ~0u},
538 {SSL_TXT_AES128, ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, ~0u, ~0u},
539 {SSL_TXT_AES256, ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, ~0u, ~0u},
540 {SSL_TXT_AES, ~0u, ~0u, SSL_AES, ~0u, ~0u, ~0u},
541 {SSL_TXT_AES_GCM, ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, ~0u, ~0u},
542 {SSL_TXT_CHACHA20, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700543
David Benjamina1c90a52015-05-30 17:03:14 -0400544 /* MAC aliases */
545 {SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700546 {SSL_TXT_SHA1, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
547 {SSL_TXT_SHA, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
David Benjamina1c90a52015-05-30 17:03:14 -0400548 {SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
549 {SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700550
David Benjamina1c90a52015-05-30 17:03:14 -0400551 /* protocol version aliases */
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700552 {SSL_TXT_SSLV3, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u},
553 {SSL_TXT_TLSV1, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u},
554 {SSL_TXT_TLSV1_2, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u},
Adam Langley95c29f32014-06-20 12:00:00 -0700555
David Benjamina1c90a52015-05-30 17:03:14 -0400556 /* strength classes */
557 {SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
558 {SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
559 /* FIPS 140-2 approved ciphersuite */
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700560 {SSL_TXT_FIPS, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS},
Adam Langleyfcf25832014-12-18 17:42:32 -0800561};
Adam Langley95c29f32014-06-20 12:00:00 -0700562
David Benjamina1c90a52015-05-30 17:03:14 -0400563static const size_t kCipherAliasesLen =
564 sizeof(kCipherAliases) / sizeof(kCipherAliases[0]);
565
566static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
567 const SSL_CIPHER *a = in_a;
568 const SSL_CIPHER *b = in_b;
569
570 if (a->id > b->id) {
571 return 1;
572 } else if (a->id < b->id) {
573 return -1;
574 } else {
575 return 0;
576 }
577}
578
579static int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **a, const SSL_CIPHER **b) {
580 return ssl_cipher_id_cmp(*a, *b);
581}
582
583const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
584 SSL_CIPHER c;
585
586 c.id = 0x03000000L | value;
587 return bsearch(&c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER),
588 ssl_cipher_id_cmp);
589}
David Benjamin0344daf2015-04-08 02:08:01 -0400590
David Benjaminea72bd02014-12-21 21:27:41 -0500591int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
592 size_t *out_mac_secret_len,
593 size_t *out_fixed_iv_len,
594 const SSL_CIPHER *cipher, uint16_t version) {
595 *out_aead = NULL;
596 *out_mac_secret_len = 0;
597 *out_fixed_iv_len = 0;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700598
David Benjaminea72bd02014-12-21 21:27:41 -0500599 switch (cipher->algorithm_enc) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800600 case SSL_AES128GCM:
David Benjaminea72bd02014-12-21 21:27:41 -0500601 *out_aead = EVP_aead_aes_128_gcm();
602 *out_fixed_iv_len = 4;
Adam Langleyfcf25832014-12-18 17:42:32 -0800603 return 1;
604
605 case SSL_AES256GCM:
David Benjaminea72bd02014-12-21 21:27:41 -0500606 *out_aead = EVP_aead_aes_256_gcm();
607 *out_fixed_iv_len = 4;
Adam Langleyfcf25832014-12-18 17:42:32 -0800608 return 1;
609
610 case SSL_CHACHA20POLY1305:
David Benjaminea72bd02014-12-21 21:27:41 -0500611 *out_aead = EVP_aead_chacha20_poly1305();
612 *out_fixed_iv_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800613 return 1;
614
615 case SSL_RC4:
David Benjaminea72bd02014-12-21 21:27:41 -0500616 switch (cipher->algorithm_mac) {
617 case SSL_MD5:
David Benjamin044abb02014-12-23 10:57:17 -0500618 if (version == SSL3_VERSION) {
619 *out_aead = EVP_aead_rc4_md5_ssl3();
620 } else {
621 *out_aead = EVP_aead_rc4_md5_tls();
622 }
David Benjaminea72bd02014-12-21 21:27:41 -0500623 *out_mac_secret_len = MD5_DIGEST_LENGTH;
624 return 1;
625 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500626 if (version == SSL3_VERSION) {
627 *out_aead = EVP_aead_rc4_sha1_ssl3();
628 } else {
629 *out_aead = EVP_aead_rc4_sha1_tls();
630 }
David Benjaminea72bd02014-12-21 21:27:41 -0500631 *out_mac_secret_len = SHA_DIGEST_LENGTH;
632 return 1;
633 default:
634 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800635 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800636
David Benjaminea72bd02014-12-21 21:27:41 -0500637 case SSL_AES128:
638 switch (cipher->algorithm_mac) {
639 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500640 if (version == SSL3_VERSION) {
641 *out_aead = EVP_aead_aes_128_cbc_sha1_ssl3();
642 *out_fixed_iv_len = 16;
643 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500644 *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv();
645 *out_fixed_iv_len = 16;
646 } else {
647 *out_aead = EVP_aead_aes_128_cbc_sha1_tls();
648 }
649 *out_mac_secret_len = SHA_DIGEST_LENGTH;
650 return 1;
651 case SSL_SHA256:
652 *out_aead = EVP_aead_aes_128_cbc_sha256_tls();
653 *out_mac_secret_len = SHA256_DIGEST_LENGTH;
654 return 1;
655 default:
656 return 0;
657 }
658
659 case SSL_AES256:
660 switch (cipher->algorithm_mac) {
661 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500662 if (version == SSL3_VERSION) {
663 *out_aead = EVP_aead_aes_256_cbc_sha1_ssl3();
664 *out_fixed_iv_len = 16;
665 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500666 *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv();
667 *out_fixed_iv_len = 16;
668 } else {
669 *out_aead = EVP_aead_aes_256_cbc_sha1_tls();
670 }
671 *out_mac_secret_len = SHA_DIGEST_LENGTH;
672 return 1;
673 case SSL_SHA256:
674 *out_aead = EVP_aead_aes_256_cbc_sha256_tls();
675 *out_mac_secret_len = SHA256_DIGEST_LENGTH;
676 return 1;
677 case SSL_SHA384:
678 *out_aead = EVP_aead_aes_256_cbc_sha384_tls();
679 *out_mac_secret_len = SHA384_DIGEST_LENGTH;
680 return 1;
681 default:
682 return 0;
683 }
684
685 case SSL_3DES:
686 switch (cipher->algorithm_mac) {
687 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500688 if (version == SSL3_VERSION) {
689 *out_aead = EVP_aead_des_ede3_cbc_sha1_ssl3();
690 *out_fixed_iv_len = 8;
691 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500692 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv();
693 *out_fixed_iv_len = 8;
694 } else {
695 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls();
696 }
697 *out_mac_secret_len = SHA_DIGEST_LENGTH;
698 return 1;
699 default:
700 return 0;
701 }
702
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700703 case SSL_eNULL:
704 switch (cipher->algorithm_mac) {
705 case SSL_SHA1:
706 if (version == SSL3_VERSION) {
707 *out_aead = EVP_aead_null_sha1_ssl3();
708 } else {
709 *out_aead = EVP_aead_null_sha1_tls();
710 }
711 *out_mac_secret_len = SHA_DIGEST_LENGTH;
712 return 1;
713 default:
714 return 0;
715 }
716
David Benjaminea72bd02014-12-21 21:27:41 -0500717 default:
718 return 0;
719 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800720}
Adam Langleyc9fb3752014-06-20 12:00:00 -0700721
David Benjaminb0883312015-08-06 09:54:13 -0400722const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf) {
723 switch (algorithm_prf) {
724 case SSL_HANDSHAKE_MAC_DEFAULT:
725 return EVP_sha1();
726 case SSL_HANDSHAKE_MAC_SHA256:
727 return EVP_sha256();
728 case SSL_HANDSHAKE_MAC_SHA384:
729 return EVP_sha384();
730 default:
731 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800732 }
Adam Langley95c29f32014-06-20 12:00:00 -0700733}
734
735#define ITEM_SEP(a) \
Adam Langleyfcf25832014-12-18 17:42:32 -0800736 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
Adam Langley95c29f32014-06-20 12:00:00 -0700737
David Benjamin0344daf2015-04-08 02:08:01 -0400738/* rule_equals returns one iff the NUL-terminated string |rule| is equal to the
739 * |buf_len| bytes at |buf|. */
740static int rule_equals(const char *rule, const char *buf, size_t buf_len) {
741 /* |strncmp| alone only checks that |buf| is a prefix of |rule|. */
742 return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0';
743}
744
Adam Langley95c29f32014-06-20 12:00:00 -0700745static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800746 CIPHER_ORDER **tail) {
747 if (curr == *tail) {
748 return;
749 }
750 if (curr == *head) {
751 *head = curr->next;
752 }
753 if (curr->prev != NULL) {
754 curr->prev->next = curr->next;
755 }
756 if (curr->next != NULL) {
757 curr->next->prev = curr->prev;
758 }
759 (*tail)->next = curr;
760 curr->prev = *tail;
761 curr->next = NULL;
762 *tail = curr;
763}
Adam Langley95c29f32014-06-20 12:00:00 -0700764
765static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800766 CIPHER_ORDER **tail) {
767 if (curr == *head) {
768 return;
769 }
770 if (curr == *tail) {
771 *tail = curr->prev;
772 }
773 if (curr->next != NULL) {
774 curr->next->prev = curr->prev;
775 }
776 if (curr->prev != NULL) {
777 curr->prev->next = curr->next;
778 }
779 (*head)->prev = curr;
780 curr->next = *head;
781 curr->prev = NULL;
782 *head = curr;
783}
Adam Langley95c29f32014-06-20 12:00:00 -0700784
David Benjamin82c9e902014-12-12 15:55:27 -0500785static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method,
Adam Langleyfcf25832014-12-18 17:42:32 -0800786 CIPHER_ORDER *co_list,
787 CIPHER_ORDER **head_p,
788 CIPHER_ORDER **tail_p) {
David Benjamina1c90a52015-05-30 17:03:14 -0400789 /* The set of ciphers is static, but some subset may be unsupported by
790 * |ssl_method|, so the list may be smaller. */
791 size_t co_list_num = 0;
792 size_t i;
793 for (i = 0; i < kCiphersLen; i++) {
794 const SSL_CIPHER *cipher = &kCiphers[i];
795 if (ssl_method->supports_cipher(cipher)) {
796 co_list[co_list_num].cipher = cipher;
Adam Langleyfcf25832014-12-18 17:42:32 -0800797 co_list[co_list_num].next = NULL;
798 co_list[co_list_num].prev = NULL;
799 co_list[co_list_num].active = 0;
800 co_list[co_list_num].in_group = 0;
801 co_list_num++;
802 }
803 }
Adam Langley95c29f32014-06-20 12:00:00 -0700804
Adam Langleyfcf25832014-12-18 17:42:32 -0800805 /* Prepare linked list from list entries. */
806 if (co_list_num > 0) {
807 co_list[0].prev = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700808
Adam Langleyfcf25832014-12-18 17:42:32 -0800809 if (co_list_num > 1) {
810 co_list[0].next = &co_list[1];
Adam Langley95c29f32014-06-20 12:00:00 -0700811
Adam Langleyfcf25832014-12-18 17:42:32 -0800812 for (i = 1; i < co_list_num - 1; i++) {
813 co_list[i].prev = &co_list[i - 1];
814 co_list[i].next = &co_list[i + 1];
815 }
Adam Langley95c29f32014-06-20 12:00:00 -0700816
Adam Langleyfcf25832014-12-18 17:42:32 -0800817 co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
818 }
819
820 co_list[co_list_num - 1].next = NULL;
821
822 *head_p = &co_list[0];
823 *tail_p = &co_list[co_list_num - 1];
824 }
825}
Adam Langley95c29f32014-06-20 12:00:00 -0700826
David Benjamin0344daf2015-04-08 02:08:01 -0400827/* ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
828 * parameters in the linked list from |*head_p| to |*tail_p|. It writes the new
829 * head and tail of the list to |*head_p| and |*tail_p|, respectively.
830 *
831 * - If |cipher_id| is non-zero, only that cipher is selected.
832 * - Otherwise, if |strength_bits| is non-negative, it selects ciphers
833 * of that strength.
834 * - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and
835 * |algo_strength|. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800836static void ssl_cipher_apply_rule(
David Benjamin107db582015-04-08 00:41:59 -0400837 uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
838 uint32_t alg_enc, uint32_t alg_mac, uint32_t alg_ssl,
839 uint32_t algo_strength, int rule, int strength_bits, int in_group,
Adam Langleyfcf25832014-12-18 17:42:32 -0800840 CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) {
841 CIPHER_ORDER *head, *tail, *curr, *next, *last;
842 const SSL_CIPHER *cp;
843 int reverse = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700844
David Benjamin0344daf2015-04-08 02:08:01 -0400845 if (cipher_id == 0 && strength_bits == -1 &&
846 (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0 ||
847 alg_ssl == 0 || algo_strength == 0)) {
848 /* The rule matches nothing, so bail early. */
849 return;
850 }
851
Adam Langleyfcf25832014-12-18 17:42:32 -0800852 if (rule == CIPHER_DEL) {
853 /* needed to maintain sorting between currently deleted ciphers */
854 reverse = 1;
855 }
Adam Langley95c29f32014-06-20 12:00:00 -0700856
Adam Langleyfcf25832014-12-18 17:42:32 -0800857 head = *head_p;
858 tail = *tail_p;
Adam Langley95c29f32014-06-20 12:00:00 -0700859
Adam Langleyfcf25832014-12-18 17:42:32 -0800860 if (reverse) {
861 next = tail;
862 last = head;
863 } else {
864 next = head;
865 last = tail;
866 }
Adam Langley95c29f32014-06-20 12:00:00 -0700867
Adam Langleyfcf25832014-12-18 17:42:32 -0800868 curr = NULL;
869 for (;;) {
870 if (curr == last) {
871 break;
872 }
Adam Langley95c29f32014-06-20 12:00:00 -0700873
Adam Langleyfcf25832014-12-18 17:42:32 -0800874 curr = next;
875 if (curr == NULL) {
876 break;
877 }
Adam Langleye3142a72014-07-24 17:56:48 -0700878
Adam Langleyfcf25832014-12-18 17:42:32 -0800879 next = reverse ? curr->prev : curr->next;
880 cp = curr->cipher;
Adam Langleye3142a72014-07-24 17:56:48 -0700881
David Benjamin0344daf2015-04-08 02:08:01 -0400882 /* Selection criteria is either a specific cipher, the value of
883 * |strength_bits|, or the algorithms used. */
884 if (cipher_id != 0) {
885 if (cipher_id != cp->id) {
886 continue;
887 }
888 } else if (strength_bits >= 0) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800889 if (strength_bits != cp->strength_bits) {
890 continue;
891 }
David Benjamin0344daf2015-04-08 02:08:01 -0400892 } else if (!(alg_mkey & cp->algorithm_mkey) ||
893 !(alg_auth & cp->algorithm_auth) ||
894 !(alg_enc & cp->algorithm_enc) ||
895 !(alg_mac & cp->algorithm_mac) ||
896 !(alg_ssl & cp->algorithm_ssl) ||
897 !(algo_strength & cp->algo_strength)) {
898 continue;
Adam Langleyfcf25832014-12-18 17:42:32 -0800899 }
Adam Langleye3142a72014-07-24 17:56:48 -0700900
Adam Langleyfcf25832014-12-18 17:42:32 -0800901 /* add the cipher if it has not been added yet. */
902 if (rule == CIPHER_ADD) {
903 /* reverse == 0 */
904 if (!curr->active) {
905 ll_append_tail(&head, curr, &tail);
906 curr->active = 1;
907 curr->in_group = in_group;
908 }
909 }
Adam Langley95c29f32014-06-20 12:00:00 -0700910
Adam Langleyfcf25832014-12-18 17:42:32 -0800911 /* Move the added cipher to this location */
912 else if (rule == CIPHER_ORD) {
913 /* reverse == 0 */
914 if (curr->active) {
915 ll_append_tail(&head, curr, &tail);
916 curr->in_group = 0;
917 }
918 } else if (rule == CIPHER_DEL) {
919 /* reverse == 1 */
920 if (curr->active) {
921 /* most recently deleted ciphersuites get best positions
922 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
923 * works in reverse to maintain the order) */
924 ll_append_head(&head, curr, &tail);
925 curr->active = 0;
926 curr->in_group = 0;
927 }
928 } else if (rule == CIPHER_KILL) {
929 /* reverse == 0 */
930 if (head == curr) {
931 head = curr->next;
932 } else {
933 curr->prev->next = curr->next;
934 }
Adam Langley95c29f32014-06-20 12:00:00 -0700935
Adam Langleyfcf25832014-12-18 17:42:32 -0800936 if (tail == curr) {
937 tail = curr->prev;
938 }
939 curr->active = 0;
940 if (curr->next != NULL) {
941 curr->next->prev = curr->prev;
942 }
943 if (curr->prev != NULL) {
944 curr->prev->next = curr->next;
945 }
946 curr->next = NULL;
947 curr->prev = NULL;
948 }
949 }
Adam Langley95c29f32014-06-20 12:00:00 -0700950
Adam Langleyfcf25832014-12-18 17:42:32 -0800951 *head_p = head;
952 *tail_p = tail;
953}
Adam Langley95c29f32014-06-20 12:00:00 -0700954
955static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
Adam Langleyfcf25832014-12-18 17:42:32 -0800956 CIPHER_ORDER **tail_p) {
957 int max_strength_bits, i, *number_uses;
958 CIPHER_ORDER *curr;
Adam Langley95c29f32014-06-20 12:00:00 -0700959
Adam Langleyfcf25832014-12-18 17:42:32 -0800960 /* This routine sorts the ciphers with descending strength. The sorting must
961 * keep the pre-sorted sequence, so we apply the normal sorting routine as
962 * '+' movement to the end of the list. */
963 max_strength_bits = 0;
964 curr = *head_p;
965 while (curr != NULL) {
966 if (curr->active && curr->cipher->strength_bits > max_strength_bits) {
967 max_strength_bits = curr->cipher->strength_bits;
968 }
969 curr = curr->next;
970 }
Adam Langley95c29f32014-06-20 12:00:00 -0700971
Adam Langleyfcf25832014-12-18 17:42:32 -0800972 number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
973 if (!number_uses) {
David Benjamin3570d732015-06-29 00:28:17 -0400974 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800975 return 0;
976 }
977 memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
Adam Langley95c29f32014-06-20 12:00:00 -0700978
Adam Langleyfcf25832014-12-18 17:42:32 -0800979 /* Now find the strength_bits values actually used. */
980 curr = *head_p;
981 while (curr != NULL) {
982 if (curr->active) {
983 number_uses[curr->cipher->strength_bits]++;
984 }
985 curr = curr->next;
986 }
Adam Langley95c29f32014-06-20 12:00:00 -0700987
Adam Langleyfcf25832014-12-18 17:42:32 -0800988 /* Go through the list of used strength_bits values in descending order. */
989 for (i = max_strength_bits; i >= 0; i--) {
990 if (number_uses[i] > 0) {
991 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p,
992 tail_p);
993 }
994 }
995
996 OPENSSL_free(number_uses);
997 return 1;
998}
Adam Langley95c29f32014-06-20 12:00:00 -0700999
David Benjamin0344daf2015-04-08 02:08:01 -04001000static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
1001 const char *rule_str,
Adam Langleyfcf25832014-12-18 17:42:32 -08001002 CIPHER_ORDER **head_p,
David Benjamin0344daf2015-04-08 02:08:01 -04001003 CIPHER_ORDER **tail_p) {
David Benjamin107db582015-04-08 00:41:59 -04001004 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
Adam Langleyfcf25832014-12-18 17:42:32 -08001005 const char *l, *buf;
David Benjamin0344daf2015-04-08 02:08:01 -04001006 int multi, rule, retval, ok, in_group = 0, has_group = 0;
1007 size_t j, buf_len;
1008 uint32_t cipher_id;
Adam Langleyfcf25832014-12-18 17:42:32 -08001009 char ch;
Adam Langley95c29f32014-06-20 12:00:00 -07001010
Adam Langleyfcf25832014-12-18 17:42:32 -08001011 retval = 1;
1012 l = rule_str;
1013 for (;;) {
1014 ch = *l;
Adam Langley95c29f32014-06-20 12:00:00 -07001015
Adam Langleyfcf25832014-12-18 17:42:32 -08001016 if (ch == '\0') {
1017 break; /* done */
1018 }
Adam Langley95c29f32014-06-20 12:00:00 -07001019
Adam Langleyfcf25832014-12-18 17:42:32 -08001020 if (in_group) {
1021 if (ch == ']') {
Adam Langleyfcf25832014-12-18 17:42:32 -08001022 if (*tail_p) {
1023 (*tail_p)->in_group = 0;
1024 }
1025 in_group = 0;
1026 l++;
1027 continue;
1028 }
David Benjamin37d92462014-09-20 17:54:24 -04001029
Adam Langleyfcf25832014-12-18 17:42:32 -08001030 if (ch == '|') {
1031 rule = CIPHER_ADD;
1032 l++;
1033 continue;
1034 } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') &&
1035 !(ch >= '0' && ch <= '9')) {
David Benjamin3570d732015-06-29 00:28:17 -04001036 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
David Benjamin0344daf2015-04-08 02:08:01 -04001037 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001038 break;
1039 } else {
1040 rule = CIPHER_ADD;
1041 }
1042 } else if (ch == '-') {
1043 rule = CIPHER_DEL;
1044 l++;
1045 } else if (ch == '+') {
1046 rule = CIPHER_ORD;
1047 l++;
1048 } else if (ch == '!') {
1049 rule = CIPHER_KILL;
1050 l++;
1051 } else if (ch == '@') {
1052 rule = CIPHER_SPECIAL;
1053 l++;
1054 } else if (ch == '[') {
1055 if (in_group) {
David Benjamin3570d732015-06-29 00:28:17 -04001056 OPENSSL_PUT_ERROR(SSL, SSL_R_NESTED_GROUP);
David Benjamin0344daf2015-04-08 02:08:01 -04001057 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001058 break;
1059 }
1060 in_group = 1;
1061 has_group = 1;
1062 l++;
1063 continue;
1064 } else {
1065 rule = CIPHER_ADD;
1066 }
Adam Langley95c29f32014-06-20 12:00:00 -07001067
Adam Langleyfcf25832014-12-18 17:42:32 -08001068 /* If preference groups are enabled, the only legal operator is +.
1069 * Otherwise the in_group bits will get mixed up. */
1070 if (has_group && rule != CIPHER_ADD) {
David Benjamin3570d732015-06-29 00:28:17 -04001071 OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
David Benjamin0344daf2015-04-08 02:08:01 -04001072 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001073 break;
1074 }
Adam Langley95c29f32014-06-20 12:00:00 -07001075
Adam Langleyfcf25832014-12-18 17:42:32 -08001076 if (ITEM_SEP(ch)) {
1077 l++;
1078 continue;
1079 }
Adam Langley95c29f32014-06-20 12:00:00 -07001080
David Benjamin0344daf2015-04-08 02:08:01 -04001081 multi = 0;
1082 cipher_id = 0;
1083 alg_mkey = ~0u;
1084 alg_auth = ~0u;
1085 alg_enc = ~0u;
1086 alg_mac = ~0u;
1087 alg_ssl = ~0u;
1088 algo_strength = ~0u;
Adam Langley95c29f32014-06-20 12:00:00 -07001089
Adam Langleyfcf25832014-12-18 17:42:32 -08001090 for (;;) {
1091 ch = *l;
1092 buf = l;
David Benjamin0344daf2015-04-08 02:08:01 -04001093 buf_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001094 while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) ||
1095 ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) {
1096 ch = *(++l);
David Benjamin0344daf2015-04-08 02:08:01 -04001097 buf_len++;
Adam Langleyfcf25832014-12-18 17:42:32 -08001098 }
Adam Langley95c29f32014-06-20 12:00:00 -07001099
David Benjamin0344daf2015-04-08 02:08:01 -04001100 if (buf_len == 0) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001101 /* We hit something we cannot deal with, it is no command or separator
1102 * nor alphanumeric, so we call this an error. */
David Benjamin3570d732015-06-29 00:28:17 -04001103 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjamin0344daf2015-04-08 02:08:01 -04001104 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001105 l++;
1106 break;
1107 }
Adam Langley95c29f32014-06-20 12:00:00 -07001108
Adam Langleyfcf25832014-12-18 17:42:32 -08001109 if (rule == CIPHER_SPECIAL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001110 break;
1111 }
David Benjamin0344daf2015-04-08 02:08:01 -04001112
1113 /* Look for a matching exact cipher. These aren't allowed in multipart
1114 * rules. */
1115 if (!multi && ch != '+') {
David Benjamina1c90a52015-05-30 17:03:14 -04001116 for (j = 0; j < kCiphersLen; j++) {
1117 const SSL_CIPHER *cipher = &kCiphers[j];
1118 if (rule_equals(cipher->name, buf, buf_len)) {
David Benjamin0344daf2015-04-08 02:08:01 -04001119 cipher_id = cipher->id;
1120 break;
1121 }
1122 }
1123 }
1124 if (cipher_id == 0) {
1125 /* If not an exact cipher, look for a matching cipher alias. */
David Benjamina1c90a52015-05-30 17:03:14 -04001126 for (j = 0; j < kCipherAliasesLen; j++) {
David Benjamin0344daf2015-04-08 02:08:01 -04001127 if (rule_equals(kCipherAliases[j].name, buf, buf_len)) {
1128 alg_mkey &= kCipherAliases[j].algorithm_mkey;
1129 alg_auth &= kCipherAliases[j].algorithm_auth;
1130 alg_enc &= kCipherAliases[j].algorithm_enc;
1131 alg_mac &= kCipherAliases[j].algorithm_mac;
1132 alg_ssl &= kCipherAliases[j].algorithm_ssl;
1133 algo_strength &= kCipherAliases[j].algo_strength;
1134 break;
1135 }
1136 }
David Benjamina1c90a52015-05-30 17:03:14 -04001137 if (j == kCipherAliasesLen) {
David Benjamin0344daf2015-04-08 02:08:01 -04001138 alg_mkey = alg_auth = alg_enc = alg_mac = alg_ssl = algo_strength = 0;
1139 }
1140 }
1141
1142 /* Check for a multipart rule. */
1143 if (ch != '+') {
1144 break;
1145 }
1146 l++;
1147 multi = 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001148 }
Adam Langley95c29f32014-06-20 12:00:00 -07001149
Adam Langleyfcf25832014-12-18 17:42:32 -08001150 /* Ok, we have the rule, now apply it. */
1151 if (rule == CIPHER_SPECIAL) {
1152 /* special command */
1153 ok = 0;
David Benjamin0344daf2015-04-08 02:08:01 -04001154 if (buf_len == 8 && !strncmp(buf, "STRENGTH", 8)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001155 ok = ssl_cipher_strength_sort(head_p, tail_p);
1156 } else {
David Benjamin3570d732015-06-29 00:28:17 -04001157 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
Adam Langleyfcf25832014-12-18 17:42:32 -08001158 }
Adam Langley95c29f32014-06-20 12:00:00 -07001159
Adam Langleyfcf25832014-12-18 17:42:32 -08001160 if (ok == 0) {
1161 retval = 0;
1162 }
Adam Langley95c29f32014-06-20 12:00:00 -07001163
Adam Langleyfcf25832014-12-18 17:42:32 -08001164 /* We do not support any "multi" options together with "@", so throw away
1165 * the rest of the command, if any left, until end or ':' is found. */
1166 while (*l != '\0' && !ITEM_SEP(*l)) {
1167 l++;
1168 }
David Benjamin0344daf2015-04-08 02:08:01 -04001169 } else {
Adam Langleyfcf25832014-12-18 17:42:32 -08001170 ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac,
1171 alg_ssl, algo_strength, rule, -1, in_group, head_p,
1172 tail_p);
Adam Langleyfcf25832014-12-18 17:42:32 -08001173 }
1174 }
Adam Langley95c29f32014-06-20 12:00:00 -07001175
Adam Langleyfcf25832014-12-18 17:42:32 -08001176 if (in_group) {
David Benjamin3570d732015-06-29 00:28:17 -04001177 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
Adam Langleyfcf25832014-12-18 17:42:32 -08001178 retval = 0;
1179 }
Adam Langley95c29f32014-06-20 12:00:00 -07001180
Adam Langleyfcf25832014-12-18 17:42:32 -08001181 return retval;
1182}
Adam Langley95c29f32014-06-20 12:00:00 -07001183
Adam Langleyfcf25832014-12-18 17:42:32 -08001184STACK_OF(SSL_CIPHER) *
1185ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
David Benjamin71f07942015-04-08 02:36:59 -04001186 struct ssl_cipher_preference_list_st **out_cipher_list,
1187 STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
1188 const char *rule_str) {
David Benjamin0344daf2015-04-08 02:08:01 -04001189 int ok;
Adam Langleyfcf25832014-12-18 17:42:32 -08001190 STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
1191 const char *rule_p;
1192 CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
Adam Langleyfcf25832014-12-18 17:42:32 -08001193 uint8_t *in_group_flags = NULL;
1194 unsigned int num_in_group_flags = 0;
1195 struct ssl_cipher_preference_list_st *pref_list = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001196
Adam Langleyfcf25832014-12-18 17:42:32 -08001197 /* Return with error if nothing to do. */
David Benjamin71f07942015-04-08 02:36:59 -04001198 if (rule_str == NULL || out_cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001199 return NULL;
1200 }
David Benjamin5213df42014-08-20 14:19:54 -04001201
Adam Langleyfcf25832014-12-18 17:42:32 -08001202 /* Now we have to collect the available ciphers from the compiled in ciphers.
1203 * We cannot get more than the number compiled in, so it is used for
1204 * allocation. */
David Benjamina1c90a52015-05-30 17:03:14 -04001205 co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
Adam Langleyfcf25832014-12-18 17:42:32 -08001206 if (co_list == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001207 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001208 return NULL;
1209 }
Adam Langley95c29f32014-06-20 12:00:00 -07001210
David Benjamina1c90a52015-05-30 17:03:14 -04001211 ssl_cipher_collect_ciphers(ssl_method, co_list, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001212
Adam Langleyfcf25832014-12-18 17:42:32 -08001213 /* Now arrange all ciphers by preference:
1214 * TODO(davidben): Compute this order once and copy it. */
Adam Langley95c29f32014-06-20 12:00:00 -07001215
Adam Langleyfcf25832014-12-18 17:42:32 -08001216 /* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other
1217 * key exchange mechanisms */
David Benjamina1c90a52015-05-30 17:03:14 -04001218 ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u,
1219 CIPHER_ADD, -1, 0, &head, &tail);
David Benjamin0344daf2015-04-08 02:08:01 -04001220 ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
Adam Langleyfcf25832014-12-18 17:42:32 -08001221 0, &head, &tail);
David Benjamin0344daf2015-04-08 02:08:01 -04001222 ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1,
1223 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001224
Adam Langleyfcf25832014-12-18 17:42:32 -08001225 /* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
1226 * CHACHA20 unless there is hardware support for fast and constant-time
1227 * AES_GCM. */
1228 if (EVP_has_aes_hardware()) {
David Benjamin0344daf2015-04-08 02:08:01 -04001229 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
Adam Langleyfcf25832014-12-18 17:42:32 -08001230 -1, 0, &head, &tail);
David Benjamin0344daf2015-04-08 02:08:01 -04001231 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
1232 -1, 0, &head, &tail);
1233 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u,
1234 CIPHER_ADD, -1, 0, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001235 } else {
David Benjamin0344daf2015-04-08 02:08:01 -04001236 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, ~0u, ~0u,
1237 CIPHER_ADD, -1, 0, &head, &tail);
1238 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
Adam Langleyfcf25832014-12-18 17:42:32 -08001239 -1, 0, &head, &tail);
David Benjamin0344daf2015-04-08 02:08:01 -04001240 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, ~0u, ~0u, CIPHER_ADD,
1241 -1, 0, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001242 }
Adam Langley95c29f32014-06-20 12:00:00 -07001243
Adam Langleyfcf25832014-12-18 17:42:32 -08001244 /* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC, RC4_128_SHA,
1245 * RC4_128_MD5, 3DES_EDE_CBC_SHA. */
David Benjamin0344daf2015-04-08 02:08:01 -04001246 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
1247 0, &head, &tail);
1248 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, ~0u, ~0u, CIPHER_ADD, -1,
1249 0, &head, &tail);
1250 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, ~0u, ~0u, CIPHER_ADD,
1251 -1, 0, &head, &tail);
1252 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, ~0u, ~0u, CIPHER_ADD, -1,
1253 0, &head, &tail);
1254 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0,
Adam Langleyfcf25832014-12-18 17:42:32 -08001255 &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001256
Adam Langleyfcf25832014-12-18 17:42:32 -08001257 /* Temporarily enable everything else for sorting */
David Benjamin0344daf2015-04-08 02:08:01 -04001258 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_ADD, -1, 0,
1259 &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001260
Adam Langleyfcf25832014-12-18 17:42:32 -08001261 /* Move ciphers without forward secrecy to the end. */
David Benjamin0344daf2015-04-08 02:08:01 -04001262 ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, ~0u, ~0u,
1263 CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001264
Adam Langleyfcf25832014-12-18 17:42:32 -08001265 /* Now disable everything (maintaining the ordering!) */
David Benjamin0344daf2015-04-08 02:08:01 -04001266 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u, CIPHER_DEL, -1, 0,
1267 &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001268
Adam Langleyfcf25832014-12-18 17:42:32 -08001269 /* If the rule_string begins with DEFAULT, apply the default rule before
1270 * using the (possibly available) additional rules. */
1271 ok = 1;
1272 rule_p = rule_str;
1273 if (strncmp(rule_str, "DEFAULT", 7) == 0) {
David Benjamin0344daf2015-04-08 02:08:01 -04001274 ok = ssl_cipher_process_rulestr(ssl_method, SSL_DEFAULT_CIPHER_LIST, &head,
1275 &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001276 rule_p += 7;
1277 if (*rule_p == ':') {
1278 rule_p++;
1279 }
1280 }
Adam Langley858a88d2014-06-20 12:00:00 -07001281
Adam Langleyfcf25832014-12-18 17:42:32 -08001282 if (ok && strlen(rule_p) > 0) {
David Benjamin0344daf2015-04-08 02:08:01 -04001283 ok = ssl_cipher_process_rulestr(ssl_method, rule_p, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001284 }
Adam Langley95c29f32014-06-20 12:00:00 -07001285
Adam Langleyfcf25832014-12-18 17:42:32 -08001286 if (!ok) {
1287 goto err;
1288 }
1289
1290 /* Allocate new "cipherstack" for the result, return with error
1291 * if we cannot get one. */
1292 cipherstack = sk_SSL_CIPHER_new_null();
1293 if (cipherstack == NULL) {
1294 goto err;
1295 }
1296
David Benjamina1c90a52015-05-30 17:03:14 -04001297 in_group_flags = OPENSSL_malloc(kCiphersLen);
Adam Langleyfcf25832014-12-18 17:42:32 -08001298 if (!in_group_flags) {
1299 goto err;
1300 }
1301
1302 /* The cipher selection for the list is done. The ciphers are added
1303 * to the resulting precedence to the STACK_OF(SSL_CIPHER). */
1304 for (curr = head; curr != NULL; curr = curr->next) {
1305 if (curr->active) {
David Benjamin2adb7ec2015-01-11 19:59:06 -05001306 if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
1307 goto err;
1308 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001309 in_group_flags[num_in_group_flags++] = curr->in_group;
1310 }
1311 }
1312 OPENSSL_free(co_list); /* Not needed any longer */
1313 co_list = NULL;
1314
1315 tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1316 if (tmp_cipher_list == NULL) {
1317 goto err;
1318 }
1319 pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
1320 if (!pref_list) {
1321 goto err;
1322 }
1323 pref_list->ciphers = cipherstack;
1324 pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags);
1325 if (!pref_list->in_group_flags) {
1326 goto err;
1327 }
1328 memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags);
1329 OPENSSL_free(in_group_flags);
1330 in_group_flags = NULL;
David Benjamin71f07942015-04-08 02:36:59 -04001331 if (*out_cipher_list != NULL) {
1332 ssl_cipher_preference_list_free(*out_cipher_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001333 }
David Benjamin71f07942015-04-08 02:36:59 -04001334 *out_cipher_list = pref_list;
Adam Langleyfcf25832014-12-18 17:42:32 -08001335 pref_list = NULL;
1336
David Benjamin71f07942015-04-08 02:36:59 -04001337 if (out_cipher_list_by_id != NULL) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001338 sk_SSL_CIPHER_free(*out_cipher_list_by_id);
David Benjamin71f07942015-04-08 02:36:59 -04001339 *out_cipher_list_by_id = tmp_cipher_list;
Adam Langleyfcf25832014-12-18 17:42:32 -08001340 tmp_cipher_list = NULL;
David Benjamin71f07942015-04-08 02:36:59 -04001341 (void) sk_SSL_CIPHER_set_cmp_func(*out_cipher_list_by_id,
1342 ssl_cipher_ptr_id_cmp);
Adam Langleyfcf25832014-12-18 17:42:32 -08001343
David Benjamin71f07942015-04-08 02:36:59 -04001344 sk_SSL_CIPHER_sort(*out_cipher_list_by_id);
Adam Langleyfcf25832014-12-18 17:42:32 -08001345 } else {
1346 sk_SSL_CIPHER_free(tmp_cipher_list);
1347 tmp_cipher_list = NULL;
1348 }
1349
1350 return cipherstack;
Adam Langley858a88d2014-06-20 12:00:00 -07001351
1352err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001353 OPENSSL_free(co_list);
1354 OPENSSL_free(in_group_flags);
1355 sk_SSL_CIPHER_free(cipherstack);
1356 sk_SSL_CIPHER_free(tmp_cipher_list);
1357 if (pref_list) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001358 OPENSSL_free(pref_list->in_group_flags);
1359 }
David Benjamin2755a3e2015-04-22 16:17:58 -04001360 OPENSSL_free(pref_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001361 return NULL;
1362}
Adam Langley95c29f32014-06-20 12:00:00 -07001363
David Benjamin71f07942015-04-08 02:36:59 -04001364uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
1365
David Benjamina1c90a52015-05-30 17:03:14 -04001366uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
1367 uint32_t id = cipher->id;
1368 /* All ciphers are SSLv3. */
1369 assert((id & 0xff000000) == 0x03000000);
1370 return id & 0xffff;
1371}
1372
David Benjamin71f07942015-04-08 02:36:59 -04001373int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
1374 return (cipher->algorithm_enc & SSL_AES) != 0;
1375}
1376
1377int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher) {
1378 return (cipher->algorithm_mac & SSL_MD5) != 0;
1379}
1380
1381int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
David Benjaminc0125ef2015-09-09 09:11:07 -04001382 return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
David Benjamin71f07942015-04-08 02:36:59 -04001383}
1384
1385int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
1386 return (cipher->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
1387}
1388
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001389int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
1390 return (cipher->algorithm_enc & SSL_eNULL) != 0;
1391}
1392
1393int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) {
1394 /* Neither stream cipher nor AEAD. */
1395 return (cipher->algorithm_enc & (SSL_RC4 | SSL_eNULL)) == 0 &&
1396 cipher->algorithm_mac != SSL_AEAD;
1397}
1398
David Benjamin71f07942015-04-08 02:36:59 -04001399/* return the actual cipher being used */
1400const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) {
1401 if (cipher != NULL) {
1402 return cipher->name;
1403 }
1404
1405 return "(NONE)";
1406}
1407
1408const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
1409 if (cipher == NULL) {
1410 return "";
1411 }
1412
1413 switch (cipher->algorithm_mkey) {
1414 case SSL_kRSA:
1415 return "RSA";
1416
1417 case SSL_kDHE:
1418 switch (cipher->algorithm_auth) {
1419 case SSL_aRSA:
1420 return "DHE_RSA";
1421 default:
1422 assert(0);
1423 return "UNKNOWN";
1424 }
1425
1426 case SSL_kECDHE:
1427 switch (cipher->algorithm_auth) {
1428 case SSL_aECDSA:
1429 return "ECDHE_ECDSA";
1430 case SSL_aRSA:
1431 return "ECDHE_RSA";
1432 case SSL_aPSK:
1433 return "ECDHE_PSK";
1434 default:
1435 assert(0);
1436 return "UNKNOWN";
1437 }
1438
1439 case SSL_kPSK:
1440 assert(cipher->algorithm_auth == SSL_aPSK);
1441 return "PSK";
1442
1443 default:
1444 assert(0);
1445 return "UNKNOWN";
1446 }
1447}
1448
1449static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
1450 switch (cipher->algorithm_enc) {
1451 case SSL_3DES:
1452 return "3DES_EDE_CBC";
1453 case SSL_RC4:
1454 return "RC4";
1455 case SSL_AES128:
1456 return "AES_128_CBC";
1457 case SSL_AES256:
1458 return "AES_256_CBC";
1459 case SSL_AES128GCM:
1460 return "AES_128_GCM";
1461 case SSL_AES256GCM:
1462 return "AES_256_GCM";
1463 case SSL_CHACHA20POLY1305:
1464 return "CHACHA20_POLY1305";
1465 break;
1466 default:
1467 assert(0);
1468 return "UNKNOWN";
1469 }
1470}
1471
1472static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
David Benjaminb0883312015-08-06 09:54:13 -04001473 switch (cipher->algorithm_prf) {
1474 case SSL_HANDSHAKE_MAC_DEFAULT:
1475 /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
1476 * only ever MD5 or SHA-1. */
1477 switch (cipher->algorithm_mac) {
1478 case SSL_MD5:
1479 return "MD5";
1480 case SSL_SHA1:
1481 return "SHA";
1482 }
1483 break;
1484 case SSL_HANDSHAKE_MAC_SHA256:
1485 return "SHA256";
1486 case SSL_HANDSHAKE_MAC_SHA384:
1487 return "SHA384";
David Benjamin71f07942015-04-08 02:36:59 -04001488 }
David Benjaminb0883312015-08-06 09:54:13 -04001489 assert(0);
1490 return "UNKNOWN";
David Benjamin71f07942015-04-08 02:36:59 -04001491}
1492
1493char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
1494 if (cipher == NULL) {
1495 return NULL;
1496 }
1497
1498 const char *kx_name = SSL_CIPHER_get_kx_name(cipher);
1499 const char *enc_name = ssl_cipher_get_enc_name(cipher);
1500 const char *prf_name = ssl_cipher_get_prf_name(cipher);
1501
1502 /* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name}. */
1503 size_t len = 4 + strlen(kx_name) + 6 + strlen(enc_name) + 1 +
1504 strlen(prf_name) + 1;
1505 char *ret = OPENSSL_malloc(len);
1506 if (ret == NULL) {
1507 return NULL;
1508 }
1509 if (BUF_strlcpy(ret, "TLS_", len) >= len ||
1510 BUF_strlcat(ret, kx_name, len) >= len ||
1511 BUF_strlcat(ret, "_WITH_", len) >= len ||
1512 BUF_strlcat(ret, enc_name, len) >= len ||
1513 BUF_strlcat(ret, "_", len) >= len ||
1514 BUF_strlcat(ret, prf_name, len) >= len) {
1515 assert(0);
1516 OPENSSL_free(ret);
1517 return NULL;
1518 }
1519 assert(strlen(ret) + 1 == len);
1520 return ret;
1521}
1522
1523int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) {
1524 if (cipher == NULL) {
1525 return 0;
1526 }
1527
1528 if (out_alg_bits != NULL) {
1529 *out_alg_bits = cipher->alg_bits;
1530 }
1531 return cipher->strength_bits;
1532}
1533
Adam Langleyfcf25832014-12-18 17:42:32 -08001534const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
1535 int len) {
1536 const char *ver;
1537 const char *kx, *au, *enc, *mac;
David Benjamin107db582015-04-08 00:41:59 -04001538 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl;
Adam Langleyfcf25832014-12-18 17:42:32 -08001539 static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
Adam Langley95c29f32014-06-20 12:00:00 -07001540
Adam Langleyfcf25832014-12-18 17:42:32 -08001541 alg_mkey = cipher->algorithm_mkey;
1542 alg_auth = cipher->algorithm_auth;
1543 alg_enc = cipher->algorithm_enc;
1544 alg_mac = cipher->algorithm_mac;
1545 alg_ssl = cipher->algorithm_ssl;
Adam Langley95c29f32014-06-20 12:00:00 -07001546
Adam Langleyfcf25832014-12-18 17:42:32 -08001547 if (alg_ssl & SSL_SSLV3) {
1548 ver = "SSLv3";
1549 } else if (alg_ssl & SSL_TLSV1_2) {
1550 ver = "TLSv1.2";
1551 } else {
1552 ver = "unknown";
1553 }
Adam Langley95c29f32014-06-20 12:00:00 -07001554
Adam Langleyfcf25832014-12-18 17:42:32 -08001555 switch (alg_mkey) {
1556 case SSL_kRSA:
1557 kx = "RSA";
1558 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001559
David Benjamin7061e282015-03-19 11:10:48 -04001560 case SSL_kDHE:
Adam Langleyfcf25832014-12-18 17:42:32 -08001561 kx = "DH";
1562 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001563
David Benjamin7061e282015-03-19 11:10:48 -04001564 case SSL_kECDHE:
Adam Langleyfcf25832014-12-18 17:42:32 -08001565 kx = "ECDH";
1566 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001567
Adam Langleyfcf25832014-12-18 17:42:32 -08001568 case SSL_kPSK:
1569 kx = "PSK";
1570 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001571
Adam Langleyfcf25832014-12-18 17:42:32 -08001572 default:
1573 kx = "unknown";
1574 }
Adam Langley95c29f32014-06-20 12:00:00 -07001575
Adam Langleyfcf25832014-12-18 17:42:32 -08001576 switch (alg_auth) {
1577 case SSL_aRSA:
1578 au = "RSA";
1579 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001580
Adam Langleyfcf25832014-12-18 17:42:32 -08001581 case SSL_aECDSA:
1582 au = "ECDSA";
1583 break;
Adam Langley4d4bff82014-06-20 12:00:00 -07001584
Adam Langleyfcf25832014-12-18 17:42:32 -08001585 case SSL_aPSK:
1586 au = "PSK";
1587 break;
Adam Langley4d4bff82014-06-20 12:00:00 -07001588
Adam Langleyfcf25832014-12-18 17:42:32 -08001589 default:
1590 au = "unknown";
1591 break;
1592 }
Adam Langleyde0b2022014-06-20 12:00:00 -07001593
Adam Langleyfcf25832014-12-18 17:42:32 -08001594 switch (alg_enc) {
1595 case SSL_3DES:
1596 enc = "3DES(168)";
1597 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001598
Adam Langleyfcf25832014-12-18 17:42:32 -08001599 case SSL_RC4:
1600 enc = "RC4(128)";
1601 break;
1602
1603 case SSL_AES128:
1604 enc = "AES(128)";
1605 break;
1606
1607 case SSL_AES256:
1608 enc = "AES(256)";
1609 break;
1610
1611 case SSL_AES128GCM:
1612 enc = "AESGCM(128)";
1613 break;
1614
1615 case SSL_AES256GCM:
1616 enc = "AESGCM(256)";
1617 break;
1618
1619 case SSL_CHACHA20POLY1305:
1620 enc = "ChaCha20-Poly1305";
1621 break;
1622
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001623 case SSL_eNULL:
1624 enc="None";
1625 break;
1626
Adam Langleyfcf25832014-12-18 17:42:32 -08001627 default:
1628 enc = "unknown";
1629 break;
1630 }
1631
1632 switch (alg_mac) {
1633 case SSL_MD5:
1634 mac = "MD5";
1635 break;
1636
1637 case SSL_SHA1:
1638 mac = "SHA1";
1639 break;
1640
1641 case SSL_SHA256:
1642 mac = "SHA256";
1643 break;
1644
1645 case SSL_SHA384:
1646 mac = "SHA384";
1647 break;
1648
1649 case SSL_AEAD:
1650 mac = "AEAD";
1651 break;
1652
1653 default:
1654 mac = "unknown";
1655 break;
1656 }
1657
1658 if (buf == NULL) {
1659 len = 128;
1660 buf = OPENSSL_malloc(len);
David Benjamin1eed2c02015-02-08 23:20:06 -05001661 if (buf == NULL) {
1662 return NULL;
1663 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001664 } else if (len < 128) {
1665 return "Buffer too small";
1666 }
1667
1668 BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac);
1669 return buf;
1670}
1671
David Benjamin71f07942015-04-08 02:36:59 -04001672const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
1673 return "TLSv1/SSLv3";
Adam Langleyfcf25832014-12-18 17:42:32 -08001674}
1675
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001676COMP_METHOD *SSL_COMP_get_compression_methods(void) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001677
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001678int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001679
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001680const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; }
Adam Langley95c29f32014-06-20 12:00:00 -07001681
David Benjamind1d80782015-07-05 11:54:09 -04001682int ssl_cipher_get_key_type(const SSL_CIPHER *cipher) {
David Benjamin71f07942015-04-08 02:36:59 -04001683 uint32_t alg_a = cipher->algorithm_auth;
Adam Langley95c29f32014-06-20 12:00:00 -07001684
Adam Langleyfcf25832014-12-18 17:42:32 -08001685 if (alg_a & SSL_aECDSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001686 return EVP_PKEY_EC;
Adam Langleyfcf25832014-12-18 17:42:32 -08001687 } else if (alg_a & SSL_aRSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001688 return EVP_PKEY_RSA;
Adam Langleyfcf25832014-12-18 17:42:32 -08001689 }
Adam Langley95c29f32014-06-20 12:00:00 -07001690
David Benjamind1d80782015-07-05 11:54:09 -04001691 return EVP_PKEY_NONE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001692}
David Benjamin9c651c92014-07-12 13:27:45 -04001693
Adam Langleyfcf25832014-12-18 17:42:32 -08001694int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher) {
David Benjamin32fbdf22015-04-07 01:14:06 -04001695 /* PSK-authenticated ciphers do not use a public key, except for
1696 * RSA_PSK. */
Adam Langleyfcf25832014-12-18 17:42:32 -08001697 if ((cipher->algorithm_auth & SSL_aPSK) &&
1698 !(cipher->algorithm_mkey & SSL_kRSA)) {
1699 return 0;
1700 }
1701
1702 /* All other ciphers include it. */
1703 return 1;
1704}
1705
Adam Langleyfcf25832014-12-18 17:42:32 -08001706int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
1707 /* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */
David Benjamin7061e282015-03-19 11:10:48 -04001708 if (cipher->algorithm_mkey & SSL_kDHE || cipher->algorithm_mkey & SSL_kECDHE) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001709 return 1;
1710 }
1711
1712 /* It is optional in all others. */
1713 return 0;
1714}
David Benjaminb8d28cf2015-07-28 21:34:45 -04001715
1716size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
1717 size_t block_size;
1718 switch (cipher->algorithm_enc) {
1719 case SSL_3DES:
1720 block_size = 8;
1721 break;
1722 case SSL_AES128:
1723 case SSL_AES256:
1724 block_size = 16;
1725 break;
1726 default:
1727 return 0;
1728 }
1729
1730 size_t mac_len;
1731 switch (cipher->algorithm_mac) {
1732 case SSL_MD5:
1733 mac_len = MD5_DIGEST_LENGTH;
1734 break;
1735 case SSL_SHA1:
1736 mac_len = SHA_DIGEST_LENGTH;
1737 break;
1738 default:
1739 return 0;
1740 }
1741
1742 size_t ret = 1 + mac_len;
1743 ret += block_size - (ret % block_size);
1744 return ret;
1745}