xref: /freebsd/crypto/openssl/ssl/ssl_ciph.c (revision b2bf0c7e5f4037d63458def91a026592468afd2f)
1e71b7053SJung-uk Kim /*
2*b2bf0c7eSJung-uk Kim  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
41f13597dSJung-uk Kim  * Copyright 2005 Nokia. All rights reserved.
51f13597dSJung-uk Kim  *
6e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (the "License").  You may not use
7e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
8e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
9e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
101f13597dSJung-uk Kim  */
111f13597dSJung-uk Kim 
1274664626SKris Kennaway #include <stdio.h>
13e71b7053SJung-uk Kim #include <ctype.h>
1474664626SKris Kennaway #include <openssl/objects.h>
1574664626SKris Kennaway #include <openssl/comp.h>
161f13597dSJung-uk Kim #include <openssl/engine.h>
17e71b7053SJung-uk Kim #include <openssl/crypto.h>
18e71b7053SJung-uk Kim #include <openssl/conf.h>
19e71b7053SJung-uk Kim #include "internal/nelem.h"
2017f01e99SJung-uk Kim #include "ssl_local.h"
21e71b7053SJung-uk Kim #include "internal/thread_once.h"
22e71b7053SJung-uk Kim #include "internal/cryptlib.h"
2374664626SKris Kennaway 
2474664626SKris Kennaway #define SSL_ENC_DES_IDX         0
2574664626SKris Kennaway #define SSL_ENC_3DES_IDX        1
2674664626SKris Kennaway #define SSL_ENC_RC4_IDX         2
2774664626SKris Kennaway #define SSL_ENC_RC2_IDX         3
2874664626SKris Kennaway #define SSL_ENC_IDEA_IDX        4
291f13597dSJung-uk Kim #define SSL_ENC_NULL_IDX        5
301f13597dSJung-uk Kim #define SSL_ENC_AES128_IDX      6
311f13597dSJung-uk Kim #define SSL_ENC_AES256_IDX      7
321f13597dSJung-uk Kim #define SSL_ENC_CAMELLIA128_IDX 8
331f13597dSJung-uk Kim #define SSL_ENC_CAMELLIA256_IDX 9
341f13597dSJung-uk Kim #define SSL_ENC_GOST89_IDX      10
35db522d3aSSimon L. B. Nielsen #define SSL_ENC_SEED_IDX        11
361f13597dSJung-uk Kim #define SSL_ENC_AES128GCM_IDX   12
371f13597dSJung-uk Kim #define SSL_ENC_AES256GCM_IDX   13
38e71b7053SJung-uk Kim #define SSL_ENC_AES128CCM_IDX   14
39e71b7053SJung-uk Kim #define SSL_ENC_AES256CCM_IDX   15
40e71b7053SJung-uk Kim #define SSL_ENC_AES128CCM8_IDX  16
41e71b7053SJung-uk Kim #define SSL_ENC_AES256CCM8_IDX  17
42e71b7053SJung-uk Kim #define SSL_ENC_GOST8912_IDX    18
43e71b7053SJung-uk Kim #define SSL_ENC_CHACHA_IDX      19
44e71b7053SJung-uk Kim #define SSL_ENC_ARIA128GCM_IDX  20
45e71b7053SJung-uk Kim #define SSL_ENC_ARIA256GCM_IDX  21
46e71b7053SJung-uk Kim #define SSL_ENC_NUM_IDX         22
47ed5d4f9aSSimon L. B. Nielsen 
48e71b7053SJung-uk Kim /* NB: make sure indices in these tables match values above */
49e71b7053SJung-uk Kim 
50e71b7053SJung-uk Kim typedef struct {
51e71b7053SJung-uk Kim     uint32_t mask;
52e71b7053SJung-uk Kim     int nid;
53e71b7053SJung-uk Kim } ssl_cipher_table;
54e71b7053SJung-uk Kim 
55e71b7053SJung-uk Kim /* Table of NIDs for each cipher */
56e71b7053SJung-uk Kim static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
57e71b7053SJung-uk Kim     {SSL_DES, NID_des_cbc},     /* SSL_ENC_DES_IDX 0 */
58e71b7053SJung-uk Kim     {SSL_3DES, NID_des_ede3_cbc}, /* SSL_ENC_3DES_IDX 1 */
59e71b7053SJung-uk Kim     {SSL_RC4, NID_rc4},         /* SSL_ENC_RC4_IDX 2 */
60e71b7053SJung-uk Kim     {SSL_RC2, NID_rc2_cbc},     /* SSL_ENC_RC2_IDX 3 */
61e71b7053SJung-uk Kim     {SSL_IDEA, NID_idea_cbc},   /* SSL_ENC_IDEA_IDX 4 */
62e71b7053SJung-uk Kim     {SSL_eNULL, NID_undef},     /* SSL_ENC_NULL_IDX 5 */
63e71b7053SJung-uk Kim     {SSL_AES128, NID_aes_128_cbc}, /* SSL_ENC_AES128_IDX 6 */
64e71b7053SJung-uk Kim     {SSL_AES256, NID_aes_256_cbc}, /* SSL_ENC_AES256_IDX 7 */
65e71b7053SJung-uk Kim     {SSL_CAMELLIA128, NID_camellia_128_cbc}, /* SSL_ENC_CAMELLIA128_IDX 8 */
66e71b7053SJung-uk Kim     {SSL_CAMELLIA256, NID_camellia_256_cbc}, /* SSL_ENC_CAMELLIA256_IDX 9 */
67e71b7053SJung-uk Kim     {SSL_eGOST2814789CNT, NID_gost89_cnt}, /* SSL_ENC_GOST89_IDX 10 */
68e71b7053SJung-uk Kim     {SSL_SEED, NID_seed_cbc},   /* SSL_ENC_SEED_IDX 11 */
69e71b7053SJung-uk Kim     {SSL_AES128GCM, NID_aes_128_gcm}, /* SSL_ENC_AES128GCM_IDX 12 */
70e71b7053SJung-uk Kim     {SSL_AES256GCM, NID_aes_256_gcm}, /* SSL_ENC_AES256GCM_IDX 13 */
71e71b7053SJung-uk Kim     {SSL_AES128CCM, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM_IDX 14 */
72e71b7053SJung-uk Kim     {SSL_AES256CCM, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM_IDX 15 */
73e71b7053SJung-uk Kim     {SSL_AES128CCM8, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM8_IDX 16 */
74e71b7053SJung-uk Kim     {SSL_AES256CCM8, NID_aes_256_ccm}, /* SSL_ENC_AES256CCM8_IDX 17 */
75e71b7053SJung-uk Kim     {SSL_eGOST2814789CNT12, NID_gost89_cnt_12}, /* SSL_ENC_GOST8912_IDX 18 */
76e71b7053SJung-uk Kim     {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */
77e71b7053SJung-uk Kim     {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */
78e71b7053SJung-uk Kim     {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */
7974664626SKris Kennaway };
8074664626SKris Kennaway 
81e71b7053SJung-uk Kim static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
82e71b7053SJung-uk Kim 
833b4e3dcbSSimon L. B. Nielsen #define SSL_COMP_NULL_IDX       0
843b4e3dcbSSimon L. B. Nielsen #define SSL_COMP_ZLIB_IDX       1
853b4e3dcbSSimon L. B. Nielsen #define SSL_COMP_NUM_IDX        2
863b4e3dcbSSimon L. B. Nielsen 
8774664626SKris Kennaway static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
8874664626SKris Kennaway 
89e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
90e71b7053SJung-uk Kim static CRYPTO_ONCE ssl_load_builtin_comp_once = CRYPTO_ONCE_STATIC_INIT;
91e71b7053SJung-uk Kim #endif
92e71b7053SJung-uk Kim 
936f9291ceSJung-uk Kim /*
946f9291ceSJung-uk Kim  * Constant SSL_MAX_DIGEST equal to size of digests array should be defined
9517f01e99SJung-uk Kim  * in the ssl_local.h
966f9291ceSJung-uk Kim  */
97e71b7053SJung-uk Kim 
981f13597dSJung-uk Kim #define SSL_MD_NUM_IDX  SSL_MAX_DIGEST
99e71b7053SJung-uk Kim 
100e71b7053SJung-uk Kim /* NB: make sure indices in this table matches values above */
101e71b7053SJung-uk Kim static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = {
102e71b7053SJung-uk Kim     {SSL_MD5, NID_md5},         /* SSL_MD_MD5_IDX 0 */
103e71b7053SJung-uk Kim     {SSL_SHA1, NID_sha1},       /* SSL_MD_SHA1_IDX 1 */
104e71b7053SJung-uk Kim     {SSL_GOST94, NID_id_GostR3411_94}, /* SSL_MD_GOST94_IDX 2 */
105e71b7053SJung-uk Kim     {SSL_GOST89MAC, NID_id_Gost28147_89_MAC}, /* SSL_MD_GOST89MAC_IDX 3 */
106e71b7053SJung-uk Kim     {SSL_SHA256, NID_sha256},   /* SSL_MD_SHA256_IDX 4 */
107e71b7053SJung-uk Kim     {SSL_SHA384, NID_sha384},   /* SSL_MD_SHA384_IDX 5 */
108e71b7053SJung-uk Kim     {SSL_GOST12_256, NID_id_GostR3411_2012_256}, /* SSL_MD_GOST12_256_IDX 6 */
109e71b7053SJung-uk Kim     {SSL_GOST89MAC12, NID_gost_mac_12}, /* SSL_MD_GOST89MAC12_IDX 7 */
110e71b7053SJung-uk Kim     {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */
111e71b7053SJung-uk Kim     {0, NID_md5_sha1},          /* SSL_MD_MD5_SHA1_IDX 9 */
112e71b7053SJung-uk Kim     {0, NID_sha224},            /* SSL_MD_SHA224_IDX 10 */
113e71b7053SJung-uk Kim     {0, NID_sha512}             /* SSL_MD_SHA512_IDX 11 */
1141f13597dSJung-uk Kim };
1156f9291ceSJung-uk Kim 
116e71b7053SJung-uk Kim static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = {
117e71b7053SJung-uk Kim     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
118e71b7053SJung-uk Kim };
119e71b7053SJung-uk Kim 
120e71b7053SJung-uk Kim /* *INDENT-OFF* */
121e71b7053SJung-uk Kim static const ssl_cipher_table ssl_cipher_table_kx[] = {
122e71b7053SJung-uk Kim     {SSL_kRSA,      NID_kx_rsa},
123e71b7053SJung-uk Kim     {SSL_kECDHE,    NID_kx_ecdhe},
124e71b7053SJung-uk Kim     {SSL_kDHE,      NID_kx_dhe},
125e71b7053SJung-uk Kim     {SSL_kECDHEPSK, NID_kx_ecdhe_psk},
126e71b7053SJung-uk Kim     {SSL_kDHEPSK,   NID_kx_dhe_psk},
127e71b7053SJung-uk Kim     {SSL_kRSAPSK,   NID_kx_rsa_psk},
128e71b7053SJung-uk Kim     {SSL_kPSK,      NID_kx_psk},
129e71b7053SJung-uk Kim     {SSL_kSRP,      NID_kx_srp},
130e71b7053SJung-uk Kim     {SSL_kGOST,     NID_kx_gost},
131e71b7053SJung-uk Kim     {SSL_kANY,      NID_kx_any}
132e71b7053SJung-uk Kim };
133e71b7053SJung-uk Kim 
134e71b7053SJung-uk Kim static const ssl_cipher_table ssl_cipher_table_auth[] = {
135e71b7053SJung-uk Kim     {SSL_aRSA,    NID_auth_rsa},
136e71b7053SJung-uk Kim     {SSL_aECDSA,  NID_auth_ecdsa},
137e71b7053SJung-uk Kim     {SSL_aPSK,    NID_auth_psk},
138e71b7053SJung-uk Kim     {SSL_aDSS,    NID_auth_dss},
139e71b7053SJung-uk Kim     {SSL_aGOST01, NID_auth_gost01},
140e71b7053SJung-uk Kim     {SSL_aGOST12, NID_auth_gost12},
141e71b7053SJung-uk Kim     {SSL_aSRP,    NID_auth_srp},
142e71b7053SJung-uk Kim     {SSL_aNULL,   NID_auth_null},
143e71b7053SJung-uk Kim     {SSL_aANY,    NID_auth_any}
144e71b7053SJung-uk Kim };
145e71b7053SJung-uk Kim /* *INDENT-ON* */
146e71b7053SJung-uk Kim 
147e71b7053SJung-uk Kim /* Utility function for table lookup */
148e71b7053SJung-uk Kim static int ssl_cipher_info_find(const ssl_cipher_table * table,
149e71b7053SJung-uk Kim                                 size_t table_cnt, uint32_t mask)
150e71b7053SJung-uk Kim {
151e71b7053SJung-uk Kim     size_t i;
152e71b7053SJung-uk Kim     for (i = 0; i < table_cnt; i++, table++) {
153e71b7053SJung-uk Kim         if (table->mask == mask)
154e71b7053SJung-uk Kim             return (int)i;
155e71b7053SJung-uk Kim     }
156e71b7053SJung-uk Kim     return -1;
157e71b7053SJung-uk Kim }
158e71b7053SJung-uk Kim 
159e71b7053SJung-uk Kim #define ssl_cipher_info_lookup(table, x) \
160e71b7053SJung-uk Kim     ssl_cipher_info_find(table, OSSL_NELEM(table), x)
161e71b7053SJung-uk Kim 
1626f9291ceSJung-uk Kim /*
1636f9291ceSJung-uk Kim  * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation
1646f9291ceSJung-uk Kim  * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is
1656f9291ceSJung-uk Kim  * found
1661f13597dSJung-uk Kim  */
1671f13597dSJung-uk Kim static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = {
168e71b7053SJung-uk Kim     /* MD5, SHA, GOST94, MAC89 */
1691f13597dSJung-uk Kim     EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
170e71b7053SJung-uk Kim     /* SHA256, SHA384, GOST2012_256, MAC89-12 */
171e71b7053SJung-uk Kim     EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef,
172e71b7053SJung-uk Kim     /* GOST2012_512 */
173e71b7053SJung-uk Kim     EVP_PKEY_HMAC,
1746935a639SJung-uk Kim     /* MD5/SHA1, SHA224, SHA512 */
1756935a639SJung-uk Kim     NID_undef, NID_undef, NID_undef
1761f13597dSJung-uk Kim };
1771f13597dSJung-uk Kim 
178e71b7053SJung-uk Kim static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX];
17974664626SKris Kennaway 
18074664626SKris Kennaway #define CIPHER_ADD      1
18174664626SKris Kennaway #define CIPHER_KILL     2
18274664626SKris Kennaway #define CIPHER_DEL      3
18374664626SKris Kennaway #define CIPHER_ORD      4
184f579bf8eSKris Kennaway #define CIPHER_SPECIAL  5
185e71b7053SJung-uk Kim /*
186e71b7053SJung-uk Kim  * Bump the ciphers to the top of the list.
187e71b7053SJung-uk Kim  * This rule isn't currently supported by the public cipherstring API.
188e71b7053SJung-uk Kim  */
189e71b7053SJung-uk Kim #define CIPHER_BUMP     6
19074664626SKris Kennaway 
1916f9291ceSJung-uk Kim typedef struct cipher_order_st {
1921f13597dSJung-uk Kim     const SSL_CIPHER *cipher;
19374664626SKris Kennaway     int active;
19474664626SKris Kennaway     int dead;
19574664626SKris Kennaway     struct cipher_order_st *next, *prev;
19674664626SKris Kennaway } CIPHER_ORDER;
19774664626SKris Kennaway 
198f579bf8eSKris Kennaway static const SSL_CIPHER cipher_aliases[] = {
1991f13597dSJung-uk Kim     /* "ALL" doesn't include eNULL (must be specifically enabled) */
200e71b7053SJung-uk Kim     {0, SSL_TXT_ALL, NULL, 0, 0, 0, ~SSL_eNULL},
2011f13597dSJung-uk Kim     /* "COMPLEMENTOFALL" */
202e71b7053SJung-uk Kim     {0, SSL_TXT_CMPALL, NULL, 0, 0, 0, SSL_eNULL},
20374664626SKris Kennaway 
2046f9291ceSJung-uk Kim     /*
2056f9291ceSJung-uk Kim      * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in
2066f9291ceSJung-uk Kim      * ALL!)
2076f9291ceSJung-uk Kim      */
208e71b7053SJung-uk Kim     {0, SSL_TXT_CMPDEF, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT},
20974664626SKris Kennaway 
2106f9291ceSJung-uk Kim     /*
2116f9291ceSJung-uk Kim      * key exchange aliases (some of those using only a single bit here
212e71b7053SJung-uk Kim      * combine multiple key exchange algs according to the RFCs, e.g. kDHE
2136f9291ceSJung-uk Kim      * combines DHE_DSS and DHE_RSA)
2146f9291ceSJung-uk Kim      */
215e71b7053SJung-uk Kim     {0, SSL_TXT_kRSA, NULL, 0, SSL_kRSA},
21674664626SKris Kennaway 
217e71b7053SJung-uk Kim     {0, SSL_TXT_kEDH, NULL, 0, SSL_kDHE},
218e71b7053SJung-uk Kim     {0, SSL_TXT_kDHE, NULL, 0, SSL_kDHE},
219e71b7053SJung-uk Kim     {0, SSL_TXT_DH, NULL, 0, SSL_kDHE},
22074664626SKris Kennaway 
221e71b7053SJung-uk Kim     {0, SSL_TXT_kEECDH, NULL, 0, SSL_kECDHE},
222e71b7053SJung-uk Kim     {0, SSL_TXT_kECDHE, NULL, 0, SSL_kECDHE},
223e71b7053SJung-uk Kim     {0, SSL_TXT_ECDH, NULL, 0, SSL_kECDHE},
224f579bf8eSKris Kennaway 
225e71b7053SJung-uk Kim     {0, SSL_TXT_kPSK, NULL, 0, SSL_kPSK},
226e71b7053SJung-uk Kim     {0, SSL_TXT_kRSAPSK, NULL, 0, SSL_kRSAPSK},
227e71b7053SJung-uk Kim     {0, SSL_TXT_kECDHEPSK, NULL, 0, SSL_kECDHEPSK},
228e71b7053SJung-uk Kim     {0, SSL_TXT_kDHEPSK, NULL, 0, SSL_kDHEPSK},
229e71b7053SJung-uk Kim     {0, SSL_TXT_kSRP, NULL, 0, SSL_kSRP},
230e71b7053SJung-uk Kim     {0, SSL_TXT_kGOST, NULL, 0, SSL_kGOST},
2311f13597dSJung-uk Kim 
2321f13597dSJung-uk Kim     /* server authentication aliases */
233e71b7053SJung-uk Kim     {0, SSL_TXT_aRSA, NULL, 0, 0, SSL_aRSA},
234e71b7053SJung-uk Kim     {0, SSL_TXT_aDSS, NULL, 0, 0, SSL_aDSS},
235e71b7053SJung-uk Kim     {0, SSL_TXT_DSS, NULL, 0, 0, SSL_aDSS},
236e71b7053SJung-uk Kim     {0, SSL_TXT_aNULL, NULL, 0, 0, SSL_aNULL},
237e71b7053SJung-uk Kim     {0, SSL_TXT_aECDSA, NULL, 0, 0, SSL_aECDSA},
238e71b7053SJung-uk Kim     {0, SSL_TXT_ECDSA, NULL, 0, 0, SSL_aECDSA},
239e71b7053SJung-uk Kim     {0, SSL_TXT_aPSK, NULL, 0, 0, SSL_aPSK},
240e71b7053SJung-uk Kim     {0, SSL_TXT_aGOST01, NULL, 0, 0, SSL_aGOST01},
241e71b7053SJung-uk Kim     {0, SSL_TXT_aGOST12, NULL, 0, 0, SSL_aGOST12},
242e71b7053SJung-uk Kim     {0, SSL_TXT_aGOST, NULL, 0, 0, SSL_aGOST01 | SSL_aGOST12},
243e71b7053SJung-uk Kim     {0, SSL_TXT_aSRP, NULL, 0, 0, SSL_aSRP},
2441f13597dSJung-uk Kim 
2451f13597dSJung-uk Kim     /* aliases combining key exchange and server authentication */
246e71b7053SJung-uk Kim     {0, SSL_TXT_EDH, NULL, 0, SSL_kDHE, ~SSL_aNULL},
247e71b7053SJung-uk Kim     {0, SSL_TXT_DHE, NULL, 0, SSL_kDHE, ~SSL_aNULL},
248e71b7053SJung-uk Kim     {0, SSL_TXT_EECDH, NULL, 0, SSL_kECDHE, ~SSL_aNULL},
249e71b7053SJung-uk Kim     {0, SSL_TXT_ECDHE, NULL, 0, SSL_kECDHE, ~SSL_aNULL},
250e71b7053SJung-uk Kim     {0, SSL_TXT_NULL, NULL, 0, 0, 0, SSL_eNULL},
251e71b7053SJung-uk Kim     {0, SSL_TXT_RSA, NULL, 0, SSL_kRSA, SSL_aRSA},
252e71b7053SJung-uk Kim     {0, SSL_TXT_ADH, NULL, 0, SSL_kDHE, SSL_aNULL},
253e71b7053SJung-uk Kim     {0, SSL_TXT_AECDH, NULL, 0, SSL_kECDHE, SSL_aNULL},
254e71b7053SJung-uk Kim     {0, SSL_TXT_PSK, NULL, 0, SSL_PSK},
255e71b7053SJung-uk Kim     {0, SSL_TXT_SRP, NULL, 0, SSL_kSRP},
2561f13597dSJung-uk Kim 
2571f13597dSJung-uk Kim     /* symmetric encryption aliases */
258e71b7053SJung-uk Kim     {0, SSL_TXT_3DES, NULL, 0, 0, 0, SSL_3DES},
259e71b7053SJung-uk Kim     {0, SSL_TXT_RC4, NULL, 0, 0, 0, SSL_RC4},
260e71b7053SJung-uk Kim     {0, SSL_TXT_RC2, NULL, 0, 0, 0, SSL_RC2},
261e71b7053SJung-uk Kim     {0, SSL_TXT_IDEA, NULL, 0, 0, 0, SSL_IDEA},
262e71b7053SJung-uk Kim     {0, SSL_TXT_SEED, NULL, 0, 0, 0, SSL_SEED},
263e71b7053SJung-uk Kim     {0, SSL_TXT_eNULL, NULL, 0, 0, 0, SSL_eNULL},
264e71b7053SJung-uk Kim     {0, SSL_TXT_GOST, NULL, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12},
265e71b7053SJung-uk Kim     {0, SSL_TXT_AES128, NULL, 0, 0, 0,
266e71b7053SJung-uk Kim      SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8},
267e71b7053SJung-uk Kim     {0, SSL_TXT_AES256, NULL, 0, 0, 0,
268e71b7053SJung-uk Kim      SSL_AES256 | SSL_AES256GCM | SSL_AES256CCM | SSL_AES256CCM8},
269e71b7053SJung-uk Kim     {0, SSL_TXT_AES, NULL, 0, 0, 0, SSL_AES},
270e71b7053SJung-uk Kim     {0, SSL_TXT_AES_GCM, NULL, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM},
271e71b7053SJung-uk Kim     {0, SSL_TXT_AES_CCM, NULL, 0, 0, 0,
272e71b7053SJung-uk Kim      SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8},
273e71b7053SJung-uk Kim     {0, SSL_TXT_AES_CCM_8, NULL, 0, 0, 0, SSL_AES128CCM8 | SSL_AES256CCM8},
274e71b7053SJung-uk Kim     {0, SSL_TXT_CAMELLIA128, NULL, 0, 0, 0, SSL_CAMELLIA128},
275e71b7053SJung-uk Kim     {0, SSL_TXT_CAMELLIA256, NULL, 0, 0, 0, SSL_CAMELLIA256},
276e71b7053SJung-uk Kim     {0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA},
277e71b7053SJung-uk Kim     {0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20},
278e71b7053SJung-uk Kim 
279e71b7053SJung-uk Kim     {0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA},
280e71b7053SJung-uk Kim     {0, SSL_TXT_ARIA_GCM, NULL, 0, 0, 0, SSL_ARIA128GCM | SSL_ARIA256GCM},
281e71b7053SJung-uk Kim     {0, SSL_TXT_ARIA128, NULL, 0, 0, 0, SSL_ARIA128GCM},
282e71b7053SJung-uk Kim     {0, SSL_TXT_ARIA256, NULL, 0, 0, 0, SSL_ARIA256GCM},
2831f13597dSJung-uk Kim 
2841f13597dSJung-uk Kim     /* MAC aliases */
285e71b7053SJung-uk Kim     {0, SSL_TXT_MD5, NULL, 0, 0, 0, 0, SSL_MD5},
286e71b7053SJung-uk Kim     {0, SSL_TXT_SHA1, NULL, 0, 0, 0, 0, SSL_SHA1},
287e71b7053SJung-uk Kim     {0, SSL_TXT_SHA, NULL, 0, 0, 0, 0, SSL_SHA1},
288e71b7053SJung-uk Kim     {0, SSL_TXT_GOST94, NULL, 0, 0, 0, 0, SSL_GOST94},
289e71b7053SJung-uk Kim     {0, SSL_TXT_GOST89MAC, NULL, 0, 0, 0, 0, SSL_GOST89MAC | SSL_GOST89MAC12},
290e71b7053SJung-uk Kim     {0, SSL_TXT_SHA256, NULL, 0, 0, 0, 0, SSL_SHA256},
291e71b7053SJung-uk Kim     {0, SSL_TXT_SHA384, NULL, 0, 0, 0, 0, SSL_SHA384},
292e71b7053SJung-uk Kim     {0, SSL_TXT_GOST12, NULL, 0, 0, 0, 0, SSL_GOST12_256},
2931f13597dSJung-uk Kim 
2941f13597dSJung-uk Kim     /* protocol version aliases */
295e71b7053SJung-uk Kim     {0, SSL_TXT_SSLV3, NULL, 0, 0, 0, 0, 0, SSL3_VERSION},
296e71b7053SJung-uk Kim     {0, SSL_TXT_TLSV1, NULL, 0, 0, 0, 0, 0, TLS1_VERSION},
297e71b7053SJung-uk Kim     {0, "TLSv1.0", NULL, 0, 0, 0, 0, 0, TLS1_VERSION},
298e71b7053SJung-uk Kim     {0, SSL_TXT_TLSV1_2, NULL, 0, 0, 0, 0, 0, TLS1_2_VERSION},
2991f13597dSJung-uk Kim 
3001f13597dSJung-uk Kim     /* strength classes */
301e71b7053SJung-uk Kim     {0, SSL_TXT_LOW, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_LOW},
302e71b7053SJung-uk Kim     {0, SSL_TXT_MEDIUM, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_MEDIUM},
303e71b7053SJung-uk Kim     {0, SSL_TXT_HIGH, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, SSL_HIGH},
3041f13597dSJung-uk Kim     /* FIPS 140-2 approved ciphersuite */
305e71b7053SJung-uk Kim     {0, SSL_TXT_FIPS, NULL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, SSL_FIPS},
306e71b7053SJung-uk Kim 
307e71b7053SJung-uk Kim     /* "EDH-" aliases to "DHE-" labels (for backward compatibility) */
308e71b7053SJung-uk Kim     {0, SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, NULL, 0,
309e71b7053SJung-uk Kim      SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, 0, 0, 0, 0, SSL_HIGH | SSL_FIPS},
310e71b7053SJung-uk Kim     {0, SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, NULL, 0,
311e71b7053SJung-uk Kim      SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, 0, 0, 0, 0, SSL_HIGH | SSL_FIPS},
312e71b7053SJung-uk Kim 
31374664626SKris Kennaway };
3146f9291ceSJung-uk Kim 
3156f9291ceSJung-uk Kim /*
3166f9291ceSJung-uk Kim  * Search for public key algorithm with given name and return its pkey_id if
3176f9291ceSJung-uk Kim  * it is available. Otherwise return 0
3181f13597dSJung-uk Kim  */
3191f13597dSJung-uk Kim #ifdef OPENSSL_NO_ENGINE
3201f13597dSJung-uk Kim 
3211f13597dSJung-uk Kim static int get_optional_pkey_id(const char *pkey_name)
3221f13597dSJung-uk Kim {
3231f13597dSJung-uk Kim     const EVP_PKEY_ASN1_METHOD *ameth;
3241f13597dSJung-uk Kim     int pkey_id = 0;
3251f13597dSJung-uk Kim     ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1);
32680815a77SJung-uk Kim     if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
327e71b7053SJung-uk Kim                                          ameth) > 0)
3281f13597dSJung-uk Kim         return pkey_id;
32980815a77SJung-uk Kim     return 0;
33080815a77SJung-uk Kim }
3311f13597dSJung-uk Kim 
3321f13597dSJung-uk Kim #else
3331f13597dSJung-uk Kim 
3341f13597dSJung-uk Kim static int get_optional_pkey_id(const char *pkey_name)
3351f13597dSJung-uk Kim {
3361f13597dSJung-uk Kim     const EVP_PKEY_ASN1_METHOD *ameth;
3371f13597dSJung-uk Kim     ENGINE *tmpeng = NULL;
3381f13597dSJung-uk Kim     int pkey_id = 0;
3391f13597dSJung-uk Kim     ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1);
3406f9291ceSJung-uk Kim     if (ameth) {
34180815a77SJung-uk Kim         if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
34280815a77SJung-uk Kim                                     ameth) <= 0)
34380815a77SJung-uk Kim             pkey_id = 0;
3441f13597dSJung-uk Kim     }
3456f9291ceSJung-uk Kim     ENGINE_finish(tmpeng);
3461f13597dSJung-uk Kim     return pkey_id;
3471f13597dSJung-uk Kim }
3481f13597dSJung-uk Kim 
3491f13597dSJung-uk Kim #endif
35074664626SKris Kennaway 
351e71b7053SJung-uk Kim /* masks of disabled algorithms */
352e71b7053SJung-uk Kim static uint32_t disabled_enc_mask;
353e71b7053SJung-uk Kim static uint32_t disabled_mac_mask;
354e71b7053SJung-uk Kim static uint32_t disabled_mkey_mask;
355e71b7053SJung-uk Kim static uint32_t disabled_auth_mask;
356e71b7053SJung-uk Kim 
357e71b7053SJung-uk Kim int ssl_load_ciphers(void)
35874664626SKris Kennaway {
359e71b7053SJung-uk Kim     size_t i;
360e71b7053SJung-uk Kim     const ssl_cipher_table *t;
361e71b7053SJung-uk Kim 
362e71b7053SJung-uk Kim     disabled_enc_mask = 0;
363e71b7053SJung-uk Kim     ssl_sort_cipher_list();
364e71b7053SJung-uk Kim     for (i = 0, t = ssl_cipher_table_cipher; i < SSL_ENC_NUM_IDX; i++, t++) {
365e71b7053SJung-uk Kim         if (t->nid == NID_undef) {
366e71b7053SJung-uk Kim             ssl_cipher_methods[i] = NULL;
367e71b7053SJung-uk Kim         } else {
368e71b7053SJung-uk Kim             const EVP_CIPHER *cipher = EVP_get_cipherbynid(t->nid);
369e71b7053SJung-uk Kim             ssl_cipher_methods[i] = cipher;
370e71b7053SJung-uk Kim             if (cipher == NULL)
371e71b7053SJung-uk Kim                 disabled_enc_mask |= t->mask;
372e71b7053SJung-uk Kim         }
373e71b7053SJung-uk Kim     }
374e71b7053SJung-uk Kim     disabled_mac_mask = 0;
375e71b7053SJung-uk Kim     for (i = 0, t = ssl_cipher_table_mac; i < SSL_MD_NUM_IDX; i++, t++) {
376e71b7053SJung-uk Kim         const EVP_MD *md = EVP_get_digestbynid(t->nid);
377e71b7053SJung-uk Kim         ssl_digest_methods[i] = md;
378e71b7053SJung-uk Kim         if (md == NULL) {
379e71b7053SJung-uk Kim             disabled_mac_mask |= t->mask;
380e71b7053SJung-uk Kim         } else {
381e71b7053SJung-uk Kim             int tmpsize = EVP_MD_size(md);
382e71b7053SJung-uk Kim             if (!ossl_assert(tmpsize >= 0))
383e71b7053SJung-uk Kim                 return 0;
384e71b7053SJung-uk Kim             ssl_mac_secret_size[i] = tmpsize;
385e71b7053SJung-uk Kim         }
386e71b7053SJung-uk Kim     }
387e71b7053SJung-uk Kim     /* Make sure we can access MD5 and SHA1 */
388e71b7053SJung-uk Kim     if (!ossl_assert(ssl_digest_methods[SSL_MD_MD5_IDX] != NULL))
389e71b7053SJung-uk Kim         return 0;
390e71b7053SJung-uk Kim     if (!ossl_assert(ssl_digest_methods[SSL_MD_SHA1_IDX] != NULL))
391e71b7053SJung-uk Kim         return 0;
392e71b7053SJung-uk Kim 
393e71b7053SJung-uk Kim     disabled_mkey_mask = 0;
394e71b7053SJung-uk Kim     disabled_auth_mask = 0;
395e71b7053SJung-uk Kim 
396e71b7053SJung-uk Kim #ifdef OPENSSL_NO_RSA
397e71b7053SJung-uk Kim     disabled_mkey_mask |= SSL_kRSA | SSL_kRSAPSK;
398e71b7053SJung-uk Kim     disabled_auth_mask |= SSL_aRSA;
399ced566fdSJacques Vidrine #endif
400e71b7053SJung-uk Kim #ifdef OPENSSL_NO_DSA
401e71b7053SJung-uk Kim     disabled_auth_mask |= SSL_aDSS;
402e71b7053SJung-uk Kim #endif
403e71b7053SJung-uk Kim #ifdef OPENSSL_NO_DH
404e71b7053SJung-uk Kim     disabled_mkey_mask |= SSL_kDHE | SSL_kDHEPSK;
405e71b7053SJung-uk Kim #endif
406e71b7053SJung-uk Kim #ifdef OPENSSL_NO_EC
407e71b7053SJung-uk Kim     disabled_mkey_mask |= SSL_kECDHE | SSL_kECDHEPSK;
408e71b7053SJung-uk Kim     disabled_auth_mask |= SSL_aECDSA;
409e71b7053SJung-uk Kim #endif
410e71b7053SJung-uk Kim #ifdef OPENSSL_NO_PSK
411e71b7053SJung-uk Kim     disabled_mkey_mask |= SSL_PSK;
412e71b7053SJung-uk Kim     disabled_auth_mask |= SSL_aPSK;
413e71b7053SJung-uk Kim #endif
414e71b7053SJung-uk Kim #ifdef OPENSSL_NO_SRP
415e71b7053SJung-uk Kim     disabled_mkey_mask |= SSL_kSRP;
416e71b7053SJung-uk Kim #endif
41774664626SKris Kennaway 
418e71b7053SJung-uk Kim     /*
419e71b7053SJung-uk Kim      * Check for presence of GOST 34.10 algorithms, and if they are not
420e71b7053SJung-uk Kim      * present, disable appropriate auth and key exchange
421e71b7053SJung-uk Kim      */
4221f13597dSJung-uk Kim     ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac");
423e71b7053SJung-uk Kim     if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX])
4241f13597dSJung-uk Kim         ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32;
425e71b7053SJung-uk Kim     else
426e71b7053SJung-uk Kim         disabled_mac_mask |= SSL_GOST89MAC;
42774664626SKris Kennaway 
428e71b7053SJung-uk Kim     ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] =
429e71b7053SJung-uk Kim         get_optional_pkey_id("gost-mac-12");
430e71b7053SJung-uk Kim     if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX])
431e71b7053SJung-uk Kim         ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32;
432e71b7053SJung-uk Kim     else
433e71b7053SJung-uk Kim         disabled_mac_mask |= SSL_GOST89MAC12;
434e71b7053SJung-uk Kim 
435e71b7053SJung-uk Kim     if (!get_optional_pkey_id("gost2001"))
436e71b7053SJung-uk Kim         disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12;
437e71b7053SJung-uk Kim     if (!get_optional_pkey_id("gost2012_256"))
438e71b7053SJung-uk Kim         disabled_auth_mask |= SSL_aGOST12;
439e71b7053SJung-uk Kim     if (!get_optional_pkey_id("gost2012_512"))
440e71b7053SJung-uk Kim         disabled_auth_mask |= SSL_aGOST12;
441e71b7053SJung-uk Kim     /*
442e71b7053SJung-uk Kim      * Disable GOST key exchange if no GOST signature algs are available *
443e71b7053SJung-uk Kim      */
444e71b7053SJung-uk Kim     if ((disabled_auth_mask & (SSL_aGOST01 | SSL_aGOST12)) ==
445e71b7053SJung-uk Kim         (SSL_aGOST01 | SSL_aGOST12))
446e71b7053SJung-uk Kim         disabled_mkey_mask |= SSL_kGOST;
447e71b7053SJung-uk Kim 
448e71b7053SJung-uk Kim     return 1;
4491f13597dSJung-uk Kim }
4506f9291ceSJung-uk Kim 
4513b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
4523b4e3dcbSSimon L. B. Nielsen 
4536f9291ceSJung-uk Kim static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b)
4543b4e3dcbSSimon L. B. Nielsen {
4553b4e3dcbSSimon L. B. Nielsen     return ((*a)->id - (*b)->id);
4563b4e3dcbSSimon L. B. Nielsen }
4573b4e3dcbSSimon L. B. Nielsen 
458e71b7053SJung-uk Kim DEFINE_RUN_ONCE_STATIC(do_load_builtin_compressions)
4593b4e3dcbSSimon L. B. Nielsen {
4603b4e3dcbSSimon L. B. Nielsen     SSL_COMP *comp = NULL;
461e71b7053SJung-uk Kim     COMP_METHOD *method = COMP_zlib();
4623b4e3dcbSSimon L. B. Nielsen 
463e71b7053SJung-uk Kim     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
4643b4e3dcbSSimon L. B. Nielsen     ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp);
465e71b7053SJung-uk Kim 
466e71b7053SJung-uk Kim     if (COMP_get_type(method) != NID_undef && ssl_comp_methods != NULL) {
467e71b7053SJung-uk Kim         comp = OPENSSL_malloc(sizeof(*comp));
4686f9291ceSJung-uk Kim         if (comp != NULL) {
469e71b7053SJung-uk Kim             comp->method = method;
4703b4e3dcbSSimon L. B. Nielsen             comp->id = SSL_COMP_ZLIB_IDX;
471e71b7053SJung-uk Kim             comp->name = COMP_get_name(method);
4723b4e3dcbSSimon L. B. Nielsen             sk_SSL_COMP_push(ssl_comp_methods, comp);
47312de4ed2SJung-uk Kim             sk_SSL_COMP_sort(ssl_comp_methods);
4743b4e3dcbSSimon L. B. Nielsen         }
4753b4e3dcbSSimon L. B. Nielsen     }
476e71b7053SJung-uk Kim     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
477e71b7053SJung-uk Kim     return 1;
478ed5d4f9aSSimon L. B. Nielsen }
479ed5d4f9aSSimon L. B. Nielsen 
480e71b7053SJung-uk Kim static int load_builtin_compressions(void)
481e71b7053SJung-uk Kim {
482e71b7053SJung-uk Kim     return RUN_ONCE(&ssl_load_builtin_comp_once, do_load_builtin_compressions);
4833b4e3dcbSSimon L. B. Nielsen }
4843b4e3dcbSSimon L. B. Nielsen #endif
4853b4e3dcbSSimon L. B. Nielsen 
4863b4e3dcbSSimon L. B. Nielsen int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
4876f9291ceSJung-uk Kim                        const EVP_MD **md, int *mac_pkey_type,
488e71b7053SJung-uk Kim                        size_t *mac_secret_size, SSL_COMP **comp, int use_etm)
48974664626SKris Kennaway {
49074664626SKris Kennaway     int i;
4911f13597dSJung-uk Kim     const SSL_CIPHER *c;
49274664626SKris Kennaway 
49374664626SKris Kennaway     c = s->cipher;
4946f9291ceSJung-uk Kim     if (c == NULL)
495e71b7053SJung-uk Kim         return 0;
4966f9291ceSJung-uk Kim     if (comp != NULL) {
49774664626SKris Kennaway         SSL_COMP ctmp;
4983b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_COMP
499e71b7053SJung-uk Kim         if (!load_builtin_compressions()) {
500e71b7053SJung-uk Kim             /*
501e71b7053SJung-uk Kim              * Currently don't care, since a failure only means that
502e71b7053SJung-uk Kim              * ssl_comp_methods is NULL, which is perfectly OK
503e71b7053SJung-uk Kim              */
504e71b7053SJung-uk Kim         }
5053b4e3dcbSSimon L. B. Nielsen #endif
50674664626SKris Kennaway         *comp = NULL;
50774664626SKris Kennaway         ctmp.id = s->compress_meth;
5086f9291ceSJung-uk Kim         if (ssl_comp_methods != NULL) {
50974664626SKris Kennaway             i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp);
51074664626SKris Kennaway             *comp = sk_SSL_COMP_value(ssl_comp_methods, i);
51174664626SKris Kennaway         }
512e71b7053SJung-uk Kim         /* If were only interested in comp then return success */
513e71b7053SJung-uk Kim         if ((enc == NULL) && (md == NULL))
514e71b7053SJung-uk Kim             return 1;
51574664626SKris Kennaway     }
51674664626SKris Kennaway 
5176f9291ceSJung-uk Kim     if ((enc == NULL) || (md == NULL))
518e71b7053SJung-uk Kim         return 0;
51974664626SKris Kennaway 
520e71b7053SJung-uk Kim     i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc);
52174664626SKris Kennaway 
522e71b7053SJung-uk Kim     if (i == -1) {
52374664626SKris Kennaway         *enc = NULL;
524e71b7053SJung-uk Kim     } else {
52574664626SKris Kennaway         if (i == SSL_ENC_NULL_IDX)
52674664626SKris Kennaway             *enc = EVP_enc_null();
52774664626SKris Kennaway         else
52874664626SKris Kennaway             *enc = ssl_cipher_methods[i];
52974664626SKris Kennaway     }
53074664626SKris Kennaway 
531e71b7053SJung-uk Kim     i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
532e71b7053SJung-uk Kim     if (i == -1) {
53374664626SKris Kennaway         *md = NULL;
5346f9291ceSJung-uk Kim         if (mac_pkey_type != NULL)
5356f9291ceSJung-uk Kim             *mac_pkey_type = NID_undef;
5366f9291ceSJung-uk Kim         if (mac_secret_size != NULL)
5376f9291ceSJung-uk Kim             *mac_secret_size = 0;
5381f13597dSJung-uk Kim         if (c->algorithm_mac == SSL_AEAD)
5391f13597dSJung-uk Kim             mac_pkey_type = NULL;
5406f9291ceSJung-uk Kim     } else {
54174664626SKris Kennaway         *md = ssl_digest_methods[i];
5426f9291ceSJung-uk Kim         if (mac_pkey_type != NULL)
5436f9291ceSJung-uk Kim             *mac_pkey_type = ssl_mac_pkey_id[i];
5446f9291ceSJung-uk Kim         if (mac_secret_size != NULL)
5456f9291ceSJung-uk Kim             *mac_secret_size = ssl_mac_secret_size[i];
5461f13597dSJung-uk Kim     }
54774664626SKris Kennaway 
5481f13597dSJung-uk Kim     if ((*enc != NULL) &&
5496f9291ceSJung-uk Kim         (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER))
5506f9291ceSJung-uk Kim         && (!mac_pkey_type || *mac_pkey_type != NID_undef)) {
5511f13597dSJung-uk Kim         const EVP_CIPHER *evp;
5521f13597dSJung-uk Kim 
553e71b7053SJung-uk Kim         if (use_etm)
554e71b7053SJung-uk Kim             return 1;
555e71b7053SJung-uk Kim 
5561f13597dSJung-uk Kim         if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR ||
5571f13597dSJung-uk Kim             s->ssl_version < TLS1_VERSION)
5581f13597dSJung-uk Kim             return 1;
5591f13597dSJung-uk Kim 
5601f13597dSJung-uk Kim         if (c->algorithm_enc == SSL_RC4 &&
5611f13597dSJung-uk Kim             c->algorithm_mac == SSL_MD5 &&
5621f13597dSJung-uk Kim             (evp = EVP_get_cipherbyname("RC4-HMAC-MD5")))
5631f13597dSJung-uk Kim             *enc = evp, *md = NULL;
5641f13597dSJung-uk Kim         else if (c->algorithm_enc == SSL_AES128 &&
5651f13597dSJung-uk Kim                  c->algorithm_mac == SSL_SHA1 &&
5661f13597dSJung-uk Kim                  (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
5671f13597dSJung-uk Kim             *enc = evp, *md = NULL;
5681f13597dSJung-uk Kim         else if (c->algorithm_enc == SSL_AES256 &&
5691f13597dSJung-uk Kim                  c->algorithm_mac == SSL_SHA1 &&
5701f13597dSJung-uk Kim                  (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
5711f13597dSJung-uk Kim             *enc = evp, *md = NULL;
5727bded2dbSJung-uk Kim         else if (c->algorithm_enc == SSL_AES128 &&
5737bded2dbSJung-uk Kim                  c->algorithm_mac == SSL_SHA256 &&
5747bded2dbSJung-uk Kim                  (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256")))
5757bded2dbSJung-uk Kim             *enc = evp, *md = NULL;
5767bded2dbSJung-uk Kim         else if (c->algorithm_enc == SSL_AES256 &&
5777bded2dbSJung-uk Kim                  c->algorithm_mac == SSL_SHA256 &&
5787bded2dbSJung-uk Kim                  (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256")))
5797bded2dbSJung-uk Kim             *enc = evp, *md = NULL;
580e71b7053SJung-uk Kim         return 1;
581e71b7053SJung-uk Kim     } else {
5821f13597dSJung-uk Kim         return 0;
5831f13597dSJung-uk Kim     }
584e71b7053SJung-uk Kim }
585e71b7053SJung-uk Kim 
586e71b7053SJung-uk Kim const EVP_MD *ssl_md(int idx)
587e71b7053SJung-uk Kim {
588e71b7053SJung-uk Kim     idx &= SSL_HANDSHAKE_MAC_MASK;
589e71b7053SJung-uk Kim     if (idx < 0 || idx >= SSL_MD_NUM_IDX)
590e71b7053SJung-uk Kim         return NULL;
591e71b7053SJung-uk Kim     return ssl_digest_methods[idx];
592e71b7053SJung-uk Kim }
593e71b7053SJung-uk Kim 
594e71b7053SJung-uk Kim const EVP_MD *ssl_handshake_md(SSL *s)
595e71b7053SJung-uk Kim {
596e71b7053SJung-uk Kim     return ssl_md(ssl_get_algorithm2(s));
597e71b7053SJung-uk Kim }
598e71b7053SJung-uk Kim 
599e71b7053SJung-uk Kim const EVP_MD *ssl_prf_md(SSL *s)
600e71b7053SJung-uk Kim {
601e71b7053SJung-uk Kim     return ssl_md(ssl_get_algorithm2(s) >> TLS1_PRF_DGST_SHIFT);
6021f13597dSJung-uk Kim }
6031f13597dSJung-uk Kim 
60474664626SKris Kennaway #define ITEM_SEP(a) \
60574664626SKris Kennaway         (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
60674664626SKris Kennaway 
60774664626SKris Kennaway static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
60874664626SKris Kennaway                            CIPHER_ORDER **tail)
60974664626SKris Kennaway {
6106f9291ceSJung-uk Kim     if (curr == *tail)
6116f9291ceSJung-uk Kim         return;
61274664626SKris Kennaway     if (curr == *head)
61374664626SKris Kennaway         *head = curr->next;
61474664626SKris Kennaway     if (curr->prev != NULL)
61574664626SKris Kennaway         curr->prev->next = curr->next;
6161f13597dSJung-uk Kim     if (curr->next != NULL)
61774664626SKris Kennaway         curr->next->prev = curr->prev;
61874664626SKris Kennaway     (*tail)->next = curr;
61974664626SKris Kennaway     curr->prev = *tail;
62074664626SKris Kennaway     curr->next = NULL;
62174664626SKris Kennaway     *tail = curr;
62274664626SKris Kennaway }
62374664626SKris Kennaway 
6241f13597dSJung-uk Kim static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
6251f13597dSJung-uk Kim                            CIPHER_ORDER **tail)
62674664626SKris Kennaway {
6276f9291ceSJung-uk Kim     if (curr == *head)
6286f9291ceSJung-uk Kim         return;
6291f13597dSJung-uk Kim     if (curr == *tail)
6301f13597dSJung-uk Kim         *tail = curr->prev;
6311f13597dSJung-uk Kim     if (curr->next != NULL)
6321f13597dSJung-uk Kim         curr->next->prev = curr->prev;
6331f13597dSJung-uk Kim     if (curr->prev != NULL)
6341f13597dSJung-uk Kim         curr->prev->next = curr->next;
6351f13597dSJung-uk Kim     (*head)->prev = curr;
6361f13597dSJung-uk Kim     curr->next = *head;
6371f13597dSJung-uk Kim     curr->prev = NULL;
6381f13597dSJung-uk Kim     *head = curr;
6391f13597dSJung-uk Kim }
64074664626SKris Kennaway 
641f579bf8eSKris Kennaway static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
6421f13597dSJung-uk Kim                                        int num_of_ciphers,
643e71b7053SJung-uk Kim                                        uint32_t disabled_mkey,
644e71b7053SJung-uk Kim                                        uint32_t disabled_auth,
645e71b7053SJung-uk Kim                                        uint32_t disabled_enc,
646e71b7053SJung-uk Kim                                        uint32_t disabled_mac,
6471f13597dSJung-uk Kim                                        CIPHER_ORDER *co_list,
6486f9291ceSJung-uk Kim                                        CIPHER_ORDER **head_p,
6496f9291ceSJung-uk Kim                                        CIPHER_ORDER **tail_p)
650f579bf8eSKris Kennaway {
651ced566fdSJacques Vidrine     int i, co_list_num;
6521f13597dSJung-uk Kim     const SSL_CIPHER *c;
653f579bf8eSKris Kennaway 
654f579bf8eSKris Kennaway     /*
655f579bf8eSKris Kennaway      * We have num_of_ciphers descriptions compiled in, depending on the
656e71b7053SJung-uk Kim      * method selected (SSLv3, TLSv1 etc).
657f579bf8eSKris Kennaway      * These will later be sorted in a linked list with at most num
658f579bf8eSKris Kennaway      * entries.
659f579bf8eSKris Kennaway      */
66074664626SKris Kennaway 
66174664626SKris Kennaway     /* Get the initial list of ciphers */
662ced566fdSJacques Vidrine     co_list_num = 0;            /* actual count of ciphers */
6636f9291ceSJung-uk Kim     for (i = 0; i < num_of_ciphers; i++) {
664f579bf8eSKris Kennaway         c = ssl_method->get_cipher(i);
66574664626SKris Kennaway         /* drop those that use any of that is not available */
666e71b7053SJung-uk Kim         if (c == NULL || !c->valid)
667e71b7053SJung-uk Kim             continue;
668e71b7053SJung-uk Kim         if ((c->algorithm_mkey & disabled_mkey) ||
669e71b7053SJung-uk Kim             (c->algorithm_auth & disabled_auth) ||
670e71b7053SJung-uk Kim             (c->algorithm_enc & disabled_enc) ||
671e71b7053SJung-uk Kim             (c->algorithm_mac & disabled_mac))
672e71b7053SJung-uk Kim             continue;
673e71b7053SJung-uk Kim         if (((ssl_method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) == 0) &&
674e71b7053SJung-uk Kim             c->min_tls == 0)
675e71b7053SJung-uk Kim             continue;
676e71b7053SJung-uk Kim         if (((ssl_method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0) &&
677e71b7053SJung-uk Kim             c->min_dtls == 0)
678e71b7053SJung-uk Kim             continue;
679e71b7053SJung-uk Kim 
680ced566fdSJacques Vidrine         co_list[co_list_num].cipher = c;
681ced566fdSJacques Vidrine         co_list[co_list_num].next = NULL;
682ced566fdSJacques Vidrine         co_list[co_list_num].prev = NULL;
683ced566fdSJacques Vidrine         co_list[co_list_num].active = 0;
684ced566fdSJacques Vidrine         co_list_num++;
68574664626SKris Kennaway     }
68674664626SKris Kennaway 
687f579bf8eSKris Kennaway     /*
688f579bf8eSKris Kennaway      * Prepare linked list from list entries
689f579bf8eSKris Kennaway      */
6906f9291ceSJung-uk Kim     if (co_list_num > 0) {
6911f13597dSJung-uk Kim         co_list[0].prev = NULL;
6921f13597dSJung-uk Kim 
6936f9291ceSJung-uk Kim         if (co_list_num > 1) {
6941f13597dSJung-uk Kim             co_list[0].next = &co_list[1];
6951f13597dSJung-uk Kim 
6966f9291ceSJung-uk Kim             for (i = 1; i < co_list_num - 1; i++) {
6971f13597dSJung-uk Kim                 co_list[i].prev = &co_list[i - 1];
6981f13597dSJung-uk Kim                 co_list[i].next = &co_list[i + 1];
6991f13597dSJung-uk Kim             }
7001f13597dSJung-uk Kim 
7011f13597dSJung-uk Kim             co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
7021f13597dSJung-uk Kim         }
7031f13597dSJung-uk Kim 
7041f13597dSJung-uk Kim         co_list[co_list_num - 1].next = NULL;
7051f13597dSJung-uk Kim 
7061f13597dSJung-uk Kim         *head_p = &co_list[0];
7071f13597dSJung-uk Kim         *tail_p = &co_list[co_list_num - 1];
708f579bf8eSKris Kennaway     }
70974664626SKris Kennaway }
71074664626SKris Kennaway 
7111f13597dSJung-uk Kim static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
7121f13597dSJung-uk Kim                                        int num_of_group_aliases,
713e71b7053SJung-uk Kim                                        uint32_t disabled_mkey,
714e71b7053SJung-uk Kim                                        uint32_t disabled_auth,
715e71b7053SJung-uk Kim                                        uint32_t disabled_enc,
716e71b7053SJung-uk Kim                                        uint32_t disabled_mac,
717f579bf8eSKris Kennaway                                        CIPHER_ORDER *head)
71874664626SKris Kennaway {
719f579bf8eSKris Kennaway     CIPHER_ORDER *ciph_curr;
7201f13597dSJung-uk Kim     const SSL_CIPHER **ca_curr;
721f579bf8eSKris Kennaway     int i;
722e71b7053SJung-uk Kim     uint32_t mask_mkey = ~disabled_mkey;
723e71b7053SJung-uk Kim     uint32_t mask_auth = ~disabled_auth;
724e71b7053SJung-uk Kim     uint32_t mask_enc = ~disabled_enc;
725e71b7053SJung-uk Kim     uint32_t mask_mac = ~disabled_mac;
726f579bf8eSKris Kennaway 
727f579bf8eSKris Kennaway     /*
728f579bf8eSKris Kennaway      * First, add the real ciphers as already collected
729f579bf8eSKris Kennaway      */
730f579bf8eSKris Kennaway     ciph_curr = head;
731f579bf8eSKris Kennaway     ca_curr = ca_list;
7326f9291ceSJung-uk Kim     while (ciph_curr != NULL) {
733f579bf8eSKris Kennaway         *ca_curr = ciph_curr->cipher;
734f579bf8eSKris Kennaway         ca_curr++;
735f579bf8eSKris Kennaway         ciph_curr = ciph_curr->next;
73674664626SKris Kennaway     }
73774664626SKris Kennaway 
738f579bf8eSKris Kennaway     /*
739f579bf8eSKris Kennaway      * Now we add the available ones from the cipher_aliases[] table.
7401f13597dSJung-uk Kim      * They represent either one or more algorithms, some of which
7411f13597dSJung-uk Kim      * in any affected category must be supported (set in enabled_mask),
7421f13597dSJung-uk Kim      * or represent a cipher strength value (will be added in any case because algorithms=0).
743f579bf8eSKris Kennaway      */
7446f9291ceSJung-uk Kim     for (i = 0; i < num_of_group_aliases; i++) {
745e71b7053SJung-uk Kim         uint32_t algorithm_mkey = cipher_aliases[i].algorithm_mkey;
746e71b7053SJung-uk Kim         uint32_t algorithm_auth = cipher_aliases[i].algorithm_auth;
747e71b7053SJung-uk Kim         uint32_t algorithm_enc = cipher_aliases[i].algorithm_enc;
748e71b7053SJung-uk Kim         uint32_t algorithm_mac = cipher_aliases[i].algorithm_mac;
7491f13597dSJung-uk Kim 
7501f13597dSJung-uk Kim         if (algorithm_mkey)
7511f13597dSJung-uk Kim             if ((algorithm_mkey & mask_mkey) == 0)
7521f13597dSJung-uk Kim                 continue;
7531f13597dSJung-uk Kim 
7541f13597dSJung-uk Kim         if (algorithm_auth)
7551f13597dSJung-uk Kim             if ((algorithm_auth & mask_auth) == 0)
7561f13597dSJung-uk Kim                 continue;
7571f13597dSJung-uk Kim 
7581f13597dSJung-uk Kim         if (algorithm_enc)
7591f13597dSJung-uk Kim             if ((algorithm_enc & mask_enc) == 0)
7601f13597dSJung-uk Kim                 continue;
7611f13597dSJung-uk Kim 
7621f13597dSJung-uk Kim         if (algorithm_mac)
7631f13597dSJung-uk Kim             if ((algorithm_mac & mask_mac) == 0)
7641f13597dSJung-uk Kim                 continue;
7651f13597dSJung-uk Kim 
766f579bf8eSKris Kennaway         *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
767f579bf8eSKris Kennaway         ca_curr++;
76874664626SKris Kennaway     }
76974664626SKris Kennaway 
770f579bf8eSKris Kennaway     *ca_curr = NULL;            /* end of list */
771f579bf8eSKris Kennaway }
772f579bf8eSKris Kennaway 
773e71b7053SJung-uk Kim static void ssl_cipher_apply_rule(uint32_t cipher_id, uint32_t alg_mkey,
774e71b7053SJung-uk Kim                                   uint32_t alg_auth, uint32_t alg_enc,
775e71b7053SJung-uk Kim                                   uint32_t alg_mac, int min_tls,
776e71b7053SJung-uk Kim                                   uint32_t algo_strength, int rule,
777e71b7053SJung-uk Kim                                   int32_t strength_bits, CIPHER_ORDER **head_p,
7786f9291ceSJung-uk Kim                                   CIPHER_ORDER **tail_p)
77974664626SKris Kennaway {
780a93cbc2bSJung-uk Kim     CIPHER_ORDER *head, *tail, *curr, *next, *last;
7811f13597dSJung-uk Kim     const SSL_CIPHER *cp;
7821f13597dSJung-uk Kim     int reverse = 0;
783f579bf8eSKris Kennaway 
784f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG
7856f9291ceSJung-uk Kim     fprintf(stderr,
786e71b7053SJung-uk Kim             "Applying rule %d with %08x/%08x/%08x/%08x/%08x %08x (%d)\n",
787e71b7053SJung-uk Kim             rule, alg_mkey, alg_auth, alg_enc, alg_mac, min_tls,
7886f9291ceSJung-uk Kim             algo_strength, strength_bits);
78974664626SKris Kennaway #endif
79074664626SKris Kennaway 
791e71b7053SJung-uk Kim     if (rule == CIPHER_DEL || rule == CIPHER_BUMP)
792e71b7053SJung-uk Kim         reverse = 1;            /* needed to maintain sorting between currently
793e71b7053SJung-uk Kim                                  * deleted ciphers */
7941f13597dSJung-uk Kim 
7951f13597dSJung-uk Kim     head = *head_p;
7961f13597dSJung-uk Kim     tail = *tail_p;
7971f13597dSJung-uk Kim 
7986f9291ceSJung-uk Kim     if (reverse) {
799a93cbc2bSJung-uk Kim         next = tail;
8001f13597dSJung-uk Kim         last = head;
8016f9291ceSJung-uk Kim     } else {
802a93cbc2bSJung-uk Kim         next = head;
8031f13597dSJung-uk Kim         last = tail;
8041f13597dSJung-uk Kim     }
8051f13597dSJung-uk Kim 
806a93cbc2bSJung-uk Kim     curr = NULL;
8076f9291ceSJung-uk Kim     for (;;) {
8086f9291ceSJung-uk Kim         if (curr == last)
8096f9291ceSJung-uk Kim             break;
810a93cbc2bSJung-uk Kim 
811a93cbc2bSJung-uk Kim         curr = next;
812a93cbc2bSJung-uk Kim 
8136f9291ceSJung-uk Kim         if (curr == NULL)
8146f9291ceSJung-uk Kim             break;
815a93cbc2bSJung-uk Kim 
816a93cbc2bSJung-uk Kim         next = reverse ? curr->prev : curr->next;
81774664626SKris Kennaway 
81874664626SKris Kennaway         cp = curr->cipher;
819f579bf8eSKris Kennaway 
8201f13597dSJung-uk Kim         /*
8211f13597dSJung-uk Kim          * Selection criteria is either the value of strength_bits
8221f13597dSJung-uk Kim          * or the algorithms used.
8231f13597dSJung-uk Kim          */
8246f9291ceSJung-uk Kim         if (strength_bits >= 0) {
8251f13597dSJung-uk Kim             if (strength_bits != cp->strength_bits)
8263b4e3dcbSSimon L. B. Nielsen                 continue;
8276f9291ceSJung-uk Kim         } else {
828f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG
8296f9291ceSJung-uk Kim             fprintf(stderr,
830e71b7053SJung-uk Kim                     "\nName: %s:\nAlgo = %08x/%08x/%08x/%08x/%08x Algo_strength = %08x\n",
8316f9291ceSJung-uk Kim                     cp->name, cp->algorithm_mkey, cp->algorithm_auth,
832e71b7053SJung-uk Kim                     cp->algorithm_enc, cp->algorithm_mac, cp->min_tls,
8336f9291ceSJung-uk Kim                     cp->algo_strength);
834f579bf8eSKris Kennaway #endif
835e71b7053SJung-uk Kim             if (cipher_id != 0 && (cipher_id != cp->id))
8367bded2dbSJung-uk Kim                 continue;
8371f13597dSJung-uk Kim             if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
8381f13597dSJung-uk Kim                 continue;
8391f13597dSJung-uk Kim             if (alg_auth && !(alg_auth & cp->algorithm_auth))
8401f13597dSJung-uk Kim                 continue;
8411f13597dSJung-uk Kim             if (alg_enc && !(alg_enc & cp->algorithm_enc))
8421f13597dSJung-uk Kim                 continue;
8431f13597dSJung-uk Kim             if (alg_mac && !(alg_mac & cp->algorithm_mac))
8441f13597dSJung-uk Kim                 continue;
845e71b7053SJung-uk Kim             if (min_tls && (min_tls != cp->min_tls))
8461f13597dSJung-uk Kim                 continue;
8476f9291ceSJung-uk Kim             if ((algo_strength & SSL_STRONG_MASK)
8486f9291ceSJung-uk Kim                 && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
8491f13597dSJung-uk Kim                 continue;
850e71b7053SJung-uk Kim             if ((algo_strength & SSL_DEFAULT_MASK)
851e71b7053SJung-uk Kim                 && !(algo_strength & SSL_DEFAULT_MASK & cp->algo_strength))
852b8721c16SJung-uk Kim                 continue;
85374664626SKris Kennaway         }
854f579bf8eSKris Kennaway 
855f579bf8eSKris Kennaway #ifdef CIPHER_DEBUG
856751d2991SJung-uk Kim         fprintf(stderr, "Action = %d\n", rule);
857f579bf8eSKris Kennaway #endif
85874664626SKris Kennaway 
85974664626SKris Kennaway         /* add the cipher if it has not been added yet. */
8606f9291ceSJung-uk Kim         if (rule == CIPHER_ADD) {
8611f13597dSJung-uk Kim             /* reverse == 0 */
8626f9291ceSJung-uk Kim             if (!curr->active) {
86374664626SKris Kennaway                 ll_append_tail(&head, curr, &tail);
86474664626SKris Kennaway                 curr->active = 1;
86574664626SKris Kennaway             }
86674664626SKris Kennaway         }
86774664626SKris Kennaway         /* Move the added cipher to this location */
8686f9291ceSJung-uk Kim         else if (rule == CIPHER_ORD) {
8691f13597dSJung-uk Kim             /* reverse == 0 */
8706f9291ceSJung-uk Kim             if (curr->active) {
87174664626SKris Kennaway                 ll_append_tail(&head, curr, &tail);
87274664626SKris Kennaway             }
8736f9291ceSJung-uk Kim         } else if (rule == CIPHER_DEL) {
8741f13597dSJung-uk Kim             /* reverse == 1 */
8756f9291ceSJung-uk Kim             if (curr->active) {
8766f9291ceSJung-uk Kim                 /*
8776f9291ceSJung-uk Kim                  * most recently deleted ciphersuites get best positions for
8786f9291ceSJung-uk Kim                  * any future CIPHER_ADD (note that the CIPHER_DEL loop works
8796f9291ceSJung-uk Kim                  * in reverse to maintain the order)
8806f9291ceSJung-uk Kim                  */
8811f13597dSJung-uk Kim                 ll_append_head(&head, curr, &tail);
88274664626SKris Kennaway                 curr->active = 0;
8831f13597dSJung-uk Kim             }
884e71b7053SJung-uk Kim         } else if (rule == CIPHER_BUMP) {
885e71b7053SJung-uk Kim             if (curr->active)
886e71b7053SJung-uk Kim                 ll_append_head(&head, curr, &tail);
8876f9291ceSJung-uk Kim         } else if (rule == CIPHER_KILL) {
8881f13597dSJung-uk Kim             /* reverse == 0 */
88974664626SKris Kennaway             if (head == curr)
89074664626SKris Kennaway                 head = curr->next;
89174664626SKris Kennaway             else
89274664626SKris Kennaway                 curr->prev->next = curr->next;
89374664626SKris Kennaway             if (tail == curr)
89474664626SKris Kennaway                 tail = curr->prev;
89574664626SKris Kennaway             curr->active = 0;
89674664626SKris Kennaway             if (curr->next != NULL)
89774664626SKris Kennaway                 curr->next->prev = curr->prev;
89874664626SKris Kennaway             if (curr->prev != NULL)
89974664626SKris Kennaway                 curr->prev->next = curr->next;
90074664626SKris Kennaway             curr->next = NULL;
90174664626SKris Kennaway             curr->prev = NULL;
90274664626SKris Kennaway         }
90374664626SKris Kennaway     }
904f579bf8eSKris Kennaway 
905f579bf8eSKris Kennaway     *head_p = head;
906f579bf8eSKris Kennaway     *tail_p = tail;
90774664626SKris Kennaway }
90874664626SKris Kennaway 
9091f13597dSJung-uk Kim static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
910f579bf8eSKris Kennaway                                     CIPHER_ORDER **tail_p)
911f579bf8eSKris Kennaway {
912e71b7053SJung-uk Kim     int32_t max_strength_bits;
913e71b7053SJung-uk Kim     int i, *number_uses;
914f579bf8eSKris Kennaway     CIPHER_ORDER *curr;
915f579bf8eSKris Kennaway 
916f579bf8eSKris Kennaway     /*
917f579bf8eSKris Kennaway      * This routine sorts the ciphers with descending strength. The sorting
918f579bf8eSKris Kennaway      * must keep the pre-sorted sequence, so we apply the normal sorting
919f579bf8eSKris Kennaway      * routine as '+' movement to the end of the list.
920f579bf8eSKris Kennaway      */
921f579bf8eSKris Kennaway     max_strength_bits = 0;
922f579bf8eSKris Kennaway     curr = *head_p;
9236f9291ceSJung-uk Kim     while (curr != NULL) {
9246f9291ceSJung-uk Kim         if (curr->active && (curr->cipher->strength_bits > max_strength_bits))
925f579bf8eSKris Kennaway             max_strength_bits = curr->cipher->strength_bits;
926f579bf8eSKris Kennaway         curr = curr->next;
927f579bf8eSKris Kennaway     }
928f579bf8eSKris Kennaway 
929e71b7053SJung-uk Kim     number_uses = OPENSSL_zalloc(sizeof(int) * (max_strength_bits + 1));
930e71b7053SJung-uk Kim     if (number_uses == NULL) {
931f579bf8eSKris Kennaway         SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE);
932e71b7053SJung-uk Kim         return 0;
933f579bf8eSKris Kennaway     }
934f579bf8eSKris Kennaway 
935f579bf8eSKris Kennaway     /*
936f579bf8eSKris Kennaway      * Now find the strength_bits values actually used
937f579bf8eSKris Kennaway      */
938f579bf8eSKris Kennaway     curr = *head_p;
9396f9291ceSJung-uk Kim     while (curr != NULL) {
940f579bf8eSKris Kennaway         if (curr->active)
941f579bf8eSKris Kennaway             number_uses[curr->cipher->strength_bits]++;
942f579bf8eSKris Kennaway         curr = curr->next;
943f579bf8eSKris Kennaway     }
944f579bf8eSKris Kennaway     /*
945f579bf8eSKris Kennaway      * Go through the list of used strength_bits values in descending
946f579bf8eSKris Kennaway      * order.
947f579bf8eSKris Kennaway      */
948f579bf8eSKris Kennaway     for (i = max_strength_bits; i >= 0; i--)
949f579bf8eSKris Kennaway         if (number_uses[i] > 0)
9506f9291ceSJung-uk Kim             ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p,
9516f9291ceSJung-uk Kim                                   tail_p);
952f579bf8eSKris Kennaway 
953ddd58736SKris Kennaway     OPENSSL_free(number_uses);
954e71b7053SJung-uk Kim     return 1;
955f579bf8eSKris Kennaway }
956f579bf8eSKris Kennaway 
957f579bf8eSKris Kennaway static int ssl_cipher_process_rulestr(const char *rule_str,
9586f9291ceSJung-uk Kim                                       CIPHER_ORDER **head_p,
9596f9291ceSJung-uk Kim                                       CIPHER_ORDER **tail_p,
960e71b7053SJung-uk Kim                                       const SSL_CIPHER **ca_list, CERT *c)
961f579bf8eSKris Kennaway {
962e71b7053SJung-uk Kim     uint32_t alg_mkey, alg_auth, alg_enc, alg_mac, algo_strength;
963e71b7053SJung-uk Kim     int min_tls;
964a3ddd25aSSimon L. B. Nielsen     const char *l, *buf;
965f579bf8eSKris Kennaway     int j, multi, found, rule, retval, ok, buflen;
966e71b7053SJung-uk Kim     uint32_t cipher_id = 0;
967f579bf8eSKris Kennaway     char ch;
968f579bf8eSKris Kennaway 
969f579bf8eSKris Kennaway     retval = 1;
970f579bf8eSKris Kennaway     l = rule_str;
9716f9291ceSJung-uk Kim     for ( ; ; ) {
972f579bf8eSKris Kennaway         ch = *l;
973f579bf8eSKris Kennaway 
974f579bf8eSKris Kennaway         if (ch == '\0')
975f579bf8eSKris Kennaway             break;              /* done */
9766f9291ceSJung-uk Kim         if (ch == '-') {
9776f9291ceSJung-uk Kim             rule = CIPHER_DEL;
9786f9291ceSJung-uk Kim             l++;
9796f9291ceSJung-uk Kim         } else if (ch == '+') {
9806f9291ceSJung-uk Kim             rule = CIPHER_ORD;
9816f9291ceSJung-uk Kim             l++;
9826f9291ceSJung-uk Kim         } else if (ch == '!') {
9836f9291ceSJung-uk Kim             rule = CIPHER_KILL;
9846f9291ceSJung-uk Kim             l++;
9856f9291ceSJung-uk Kim         } else if (ch == '@') {
9866f9291ceSJung-uk Kim             rule = CIPHER_SPECIAL;
9876f9291ceSJung-uk Kim             l++;
9886f9291ceSJung-uk Kim         } else {
9896f9291ceSJung-uk Kim             rule = CIPHER_ADD;
9906f9291ceSJung-uk Kim         }
991f579bf8eSKris Kennaway 
9926f9291ceSJung-uk Kim         if (ITEM_SEP(ch)) {
993f579bf8eSKris Kennaway             l++;
994f579bf8eSKris Kennaway             continue;
995f579bf8eSKris Kennaway         }
996f579bf8eSKris Kennaway 
9971f13597dSJung-uk Kim         alg_mkey = 0;
9981f13597dSJung-uk Kim         alg_auth = 0;
9991f13597dSJung-uk Kim         alg_enc = 0;
10001f13597dSJung-uk Kim         alg_mac = 0;
1001e71b7053SJung-uk Kim         min_tls = 0;
10021f13597dSJung-uk Kim         algo_strength = 0;
1003f579bf8eSKris Kennaway 
10046f9291ceSJung-uk Kim         for (;;) {
1005f579bf8eSKris Kennaway             ch = *l;
1006f579bf8eSKris Kennaway             buf = l;
1007f579bf8eSKris Kennaway             buflen = 0;
1008f579bf8eSKris Kennaway #ifndef CHARSET_EBCDIC
1009f579bf8eSKris Kennaway             while (((ch >= 'A') && (ch <= 'Z')) ||
1010f579bf8eSKris Kennaway                    ((ch >= '0') && (ch <= '9')) ||
1011e71b7053SJung-uk Kim                    ((ch >= 'a') && (ch <= 'z')) ||
1012e71b7053SJung-uk Kim                    (ch == '-') || (ch == '.') || (ch == '='))
1013f579bf8eSKris Kennaway #else
1014e71b7053SJung-uk Kim             while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.')
1015e71b7053SJung-uk Kim                    || (ch == '='))
1016f579bf8eSKris Kennaway #endif
1017f579bf8eSKris Kennaway             {
1018f579bf8eSKris Kennaway                 ch = *(++l);
1019f579bf8eSKris Kennaway                 buflen++;
1020f579bf8eSKris Kennaway             }
1021f579bf8eSKris Kennaway 
10226f9291ceSJung-uk Kim             if (buflen == 0) {
1023f579bf8eSKris Kennaway                 /*
1024f579bf8eSKris Kennaway                  * We hit something we cannot deal with,
1025f579bf8eSKris Kennaway                  * it is no command or separator nor
1026f579bf8eSKris Kennaway                  * alphanumeric, so we call this an error.
1027f579bf8eSKris Kennaway                  */
1028e71b7053SJung-uk Kim                 SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
1029f579bf8eSKris Kennaway                 retval = found = 0;
1030f579bf8eSKris Kennaway                 l++;
1031f579bf8eSKris Kennaway                 break;
1032f579bf8eSKris Kennaway             }
1033f579bf8eSKris Kennaway 
10346f9291ceSJung-uk Kim             if (rule == CIPHER_SPECIAL) {
1035f579bf8eSKris Kennaway                 found = 0;      /* unused -- avoid compiler warning */
1036f579bf8eSKris Kennaway                 break;          /* special treatment */
1037f579bf8eSKris Kennaway             }
1038f579bf8eSKris Kennaway 
1039f579bf8eSKris Kennaway             /* check for multi-part specification */
10406f9291ceSJung-uk Kim             if (ch == '+') {
1041f579bf8eSKris Kennaway                 multi = 1;
1042f579bf8eSKris Kennaway                 l++;
1043e71b7053SJung-uk Kim             } else {
1044f579bf8eSKris Kennaway                 multi = 0;
1045e71b7053SJung-uk Kim             }
1046f579bf8eSKris Kennaway 
1047f579bf8eSKris Kennaway             /*
1048f579bf8eSKris Kennaway              * Now search for the cipher alias in the ca_list. Be careful
1049f579bf8eSKris Kennaway              * with the strncmp, because the "buflen" limitation
1050f579bf8eSKris Kennaway              * will make the rule "ADH:SOME" and the cipher
1051f579bf8eSKris Kennaway              * "ADH-MY-CIPHER" look like a match for buflen=3.
1052f579bf8eSKris Kennaway              * So additionally check whether the cipher name found
1053f579bf8eSKris Kennaway              * has the correct length. We can save a strlen() call:
1054f579bf8eSKris Kennaway              * just checking for the '\0' at the right place is
105550ef0093SJacques Vidrine              * sufficient, we have to strncmp() anyway. (We cannot
105650ef0093SJacques Vidrine              * use strcmp(), because buf is not '\0' terminated.)
1057f579bf8eSKris Kennaway              */
1058f579bf8eSKris Kennaway             j = found = 0;
10593b4e3dcbSSimon L. B. Nielsen             cipher_id = 0;
10606f9291ceSJung-uk Kim             while (ca_list[j]) {
1061e71b7053SJung-uk Kim                 if (strncmp(buf, ca_list[j]->name, buflen) == 0
1062e71b7053SJung-uk Kim                     && (ca_list[j]->name[buflen] == '\0')) {
1063f579bf8eSKris Kennaway                     found = 1;
1064f579bf8eSKris Kennaway                     break;
10656f9291ceSJung-uk Kim                 } else
1066f579bf8eSKris Kennaway                     j++;
1067f579bf8eSKris Kennaway             }
10681f13597dSJung-uk Kim 
1069f579bf8eSKris Kennaway             if (!found)
1070f579bf8eSKris Kennaway                 break;          /* ignore this entry */
1071f579bf8eSKris Kennaway 
10726f9291ceSJung-uk Kim             if (ca_list[j]->algorithm_mkey) {
10736f9291ceSJung-uk Kim                 if (alg_mkey) {
10741f13597dSJung-uk Kim                     alg_mkey &= ca_list[j]->algorithm_mkey;
10756f9291ceSJung-uk Kim                     if (!alg_mkey) {
10766f9291ceSJung-uk Kim                         found = 0;
10776f9291ceSJung-uk Kim                         break;
10781f13597dSJung-uk Kim                     }
1079e71b7053SJung-uk Kim                 } else {
10801f13597dSJung-uk Kim                     alg_mkey = ca_list[j]->algorithm_mkey;
10811f13597dSJung-uk Kim                 }
1082e71b7053SJung-uk Kim             }
1083f579bf8eSKris Kennaway 
10846f9291ceSJung-uk Kim             if (ca_list[j]->algorithm_auth) {
10856f9291ceSJung-uk Kim                 if (alg_auth) {
10861f13597dSJung-uk Kim                     alg_auth &= ca_list[j]->algorithm_auth;
10876f9291ceSJung-uk Kim                     if (!alg_auth) {
10886f9291ceSJung-uk Kim                         found = 0;
10896f9291ceSJung-uk Kim                         break;
10901f13597dSJung-uk Kim                     }
1091e71b7053SJung-uk Kim                 } else {
10921f13597dSJung-uk Kim                     alg_auth = ca_list[j]->algorithm_auth;
10931f13597dSJung-uk Kim                 }
1094e71b7053SJung-uk Kim             }
10951f13597dSJung-uk Kim 
10966f9291ceSJung-uk Kim             if (ca_list[j]->algorithm_enc) {
10976f9291ceSJung-uk Kim                 if (alg_enc) {
10981f13597dSJung-uk Kim                     alg_enc &= ca_list[j]->algorithm_enc;
10996f9291ceSJung-uk Kim                     if (!alg_enc) {
11006f9291ceSJung-uk Kim                         found = 0;
11016f9291ceSJung-uk Kim                         break;
11021f13597dSJung-uk Kim                     }
1103e71b7053SJung-uk Kim                 } else {
11041f13597dSJung-uk Kim                     alg_enc = ca_list[j]->algorithm_enc;
11051f13597dSJung-uk Kim                 }
1106e71b7053SJung-uk Kim             }
11071f13597dSJung-uk Kim 
11086f9291ceSJung-uk Kim             if (ca_list[j]->algorithm_mac) {
11096f9291ceSJung-uk Kim                 if (alg_mac) {
11101f13597dSJung-uk Kim                     alg_mac &= ca_list[j]->algorithm_mac;
11116f9291ceSJung-uk Kim                     if (!alg_mac) {
11126f9291ceSJung-uk Kim                         found = 0;
11136f9291ceSJung-uk Kim                         break;
11141f13597dSJung-uk Kim                     }
1115e71b7053SJung-uk Kim                 } else {
11161f13597dSJung-uk Kim                     alg_mac = ca_list[j]->algorithm_mac;
11171f13597dSJung-uk Kim                 }
11181f13597dSJung-uk Kim             }
11191f13597dSJung-uk Kim 
11206f9291ceSJung-uk Kim             if (ca_list[j]->algo_strength & SSL_STRONG_MASK) {
11216f9291ceSJung-uk Kim                 if (algo_strength & SSL_STRONG_MASK) {
11226f9291ceSJung-uk Kim                     algo_strength &=
11236f9291ceSJung-uk Kim                         (ca_list[j]->algo_strength & SSL_STRONG_MASK) |
11246f9291ceSJung-uk Kim                         ~SSL_STRONG_MASK;
11256f9291ceSJung-uk Kim                     if (!(algo_strength & SSL_STRONG_MASK)) {
11266f9291ceSJung-uk Kim                         found = 0;
11276f9291ceSJung-uk Kim                         break;
11281f13597dSJung-uk Kim                     }
1129e71b7053SJung-uk Kim                 } else {
1130e71b7053SJung-uk Kim                     algo_strength = ca_list[j]->algo_strength & SSL_STRONG_MASK;
1131e71b7053SJung-uk Kim                 }
11321f13597dSJung-uk Kim             }
11331f13597dSJung-uk Kim 
1134e71b7053SJung-uk Kim             if (ca_list[j]->algo_strength & SSL_DEFAULT_MASK) {
1135e71b7053SJung-uk Kim                 if (algo_strength & SSL_DEFAULT_MASK) {
1136e71b7053SJung-uk Kim                     algo_strength &=
1137e71b7053SJung-uk Kim                         (ca_list[j]->algo_strength & SSL_DEFAULT_MASK) |
1138e71b7053SJung-uk Kim                         ~SSL_DEFAULT_MASK;
1139e71b7053SJung-uk Kim                     if (!(algo_strength & SSL_DEFAULT_MASK)) {
1140e71b7053SJung-uk Kim                         found = 0;
1141e71b7053SJung-uk Kim                         break;
1142e71b7053SJung-uk Kim                     }
1143e71b7053SJung-uk Kim                 } else {
1144e71b7053SJung-uk Kim                     algo_strength |=
1145e71b7053SJung-uk Kim                         ca_list[j]->algo_strength & SSL_DEFAULT_MASK;
1146e71b7053SJung-uk Kim                 }
1147b8721c16SJung-uk Kim             }
1148b8721c16SJung-uk Kim 
11496f9291ceSJung-uk Kim             if (ca_list[j]->valid) {
11506f9291ceSJung-uk Kim                 /*
11516f9291ceSJung-uk Kim                  * explicit ciphersuite found; its protocol version does not
11526f9291ceSJung-uk Kim                  * become part of the search pattern!
11536f9291ceSJung-uk Kim                  */
11541f13597dSJung-uk Kim 
1155ed5d4f9aSSimon L. B. Nielsen                 cipher_id = ca_list[j]->id;
11566f9291ceSJung-uk Kim             } else {
11576f9291ceSJung-uk Kim                 /*
11586f9291ceSJung-uk Kim                  * not an explicit ciphersuite; only in this case, the
11596f9291ceSJung-uk Kim                  * protocol version is considered part of the search pattern
11606f9291ceSJung-uk Kim                  */
11611f13597dSJung-uk Kim 
1162e71b7053SJung-uk Kim                 if (ca_list[j]->min_tls) {
1163e71b7053SJung-uk Kim                     if (min_tls != 0 && min_tls != ca_list[j]->min_tls) {
11646f9291ceSJung-uk Kim                         found = 0;
11656f9291ceSJung-uk Kim                         break;
1166e71b7053SJung-uk Kim                     } else {
1167e71b7053SJung-uk Kim                         min_tls = ca_list[j]->min_tls;
11681f13597dSJung-uk Kim                     }
11691f13597dSJung-uk Kim                 }
1170ed5d4f9aSSimon L. B. Nielsen             }
1171ed5d4f9aSSimon L. B. Nielsen 
11726f9291ceSJung-uk Kim             if (!multi)
11736f9291ceSJung-uk Kim                 break;
1174f579bf8eSKris Kennaway         }
1175f579bf8eSKris Kennaway 
1176f579bf8eSKris Kennaway         /*
1177f579bf8eSKris Kennaway          * Ok, we have the rule, now apply it
1178f579bf8eSKris Kennaway          */
11796f9291ceSJung-uk Kim         if (rule == CIPHER_SPECIAL) { /* special command */
1180f579bf8eSKris Kennaway             ok = 0;
1181e71b7053SJung-uk Kim             if ((buflen == 8) && strncmp(buf, "STRENGTH", 8) == 0) {
11821f13597dSJung-uk Kim                 ok = ssl_cipher_strength_sort(head_p, tail_p);
1183e71b7053SJung-uk Kim             } else if (buflen == 10 && strncmp(buf, "SECLEVEL=", 9) == 0) {
1184e71b7053SJung-uk Kim                 int level = buf[9] - '0';
1185e71b7053SJung-uk Kim                 if (level < 0 || level > 5) {
1186f579bf8eSKris Kennaway                     SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR,
1187f579bf8eSKris Kennaway                            SSL_R_INVALID_COMMAND);
1188e71b7053SJung-uk Kim                 } else {
1189e71b7053SJung-uk Kim                     c->sec_level = level;
1190e71b7053SJung-uk Kim                     ok = 1;
1191e71b7053SJung-uk Kim                 }
1192e71b7053SJung-uk Kim             } else {
1193e71b7053SJung-uk Kim                 SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, SSL_R_INVALID_COMMAND);
1194e71b7053SJung-uk Kim             }
1195f579bf8eSKris Kennaway             if (ok == 0)
1196f579bf8eSKris Kennaway                 retval = 0;
1197f579bf8eSKris Kennaway             /*
1198f579bf8eSKris Kennaway              * We do not support any "multi" options
1199f579bf8eSKris Kennaway              * together with "@", so throw away the
1200f579bf8eSKris Kennaway              * rest of the command, if any left, until
1201f579bf8eSKris Kennaway              * end or ':' is found.
1202f579bf8eSKris Kennaway              */
12035471f83eSSimon L. B. Nielsen             while ((*l != '\0') && !ITEM_SEP(*l))
1204f579bf8eSKris Kennaway                 l++;
12056f9291ceSJung-uk Kim         } else if (found) {
12061f13597dSJung-uk Kim             ssl_cipher_apply_rule(cipher_id,
12076f9291ceSJung-uk Kim                                   alg_mkey, alg_auth, alg_enc, alg_mac,
1208e71b7053SJung-uk Kim                                   min_tls, algo_strength, rule, -1, head_p,
12096f9291ceSJung-uk Kim                                   tail_p);
12106f9291ceSJung-uk Kim         } else {
12115471f83eSSimon L. B. Nielsen             while ((*l != '\0') && !ITEM_SEP(*l))
1212f579bf8eSKris Kennaway                 l++;
1213f579bf8eSKris Kennaway         }
12146f9291ceSJung-uk Kim         if (*l == '\0')
12156f9291ceSJung-uk Kim             break;              /* done */
1216f579bf8eSKris Kennaway     }
1217f579bf8eSKris Kennaway 
1218e71b7053SJung-uk Kim     return retval;
1219f579bf8eSKris Kennaway }
1220f579bf8eSKris Kennaway 
12217bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
12227bded2dbSJung-uk Kim static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
12237bded2dbSJung-uk Kim                                     const char **prule_str)
12247bded2dbSJung-uk Kim {
12257bded2dbSJung-uk Kim     unsigned int suiteb_flags = 0, suiteb_comb2 = 0;
122680815a77SJung-uk Kim     if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) {
12277bded2dbSJung-uk Kim         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;
122880815a77SJung-uk Kim     } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) {
12297bded2dbSJung-uk Kim         suiteb_comb2 = 1;
12307bded2dbSJung-uk Kim         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
123180815a77SJung-uk Kim     } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) {
123280815a77SJung-uk Kim         suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
123380815a77SJung-uk Kim     } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) {
12347bded2dbSJung-uk Kim         suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;
123580815a77SJung-uk Kim     }
12367bded2dbSJung-uk Kim 
12377bded2dbSJung-uk Kim     if (suiteb_flags) {
12387bded2dbSJung-uk Kim         c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;
12397bded2dbSJung-uk Kim         c->cert_flags |= suiteb_flags;
1240e71b7053SJung-uk Kim     } else {
12417bded2dbSJung-uk Kim         suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;
1242e71b7053SJung-uk Kim     }
12437bded2dbSJung-uk Kim 
12447bded2dbSJung-uk Kim     if (!suiteb_flags)
12457bded2dbSJung-uk Kim         return 1;
12467bded2dbSJung-uk Kim     /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */
12477bded2dbSJung-uk Kim 
12487bded2dbSJung-uk Kim     if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) {
12497bded2dbSJung-uk Kim         SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST,
1250e71b7053SJung-uk Kim                SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE);
12517bded2dbSJung-uk Kim         return 0;
12527bded2dbSJung-uk Kim     }
1253e71b7053SJung-uk Kim # ifndef OPENSSL_NO_EC
12547bded2dbSJung-uk Kim     switch (suiteb_flags) {
12557bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS:
12567bded2dbSJung-uk Kim         if (suiteb_comb2)
12577bded2dbSJung-uk Kim             *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
12587bded2dbSJung-uk Kim         else
12597bded2dbSJung-uk Kim             *prule_str =
12607bded2dbSJung-uk Kim                 "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";
12617bded2dbSJung-uk Kim         break;
12627bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
12637bded2dbSJung-uk Kim         *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";
12647bded2dbSJung-uk Kim         break;
12657bded2dbSJung-uk Kim     case SSL_CERT_FLAG_SUITEB_192_LOS:
12667bded2dbSJung-uk Kim         *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
12677bded2dbSJung-uk Kim         break;
12687bded2dbSJung-uk Kim     }
12697bded2dbSJung-uk Kim     return 1;
12707bded2dbSJung-uk Kim # else
1271e71b7053SJung-uk Kim     SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE);
12727bded2dbSJung-uk Kim     return 0;
12737bded2dbSJung-uk Kim # endif
12747bded2dbSJung-uk Kim }
12757bded2dbSJung-uk Kim #endif
12767bded2dbSJung-uk Kim 
1277e71b7053SJung-uk Kim static int ciphersuite_cb(const char *elem, int len, void *arg)
1278f579bf8eSKris Kennaway {
1279e71b7053SJung-uk Kim     STACK_OF(SSL_CIPHER) *ciphersuites = (STACK_OF(SSL_CIPHER) *)arg;
1280e71b7053SJung-uk Kim     const SSL_CIPHER *cipher;
1281e71b7053SJung-uk Kim     /* Arbitrary sized temp buffer for the cipher name. Should be big enough */
1282e71b7053SJung-uk Kim     char name[80];
1283e71b7053SJung-uk Kim 
1284e71b7053SJung-uk Kim     if (len > (int)(sizeof(name) - 1)) {
1285e71b7053SJung-uk Kim         SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH);
1286e71b7053SJung-uk Kim         return 0;
1287e71b7053SJung-uk Kim     }
1288e71b7053SJung-uk Kim 
1289e71b7053SJung-uk Kim     memcpy(name, elem, len);
1290e71b7053SJung-uk Kim     name[len] = '\0';
1291e71b7053SJung-uk Kim 
1292e71b7053SJung-uk Kim     cipher = ssl3_get_cipher_by_std_name(name);
1293e71b7053SJung-uk Kim     if (cipher == NULL) {
1294e71b7053SJung-uk Kim         SSLerr(SSL_F_CIPHERSUITE_CB, SSL_R_NO_CIPHER_MATCH);
1295e71b7053SJung-uk Kim         return 0;
1296e71b7053SJung-uk Kim     }
1297e71b7053SJung-uk Kim 
1298e71b7053SJung-uk Kim     if (!sk_SSL_CIPHER_push(ciphersuites, cipher)) {
1299e71b7053SJung-uk Kim         SSLerr(SSL_F_CIPHERSUITE_CB, ERR_R_INTERNAL_ERROR);
1300e71b7053SJung-uk Kim         return 0;
1301e71b7053SJung-uk Kim     }
1302e71b7053SJung-uk Kim 
1303e71b7053SJung-uk Kim     return 1;
1304e71b7053SJung-uk Kim }
1305e71b7053SJung-uk Kim 
1306c9cf7b5cSJung-uk Kim static __owur int set_ciphersuites(STACK_OF(SSL_CIPHER) **currciphers, const char *str)
1307e71b7053SJung-uk Kim {
1308e71b7053SJung-uk Kim     STACK_OF(SSL_CIPHER) *newciphers = sk_SSL_CIPHER_new_null();
1309e71b7053SJung-uk Kim 
1310e71b7053SJung-uk Kim     if (newciphers == NULL)
1311e71b7053SJung-uk Kim         return 0;
1312e71b7053SJung-uk Kim 
1313e71b7053SJung-uk Kim     /* Parse the list. We explicitly allow an empty list */
1314e71b7053SJung-uk Kim     if (*str != '\0'
1315e71b7053SJung-uk Kim             && !CONF_parse_list(str, ':', 1, ciphersuite_cb, newciphers)) {
1316e71b7053SJung-uk Kim         sk_SSL_CIPHER_free(newciphers);
1317e71b7053SJung-uk Kim         return 0;
1318e71b7053SJung-uk Kim     }
1319e71b7053SJung-uk Kim     sk_SSL_CIPHER_free(*currciphers);
1320e71b7053SJung-uk Kim     *currciphers = newciphers;
1321e71b7053SJung-uk Kim 
1322e71b7053SJung-uk Kim     return 1;
1323e71b7053SJung-uk Kim }
1324e71b7053SJung-uk Kim 
1325e71b7053SJung-uk Kim static int update_cipher_list_by_id(STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1326e71b7053SJung-uk Kim                                     STACK_OF(SSL_CIPHER) *cipherstack)
1327e71b7053SJung-uk Kim {
1328e71b7053SJung-uk Kim     STACK_OF(SSL_CIPHER) *tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1329e71b7053SJung-uk Kim 
1330e71b7053SJung-uk Kim     if (tmp_cipher_list == NULL) {
1331e71b7053SJung-uk Kim         return 0;
1332e71b7053SJung-uk Kim     }
1333e71b7053SJung-uk Kim 
1334e71b7053SJung-uk Kim     sk_SSL_CIPHER_free(*cipher_list_by_id);
1335e71b7053SJung-uk Kim     *cipher_list_by_id = tmp_cipher_list;
1336e71b7053SJung-uk Kim 
1337e71b7053SJung-uk Kim     (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, ssl_cipher_ptr_id_cmp);
1338e71b7053SJung-uk Kim     sk_SSL_CIPHER_sort(*cipher_list_by_id);
1339e71b7053SJung-uk Kim 
1340e71b7053SJung-uk Kim     return 1;
1341e71b7053SJung-uk Kim }
1342e71b7053SJung-uk Kim 
1343e71b7053SJung-uk Kim static int update_cipher_list(STACK_OF(SSL_CIPHER) **cipher_list,
1344e71b7053SJung-uk Kim                               STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1345e71b7053SJung-uk Kim                               STACK_OF(SSL_CIPHER) *tls13_ciphersuites)
1346e71b7053SJung-uk Kim {
1347e71b7053SJung-uk Kim     int i;
1348e71b7053SJung-uk Kim     STACK_OF(SSL_CIPHER) *tmp_cipher_list = sk_SSL_CIPHER_dup(*cipher_list);
1349e71b7053SJung-uk Kim 
1350e71b7053SJung-uk Kim     if (tmp_cipher_list == NULL)
1351e71b7053SJung-uk Kim         return 0;
1352e71b7053SJung-uk Kim 
1353e71b7053SJung-uk Kim     /*
1354e71b7053SJung-uk Kim      * Delete any existing TLSv1.3 ciphersuites. These are always first in the
1355e71b7053SJung-uk Kim      * list.
1356e71b7053SJung-uk Kim      */
1357e71b7053SJung-uk Kim     while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0
1358e71b7053SJung-uk Kim            && sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls
1359e71b7053SJung-uk Kim               == TLS1_3_VERSION)
1360e71b7053SJung-uk Kim         sk_SSL_CIPHER_delete(tmp_cipher_list, 0);
1361e71b7053SJung-uk Kim 
1362e71b7053SJung-uk Kim     /* Insert the new TLSv1.3 ciphersuites */
1363e71b7053SJung-uk Kim     for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++)
1364e71b7053SJung-uk Kim         sk_SSL_CIPHER_insert(tmp_cipher_list,
1365e71b7053SJung-uk Kim                              sk_SSL_CIPHER_value(tls13_ciphersuites, i), i);
1366e71b7053SJung-uk Kim 
1367e71b7053SJung-uk Kim     if (!update_cipher_list_by_id(cipher_list_by_id, tmp_cipher_list))
1368e71b7053SJung-uk Kim         return 0;
1369e71b7053SJung-uk Kim 
1370e71b7053SJung-uk Kim     sk_SSL_CIPHER_free(*cipher_list);
1371e71b7053SJung-uk Kim     *cipher_list = tmp_cipher_list;
1372e71b7053SJung-uk Kim 
1373e71b7053SJung-uk Kim     return 1;
1374e71b7053SJung-uk Kim }
1375e71b7053SJung-uk Kim 
1376e71b7053SJung-uk Kim int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str)
1377e71b7053SJung-uk Kim {
1378e71b7053SJung-uk Kim     int ret = set_ciphersuites(&(ctx->tls13_ciphersuites), str);
1379e71b7053SJung-uk Kim 
1380da327cd2SJung-uk Kim     if (ret && ctx->cipher_list != NULL)
1381e71b7053SJung-uk Kim         return update_cipher_list(&ctx->cipher_list, &ctx->cipher_list_by_id,
1382e71b7053SJung-uk Kim                                   ctx->tls13_ciphersuites);
1383e71b7053SJung-uk Kim 
1384e71b7053SJung-uk Kim     return ret;
1385e71b7053SJung-uk Kim }
1386e71b7053SJung-uk Kim 
1387e71b7053SJung-uk Kim int SSL_set_ciphersuites(SSL *s, const char *str)
1388e71b7053SJung-uk Kim {
1389da327cd2SJung-uk Kim     STACK_OF(SSL_CIPHER) *cipher_list;
1390e71b7053SJung-uk Kim     int ret = set_ciphersuites(&(s->tls13_ciphersuites), str);
1391e71b7053SJung-uk Kim 
1392da327cd2SJung-uk Kim     if (s->cipher_list == NULL) {
1393da327cd2SJung-uk Kim         if ((cipher_list = SSL_get_ciphers(s)) != NULL)
1394da327cd2SJung-uk Kim             s->cipher_list = sk_SSL_CIPHER_dup(cipher_list);
1395da327cd2SJung-uk Kim     }
1396da327cd2SJung-uk Kim     if (ret && s->cipher_list != NULL)
1397e71b7053SJung-uk Kim         return update_cipher_list(&s->cipher_list, &s->cipher_list_by_id,
1398e71b7053SJung-uk Kim                                   s->tls13_ciphersuites);
1399e71b7053SJung-uk Kim 
1400e71b7053SJung-uk Kim     return ret;
1401e71b7053SJung-uk Kim }
1402e71b7053SJung-uk Kim 
1403e71b7053SJung-uk Kim STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
1404e71b7053SJung-uk Kim                                              STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
1405e71b7053SJung-uk Kim                                              STACK_OF(SSL_CIPHER) **cipher_list,
1406e71b7053SJung-uk Kim                                              STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1407e71b7053SJung-uk Kim                                              const char *rule_str,
1408e71b7053SJung-uk Kim                                              CERT *c)
1409e71b7053SJung-uk Kim {
1410e71b7053SJung-uk Kim     int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases, i;
1411e71b7053SJung-uk Kim     uint32_t disabled_mkey, disabled_auth, disabled_enc, disabled_mac;
1412e71b7053SJung-uk Kim     STACK_OF(SSL_CIPHER) *cipherstack;
1413f579bf8eSKris Kennaway     const char *rule_p;
1414ced566fdSJacques Vidrine     CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
14151f13597dSJung-uk Kim     const SSL_CIPHER **ca_list = NULL;
1416f579bf8eSKris Kennaway 
1417f579bf8eSKris Kennaway     /*
1418f579bf8eSKris Kennaway      * Return with error if nothing to do.
1419f579bf8eSKris Kennaway      */
14203b4e3dcbSSimon L. B. Nielsen     if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
14213b4e3dcbSSimon L. B. Nielsen         return NULL;
14227bded2dbSJung-uk Kim #ifndef OPENSSL_NO_EC
14237bded2dbSJung-uk Kim     if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
14247bded2dbSJung-uk Kim         return NULL;
14257bded2dbSJung-uk Kim #endif
1426f579bf8eSKris Kennaway 
1427f579bf8eSKris Kennaway     /*
1428f579bf8eSKris Kennaway      * To reduce the work to do we only want to process the compiled
1429f579bf8eSKris Kennaway      * in algorithms, so we first get the mask of disabled ciphers.
1430f579bf8eSKris Kennaway      */
1431e71b7053SJung-uk Kim 
1432e71b7053SJung-uk Kim     disabled_mkey = disabled_mkey_mask;
1433e71b7053SJung-uk Kim     disabled_auth = disabled_auth_mask;
1434e71b7053SJung-uk Kim     disabled_enc = disabled_enc_mask;
1435e71b7053SJung-uk Kim     disabled_mac = disabled_mac_mask;
1436f579bf8eSKris Kennaway 
1437f579bf8eSKris Kennaway     /*
1438f579bf8eSKris Kennaway      * Now we have to collect the available ciphers from the compiled
1439f579bf8eSKris Kennaway      * in ciphers. We cannot get more than the number compiled in, so
1440f579bf8eSKris Kennaway      * it is used for allocation.
1441f579bf8eSKris Kennaway      */
1442f579bf8eSKris Kennaway     num_of_ciphers = ssl_method->num_ciphers();
1443e71b7053SJung-uk Kim 
1444e71b7053SJung-uk Kim     co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers);
14456f9291ceSJung-uk Kim     if (co_list == NULL) {
1446f579bf8eSKris Kennaway         SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
1447e71b7053SJung-uk Kim         return NULL;          /* Failure */
1448f579bf8eSKris Kennaway     }
1449f579bf8eSKris Kennaway 
14501f13597dSJung-uk Kim     ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
14516f9291ceSJung-uk Kim                                disabled_mkey, disabled_auth, disabled_enc,
1452e71b7053SJung-uk Kim                                disabled_mac, co_list, &head, &tail);
14531f13597dSJung-uk Kim 
1454e71b7053SJung-uk Kim     /* Now arrange all ciphers by preference. */
14551f13597dSJung-uk Kim 
14566f9291ceSJung-uk Kim     /*
14576f9291ceSJung-uk Kim      * Everything else being equal, prefer ephemeral ECDH over other key
1458e71b7053SJung-uk Kim      * exchange mechanisms.
1459e71b7053SJung-uk Kim      * For consistency, prefer ECDSA over RSA (though this only matters if the
1460e71b7053SJung-uk Kim      * server has both certificates, and is using the DEFAULT, or a client
1461e71b7053SJung-uk Kim      * preference).
14626f9291ceSJung-uk Kim      */
1463e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, 0, 0, 0, 0, CIPHER_ADD,
1464e71b7053SJung-uk Kim                           -1, &head, &tail);
1465e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head,
14666f9291ceSJung-uk Kim                           &tail);
1467e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head,
14686f9291ceSJung-uk Kim                           &tail);
14691f13597dSJung-uk Kim 
1470e71b7053SJung-uk Kim     /* Within each strength group, we prefer GCM over CHACHA... */
1471e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, SSL_AESGCM, 0, 0, 0, CIPHER_ADD, -1,
1472e71b7053SJung-uk Kim                           &head, &tail);
1473e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20, 0, 0, 0, CIPHER_ADD, -1,
1474e71b7053SJung-uk Kim                           &head, &tail);
1475e71b7053SJung-uk Kim 
1476e71b7053SJung-uk Kim     /*
1477e71b7053SJung-uk Kim      * ...and generally, our preferred cipher is AES.
1478e71b7053SJung-uk Kim      * Note that AEADs will be bumped to take preference after sorting by
1479e71b7053SJung-uk Kim      * strength.
1480e71b7053SJung-uk Kim      */
1481e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, SSL_AES ^ SSL_AESGCM, 0, 0, 0, CIPHER_ADD,
1482e71b7053SJung-uk Kim                           -1, &head, &tail);
14831f13597dSJung-uk Kim 
14841f13597dSJung-uk Kim     /* Temporarily enable everything else for sorting */
14851f13597dSJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail);
14861f13597dSJung-uk Kim 
14871f13597dSJung-uk Kim     /* Low priority for MD5 */
14886f9291ceSJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head,
14896f9291ceSJung-uk Kim                           &tail);
14901f13597dSJung-uk Kim 
14916f9291ceSJung-uk Kim     /*
14926f9291ceSJung-uk Kim      * Move anonymous ciphers to the end.  Usually, these will remain
14936f9291ceSJung-uk Kim      * disabled. (For applications that allow them, they aren't too bad, but
14946f9291ceSJung-uk Kim      * we prefer authenticated ciphers.)
14956f9291ceSJung-uk Kim      */
14966f9291ceSJung-uk Kim     ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
14976f9291ceSJung-uk Kim                           &tail);
14981f13597dSJung-uk Kim 
14996f9291ceSJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
15006f9291ceSJung-uk Kim                           &tail);
15016f9291ceSJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head,
15026f9291ceSJung-uk Kim                           &tail);
15031f13597dSJung-uk Kim 
1504e71b7053SJung-uk Kim     /* RC4 is sort-of broken -- move to the end */
15056f9291ceSJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head,
15066f9291ceSJung-uk Kim                           &tail);
15071f13597dSJung-uk Kim 
15086f9291ceSJung-uk Kim     /*
15096f9291ceSJung-uk Kim      * Now sort by symmetric encryption strength.  The above ordering remains
15106f9291ceSJung-uk Kim      * in force within each class
15116f9291ceSJung-uk Kim      */
15126f9291ceSJung-uk Kim     if (!ssl_cipher_strength_sort(&head, &tail)) {
15131f13597dSJung-uk Kim         OPENSSL_free(co_list);
15141f13597dSJung-uk Kim         return NULL;
15151f13597dSJung-uk Kim     }
15161f13597dSJung-uk Kim 
1517e71b7053SJung-uk Kim     /*
1518e71b7053SJung-uk Kim      * Partially overrule strength sort to prefer TLS 1.2 ciphers/PRFs.
1519e71b7053SJung-uk Kim      * TODO(openssl-team): is there an easier way to accomplish all this?
1520e71b7053SJung-uk Kim      */
1521e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, 0, 0, TLS1_2_VERSION, 0, CIPHER_BUMP, -1,
1522e71b7053SJung-uk Kim                           &head, &tail);
1523e71b7053SJung-uk Kim 
1524e71b7053SJung-uk Kim     /*
1525e71b7053SJung-uk Kim      * Irrespective of strength, enforce the following order:
1526e71b7053SJung-uk Kim      * (EC)DHE + AEAD > (EC)DHE > rest of AEAD > rest.
1527e71b7053SJung-uk Kim      * Within each group, ciphers remain sorted by strength and previous
1528e71b7053SJung-uk Kim      * preference, i.e.,
1529e71b7053SJung-uk Kim      * 1) ECDHE > DHE
1530e71b7053SJung-uk Kim      * 2) GCM > CHACHA
1531e71b7053SJung-uk Kim      * 3) AES > rest
1532e71b7053SJung-uk Kim      * 4) TLS 1.2 > legacy
1533e71b7053SJung-uk Kim      *
1534e71b7053SJung-uk Kim      * Because we now bump ciphers to the top of the list, we proceed in
1535e71b7053SJung-uk Kim      * reverse order of preference.
1536e71b7053SJung-uk Kim      */
1537e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, 0, SSL_AEAD, 0, 0, CIPHER_BUMP, -1,
1538e71b7053SJung-uk Kim                           &head, &tail);
1539e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, 0, 0, 0,
1540e71b7053SJung-uk Kim                           CIPHER_BUMP, -1, &head, &tail);
1541e71b7053SJung-uk Kim     ssl_cipher_apply_rule(0, SSL_kDHE | SSL_kECDHE, 0, 0, SSL_AEAD, 0, 0,
1542e71b7053SJung-uk Kim                           CIPHER_BUMP, -1, &head, &tail);
1543e71b7053SJung-uk Kim 
15441f13597dSJung-uk Kim     /* Now disable everything (maintaining the ordering!) */
15451f13597dSJung-uk Kim     ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail);
15461f13597dSJung-uk Kim 
1547f579bf8eSKris Kennaway     /*
1548f579bf8eSKris Kennaway      * We also need cipher aliases for selecting based on the rule_str.
1549f579bf8eSKris Kennaway      * There might be two types of entries in the rule_str: 1) names
1550f579bf8eSKris Kennaway      * of ciphers themselves 2) aliases for groups of ciphers.
1551f579bf8eSKris Kennaway      * For 1) we need the available ciphers and for 2) the cipher
1552f579bf8eSKris Kennaway      * groups of cipher_aliases added together in one list (otherwise
1553f579bf8eSKris Kennaway      * we would be happy with just the cipher_aliases table).
1554f579bf8eSKris Kennaway      */
1555e71b7053SJung-uk Kim     num_of_group_aliases = OSSL_NELEM(cipher_aliases);
1556f579bf8eSKris Kennaway     num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
1557e71b7053SJung-uk Kim     ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max);
15586f9291ceSJung-uk Kim     if (ca_list == NULL) {
1559ced566fdSJacques Vidrine         OPENSSL_free(co_list);
1560f579bf8eSKris Kennaway         SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
1561e71b7053SJung-uk Kim         return NULL;          /* Failure */
1562f579bf8eSKris Kennaway     }
15635471f83eSSimon L. B. Nielsen     ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
15641f13597dSJung-uk Kim                                disabled_mkey, disabled_auth, disabled_enc,
1565e71b7053SJung-uk Kim                                disabled_mac, head);
1566f579bf8eSKris Kennaway 
1567f579bf8eSKris Kennaway     /*
1568f579bf8eSKris Kennaway      * If the rule_string begins with DEFAULT, apply the default rule
1569f579bf8eSKris Kennaway      * before using the (possibly available) additional rules.
1570f579bf8eSKris Kennaway      */
1571f579bf8eSKris Kennaway     ok = 1;
1572f579bf8eSKris Kennaway     rule_p = rule_str;
15736f9291ceSJung-uk Kim     if (strncmp(rule_str, "DEFAULT", 7) == 0) {
1574f579bf8eSKris Kennaway         ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
1575e71b7053SJung-uk Kim                                         &head, &tail, ca_list, c);
1576f579bf8eSKris Kennaway         rule_p += 7;
1577f579bf8eSKris Kennaway         if (*rule_p == ':')
1578f579bf8eSKris Kennaway             rule_p++;
1579f579bf8eSKris Kennaway     }
1580f579bf8eSKris Kennaway 
1581f579bf8eSKris Kennaway     if (ok && (strlen(rule_p) > 0))
1582e71b7053SJung-uk Kim         ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list, c);
1583f579bf8eSKris Kennaway 
1584e71b7053SJung-uk Kim     OPENSSL_free(ca_list);      /* Not needed anymore */
1585f579bf8eSKris Kennaway 
15866f9291ceSJung-uk Kim     if (!ok) {                  /* Rule processing failure */
1587ced566fdSJacques Vidrine         OPENSSL_free(co_list);
1588e71b7053SJung-uk Kim         return NULL;
1589f579bf8eSKris Kennaway     }
15901f13597dSJung-uk Kim 
1591f579bf8eSKris Kennaway     /*
1592f579bf8eSKris Kennaway      * Allocate new "cipherstack" for the result, return with error
1593f579bf8eSKris Kennaway      * if we cannot get one.
1594f579bf8eSKris Kennaway      */
15956f9291ceSJung-uk Kim     if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
1596ced566fdSJacques Vidrine         OPENSSL_free(co_list);
1597e71b7053SJung-uk Kim         return NULL;
1598e71b7053SJung-uk Kim     }
1599e71b7053SJung-uk Kim 
1600e71b7053SJung-uk Kim     /* Add TLSv1.3 ciphers first - we always prefer those if possible */
1601e71b7053SJung-uk Kim     for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {
1602e71b7053SJung-uk Kim         if (!sk_SSL_CIPHER_push(cipherstack,
1603e71b7053SJung-uk Kim                                 sk_SSL_CIPHER_value(tls13_ciphersuites, i))) {
1604*b2bf0c7eSJung-uk Kim             OPENSSL_free(co_list);
1605e71b7053SJung-uk Kim             sk_SSL_CIPHER_free(cipherstack);
1606e71b7053SJung-uk Kim             return NULL;
1607e71b7053SJung-uk Kim         }
1608f579bf8eSKris Kennaway     }
1609f579bf8eSKris Kennaway 
1610f579bf8eSKris Kennaway     /*
1611f579bf8eSKris Kennaway      * The cipher selection for the list is done. The ciphers are added
1612f579bf8eSKris Kennaway      * to the resulting precedence to the STACK_OF(SSL_CIPHER).
1613f579bf8eSKris Kennaway      */
16146f9291ceSJung-uk Kim     for (curr = head; curr != NULL; curr = curr->next) {
1615e71b7053SJung-uk Kim         if (curr->active) {
1616e71b7053SJung-uk Kim             if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) {
1617e71b7053SJung-uk Kim                 OPENSSL_free(co_list);
1618e71b7053SJung-uk Kim                 sk_SSL_CIPHER_free(cipherstack);
1619e71b7053SJung-uk Kim                 return NULL;
1620e71b7053SJung-uk Kim             }
162174664626SKris Kennaway #ifdef CIPHER_DEBUG
1622751d2991SJung-uk Kim             fprintf(stderr, "<%s>\n", curr->cipher->name);
162374664626SKris Kennaway #endif
162474664626SKris Kennaway         }
162574664626SKris Kennaway     }
1626ced566fdSJacques Vidrine     OPENSSL_free(co_list);      /* Not needed any longer */
162774664626SKris Kennaway 
1628e71b7053SJung-uk Kim     if (!update_cipher_list_by_id(cipher_list_by_id, cipherstack)) {
16293b4e3dcbSSimon L. B. Nielsen         sk_SSL_CIPHER_free(cipherstack);
16303b4e3dcbSSimon L. B. Nielsen         return NULL;
16313b4e3dcbSSimon L. B. Nielsen     }
163274664626SKris Kennaway     sk_SSL_CIPHER_free(*cipher_list);
1633f579bf8eSKris Kennaway     *cipher_list = cipherstack;
163474664626SKris Kennaway 
1635e71b7053SJung-uk Kim     return cipherstack;
163674664626SKris Kennaway }
163774664626SKris Kennaway 
16386a599222SSimon L. B. Nielsen char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
163974664626SKris Kennaway {
1640e71b7053SJung-uk Kim     const char *ver;
16413b4e3dcbSSimon L. B. Nielsen     const char *kx, *au, *enc, *mac;
1642e71b7053SJung-uk Kim     uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
1643e71b7053SJung-uk Kim     static const char *format = "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
1644e71b7053SJung-uk Kim 
1645e71b7053SJung-uk Kim     if (buf == NULL) {
1646e71b7053SJung-uk Kim         len = 128;
1647e71b7053SJung-uk Kim         if ((buf = OPENSSL_malloc(len)) == NULL) {
1648e71b7053SJung-uk Kim             SSLerr(SSL_F_SSL_CIPHER_DESCRIPTION, ERR_R_MALLOC_FAILURE);
1649e71b7053SJung-uk Kim             return NULL;
1650e71b7053SJung-uk Kim         }
1651e71b7053SJung-uk Kim     } else if (len < 128) {
1652e71b7053SJung-uk Kim         return NULL;
1653e71b7053SJung-uk Kim     }
165474664626SKris Kennaway 
16551f13597dSJung-uk Kim     alg_mkey = cipher->algorithm_mkey;
16561f13597dSJung-uk Kim     alg_auth = cipher->algorithm_auth;
16571f13597dSJung-uk Kim     alg_enc = cipher->algorithm_enc;
16581f13597dSJung-uk Kim     alg_mac = cipher->algorithm_mac;
16591f13597dSJung-uk Kim 
1660e71b7053SJung-uk Kim     ver = ssl_protocol_to_string(cipher->min_tls);
166174664626SKris Kennaway 
16626f9291ceSJung-uk Kim     switch (alg_mkey) {
166374664626SKris Kennaway     case SSL_kRSA:
1664e71b7053SJung-uk Kim         kx = "RSA";
166574664626SKris Kennaway         break;
1666e71b7053SJung-uk Kim     case SSL_kDHE:
1667e71b7053SJung-uk Kim         kx = "DH";
166874664626SKris Kennaway         break;
1669e71b7053SJung-uk Kim     case SSL_kECDHE:
16701f13597dSJung-uk Kim         kx = "ECDH";
16711f13597dSJung-uk Kim         break;
16721f13597dSJung-uk Kim     case SSL_kPSK:
16731f13597dSJung-uk Kim         kx = "PSK";
16741f13597dSJung-uk Kim         break;
1675e71b7053SJung-uk Kim     case SSL_kRSAPSK:
1676e71b7053SJung-uk Kim         kx = "RSAPSK";
1677e71b7053SJung-uk Kim         break;
1678e71b7053SJung-uk Kim     case SSL_kECDHEPSK:
1679e71b7053SJung-uk Kim         kx = "ECDHEPSK";
1680e71b7053SJung-uk Kim         break;
1681e71b7053SJung-uk Kim     case SSL_kDHEPSK:
1682e71b7053SJung-uk Kim         kx = "DHEPSK";
1683e71b7053SJung-uk Kim         break;
16841f13597dSJung-uk Kim     case SSL_kSRP:
16851f13597dSJung-uk Kim         kx = "SRP";
16863b4e3dcbSSimon L. B. Nielsen         break;
1687a93cbc2bSJung-uk Kim     case SSL_kGOST:
1688a93cbc2bSJung-uk Kim         kx = "GOST";
1689a93cbc2bSJung-uk Kim         break;
1690e71b7053SJung-uk Kim     case SSL_kANY:
1691e71b7053SJung-uk Kim         kx = "any";
1692e71b7053SJung-uk Kim         break;
169374664626SKris Kennaway     default:
169474664626SKris Kennaway         kx = "unknown";
169574664626SKris Kennaway     }
169674664626SKris Kennaway 
16976f9291ceSJung-uk Kim     switch (alg_auth) {
169874664626SKris Kennaway     case SSL_aRSA:
169974664626SKris Kennaway         au = "RSA";
170074664626SKris Kennaway         break;
170174664626SKris Kennaway     case SSL_aDSS:
170274664626SKris Kennaway         au = "DSS";
170374664626SKris Kennaway         break;
170474664626SKris Kennaway     case SSL_aNULL:
170574664626SKris Kennaway         au = "None";
170674664626SKris Kennaway         break;
17073b4e3dcbSSimon L. B. Nielsen     case SSL_aECDSA:
17083b4e3dcbSSimon L. B. Nielsen         au = "ECDSA";
17093b4e3dcbSSimon L. B. Nielsen         break;
17101f13597dSJung-uk Kim     case SSL_aPSK:
17111f13597dSJung-uk Kim         au = "PSK";
17121f13597dSJung-uk Kim         break;
1713a93cbc2bSJung-uk Kim     case SSL_aSRP:
1714a93cbc2bSJung-uk Kim         au = "SRP";
1715a93cbc2bSJung-uk Kim         break;
1716a93cbc2bSJung-uk Kim     case SSL_aGOST01:
1717a93cbc2bSJung-uk Kim         au = "GOST01";
1718a93cbc2bSJung-uk Kim         break;
1719e71b7053SJung-uk Kim     /* New GOST ciphersuites have both SSL_aGOST12 and SSL_aGOST01 bits */
1720e71b7053SJung-uk Kim     case (SSL_aGOST12 | SSL_aGOST01):
1721e71b7053SJung-uk Kim         au = "GOST12";
1722e71b7053SJung-uk Kim         break;
1723e71b7053SJung-uk Kim     case SSL_aANY:
1724e71b7053SJung-uk Kim         au = "any";
1725e71b7053SJung-uk Kim         break;
172674664626SKris Kennaway     default:
172774664626SKris Kennaway         au = "unknown";
172874664626SKris Kennaway         break;
172974664626SKris Kennaway     }
173074664626SKris Kennaway 
17316f9291ceSJung-uk Kim     switch (alg_enc) {
173274664626SKris Kennaway     case SSL_DES:
1733e71b7053SJung-uk Kim         enc = "DES(56)";
173474664626SKris Kennaway         break;
173574664626SKris Kennaway     case SSL_3DES:
173674664626SKris Kennaway         enc = "3DES(168)";
173774664626SKris Kennaway         break;
173874664626SKris Kennaway     case SSL_RC4:
1739e71b7053SJung-uk Kim         enc = "RC4(128)";
174074664626SKris Kennaway         break;
174174664626SKris Kennaway     case SSL_RC2:
1742e71b7053SJung-uk Kim         enc = "RC2(128)";
174374664626SKris Kennaway         break;
174474664626SKris Kennaway     case SSL_IDEA:
174574664626SKris Kennaway         enc = "IDEA(128)";
174674664626SKris Kennaway         break;
174774664626SKris Kennaway     case SSL_eNULL:
174874664626SKris Kennaway         enc = "None";
174974664626SKris Kennaway         break;
17501f13597dSJung-uk Kim     case SSL_AES128:
17511f13597dSJung-uk Kim         enc = "AES(128)";
17525c87c606SMark Murray         break;
17531f13597dSJung-uk Kim     case SSL_AES256:
17541f13597dSJung-uk Kim         enc = "AES(256)";
17551f13597dSJung-uk Kim         break;
17561f13597dSJung-uk Kim     case SSL_AES128GCM:
17571f13597dSJung-uk Kim         enc = "AESGCM(128)";
17581f13597dSJung-uk Kim         break;
17591f13597dSJung-uk Kim     case SSL_AES256GCM:
17601f13597dSJung-uk Kim         enc = "AESGCM(256)";
17611f13597dSJung-uk Kim         break;
1762e71b7053SJung-uk Kim     case SSL_AES128CCM:
1763e71b7053SJung-uk Kim         enc = "AESCCM(128)";
1764e71b7053SJung-uk Kim         break;
1765e71b7053SJung-uk Kim     case SSL_AES256CCM:
1766e71b7053SJung-uk Kim         enc = "AESCCM(256)";
1767e71b7053SJung-uk Kim         break;
1768e71b7053SJung-uk Kim     case SSL_AES128CCM8:
1769e71b7053SJung-uk Kim         enc = "AESCCM8(128)";
1770e71b7053SJung-uk Kim         break;
1771e71b7053SJung-uk Kim     case SSL_AES256CCM8:
1772e71b7053SJung-uk Kim         enc = "AESCCM8(256)";
1773e71b7053SJung-uk Kim         break;
17741f13597dSJung-uk Kim     case SSL_CAMELLIA128:
17751f13597dSJung-uk Kim         enc = "Camellia(128)";
17761f13597dSJung-uk Kim         break;
17771f13597dSJung-uk Kim     case SSL_CAMELLIA256:
17781f13597dSJung-uk Kim         enc = "Camellia(256)";
1779ed5d4f9aSSimon L. B. Nielsen         break;
1780e71b7053SJung-uk Kim     case SSL_ARIA128GCM:
1781e71b7053SJung-uk Kim         enc = "ARIAGCM(128)";
1782e71b7053SJung-uk Kim         break;
1783e71b7053SJung-uk Kim     case SSL_ARIA256GCM:
1784e71b7053SJung-uk Kim         enc = "ARIAGCM(256)";
1785e71b7053SJung-uk Kim         break;
1786db522d3aSSimon L. B. Nielsen     case SSL_SEED:
1787db522d3aSSimon L. B. Nielsen         enc = "SEED(128)";
1788db522d3aSSimon L. B. Nielsen         break;
1789a93cbc2bSJung-uk Kim     case SSL_eGOST2814789CNT:
1790e71b7053SJung-uk Kim     case SSL_eGOST2814789CNT12:
1791a93cbc2bSJung-uk Kim         enc = "GOST89(256)";
1792a93cbc2bSJung-uk Kim         break;
1793e71b7053SJung-uk Kim     case SSL_CHACHA20POLY1305:
1794e71b7053SJung-uk Kim         enc = "CHACHA20/POLY1305(256)";
1795e71b7053SJung-uk Kim         break;
179674664626SKris Kennaway     default:
179774664626SKris Kennaway         enc = "unknown";
179874664626SKris Kennaway         break;
179974664626SKris Kennaway     }
180074664626SKris Kennaway 
18016f9291ceSJung-uk Kim     switch (alg_mac) {
180274664626SKris Kennaway     case SSL_MD5:
180374664626SKris Kennaway         mac = "MD5";
180474664626SKris Kennaway         break;
180574664626SKris Kennaway     case SSL_SHA1:
180674664626SKris Kennaway         mac = "SHA1";
180774664626SKris Kennaway         break;
18081f13597dSJung-uk Kim     case SSL_SHA256:
18091f13597dSJung-uk Kim         mac = "SHA256";
18101f13597dSJung-uk Kim         break;
18111f13597dSJung-uk Kim     case SSL_SHA384:
18121f13597dSJung-uk Kim         mac = "SHA384";
18131f13597dSJung-uk Kim         break;
18141f13597dSJung-uk Kim     case SSL_AEAD:
18151f13597dSJung-uk Kim         mac = "AEAD";
18161f13597dSJung-uk Kim         break;
1817a93cbc2bSJung-uk Kim     case SSL_GOST89MAC:
1818e71b7053SJung-uk Kim     case SSL_GOST89MAC12:
1819a93cbc2bSJung-uk Kim         mac = "GOST89";
1820a93cbc2bSJung-uk Kim         break;
1821a93cbc2bSJung-uk Kim     case SSL_GOST94:
1822a93cbc2bSJung-uk Kim         mac = "GOST94";
1823a93cbc2bSJung-uk Kim         break;
1824e71b7053SJung-uk Kim     case SSL_GOST12_256:
1825e71b7053SJung-uk Kim     case SSL_GOST12_512:
1826e71b7053SJung-uk Kim         mac = "GOST2012";
1827e71b7053SJung-uk Kim         break;
182874664626SKris Kennaway     default:
182974664626SKris Kennaway         mac = "unknown";
183074664626SKris Kennaway         break;
183174664626SKris Kennaway     }
183274664626SKris Kennaway 
1833e71b7053SJung-uk Kim     BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac);
183474664626SKris Kennaway 
1835e71b7053SJung-uk Kim     return buf;
183674664626SKris Kennaway }
183774664626SKris Kennaway 
1838e71b7053SJung-uk Kim const char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
183974664626SKris Kennaway {
18406f9291ceSJung-uk Kim     if (c == NULL)
1841e71b7053SJung-uk Kim         return "(NONE)";
1842e71b7053SJung-uk Kim 
1843e71b7053SJung-uk Kim     /*
1844e71b7053SJung-uk Kim      * Backwards-compatibility crutch.  In almost all contexts we report TLS
1845e71b7053SJung-uk Kim      * 1.0 as "TLSv1", but for ciphers we report "TLSv1.0".
1846e71b7053SJung-uk Kim      */
1847e71b7053SJung-uk Kim     if (c->min_tls == TLS1_VERSION)
1848e71b7053SJung-uk Kim         return "TLSv1.0";
1849e71b7053SJung-uk Kim     return ssl_protocol_to_string(c->min_tls);
185074664626SKris Kennaway }
185174664626SKris Kennaway 
185274664626SKris Kennaway /* return the actual cipher being used */
18533b4e3dcbSSimon L. B. Nielsen const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
185474664626SKris Kennaway {
185574664626SKris Kennaway     if (c != NULL)
1856e71b7053SJung-uk Kim         return c->name;
1857e71b7053SJung-uk Kim     return "(NONE)";
1858e71b7053SJung-uk Kim }
1859e71b7053SJung-uk Kim 
1860e71b7053SJung-uk Kim /* return the actual cipher being used in RFC standard name */
1861e71b7053SJung-uk Kim const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c)
1862e71b7053SJung-uk Kim {
1863e71b7053SJung-uk Kim     if (c != NULL)
1864e71b7053SJung-uk Kim         return c->stdname;
1865e71b7053SJung-uk Kim     return "(NONE)";
1866e71b7053SJung-uk Kim }
1867e71b7053SJung-uk Kim 
1868e71b7053SJung-uk Kim /* return the OpenSSL name based on given RFC standard name */
1869e71b7053SJung-uk Kim const char *OPENSSL_cipher_name(const char *stdname)
1870e71b7053SJung-uk Kim {
1871e71b7053SJung-uk Kim     const SSL_CIPHER *c;
1872e71b7053SJung-uk Kim 
1873e71b7053SJung-uk Kim     if (stdname == NULL)
1874e71b7053SJung-uk Kim         return "(NONE)";
1875e71b7053SJung-uk Kim     c = ssl3_get_cipher_by_std_name(stdname);
1876e71b7053SJung-uk Kim     return SSL_CIPHER_get_name(c);
187774664626SKris Kennaway }
187874664626SKris Kennaway 
1879f579bf8eSKris Kennaway /* number of bits for symmetric cipher */
18803b4e3dcbSSimon L. B. Nielsen int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
188174664626SKris Kennaway {
1882f579bf8eSKris Kennaway     int ret = 0;
188374664626SKris Kennaway 
18846f9291ceSJung-uk Kim     if (c != NULL) {
18856f9291ceSJung-uk Kim         if (alg_bits != NULL)
1886e71b7053SJung-uk Kim             *alg_bits = (int)c->alg_bits;
1887e71b7053SJung-uk Kim         ret = (int)c->strength_bits;
188874664626SKris Kennaway     }
1889e71b7053SJung-uk Kim     return ret;
189074664626SKris Kennaway }
189174664626SKris Kennaway 
1892e71b7053SJung-uk Kim uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c)
18931f13597dSJung-uk Kim {
18941f13597dSJung-uk Kim     return c->id;
18951f13597dSJung-uk Kim }
18961f13597dSJung-uk Kim 
1897e71b7053SJung-uk Kim uint16_t SSL_CIPHER_get_protocol_id(const SSL_CIPHER *c)
1898e71b7053SJung-uk Kim {
1899e71b7053SJung-uk Kim     return c->id & 0xFFFF;
1900e71b7053SJung-uk Kim }
1901e71b7053SJung-uk Kim 
190274664626SKris Kennaway SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
190374664626SKris Kennaway {
190474664626SKris Kennaway     SSL_COMP *ctmp;
190574664626SKris Kennaway     int i, nn;
190674664626SKris Kennaway 
19076f9291ceSJung-uk Kim     if ((n == 0) || (sk == NULL))
1908e71b7053SJung-uk Kim         return NULL;
190974664626SKris Kennaway     nn = sk_SSL_COMP_num(sk);
19106f9291ceSJung-uk Kim     for (i = 0; i < nn; i++) {
191174664626SKris Kennaway         ctmp = sk_SSL_COMP_value(sk, i);
191274664626SKris Kennaway         if (ctmp->id == n)
1913e71b7053SJung-uk Kim             return ctmp;
191474664626SKris Kennaway     }
1915e71b7053SJung-uk Kim     return NULL;
191674664626SKris Kennaway }
191774664626SKris Kennaway 
19183b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_NO_COMP
1919aeb5019cSJung-uk Kim STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
192074664626SKris Kennaway {
19213b4e3dcbSSimon L. B. Nielsen     return NULL;
19223b4e3dcbSSimon L. B. Nielsen }
19236f9291ceSJung-uk Kim 
1924aeb5019cSJung-uk Kim STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
1925aeb5019cSJung-uk Kim                                                       *meths)
1926aeb5019cSJung-uk Kim {
1927e71b7053SJung-uk Kim     return meths;
1928aeb5019cSJung-uk Kim }
1929aeb5019cSJung-uk Kim 
1930aeb5019cSJung-uk Kim int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
19313b4e3dcbSSimon L. B. Nielsen {
19323b4e3dcbSSimon L. B. Nielsen     return 1;
193374664626SKris Kennaway }
193474664626SKris Kennaway 
19353b4e3dcbSSimon L. B. Nielsen #else
193674664626SKris Kennaway STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
193774664626SKris Kennaway {
19383b4e3dcbSSimon L. B. Nielsen     load_builtin_compressions();
1939e71b7053SJung-uk Kim     return ssl_comp_methods;
194074664626SKris Kennaway }
194174664626SKris Kennaway 
19427bded2dbSJung-uk Kim STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
19437bded2dbSJung-uk Kim                                                       *meths)
19447bded2dbSJung-uk Kim {
19457bded2dbSJung-uk Kim     STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods;
19467bded2dbSJung-uk Kim     ssl_comp_methods = meths;
19477bded2dbSJung-uk Kim     return old_meths;
19487bded2dbSJung-uk Kim }
19497bded2dbSJung-uk Kim 
19507bded2dbSJung-uk Kim static void cmeth_free(SSL_COMP *cm)
19517bded2dbSJung-uk Kim {
19527bded2dbSJung-uk Kim     OPENSSL_free(cm);
19537bded2dbSJung-uk Kim }
19547bded2dbSJung-uk Kim 
1955e71b7053SJung-uk Kim void ssl_comp_free_compression_methods_int(void)
19567bded2dbSJung-uk Kim {
19577bded2dbSJung-uk Kim     STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods;
19587bded2dbSJung-uk Kim     ssl_comp_methods = NULL;
19597bded2dbSJung-uk Kim     sk_SSL_COMP_pop_free(old_meths, cmeth_free);
19607bded2dbSJung-uk Kim }
19617bded2dbSJung-uk Kim 
196274664626SKris Kennaway int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
196374664626SKris Kennaway {
196474664626SKris Kennaway     SSL_COMP *comp;
196574664626SKris Kennaway 
1966e71b7053SJung-uk Kim     if (cm == NULL || COMP_get_type(cm) == NID_undef)
19675c87c606SMark Murray         return 1;
19685c87c606SMark Murray 
19696f9291ceSJung-uk Kim     /*-
19706f9291ceSJung-uk Kim      * According to draft-ietf-tls-compression-04.txt, the
19716f9291ceSJung-uk Kim      * compression number ranges should be the following:
19726f9291ceSJung-uk Kim      *
19736f9291ceSJung-uk Kim      *   0 to  63:  methods defined by the IETF
19746f9291ceSJung-uk Kim      *  64 to 192:  external party methods assigned by IANA
19756f9291ceSJung-uk Kim      * 193 to 255:  reserved for private use
19766f9291ceSJung-uk Kim      */
19776f9291ceSJung-uk Kim     if (id < 193 || id > 255) {
19786f9291ceSJung-uk Kim         SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,
19796f9291ceSJung-uk Kim                SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
1980ed7112f0SJung-uk Kim         return 1;
19813b4e3dcbSSimon L. B. Nielsen     }
19823b4e3dcbSSimon L. B. Nielsen 
1983e71b7053SJung-uk Kim     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
1984e71b7053SJung-uk Kim     comp = OPENSSL_malloc(sizeof(*comp));
1985aeb5019cSJung-uk Kim     if (comp == NULL) {
1986e71b7053SJung-uk Kim         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
1987aeb5019cSJung-uk Kim         SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE);
1988aeb5019cSJung-uk Kim         return 1;
1989aeb5019cSJung-uk Kim     }
1990e71b7053SJung-uk Kim 
199174664626SKris Kennaway     comp->id = id;
199274664626SKris Kennaway     comp->method = cm;
19933b4e3dcbSSimon L. B. Nielsen     load_builtin_compressions();
19946f9291ceSJung-uk Kim     if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) {
19953b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(comp);
1996e71b7053SJung-uk Kim         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
19976f9291ceSJung-uk Kim         SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,
19986f9291ceSJung-uk Kim                SSL_R_DUPLICATE_COMPRESSION_ID);
1999e71b7053SJung-uk Kim         return 1;
2000e71b7053SJung-uk Kim     }
2001e71b7053SJung-uk Kim     if (ssl_comp_methods == NULL || !sk_SSL_COMP_push(ssl_comp_methods, comp)) {
20023b4e3dcbSSimon L. B. Nielsen         OPENSSL_free(comp);
2003e71b7053SJung-uk Kim         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
200474664626SKris Kennaway         SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE);
2005e71b7053SJung-uk Kim         return 1;
200674664626SKris Kennaway     }
2007e71b7053SJung-uk Kim     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
2008e71b7053SJung-uk Kim     return 0;
20095c87c606SMark Murray }
2010e71b7053SJung-uk Kim #endif
20113b4e3dcbSSimon L. B. Nielsen 
20123b4e3dcbSSimon L. B. Nielsen const char *SSL_COMP_get_name(const COMP_METHOD *comp)
20133b4e3dcbSSimon L. B. Nielsen {
2014e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
2015e71b7053SJung-uk Kim     return comp ? COMP_get_name(comp) : NULL;
2016e71b7053SJung-uk Kim #else
20173b4e3dcbSSimon L. B. Nielsen     return NULL;
20183b4e3dcbSSimon L. B. Nielsen #endif
20197bded2dbSJung-uk Kim }
20207bded2dbSJung-uk Kim 
2021e71b7053SJung-uk Kim const char *SSL_COMP_get0_name(const SSL_COMP *comp)
20227bded2dbSJung-uk Kim {
2023e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
2024e71b7053SJung-uk Kim     return comp->name;
2025e71b7053SJung-uk Kim #else
2026e71b7053SJung-uk Kim     return NULL;
2027e71b7053SJung-uk Kim #endif
2028e71b7053SJung-uk Kim }
2029e71b7053SJung-uk Kim 
2030e71b7053SJung-uk Kim int SSL_COMP_get_id(const SSL_COMP *comp)
2031e71b7053SJung-uk Kim {
2032e71b7053SJung-uk Kim #ifndef OPENSSL_NO_COMP
2033e71b7053SJung-uk Kim     return comp->id;
2034e71b7053SJung-uk Kim #else
2035e71b7053SJung-uk Kim     return -1;
2036e71b7053SJung-uk Kim #endif
2037e71b7053SJung-uk Kim }
2038e71b7053SJung-uk Kim 
2039e71b7053SJung-uk Kim const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr,
2040e71b7053SJung-uk Kim                                          int all)
2041e71b7053SJung-uk Kim {
2042e71b7053SJung-uk Kim     const SSL_CIPHER *c = ssl->method->get_cipher_by_char(ptr);
2043e71b7053SJung-uk Kim 
2044e71b7053SJung-uk Kim     if (c == NULL || (!all && c->valid == 0))
20457bded2dbSJung-uk Kim         return NULL;
20467bded2dbSJung-uk Kim     return c;
20477bded2dbSJung-uk Kim }
20487bded2dbSJung-uk Kim 
20497bded2dbSJung-uk Kim const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr)
20507bded2dbSJung-uk Kim {
20517bded2dbSJung-uk Kim     return ssl->method->get_cipher_by_char(ptr);
20527bded2dbSJung-uk Kim }
2053e71b7053SJung-uk Kim 
2054e71b7053SJung-uk Kim int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c)
2055e71b7053SJung-uk Kim {
2056e71b7053SJung-uk Kim     int i;
2057e71b7053SJung-uk Kim     if (c == NULL)
2058e71b7053SJung-uk Kim         return NID_undef;
2059e71b7053SJung-uk Kim     i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, c->algorithm_enc);
2060e71b7053SJung-uk Kim     if (i == -1)
2061e71b7053SJung-uk Kim         return NID_undef;
2062e71b7053SJung-uk Kim     return ssl_cipher_table_cipher[i].nid;
2063e71b7053SJung-uk Kim }
2064e71b7053SJung-uk Kim 
2065e71b7053SJung-uk Kim int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c)
2066e71b7053SJung-uk Kim {
2067e71b7053SJung-uk Kim     int i = ssl_cipher_info_lookup(ssl_cipher_table_mac, c->algorithm_mac);
2068e71b7053SJung-uk Kim 
2069e71b7053SJung-uk Kim     if (i == -1)
2070e71b7053SJung-uk Kim         return NID_undef;
2071e71b7053SJung-uk Kim     return ssl_cipher_table_mac[i].nid;
2072e71b7053SJung-uk Kim }
2073e71b7053SJung-uk Kim 
2074e71b7053SJung-uk Kim int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c)
2075e71b7053SJung-uk Kim {
2076e71b7053SJung-uk Kim     int i = ssl_cipher_info_lookup(ssl_cipher_table_kx, c->algorithm_mkey);
2077e71b7053SJung-uk Kim 
2078e71b7053SJung-uk Kim     if (i == -1)
2079e71b7053SJung-uk Kim         return NID_undef;
2080e71b7053SJung-uk Kim     return ssl_cipher_table_kx[i].nid;
2081e71b7053SJung-uk Kim }
2082e71b7053SJung-uk Kim 
2083e71b7053SJung-uk Kim int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
2084e71b7053SJung-uk Kim {
2085e71b7053SJung-uk Kim     int i = ssl_cipher_info_lookup(ssl_cipher_table_auth, c->algorithm_auth);
2086e71b7053SJung-uk Kim 
2087e71b7053SJung-uk Kim     if (i == -1)
2088e71b7053SJung-uk Kim         return NID_undef;
2089e71b7053SJung-uk Kim     return ssl_cipher_table_auth[i].nid;
2090e71b7053SJung-uk Kim }
2091e71b7053SJung-uk Kim 
2092e71b7053SJung-uk Kim const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c)
2093e71b7053SJung-uk Kim {
2094e71b7053SJung-uk Kim     int idx = c->algorithm2 & SSL_HANDSHAKE_MAC_MASK;
2095e71b7053SJung-uk Kim 
2096e71b7053SJung-uk Kim     if (idx < 0 || idx >= SSL_MD_NUM_IDX)
2097e71b7053SJung-uk Kim         return NULL;
2098e71b7053SJung-uk Kim     return ssl_digest_methods[idx];
2099e71b7053SJung-uk Kim }
2100e71b7053SJung-uk Kim 
2101e71b7053SJung-uk Kim int SSL_CIPHER_is_aead(const SSL_CIPHER *c)
2102e71b7053SJung-uk Kim {
2103e71b7053SJung-uk Kim     return (c->algorithm_mac & SSL_AEAD) ? 1 : 0;
2104e71b7053SJung-uk Kim }
2105e71b7053SJung-uk Kim 
2106e71b7053SJung-uk Kim int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
2107e71b7053SJung-uk Kim                             size_t *int_overhead, size_t *blocksize,
2108e71b7053SJung-uk Kim                             size_t *ext_overhead)
2109e71b7053SJung-uk Kim {
2110e71b7053SJung-uk Kim     size_t mac = 0, in = 0, blk = 0, out = 0;
2111e71b7053SJung-uk Kim 
2112e71b7053SJung-uk Kim     /* Some hard-coded numbers for the CCM/Poly1305 MAC overhead
2113e71b7053SJung-uk Kim      * because there are no handy #defines for those. */
2114e71b7053SJung-uk Kim     if (c->algorithm_enc & (SSL_AESGCM | SSL_ARIAGCM)) {
2115e71b7053SJung-uk Kim         out = EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
2116e71b7053SJung-uk Kim     } else if (c->algorithm_enc & (SSL_AES128CCM | SSL_AES256CCM)) {
2117e71b7053SJung-uk Kim         out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 16;
2118e71b7053SJung-uk Kim     } else if (c->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) {
2119e71b7053SJung-uk Kim         out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 8;
2120e71b7053SJung-uk Kim     } else if (c->algorithm_enc & SSL_CHACHA20POLY1305) {
2121e71b7053SJung-uk Kim         out = 16;
2122e71b7053SJung-uk Kim     } else if (c->algorithm_mac & SSL_AEAD) {
2123e71b7053SJung-uk Kim         /* We're supposed to have handled all the AEAD modes above */
2124e71b7053SJung-uk Kim         return 0;
2125e71b7053SJung-uk Kim     } else {
2126e71b7053SJung-uk Kim         /* Non-AEAD modes. Calculate MAC/cipher overhead separately */
2127e71b7053SJung-uk Kim         int digest_nid = SSL_CIPHER_get_digest_nid(c);
2128e71b7053SJung-uk Kim         const EVP_MD *e_md = EVP_get_digestbynid(digest_nid);
2129e71b7053SJung-uk Kim 
2130e71b7053SJung-uk Kim         if (e_md == NULL)
2131e71b7053SJung-uk Kim             return 0;
2132e71b7053SJung-uk Kim 
2133e71b7053SJung-uk Kim         mac = EVP_MD_size(e_md);
2134e71b7053SJung-uk Kim         if (c->algorithm_enc != SSL_eNULL) {
2135e71b7053SJung-uk Kim             int cipher_nid = SSL_CIPHER_get_cipher_nid(c);
2136e71b7053SJung-uk Kim             const EVP_CIPHER *e_ciph = EVP_get_cipherbynid(cipher_nid);
2137e71b7053SJung-uk Kim 
2138e71b7053SJung-uk Kim             /* If it wasn't AEAD or SSL_eNULL, we expect it to be a
2139e71b7053SJung-uk Kim                known CBC cipher. */
2140e71b7053SJung-uk Kim             if (e_ciph == NULL ||
2141e71b7053SJung-uk Kim                 EVP_CIPHER_mode(e_ciph) != EVP_CIPH_CBC_MODE)
2142e71b7053SJung-uk Kim                 return 0;
2143e71b7053SJung-uk Kim 
2144e71b7053SJung-uk Kim             in = 1; /* padding length byte */
2145e71b7053SJung-uk Kim             out = EVP_CIPHER_iv_length(e_ciph);
2146e71b7053SJung-uk Kim             blk = EVP_CIPHER_block_size(e_ciph);
2147e71b7053SJung-uk Kim         }
2148e71b7053SJung-uk Kim     }
2149e71b7053SJung-uk Kim 
2150e71b7053SJung-uk Kim     *mac_overhead = mac;
2151e71b7053SJung-uk Kim     *int_overhead = in;
2152e71b7053SJung-uk Kim     *blocksize = blk;
2153e71b7053SJung-uk Kim     *ext_overhead = out;
2154e71b7053SJung-uk Kim 
2155e71b7053SJung-uk Kim     return 1;
2156e71b7053SJung-uk Kim }
2157e71b7053SJung-uk Kim 
2158e71b7053SJung-uk Kim int ssl_cert_is_disabled(size_t idx)
2159e71b7053SJung-uk Kim {
2160e71b7053SJung-uk Kim     const SSL_CERT_LOOKUP *cl = ssl_cert_lookup_by_idx(idx);
2161e71b7053SJung-uk Kim 
2162e71b7053SJung-uk Kim     if (cl == NULL || (cl->amask & disabled_auth_mask) != 0)
2163e71b7053SJung-uk Kim         return 1;
2164e71b7053SJung-uk Kim     return 0;
2165e71b7053SJung-uk Kim }
2166