xref: /dflybsd-src/crypto/libressl/ssl/ssl_ciph.c (revision cca6fc5243d2098262ea81f83ad5b28d3b800f4a)
1*cca6fc52SDaniel Fojt /* $OpenBSD: ssl_ciph.c,v 1.117 2020/04/19 14:54:14 jsing 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>
146f5b1c8a1SJohn Marino 
147f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE
148f5b1c8a1SJohn Marino #include <openssl/engine.h>
149f5b1c8a1SJohn Marino #endif
150f5b1c8a1SJohn Marino 
151f5b1c8a1SJohn Marino #include "ssl_locl.h"
152f5b1c8a1SJohn Marino 
153f5b1c8a1SJohn Marino #define CIPHER_ADD	1
154f5b1c8a1SJohn Marino #define CIPHER_KILL	2
155f5b1c8a1SJohn Marino #define CIPHER_DEL	3
156f5b1c8a1SJohn Marino #define CIPHER_ORD	4
157f5b1c8a1SJohn Marino #define CIPHER_SPECIAL	5
158f5b1c8a1SJohn Marino 
159f5b1c8a1SJohn Marino typedef struct cipher_order_st {
160f5b1c8a1SJohn Marino 	const SSL_CIPHER *cipher;
161f5b1c8a1SJohn Marino 	int active;
162f5b1c8a1SJohn Marino 	int dead;
163f5b1c8a1SJohn Marino 	struct cipher_order_st *next, *prev;
164f5b1c8a1SJohn Marino } CIPHER_ORDER;
165f5b1c8a1SJohn Marino 
166f5b1c8a1SJohn Marino static const SSL_CIPHER cipher_aliases[] = {
167f5b1c8a1SJohn Marino 
168f5b1c8a1SJohn Marino 	/* "ALL" doesn't include eNULL (must be specifically enabled) */
169f5b1c8a1SJohn Marino 	{
170f5b1c8a1SJohn Marino 		.name = SSL_TXT_ALL,
171f5b1c8a1SJohn Marino 		.algorithm_enc = ~SSL_eNULL,
172f5b1c8a1SJohn Marino 	},
173f5b1c8a1SJohn Marino 
174f5b1c8a1SJohn Marino 	/* "COMPLEMENTOFALL" */
175f5b1c8a1SJohn Marino 	{
176f5b1c8a1SJohn Marino 		.name = SSL_TXT_CMPALL,
177f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
178f5b1c8a1SJohn Marino 	},
179f5b1c8a1SJohn Marino 
180f5b1c8a1SJohn Marino 	/*
181f5b1c8a1SJohn Marino 	 * "COMPLEMENTOFDEFAULT"
182f5b1c8a1SJohn Marino 	 * (does *not* include ciphersuites not found in ALL!)
183f5b1c8a1SJohn Marino 	 */
184f5b1c8a1SJohn Marino 	{
185f5b1c8a1SJohn Marino 		.name = SSL_TXT_CMPDEF,
186f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE|SSL_kECDHE,
187f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
188f5b1c8a1SJohn Marino 		.algorithm_enc = ~SSL_eNULL,
189f5b1c8a1SJohn Marino 	},
190f5b1c8a1SJohn Marino 
191f5b1c8a1SJohn Marino 	/*
192f5b1c8a1SJohn Marino 	 * key exchange aliases
193f5b1c8a1SJohn Marino 	 * (some of those using only a single bit here combine multiple key
194f5b1c8a1SJohn Marino 	 * exchange algs according to the RFCs, e.g. kEDH combines DHE_DSS
195f5b1c8a1SJohn Marino 	 * and DHE_RSA)
196f5b1c8a1SJohn Marino 	 */
197f5b1c8a1SJohn Marino 	{
198f5b1c8a1SJohn Marino 		.name = SSL_TXT_kRSA,
199f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kRSA,
200f5b1c8a1SJohn Marino 	},
201f5b1c8a1SJohn Marino 	{
202f5b1c8a1SJohn Marino 		.name = SSL_TXT_kEDH,
203f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
204f5b1c8a1SJohn Marino 	},
205f5b1c8a1SJohn Marino 	{
206f5b1c8a1SJohn Marino 		.name = SSL_TXT_DH,
207f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
208f5b1c8a1SJohn Marino 	},
209f5b1c8a1SJohn Marino 	{
210f5b1c8a1SJohn Marino 		.name = SSL_TXT_kEECDH,
211f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
212f5b1c8a1SJohn Marino 	},
213f5b1c8a1SJohn Marino 	{
214f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDH,
21572c33676SMaxim Ag 		.algorithm_mkey = SSL_kECDHE,
216f5b1c8a1SJohn Marino 	},
217f5b1c8a1SJohn Marino 	{
218f5b1c8a1SJohn Marino 		.name = SSL_TXT_kGOST,
219f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kGOST,
220f5b1c8a1SJohn Marino 	},
221f5b1c8a1SJohn Marino 
222f5b1c8a1SJohn Marino 	/* server authentication aliases */
223f5b1c8a1SJohn Marino 	{
224f5b1c8a1SJohn Marino 		.name = SSL_TXT_aRSA,
225f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aRSA,
226f5b1c8a1SJohn Marino 	},
227f5b1c8a1SJohn Marino 	{
228f5b1c8a1SJohn Marino 		.name = SSL_TXT_aDSS,
229f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aDSS,
230f5b1c8a1SJohn Marino 	},
231f5b1c8a1SJohn Marino 	{
232f5b1c8a1SJohn Marino 		.name = SSL_TXT_DSS,
233f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aDSS,
234f5b1c8a1SJohn Marino 	},
235f5b1c8a1SJohn Marino 	{
236f5b1c8a1SJohn Marino 		.name = SSL_TXT_aNULL,
237f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
238f5b1c8a1SJohn Marino 	},
239f5b1c8a1SJohn Marino 	{
240f5b1c8a1SJohn Marino 		.name = SSL_TXT_aECDSA,
241f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aECDSA,
242f5b1c8a1SJohn Marino 	},
243f5b1c8a1SJohn Marino 	{
244f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDSA,
245f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aECDSA,
246f5b1c8a1SJohn Marino 	},
247f5b1c8a1SJohn Marino 	{
248f5b1c8a1SJohn Marino 		.name = SSL_TXT_aGOST01,
249f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aGOST01,
250f5b1c8a1SJohn Marino 	},
251f5b1c8a1SJohn Marino 	{
252f5b1c8a1SJohn Marino 		.name = SSL_TXT_aGOST,
253f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aGOST01,
254f5b1c8a1SJohn Marino 	},
255f5b1c8a1SJohn Marino 
256f5b1c8a1SJohn Marino 	/* aliases combining key exchange and server authentication */
257f5b1c8a1SJohn Marino 	{
258f5b1c8a1SJohn Marino 		.name = SSL_TXT_DHE,
259f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
260f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
261f5b1c8a1SJohn Marino 	},
262f5b1c8a1SJohn Marino 	{
263f5b1c8a1SJohn Marino 		.name = SSL_TXT_EDH,
264f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
265f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
266f5b1c8a1SJohn Marino 	},
267f5b1c8a1SJohn Marino 	{
268f5b1c8a1SJohn Marino 		.name = SSL_TXT_ECDHE,
269f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
270f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
271f5b1c8a1SJohn Marino 	},
272f5b1c8a1SJohn Marino 	{
273f5b1c8a1SJohn Marino 		.name = SSL_TXT_EECDH,
274f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
275f5b1c8a1SJohn Marino 		.algorithm_auth = ~SSL_aNULL,
276f5b1c8a1SJohn Marino 	},
277f5b1c8a1SJohn Marino 	{
278f5b1c8a1SJohn Marino 		.name = SSL_TXT_NULL,
279f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
280f5b1c8a1SJohn Marino 	},
281f5b1c8a1SJohn Marino 	{
282f5b1c8a1SJohn Marino 		.name = SSL_TXT_RSA,
283f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kRSA,
284f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aRSA,
285f5b1c8a1SJohn Marino 	},
286f5b1c8a1SJohn Marino 	{
287f5b1c8a1SJohn Marino 		.name = SSL_TXT_ADH,
288f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kDHE,
289f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
290f5b1c8a1SJohn Marino 	},
291f5b1c8a1SJohn Marino 	{
292f5b1c8a1SJohn Marino 		.name = SSL_TXT_AECDH,
293f5b1c8a1SJohn Marino 		.algorithm_mkey = SSL_kECDHE,
294f5b1c8a1SJohn Marino 		.algorithm_auth = SSL_aNULL,
295f5b1c8a1SJohn Marino 	},
296f5b1c8a1SJohn Marino 
297f5b1c8a1SJohn Marino 	/* symmetric encryption aliases */
298f5b1c8a1SJohn Marino 	{
299f5b1c8a1SJohn Marino 		.name = SSL_TXT_3DES,
300f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_3DES,
301f5b1c8a1SJohn Marino 	},
302f5b1c8a1SJohn Marino 	{
303f5b1c8a1SJohn Marino 		.name = SSL_TXT_RC4,
304f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_RC4,
305f5b1c8a1SJohn Marino 	},
306f5b1c8a1SJohn Marino 	{
307f5b1c8a1SJohn Marino 		.name = SSL_TXT_eNULL,
308f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_eNULL,
309f5b1c8a1SJohn Marino 	},
310f5b1c8a1SJohn Marino 	{
311f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES128,
312f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES128|SSL_AES128GCM,
313f5b1c8a1SJohn Marino 	},
314f5b1c8a1SJohn Marino 	{
315f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES256,
316f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES256|SSL_AES256GCM,
317f5b1c8a1SJohn Marino 	},
318f5b1c8a1SJohn Marino 	{
319f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES,
320f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES,
321f5b1c8a1SJohn Marino 	},
322f5b1c8a1SJohn Marino 	{
323f5b1c8a1SJohn Marino 		.name = SSL_TXT_AES_GCM,
324f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_AES128GCM|SSL_AES256GCM,
325f5b1c8a1SJohn Marino 	},
326f5b1c8a1SJohn Marino 	{
327f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA128,
328f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA128,
329f5b1c8a1SJohn Marino 	},
330f5b1c8a1SJohn Marino 	{
331f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA256,
332f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA256,
333f5b1c8a1SJohn Marino 	},
334f5b1c8a1SJohn Marino 	{
335f5b1c8a1SJohn Marino 		.name = SSL_TXT_CAMELLIA,
336f5b1c8a1SJohn Marino 		.algorithm_enc = SSL_CAMELLIA128|SSL_CAMELLIA256,
337f5b1c8a1SJohn Marino 	},
338f5b1c8a1SJohn Marino 	{
339f5b1c8a1SJohn Marino 		.name = SSL_TXT_CHACHA20,
34072c33676SMaxim Ag 		.algorithm_enc = SSL_CHACHA20POLY1305,
341f5b1c8a1SJohn Marino 	},
342f5b1c8a1SJohn Marino 
343f5b1c8a1SJohn Marino 	/* MAC aliases */
344f5b1c8a1SJohn Marino 	{
345f5b1c8a1SJohn Marino 		.name = SSL_TXT_AEAD,
346f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_AEAD,
347f5b1c8a1SJohn Marino 	},
348f5b1c8a1SJohn Marino 	{
349f5b1c8a1SJohn Marino 		.name = SSL_TXT_MD5,
350f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_MD5,
351f5b1c8a1SJohn Marino 	},
352f5b1c8a1SJohn Marino 	{
353f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA1,
354f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA1,
355f5b1c8a1SJohn Marino 	},
356f5b1c8a1SJohn Marino 	{
357f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA,
358f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA1,
359f5b1c8a1SJohn Marino 	},
360f5b1c8a1SJohn Marino 	{
361f5b1c8a1SJohn Marino 		.name = SSL_TXT_GOST94,
362f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_GOST94,
363f5b1c8a1SJohn Marino 	},
364f5b1c8a1SJohn Marino 	{
365f5b1c8a1SJohn Marino 		.name = SSL_TXT_GOST89MAC,
366f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_GOST89MAC,
367f5b1c8a1SJohn Marino 	},
368f5b1c8a1SJohn Marino 	{
369f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA256,
370f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA256,
371f5b1c8a1SJohn Marino 	},
372f5b1c8a1SJohn Marino 	{
373f5b1c8a1SJohn Marino 		.name = SSL_TXT_SHA384,
374f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_SHA384,
375f5b1c8a1SJohn Marino 	},
376f5b1c8a1SJohn Marino 	{
377f5b1c8a1SJohn Marino 		.name = SSL_TXT_STREEBOG256,
378f5b1c8a1SJohn Marino 		.algorithm_mac = SSL_STREEBOG256,
379f5b1c8a1SJohn Marino 	},
380f5b1c8a1SJohn Marino 
381f5b1c8a1SJohn Marino 	/* protocol version aliases */
382f5b1c8a1SJohn Marino 	{
383f5b1c8a1SJohn Marino 		.name = SSL_TXT_SSLV3,
384f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_SSLV3,
385f5b1c8a1SJohn Marino 	},
386f5b1c8a1SJohn Marino 	{
387f5b1c8a1SJohn Marino 		.name = SSL_TXT_TLSV1,
388f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_TLSV1,
389f5b1c8a1SJohn Marino 	},
390f5b1c8a1SJohn Marino 	{
391f5b1c8a1SJohn Marino 		.name = SSL_TXT_TLSV1_2,
392f5b1c8a1SJohn Marino 		.algorithm_ssl = SSL_TLSV1_2,
393f5b1c8a1SJohn Marino 	},
39472c33676SMaxim Ag 	{
39572c33676SMaxim Ag 		.name = SSL_TXT_TLSV1_3,
39672c33676SMaxim Ag 		.algorithm_ssl = SSL_TLSV1_3,
39772c33676SMaxim Ag 	},
398f5b1c8a1SJohn Marino 
399*cca6fc52SDaniel Fojt 	/* cipher suite aliases */
400*cca6fc52SDaniel Fojt #ifdef LIBRESSL_HAS_TLS1_3
401*cca6fc52SDaniel Fojt 	{
402*cca6fc52SDaniel Fojt 		.valid = 1,
403*cca6fc52SDaniel Fojt 		.name = "TLS_AES_128_GCM_SHA256",
404*cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_AES_128_GCM_SHA256,
405*cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
406*cca6fc52SDaniel Fojt 	},
407*cca6fc52SDaniel Fojt 	{
408*cca6fc52SDaniel Fojt 		.valid = 1,
409*cca6fc52SDaniel Fojt 		.name = "TLS_AES_256_GCM_SHA384",
410*cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_AES_256_GCM_SHA384,
411*cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
412*cca6fc52SDaniel Fojt 	},
413*cca6fc52SDaniel Fojt 	{
414*cca6fc52SDaniel Fojt 		.valid = 1,
415*cca6fc52SDaniel Fojt 		.name = "TLS_CHACHA20_POLY1305_SHA256",
416*cca6fc52SDaniel Fojt 		.id = TLS1_3_CK_CHACHA20_POLY1305_SHA256,
417*cca6fc52SDaniel Fojt 		.algorithm_ssl = SSL_TLSV1_3,
418*cca6fc52SDaniel Fojt 	},
419*cca6fc52SDaniel Fojt #endif
420*cca6fc52SDaniel Fojt 
421f5b1c8a1SJohn Marino 	/* strength classes */
422f5b1c8a1SJohn Marino 	{
423f5b1c8a1SJohn Marino 		.name = SSL_TXT_LOW,
424f5b1c8a1SJohn Marino 		.algo_strength = SSL_LOW,
425f5b1c8a1SJohn Marino 	},
426f5b1c8a1SJohn Marino 	{
427f5b1c8a1SJohn Marino 		.name = SSL_TXT_MEDIUM,
428f5b1c8a1SJohn Marino 		.algo_strength = SSL_MEDIUM,
429f5b1c8a1SJohn Marino 	},
430f5b1c8a1SJohn Marino 	{
431f5b1c8a1SJohn Marino 		.name = SSL_TXT_HIGH,
432f5b1c8a1SJohn Marino 		.algo_strength = SSL_HIGH,
433f5b1c8a1SJohn Marino 	},
434f5b1c8a1SJohn Marino };
435f5b1c8a1SJohn Marino 
436f5b1c8a1SJohn Marino int
43772c33676SMaxim Ag ssl_cipher_get_evp(const SSL_SESSION *ss, const EVP_CIPHER **enc,
438f5b1c8a1SJohn Marino     const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
439f5b1c8a1SJohn Marino {
44072c33676SMaxim Ag 	*enc = NULL;
44172c33676SMaxim Ag 	*md = NULL;
44272c33676SMaxim Ag 	*mac_pkey_type = NID_undef;
44372c33676SMaxim Ag 	*mac_secret_size = 0;
444f5b1c8a1SJohn Marino 
44572c33676SMaxim Ag 	if (ss->cipher == NULL)
44672c33676SMaxim Ag 		return 0;
447f5b1c8a1SJohn Marino 
448f5b1c8a1SJohn Marino 	/*
449f5b1c8a1SJohn Marino 	 * This function does not handle EVP_AEAD.
450f5b1c8a1SJohn Marino 	 * See ssl_cipher_get_aead_evp instead.
451f5b1c8a1SJohn Marino 	 */
45272c33676SMaxim Ag 	if (ss->cipher->algorithm_mac & SSL_AEAD)
45372c33676SMaxim Ag 		return 0;
454f5b1c8a1SJohn Marino 
45572c33676SMaxim Ag 	switch (ss->cipher->algorithm_enc) {
456f5b1c8a1SJohn Marino 	case SSL_3DES:
45772c33676SMaxim Ag 		*enc = EVP_des_ede3_cbc();
458f5b1c8a1SJohn Marino 		break;
459f5b1c8a1SJohn Marino 	case SSL_RC4:
46072c33676SMaxim Ag 		*enc = EVP_rc4();
461f5b1c8a1SJohn Marino 		break;
462f5b1c8a1SJohn Marino 	case SSL_eNULL:
46372c33676SMaxim Ag 		*enc = EVP_enc_null();
464f5b1c8a1SJohn Marino 		break;
465f5b1c8a1SJohn Marino 	case SSL_AES128:
46672c33676SMaxim Ag 		*enc = EVP_aes_128_cbc();
467f5b1c8a1SJohn Marino 		break;
468f5b1c8a1SJohn Marino 	case SSL_AES256:
46972c33676SMaxim Ag 		*enc = EVP_aes_256_cbc();
470f5b1c8a1SJohn Marino 		break;
471f5b1c8a1SJohn Marino 	case SSL_CAMELLIA128:
47272c33676SMaxim Ag 		*enc = EVP_camellia_128_cbc();
473f5b1c8a1SJohn Marino 		break;
474f5b1c8a1SJohn Marino 	case SSL_CAMELLIA256:
47572c33676SMaxim Ag 		*enc = EVP_camellia_256_cbc();
476f5b1c8a1SJohn Marino 		break;
477f5b1c8a1SJohn Marino 	case SSL_eGOST2814789CNT:
47872c33676SMaxim Ag 		*enc = EVP_gost2814789_cnt();
479f5b1c8a1SJohn Marino 		break;
480f5b1c8a1SJohn Marino 	}
481f5b1c8a1SJohn Marino 
48272c33676SMaxim Ag 	switch (ss->cipher->algorithm_mac) {
483f5b1c8a1SJohn Marino 	case SSL_MD5:
48472c33676SMaxim Ag 		*md = EVP_md5();
485f5b1c8a1SJohn Marino 		break;
486f5b1c8a1SJohn Marino 	case SSL_SHA1:
48772c33676SMaxim Ag 		*md = EVP_sha1();
488f5b1c8a1SJohn Marino 		break;
489f5b1c8a1SJohn Marino 	case SSL_SHA256:
49072c33676SMaxim Ag 		*md = EVP_sha256();
491f5b1c8a1SJohn Marino 		break;
492f5b1c8a1SJohn Marino 	case SSL_SHA384:
49372c33676SMaxim Ag 		*md = EVP_sha384();
494f5b1c8a1SJohn Marino 		break;
495f5b1c8a1SJohn Marino 	case SSL_GOST89MAC:
49672c33676SMaxim Ag 		*md = EVP_gost2814789imit();
49772c33676SMaxim Ag 		break;
49872c33676SMaxim Ag 	case SSL_GOST94:
49972c33676SMaxim Ag 		*md = EVP_gostr341194();
500f5b1c8a1SJohn Marino 		break;
501f5b1c8a1SJohn Marino 	case SSL_STREEBOG256:
50272c33676SMaxim Ag 		*md = EVP_streebog256();
503f5b1c8a1SJohn Marino 		break;
504f5b1c8a1SJohn Marino 	}
505f5b1c8a1SJohn Marino 
50672c33676SMaxim Ag 	if (*enc == NULL || *md == NULL)
50772c33676SMaxim Ag 		return 0;
50872c33676SMaxim Ag 
50972c33676SMaxim Ag 	/*
51072c33676SMaxim Ag 	 * EVP_CIPH_FLAG_AEAD_CIPHER and EVP_CIPH_GCM_MODE ciphers are not
51172c33676SMaxim Ag 	 * supported via EVP_CIPHER (they should be using EVP_AEAD instead).
51272c33676SMaxim Ag 	 */
51372c33676SMaxim Ag 	if (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)
51472c33676SMaxim Ag 		return 0;
51572c33676SMaxim Ag 	if (EVP_CIPHER_mode(*enc) == EVP_CIPH_GCM_MODE)
51672c33676SMaxim Ag 		return 0;
51772c33676SMaxim Ag 
51872c33676SMaxim Ag 	if (ss->cipher->algorithm_mac == SSL_GOST89MAC) {
51972c33676SMaxim Ag 		*mac_pkey_type = EVP_PKEY_GOSTIMIT;
52072c33676SMaxim Ag 		*mac_secret_size = 32; /* XXX */
521f5b1c8a1SJohn Marino 	} else {
52272c33676SMaxim Ag 		*mac_pkey_type = EVP_PKEY_HMAC;
52372c33676SMaxim Ag 		*mac_secret_size = EVP_MD_size(*md);
524f5b1c8a1SJohn Marino 	}
525f5b1c8a1SJohn Marino 
526f5b1c8a1SJohn Marino 	return 1;
527f5b1c8a1SJohn Marino }
528f5b1c8a1SJohn Marino 
529f5b1c8a1SJohn Marino /*
530f5b1c8a1SJohn Marino  * ssl_cipher_get_evp_aead sets aead to point to the correct EVP_AEAD object
531f5b1c8a1SJohn Marino  * for s->cipher. It returns 1 on success and 0 on error.
532f5b1c8a1SJohn Marino  */
533f5b1c8a1SJohn Marino int
53472c33676SMaxim Ag ssl_cipher_get_evp_aead(const SSL_SESSION *ss, const EVP_AEAD **aead)
535f5b1c8a1SJohn Marino {
536f5b1c8a1SJohn Marino 	*aead = NULL;
537f5b1c8a1SJohn Marino 
53872c33676SMaxim Ag 	if (ss->cipher == NULL)
539f5b1c8a1SJohn Marino 		return 0;
54072c33676SMaxim Ag 	if ((ss->cipher->algorithm_mac & SSL_AEAD) == 0)
541f5b1c8a1SJohn Marino 		return 0;
542f5b1c8a1SJohn Marino 
54372c33676SMaxim Ag 	switch (ss->cipher->algorithm_enc) {
544f5b1c8a1SJohn Marino 	case SSL_AES128GCM:
545f5b1c8a1SJohn Marino 		*aead = EVP_aead_aes_128_gcm();
546f5b1c8a1SJohn Marino 		return 1;
547f5b1c8a1SJohn Marino 	case SSL_AES256GCM:
548f5b1c8a1SJohn Marino 		*aead = EVP_aead_aes_256_gcm();
549f5b1c8a1SJohn Marino 		return 1;
550f5b1c8a1SJohn Marino 	case SSL_CHACHA20POLY1305:
551f5b1c8a1SJohn Marino 		*aead = EVP_aead_chacha20_poly1305();
552f5b1c8a1SJohn Marino 		return 1;
553f5b1c8a1SJohn Marino 	default:
554f5b1c8a1SJohn Marino 		break;
555f5b1c8a1SJohn Marino 	}
556f5b1c8a1SJohn Marino 	return 0;
557f5b1c8a1SJohn Marino }
558f5b1c8a1SJohn Marino 
559f5b1c8a1SJohn Marino int
56072c33676SMaxim Ag ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md)
561f5b1c8a1SJohn Marino {
562f5b1c8a1SJohn Marino 	*md = NULL;
56372c33676SMaxim Ag 
56472c33676SMaxim Ag 	switch (ssl_get_algorithm2(s) & SSL_HANDSHAKE_MAC_MASK) {
56572c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_DEFAULT:
56672c33676SMaxim Ag 		*md = EVP_md5_sha1();
567f5b1c8a1SJohn Marino 		return 1;
56872c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_GOST94:
56972c33676SMaxim Ag 		*md = EVP_gostr341194();
57072c33676SMaxim Ag 		return 1;
57172c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_SHA256:
57272c33676SMaxim Ag 		*md = EVP_sha256();
57372c33676SMaxim Ag 		return 1;
57472c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_SHA384:
57572c33676SMaxim Ag 		*md = EVP_sha384();
57672c33676SMaxim Ag 		return 1;
57772c33676SMaxim Ag 	case SSL_HANDSHAKE_MAC_STREEBOG256:
57872c33676SMaxim Ag 		*md = EVP_streebog256();
57972c33676SMaxim Ag 		return 1;
58072c33676SMaxim Ag 	default:
58172c33676SMaxim Ag 		break;
58272c33676SMaxim Ag 	}
58372c33676SMaxim Ag 
58472c33676SMaxim Ag 	return 0;
585f5b1c8a1SJohn Marino }
586f5b1c8a1SJohn Marino 
587f5b1c8a1SJohn Marino #define ITEM_SEP(a) \
588f5b1c8a1SJohn Marino 	(((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
589f5b1c8a1SJohn Marino 
590f5b1c8a1SJohn Marino static void
591f5b1c8a1SJohn Marino ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
592f5b1c8a1SJohn Marino     CIPHER_ORDER **tail)
593f5b1c8a1SJohn Marino {
594f5b1c8a1SJohn Marino 	if (curr == *tail)
595f5b1c8a1SJohn Marino 		return;
596f5b1c8a1SJohn Marino 	if (curr == *head)
597f5b1c8a1SJohn Marino 		*head = curr->next;
598f5b1c8a1SJohn Marino 	if (curr->prev != NULL)
599f5b1c8a1SJohn Marino 		curr->prev->next = curr->next;
600f5b1c8a1SJohn Marino 	if (curr->next != NULL)
601f5b1c8a1SJohn Marino 		curr->next->prev = curr->prev;
602f5b1c8a1SJohn Marino 	(*tail)->next = curr;
603f5b1c8a1SJohn Marino 	curr->prev= *tail;
604f5b1c8a1SJohn Marino 	curr->next = NULL;
605f5b1c8a1SJohn Marino 	*tail = curr;
606f5b1c8a1SJohn Marino }
607f5b1c8a1SJohn Marino 
608f5b1c8a1SJohn Marino static void
609f5b1c8a1SJohn Marino ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
610f5b1c8a1SJohn Marino     CIPHER_ORDER **tail)
611f5b1c8a1SJohn Marino {
612f5b1c8a1SJohn Marino 	if (curr == *head)
613f5b1c8a1SJohn Marino 		return;
614f5b1c8a1SJohn Marino 	if (curr == *tail)
615f5b1c8a1SJohn Marino 		*tail = curr->prev;
616f5b1c8a1SJohn Marino 	if (curr->next != NULL)
617f5b1c8a1SJohn Marino 		curr->next->prev = curr->prev;
618f5b1c8a1SJohn Marino 	if (curr->prev != NULL)
619f5b1c8a1SJohn Marino 		curr->prev->next = curr->next;
620f5b1c8a1SJohn Marino 	(*head)->prev = curr;
621f5b1c8a1SJohn Marino 	curr->next= *head;
622f5b1c8a1SJohn Marino 	curr->prev = NULL;
623f5b1c8a1SJohn Marino 	*head = curr;
624f5b1c8a1SJohn Marino }
625f5b1c8a1SJohn Marino 
626f5b1c8a1SJohn Marino static void
627f5b1c8a1SJohn Marino ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth,
628f5b1c8a1SJohn Marino     unsigned long *enc, unsigned long *mac, unsigned long *ssl)
629f5b1c8a1SJohn Marino {
630f5b1c8a1SJohn Marino 	*mkey = 0;
631f5b1c8a1SJohn Marino 	*auth = 0;
632f5b1c8a1SJohn Marino 	*enc = 0;
633f5b1c8a1SJohn Marino 	*mac = 0;
634f5b1c8a1SJohn Marino 	*ssl = 0;
635f5b1c8a1SJohn Marino 
636f5b1c8a1SJohn Marino 	/*
637f5b1c8a1SJohn Marino 	 * Check for the availability of GOST 34.10 public/private key
638f5b1c8a1SJohn Marino 	 * algorithms. If they are not available disable the associated
639f5b1c8a1SJohn Marino 	 * authentication and key exchange algorithms.
640f5b1c8a1SJohn Marino 	 */
641f5b1c8a1SJohn Marino 	if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) {
642f5b1c8a1SJohn Marino 		*auth |= SSL_aGOST01;
643f5b1c8a1SJohn Marino 		*mkey |= SSL_kGOST;
644f5b1c8a1SJohn Marino 	}
645f5b1c8a1SJohn Marino 
646f5b1c8a1SJohn Marino #ifdef SSL_FORBID_ENULL
647f5b1c8a1SJohn Marino 	*enc |= SSL_eNULL;
648f5b1c8a1SJohn Marino #endif
649f5b1c8a1SJohn Marino }
650f5b1c8a1SJohn Marino 
651f5b1c8a1SJohn Marino static void
652f5b1c8a1SJohn Marino ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers,
653f5b1c8a1SJohn Marino     unsigned long disabled_mkey, unsigned long disabled_auth,
654f5b1c8a1SJohn Marino     unsigned long disabled_enc, unsigned long disabled_mac,
655f5b1c8a1SJohn Marino     unsigned long disabled_ssl, CIPHER_ORDER *co_list,
656f5b1c8a1SJohn Marino     CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
657f5b1c8a1SJohn Marino {
658f5b1c8a1SJohn Marino 	int i, co_list_num;
659f5b1c8a1SJohn Marino 	const SSL_CIPHER *c;
660f5b1c8a1SJohn Marino 
661f5b1c8a1SJohn Marino 	/*
662f5b1c8a1SJohn Marino 	 * We have num_of_ciphers descriptions compiled in, depending on the
663f5b1c8a1SJohn Marino 	 * method selected (SSLv3, TLSv1, etc). These will later be sorted in
664f5b1c8a1SJohn Marino 	 * a linked list with at most num entries.
665f5b1c8a1SJohn Marino 	 */
666f5b1c8a1SJohn Marino 
667f5b1c8a1SJohn Marino 	/* Get the initial list of ciphers */
668f5b1c8a1SJohn Marino 	co_list_num = 0;	/* actual count of ciphers */
669f5b1c8a1SJohn Marino 	for (i = 0; i < num_of_ciphers; i++) {
670f5b1c8a1SJohn Marino 		c = ssl_method->get_cipher(i);
671f5b1c8a1SJohn Marino 		/* drop those that use any of that is not available */
672f5b1c8a1SJohn Marino 		if ((c != NULL) && c->valid &&
673f5b1c8a1SJohn Marino 		    !(c->algorithm_mkey & disabled_mkey) &&
674f5b1c8a1SJohn Marino 		    !(c->algorithm_auth & disabled_auth) &&
675f5b1c8a1SJohn Marino 		    !(c->algorithm_enc & disabled_enc) &&
676f5b1c8a1SJohn Marino 		    !(c->algorithm_mac & disabled_mac) &&
677f5b1c8a1SJohn Marino 		    !(c->algorithm_ssl & disabled_ssl)) {
678f5b1c8a1SJohn Marino 			co_list[co_list_num].cipher = c;
679f5b1c8a1SJohn Marino 			co_list[co_list_num].next = NULL;
680f5b1c8a1SJohn Marino 			co_list[co_list_num].prev = NULL;
681f5b1c8a1SJohn Marino 			co_list[co_list_num].active = 0;
682f5b1c8a1SJohn Marino 			co_list_num++;
683f5b1c8a1SJohn Marino 			/*
684f5b1c8a1SJohn Marino 			if (!sk_push(ca_list,(char *)c)) goto err;
685f5b1c8a1SJohn Marino 			*/
686f5b1c8a1SJohn Marino 		}
687f5b1c8a1SJohn Marino 	}
688f5b1c8a1SJohn Marino 
689f5b1c8a1SJohn Marino 	/*
690f5b1c8a1SJohn Marino 	 * Prepare linked list from list entries
691f5b1c8a1SJohn Marino 	 */
692f5b1c8a1SJohn Marino 	if (co_list_num > 0) {
693f5b1c8a1SJohn Marino 		co_list[0].prev = NULL;
694f5b1c8a1SJohn Marino 
695f5b1c8a1SJohn Marino 		if (co_list_num > 1) {
696f5b1c8a1SJohn Marino 			co_list[0].next = &co_list[1];
697f5b1c8a1SJohn Marino 
698f5b1c8a1SJohn Marino 			for (i = 1; i < co_list_num - 1; i++) {
699f5b1c8a1SJohn Marino 				co_list[i].prev = &co_list[i - 1];
700f5b1c8a1SJohn Marino 				co_list[i].next = &co_list[i + 1];
701f5b1c8a1SJohn Marino 			}
702f5b1c8a1SJohn Marino 
703f5b1c8a1SJohn Marino 			co_list[co_list_num - 1].prev =
704f5b1c8a1SJohn Marino 			    &co_list[co_list_num - 2];
705f5b1c8a1SJohn Marino 		}
706f5b1c8a1SJohn Marino 
707f5b1c8a1SJohn Marino 		co_list[co_list_num - 1].next = NULL;
708f5b1c8a1SJohn Marino 
709f5b1c8a1SJohn Marino 		*head_p = &co_list[0];
710f5b1c8a1SJohn Marino 		*tail_p = &co_list[co_list_num - 1];
711f5b1c8a1SJohn Marino 	}
712f5b1c8a1SJohn Marino }
713f5b1c8a1SJohn Marino 
714f5b1c8a1SJohn Marino static void
715f5b1c8a1SJohn Marino ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases,
716f5b1c8a1SJohn Marino     unsigned long disabled_mkey, unsigned long disabled_auth,
717f5b1c8a1SJohn Marino     unsigned long disabled_enc, unsigned long disabled_mac,
718f5b1c8a1SJohn Marino     unsigned long disabled_ssl, CIPHER_ORDER *head)
719f5b1c8a1SJohn Marino {
720f5b1c8a1SJohn Marino 	CIPHER_ORDER *ciph_curr;
721f5b1c8a1SJohn Marino 	const SSL_CIPHER **ca_curr;
722f5b1c8a1SJohn Marino 	int i;
723f5b1c8a1SJohn Marino 	unsigned long mask_mkey = ~disabled_mkey;
724f5b1c8a1SJohn Marino 	unsigned long mask_auth = ~disabled_auth;
725f5b1c8a1SJohn Marino 	unsigned long mask_enc = ~disabled_enc;
726f5b1c8a1SJohn Marino 	unsigned long mask_mac = ~disabled_mac;
727f5b1c8a1SJohn Marino 	unsigned long mask_ssl = ~disabled_ssl;
728f5b1c8a1SJohn Marino 
729f5b1c8a1SJohn Marino 	/*
730f5b1c8a1SJohn Marino 	 * First, add the real ciphers as already collected
731f5b1c8a1SJohn Marino 	 */
732f5b1c8a1SJohn Marino 	ciph_curr = head;
733f5b1c8a1SJohn Marino 	ca_curr = ca_list;
734f5b1c8a1SJohn Marino 	while (ciph_curr != NULL) {
735f5b1c8a1SJohn Marino 		*ca_curr = ciph_curr->cipher;
736f5b1c8a1SJohn Marino 		ca_curr++;
737f5b1c8a1SJohn Marino 		ciph_curr = ciph_curr->next;
738f5b1c8a1SJohn Marino 	}
739f5b1c8a1SJohn Marino 
740f5b1c8a1SJohn Marino 	/*
741f5b1c8a1SJohn Marino 	 * Now we add the available ones from the cipher_aliases[] table.
742f5b1c8a1SJohn Marino 	 * They represent either one or more algorithms, some of which
743f5b1c8a1SJohn Marino 	 * in any affected category must be supported (set in enabled_mask),
744f5b1c8a1SJohn Marino 	 * or represent a cipher strength value (will be added in any case because algorithms=0).
745f5b1c8a1SJohn Marino 	 */
746f5b1c8a1SJohn Marino 	for (i = 0; i < num_of_group_aliases; i++) {
747f5b1c8a1SJohn Marino 		unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
748f5b1c8a1SJohn Marino 		unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
749f5b1c8a1SJohn Marino 		unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
750f5b1c8a1SJohn Marino 		unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
751f5b1c8a1SJohn Marino 		unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
752f5b1c8a1SJohn Marino 
753f5b1c8a1SJohn Marino 		if (algorithm_mkey)
754f5b1c8a1SJohn Marino 			if ((algorithm_mkey & mask_mkey) == 0)
755f5b1c8a1SJohn Marino 				continue;
756f5b1c8a1SJohn Marino 
757f5b1c8a1SJohn Marino 		if (algorithm_auth)
758f5b1c8a1SJohn Marino 			if ((algorithm_auth & mask_auth) == 0)
759f5b1c8a1SJohn Marino 				continue;
760f5b1c8a1SJohn Marino 
761f5b1c8a1SJohn Marino 		if (algorithm_enc)
762f5b1c8a1SJohn Marino 			if ((algorithm_enc & mask_enc) == 0)
763f5b1c8a1SJohn Marino 				continue;
764f5b1c8a1SJohn Marino 
765f5b1c8a1SJohn Marino 		if (algorithm_mac)
766f5b1c8a1SJohn Marino 			if ((algorithm_mac & mask_mac) == 0)
767f5b1c8a1SJohn Marino 				continue;
768f5b1c8a1SJohn Marino 
769f5b1c8a1SJohn Marino 		if (algorithm_ssl)
770f5b1c8a1SJohn Marino 			if ((algorithm_ssl & mask_ssl) == 0)
771f5b1c8a1SJohn Marino 				continue;
772f5b1c8a1SJohn Marino 
773f5b1c8a1SJohn Marino 		*ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
774f5b1c8a1SJohn Marino 		ca_curr++;
775f5b1c8a1SJohn Marino 	}
776f5b1c8a1SJohn Marino 
777f5b1c8a1SJohn Marino 	*ca_curr = NULL;	/* end of list */
778f5b1c8a1SJohn Marino }
779f5b1c8a1SJohn Marino 
780f5b1c8a1SJohn Marino static void
781f5b1c8a1SJohn Marino ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long alg_mkey,
782f5b1c8a1SJohn Marino     unsigned long alg_auth, unsigned long alg_enc, unsigned long alg_mac,
783*cca6fc52SDaniel Fojt     unsigned long alg_ssl, unsigned long algo_strength, int rule,
784*cca6fc52SDaniel Fojt     int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
785f5b1c8a1SJohn Marino {
786f5b1c8a1SJohn Marino 	CIPHER_ORDER *head, *tail, *curr, *next, *last;
787f5b1c8a1SJohn Marino 	const SSL_CIPHER *cp;
788f5b1c8a1SJohn Marino 	int reverse = 0;
789f5b1c8a1SJohn Marino 
790f5b1c8a1SJohn Marino 	if (rule == CIPHER_DEL)
791f5b1c8a1SJohn Marino 		reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
792f5b1c8a1SJohn Marino 
793f5b1c8a1SJohn Marino 	head = *head_p;
794f5b1c8a1SJohn Marino 	tail = *tail_p;
795f5b1c8a1SJohn Marino 
796f5b1c8a1SJohn Marino 	if (reverse) {
797f5b1c8a1SJohn Marino 		next = tail;
798f5b1c8a1SJohn Marino 		last = head;
799f5b1c8a1SJohn Marino 	} else {
800f5b1c8a1SJohn Marino 		next = head;
801f5b1c8a1SJohn Marino 		last = tail;
802f5b1c8a1SJohn Marino 	}
803f5b1c8a1SJohn Marino 
804f5b1c8a1SJohn Marino 	curr = NULL;
805f5b1c8a1SJohn Marino 	for (;;) {
806f5b1c8a1SJohn Marino 		if (curr == last)
807f5b1c8a1SJohn Marino 			break;
808f5b1c8a1SJohn Marino 		curr = next;
809f5b1c8a1SJohn Marino 		next = reverse ? curr->prev : curr->next;
810f5b1c8a1SJohn Marino 
811f5b1c8a1SJohn Marino 		cp = curr->cipher;
812f5b1c8a1SJohn Marino 
81372c33676SMaxim Ag 		if (cipher_id && cp->id != cipher_id)
81472c33676SMaxim Ag 			continue;
81572c33676SMaxim Ag 
816f5b1c8a1SJohn Marino 		/*
817f5b1c8a1SJohn Marino 		 * Selection criteria is either the value of strength_bits
818f5b1c8a1SJohn Marino 		 * or the algorithms used.
819f5b1c8a1SJohn Marino 		 */
820f5b1c8a1SJohn Marino 		if (strength_bits >= 0) {
821f5b1c8a1SJohn Marino 			if (strength_bits != cp->strength_bits)
822f5b1c8a1SJohn Marino 				continue;
823f5b1c8a1SJohn Marino 		} else {
824f5b1c8a1SJohn Marino 			if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
825f5b1c8a1SJohn Marino 				continue;
826f5b1c8a1SJohn Marino 			if (alg_auth && !(alg_auth & cp->algorithm_auth))
827f5b1c8a1SJohn Marino 				continue;
828f5b1c8a1SJohn Marino 			if (alg_enc && !(alg_enc & cp->algorithm_enc))
829f5b1c8a1SJohn Marino 				continue;
830f5b1c8a1SJohn Marino 			if (alg_mac && !(alg_mac & cp->algorithm_mac))
831f5b1c8a1SJohn Marino 				continue;
832f5b1c8a1SJohn Marino 			if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
833f5b1c8a1SJohn Marino 				continue;
834f5b1c8a1SJohn Marino 			if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
835f5b1c8a1SJohn Marino 				continue;
836f5b1c8a1SJohn Marino 		}
837f5b1c8a1SJohn Marino 
838f5b1c8a1SJohn Marino 		/* add the cipher if it has not been added yet. */
839f5b1c8a1SJohn Marino 		if (rule == CIPHER_ADD) {
840f5b1c8a1SJohn Marino 			/* reverse == 0 */
841f5b1c8a1SJohn Marino 			if (!curr->active) {
842f5b1c8a1SJohn Marino 				ll_append_tail(&head, curr, &tail);
843f5b1c8a1SJohn Marino 				curr->active = 1;
844f5b1c8a1SJohn Marino 			}
845f5b1c8a1SJohn Marino 		}
846f5b1c8a1SJohn Marino 		/* Move the added cipher to this location */
847f5b1c8a1SJohn Marino 		else if (rule == CIPHER_ORD) {
848f5b1c8a1SJohn Marino 			/* reverse == 0 */
849f5b1c8a1SJohn Marino 			if (curr->active) {
850f5b1c8a1SJohn Marino 				ll_append_tail(&head, curr, &tail);
851f5b1c8a1SJohn Marino 			}
852f5b1c8a1SJohn Marino 		} else if (rule == CIPHER_DEL) {
853f5b1c8a1SJohn Marino 			/* reverse == 1 */
854f5b1c8a1SJohn Marino 			if (curr->active) {
855f5b1c8a1SJohn Marino 				/* most recently deleted ciphersuites get best positions
856f5b1c8a1SJohn Marino 				 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
857f5b1c8a1SJohn Marino 				 * works in reverse to maintain the order) */
858f5b1c8a1SJohn Marino 				ll_append_head(&head, curr, &tail);
859f5b1c8a1SJohn Marino 				curr->active = 0;
860f5b1c8a1SJohn Marino 			}
861f5b1c8a1SJohn Marino 		} else if (rule == CIPHER_KILL) {
862f5b1c8a1SJohn Marino 			/* reverse == 0 */
863f5b1c8a1SJohn Marino 			if (head == curr)
864f5b1c8a1SJohn Marino 				head = curr->next;
865f5b1c8a1SJohn Marino 			else
866f5b1c8a1SJohn Marino 				curr->prev->next = curr->next;
867f5b1c8a1SJohn Marino 			if (tail == curr)
868f5b1c8a1SJohn Marino 				tail = curr->prev;
869f5b1c8a1SJohn Marino 			curr->active = 0;
870f5b1c8a1SJohn Marino 			if (curr->next != NULL)
871f5b1c8a1SJohn Marino 				curr->next->prev = curr->prev;
872f5b1c8a1SJohn Marino 			if (curr->prev != NULL)
873f5b1c8a1SJohn Marino 				curr->prev->next = curr->next;
874f5b1c8a1SJohn Marino 			curr->next = NULL;
875f5b1c8a1SJohn Marino 			curr->prev = NULL;
876f5b1c8a1SJohn Marino 		}
877f5b1c8a1SJohn Marino 	}
878f5b1c8a1SJohn Marino 
879f5b1c8a1SJohn Marino 	*head_p = head;
880f5b1c8a1SJohn Marino 	*tail_p = tail;
881f5b1c8a1SJohn Marino }
882f5b1c8a1SJohn Marino 
883f5b1c8a1SJohn Marino static int
884f5b1c8a1SJohn Marino ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
885f5b1c8a1SJohn Marino {
886f5b1c8a1SJohn Marino 	int max_strength_bits, i, *number_uses;
887f5b1c8a1SJohn Marino 	CIPHER_ORDER *curr;
888f5b1c8a1SJohn Marino 
889f5b1c8a1SJohn Marino 	/*
890f5b1c8a1SJohn Marino 	 * This routine sorts the ciphers with descending strength. The sorting
891f5b1c8a1SJohn Marino 	 * must keep the pre-sorted sequence, so we apply the normal sorting
892f5b1c8a1SJohn Marino 	 * routine as '+' movement to the end of the list.
893f5b1c8a1SJohn Marino 	 */
894f5b1c8a1SJohn Marino 	max_strength_bits = 0;
895f5b1c8a1SJohn Marino 	curr = *head_p;
896f5b1c8a1SJohn Marino 	while (curr != NULL) {
897f5b1c8a1SJohn Marino 		if (curr->active &&
898f5b1c8a1SJohn Marino 		    (curr->cipher->strength_bits > max_strength_bits))
899f5b1c8a1SJohn Marino 			max_strength_bits = curr->cipher->strength_bits;
900f5b1c8a1SJohn Marino 		curr = curr->next;
901f5b1c8a1SJohn Marino 	}
902f5b1c8a1SJohn Marino 
903f5b1c8a1SJohn Marino 	number_uses = calloc((max_strength_bits + 1), sizeof(int));
904f5b1c8a1SJohn Marino 	if (!number_uses) {
90572c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
906f5b1c8a1SJohn Marino 		return (0);
907f5b1c8a1SJohn Marino 	}
908f5b1c8a1SJohn Marino 
909f5b1c8a1SJohn Marino 	/*
910f5b1c8a1SJohn Marino 	 * Now find the strength_bits values actually used
911f5b1c8a1SJohn Marino 	 */
912f5b1c8a1SJohn Marino 	curr = *head_p;
913f5b1c8a1SJohn Marino 	while (curr != NULL) {
914f5b1c8a1SJohn Marino 		if (curr->active)
915f5b1c8a1SJohn Marino 			number_uses[curr->cipher->strength_bits]++;
916f5b1c8a1SJohn Marino 		curr = curr->next;
917f5b1c8a1SJohn Marino 	}
918f5b1c8a1SJohn Marino 	/*
919f5b1c8a1SJohn Marino 	 * Go through the list of used strength_bits values in descending
920f5b1c8a1SJohn Marino 	 * order.
921f5b1c8a1SJohn Marino 	 */
922f5b1c8a1SJohn Marino 	for (i = max_strength_bits; i >= 0; i--)
923f5b1c8a1SJohn Marino 		if (number_uses[i] > 0)
924f5b1c8a1SJohn Marino 			ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p);
925f5b1c8a1SJohn Marino 
926f5b1c8a1SJohn Marino 	free(number_uses);
927f5b1c8a1SJohn Marino 	return (1);
928f5b1c8a1SJohn Marino }
929f5b1c8a1SJohn Marino 
930f5b1c8a1SJohn Marino static int
931f5b1c8a1SJohn Marino ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p,
932*cca6fc52SDaniel Fojt     CIPHER_ORDER **tail_p, const SSL_CIPHER **ca_list, int *tls13_seen)
933f5b1c8a1SJohn Marino {
934f5b1c8a1SJohn Marino 	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl;
935f5b1c8a1SJohn Marino 	unsigned long algo_strength;
936f5b1c8a1SJohn Marino 	int j, multi, found, rule, retval, ok, buflen;
937f5b1c8a1SJohn Marino 	unsigned long cipher_id = 0;
938f5b1c8a1SJohn Marino 	const char *l, *buf;
939f5b1c8a1SJohn Marino 	char ch;
940f5b1c8a1SJohn Marino 
941*cca6fc52SDaniel Fojt 	*tls13_seen = 0;
942*cca6fc52SDaniel Fojt 
943f5b1c8a1SJohn Marino 	retval = 1;
944f5b1c8a1SJohn Marino 	l = rule_str;
945f5b1c8a1SJohn Marino 	for (;;) {
946f5b1c8a1SJohn Marino 		ch = *l;
947f5b1c8a1SJohn Marino 
948f5b1c8a1SJohn Marino 		if (ch == '\0')
949f5b1c8a1SJohn Marino 			break;
950f5b1c8a1SJohn Marino 
951f5b1c8a1SJohn Marino 		if (ch == '-') {
952f5b1c8a1SJohn Marino 			rule = CIPHER_DEL;
953f5b1c8a1SJohn Marino 			l++;
954f5b1c8a1SJohn Marino 		} else if (ch == '+') {
955f5b1c8a1SJohn Marino 			rule = CIPHER_ORD;
956f5b1c8a1SJohn Marino 			l++;
957f5b1c8a1SJohn Marino 		} else if (ch == '!') {
958f5b1c8a1SJohn Marino 			rule = CIPHER_KILL;
959f5b1c8a1SJohn Marino 			l++;
960f5b1c8a1SJohn Marino 		} else if (ch == '@') {
961f5b1c8a1SJohn Marino 			rule = CIPHER_SPECIAL;
962f5b1c8a1SJohn Marino 			l++;
963f5b1c8a1SJohn Marino 		} else {
964f5b1c8a1SJohn Marino 			rule = CIPHER_ADD;
965f5b1c8a1SJohn Marino 		}
966f5b1c8a1SJohn Marino 
967f5b1c8a1SJohn Marino 		if (ITEM_SEP(ch)) {
968f5b1c8a1SJohn Marino 			l++;
969f5b1c8a1SJohn Marino 			continue;
970f5b1c8a1SJohn Marino 		}
971f5b1c8a1SJohn Marino 
972f5b1c8a1SJohn Marino 		alg_mkey = 0;
973f5b1c8a1SJohn Marino 		alg_auth = 0;
974f5b1c8a1SJohn Marino 		alg_enc = 0;
975f5b1c8a1SJohn Marino 		alg_mac = 0;
976f5b1c8a1SJohn Marino 		alg_ssl = 0;
977f5b1c8a1SJohn Marino 		algo_strength = 0;
978f5b1c8a1SJohn Marino 
979f5b1c8a1SJohn Marino 		for (;;) {
980f5b1c8a1SJohn Marino 			ch = *l;
981f5b1c8a1SJohn Marino 			buf = l;
982f5b1c8a1SJohn Marino 			buflen = 0;
983f5b1c8a1SJohn Marino 			while (((ch >= 'A') && (ch <= 'Z')) ||
984f5b1c8a1SJohn Marino 			    ((ch >= '0') && (ch <= '9')) ||
985f5b1c8a1SJohn Marino 			    ((ch >= 'a') && (ch <= 'z')) ||
986*cca6fc52SDaniel Fojt 			    (ch == '-') || (ch == '.') ||
987*cca6fc52SDaniel Fojt 			    (ch == '_')) {
988f5b1c8a1SJohn Marino 				ch = *(++l);
989f5b1c8a1SJohn Marino 				buflen++;
990f5b1c8a1SJohn Marino 			}
991f5b1c8a1SJohn Marino 
992f5b1c8a1SJohn Marino 			if (buflen == 0) {
993f5b1c8a1SJohn Marino 				/*
994f5b1c8a1SJohn Marino 				 * We hit something we cannot deal with,
995f5b1c8a1SJohn Marino 				 * it is no command or separator nor
996f5b1c8a1SJohn Marino 				 * alphanumeric, so we call this an error.
997f5b1c8a1SJohn Marino 				 */
99872c33676SMaxim Ag 				SSLerrorx(SSL_R_INVALID_COMMAND);
999f5b1c8a1SJohn Marino 				retval = found = 0;
1000f5b1c8a1SJohn Marino 				l++;
1001f5b1c8a1SJohn Marino 				break;
1002f5b1c8a1SJohn Marino 			}
1003f5b1c8a1SJohn Marino 
1004f5b1c8a1SJohn Marino 			if (rule == CIPHER_SPECIAL) {
1005f5b1c8a1SJohn Marino 				 /* unused -- avoid compiler warning */
1006f5b1c8a1SJohn Marino 				found = 0;
1007f5b1c8a1SJohn Marino 				/* special treatment */
1008f5b1c8a1SJohn Marino 				break;
1009f5b1c8a1SJohn Marino 			}
1010f5b1c8a1SJohn Marino 
1011f5b1c8a1SJohn Marino 			/* check for multi-part specification */
1012f5b1c8a1SJohn Marino 			if (ch == '+') {
1013f5b1c8a1SJohn Marino 				multi = 1;
1014f5b1c8a1SJohn Marino 				l++;
1015f5b1c8a1SJohn Marino 			} else
1016f5b1c8a1SJohn Marino 				multi = 0;
1017f5b1c8a1SJohn Marino 
1018f5b1c8a1SJohn Marino 			/*
1019f5b1c8a1SJohn Marino 			 * Now search for the cipher alias in the ca_list.
1020f5b1c8a1SJohn Marino 			 * Be careful with the strncmp, because the "buflen"
1021f5b1c8a1SJohn Marino 			 * limitation will make the rule "ADH:SOME" and the
1022f5b1c8a1SJohn Marino 			 * cipher "ADH-MY-CIPHER" look like a match for
1023f5b1c8a1SJohn Marino 			 * buflen=3. So additionally check whether the cipher
1024f5b1c8a1SJohn Marino 			 * name found has the correct length. We can save a
1025f5b1c8a1SJohn Marino 			 * strlen() call: just checking for the '\0' at the
1026f5b1c8a1SJohn Marino 			 * right place is sufficient, we have to strncmp()
1027f5b1c8a1SJohn Marino 			 * anyway (we cannot use strcmp(), because buf is not
1028f5b1c8a1SJohn Marino 			 * '\0' terminated.)
1029f5b1c8a1SJohn Marino 			 */
1030f5b1c8a1SJohn Marino 			j = found = 0;
1031f5b1c8a1SJohn Marino 			cipher_id = 0;
1032f5b1c8a1SJohn Marino 			while (ca_list[j]) {
1033f5b1c8a1SJohn Marino 				if (!strncmp(buf, ca_list[j]->name, buflen) &&
1034f5b1c8a1SJohn Marino 				    (ca_list[j]->name[buflen] == '\0')) {
1035f5b1c8a1SJohn Marino 					found = 1;
1036f5b1c8a1SJohn Marino 					break;
1037f5b1c8a1SJohn Marino 				} else
1038f5b1c8a1SJohn Marino 					j++;
1039f5b1c8a1SJohn Marino 			}
1040f5b1c8a1SJohn Marino 
1041f5b1c8a1SJohn Marino 			if (!found)
1042f5b1c8a1SJohn Marino 				break;	/* ignore this entry */
1043f5b1c8a1SJohn Marino 
1044f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_mkey) {
1045f5b1c8a1SJohn Marino 				if (alg_mkey) {
1046f5b1c8a1SJohn Marino 					alg_mkey &= ca_list[j]->algorithm_mkey;
1047f5b1c8a1SJohn Marino 					if (!alg_mkey) {
1048f5b1c8a1SJohn Marino 						found = 0;
1049f5b1c8a1SJohn Marino 						break;
1050f5b1c8a1SJohn Marino 					}
1051f5b1c8a1SJohn Marino 				} else
1052f5b1c8a1SJohn Marino 					alg_mkey = ca_list[j]->algorithm_mkey;
1053f5b1c8a1SJohn Marino 			}
1054f5b1c8a1SJohn Marino 
1055f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_auth) {
1056f5b1c8a1SJohn Marino 				if (alg_auth) {
1057f5b1c8a1SJohn Marino 					alg_auth &= ca_list[j]->algorithm_auth;
1058f5b1c8a1SJohn Marino 					if (!alg_auth) {
1059f5b1c8a1SJohn Marino 						found = 0;
1060f5b1c8a1SJohn Marino 						break;
1061f5b1c8a1SJohn Marino 					}
1062f5b1c8a1SJohn Marino 				} else
1063f5b1c8a1SJohn Marino 					alg_auth = ca_list[j]->algorithm_auth;
1064f5b1c8a1SJohn Marino 			}
1065f5b1c8a1SJohn Marino 
1066f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_enc) {
1067f5b1c8a1SJohn Marino 				if (alg_enc) {
1068f5b1c8a1SJohn Marino 					alg_enc &= ca_list[j]->algorithm_enc;
1069f5b1c8a1SJohn Marino 					if (!alg_enc) {
1070f5b1c8a1SJohn Marino 						found = 0;
1071f5b1c8a1SJohn Marino 						break;
1072f5b1c8a1SJohn Marino 					}
1073f5b1c8a1SJohn Marino 				} else
1074f5b1c8a1SJohn Marino 					alg_enc = ca_list[j]->algorithm_enc;
1075f5b1c8a1SJohn Marino 			}
1076f5b1c8a1SJohn Marino 
1077f5b1c8a1SJohn Marino 			if (ca_list[j]->algorithm_mac) {
1078f5b1c8a1SJohn Marino 				if (alg_mac) {
1079f5b1c8a1SJohn Marino 					alg_mac &= ca_list[j]->algorithm_mac;
1080f5b1c8a1SJohn Marino 					if (!alg_mac) {
1081f5b1c8a1SJohn Marino 						found = 0;
1082f5b1c8a1SJohn Marino 						break;
1083f5b1c8a1SJohn Marino 					}
1084f5b1c8a1SJohn Marino 				} else
1085f5b1c8a1SJohn Marino 					alg_mac = ca_list[j]->algorithm_mac;
1086f5b1c8a1SJohn Marino 			}
1087f5b1c8a1SJohn Marino 
1088f5b1c8a1SJohn Marino 			if (ca_list[j]->algo_strength & SSL_STRONG_MASK) {
1089f5b1c8a1SJohn Marino 				if (algo_strength & SSL_STRONG_MASK) {
1090f5b1c8a1SJohn Marino 					algo_strength &=
1091f5b1c8a1SJohn Marino 					    (ca_list[j]->algo_strength &
1092f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
1093f5b1c8a1SJohn Marino 					if (!(algo_strength &
1094f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK)) {
1095f5b1c8a1SJohn Marino 						found = 0;
1096f5b1c8a1SJohn Marino 						break;
1097f5b1c8a1SJohn Marino 					}
1098f5b1c8a1SJohn Marino 				} else
1099f5b1c8a1SJohn Marino 					algo_strength |=
1100f5b1c8a1SJohn Marino 					    ca_list[j]->algo_strength &
1101f5b1c8a1SJohn Marino 					    SSL_STRONG_MASK;
1102f5b1c8a1SJohn Marino 			}
1103f5b1c8a1SJohn Marino 
1104f5b1c8a1SJohn Marino 			if (ca_list[j]->valid) {
1105f5b1c8a1SJohn Marino 				/*
1106f5b1c8a1SJohn Marino 				 * explicit ciphersuite found; its protocol
1107f5b1c8a1SJohn Marino 				 * version does not become part of the search
1108f5b1c8a1SJohn Marino 				 * pattern!
1109f5b1c8a1SJohn Marino 				 */
1110f5b1c8a1SJohn Marino 				cipher_id = ca_list[j]->id;
1111*cca6fc52SDaniel Fojt 				if (ca_list[j]->algorithm_ssl == SSL_TLSV1_3)
1112*cca6fc52SDaniel Fojt 					*tls13_seen = 1;
1113f5b1c8a1SJohn Marino 			} else {
1114f5b1c8a1SJohn Marino 				/*
1115f5b1c8a1SJohn Marino 				 * not an explicit ciphersuite; only in this
1116f5b1c8a1SJohn Marino 				 * case, the protocol version is considered
1117f5b1c8a1SJohn Marino 				 * part of the search pattern
1118f5b1c8a1SJohn Marino 				 */
1119f5b1c8a1SJohn Marino 				if (ca_list[j]->algorithm_ssl) {
1120f5b1c8a1SJohn Marino 					if (alg_ssl) {
1121f5b1c8a1SJohn Marino 						alg_ssl &=
1122f5b1c8a1SJohn Marino 						    ca_list[j]->algorithm_ssl;
1123f5b1c8a1SJohn Marino 						if (!alg_ssl) {
1124f5b1c8a1SJohn Marino 							found = 0;
1125f5b1c8a1SJohn Marino 							break;
1126f5b1c8a1SJohn Marino 						}
1127f5b1c8a1SJohn Marino 					} else
1128f5b1c8a1SJohn Marino 						alg_ssl =
1129f5b1c8a1SJohn Marino 						    ca_list[j]->algorithm_ssl;
1130f5b1c8a1SJohn Marino 				}
1131f5b1c8a1SJohn Marino 			}
1132f5b1c8a1SJohn Marino 
1133f5b1c8a1SJohn Marino 			if (!multi)
1134f5b1c8a1SJohn Marino 				break;
1135f5b1c8a1SJohn Marino 		}
1136f5b1c8a1SJohn Marino 
1137f5b1c8a1SJohn Marino 		/*
1138f5b1c8a1SJohn Marino 		 * Ok, we have the rule, now apply it
1139f5b1c8a1SJohn Marino 		 */
1140f5b1c8a1SJohn Marino 		if (rule == CIPHER_SPECIAL) {
1141f5b1c8a1SJohn Marino 			/* special command */
1142f5b1c8a1SJohn Marino 			ok = 0;
1143f5b1c8a1SJohn Marino 			if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8))
1144f5b1c8a1SJohn Marino 				ok = ssl_cipher_strength_sort(head_p, tail_p);
1145f5b1c8a1SJohn Marino 			else
114672c33676SMaxim Ag 				SSLerrorx(SSL_R_INVALID_COMMAND);
1147f5b1c8a1SJohn Marino 			if (ok == 0)
1148f5b1c8a1SJohn Marino 				retval = 0;
1149f5b1c8a1SJohn Marino 			/*
1150f5b1c8a1SJohn Marino 			 * We do not support any "multi" options
1151f5b1c8a1SJohn Marino 			 * together with "@", so throw away the
1152f5b1c8a1SJohn Marino 			 * rest of the command, if any left, until
1153f5b1c8a1SJohn Marino 			 * end or ':' is found.
1154f5b1c8a1SJohn Marino 			 */
1155f5b1c8a1SJohn Marino 			while ((*l != '\0') && !ITEM_SEP(*l))
1156f5b1c8a1SJohn Marino 				l++;
1157f5b1c8a1SJohn Marino 		} else if (found) {
1158*cca6fc52SDaniel Fojt 			if (alg_ssl == SSL_TLSV1_3)
1159*cca6fc52SDaniel Fojt 				*tls13_seen = 1;
1160f5b1c8a1SJohn Marino 			ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth,
1161f5b1c8a1SJohn Marino 			    alg_enc, alg_mac, alg_ssl, algo_strength, rule,
1162f5b1c8a1SJohn Marino 			    -1, head_p, tail_p);
1163f5b1c8a1SJohn Marino 		} else {
1164f5b1c8a1SJohn Marino 			while ((*l != '\0') && !ITEM_SEP(*l))
1165f5b1c8a1SJohn Marino 				l++;
1166f5b1c8a1SJohn Marino 		}
1167f5b1c8a1SJohn Marino 		if (*l == '\0')
1168f5b1c8a1SJohn Marino 			break; /* done */
1169f5b1c8a1SJohn Marino 	}
1170f5b1c8a1SJohn Marino 
1171f5b1c8a1SJohn Marino 	return (retval);
1172f5b1c8a1SJohn Marino }
1173f5b1c8a1SJohn Marino 
1174f5b1c8a1SJohn Marino static inline int
1175f5b1c8a1SJohn Marino ssl_aes_is_accelerated(void)
1176f5b1c8a1SJohn Marino {
1177f5b1c8a1SJohn Marino #if defined(__i386__) || defined(__x86_64__)
1178f5b1c8a1SJohn Marino 	return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0);
1179f5b1c8a1SJohn Marino #else
1180f5b1c8a1SJohn Marino 	return (0);
1181f5b1c8a1SJohn Marino #endif
1182f5b1c8a1SJohn Marino }
1183f5b1c8a1SJohn Marino 
1184f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) *
1185f5b1c8a1SJohn Marino ssl_create_cipher_list(const SSL_METHOD *ssl_method,
1186f5b1c8a1SJohn Marino     STACK_OF(SSL_CIPHER) **cipher_list,
1187f5b1c8a1SJohn Marino     STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1188f5b1c8a1SJohn Marino     const char *rule_str)
1189f5b1c8a1SJohn Marino {
1190f5b1c8a1SJohn Marino 	int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
1191f5b1c8a1SJohn Marino 	unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
1192f5b1c8a1SJohn Marino 	STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list;
1193f5b1c8a1SJohn Marino 	const char *rule_p;
1194f5b1c8a1SJohn Marino 	CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
1195f5b1c8a1SJohn Marino 	const SSL_CIPHER **ca_list = NULL;
1196*cca6fc52SDaniel Fojt 	int tls13_seen = 0;
1197*cca6fc52SDaniel Fojt 	int any_active;
1198f5b1c8a1SJohn Marino 
1199f5b1c8a1SJohn Marino 	/*
1200f5b1c8a1SJohn Marino 	 * Return with error if nothing to do.
1201f5b1c8a1SJohn Marino 	 */
1202f5b1c8a1SJohn Marino 	if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
1203f5b1c8a1SJohn Marino 		return NULL;
1204f5b1c8a1SJohn Marino 
1205f5b1c8a1SJohn Marino 	/*
1206f5b1c8a1SJohn Marino 	 * To reduce the work to do we only want to process the compiled
1207f5b1c8a1SJohn Marino 	 * in algorithms, so we first get the mask of disabled ciphers.
1208f5b1c8a1SJohn Marino 	 */
1209f5b1c8a1SJohn Marino 	ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
1210f5b1c8a1SJohn Marino 
1211f5b1c8a1SJohn Marino 	/*
1212f5b1c8a1SJohn Marino 	 * Now we have to collect the available ciphers from the compiled
1213f5b1c8a1SJohn Marino 	 * in ciphers. We cannot get more than the number compiled in, so
1214f5b1c8a1SJohn Marino 	 * it is used for allocation.
1215f5b1c8a1SJohn Marino 	 */
1216f5b1c8a1SJohn Marino 	num_of_ciphers = ssl_method->num_ciphers();
1217f5b1c8a1SJohn Marino 	co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER));
1218f5b1c8a1SJohn Marino 	if (co_list == NULL) {
121972c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
1220f5b1c8a1SJohn Marino 		return(NULL);	/* Failure */
1221f5b1c8a1SJohn Marino 	}
1222f5b1c8a1SJohn Marino 
1223f5b1c8a1SJohn Marino 	ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
1224f5b1c8a1SJohn Marino 	    disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
1225f5b1c8a1SJohn Marino 	    co_list, &head, &tail);
1226f5b1c8a1SJohn Marino 
1227f5b1c8a1SJohn Marino 
1228f5b1c8a1SJohn Marino 	/* Now arrange all ciphers by preference: */
1229f5b1c8a1SJohn Marino 
1230f5b1c8a1SJohn Marino 	/* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
1231f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1232f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
1233f5b1c8a1SJohn Marino 
1234*cca6fc52SDaniel Fojt 	if (ssl_aes_is_accelerated()) {
1235f5b1c8a1SJohn Marino 		/*
1236f5b1c8a1SJohn Marino 		 * We have hardware assisted AES - prefer AES as a symmetric
1237f5b1c8a1SJohn Marino 		 * cipher, with CHACHA20 second.
1238f5b1c8a1SJohn Marino 		 */
1239f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
1240f5b1c8a1SJohn Marino 		    CIPHER_ADD, -1, &head, &tail);
1241f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
1242f5b1c8a1SJohn Marino 		    0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1243f5b1c8a1SJohn Marino 	} else {
1244f5b1c8a1SJohn Marino 		/*
1245f5b1c8a1SJohn Marino 		 * CHACHA20 is fast and safe on all hardware and is thus our
1246f5b1c8a1SJohn Marino 		 * preferred symmetric cipher, with AES second.
1247f5b1c8a1SJohn Marino 		 */
1248f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305,
1249f5b1c8a1SJohn Marino 		    0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1250f5b1c8a1SJohn Marino 		ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0,
1251f5b1c8a1SJohn Marino 		    CIPHER_ADD, -1, &head, &tail);
1252f5b1c8a1SJohn Marino 	}
1253f5b1c8a1SJohn Marino 
1254f5b1c8a1SJohn Marino 	/* Temporarily enable everything else for sorting */
1255f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
1256f5b1c8a1SJohn Marino 
1257f5b1c8a1SJohn Marino 	/* Low priority for MD5 */
1258f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail);
1259f5b1c8a1SJohn Marino 
1260f5b1c8a1SJohn Marino 	/* Move anonymous ciphers to the end.  Usually, these will remain disabled.
1261f5b1c8a1SJohn Marino 	 * (For applications that allow them, they aren't too bad, but we prefer
1262f5b1c8a1SJohn Marino 	 * authenticated ciphers.) */
1263f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1264f5b1c8a1SJohn Marino 
1265f5b1c8a1SJohn Marino 	/* Move ciphers without forward secrecy to the end */
1266f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1267f5b1c8a1SJohn Marino 
1268f5b1c8a1SJohn Marino 	/* RC4 is sort of broken - move it to the end */
1269f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail);
1270f5b1c8a1SJohn Marino 
1271f5b1c8a1SJohn Marino 	/* Now sort by symmetric encryption strength.  The above ordering remains
1272f5b1c8a1SJohn Marino 	 * in force within each class */
1273f5b1c8a1SJohn Marino 	if (!ssl_cipher_strength_sort(&head, &tail)) {
1274f5b1c8a1SJohn Marino 		free(co_list);
1275f5b1c8a1SJohn Marino 		return NULL;
1276f5b1c8a1SJohn Marino 	}
1277f5b1c8a1SJohn Marino 
1278f5b1c8a1SJohn Marino 	/* Now disable everything (maintaining the ordering!) */
1279f5b1c8a1SJohn Marino 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
1280f5b1c8a1SJohn Marino 
128172c33676SMaxim Ag 	/* TLSv1.3 first. */
128272c33676SMaxim Ag 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_ADD, -1, &head, &tail);
128372c33676SMaxim Ag 	ssl_cipher_apply_rule(0, 0, 0, 0, 0, SSL_TLSV1_3, 0, CIPHER_DEL, -1, &head, &tail);
1284f5b1c8a1SJohn Marino 
1285f5b1c8a1SJohn Marino 	/*
1286f5b1c8a1SJohn Marino 	 * We also need cipher aliases for selecting based on the rule_str.
1287f5b1c8a1SJohn Marino 	 * There might be two types of entries in the rule_str: 1) names
1288f5b1c8a1SJohn Marino 	 * of ciphers themselves 2) aliases for groups of ciphers.
1289f5b1c8a1SJohn Marino 	 * For 1) we need the available ciphers and for 2) the cipher
1290f5b1c8a1SJohn Marino 	 * groups of cipher_aliases added together in one list (otherwise
1291f5b1c8a1SJohn Marino 	 * we would be happy with just the cipher_aliases table).
1292f5b1c8a1SJohn Marino 	 */
1293f5b1c8a1SJohn Marino 	num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
1294f5b1c8a1SJohn Marino 	num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
1295f5b1c8a1SJohn Marino 	ca_list = reallocarray(NULL, num_of_alias_max, sizeof(SSL_CIPHER *));
1296f5b1c8a1SJohn Marino 	if (ca_list == NULL) {
1297f5b1c8a1SJohn Marino 		free(co_list);
129872c33676SMaxim Ag 		SSLerrorx(ERR_R_MALLOC_FAILURE);
1299f5b1c8a1SJohn Marino 		return(NULL);	/* Failure */
1300f5b1c8a1SJohn Marino 	}
1301*cca6fc52SDaniel Fojt 	ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, disabled_mkey,
1302*cca6fc52SDaniel Fojt 	    disabled_auth, disabled_enc, disabled_mac, disabled_ssl, head);
1303f5b1c8a1SJohn Marino 
1304f5b1c8a1SJohn Marino 	/*
1305f5b1c8a1SJohn Marino 	 * If the rule_string begins with DEFAULT, apply the default rule
1306f5b1c8a1SJohn Marino 	 * before using the (possibly available) additional rules.
1307f5b1c8a1SJohn Marino 	 */
1308f5b1c8a1SJohn Marino 	ok = 1;
1309f5b1c8a1SJohn Marino 	rule_p = rule_str;
1310f5b1c8a1SJohn Marino 	if (strncmp(rule_str, "DEFAULT", 7) == 0) {
1311f5b1c8a1SJohn Marino 		ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
1312*cca6fc52SDaniel Fojt 		    &head, &tail, ca_list, &tls13_seen);
1313f5b1c8a1SJohn Marino 		rule_p += 7;
1314f5b1c8a1SJohn Marino 		if (*rule_p == ':')
1315f5b1c8a1SJohn Marino 			rule_p++;
1316f5b1c8a1SJohn Marino 	}
1317f5b1c8a1SJohn Marino 
1318f5b1c8a1SJohn Marino 	if (ok && (strlen(rule_p) > 0))
1319*cca6fc52SDaniel Fojt 		ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list,
1320*cca6fc52SDaniel Fojt 		    &tls13_seen);
1321f5b1c8a1SJohn Marino 
1322f5b1c8a1SJohn Marino 	free((void *)ca_list);	/* Not needed anymore */
1323f5b1c8a1SJohn Marino 
1324f5b1c8a1SJohn Marino 	if (!ok) {
1325f5b1c8a1SJohn Marino 		/* Rule processing failure */
1326f5b1c8a1SJohn Marino 		free(co_list);
1327f5b1c8a1SJohn Marino 		return (NULL);
1328f5b1c8a1SJohn Marino 	}
1329f5b1c8a1SJohn Marino 
1330f5b1c8a1SJohn Marino 	/*
1331f5b1c8a1SJohn Marino 	 * Allocate new "cipherstack" for the result, return with error
1332f5b1c8a1SJohn Marino 	 * if we cannot get one.
1333f5b1c8a1SJohn Marino 	 */
1334f5b1c8a1SJohn Marino 	if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
1335f5b1c8a1SJohn Marino 		free(co_list);
1336f5b1c8a1SJohn Marino 		return (NULL);
1337f5b1c8a1SJohn Marino 	}
1338f5b1c8a1SJohn Marino 
1339f5b1c8a1SJohn Marino 	/*
1340f5b1c8a1SJohn Marino 	 * The cipher selection for the list is done. The ciphers are added
1341f5b1c8a1SJohn Marino 	 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
1342*cca6fc52SDaniel Fojt 	 *
1343*cca6fc52SDaniel Fojt 	 * If the rule string did not contain any references to TLSv1.3,
1344*cca6fc52SDaniel Fojt 	 * include inactive TLSv1.3 cipher suites. This avoids attempts to
1345*cca6fc52SDaniel Fojt 	 * use TLSv1.3 with an older rule string that does not include
1346*cca6fc52SDaniel Fojt 	 * TLSv1.3 cipher suites. If the rule string resulted in no active
1347*cca6fc52SDaniel Fojt 	 * cipher suites then we return an empty stack.
1348f5b1c8a1SJohn Marino 	 */
1349*cca6fc52SDaniel Fojt 	any_active = 0;
1350f5b1c8a1SJohn Marino 	for (curr = head; curr != NULL; curr = curr->next) {
1351*cca6fc52SDaniel Fojt 		if (curr->active ||
1352*cca6fc52SDaniel Fojt 		    (!tls13_seen && curr->cipher->algorithm_ssl == SSL_TLSV1_3))
1353f5b1c8a1SJohn Marino 			sk_SSL_CIPHER_push(cipherstack, curr->cipher);
1354*cca6fc52SDaniel Fojt 		any_active |= curr->active;
1355f5b1c8a1SJohn Marino 	}
1356*cca6fc52SDaniel Fojt 	if (!any_active)
1357*cca6fc52SDaniel Fojt 		sk_SSL_CIPHER_zero(cipherstack);
1358*cca6fc52SDaniel Fojt 
1359f5b1c8a1SJohn Marino 	free(co_list);	/* Not needed any longer */
1360f5b1c8a1SJohn Marino 
1361f5b1c8a1SJohn Marino 	tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1362f5b1c8a1SJohn Marino 	if (tmp_cipher_list == NULL) {
1363f5b1c8a1SJohn Marino 		sk_SSL_CIPHER_free(cipherstack);
1364f5b1c8a1SJohn Marino 		return NULL;
1365f5b1c8a1SJohn Marino 	}
1366f5b1c8a1SJohn Marino 	sk_SSL_CIPHER_free(*cipher_list);
1367f5b1c8a1SJohn Marino 	*cipher_list = cipherstack;
1368f5b1c8a1SJohn Marino 	sk_SSL_CIPHER_free(*cipher_list_by_id);
1369f5b1c8a1SJohn Marino 	*cipher_list_by_id = tmp_cipher_list;
1370f5b1c8a1SJohn Marino 	(void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,
1371f5b1c8a1SJohn Marino 	    ssl_cipher_ptr_id_cmp);
1372f5b1c8a1SJohn Marino 
1373f5b1c8a1SJohn Marino 	sk_SSL_CIPHER_sort(*cipher_list_by_id);
1374f5b1c8a1SJohn Marino 	return (cipherstack);
1375f5b1c8a1SJohn Marino }
1376f5b1c8a1SJohn Marino 
1377f5b1c8a1SJohn Marino const SSL_CIPHER *
1378f5b1c8a1SJohn Marino SSL_CIPHER_get_by_id(unsigned int id)
1379f5b1c8a1SJohn Marino {
1380f5b1c8a1SJohn Marino 	return ssl3_get_cipher_by_id(id);
1381f5b1c8a1SJohn Marino }
1382f5b1c8a1SJohn Marino 
1383f5b1c8a1SJohn Marino const SSL_CIPHER *
1384f5b1c8a1SJohn Marino SSL_CIPHER_get_by_value(uint16_t value)
1385f5b1c8a1SJohn Marino {
1386f5b1c8a1SJohn Marino 	return ssl3_get_cipher_by_value(value);
1387f5b1c8a1SJohn Marino }
1388f5b1c8a1SJohn Marino 
1389f5b1c8a1SJohn Marino char *
1390f5b1c8a1SJohn Marino SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
1391f5b1c8a1SJohn Marino {
1392f5b1c8a1SJohn Marino 	unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2;
1393f5b1c8a1SJohn Marino 	const char *ver, *kx, *au, *enc, *mac;
1394f5b1c8a1SJohn Marino 	char *ret;
1395f5b1c8a1SJohn Marino 	int l;
1396f5b1c8a1SJohn Marino 
1397f5b1c8a1SJohn Marino 	alg_mkey = cipher->algorithm_mkey;
1398f5b1c8a1SJohn Marino 	alg_auth = cipher->algorithm_auth;
1399f5b1c8a1SJohn Marino 	alg_enc = cipher->algorithm_enc;
1400f5b1c8a1SJohn Marino 	alg_mac = cipher->algorithm_mac;
1401f5b1c8a1SJohn Marino 	alg_ssl = cipher->algorithm_ssl;
1402f5b1c8a1SJohn Marino 
1403f5b1c8a1SJohn Marino 	alg2 = cipher->algorithm2;
1404f5b1c8a1SJohn Marino 
1405f5b1c8a1SJohn Marino 	if (alg_ssl & SSL_SSLV3)
1406f5b1c8a1SJohn Marino 		ver = "SSLv3";
1407f5b1c8a1SJohn Marino 	else if (alg_ssl & SSL_TLSV1_2)
1408f5b1c8a1SJohn Marino 		ver = "TLSv1.2";
140972c33676SMaxim Ag 	else if (alg_ssl & SSL_TLSV1_3)
141072c33676SMaxim Ag 		ver = "TLSv1.3";
1411f5b1c8a1SJohn Marino 	else
1412f5b1c8a1SJohn Marino 		ver = "unknown";
1413f5b1c8a1SJohn Marino 
1414f5b1c8a1SJohn Marino 	switch (alg_mkey) {
1415f5b1c8a1SJohn Marino 	case SSL_kRSA:
1416f5b1c8a1SJohn Marino 		kx = "RSA";
1417f5b1c8a1SJohn Marino 		break;
1418f5b1c8a1SJohn Marino 	case SSL_kDHE:
1419f5b1c8a1SJohn Marino 		kx = "DH";
1420f5b1c8a1SJohn Marino 		break;
1421f5b1c8a1SJohn Marino 	case SSL_kECDHE:
1422f5b1c8a1SJohn Marino 		kx = "ECDH";
1423f5b1c8a1SJohn Marino 		break;
1424f5b1c8a1SJohn Marino 	case SSL_kGOST:
1425f5b1c8a1SJohn Marino 		kx = "GOST";
1426f5b1c8a1SJohn Marino 		break;
1427*cca6fc52SDaniel Fojt 	case SSL_kTLS1_3:
1428*cca6fc52SDaniel Fojt 		kx = "TLSv1.3";
1429*cca6fc52SDaniel Fojt 		break;
1430f5b1c8a1SJohn Marino 	default:
1431f5b1c8a1SJohn Marino 		kx = "unknown";
1432f5b1c8a1SJohn Marino 	}
1433f5b1c8a1SJohn Marino 
1434f5b1c8a1SJohn Marino 	switch (alg_auth) {
1435f5b1c8a1SJohn Marino 	case SSL_aRSA:
1436f5b1c8a1SJohn Marino 		au = "RSA";
1437f5b1c8a1SJohn Marino 		break;
1438f5b1c8a1SJohn Marino 	case SSL_aDSS:
1439f5b1c8a1SJohn Marino 		au = "DSS";
1440f5b1c8a1SJohn Marino 		break;
1441f5b1c8a1SJohn Marino 	case SSL_aNULL:
1442f5b1c8a1SJohn Marino 		au = "None";
1443f5b1c8a1SJohn Marino 		break;
1444f5b1c8a1SJohn Marino 	case SSL_aECDSA:
1445f5b1c8a1SJohn Marino 		au = "ECDSA";
1446f5b1c8a1SJohn Marino 		break;
1447f5b1c8a1SJohn Marino 	case SSL_aGOST01:
1448f5b1c8a1SJohn Marino 		au = "GOST01";
1449f5b1c8a1SJohn Marino 		break;
1450*cca6fc52SDaniel Fojt 	case SSL_aTLS1_3:
1451*cca6fc52SDaniel Fojt 		au = "TLSv1.3";
1452*cca6fc52SDaniel Fojt 		break;
1453f5b1c8a1SJohn Marino 	default:
1454f5b1c8a1SJohn Marino 		au = "unknown";
1455f5b1c8a1SJohn Marino 		break;
1456f5b1c8a1SJohn Marino 	}
1457f5b1c8a1SJohn Marino 
1458f5b1c8a1SJohn Marino 	switch (alg_enc) {
1459f5b1c8a1SJohn Marino 	case SSL_3DES:
1460f5b1c8a1SJohn Marino 		enc = "3DES(168)";
1461f5b1c8a1SJohn Marino 		break;
1462f5b1c8a1SJohn Marino 	case SSL_RC4:
1463f5b1c8a1SJohn Marino 		enc = alg2 & SSL2_CF_8_BYTE_ENC ? "RC4(64)" : "RC4(128)";
1464f5b1c8a1SJohn Marino 		break;
1465f5b1c8a1SJohn Marino 	case SSL_eNULL:
1466f5b1c8a1SJohn Marino 		enc = "None";
1467f5b1c8a1SJohn Marino 		break;
1468f5b1c8a1SJohn Marino 	case SSL_AES128:
1469f5b1c8a1SJohn Marino 		enc = "AES(128)";
1470f5b1c8a1SJohn Marino 		break;
1471f5b1c8a1SJohn Marino 	case SSL_AES256:
1472f5b1c8a1SJohn Marino 		enc = "AES(256)";
1473f5b1c8a1SJohn Marino 		break;
1474f5b1c8a1SJohn Marino 	case SSL_AES128GCM:
1475f5b1c8a1SJohn Marino 		enc = "AESGCM(128)";
1476f5b1c8a1SJohn Marino 		break;
1477f5b1c8a1SJohn Marino 	case SSL_AES256GCM:
1478f5b1c8a1SJohn Marino 		enc = "AESGCM(256)";
1479f5b1c8a1SJohn Marino 		break;
1480f5b1c8a1SJohn Marino 	case SSL_CAMELLIA128:
1481f5b1c8a1SJohn Marino 		enc = "Camellia(128)";
1482f5b1c8a1SJohn Marino 		break;
1483f5b1c8a1SJohn Marino 	case SSL_CAMELLIA256:
1484f5b1c8a1SJohn Marino 		enc = "Camellia(256)";
1485f5b1c8a1SJohn Marino 		break;
1486f5b1c8a1SJohn Marino 	case SSL_CHACHA20POLY1305:
1487f5b1c8a1SJohn Marino 		enc = "ChaCha20-Poly1305";
1488f5b1c8a1SJohn Marino 		break;
1489f5b1c8a1SJohn Marino 	case SSL_eGOST2814789CNT:
1490f5b1c8a1SJohn Marino 		enc = "GOST-28178-89-CNT";
1491f5b1c8a1SJohn Marino 		break;
1492f5b1c8a1SJohn Marino 	default:
1493f5b1c8a1SJohn Marino 		enc = "unknown";
1494f5b1c8a1SJohn Marino 		break;
1495f5b1c8a1SJohn Marino 	}
1496f5b1c8a1SJohn Marino 
1497f5b1c8a1SJohn Marino 	switch (alg_mac) {
1498f5b1c8a1SJohn Marino 	case SSL_MD5:
1499f5b1c8a1SJohn Marino 		mac = "MD5";
1500f5b1c8a1SJohn Marino 		break;
1501f5b1c8a1SJohn Marino 	case SSL_SHA1:
1502f5b1c8a1SJohn Marino 		mac = "SHA1";
1503f5b1c8a1SJohn Marino 		break;
1504f5b1c8a1SJohn Marino 	case SSL_SHA256:
1505f5b1c8a1SJohn Marino 		mac = "SHA256";
1506f5b1c8a1SJohn Marino 		break;
1507f5b1c8a1SJohn Marino 	case SSL_SHA384:
1508f5b1c8a1SJohn Marino 		mac = "SHA384";
1509f5b1c8a1SJohn Marino 		break;
1510f5b1c8a1SJohn Marino 	case SSL_AEAD:
1511f5b1c8a1SJohn Marino 		mac = "AEAD";
1512f5b1c8a1SJohn Marino 		break;
1513f5b1c8a1SJohn Marino 	case SSL_GOST94:
1514f5b1c8a1SJohn Marino 		mac = "GOST94";
1515f5b1c8a1SJohn Marino 		break;
1516f5b1c8a1SJohn Marino 	case SSL_GOST89MAC:
1517f5b1c8a1SJohn Marino 		mac = "GOST89IMIT";
1518f5b1c8a1SJohn Marino 		break;
1519f5b1c8a1SJohn Marino 	case SSL_STREEBOG256:
1520f5b1c8a1SJohn Marino 		mac = "STREEBOG256";
1521f5b1c8a1SJohn Marino 		break;
1522f5b1c8a1SJohn Marino 	default:
1523f5b1c8a1SJohn Marino 		mac = "unknown";
1524f5b1c8a1SJohn Marino 		break;
1525f5b1c8a1SJohn Marino 	}
1526f5b1c8a1SJohn Marino 
1527f5b1c8a1SJohn Marino 	if (asprintf(&ret, "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n",
1528f5b1c8a1SJohn Marino 	    cipher->name, ver, kx, au, enc, mac) == -1)
1529f5b1c8a1SJohn Marino 		return "OPENSSL_malloc Error";
1530f5b1c8a1SJohn Marino 
1531f5b1c8a1SJohn Marino 	if (buf != NULL) {
1532f5b1c8a1SJohn Marino 		l = strlcpy(buf, ret, len);
1533f5b1c8a1SJohn Marino 		free(ret);
1534f5b1c8a1SJohn Marino 		ret = buf;
1535f5b1c8a1SJohn Marino 		if (l >= len)
1536f5b1c8a1SJohn Marino 			ret = "Buffer too small";
1537f5b1c8a1SJohn Marino 	}
1538f5b1c8a1SJohn Marino 
1539f5b1c8a1SJohn Marino 	return (ret);
1540f5b1c8a1SJohn Marino }
1541f5b1c8a1SJohn Marino 
154272c33676SMaxim Ag const char *
1543f5b1c8a1SJohn Marino SSL_CIPHER_get_version(const SSL_CIPHER *c)
1544f5b1c8a1SJohn Marino {
1545f5b1c8a1SJohn Marino 	if (c == NULL)
1546f5b1c8a1SJohn Marino 		return("(NONE)");
1547f5b1c8a1SJohn Marino 	if ((c->id >> 24) == 3)
1548f5b1c8a1SJohn Marino 		return("TLSv1/SSLv3");
1549f5b1c8a1SJohn Marino 	else
1550f5b1c8a1SJohn Marino 		return("unknown");
1551f5b1c8a1SJohn Marino }
1552f5b1c8a1SJohn Marino 
1553f5b1c8a1SJohn Marino /* return the actual cipher being used */
1554f5b1c8a1SJohn Marino const char *
1555f5b1c8a1SJohn Marino SSL_CIPHER_get_name(const SSL_CIPHER *c)
1556f5b1c8a1SJohn Marino {
1557f5b1c8a1SJohn Marino 	if (c != NULL)
1558f5b1c8a1SJohn Marino 		return (c->name);
1559f5b1c8a1SJohn Marino 	return("(NONE)");
1560f5b1c8a1SJohn Marino }
1561f5b1c8a1SJohn Marino 
1562f5b1c8a1SJohn Marino /* number of bits for symmetric cipher */
1563f5b1c8a1SJohn Marino int
1564f5b1c8a1SJohn Marino SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
1565f5b1c8a1SJohn Marino {
1566f5b1c8a1SJohn Marino 	int ret = 0;
1567f5b1c8a1SJohn Marino 
1568f5b1c8a1SJohn Marino 	if (c != NULL) {
1569f5b1c8a1SJohn Marino 		if (alg_bits != NULL)
1570f5b1c8a1SJohn Marino 			*alg_bits = c->alg_bits;
1571f5b1c8a1SJohn Marino 		ret = c->strength_bits;
1572f5b1c8a1SJohn Marino 	}
1573f5b1c8a1SJohn Marino 	return (ret);
1574f5b1c8a1SJohn Marino }
1575f5b1c8a1SJohn Marino 
1576f5b1c8a1SJohn Marino unsigned long
1577f5b1c8a1SJohn Marino SSL_CIPHER_get_id(const SSL_CIPHER *c)
1578f5b1c8a1SJohn Marino {
1579f5b1c8a1SJohn Marino 	return c->id;
1580f5b1c8a1SJohn Marino }
1581f5b1c8a1SJohn Marino 
1582f5b1c8a1SJohn Marino uint16_t
1583f5b1c8a1SJohn Marino SSL_CIPHER_get_value(const SSL_CIPHER *c)
1584f5b1c8a1SJohn Marino {
1585f5b1c8a1SJohn Marino 	return ssl3_cipher_get_value(c);
1586f5b1c8a1SJohn Marino }
1587f5b1c8a1SJohn Marino 
158872c33676SMaxim Ag int
158972c33676SMaxim Ag SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
159072c33676SMaxim Ag {
159172c33676SMaxim Ag 	switch (c->algorithm_enc) {
159272c33676SMaxim Ag 	case SSL_eNULL:
159372c33676SMaxim Ag 		return NID_undef;
159472c33676SMaxim Ag 	case SSL_3DES:
159572c33676SMaxim Ag 		return NID_des_ede3_cbc;
159672c33676SMaxim Ag 	case SSL_AES128:
159772c33676SMaxim Ag 		return NID_aes_128_cbc;
159872c33676SMaxim Ag 	case SSL_AES128GCM:
159972c33676SMaxim Ag 		return NID_aes_128_gcm;
160072c33676SMaxim Ag 	case SSL_AES256:
160172c33676SMaxim Ag 		return NID_aes_256_cbc;
160272c33676SMaxim Ag 	case SSL_AES256GCM:
160372c33676SMaxim Ag 		return NID_aes_256_gcm;
160472c33676SMaxim Ag 	case SSL_CAMELLIA128:
160572c33676SMaxim Ag 		return NID_camellia_128_cbc;
160672c33676SMaxim Ag 	case SSL_CAMELLIA256:
160772c33676SMaxim Ag 		return NID_camellia_256_cbc;
160872c33676SMaxim Ag 	case SSL_CHACHA20POLY1305:
160972c33676SMaxim Ag 		return NID_chacha20_poly1305;
161072c33676SMaxim Ag 	case SSL_DES:
161172c33676SMaxim Ag 		return NID_des_cbc;
161272c33676SMaxim Ag 	case SSL_RC4:
161372c33676SMaxim Ag 		return NID_rc4;
161472c33676SMaxim Ag 	case SSL_eGOST2814789CNT:
161572c33676SMaxim Ag 		return NID_gost89_cnt;
161672c33676SMaxim Ag 	default:
161772c33676SMaxim Ag 		return NID_undef;
161872c33676SMaxim Ag 	}
161972c33676SMaxim Ag }
162072c33676SMaxim Ag 
162172c33676SMaxim Ag int
162272c33676SMaxim Ag SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
162372c33676SMaxim Ag {
162472c33676SMaxim Ag 	switch (c->algorithm_mac) {
162572c33676SMaxim Ag 	case SSL_AEAD:
162672c33676SMaxim Ag 		return NID_undef;
162772c33676SMaxim Ag 	case SSL_GOST89MAC:
162872c33676SMaxim Ag 		return NID_id_Gost28147_89_MAC;
162972c33676SMaxim Ag 	case SSL_GOST94:
163072c33676SMaxim Ag 		return NID_id_GostR3411_94;
163172c33676SMaxim Ag 	case SSL_MD5:
163272c33676SMaxim Ag 		return NID_md5;
163372c33676SMaxim Ag 	case SSL_SHA1:
163472c33676SMaxim Ag 		return NID_sha1;
163572c33676SMaxim Ag 	case SSL_SHA256:
163672c33676SMaxim Ag 		return NID_sha256;
163772c33676SMaxim Ag 	case SSL_SHA384:
163872c33676SMaxim Ag 		return NID_sha384;
163972c33676SMaxim Ag 	case SSL_STREEBOG256:
164072c33676SMaxim Ag 		return NID_id_tc26_gost3411_2012_256;
164172c33676SMaxim Ag 	default:
164272c33676SMaxim Ag 		return NID_undef;
164372c33676SMaxim Ag 	}
164472c33676SMaxim Ag }
164572c33676SMaxim Ag 
164672c33676SMaxim Ag int
164772c33676SMaxim Ag SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
164872c33676SMaxim Ag {
164972c33676SMaxim Ag 	switch (c->algorithm_mkey) {
165072c33676SMaxim Ag 	case SSL_kDHE:
165172c33676SMaxim Ag 		return NID_kx_dhe;
165272c33676SMaxim Ag 	case SSL_kECDHE:
165372c33676SMaxim Ag 		return NID_kx_ecdhe;
165472c33676SMaxim Ag 	case SSL_kGOST:
165572c33676SMaxim Ag 		return NID_kx_gost;
165672c33676SMaxim Ag 	case SSL_kRSA:
165772c33676SMaxim Ag 		return NID_kx_rsa;
165872c33676SMaxim Ag 	default:
165972c33676SMaxim Ag 		return NID_undef;
166072c33676SMaxim Ag 	}
166172c33676SMaxim Ag }
166272c33676SMaxim Ag 
166372c33676SMaxim Ag int
166472c33676SMaxim Ag SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
166572c33676SMaxim Ag {
166672c33676SMaxim Ag 	switch (c->algorithm_auth) {
166772c33676SMaxim Ag 	case SSL_aNULL:
166872c33676SMaxim Ag 		return NID_auth_null;
166972c33676SMaxim Ag 	case SSL_aECDSA:
167072c33676SMaxim Ag 		return NID_auth_ecdsa;
167172c33676SMaxim Ag 	case SSL_aGOST01:
167272c33676SMaxim Ag 		return NID_auth_gost01;
167372c33676SMaxim Ag 	case SSL_aRSA:
167472c33676SMaxim Ag 		return NID_auth_rsa;
167572c33676SMaxim Ag 	default:
167672c33676SMaxim Ag 		return NID_undef;
167772c33676SMaxim Ag 	}
167872c33676SMaxim Ag }
167972c33676SMaxim Ag 
168072c33676SMaxim Ag int
168172c33676SMaxim Ag SSL_CIPHER_is_aead(const SSL_CIPHER *c)
168272c33676SMaxim Ag {
168372c33676SMaxim Ag 	return (c->algorithm_mac & SSL_AEAD) == SSL_AEAD;
168472c33676SMaxim Ag }
168572c33676SMaxim Ag 
1686f5b1c8a1SJohn Marino void *
1687f5b1c8a1SJohn Marino SSL_COMP_get_compression_methods(void)
1688f5b1c8a1SJohn Marino {
1689f5b1c8a1SJohn Marino 	return NULL;
1690f5b1c8a1SJohn Marino }
1691f5b1c8a1SJohn Marino 
1692f5b1c8a1SJohn Marino int
1693f5b1c8a1SJohn Marino SSL_COMP_add_compression_method(int id, void *cm)
1694f5b1c8a1SJohn Marino {
1695f5b1c8a1SJohn Marino 	return 1;
1696f5b1c8a1SJohn Marino }
1697f5b1c8a1SJohn Marino 
1698f5b1c8a1SJohn Marino const char *
1699f5b1c8a1SJohn Marino SSL_COMP_get_name(const void *comp)
1700f5b1c8a1SJohn Marino {
1701f5b1c8a1SJohn Marino 	return NULL;
1702f5b1c8a1SJohn Marino }
1703