xref: /dflybsd-src/crypto/libressl/ssl/ssl_ciph.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: ssl_ciph.c,v 1.134 2022/09/08 15:31:12 millert Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino  * All rights reserved.
4f5b1c8a1SJohn Marino  *
5f5b1c8a1SJohn Marino  * This package is an SSL implementation written
6f5b1c8a1SJohn Marino  * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino  * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino  *
9f5b1c8a1SJohn Marino  * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino  * the following conditions are aheared to.  The following conditions
11f5b1c8a1SJohn Marino  * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13f5b1c8a1SJohn Marino  * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino  *
16f5b1c8a1SJohn Marino  * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino  * the code are not to be removed.
18f5b1c8a1SJohn Marino  * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino  * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino  * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino  * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino  *
23f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino  * are met:
26f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino  *    documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino  *    must display the following acknowledgement:
33f5b1c8a1SJohn Marino  *    "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino  *     Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino  *    The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino  *    being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino  * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino  *    the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino  *
41f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino  * SUCH DAMAGE.
52f5b1c8a1SJohn Marino  *
53f5b1c8a1SJohn Marino  * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55f5b1c8a1SJohn Marino  * copied and put under another distribution licence
56f5b1c8a1SJohn Marino  * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino  */
58f5b1c8a1SJohn Marino /* ====================================================================
59f5b1c8a1SJohn Marino  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60f5b1c8a1SJohn Marino  *
61f5b1c8a1SJohn Marino  * Redistribution and use in source and binary forms, with or without
62f5b1c8a1SJohn Marino  * modification, are permitted provided that the following conditions
63f5b1c8a1SJohn Marino  * are met:
64f5b1c8a1SJohn Marino  *
65f5b1c8a1SJohn Marino  * 1. Redistributions of source code must retain the above copyright
66f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer.
67f5b1c8a1SJohn Marino  *
68f5b1c8a1SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
69f5b1c8a1SJohn Marino  *    notice, this list of conditions and the following disclaimer in
70f5b1c8a1SJohn Marino  *    the documentation and/or other materials provided with the
71f5b1c8a1SJohn Marino  *    distribution.
72f5b1c8a1SJohn Marino  *
73f5b1c8a1SJohn Marino  * 3. All advertising materials mentioning features or use of this
74f5b1c8a1SJohn Marino  *    software must display the following acknowledgment:
75f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
76f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77f5b1c8a1SJohn Marino  *
78f5b1c8a1SJohn Marino  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79f5b1c8a1SJohn Marino  *    endorse or promote products derived from this software without
80f5b1c8a1SJohn Marino  *    prior written permission. For written permission, please contact
81f5b1c8a1SJohn Marino  *    openssl-core@openssl.org.
82f5b1c8a1SJohn Marino  *
83f5b1c8a1SJohn Marino  * 5. Products derived from this software may not be called "OpenSSL"
84f5b1c8a1SJohn Marino  *    nor may "OpenSSL" appear in their names without prior written
85f5b1c8a1SJohn Marino  *    permission of the OpenSSL Project.
86f5b1c8a1SJohn Marino  *
87f5b1c8a1SJohn Marino  * 6. Redistributions of any form whatsoever must retain the following
88f5b1c8a1SJohn Marino  *    acknowledgment:
89f5b1c8a1SJohn Marino  *    "This product includes software developed by the OpenSSL Project
90f5b1c8a1SJohn Marino  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91f5b1c8a1SJohn Marino  *
92f5b1c8a1SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93f5b1c8a1SJohn Marino  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94f5b1c8a1SJohn Marino  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95f5b1c8a1SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96f5b1c8a1SJohn Marino  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97f5b1c8a1SJohn Marino  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98f5b1c8a1SJohn Marino  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99f5b1c8a1SJohn Marino  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100f5b1c8a1SJohn Marino  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101f5b1c8a1SJohn Marino  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102f5b1c8a1SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103f5b1c8a1SJohn Marino  * OF THE POSSIBILITY OF SUCH DAMAGE.
104f5b1c8a1SJohn Marino  * ====================================================================
105f5b1c8a1SJohn Marino  *
106f5b1c8a1SJohn Marino  * This product includes cryptographic software written by Eric Young
107f5b1c8a1SJohn Marino  * (eay@cryptsoft.com).  This product includes software written by Tim
108f5b1c8a1SJohn Marino  * Hudson (tjh@cryptsoft.com).
109f5b1c8a1SJohn Marino  *
110f5b1c8a1SJohn Marino  */
111f5b1c8a1SJohn Marino /* ====================================================================
112f5b1c8a1SJohn Marino  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113f5b1c8a1SJohn Marino  * ECC cipher suite support in OpenSSL originally developed by
114f5b1c8a1SJohn Marino  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115f5b1c8a1SJohn Marino  */
116f5b1c8a1SJohn Marino /* ====================================================================
117f5b1c8a1SJohn Marino  * Copyright 2005 Nokia. All rights reserved.
118f5b1c8a1SJohn Marino  *
119f5b1c8a1SJohn Marino  * The portions of the attached software ("Contribution") is developed by
120f5b1c8a1SJohn Marino  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
121f5b1c8a1SJohn Marino  * license.
122f5b1c8a1SJohn Marino  *
123f5b1c8a1SJohn Marino  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
124f5b1c8a1SJohn Marino  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
125f5b1c8a1SJohn Marino  * support (see RFC 4279) to OpenSSL.
126f5b1c8a1SJohn Marino  *
127f5b1c8a1SJohn Marino  * No patent licenses or other rights except those expressly stated in
128f5b1c8a1SJohn Marino  * the OpenSSL open source license shall be deemed granted or received
129f5b1c8a1SJohn Marino  * expressly, by implication, estoppel, or otherwise.
130f5b1c8a1SJohn Marino  *
131f5b1c8a1SJohn Marino  * No assurances are provided by Nokia that the Contribution does not
132f5b1c8a1SJohn Marino  * infringe the patent or other intellectual property rights of any third
133f5b1c8a1SJohn Marino  * party or that the license provides you with all the necessary rights
134f5b1c8a1SJohn Marino  * to make use of the Contribution.
135f5b1c8a1SJohn Marino  *
136f5b1c8a1SJohn Marino  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
137f5b1c8a1SJohn Marino  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
138f5b1c8a1SJohn Marino  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
139f5b1c8a1SJohn Marino  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
140f5b1c8a1SJohn Marino  * OTHERWISE.
141f5b1c8a1SJohn Marino  */
142f5b1c8a1SJohn Marino 
143f5b1c8a1SJohn Marino #include <stdio.h>
144f5b1c8a1SJohn Marino 
145f5b1c8a1SJohn Marino #include <openssl/objects.h>
146*de0e0e4dSAntonio Huete Jimenez #include <openssl/opensslconf.h>
147f5b1c8a1SJohn Marino 
148f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
149f5b1c8a1SJohn Marino #include <openssl/engine.h>
150f5b1c8a1SJohn Marino #endif
151f5b1c8a1SJohn Marino 
152f5b1c8a1SJohn Marino #include "ssl_locl.h"
153f5b1c8a1SJohn Marino 
154f5b1c8a1SJohn Marino #define CIPHER_ADD	1
155f5b1c8a1SJohn Marino #define CIPHER_KILL	2
156f5b1c8a1SJohn Marino #define CIPHER_DEL	3
157f5b1c8a1SJohn Marino #define CIPHER_ORD	4
158f5b1c8a1SJohn Marino #define CIPHER_SPECIAL	5
159f5b1c8a1SJohn Marino 
160f5b1c8a1SJohn Marino typedef struct cipher_order_st {
161f5b1c8a1SJohn Marino 	const SSL_CIPHER *cipher;
162f5b1c8a1SJohn Marino 	int active;
163f5b1c8a1SJohn Marino 	int dead;
164f5b1c8a1SJohn Marino 	struct cipher_order_st *next, *prev;
165f5b1c8a1SJohn Marino } CIPHER_ORDER;
166f5b1c8a1SJohn Marino 
167f5b1c8a1SJohn Marino static const SSL_CIPHER cipher_aliases[] = {
168f5b1c8a1SJohn Marino 
169f5b1c8a1SJohn Marino 	/* "ALL" doesn't include eNULL (must be specifically enabled) */
170f5b1c8a1SJohn Marino 	{
171f5b1c8a1SJohn Marino 		.name = SSL_TXT_ALL,
172f5b1c8a1SJohn Marino 		.algorithm_enc = ~SSL_eNULL,
173f5b1c8a1SJohn Marino 	},
174f5b1c8a1SJohn Marino 
175f5b1c8a1SJohn Marino 	/* "COMPLEMENTOFALL" */
176f5b1c8a1SJohn Marino 	{
177f5b1c8a1SJohn Marino 		.name = SSL_TXT_CMPALL,
178f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
179f5b1c8a1SJohn Marino 	},
180f5b1c8a1SJohn Marino 
181f5b1c8a1SJohn Marino 	/*
182f5b1c8a1SJohn Marino 	 * "COMPLEMENTOFDEFAULT"
183f5b1c8a1SJohn Marino 	 * (does *not* include ciphersuites not found in ALL!)
184f5b1c8a1SJohn Marino 	 */
185f5b1c8a1SJohn Marino 	{
186f5b1c8a1SJohn Marino 		.name = SSL_TXT_CMPDEF,
187f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE|SSL_kECDHE,
188f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
189f5b1c8a1SJohn Marino 		.algorithm_enc = ~SSL_eNULL,
190f5b1c8a1SJohn Marino 	},
191f5b1c8a1SJohn Marino 
192f5b1c8a1SJohn Marino 	/*
193f5b1c8a1SJohn Marino 	 * key exchange aliases
194f5b1c8a1SJohn Marino 	 * (some of those using only a single bit here combine multiple key
195f5b1c8a1SJohn Marino 	 * exchange algs according to the RFCs, e.g. kEDH combines DHE_DSS
196f5b1c8a1SJohn Marino 	 * and DHE_RSA)
197f5b1c8a1SJohn Marino 	 */
198f5b1c8a1SJohn Marino 	{
199f5b1c8a1SJohn Marino 		.name = SSL_TXT_kRSA,
200f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kRSA,
201f5b1c8a1SJohn Marino 	},
202f5b1c8a1SJohn Marino 	{
203f5b1c8a1SJohn Marino 		.name = SSL_TXT_kEDH,
204f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
205f5b1c8a1SJohn Marino 	},
206f5b1c8a1SJohn Marino 	{
207f5b1c8a1SJohn Marino 		.name = SSL_TXT_DH,
208f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
209f5b1c8a1SJohn Marino 	},
210f5b1c8a1SJohn Marino 	{
211f5b1c8a1SJohn Marino 		.name = SSL_TXT_kEECDH,
212f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
213f5b1c8a1SJohn Marino 	},
214f5b1c8a1SJohn Marino 	{
215f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDH,
21672c33676SMaxim Ag 		.algorithm_mkey = SSL_kECDHE,
217f5b1c8a1SJohn Marino 	},
218f5b1c8a1SJohn Marino 	{
219f5b1c8a1SJohn Marino 		.name = SSL_TXT_kGOST,
220f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kGOST,
221f5b1c8a1SJohn Marino 	},
222f5b1c8a1SJohn Marino 
223f5b1c8a1SJohn Marino 	/* server authentication aliases */
224f5b1c8a1SJohn Marino 	{
225f5b1c8a1SJohn Marino 		.name = SSL_TXT_aRSA,
226f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aRSA,
227f5b1c8a1SJohn Marino 	},
228f5b1c8a1SJohn Marino 	{
229f5b1c8a1SJohn Marino 		.name = SSL_TXT_aDSS,
230f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aDSS,
231f5b1c8a1SJohn Marino 	},
232f5b1c8a1SJohn Marino 	{
233f5b1c8a1SJohn Marino 		.name = SSL_TXT_DSS,
234f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aDSS,
235f5b1c8a1SJohn Marino 	},
236f5b1c8a1SJohn Marino 	{
237f5b1c8a1SJohn Marino 		.name = SSL_TXT_aNULL,
238f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
239f5b1c8a1SJohn Marino 	},
240f5b1c8a1SJohn Marino 	{
241f5b1c8a1SJohn Marino 		.name = SSL_TXT_aECDSA,
242f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aECDSA,
243f5b1c8a1SJohn Marino 	},
244f5b1c8a1SJohn Marino 	{
245f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDSA,
246f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aECDSA,
247f5b1c8a1SJohn Marino 	},
248f5b1c8a1SJohn Marino 	{
249f5b1c8a1SJohn Marino 		.name = SSL_TXT_aGOST01,
250f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aGOST01,
251f5b1c8a1SJohn Marino 	},
252f5b1c8a1SJohn Marino 	{
253f5b1c8a1SJohn Marino 		.name = SSL_TXT_aGOST,
254f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aGOST01,
255f5b1c8a1SJohn Marino 	},
256f5b1c8a1SJohn Marino 
257f5b1c8a1SJohn Marino 	/* aliases combining key exchange and server authentication */
258f5b1c8a1SJohn Marino 	{
259f5b1c8a1SJohn Marino 		.name = SSL_TXT_DHE,
260f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
261f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
262f5b1c8a1SJohn Marino 	},
263f5b1c8a1SJohn Marino 	{
264f5b1c8a1SJohn Marino 		.name = SSL_TXT_EDH,
265f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
266f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
267f5b1c8a1SJohn Marino 	},
268f5b1c8a1SJohn Marino 	{
269f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDHE,
270f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
271f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
272f5b1c8a1SJohn Marino 	},
273f5b1c8a1SJohn Marino 	{
274f5b1c8a1SJohn Marino 		.name = SSL_TXT_EECDH,
275f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
276f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
277f5b1c8a1SJohn Marino 	},
278f5b1c8a1SJohn Marino 	{
279f5b1c8a1SJohn Marino 		.name = SSL_TXT_NULL,
280f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
281f5b1c8a1SJohn Marino 	},
282f5b1c8a1SJohn Marino 	{
283f5b1c8a1SJohn Marino 		.name = SSL_TXT_RSA,
284f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kRSA,
285f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aRSA,
286f5b1c8a1SJohn Marino 	},
287f5b1c8a1SJohn Marino 	{
288f5b1c8a1SJohn Marino 		.name = SSL_TXT_ADH,
289f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
290f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
291f5b1c8a1SJohn Marino 	},
292f5b1c8a1SJohn Marino 	{
293f5b1c8a1SJohn Marino 		.name = SSL_TXT_AECDH,
294f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
295f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
296f5b1c8a1SJohn Marino 	},
297f5b1c8a1SJohn Marino 
298f5b1c8a1SJohn Marino 	/* symmetric encryption aliases */
299f5b1c8a1SJohn Marino 	{
300f5b1c8a1SJohn Marino 		.name = SSL_TXT_3DES,
301f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_3DES,
302f5b1c8a1SJohn Marino 	},
303f5b1c8a1SJohn Marino 	{
304f5b1c8a1SJohn Marino 		.name = SSL_TXT_RC4,
305f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_RC4,
306f5b1c8a1SJohn Marino 	},
307f5b1c8a1SJohn Marino 	{
308f5b1c8a1SJohn Marino 		.name = SSL_TXT_eNULL,
309f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
310f5b1c8a1SJohn Marino 	},
311f5b1c8a1SJohn Marino 	{
312f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES128,
313f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES128|SSL_AES128GCM,
314f5b1c8a1SJohn Marino 	},
315f5b1c8a1SJohn Marino 	{
316f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES256,
317f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES256|SSL_AES256GCM,
318f5b1c8a1SJohn Marino 	},
319f5b1c8a1SJohn Marino 	{
320f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES,
321f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES,
322f5b1c8a1SJohn Marino 	},
323f5b1c8a1SJohn Marino 	{
324f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES_GCM,
325f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES128GCM|SSL_AES256GCM,
326f5b1c8a1SJohn Marino 	},
327f5b1c8a1SJohn Marino 	{
328f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA128,
329f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA128,
330f5b1c8a1SJohn Marino 	},
331f5b1c8a1SJohn Marino 	{
332f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA256,
333f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA256,
334f5b1c8a1SJohn Marino 	},
335f5b1c8a1SJohn Marino 	{
336f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA,
337f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA128|SSL_CAMELLIA256,
338f5b1c8a1SJohn Marino 	},
339f5b1c8a1SJohn Marino 	{
340f5b1c8a1SJohn Marino 		.name = SSL_TXT_CHACHA20,
34172c33676SMaxim Ag 		.algorithm_enc = SSL_CHACHA20POLY1305,
342f5b1c8a1SJohn Marino 	},
343f5b1c8a1SJohn Marino 
344f5b1c8a1SJohn Marino 	/* MAC aliases */
345f5b1c8a1SJohn Marino 	{
346f5b1c8a1SJohn Marino 		.name = SSL_TXT_AEAD,
347f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_AEAD,
348f5b1c8a1SJohn Marino 	},
349f5b1c8a1SJohn Marino 	{
350f5b1c8a1SJohn Marino 		.name = SSL_TXT_MD5,
351f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_MD5,
352f5b1c8a1SJohn Marino 	},
353f5b1c8a1SJohn Marino 	{
354f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA1,
355f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA1,
356f5b1c8a1SJohn Marino 	},
357f5b1c8a1SJohn Marino 	{
358f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA,
359f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA1,
360f5b1c8a1SJohn Marino 	},
361f5b1c8a1SJohn Marino 	{
362f5b1c8a1SJohn Marino 		.name = SSL_TXT_GOST94,
363f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_GOST94,
364f5b1c8a1SJohn Marino 	},
365f5b1c8a1SJohn Marino 	{
366f5b1c8a1SJohn Marino 		.name = SSL_TXT_GOST89MAC,
367f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_GOST89MAC,
368f5b1c8a1SJohn Marino 	},
369f5b1c8a1SJohn Marino 	{
370f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA256,
371f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA256,
372f5b1c8a1SJohn Marino 	},
373f5b1c8a1SJohn Marino 	{
374f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA384,
375f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA384,
376f5b1c8a1SJohn Marino 	},
377f5b1c8a1SJohn Marino 	{
378f5b1c8a1SJohn Marino 		.name = SSL_TXT_STREEBOG256,
379f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_STREEBOG256,
380f5b1c8a1SJohn Marino 	},
381f5b1c8a1SJohn Marino 
382f5b1c8a1SJohn Marino 	/* protocol version aliases */
383f5b1c8a1SJohn Marino 	{
384f5b1c8a1SJohn Marino 		.name = SSL_TXT_SSLV3,
385f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_SSLV3,
386f5b1c8a1SJohn Marino 	},
387f5b1c8a1SJohn Marino 	{
388f5b1c8a1SJohn Marino 		.name = SSL_TXT_TLSV1,
389f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_TLSV1,
390f5b1c8a1SJohn Marino 	},
391f5b1c8a1SJohn Marino 	{
392f5b1c8a1SJohn Marino 		.name = SSL_TXT_TLSV1_2,
393f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_TLSV1_2,
394f5b1c8a1SJohn Marino 	},
39572c33676SMaxim Ag 	{
39672c33676SMaxim Ag 		.name = SSL_TXT_TLSV1_3,
39772c33676SMaxim Ag 		.algorithm_ssl = SSL_TLSV1_3,
39872c33676SMaxim Ag 	},
399f5b1c8a1SJohn Marino 
400cca6fc52SDaniel Fojt 	/* cipher suite aliases */
401cca6fc52SDaniel Fojt #ifdef LIBRESSL_HAS_TLS1_3
402cca6fc52SDaniel Fojt 	{
403cca6fc52SDaniel Fojt 		.valid = 1,
404cca6fc52SDaniel Fojt 		.name = "TLS_AES_128_GCM_SHA256",
405cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_AES_128_GCM_SHA256,
406cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
407cca6fc52SDaniel Fojt 	},
408cca6fc52SDaniel Fojt 	{
409cca6fc52SDaniel Fojt 		.valid = 1,
410cca6fc52SDaniel Fojt 		.name = "TLS_AES_256_GCM_SHA384",
411cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_AES_256_GCM_SHA384,
412cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
413cca6fc52SDaniel Fojt 	},
414cca6fc52SDaniel Fojt 	{
415cca6fc52SDaniel Fojt 		.valid = 1,
416cca6fc52SDaniel Fojt 		.name = "TLS_CHACHA20_POLY1305_SHA256",
417cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
418cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
419cca6fc52SDaniel Fojt 	},
420cca6fc52SDaniel Fojt #endif
421cca6fc52SDaniel Fojt 
422f5b1c8a1SJohn Marino 	/* strength classes */
423f5b1c8a1SJohn Marino 	{
424f5b1c8a1SJohn Marino 		.name = SSL_TXT_LOW,
425f5b1c8a1SJohn Marino 		.algo_strength = SSL_LOW,
426f5b1c8a1SJohn Marino 	},
427f5b1c8a1SJohn Marino 	{
428f5b1c8a1SJohn Marino 		.name = SSL_TXT_MEDIUM,
429f5b1c8a1SJohn Marino 		.algo_strength = SSL_MEDIUM,
430f5b1c8a1SJohn Marino 	},
431f5b1c8a1SJohn Marino 	{
432f5b1c8a1SJohn Marino 		.name = SSL_TXT_HIGH,
433f5b1c8a1SJohn Marino 		.algo_strength = SSL_HIGH,
434f5b1c8a1SJohn Marino 	},
435f5b1c8a1SJohn Marino };
436f5b1c8a1SJohn Marino 
437f5b1c8a1SJohn Marino int
ssl_cipher_get_evp(const SSL_SESSION * ss,const EVP_CIPHER ** enc,const EVP_MD ** md,int * mac_pkey_type,int * mac_secret_size)43872c33676SMaxim Ag ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
439f5b1c8a1SJohn Marino     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
440f5b1c8a1SJohn Marino {
44172c33676SMaxim Ag 	*enc = NULL;
44272c33676SMaxim Ag 	*md = NULL;
44372c33676SMaxim Ag 	*mac_pkey_type = NID_undef;
44472c33676SMaxim Ag 	*mac_secret_size = 0;
445f5b1c8a1SJohn Marino 
44672c33676SMaxim Ag 	if (ss->cipher == NULL)
44772c33676SMaxim Ag 		return 0;
448f5b1c8a1SJohn Marino 
449f5b1c8a1SJohn Marino 	/*
450f5b1c8a1SJohn Marino 	 * This function does not handle EVP_AEAD.
451*de0e0e4dSAntonio Huete Jimenez 	 * See ssl_cipher_get_evp_aead instead.
452f5b1c8a1SJohn Marino 	 */
45372c33676SMaxim Ag 	if (ss->cipher->algorithm_mac & SSL_AEAD)
45472c33676SMaxim Ag 		return 0;
455f5b1c8a1SJohn Marino 
45672c33676SMaxim Ag 	switch (ss->cipher->algorithm_enc) {
457f5b1c8a1SJohn Marino 	case SSL_3DES:
45872c33676SMaxim Ag 		*enc = EVP_des_ede3_cbc();
459f5b1c8a1SJohn Marino 		break;
460f5b1c8a1SJohn Marino 	case SSL_RC4:
46172c33676SMaxim Ag 		*enc = EVP_rc4();
462f5b1c8a1SJohn Marino 		break;
463f5b1c8a1SJohn Marino 	case SSL_eNULL:
46472c33676SMaxim Ag 		*enc = EVP_enc_null();
465f5b1c8a1SJohn Marino 		break;
466f5b1c8a1SJohn Marino 	case SSL_AES128:
46772c33676SMaxim Ag 		*enc = EVP_aes_128_cbc();
468f5b1c8a1SJohn Marino 		break;
469f5b1c8a1SJohn Marino 	case SSL_AES256:
47072c33676SMaxim Ag 		*enc = EVP_aes_256_cbc();
471f5b1c8a1SJohn Marino 		break;
472f5b1c8a1SJohn Marino 	case SSL_CAMELLIA128:
47372c33676SMaxim Ag 		*enc = EVP_camellia_128_cbc();
474f5b1c8a1SJohn Marino 		break;
475f5b1c8a1SJohn Marino 	case SSL_CAMELLIA256:
47672c33676SMaxim Ag 		*enc = EVP_camellia_256_cbc();
477f5b1c8a1SJohn Marino 		break;
478f5b1c8a1SJohn Marino 	case SSL_eGOST2814789CNT:
47972c33676SMaxim Ag 		*enc = EVP_gost2814789_cnt();
480f5b1c8a1SJohn Marino 		break;
481f5b1c8a1SJohn Marino 	}
482f5b1c8a1SJohn Marino 
48372c33676SMaxim Ag 	switch (ss->cipher->algorithm_mac) {
484f5b1c8a1SJohn Marino 	case SSL_MD5:
48572c33676SMaxim Ag 		*md = EVP_md5();
486f5b1c8a1SJohn Marino 		break;
487f5b1c8a1SJohn Marino 	case SSL_SHA1:
48872c33676SMaxim Ag 		*md = EVP_sha1();
489f5b1c8a1SJohn Marino 		break;
490f5b1c8a1SJohn Marino 	case SSL_SHA256:
49172c33676SMaxim Ag 		*md = EVP_sha256();
492f5b1c8a1SJohn Marino 		break;
493f5b1c8a1SJohn Marino 	case SSL_SHA384:
49472c33676SMaxim Ag 		*md = EVP_sha384();
495f5b1c8a1SJohn Marino 		break;
496f5b1c8a1SJohn Marino 	case SSL_GOST89MAC:
49772c33676SMaxim Ag 		*md = EVP_gost2814789imit();
49872c33676SMaxim Ag 		break;
49972c33676SMaxim Ag 	case SSL_GOST94:
50072c33676SMaxim Ag 		*md = EVP_gostr341194();
501f5b1c8a1SJohn Marino 		break;
502f5b1c8a1SJohn Marino 	case SSL_STREEBOG256:
50372c33676SMaxim Ag 		*md = EVP_streebog256();
504f5b1c8a1SJohn Marino 		break;
505f5b1c8a1SJohn Marino 	}
506f5b1c8a1SJohn Marino 
50772c33676SMaxim Ag 	if (*enc == NULL || *md == NULL)
50872c33676SMaxim Ag 		return 0;
50972c33676SMaxim Ag 
51072c33676SMaxim Ag 	/*
51172c33676SMaxim Ag 	 * EVP_CIPH_FLAG_AEAD_CIPHER and EVP_CIPH_GCM_MODE ciphers are not
51272c33676SMaxim Ag 	 * supported via EVP_CIPHER (they should be using EVP_AEAD instead).
51372c33676SMaxim Ag 	 */
51472c33676SMaxim Ag 	if (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)
51572c33676SMaxim Ag 		return 0;
51672c33676SMaxim Ag 	if (EVP_CIPHER_mode(*enc) == EVP_CIPH_GCM_MODE)
51772c33676SMaxim Ag 		return 0;
51872c33676SMaxim Ag 
51972c33676SMaxim Ag 	if (ss->cipher->algorithm_mac == SSL_GOST89MAC) {
52072c33676SMaxim Ag 		*mac_pkey_type = EVP_PKEY_GOSTIMIT;
52172c33676SMaxim Ag 		*mac_secret_size = 32; /* XXX */
522f5b1c8a1SJohn Marino 	} else {
52372c33676SMaxim Ag 		*mac_pkey_type = EVP_PKEY_HMAC;
52472c33676SMaxim Ag 		*mac_secret_size = EVP_MD_size(*md);
525f5b1c8a1SJohn Marino 	}
526f5b1c8a1SJohn Marino 
527f5b1c8a1SJohn Marino 	return 1;
528f5b1c8a1SJohn Marino }
529f5b1c8a1SJohn Marino 
530f5b1c8a1SJohn Marino /*
531f5b1c8a1SJohn Marino  * ssl_cipher_get_evp_aead sets aead to point to the correct EVP_AEAD object
532f5b1c8a1SJohn Marino  * for s->cipher. It returns 1 on success and 0 on error.
533f5b1c8a1SJohn Marino  */
534f5b1c8a1SJohn Marino int
ssl_cipher_get_evp_aead(const SSL_SESSION * ss,const EVP_AEAD ** aead)53572c33676SMaxim Ag ssl_cipher_get_evp_aead(const SSL_SESSION *ss, const EVP_AEAD **aead)
536f5b1c8a1SJohn Marino {
537f5b1c8a1SJohn Marino 	*aead = NULL;
538f5b1c8a1SJohn Marino 
53972c33676SMaxim Ag 	if (ss->cipher == NULL)
540f5b1c8a1SJohn Marino 		return 0;
54172c33676SMaxim Ag 	if ((ss->cipher->algorithm_mac & SSL_AEAD) == 0)
542f5b1c8a1SJohn Marino 		return 0;
543f5b1c8a1SJohn Marino 
54472c33676SMaxim Ag 	switch (ss->cipher->algorithm_enc) {
545f5b1c8a1SJohn Marino 	case SSL_AES128GCM:
546f5b1c8a1SJohn Marino 		*aead = EVP_aead_aes_128_gcm();
547f5b1c8a1SJohn Marino 		return 1;
548f5b1c8a1SJohn Marino 	case SSL_AES256GCM:
549f5b1c8a1SJohn Marino 		*aead = EVP_aead_aes_256_gcm();
550f5b1c8a1SJohn Marino 		return 1;
551f5b1c8a1SJohn Marino 	case SSL_CHACHA20POLY1305:
552f5b1c8a1SJohn Marino 		*aead = EVP_aead_chacha20_poly1305();
553f5b1c8a1SJohn Marino 		return 1;
554f5b1c8a1SJohn Marino 	default:
555f5b1c8a1SJohn Marino 		break;
556f5b1c8a1SJohn Marino 	}
557f5b1c8a1SJohn Marino 	return 0;
558f5b1c8a1SJohn Marino }
559f5b1c8a1SJohn Marino 
560f5b1c8a1SJohn Marino int
ssl_get_handshake_evp_md(SSL * s,const EVP_MD ** md)56172c33676SMaxim Ag ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md)
562f5b1c8a1SJohn Marino {
563*de0e0e4dSAntonio Huete Jimenez 	unsigned long handshake_mac;
564*de0e0e4dSAntonio Huete Jimenez 
565f5b1c8a1SJohn Marino 	*md = NULL;
56672c33676SMaxim Ag 
567*de0e0e4dSAntonio Huete Jimenez 	if (s->s3->hs.cipher == NULL)
568*de0e0e4dSAntonio Huete Jimenez 		return 0;
569*de0e0e4dSAntonio Huete Jimenez 
570*de0e0e4dSAntonio Huete Jimenez 	handshake_mac = s->s3->hs.cipher->algorithm2 &
571*de0e0e4dSAntonio Huete Jimenez 	    SSL_HANDSHAKE_MAC_MASK;
572*de0e0e4dSAntonio Huete Jimenez 
573*de0e0e4dSAntonio Huete Jimenez 	/* For TLSv1.2 we upgrade the default MD5+SHA1 MAC to SHA256. */
574*de0e0e4dSAntonio Huete Jimenez 	if (SSL_USE_SHA256_PRF(s) && handshake_mac == SSL_HANDSHAKE_MAC_DEFAULT)
575*de0e0e4dSAntonio Huete Jimenez 		handshake_mac = SSL_HANDSHAKE_MAC_SHA256;
576*de0e0e4dSAntonio Huete Jimenez 
577*de0e0e4dSAntonio Huete Jimenez 	switch (handshake_mac) {
57872c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_DEFAULT:
57972c33676SMaxim Ag 		*md = EVP_md5_sha1();
580f5b1c8a1SJohn Marino 		return 1;
58172c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_GOST94:
58272c33676SMaxim Ag 		*md = EVP_gostr341194();
58372c33676SMaxim Ag 		return 1;
58472c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_SHA256:
58572c33676SMaxim Ag 		*md = EVP_sha256();
58672c33676SMaxim Ag 		return 1;
58772c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_SHA384:
58872c33676SMaxim Ag 		*md = EVP_sha384();
58972c33676SMaxim Ag 		return 1;
59072c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_STREEBOG256:
59172c33676SMaxim Ag 		*md = EVP_streebog256();
59272c33676SMaxim Ag 		return 1;
59372c33676SMaxim Ag 	default:
59472c33676SMaxim Ag 		break;
59572c33676SMaxim Ag 	}
59672c33676SMaxim Ag 
59772c33676SMaxim Ag 	return 0;
598f5b1c8a1SJohn Marino }
599f5b1c8a1SJohn Marino 
600f5b1c8a1SJohn Marino #define ITEM_SEP(a) \
601f5b1c8a1SJohn Marino 	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
602f5b1c8a1SJohn Marino 
603f5b1c8a1SJohn Marino static void
ll_append_tail(CIPHER_ORDER ** head,CIPHER_ORDER * curr,CIPHER_ORDER ** tail)604f5b1c8a1SJohn Marino ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
605f5b1c8a1SJohn Marino     CIPHER_ORDER **tail)
606f5b1c8a1SJohn Marino {
607f5b1c8a1SJohn Marino 	if (curr == *tail)
608f5b1c8a1SJohn Marino 		return;
609f5b1c8a1SJohn Marino 	if (curr == *head)
610f5b1c8a1SJohn Marino 		*head = curr->next;
611f5b1c8a1SJohn Marino 	if (curr->prev != NULL)
612f5b1c8a1SJohn Marino 		curr->prev->next = curr->next;
613f5b1c8a1SJohn Marino 	if (curr->next != NULL)
614f5b1c8a1SJohn Marino 		curr->next->prev = curr->prev;
615f5b1c8a1SJohn Marino 	(*tail)->next = curr;
616f5b1c8a1SJohn Marino 	curr->prev= *tail;
617f5b1c8a1SJohn Marino 	curr->next = NULL;
618f5b1c8a1SJohn Marino 	*tail = curr;
619f5b1c8a1SJohn Marino }
620f5b1c8a1SJohn Marino 
621f5b1c8a1SJohn Marino static void
ll_append_head(CIPHER_ORDER ** head,CIPHER_ORDER * curr,CIPHER_ORDER ** tail)622f5b1c8a1SJohn Marino ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
623f5b1c8a1SJohn Marino     CIPHER_ORDER **tail)
624f5b1c8a1SJohn Marino {
625f5b1c8a1SJohn Marino 	if (curr == *head)
626f5b1c8a1SJohn Marino 		return;
627f5b1c8a1SJohn Marino 	if (curr == *tail)
628f5b1c8a1SJohn Marino 		*tail = curr->prev;
629f5b1c8a1SJohn Marino 	if (curr->next != NULL)
630f5b1c8a1SJohn Marino 		curr->next->prev = curr->prev;
631f5b1c8a1SJohn Marino 	if (curr->prev != NULL)
632f5b1c8a1SJohn Marino 		curr->prev->next = curr->next;
633f5b1c8a1SJohn Marino 	(*head)->prev = curr;
634f5b1c8a1SJohn Marino 	curr->next= *head;
635f5b1c8a1SJohn Marino 	curr->prev = NULL;
636f5b1c8a1SJohn Marino 	*head = curr;
637f5b1c8a1SJohn Marino }
638f5b1c8a1SJohn Marino 
639f5b1c8a1SJohn Marino static void
ssl_cipher_get_disabled(unsigned long * mkey,unsigned long * auth,unsigned long * enc,unsigned long * mac,unsigned long * ssl)640f5b1c8a1SJohn Marino ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth,
641f5b1c8a1SJohn Marino     unsigned long *enc, unsigned long *mac, unsigned long *ssl)
642f5b1c8a1SJohn Marino {
643f5b1c8a1SJohn Marino 	*mkey = 0;
644f5b1c8a1SJohn Marino 	*auth = 0;
645f5b1c8a1SJohn Marino 	*enc = 0;
646f5b1c8a1SJohn Marino 	*mac = 0;
647f5b1c8a1SJohn Marino 	*ssl = 0;
648f5b1c8a1SJohn Marino 
649f5b1c8a1SJohn Marino 	/*
650f5b1c8a1SJohn Marino 	 * Check for the availability of GOST 34.10 public/private key
651f5b1c8a1SJohn Marino 	 * algorithms. If they are not available disable the associated
652f5b1c8a1SJohn Marino 	 * authentication and key exchange algorithms.
653f5b1c8a1SJohn Marino 	 */
654f5b1c8a1SJohn Marino 	if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) {
655f5b1c8a1SJohn Marino 		*auth |= SSL_aGOST01;
656f5b1c8a1SJohn Marino 		*mkey |= SSL_kGOST;
657f5b1c8a1SJohn Marino 	}
658f5b1c8a1SJohn Marino 
659f5b1c8a1SJohn Marino #ifdef SSL_FORBID_ENULL
660f5b1c8a1SJohn Marino 	*enc |= SSL_eNULL;
661f5b1c8a1SJohn Marino #endif
662f5b1c8a1SJohn Marino }
663f5b1c8a1SJohn Marino 
664f5b1c8a1SJohn Marino static void
ssl_cipher_collect_ciphers(const SSL_METHOD * ssl_method,int num_of_ciphers,unsigned long disabled_mkey,unsigned long disabled_auth,unsigned long disabled_enc,unsigned long disabled_mac,unsigned long disabled_ssl,CIPHER_ORDER * co_list,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)665f5b1c8a1SJohn Marino ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers,
666f5b1c8a1SJohn Marino     unsigned long disabled_mkey, unsigned long disabled_auth,
667f5b1c8a1SJohn Marino     unsigned long disabled_enc, unsigned long disabled_mac,
668f5b1c8a1SJohn Marino     unsigned long disabled_ssl, CIPHER_ORDER *co_list,
669f5b1c8a1SJohn Marino     CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
670f5b1c8a1SJohn Marino {
671f5b1c8a1SJohn Marino 	int i, co_list_num;
672f5b1c8a1SJohn Marino 	const SSL_CIPHER *c;
673f5b1c8a1SJohn Marino 
674f5b1c8a1SJohn Marino 	/*
675f5b1c8a1SJohn Marino 	 * We have num_of_ciphers descriptions compiled in, depending on the
676f5b1c8a1SJohn Marino 	 * method selected (SSLv3, TLSv1, etc). These will later be sorted in
677f5b1c8a1SJohn Marino 	 * a linked list with at most num entries.
678f5b1c8a1SJohn Marino 	 */
679f5b1c8a1SJohn Marino 
680f5b1c8a1SJohn Marino 	/* Get the initial list of ciphers */
681f5b1c8a1SJohn Marino 	co_list_num = 0;	/* actual count of ciphers */
682f5b1c8a1SJohn Marino 	for (i = 0; i < num_of_ciphers; i++) {
683f5b1c8a1SJohn Marino 		c = ssl_method->get_cipher(i);
684*de0e0e4dSAntonio Huete Jimenez 		/*
685*de0e0e4dSAntonio Huete Jimenez 		 * Drop any invalid ciphers and any which use unavailable
686*de0e0e4dSAntonio Huete Jimenez 		 * algorithms.
687*de0e0e4dSAntonio Huete Jimenez 		 */
688f5b1c8a1SJohn Marino 		if ((c != NULL) && c->valid &&
689f5b1c8a1SJohn Marino 		    !(c->algorithm_mkey & disabled_mkey) &&
690f5b1c8a1SJohn Marino 		    !(c->algorithm_auth & disabled_auth) &&
691f5b1c8a1SJohn Marino 		    !(c->algorithm_enc & disabled_enc) &&
692f5b1c8a1SJohn Marino 		    !(c->algorithm_mac & disabled_mac) &&
693f5b1c8a1SJohn Marino 		    !(c->algorithm_ssl & disabled_ssl)) {
694f5b1c8a1SJohn Marino 			co_list[co_list_num].cipher = c;
695f5b1c8a1SJohn Marino 			co_list[co_list_num].next = NULL;
696f5b1c8a1SJohn Marino 			co_list[co_list_num].prev = NULL;
697f5b1c8a1SJohn Marino 			co_list[co_list_num].active = 0;
698f5b1c8a1SJohn Marino 			co_list_num++;
699f5b1c8a1SJohn Marino 		}
700f5b1c8a1SJohn Marino 	}
701f5b1c8a1SJohn Marino 
702f5b1c8a1SJohn Marino 	/*
703f5b1c8a1SJohn Marino 	 * Prepare linked list from list entries
704f5b1c8a1SJohn Marino 	 */
705f5b1c8a1SJohn Marino 	if (co_list_num > 0) {
706f5b1c8a1SJohn Marino 		co_list[0].prev = NULL;
707f5b1c8a1SJohn Marino 
708f5b1c8a1SJohn Marino 		if (co_list_num > 1) {
709f5b1c8a1SJohn Marino 			co_list[0].next = &co_list[1];
710f5b1c8a1SJohn Marino 
711f5b1c8a1SJohn Marino 			for (i = 1; i < co_list_num - 1; i++) {
712f5b1c8a1SJohn Marino 				co_list[i].prev = &co_list[i - 1];
713f5b1c8a1SJohn Marino 				co_list[i].next = &co_list[i + 1];
714f5b1c8a1SJohn Marino 			}
715f5b1c8a1SJohn Marino 
716f5b1c8a1SJohn Marino 			co_list[co_list_num - 1].prev =
717f5b1c8a1SJohn Marino 			    &co_list[co_list_num - 2];
718f5b1c8a1SJohn Marino 		}
719f5b1c8a1SJohn Marino 
720f5b1c8a1SJohn Marino 		co_list[co_list_num - 1].next = NULL;
721f5b1c8a1SJohn Marino 
722f5b1c8a1SJohn Marino 		*head_p = &co_list[0];
723f5b1c8a1SJohn Marino 		*tail_p = &co_list[co_list_num - 1];
724f5b1c8a1SJohn Marino 	}
725f5b1c8a1SJohn Marino }
726f5b1c8a1SJohn Marino 
727f5b1c8a1SJohn Marino static void
ssl_cipher_collect_aliases(const SSL_CIPHER ** ca_list,int num_of_group_aliases,unsigned long disabled_mkey,unsigned long disabled_auth,unsigned long disabled_enc,unsigned long disabled_mac,unsigned long disabled_ssl,CIPHER_ORDER * head)728f5b1c8a1SJohn Marino ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases,
729f5b1c8a1SJohn Marino     unsigned long disabled_mkey, unsigned long disabled_auth,
730f5b1c8a1SJohn Marino     unsigned long disabled_enc, unsigned long disabled_mac,
731f5b1c8a1SJohn Marino     unsigned long disabled_ssl, CIPHER_ORDER *head)
732f5b1c8a1SJohn Marino {
733f5b1c8a1SJohn Marino 	CIPHER_ORDER *ciph_curr;
734f5b1c8a1SJohn Marino 	const SSL_CIPHER **ca_curr;
735f5b1c8a1SJohn Marino 	int i;
736f5b1c8a1SJohn Marino 	unsigned long mask_mkey = ~disabled_mkey;
737f5b1c8a1SJohn Marino 	unsigned long mask_auth = ~disabled_auth;
738f5b1c8a1SJohn Marino 	unsigned long mask_enc = ~disabled_enc;
739f5b1c8a1SJohn Marino 	unsigned long mask_mac = ~disabled_mac;
740f5b1c8a1SJohn Marino 	unsigned long mask_ssl = ~disabled_ssl;
741f5b1c8a1SJohn Marino 
742f5b1c8a1SJohn Marino 	/*
743f5b1c8a1SJohn Marino 	 * First, add the real ciphers as already collected
744f5b1c8a1SJohn Marino 	 */
745f5b1c8a1SJohn Marino 	ciph_curr = head;
746f5b1c8a1SJohn Marino 	ca_curr = ca_list;
747f5b1c8a1SJohn Marino 	while (ciph_curr != NULL) {
748f5b1c8a1SJohn Marino 		*ca_curr = ciph_curr->cipher;
749f5b1c8a1SJohn Marino 		ca_curr++;
750f5b1c8a1SJohn Marino 		ciph_curr = ciph_curr->next;
751f5b1c8a1SJohn Marino 	}
752f5b1c8a1SJohn Marino 
753f5b1c8a1SJohn Marino 	/*
754f5b1c8a1SJohn Marino 	 * Now we add the available ones from the cipher_aliases[] table.
755f5b1c8a1SJohn Marino 	 * They represent either one or more algorithms, some of which
756f5b1c8a1SJohn Marino 	 * in any affected category must be supported (set in enabled_mask),
757f5b1c8a1SJohn Marino 	 * or represent a cipher strength value (will be added in any case because algorithms=0).
758f5b1c8a1SJohn Marino 	 */
759f5b1c8a1SJohn Marino 	for (i = 0; i < num_of_group_aliases; i++) {
760f5b1c8a1SJohn Marino 		unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
761f5b1c8a1SJohn Marino 		unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
762f5b1c8a1SJohn Marino 		unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
763f5b1c8a1SJohn Marino 		unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
764f5b1c8a1SJohn Marino 		unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
765f5b1c8a1SJohn Marino 
766f5b1c8a1SJohn Marino 		if (algorithm_mkey)
767f5b1c8a1SJohn Marino 			if ((algorithm_mkey & mask_mkey) == 0)
768f5b1c8a1SJohn Marino 				continue;
769f5b1c8a1SJohn Marino 
770f5b1c8a1SJohn Marino 		if (algorithm_auth)
771f5b1c8a1SJohn Marino 			if ((algorithm_auth & mask_auth) == 0)
772f5b1c8a1SJohn Marino 				continue;
773f5b1c8a1SJohn Marino 
774f5b1c8a1SJohn Marino 		if (algorithm_enc)
775f5b1c8a1SJohn Marino 			if ((algorithm_enc & mask_enc) == 0)
776f5b1c8a1SJohn Marino 				continue;
777f5b1c8a1SJohn Marino 
778f5b1c8a1SJohn Marino 		if (algorithm_mac)
779f5b1c8a1SJohn Marino 			if ((algorithm_mac & mask_mac) == 0)
780f5b1c8a1SJohn Marino 				continue;
781f5b1c8a1SJohn Marino 
782f5b1c8a1SJohn Marino 		if (algorithm_ssl)
783f5b1c8a1SJohn Marino 			if ((algorithm_ssl & mask_ssl) == 0)
784f5b1c8a1SJohn Marino 				continue;
785f5b1c8a1SJohn Marino 
786f5b1c8a1SJohn Marino 		*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
787f5b1c8a1SJohn Marino 		ca_curr++;
788f5b1c8a1SJohn Marino 	}
789f5b1c8a1SJohn Marino 
790f5b1c8a1SJohn Marino 	*ca_curr = NULL;	/* end of list */
791f5b1c8a1SJohn Marino }
792f5b1c8a1SJohn Marino 
793f5b1c8a1SJohn Marino static void
ssl_cipher_apply_rule(unsigned long cipher_id,unsigned long alg_mkey,unsigned long alg_auth,unsigned long alg_enc,unsigned long alg_mac,unsigned long alg_ssl,unsigned long algo_strength,int rule,int strength_bits,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)794f5b1c8a1SJohn Marino ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long alg_mkey,
795f5b1c8a1SJohn Marino     unsigned long alg_auth, unsigned long alg_enc, unsigned long alg_mac,
796cca6fc52SDaniel Fojt     unsigned long alg_ssl, unsigned long algo_strength, int rule,
797cca6fc52SDaniel Fojt     int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
798f5b1c8a1SJohn Marino {
799f5b1c8a1SJohn Marino 	CIPHER_ORDER *head, *tail, *curr, *next, *last;
800f5b1c8a1SJohn Marino 	const SSL_CIPHER *cp;
801f5b1c8a1SJohn Marino 	int reverse = 0;
802f5b1c8a1SJohn Marino 
803f5b1c8a1SJohn Marino 	if (rule == CIPHER_DEL)
804f5b1c8a1SJohn Marino 		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
805f5b1c8a1SJohn Marino 
806f5b1c8a1SJohn Marino 	head = *head_p;
807f5b1c8a1SJohn Marino 	tail = *tail_p;
808f5b1c8a1SJohn Marino 
809f5b1c8a1SJohn Marino 	if (reverse) {
810f5b1c8a1SJohn Marino 		next = tail;
811f5b1c8a1SJohn Marino 		last = head;
812f5b1c8a1SJohn Marino 	} else {
813f5b1c8a1SJohn Marino 		next = head;
814f5b1c8a1SJohn Marino 		last = tail;
815f5b1c8a1SJohn Marino 	}
816f5b1c8a1SJohn Marino 
817f5b1c8a1SJohn Marino 	curr = NULL;
818f5b1c8a1SJohn Marino 	for (;;) {
819f5b1c8a1SJohn Marino 		if (curr == last)
820f5b1c8a1SJohn Marino 			break;
821f5b1c8a1SJohn Marino 		curr = next;
822f5b1c8a1SJohn Marino 		next = reverse ? curr->prev : curr->next;
823f5b1c8a1SJohn Marino 
824f5b1c8a1SJohn Marino 		cp = curr->cipher;
825f5b1c8a1SJohn Marino 
82672c33676SMaxim Ag 		if (cipher_id && cp->id != cipher_id)
82772c33676SMaxim Ag 			continue;
82872c33676SMaxim Ag 
829f5b1c8a1SJohn Marino 		/*
830f5b1c8a1SJohn Marino 		 * Selection criteria is either the value of strength_bits
831f5b1c8a1SJohn Marino 		 * or the algorithms used.
832f5b1c8a1SJohn Marino 		 */
833f5b1c8a1SJohn Marino 		if (strength_bits >= 0) {
834f5b1c8a1SJohn Marino 			if (strength_bits != cp->strength_bits)
835f5b1c8a1SJohn Marino 				continue;
836f5b1c8a1SJohn Marino 		} else {
837f5b1c8a1SJohn Marino 			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
838f5b1c8a1SJohn Marino 				continue;
839f5b1c8a1SJohn Marino 			if (alg_auth && !(alg_auth & cp->algorithm_auth))
840f5b1c8a1SJohn Marino 				continue;
841f5b1c8a1SJohn Marino 			if (alg_enc && !(alg_enc & cp->algorithm_enc))
842f5b1c8a1SJohn Marino 				continue;
843f5b1c8a1SJohn Marino 			if (alg_mac && !(alg_mac & cp->algorithm_mac))
844f5b1c8a1SJohn Marino 				continue;
845f5b1c8a1SJohn Marino 			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
846f5b1c8a1SJohn Marino 				continue;
847f5b1c8a1SJohn Marino 			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
848f5b1c8a1SJohn Marino 				continue;
849f5b1c8a1SJohn Marino 		}
850f5b1c8a1SJohn Marino 
851f5b1c8a1SJohn Marino 		/* add the cipher if it has not been added yet. */
852f5b1c8a1SJohn Marino 		if (rule == CIPHER_ADD) {
853f5b1c8a1SJohn Marino 			/* reverse == 0 */
854f5b1c8a1SJohn Marino 			if (!curr->active) {
855f5b1c8a1SJohn Marino 				ll_append_tail(&head, curr, &tail);
856f5b1c8a1SJohn Marino 				curr->active = 1;
857f5b1c8a1SJohn Marino 			}
858f5b1c8a1SJohn Marino 		}
859f5b1c8a1SJohn Marino 		/* Move the added cipher to this location */
860f5b1c8a1SJohn Marino 		else if (rule == CIPHER_ORD) {
861f5b1c8a1SJohn Marino 			/* reverse == 0 */
862f5b1c8a1SJohn Marino 			if (curr->active) {
863f5b1c8a1SJohn Marino 				ll_append_tail(&head, curr, &tail);
864f5b1c8a1SJohn Marino 			}
865f5b1c8a1SJohn Marino 		} else if (rule == CIPHER_DEL) {
866f5b1c8a1SJohn Marino 			/* reverse == 1 */
867f5b1c8a1SJohn Marino 			if (curr->active) {
868f5b1c8a1SJohn Marino 				/* most recently deleted ciphersuites get best positions
869f5b1c8a1SJohn Marino 				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
870f5b1c8a1SJohn Marino 				 * works in reverse to maintain the order) */
871f5b1c8a1SJohn Marino 				ll_append_head(&head, curr, &tail);
872f5b1c8a1SJohn Marino 				curr->active = 0;
873f5b1c8a1SJohn Marino 			}
874f5b1c8a1SJohn Marino 		} else if (rule == CIPHER_KILL) {
875f5b1c8a1SJohn Marino 			/* reverse == 0 */
876f5b1c8a1SJohn Marino 			if (head == curr)
877f5b1c8a1SJohn Marino 				head = curr->next;
878f5b1c8a1SJohn Marino 			else
879f5b1c8a1SJohn Marino 				curr->prev->next = curr->next;
880f5b1c8a1SJohn Marino 			if (tail == curr)
881f5b1c8a1SJohn Marino 				tail = curr->prev;
882f5b1c8a1SJohn Marino 			curr->active = 0;
883f5b1c8a1SJohn Marino 			if (curr->next != NULL)
884f5b1c8a1SJohn Marino 				curr->next->prev = curr->prev;
885f5b1c8a1SJohn Marino 			if (curr->prev != NULL)
886f5b1c8a1SJohn Marino 				curr->prev->next = curr->next;
887f5b1c8a1SJohn Marino 			curr->next = NULL;
888f5b1c8a1SJohn Marino 			curr->prev = NULL;
889f5b1c8a1SJohn Marino 		}
890f5b1c8a1SJohn Marino 	}
891f5b1c8a1SJohn Marino 
892f5b1c8a1SJohn Marino 	*head_p = head;
893f5b1c8a1SJohn Marino 	*tail_p = tail;
894f5b1c8a1SJohn Marino }
895f5b1c8a1SJohn Marino 
896f5b1c8a1SJohn Marino static int
ssl_cipher_strength_sort(CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p)897f5b1c8a1SJohn Marino ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
898f5b1c8a1SJohn Marino {
899f5b1c8a1SJohn Marino 	int max_strength_bits, i, *number_uses;
900f5b1c8a1SJohn Marino 	CIPHER_ORDER *curr;
901f5b1c8a1SJohn Marino 
902f5b1c8a1SJohn Marino 	/*
903f5b1c8a1SJohn Marino 	 * This routine sorts the ciphers with descending strength. The sorting
904f5b1c8a1SJohn Marino 	 * must keep the pre-sorted sequence, so we apply the normal sorting
905f5b1c8a1SJohn Marino 	 * routine as '+' movement to the end of the list.
906f5b1c8a1SJohn Marino 	 */
907f5b1c8a1SJohn Marino 	max_strength_bits = 0;
908f5b1c8a1SJohn Marino 	curr = *head_p;
909f5b1c8a1SJohn Marino 	while (curr != NULL) {
910f5b1c8a1SJohn Marino 		if (curr->active &&
911f5b1c8a1SJohn Marino 		    (curr->cipher->strength_bits > max_strength_bits))
912f5b1c8a1SJohn Marino 			max_strength_bits = curr->cipher->strength_bits;
913f5b1c8a1SJohn Marino 		curr = curr->next;
914f5b1c8a1SJohn Marino 	}
915f5b1c8a1SJohn Marino 
916f5b1c8a1SJohn Marino 	number_uses = calloc((max_strength_bits + 1), sizeof(int));
917f5b1c8a1SJohn Marino 	if (!number_uses) {
91872c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
919f5b1c8a1SJohn Marino 		return (0);
920f5b1c8a1SJohn Marino 	}
921f5b1c8a1SJohn Marino 
922f5b1c8a1SJohn Marino 	/*
923f5b1c8a1SJohn Marino 	 * Now find the strength_bits values actually used
924f5b1c8a1SJohn Marino 	 */
925f5b1c8a1SJohn Marino 	curr = *head_p;
926f5b1c8a1SJohn Marino 	while (curr != NULL) {
927f5b1c8a1SJohn Marino 		if (curr->active)
928f5b1c8a1SJohn Marino 			number_uses[curr->cipher->strength_bits]++;
929f5b1c8a1SJohn Marino 		curr = curr->next;
930f5b1c8a1SJohn Marino 	}
931f5b1c8a1SJohn Marino 	/*
932f5b1c8a1SJohn Marino 	 * Go through the list of used strength_bits values in descending
933f5b1c8a1SJohn Marino 	 * order.
934f5b1c8a1SJohn Marino 	 */
935f5b1c8a1SJohn Marino 	for (i = max_strength_bits; i >= 0; i--)
936f5b1c8a1SJohn Marino 		if (number_uses[i] > 0)
937f5b1c8a1SJohn Marino 			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p);
938f5b1c8a1SJohn Marino 
939f5b1c8a1SJohn Marino 	free(number_uses);
940f5b1c8a1SJohn Marino 	return (1);
941f5b1c8a1SJohn Marino }
942f5b1c8a1SJohn Marino 
943f5b1c8a1SJohn Marino static int
ssl_cipher_process_rulestr(const char * rule_str,CIPHER_ORDER ** head_p,CIPHER_ORDER ** tail_p,const SSL_CIPHER ** ca_list,SSL_CERT * cert,int * tls13_seen)944f5b1c8a1SJohn Marino ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p,
945*de0e0e4dSAntonio Huete Jimenez     CIPHER_ORDER **tail_p, const SSL_CIPHER **ca_list, SSL_CERT *cert,
946*de0e0e4dSAntonio Huete Jimenez     int *tls13_seen)
947f5b1c8a1SJohn Marino {
948f5b1c8a1SJohn Marino 	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl;
949f5b1c8a1SJohn Marino 	unsigned long algo_strength;
950f5b1c8a1SJohn Marino 	int j, multi, found, rule, retval, ok, buflen;
951f5b1c8a1SJohn Marino 	unsigned long cipher_id = 0;
952f5b1c8a1SJohn Marino 	const char *l, *buf;
953f5b1c8a1SJohn Marino 	char ch;
954f5b1c8a1SJohn Marino 
955cca6fc52SDaniel Fojt 	*tls13_seen = 0;
956cca6fc52SDaniel Fojt 
957f5b1c8a1SJohn Marino 	retval = 1;
958f5b1c8a1SJohn Marino 	l = rule_str;
959f5b1c8a1SJohn Marino 	for (;;) {
960f5b1c8a1SJohn Marino 		ch = *l;
961f5b1c8a1SJohn Marino 
962f5b1c8a1SJohn Marino 		if (ch == '\0')
963f5b1c8a1SJohn Marino 			break;
964f5b1c8a1SJohn Marino 
965f5b1c8a1SJohn Marino 		if (ch == '-') {
966f5b1c8a1SJohn Marino 			rule = CIPHER_DEL;
967f5b1c8a1SJohn Marino 			l++;
968f5b1c8a1SJohn Marino 		} else if (ch == '+') {
969f5b1c8a1SJohn Marino 			rule = CIPHER_ORD;
970f5b1c8a1SJohn Marino 			l++;
971f5b1c8a1SJohn Marino 		} else if (ch == '!') {
972f5b1c8a1SJohn Marino 			rule = CIPHER_KILL;
973f5b1c8a1SJohn Marino 			l++;
974f5b1c8a1SJohn Marino 		} else if (ch == '@') {
975f5b1c8a1SJohn Marino 			rule = CIPHER_SPECIAL;
976f5b1c8a1SJohn Marino 			l++;
977f5b1c8a1SJohn Marino 		} else {
978f5b1c8a1SJohn Marino 			rule = CIPHER_ADD;
979f5b1c8a1SJohn Marino 		}
980f5b1c8a1SJohn Marino 
981f5b1c8a1SJohn Marino 		if (ITEM_SEP(ch)) {
982f5b1c8a1SJohn Marino 			l++;
983f5b1c8a1SJohn Marino 			continue;
984f5b1c8a1SJohn Marino 		}
985f5b1c8a1SJohn Marino 
986f5b1c8a1SJohn Marino 		alg_mkey = 0;
987f5b1c8a1SJohn Marino 		alg_auth = 0;
988f5b1c8a1SJohn Marino 		alg_enc = 0;
989f5b1c8a1SJohn Marino 		alg_mac = 0;
990f5b1c8a1SJohn Marino 		alg_ssl = 0;
991f5b1c8a1SJohn Marino 		algo_strength = 0;
992f5b1c8a1SJohn Marino 
993f5b1c8a1SJohn Marino 		for (;;) {
994f5b1c8a1SJohn Marino 			ch = *l;
995f5b1c8a1SJohn Marino 			buf = l;
996f5b1c8a1SJohn Marino 			buflen = 0;
997f5b1c8a1SJohn Marino 			while (((ch >= 'A') && (ch <= 'Z')) ||
998f5b1c8a1SJohn Marino 			    ((ch >= '0') && (ch <= '9')) ||
999f5b1c8a1SJohn Marino 			    ((ch >= 'a') && (ch <= 'z')) ||
1000cca6fc52SDaniel Fojt 			    (ch == '-') || (ch == '.') ||
1001*de0e0e4dSAntonio Huete Jimenez 			    (ch == '_') || (ch == '=')) {
1002f5b1c8a1SJohn Marino 				ch = *(++l);
1003f5b1c8a1SJohn Marino 				buflen++;
1004f5b1c8a1SJohn Marino 			}
1005f5b1c8a1SJohn Marino 
1006f5b1c8a1SJohn Marino 			if (buflen == 0) {
1007f5b1c8a1SJohn Marino 				/*
1008f5b1c8a1SJohn Marino 				 * We hit something we cannot deal with,
1009f5b1c8a1SJohn Marino 				 * it is no command or separator nor
1010f5b1c8a1SJohn Marino 				 * alphanumeric, so we call this an error.
1011f5b1c8a1SJohn Marino 				 */
101272c33676SMaxim Ag 				SSLerrorx(SSL_R_INVALID_COMMAND);
1013*de0e0e4dSAntonio Huete Jimenez 				return 0;
1014f5b1c8a1SJohn Marino 			}
1015f5b1c8a1SJohn Marino 
1016f5b1c8a1SJohn Marino 			if (rule == CIPHER_SPECIAL) {
1017f5b1c8a1SJohn Marino 				 /* unused -- avoid compiler warning */
1018f5b1c8a1SJohn Marino 				found = 0;
1019f5b1c8a1SJohn Marino 				/* special treatment */
1020f5b1c8a1SJohn Marino 				break;
1021f5b1c8a1SJohn Marino 			}
1022f5b1c8a1SJohn Marino 
1023f5b1c8a1SJohn Marino 			/* check for multi-part specification */
1024f5b1c8a1SJohn Marino 			if (ch == '+') {
1025f5b1c8a1SJohn Marino 				multi = 1;
1026f5b1c8a1SJohn Marino 				l++;
1027f5b1c8a1SJohn Marino 			} else
1028f5b1c8a1SJohn Marino 				multi = 0;
1029f5b1c8a1SJohn Marino 
1030f5b1c8a1SJohn Marino 			/*
1031f5b1c8a1SJohn Marino 			 * Now search for the cipher alias in the ca_list.
1032f5b1c8a1SJohn Marino 			 * Be careful with the strncmp, because the "buflen"
1033f5b1c8a1SJohn Marino 			 * limitation will make the rule "ADH:SOME" and the
1034f5b1c8a1SJohn Marino 			 * cipher "ADH-MY-CIPHER" look like a match for
1035f5b1c8a1SJohn Marino 			 * buflen=3. So additionally check whether the cipher
1036f5b1c8a1SJohn Marino 			 * name found has the correct length. We can save a
1037f5b1c8a1SJohn Marino 			 * strlen() call: just checking for the '\0' at the
1038f5b1c8a1SJohn Marino 			 * right place is sufficient, we have to strncmp()
1039f5b1c8a1SJohn Marino 			 * anyway (we cannot use strcmp(), because buf is not
1040f5b1c8a1SJohn Marino 			 * '\0' terminated.)
1041f5b1c8a1SJohn Marino 			 */
1042f5b1c8a1SJohn Marino 			j = found = 0;
1043f5b1c8a1SJohn Marino 			cipher_id = 0;
1044f5b1c8a1SJohn Marino 			while (ca_list[j]) {
1045f5b1c8a1SJohn Marino 				if (!strncmp(buf, ca_list[j]->name, buflen) &&
1046f5b1c8a1SJohn Marino 				    (ca_list[j]->name[buflen] == '\0')) {
1047f5b1c8a1SJohn Marino 					found = 1;
1048f5b1c8a1SJohn Marino 					break;
1049f5b1c8a1SJohn Marino 				} else
1050f5b1c8a1SJohn Marino 					j++;
1051f5b1c8a1SJohn Marino 			}
1052f5b1c8a1SJohn Marino 
1053f5b1c8a1SJohn Marino 			if (!found)
1054f5b1c8a1SJohn Marino 				break;	/* ignore this entry */
1055f5b1c8a1SJohn Marino 
1056f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_mkey) {
1057f5b1c8a1SJohn Marino 				if (alg_mkey) {
1058f5b1c8a1SJohn Marino 					alg_mkey &= ca_list[j]->algorithm_mkey;
1059f5b1c8a1SJohn Marino 					if (!alg_mkey) {
1060f5b1c8a1SJohn Marino 						found = 0;
1061f5b1c8a1SJohn Marino 						break;
1062f5b1c8a1SJohn Marino 					}
1063f5b1c8a1SJohn Marino 				} else
1064f5b1c8a1SJohn Marino 					alg_mkey = ca_list[j]->algorithm_mkey;
1065f5b1c8a1SJohn Marino 			}
1066f5b1c8a1SJohn Marino 
1067f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_auth) {
1068f5b1c8a1SJohn Marino 				if (alg_auth) {
1069f5b1c8a1SJohn Marino 					alg_auth &= ca_list[j]->algorithm_auth;
1070f5b1c8a1SJohn Marino 					if (!alg_auth) {
1071f5b1c8a1SJohn Marino 						found = 0;
1072f5b1c8a1SJohn Marino 						break;
1073f5b1c8a1SJohn Marino 					}
1074f5b1c8a1SJohn Marino 				} else
1075f5b1c8a1SJohn Marino 					alg_auth = ca_list[j]->algorithm_auth;
1076f5b1c8a1SJohn Marino 			}
1077f5b1c8a1SJohn Marino 
1078f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_enc) {
1079f5b1c8a1SJohn Marino 				if (alg_enc) {
1080f5b1c8a1SJohn Marino 					alg_enc &= ca_list[j]->algorithm_enc;
1081f5b1c8a1SJohn Marino 					if (!alg_enc) {
1082f5b1c8a1SJohn Marino 						found = 0;
1083f5b1c8a1SJohn Marino 						break;
1084f5b1c8a1SJohn Marino 					}
1085f5b1c8a1SJohn Marino 				} else
1086f5b1c8a1SJohn Marino 					alg_enc = ca_list[j]->algorithm_enc;
1087f5b1c8a1SJohn Marino 			}
1088f5b1c8a1SJohn Marino 
1089f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_mac) {
1090f5b1c8a1SJohn Marino 				if (alg_mac) {
1091f5b1c8a1SJohn Marino 					alg_mac &= ca_list[j]->algorithm_mac;
1092f5b1c8a1SJohn Marino 					if (!alg_mac) {
1093f5b1c8a1SJohn Marino 						found = 0;
1094f5b1c8a1SJohn Marino 						break;
1095f5b1c8a1SJohn Marino 					}
1096f5b1c8a1SJohn Marino 				} else
1097f5b1c8a1SJohn Marino 					alg_mac = ca_list[j]->algorithm_mac;
1098f5b1c8a1SJohn Marino 			}
1099f5b1c8a1SJohn Marino 
1100f5b1c8a1SJohn Marino 			if (ca_list[j]->algo_strength & SSL_STRONG_MASK) {
1101f5b1c8a1SJohn Marino 				if (algo_strength & SSL_STRONG_MASK) {
1102f5b1c8a1SJohn Marino 					algo_strength &=
1103f5b1c8a1SJohn Marino 					    (ca_list[j]->algo_strength &
1104f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
1105f5b1c8a1SJohn Marino 					if (!(algo_strength &
1106f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK)) {
1107f5b1c8a1SJohn Marino 						found = 0;
1108f5b1c8a1SJohn Marino 						break;
1109f5b1c8a1SJohn Marino 					}
1110f5b1c8a1SJohn Marino 				} else
1111f5b1c8a1SJohn Marino 					algo_strength |=
1112f5b1c8a1SJohn Marino 					    ca_list[j]->algo_strength &
1113f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK;
1114f5b1c8a1SJohn Marino 			}
1115f5b1c8a1SJohn Marino 
1116f5b1c8a1SJohn Marino 			if (ca_list[j]->valid) {
1117f5b1c8a1SJohn Marino 				/*
1118f5b1c8a1SJohn Marino 				 * explicit ciphersuite found; its protocol
1119f5b1c8a1SJohn Marino 				 * version does not become part of the search
1120f5b1c8a1SJohn Marino 				 * pattern!
1121f5b1c8a1SJohn Marino 				 */
1122f5b1c8a1SJohn Marino 				cipher_id = ca_list[j]->id;
1123cca6fc52SDaniel Fojt 				if (ca_list[j]->algorithm_ssl == SSL_TLSV1_3)
1124cca6fc52SDaniel Fojt 					*tls13_seen = 1;
1125f5b1c8a1SJohn Marino 			} else {
1126f5b1c8a1SJohn Marino 				/*
1127f5b1c8a1SJohn Marino 				 * not an explicit ciphersuite; only in this
1128f5b1c8a1SJohn Marino 				 * case, the protocol version is considered
1129f5b1c8a1SJohn Marino 				 * part of the search pattern
1130f5b1c8a1SJohn Marino 				 */
1131f5b1c8a1SJohn Marino 				if (ca_list[j]->algorithm_ssl) {
1132f5b1c8a1SJohn Marino 					if (alg_ssl) {
1133f5b1c8a1SJohn Marino 						alg_ssl &=
1134f5b1c8a1SJohn Marino 						    ca_list[j]->algorithm_ssl;
1135f5b1c8a1SJohn Marino 						if (!alg_ssl) {
1136f5b1c8a1SJohn Marino 							found = 0;
1137f5b1c8a1SJohn Marino 							break;
1138f5b1c8a1SJohn Marino 						}
1139f5b1c8a1SJohn Marino 					} else
1140f5b1c8a1SJohn Marino 						alg_ssl =
1141f5b1c8a1SJohn Marino 						    ca_list[j]->algorithm_ssl;
1142f5b1c8a1SJohn Marino 				}
1143f5b1c8a1SJohn Marino 			}
1144f5b1c8a1SJohn Marino 
1145f5b1c8a1SJohn Marino 			if (!multi)
1146f5b1c8a1SJohn Marino 				break;
1147f5b1c8a1SJohn Marino 		}
1148f5b1c8a1SJohn Marino 
1149f5b1c8a1SJohn Marino 		/*
1150f5b1c8a1SJohn Marino 		 * Ok, we have the rule, now apply it
1151f5b1c8a1SJohn Marino 		 */
1152f5b1c8a1SJohn Marino 		if (rule == CIPHER_SPECIAL) {
1153f5b1c8a1SJohn Marino 			/* special command */
1154f5b1c8a1SJohn Marino 			ok = 0;
1155*de0e0e4dSAntonio Huete Jimenez 			if (buflen == 8 && strncmp(buf, "STRENGTH", 8) == 0) {
1156f5b1c8a1SJohn Marino 				ok = ssl_cipher_strength_sort(head_p, tail_p);
1157*de0e0e4dSAntonio Huete Jimenez 			} else if (buflen == 10 &&
1158*de0e0e4dSAntonio Huete Jimenez 			    strncmp(buf, "SECLEVEL=", 9) == 0) {
1159*de0e0e4dSAntonio Huete Jimenez 				int level = buf[9] - '0';
1160*de0e0e4dSAntonio Huete Jimenez 
1161*de0e0e4dSAntonio Huete Jimenez 				if (level >= 0 && level <= 5) {
1162*de0e0e4dSAntonio Huete Jimenez 					cert->security_level = level;
1163*de0e0e4dSAntonio Huete Jimenez 					ok = 1;
1164*de0e0e4dSAntonio Huete Jimenez 				} else {
116572c33676SMaxim Ag 					SSLerrorx(SSL_R_INVALID_COMMAND);
1166*de0e0e4dSAntonio Huete Jimenez 				}
1167*de0e0e4dSAntonio Huete Jimenez 			} else {
1168*de0e0e4dSAntonio Huete Jimenez 				SSLerrorx(SSL_R_INVALID_COMMAND);
1169*de0e0e4dSAntonio Huete Jimenez 			}
1170f5b1c8a1SJohn Marino 			if (ok == 0)
1171f5b1c8a1SJohn Marino 				retval = 0;
1172*de0e0e4dSAntonio Huete Jimenez 
1173f5b1c8a1SJohn Marino 			while ((*l != '\0') && !ITEM_SEP(*l))
1174f5b1c8a1SJohn Marino 				l++;
1175f5b1c8a1SJohn Marino 		} else if (found) {
1176cca6fc52SDaniel Fojt 			if (alg_ssl == SSL_TLSV1_3)
1177cca6fc52SDaniel Fojt 				*tls13_seen = 1;
1178f5b1c8a1SJohn Marino 			ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth,
1179f5b1c8a1SJohn Marino 			    alg_enc, alg_mac, alg_ssl, algo_strength, rule,
1180f5b1c8a1SJohn Marino 			    -1, head_p, tail_p);
1181f5b1c8a1SJohn Marino 		} else {
1182f5b1c8a1SJohn Marino 			while ((*l != '\0') && !ITEM_SEP(*l))
1183f5b1c8a1SJohn Marino 				l++;
1184f5b1c8a1SJohn Marino 		}
1185f5b1c8a1SJohn Marino 		if (*l == '\0')
1186f5b1c8a1SJohn Marino 			break; /* done */
1187f5b1c8a1SJohn Marino 	}
1188f5b1c8a1SJohn Marino 
1189f5b1c8a1SJohn Marino 	return (retval);
1190f5b1c8a1SJohn Marino }
1191f5b1c8a1SJohn Marino 
1192f5b1c8a1SJohn Marino static inline int
ssl_aes_is_accelerated(void)1193f5b1c8a1SJohn Marino ssl_aes_is_accelerated(void)
1194f5b1c8a1SJohn Marino {
1195f5b1c8a1SJohn Marino #if defined(__i386__) || defined(__x86_64__)
1196f5b1c8a1SJohn Marino 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
1197f5b1c8a1SJohn Marino #else
1198f5b1c8a1SJohn Marino 	return (0);
1199f5b1c8a1SJohn Marino #endif
1200f5b1c8a1SJohn Marino }
1201f5b1c8a1SJohn Marino 
STACK_OF(SSL_CIPHER)1202f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) *
1203f5b1c8a1SJohn Marino ssl_create_cipher_list(const SSL_METHOD *ssl_method,
1204f5b1c8a1SJohn Marino     STACK_OF(SSL_CIPHER) **cipher_list,
12058edacedfSDaniel Fojt     STACK_OF(SSL_CIPHER) *cipher_list_tls13,
1206*de0e0e4dSAntonio Huete Jimenez     const char *rule_str, SSL_CERT *cert)
1207f5b1c8a1SJohn Marino {
1208f5b1c8a1SJohn Marino 	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
1209f5b1c8a1SJohn Marino 	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
1210*de0e0e4dSAntonio Huete Jimenez 	STACK_OF(SSL_CIPHER) *cipherstack = NULL, *ret = NULL;
1211f5b1c8a1SJohn Marino 	const char *rule_p;
1212f5b1c8a1SJohn Marino 	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
1213f5b1c8a1SJohn Marino 	const SSL_CIPHER **ca_list = NULL;
12148edacedfSDaniel Fojt 	const SSL_CIPHER *cipher;
1215cca6fc52SDaniel Fojt 	int tls13_seen = 0;
1216cca6fc52SDaniel Fojt 	int any_active;
12178edacedfSDaniel Fojt 	int i;
1218f5b1c8a1SJohn Marino 
1219f5b1c8a1SJohn Marino 	/*
1220f5b1c8a1SJohn Marino 	 * Return with error if nothing to do.
1221f5b1c8a1SJohn Marino 	 */
12228edacedfSDaniel Fojt 	if (rule_str == NULL || cipher_list == NULL)
1223*de0e0e4dSAntonio Huete Jimenez 		goto err;
1224f5b1c8a1SJohn Marino 
1225f5b1c8a1SJohn Marino 	/*
1226f5b1c8a1SJohn Marino 	 * To reduce the work to do we only want to process the compiled
1227f5b1c8a1SJohn Marino 	 * in algorithms, so we first get the mask of disabled ciphers.
1228f5b1c8a1SJohn Marino 	 */
1229f5b1c8a1SJohn Marino 	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
1230f5b1c8a1SJohn Marino 
1231f5b1c8a1SJohn Marino 	/*
1232f5b1c8a1SJohn Marino 	 * Now we have to collect the available ciphers from the compiled
1233f5b1c8a1SJohn Marino 	 * in ciphers. We cannot get more than the number compiled in, so
1234f5b1c8a1SJohn Marino 	 * it is used for allocation.
1235f5b1c8a1SJohn Marino 	 */
1236*de0e0e4dSAntonio Huete Jimenez 	num_of_ciphers = ssl3_num_ciphers();
1237f5b1c8a1SJohn Marino 	co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER));
1238f5b1c8a1SJohn Marino 	if (co_list == NULL) {
123972c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
1240*de0e0e4dSAntonio Huete Jimenez 		goto err;
1241f5b1c8a1SJohn Marino 	}
1242f5b1c8a1SJohn Marino 
1243f5b1c8a1SJohn Marino 	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
1244f5b1c8a1SJohn Marino 	    disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
1245f5b1c8a1SJohn Marino 	    co_list, &head, &tail);
1246f5b1c8a1SJohn Marino 
1247f5b1c8a1SJohn Marino 
1248f5b1c8a1SJohn Marino 	/* Now arrange all ciphers by preference: */
1249f5b1c8a1SJohn Marino 
1250f5b1c8a1SJohn Marino 	/* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
1251f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1252f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
1253f5b1c8a1SJohn Marino 
1254cca6fc52SDaniel Fojt 	if (ssl_aes_is_accelerated()) {
1255f5b1c8a1SJohn Marino 		/*
1256f5b1c8a1SJohn Marino 		 * We have hardware assisted AES - prefer AES as a symmetric
1257f5b1c8a1SJohn Marino 		 * cipher, with CHACHA20 second.
1258f5b1c8a1SJohn Marino 		 */
1259f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
1260f5b1c8a1SJohn Marino 		    CIPHER_ADD, -1, &head, &tail);
1261f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
1262f5b1c8a1SJohn Marino 		    0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1263f5b1c8a1SJohn Marino 	} else {
1264f5b1c8a1SJohn Marino 		/*
1265f5b1c8a1SJohn Marino 		 * CHACHA20 is fast and safe on all hardware and is thus our
1266f5b1c8a1SJohn Marino 		 * preferred symmetric cipher, with AES second.
1267f5b1c8a1SJohn Marino 		 */
1268f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
1269f5b1c8a1SJohn Marino 		    0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1270f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
1271f5b1c8a1SJohn Marino 		    CIPHER_ADD, -1, &head, &tail);
1272f5b1c8a1SJohn Marino 	}
1273f5b1c8a1SJohn Marino 
1274f5b1c8a1SJohn Marino 	/* Temporarily enable everything else for sorting */
1275f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1276f5b1c8a1SJohn Marino 
1277f5b1c8a1SJohn Marino 	/* Low priority for MD5 */
1278f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
1279f5b1c8a1SJohn Marino 
1280f5b1c8a1SJohn Marino 	/* Move anonymous ciphers to the end.  Usually, these will remain disabled.
1281f5b1c8a1SJohn Marino 	 * (For applications that allow them, they aren't too bad, but we prefer
1282f5b1c8a1SJohn Marino 	 * authenticated ciphers.) */
1283f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1284f5b1c8a1SJohn Marino 
1285f5b1c8a1SJohn Marino 	/* Move ciphers without forward secrecy to the end */
1286f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1287f5b1c8a1SJohn Marino 
1288f5b1c8a1SJohn Marino 	/* RC4 is sort of broken - move it to the end */
1289f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1290f5b1c8a1SJohn Marino 
1291f5b1c8a1SJohn Marino 	/* Now sort by symmetric encryption strength.  The above ordering remains
1292f5b1c8a1SJohn Marino 	 * in force within each class */
1293*de0e0e4dSAntonio Huete Jimenez 	if (!ssl_cipher_strength_sort(&head, &tail))
1294*de0e0e4dSAntonio Huete Jimenez 		goto err;
1295f5b1c8a1SJohn Marino 
1296f5b1c8a1SJohn Marino 	/* Now disable everything (maintaining the ordering!) */
1297f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
1298f5b1c8a1SJohn Marino 
129972c33676SMaxim Ag 	/* TLSv1.3 first. */
130072c33676SMaxim Ag 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_ADD, -1, &head, &tail);
130172c33676SMaxim Ag 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_DEL, -1, &head, &tail);
1302f5b1c8a1SJohn Marino 
1303f5b1c8a1SJohn Marino 	/*
1304f5b1c8a1SJohn Marino 	 * We also need cipher aliases for selecting based on the rule_str.
1305f5b1c8a1SJohn Marino 	 * There might be two types of entries in the rule_str: 1) names
1306f5b1c8a1SJohn Marino 	 * of ciphers themselves 2) aliases for groups of ciphers.
1307f5b1c8a1SJohn Marino 	 * For 1) we need the available ciphers and for 2) the cipher
1308f5b1c8a1SJohn Marino 	 * groups of cipher_aliases added together in one list (otherwise
1309f5b1c8a1SJohn Marino 	 * we would be happy with just the cipher_aliases table).
1310f5b1c8a1SJohn Marino 	 */
1311f5b1c8a1SJohn Marino 	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
1312f5b1c8a1SJohn Marino 	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
1313f5b1c8a1SJohn Marino 	ca_list = reallocarray(NULL, num_of_alias_max, sizeof(SSL_CIPHER *));
1314f5b1c8a1SJohn Marino 	if (ca_list == NULL) {
131572c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
1316*de0e0e4dSAntonio Huete Jimenez 		goto err;
1317f5b1c8a1SJohn Marino 	}
1318cca6fc52SDaniel Fojt 	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mkey,
1319cca6fc52SDaniel Fojt 	    disabled_auth, disabled_enc, disabled_mac, disabled_ssl, head);
1320f5b1c8a1SJohn Marino 
1321f5b1c8a1SJohn Marino 	/*
1322f5b1c8a1SJohn Marino 	 * If the rule_string begins with DEFAULT, apply the default rule
1323f5b1c8a1SJohn Marino 	 * before using the (possibly available) additional rules.
1324f5b1c8a1SJohn Marino 	 */
1325f5b1c8a1SJohn Marino 	ok = 1;
1326f5b1c8a1SJohn Marino 	rule_p = rule_str;
1327f5b1c8a1SJohn Marino 	if (strncmp(rule_str, "DEFAULT", 7) == 0) {
1328f5b1c8a1SJohn Marino 		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
1329*de0e0e4dSAntonio Huete Jimenez 		    &head, &tail, ca_list, cert, &tls13_seen);
1330f5b1c8a1SJohn Marino 		rule_p += 7;
1331f5b1c8a1SJohn Marino 		if (*rule_p == ':')
1332f5b1c8a1SJohn Marino 			rule_p++;
1333f5b1c8a1SJohn Marino 	}
1334f5b1c8a1SJohn Marino 
1335f5b1c8a1SJohn Marino 	if (ok && (strlen(rule_p) > 0))
1336cca6fc52SDaniel Fojt 		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list,
1337*de0e0e4dSAntonio Huete Jimenez 		    cert, &tls13_seen);
1338f5b1c8a1SJohn Marino 
1339f5b1c8a1SJohn Marino 	if (!ok) {
1340f5b1c8a1SJohn Marino 		/* Rule processing failure */
1341*de0e0e4dSAntonio Huete Jimenez 		goto err;
1342f5b1c8a1SJohn Marino 	}
1343f5b1c8a1SJohn Marino 
1344f5b1c8a1SJohn Marino 	/*
1345f5b1c8a1SJohn Marino 	 * Allocate new "cipherstack" for the result, return with error
1346f5b1c8a1SJohn Marino 	 * if we cannot get one.
1347f5b1c8a1SJohn Marino 	 */
1348f5b1c8a1SJohn Marino 	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
1349*de0e0e4dSAntonio Huete Jimenez 		SSLerrorx(ERR_R_MALLOC_FAILURE);
1350*de0e0e4dSAntonio Huete Jimenez 		goto err;
1351f5b1c8a1SJohn Marino 	}
1352f5b1c8a1SJohn Marino 
13538edacedfSDaniel Fojt 	/* Prefer TLSv1.3 cipher suites. */
13548edacedfSDaniel Fojt 	if (cipher_list_tls13 != NULL) {
13558edacedfSDaniel Fojt 		for (i = 0; i < sk_SSL_CIPHER_num(cipher_list_tls13); i++) {
13568edacedfSDaniel Fojt 			cipher = sk_SSL_CIPHER_value(cipher_list_tls13, i);
1357*de0e0e4dSAntonio Huete Jimenez 			if (!sk_SSL_CIPHER_push(cipherstack, cipher)) {
1358*de0e0e4dSAntonio Huete Jimenez 				SSLerrorx(ERR_R_MALLOC_FAILURE);
1359*de0e0e4dSAntonio Huete Jimenez 				goto err;
1360*de0e0e4dSAntonio Huete Jimenez 			}
13618edacedfSDaniel Fojt 		}
13628edacedfSDaniel Fojt 		tls13_seen = 1;
13638edacedfSDaniel Fojt 	}
13648edacedfSDaniel Fojt 
1365f5b1c8a1SJohn Marino 	/*
1366f5b1c8a1SJohn Marino 	 * The cipher selection for the list is done. The ciphers are added
1367f5b1c8a1SJohn Marino 	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
1368cca6fc52SDaniel Fojt 	 *
13698edacedfSDaniel Fojt 	 * If the rule string did not contain any references to TLSv1.3 and
13708edacedfSDaniel Fojt 	 * TLSv1.3 cipher suites have not been configured separately,
1371cca6fc52SDaniel Fojt 	 * include inactive TLSv1.3 cipher suites. This avoids attempts to
1372cca6fc52SDaniel Fojt 	 * use TLSv1.3 with an older rule string that does not include
1373cca6fc52SDaniel Fojt 	 * TLSv1.3 cipher suites. If the rule string resulted in no active
1374cca6fc52SDaniel Fojt 	 * cipher suites then we return an empty stack.
1375f5b1c8a1SJohn Marino 	 */
1376cca6fc52SDaniel Fojt 	any_active = 0;
1377f5b1c8a1SJohn Marino 	for (curr = head; curr != NULL; curr = curr->next) {
1378cca6fc52SDaniel Fojt 		if (curr->active ||
1379*de0e0e4dSAntonio Huete Jimenez 		    (!tls13_seen && curr->cipher->algorithm_ssl == SSL_TLSV1_3)) {
1380*de0e0e4dSAntonio Huete Jimenez 			if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
1381*de0e0e4dSAntonio Huete Jimenez 				SSLerrorx(ERR_R_MALLOC_FAILURE);
1382*de0e0e4dSAntonio Huete Jimenez 				goto err;
1383*de0e0e4dSAntonio Huete Jimenez 			}
1384*de0e0e4dSAntonio Huete Jimenez 		}
1385cca6fc52SDaniel Fojt 		any_active |= curr->active;
1386f5b1c8a1SJohn Marino 	}
1387cca6fc52SDaniel Fojt 	if (!any_active)
1388cca6fc52SDaniel Fojt 		sk_SSL_CIPHER_zero(cipherstack);
1389cca6fc52SDaniel Fojt 
1390f5b1c8a1SJohn Marino 	sk_SSL_CIPHER_free(*cipher_list);
1391f5b1c8a1SJohn Marino 	*cipher_list = cipherstack;
1392*de0e0e4dSAntonio Huete Jimenez 	cipherstack = NULL;
1393f5b1c8a1SJohn Marino 
1394*de0e0e4dSAntonio Huete Jimenez 	ret = *cipher_list;
1395*de0e0e4dSAntonio Huete Jimenez 
1396*de0e0e4dSAntonio Huete Jimenez  err:
1397*de0e0e4dSAntonio Huete Jimenez 	sk_SSL_CIPHER_free(cipherstack);
1398*de0e0e4dSAntonio Huete Jimenez 	free((void *)ca_list);
1399*de0e0e4dSAntonio Huete Jimenez 	free(co_list);
1400*de0e0e4dSAntonio Huete Jimenez 
1401*de0e0e4dSAntonio Huete Jimenez 	return ret;
1402f5b1c8a1SJohn Marino }
1403f5b1c8a1SJohn Marino 
1404f5b1c8a1SJohn Marino const SSL_CIPHER *
SSL_CIPHER_get_by_id(unsigned int id)1405f5b1c8a1SJohn Marino SSL_CIPHER_get_by_id(unsigned int id)
1406f5b1c8a1SJohn Marino {
1407f5b1c8a1SJohn Marino 	return ssl3_get_cipher_by_id(id);
1408f5b1c8a1SJohn Marino }
1409f5b1c8a1SJohn Marino 
1410f5b1c8a1SJohn Marino const SSL_CIPHER *
SSL_CIPHER_get_by_value(uint16_t value)1411f5b1c8a1SJohn Marino SSL_CIPHER_get_by_value(uint16_t value)
1412f5b1c8a1SJohn Marino {
1413f5b1c8a1SJohn Marino 	return ssl3_get_cipher_by_value(value);
1414f5b1c8a1SJohn Marino }
1415f5b1c8a1SJohn Marino 
1416f5b1c8a1SJohn Marino char *
SSL_CIPHER_description(const SSL_CIPHER * cipher,char * buf,int len)1417f5b1c8a1SJohn Marino SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
1418f5b1c8a1SJohn Marino {
1419f5b1c8a1SJohn Marino 	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2;
1420f5b1c8a1SJohn Marino 	const char *ver, *kx, *au, *enc, *mac;
1421f5b1c8a1SJohn Marino 	char *ret;
1422f5b1c8a1SJohn Marino 	int l;
1423f5b1c8a1SJohn Marino 
1424f5b1c8a1SJohn Marino 	alg_mkey = cipher->algorithm_mkey;
1425f5b1c8a1SJohn Marino 	alg_auth = cipher->algorithm_auth;
1426f5b1c8a1SJohn Marino 	alg_enc = cipher->algorithm_enc;
1427f5b1c8a1SJohn Marino 	alg_mac = cipher->algorithm_mac;
1428f5b1c8a1SJohn Marino 	alg_ssl = cipher->algorithm_ssl;
1429f5b1c8a1SJohn Marino 
1430f5b1c8a1SJohn Marino 	alg2 = cipher->algorithm2;
1431f5b1c8a1SJohn Marino 
1432f5b1c8a1SJohn Marino 	if (alg_ssl & SSL_SSLV3)
1433f5b1c8a1SJohn Marino 		ver = "SSLv3";
1434f5b1c8a1SJohn Marino 	else if (alg_ssl & SSL_TLSV1_2)
1435f5b1c8a1SJohn Marino 		ver = "TLSv1.2";
143672c33676SMaxim Ag 	else if (alg_ssl & SSL_TLSV1_3)
143772c33676SMaxim Ag 		ver = "TLSv1.3";
1438f5b1c8a1SJohn Marino 	else
1439f5b1c8a1SJohn Marino 		ver = "unknown";
1440f5b1c8a1SJohn Marino 
1441f5b1c8a1SJohn Marino 	switch (alg_mkey) {
1442f5b1c8a1SJohn Marino 	case SSL_kRSA:
1443f5b1c8a1SJohn Marino 		kx = "RSA";
1444f5b1c8a1SJohn Marino 		break;
1445f5b1c8a1SJohn Marino 	case SSL_kDHE:
1446f5b1c8a1SJohn Marino 		kx = "DH";
1447f5b1c8a1SJohn Marino 		break;
1448f5b1c8a1SJohn Marino 	case SSL_kECDHE:
1449f5b1c8a1SJohn Marino 		kx = "ECDH";
1450f5b1c8a1SJohn Marino 		break;
1451f5b1c8a1SJohn Marino 	case SSL_kGOST:
1452f5b1c8a1SJohn Marino 		kx = "GOST";
1453f5b1c8a1SJohn Marino 		break;
1454cca6fc52SDaniel Fojt 	case SSL_kTLS1_3:
1455cca6fc52SDaniel Fojt 		kx = "TLSv1.3";
1456cca6fc52SDaniel Fojt 		break;
1457f5b1c8a1SJohn Marino 	default:
1458f5b1c8a1SJohn Marino 		kx = "unknown";
1459f5b1c8a1SJohn Marino 	}
1460f5b1c8a1SJohn Marino 
1461f5b1c8a1SJohn Marino 	switch (alg_auth) {
1462f5b1c8a1SJohn Marino 	case SSL_aRSA:
1463f5b1c8a1SJohn Marino 		au = "RSA";
1464f5b1c8a1SJohn Marino 		break;
1465f5b1c8a1SJohn Marino 	case SSL_aDSS:
1466f5b1c8a1SJohn Marino 		au = "DSS";
1467f5b1c8a1SJohn Marino 		break;
1468f5b1c8a1SJohn Marino 	case SSL_aNULL:
1469f5b1c8a1SJohn Marino 		au = "None";
1470f5b1c8a1SJohn Marino 		break;
1471f5b1c8a1SJohn Marino 	case SSL_aECDSA:
1472f5b1c8a1SJohn Marino 		au = "ECDSA";
1473f5b1c8a1SJohn Marino 		break;
1474f5b1c8a1SJohn Marino 	case SSL_aGOST01:
1475f5b1c8a1SJohn Marino 		au = "GOST01";
1476f5b1c8a1SJohn Marino 		break;
1477cca6fc52SDaniel Fojt 	case SSL_aTLS1_3:
1478cca6fc52SDaniel Fojt 		au = "TLSv1.3";
1479cca6fc52SDaniel Fojt 		break;
1480f5b1c8a1SJohn Marino 	default:
1481f5b1c8a1SJohn Marino 		au = "unknown";
1482f5b1c8a1SJohn Marino 		break;
1483f5b1c8a1SJohn Marino 	}
1484f5b1c8a1SJohn Marino 
1485f5b1c8a1SJohn Marino 	switch (alg_enc) {
1486f5b1c8a1SJohn Marino 	case SSL_3DES:
1487f5b1c8a1SJohn Marino 		enc = "3DES(168)";
1488f5b1c8a1SJohn Marino 		break;
1489f5b1c8a1SJohn Marino 	case SSL_RC4:
1490f5b1c8a1SJohn Marino 		enc = alg2 & SSL2_CF_8_BYTE_ENC ? "RC4(64)" : "RC4(128)";
1491f5b1c8a1SJohn Marino 		break;
1492f5b1c8a1SJohn Marino 	case SSL_eNULL:
1493f5b1c8a1SJohn Marino 		enc = "None";
1494f5b1c8a1SJohn Marino 		break;
1495f5b1c8a1SJohn Marino 	case SSL_AES128:
1496f5b1c8a1SJohn Marino 		enc = "AES(128)";
1497f5b1c8a1SJohn Marino 		break;
1498f5b1c8a1SJohn Marino 	case SSL_AES256:
1499f5b1c8a1SJohn Marino 		enc = "AES(256)";
1500f5b1c8a1SJohn Marino 		break;
1501f5b1c8a1SJohn Marino 	case SSL_AES128GCM:
1502f5b1c8a1SJohn Marino 		enc = "AESGCM(128)";
1503f5b1c8a1SJohn Marino 		break;
1504f5b1c8a1SJohn Marino 	case SSL_AES256GCM:
1505f5b1c8a1SJohn Marino 		enc = "AESGCM(256)";
1506f5b1c8a1SJohn Marino 		break;
1507f5b1c8a1SJohn Marino 	case SSL_CAMELLIA128:
1508f5b1c8a1SJohn Marino 		enc = "Camellia(128)";
1509f5b1c8a1SJohn Marino 		break;
1510f5b1c8a1SJohn Marino 	case SSL_CAMELLIA256:
1511f5b1c8a1SJohn Marino 		enc = "Camellia(256)";
1512f5b1c8a1SJohn Marino 		break;
1513f5b1c8a1SJohn Marino 	case SSL_CHACHA20POLY1305:
1514f5b1c8a1SJohn Marino 		enc = "ChaCha20-Poly1305";
1515f5b1c8a1SJohn Marino 		break;
1516f5b1c8a1SJohn Marino 	case SSL_eGOST2814789CNT:
1517f5b1c8a1SJohn Marino 		enc = "GOST-28178-89-CNT";
1518f5b1c8a1SJohn Marino 		break;
1519f5b1c8a1SJohn Marino 	default:
1520f5b1c8a1SJohn Marino 		enc = "unknown";
1521f5b1c8a1SJohn Marino 		break;
1522f5b1c8a1SJohn Marino 	}
1523f5b1c8a1SJohn Marino 
1524f5b1c8a1SJohn Marino 	switch (alg_mac) {
1525f5b1c8a1SJohn Marino 	case SSL_MD5:
1526f5b1c8a1SJohn Marino 		mac = "MD5";
1527f5b1c8a1SJohn Marino 		break;
1528f5b1c8a1SJohn Marino 	case SSL_SHA1:
1529f5b1c8a1SJohn Marino 		mac = "SHA1";
1530f5b1c8a1SJohn Marino 		break;
1531f5b1c8a1SJohn Marino 	case SSL_SHA256:
1532f5b1c8a1SJohn Marino 		mac = "SHA256";
1533f5b1c8a1SJohn Marino 		break;
1534f5b1c8a1SJohn Marino 	case SSL_SHA384:
1535f5b1c8a1SJohn Marino 		mac = "SHA384";
1536f5b1c8a1SJohn Marino 		break;
1537f5b1c8a1SJohn Marino 	case SSL_AEAD:
1538f5b1c8a1SJohn Marino 		mac = "AEAD";
1539f5b1c8a1SJohn Marino 		break;
1540f5b1c8a1SJohn Marino 	case SSL_GOST94:
1541f5b1c8a1SJohn Marino 		mac = "GOST94";
1542f5b1c8a1SJohn Marino 		break;
1543f5b1c8a1SJohn Marino 	case SSL_GOST89MAC:
1544f5b1c8a1SJohn Marino 		mac = "GOST89IMIT";
1545f5b1c8a1SJohn Marino 		break;
1546f5b1c8a1SJohn Marino 	case SSL_STREEBOG256:
1547f5b1c8a1SJohn Marino 		mac = "STREEBOG256";
1548f5b1c8a1SJohn Marino 		break;
1549f5b1c8a1SJohn Marino 	default:
1550f5b1c8a1SJohn Marino 		mac = "unknown";
1551f5b1c8a1SJohn Marino 		break;
1552f5b1c8a1SJohn Marino 	}
1553f5b1c8a1SJohn Marino 
1554f5b1c8a1SJohn Marino 	if (asprintf(&ret, "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n",
1555f5b1c8a1SJohn Marino 	    cipher->name, ver, kx, au, enc, mac) == -1)
1556f5b1c8a1SJohn Marino 		return "OPENSSL_malloc Error";
1557f5b1c8a1SJohn Marino 
1558f5b1c8a1SJohn Marino 	if (buf != NULL) {
1559f5b1c8a1SJohn Marino 		l = strlcpy(buf, ret, len);
1560f5b1c8a1SJohn Marino 		free(ret);
1561f5b1c8a1SJohn Marino 		ret = buf;
1562f5b1c8a1SJohn Marino 		if (l >= len)
1563f5b1c8a1SJohn Marino 			ret = "Buffer too small";
1564f5b1c8a1SJohn Marino 	}
1565f5b1c8a1SJohn Marino 
1566f5b1c8a1SJohn Marino 	return (ret);
1567f5b1c8a1SJohn Marino }
1568f5b1c8a1SJohn Marino 
156972c33676SMaxim Ag const char *
SSL_CIPHER_get_version(const SSL_CIPHER * c)1570f5b1c8a1SJohn Marino SSL_CIPHER_get_version(const SSL_CIPHER *c)
1571f5b1c8a1SJohn Marino {
1572f5b1c8a1SJohn Marino 	if (c == NULL)
1573f5b1c8a1SJohn Marino 		return("(NONE)");
1574f5b1c8a1SJohn Marino 	if ((c->id >> 24) == 3)
1575f5b1c8a1SJohn Marino 		return("TLSv1/SSLv3");
1576f5b1c8a1SJohn Marino 	else
1577f5b1c8a1SJohn Marino 		return("unknown");
1578f5b1c8a1SJohn Marino }
1579f5b1c8a1SJohn Marino 
1580f5b1c8a1SJohn Marino /* return the actual cipher being used */
1581f5b1c8a1SJohn Marino const char *
SSL_CIPHER_get_name(const SSL_CIPHER * c)1582f5b1c8a1SJohn Marino SSL_CIPHER_get_name(const SSL_CIPHER *c)
1583f5b1c8a1SJohn Marino {
1584f5b1c8a1SJohn Marino 	if (c != NULL)
1585f5b1c8a1SJohn Marino 		return (c->name);
1586f5b1c8a1SJohn Marino 	return("(NONE)");
1587f5b1c8a1SJohn Marino }
1588f5b1c8a1SJohn Marino 
1589f5b1c8a1SJohn Marino /* number of bits for symmetric cipher */
1590f5b1c8a1SJohn Marino int
SSL_CIPHER_get_bits(const SSL_CIPHER * c,int * alg_bits)1591f5b1c8a1SJohn Marino SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
1592f5b1c8a1SJohn Marino {
1593f5b1c8a1SJohn Marino 	int ret = 0;
1594f5b1c8a1SJohn Marino 
1595f5b1c8a1SJohn Marino 	if (c != NULL) {
1596f5b1c8a1SJohn Marino 		if (alg_bits != NULL)
1597f5b1c8a1SJohn Marino 			*alg_bits = c->alg_bits;
1598f5b1c8a1SJohn Marino 		ret = c->strength_bits;
1599f5b1c8a1SJohn Marino 	}
1600f5b1c8a1SJohn Marino 	return (ret);
1601f5b1c8a1SJohn Marino }
1602f5b1c8a1SJohn Marino 
1603f5b1c8a1SJohn Marino unsigned long
SSL_CIPHER_get_id(const SSL_CIPHER * c)1604f5b1c8a1SJohn Marino SSL_CIPHER_get_id(const SSL_CIPHER *c)
1605f5b1c8a1SJohn Marino {
1606f5b1c8a1SJohn Marino 	return c->id;
1607f5b1c8a1SJohn Marino }
1608f5b1c8a1SJohn Marino 
1609f5b1c8a1SJohn Marino uint16_t
SSL_CIPHER_get_value(const SSL_CIPHER * c)1610f5b1c8a1SJohn Marino SSL_CIPHER_get_value(const SSL_CIPHER *c)
1611f5b1c8a1SJohn Marino {
1612f5b1c8a1SJohn Marino 	return ssl3_cipher_get_value(c);
1613f5b1c8a1SJohn Marino }
1614f5b1c8a1SJohn Marino 
1615*de0e0e4dSAntonio Huete Jimenez const SSL_CIPHER *
SSL_CIPHER_find(SSL * ssl,const unsigned char * ptr)1616*de0e0e4dSAntonio Huete Jimenez SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
1617*de0e0e4dSAntonio Huete Jimenez {
1618*de0e0e4dSAntonio Huete Jimenez 	uint16_t cipher_value;
1619*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
1620*de0e0e4dSAntonio Huete Jimenez 
1621*de0e0e4dSAntonio Huete Jimenez 	/* This API is documented with ptr being an array of length two. */
1622*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, ptr, 2);
1623*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_u16(&cbs, &cipher_value))
1624*de0e0e4dSAntonio Huete Jimenez 		return NULL;
1625*de0e0e4dSAntonio Huete Jimenez 
1626*de0e0e4dSAntonio Huete Jimenez 	return ssl3_get_cipher_by_value(cipher_value);
1627*de0e0e4dSAntonio Huete Jimenez }
1628*de0e0e4dSAntonio Huete Jimenez 
162972c33676SMaxim Ag int
SSL_CIPHER_get_cipher_nid(const SSL_CIPHER * c)163072c33676SMaxim Ag SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
163172c33676SMaxim Ag {
163272c33676SMaxim Ag 	switch (c->algorithm_enc) {
163372c33676SMaxim Ag 	case SSL_eNULL:
163472c33676SMaxim Ag 		return NID_undef;
163572c33676SMaxim Ag 	case SSL_3DES:
163672c33676SMaxim Ag 		return NID_des_ede3_cbc;
163772c33676SMaxim Ag 	case SSL_AES128:
163872c33676SMaxim Ag 		return NID_aes_128_cbc;
163972c33676SMaxim Ag 	case SSL_AES128GCM:
164072c33676SMaxim Ag 		return NID_aes_128_gcm;
164172c33676SMaxim Ag 	case SSL_AES256:
164272c33676SMaxim Ag 		return NID_aes_256_cbc;
164372c33676SMaxim Ag 	case SSL_AES256GCM:
164472c33676SMaxim Ag 		return NID_aes_256_gcm;
164572c33676SMaxim Ag 	case SSL_CAMELLIA128:
164672c33676SMaxim Ag 		return NID_camellia_128_cbc;
164772c33676SMaxim Ag 	case SSL_CAMELLIA256:
164872c33676SMaxim Ag 		return NID_camellia_256_cbc;
164972c33676SMaxim Ag 	case SSL_CHACHA20POLY1305:
165072c33676SMaxim Ag 		return NID_chacha20_poly1305;
165172c33676SMaxim Ag 	case SSL_DES:
165272c33676SMaxim Ag 		return NID_des_cbc;
165372c33676SMaxim Ag 	case SSL_RC4:
165472c33676SMaxim Ag 		return NID_rc4;
165572c33676SMaxim Ag 	case SSL_eGOST2814789CNT:
165672c33676SMaxim Ag 		return NID_gost89_cnt;
165772c33676SMaxim Ag 	default:
165872c33676SMaxim Ag 		return NID_undef;
165972c33676SMaxim Ag 	}
166072c33676SMaxim Ag }
166172c33676SMaxim Ag 
166272c33676SMaxim Ag int
SSL_CIPHER_get_digest_nid(const SSL_CIPHER * c)166372c33676SMaxim Ag SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
166472c33676SMaxim Ag {
166572c33676SMaxim Ag 	switch (c->algorithm_mac) {
166672c33676SMaxim Ag 	case SSL_AEAD:
166772c33676SMaxim Ag 		return NID_undef;
166872c33676SMaxim Ag 	case SSL_GOST89MAC:
166972c33676SMaxim Ag 		return NID_id_Gost28147_89_MAC;
167072c33676SMaxim Ag 	case SSL_GOST94:
167172c33676SMaxim Ag 		return NID_id_GostR3411_94;
167272c33676SMaxim Ag 	case SSL_MD5:
167372c33676SMaxim Ag 		return NID_md5;
167472c33676SMaxim Ag 	case SSL_SHA1:
167572c33676SMaxim Ag 		return NID_sha1;
167672c33676SMaxim Ag 	case SSL_SHA256:
167772c33676SMaxim Ag 		return NID_sha256;
167872c33676SMaxim Ag 	case SSL_SHA384:
167972c33676SMaxim Ag 		return NID_sha384;
168072c33676SMaxim Ag 	case SSL_STREEBOG256:
168172c33676SMaxim Ag 		return NID_id_tc26_gost3411_2012_256;
168272c33676SMaxim Ag 	default:
168372c33676SMaxim Ag 		return NID_undef;
168472c33676SMaxim Ag 	}
168572c33676SMaxim Ag }
168672c33676SMaxim Ag 
168772c33676SMaxim Ag int
SSL_CIPHER_get_kx_nid(const SSL_CIPHER * c)168872c33676SMaxim Ag SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
168972c33676SMaxim Ag {
169072c33676SMaxim Ag 	switch (c->algorithm_mkey) {
169172c33676SMaxim Ag 	case SSL_kDHE:
169272c33676SMaxim Ag 		return NID_kx_dhe;
169372c33676SMaxim Ag 	case SSL_kECDHE:
169472c33676SMaxim Ag 		return NID_kx_ecdhe;
169572c33676SMaxim Ag 	case SSL_kGOST:
169672c33676SMaxim Ag 		return NID_kx_gost;
169772c33676SMaxim Ag 	case SSL_kRSA:
169872c33676SMaxim Ag 		return NID_kx_rsa;
169972c33676SMaxim Ag 	default:
170072c33676SMaxim Ag 		return NID_undef;
170172c33676SMaxim Ag 	}
170272c33676SMaxim Ag }
170372c33676SMaxim Ag 
170472c33676SMaxim Ag int
SSL_CIPHER_get_auth_nid(const SSL_CIPHER * c)170572c33676SMaxim Ag SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
170672c33676SMaxim Ag {
170772c33676SMaxim Ag 	switch (c->algorithm_auth) {
170872c33676SMaxim Ag 	case SSL_aNULL:
170972c33676SMaxim Ag 		return NID_auth_null;
171072c33676SMaxim Ag 	case SSL_aECDSA:
171172c33676SMaxim Ag 		return NID_auth_ecdsa;
171272c33676SMaxim Ag 	case SSL_aGOST01:
171372c33676SMaxim Ag 		return NID_auth_gost01;
171472c33676SMaxim Ag 	case SSL_aRSA:
171572c33676SMaxim Ag 		return NID_auth_rsa;
171672c33676SMaxim Ag 	default:
171772c33676SMaxim Ag 		return NID_undef;
171872c33676SMaxim Ag 	}
171972c33676SMaxim Ag }
172072c33676SMaxim Ag 
172172c33676SMaxim Ag int
SSL_CIPHER_is_aead(const SSL_CIPHER * c)172272c33676SMaxim Ag SSL_CIPHER_is_aead(const SSL_CIPHER *c)
172372c33676SMaxim Ag {
172472c33676SMaxim Ag 	return (c->algorithm_mac & SSL_AEAD) == SSL_AEAD;
172572c33676SMaxim Ag }
172672c33676SMaxim Ag 
1727f5b1c8a1SJohn Marino void *
SSL_COMP_get_compression_methods(void)1728f5b1c8a1SJohn Marino SSL_COMP_get_compression_methods(void)
1729f5b1c8a1SJohn Marino {
1730f5b1c8a1SJohn Marino 	return NULL;
1731f5b1c8a1SJohn Marino }
1732f5b1c8a1SJohn Marino 
1733f5b1c8a1SJohn Marino int
SSL_COMP_add_compression_method(int id,void * cm)1734f5b1c8a1SJohn Marino SSL_COMP_add_compression_method(int id, void *cm)
1735f5b1c8a1SJohn Marino {
1736f5b1c8a1SJohn Marino 	return 1;
1737f5b1c8a1SJohn Marino }
1738f5b1c8a1SJohn Marino 
1739f5b1c8a1SJohn Marino const char *
SSL_COMP_get_name(const void * comp)1740f5b1c8a1SJohn Marino SSL_COMP_get_name(const void *comp)
1741f5b1c8a1SJohn Marino {
1742f5b1c8a1SJohn Marino 	return NULL;
1743f5b1c8a1SJohn Marino }
1744