blob: 85d85a0faeb0e271befae0ed029bb64571d0739c [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
David Benjamin9e4e01e2015-09-15 01:48:04 -0400141#include <openssl/ssl.h>
142
Adam Langley95c29f32014-06-20 12:00:00 -0700143#include <assert.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400144#include <stdio.h>
145#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700146
David Benjamin71f07942015-04-08 02:36:59 -0400147#include <openssl/buf.h>
David Benjaminf0ae1702015-04-07 23:05:04 -0400148#include <openssl/err.h>
David Benjaminea72bd02014-12-21 21:27:41 -0500149#include <openssl/md5.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700150#include <openssl/mem.h>
David Benjaminea72bd02014-12-21 21:27:41 -0500151#include <openssl/sha.h>
David Benjamin71f07942015-04-08 02:36:59 -0400152#include <openssl/stack.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700153
David Benjamin2ee94aa2015-04-07 22:38:30 -0400154#include "internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -0700155
Adam Langley95c29f32014-06-20 12:00:00 -0700156
David Benjamina1c90a52015-05-30 17:03:14 -0400157/* kCiphers is an array of all supported ciphers, sorted by id. */
David Benjamin20c37312015-11-11 21:33:18 -0800158static const SSL_CIPHER kCiphers[] = {
David Benjamina1c90a52015-05-30 17:03:14 -0400159 /* The RSA ciphers */
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700160 /* Cipher 02 */
161 {
162 SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA, SSL_aRSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500163 SSL_eNULL, SSL_SHA1, SSL_HANDSHAKE_MAC_DEFAULT, 0, 0,
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700164 },
165
David Benjamina1c90a52015-05-30 17:03:14 -0400166 /* Cipher 04 */
167 {
168 SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500169 SSL_RC4, SSL_MD5, SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
David Benjamina1c90a52015-05-30 17:03:14 -0400170 },
171
172 /* Cipher 05 */
173 {
174 SSL3_TXT_RSA_RC4_128_SHA, SSL3_CK_RSA_RC4_128_SHA, SSL_kRSA, SSL_aRSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500175 SSL_RC4, SSL_SHA1, SSL_HANDSHAKE_MAC_DEFAULT, 128, 128,
David Benjamina1c90a52015-05-30 17:03:14 -0400176 },
177
178 /* Cipher 0A */
179 {
180 SSL3_TXT_RSA_DES_192_CBC3_SHA, SSL3_CK_RSA_DES_192_CBC3_SHA, SSL_kRSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500181 SSL_aRSA, SSL_3DES, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400182 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500191 SSL_aRSA, SSL_AES128, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400192 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500198 SSL_kDHE, SSL_aRSA, SSL_AES128, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400199 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500205 SSL_aRSA, SSL_AES256, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400206 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500212 SSL_kDHE, SSL_aRSA, SSL_AES256, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400213 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500222 SSL_kRSA, SSL_aRSA, SSL_AES128, SSL_SHA256,
David Benjamindcb6ef02015-11-06 15:35:54 -0500223 SSL_HANDSHAKE_MAC_SHA256, 128, 128,
David Benjamina1c90a52015-05-30 17:03:14 -0400224 },
225
226 /* Cipher 3D */
227 {
228 TLS1_TXT_RSA_WITH_AES_256_SHA256, TLS1_CK_RSA_WITH_AES_256_SHA256,
David Benjamindcb6ef02015-11-06 15:35:54 -0500229 SSL_kRSA, SSL_aRSA, SSL_AES256, SSL_SHA256,
David Benjamind6e9eec2015-11-18 09:48:55 -0500230 SSL_HANDSHAKE_MAC_SHA256, 256, 256,
David Benjamina1c90a52015-05-30 17:03:14 -0400231 },
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500237 SSL_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400238 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500245 SSL_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400246 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500254 SSL_aPSK, SSL_RC4, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400255 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500261 SSL_kPSK, SSL_aPSK, SSL_AES128, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400262 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500268 SSL_kPSK, SSL_aPSK, SSL_AES256, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400269 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500278 SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500287 SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500296 SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500305 SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500314 SSL_SHA1, SSL_HANDSHAKE_MAC_DEFAULT, 128,
David Benjamina1c90a52015-05-30 17:03:14 -0400315 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500322 SSL_AES128, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400323 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500330 SSL_AES256, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400331 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500337 SSL_kECDHE, SSL_aRSA, SSL_RC4, SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400338 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500345 SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400346 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500353 SSL_SHA1,
David Benjamina1c90a52015-05-30 17:03:14 -0400354 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500364 SSL_AES128, SSL_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400365 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500372 SSL_AES256, SSL_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400373 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500380 SSL_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400381 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500388 SSL_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400389 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500399 SSL_AES128GCM, SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500408 SSL_AES256GCM, SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500417 SSL_AES128GCM, SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500426 SSL_AES256GCM, SSL_AEAD,
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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500437 SSL_kECDHE, SSL_aPSK, SSL_AES128, SSL_SHA1,
Adam Langley85bc5602015-06-09 09:54:04 -0700438 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,
David Benjamind6e9eec2015-11-18 09:48:55 -0500445 SSL_kECDHE, SSL_aPSK, SSL_AES256, SSL_SHA1,
Adam Langley85bc5602015-06-09 09:54:04 -0700446 SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
447 },
448
Adam Langleyd98dc132015-09-23 16:41:33 -0700449#if !defined(BORINGSSL_ANDROID_SYSTEM)
Adam Langley85bc5602015-06-09 09:54:04 -0700450 /* ChaCha20-Poly1305 cipher suites. */
451
David Benjamina1c90a52015-05-30 17:03:14 -0400452 {
Brian Smith271777f2015-10-03 13:53:33 -1000453 TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD,
454 TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aRSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500455 SSL_CHACHA20POLY1305_OLD, SSL_AEAD,
David Benjamina1c90a52015-05-30 17:03:14 -0400456 SSL_HANDSHAKE_MAC_SHA256,
David Benjaminbe8a8692015-08-21 13:51:56 -0400457 256, 256,
David Benjamina1c90a52015-05-30 17:03:14 -0400458 },
459
460 {
Brian Smith271777f2015-10-03 13:53:33 -1000461 TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD,
462 TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD, SSL_kECDHE, SSL_aECDSA,
David Benjamind6e9eec2015-11-18 09:48:55 -0500463 SSL_CHACHA20POLY1305_OLD, SSL_AEAD,
David Benjamina1c90a52015-05-30 17:03:14 -0400464 SSL_HANDSHAKE_MAC_SHA256,
David Benjaminbe8a8692015-08-21 13:51:56 -0400465 256, 256,
David Benjamina1c90a52015-05-30 17:03:14 -0400466 },
Adam Langleyd98dc132015-09-23 16:41:33 -0700467#endif
David Benjamina1c90a52015-05-30 17:03:14 -0400468};
469
470static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
471
Adam Langleyfcf25832014-12-18 17:42:32 -0800472#define CIPHER_ADD 1
473#define CIPHER_KILL 2
474#define CIPHER_DEL 3
475#define CIPHER_ORD 4
476#define CIPHER_SPECIAL 5
Adam Langley95c29f32014-06-20 12:00:00 -0700477
Adam Langleyfcf25832014-12-18 17:42:32 -0800478typedef struct cipher_order_st {
479 const SSL_CIPHER *cipher;
480 int active;
Adam Langleyfcf25832014-12-18 17:42:32 -0800481 int in_group;
482 struct cipher_order_st *next, *prev;
483} CIPHER_ORDER;
Adam Langley95c29f32014-06-20 12:00:00 -0700484
David Benjamin0344daf2015-04-08 02:08:01 -0400485typedef struct cipher_alias_st {
486 /* name is the name of the cipher alias. */
487 const char *name;
488
489 /* The following fields are bitmasks for the corresponding fields on
490 * |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the
491 * bit corresponding to the cipher's value is set to 1. If any bitmask is
492 * all zeroes, the alias matches nothing. Use |~0u| for the default value. */
493 uint32_t algorithm_mkey;
494 uint32_t algorithm_auth;
495 uint32_t algorithm_enc;
496 uint32_t algorithm_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -0500497
498 /* min_version, if non-zero, matches all ciphers which were added in that
499 * particular protocol version. */
500 uint16_t min_version;
David Benjamin0344daf2015-04-08 02:08:01 -0400501} CIPHER_ALIAS;
502
David Benjamina1c90a52015-05-30 17:03:14 -0400503static const CIPHER_ALIAS kCipherAliases[] = {
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700504 /* "ALL" doesn't include eNULL (must be specifically enabled) */
David Benjamind6e9eec2015-11-18 09:48:55 -0500505 {"ALL", ~0u, ~0u, ~SSL_eNULL, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700506
David Benjamina1c90a52015-05-30 17:03:14 -0400507 /* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
Adam Langley95c29f32014-06-20 12:00:00 -0700508
David Benjamina1c90a52015-05-30 17:03:14 -0400509 /* key exchange aliases
510 * (some of those using only a single bit here combine
511 * multiple key exchange algs according to the RFCs,
512 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
David Benjamind6e9eec2015-11-18 09:48:55 -0500513 {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700514
David Benjamind6e9eec2015-11-18 09:48:55 -0500515 {"kDHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
516 {"kEDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
517 {"DH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700518
David Benjamind6e9eec2015-11-18 09:48:55 -0500519 {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
520 {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
521 {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700522
David Benjamind6e9eec2015-11-18 09:48:55 -0500523 {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700524
David Benjamina1c90a52015-05-30 17:03:14 -0400525 /* server authentication aliases */
David Benjamind6e9eec2015-11-18 09:48:55 -0500526 {"aRSA", ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, 0},
527 {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
528 {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
529 {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700530
David Benjamina1c90a52015-05-30 17:03:14 -0400531 /* aliases combining key exchange and server authentication */
David Benjamind6e9eec2015-11-18 09:48:55 -0500532 {"DHE", SSL_kDHE, ~0u, ~0u, ~0u, 0},
533 {"EDH", SSL_kDHE, ~0u, ~0u, ~0u, 0},
534 {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
535 {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
536 {"RSA", SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, 0},
537 {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700538
David Benjamina1c90a52015-05-30 17:03:14 -0400539 /* symmetric encryption aliases */
David Benjamind6e9eec2015-11-18 09:48:55 -0500540 {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0},
541 {"RC4", ~0u, ~0u, SSL_RC4, ~0u, 0},
542 {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0},
543 {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0},
544 {"AES", ~0u, ~0u, SSL_AES, ~0u, 0},
545 {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0},
546 {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700547
David Benjamina1c90a52015-05-30 17:03:14 -0400548 /* MAC aliases */
David Benjamind6e9eec2015-11-18 09:48:55 -0500549 {"MD5", ~0u, ~0u, ~0u, SSL_MD5, 0},
550 {"SHA1", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0},
551 {"SHA", ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, 0},
552 {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, 0},
553 {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700554
David Benjamindcb6ef02015-11-06 15:35:54 -0500555 /* Legacy protocol minimum version aliases. "TLSv1" is intentionally the
556 * same as "SSLv3". */
David Benjamind6e9eec2015-11-18 09:48:55 -0500557 {"SSLv3", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION},
558 {"TLSv1", ~0u, ~0u, ~SSL_eNULL, ~0u, SSL3_VERSION},
559 {"TLSv1.2", ~0u, ~0u, ~SSL_eNULL, ~0u, TLS1_2_VERSION},
Adam Langley95c29f32014-06-20 12:00:00 -0700560
David Benjamind6e9eec2015-11-18 09:48:55 -0500561 /* Legacy strength classes. */
562 {"MEDIUM", ~0u, ~0u, SSL_RC4, ~0u, 0},
563 {"HIGH", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0},
564 {"FIPS", ~0u, ~0u, ~(SSL_eNULL|SSL_RC4), ~0u, 0},
Adam Langleyfcf25832014-12-18 17:42:32 -0800565};
Adam Langley95c29f32014-06-20 12:00:00 -0700566
David Benjamina1c90a52015-05-30 17:03:14 -0400567static const size_t kCipherAliasesLen =
568 sizeof(kCipherAliases) / sizeof(kCipherAliases[0]);
569
570static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) {
571 const SSL_CIPHER *a = in_a;
572 const SSL_CIPHER *b = in_b;
573
574 if (a->id > b->id) {
575 return 1;
576 } else if (a->id < b->id) {
577 return -1;
578 } else {
579 return 0;
580 }
581}
582
583static int ssl_cipher_ptr_id_cmp(const SSL_CIPHER **a, const SSL_CIPHER **b) {
584 return ssl_cipher_id_cmp(*a, *b);
585}
586
587const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
588 SSL_CIPHER c;
589
590 c.id = 0x03000000L | value;
591 return bsearch(&c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER),
592 ssl_cipher_id_cmp);
593}
David Benjamin0344daf2015-04-08 02:08:01 -0400594
David Benjaminea72bd02014-12-21 21:27:41 -0500595int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
596 size_t *out_mac_secret_len,
597 size_t *out_fixed_iv_len,
598 const SSL_CIPHER *cipher, uint16_t version) {
599 *out_aead = NULL;
600 *out_mac_secret_len = 0;
601 *out_fixed_iv_len = 0;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700602
David Benjaminea72bd02014-12-21 21:27:41 -0500603 switch (cipher->algorithm_enc) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800604 case SSL_AES128GCM:
David Benjaminea72bd02014-12-21 21:27:41 -0500605 *out_aead = EVP_aead_aes_128_gcm();
606 *out_fixed_iv_len = 4;
Adam Langleyfcf25832014-12-18 17:42:32 -0800607 return 1;
608
609 case SSL_AES256GCM:
David Benjaminea72bd02014-12-21 21:27:41 -0500610 *out_aead = EVP_aead_aes_256_gcm();
611 *out_fixed_iv_len = 4;
Adam Langleyfcf25832014-12-18 17:42:32 -0800612 return 1;
613
Adam Langleyd98dc132015-09-23 16:41:33 -0700614#if !defined(BORINGSSL_ANDROID_SYSTEM)
Brian Smith271777f2015-10-03 13:53:33 -1000615 case SSL_CHACHA20POLY1305_OLD:
Brian Smith3e23e4c2015-10-03 11:38:58 -1000616 *out_aead = EVP_aead_chacha20_poly1305_old();
David Benjaminea72bd02014-12-21 21:27:41 -0500617 *out_fixed_iv_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800618 return 1;
Adam Langleyd98dc132015-09-23 16:41:33 -0700619#endif
Adam Langleyfcf25832014-12-18 17:42:32 -0800620
621 case SSL_RC4:
David Benjaminea72bd02014-12-21 21:27:41 -0500622 switch (cipher->algorithm_mac) {
623 case SSL_MD5:
David Benjamin044abb02014-12-23 10:57:17 -0500624 if (version == SSL3_VERSION) {
625 *out_aead = EVP_aead_rc4_md5_ssl3();
626 } else {
627 *out_aead = EVP_aead_rc4_md5_tls();
628 }
David Benjaminea72bd02014-12-21 21:27:41 -0500629 *out_mac_secret_len = MD5_DIGEST_LENGTH;
630 return 1;
631 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500632 if (version == SSL3_VERSION) {
633 *out_aead = EVP_aead_rc4_sha1_ssl3();
634 } else {
635 *out_aead = EVP_aead_rc4_sha1_tls();
636 }
David Benjaminea72bd02014-12-21 21:27:41 -0500637 *out_mac_secret_len = SHA_DIGEST_LENGTH;
638 return 1;
639 default:
640 return 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800641 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800642
David Benjaminea72bd02014-12-21 21:27:41 -0500643 case SSL_AES128:
644 switch (cipher->algorithm_mac) {
645 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500646 if (version == SSL3_VERSION) {
647 *out_aead = EVP_aead_aes_128_cbc_sha1_ssl3();
648 *out_fixed_iv_len = 16;
649 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500650 *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv();
651 *out_fixed_iv_len = 16;
652 } else {
653 *out_aead = EVP_aead_aes_128_cbc_sha1_tls();
654 }
655 *out_mac_secret_len = SHA_DIGEST_LENGTH;
656 return 1;
657 case SSL_SHA256:
658 *out_aead = EVP_aead_aes_128_cbc_sha256_tls();
659 *out_mac_secret_len = SHA256_DIGEST_LENGTH;
660 return 1;
661 default:
662 return 0;
663 }
664
665 case SSL_AES256:
666 switch (cipher->algorithm_mac) {
667 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500668 if (version == SSL3_VERSION) {
669 *out_aead = EVP_aead_aes_256_cbc_sha1_ssl3();
670 *out_fixed_iv_len = 16;
671 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500672 *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv();
673 *out_fixed_iv_len = 16;
674 } else {
675 *out_aead = EVP_aead_aes_256_cbc_sha1_tls();
676 }
677 *out_mac_secret_len = SHA_DIGEST_LENGTH;
678 return 1;
679 case SSL_SHA256:
680 *out_aead = EVP_aead_aes_256_cbc_sha256_tls();
681 *out_mac_secret_len = SHA256_DIGEST_LENGTH;
682 return 1;
683 case SSL_SHA384:
684 *out_aead = EVP_aead_aes_256_cbc_sha384_tls();
685 *out_mac_secret_len = SHA384_DIGEST_LENGTH;
686 return 1;
687 default:
688 return 0;
689 }
690
691 case SSL_3DES:
692 switch (cipher->algorithm_mac) {
693 case SSL_SHA1:
David Benjamin044abb02014-12-23 10:57:17 -0500694 if (version == SSL3_VERSION) {
695 *out_aead = EVP_aead_des_ede3_cbc_sha1_ssl3();
696 *out_fixed_iv_len = 8;
697 } else if (version == TLS1_VERSION) {
David Benjaminea72bd02014-12-21 21:27:41 -0500698 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv();
699 *out_fixed_iv_len = 8;
700 } else {
701 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls();
702 }
703 *out_mac_secret_len = SHA_DIGEST_LENGTH;
704 return 1;
705 default:
706 return 0;
707 }
708
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700709 case SSL_eNULL:
710 switch (cipher->algorithm_mac) {
711 case SSL_SHA1:
712 if (version == SSL3_VERSION) {
713 *out_aead = EVP_aead_null_sha1_ssl3();
714 } else {
715 *out_aead = EVP_aead_null_sha1_tls();
716 }
717 *out_mac_secret_len = SHA_DIGEST_LENGTH;
718 return 1;
719 default:
720 return 0;
721 }
722
David Benjaminea72bd02014-12-21 21:27:41 -0500723 default:
724 return 0;
725 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800726}
Adam Langleyc9fb3752014-06-20 12:00:00 -0700727
David Benjaminb0883312015-08-06 09:54:13 -0400728const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf) {
729 switch (algorithm_prf) {
730 case SSL_HANDSHAKE_MAC_DEFAULT:
731 return EVP_sha1();
732 case SSL_HANDSHAKE_MAC_SHA256:
733 return EVP_sha256();
734 case SSL_HANDSHAKE_MAC_SHA384:
735 return EVP_sha384();
736 default:
737 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800738 }
Adam Langley95c29f32014-06-20 12:00:00 -0700739}
740
741#define ITEM_SEP(a) \
Adam Langleyfcf25832014-12-18 17:42:32 -0800742 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
Adam Langley95c29f32014-06-20 12:00:00 -0700743
David Benjamin0344daf2015-04-08 02:08:01 -0400744/* rule_equals returns one iff the NUL-terminated string |rule| is equal to the
745 * |buf_len| bytes at |buf|. */
746static int rule_equals(const char *rule, const char *buf, size_t buf_len) {
747 /* |strncmp| alone only checks that |buf| is a prefix of |rule|. */
748 return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0';
749}
750
Adam Langley95c29f32014-06-20 12:00:00 -0700751static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800752 CIPHER_ORDER **tail) {
753 if (curr == *tail) {
754 return;
755 }
756 if (curr == *head) {
757 *head = curr->next;
758 }
759 if (curr->prev != NULL) {
760 curr->prev->next = curr->next;
761 }
762 if (curr->next != NULL) {
763 curr->next->prev = curr->prev;
764 }
765 (*tail)->next = curr;
766 curr->prev = *tail;
767 curr->next = NULL;
768 *tail = curr;
769}
Adam Langley95c29f32014-06-20 12:00:00 -0700770
771static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800772 CIPHER_ORDER **tail) {
773 if (curr == *head) {
774 return;
775 }
776 if (curr == *tail) {
777 *tail = curr->prev;
778 }
779 if (curr->next != NULL) {
780 curr->next->prev = curr->prev;
781 }
782 if (curr->prev != NULL) {
783 curr->prev->next = curr->next;
784 }
785 (*head)->prev = curr;
786 curr->next = *head;
787 curr->prev = NULL;
788 *head = curr;
789}
Adam Langley95c29f32014-06-20 12:00:00 -0700790
David Benjamin82c9e902014-12-12 15:55:27 -0500791static void ssl_cipher_collect_ciphers(const SSL_PROTOCOL_METHOD *ssl_method,
Adam Langleyfcf25832014-12-18 17:42:32 -0800792 CIPHER_ORDER *co_list,
793 CIPHER_ORDER **head_p,
794 CIPHER_ORDER **tail_p) {
David Benjamina1c90a52015-05-30 17:03:14 -0400795 /* The set of ciphers is static, but some subset may be unsupported by
796 * |ssl_method|, so the list may be smaller. */
797 size_t co_list_num = 0;
798 size_t i;
799 for (i = 0; i < kCiphersLen; i++) {
800 const SSL_CIPHER *cipher = &kCiphers[i];
801 if (ssl_method->supports_cipher(cipher)) {
802 co_list[co_list_num].cipher = cipher;
Adam Langleyfcf25832014-12-18 17:42:32 -0800803 co_list[co_list_num].next = NULL;
804 co_list[co_list_num].prev = NULL;
805 co_list[co_list_num].active = 0;
806 co_list[co_list_num].in_group = 0;
807 co_list_num++;
808 }
809 }
Adam Langley95c29f32014-06-20 12:00:00 -0700810
Adam Langleyfcf25832014-12-18 17:42:32 -0800811 /* Prepare linked list from list entries. */
812 if (co_list_num > 0) {
813 co_list[0].prev = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700814
Adam Langleyfcf25832014-12-18 17:42:32 -0800815 if (co_list_num > 1) {
816 co_list[0].next = &co_list[1];
Adam Langley95c29f32014-06-20 12:00:00 -0700817
Adam Langleyfcf25832014-12-18 17:42:32 -0800818 for (i = 1; i < co_list_num - 1; i++) {
819 co_list[i].prev = &co_list[i - 1];
820 co_list[i].next = &co_list[i + 1];
821 }
Adam Langley95c29f32014-06-20 12:00:00 -0700822
Adam Langleyfcf25832014-12-18 17:42:32 -0800823 co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
824 }
825
826 co_list[co_list_num - 1].next = NULL;
827
828 *head_p = &co_list[0];
829 *tail_p = &co_list[co_list_num - 1];
830 }
831}
Adam Langley95c29f32014-06-20 12:00:00 -0700832
David Benjamin0344daf2015-04-08 02:08:01 -0400833/* ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
834 * parameters in the linked list from |*head_p| to |*tail_p|. It writes the new
835 * head and tail of the list to |*head_p| and |*tail_p|, respectively.
836 *
837 * - If |cipher_id| is non-zero, only that cipher is selected.
838 * - Otherwise, if |strength_bits| is non-negative, it selects ciphers
839 * of that strength.
David Benjamind6e9eec2015-11-18 09:48:55 -0500840 * - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and
David Benjamindcb6ef02015-11-06 15:35:54 -0500841 * |min_version|. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800842static void ssl_cipher_apply_rule(
David Benjamin107db582015-04-08 00:41:59 -0400843 uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
David Benjamind6e9eec2015-11-18 09:48:55 -0500844 uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule,
845 int strength_bits, int in_group, CIPHER_ORDER **head_p,
846 CIPHER_ORDER **tail_p) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800847 CIPHER_ORDER *head, *tail, *curr, *next, *last;
848 const SSL_CIPHER *cp;
849 int reverse = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700850
David Benjamindcb6ef02015-11-06 15:35:54 -0500851 if (cipher_id == 0 && strength_bits == -1 && min_version == 0 &&
David Benjamind6e9eec2015-11-18 09:48:55 -0500852 (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) {
David Benjamin0344daf2015-04-08 02:08:01 -0400853 /* The rule matches nothing, so bail early. */
854 return;
855 }
856
Adam Langleyfcf25832014-12-18 17:42:32 -0800857 if (rule == CIPHER_DEL) {
858 /* needed to maintain sorting between currently deleted ciphers */
859 reverse = 1;
860 }
Adam Langley95c29f32014-06-20 12:00:00 -0700861
Adam Langleyfcf25832014-12-18 17:42:32 -0800862 head = *head_p;
863 tail = *tail_p;
Adam Langley95c29f32014-06-20 12:00:00 -0700864
Adam Langleyfcf25832014-12-18 17:42:32 -0800865 if (reverse) {
866 next = tail;
867 last = head;
868 } else {
869 next = head;
870 last = tail;
871 }
Adam Langley95c29f32014-06-20 12:00:00 -0700872
Adam Langleyfcf25832014-12-18 17:42:32 -0800873 curr = NULL;
874 for (;;) {
875 if (curr == last) {
876 break;
877 }
Adam Langley95c29f32014-06-20 12:00:00 -0700878
Adam Langleyfcf25832014-12-18 17:42:32 -0800879 curr = next;
880 if (curr == NULL) {
881 break;
882 }
Adam Langleye3142a72014-07-24 17:56:48 -0700883
Adam Langleyfcf25832014-12-18 17:42:32 -0800884 next = reverse ? curr->prev : curr->next;
885 cp = curr->cipher;
Adam Langleye3142a72014-07-24 17:56:48 -0700886
David Benjamin0344daf2015-04-08 02:08:01 -0400887 /* Selection criteria is either a specific cipher, the value of
888 * |strength_bits|, or the algorithms used. */
889 if (cipher_id != 0) {
890 if (cipher_id != cp->id) {
891 continue;
892 }
893 } else if (strength_bits >= 0) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800894 if (strength_bits != cp->strength_bits) {
895 continue;
896 }
David Benjamin0344daf2015-04-08 02:08:01 -0400897 } else if (!(alg_mkey & cp->algorithm_mkey) ||
898 !(alg_auth & cp->algorithm_auth) ||
899 !(alg_enc & cp->algorithm_enc) ||
900 !(alg_mac & cp->algorithm_mac) ||
David Benjamindcb6ef02015-11-06 15:35:54 -0500901 (min_version != 0 &&
902 SSL_CIPHER_get_min_version(cp) != min_version)) {
David Benjamin0344daf2015-04-08 02:08:01 -0400903 continue;
Adam Langleyfcf25832014-12-18 17:42:32 -0800904 }
Adam Langleye3142a72014-07-24 17:56:48 -0700905
Adam Langleyfcf25832014-12-18 17:42:32 -0800906 /* add the cipher if it has not been added yet. */
907 if (rule == CIPHER_ADD) {
908 /* reverse == 0 */
909 if (!curr->active) {
910 ll_append_tail(&head, curr, &tail);
911 curr->active = 1;
912 curr->in_group = in_group;
913 }
914 }
Adam Langley95c29f32014-06-20 12:00:00 -0700915
Adam Langleyfcf25832014-12-18 17:42:32 -0800916 /* Move the added cipher to this location */
917 else if (rule == CIPHER_ORD) {
918 /* reverse == 0 */
919 if (curr->active) {
920 ll_append_tail(&head, curr, &tail);
921 curr->in_group = 0;
922 }
923 } else if (rule == CIPHER_DEL) {
924 /* reverse == 1 */
925 if (curr->active) {
926 /* most recently deleted ciphersuites get best positions
927 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
928 * works in reverse to maintain the order) */
929 ll_append_head(&head, curr, &tail);
930 curr->active = 0;
931 curr->in_group = 0;
932 }
933 } else if (rule == CIPHER_KILL) {
934 /* reverse == 0 */
935 if (head == curr) {
936 head = curr->next;
937 } else {
938 curr->prev->next = curr->next;
939 }
Adam Langley95c29f32014-06-20 12:00:00 -0700940
Adam Langleyfcf25832014-12-18 17:42:32 -0800941 if (tail == curr) {
942 tail = curr->prev;
943 }
944 curr->active = 0;
945 if (curr->next != NULL) {
946 curr->next->prev = curr->prev;
947 }
948 if (curr->prev != NULL) {
949 curr->prev->next = curr->next;
950 }
951 curr->next = NULL;
952 curr->prev = NULL;
953 }
954 }
Adam Langley95c29f32014-06-20 12:00:00 -0700955
Adam Langleyfcf25832014-12-18 17:42:32 -0800956 *head_p = head;
957 *tail_p = tail;
958}
Adam Langley95c29f32014-06-20 12:00:00 -0700959
960static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
Adam Langleyfcf25832014-12-18 17:42:32 -0800961 CIPHER_ORDER **tail_p) {
962 int max_strength_bits, i, *number_uses;
963 CIPHER_ORDER *curr;
Adam Langley95c29f32014-06-20 12:00:00 -0700964
Adam Langleyfcf25832014-12-18 17:42:32 -0800965 /* This routine sorts the ciphers with descending strength. The sorting must
966 * keep the pre-sorted sequence, so we apply the normal sorting routine as
967 * '+' movement to the end of the list. */
968 max_strength_bits = 0;
969 curr = *head_p;
970 while (curr != NULL) {
971 if (curr->active && curr->cipher->strength_bits > max_strength_bits) {
972 max_strength_bits = curr->cipher->strength_bits;
973 }
974 curr = curr->next;
975 }
Adam Langley95c29f32014-06-20 12:00:00 -0700976
Adam Langleyfcf25832014-12-18 17:42:32 -0800977 number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
978 if (!number_uses) {
David Benjamin3570d732015-06-29 00:28:17 -0400979 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800980 return 0;
981 }
982 memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
Adam Langley95c29f32014-06-20 12:00:00 -0700983
Adam Langleyfcf25832014-12-18 17:42:32 -0800984 /* Now find the strength_bits values actually used. */
985 curr = *head_p;
986 while (curr != NULL) {
987 if (curr->active) {
988 number_uses[curr->cipher->strength_bits]++;
989 }
990 curr = curr->next;
991 }
Adam Langley95c29f32014-06-20 12:00:00 -0700992
Adam Langleyfcf25832014-12-18 17:42:32 -0800993 /* Go through the list of used strength_bits values in descending order. */
994 for (i = max_strength_bits; i >= 0; i--) {
995 if (number_uses[i] > 0) {
David Benjamind6e9eec2015-11-18 09:48:55 -0500996 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, tail_p);
Adam Langleyfcf25832014-12-18 17:42:32 -0800997 }
998 }
999
1000 OPENSSL_free(number_uses);
1001 return 1;
1002}
Adam Langley95c29f32014-06-20 12:00:00 -07001003
David Benjamin0344daf2015-04-08 02:08:01 -04001004static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
1005 const char *rule_str,
Adam Langleyfcf25832014-12-18 17:42:32 -08001006 CIPHER_ORDER **head_p,
David Benjamin0344daf2015-04-08 02:08:01 -04001007 CIPHER_ORDER **tail_p) {
David Benjamind6e9eec2015-11-18 09:48:55 -05001008 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -05001009 uint16_t min_version;
Adam Langleyfcf25832014-12-18 17:42:32 -08001010 const char *l, *buf;
David Benjamindcb6ef02015-11-06 15:35:54 -05001011 int multi, skip_rule, rule, retval, ok, in_group = 0, has_group = 0;
David Benjamin0344daf2015-04-08 02:08:01 -04001012 size_t j, buf_len;
1013 uint32_t cipher_id;
Adam Langleyfcf25832014-12-18 17:42:32 -08001014 char ch;
Adam Langley95c29f32014-06-20 12:00:00 -07001015
Adam Langleyfcf25832014-12-18 17:42:32 -08001016 retval = 1;
1017 l = rule_str;
1018 for (;;) {
1019 ch = *l;
Adam Langley95c29f32014-06-20 12:00:00 -07001020
Adam Langleyfcf25832014-12-18 17:42:32 -08001021 if (ch == '\0') {
1022 break; /* done */
1023 }
Adam Langley95c29f32014-06-20 12:00:00 -07001024
Adam Langleyfcf25832014-12-18 17:42:32 -08001025 if (in_group) {
1026 if (ch == ']') {
Adam Langleyfcf25832014-12-18 17:42:32 -08001027 if (*tail_p) {
1028 (*tail_p)->in_group = 0;
1029 }
1030 in_group = 0;
1031 l++;
1032 continue;
1033 }
David Benjamin37d92462014-09-20 17:54:24 -04001034
Adam Langleyfcf25832014-12-18 17:42:32 -08001035 if (ch == '|') {
1036 rule = CIPHER_ADD;
1037 l++;
1038 continue;
1039 } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') &&
1040 !(ch >= '0' && ch <= '9')) {
David Benjamin3570d732015-06-29 00:28:17 -04001041 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
David Benjamin0344daf2015-04-08 02:08:01 -04001042 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001043 break;
1044 } else {
1045 rule = CIPHER_ADD;
1046 }
1047 } else if (ch == '-') {
1048 rule = CIPHER_DEL;
1049 l++;
1050 } else if (ch == '+') {
1051 rule = CIPHER_ORD;
1052 l++;
1053 } else if (ch == '!') {
1054 rule = CIPHER_KILL;
1055 l++;
1056 } else if (ch == '@') {
1057 rule = CIPHER_SPECIAL;
1058 l++;
1059 } else if (ch == '[') {
1060 if (in_group) {
David Benjamin3570d732015-06-29 00:28:17 -04001061 OPENSSL_PUT_ERROR(SSL, SSL_R_NESTED_GROUP);
David Benjamin0344daf2015-04-08 02:08:01 -04001062 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001063 break;
1064 }
1065 in_group = 1;
1066 has_group = 1;
1067 l++;
1068 continue;
1069 } else {
1070 rule = CIPHER_ADD;
1071 }
Adam Langley95c29f32014-06-20 12:00:00 -07001072
Adam Langleyfcf25832014-12-18 17:42:32 -08001073 /* If preference groups are enabled, the only legal operator is +.
1074 * Otherwise the in_group bits will get mixed up. */
1075 if (has_group && rule != CIPHER_ADD) {
David Benjamin3570d732015-06-29 00:28:17 -04001076 OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
David Benjamin0344daf2015-04-08 02:08:01 -04001077 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001078 break;
1079 }
Adam Langley95c29f32014-06-20 12:00:00 -07001080
Adam Langleyfcf25832014-12-18 17:42:32 -08001081 if (ITEM_SEP(ch)) {
1082 l++;
1083 continue;
1084 }
Adam Langley95c29f32014-06-20 12:00:00 -07001085
David Benjamin0344daf2015-04-08 02:08:01 -04001086 multi = 0;
1087 cipher_id = 0;
1088 alg_mkey = ~0u;
1089 alg_auth = ~0u;
1090 alg_enc = ~0u;
1091 alg_mac = ~0u;
David Benjamindcb6ef02015-11-06 15:35:54 -05001092 min_version = 0;
1093 skip_rule = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001094
Adam Langleyfcf25832014-12-18 17:42:32 -08001095 for (;;) {
1096 ch = *l;
1097 buf = l;
David Benjamin0344daf2015-04-08 02:08:01 -04001098 buf_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001099 while (((ch >= 'A') && (ch <= 'Z')) || ((ch >= '0') && (ch <= '9')) ||
1100 ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) {
1101 ch = *(++l);
David Benjamin0344daf2015-04-08 02:08:01 -04001102 buf_len++;
Adam Langleyfcf25832014-12-18 17:42:32 -08001103 }
Adam Langley95c29f32014-06-20 12:00:00 -07001104
David Benjamin0344daf2015-04-08 02:08:01 -04001105 if (buf_len == 0) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001106 /* We hit something we cannot deal with, it is no command or separator
1107 * nor alphanumeric, so we call this an error. */
David Benjamin3570d732015-06-29 00:28:17 -04001108 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjamin0344daf2015-04-08 02:08:01 -04001109 retval = in_group = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -08001110 l++;
1111 break;
1112 }
Adam Langley95c29f32014-06-20 12:00:00 -07001113
Adam Langleyfcf25832014-12-18 17:42:32 -08001114 if (rule == CIPHER_SPECIAL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001115 break;
1116 }
David Benjamin0344daf2015-04-08 02:08:01 -04001117
1118 /* Look for a matching exact cipher. These aren't allowed in multipart
1119 * rules. */
1120 if (!multi && ch != '+') {
David Benjamina1c90a52015-05-30 17:03:14 -04001121 for (j = 0; j < kCiphersLen; j++) {
1122 const SSL_CIPHER *cipher = &kCiphers[j];
1123 if (rule_equals(cipher->name, buf, buf_len)) {
David Benjamin0344daf2015-04-08 02:08:01 -04001124 cipher_id = cipher->id;
1125 break;
1126 }
1127 }
1128 }
1129 if (cipher_id == 0) {
1130 /* If not an exact cipher, look for a matching cipher alias. */
David Benjamina1c90a52015-05-30 17:03:14 -04001131 for (j = 0; j < kCipherAliasesLen; j++) {
David Benjamin0344daf2015-04-08 02:08:01 -04001132 if (rule_equals(kCipherAliases[j].name, buf, buf_len)) {
1133 alg_mkey &= kCipherAliases[j].algorithm_mkey;
1134 alg_auth &= kCipherAliases[j].algorithm_auth;
1135 alg_enc &= kCipherAliases[j].algorithm_enc;
1136 alg_mac &= kCipherAliases[j].algorithm_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -05001137
1138 if (min_version != 0 &&
1139 min_version != kCipherAliases[j].min_version) {
1140 skip_rule = 1;
1141 } else {
1142 min_version = kCipherAliases[j].min_version;
1143 }
David Benjamin0344daf2015-04-08 02:08:01 -04001144 break;
1145 }
1146 }
David Benjamina1c90a52015-05-30 17:03:14 -04001147 if (j == kCipherAliasesLen) {
David Benjamindcb6ef02015-11-06 15:35:54 -05001148 skip_rule = 1;
David Benjamin0344daf2015-04-08 02:08:01 -04001149 }
1150 }
1151
1152 /* Check for a multipart rule. */
1153 if (ch != '+') {
1154 break;
1155 }
1156 l++;
1157 multi = 1;
Adam Langleyfcf25832014-12-18 17:42:32 -08001158 }
Adam Langley95c29f32014-06-20 12:00:00 -07001159
Adam Langleyfcf25832014-12-18 17:42:32 -08001160 /* Ok, we have the rule, now apply it. */
1161 if (rule == CIPHER_SPECIAL) {
1162 /* special command */
1163 ok = 0;
David Benjamin0344daf2015-04-08 02:08:01 -04001164 if (buf_len == 8 && !strncmp(buf, "STRENGTH", 8)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001165 ok = ssl_cipher_strength_sort(head_p, tail_p);
1166 } else {
David Benjamin3570d732015-06-29 00:28:17 -04001167 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
Adam Langleyfcf25832014-12-18 17:42:32 -08001168 }
Adam Langley95c29f32014-06-20 12:00:00 -07001169
Adam Langleyfcf25832014-12-18 17:42:32 -08001170 if (ok == 0) {
1171 retval = 0;
1172 }
Adam Langley95c29f32014-06-20 12:00:00 -07001173
Adam Langleyfcf25832014-12-18 17:42:32 -08001174 /* We do not support any "multi" options together with "@", so throw away
1175 * the rest of the command, if any left, until end or ':' is found. */
1176 while (*l != '\0' && !ITEM_SEP(*l)) {
1177 l++;
1178 }
David Benjamindcb6ef02015-11-06 15:35:54 -05001179 } else if (!skip_rule) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001180 ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac,
David Benjamind6e9eec2015-11-18 09:48:55 -05001181 min_version, rule, -1, in_group, head_p, tail_p);
Adam Langleyfcf25832014-12-18 17:42:32 -08001182 }
1183 }
Adam Langley95c29f32014-06-20 12:00:00 -07001184
Adam Langleyfcf25832014-12-18 17:42:32 -08001185 if (in_group) {
David Benjamin3570d732015-06-29 00:28:17 -04001186 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
Adam Langleyfcf25832014-12-18 17:42:32 -08001187 retval = 0;
1188 }
Adam Langley95c29f32014-06-20 12:00:00 -07001189
Adam Langleyfcf25832014-12-18 17:42:32 -08001190 return retval;
1191}
Adam Langley95c29f32014-06-20 12:00:00 -07001192
Adam Langleyfcf25832014-12-18 17:42:32 -08001193STACK_OF(SSL_CIPHER) *
1194ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
David Benjamin71f07942015-04-08 02:36:59 -04001195 struct ssl_cipher_preference_list_st **out_cipher_list,
1196 STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
1197 const char *rule_str) {
David Benjamin0344daf2015-04-08 02:08:01 -04001198 int ok;
Adam Langleyfcf25832014-12-18 17:42:32 -08001199 STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
1200 const char *rule_p;
1201 CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
Adam Langleyfcf25832014-12-18 17:42:32 -08001202 uint8_t *in_group_flags = NULL;
1203 unsigned int num_in_group_flags = 0;
1204 struct ssl_cipher_preference_list_st *pref_list = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001205
Adam Langleyfcf25832014-12-18 17:42:32 -08001206 /* Return with error if nothing to do. */
David Benjamin71f07942015-04-08 02:36:59 -04001207 if (rule_str == NULL || out_cipher_list == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001208 return NULL;
1209 }
David Benjamin5213df42014-08-20 14:19:54 -04001210
Adam Langleyfcf25832014-12-18 17:42:32 -08001211 /* Now we have to collect the available ciphers from the compiled in ciphers.
1212 * We cannot get more than the number compiled in, so it is used for
1213 * allocation. */
David Benjamina1c90a52015-05-30 17:03:14 -04001214 co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
Adam Langleyfcf25832014-12-18 17:42:32 -08001215 if (co_list == NULL) {
David Benjamin3570d732015-06-29 00:28:17 -04001216 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
Adam Langleyfcf25832014-12-18 17:42:32 -08001217 return NULL;
1218 }
Adam Langley95c29f32014-06-20 12:00:00 -07001219
David Benjamina1c90a52015-05-30 17:03:14 -04001220 ssl_cipher_collect_ciphers(ssl_method, co_list, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001221
Adam Langleyfcf25832014-12-18 17:42:32 -08001222 /* Now arrange all ciphers by preference:
1223 * TODO(davidben): Compute this order once and copy it. */
Adam Langley95c29f32014-06-20 12:00:00 -07001224
Adam Langleyfcf25832014-12-18 17:42:32 -08001225 /* Everything else being equal, prefer ECDHE_ECDSA then ECDHE_RSA over other
1226 * key exchange mechanisms */
David Benjamind6e9eec2015-11-18 09:48:55 -05001227 ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1,
Adam Langleyfcf25832014-12-18 17:42:32 -08001228 0, &head, &tail);
David Benjamind6e9eec2015-11-18 09:48:55 -05001229 ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0,
1230 &head, &tail);
1231 ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0,
1232 &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001233
Adam Langleyfcf25832014-12-18 17:42:32 -08001234 /* Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
1235 * CHACHA20 unless there is hardware support for fast and constant-time
1236 * AES_GCM. */
1237 if (EVP_has_aes_hardware()) {
David Benjamind6e9eec2015-11-18 09:48:55 -05001238 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
1239 &head, &tail);
1240 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
1241 &head, &tail);
1242 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
David Benjamin0344daf2015-04-08 02:08:01 -04001243 CIPHER_ADD, -1, 0, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001244 } else {
David Benjamind6e9eec2015-11-18 09:48:55 -05001245 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305_OLD, ~0u, 0,
David Benjamin0344daf2015-04-08 02:08:01 -04001246 CIPHER_ADD, -1, 0, &head, &tail);
David Benjamind6e9eec2015-11-18 09:48:55 -05001247 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
1248 &head, &tail);
1249 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
1250 &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001251 }
Adam Langley95c29f32014-06-20 12:00:00 -07001252
Adam Langleyfcf25832014-12-18 17:42:32 -08001253 /* Then the legacy non-AEAD ciphers: AES_256_CBC, AES-128_CBC, RC4_128_SHA,
1254 * RC4_128_MD5, 3DES_EDE_CBC_SHA. */
David Benjamind6e9eec2015-11-18 09:48:55 -05001255 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
Adam Langleyfcf25832014-12-18 17:42:32 -08001256 &head, &tail);
David Benjamind6e9eec2015-11-18 09:48:55 -05001257 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, 0,
1258 &head, &tail);
1259 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, ~SSL_MD5, 0, CIPHER_ADD, -1, 0,
1260 &head, &tail);
1261 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_RC4, SSL_MD5, 0, CIPHER_ADD, -1, 0,
1262 &head, &tail);
1263 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head,
1264 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001265
Adam Langleyfcf25832014-12-18 17:42:32 -08001266 /* Temporarily enable everything else for sorting */
David Benjamind6e9eec2015-11-18 09:48:55 -05001267 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head,
1268 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001269
Adam Langleyfcf25832014-12-18 17:42:32 -08001270 /* Move ciphers without forward secrecy to the end. */
David Benjamind6e9eec2015-11-18 09:48:55 -05001271 ssl_cipher_apply_rule(0, ~(SSL_kDHE | SSL_kECDHE), ~0u, ~0u, ~0u, 0,
David Benjamin0344daf2015-04-08 02:08:01 -04001272 CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001273
Adam Langleyfcf25832014-12-18 17:42:32 -08001274 /* Now disable everything (maintaining the ordering!) */
David Benjamind6e9eec2015-11-18 09:48:55 -05001275 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head,
1276 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001277
Adam Langleyfcf25832014-12-18 17:42:32 -08001278 /* If the rule_string begins with DEFAULT, apply the default rule before
1279 * using the (possibly available) additional rules. */
1280 ok = 1;
1281 rule_p = rule_str;
1282 if (strncmp(rule_str, "DEFAULT", 7) == 0) {
David Benjamin0344daf2015-04-08 02:08:01 -04001283 ok = ssl_cipher_process_rulestr(ssl_method, SSL_DEFAULT_CIPHER_LIST, &head,
1284 &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001285 rule_p += 7;
1286 if (*rule_p == ':') {
1287 rule_p++;
1288 }
1289 }
Adam Langley858a88d2014-06-20 12:00:00 -07001290
Adam Langleyfcf25832014-12-18 17:42:32 -08001291 if (ok && strlen(rule_p) > 0) {
David Benjamin0344daf2015-04-08 02:08:01 -04001292 ok = ssl_cipher_process_rulestr(ssl_method, rule_p, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001293 }
Adam Langley95c29f32014-06-20 12:00:00 -07001294
Adam Langleyfcf25832014-12-18 17:42:32 -08001295 if (!ok) {
1296 goto err;
1297 }
1298
1299 /* Allocate new "cipherstack" for the result, return with error
1300 * if we cannot get one. */
1301 cipherstack = sk_SSL_CIPHER_new_null();
1302 if (cipherstack == NULL) {
1303 goto err;
1304 }
1305
David Benjamina1c90a52015-05-30 17:03:14 -04001306 in_group_flags = OPENSSL_malloc(kCiphersLen);
Adam Langleyfcf25832014-12-18 17:42:32 -08001307 if (!in_group_flags) {
1308 goto err;
1309 }
1310
1311 /* The cipher selection for the list is done. The ciphers are added
1312 * to the resulting precedence to the STACK_OF(SSL_CIPHER). */
1313 for (curr = head; curr != NULL; curr = curr->next) {
1314 if (curr->active) {
David Benjamin2adb7ec2015-01-11 19:59:06 -05001315 if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
1316 goto err;
1317 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001318 in_group_flags[num_in_group_flags++] = curr->in_group;
1319 }
1320 }
1321 OPENSSL_free(co_list); /* Not needed any longer */
1322 co_list = NULL;
1323
1324 tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1325 if (tmp_cipher_list == NULL) {
1326 goto err;
1327 }
1328 pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
1329 if (!pref_list) {
1330 goto err;
1331 }
1332 pref_list->ciphers = cipherstack;
1333 pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags);
1334 if (!pref_list->in_group_flags) {
1335 goto err;
1336 }
1337 memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags);
1338 OPENSSL_free(in_group_flags);
1339 in_group_flags = NULL;
David Benjamin71f07942015-04-08 02:36:59 -04001340 if (*out_cipher_list != NULL) {
1341 ssl_cipher_preference_list_free(*out_cipher_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001342 }
David Benjamin71f07942015-04-08 02:36:59 -04001343 *out_cipher_list = pref_list;
Adam Langleyfcf25832014-12-18 17:42:32 -08001344 pref_list = NULL;
1345
David Benjamin71f07942015-04-08 02:36:59 -04001346 if (out_cipher_list_by_id != NULL) {
David Benjamin2755a3e2015-04-22 16:17:58 -04001347 sk_SSL_CIPHER_free(*out_cipher_list_by_id);
David Benjamin71f07942015-04-08 02:36:59 -04001348 *out_cipher_list_by_id = tmp_cipher_list;
Adam Langleyfcf25832014-12-18 17:42:32 -08001349 tmp_cipher_list = NULL;
David Benjamin71f07942015-04-08 02:36:59 -04001350 (void) sk_SSL_CIPHER_set_cmp_func(*out_cipher_list_by_id,
1351 ssl_cipher_ptr_id_cmp);
Adam Langleyfcf25832014-12-18 17:42:32 -08001352
David Benjamin71f07942015-04-08 02:36:59 -04001353 sk_SSL_CIPHER_sort(*out_cipher_list_by_id);
Adam Langleyfcf25832014-12-18 17:42:32 -08001354 } else {
1355 sk_SSL_CIPHER_free(tmp_cipher_list);
1356 tmp_cipher_list = NULL;
1357 }
1358
1359 return cipherstack;
Adam Langley858a88d2014-06-20 12:00:00 -07001360
1361err:
David Benjamin2755a3e2015-04-22 16:17:58 -04001362 OPENSSL_free(co_list);
1363 OPENSSL_free(in_group_flags);
1364 sk_SSL_CIPHER_free(cipherstack);
1365 sk_SSL_CIPHER_free(tmp_cipher_list);
1366 if (pref_list) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001367 OPENSSL_free(pref_list->in_group_flags);
1368 }
David Benjamin2755a3e2015-04-22 16:17:58 -04001369 OPENSSL_free(pref_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001370 return NULL;
1371}
Adam Langley95c29f32014-06-20 12:00:00 -07001372
David Benjamin71f07942015-04-08 02:36:59 -04001373uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
1374
David Benjamina1c90a52015-05-30 17:03:14 -04001375uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
1376 uint32_t id = cipher->id;
1377 /* All ciphers are SSLv3. */
1378 assert((id & 0xff000000) == 0x03000000);
1379 return id & 0xffff;
1380}
1381
David Benjamin71f07942015-04-08 02:36:59 -04001382int SSL_CIPHER_is_AES(const SSL_CIPHER *cipher) {
1383 return (cipher->algorithm_enc & SSL_AES) != 0;
1384}
1385
1386int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher) {
1387 return (cipher->algorithm_mac & SSL_MD5) != 0;
1388}
1389
David Benjaminef793f42015-11-05 18:16:27 -05001390int SSL_CIPHER_has_SHA1_HMAC(const SSL_CIPHER *cipher) {
1391 return (cipher->algorithm_mac & SSL_SHA1) != 0;
1392}
1393
David Benjamin71f07942015-04-08 02:36:59 -04001394int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
David Benjaminc0125ef2015-09-09 09:11:07 -04001395 return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
David Benjamin71f07942015-04-08 02:36:59 -04001396}
1397
David Benjaminef793f42015-11-05 18:16:27 -05001398int SSL_CIPHER_is_AES128GCM(const SSL_CIPHER *cipher) {
1399 return (cipher->algorithm_enc & SSL_AES128GCM) != 0;
1400}
1401
Adam Langleyb00061c2015-11-16 17:44:52 -08001402int SSL_CIPHER_is_AES128CBC(const SSL_CIPHER *cipher) {
1403 return (cipher->algorithm_enc & SSL_AES128) != 0;
1404}
1405
1406int SSL_CIPHER_is_AES256CBC(const SSL_CIPHER *cipher) {
1407 return (cipher->algorithm_enc & SSL_AES256) != 0;
1408}
1409
David Benjamin51a01a52015-10-29 13:19:56 -04001410int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
Brian Smith271777f2015-10-03 13:53:33 -10001411 return (cipher->algorithm_enc & SSL_CHACHA20POLY1305_OLD) != 0;
David Benjamin71f07942015-04-08 02:36:59 -04001412}
1413
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001414int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
1415 return (cipher->algorithm_enc & SSL_eNULL) != 0;
1416}
1417
Adam Langleyd7fe75c2015-09-18 15:40:48 -07001418int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher) {
1419 return (cipher->algorithm_enc & SSL_RC4) != 0;
1420}
1421
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001422int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) {
1423 /* Neither stream cipher nor AEAD. */
1424 return (cipher->algorithm_enc & (SSL_RC4 | SSL_eNULL)) == 0 &&
1425 cipher->algorithm_mac != SSL_AEAD;
1426}
1427
David Benjaminef793f42015-11-05 18:16:27 -05001428int SSL_CIPHER_is_ECDSA(const SSL_CIPHER *cipher) {
1429 return (cipher->algorithm_auth & SSL_aECDSA) != 0;
1430}
1431
1432uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) {
David Benjamindcb6ef02015-11-06 15:35:54 -05001433 if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) {
1434 /* Cipher suites before TLS 1.2 use the default PRF, while all those added
1435 * afterwards specify a particular hash. */
David Benjaminef793f42015-11-05 18:16:27 -05001436 return TLS1_2_VERSION;
1437 }
1438 return SSL3_VERSION;
1439}
1440
David Benjamin71f07942015-04-08 02:36:59 -04001441/* return the actual cipher being used */
1442const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) {
1443 if (cipher != NULL) {
1444 return cipher->name;
1445 }
1446
1447 return "(NONE)";
1448}
1449
1450const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
1451 if (cipher == NULL) {
1452 return "";
1453 }
1454
1455 switch (cipher->algorithm_mkey) {
1456 case SSL_kRSA:
1457 return "RSA";
1458
1459 case SSL_kDHE:
1460 switch (cipher->algorithm_auth) {
1461 case SSL_aRSA:
1462 return "DHE_RSA";
1463 default:
1464 assert(0);
1465 return "UNKNOWN";
1466 }
1467
1468 case SSL_kECDHE:
1469 switch (cipher->algorithm_auth) {
1470 case SSL_aECDSA:
1471 return "ECDHE_ECDSA";
1472 case SSL_aRSA:
1473 return "ECDHE_RSA";
1474 case SSL_aPSK:
1475 return "ECDHE_PSK";
1476 default:
1477 assert(0);
1478 return "UNKNOWN";
1479 }
1480
1481 case SSL_kPSK:
1482 assert(cipher->algorithm_auth == SSL_aPSK);
1483 return "PSK";
1484
1485 default:
1486 assert(0);
1487 return "UNKNOWN";
1488 }
1489}
1490
1491static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
1492 switch (cipher->algorithm_enc) {
1493 case SSL_3DES:
1494 return "3DES_EDE_CBC";
1495 case SSL_RC4:
1496 return "RC4";
1497 case SSL_AES128:
1498 return "AES_128_CBC";
1499 case SSL_AES256:
1500 return "AES_256_CBC";
1501 case SSL_AES128GCM:
1502 return "AES_128_GCM";
1503 case SSL_AES256GCM:
1504 return "AES_256_GCM";
Brian Smith271777f2015-10-03 13:53:33 -10001505 case SSL_CHACHA20POLY1305_OLD:
David Benjamin71f07942015-04-08 02:36:59 -04001506 return "CHACHA20_POLY1305";
1507 break;
1508 default:
1509 assert(0);
1510 return "UNKNOWN";
1511 }
1512}
1513
1514static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
David Benjaminb0883312015-08-06 09:54:13 -04001515 switch (cipher->algorithm_prf) {
1516 case SSL_HANDSHAKE_MAC_DEFAULT:
1517 /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
1518 * only ever MD5 or SHA-1. */
1519 switch (cipher->algorithm_mac) {
1520 case SSL_MD5:
1521 return "MD5";
1522 case SSL_SHA1:
1523 return "SHA";
1524 }
1525 break;
1526 case SSL_HANDSHAKE_MAC_SHA256:
1527 return "SHA256";
1528 case SSL_HANDSHAKE_MAC_SHA384:
1529 return "SHA384";
David Benjamin71f07942015-04-08 02:36:59 -04001530 }
David Benjaminb0883312015-08-06 09:54:13 -04001531 assert(0);
1532 return "UNKNOWN";
David Benjamin71f07942015-04-08 02:36:59 -04001533}
1534
1535char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
1536 if (cipher == NULL) {
1537 return NULL;
1538 }
1539
1540 const char *kx_name = SSL_CIPHER_get_kx_name(cipher);
1541 const char *enc_name = ssl_cipher_get_enc_name(cipher);
1542 const char *prf_name = ssl_cipher_get_prf_name(cipher);
1543
1544 /* The final name is TLS_{kx_name}_WITH_{enc_name}_{prf_name}. */
1545 size_t len = 4 + strlen(kx_name) + 6 + strlen(enc_name) + 1 +
1546 strlen(prf_name) + 1;
1547 char *ret = OPENSSL_malloc(len);
1548 if (ret == NULL) {
1549 return NULL;
1550 }
1551 if (BUF_strlcpy(ret, "TLS_", len) >= len ||
1552 BUF_strlcat(ret, kx_name, len) >= len ||
1553 BUF_strlcat(ret, "_WITH_", len) >= len ||
1554 BUF_strlcat(ret, enc_name, len) >= len ||
1555 BUF_strlcat(ret, "_", len) >= len ||
1556 BUF_strlcat(ret, prf_name, len) >= len) {
1557 assert(0);
1558 OPENSSL_free(ret);
1559 return NULL;
1560 }
1561 assert(strlen(ret) + 1 == len);
1562 return ret;
1563}
1564
1565int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) {
1566 if (cipher == NULL) {
1567 return 0;
1568 }
1569
1570 if (out_alg_bits != NULL) {
1571 *out_alg_bits = cipher->alg_bits;
1572 }
1573 return cipher->strength_bits;
1574}
1575
Adam Langleyfcf25832014-12-18 17:42:32 -08001576const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
1577 int len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001578 const char *kx, *au, *enc, *mac;
David Benjamindcb6ef02015-11-06 15:35:54 -05001579 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
1580 static const char *format = "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
Adam Langley95c29f32014-06-20 12:00:00 -07001581
Adam Langleyfcf25832014-12-18 17:42:32 -08001582 alg_mkey = cipher->algorithm_mkey;
1583 alg_auth = cipher->algorithm_auth;
1584 alg_enc = cipher->algorithm_enc;
1585 alg_mac = cipher->algorithm_mac;
Adam Langley95c29f32014-06-20 12:00:00 -07001586
Adam Langleyfcf25832014-12-18 17:42:32 -08001587 switch (alg_mkey) {
1588 case SSL_kRSA:
1589 kx = "RSA";
1590 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001591
David Benjamin7061e282015-03-19 11:10:48 -04001592 case SSL_kDHE:
Adam Langleyfcf25832014-12-18 17:42:32 -08001593 kx = "DH";
1594 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001595
David Benjamin7061e282015-03-19 11:10:48 -04001596 case SSL_kECDHE:
Adam Langleyfcf25832014-12-18 17:42:32 -08001597 kx = "ECDH";
1598 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001599
Adam Langleyfcf25832014-12-18 17:42:32 -08001600 case SSL_kPSK:
1601 kx = "PSK";
1602 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001603
Adam Langleyfcf25832014-12-18 17:42:32 -08001604 default:
1605 kx = "unknown";
1606 }
Adam Langley95c29f32014-06-20 12:00:00 -07001607
Adam Langleyfcf25832014-12-18 17:42:32 -08001608 switch (alg_auth) {
1609 case SSL_aRSA:
1610 au = "RSA";
1611 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001612
Adam Langleyfcf25832014-12-18 17:42:32 -08001613 case SSL_aECDSA:
1614 au = "ECDSA";
1615 break;
Adam Langley4d4bff82014-06-20 12:00:00 -07001616
Adam Langleyfcf25832014-12-18 17:42:32 -08001617 case SSL_aPSK:
1618 au = "PSK";
1619 break;
Adam Langley4d4bff82014-06-20 12:00:00 -07001620
Adam Langleyfcf25832014-12-18 17:42:32 -08001621 default:
1622 au = "unknown";
1623 break;
1624 }
Adam Langleyde0b2022014-06-20 12:00:00 -07001625
Adam Langleyfcf25832014-12-18 17:42:32 -08001626 switch (alg_enc) {
1627 case SSL_3DES:
1628 enc = "3DES(168)";
1629 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001630
Adam Langleyfcf25832014-12-18 17:42:32 -08001631 case SSL_RC4:
1632 enc = "RC4(128)";
1633 break;
1634
1635 case SSL_AES128:
1636 enc = "AES(128)";
1637 break;
1638
1639 case SSL_AES256:
1640 enc = "AES(256)";
1641 break;
1642
1643 case SSL_AES128GCM:
1644 enc = "AESGCM(128)";
1645 break;
1646
1647 case SSL_AES256GCM:
1648 enc = "AESGCM(256)";
1649 break;
1650
Brian Smith271777f2015-10-03 13:53:33 -10001651 case SSL_CHACHA20POLY1305_OLD:
Adam Langleyfcf25832014-12-18 17:42:32 -08001652 enc = "ChaCha20-Poly1305";
1653 break;
1654
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001655 case SSL_eNULL:
1656 enc="None";
1657 break;
1658
Adam Langleyfcf25832014-12-18 17:42:32 -08001659 default:
1660 enc = "unknown";
1661 break;
1662 }
1663
1664 switch (alg_mac) {
1665 case SSL_MD5:
1666 mac = "MD5";
1667 break;
1668
1669 case SSL_SHA1:
1670 mac = "SHA1";
1671 break;
1672
1673 case SSL_SHA256:
1674 mac = "SHA256";
1675 break;
1676
1677 case SSL_SHA384:
1678 mac = "SHA384";
1679 break;
1680
1681 case SSL_AEAD:
1682 mac = "AEAD";
1683 break;
1684
1685 default:
1686 mac = "unknown";
1687 break;
1688 }
1689
1690 if (buf == NULL) {
1691 len = 128;
1692 buf = OPENSSL_malloc(len);
David Benjamin1eed2c02015-02-08 23:20:06 -05001693 if (buf == NULL) {
1694 return NULL;
1695 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001696 } else if (len < 128) {
1697 return "Buffer too small";
1698 }
1699
David Benjamindcb6ef02015-11-06 15:35:54 -05001700 BIO_snprintf(buf, len, format, cipher->name, kx, au, enc, mac);
Adam Langleyfcf25832014-12-18 17:42:32 -08001701 return buf;
1702}
1703
David Benjamin71f07942015-04-08 02:36:59 -04001704const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
1705 return "TLSv1/SSLv3";
Adam Langleyfcf25832014-12-18 17:42:32 -08001706}
1707
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001708COMP_METHOD *SSL_COMP_get_compression_methods(void) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001709
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001710int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001711
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001712const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; }
Adam Langley95c29f32014-06-20 12:00:00 -07001713
David Benjamind1d80782015-07-05 11:54:09 -04001714int ssl_cipher_get_key_type(const SSL_CIPHER *cipher) {
David Benjamin71f07942015-04-08 02:36:59 -04001715 uint32_t alg_a = cipher->algorithm_auth;
Adam Langley95c29f32014-06-20 12:00:00 -07001716
Adam Langleyfcf25832014-12-18 17:42:32 -08001717 if (alg_a & SSL_aECDSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001718 return EVP_PKEY_EC;
Adam Langleyfcf25832014-12-18 17:42:32 -08001719 } else if (alg_a & SSL_aRSA) {
David Benjamind1d80782015-07-05 11:54:09 -04001720 return EVP_PKEY_RSA;
Adam Langleyfcf25832014-12-18 17:42:32 -08001721 }
Adam Langley95c29f32014-06-20 12:00:00 -07001722
David Benjamind1d80782015-07-05 11:54:09 -04001723 return EVP_PKEY_NONE;
Adam Langleyfcf25832014-12-18 17:42:32 -08001724}
David Benjamin9c651c92014-07-12 13:27:45 -04001725
Adam Langleyfcf25832014-12-18 17:42:32 -08001726int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher) {
David Benjamindf0905a2015-09-19 09:58:31 -04001727 /* PSK-authenticated ciphers do not use a certificate. (RSA_PSK is not
1728 * supported.) */
1729 if (cipher->algorithm_auth & SSL_aPSK) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001730 return 0;
1731 }
1732
1733 /* All other ciphers include it. */
1734 return 1;
1735}
1736
Adam Langleyfcf25832014-12-18 17:42:32 -08001737int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
1738 /* Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. */
David Benjamin7061e282015-03-19 11:10:48 -04001739 if (cipher->algorithm_mkey & SSL_kDHE || cipher->algorithm_mkey & SSL_kECDHE) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001740 return 1;
1741 }
1742
1743 /* It is optional in all others. */
1744 return 0;
1745}
David Benjaminb8d28cf2015-07-28 21:34:45 -04001746
1747size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
1748 size_t block_size;
1749 switch (cipher->algorithm_enc) {
1750 case SSL_3DES:
1751 block_size = 8;
1752 break;
1753 case SSL_AES128:
1754 case SSL_AES256:
1755 block_size = 16;
1756 break;
1757 default:
1758 return 0;
1759 }
1760
1761 size_t mac_len;
1762 switch (cipher->algorithm_mac) {
1763 case SSL_MD5:
1764 mac_len = MD5_DIGEST_LENGTH;
1765 break;
1766 case SSL_SHA1:
1767 mac_len = SHA_DIGEST_LENGTH;
1768 break;
1769 default:
1770 return 0;
1771 }
1772
1773 size_t ret = 1 + mac_len;
1774 ret += block_size - (ret % block_size);
1775 return ret;
1776}