blob: 5a8668363ad4e2c73d757b5abe25f91cf56b742b [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110/* ====================================================================
111 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112 * ECC cipher suite support in OpenSSL originally developed by
113 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
114 */
115/* ====================================================================
116 * Copyright 2005 Nokia. All rights reserved.
117 *
118 * The portions of the attached software ("Contribution") is developed by
119 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
120 * license.
121 *
122 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
123 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
124 * support (see RFC 4279) to OpenSSL.
125 *
126 * No patent licenses or other rights except those expressly stated in
127 * the OpenSSL open source license shall be deemed granted or received
128 * expressly, by implication, estoppel, or otherwise.
129 *
130 * No assurances are provided by Nokia that the Contribution does not
131 * infringe the patent or other intellectual property rights of any third
132 * party or that the license provides you with all the necessary rights
133 * to make use of the Contribution.
134 *
135 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
136 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
137 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
138 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
139 * OTHERWISE. */
140
141#include <stdio.h>
142#include <assert.h>
143
Adam Langley95c29f32014-06-20 12:00:00 -0700144#include <openssl/engine.h>
145#include <openssl/mem.h>
146#include <openssl/obj.h>
147
148#include "ssl_locl.h"
149
150#define SSL_ENC_DES_IDX 0
151#define SSL_ENC_3DES_IDX 1
152#define SSL_ENC_RC4_IDX 2
153#define SSL_ENC_RC2_IDX 3
154#define SSL_ENC_IDEA_IDX 4
155#define SSL_ENC_NULL_IDX 5
156#define SSL_ENC_AES128_IDX 6
157#define SSL_ENC_AES256_IDX 7
158#define SSL_ENC_CAMELLIA128_IDX 8
159#define SSL_ENC_CAMELLIA256_IDX 9
David Benjamin019c3cc2014-07-14 23:13:22 -0400160#define SSL_ENC_SEED_IDX 10
161#define SSL_ENC_AES128GCM_IDX 11
162#define SSL_ENC_AES256GCM_IDX 12
163#define SSL_ENC_NUM_IDX 13
Adam Langley95c29f32014-06-20 12:00:00 -0700164
165
David Benjamin019c3cc2014-07-14 23:13:22 -0400166static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]= { 0 };
Adam Langley95c29f32014-06-20 12:00:00 -0700167
168#define SSL_COMP_NULL_IDX 0
169#define SSL_COMP_ZLIB_IDX 1
170#define SSL_COMP_NUM_IDX 2
171
Adam Langley95c29f32014-06-20 12:00:00 -0700172#define SSL_MD_MD5_IDX 0
173#define SSL_MD_SHA1_IDX 1
David Benjamin019c3cc2014-07-14 23:13:22 -0400174#define SSL_MD_SHA256_IDX 2
175#define SSL_MD_SHA384_IDX 3
Adam Langley95c29f32014-06-20 12:00:00 -0700176/*Constant SSL_MAX_DIGEST equal to size of digests array should be
177 * defined in the
178 * ssl_locl.h */
179#define SSL_MD_NUM_IDX SSL_MAX_DIGEST
David Benjamin019c3cc2014-07-14 23:13:22 -0400180static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { 0 };
Adam Langley95c29f32014-06-20 12:00:00 -0700181static int ssl_mac_pkey_id[SSL_MD_NUM_IDX]={
David Benjamin019c3cc2014-07-14 23:13:22 -0400182 EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC,
Adam Langley95c29f32014-06-20 12:00:00 -0700183 };
184
David Benjamin019c3cc2014-07-14 23:13:22 -0400185static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { 0 };
Adam Langley95c29f32014-06-20 12:00:00 -0700186
187static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX]={
David Benjamin019c3cc2014-07-14 23:13:22 -0400188 SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA,
189 SSL_HANDSHAKE_MAC_SHA256, SSL_HANDSHAKE_MAC_SHA384,
Adam Langley95c29f32014-06-20 12:00:00 -0700190 };
191
192#define CIPHER_ADD 1
193#define CIPHER_KILL 2
194#define CIPHER_DEL 3
195#define CIPHER_ORD 4
196#define CIPHER_SPECIAL 5
197
198typedef struct cipher_order_st
199 {
200 const SSL_CIPHER *cipher;
201 int active;
202 int dead;
Adam Langley858a88d2014-06-20 12:00:00 -0700203 int in_group;
Adam Langley95c29f32014-06-20 12:00:00 -0700204 struct cipher_order_st *next,*prev;
205 } CIPHER_ORDER;
206
207static const SSL_CIPHER cipher_aliases[]={
208 /* "ALL" doesn't include eNULL (must be specifically enabled) */
209 {0,SSL_TXT_ALL,0, 0,0,~SSL_eNULL,0,0,0,0,0,0},
210 /* "COMPLEMENTOFALL" */
211 {0,SSL_TXT_CMPALL,0, 0,0,SSL_eNULL,0,0,0,0,0,0},
212
213 /* "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in ALL!) */
214 {0,SSL_TXT_CMPDEF,0, SSL_kEDH|SSL_kEECDH,SSL_aNULL,~SSL_eNULL,0,0,0,0,0,0},
215
216 /* key exchange aliases
217 * (some of those using only a single bit here combine
218 * multiple key exchange algs according to the RFCs,
219 * e.g. kEDH combines DHE_DSS and DHE_RSA) */
220 {0,SSL_TXT_kRSA,0, SSL_kRSA, 0,0,0,0,0,0,0,0},
221
222 {0,SSL_TXT_kDHr,0, SSL_kDHr, 0,0,0,0,0,0,0,0},
223 {0,SSL_TXT_kDHd,0, SSL_kDHd, 0,0,0,0,0,0,0,0},
224 {0,SSL_TXT_kDH,0, SSL_kDHr|SSL_kDHd,0,0,0,0,0,0,0,0},
225 {0,SSL_TXT_kEDH,0, SSL_kEDH, 0,0,0,0,0,0,0,0},
226 {0,SSL_TXT_DH,0, SSL_kDHr|SSL_kDHd|SSL_kEDH,0,0,0,0,0,0,0,0},
227
Adam Langley95c29f32014-06-20 12:00:00 -0700228 {0,SSL_TXT_kECDHr,0, SSL_kECDHr,0,0,0,0,0,0,0,0},
229 {0,SSL_TXT_kECDHe,0, SSL_kECDHe,0,0,0,0,0,0,0,0},
230 {0,SSL_TXT_kECDH,0, SSL_kECDHr|SSL_kECDHe,0,0,0,0,0,0,0,0},
231 {0,SSL_TXT_kEECDH,0, SSL_kEECDH,0,0,0,0,0,0,0,0},
232 {0,SSL_TXT_ECDH,0, SSL_kECDHr|SSL_kECDHe|SSL_kEECDH,0,0,0,0,0,0,0,0},
233
234 {0,SSL_TXT_kPSK,0, SSL_kPSK, 0,0,0,0,0,0,0,0},
235 {0,SSL_TXT_kSRP,0, SSL_kSRP, 0,0,0,0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700236
237 /* server authentication aliases */
238 {0,SSL_TXT_aRSA,0, 0,SSL_aRSA, 0,0,0,0,0,0,0},
239 {0,SSL_TXT_aDSS,0, 0,SSL_aDSS, 0,0,0,0,0,0,0},
240 {0,SSL_TXT_DSS,0, 0,SSL_aDSS, 0,0,0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700241 {0,SSL_TXT_aNULL,0, 0,SSL_aNULL, 0,0,0,0,0,0,0},
242 {0,SSL_TXT_aDH,0, 0,SSL_aDH, 0,0,0,0,0,0,0}, /* no such ciphersuites supported! */
243 {0,SSL_TXT_aECDH,0, 0,SSL_aECDH, 0,0,0,0,0,0,0},
244 {0,SSL_TXT_aECDSA,0, 0,SSL_aECDSA,0,0,0,0,0,0,0},
245 {0,SSL_TXT_ECDSA,0, 0,SSL_aECDSA, 0,0,0,0,0,0,0},
246 {0,SSL_TXT_aPSK,0, 0,SSL_aPSK, 0,0,0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700247
248 /* aliases combining key exchange and server authentication */
249 {0,SSL_TXT_EDH,0, SSL_kEDH,~SSL_aNULL,0,0,0,0,0,0,0},
250 {0,SSL_TXT_EECDH,0, SSL_kEECDH,~SSL_aNULL,0,0,0,0,0,0,0},
251 {0,SSL_TXT_NULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700252 {0,SSL_TXT_RSA,0, SSL_kRSA,SSL_aRSA,0,0,0,0,0,0,0},
253 {0,SSL_TXT_ADH,0, SSL_kEDH,SSL_aNULL,0,0,0,0,0,0,0},
254 {0,SSL_TXT_AECDH,0, SSL_kEECDH,SSL_aNULL,0,0,0,0,0,0,0},
255 {0,SSL_TXT_PSK,0, SSL_kPSK,SSL_aPSK,0,0,0,0,0,0,0},
256 {0,SSL_TXT_SRP,0, SSL_kSRP,0,0,0,0,0,0,0,0},
257
258
259 /* symmetric encryption aliases */
260 {0,SSL_TXT_DES,0, 0,0,SSL_DES, 0,0,0,0,0,0},
261 {0,SSL_TXT_3DES,0, 0,0,SSL_3DES, 0,0,0,0,0,0},
262 {0,SSL_TXT_RC4,0, 0,0,SSL_RC4, 0,0,0,0,0,0},
263 {0,SSL_TXT_RC2,0, 0,0,SSL_RC2, 0,0,0,0,0,0},
264 {0,SSL_TXT_IDEA,0, 0,0,SSL_IDEA, 0,0,0,0,0,0},
265 {0,SSL_TXT_SEED,0, 0,0,SSL_SEED, 0,0,0,0,0,0},
266 {0,SSL_TXT_eNULL,0, 0,0,SSL_eNULL, 0,0,0,0,0,0},
267 {0,SSL_TXT_AES128,0, 0,0,SSL_AES128|SSL_AES128GCM,0,0,0,0,0,0},
268 {0,SSL_TXT_AES256,0, 0,0,SSL_AES256|SSL_AES256GCM,0,0,0,0,0,0},
269 {0,SSL_TXT_AES,0, 0,0,SSL_AES,0,0,0,0,0,0},
270 {0,SSL_TXT_AES_GCM,0, 0,0,SSL_AES128GCM|SSL_AES256GCM,0,0,0,0,0,0},
271 {0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
272 {0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
273 {0,SSL_TXT_CAMELLIA ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
Adam Langleyde0b2022014-06-20 12:00:00 -0700274 {0,SSL_TXT_CHACHA20 ,0,0,0,SSL_CHACHA20POLY1305,0,0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700275
276 /* MAC aliases */
277 {0,SSL_TXT_MD5,0, 0,0,0,SSL_MD5, 0,0,0,0,0},
278 {0,SSL_TXT_SHA1,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
279 {0,SSL_TXT_SHA,0, 0,0,0,SSL_SHA1, 0,0,0,0,0},
Adam Langley95c29f32014-06-20 12:00:00 -0700280 {0,SSL_TXT_SHA256,0, 0,0,0,SSL_SHA256, 0,0,0,0,0},
281 {0,SSL_TXT_SHA384,0, 0,0,0,SSL_SHA384, 0,0,0,0,0},
282
283 /* protocol version aliases */
284 {0,SSL_TXT_SSLV2,0, 0,0,0,0,SSL_SSLV2, 0,0,0,0},
285 {0,SSL_TXT_SSLV3,0, 0,0,0,0,SSL_SSLV3, 0,0,0,0},
286 {0,SSL_TXT_TLSV1,0, 0,0,0,0,SSL_TLSV1, 0,0,0,0},
287 {0,SSL_TXT_TLSV1_2,0, 0,0,0,0,SSL_TLSV1_2, 0,0,0,0},
288
289 /* export flag */
290 {0,SSL_TXT_EXP,0, 0,0,0,0,0,SSL_EXPORT,0,0,0},
291 {0,SSL_TXT_EXPORT,0, 0,0,0,0,0,SSL_EXPORT,0,0,0},
292
293 /* strength classes */
294 {0,SSL_TXT_EXP40,0, 0,0,0,0,0,SSL_EXP40, 0,0,0},
295 {0,SSL_TXT_EXP56,0, 0,0,0,0,0,SSL_EXP56, 0,0,0},
296 {0,SSL_TXT_LOW,0, 0,0,0,0,0,SSL_LOW, 0,0,0},
297 {0,SSL_TXT_MEDIUM,0, 0,0,0,0,0,SSL_MEDIUM,0,0,0},
298 {0,SSL_TXT_HIGH,0, 0,0,0,0,0,SSL_HIGH, 0,0,0},
299 /* FIPS 140-2 approved ciphersuite */
300 {0,SSL_TXT_FIPS,0, 0,0,~SSL_eNULL,0,0,SSL_FIPS, 0,0,0},
301 };
302
303void ssl_load_ciphers(void)
304 {
305 ssl_cipher_methods[SSL_ENC_DES_IDX]= EVP_des_cbc();
306 ssl_cipher_methods[SSL_ENC_3DES_IDX]= EVP_des_ede3_cbc();
307 ssl_cipher_methods[SSL_ENC_RC4_IDX]= EVP_rc4();
308 ssl_cipher_methods[SSL_ENC_AES128_IDX]= EVP_aes_128_cbc();
309 ssl_cipher_methods[SSL_ENC_AES256_IDX]= EVP_aes_256_cbc();
310
311 ssl_cipher_methods[SSL_ENC_AES128GCM_IDX]= EVP_aes_128_gcm();
312 ssl_cipher_methods[SSL_ENC_AES256GCM_IDX]= EVP_aes_256_gcm();
313
314 ssl_digest_methods[SSL_MD_MD5_IDX]= EVP_md5();
315 ssl_mac_secret_size[SSL_MD_MD5_IDX]= EVP_MD_size(EVP_md5());
316 assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0);
317 ssl_digest_methods[SSL_MD_SHA1_IDX]=EVP_sha1();
318 ssl_mac_secret_size[SSL_MD_SHA1_IDX]= EVP_MD_size(EVP_sha1());
319 assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0);
320
321 ssl_digest_methods[SSL_MD_SHA256_IDX]= EVP_sha256();
322 ssl_mac_secret_size[SSL_MD_SHA256_IDX]= EVP_MD_size(EVP_sha256());
323 ssl_digest_methods[SSL_MD_SHA384_IDX]= EVP_sha384();
324 ssl_mac_secret_size[SSL_MD_SHA384_IDX]= EVP_MD_size(EVP_sha384());
325 }
326
Adam Langleyc9fb3752014-06-20 12:00:00 -0700327/* ssl_cipher_get_evp_aead sets |*aead| to point to the correct EVP_AEAD object
328 * for |s->cipher|. It returns 1 on success and 0 on error. */
329int ssl_cipher_get_evp_aead(const SSL_SESSION *s, const EVP_AEAD **aead)
330 {
331 const SSL_CIPHER *c = s->cipher;
332
333 *aead = NULL;
334
335 if (c == NULL)
336 return 0;
Adam Langley9447dff2014-06-24 17:29:06 -0700337 if ((c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) == 0 &&
338 (c->algorithm2 & SSL_CIPHER_ALGORITHM2_STATEFUL_AEAD) == 0)
Adam Langleyc9fb3752014-06-20 12:00:00 -0700339 return 0;
340
341#ifndef OPENSSL_NO_AES
Adam Langleyde0b2022014-06-20 12:00:00 -0700342 switch (c->algorithm_enc)
343 {
344 case SSL_AES128GCM:
345 *aead = EVP_aead_aes_128_gcm();
346 return 1;
Adam Langley5c270c52014-06-20 12:00:00 -0700347 case SSL_AES256GCM:
348 *aead = EVP_aead_aes_256_gcm();
349 return 1;
Adam Langleyde0b2022014-06-20 12:00:00 -0700350 case SSL_CHACHA20POLY1305:
351 *aead = EVP_aead_chacha20_poly1305();
352 return 1;
Adam Langley9447dff2014-06-24 17:29:06 -0700353 case SSL_RC4:
354 if (c->algorithm_mac == SSL_MD5)
355 *aead = EVP_aead_rc4_md5_tls();
356 else
357 return 0;
358 return 1;
359 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700360#endif
361
362 return 0;
363 }
364
365int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
366 const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
367 {
Adam Langley95c29f32014-06-20 12:00:00 -0700368 int i;
369 const SSL_CIPHER *c;
370
371 c=s->cipher;
372 if (c == NULL) return(0);
Adam Langley95c29f32014-06-20 12:00:00 -0700373
Adam Langleyc9fb3752014-06-20 12:00:00 -0700374 /* This function doesn't deal with EVP_AEAD. See
375 * |ssl_cipher_get_aead_evp|. */
376 if (c->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD)
377 return(0);
Adam Langley95c29f32014-06-20 12:00:00 -0700378
379 if ((enc == NULL) || (md == NULL)) return(0);
380
381 switch (c->algorithm_enc)
382 {
383 case SSL_DES:
384 i=SSL_ENC_DES_IDX;
385 break;
386 case SSL_3DES:
387 i=SSL_ENC_3DES_IDX;
388 break;
389 case SSL_RC4:
390 i=SSL_ENC_RC4_IDX;
391 break;
392 case SSL_RC2:
393 i=SSL_ENC_RC2_IDX;
394 break;
395 case SSL_IDEA:
396 i=SSL_ENC_IDEA_IDX;
397 break;
398 case SSL_eNULL:
399 i=SSL_ENC_NULL_IDX;
400 break;
401 case SSL_AES128:
402 i=SSL_ENC_AES128_IDX;
403 break;
404 case SSL_AES256:
405 i=SSL_ENC_AES256_IDX;
406 break;
407 case SSL_CAMELLIA128:
408 i=SSL_ENC_CAMELLIA128_IDX;
409 break;
410 case SSL_CAMELLIA256:
411 i=SSL_ENC_CAMELLIA256_IDX;
412 break;
Adam Langley95c29f32014-06-20 12:00:00 -0700413 case SSL_SEED:
414 i=SSL_ENC_SEED_IDX;
415 break;
416 case SSL_AES128GCM:
417 i=SSL_ENC_AES128GCM_IDX;
418 break;
419 case SSL_AES256GCM:
420 i=SSL_ENC_AES256GCM_IDX;
421 break;
422 default:
423 i= -1;
424 break;
425 }
426
Adam Langley4c65f3a2014-06-20 12:00:00 -0700427 if ((i < 0) || (i >= SSL_ENC_NUM_IDX))
Adam Langley95c29f32014-06-20 12:00:00 -0700428 *enc=NULL;
429 else
430 {
431 if (i == SSL_ENC_NULL_IDX)
432 *enc = EVP_enc_null();
433
434 *enc=ssl_cipher_methods[i];
435 }
436
Adam Langley9447dff2014-06-24 17:29:06 -0700437 if (!ssl_cipher_get_mac(s, md, mac_pkey_type, mac_secret_size))
438 return 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700439
440 if ((*enc != NULL) &&
441 (*md != NULL || (EVP_CIPHER_flags(*enc)&EVP_CIPH_FLAG_AEAD_CIPHER)) &&
442 (!mac_pkey_type||*mac_pkey_type != NID_undef))
443 {
444 if (s->ssl_version>>8 != TLS1_VERSION_MAJOR ||
445 s->ssl_version < TLS1_VERSION)
446 return 1;
447
Adam Langley95c29f32014-06-20 12:00:00 -0700448 /* TODO(fork): enable the stitched cipher modes. */
449#if 0
450 if (c->algorithm_enc == SSL_RC4 &&
451 c->algorithm_mac == SSL_MD5 &&
452 (evp=EVP_get_cipherbyname("RC4-HMAC-MD5")))
453 *enc = evp, *md = NULL;
454 else if (c->algorithm_enc == SSL_AES128 &&
455 c->algorithm_mac == SSL_SHA1 &&
456 (evp=EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1")))
457 *enc = evp, *md = NULL;
458 else if (c->algorithm_enc == SSL_AES256 &&
459 c->algorithm_mac == SSL_SHA1 &&
460 (evp=EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1")))
461 *enc = evp, *md = NULL;
462#endif
463 return(1);
464 }
465 else
466 return(0);
467 }
468
Adam Langley9447dff2014-06-24 17:29:06 -0700469int ssl_cipher_get_mac(const SSL_SESSION *s, const EVP_MD **md, int *mac_pkey_type, int *mac_secret_size)
470 {
471 int i;
472 const SSL_CIPHER *c;
473
474 c=s->cipher;
475 if (c == NULL) return(0);
476
477 switch (c->algorithm_mac)
478 {
479 case SSL_MD5:
480 i=SSL_MD_MD5_IDX;
481 break;
482 case SSL_SHA1:
483 i=SSL_MD_SHA1_IDX;
484 break;
485 case SSL_SHA256:
486 i=SSL_MD_SHA256_IDX;
487 break;
488 case SSL_SHA384:
489 i=SSL_MD_SHA384_IDX;
490 break;
Adam Langley9447dff2014-06-24 17:29:06 -0700491 default:
492 i= -1;
493 break;
494 }
495
496 if ((i < 0) || (i >= SSL_MD_NUM_IDX))
497 {
498 *md=NULL;
499 if (mac_pkey_type!=NULL) *mac_pkey_type = NID_undef;
500 if (mac_secret_size!=NULL) *mac_secret_size = 0;
501 }
502 else
503 {
504 *md=ssl_digest_methods[i];
505 if (mac_pkey_type!=NULL) *mac_pkey_type = ssl_mac_pkey_id[i];
506 if (mac_secret_size!=NULL) *mac_secret_size = ssl_mac_secret_size[i];
507 }
508
509 return 1;
510 }
511
Adam Langley95c29f32014-06-20 12:00:00 -0700512int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md)
513{
514 if (idx <0||idx>=SSL_MD_NUM_IDX)
515 {
516 return 0;
517 }
518 *mask = ssl_handshake_digest_flag[idx];
519 if (*mask)
520 *md = ssl_digest_methods[idx];
521 else
522 *md = NULL;
523 return 1;
524}
525
526#define ITEM_SEP(a) \
527 (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ','))
528
529static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr,
530 CIPHER_ORDER **tail)
531 {
532 if (curr == *tail) return;
533 if (curr == *head)
534 *head=curr->next;
535 if (curr->prev != NULL)
536 curr->prev->next=curr->next;
537 if (curr->next != NULL)
538 curr->next->prev=curr->prev;
539 (*tail)->next=curr;
540 curr->prev= *tail;
541 curr->next=NULL;
542 *tail=curr;
543 }
544
545static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr,
546 CIPHER_ORDER **tail)
547 {
548 if (curr == *head) return;
549 if (curr == *tail)
550 *tail=curr->prev;
551 if (curr->next != NULL)
552 curr->next->prev=curr->prev;
553 if (curr->prev != NULL)
554 curr->prev->next=curr->next;
555 (*head)->prev=curr;
556 curr->next= *head;
557 curr->prev=NULL;
558 *head=curr;
559 }
560
561static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, unsigned long *enc, unsigned long *mac, unsigned long *ssl)
562 {
563 *mkey = 0;
564 *auth = 0;
565 *enc = 0;
566 *mac = 0;
567 *ssl = 0;
568
Adam Langley95c29f32014-06-20 12:00:00 -0700569#ifdef OPENSSL_NO_DSA
570 *auth |= SSL_aDSS;
571#endif
572#ifdef OPENSSL_NO_DH
573 *mkey |= SSL_kDHr|SSL_kDHd|SSL_kEDH;
574 *auth |= SSL_aDH;
575#endif
576#ifdef OPENSSL_NO_ECDSA
577 *auth |= SSL_aECDSA;
578#endif
579#ifdef OPENSSL_NO_ECDH
580 *mkey |= SSL_kECDHe|SSL_kECDHr;
581 *auth |= SSL_aECDH;
582#endif
Adam Langley95c29f32014-06-20 12:00:00 -0700583#ifdef SSL_FORBID_ENULL
584 *enc |= SSL_eNULL;
585#endif
586
587
588
589 *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX ] == NULL) ? SSL_DES :0;
590 *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES:0;
591 *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX ] == NULL) ? SSL_RC4 :0;
592 *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX ] == NULL) ? SSL_RC2 :0;
593 *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA:0;
594 *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128:0;
595 *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256:0;
596 *enc |= (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == NULL) ? SSL_AES128GCM:0;
597 *enc |= (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == NULL) ? SSL_AES256GCM:0;
598 *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == NULL) ? SSL_CAMELLIA128:0;
599 *enc |= (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == NULL) ? SSL_CAMELLIA256:0;
Adam Langley95c29f32014-06-20 12:00:00 -0700600 *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED:0;
601
602 *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX ] == NULL) ? SSL_MD5 :0;
603 *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1:0;
604 *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256:0;
605 *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384:0;
Adam Langley95c29f32014-06-20 12:00:00 -0700606
607 }
608
609static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method,
610 int num_of_ciphers,
611 unsigned long disabled_mkey, unsigned long disabled_auth,
612 unsigned long disabled_enc, unsigned long disabled_mac,
613 unsigned long disabled_ssl,
614 CIPHER_ORDER *co_list,
615 CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
616 {
617 int i, co_list_num;
618 const SSL_CIPHER *c;
619
620 /*
621 * We have num_of_ciphers descriptions compiled in, depending on the
622 * method selected (SSLv2 and/or SSLv3, TLSv1 etc).
623 * These will later be sorted in a linked list with at most num
624 * entries.
625 */
626
627 /* Get the initial list of ciphers */
628 co_list_num = 0; /* actual count of ciphers */
629 for (i = 0; i < num_of_ciphers; i++)
630 {
631 c = ssl_method->get_cipher(i);
632 /* drop those that use any of that is not available */
633 if ((c != NULL) && c->valid &&
Adam Langley95c29f32014-06-20 12:00:00 -0700634 !(c->algorithm_mkey & disabled_mkey) &&
635 !(c->algorithm_auth & disabled_auth) &&
636 !(c->algorithm_enc & disabled_enc) &&
637 !(c->algorithm_mac & disabled_mac) &&
638 !(c->algorithm_ssl & disabled_ssl))
639 {
640 co_list[co_list_num].cipher = c;
641 co_list[co_list_num].next = NULL;
642 co_list[co_list_num].prev = NULL;
643 co_list[co_list_num].active = 0;
Adam Langley858a88d2014-06-20 12:00:00 -0700644 co_list[co_list_num].in_group = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700645 co_list_num++;
646#ifdef KSSL_DEBUG
647 printf("\t%d: %s %lx %lx %lx\n",i,c->name,c->id,c->algorithm_mkey,c->algorithm_auth);
648#endif /* KSSL_DEBUG */
649 /*
650 if (!sk_push(ca_list,(char *)c)) goto err;
651 */
652 }
653 }
654
655 /*
656 * Prepare linked list from list entries
657 */
658 if (co_list_num > 0)
659 {
660 co_list[0].prev = NULL;
661
662 if (co_list_num > 1)
663 {
664 co_list[0].next = &co_list[1];
665
666 for (i = 1; i < co_list_num - 1; i++)
667 {
668 co_list[i].prev = &co_list[i - 1];
669 co_list[i].next = &co_list[i + 1];
670 }
671
672 co_list[co_list_num - 1].prev = &co_list[co_list_num - 2];
673 }
674
675 co_list[co_list_num - 1].next = NULL;
676
677 *head_p = &co_list[0];
678 *tail_p = &co_list[co_list_num - 1];
679 }
680 }
681
682static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list,
683 int num_of_group_aliases,
684 unsigned long disabled_mkey, unsigned long disabled_auth,
685 unsigned long disabled_enc, unsigned long disabled_mac,
686 unsigned long disabled_ssl,
687 CIPHER_ORDER *head)
688 {
689 CIPHER_ORDER *ciph_curr;
690 const SSL_CIPHER **ca_curr;
691 int i;
692 unsigned long mask_mkey = ~disabled_mkey;
693 unsigned long mask_auth = ~disabled_auth;
694 unsigned long mask_enc = ~disabled_enc;
695 unsigned long mask_mac = ~disabled_mac;
696 unsigned long mask_ssl = ~disabled_ssl;
697
698 /*
699 * First, add the real ciphers as already collected
700 */
701 ciph_curr = head;
702 ca_curr = ca_list;
703 while (ciph_curr != NULL)
704 {
705 *ca_curr = ciph_curr->cipher;
706 ca_curr++;
707 ciph_curr = ciph_curr->next;
708 }
709
710 /*
711 * Now we add the available ones from the cipher_aliases[] table.
712 * They represent either one or more algorithms, some of which
713 * in any affected category must be supported (set in enabled_mask),
714 * or represent a cipher strength value (will be added in any case because algorithms=0).
715 */
716 for (i = 0; i < num_of_group_aliases; i++)
717 {
718 unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey;
719 unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth;
720 unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc;
721 unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac;
722 unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl;
723
724 if (algorithm_mkey)
725 if ((algorithm_mkey & mask_mkey) == 0)
726 continue;
727
728 if (algorithm_auth)
729 if ((algorithm_auth & mask_auth) == 0)
730 continue;
731
732 if (algorithm_enc)
733 if ((algorithm_enc & mask_enc) == 0)
734 continue;
735
736 if (algorithm_mac)
737 if ((algorithm_mac & mask_mac) == 0)
738 continue;
739
740 if (algorithm_ssl)
741 if ((algorithm_ssl & mask_ssl) == 0)
742 continue;
743
744 *ca_curr = (SSL_CIPHER *)(cipher_aliases + i);
745 ca_curr++;
746 }
747
748 *ca_curr = NULL; /* end of list */
749 }
750
751static void ssl_cipher_apply_rule(unsigned long cipher_id,
752 unsigned long alg_mkey, unsigned long alg_auth,
753 unsigned long alg_enc, unsigned long alg_mac,
754 unsigned long alg_ssl,
755 unsigned long algo_strength,
Adam Langley858a88d2014-06-20 12:00:00 -0700756 int rule, int strength_bits, int in_group,
Adam Langley95c29f32014-06-20 12:00:00 -0700757 CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p)
758 {
Adam Langleye3142a72014-07-24 17:56:48 -0700759 CIPHER_ORDER *head, *tail, *curr, *next, *last;
Adam Langley95c29f32014-06-20 12:00:00 -0700760 const SSL_CIPHER *cp;
761 int reverse = 0;
762
763#ifdef CIPHER_DEBUG
Adam Langley858a88d2014-06-20 12:00:00 -0700764 printf("Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d) in_group:%d\n",
765 rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength, strength_bits, in_group);
Adam Langley95c29f32014-06-20 12:00:00 -0700766#endif
767
768 if (rule == CIPHER_DEL)
769 reverse = 1; /* needed to maintain sorting between currently deleted ciphers */
770
771 head = *head_p;
772 tail = *tail_p;
773
774 if (reverse)
775 {
Adam Langleye3142a72014-07-24 17:56:48 -0700776 next = tail;
Adam Langley95c29f32014-06-20 12:00:00 -0700777 last = head;
778 }
779 else
780 {
Adam Langleye3142a72014-07-24 17:56:48 -0700781 next = head;
Adam Langley95c29f32014-06-20 12:00:00 -0700782 last = tail;
783 }
784
Adam Langleye3142a72014-07-24 17:56:48 -0700785 curr = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -0700786 for (;;)
787 {
Adam Langleye3142a72014-07-24 17:56:48 -0700788 if (curr == last) break;
789
790 curr = next;
791
792 if (curr == NULL) break;
793
794 next = reverse ? curr->prev : curr->next;
Adam Langley95c29f32014-06-20 12:00:00 -0700795
796 cp = curr->cipher;
797
798 /*
799 * Selection criteria is either the value of strength_bits
800 * or the algorithms used.
801 */
802 if (strength_bits >= 0)
803 {
804 if (strength_bits != cp->strength_bits)
805 continue;
806 }
807 else
808 {
809#ifdef CIPHER_DEBUG
810 printf("\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", cp->name, cp->algorithm_mkey, cp->algorithm_auth, cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, cp->algo_strength);
811#endif
812#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
813 if (cipher_id && cipher_id != cp->id)
814 continue;
815#endif
816 if (alg_mkey && !(alg_mkey & cp->algorithm_mkey))
817 continue;
818 if (alg_auth && !(alg_auth & cp->algorithm_auth))
819 continue;
820 if (alg_enc && !(alg_enc & cp->algorithm_enc))
821 continue;
822 if (alg_mac && !(alg_mac & cp->algorithm_mac))
823 continue;
824 if (alg_ssl && !(alg_ssl & cp->algorithm_ssl))
825 continue;
826 if ((algo_strength & SSL_EXP_MASK) && !(algo_strength & SSL_EXP_MASK & cp->algo_strength))
827 continue;
828 if ((algo_strength & SSL_STRONG_MASK) && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength))
829 continue;
830 }
831
832#ifdef CIPHER_DEBUG
833 printf("Action = %d\n", rule);
834#endif
835
836 /* add the cipher if it has not been added yet. */
837 if (rule == CIPHER_ADD)
838 {
839 /* reverse == 0 */
840 if (!curr->active)
841 {
842 ll_append_tail(&head, curr, &tail);
843 curr->active = 1;
Adam Langley858a88d2014-06-20 12:00:00 -0700844 curr->in_group = in_group;
Adam Langley95c29f32014-06-20 12:00:00 -0700845 }
846 }
847 /* Move the added cipher to this location */
848 else if (rule == CIPHER_ORD)
849 {
850 /* reverse == 0 */
851 if (curr->active)
852 {
853 ll_append_tail(&head, curr, &tail);
Adam Langley858a88d2014-06-20 12:00:00 -0700854 curr->in_group = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700855 }
856 }
857 else if (rule == CIPHER_DEL)
858 {
859 /* reverse == 1 */
860 if (curr->active)
861 {
862 /* most recently deleted ciphersuites get best positions
863 * for any future CIPHER_ADD (note that the CIPHER_DEL loop
864 * works in reverse to maintain the order) */
865 ll_append_head(&head, curr, &tail);
866 curr->active = 0;
Adam Langley858a88d2014-06-20 12:00:00 -0700867 curr->in_group = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700868 }
869 }
870 else if (rule == CIPHER_KILL)
871 {
872 /* reverse == 0 */
873 if (head == curr)
874 head = curr->next;
875 else
876 curr->prev->next = curr->next;
877 if (tail == curr)
878 tail = curr->prev;
879 curr->active = 0;
880 if (curr->next != NULL)
881 curr->next->prev = curr->prev;
882 if (curr->prev != NULL)
883 curr->prev->next = curr->next;
884 curr->next = NULL;
885 curr->prev = NULL;
886 }
887 }
888
889 *head_p = head;
890 *tail_p = tail;
891 }
892
893static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
894 CIPHER_ORDER **tail_p)
895 {
896 int max_strength_bits, i, *number_uses;
897 CIPHER_ORDER *curr;
898
899 /*
900 * This routine sorts the ciphers with descending strength. The sorting
901 * must keep the pre-sorted sequence, so we apply the normal sorting
902 * routine as '+' movement to the end of the list.
903 */
904 max_strength_bits = 0;
905 curr = *head_p;
906 while (curr != NULL)
907 {
908 if (curr->active &&
909 (curr->cipher->strength_bits > max_strength_bits))
910 max_strength_bits = curr->cipher->strength_bits;
911 curr = curr->next;
912 }
913
914 number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
915 if (!number_uses)
916 {
917 OPENSSL_PUT_ERROR(SSL, ssl_cipher_strength_sort, ERR_R_MALLOC_FAILURE);
918 return(0);
919 }
920 memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
921
922 /*
923 * Now find the strength_bits values actually used
924 */
925 curr = *head_p;
926 while (curr != NULL)
927 {
928 if (curr->active)
929 number_uses[curr->cipher->strength_bits]++;
930 curr = curr->next;
931 }
932 /*
933 * Go through the list of used strength_bits values in descending
934 * order.
935 */
936 for (i = max_strength_bits; i >= 0; i--)
937 if (number_uses[i] > 0)
Adam Langley858a88d2014-06-20 12:00:00 -0700938 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, tail_p);
Adam Langley95c29f32014-06-20 12:00:00 -0700939
940 OPENSSL_free(number_uses);
941 return(1);
942 }
943
944static int ssl_cipher_process_rulestr(const char *rule_str,
945 CIPHER_ORDER **head_p, CIPHER_ORDER **tail_p,
946 const SSL_CIPHER **ca_list)
947 {
948 unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength;
949 const char *l, *buf;
Adam Langley858a88d2014-06-20 12:00:00 -0700950 int j, multi, found, rule, retval, ok, buflen, in_group = 0,
951 has_group = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700952 unsigned long cipher_id = 0;
953 char ch;
954
955 retval = 1;
956 l = rule_str;
957 for (;;)
958 {
959 ch = *l;
960
961 if (ch == '\0')
962 break; /* done */
Adam Langley858a88d2014-06-20 12:00:00 -0700963 if (in_group)
964 {
965 if (ch == ']')
966 {
967 if (!in_group)
968 {
969 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_UNEXPECTED_GROUP_CLOSE);
970 retval = found = in_group = 0;
971 break;
972 }
973 if (*tail_p)
974 (*tail_p)->in_group = 0;
975 in_group = 0;
976 l++;
977 continue;
978 }
979 if (ch == '|')
980 { rule = CIPHER_ADD; l++; continue; }
981 else if (!(ch >= 'a' && ch <= 'z') &&
982 !(ch >= 'A' && ch <= 'Z') &&
983 !(ch >= '0' && ch <= '9'))
984 {
985 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
986 retval = found = in_group = 0;
987 break;
988 }
989 else
990 rule = CIPHER_ADD;
991 }
992 else if (ch == '-')
Adam Langley95c29f32014-06-20 12:00:00 -0700993 { rule = CIPHER_DEL; l++; }
994 else if (ch == '+')
995 { rule = CIPHER_ORD; l++; }
Adam Langley858a88d2014-06-20 12:00:00 -0700996 else if (ch == '!' && has_group)
997 {
998 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
999 retval = found = in_group = 0;
1000 break;
1001 }
Adam Langley95c29f32014-06-20 12:00:00 -07001002 else if (ch == '!')
1003 { rule = CIPHER_KILL; l++; }
Adam Langley858a88d2014-06-20 12:00:00 -07001004 else if (ch == '@' && has_group)
1005 {
1006 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
1007 retval = found = in_group = 0;
1008 break;
1009 }
Adam Langley95c29f32014-06-20 12:00:00 -07001010 else if (ch == '@')
1011 { rule = CIPHER_SPECIAL; l++; }
Adam Langley858a88d2014-06-20 12:00:00 -07001012 else if (ch == '[')
1013 {
1014 if (in_group)
1015 {
1016 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_NESTED_GROUP);
1017 retval = found = in_group = 0;
1018 break;
1019 }
1020 in_group = 1;
1021 has_group = 1;
1022 l++;
1023 continue;
1024 }
Adam Langley95c29f32014-06-20 12:00:00 -07001025 else
1026 { rule = CIPHER_ADD; }
1027
1028 if (ITEM_SEP(ch))
1029 {
1030 l++;
1031 continue;
1032 }
1033
1034 alg_mkey = 0;
1035 alg_auth = 0;
1036 alg_enc = 0;
1037 alg_mac = 0;
1038 alg_ssl = 0;
1039 algo_strength = 0;
1040
1041 for (;;)
1042 {
1043 ch = *l;
1044 buf = l;
1045 buflen = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001046 while ( ((ch >= 'A') && (ch <= 'Z')) ||
1047 ((ch >= '0') && (ch <= '9')) ||
1048 ((ch >= 'a') && (ch <= 'z')) ||
1049 (ch == '-') || (ch == '.'))
Adam Langley95c29f32014-06-20 12:00:00 -07001050 {
1051 ch = *(++l);
1052 buflen++;
1053 }
1054
1055 if (buflen == 0)
1056 {
1057 /*
1058 * We hit something we cannot deal with,
1059 * it is no command or separator nor
1060 * alphanumeric, so we call this an error.
1061 */
1062 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_INVALID_COMMAND);
Adam Langley858a88d2014-06-20 12:00:00 -07001063 retval = found = in_group = 0;
Adam Langley95c29f32014-06-20 12:00:00 -07001064 l++;
1065 break;
1066 }
1067
1068 if (rule == CIPHER_SPECIAL)
1069 {
1070 found = 0; /* unused -- avoid compiler warning */
1071 break; /* special treatment */
1072 }
1073
1074 /* check for multi-part specification */
1075 if (ch == '+')
1076 {
1077 multi=1;
1078 l++;
1079 }
1080 else
1081 multi=0;
1082
1083 /*
1084 * Now search for the cipher alias in the ca_list. Be careful
1085 * with the strncmp, because the "buflen" limitation
1086 * will make the rule "ADH:SOME" and the cipher
1087 * "ADH-MY-CIPHER" look like a match for buflen=3.
1088 * So additionally check whether the cipher name found
1089 * has the correct length. We can save a strlen() call:
1090 * just checking for the '\0' at the right place is
1091 * sufficient, we have to strncmp() anyway. (We cannot
1092 * use strcmp(), because buf is not '\0' terminated.)
1093 */
1094 j = found = 0;
1095 cipher_id = 0;
1096 while (ca_list[j])
1097 {
1098 if (!strncmp(buf, ca_list[j]->name, buflen) &&
1099 (ca_list[j]->name[buflen] == '\0'))
1100 {
1101 found = 1;
1102 break;
1103 }
1104 else
1105 j++;
1106 }
1107
1108 if (!found)
1109 break; /* ignore this entry */
1110
1111 if (ca_list[j]->algorithm_mkey)
1112 {
1113 if (alg_mkey)
1114 {
1115 alg_mkey &= ca_list[j]->algorithm_mkey;
1116 if (!alg_mkey) { found = 0; break; }
1117 }
1118 else
1119 alg_mkey = ca_list[j]->algorithm_mkey;
1120 }
1121
1122 if (ca_list[j]->algorithm_auth)
1123 {
1124 if (alg_auth)
1125 {
1126 alg_auth &= ca_list[j]->algorithm_auth;
1127 if (!alg_auth) { found = 0; break; }
1128 }
1129 else
1130 alg_auth = ca_list[j]->algorithm_auth;
1131 }
1132
1133 if (ca_list[j]->algorithm_enc)
1134 {
1135 if (alg_enc)
1136 {
1137 alg_enc &= ca_list[j]->algorithm_enc;
1138 if (!alg_enc) { found = 0; break; }
1139 }
1140 else
1141 alg_enc = ca_list[j]->algorithm_enc;
1142 }
1143
1144 if (ca_list[j]->algorithm_mac)
1145 {
1146 if (alg_mac)
1147 {
1148 alg_mac &= ca_list[j]->algorithm_mac;
1149 if (!alg_mac) { found = 0; break; }
1150 }
1151 else
1152 alg_mac = ca_list[j]->algorithm_mac;
1153 }
1154
1155 if (ca_list[j]->algo_strength & SSL_EXP_MASK)
1156 {
1157 if (algo_strength & SSL_EXP_MASK)
1158 {
1159 algo_strength &= (ca_list[j]->algo_strength & SSL_EXP_MASK) | ~SSL_EXP_MASK;
1160 if (!(algo_strength & SSL_EXP_MASK)) { found = 0; break; }
1161 }
1162 else
1163 algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK;
1164 }
1165
1166 if (ca_list[j]->algo_strength & SSL_STRONG_MASK)
1167 {
1168 if (algo_strength & SSL_STRONG_MASK)
1169 {
1170 algo_strength &= (ca_list[j]->algo_strength & SSL_STRONG_MASK) | ~SSL_STRONG_MASK;
1171 if (!(algo_strength & SSL_STRONG_MASK)) { found = 0; break; }
1172 }
1173 else
1174 algo_strength |= ca_list[j]->algo_strength & SSL_STRONG_MASK;
1175 }
1176
1177 if (ca_list[j]->valid)
1178 {
1179 /* explicit ciphersuite found; its protocol version
1180 * does not become part of the search pattern!*/
1181
1182 cipher_id = ca_list[j]->id;
1183 }
1184 else
1185 {
1186 /* not an explicit ciphersuite; only in this case, the
1187 * protocol version is considered part of the search pattern */
1188
1189 if (ca_list[j]->algorithm_ssl)
1190 {
1191 if (alg_ssl)
1192 {
1193 alg_ssl &= ca_list[j]->algorithm_ssl;
1194 if (!alg_ssl) { found = 0; break; }
1195 }
1196 else
1197 alg_ssl = ca_list[j]->algorithm_ssl;
1198 }
1199 }
1200
1201 if (!multi) break;
1202 }
1203
1204 /*
1205 * Ok, we have the rule, now apply it
1206 */
1207 if (rule == CIPHER_SPECIAL)
1208 { /* special command */
1209 ok = 0;
1210 if ((buflen == 8) &&
1211 !strncmp(buf, "STRENGTH", 8))
1212 ok = ssl_cipher_strength_sort(head_p, tail_p);
1213 else
1214 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_INVALID_COMMAND);
1215 if (ok == 0)
1216 retval = 0;
1217 /*
1218 * We do not support any "multi" options
1219 * together with "@", so throw away the
1220 * rest of the command, if any left, until
1221 * end or ':' is found.
1222 */
1223 while ((*l != '\0') && !ITEM_SEP(*l))
1224 l++;
1225 }
1226 else if (found)
1227 {
1228 ssl_cipher_apply_rule(cipher_id,
1229 alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, algo_strength,
Adam Langley858a88d2014-06-20 12:00:00 -07001230 rule, -1, in_group, head_p, tail_p);
Adam Langley95c29f32014-06-20 12:00:00 -07001231 }
1232 else
1233 {
1234 while ((*l != '\0') && !ITEM_SEP(*l))
1235 l++;
1236 }
1237 if (*l == '\0') break; /* done */
1238 }
1239
Adam Langley858a88d2014-06-20 12:00:00 -07001240 if (in_group)
1241 {
1242 OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_INVALID_COMMAND);
1243 retval = 0;
1244 }
1245
Adam Langley95c29f32014-06-20 12:00:00 -07001246 return(retval);
1247 }
1248#ifndef OPENSSL_NO_EC
1249static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c,
1250 const char **prule_str)
1251 {
1252 unsigned int suiteb_flags = 0, suiteb_comb2 = 0;
1253 if (!strcmp(*prule_str, "SUITEB128"))
1254 suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
1255 else if (!strcmp(*prule_str, "SUITEB128ONLY"))
1256 suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY;
1257 else if (!strcmp(*prule_str, "SUITEB128C2"))
1258 {
1259 suiteb_comb2 = 1;
1260 suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS;
1261 }
1262 else if (!strcmp(*prule_str, "SUITEB192"))
1263 suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS;
1264
1265 if (suiteb_flags)
1266 {
1267 c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS;
1268 c->cert_flags |= suiteb_flags;
1269 }
1270 else
1271 suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS;
1272
1273 if (!suiteb_flags)
1274 return 1;
1275 /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */
1276
1277 if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS))
1278 {
1279 if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)
1280 OPENSSL_PUT_ERROR(SSL, check_suiteb_cipher_list, SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE);
1281 else
1282 OPENSSL_PUT_ERROR(SSL, check_suiteb_cipher_list, SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE);
1283 return 0;
1284 }
1285
1286 switch(suiteb_flags)
1287 {
1288 case SSL_CERT_FLAG_SUITEB_128_LOS:
1289 if (suiteb_comb2)
1290 *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
1291 else
1292 *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384";
1293 break;
1294 case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY:
1295 *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256";
1296 break;
1297 case SSL_CERT_FLAG_SUITEB_192_LOS:
1298 *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384";
1299 break;
1300 }
1301 /* Set auto ECDH parameter determination */
1302 c->ecdh_tmp_auto = 1;
1303 return 1;
1304 }
1305#endif
1306
1307
1308STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method,
Adam Langley858a88d2014-06-20 12:00:00 -07001309 struct ssl_cipher_preference_list_st **cipher_list,
Adam Langley95c29f32014-06-20 12:00:00 -07001310 STACK_OF(SSL_CIPHER) **cipher_list_by_id,
1311 const char *rule_str, CERT *c)
1312 {
1313 int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases;
1314 unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl;
Adam Langley858a88d2014-06-20 12:00:00 -07001315 STACK_OF(SSL_CIPHER) *cipherstack = NULL, *tmp_cipher_list = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001316 const char *rule_p;
1317 CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
1318 const SSL_CIPHER **ca_list = NULL;
Adam Langley858a88d2014-06-20 12:00:00 -07001319 unsigned char *in_group_flags = NULL;
1320 unsigned int num_in_group_flags = 0;
1321 struct ssl_cipher_preference_list_st *pref_list = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001322
1323 /*
1324 * Return with error if nothing to do.
1325 */
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001326 if (rule_str == NULL || cipher_list == NULL)
Adam Langley95c29f32014-06-20 12:00:00 -07001327 return NULL;
1328#ifndef OPENSSL_NO_EC
1329 if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
1330 return NULL;
1331#endif
1332
1333 /*
1334 * To reduce the work to do we only want to process the compiled
1335 * in algorithms, so we first get the mask of disabled ciphers.
1336 */
1337 ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, &disabled_mac, &disabled_ssl);
1338
1339 /*
1340 * Now we have to collect the available ciphers from the compiled
1341 * in ciphers. We cannot get more than the number compiled in, so
1342 * it is used for allocation.
1343 */
1344 num_of_ciphers = ssl_method->num_ciphers();
1345#ifdef KSSL_DEBUG
1346 printf("ssl_create_cipher_list() for %d ciphers\n", num_of_ciphers);
1347#endif /* KSSL_DEBUG */
1348 co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers);
1349 if (co_list == NULL)
1350 {
1351 OPENSSL_PUT_ERROR(SSL, ssl_create_cipher_list, ERR_R_MALLOC_FAILURE);
1352 return(NULL); /* Failure */
1353 }
1354
1355 ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
1356 disabled_mkey, disabled_auth, disabled_enc, disabled_mac, disabled_ssl,
1357 co_list, &head, &tail);
1358
1359
1360 /* Now arrange all ciphers by preference: */
1361
1362 /* Everything else being equal, prefer ephemeral ECDH over other key exchange mechanisms */
Adam Langley858a88d2014-06-20 12:00:00 -07001363 ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
1364 ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001365
1366 /* AES is our preferred symmetric cipher */
Adam Langley858a88d2014-06-20 12:00:00 -07001367 ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001368
1369 /* Temporarily enable everything else for sorting */
Adam Langley858a88d2014-06-20 12:00:00 -07001370 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001371
1372 /* Low priority for MD5 */
Adam Langley858a88d2014-06-20 12:00:00 -07001373 ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001374
1375 /* Move anonymous ciphers to the end. Usually, these will remain disabled.
1376 * (For applications that allow them, they aren't too bad, but we prefer
1377 * authenticated ciphers.) */
Adam Langley858a88d2014-06-20 12:00:00 -07001378 ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001379
1380 /* Move ciphers without forward secrecy to the end */
Adam Langley858a88d2014-06-20 12:00:00 -07001381 ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
1382 /* ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail); */
1383 ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
1384 ssl_cipher_apply_rule(0, SSL_kPSK, 0,0, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001385
1386 /* RC4 is sort-of broken -- move the the end */
Adam Langley858a88d2014-06-20 12:00:00 -07001387 ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001388
1389 /* Now sort by symmetric encryption strength. The above ordering remains
1390 * in force within each class */
1391 if (!ssl_cipher_strength_sort(&head, &tail))
1392 {
1393 OPENSSL_free(co_list);
1394 return NULL;
1395 }
1396
1397 /* Now disable everything (maintaining the ordering!) */
Adam Langley858a88d2014-06-20 12:00:00 -07001398 ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, 0, &head, &tail);
Adam Langley95c29f32014-06-20 12:00:00 -07001399
1400
1401 /*
1402 * We also need cipher aliases for selecting based on the rule_str.
1403 * There might be two types of entries in the rule_str: 1) names
1404 * of ciphers themselves 2) aliases for groups of ciphers.
1405 * For 1) we need the available ciphers and for 2) the cipher
1406 * groups of cipher_aliases added together in one list (otherwise
1407 * we would be happy with just the cipher_aliases table).
1408 */
1409 num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER);
1410 num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
1411 ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max);
1412 if (ca_list == NULL)
1413 {
1414 OPENSSL_free(co_list);
1415 OPENSSL_PUT_ERROR(SSL, ssl_create_cipher_list, ERR_R_MALLOC_FAILURE);
1416 return(NULL); /* Failure */
1417 }
1418 ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
1419 disabled_mkey, disabled_auth, disabled_enc,
1420 disabled_mac, disabled_ssl, head);
1421
1422 /*
1423 * If the rule_string begins with DEFAULT, apply the default rule
1424 * before using the (possibly available) additional rules.
1425 */
1426 ok = 1;
1427 rule_p = rule_str;
1428 if (strncmp(rule_str,"DEFAULT",7) == 0)
1429 {
1430 ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST,
1431 &head, &tail, ca_list);
1432 rule_p += 7;
1433 if (*rule_p == ':')
1434 rule_p++;
1435 }
1436
1437 if (ok && (strlen(rule_p) > 0))
1438 ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list);
1439
1440 OPENSSL_free((void *)ca_list); /* Not needed anymore */
1441
1442 if (!ok)
Adam Langley858a88d2014-06-20 12:00:00 -07001443 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001444
1445 /*
1446 * Allocate new "cipherstack" for the result, return with error
1447 * if we cannot get one.
1448 */
1449 if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL)
Adam Langley858a88d2014-06-20 12:00:00 -07001450 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001451
Adam Langley858a88d2014-06-20 12:00:00 -07001452 in_group_flags = OPENSSL_malloc(num_of_ciphers);
1453 if (!in_group_flags)
1454 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001455 /*
1456 * The cipher selection for the list is done. The ciphers are added
1457 * to the resulting precedence to the STACK_OF(SSL_CIPHER).
1458 */
1459 for (curr = head; curr != NULL; curr = curr->next)
1460 {
Adam Langley95c29f32014-06-20 12:00:00 -07001461 if (curr->active)
Adam Langley95c29f32014-06-20 12:00:00 -07001462 {
1463 sk_SSL_CIPHER_push(cipherstack, curr->cipher);
Adam Langley858a88d2014-06-20 12:00:00 -07001464 in_group_flags[num_in_group_flags++] = curr->in_group;
Adam Langley95c29f32014-06-20 12:00:00 -07001465#ifdef CIPHER_DEBUG
1466 printf("<%s>\n",curr->cipher->name);
1467#endif
1468 }
1469 }
1470 OPENSSL_free(co_list); /* Not needed any longer */
Adam Langley858a88d2014-06-20 12:00:00 -07001471 co_list = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001472
1473 tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack);
1474 if (tmp_cipher_list == NULL)
Adam Langley858a88d2014-06-20 12:00:00 -07001475 goto err;
1476 pref_list = OPENSSL_malloc(sizeof(struct ssl_cipher_preference_list_st));
1477 if (!pref_list)
1478 goto err;
1479 pref_list->ciphers = cipherstack;
1480 pref_list->in_group_flags = OPENSSL_malloc(num_in_group_flags);
1481 if (!pref_list->in_group_flags)
1482 goto err;
1483 memcpy(pref_list->in_group_flags, in_group_flags, num_in_group_flags);
1484 OPENSSL_free(in_group_flags);
1485 in_group_flags = NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001486 if (*cipher_list != NULL)
Adam Langley858a88d2014-06-20 12:00:00 -07001487 ssl_cipher_preference_list_free(*cipher_list);
1488 *cipher_list = pref_list;
1489 pref_list = NULL;
1490
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001491 if (cipher_list_by_id != NULL)
1492 {
1493 if (*cipher_list_by_id != NULL)
1494 sk_SSL_CIPHER_free(*cipher_list_by_id);
1495 *cipher_list_by_id = tmp_cipher_list;
Adam Langley858a88d2014-06-20 12:00:00 -07001496 tmp_cipher_list = NULL;
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001497 (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id,ssl_cipher_ptr_id_cmp);
Adam Langley95c29f32014-06-20 12:00:00 -07001498
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001499 sk_SSL_CIPHER_sort(*cipher_list_by_id);
1500 }
1501 else
Adam Langley858a88d2014-06-20 12:00:00 -07001502 {
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001503 sk_SSL_CIPHER_free(tmp_cipher_list);
Adam Langley858a88d2014-06-20 12:00:00 -07001504 tmp_cipher_list = NULL;
1505 }
Adam Langley0b5c1ac2014-06-20 12:00:00 -07001506
Adam Langley95c29f32014-06-20 12:00:00 -07001507 return(cipherstack);
Adam Langley858a88d2014-06-20 12:00:00 -07001508
1509err:
1510 if (co_list)
1511 OPENSSL_free(co_list);
1512 if (in_group_flags)
1513 OPENSSL_free(in_group_flags);
1514 if (cipherstack)
1515 sk_SSL_CIPHER_free(cipherstack);
1516 if (tmp_cipher_list)
1517 sk_SSL_CIPHER_free(tmp_cipher_list);
1518 if (pref_list && pref_list->in_group_flags)
1519 OPENSSL_free(pref_list->in_group_flags);
1520 if (pref_list)
1521 OPENSSL_free(pref_list);
1522 return NULL;
Adam Langley95c29f32014-06-20 12:00:00 -07001523 }
1524
Adam Langley73510762014-06-20 12:00:00 -07001525const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
Adam Langley95c29f32014-06-20 12:00:00 -07001526 {
David Benjamin060d9d22014-07-15 00:54:26 -04001527 const char *ver;
Adam Langley95c29f32014-06-20 12:00:00 -07001528 const char *kx,*au,*enc,*mac;
1529 unsigned long alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl,alg2;
1530#ifdef KSSL_DEBUG
David Benjamin060d9d22014-07-15 00:54:26 -04001531 static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s AL=%lx/%lx/%lx/%lx/%lx\n";
Adam Langley95c29f32014-06-20 12:00:00 -07001532#else
David Benjamin060d9d22014-07-15 00:54:26 -04001533 static const char *format="%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n";
Adam Langley95c29f32014-06-20 12:00:00 -07001534#endif /* KSSL_DEBUG */
1535
1536 alg_mkey = cipher->algorithm_mkey;
1537 alg_auth = cipher->algorithm_auth;
1538 alg_enc = cipher->algorithm_enc;
1539 alg_mac = cipher->algorithm_mac;
1540 alg_ssl = cipher->algorithm_ssl;
1541
1542 alg2=cipher->algorithm2;
1543
Adam Langley95c29f32014-06-20 12:00:00 -07001544 if (alg_ssl & SSL_SSLV2)
1545 ver="SSLv2";
1546 else if (alg_ssl & SSL_SSLV3)
1547 ver="SSLv3";
1548 else if (alg_ssl & SSL_TLSV1_2)
1549 ver="TLSv1.2";
1550 else
1551 ver="unknown";
1552
1553 switch (alg_mkey)
1554 {
1555 case SSL_kRSA:
David Benjamin060d9d22014-07-15 00:54:26 -04001556 kx="RSA";
Adam Langley95c29f32014-06-20 12:00:00 -07001557 break;
1558 case SSL_kDHr:
1559 kx="DH/RSA";
1560 break;
1561 case SSL_kDHd:
1562 kx="DH/DSS";
1563 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001564 case SSL_kEDH:
David Benjamin060d9d22014-07-15 00:54:26 -04001565 kx="DH";
Adam Langley95c29f32014-06-20 12:00:00 -07001566 break;
1567 case SSL_kECDHr:
1568 kx="ECDH/RSA";
1569 break;
1570 case SSL_kECDHe:
1571 kx="ECDH/ECDSA";
1572 break;
1573 case SSL_kEECDH:
1574 kx="ECDH";
1575 break;
1576 case SSL_kPSK:
1577 kx="PSK";
1578 break;
1579 case SSL_kSRP:
1580 kx="SRP";
1581 break;
1582 default:
1583 kx="unknown";
1584 }
1585
1586 switch (alg_auth)
1587 {
1588 case SSL_aRSA:
1589 au="RSA";
1590 break;
1591 case SSL_aDSS:
1592 au="DSS";
1593 break;
1594 case SSL_aDH:
1595 au="DH";
1596 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001597 case SSL_aECDH:
1598 au="ECDH";
1599 break;
1600 case SSL_aNULL:
1601 au="None";
1602 break;
1603 case SSL_aECDSA:
1604 au="ECDSA";
1605 break;
1606 case SSL_aPSK:
1607 au="PSK";
1608 break;
1609 default:
1610 au="unknown";
1611 break;
1612 }
1613
1614 switch (alg_enc)
1615 {
1616 case SSL_DES:
David Benjamin060d9d22014-07-15 00:54:26 -04001617 enc="DES(56)";
Adam Langley95c29f32014-06-20 12:00:00 -07001618 break;
1619 case SSL_3DES:
1620 enc="3DES(168)";
1621 break;
1622 case SSL_RC4:
David Benjamin060d9d22014-07-15 00:54:26 -04001623 enc=(alg2&SSL2_CF_8_BYTE_ENC)?"RC4(64)":"RC4(128)";
Adam Langley95c29f32014-06-20 12:00:00 -07001624 break;
1625 case SSL_RC2:
David Benjamin060d9d22014-07-15 00:54:26 -04001626 enc="RC2(128)";
Adam Langley95c29f32014-06-20 12:00:00 -07001627 break;
1628 case SSL_IDEA:
1629 enc="IDEA(128)";
1630 break;
1631 case SSL_eNULL:
1632 enc="None";
1633 break;
1634 case SSL_AES128:
1635 enc="AES(128)";
1636 break;
1637 case SSL_AES256:
1638 enc="AES(256)";
1639 break;
1640 case SSL_AES128GCM:
1641 enc="AESGCM(128)";
1642 break;
1643 case SSL_AES256GCM:
1644 enc="AESGCM(256)";
1645 break;
1646 case SSL_CAMELLIA128:
1647 enc="Camellia(128)";
1648 break;
1649 case SSL_CAMELLIA256:
1650 enc="Camellia(256)";
1651 break;
1652 case SSL_SEED:
1653 enc="SEED(128)";
1654 break;
Adam Langleyde0b2022014-06-20 12:00:00 -07001655 case SSL_CHACHA20POLY1305:
1656 enc="ChaCha20-Poly1305";
1657 break;
Adam Langley95c29f32014-06-20 12:00:00 -07001658 default:
1659 enc="unknown";
1660 break;
1661 }
1662
1663 switch (alg_mac)
1664 {
1665 case SSL_MD5:
1666 mac="MD5";
1667 break;
1668 case SSL_SHA1:
1669 mac="SHA1";
1670 break;
1671 case SSL_SHA256:
1672 mac="SHA256";
1673 break;
1674 case SSL_SHA384:
1675 mac="SHA384";
1676 break;
1677 case SSL_AEAD:
1678 mac="AEAD";
1679 break;
1680 default:
1681 mac="unknown";
1682 break;
1683 }
1684
1685 if (buf == NULL)
1686 {
1687 len=128;
1688 buf=OPENSSL_malloc(len);
1689 if (buf == NULL) return("OPENSSL_malloc Error");
1690 }
1691 else if (len < 128)
1692 return("Buffer too small");
1693
1694#ifdef KSSL_DEBUG
David Benjamin060d9d22014-07-15 00:54:26 -04001695 BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac,alg_mkey,alg_auth,alg_enc,alg_mac,alg_ssl);
Adam Langley95c29f32014-06-20 12:00:00 -07001696#else
David Benjamin060d9d22014-07-15 00:54:26 -04001697 BIO_snprintf(buf,len,format,cipher->name,ver,kx,au,enc,mac);
Adam Langley95c29f32014-06-20 12:00:00 -07001698#endif /* KSSL_DEBUG */
1699 return(buf);
1700 }
1701
Adam Langley4d4bff82014-06-20 12:00:00 -07001702/* Next three functions require non-null cipher */
1703int SSL_CIPHER_is_AES(const SSL_CIPHER *c)
1704 {
1705 return (c->algorithm_enc & SSL_AES) != 0;
1706 }
1707
1708int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c)
1709 {
1710 return (c->algorithm_mac & SSL_MD5) != 0;
1711 }
1712
1713int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c)
1714 {
1715 return (c->algorithm_mac & (SSL_AES128GCM|SSL_AES256GCM)) != 0;
1716 }
1717
Adam Langleyde0b2022014-06-20 12:00:00 -07001718int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c)
1719 {
1720 return (c->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
1721 }
1722
Adam Langley73510762014-06-20 12:00:00 -07001723const char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
Adam Langley95c29f32014-06-20 12:00:00 -07001724 {
1725 int i;
1726
1727 if (c == NULL) return("(NONE)");
1728 i=(int)(c->id>>24L);
1729 if (i == 3)
1730 return("TLSv1/SSLv3");
1731 else if (i == 2)
1732 return("SSLv2");
1733 else
1734 return("unknown");
1735 }
1736
1737/* return the actual cipher being used */
1738const char *SSL_CIPHER_get_name(const SSL_CIPHER *c)
1739 {
1740 if (c != NULL)
1741 return(c->name);
1742 return("(NONE)");
1743 }
1744
1745/* number of bits for symmetric cipher */
1746int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
1747 {
1748 int ret=0;
1749
1750 if (c != NULL)
1751 {
1752 if (alg_bits != NULL) *alg_bits = c->alg_bits;
1753 ret = c->strength_bits;
1754 }
1755 return(ret);
1756 }
1757
1758unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c)
1759 {
1760 return c->id;
1761 }
1762
Adam Langley95c29f32014-06-20 12:00:00 -07001763void *SSL_COMP_get_compression_methods(void)
1764 {
1765 return NULL;
1766 }
1767int SSL_COMP_add_compression_method(int id, void *cm)
1768 {
1769 return 1;
1770 }
1771
1772const char *SSL_COMP_get_name(const void *comp)
1773 {
1774 return NULL;
1775 }
1776
1777/* For a cipher return the index corresponding to the certificate type */
1778int ssl_cipher_get_cert_index(const SSL_CIPHER *c)
1779 {
1780 unsigned long alg_k, alg_a;
1781
1782 alg_k = c->algorithm_mkey;
1783 alg_a = c->algorithm_auth;
1784
1785 if (alg_k & (SSL_kECDHr|SSL_kECDHe))
1786 {
1787 /* we don't need to look at SSL_kEECDH
1788 * since no certificate is needed for
1789 * anon ECDH and for authenticated
1790 * EECDH, the check for the auth
1791 * algorithm will set i correctly
1792 * NOTE: For ECDH-RSA, we need an ECC
1793 * not an RSA cert but for EECDH-RSA
1794 * we need an RSA cert. Placing the
1795 * checks for SSL_kECDH before RSA
1796 * checks ensures the correct cert is chosen.
1797 */
1798 return SSL_PKEY_ECC;
1799 }
1800 else if (alg_a & SSL_aECDSA)
1801 return SSL_PKEY_ECC;
1802 else if (alg_k & SSL_kDHr)
1803 return SSL_PKEY_DH_RSA;
1804 else if (alg_k & SSL_kDHd)
1805 return SSL_PKEY_DH_DSA;
1806 else if (alg_a & SSL_aDSS)
1807 return SSL_PKEY_DSA_SIGN;
1808 else if (alg_a & SSL_aRSA)
1809 return SSL_PKEY_RSA_ENC;
Adam Langley95c29f32014-06-20 12:00:00 -07001810 return -1;
1811 }
1812
David Benjamine8f3d662014-07-12 01:10:19 -04001813/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a
1814 * server public key in the key exchange, sent in a server Certificate
1815 * message. Otherwise it returns 0. */
1816int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher)
1817 {
1818 /* Anonymous ciphers do not include a server certificate. */
1819 if (cipher->algorithm_auth & SSL_aNULL)
1820 return 0;
1821 /* Neither do PSK ciphers, except for RSA_PSK. */
1822 if ((cipher->algorithm_auth & SSL_aPSK) &&
1823 !(cipher->algorithm_mkey & SSL_kRSA))
1824 return 0;
1825 /* All other ciphers include it. */
1826 return 1;
1827 }
David Benjamin9c651c92014-07-12 13:27:45 -04001828
1829/* ssl_cipher_requires_server_key_exchange returns 1 if |cipher|
1830 * requires a ServerKeyExchange message. Otherwise it returns 0.
1831 *
1832 * Unlike ssl_cipher_has_server_public_key, some ciphers take optional
1833 * ServerKeyExchanges. PSK and RSA_PSK only use the ServerKeyExchange
1834 * to communicate a psk_identity_hint, so it is optional.
1835 *
1836 * Also, as implemented, the RSA key exchange takes an optional
1837 * ServerKeyExchange containing a signed ephemeral RSA encryption key.
1838 *
1839 * TODO(davidben): Can we remove the RSA one? This is a remnant of
1840 * RSA_EXPORT ciphers which required this (it was used to generate an
1841 * ephemeral 512-bit RSA encryption key), but it's allowed for all RSA
David Benjaminb9cc33a2014-07-15 00:09:48 -04001842 * ciphers. */
David Benjamin9c651c92014-07-12 13:27:45 -04001843int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher)
1844 {
1845 /* Ephemeral Diffie-Hellman key exchanges require a
1846 * ServerKeyExchange. */
1847 if (cipher->algorithm_mkey & SSL_kEDH ||
1848 cipher->algorithm_mkey & SSL_kEECDH)
1849 return 1;
1850 /* It is optional in all others. */
1851 return 0;
1852 }