blob: 73564b390e29b08e35375d37d8419bc1e71f5c0d [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.
Adam Langleye745b252018-02-26 14:02:17 -08007 *
Adam Langley95c29f32014-06-20 12:00:00 -07008 * 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).
Adam Langleye745b252018-02-26 14:02:17 -080014 *
Adam Langley95c29f32014-06-20 12:00:00 -070015 * 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.
Adam Langleye745b252018-02-26 14:02:17 -080021 *
Adam Langley95c29f32014-06-20 12:00:00 -070022 * 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 :-).
Adam Langleye745b252018-02-26 14:02:17 -080036 * 4. If you include any Windows specific code (or a derivative thereof) from
Adam Langley95c29f32014-06-20 12:00:00 -070037 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
Adam Langleye745b252018-02-26 14:02:17 -080039 *
Adam Langley95c29f32014-06-20 12:00:00 -070040 * 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.
Adam Langleye745b252018-02-26 14:02:17 -080051 *
Adam Langley95c29f32014-06-20 12:00:00 -070052 * 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
Adam Langleye745b252018-02-26 14:02:17 -080065 * notice, this list of conditions and the following disclaimer.
Adam Langley95c29f32014-06-20 12:00:00 -070066 *
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.
Adam Langleye745b252018-02-26 14:02:17 -0800112 * ECC cipher suite support in OpenSSL originally developed by
Adam Langley95c29f32014-06-20 12:00:00 -0700113 * 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 <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700145
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"
Steven Valdezcb966542016-08-17 16:56:14 -0400153#include "../crypto/internal.h"
Adam Langley95c29f32014-06-20 12:00:00 -0700154
Adam Langley95c29f32014-06-20 12:00:00 -0700155
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -0700156BSSL_NAMESPACE_BEGIN
David Benjamin86e95b82017-07-18 16:34:25 -0400157
MichaƂ Janiszewskic4f3b8a2018-07-30 22:50:40 +0200158static constexpr SSL_CIPHER kCiphers[] = {
David Benjaminc11ea9422017-08-29 16:33:21 -0400159 // The RSA ciphers
160 // Cipher 02
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700161 {
David Benjaminff2df332015-11-18 10:01:16 -0500162 SSL3_TXT_RSA_NULL_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400163 "TLS_RSA_WITH_NULL_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500164 SSL3_CK_RSA_NULL_SHA,
165 SSL_kRSA,
166 SSL_aRSA,
167 SSL_eNULL,
168 SSL_SHA1,
169 SSL_HANDSHAKE_MAC_DEFAULT,
Matt Braithwaiteaf096752015-09-02 19:48:16 -0700170 },
171
David Benjaminc11ea9422017-08-29 16:33:21 -0400172 // Cipher 0A
David Benjamina1c90a52015-05-30 17:03:14 -0400173 {
David Benjaminff2df332015-11-18 10:01:16 -0500174 SSL3_TXT_RSA_DES_192_CBC3_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400175 "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500176 SSL3_CK_RSA_DES_192_CBC3_SHA,
177 SSL_kRSA,
178 SSL_aRSA,
179 SSL_3DES,
180 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500181 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400182 },
183
184
David Benjaminc11ea9422017-08-29 16:33:21 -0400185 // New AES ciphersuites
David Benjamina1c90a52015-05-30 17:03:14 -0400186
David Benjaminc11ea9422017-08-29 16:33:21 -0400187 // Cipher 2F
David Benjamina1c90a52015-05-30 17:03:14 -0400188 {
David Benjaminff2df332015-11-18 10:01:16 -0500189 TLS1_TXT_RSA_WITH_AES_128_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400190 "TLS_RSA_WITH_AES_128_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500191 TLS1_CK_RSA_WITH_AES_128_SHA,
192 SSL_kRSA,
193 SSL_aRSA,
194 SSL_AES128,
195 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500196 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400197 },
198
David Benjaminc11ea9422017-08-29 16:33:21 -0400199 // Cipher 35
David Benjamina1c90a52015-05-30 17:03:14 -0400200 {
David Benjaminff2df332015-11-18 10:01:16 -0500201 TLS1_TXT_RSA_WITH_AES_256_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400202 "TLS_RSA_WITH_AES_256_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500203 TLS1_CK_RSA_WITH_AES_256_SHA,
204 SSL_kRSA,
205 SSL_aRSA,
206 SSL_AES256,
207 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500208 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400209 },
210
David Benjaminc11ea9422017-08-29 16:33:21 -0400211 // PSK cipher suites.
Adam Langley85bc5602015-06-09 09:54:04 -0700212
David Benjaminc11ea9422017-08-29 16:33:21 -0400213 // Cipher 8C
David Benjamina1c90a52015-05-30 17:03:14 -0400214 {
David Benjaminff2df332015-11-18 10:01:16 -0500215 TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400216 "TLS_PSK_WITH_AES_128_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500217 TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
218 SSL_kPSK,
219 SSL_aPSK,
220 SSL_AES128,
221 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500222 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400223 },
224
David Benjaminc11ea9422017-08-29 16:33:21 -0400225 // Cipher 8D
David Benjamina1c90a52015-05-30 17:03:14 -0400226 {
David Benjaminff2df332015-11-18 10:01:16 -0500227 TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400228 "TLS_PSK_WITH_AES_256_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500229 TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
230 SSL_kPSK,
231 SSL_aPSK,
232 SSL_AES256,
233 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500234 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400235 },
236
David Benjamin8648c532021-08-19 18:02:37 -0400237 // GCM ciphersuites from RFC 5288
David Benjamina1c90a52015-05-30 17:03:14 -0400238
David Benjaminc11ea9422017-08-29 16:33:21 -0400239 // Cipher 9C
David Benjamina1c90a52015-05-30 17:03:14 -0400240 {
241 TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400242 "TLS_RSA_WITH_AES_128_GCM_SHA256",
David Benjaminff2df332015-11-18 10:01:16 -0500243 TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
244 SSL_kRSA,
245 SSL_aRSA,
246 SSL_AES128GCM,
David Benjamind6e9eec2015-11-18 09:48:55 -0500247 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400248 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400249 },
250
David Benjaminc11ea9422017-08-29 16:33:21 -0400251 // Cipher 9D
David Benjamina1c90a52015-05-30 17:03:14 -0400252 {
253 TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
David Benjamin6fff3862017-06-21 21:07:04 -0400254 "TLS_RSA_WITH_AES_256_GCM_SHA384",
David Benjaminff2df332015-11-18 10:01:16 -0500255 TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
256 SSL_kRSA,
257 SSL_aRSA,
258 SSL_AES256GCM,
David Benjamind6e9eec2015-11-18 09:48:55 -0500259 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400260 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400261 },
262
David Benjaminc11ea9422017-08-29 16:33:21 -0400263 // TLS 1.3 suites.
Steven Valdez803c77a2016-09-06 14:13:43 -0400264
David Benjaminc11ea9422017-08-29 16:33:21 -0400265 // Cipher 1301
Steven Valdez803c77a2016-09-06 14:13:43 -0400266 {
Bob Becka6981a32022-07-19 09:20:50 -0600267 TLS1_3_RFC_AES_128_GCM_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400268 "TLS_AES_128_GCM_SHA256",
David Benjamindfddbc42022-07-18 16:08:06 -0400269 TLS1_3_CK_AES_128_GCM_SHA256,
Steven Valdez803c77a2016-09-06 14:13:43 -0400270 SSL_kGENERIC,
271 SSL_aGENERIC,
272 SSL_AES128GCM,
273 SSL_AEAD,
274 SSL_HANDSHAKE_MAC_SHA256,
275 },
276
David Benjaminc11ea9422017-08-29 16:33:21 -0400277 // Cipher 1302
Steven Valdez803c77a2016-09-06 14:13:43 -0400278 {
Bob Becka6981a32022-07-19 09:20:50 -0600279 TLS1_3_RFC_AES_256_GCM_SHA384,
David Benjamin6fff3862017-06-21 21:07:04 -0400280 "TLS_AES_256_GCM_SHA384",
David Benjamindfddbc42022-07-18 16:08:06 -0400281 TLS1_3_CK_AES_256_GCM_SHA384,
Steven Valdez803c77a2016-09-06 14:13:43 -0400282 SSL_kGENERIC,
283 SSL_aGENERIC,
284 SSL_AES256GCM,
285 SSL_AEAD,
286 SSL_HANDSHAKE_MAC_SHA384,
287 },
288
David Benjaminc11ea9422017-08-29 16:33:21 -0400289 // Cipher 1303
Steven Valdez803c77a2016-09-06 14:13:43 -0400290 {
Bob Becka6981a32022-07-19 09:20:50 -0600291 TLS1_3_RFC_CHACHA20_POLY1305_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400292 "TLS_CHACHA20_POLY1305_SHA256",
David Benjamindfddbc42022-07-18 16:08:06 -0400293 TLS1_3_CK_CHACHA20_POLY1305_SHA256,
Steven Valdez803c77a2016-09-06 14:13:43 -0400294 SSL_kGENERIC,
295 SSL_aGENERIC,
296 SSL_CHACHA20POLY1305,
297 SSL_AEAD,
298 SSL_HANDSHAKE_MAC_SHA256,
299 },
300
David Benjaminc11ea9422017-08-29 16:33:21 -0400301 // Cipher C009
David Benjamina1c90a52015-05-30 17:03:14 -0400302 {
303 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400304 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500305 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
306 SSL_kECDHE,
307 SSL_aECDSA,
308 SSL_AES128,
309 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500310 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400311 },
312
David Benjaminc11ea9422017-08-29 16:33:21 -0400313 // Cipher C00A
David Benjamina1c90a52015-05-30 17:03:14 -0400314 {
315 TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400316 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500317 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
318 SSL_kECDHE,
319 SSL_aECDSA,
320 SSL_AES256,
321 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500322 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400323 },
324
David Benjaminc11ea9422017-08-29 16:33:21 -0400325 // Cipher C013
David Benjamina1c90a52015-05-30 17:03:14 -0400326 {
327 TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400328 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500329 TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
330 SSL_kECDHE,
331 SSL_aRSA,
332 SSL_AES128,
David Benjamind6e9eec2015-11-18 09:48:55 -0500333 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500334 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400335 },
336
David Benjaminc11ea9422017-08-29 16:33:21 -0400337 // Cipher C014
David Benjamina1c90a52015-05-30 17:03:14 -0400338 {
339 TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400340 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
David Benjaminff2df332015-11-18 10:01:16 -0500341 TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
342 SSL_kECDHE,
343 SSL_aRSA,
344 SSL_AES256,
David Benjamind6e9eec2015-11-18 09:48:55 -0500345 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500346 SSL_HANDSHAKE_MAC_DEFAULT,
David Benjamina1c90a52015-05-30 17:03:14 -0400347 },
348
David Benjamin8648c532021-08-19 18:02:37 -0400349 // GCM based TLS v1.2 ciphersuites from RFC 5289
David Benjamina1c90a52015-05-30 17:03:14 -0400350
David Benjaminc11ea9422017-08-29 16:33:21 -0400351 // Cipher C02B
David Benjamina1c90a52015-05-30 17:03:14 -0400352 {
353 TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400354 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
David Benjaminff2df332015-11-18 10:01:16 -0500355 TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
356 SSL_kECDHE,
357 SSL_aECDSA,
358 SSL_AES128GCM,
359 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400360 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400361 },
362
David Benjaminc11ea9422017-08-29 16:33:21 -0400363 // Cipher C02C
David Benjamina1c90a52015-05-30 17:03:14 -0400364 {
365 TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
David Benjamin6fff3862017-06-21 21:07:04 -0400366 "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
David Benjaminff2df332015-11-18 10:01:16 -0500367 TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
368 SSL_kECDHE,
369 SSL_aECDSA,
370 SSL_AES256GCM,
371 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400372 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400373 },
374
David Benjaminc11ea9422017-08-29 16:33:21 -0400375 // Cipher C02F
David Benjamina1c90a52015-05-30 17:03:14 -0400376 {
377 TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400378 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
David Benjaminff2df332015-11-18 10:01:16 -0500379 TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
380 SSL_kECDHE,
381 SSL_aRSA,
382 SSL_AES128GCM,
383 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400384 SSL_HANDSHAKE_MAC_SHA256,
David Benjamina1c90a52015-05-30 17:03:14 -0400385 },
386
David Benjaminc11ea9422017-08-29 16:33:21 -0400387 // Cipher C030
David Benjamina1c90a52015-05-30 17:03:14 -0400388 {
389 TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
David Benjamin6fff3862017-06-21 21:07:04 -0400390 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
David Benjaminff2df332015-11-18 10:01:16 -0500391 TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
392 SSL_kECDHE,
393 SSL_aRSA,
394 SSL_AES256GCM,
395 SSL_AEAD,
David Benjaminb2a985b2015-06-21 15:13:57 -0400396 SSL_HANDSHAKE_MAC_SHA384,
David Benjamina1c90a52015-05-30 17:03:14 -0400397 },
398
David Benjaminc11ea9422017-08-29 16:33:21 -0400399 // ECDHE-PSK cipher suites.
Adam Langley85bc5602015-06-09 09:54:04 -0700400
David Benjaminc11ea9422017-08-29 16:33:21 -0400401 // Cipher C035
Adam Langley85bc5602015-06-09 09:54:04 -0700402 {
403 TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400404 "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
Adam Langley85bc5602015-06-09 09:54:04 -0700405 TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
David Benjaminff2df332015-11-18 10:01:16 -0500406 SSL_kECDHE,
407 SSL_aPSK,
408 SSL_AES128,
409 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500410 SSL_HANDSHAKE_MAC_DEFAULT,
Adam Langley85bc5602015-06-09 09:54:04 -0700411 },
412
David Benjaminc11ea9422017-08-29 16:33:21 -0400413 // Cipher C036
Adam Langley85bc5602015-06-09 09:54:04 -0700414 {
415 TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA,
David Benjamin6fff3862017-06-21 21:07:04 -0400416 "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
Adam Langley85bc5602015-06-09 09:54:04 -0700417 TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA,
David Benjaminff2df332015-11-18 10:01:16 -0500418 SSL_kECDHE,
419 SSL_aPSK,
420 SSL_AES256,
421 SSL_SHA1,
David Benjamin9f2e2772015-11-18 09:59:43 -0500422 SSL_HANDSHAKE_MAC_DEFAULT,
Adam Langley85bc5602015-06-09 09:54:04 -0700423 },
424
David Benjaminc11ea9422017-08-29 16:33:21 -0400425 // ChaCha20-Poly1305 cipher suites.
Adam Langley85bc5602015-06-09 09:54:04 -0700426
David Benjaminc11ea9422017-08-29 16:33:21 -0400427 // Cipher CCA8
David Benjamin13414b32015-12-09 23:02:39 -0500428 {
429 TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400430 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
David Benjamin13414b32015-12-09 23:02:39 -0500431 TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
432 SSL_kECDHE,
433 SSL_aRSA,
434 SSL_CHACHA20POLY1305,
435 SSL_AEAD,
436 SSL_HANDSHAKE_MAC_SHA256,
437 },
438
David Benjaminc11ea9422017-08-29 16:33:21 -0400439 // Cipher CCA9
David Benjamin13414b32015-12-09 23:02:39 -0500440 {
441 TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400442 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
David Benjamin13414b32015-12-09 23:02:39 -0500443 TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
444 SSL_kECDHE,
445 SSL_aECDSA,
446 SSL_CHACHA20POLY1305,
447 SSL_AEAD,
448 SSL_HANDSHAKE_MAC_SHA256,
449 },
450
David Benjaminc11ea9422017-08-29 16:33:21 -0400451 // Cipher CCAB
David Benjamin13414b32015-12-09 23:02:39 -0500452 {
453 TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
David Benjamin6fff3862017-06-21 21:07:04 -0400454 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256",
David Benjamin13414b32015-12-09 23:02:39 -0500455 TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256,
456 SSL_kECDHE,
457 SSL_aPSK,
458 SSL_CHACHA20POLY1305,
459 SSL_AEAD,
460 SSL_HANDSHAKE_MAC_SHA256,
461 },
Matt Braithwaite053931e2016-05-25 12:06:05 -0700462
David Benjamina1c90a52015-05-30 17:03:14 -0400463};
464
Matthew Braithwaited2ed3822018-07-10 16:27:22 -0700465Span<const SSL_CIPHER> AllCiphers() {
466 return MakeConstSpan(kCiphers, OPENSSL_ARRAY_SIZE(kCiphers));
467}
David Benjamina1c90a52015-05-30 17:03:14 -0400468
Adam Langleyfcf25832014-12-18 17:42:32 -0800469#define CIPHER_ADD 1
470#define CIPHER_KILL 2
471#define CIPHER_DEL 3
472#define CIPHER_ORD 4
473#define CIPHER_SPECIAL 5
Adam Langley95c29f32014-06-20 12:00:00 -0700474
Adam Langleyfcf25832014-12-18 17:42:32 -0800475typedef struct cipher_order_st {
476 const SSL_CIPHER *cipher;
David Benjaminf4962492017-09-27 19:34:32 -0400477 bool active;
478 bool in_group;
Adam Langleyfcf25832014-12-18 17:42:32 -0800479 struct cipher_order_st *next, *prev;
480} CIPHER_ORDER;
Adam Langley95c29f32014-06-20 12:00:00 -0700481
David Benjamin0344daf2015-04-08 02:08:01 -0400482typedef struct cipher_alias_st {
David Benjaminc11ea9422017-08-29 16:33:21 -0400483 // name is the name of the cipher alias.
David Benjamin0344daf2015-04-08 02:08:01 -0400484 const char *name;
485
David Benjaminc11ea9422017-08-29 16:33:21 -0400486 // The following fields are bitmasks for the corresponding fields on
487 // |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the
488 // bit corresponding to the cipher's value is set to 1. If any bitmask is
489 // all zeroes, the alias matches nothing. Use |~0u| for the default value.
David Benjamin0344daf2015-04-08 02:08:01 -0400490 uint32_t algorithm_mkey;
491 uint32_t algorithm_auth;
492 uint32_t algorithm_enc;
493 uint32_t algorithm_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -0500494
David Benjaminc11ea9422017-08-29 16:33:21 -0400495 // min_version, if non-zero, matches all ciphers which were added in that
496 // particular protocol version.
David Benjamindcb6ef02015-11-06 15:35:54 -0500497 uint16_t min_version;
David Benjamin0344daf2015-04-08 02:08:01 -0400498} CIPHER_ALIAS;
499
David Benjamina1c90a52015-05-30 17:03:14 -0400500static const CIPHER_ALIAS kCipherAliases[] = {
David Benjaminc11ea9422017-08-29 16:33:21 -0400501 // "ALL" doesn't include eNULL. It must be explicitly enabled.
David Benjamin3b903f22017-09-29 18:44:56 -0400502 {"ALL", ~0u, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700503
David Benjaminc11ea9422017-08-29 16:33:21 -0400504 // The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing.
Adam Langley95c29f32014-06-20 12:00:00 -0700505
David Benjaminc11ea9422017-08-29 16:33:21 -0400506 // key exchange aliases
507 // (some of those using only a single bit here combine
508 // multiple key exchange algs according to the RFCs.
David Benjamind6e9eec2015-11-18 09:48:55 -0500509 {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700510
David Benjamind6e9eec2015-11-18 09:48:55 -0500511 {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
512 {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
513 {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700514
David Benjamind6e9eec2015-11-18 09:48:55 -0500515 {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700516
David Benjaminc11ea9422017-08-29 16:33:21 -0400517 // server authentication aliases
David Benjamin3b903f22017-09-29 18:44:56 -0400518 {"aRSA", ~0u, SSL_aRSA, ~0u, ~0u, 0},
Matthew Braithwaite651aaef2016-12-08 16:14:36 -0800519 {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
520 {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0},
David Benjamind6e9eec2015-11-18 09:48:55 -0500521 {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700522
David Benjaminc11ea9422017-08-29 16:33:21 -0400523 // aliases combining key exchange and server authentication
David Benjamind6e9eec2015-11-18 09:48:55 -0500524 {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
525 {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0},
David Benjamin3b903f22017-09-29 18:44:56 -0400526 {"RSA", SSL_kRSA, SSL_aRSA, ~0u, ~0u, 0},
David Benjamind6e9eec2015-11-18 09:48:55 -0500527 {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700528
David Benjaminc11ea9422017-08-29 16:33:21 -0400529 // symmetric encryption aliases
David Benjamind6e9eec2015-11-18 09:48:55 -0500530 {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0},
David Benjamind6e9eec2015-11-18 09:48:55 -0500531 {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0},
Matthew Braithwaite651aaef2016-12-08 16:14:36 -0800532 {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0},
533 {"AES", ~0u, ~0u, SSL_AES, ~0u, 0},
534 {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0},
Adam Langley2e839242017-01-19 15:12:44 -0800535 {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700536
David Benjaminc11ea9422017-08-29 16:33:21 -0400537 // MAC aliases
David Benjamin3b903f22017-09-29 18:44:56 -0400538 {"SHA1", ~0u, ~0u, ~0u, SSL_SHA1, 0},
539 {"SHA", ~0u, ~0u, ~0u, SSL_SHA1, 0},
Adam Langley95c29f32014-06-20 12:00:00 -0700540
David Benjaminc11ea9422017-08-29 16:33:21 -0400541 // Legacy protocol minimum version aliases. "TLSv1" is intentionally the
542 // same as "SSLv3".
David Benjamin3b903f22017-09-29 18:44:56 -0400543 {"SSLv3", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION},
544 {"TLSv1", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION},
545 {"TLSv1.2", ~0u, ~0u, ~0u, ~0u, TLS1_2_VERSION},
Adam Langley95c29f32014-06-20 12:00:00 -0700546
David Benjaminc11ea9422017-08-29 16:33:21 -0400547 // Legacy strength classes.
David Benjamin3b903f22017-09-29 18:44:56 -0400548 {"HIGH", ~0u, ~0u, ~0u, ~0u, 0},
549 {"FIPS", ~0u, ~0u, ~0u, ~0u, 0},
David Benjamin0ca92142018-05-03 11:35:10 -0400550
551 // Temporary no-op aliases corresponding to removed SHA-2 legacy CBC
552 // ciphers. These should be removed after 2018-05-14.
553 {"SHA256", 0, 0, 0, 0, 0},
554 {"SHA384", 0, 0, 0, 0, 0},
Adam Langleyfcf25832014-12-18 17:42:32 -0800555};
Adam Langley95c29f32014-06-20 12:00:00 -0700556
Steven Valdezcb966542016-08-17 16:56:14 -0400557static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases);
David Benjamina1c90a52015-05-30 17:03:14 -0400558
David Benjaminf4962492017-09-27 19:34:32 -0400559bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
560 size_t *out_mac_secret_len,
561 size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
David Benjamin8525ff32018-09-05 18:44:15 -0500562 uint16_t version, bool is_dtls) {
David Benjaminea72bd02014-12-21 21:27:41 -0500563 *out_aead = NULL;
564 *out_mac_secret_len = 0;
565 *out_fixed_iv_len = 0;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700566
David Benjamin8525ff32018-09-05 18:44:15 -0500567 const bool is_tls12 = version == TLS1_2_VERSION && !is_dtls;
568 const bool is_tls13 = version == TLS1_3_VERSION && !is_dtls;
Steven Valdez2f3404b2017-05-24 16:54:35 -0400569
David Benjamin305e6fb2016-10-27 18:19:00 -0400570 if (cipher->algorithm_mac == SSL_AEAD) {
571 if (cipher->algorithm_enc == SSL_AES128GCM) {
Adam Langleybcfb4992018-06-18 14:04:41 -0700572 if (is_tls12) {
573 *out_aead = EVP_aead_aes_128_gcm_tls12();
574 } else if (is_tls13) {
575 *out_aead = EVP_aead_aes_128_gcm_tls13();
576 } else {
577 *out_aead = EVP_aead_aes_128_gcm();
578 }
David Benjaminea72bd02014-12-21 21:27:41 -0500579 *out_fixed_iv_len = 4;
David Benjamin305e6fb2016-10-27 18:19:00 -0400580 } else if (cipher->algorithm_enc == SSL_AES256GCM) {
Adam Langleybcfb4992018-06-18 14:04:41 -0700581 if (is_tls12) {
582 *out_aead = EVP_aead_aes_256_gcm_tls12();
583 } else if (is_tls13) {
584 *out_aead = EVP_aead_aes_256_gcm_tls13();
585 } else {
586 *out_aead = EVP_aead_aes_256_gcm();
587 }
David Benjaminea72bd02014-12-21 21:27:41 -0500588 *out_fixed_iv_len = 4;
David Benjamin305e6fb2016-10-27 18:19:00 -0400589 } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) {
David Benjamin13414b32015-12-09 23:02:39 -0500590 *out_aead = EVP_aead_chacha20_poly1305();
591 *out_fixed_iv_len = 12;
David Benjamin305e6fb2016-10-27 18:19:00 -0400592 } else {
David Benjaminf4962492017-09-27 19:34:32 -0400593 return false;
David Benjamin305e6fb2016-10-27 18:19:00 -0400594 }
595
David Benjaminc11ea9422017-08-29 16:33:21 -0400596 // In TLS 1.3, the iv_len is equal to the AEAD nonce length whereas the code
597 // above computes the TLS 1.2 construction.
David Benjamin305e6fb2016-10-27 18:19:00 -0400598 if (version >= TLS1_3_VERSION) {
599 *out_fixed_iv_len = EVP_AEAD_nonce_length(*out_aead);
600 }
601 } else if (cipher->algorithm_mac == SSL_SHA1) {
602 if (cipher->algorithm_enc == SSL_eNULL) {
David Benjamin9bb15f52018-06-26 00:07:40 -0400603 *out_aead = EVP_aead_null_sha1_tls();
David Benjamin305e6fb2016-10-27 18:19:00 -0400604 } else if (cipher->algorithm_enc == SSL_3DES) {
David Benjamin9bb15f52018-06-26 00:07:40 -0400605 if (version == TLS1_VERSION) {
David Benjamin305e6fb2016-10-27 18:19:00 -0400606 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv();
607 *out_fixed_iv_len = 8;
608 } else {
609 *out_aead = EVP_aead_des_ede3_cbc_sha1_tls();
610 }
611 } else if (cipher->algorithm_enc == SSL_AES128) {
David Benjamin9bb15f52018-06-26 00:07:40 -0400612 if (version == TLS1_VERSION) {
David Benjamin305e6fb2016-10-27 18:19:00 -0400613 *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv();
614 *out_fixed_iv_len = 16;
615 } else {
616 *out_aead = EVP_aead_aes_128_cbc_sha1_tls();
617 }
618 } else if (cipher->algorithm_enc == SSL_AES256) {
David Benjamin9bb15f52018-06-26 00:07:40 -0400619 if (version == TLS1_VERSION) {
David Benjamin305e6fb2016-10-27 18:19:00 -0400620 *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv();
621 *out_fixed_iv_len = 16;
622 } else {
623 *out_aead = EVP_aead_aes_256_cbc_sha1_tls();
624 }
625 } else {
David Benjaminf4962492017-09-27 19:34:32 -0400626 return false;
David Benjamin305e6fb2016-10-27 18:19:00 -0400627 }
628
629 *out_mac_secret_len = SHA_DIGEST_LENGTH;
David Benjamin305e6fb2016-10-27 18:19:00 -0400630 } else {
David Benjaminf4962492017-09-27 19:34:32 -0400631 return false;
David Benjaminea72bd02014-12-21 21:27:41 -0500632 }
Steven Valdez79750562016-06-16 06:38:04 -0400633
David Benjaminf4962492017-09-27 19:34:32 -0400634 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800635}
Adam Langleyc9fb3752014-06-20 12:00:00 -0700636
David Benjaminca9e8f52017-08-09 15:02:34 -0400637const EVP_MD *ssl_get_handshake_digest(uint16_t version,
638 const SSL_CIPHER *cipher) {
639 switch (cipher->algorithm_prf) {
David Benjaminb0883312015-08-06 09:54:13 -0400640 case SSL_HANDSHAKE_MAC_DEFAULT:
Steven Valdez908ac192017-01-12 13:17:07 -0500641 return version >= TLS1_2_VERSION ? EVP_sha256() : EVP_md5_sha1();
David Benjaminb0883312015-08-06 09:54:13 -0400642 case SSL_HANDSHAKE_MAC_SHA256:
643 return EVP_sha256();
644 case SSL_HANDSHAKE_MAC_SHA384:
645 return EVP_sha384();
646 default:
David Benjaminca9e8f52017-08-09 15:02:34 -0400647 assert(0);
David Benjaminb0883312015-08-06 09:54:13 -0400648 return NULL;
Adam Langleyfcf25832014-12-18 17:42:32 -0800649 }
Adam Langley95c29f32014-06-20 12:00:00 -0700650}
651
David Benjamin8525ff32018-09-05 18:44:15 -0500652static bool is_cipher_list_separator(char c, bool is_strict) {
Adam Langley22df6912017-07-25 12:27:37 -0700653 if (c == ':') {
654 return true;
655 }
656 return !is_strict && (c == ' ' || c == ';' || c == ',');
657}
Adam Langley95c29f32014-06-20 12:00:00 -0700658
David Benjaminf4962492017-09-27 19:34:32 -0400659// rule_equals returns whether the NUL-terminated string |rule| is equal to the
David Benjaminc11ea9422017-08-29 16:33:21 -0400660// |buf_len| bytes at |buf|.
David Benjaminf4962492017-09-27 19:34:32 -0400661static bool rule_equals(const char *rule, const char *buf, size_t buf_len) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400662 // |strncmp| alone only checks that |buf| is a prefix of |rule|.
David Benjamin0344daf2015-04-08 02:08:01 -0400663 return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0';
664}
665
Adam Langley95c29f32014-06-20 12:00:00 -0700666static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800667 CIPHER_ORDER **tail) {
668 if (curr == *tail) {
669 return;
670 }
671 if (curr == *head) {
672 *head = curr->next;
673 }
674 if (curr->prev != NULL) {
675 curr->prev->next = curr->next;
676 }
677 if (curr->next != NULL) {
678 curr->next->prev = curr->prev;
679 }
680 (*tail)->next = curr;
681 curr->prev = *tail;
682 curr->next = NULL;
683 *tail = curr;
684}
Adam Langley95c29f32014-06-20 12:00:00 -0700685
686static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
Adam Langleyfcf25832014-12-18 17:42:32 -0800687 CIPHER_ORDER **tail) {
688 if (curr == *head) {
689 return;
690 }
691 if (curr == *tail) {
692 *tail = curr->prev;
693 }
694 if (curr->next != NULL) {
695 curr->next->prev = curr->prev;
696 }
697 if (curr->prev != NULL) {
698 curr->prev->next = curr->next;
699 }
700 (*head)->prev = curr;
701 curr->next = *head;
702 curr->prev = NULL;
703 *head = curr;
704}
Adam Langley95c29f32014-06-20 12:00:00 -0700705
David Benjamin48b276d2018-04-12 17:37:32 -0400706static bool ssl_cipher_collect_ciphers(Array<CIPHER_ORDER> *out_co_list,
707 CIPHER_ORDER **out_head,
708 CIPHER_ORDER **out_tail) {
709 Array<CIPHER_ORDER> co_list;
Matthew Braithwaited2ed3822018-07-10 16:27:22 -0700710 if (!co_list.Init(OPENSSL_ARRAY_SIZE(kCiphers))) {
David Benjamin48b276d2018-04-12 17:37:32 -0400711 return false;
712 }
713
David Benjamina1c90a52015-05-30 17:03:14 -0400714 size_t co_list_num = 0;
David Benjamin5be3a742017-10-28 16:08:58 -0400715 for (const SSL_CIPHER &cipher : kCiphers) {
716 // TLS 1.3 ciphers do not participate in this mechanism.
717 if (cipher.algorithm_mkey != SSL_kGENERIC) {
718 co_list[co_list_num].cipher = &cipher;
Adam Langleyfcf25832014-12-18 17:42:32 -0800719 co_list[co_list_num].next = NULL;
720 co_list[co_list_num].prev = NULL;
David Benjaminf4962492017-09-27 19:34:32 -0400721 co_list[co_list_num].active = false;
722 co_list[co_list_num].in_group = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800723 co_list_num++;
724 }
725 }
Adam Langley95c29f32014-06-20 12:00:00 -0700726
David Benjaminc11ea9422017-08-29 16:33:21 -0400727 // Prepare linked list from list entries.
Adam Langleyfcf25832014-12-18 17:42:32 -0800728 if (co_list_num > 0) {
729 co_list[0].prev = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700730
Adam Langleyfcf25832014-12-18 17:42:32 -0800731 if (co_list_num > 1) {
732 co_list[0].next = &co_list[1];
Adam Langley95c29f32014-06-20 12:00:00 -0700733
David Benjamin54091232016-09-05 12:47:25 -0400734 for (size_t i = 1; i < co_list_num - 1; i++) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800735 co_list[i].prev = &co_list[i - 1];
736 co_list[i].next = &co_list[i + 1];
737 }
Adam Langley95c29f32014-06-20 12:00:00 -0700738
Adam Langleyfcf25832014-12-18 17:42:32 -0800739 co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
740 }
741
742 co_list[co_list_num - 1].next = NULL;
743
David Benjamin48b276d2018-04-12 17:37:32 -0400744 *out_head = &co_list[0];
745 *out_tail = &co_list[co_list_num - 1];
746 } else {
747 *out_head = nullptr;
748 *out_tail = nullptr;
Adam Langleyfcf25832014-12-18 17:42:32 -0800749 }
David Benjamin48b276d2018-04-12 17:37:32 -0400750 *out_co_list = std::move(co_list);
751 return true;
752}
753
754SSLCipherPreferenceList::~SSLCipherPreferenceList() {
755 OPENSSL_free(in_group_flags);
756}
757
758bool SSLCipherPreferenceList::Init(UniquePtr<STACK_OF(SSL_CIPHER)> ciphers_arg,
759 Span<const bool> in_group_flags_arg) {
760 if (sk_SSL_CIPHER_num(ciphers_arg.get()) != in_group_flags_arg.size()) {
761 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
762 return false;
763 }
764
765 Array<bool> copy;
766 if (!copy.CopyFrom(in_group_flags_arg)) {
767 return false;
768 }
769 ciphers = std::move(ciphers_arg);
770 size_t unused_len;
771 copy.Release(&in_group_flags, &unused_len);
772 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800773}
Adam Langley95c29f32014-06-20 12:00:00 -0700774
Matthew Braithwaited2ed3822018-07-10 16:27:22 -0700775bool SSLCipherPreferenceList::Init(const SSLCipherPreferenceList& other) {
776 size_t size = sk_SSL_CIPHER_num(other.ciphers.get());
777 Span<const bool> other_flags(other.in_group_flags, size);
778 UniquePtr<STACK_OF(SSL_CIPHER)> other_ciphers(sk_SSL_CIPHER_dup(
779 other.ciphers.get()));
780 if (!other_ciphers) {
781 return false;
782 }
783 return Init(std::move(other_ciphers), other_flags);
784}
785
786void SSLCipherPreferenceList::Remove(const SSL_CIPHER *cipher) {
787 size_t index;
788 if (!sk_SSL_CIPHER_find(ciphers.get(), &index, cipher)) {
789 return;
790 }
791 if (!in_group_flags[index] /* last element of group */ && index > 0) {
792 in_group_flags[index-1] = false;
793 }
794 for (size_t i = index; i < sk_SSL_CIPHER_num(ciphers.get()) - 1; ++i) {
795 in_group_flags[i] = in_group_flags[i+1];
796 }
797 sk_SSL_CIPHER_delete(ciphers.get(), index);
798}
799
David Benjaminc11ea9422017-08-29 16:33:21 -0400800// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its
801// parameters in the linked list from |*head_p| to |*tail_p|. It writes the new
802// head and tail of the list to |*head_p| and |*tail_p|, respectively.
803//
804// - If |cipher_id| is non-zero, only that cipher is selected.
805// - Otherwise, if |strength_bits| is non-negative, it selects ciphers
806// of that strength.
807// - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and
808// |min_version|.
Adam Langleyfcf25832014-12-18 17:42:32 -0800809static void ssl_cipher_apply_rule(
David Benjamin107db582015-04-08 00:41:59 -0400810 uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
David Benjamind6e9eec2015-11-18 09:48:55 -0500811 uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule,
David Benjaminf4962492017-09-27 19:34:32 -0400812 int strength_bits, bool in_group, CIPHER_ORDER **head_p,
David Benjamind6e9eec2015-11-18 09:48:55 -0500813 CIPHER_ORDER **tail_p) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800814 CIPHER_ORDER *head, *tail, *curr, *next, *last;
815 const SSL_CIPHER *cp;
David Benjaminf4962492017-09-27 19:34:32 -0400816 bool reverse = false;
Adam Langley95c29f32014-06-20 12:00:00 -0700817
David Benjamindcb6ef02015-11-06 15:35:54 -0500818 if (cipher_id == 0 && strength_bits == -1 && min_version == 0 &&
David Benjamind6e9eec2015-11-18 09:48:55 -0500819 (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400820 // The rule matches nothing, so bail early.
David Benjamin0344daf2015-04-08 02:08:01 -0400821 return;
822 }
823
Adam Langleyfcf25832014-12-18 17:42:32 -0800824 if (rule == CIPHER_DEL) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400825 // needed to maintain sorting between currently deleted ciphers
David Benjaminf4962492017-09-27 19:34:32 -0400826 reverse = true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800827 }
Adam Langley95c29f32014-06-20 12:00:00 -0700828
Adam Langleyfcf25832014-12-18 17:42:32 -0800829 head = *head_p;
830 tail = *tail_p;
Adam Langley95c29f32014-06-20 12:00:00 -0700831
Adam Langleyfcf25832014-12-18 17:42:32 -0800832 if (reverse) {
833 next = tail;
834 last = head;
835 } else {
836 next = head;
837 last = tail;
838 }
Adam Langley95c29f32014-06-20 12:00:00 -0700839
Adam Langleyfcf25832014-12-18 17:42:32 -0800840 curr = NULL;
841 for (;;) {
842 if (curr == last) {
843 break;
844 }
Adam Langley95c29f32014-06-20 12:00:00 -0700845
Adam Langleyfcf25832014-12-18 17:42:32 -0800846 curr = next;
847 if (curr == NULL) {
848 break;
849 }
Adam Langleye3142a72014-07-24 17:56:48 -0700850
Adam Langleyfcf25832014-12-18 17:42:32 -0800851 next = reverse ? curr->prev : curr->next;
852 cp = curr->cipher;
Adam Langleye3142a72014-07-24 17:56:48 -0700853
David Benjaminc11ea9422017-08-29 16:33:21 -0400854 // Selection criteria is either a specific cipher, the value of
855 // |strength_bits|, or the algorithms used.
David Benjamin0344daf2015-04-08 02:08:01 -0400856 if (cipher_id != 0) {
857 if (cipher_id != cp->id) {
858 continue;
859 }
860 } else if (strength_bits >= 0) {
David Benjamin9f2e2772015-11-18 09:59:43 -0500861 if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800862 continue;
863 }
David Benjamin881f1962016-08-10 18:29:12 -0400864 } else {
865 if (!(alg_mkey & cp->algorithm_mkey) ||
866 !(alg_auth & cp->algorithm_auth) ||
867 !(alg_enc & cp->algorithm_enc) ||
868 !(alg_mac & cp->algorithm_mac) ||
David Benjamin3b903f22017-09-29 18:44:56 -0400869 (min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version) ||
870 // The NULL cipher must be selected explicitly.
871 cp->algorithm_enc == SSL_eNULL) {
David Benjamin881f1962016-08-10 18:29:12 -0400872 continue;
873 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800874 }
Adam Langleye3142a72014-07-24 17:56:48 -0700875
David Benjaminc11ea9422017-08-29 16:33:21 -0400876 // add the cipher if it has not been added yet.
Adam Langleyfcf25832014-12-18 17:42:32 -0800877 if (rule == CIPHER_ADD) {
David Benjaminf4962492017-09-27 19:34:32 -0400878 // reverse == false
Adam Langleyfcf25832014-12-18 17:42:32 -0800879 if (!curr->active) {
880 ll_append_tail(&head, curr, &tail);
David Benjaminf4962492017-09-27 19:34:32 -0400881 curr->active = true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800882 curr->in_group = in_group;
883 }
884 }
Adam Langley95c29f32014-06-20 12:00:00 -0700885
David Benjaminc11ea9422017-08-29 16:33:21 -0400886 // Move the added cipher to this location
Adam Langleyfcf25832014-12-18 17:42:32 -0800887 else if (rule == CIPHER_ORD) {
David Benjaminf4962492017-09-27 19:34:32 -0400888 // reverse == false
Adam Langleyfcf25832014-12-18 17:42:32 -0800889 if (curr->active) {
890 ll_append_tail(&head, curr, &tail);
David Benjaminf4962492017-09-27 19:34:32 -0400891 curr->in_group = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800892 }
893 } else if (rule == CIPHER_DEL) {
David Benjaminf4962492017-09-27 19:34:32 -0400894 // reverse == true
Adam Langleyfcf25832014-12-18 17:42:32 -0800895 if (curr->active) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400896 // most recently deleted ciphersuites get best positions
897 // for any future CIPHER_ADD (note that the CIPHER_DEL loop
898 // works in reverse to maintain the order)
Adam Langleyfcf25832014-12-18 17:42:32 -0800899 ll_append_head(&head, curr, &tail);
David Benjaminf4962492017-09-27 19:34:32 -0400900 curr->active = false;
901 curr->in_group = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800902 }
903 } else if (rule == CIPHER_KILL) {
David Benjaminf4962492017-09-27 19:34:32 -0400904 // reverse == false
Adam Langleyfcf25832014-12-18 17:42:32 -0800905 if (head == curr) {
906 head = curr->next;
907 } else {
908 curr->prev->next = curr->next;
909 }
Adam Langley95c29f32014-06-20 12:00:00 -0700910
Adam Langleyfcf25832014-12-18 17:42:32 -0800911 if (tail == curr) {
912 tail = curr->prev;
913 }
David Benjaminf4962492017-09-27 19:34:32 -0400914 curr->active = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800915 if (curr->next != NULL) {
916 curr->next->prev = curr->prev;
917 }
918 if (curr->prev != NULL) {
919 curr->prev->next = curr->next;
920 }
921 curr->next = NULL;
922 curr->prev = NULL;
923 }
924 }
Adam Langley95c29f32014-06-20 12:00:00 -0700925
Adam Langleyfcf25832014-12-18 17:42:32 -0800926 *head_p = head;
927 *tail_p = tail;
928}
Adam Langley95c29f32014-06-20 12:00:00 -0700929
David Benjaminf4962492017-09-27 19:34:32 -0400930static bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
931 CIPHER_ORDER **tail_p) {
David Benjaminc11ea9422017-08-29 16:33:21 -0400932 // This routine sorts the ciphers with descending strength. The sorting must
933 // keep the pre-sorted sequence, so we apply the normal sorting routine as
934 // '+' movement to the end of the list.
David Benjaminf4962492017-09-27 19:34:32 -0400935 int max_strength_bits = 0;
936 CIPHER_ORDER *curr = *head_p;
Adam Langleyfcf25832014-12-18 17:42:32 -0800937 while (curr != NULL) {
David Benjamin9f2e2772015-11-18 09:59:43 -0500938 if (curr->active &&
939 SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) {
940 max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL);
Adam Langleyfcf25832014-12-18 17:42:32 -0800941 }
942 curr = curr->next;
943 }
Adam Langley95c29f32014-06-20 12:00:00 -0700944
David Benjaminf4962492017-09-27 19:34:32 -0400945 Array<int> number_uses;
946 if (!number_uses.Init(max_strength_bits + 1)) {
947 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800948 }
David Benjaminf4962492017-09-27 19:34:32 -0400949 OPENSSL_memset(number_uses.data(), 0, (max_strength_bits + 1) * sizeof(int));
Adam Langley95c29f32014-06-20 12:00:00 -0700950
David Benjaminc11ea9422017-08-29 16:33:21 -0400951 // Now find the strength_bits values actually used.
Adam Langleyfcf25832014-12-18 17:42:32 -0800952 curr = *head_p;
953 while (curr != NULL) {
954 if (curr->active) {
David Benjamin9f2e2772015-11-18 09:59:43 -0500955 number_uses[SSL_CIPHER_get_bits(curr->cipher, NULL)]++;
Adam Langleyfcf25832014-12-18 17:42:32 -0800956 }
957 curr = curr->next;
958 }
Adam Langley95c29f32014-06-20 12:00:00 -0700959
David Benjaminc11ea9422017-08-29 16:33:21 -0400960 // Go through the list of used strength_bits values in descending order.
David Benjaminf4962492017-09-27 19:34:32 -0400961 for (int i = max_strength_bits; i >= 0; i--) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800962 if (number_uses[i] > 0) {
David Benjaminf4962492017-09-27 19:34:32 -0400963 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p,
964 tail_p);
Adam Langleyfcf25832014-12-18 17:42:32 -0800965 }
966 }
967
David Benjaminf4962492017-09-27 19:34:32 -0400968 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -0800969}
Adam Langley95c29f32014-06-20 12:00:00 -0700970
David Benjamin5be3a742017-10-28 16:08:58 -0400971static bool ssl_cipher_process_rulestr(const char *rule_str,
David Benjaminf4962492017-09-27 19:34:32 -0400972 CIPHER_ORDER **head_p,
973 CIPHER_ORDER **tail_p, bool strict) {
David Benjamind6e9eec2015-11-18 09:48:55 -0500974 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -0500975 uint16_t min_version;
Adam Langleyfcf25832014-12-18 17:42:32 -0800976 const char *l, *buf;
David Benjaminf4962492017-09-27 19:34:32 -0400977 int rule;
978 bool multi, skip_rule, in_group = false, has_group = false;
David Benjamin0344daf2015-04-08 02:08:01 -0400979 size_t j, buf_len;
980 uint32_t cipher_id;
Adam Langleyfcf25832014-12-18 17:42:32 -0800981 char ch;
Adam Langley95c29f32014-06-20 12:00:00 -0700982
Adam Langleyfcf25832014-12-18 17:42:32 -0800983 l = rule_str;
984 for (;;) {
985 ch = *l;
Adam Langley95c29f32014-06-20 12:00:00 -0700986
Adam Langleyfcf25832014-12-18 17:42:32 -0800987 if (ch == '\0') {
David Benjaminc11ea9422017-08-29 16:33:21 -0400988 break; // done
Adam Langleyfcf25832014-12-18 17:42:32 -0800989 }
Adam Langley95c29f32014-06-20 12:00:00 -0700990
Adam Langleyfcf25832014-12-18 17:42:32 -0800991 if (in_group) {
992 if (ch == ']') {
Adam Langleyfcf25832014-12-18 17:42:32 -0800993 if (*tail_p) {
David Benjaminf4962492017-09-27 19:34:32 -0400994 (*tail_p)->in_group = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800995 }
David Benjaminf4962492017-09-27 19:34:32 -0400996 in_group = false;
Adam Langleyfcf25832014-12-18 17:42:32 -0800997 l++;
998 continue;
999 }
David Benjamin37d92462014-09-20 17:54:24 -04001000
Adam Langleyfcf25832014-12-18 17:42:32 -08001001 if (ch == '|') {
1002 rule = CIPHER_ADD;
1003 l++;
1004 continue;
Bob Beck00c70b82023-02-01 12:41:49 -07001005 } else if (!OPENSSL_isalnum(ch)) {
David Benjamin3570d732015-06-29 00:28:17 -04001006 OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
David Benjaminf4962492017-09-27 19:34:32 -04001007 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001008 } else {
1009 rule = CIPHER_ADD;
1010 }
1011 } else if (ch == '-') {
1012 rule = CIPHER_DEL;
1013 l++;
1014 } else if (ch == '+') {
1015 rule = CIPHER_ORD;
1016 l++;
1017 } else if (ch == '!') {
1018 rule = CIPHER_KILL;
1019 l++;
1020 } else if (ch == '@') {
1021 rule = CIPHER_SPECIAL;
1022 l++;
1023 } else if (ch == '[') {
David Benjaminbf5f1922017-07-01 11:13:53 -04001024 assert(!in_group);
David Benjaminf4962492017-09-27 19:34:32 -04001025 in_group = true;
1026 has_group = true;
Adam Langleyfcf25832014-12-18 17:42:32 -08001027 l++;
1028 continue;
1029 } else {
1030 rule = CIPHER_ADD;
1031 }
Adam Langley95c29f32014-06-20 12:00:00 -07001032
David Benjaminc11ea9422017-08-29 16:33:21 -04001033 // If preference groups are enabled, the only legal operator is +.
1034 // Otherwise the in_group bits will get mixed up.
Adam Langleyfcf25832014-12-18 17:42:32 -08001035 if (has_group && rule != CIPHER_ADD) {
David Benjamin3570d732015-06-29 00:28:17 -04001036 OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
David Benjaminf4962492017-09-27 19:34:32 -04001037 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001038 }
Adam Langley95c29f32014-06-20 12:00:00 -07001039
Adam Langley22df6912017-07-25 12:27:37 -07001040 if (is_cipher_list_separator(ch, strict)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001041 l++;
1042 continue;
1043 }
Adam Langley95c29f32014-06-20 12:00:00 -07001044
David Benjaminf4962492017-09-27 19:34:32 -04001045 multi = false;
David Benjamin0344daf2015-04-08 02:08:01 -04001046 cipher_id = 0;
1047 alg_mkey = ~0u;
1048 alg_auth = ~0u;
1049 alg_enc = ~0u;
1050 alg_mac = ~0u;
David Benjamindcb6ef02015-11-06 15:35:54 -05001051 min_version = 0;
David Benjaminf4962492017-09-27 19:34:32 -04001052 skip_rule = false;
Adam Langley95c29f32014-06-20 12:00:00 -07001053
Adam Langleyfcf25832014-12-18 17:42:32 -08001054 for (;;) {
1055 ch = *l;
1056 buf = l;
David Benjamin0344daf2015-04-08 02:08:01 -04001057 buf_len = 0;
Bob Beck00c70b82023-02-01 12:41:49 -07001058 while (OPENSSL_isalnum(ch) || ch == '-' || ch == '.' || ch == '_') {
Adam Langleyfcf25832014-12-18 17:42:32 -08001059 ch = *(++l);
David Benjamin0344daf2015-04-08 02:08:01 -04001060 buf_len++;
Adam Langleyfcf25832014-12-18 17:42:32 -08001061 }
Adam Langley95c29f32014-06-20 12:00:00 -07001062
David Benjamin0344daf2015-04-08 02:08:01 -04001063 if (buf_len == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001064 // We hit something we cannot deal with, it is no command or separator
1065 // nor alphanumeric, so we call this an error.
David Benjamin3570d732015-06-29 00:28:17 -04001066 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjaminf4962492017-09-27 19:34:32 -04001067 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001068 }
Adam Langley95c29f32014-06-20 12:00:00 -07001069
Adam Langleyfcf25832014-12-18 17:42:32 -08001070 if (rule == CIPHER_SPECIAL) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001071 break;
1072 }
David Benjamin0344daf2015-04-08 02:08:01 -04001073
David Benjaminc11ea9422017-08-29 16:33:21 -04001074 // Look for a matching exact cipher. These aren't allowed in multipart
1075 // rules.
David Benjamin0344daf2015-04-08 02:08:01 -04001076 if (!multi && ch != '+') {
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07001077 for (j = 0; j < OPENSSL_ARRAY_SIZE(kCiphers); j++) {
David Benjamina1c90a52015-05-30 17:03:14 -04001078 const SSL_CIPHER *cipher = &kCiphers[j];
David Benjamin6fff3862017-06-21 21:07:04 -04001079 if (rule_equals(cipher->name, buf, buf_len) ||
1080 rule_equals(cipher->standard_name, buf, buf_len)) {
David Benjamin0344daf2015-04-08 02:08:01 -04001081 cipher_id = cipher->id;
1082 break;
1083 }
1084 }
1085 }
1086 if (cipher_id == 0) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001087 // If not an exact cipher, look for a matching cipher alias.
David Benjamina1c90a52015-05-30 17:03:14 -04001088 for (j = 0; j < kCipherAliasesLen; j++) {
David Benjamin0344daf2015-04-08 02:08:01 -04001089 if (rule_equals(kCipherAliases[j].name, buf, buf_len)) {
1090 alg_mkey &= kCipherAliases[j].algorithm_mkey;
1091 alg_auth &= kCipherAliases[j].algorithm_auth;
1092 alg_enc &= kCipherAliases[j].algorithm_enc;
1093 alg_mac &= kCipherAliases[j].algorithm_mac;
David Benjamindcb6ef02015-11-06 15:35:54 -05001094
1095 if (min_version != 0 &&
1096 min_version != kCipherAliases[j].min_version) {
David Benjaminf4962492017-09-27 19:34:32 -04001097 skip_rule = true;
David Benjamindcb6ef02015-11-06 15:35:54 -05001098 } else {
1099 min_version = kCipherAliases[j].min_version;
1100 }
David Benjamin0344daf2015-04-08 02:08:01 -04001101 break;
1102 }
1103 }
David Benjamina1c90a52015-05-30 17:03:14 -04001104 if (j == kCipherAliasesLen) {
David Benjaminf4962492017-09-27 19:34:32 -04001105 skip_rule = true;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001106 if (strict) {
1107 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjaminf4962492017-09-27 19:34:32 -04001108 return false;
Matthew Braithwaitea57dcfb2017-02-17 22:08:23 -08001109 }
David Benjamin0344daf2015-04-08 02:08:01 -04001110 }
1111 }
1112
David Benjaminc11ea9422017-08-29 16:33:21 -04001113 // Check for a multipart rule.
David Benjamin0344daf2015-04-08 02:08:01 -04001114 if (ch != '+') {
1115 break;
1116 }
1117 l++;
David Benjaminf4962492017-09-27 19:34:32 -04001118 multi = true;
Adam Langleyfcf25832014-12-18 17:42:32 -08001119 }
Adam Langley95c29f32014-06-20 12:00:00 -07001120
David Benjaminc11ea9422017-08-29 16:33:21 -04001121 // Ok, we have the rule, now apply it.
Adam Langleyfcf25832014-12-18 17:42:32 -08001122 if (rule == CIPHER_SPECIAL) {
David Benjaminbf5f1922017-07-01 11:13:53 -04001123 if (buf_len != 8 || strncmp(buf, "STRENGTH", 8) != 0) {
David Benjamin3570d732015-06-29 00:28:17 -04001124 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjaminf4962492017-09-27 19:34:32 -04001125 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001126 }
David Benjaminbf5f1922017-07-01 11:13:53 -04001127 if (!ssl_cipher_strength_sort(head_p, tail_p)) {
David Benjaminf4962492017-09-27 19:34:32 -04001128 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001129 }
Adam Langley95c29f32014-06-20 12:00:00 -07001130
David Benjaminc11ea9422017-08-29 16:33:21 -04001131 // We do not support any "multi" options together with "@", so throw away
1132 // the rest of the command, if any left, until end or ':' is found.
Adam Langley22df6912017-07-25 12:27:37 -07001133 while (*l != '\0' && !is_cipher_list_separator(*l, strict)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001134 l++;
1135 }
David Benjamindcb6ef02015-11-06 15:35:54 -05001136 } else if (!skip_rule) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001137 ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac,
David Benjamind6e9eec2015-11-18 09:48:55 -05001138 min_version, rule, -1, in_group, head_p, tail_p);
Adam Langleyfcf25832014-12-18 17:42:32 -08001139 }
1140 }
Adam Langley95c29f32014-06-20 12:00:00 -07001141
Adam Langleyfcf25832014-12-18 17:42:32 -08001142 if (in_group) {
David Benjamin3570d732015-06-29 00:28:17 -04001143 OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
David Benjaminf4962492017-09-27 19:34:32 -04001144 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001145 }
Adam Langley95c29f32014-06-20 12:00:00 -07001146
David Benjaminf4962492017-09-27 19:34:32 -04001147 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08001148}
Adam Langley95c29f32014-06-20 12:00:00 -07001149
David Benjamin0ce090a2018-07-02 20:24:40 -04001150bool ssl_create_cipher_list(UniquePtr<SSLCipherPreferenceList> *out_cipher_list,
Bob Beck8cacbd92023-04-05 14:38:38 -06001151 const bool has_aes_hw, const char *rule_str,
1152 bool strict) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001153 // Return with error if nothing to do.
David Benjamin71f07942015-04-08 02:36:59 -04001154 if (rule_str == NULL || out_cipher_list == NULL) {
David Benjaminf4962492017-09-27 19:34:32 -04001155 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001156 }
David Benjamin5213df42014-08-20 14:19:54 -04001157
David Benjaminc11ea9422017-08-29 16:33:21 -04001158 // Now we have to collect the available ciphers from the compiled in ciphers.
1159 // We cannot get more than the number compiled in, so it is used for
1160 // allocation.
David Benjamin48b276d2018-04-12 17:37:32 -04001161 Array<CIPHER_ORDER> co_list;
1162 CIPHER_ORDER *head = nullptr, *tail = nullptr;
1163 if (!ssl_cipher_collect_ciphers(&co_list, &head, &tail)) {
David Benjaminf4962492017-09-27 19:34:32 -04001164 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001165 }
Adam Langley95c29f32014-06-20 12:00:00 -07001166
David Benjaminc11ea9422017-08-29 16:33:21 -04001167 // Now arrange all ciphers by preference:
1168 // TODO(davidben): Compute this order once and copy it.
Adam Langley95c29f32014-06-20 12:00:00 -07001169
David Benjaminc11ea9422017-08-29 16:33:21 -04001170 // Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other
1171 // key exchange mechanisms
David Benjamind6e9eec2015-11-18 09:48:55 -05001172 ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1,
David Benjaminf4962492017-09-27 19:34:32 -04001173 false, &head, &tail);
1174 ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false,
David Benjamind6e9eec2015-11-18 09:48:55 -05001175 &head, &tail);
David Benjaminf4962492017-09-27 19:34:32 -04001176 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head,
Steven Valdez803c77a2016-09-06 14:13:43 -04001177 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001178
David Benjaminc11ea9422017-08-29 16:33:21 -04001179 // Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
1180 // CHACHA20 unless there is hardware support for fast and constant-time
1181 // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the
1182 // old one.
Bob Beck8cacbd92023-04-05 14:38:38 -06001183 if (has_aes_hw) {
David Benjaminf4962492017-09-27 19:34:32 -04001184 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1,
1185 false, &head, &tail);
1186 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1,
1187 false, &head, &tail);
David Benjamin13414b32015-12-09 23:02:39 -05001188 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
David Benjaminf4962492017-09-27 19:34:32 -04001189 -1, false, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001190 } else {
David Benjamin13414b32015-12-09 23:02:39 -05001191 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
David Benjaminf4962492017-09-27 19:34:32 -04001192 -1, false, &head, &tail);
1193 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1,
1194 false, &head, &tail);
1195 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1,
1196 false, &head, &tail);
Adam Langleyfcf25832014-12-18 17:42:32 -08001197 }
Adam Langley95c29f32014-06-20 12:00:00 -07001198
David Benjaminc11ea9422017-08-29 16:33:21 -04001199 // Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC,
1200 // 3DES_EDE_CBC_SHA.
David Benjaminf4962492017-09-27 19:34:32 -04001201 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false,
David Benjamind6e9eec2015-11-18 09:48:55 -05001202 &head, &tail);
David Benjaminf4962492017-09-27 19:34:32 -04001203 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false,
David Benjamin43336652016-03-03 15:32:29 -05001204 &head, &tail);
David Benjaminf4962492017-09-27 19:34:32 -04001205 ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false,
1206 &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001207
David Benjaminc11ea9422017-08-29 16:33:21 -04001208 // Temporarily enable everything else for sorting
David Benjaminf4962492017-09-27 19:34:32 -04001209 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head,
David Benjamind6e9eec2015-11-18 09:48:55 -05001210 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001211
David Benjaminc11ea9422017-08-29 16:33:21 -04001212 // Move ciphers without forward secrecy to the end.
David Benjaminf4962492017-09-27 19:34:32 -04001213 ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD,
1214 -1, false, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001215
David Benjaminc11ea9422017-08-29 16:33:21 -04001216 // Now disable everything (maintaining the ordering!)
David Benjaminf4962492017-09-27 19:34:32 -04001217 ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head,
David Benjamind6e9eec2015-11-18 09:48:55 -05001218 &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001219
David Benjaminc11ea9422017-08-29 16:33:21 -04001220 // If the rule_string begins with DEFAULT, apply the default rule before
1221 // using the (possibly available) additional rules.
David Benjamin11a7b3c2016-11-03 17:03:48 -04001222 const char *rule_p = rule_str;
Adam Langleyfcf25832014-12-18 17:42:32 -08001223 if (strncmp(rule_str, "DEFAULT", 7) == 0) {
David Benjamin5be3a742017-10-28 16:08:58 -04001224 if (!ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, &head, &tail,
1225 strict)) {
David Benjamin48b276d2018-04-12 17:37:32 -04001226 return false;
David Benjamin11a7b3c2016-11-03 17:03:48 -04001227 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001228 rule_p += 7;
1229 if (*rule_p == ':') {
1230 rule_p++;
1231 }
1232 }
Adam Langley858a88d2014-06-20 12:00:00 -07001233
David Benjamin11a7b3c2016-11-03 17:03:48 -04001234 if (*rule_p != '\0' &&
David Benjamin5be3a742017-10-28 16:08:58 -04001235 !ssl_cipher_process_rulestr(rule_p, &head, &tail, strict)) {
David Benjamin48b276d2018-04-12 17:37:32 -04001236 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001237 }
1238
David Benjaminc11ea9422017-08-29 16:33:21 -04001239 // Allocate new "cipherstack" for the result, return with error
1240 // if we cannot get one.
David Benjamin48b276d2018-04-12 17:37:32 -04001241 UniquePtr<STACK_OF(SSL_CIPHER)> cipherstack(sk_SSL_CIPHER_new_null());
1242 Array<bool> in_group_flags;
1243 if (cipherstack == nullptr ||
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07001244 !in_group_flags.Init(OPENSSL_ARRAY_SIZE(kCiphers))) {
David Benjamin48b276d2018-04-12 17:37:32 -04001245 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001246 }
1247
David Benjaminc11ea9422017-08-29 16:33:21 -04001248 // The cipher selection for the list is done. The ciphers are added
1249 // to the resulting precedence to the STACK_OF(SSL_CIPHER).
David Benjamin48b276d2018-04-12 17:37:32 -04001250 size_t num_in_group_flags = 0;
1251 for (CIPHER_ORDER *curr = head; curr != NULL; curr = curr->next) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001252 if (curr->active) {
David Benjamin48b276d2018-04-12 17:37:32 -04001253 if (!sk_SSL_CIPHER_push(cipherstack.get(), curr->cipher)) {
1254 return false;
David Benjamin2adb7ec2015-01-11 19:59:06 -05001255 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001256 in_group_flags[num_in_group_flags++] = curr->in_group;
1257 }
1258 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001259
David Benjamin48b276d2018-04-12 17:37:32 -04001260 UniquePtr<SSLCipherPreferenceList> pref_list =
1261 MakeUnique<SSLCipherPreferenceList>();
1262 if (!pref_list ||
1263 !pref_list->Init(
1264 std::move(cipherstack),
1265 MakeConstSpan(in_group_flags).subspan(0, num_in_group_flags))) {
1266 return false;
Adam Langleyfcf25832014-12-18 17:42:32 -08001267 }
David Benjamin48b276d2018-04-12 17:37:32 -04001268
David Benjamin0ce090a2018-07-02 20:24:40 -04001269 *out_cipher_list = std::move(pref_list);
Adam Langleyfcf25832014-12-18 17:42:32 -08001270
David Benjaminc11ea9422017-08-29 16:33:21 -04001271 // Configuring an empty cipher list is an error but still updates the
1272 // output.
David Benjamin48b276d2018-04-12 17:37:32 -04001273 if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers.get()) == 0) {
David Benjamin91222b82017-03-09 20:10:56 -05001274 OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
David Benjaminf4962492017-09-27 19:34:32 -04001275 return false;
David Benjamin91222b82017-03-09 20:10:56 -05001276 }
1277
David Benjaminf4962492017-09-27 19:34:32 -04001278 return true;
Adam Langleyfcf25832014-12-18 17:42:32 -08001279}
Adam Langley95c29f32014-06-20 12:00:00 -07001280
David Benjamin86e95b82017-07-18 16:34:25 -04001281uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) {
1282 switch (EVP_PKEY_id(key)) {
1283 case EVP_PKEY_RSA:
1284 return SSL_aRSA;
1285 case EVP_PKEY_EC:
1286 case EVP_PKEY_ED25519:
David Benjaminc11ea9422017-08-29 16:33:21 -04001287 // Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers.
David Benjamin86e95b82017-07-18 16:34:25 -04001288 return SSL_aECDSA;
1289 default:
1290 return 0;
1291 }
1292}
1293
David Benjaminf4962492017-09-27 19:34:32 -04001294bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) {
David Benjamin86e95b82017-07-18 16:34:25 -04001295 return (cipher->algorithm_auth & SSL_aCERT) != 0;
1296}
1297
David Benjaminf4962492017-09-27 19:34:32 -04001298bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
1299 // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. It is
1300 // optional or omitted in all others.
1301 return (cipher->algorithm_mkey & SSL_kECDHE) != 0;
David Benjamin86e95b82017-07-18 16:34:25 -04001302}
1303
1304size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
1305 size_t block_size;
1306 switch (cipher->algorithm_enc) {
1307 case SSL_3DES:
1308 block_size = 8;
1309 break;
1310 case SSL_AES128:
1311 case SSL_AES256:
1312 block_size = 16;
1313 break;
1314 default:
1315 return 0;
1316 }
1317
David Benjaminc11ea9422017-08-29 16:33:21 -04001318 // All supported TLS 1.0 ciphers use SHA-1.
David Benjamin86e95b82017-07-18 16:34:25 -04001319 assert(cipher->algorithm_mac == SSL_SHA1);
1320 size_t ret = 1 + SHA_DIGEST_LENGTH;
1321 ret += block_size - (ret % block_size);
1322 return ret;
1323}
1324
Joshua Liebow-Feeser8c7c6352018-08-26 18:53:36 -07001325BSSL_NAMESPACE_END
David Benjamin86e95b82017-07-18 16:34:25 -04001326
1327using namespace bssl;
1328
David Benjamin493d5cb2022-04-18 17:20:27 -04001329static constexpr int ssl_cipher_id_cmp(const SSL_CIPHER *a,
1330 const SSL_CIPHER *b) {
1331 if (a->id > b->id) {
1332 return 1;
1333 }
1334 if (a->id < b->id) {
1335 return -1;
1336 }
1337 return 0;
MichaƂ Janiszewskic4f3b8a2018-07-30 22:50:40 +02001338}
1339
David Benjamin493d5cb2022-04-18 17:20:27 -04001340static int ssl_cipher_id_cmp_void(const void *in_a, const void *in_b) {
1341 return ssl_cipher_id_cmp(reinterpret_cast<const SSL_CIPHER *>(in_a),
1342 reinterpret_cast<const SSL_CIPHER *>(in_b));
MichaƂ Janiszewskic4f3b8a2018-07-30 22:50:40 +02001343}
1344
David Benjamin493d5cb2022-04-18 17:20:27 -04001345template <size_t N>
1346static constexpr bool ssl_ciphers_sorted(const SSL_CIPHER (&ciphers)[N]) {
1347 for (size_t i = 1; i < N; i++) {
1348 if (ssl_cipher_id_cmp(&ciphers[i - 1], &ciphers[i]) >= 0) {
1349 return false;
1350 }
1351 }
1352 return true;
MichaƂ Janiszewskic4f3b8a2018-07-30 22:50:40 +02001353}
1354
David Benjamin493d5cb2022-04-18 17:20:27 -04001355static_assert(ssl_ciphers_sorted(kCiphers),
MichaƂ Janiszewskic4f3b8a2018-07-30 22:50:40 +02001356 "Ciphers are not sorted, bsearch won't work");
1357
David Benjamin86e95b82017-07-18 16:34:25 -04001358const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) {
1359 SSL_CIPHER c;
1360
1361 c.id = 0x03000000L | value;
1362 return reinterpret_cast<const SSL_CIPHER *>(bsearch(
Matthew Braithwaited2ed3822018-07-10 16:27:22 -07001363 &c, kCiphers, OPENSSL_ARRAY_SIZE(kCiphers), sizeof(SSL_CIPHER),
David Benjamin493d5cb2022-04-18 17:20:27 -04001364 ssl_cipher_id_cmp_void));
David Benjamin86e95b82017-07-18 16:34:25 -04001365}
1366
1367uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; }
1368
David Benjamin3743aaf2020-09-21 13:55:16 -04001369uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *cipher) {
1370 // All OpenSSL cipher IDs are prefaced with 0x03. Historically this referred
1371 // to SSLv2 vs SSLv3.
1372 assert((cipher->id & 0xff000000) == 0x03000000);
Adam Langley04a89c82019-09-18 14:31:00 -07001373 return static_cast<uint16_t>(cipher->id);
1374}
1375
David Benjamin3743aaf2020-09-21 13:55:16 -04001376uint16_t SSL_CIPHER_get_value(const SSL_CIPHER *cipher) {
1377 return SSL_CIPHER_get_protocol_id(cipher);
1378}
1379
David Benjamin348f0d82017-08-10 16:06:27 -04001380int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher) {
Alessandro Ghedini0726fb72017-01-17 13:27:08 +00001381 return (cipher->algorithm_mac & SSL_AEAD) != 0;
1382}
1383
David Benjamin348f0d82017-08-10 16:06:27 -04001384int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher) {
1385 switch (cipher->algorithm_enc) {
1386 case SSL_eNULL:
1387 return NID_undef;
1388 case SSL_3DES:
1389 return NID_des_ede3_cbc;
1390 case SSL_AES128:
1391 return NID_aes_128_cbc;
1392 case SSL_AES256:
1393 return NID_aes_256_cbc;
1394 case SSL_AES128GCM:
1395 return NID_aes_128_gcm;
1396 case SSL_AES256GCM:
1397 return NID_aes_256_gcm;
1398 case SSL_CHACHA20POLY1305:
1399 return NID_chacha20_poly1305;
1400 }
1401 assert(0);
1402 return NID_undef;
1403}
1404
1405int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher) {
1406 switch (cipher->algorithm_mac) {
1407 case SSL_AEAD:
1408 return NID_undef;
1409 case SSL_SHA1:
1410 return NID_sha1;
David Benjamin348f0d82017-08-10 16:06:27 -04001411 }
1412 assert(0);
1413 return NID_undef;
1414}
1415
1416int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher) {
1417 switch (cipher->algorithm_mkey) {
1418 case SSL_kRSA:
1419 return NID_kx_rsa;
1420 case SSL_kECDHE:
1421 return NID_kx_ecdhe;
1422 case SSL_kPSK:
1423 return NID_kx_psk;
1424 case SSL_kGENERIC:
1425 return NID_kx_any;
1426 }
1427 assert(0);
1428 return NID_undef;
1429}
1430
1431int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher) {
1432 switch (cipher->algorithm_auth) {
1433 case SSL_aRSA:
1434 return NID_auth_rsa;
1435 case SSL_aECDSA:
1436 return NID_auth_ecdsa;
1437 case SSL_aPSK:
1438 return NID_auth_psk;
1439 case SSL_aGENERIC:
1440 return NID_auth_any;
1441 }
1442 assert(0);
1443 return NID_undef;
1444}
1445
David Benjaminb1b76ae2017-09-21 17:03:34 -04001446int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) {
1447 switch (cipher->algorithm_prf) {
1448 case SSL_HANDSHAKE_MAC_DEFAULT:
1449 return NID_md5_sha1;
1450 case SSL_HANDSHAKE_MAC_SHA256:
1451 return NID_sha256;
1452 case SSL_HANDSHAKE_MAC_SHA384:
1453 return NID_sha384;
1454 }
1455 assert(0);
1456 return NID_undef;
1457}
1458
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001459int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) {
Matthew Braithwaite8aaa9e12016-09-07 15:09:58 -07001460 return (cipher->algorithm_enc & SSL_eNULL) == 0 &&
Matt Braithwaiteaf096752015-09-02 19:48:16 -07001461 cipher->algorithm_mac != SSL_AEAD;
1462}
1463
David Benjaminef793f42015-11-05 18:16:27 -05001464uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) {
Steven Valdez803c77a2016-09-06 14:13:43 -04001465 if (cipher->algorithm_mkey == SSL_kGENERIC ||
1466 cipher->algorithm_auth == SSL_aGENERIC) {
1467 return TLS1_3_VERSION;
1468 }
1469
David Benjamindcb6ef02015-11-06 15:35:54 -05001470 if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) {
David Benjaminc11ea9422017-08-29 16:33:21 -04001471 // Cipher suites before TLS 1.2 use the default PRF, while all those added
1472 // afterwards specify a particular hash.
David Benjaminef793f42015-11-05 18:16:27 -05001473 return TLS1_2_VERSION;
1474 }
1475 return SSL3_VERSION;
1476}
1477
Nick Harper1fd39d82016-06-14 18:14:35 -07001478uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) {
Steven Valdez803c77a2016-09-06 14:13:43 -04001479 if (cipher->algorithm_mkey == SSL_kGENERIC ||
1480 cipher->algorithm_auth == SSL_aGENERIC) {
Nick Harper1fd39d82016-06-14 18:14:35 -07001481 return TLS1_3_VERSION;
1482 }
1483 return TLS1_2_VERSION;
1484}
1485
David Benjaminc11ea9422017-08-29 16:33:21 -04001486// return the actual cipher being used
David Benjamin71f07942015-04-08 02:36:59 -04001487const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) {
1488 if (cipher != NULL) {
1489 return cipher->name;
1490 }
1491
1492 return "(NONE)";
1493}
1494
David Benjamin6fff3862017-06-21 21:07:04 -04001495const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher) {
1496 return cipher->standard_name;
1497}
1498
David Benjamin71f07942015-04-08 02:36:59 -04001499const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) {
1500 if (cipher == NULL) {
1501 return "";
1502 }
1503
1504 switch (cipher->algorithm_mkey) {
1505 case SSL_kRSA:
1506 return "RSA";
1507
David Benjamin71f07942015-04-08 02:36:59 -04001508 case SSL_kECDHE:
1509 switch (cipher->algorithm_auth) {
1510 case SSL_aECDSA:
1511 return "ECDHE_ECDSA";
1512 case SSL_aRSA:
1513 return "ECDHE_RSA";
1514 case SSL_aPSK:
1515 return "ECDHE_PSK";
1516 default:
1517 assert(0);
1518 return "UNKNOWN";
1519 }
1520
1521 case SSL_kPSK:
1522 assert(cipher->algorithm_auth == SSL_aPSK);
1523 return "PSK";
1524
Steven Valdez803c77a2016-09-06 14:13:43 -04001525 case SSL_kGENERIC:
1526 assert(cipher->algorithm_auth == SSL_aGENERIC);
1527 return "GENERIC";
1528
David Benjamin71f07942015-04-08 02:36:59 -04001529 default:
1530 assert(0);
1531 return "UNKNOWN";
1532 }
1533}
1534
David Benjamin71f07942015-04-08 02:36:59 -04001535int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) {
1536 if (cipher == NULL) {
1537 return 0;
1538 }
1539
David Benjamin9f2e2772015-11-18 09:59:43 -05001540 int alg_bits, strength_bits;
1541 switch (cipher->algorithm_enc) {
1542 case SSL_AES128:
1543 case SSL_AES128GCM:
David Benjamin9f2e2772015-11-18 09:59:43 -05001544 alg_bits = 128;
1545 strength_bits = 128;
1546 break;
1547
1548 case SSL_AES256:
1549 case SSL_AES256GCM:
David Benjamin13414b32015-12-09 23:02:39 -05001550 case SSL_CHACHA20POLY1305:
David Benjamin9f2e2772015-11-18 09:59:43 -05001551 alg_bits = 256;
1552 strength_bits = 256;
1553 break;
1554
1555 case SSL_3DES:
1556 alg_bits = 168;
1557 strength_bits = 112;
1558 break;
1559
1560 case SSL_eNULL:
1561 alg_bits = 0;
1562 strength_bits = 0;
1563 break;
1564
1565 default:
1566 assert(0);
1567 alg_bits = 0;
1568 strength_bits = 0;
David Benjamin71f07942015-04-08 02:36:59 -04001569 }
David Benjamin9f2e2772015-11-18 09:59:43 -05001570
1571 if (out_alg_bits != NULL) {
1572 *out_alg_bits = alg_bits;
1573 }
1574 return strength_bits;
David Benjamin71f07942015-04-08 02:36:59 -04001575}
1576
Adam Langleyfcf25832014-12-18 17:42:32 -08001577const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
1578 int len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001579 const char *kx, *au, *enc, *mac;
David Benjamindcb6ef02015-11-06 15:35:54 -05001580 uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
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_kECDHE:
Adam Langleyfcf25832014-12-18 17:42:32 -08001593 kx = "ECDH";
1594 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001595
Adam Langleyfcf25832014-12-18 17:42:32 -08001596 case SSL_kPSK:
1597 kx = "PSK";
1598 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001599
Steven Valdez803c77a2016-09-06 14:13:43 -04001600 case SSL_kGENERIC:
1601 kx = "GENERIC";
1602 break;
1603
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
Steven Valdez803c77a2016-09-06 14:13:43 -04001621 case SSL_aGENERIC:
1622 au = "GENERIC";
1623 break;
1624
Adam Langleyfcf25832014-12-18 17:42:32 -08001625 default:
1626 au = "unknown";
1627 break;
1628 }
Adam Langleyde0b2022014-06-20 12:00:00 -07001629
Adam Langleyfcf25832014-12-18 17:42:32 -08001630 switch (alg_enc) {
1631 case SSL_3DES:
1632 enc = "3DES(168)";
1633 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001634
Adam Langleyfcf25832014-12-18 17:42:32 -08001635 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
David Benjamin13414b32015-12-09 23:02:39 -05001651 case SSL_CHACHA20POLY1305:
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) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001665 case SSL_SHA1:
1666 mac = "SHA1";
1667 break;
1668
Adam Langleyfcf25832014-12-18 17:42:32 -08001669 case SSL_AEAD:
1670 mac = "AEAD";
1671 break;
1672
1673 default:
1674 mac = "unknown";
1675 break;
1676 }
1677
1678 if (buf == NULL) {
1679 len = 128;
David Benjamine64d2c72017-07-12 16:31:08 -04001680 buf = (char *)OPENSSL_malloc(len);
David Benjamin1eed2c02015-02-08 23:20:06 -05001681 if (buf == NULL) {
1682 return NULL;
1683 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001684 } else if (len < 128) {
1685 return "Buffer too small";
1686 }
1687
Brian Smith0687bdf2016-01-17 09:18:26 -10001688 BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n",
1689 cipher->name, kx, au, enc, mac);
Adam Langleyfcf25832014-12-18 17:42:32 -08001690 return buf;
1691}
1692
David Benjamin71f07942015-04-08 02:36:59 -04001693const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
1694 return "TLSv1/SSLv3";
Adam Langleyfcf25832014-12-18 17:42:32 -08001695}
1696
David Benjamind55bd792017-05-18 11:33:08 -04001697STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) { return NULL; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001698
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001699int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
Adam Langleyfcf25832014-12-18 17:42:32 -08001700
Matt Braithwaite6a1275b2015-06-26 12:09:10 -07001701const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; }
Adam Langley95c29f32014-06-20 12:00:00 -07001702
Adam Langleyfa3e9c32018-03-14 17:32:04 -07001703const char *SSL_COMP_get0_name(const SSL_COMP *comp) { return comp->name; }
1704
1705int SSL_COMP_get_id(const SSL_COMP *comp) { return comp->id; }
1706
Adam Langley3e9e0432016-10-03 15:58:07 -07001707void SSL_COMP_free_compression_methods(void) {}