1*f5b1c8a1SJohn Marino /* $OpenBSD: ssl_ciph.c,v 1.85 2016/04/28 16:06:53 jsing Exp $ */ 2*f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3*f5b1c8a1SJohn Marino * All rights reserved. 4*f5b1c8a1SJohn Marino * 5*f5b1c8a1SJohn Marino * This package is an SSL implementation written 6*f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com). 7*f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL. 8*f5b1c8a1SJohn Marino * 9*f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as 10*f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions 11*f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA, 12*f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13*f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms 14*f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15*f5b1c8a1SJohn Marino * 16*f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in 17*f5b1c8a1SJohn Marino * the code are not to be removed. 18*f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution 19*f5b1c8a1SJohn Marino * as the author of the parts of the library used. 20*f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or 21*f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package. 22*f5b1c8a1SJohn Marino * 23*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 24*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 25*f5b1c8a1SJohn Marino * are met: 26*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright 27*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 28*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 29*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the 30*f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution. 31*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software 32*f5b1c8a1SJohn Marino * must display the following acknowledgement: 33*f5b1c8a1SJohn Marino * "This product includes cryptographic software written by 34*f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)" 35*f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library 36*f5b1c8a1SJohn Marino * being used are not cryptographic related :-). 37*f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from 38*f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement: 39*f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40*f5b1c8a1SJohn Marino * 41*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42*f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44*f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45*f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46*f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47*f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49*f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50*f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51*f5b1c8a1SJohn Marino * SUCH DAMAGE. 52*f5b1c8a1SJohn Marino * 53*f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or 54*f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be 55*f5b1c8a1SJohn Marino * copied and put under another distribution licence 56*f5b1c8a1SJohn Marino * [including the GNU Public Licence.] 57*f5b1c8a1SJohn Marino */ 58*f5b1c8a1SJohn Marino /* ==================================================================== 59*f5b1c8a1SJohn Marino * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. 60*f5b1c8a1SJohn Marino * 61*f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without 62*f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions 63*f5b1c8a1SJohn Marino * are met: 64*f5b1c8a1SJohn Marino * 65*f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the above copyright 66*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer. 67*f5b1c8a1SJohn Marino * 68*f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright 69*f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in 70*f5b1c8a1SJohn Marino * the documentation and/or other materials provided with the 71*f5b1c8a1SJohn Marino * distribution. 72*f5b1c8a1SJohn Marino * 73*f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this 74*f5b1c8a1SJohn Marino * software must display the following acknowledgment: 75*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 76*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77*f5b1c8a1SJohn Marino * 78*f5b1c8a1SJohn Marino * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79*f5b1c8a1SJohn Marino * endorse or promote products derived from this software without 80*f5b1c8a1SJohn Marino * prior written permission. For written permission, please contact 81*f5b1c8a1SJohn Marino * openssl-core@openssl.org. 82*f5b1c8a1SJohn Marino * 83*f5b1c8a1SJohn Marino * 5. Products derived from this software may not be called "OpenSSL" 84*f5b1c8a1SJohn Marino * nor may "OpenSSL" appear in their names without prior written 85*f5b1c8a1SJohn Marino * permission of the OpenSSL Project. 86*f5b1c8a1SJohn Marino * 87*f5b1c8a1SJohn Marino * 6. Redistributions of any form whatsoever must retain the following 88*f5b1c8a1SJohn Marino * acknowledgment: 89*f5b1c8a1SJohn Marino * "This product includes software developed by the OpenSSL Project 90*f5b1c8a1SJohn Marino * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91*f5b1c8a1SJohn Marino * 92*f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93*f5b1c8a1SJohn Marino * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94*f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95*f5b1c8a1SJohn Marino * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96*f5b1c8a1SJohn Marino * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97*f5b1c8a1SJohn Marino * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98*f5b1c8a1SJohn Marino * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99*f5b1c8a1SJohn Marino * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100*f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101*f5b1c8a1SJohn Marino * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102*f5b1c8a1SJohn Marino * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103*f5b1c8a1SJohn Marino * OF THE POSSIBILITY OF SUCH DAMAGE. 104*f5b1c8a1SJohn Marino * ==================================================================== 105*f5b1c8a1SJohn Marino * 106*f5b1c8a1SJohn Marino * This product includes cryptographic software written by Eric Young 107*f5b1c8a1SJohn Marino * (eay@cryptsoft.com). This product includes software written by Tim 108*f5b1c8a1SJohn Marino * Hudson (tjh@cryptsoft.com). 109*f5b1c8a1SJohn Marino * 110*f5b1c8a1SJohn Marino */ 111*f5b1c8a1SJohn Marino /* ==================================================================== 112*f5b1c8a1SJohn Marino * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113*f5b1c8a1SJohn Marino * ECC cipher suite support in OpenSSL originally developed by 114*f5b1c8a1SJohn Marino * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115*f5b1c8a1SJohn Marino */ 116*f5b1c8a1SJohn Marino /* ==================================================================== 117*f5b1c8a1SJohn Marino * Copyright 2005 Nokia. All rights reserved. 118*f5b1c8a1SJohn Marino * 119*f5b1c8a1SJohn Marino * The portions of the attached software ("Contribution") is developed by 120*f5b1c8a1SJohn Marino * Nokia Corporation and is licensed pursuant to the OpenSSL open source 121*f5b1c8a1SJohn Marino * license. 122*f5b1c8a1SJohn Marino * 123*f5b1c8a1SJohn Marino * The Contribution, originally written by Mika Kousa and Pasi Eronen of 124*f5b1c8a1SJohn Marino * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 125*f5b1c8a1SJohn Marino * support (see RFC 4279) to OpenSSL. 126*f5b1c8a1SJohn Marino * 127*f5b1c8a1SJohn Marino * No patent licenses or other rights except those expressly stated in 128*f5b1c8a1SJohn Marino * the OpenSSL open source license shall be deemed granted or received 129*f5b1c8a1SJohn Marino * expressly, by implication, estoppel, or otherwise. 130*f5b1c8a1SJohn Marino * 131*f5b1c8a1SJohn Marino * No assurances are provided by Nokia that the Contribution does not 132*f5b1c8a1SJohn Marino * infringe the patent or other intellectual property rights of any third 133*f5b1c8a1SJohn Marino * party or that the license provides you with all the necessary rights 134*f5b1c8a1SJohn Marino * to make use of the Contribution. 135*f5b1c8a1SJohn Marino * 136*f5b1c8a1SJohn Marino * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 137*f5b1c8a1SJohn Marino * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 138*f5b1c8a1SJohn Marino * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 139*f5b1c8a1SJohn Marino * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 140*f5b1c8a1SJohn Marino * OTHERWISE. 141*f5b1c8a1SJohn Marino */ 142*f5b1c8a1SJohn Marino 143*f5b1c8a1SJohn Marino #include <stdio.h> 144*f5b1c8a1SJohn Marino 145*f5b1c8a1SJohn Marino #include <openssl/objects.h> 146*f5b1c8a1SJohn Marino 147*f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_ENGINE 148*f5b1c8a1SJohn Marino #include <openssl/engine.h> 149*f5b1c8a1SJohn Marino #endif 150*f5b1c8a1SJohn Marino 151*f5b1c8a1SJohn Marino #include "ssl_locl.h" 152*f5b1c8a1SJohn Marino 153*f5b1c8a1SJohn Marino #define SSL_ENC_DES_IDX 0 154*f5b1c8a1SJohn Marino #define SSL_ENC_3DES_IDX 1 155*f5b1c8a1SJohn Marino #define SSL_ENC_RC4_IDX 2 156*f5b1c8a1SJohn Marino #define SSL_ENC_IDEA_IDX 3 157*f5b1c8a1SJohn Marino #define SSL_ENC_NULL_IDX 4 158*f5b1c8a1SJohn Marino #define SSL_ENC_AES128_IDX 5 159*f5b1c8a1SJohn Marino #define SSL_ENC_AES256_IDX 6 160*f5b1c8a1SJohn Marino #define SSL_ENC_CAMELLIA128_IDX 7 161*f5b1c8a1SJohn Marino #define SSL_ENC_CAMELLIA256_IDX 8 162*f5b1c8a1SJohn Marino #define SSL_ENC_GOST89_IDX 9 163*f5b1c8a1SJohn Marino #define SSL_ENC_AES128GCM_IDX 10 164*f5b1c8a1SJohn Marino #define SSL_ENC_AES256GCM_IDX 11 165*f5b1c8a1SJohn Marino #define SSL_ENC_NUM_IDX 12 166*f5b1c8a1SJohn Marino 167*f5b1c8a1SJohn Marino 168*f5b1c8a1SJohn Marino static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { 169*f5b1c8a1SJohn Marino NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 170*f5b1c8a1SJohn Marino }; 171*f5b1c8a1SJohn Marino 172*f5b1c8a1SJohn Marino #define SSL_MD_MD5_IDX 0 173*f5b1c8a1SJohn Marino #define SSL_MD_SHA1_IDX 1 174*f5b1c8a1SJohn Marino #define SSL_MD_GOST94_IDX 2 175*f5b1c8a1SJohn Marino #define SSL_MD_GOST89MAC_IDX 3 176*f5b1c8a1SJohn Marino #define SSL_MD_SHA256_IDX 4 177*f5b1c8a1SJohn Marino #define SSL_MD_SHA384_IDX 5 178*f5b1c8a1SJohn Marino #define SSL_MD_STREEBOG256_IDX 6 179*f5b1c8a1SJohn Marino #define SSL_MD_STREEBOG512_IDX 7 180*f5b1c8a1SJohn Marino /*Constant SSL_MAX_DIGEST equal to size of digests array should be 181*f5b1c8a1SJohn Marino * defined in the 182*f5b1c8a1SJohn Marino * ssl_locl.h */ 183*f5b1c8a1SJohn Marino #define SSL_MD_NUM_IDX SSL_MAX_DIGEST 184*f5b1c8a1SJohn Marino static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { 185*f5b1c8a1SJohn Marino NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 186*f5b1c8a1SJohn Marino }; 187*f5b1c8a1SJohn Marino 188*f5b1c8a1SJohn Marino static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { 189*f5b1c8a1SJohn Marino EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_GOSTIMIT, 190*f5b1c8a1SJohn Marino EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, 191*f5b1c8a1SJohn Marino }; 192*f5b1c8a1SJohn Marino 193*f5b1c8a1SJohn Marino static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { 194*f5b1c8a1SJohn Marino 0, 0, 0, 0, 0, 0, 0, 0 195*f5b1c8a1SJohn Marino }; 196*f5b1c8a1SJohn Marino 197*f5b1c8a1SJohn Marino static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { 198*f5b1c8a1SJohn Marino SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, 199*f5b1c8a1SJohn Marino SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, 200*f5b1c8a1SJohn Marino SSL_HANDSHAKE_MAC_SHA384, SSL_HANDSHAKE_MAC_STREEBOG256, 201*f5b1c8a1SJohn Marino SSL_HANDSHAKE_MAC_STREEBOG512 202*f5b1c8a1SJohn Marino }; 203*f5b1c8a1SJohn Marino 204*f5b1c8a1SJohn Marino #define CIPHER_ADD 1 205*f5b1c8a1SJohn Marino #define CIPHER_KILL 2 206*f5b1c8a1SJohn Marino #define CIPHER_DEL 3 207*f5b1c8a1SJohn Marino #define CIPHER_ORD 4 208*f5b1c8a1SJohn Marino #define CIPHER_SPECIAL 5 209*f5b1c8a1SJohn Marino 210*f5b1c8a1SJohn Marino typedef struct cipher_order_st { 211*f5b1c8a1SJohn Marino const SSL_CIPHER *cipher; 212*f5b1c8a1SJohn Marino int active; 213*f5b1c8a1SJohn Marino int dead; 214*f5b1c8a1SJohn Marino struct cipher_order_st *next, *prev; 215*f5b1c8a1SJohn Marino } CIPHER_ORDER; 216*f5b1c8a1SJohn Marino 217*f5b1c8a1SJohn Marino static const SSL_CIPHER cipher_aliases[] = { 218*f5b1c8a1SJohn Marino 219*f5b1c8a1SJohn Marino /* "ALL" doesn't include eNULL (must be specifically enabled) */ 220*f5b1c8a1SJohn Marino { 221*f5b1c8a1SJohn Marino .name = SSL_TXT_ALL, 222*f5b1c8a1SJohn Marino .algorithm_enc = ~SSL_eNULL, 223*f5b1c8a1SJohn Marino }, 224*f5b1c8a1SJohn Marino 225*f5b1c8a1SJohn Marino /* "COMPLEMENTOFALL" */ 226*f5b1c8a1SJohn Marino { 227*f5b1c8a1SJohn Marino .name = SSL_TXT_CMPALL, 228*f5b1c8a1SJohn Marino .algorithm_enc = SSL_eNULL, 229*f5b1c8a1SJohn Marino }, 230*f5b1c8a1SJohn Marino 231*f5b1c8a1SJohn Marino /* 232*f5b1c8a1SJohn Marino * "COMPLEMENTOFDEFAULT" 233*f5b1c8a1SJohn Marino * (does *not* include ciphersuites not found in ALL!) 234*f5b1c8a1SJohn Marino */ 235*f5b1c8a1SJohn Marino { 236*f5b1c8a1SJohn Marino .name = SSL_TXT_CMPDEF, 237*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE|SSL_kECDHE, 238*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aNULL, 239*f5b1c8a1SJohn Marino .algorithm_enc = ~SSL_eNULL, 240*f5b1c8a1SJohn Marino }, 241*f5b1c8a1SJohn Marino 242*f5b1c8a1SJohn Marino /* 243*f5b1c8a1SJohn Marino * key exchange aliases 244*f5b1c8a1SJohn Marino * (some of those using only a single bit here combine multiple key 245*f5b1c8a1SJohn Marino * exchange algs according to the RFCs, e.g. kEDH combines DHE_DSS 246*f5b1c8a1SJohn Marino * and DHE_RSA) 247*f5b1c8a1SJohn Marino */ 248*f5b1c8a1SJohn Marino { 249*f5b1c8a1SJohn Marino .name = SSL_TXT_kRSA, 250*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kRSA, 251*f5b1c8a1SJohn Marino }, 252*f5b1c8a1SJohn Marino { 253*f5b1c8a1SJohn Marino .name = SSL_TXT_kEDH, 254*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE, 255*f5b1c8a1SJohn Marino }, 256*f5b1c8a1SJohn Marino { 257*f5b1c8a1SJohn Marino .name = SSL_TXT_DH, 258*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE, 259*f5b1c8a1SJohn Marino }, 260*f5b1c8a1SJohn Marino 261*f5b1c8a1SJohn Marino { 262*f5b1c8a1SJohn Marino .name = SSL_TXT_kECDHr, 263*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHr, 264*f5b1c8a1SJohn Marino }, 265*f5b1c8a1SJohn Marino { 266*f5b1c8a1SJohn Marino .name = SSL_TXT_kECDHe, 267*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHe, 268*f5b1c8a1SJohn Marino }, 269*f5b1c8a1SJohn Marino { 270*f5b1c8a1SJohn Marino .name = SSL_TXT_kECDH, 271*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHr|SSL_kECDHe, 272*f5b1c8a1SJohn Marino }, 273*f5b1c8a1SJohn Marino { 274*f5b1c8a1SJohn Marino .name = SSL_TXT_kEECDH, 275*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHE, 276*f5b1c8a1SJohn Marino }, 277*f5b1c8a1SJohn Marino { 278*f5b1c8a1SJohn Marino .name = SSL_TXT_ECDH, 279*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHr|SSL_kECDHe|SSL_kECDHE, 280*f5b1c8a1SJohn Marino }, 281*f5b1c8a1SJohn Marino 282*f5b1c8a1SJohn Marino { 283*f5b1c8a1SJohn Marino .name = SSL_TXT_kGOST, 284*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kGOST, 285*f5b1c8a1SJohn Marino }, 286*f5b1c8a1SJohn Marino 287*f5b1c8a1SJohn Marino /* server authentication aliases */ 288*f5b1c8a1SJohn Marino { 289*f5b1c8a1SJohn Marino .name = SSL_TXT_aRSA, 290*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aRSA, 291*f5b1c8a1SJohn Marino }, 292*f5b1c8a1SJohn Marino { 293*f5b1c8a1SJohn Marino .name = SSL_TXT_aDSS, 294*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aDSS, 295*f5b1c8a1SJohn Marino }, 296*f5b1c8a1SJohn Marino { 297*f5b1c8a1SJohn Marino .name = SSL_TXT_DSS, 298*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aDSS, 299*f5b1c8a1SJohn Marino }, 300*f5b1c8a1SJohn Marino { 301*f5b1c8a1SJohn Marino .name = SSL_TXT_aNULL, 302*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aNULL, 303*f5b1c8a1SJohn Marino }, 304*f5b1c8a1SJohn Marino { 305*f5b1c8a1SJohn Marino .name = SSL_TXT_aECDH, 306*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aECDH, 307*f5b1c8a1SJohn Marino }, 308*f5b1c8a1SJohn Marino { 309*f5b1c8a1SJohn Marino .name = SSL_TXT_aECDSA, 310*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aECDSA, 311*f5b1c8a1SJohn Marino }, 312*f5b1c8a1SJohn Marino { 313*f5b1c8a1SJohn Marino .name = SSL_TXT_ECDSA, 314*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aECDSA, 315*f5b1c8a1SJohn Marino }, 316*f5b1c8a1SJohn Marino { 317*f5b1c8a1SJohn Marino .name = SSL_TXT_aGOST01, 318*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aGOST01, 319*f5b1c8a1SJohn Marino }, 320*f5b1c8a1SJohn Marino { 321*f5b1c8a1SJohn Marino .name = SSL_TXT_aGOST, 322*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aGOST01, 323*f5b1c8a1SJohn Marino }, 324*f5b1c8a1SJohn Marino 325*f5b1c8a1SJohn Marino /* aliases combining key exchange and server authentication */ 326*f5b1c8a1SJohn Marino { 327*f5b1c8a1SJohn Marino .name = SSL_TXT_DHE, 328*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE, 329*f5b1c8a1SJohn Marino .algorithm_auth = ~SSL_aNULL, 330*f5b1c8a1SJohn Marino }, 331*f5b1c8a1SJohn Marino { 332*f5b1c8a1SJohn Marino .name = SSL_TXT_EDH, 333*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE, 334*f5b1c8a1SJohn Marino .algorithm_auth = ~SSL_aNULL, 335*f5b1c8a1SJohn Marino }, 336*f5b1c8a1SJohn Marino { 337*f5b1c8a1SJohn Marino .name = SSL_TXT_ECDHE, 338*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHE, 339*f5b1c8a1SJohn Marino .algorithm_auth = ~SSL_aNULL, 340*f5b1c8a1SJohn Marino }, 341*f5b1c8a1SJohn Marino { 342*f5b1c8a1SJohn Marino .name = SSL_TXT_EECDH, 343*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHE, 344*f5b1c8a1SJohn Marino .algorithm_auth = ~SSL_aNULL, 345*f5b1c8a1SJohn Marino }, 346*f5b1c8a1SJohn Marino { 347*f5b1c8a1SJohn Marino .name = SSL_TXT_NULL, 348*f5b1c8a1SJohn Marino .algorithm_enc = SSL_eNULL, 349*f5b1c8a1SJohn Marino }, 350*f5b1c8a1SJohn Marino { 351*f5b1c8a1SJohn Marino .name = SSL_TXT_RSA, 352*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kRSA, 353*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aRSA, 354*f5b1c8a1SJohn Marino }, 355*f5b1c8a1SJohn Marino { 356*f5b1c8a1SJohn Marino .name = SSL_TXT_ADH, 357*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kDHE, 358*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aNULL, 359*f5b1c8a1SJohn Marino }, 360*f5b1c8a1SJohn Marino { 361*f5b1c8a1SJohn Marino .name = SSL_TXT_AECDH, 362*f5b1c8a1SJohn Marino .algorithm_mkey = SSL_kECDHE, 363*f5b1c8a1SJohn Marino .algorithm_auth = SSL_aNULL, 364*f5b1c8a1SJohn Marino }, 365*f5b1c8a1SJohn Marino 366*f5b1c8a1SJohn Marino /* symmetric encryption aliases */ 367*f5b1c8a1SJohn Marino { 368*f5b1c8a1SJohn Marino .name = SSL_TXT_DES, 369*f5b1c8a1SJohn Marino .algorithm_enc = SSL_DES, 370*f5b1c8a1SJohn Marino }, 371*f5b1c8a1SJohn Marino { 372*f5b1c8a1SJohn Marino .name = SSL_TXT_3DES, 373*f5b1c8a1SJohn Marino .algorithm_enc = SSL_3DES, 374*f5b1c8a1SJohn Marino }, 375*f5b1c8a1SJohn Marino { 376*f5b1c8a1SJohn Marino .name = SSL_TXT_RC4, 377*f5b1c8a1SJohn Marino .algorithm_enc = SSL_RC4, 378*f5b1c8a1SJohn Marino }, 379*f5b1c8a1SJohn Marino { 380*f5b1c8a1SJohn Marino .name = SSL_TXT_IDEA, 381*f5b1c8a1SJohn Marino .algorithm_enc = SSL_IDEA, 382*f5b1c8a1SJohn Marino }, 383*f5b1c8a1SJohn Marino { 384*f5b1c8a1SJohn Marino .name = SSL_TXT_eNULL, 385*f5b1c8a1SJohn Marino .algorithm_enc = SSL_eNULL, 386*f5b1c8a1SJohn Marino }, 387*f5b1c8a1SJohn Marino { 388*f5b1c8a1SJohn Marino .name = SSL_TXT_AES128, 389*f5b1c8a1SJohn Marino .algorithm_enc = SSL_AES128|SSL_AES128GCM, 390*f5b1c8a1SJohn Marino }, 391*f5b1c8a1SJohn Marino { 392*f5b1c8a1SJohn Marino .name = SSL_TXT_AES256, 393*f5b1c8a1SJohn Marino .algorithm_enc = SSL_AES256|SSL_AES256GCM, 394*f5b1c8a1SJohn Marino }, 395*f5b1c8a1SJohn Marino { 396*f5b1c8a1SJohn Marino .name = SSL_TXT_AES, 397*f5b1c8a1SJohn Marino .algorithm_enc = SSL_AES, 398*f5b1c8a1SJohn Marino }, 399*f5b1c8a1SJohn Marino { 400*f5b1c8a1SJohn Marino .name = SSL_TXT_AES_GCM, 401*f5b1c8a1SJohn Marino .algorithm_enc = SSL_AES128GCM|SSL_AES256GCM, 402*f5b1c8a1SJohn Marino }, 403*f5b1c8a1SJohn Marino { 404*f5b1c8a1SJohn Marino .name = SSL_TXT_CAMELLIA128, 405*f5b1c8a1SJohn Marino .algorithm_enc = SSL_CAMELLIA128, 406*f5b1c8a1SJohn Marino }, 407*f5b1c8a1SJohn Marino { 408*f5b1c8a1SJohn Marino .name = SSL_TXT_CAMELLIA256, 409*f5b1c8a1SJohn Marino .algorithm_enc = SSL_CAMELLIA256, 410*f5b1c8a1SJohn Marino }, 411*f5b1c8a1SJohn Marino { 412*f5b1c8a1SJohn Marino .name = SSL_TXT_CAMELLIA, 413*f5b1c8a1SJohn Marino .algorithm_enc = SSL_CAMELLIA128|SSL_CAMELLIA256, 414*f5b1c8a1SJohn Marino }, 415*f5b1c8a1SJohn Marino { 416*f5b1c8a1SJohn Marino .name = SSL_TXT_CHACHA20, 417*f5b1c8a1SJohn Marino .algorithm_enc = SSL_CHACHA20POLY1305|SSL_CHACHA20POLY1305_OLD, 418*f5b1c8a1SJohn Marino }, 419*f5b1c8a1SJohn Marino 420*f5b1c8a1SJohn Marino /* MAC aliases */ 421*f5b1c8a1SJohn Marino { 422*f5b1c8a1SJohn Marino .name = SSL_TXT_AEAD, 423*f5b1c8a1SJohn Marino .algorithm_mac = SSL_AEAD, 424*f5b1c8a1SJohn Marino }, 425*f5b1c8a1SJohn Marino { 426*f5b1c8a1SJohn Marino .name = SSL_TXT_MD5, 427*f5b1c8a1SJohn Marino .algorithm_mac = SSL_MD5, 428*f5b1c8a1SJohn Marino }, 429*f5b1c8a1SJohn Marino { 430*f5b1c8a1SJohn Marino .name = SSL_TXT_SHA1, 431*f5b1c8a1SJohn Marino .algorithm_mac = SSL_SHA1, 432*f5b1c8a1SJohn Marino }, 433*f5b1c8a1SJohn Marino { 434*f5b1c8a1SJohn Marino .name = SSL_TXT_SHA, 435*f5b1c8a1SJohn Marino .algorithm_mac = SSL_SHA1, 436*f5b1c8a1SJohn Marino }, 437*f5b1c8a1SJohn Marino { 438*f5b1c8a1SJohn Marino .name = SSL_TXT_GOST94, 439*f5b1c8a1SJohn Marino .algorithm_mac = SSL_GOST94, 440*f5b1c8a1SJohn Marino }, 441*f5b1c8a1SJohn Marino { 442*f5b1c8a1SJohn Marino .name = SSL_TXT_GOST89MAC, 443*f5b1c8a1SJohn Marino .algorithm_mac = SSL_GOST89MAC, 444*f5b1c8a1SJohn Marino }, 445*f5b1c8a1SJohn Marino { 446*f5b1c8a1SJohn Marino .name = SSL_TXT_SHA256, 447*f5b1c8a1SJohn Marino .algorithm_mac = SSL_SHA256, 448*f5b1c8a1SJohn Marino }, 449*f5b1c8a1SJohn Marino { 450*f5b1c8a1SJohn Marino .name = SSL_TXT_SHA384, 451*f5b1c8a1SJohn Marino .algorithm_mac = SSL_SHA384, 452*f5b1c8a1SJohn Marino }, 453*f5b1c8a1SJohn Marino { 454*f5b1c8a1SJohn Marino .name = SSL_TXT_STREEBOG256, 455*f5b1c8a1SJohn Marino .algorithm_mac = SSL_STREEBOG256, 456*f5b1c8a1SJohn Marino }, 457*f5b1c8a1SJohn Marino { 458*f5b1c8a1SJohn Marino .name = SSL_TXT_STREEBOG512, 459*f5b1c8a1SJohn Marino .algorithm_mac = SSL_STREEBOG512, 460*f5b1c8a1SJohn Marino }, 461*f5b1c8a1SJohn Marino 462*f5b1c8a1SJohn Marino /* protocol version aliases */ 463*f5b1c8a1SJohn Marino { 464*f5b1c8a1SJohn Marino .name = SSL_TXT_SSLV3, 465*f5b1c8a1SJohn Marino .algorithm_ssl = SSL_SSLV3, 466*f5b1c8a1SJohn Marino }, 467*f5b1c8a1SJohn Marino { 468*f5b1c8a1SJohn Marino .name = SSL_TXT_TLSV1, 469*f5b1c8a1SJohn Marino .algorithm_ssl = SSL_TLSV1, 470*f5b1c8a1SJohn Marino }, 471*f5b1c8a1SJohn Marino { 472*f5b1c8a1SJohn Marino .name = SSL_TXT_TLSV1_2, 473*f5b1c8a1SJohn Marino .algorithm_ssl = SSL_TLSV1_2, 474*f5b1c8a1SJohn Marino }, 475*f5b1c8a1SJohn Marino 476*f5b1c8a1SJohn Marino /* strength classes */ 477*f5b1c8a1SJohn Marino { 478*f5b1c8a1SJohn Marino .name = SSL_TXT_LOW, 479*f5b1c8a1SJohn Marino .algo_strength = SSL_LOW, 480*f5b1c8a1SJohn Marino }, 481*f5b1c8a1SJohn Marino { 482*f5b1c8a1SJohn Marino .name = SSL_TXT_MEDIUM, 483*f5b1c8a1SJohn Marino .algo_strength = SSL_MEDIUM, 484*f5b1c8a1SJohn Marino }, 485*f5b1c8a1SJohn Marino { 486*f5b1c8a1SJohn Marino .name = SSL_TXT_HIGH, 487*f5b1c8a1SJohn Marino .algo_strength = SSL_HIGH, 488*f5b1c8a1SJohn Marino }, 489*f5b1c8a1SJohn Marino }; 490*f5b1c8a1SJohn Marino 491*f5b1c8a1SJohn Marino void 492*f5b1c8a1SJohn Marino ssl_load_ciphers(void) 493*f5b1c8a1SJohn Marino { 494*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_DES_IDX] = 495*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_des_cbc); 496*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_3DES_IDX] = 497*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_des_ede3_cbc); 498*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_RC4_IDX] = 499*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_rc4); 500*f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_IDEA 501*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_IDEA_IDX] = 502*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_idea_cbc); 503*f5b1c8a1SJohn Marino #else 504*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; 505*f5b1c8a1SJohn Marino #endif 506*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_AES128_IDX] = 507*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_aes_128_cbc); 508*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_AES256_IDX] = 509*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_aes_256_cbc); 510*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = 511*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_camellia_128_cbc); 512*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = 513*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_camellia_256_cbc); 514*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_GOST89_IDX] = 515*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_gost89_cnt); 516*f5b1c8a1SJohn Marino 517*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = 518*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_aes_128_gcm); 519*f5b1c8a1SJohn Marino ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = 520*f5b1c8a1SJohn Marino EVP_get_cipherbyname(SN_aes_256_gcm); 521*f5b1c8a1SJohn Marino 522*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_MD5_IDX] = 523*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_md5); 524*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_MD5_IDX] = 525*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); 526*f5b1c8a1SJohn Marino OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); 527*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_SHA1_IDX] = 528*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_sha1); 529*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_SHA1_IDX] = 530*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); 531*f5b1c8a1SJohn Marino OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); 532*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_GOST94_IDX] = 533*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_id_GostR3411_94); 534*f5b1c8a1SJohn Marino if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { 535*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_GOST94_IDX] = 536*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); 537*f5b1c8a1SJohn Marino OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); 538*f5b1c8a1SJohn Marino } 539*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = 540*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_id_Gost28147_89_MAC); 541*f5b1c8a1SJohn Marino if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { 542*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; 543*f5b1c8a1SJohn Marino } 544*f5b1c8a1SJohn Marino 545*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_SHA256_IDX] = 546*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_sha256); 547*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_SHA256_IDX] = 548*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); 549*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_SHA384_IDX] = 550*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_sha384); 551*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_SHA384_IDX] = 552*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); 553*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_STREEBOG256_IDX] = 554*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_id_tc26_gost3411_2012_256); 555*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_STREEBOG256_IDX] = 556*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG256_IDX]); 557*f5b1c8a1SJohn Marino ssl_digest_methods[SSL_MD_STREEBOG512_IDX] = 558*f5b1c8a1SJohn Marino EVP_get_digestbyname(SN_id_tc26_gost3411_2012_512); 559*f5b1c8a1SJohn Marino ssl_mac_secret_size[SSL_MD_STREEBOG512_IDX] = 560*f5b1c8a1SJohn Marino EVP_MD_size(ssl_digest_methods[SSL_MD_STREEBOG512_IDX]); 561*f5b1c8a1SJohn Marino } 562*f5b1c8a1SJohn Marino 563*f5b1c8a1SJohn Marino int 564*f5b1c8a1SJohn Marino ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, 565*f5b1c8a1SJohn Marino const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size) 566*f5b1c8a1SJohn Marino { 567*f5b1c8a1SJohn Marino const SSL_CIPHER *c; 568*f5b1c8a1SJohn Marino int i; 569*f5b1c8a1SJohn Marino 570*f5b1c8a1SJohn Marino c = s->cipher; 571*f5b1c8a1SJohn Marino if (c == NULL) 572*f5b1c8a1SJohn Marino return (0); 573*f5b1c8a1SJohn Marino 574*f5b1c8a1SJohn Marino /* 575*f5b1c8a1SJohn Marino * This function does not handle EVP_AEAD. 576*f5b1c8a1SJohn Marino * See ssl_cipher_get_aead_evp instead. 577*f5b1c8a1SJohn Marino */ 578*f5b1c8a1SJohn Marino if (c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) 579*f5b1c8a1SJohn Marino return(0); 580*f5b1c8a1SJohn Marino 581*f5b1c8a1SJohn Marino if ((enc == NULL) || (md == NULL)) 582*f5b1c8a1SJohn Marino return (0); 583*f5b1c8a1SJohn Marino 584*f5b1c8a1SJohn Marino switch (c->algorithm_enc) { 585*f5b1c8a1SJohn Marino case SSL_DES: 586*f5b1c8a1SJohn Marino i = SSL_ENC_DES_IDX; 587*f5b1c8a1SJohn Marino break; 588*f5b1c8a1SJohn Marino case SSL_3DES: 589*f5b1c8a1SJohn Marino i = SSL_ENC_3DES_IDX; 590*f5b1c8a1SJohn Marino break; 591*f5b1c8a1SJohn Marino case SSL_RC4: 592*f5b1c8a1SJohn Marino i = SSL_ENC_RC4_IDX; 593*f5b1c8a1SJohn Marino break; 594*f5b1c8a1SJohn Marino case SSL_IDEA: 595*f5b1c8a1SJohn Marino i = SSL_ENC_IDEA_IDX; 596*f5b1c8a1SJohn Marino break; 597*f5b1c8a1SJohn Marino case SSL_eNULL: 598*f5b1c8a1SJohn Marino i = SSL_ENC_NULL_IDX; 599*f5b1c8a1SJohn Marino break; 600*f5b1c8a1SJohn Marino case SSL_AES128: 601*f5b1c8a1SJohn Marino i = SSL_ENC_AES128_IDX; 602*f5b1c8a1SJohn Marino break; 603*f5b1c8a1SJohn Marino case SSL_AES256: 604*f5b1c8a1SJohn Marino i = SSL_ENC_AES256_IDX; 605*f5b1c8a1SJohn Marino break; 606*f5b1c8a1SJohn Marino case SSL_CAMELLIA128: 607*f5b1c8a1SJohn Marino i = SSL_ENC_CAMELLIA128_IDX; 608*f5b1c8a1SJohn Marino break; 609*f5b1c8a1SJohn Marino case SSL_CAMELLIA256: 610*f5b1c8a1SJohn Marino i = SSL_ENC_CAMELLIA256_IDX; 611*f5b1c8a1SJohn Marino break; 612*f5b1c8a1SJohn Marino case SSL_eGOST2814789CNT: 613*f5b1c8a1SJohn Marino i = SSL_ENC_GOST89_IDX; 614*f5b1c8a1SJohn Marino break; 615*f5b1c8a1SJohn Marino case SSL_AES128GCM: 616*f5b1c8a1SJohn Marino i = SSL_ENC_AES128GCM_IDX; 617*f5b1c8a1SJohn Marino break; 618*f5b1c8a1SJohn Marino case SSL_AES256GCM: 619*f5b1c8a1SJohn Marino i = SSL_ENC_AES256GCM_IDX; 620*f5b1c8a1SJohn Marino break; 621*f5b1c8a1SJohn Marino default: 622*f5b1c8a1SJohn Marino i = -1; 623*f5b1c8a1SJohn Marino break; 624*f5b1c8a1SJohn Marino } 625*f5b1c8a1SJohn Marino 626*f5b1c8a1SJohn Marino if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) 627*f5b1c8a1SJohn Marino *enc = NULL; 628*f5b1c8a1SJohn Marino else { 629*f5b1c8a1SJohn Marino if (i == SSL_ENC_NULL_IDX) 630*f5b1c8a1SJohn Marino *enc = EVP_enc_null(); 631*f5b1c8a1SJohn Marino else 632*f5b1c8a1SJohn Marino *enc = ssl_cipher_methods[i]; 633*f5b1c8a1SJohn Marino } 634*f5b1c8a1SJohn Marino 635*f5b1c8a1SJohn Marino switch (c->algorithm_mac) { 636*f5b1c8a1SJohn Marino case SSL_MD5: 637*f5b1c8a1SJohn Marino i = SSL_MD_MD5_IDX; 638*f5b1c8a1SJohn Marino break; 639*f5b1c8a1SJohn Marino case SSL_SHA1: 640*f5b1c8a1SJohn Marino i = SSL_MD_SHA1_IDX; 641*f5b1c8a1SJohn Marino break; 642*f5b1c8a1SJohn Marino case SSL_SHA256: 643*f5b1c8a1SJohn Marino i = SSL_MD_SHA256_IDX; 644*f5b1c8a1SJohn Marino break; 645*f5b1c8a1SJohn Marino case SSL_SHA384: 646*f5b1c8a1SJohn Marino i = SSL_MD_SHA384_IDX; 647*f5b1c8a1SJohn Marino break; 648*f5b1c8a1SJohn Marino case SSL_GOST94: 649*f5b1c8a1SJohn Marino i = SSL_MD_GOST94_IDX; 650*f5b1c8a1SJohn Marino break; 651*f5b1c8a1SJohn Marino case SSL_GOST89MAC: 652*f5b1c8a1SJohn Marino i = SSL_MD_GOST89MAC_IDX; 653*f5b1c8a1SJohn Marino break; 654*f5b1c8a1SJohn Marino case SSL_STREEBOG256: 655*f5b1c8a1SJohn Marino i = SSL_MD_STREEBOG256_IDX; 656*f5b1c8a1SJohn Marino break; 657*f5b1c8a1SJohn Marino case SSL_STREEBOG512: 658*f5b1c8a1SJohn Marino i = SSL_MD_STREEBOG512_IDX; 659*f5b1c8a1SJohn Marino break; 660*f5b1c8a1SJohn Marino default: 661*f5b1c8a1SJohn Marino i = -1; 662*f5b1c8a1SJohn Marino break; 663*f5b1c8a1SJohn Marino } 664*f5b1c8a1SJohn Marino if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { 665*f5b1c8a1SJohn Marino *md = NULL; 666*f5b1c8a1SJohn Marino 667*f5b1c8a1SJohn Marino if (mac_pkey_type != NULL) 668*f5b1c8a1SJohn Marino *mac_pkey_type = NID_undef; 669*f5b1c8a1SJohn Marino if (mac_secret_size != NULL) 670*f5b1c8a1SJohn Marino *mac_secret_size = 0; 671*f5b1c8a1SJohn Marino if (c->algorithm_mac == SSL_AEAD) 672*f5b1c8a1SJohn Marino mac_pkey_type = NULL; 673*f5b1c8a1SJohn Marino } else { 674*f5b1c8a1SJohn Marino *md = ssl_digest_methods[i]; 675*f5b1c8a1SJohn Marino if (mac_pkey_type != NULL) 676*f5b1c8a1SJohn Marino *mac_pkey_type = ssl_mac_pkey_id[i]; 677*f5b1c8a1SJohn Marino if (mac_secret_size != NULL) 678*f5b1c8a1SJohn Marino *mac_secret_size = ssl_mac_secret_size[i]; 679*f5b1c8a1SJohn Marino } 680*f5b1c8a1SJohn Marino 681*f5b1c8a1SJohn Marino if ((*enc != NULL) && 682*f5b1c8a1SJohn Marino (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) && 683*f5b1c8a1SJohn Marino (!mac_pkey_type || *mac_pkey_type != NID_undef)) { 684*f5b1c8a1SJohn Marino const EVP_CIPHER *evp; 685*f5b1c8a1SJohn Marino 686*f5b1c8a1SJohn Marino if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || 687*f5b1c8a1SJohn Marino s->ssl_version < TLS1_VERSION) 688*f5b1c8a1SJohn Marino return 1; 689*f5b1c8a1SJohn Marino 690*f5b1c8a1SJohn Marino if (c->algorithm_enc == SSL_RC4 && 691*f5b1c8a1SJohn Marino c->algorithm_mac == SSL_MD5 && 692*f5b1c8a1SJohn Marino (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) 693*f5b1c8a1SJohn Marino *enc = evp, *md = NULL; 694*f5b1c8a1SJohn Marino else if (c->algorithm_enc == SSL_AES128 && 695*f5b1c8a1SJohn Marino c->algorithm_mac == SSL_SHA1 && 696*f5b1c8a1SJohn Marino (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) 697*f5b1c8a1SJohn Marino *enc = evp, *md = NULL; 698*f5b1c8a1SJohn Marino else if (c->algorithm_enc == SSL_AES256 && 699*f5b1c8a1SJohn Marino c->algorithm_mac == SSL_SHA1 && 700*f5b1c8a1SJohn Marino (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) 701*f5b1c8a1SJohn Marino *enc = evp, *md = NULL; 702*f5b1c8a1SJohn Marino return (1); 703*f5b1c8a1SJohn Marino } else 704*f5b1c8a1SJohn Marino return (0); 705*f5b1c8a1SJohn Marino } 706*f5b1c8a1SJohn Marino 707*f5b1c8a1SJohn Marino /* 708*f5b1c8a1SJohn Marino * ssl_cipher_get_evp_aead sets aead to point to the correct EVP_AEAD object 709*f5b1c8a1SJohn Marino * for s->cipher. It returns 1 on success and 0 on error. 710*f5b1c8a1SJohn Marino */ 711*f5b1c8a1SJohn Marino int 712*f5b1c8a1SJohn Marino ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead) 713*f5b1c8a1SJohn Marino { 714*f5b1c8a1SJohn Marino const SSL_CIPHER *c = s->cipher; 715*f5b1c8a1SJohn Marino 716*f5b1c8a1SJohn Marino *aead = NULL; 717*f5b1c8a1SJohn Marino 718*f5b1c8a1SJohn Marino if (c == NULL) 719*f5b1c8a1SJohn Marino return 0; 720*f5b1c8a1SJohn Marino if ((c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) == 0) 721*f5b1c8a1SJohn Marino return 0; 722*f5b1c8a1SJohn Marino 723*f5b1c8a1SJohn Marino switch (c->algorithm_enc) { 724*f5b1c8a1SJohn Marino #ifndef OPENSSL_NO_AES 725*f5b1c8a1SJohn Marino case SSL_AES128GCM: 726*f5b1c8a1SJohn Marino *aead = EVP_aead_aes_128_gcm(); 727*f5b1c8a1SJohn Marino return 1; 728*f5b1c8a1SJohn Marino case SSL_AES256GCM: 729*f5b1c8a1SJohn Marino *aead = EVP_aead_aes_256_gcm(); 730*f5b1c8a1SJohn Marino return 1; 731*f5b1c8a1SJohn Marino #endif 732*f5b1c8a1SJohn Marino #if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) 733*f5b1c8a1SJohn Marino case SSL_CHACHA20POLY1305: 734*f5b1c8a1SJohn Marino *aead = EVP_aead_chacha20_poly1305(); 735*f5b1c8a1SJohn Marino return 1; 736*f5b1c8a1SJohn Marino case SSL_CHACHA20POLY1305_OLD: 737*f5b1c8a1SJohn Marino *aead = EVP_aead_chacha20_poly1305_old(); 738*f5b1c8a1SJohn Marino return 1; 739*f5b1c8a1SJohn Marino #endif 740*f5b1c8a1SJohn Marino default: 741*f5b1c8a1SJohn Marino break; 742*f5b1c8a1SJohn Marino } 743*f5b1c8a1SJohn Marino return 0; 744*f5b1c8a1SJohn Marino } 745*f5b1c8a1SJohn Marino 746*f5b1c8a1SJohn Marino int 747*f5b1c8a1SJohn Marino ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) 748*f5b1c8a1SJohn Marino { 749*f5b1c8a1SJohn Marino if (idx < 0 || idx >= SSL_MD_NUM_IDX) { 750*f5b1c8a1SJohn Marino return 0; 751*f5b1c8a1SJohn Marino } 752*f5b1c8a1SJohn Marino *mask = ssl_handshake_digest_flag[idx]; 753*f5b1c8a1SJohn Marino if (*mask) 754*f5b1c8a1SJohn Marino *md = ssl_digest_methods[idx]; 755*f5b1c8a1SJohn Marino else 756*f5b1c8a1SJohn Marino *md = NULL; 757*f5b1c8a1SJohn Marino return 1; 758*f5b1c8a1SJohn Marino } 759*f5b1c8a1SJohn Marino 760*f5b1c8a1SJohn Marino #define ITEM_SEP(a) \ 761*f5b1c8a1SJohn Marino (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) 762*f5b1c8a1SJohn Marino 763*f5b1c8a1SJohn Marino static void 764*f5b1c8a1SJohn Marino ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, 765*f5b1c8a1SJohn Marino CIPHER_ORDER **tail) 766*f5b1c8a1SJohn Marino { 767*f5b1c8a1SJohn Marino if (curr == *tail) 768*f5b1c8a1SJohn Marino return; 769*f5b1c8a1SJohn Marino if (curr == *head) 770*f5b1c8a1SJohn Marino *head = curr->next; 771*f5b1c8a1SJohn Marino if (curr->prev != NULL) 772*f5b1c8a1SJohn Marino curr->prev->next = curr->next; 773*f5b1c8a1SJohn Marino if (curr->next != NULL) 774*f5b1c8a1SJohn Marino curr->next->prev = curr->prev; 775*f5b1c8a1SJohn Marino (*tail)->next = curr; 776*f5b1c8a1SJohn Marino curr->prev= *tail; 777*f5b1c8a1SJohn Marino curr->next = NULL; 778*f5b1c8a1SJohn Marino *tail = curr; 779*f5b1c8a1SJohn Marino } 780*f5b1c8a1SJohn Marino 781*f5b1c8a1SJohn Marino static void 782*f5b1c8a1SJohn Marino ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, 783*f5b1c8a1SJohn Marino CIPHER_ORDER **tail) 784*f5b1c8a1SJohn Marino { 785*f5b1c8a1SJohn Marino if (curr == *head) 786*f5b1c8a1SJohn Marino return; 787*f5b1c8a1SJohn Marino if (curr == *tail) 788*f5b1c8a1SJohn Marino *tail = curr->prev; 789*f5b1c8a1SJohn Marino if (curr->next != NULL) 790*f5b1c8a1SJohn Marino curr->next->prev = curr->prev; 791*f5b1c8a1SJohn Marino if (curr->prev != NULL) 792*f5b1c8a1SJohn Marino curr->prev->next = curr->next; 793*f5b1c8a1SJohn Marino (*head)->prev = curr; 794*f5b1c8a1SJohn Marino curr->next= *head; 795*f5b1c8a1SJohn Marino curr->prev = NULL; 796*f5b1c8a1SJohn Marino *head = curr; 797*f5b1c8a1SJohn Marino } 798*f5b1c8a1SJohn Marino 799*f5b1c8a1SJohn Marino static void 800*f5b1c8a1SJohn Marino ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, 801*f5b1c8a1SJohn Marino unsigned long *enc, unsigned long *mac, unsigned long *ssl) 802*f5b1c8a1SJohn Marino { 803*f5b1c8a1SJohn Marino *mkey = 0; 804*f5b1c8a1SJohn Marino *auth = 0; 805*f5b1c8a1SJohn Marino *enc = 0; 806*f5b1c8a1SJohn Marino *mac = 0; 807*f5b1c8a1SJohn Marino *ssl = 0; 808*f5b1c8a1SJohn Marino 809*f5b1c8a1SJohn Marino /* 810*f5b1c8a1SJohn Marino * Check for the availability of GOST 34.10 public/private key 811*f5b1c8a1SJohn Marino * algorithms. If they are not available disable the associated 812*f5b1c8a1SJohn Marino * authentication and key exchange algorithms. 813*f5b1c8a1SJohn Marino */ 814*f5b1c8a1SJohn Marino if (EVP_PKEY_meth_find(NID_id_GostR3410_2001) == NULL) { 815*f5b1c8a1SJohn Marino *auth |= SSL_aGOST01; 816*f5b1c8a1SJohn Marino *mkey |= SSL_kGOST; 817*f5b1c8a1SJohn Marino } 818*f5b1c8a1SJohn Marino 819*f5b1c8a1SJohn Marino #ifdef SSL_FORBID_ENULL 820*f5b1c8a1SJohn Marino *enc |= SSL_eNULL; 821*f5b1c8a1SJohn Marino #endif 822*f5b1c8a1SJohn Marino 823*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES : 0; 824*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; 825*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 : 0; 826*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; 827*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; 828*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; 829*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM : 0; 830*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM : 0; 831*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128 : 0; 832*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256 : 0; 833*f5b1c8a1SJohn Marino *enc |= (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == NULL) ? SSL_eGOST2814789CNT : 0; 834*f5b1c8a1SJohn Marino 835*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 : 0; 836*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; 837*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; 838*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; 839*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; 840*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL) ? SSL_GOST89MAC : 0; 841*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_STREEBOG256_IDX] == NULL) ? SSL_STREEBOG256 : 0; 842*f5b1c8a1SJohn Marino *mac |= (ssl_digest_methods[SSL_MD_STREEBOG512_IDX] == NULL) ? SSL_STREEBOG512 : 0; 843*f5b1c8a1SJohn Marino 844*f5b1c8a1SJohn Marino } 845*f5b1c8a1SJohn Marino 846*f5b1c8a1SJohn Marino static void 847*f5b1c8a1SJohn Marino ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, int num_of_ciphers, 848*f5b1c8a1SJohn Marino unsigned long disabled_mkey, unsigned long disabled_auth, 849*f5b1c8a1SJohn Marino unsigned long disabled_enc, unsigned long disabled_mac, 850*f5b1c8a1SJohn Marino unsigned long disabled_ssl, CIPHER_ORDER *co_list, 851*f5b1c8a1SJohn Marino CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 852*f5b1c8a1SJohn Marino { 853*f5b1c8a1SJohn Marino int i, co_list_num; 854*f5b1c8a1SJohn Marino const SSL_CIPHER *c; 855*f5b1c8a1SJohn Marino 856*f5b1c8a1SJohn Marino /* 857*f5b1c8a1SJohn Marino * We have num_of_ciphers descriptions compiled in, depending on the 858*f5b1c8a1SJohn Marino * method selected (SSLv3, TLSv1, etc). These will later be sorted in 859*f5b1c8a1SJohn Marino * a linked list with at most num entries. 860*f5b1c8a1SJohn Marino */ 861*f5b1c8a1SJohn Marino 862*f5b1c8a1SJohn Marino /* Get the initial list of ciphers */ 863*f5b1c8a1SJohn Marino co_list_num = 0; /* actual count of ciphers */ 864*f5b1c8a1SJohn Marino for (i = 0; i < num_of_ciphers; i++) { 865*f5b1c8a1SJohn Marino c = ssl_method->get_cipher(i); 866*f5b1c8a1SJohn Marino /* drop those that use any of that is not available */ 867*f5b1c8a1SJohn Marino if ((c != NULL) && c->valid && 868*f5b1c8a1SJohn Marino !(c->algorithm_mkey & disabled_mkey) && 869*f5b1c8a1SJohn Marino !(c->algorithm_auth & disabled_auth) && 870*f5b1c8a1SJohn Marino !(c->algorithm_enc & disabled_enc) && 871*f5b1c8a1SJohn Marino !(c->algorithm_mac & disabled_mac) && 872*f5b1c8a1SJohn Marino !(c->algorithm_ssl & disabled_ssl)) { 873*f5b1c8a1SJohn Marino co_list[co_list_num].cipher = c; 874*f5b1c8a1SJohn Marino co_list[co_list_num].next = NULL; 875*f5b1c8a1SJohn Marino co_list[co_list_num].prev = NULL; 876*f5b1c8a1SJohn Marino co_list[co_list_num].active = 0; 877*f5b1c8a1SJohn Marino co_list_num++; 878*f5b1c8a1SJohn Marino /* 879*f5b1c8a1SJohn Marino if (!sk_push(ca_list,(char *)c)) goto err; 880*f5b1c8a1SJohn Marino */ 881*f5b1c8a1SJohn Marino } 882*f5b1c8a1SJohn Marino } 883*f5b1c8a1SJohn Marino 884*f5b1c8a1SJohn Marino /* 885*f5b1c8a1SJohn Marino * Prepare linked list from list entries 886*f5b1c8a1SJohn Marino */ 887*f5b1c8a1SJohn Marino if (co_list_num > 0) { 888*f5b1c8a1SJohn Marino co_list[0].prev = NULL; 889*f5b1c8a1SJohn Marino 890*f5b1c8a1SJohn Marino if (co_list_num > 1) { 891*f5b1c8a1SJohn Marino co_list[0].next = &co_list[1]; 892*f5b1c8a1SJohn Marino 893*f5b1c8a1SJohn Marino for (i = 1; i < co_list_num - 1; i++) { 894*f5b1c8a1SJohn Marino co_list[i].prev = &co_list[i - 1]; 895*f5b1c8a1SJohn Marino co_list[i].next = &co_list[i + 1]; 896*f5b1c8a1SJohn Marino } 897*f5b1c8a1SJohn Marino 898*f5b1c8a1SJohn Marino co_list[co_list_num - 1].prev = 899*f5b1c8a1SJohn Marino &co_list[co_list_num - 2]; 900*f5b1c8a1SJohn Marino } 901*f5b1c8a1SJohn Marino 902*f5b1c8a1SJohn Marino co_list[co_list_num - 1].next = NULL; 903*f5b1c8a1SJohn Marino 904*f5b1c8a1SJohn Marino *head_p = &co_list[0]; 905*f5b1c8a1SJohn Marino *tail_p = &co_list[co_list_num - 1]; 906*f5b1c8a1SJohn Marino } 907*f5b1c8a1SJohn Marino } 908*f5b1c8a1SJohn Marino 909*f5b1c8a1SJohn Marino static void 910*f5b1c8a1SJohn Marino ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, int num_of_group_aliases, 911*f5b1c8a1SJohn Marino unsigned long disabled_mkey, unsigned long disabled_auth, 912*f5b1c8a1SJohn Marino unsigned long disabled_enc, unsigned long disabled_mac, 913*f5b1c8a1SJohn Marino unsigned long disabled_ssl, CIPHER_ORDER *head) 914*f5b1c8a1SJohn Marino { 915*f5b1c8a1SJohn Marino CIPHER_ORDER *ciph_curr; 916*f5b1c8a1SJohn Marino const SSL_CIPHER **ca_curr; 917*f5b1c8a1SJohn Marino int i; 918*f5b1c8a1SJohn Marino unsigned long mask_mkey = ~disabled_mkey; 919*f5b1c8a1SJohn Marino unsigned long mask_auth = ~disabled_auth; 920*f5b1c8a1SJohn Marino unsigned long mask_enc = ~disabled_enc; 921*f5b1c8a1SJohn Marino unsigned long mask_mac = ~disabled_mac; 922*f5b1c8a1SJohn Marino unsigned long mask_ssl = ~disabled_ssl; 923*f5b1c8a1SJohn Marino 924*f5b1c8a1SJohn Marino /* 925*f5b1c8a1SJohn Marino * First, add the real ciphers as already collected 926*f5b1c8a1SJohn Marino */ 927*f5b1c8a1SJohn Marino ciph_curr = head; 928*f5b1c8a1SJohn Marino ca_curr = ca_list; 929*f5b1c8a1SJohn Marino while (ciph_curr != NULL) { 930*f5b1c8a1SJohn Marino *ca_curr = ciph_curr->cipher; 931*f5b1c8a1SJohn Marino ca_curr++; 932*f5b1c8a1SJohn Marino ciph_curr = ciph_curr->next; 933*f5b1c8a1SJohn Marino } 934*f5b1c8a1SJohn Marino 935*f5b1c8a1SJohn Marino /* 936*f5b1c8a1SJohn Marino * Now we add the available ones from the cipher_aliases[] table. 937*f5b1c8a1SJohn Marino * They represent either one or more algorithms, some of which 938*f5b1c8a1SJohn Marino * in any affected category must be supported (set in enabled_mask), 939*f5b1c8a1SJohn Marino * or represent a cipher strength value (will be added in any case because algorithms=0). 940*f5b1c8a1SJohn Marino */ 941*f5b1c8a1SJohn Marino for (i = 0; i < num_of_group_aliases; i++) { 942*f5b1c8a1SJohn Marino unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; 943*f5b1c8a1SJohn Marino unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; 944*f5b1c8a1SJohn Marino unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; 945*f5b1c8a1SJohn Marino unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; 946*f5b1c8a1SJohn Marino unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; 947*f5b1c8a1SJohn Marino 948*f5b1c8a1SJohn Marino if (algorithm_mkey) 949*f5b1c8a1SJohn Marino if ((algorithm_mkey & mask_mkey) == 0) 950*f5b1c8a1SJohn Marino continue; 951*f5b1c8a1SJohn Marino 952*f5b1c8a1SJohn Marino if (algorithm_auth) 953*f5b1c8a1SJohn Marino if ((algorithm_auth & mask_auth) == 0) 954*f5b1c8a1SJohn Marino continue; 955*f5b1c8a1SJohn Marino 956*f5b1c8a1SJohn Marino if (algorithm_enc) 957*f5b1c8a1SJohn Marino if ((algorithm_enc & mask_enc) == 0) 958*f5b1c8a1SJohn Marino continue; 959*f5b1c8a1SJohn Marino 960*f5b1c8a1SJohn Marino if (algorithm_mac) 961*f5b1c8a1SJohn Marino if ((algorithm_mac & mask_mac) == 0) 962*f5b1c8a1SJohn Marino continue; 963*f5b1c8a1SJohn Marino 964*f5b1c8a1SJohn Marino if (algorithm_ssl) 965*f5b1c8a1SJohn Marino if ((algorithm_ssl & mask_ssl) == 0) 966*f5b1c8a1SJohn Marino continue; 967*f5b1c8a1SJohn Marino 968*f5b1c8a1SJohn Marino *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); 969*f5b1c8a1SJohn Marino ca_curr++; 970*f5b1c8a1SJohn Marino } 971*f5b1c8a1SJohn Marino 972*f5b1c8a1SJohn Marino *ca_curr = NULL; /* end of list */ 973*f5b1c8a1SJohn Marino } 974*f5b1c8a1SJohn Marino 975*f5b1c8a1SJohn Marino static void 976*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(unsigned long cipher_id, unsigned long alg_mkey, 977*f5b1c8a1SJohn Marino unsigned long alg_auth, unsigned long alg_enc, unsigned long alg_mac, 978*f5b1c8a1SJohn Marino unsigned long alg_ssl, unsigned long algo_strength, 979*f5b1c8a1SJohn Marino int rule, int strength_bits, CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 980*f5b1c8a1SJohn Marino { 981*f5b1c8a1SJohn Marino CIPHER_ORDER *head, *tail, *curr, *next, *last; 982*f5b1c8a1SJohn Marino const SSL_CIPHER *cp; 983*f5b1c8a1SJohn Marino int reverse = 0; 984*f5b1c8a1SJohn Marino 985*f5b1c8a1SJohn Marino 986*f5b1c8a1SJohn Marino if (rule == CIPHER_DEL) 987*f5b1c8a1SJohn Marino reverse = 1; /* needed to maintain sorting between currently deleted ciphers */ 988*f5b1c8a1SJohn Marino 989*f5b1c8a1SJohn Marino head = *head_p; 990*f5b1c8a1SJohn Marino tail = *tail_p; 991*f5b1c8a1SJohn Marino 992*f5b1c8a1SJohn Marino if (reverse) { 993*f5b1c8a1SJohn Marino next = tail; 994*f5b1c8a1SJohn Marino last = head; 995*f5b1c8a1SJohn Marino } else { 996*f5b1c8a1SJohn Marino next = head; 997*f5b1c8a1SJohn Marino last = tail; 998*f5b1c8a1SJohn Marino } 999*f5b1c8a1SJohn Marino 1000*f5b1c8a1SJohn Marino curr = NULL; 1001*f5b1c8a1SJohn Marino for (;;) { 1002*f5b1c8a1SJohn Marino if (curr == last) 1003*f5b1c8a1SJohn Marino break; 1004*f5b1c8a1SJohn Marino curr = next; 1005*f5b1c8a1SJohn Marino next = reverse ? curr->prev : curr->next; 1006*f5b1c8a1SJohn Marino 1007*f5b1c8a1SJohn Marino cp = curr->cipher; 1008*f5b1c8a1SJohn Marino 1009*f5b1c8a1SJohn Marino /* 1010*f5b1c8a1SJohn Marino * Selection criteria is either the value of strength_bits 1011*f5b1c8a1SJohn Marino * or the algorithms used. 1012*f5b1c8a1SJohn Marino */ 1013*f5b1c8a1SJohn Marino if (strength_bits >= 0) { 1014*f5b1c8a1SJohn Marino if (strength_bits != cp->strength_bits) 1015*f5b1c8a1SJohn Marino continue; 1016*f5b1c8a1SJohn Marino } else { 1017*f5b1c8a1SJohn Marino 1018*f5b1c8a1SJohn Marino if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) 1019*f5b1c8a1SJohn Marino continue; 1020*f5b1c8a1SJohn Marino if (alg_auth && !(alg_auth & cp->algorithm_auth)) 1021*f5b1c8a1SJohn Marino continue; 1022*f5b1c8a1SJohn Marino if (alg_enc && !(alg_enc & cp->algorithm_enc)) 1023*f5b1c8a1SJohn Marino continue; 1024*f5b1c8a1SJohn Marino if (alg_mac && !(alg_mac & cp->algorithm_mac)) 1025*f5b1c8a1SJohn Marino continue; 1026*f5b1c8a1SJohn Marino if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) 1027*f5b1c8a1SJohn Marino continue; 1028*f5b1c8a1SJohn Marino if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) 1029*f5b1c8a1SJohn Marino continue; 1030*f5b1c8a1SJohn Marino } 1031*f5b1c8a1SJohn Marino 1032*f5b1c8a1SJohn Marino 1033*f5b1c8a1SJohn Marino /* add the cipher if it has not been added yet. */ 1034*f5b1c8a1SJohn Marino if (rule == CIPHER_ADD) { 1035*f5b1c8a1SJohn Marino /* reverse == 0 */ 1036*f5b1c8a1SJohn Marino if (!curr->active) { 1037*f5b1c8a1SJohn Marino ll_append_tail(&head, curr, &tail); 1038*f5b1c8a1SJohn Marino curr->active = 1; 1039*f5b1c8a1SJohn Marino } 1040*f5b1c8a1SJohn Marino } 1041*f5b1c8a1SJohn Marino /* Move the added cipher to this location */ 1042*f5b1c8a1SJohn Marino else if (rule == CIPHER_ORD) { 1043*f5b1c8a1SJohn Marino /* reverse == 0 */ 1044*f5b1c8a1SJohn Marino if (curr->active) { 1045*f5b1c8a1SJohn Marino ll_append_tail(&head, curr, &tail); 1046*f5b1c8a1SJohn Marino } 1047*f5b1c8a1SJohn Marino } else if (rule == CIPHER_DEL) { 1048*f5b1c8a1SJohn Marino /* reverse == 1 */ 1049*f5b1c8a1SJohn Marino if (curr->active) { 1050*f5b1c8a1SJohn Marino /* most recently deleted ciphersuites get best positions 1051*f5b1c8a1SJohn Marino * for any future CIPHER_ADD (note that the CIPHER_DEL loop 1052*f5b1c8a1SJohn Marino * works in reverse to maintain the order) */ 1053*f5b1c8a1SJohn Marino ll_append_head(&head, curr, &tail); 1054*f5b1c8a1SJohn Marino curr->active = 0; 1055*f5b1c8a1SJohn Marino } 1056*f5b1c8a1SJohn Marino } else if (rule == CIPHER_KILL) { 1057*f5b1c8a1SJohn Marino /* reverse == 0 */ 1058*f5b1c8a1SJohn Marino if (head == curr) 1059*f5b1c8a1SJohn Marino head = curr->next; 1060*f5b1c8a1SJohn Marino else 1061*f5b1c8a1SJohn Marino curr->prev->next = curr->next; 1062*f5b1c8a1SJohn Marino if (tail == curr) 1063*f5b1c8a1SJohn Marino tail = curr->prev; 1064*f5b1c8a1SJohn Marino curr->active = 0; 1065*f5b1c8a1SJohn Marino if (curr->next != NULL) 1066*f5b1c8a1SJohn Marino curr->next->prev = curr->prev; 1067*f5b1c8a1SJohn Marino if (curr->prev != NULL) 1068*f5b1c8a1SJohn Marino curr->prev->next = curr->next; 1069*f5b1c8a1SJohn Marino curr->next = NULL; 1070*f5b1c8a1SJohn Marino curr->prev = NULL; 1071*f5b1c8a1SJohn Marino } 1072*f5b1c8a1SJohn Marino } 1073*f5b1c8a1SJohn Marino 1074*f5b1c8a1SJohn Marino *head_p = head; 1075*f5b1c8a1SJohn Marino *tail_p = tail; 1076*f5b1c8a1SJohn Marino } 1077*f5b1c8a1SJohn Marino 1078*f5b1c8a1SJohn Marino static int 1079*f5b1c8a1SJohn Marino ssl_cipher_strength_sort(CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p) 1080*f5b1c8a1SJohn Marino { 1081*f5b1c8a1SJohn Marino int max_strength_bits, i, *number_uses; 1082*f5b1c8a1SJohn Marino CIPHER_ORDER *curr; 1083*f5b1c8a1SJohn Marino 1084*f5b1c8a1SJohn Marino /* 1085*f5b1c8a1SJohn Marino * This routine sorts the ciphers with descending strength. The sorting 1086*f5b1c8a1SJohn Marino * must keep the pre-sorted sequence, so we apply the normal sorting 1087*f5b1c8a1SJohn Marino * routine as '+' movement to the end of the list. 1088*f5b1c8a1SJohn Marino */ 1089*f5b1c8a1SJohn Marino max_strength_bits = 0; 1090*f5b1c8a1SJohn Marino curr = *head_p; 1091*f5b1c8a1SJohn Marino while (curr != NULL) { 1092*f5b1c8a1SJohn Marino if (curr->active && 1093*f5b1c8a1SJohn Marino (curr->cipher->strength_bits > max_strength_bits)) 1094*f5b1c8a1SJohn Marino max_strength_bits = curr->cipher->strength_bits; 1095*f5b1c8a1SJohn Marino curr = curr->next; 1096*f5b1c8a1SJohn Marino } 1097*f5b1c8a1SJohn Marino 1098*f5b1c8a1SJohn Marino number_uses = calloc((max_strength_bits + 1), sizeof(int)); 1099*f5b1c8a1SJohn Marino if (!number_uses) { 1100*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); 1101*f5b1c8a1SJohn Marino return (0); 1102*f5b1c8a1SJohn Marino } 1103*f5b1c8a1SJohn Marino 1104*f5b1c8a1SJohn Marino /* 1105*f5b1c8a1SJohn Marino * Now find the strength_bits values actually used 1106*f5b1c8a1SJohn Marino */ 1107*f5b1c8a1SJohn Marino curr = *head_p; 1108*f5b1c8a1SJohn Marino while (curr != NULL) { 1109*f5b1c8a1SJohn Marino if (curr->active) 1110*f5b1c8a1SJohn Marino number_uses[curr->cipher->strength_bits]++; 1111*f5b1c8a1SJohn Marino curr = curr->next; 1112*f5b1c8a1SJohn Marino } 1113*f5b1c8a1SJohn Marino /* 1114*f5b1c8a1SJohn Marino * Go through the list of used strength_bits values in descending 1115*f5b1c8a1SJohn Marino * order. 1116*f5b1c8a1SJohn Marino */ 1117*f5b1c8a1SJohn Marino for (i = max_strength_bits; i >= 0; i--) 1118*f5b1c8a1SJohn Marino if (number_uses[i] > 0) 1119*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, tail_p); 1120*f5b1c8a1SJohn Marino 1121*f5b1c8a1SJohn Marino free(number_uses); 1122*f5b1c8a1SJohn Marino return (1); 1123*f5b1c8a1SJohn Marino } 1124*f5b1c8a1SJohn Marino 1125*f5b1c8a1SJohn Marino static int 1126*f5b1c8a1SJohn Marino ssl_cipher_process_rulestr(const char *rule_str, CIPHER_ORDER **head_p, 1127*f5b1c8a1SJohn Marino CIPHER_ORDER **tail_p, const SSL_CIPHER **ca_list) 1128*f5b1c8a1SJohn Marino { 1129*f5b1c8a1SJohn Marino unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl; 1130*f5b1c8a1SJohn Marino unsigned long algo_strength; 1131*f5b1c8a1SJohn Marino int j, multi, found, rule, retval, ok, buflen; 1132*f5b1c8a1SJohn Marino unsigned long cipher_id = 0; 1133*f5b1c8a1SJohn Marino const char *l, *buf; 1134*f5b1c8a1SJohn Marino char ch; 1135*f5b1c8a1SJohn Marino 1136*f5b1c8a1SJohn Marino retval = 1; 1137*f5b1c8a1SJohn Marino l = rule_str; 1138*f5b1c8a1SJohn Marino for (;;) { 1139*f5b1c8a1SJohn Marino ch = *l; 1140*f5b1c8a1SJohn Marino 1141*f5b1c8a1SJohn Marino if (ch == '\0') 1142*f5b1c8a1SJohn Marino break; 1143*f5b1c8a1SJohn Marino 1144*f5b1c8a1SJohn Marino if (ch == '-') { 1145*f5b1c8a1SJohn Marino rule = CIPHER_DEL; 1146*f5b1c8a1SJohn Marino l++; 1147*f5b1c8a1SJohn Marino } else if (ch == '+') { 1148*f5b1c8a1SJohn Marino rule = CIPHER_ORD; 1149*f5b1c8a1SJohn Marino l++; 1150*f5b1c8a1SJohn Marino } else if (ch == '!') { 1151*f5b1c8a1SJohn Marino rule = CIPHER_KILL; 1152*f5b1c8a1SJohn Marino l++; 1153*f5b1c8a1SJohn Marino } else if (ch == '@') { 1154*f5b1c8a1SJohn Marino rule = CIPHER_SPECIAL; 1155*f5b1c8a1SJohn Marino l++; 1156*f5b1c8a1SJohn Marino } else { 1157*f5b1c8a1SJohn Marino rule = CIPHER_ADD; 1158*f5b1c8a1SJohn Marino } 1159*f5b1c8a1SJohn Marino 1160*f5b1c8a1SJohn Marino if (ITEM_SEP(ch)) { 1161*f5b1c8a1SJohn Marino l++; 1162*f5b1c8a1SJohn Marino continue; 1163*f5b1c8a1SJohn Marino } 1164*f5b1c8a1SJohn Marino 1165*f5b1c8a1SJohn Marino alg_mkey = 0; 1166*f5b1c8a1SJohn Marino alg_auth = 0; 1167*f5b1c8a1SJohn Marino alg_enc = 0; 1168*f5b1c8a1SJohn Marino alg_mac = 0; 1169*f5b1c8a1SJohn Marino alg_ssl = 0; 1170*f5b1c8a1SJohn Marino algo_strength = 0; 1171*f5b1c8a1SJohn Marino 1172*f5b1c8a1SJohn Marino for (;;) { 1173*f5b1c8a1SJohn Marino ch = *l; 1174*f5b1c8a1SJohn Marino buf = l; 1175*f5b1c8a1SJohn Marino buflen = 0; 1176*f5b1c8a1SJohn Marino while (((ch >= 'A') && (ch <= 'Z')) || 1177*f5b1c8a1SJohn Marino ((ch >= '0') && (ch <= '9')) || 1178*f5b1c8a1SJohn Marino ((ch >= 'a') && (ch <= 'z')) || 1179*f5b1c8a1SJohn Marino (ch == '-') || (ch == '.')) { 1180*f5b1c8a1SJohn Marino ch = *(++l); 1181*f5b1c8a1SJohn Marino buflen++; 1182*f5b1c8a1SJohn Marino } 1183*f5b1c8a1SJohn Marino 1184*f5b1c8a1SJohn Marino if (buflen == 0) { 1185*f5b1c8a1SJohn Marino /* 1186*f5b1c8a1SJohn Marino * We hit something we cannot deal with, 1187*f5b1c8a1SJohn Marino * it is no command or separator nor 1188*f5b1c8a1SJohn Marino * alphanumeric, so we call this an error. 1189*f5b1c8a1SJohn Marino */ 1190*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 1191*f5b1c8a1SJohn Marino SSL_R_INVALID_COMMAND); 1192*f5b1c8a1SJohn Marino retval = found = 0; 1193*f5b1c8a1SJohn Marino l++; 1194*f5b1c8a1SJohn Marino break; 1195*f5b1c8a1SJohn Marino } 1196*f5b1c8a1SJohn Marino 1197*f5b1c8a1SJohn Marino if (rule == CIPHER_SPECIAL) { 1198*f5b1c8a1SJohn Marino /* unused -- avoid compiler warning */ 1199*f5b1c8a1SJohn Marino found = 0; 1200*f5b1c8a1SJohn Marino /* special treatment */ 1201*f5b1c8a1SJohn Marino break; 1202*f5b1c8a1SJohn Marino } 1203*f5b1c8a1SJohn Marino 1204*f5b1c8a1SJohn Marino /* check for multi-part specification */ 1205*f5b1c8a1SJohn Marino if (ch == '+') { 1206*f5b1c8a1SJohn Marino multi = 1; 1207*f5b1c8a1SJohn Marino l++; 1208*f5b1c8a1SJohn Marino } else 1209*f5b1c8a1SJohn Marino multi = 0; 1210*f5b1c8a1SJohn Marino 1211*f5b1c8a1SJohn Marino /* 1212*f5b1c8a1SJohn Marino * Now search for the cipher alias in the ca_list. 1213*f5b1c8a1SJohn Marino * Be careful with the strncmp, because the "buflen" 1214*f5b1c8a1SJohn Marino * limitation will make the rule "ADH:SOME" and the 1215*f5b1c8a1SJohn Marino * cipher "ADH-MY-CIPHER" look like a match for 1216*f5b1c8a1SJohn Marino * buflen=3. So additionally check whether the cipher 1217*f5b1c8a1SJohn Marino * name found has the correct length. We can save a 1218*f5b1c8a1SJohn Marino * strlen() call: just checking for the '\0' at the 1219*f5b1c8a1SJohn Marino * right place is sufficient, we have to strncmp() 1220*f5b1c8a1SJohn Marino * anyway (we cannot use strcmp(), because buf is not 1221*f5b1c8a1SJohn Marino * '\0' terminated.) 1222*f5b1c8a1SJohn Marino */ 1223*f5b1c8a1SJohn Marino j = found = 0; 1224*f5b1c8a1SJohn Marino cipher_id = 0; 1225*f5b1c8a1SJohn Marino while (ca_list[j]) { 1226*f5b1c8a1SJohn Marino if (!strncmp(buf, ca_list[j]->name, buflen) && 1227*f5b1c8a1SJohn Marino (ca_list[j]->name[buflen] == '\0')) { 1228*f5b1c8a1SJohn Marino found = 1; 1229*f5b1c8a1SJohn Marino break; 1230*f5b1c8a1SJohn Marino } else 1231*f5b1c8a1SJohn Marino j++; 1232*f5b1c8a1SJohn Marino } 1233*f5b1c8a1SJohn Marino 1234*f5b1c8a1SJohn Marino if (!found) 1235*f5b1c8a1SJohn Marino break; /* ignore this entry */ 1236*f5b1c8a1SJohn Marino 1237*f5b1c8a1SJohn Marino if (ca_list[j]->algorithm_mkey) { 1238*f5b1c8a1SJohn Marino if (alg_mkey) { 1239*f5b1c8a1SJohn Marino alg_mkey &= ca_list[j]->algorithm_mkey; 1240*f5b1c8a1SJohn Marino if (!alg_mkey) { 1241*f5b1c8a1SJohn Marino found = 0; 1242*f5b1c8a1SJohn Marino break; 1243*f5b1c8a1SJohn Marino } 1244*f5b1c8a1SJohn Marino } else 1245*f5b1c8a1SJohn Marino alg_mkey = ca_list[j]->algorithm_mkey; 1246*f5b1c8a1SJohn Marino } 1247*f5b1c8a1SJohn Marino 1248*f5b1c8a1SJohn Marino if (ca_list[j]->algorithm_auth) { 1249*f5b1c8a1SJohn Marino if (alg_auth) { 1250*f5b1c8a1SJohn Marino alg_auth &= ca_list[j]->algorithm_auth; 1251*f5b1c8a1SJohn Marino if (!alg_auth) { 1252*f5b1c8a1SJohn Marino found = 0; 1253*f5b1c8a1SJohn Marino break; 1254*f5b1c8a1SJohn Marino } 1255*f5b1c8a1SJohn Marino } else 1256*f5b1c8a1SJohn Marino alg_auth = ca_list[j]->algorithm_auth; 1257*f5b1c8a1SJohn Marino } 1258*f5b1c8a1SJohn Marino 1259*f5b1c8a1SJohn Marino if (ca_list[j]->algorithm_enc) { 1260*f5b1c8a1SJohn Marino if (alg_enc) { 1261*f5b1c8a1SJohn Marino alg_enc &= ca_list[j]->algorithm_enc; 1262*f5b1c8a1SJohn Marino if (!alg_enc) { 1263*f5b1c8a1SJohn Marino found = 0; 1264*f5b1c8a1SJohn Marino break; 1265*f5b1c8a1SJohn Marino } 1266*f5b1c8a1SJohn Marino } else 1267*f5b1c8a1SJohn Marino alg_enc = ca_list[j]->algorithm_enc; 1268*f5b1c8a1SJohn Marino } 1269*f5b1c8a1SJohn Marino 1270*f5b1c8a1SJohn Marino if (ca_list[j]->algorithm_mac) { 1271*f5b1c8a1SJohn Marino if (alg_mac) { 1272*f5b1c8a1SJohn Marino alg_mac &= ca_list[j]->algorithm_mac; 1273*f5b1c8a1SJohn Marino if (!alg_mac) { 1274*f5b1c8a1SJohn Marino found = 0; 1275*f5b1c8a1SJohn Marino break; 1276*f5b1c8a1SJohn Marino } 1277*f5b1c8a1SJohn Marino } else 1278*f5b1c8a1SJohn Marino alg_mac = ca_list[j]->algorithm_mac; 1279*f5b1c8a1SJohn Marino } 1280*f5b1c8a1SJohn Marino 1281*f5b1c8a1SJohn Marino if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { 1282*f5b1c8a1SJohn Marino if (algo_strength & SSL_STRONG_MASK) { 1283*f5b1c8a1SJohn Marino algo_strength &= 1284*f5b1c8a1SJohn Marino (ca_list[j]->algo_strength & 1285*f5b1c8a1SJohn Marino SSL_STRONG_MASK) | ~SSL_STRONG_MASK; 1286*f5b1c8a1SJohn Marino if (!(algo_strength & 1287*f5b1c8a1SJohn Marino SSL_STRONG_MASK)) { 1288*f5b1c8a1SJohn Marino found = 0; 1289*f5b1c8a1SJohn Marino break; 1290*f5b1c8a1SJohn Marino } 1291*f5b1c8a1SJohn Marino } else 1292*f5b1c8a1SJohn Marino algo_strength |= 1293*f5b1c8a1SJohn Marino ca_list[j]->algo_strength & 1294*f5b1c8a1SJohn Marino SSL_STRONG_MASK; 1295*f5b1c8a1SJohn Marino } 1296*f5b1c8a1SJohn Marino 1297*f5b1c8a1SJohn Marino if (ca_list[j]->valid) { 1298*f5b1c8a1SJohn Marino /* 1299*f5b1c8a1SJohn Marino * explicit ciphersuite found; its protocol 1300*f5b1c8a1SJohn Marino * version does not become part of the search 1301*f5b1c8a1SJohn Marino * pattern! 1302*f5b1c8a1SJohn Marino */ 1303*f5b1c8a1SJohn Marino cipher_id = ca_list[j]->id; 1304*f5b1c8a1SJohn Marino } else { 1305*f5b1c8a1SJohn Marino /* 1306*f5b1c8a1SJohn Marino * not an explicit ciphersuite; only in this 1307*f5b1c8a1SJohn Marino * case, the protocol version is considered 1308*f5b1c8a1SJohn Marino * part of the search pattern 1309*f5b1c8a1SJohn Marino */ 1310*f5b1c8a1SJohn Marino if (ca_list[j]->algorithm_ssl) { 1311*f5b1c8a1SJohn Marino if (alg_ssl) { 1312*f5b1c8a1SJohn Marino alg_ssl &= 1313*f5b1c8a1SJohn Marino ca_list[j]->algorithm_ssl; 1314*f5b1c8a1SJohn Marino if (!alg_ssl) { 1315*f5b1c8a1SJohn Marino found = 0; 1316*f5b1c8a1SJohn Marino break; 1317*f5b1c8a1SJohn Marino } 1318*f5b1c8a1SJohn Marino } else 1319*f5b1c8a1SJohn Marino alg_ssl = 1320*f5b1c8a1SJohn Marino ca_list[j]->algorithm_ssl; 1321*f5b1c8a1SJohn Marino } 1322*f5b1c8a1SJohn Marino } 1323*f5b1c8a1SJohn Marino 1324*f5b1c8a1SJohn Marino if (!multi) 1325*f5b1c8a1SJohn Marino break; 1326*f5b1c8a1SJohn Marino } 1327*f5b1c8a1SJohn Marino 1328*f5b1c8a1SJohn Marino /* 1329*f5b1c8a1SJohn Marino * Ok, we have the rule, now apply it 1330*f5b1c8a1SJohn Marino */ 1331*f5b1c8a1SJohn Marino if (rule == CIPHER_SPECIAL) { 1332*f5b1c8a1SJohn Marino /* special command */ 1333*f5b1c8a1SJohn Marino ok = 0; 1334*f5b1c8a1SJohn Marino if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) 1335*f5b1c8a1SJohn Marino ok = ssl_cipher_strength_sort(head_p, tail_p); 1336*f5b1c8a1SJohn Marino else 1337*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, 1338*f5b1c8a1SJohn Marino SSL_R_INVALID_COMMAND); 1339*f5b1c8a1SJohn Marino if (ok == 0) 1340*f5b1c8a1SJohn Marino retval = 0; 1341*f5b1c8a1SJohn Marino /* 1342*f5b1c8a1SJohn Marino * We do not support any "multi" options 1343*f5b1c8a1SJohn Marino * together with "@", so throw away the 1344*f5b1c8a1SJohn Marino * rest of the command, if any left, until 1345*f5b1c8a1SJohn Marino * end or ':' is found. 1346*f5b1c8a1SJohn Marino */ 1347*f5b1c8a1SJohn Marino while ((*l != '\0') && !ITEM_SEP(*l)) 1348*f5b1c8a1SJohn Marino l++; 1349*f5b1c8a1SJohn Marino } else if (found) { 1350*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, 1351*f5b1c8a1SJohn Marino alg_enc, alg_mac, alg_ssl, algo_strength, rule, 1352*f5b1c8a1SJohn Marino -1, head_p, tail_p); 1353*f5b1c8a1SJohn Marino } else { 1354*f5b1c8a1SJohn Marino while ((*l != '\0') && !ITEM_SEP(*l)) 1355*f5b1c8a1SJohn Marino l++; 1356*f5b1c8a1SJohn Marino } 1357*f5b1c8a1SJohn Marino if (*l == '\0') 1358*f5b1c8a1SJohn Marino break; /* done */ 1359*f5b1c8a1SJohn Marino } 1360*f5b1c8a1SJohn Marino 1361*f5b1c8a1SJohn Marino return (retval); 1362*f5b1c8a1SJohn Marino } 1363*f5b1c8a1SJohn Marino 1364*f5b1c8a1SJohn Marino static inline int 1365*f5b1c8a1SJohn Marino ssl_aes_is_accelerated(void) 1366*f5b1c8a1SJohn Marino { 1367*f5b1c8a1SJohn Marino #if defined(__i386__) || defined(__x86_64__) 1368*f5b1c8a1SJohn Marino return ((OPENSSL_cpu_caps() & (1ULL << 57)) != 0); 1369*f5b1c8a1SJohn Marino #else 1370*f5b1c8a1SJohn Marino return (0); 1371*f5b1c8a1SJohn Marino #endif 1372*f5b1c8a1SJohn Marino } 1373*f5b1c8a1SJohn Marino 1374*f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) * 1375*f5b1c8a1SJohn Marino ssl_create_cipher_list(const SSL_METHOD *ssl_method, 1376*f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) **cipher_list, 1377*f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) **cipher_list_by_id, 1378*f5b1c8a1SJohn Marino const char *rule_str) 1379*f5b1c8a1SJohn Marino { 1380*f5b1c8a1SJohn Marino int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; 1381*f5b1c8a1SJohn Marino unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl; 1382*f5b1c8a1SJohn Marino STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; 1383*f5b1c8a1SJohn Marino const char *rule_p; 1384*f5b1c8a1SJohn Marino CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; 1385*f5b1c8a1SJohn Marino const SSL_CIPHER **ca_list = NULL; 1386*f5b1c8a1SJohn Marino 1387*f5b1c8a1SJohn Marino /* 1388*f5b1c8a1SJohn Marino * Return with error if nothing to do. 1389*f5b1c8a1SJohn Marino */ 1390*f5b1c8a1SJohn Marino if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) 1391*f5b1c8a1SJohn Marino return NULL; 1392*f5b1c8a1SJohn Marino 1393*f5b1c8a1SJohn Marino /* 1394*f5b1c8a1SJohn Marino * To reduce the work to do we only want to process the compiled 1395*f5b1c8a1SJohn Marino * in algorithms, so we first get the mask of disabled ciphers. 1396*f5b1c8a1SJohn Marino */ 1397*f5b1c8a1SJohn Marino ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl); 1398*f5b1c8a1SJohn Marino 1399*f5b1c8a1SJohn Marino /* 1400*f5b1c8a1SJohn Marino * Now we have to collect the available ciphers from the compiled 1401*f5b1c8a1SJohn Marino * in ciphers. We cannot get more than the number compiled in, so 1402*f5b1c8a1SJohn Marino * it is used for allocation. 1403*f5b1c8a1SJohn Marino */ 1404*f5b1c8a1SJohn Marino num_of_ciphers = ssl_method->num_ciphers(); 1405*f5b1c8a1SJohn Marino co_list = reallocarray(NULL, num_of_ciphers, sizeof(CIPHER_ORDER)); 1406*f5b1c8a1SJohn Marino if (co_list == NULL) { 1407*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); 1408*f5b1c8a1SJohn Marino return(NULL); /* Failure */ 1409*f5b1c8a1SJohn Marino } 1410*f5b1c8a1SJohn Marino 1411*f5b1c8a1SJohn Marino ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, 1412*f5b1c8a1SJohn Marino disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl, 1413*f5b1c8a1SJohn Marino co_list, &head, &tail); 1414*f5b1c8a1SJohn Marino 1415*f5b1c8a1SJohn Marino 1416*f5b1c8a1SJohn Marino /* Now arrange all ciphers by preference: */ 1417*f5b1c8a1SJohn Marino 1418*f5b1c8a1SJohn Marino /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */ 1419*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1420*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, SSL_kECDHE, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); 1421*f5b1c8a1SJohn Marino 1422*f5b1c8a1SJohn Marino if (ssl_aes_is_accelerated() == 1) { 1423*f5b1c8a1SJohn Marino /* 1424*f5b1c8a1SJohn Marino * We have hardware assisted AES - prefer AES as a symmetric 1425*f5b1c8a1SJohn Marino * cipher, with CHACHA20 second. 1426*f5b1c8a1SJohn Marino */ 1427*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, 1428*f5b1c8a1SJohn Marino CIPHER_ADD, -1, &head, &tail); 1429*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 1430*f5b1c8a1SJohn Marino 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1431*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD, 1432*f5b1c8a1SJohn Marino 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1433*f5b1c8a1SJohn Marino } else { 1434*f5b1c8a1SJohn Marino /* 1435*f5b1c8a1SJohn Marino * CHACHA20 is fast and safe on all hardware and is thus our 1436*f5b1c8a1SJohn Marino * preferred symmetric cipher, with AES second. 1437*f5b1c8a1SJohn Marino */ 1438*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305, 1439*f5b1c8a1SJohn Marino 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1440*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_CHACHA20POLY1305_OLD, 1441*f5b1c8a1SJohn Marino 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1442*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, 1443*f5b1c8a1SJohn Marino CIPHER_ADD, -1, &head, &tail); 1444*f5b1c8a1SJohn Marino } 1445*f5b1c8a1SJohn Marino 1446*f5b1c8a1SJohn Marino /* Temporarily enable everything else for sorting */ 1447*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); 1448*f5b1c8a1SJohn Marino 1449*f5b1c8a1SJohn Marino /* Low priority for MD5 */ 1450*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, &tail); 1451*f5b1c8a1SJohn Marino 1452*f5b1c8a1SJohn Marino /* Move anonymous ciphers to the end. Usually, these will remain disabled. 1453*f5b1c8a1SJohn Marino * (For applications that allow them, they aren't too bad, but we prefer 1454*f5b1c8a1SJohn Marino * authenticated ciphers.) */ 1455*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); 1456*f5b1c8a1SJohn Marino 1457*f5b1c8a1SJohn Marino /* Move ciphers without forward secrecy to the end */ 1458*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); 1459*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); 1460*f5b1c8a1SJohn Marino 1461*f5b1c8a1SJohn Marino /* RC4 is sort of broken - move it to the end */ 1462*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, &tail); 1463*f5b1c8a1SJohn Marino 1464*f5b1c8a1SJohn Marino /* Now sort by symmetric encryption strength. The above ordering remains 1465*f5b1c8a1SJohn Marino * in force within each class */ 1466*f5b1c8a1SJohn Marino if (!ssl_cipher_strength_sort(&head, &tail)) { 1467*f5b1c8a1SJohn Marino free(co_list); 1468*f5b1c8a1SJohn Marino return NULL; 1469*f5b1c8a1SJohn Marino } 1470*f5b1c8a1SJohn Marino 1471*f5b1c8a1SJohn Marino /* Now disable everything (maintaining the ordering!) */ 1472*f5b1c8a1SJohn Marino ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); 1473*f5b1c8a1SJohn Marino 1474*f5b1c8a1SJohn Marino 1475*f5b1c8a1SJohn Marino /* 1476*f5b1c8a1SJohn Marino * We also need cipher aliases for selecting based on the rule_str. 1477*f5b1c8a1SJohn Marino * There might be two types of entries in the rule_str: 1) names 1478*f5b1c8a1SJohn Marino * of ciphers themselves 2) aliases for groups of ciphers. 1479*f5b1c8a1SJohn Marino * For 1) we need the available ciphers and for 2) the cipher 1480*f5b1c8a1SJohn Marino * groups of cipher_aliases added together in one list (otherwise 1481*f5b1c8a1SJohn Marino * we would be happy with just the cipher_aliases table). 1482*f5b1c8a1SJohn Marino */ 1483*f5b1c8a1SJohn Marino num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); 1484*f5b1c8a1SJohn Marino num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; 1485*f5b1c8a1SJohn Marino ca_list = reallocarray(NULL, num_of_alias_max, sizeof(SSL_CIPHER *)); 1486*f5b1c8a1SJohn Marino if (ca_list == NULL) { 1487*f5b1c8a1SJohn Marino free(co_list); 1488*f5b1c8a1SJohn Marino SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); 1489*f5b1c8a1SJohn Marino return(NULL); /* Failure */ 1490*f5b1c8a1SJohn Marino } 1491*f5b1c8a1SJohn Marino ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, 1492*f5b1c8a1SJohn Marino disabled_mkey, disabled_auth, disabled_enc, 1493*f5b1c8a1SJohn Marino disabled_mac, disabled_ssl, head); 1494*f5b1c8a1SJohn Marino 1495*f5b1c8a1SJohn Marino /* 1496*f5b1c8a1SJohn Marino * If the rule_string begins with DEFAULT, apply the default rule 1497*f5b1c8a1SJohn Marino * before using the (possibly available) additional rules. 1498*f5b1c8a1SJohn Marino */ 1499*f5b1c8a1SJohn Marino ok = 1; 1500*f5b1c8a1SJohn Marino rule_p = rule_str; 1501*f5b1c8a1SJohn Marino if (strncmp(rule_str, "DEFAULT", 7) == 0) { 1502*f5b1c8a1SJohn Marino ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, 1503*f5b1c8a1SJohn Marino &head, &tail, ca_list); 1504*f5b1c8a1SJohn Marino rule_p += 7; 1505*f5b1c8a1SJohn Marino if (*rule_p == ':') 1506*f5b1c8a1SJohn Marino rule_p++; 1507*f5b1c8a1SJohn Marino } 1508*f5b1c8a1SJohn Marino 1509*f5b1c8a1SJohn Marino if (ok && (strlen(rule_p) > 0)) 1510*f5b1c8a1SJohn Marino ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); 1511*f5b1c8a1SJohn Marino 1512*f5b1c8a1SJohn Marino free((void *)ca_list); /* Not needed anymore */ 1513*f5b1c8a1SJohn Marino 1514*f5b1c8a1SJohn Marino if (!ok) { 1515*f5b1c8a1SJohn Marino /* Rule processing failure */ 1516*f5b1c8a1SJohn Marino free(co_list); 1517*f5b1c8a1SJohn Marino return (NULL); 1518*f5b1c8a1SJohn Marino } 1519*f5b1c8a1SJohn Marino 1520*f5b1c8a1SJohn Marino /* 1521*f5b1c8a1SJohn Marino * Allocate new "cipherstack" for the result, return with error 1522*f5b1c8a1SJohn Marino * if we cannot get one. 1523*f5b1c8a1SJohn Marino */ 1524*f5b1c8a1SJohn Marino if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { 1525*f5b1c8a1SJohn Marino free(co_list); 1526*f5b1c8a1SJohn Marino return (NULL); 1527*f5b1c8a1SJohn Marino } 1528*f5b1c8a1SJohn Marino 1529*f5b1c8a1SJohn Marino /* 1530*f5b1c8a1SJohn Marino * The cipher selection for the list is done. The ciphers are added 1531*f5b1c8a1SJohn Marino * to the resulting precedence to the STACK_OF(SSL_CIPHER). 1532*f5b1c8a1SJohn Marino */ 1533*f5b1c8a1SJohn Marino for (curr = head; curr != NULL; curr = curr->next) { 1534*f5b1c8a1SJohn Marino if (curr->active) { 1535*f5b1c8a1SJohn Marino sk_SSL_CIPHER_push(cipherstack, curr->cipher); 1536*f5b1c8a1SJohn Marino } 1537*f5b1c8a1SJohn Marino } 1538*f5b1c8a1SJohn Marino free(co_list); /* Not needed any longer */ 1539*f5b1c8a1SJohn Marino 1540*f5b1c8a1SJohn Marino tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); 1541*f5b1c8a1SJohn Marino if (tmp_cipher_list == NULL) { 1542*f5b1c8a1SJohn Marino sk_SSL_CIPHER_free(cipherstack); 1543*f5b1c8a1SJohn Marino return NULL; 1544*f5b1c8a1SJohn Marino } 1545*f5b1c8a1SJohn Marino if (*cipher_list != NULL) 1546*f5b1c8a1SJohn Marino sk_SSL_CIPHER_free(*cipher_list); 1547*f5b1c8a1SJohn Marino *cipher_list = cipherstack; 1548*f5b1c8a1SJohn Marino if (*cipher_list_by_id != NULL) 1549*f5b1c8a1SJohn Marino sk_SSL_CIPHER_free(*cipher_list_by_id); 1550*f5b1c8a1SJohn Marino *cipher_list_by_id = tmp_cipher_list; 1551*f5b1c8a1SJohn Marino (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, 1552*f5b1c8a1SJohn Marino ssl_cipher_ptr_id_cmp); 1553*f5b1c8a1SJohn Marino 1554*f5b1c8a1SJohn Marino sk_SSL_CIPHER_sort(*cipher_list_by_id); 1555*f5b1c8a1SJohn Marino return (cipherstack); 1556*f5b1c8a1SJohn Marino } 1557*f5b1c8a1SJohn Marino 1558*f5b1c8a1SJohn Marino const SSL_CIPHER * 1559*f5b1c8a1SJohn Marino SSL_CIPHER_get_by_id(unsigned int id) 1560*f5b1c8a1SJohn Marino { 1561*f5b1c8a1SJohn Marino return ssl3_get_cipher_by_id(id); 1562*f5b1c8a1SJohn Marino } 1563*f5b1c8a1SJohn Marino 1564*f5b1c8a1SJohn Marino const SSL_CIPHER * 1565*f5b1c8a1SJohn Marino SSL_CIPHER_get_by_value(uint16_t value) 1566*f5b1c8a1SJohn Marino { 1567*f5b1c8a1SJohn Marino return ssl3_get_cipher_by_value(value); 1568*f5b1c8a1SJohn Marino } 1569*f5b1c8a1SJohn Marino 1570*f5b1c8a1SJohn Marino char * 1571*f5b1c8a1SJohn Marino SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) 1572*f5b1c8a1SJohn Marino { 1573*f5b1c8a1SJohn Marino unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; 1574*f5b1c8a1SJohn Marino const char *ver, *kx, *au, *enc, *mac; 1575*f5b1c8a1SJohn Marino char *ret; 1576*f5b1c8a1SJohn Marino int l; 1577*f5b1c8a1SJohn Marino 1578*f5b1c8a1SJohn Marino alg_mkey = cipher->algorithm_mkey; 1579*f5b1c8a1SJohn Marino alg_auth = cipher->algorithm_auth; 1580*f5b1c8a1SJohn Marino alg_enc = cipher->algorithm_enc; 1581*f5b1c8a1SJohn Marino alg_mac = cipher->algorithm_mac; 1582*f5b1c8a1SJohn Marino alg_ssl = cipher->algorithm_ssl; 1583*f5b1c8a1SJohn Marino 1584*f5b1c8a1SJohn Marino alg2 = cipher->algorithm2; 1585*f5b1c8a1SJohn Marino 1586*f5b1c8a1SJohn Marino if (alg_ssl & SSL_SSLV3) 1587*f5b1c8a1SJohn Marino ver = "SSLv3"; 1588*f5b1c8a1SJohn Marino else if (alg_ssl & SSL_TLSV1_2) 1589*f5b1c8a1SJohn Marino ver = "TLSv1.2"; 1590*f5b1c8a1SJohn Marino else 1591*f5b1c8a1SJohn Marino ver = "unknown"; 1592*f5b1c8a1SJohn Marino 1593*f5b1c8a1SJohn Marino switch (alg_mkey) { 1594*f5b1c8a1SJohn Marino case SSL_kRSA: 1595*f5b1c8a1SJohn Marino kx = "RSA"; 1596*f5b1c8a1SJohn Marino break; 1597*f5b1c8a1SJohn Marino case SSL_kDHE: 1598*f5b1c8a1SJohn Marino kx = "DH"; 1599*f5b1c8a1SJohn Marino break; 1600*f5b1c8a1SJohn Marino case SSL_kECDHr: 1601*f5b1c8a1SJohn Marino kx = "ECDH/RSA"; 1602*f5b1c8a1SJohn Marino break; 1603*f5b1c8a1SJohn Marino case SSL_kECDHe: 1604*f5b1c8a1SJohn Marino kx = "ECDH/ECDSA"; 1605*f5b1c8a1SJohn Marino break; 1606*f5b1c8a1SJohn Marino case SSL_kECDHE: 1607*f5b1c8a1SJohn Marino kx = "ECDH"; 1608*f5b1c8a1SJohn Marino break; 1609*f5b1c8a1SJohn Marino case SSL_kGOST: 1610*f5b1c8a1SJohn Marino kx = "GOST"; 1611*f5b1c8a1SJohn Marino break; 1612*f5b1c8a1SJohn Marino default: 1613*f5b1c8a1SJohn Marino kx = "unknown"; 1614*f5b1c8a1SJohn Marino } 1615*f5b1c8a1SJohn Marino 1616*f5b1c8a1SJohn Marino switch (alg_auth) { 1617*f5b1c8a1SJohn Marino case SSL_aRSA: 1618*f5b1c8a1SJohn Marino au = "RSA"; 1619*f5b1c8a1SJohn Marino break; 1620*f5b1c8a1SJohn Marino case SSL_aDSS: 1621*f5b1c8a1SJohn Marino au = "DSS"; 1622*f5b1c8a1SJohn Marino break; 1623*f5b1c8a1SJohn Marino case SSL_aECDH: 1624*f5b1c8a1SJohn Marino au = "ECDH"; 1625*f5b1c8a1SJohn Marino break; 1626*f5b1c8a1SJohn Marino case SSL_aNULL: 1627*f5b1c8a1SJohn Marino au = "None"; 1628*f5b1c8a1SJohn Marino break; 1629*f5b1c8a1SJohn Marino case SSL_aECDSA: 1630*f5b1c8a1SJohn Marino au = "ECDSA"; 1631*f5b1c8a1SJohn Marino break; 1632*f5b1c8a1SJohn Marino case SSL_aGOST01: 1633*f5b1c8a1SJohn Marino au = "GOST01"; 1634*f5b1c8a1SJohn Marino break; 1635*f5b1c8a1SJohn Marino default: 1636*f5b1c8a1SJohn Marino au = "unknown"; 1637*f5b1c8a1SJohn Marino break; 1638*f5b1c8a1SJohn Marino } 1639*f5b1c8a1SJohn Marino 1640*f5b1c8a1SJohn Marino switch (alg_enc) { 1641*f5b1c8a1SJohn Marino case SSL_DES: 1642*f5b1c8a1SJohn Marino enc = "DES(56)"; 1643*f5b1c8a1SJohn Marino break; 1644*f5b1c8a1SJohn Marino case SSL_3DES: 1645*f5b1c8a1SJohn Marino enc = "3DES(168)"; 1646*f5b1c8a1SJohn Marino break; 1647*f5b1c8a1SJohn Marino case SSL_RC4: 1648*f5b1c8a1SJohn Marino enc = alg2 & SSL2_CF_8_BYTE_ENC ? "RC4(64)" : "RC4(128)"; 1649*f5b1c8a1SJohn Marino break; 1650*f5b1c8a1SJohn Marino case SSL_IDEA: 1651*f5b1c8a1SJohn Marino enc = "IDEA(128)"; 1652*f5b1c8a1SJohn Marino break; 1653*f5b1c8a1SJohn Marino case SSL_eNULL: 1654*f5b1c8a1SJohn Marino enc = "None"; 1655*f5b1c8a1SJohn Marino break; 1656*f5b1c8a1SJohn Marino case SSL_AES128: 1657*f5b1c8a1SJohn Marino enc = "AES(128)"; 1658*f5b1c8a1SJohn Marino break; 1659*f5b1c8a1SJohn Marino case SSL_AES256: 1660*f5b1c8a1SJohn Marino enc = "AES(256)"; 1661*f5b1c8a1SJohn Marino break; 1662*f5b1c8a1SJohn Marino case SSL_AES128GCM: 1663*f5b1c8a1SJohn Marino enc = "AESGCM(128)"; 1664*f5b1c8a1SJohn Marino break; 1665*f5b1c8a1SJohn Marino case SSL_AES256GCM: 1666*f5b1c8a1SJohn Marino enc = "AESGCM(256)"; 1667*f5b1c8a1SJohn Marino break; 1668*f5b1c8a1SJohn Marino case SSL_CAMELLIA128: 1669*f5b1c8a1SJohn Marino enc = "Camellia(128)"; 1670*f5b1c8a1SJohn Marino break; 1671*f5b1c8a1SJohn Marino case SSL_CAMELLIA256: 1672*f5b1c8a1SJohn Marino enc = "Camellia(256)"; 1673*f5b1c8a1SJohn Marino break; 1674*f5b1c8a1SJohn Marino case SSL_CHACHA20POLY1305: 1675*f5b1c8a1SJohn Marino enc = "ChaCha20-Poly1305"; 1676*f5b1c8a1SJohn Marino break; 1677*f5b1c8a1SJohn Marino case SSL_CHACHA20POLY1305_OLD: 1678*f5b1c8a1SJohn Marino enc = "ChaCha20-Poly1305-Old"; 1679*f5b1c8a1SJohn Marino break; 1680*f5b1c8a1SJohn Marino case SSL_eGOST2814789CNT: 1681*f5b1c8a1SJohn Marino enc = "GOST-28178-89-CNT"; 1682*f5b1c8a1SJohn Marino break; 1683*f5b1c8a1SJohn Marino default: 1684*f5b1c8a1SJohn Marino enc = "unknown"; 1685*f5b1c8a1SJohn Marino break; 1686*f5b1c8a1SJohn Marino } 1687*f5b1c8a1SJohn Marino 1688*f5b1c8a1SJohn Marino switch (alg_mac) { 1689*f5b1c8a1SJohn Marino case SSL_MD5: 1690*f5b1c8a1SJohn Marino mac = "MD5"; 1691*f5b1c8a1SJohn Marino break; 1692*f5b1c8a1SJohn Marino case SSL_SHA1: 1693*f5b1c8a1SJohn Marino mac = "SHA1"; 1694*f5b1c8a1SJohn Marino break; 1695*f5b1c8a1SJohn Marino case SSL_SHA256: 1696*f5b1c8a1SJohn Marino mac = "SHA256"; 1697*f5b1c8a1SJohn Marino break; 1698*f5b1c8a1SJohn Marino case SSL_SHA384: 1699*f5b1c8a1SJohn Marino mac = "SHA384"; 1700*f5b1c8a1SJohn Marino break; 1701*f5b1c8a1SJohn Marino case SSL_AEAD: 1702*f5b1c8a1SJohn Marino mac = "AEAD"; 1703*f5b1c8a1SJohn Marino break; 1704*f5b1c8a1SJohn Marino case SSL_GOST94: 1705*f5b1c8a1SJohn Marino mac = "GOST94"; 1706*f5b1c8a1SJohn Marino break; 1707*f5b1c8a1SJohn Marino case SSL_GOST89MAC: 1708*f5b1c8a1SJohn Marino mac = "GOST89IMIT"; 1709*f5b1c8a1SJohn Marino break; 1710*f5b1c8a1SJohn Marino case SSL_STREEBOG256: 1711*f5b1c8a1SJohn Marino mac = "STREEBOG256"; 1712*f5b1c8a1SJohn Marino break; 1713*f5b1c8a1SJohn Marino case SSL_STREEBOG512: 1714*f5b1c8a1SJohn Marino mac = "STREEBOG512"; 1715*f5b1c8a1SJohn Marino break; 1716*f5b1c8a1SJohn Marino default: 1717*f5b1c8a1SJohn Marino mac = "unknown"; 1718*f5b1c8a1SJohn Marino break; 1719*f5b1c8a1SJohn Marino } 1720*f5b1c8a1SJohn Marino 1721*f5b1c8a1SJohn Marino if (asprintf(&ret, "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", 1722*f5b1c8a1SJohn Marino cipher->name, ver, kx, au, enc, mac) == -1) 1723*f5b1c8a1SJohn Marino return "OPENSSL_malloc Error"; 1724*f5b1c8a1SJohn Marino 1725*f5b1c8a1SJohn Marino if (buf != NULL) { 1726*f5b1c8a1SJohn Marino l = strlcpy(buf, ret, len); 1727*f5b1c8a1SJohn Marino free(ret); 1728*f5b1c8a1SJohn Marino ret = buf; 1729*f5b1c8a1SJohn Marino if (l >= len) 1730*f5b1c8a1SJohn Marino ret = "Buffer too small"; 1731*f5b1c8a1SJohn Marino } 1732*f5b1c8a1SJohn Marino 1733*f5b1c8a1SJohn Marino return (ret); 1734*f5b1c8a1SJohn Marino } 1735*f5b1c8a1SJohn Marino 1736*f5b1c8a1SJohn Marino char * 1737*f5b1c8a1SJohn Marino SSL_CIPHER_get_version(const SSL_CIPHER *c) 1738*f5b1c8a1SJohn Marino { 1739*f5b1c8a1SJohn Marino if (c == NULL) 1740*f5b1c8a1SJohn Marino return("(NONE)"); 1741*f5b1c8a1SJohn Marino if ((c->id >> 24) == 3) 1742*f5b1c8a1SJohn Marino return("TLSv1/SSLv3"); 1743*f5b1c8a1SJohn Marino else 1744*f5b1c8a1SJohn Marino return("unknown"); 1745*f5b1c8a1SJohn Marino } 1746*f5b1c8a1SJohn Marino 1747*f5b1c8a1SJohn Marino /* return the actual cipher being used */ 1748*f5b1c8a1SJohn Marino const char * 1749*f5b1c8a1SJohn Marino SSL_CIPHER_get_name(const SSL_CIPHER *c) 1750*f5b1c8a1SJohn Marino { 1751*f5b1c8a1SJohn Marino if (c != NULL) 1752*f5b1c8a1SJohn Marino return (c->name); 1753*f5b1c8a1SJohn Marino return("(NONE)"); 1754*f5b1c8a1SJohn Marino } 1755*f5b1c8a1SJohn Marino 1756*f5b1c8a1SJohn Marino /* number of bits for symmetric cipher */ 1757*f5b1c8a1SJohn Marino int 1758*f5b1c8a1SJohn Marino SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) 1759*f5b1c8a1SJohn Marino { 1760*f5b1c8a1SJohn Marino int ret = 0; 1761*f5b1c8a1SJohn Marino 1762*f5b1c8a1SJohn Marino if (c != NULL) { 1763*f5b1c8a1SJohn Marino if (alg_bits != NULL) 1764*f5b1c8a1SJohn Marino *alg_bits = c->alg_bits; 1765*f5b1c8a1SJohn Marino ret = c->strength_bits; 1766*f5b1c8a1SJohn Marino } 1767*f5b1c8a1SJohn Marino return (ret); 1768*f5b1c8a1SJohn Marino } 1769*f5b1c8a1SJohn Marino 1770*f5b1c8a1SJohn Marino unsigned long 1771*f5b1c8a1SJohn Marino SSL_CIPHER_get_id(const SSL_CIPHER *c) 1772*f5b1c8a1SJohn Marino { 1773*f5b1c8a1SJohn Marino return c->id; 1774*f5b1c8a1SJohn Marino } 1775*f5b1c8a1SJohn Marino 1776*f5b1c8a1SJohn Marino uint16_t 1777*f5b1c8a1SJohn Marino SSL_CIPHER_get_value(const SSL_CIPHER *c) 1778*f5b1c8a1SJohn Marino { 1779*f5b1c8a1SJohn Marino return ssl3_cipher_get_value(c); 1780*f5b1c8a1SJohn Marino } 1781*f5b1c8a1SJohn Marino 1782*f5b1c8a1SJohn Marino void * 1783*f5b1c8a1SJohn Marino SSL_COMP_get_compression_methods(void) 1784*f5b1c8a1SJohn Marino { 1785*f5b1c8a1SJohn Marino return NULL; 1786*f5b1c8a1SJohn Marino } 1787*f5b1c8a1SJohn Marino 1788*f5b1c8a1SJohn Marino int 1789*f5b1c8a1SJohn Marino SSL_COMP_add_compression_method(int id, void *cm) 1790*f5b1c8a1SJohn Marino { 1791*f5b1c8a1SJohn Marino return 1; 1792*f5b1c8a1SJohn Marino } 1793*f5b1c8a1SJohn Marino 1794*f5b1c8a1SJohn Marino const char * 1795*f5b1c8a1SJohn Marino SSL_COMP_get_name(const void *comp) 1796*f5b1c8a1SJohn Marino { 1797*f5b1c8a1SJohn Marino return NULL; 1798*f5b1c8a1SJohn Marino } 1799