blob: dac3fcae96f96b1f052ef1b93e6f8295d6a90e43 [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 2005 Nokia. All rights reserved.
112 *
113 * The portions of the attached software ("Contribution") is developed by
114 * Nokia Corporation and is licensed pursuant to the OpenSSL open source
115 * license.
116 *
117 * The Contribution, originally written by Mika Kousa and Pasi Eronen of
118 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
119 * support (see RFC 4279) to OpenSSL.
120 *
121 * No patent licenses or other rights except those expressly stated in
122 * the OpenSSL open source license shall be deemed granted or received
123 * expressly, by implication, estoppel, or otherwise.
124 *
125 * No assurances are provided by Nokia that the Contribution does not
126 * infringe the patent or other intellectual property rights of any third
127 * party or that the license provides you with all the necessary rights
128 * to make use of the Contribution.
129 *
130 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
131 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
132 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
133 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
134 * OTHERWISE. */
135
136#include <stdio.h>
137#include <assert.h>
138
Adam Langley95c29f32014-06-20 12:00:00 -0700139#include <openssl/err.h>
140#include <openssl/evp.h>
141#include <openssl/hmac.h>
142#include <openssl/md5.h>
143#include <openssl/mem.h>
144#include <openssl/obj.h>
145#include <openssl/rand.h>
146
147#include "ssl_locl.h"
148
Adam Langley95c29f32014-06-20 12:00:00 -0700149
Adam Langleyfcf25832014-12-18 17:42:32 -0800150/* seed1 through seed3 are virtually concatenated */
151static int tls1_P_hash(const EVP_MD *md, const uint8_t *sec, int sec_len,
152 const void *seed1, int seed1_len,
153 const void *seed2, int seed2_len,
154 const void *seed3, int seed3_len,
155 uint8_t *out, int olen) {
156 int chunk;
157 size_t j;
158 EVP_MD_CTX ctx, ctx_tmp, ctx_init;
159 EVP_PKEY *mac_key;
160 uint8_t A1[EVP_MAX_MD_SIZE];
161 size_t A1_len;
162 int ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700163
Adam Langleyfcf25832014-12-18 17:42:32 -0800164 chunk = EVP_MD_size(md);
Adam Langley95c29f32014-06-20 12:00:00 -0700165
Adam Langleyfcf25832014-12-18 17:42:32 -0800166 EVP_MD_CTX_init(&ctx);
167 EVP_MD_CTX_init(&ctx_tmp);
168 EVP_MD_CTX_init(&ctx_init);
169 mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
170 A1_len = EVP_MAX_MD_SIZE;
171 if (!mac_key ||
172 !EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key) ||
173 !EVP_MD_CTX_copy_ex(&ctx, &ctx_init) ||
174 (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) ||
175 (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) ||
176 (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) ||
177 !EVP_DigestSignFinal(&ctx, A1, &A1_len)) {
178 goto err;
179 }
180
181 for (;;) {
182 /* Reinit mac contexts */
183 if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init) ||
184 !EVP_DigestSignUpdate(&ctx, A1, A1_len) ||
185 (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) ||
186 (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) ||
187 (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) ||
188 (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len))) {
189 goto err;
190 }
191
192 if (olen > chunk) {
193 j = olen;
194 if (!EVP_DigestSignFinal(&ctx, out, &j)) {
195 goto err;
196 }
197 out += j;
198 olen -= j;
199 /* calc the next A1 value */
200 A1_len = EVP_MAX_MD_SIZE;
201 if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) {
202 goto err;
203 }
204 } else {
205 /* last one */
206 A1_len = EVP_MAX_MD_SIZE;
207 if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) {
208 goto err;
209 }
210 memcpy(out, A1, olen);
211 break;
212 }
213 }
214
215 ret = 1;
216
Adam Langley95c29f32014-06-20 12:00:00 -0700217err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800218 EVP_PKEY_free(mac_key);
219 EVP_MD_CTX_cleanup(&ctx);
220 EVP_MD_CTX_cleanup(&ctx_tmp);
221 EVP_MD_CTX_cleanup(&ctx_init);
222 OPENSSL_cleanse(A1, sizeof(A1));
223 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700224}
Adam Langley9447dff2014-06-24 17:29:06 -0700225
Adam Langleyfcf25832014-12-18 17:42:32 -0800226/* seed1 through seed3 are virtually concatenated */
227static int tls1_PRF(long digest_mask,
228 const void *seed1, int seed1_len,
229 const void *seed2, int seed2_len,
230 const void *seed3, int seed3_len,
231 const uint8_t *sec, int slen,
David Benjaminaf032d62014-12-22 10:42:51 -0500232 uint8_t *out, int olen) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800233 int len, i, idx, count;
234 const uint8_t *S1;
235 long m;
236 const EVP_MD *md;
237 int ret = 0;
David Benjaminaf032d62014-12-22 10:42:51 -0500238 uint8_t *tmp;
239
240 if (olen <= 0) {
241 return 1;
242 }
243
244 /* Allocate a temporary buffer. */
245 tmp = OPENSSL_malloc(olen);
246 if (tmp == NULL) {
247 OPENSSL_PUT_ERROR(SSL, tls1_PRF, ERR_R_MALLOC_FAILURE);
248 return 0;
249 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800250
251 /* Count number of digests and partition sec evenly */
252 count = 0;
253 for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
254 if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) {
255 count++;
256 }
257 }
258 len = slen / count;
259 if (count == 1) {
260 slen = 0;
261 }
262 S1 = sec;
David Benjaminaf032d62014-12-22 10:42:51 -0500263 memset(out, 0, olen);
Adam Langleyfcf25832014-12-18 17:42:32 -0800264 for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
265 if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) {
266 if (!md) {
267 OPENSSL_PUT_ERROR(SSL, tls1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE);
268 goto err;
269 }
270 if (!tls1_P_hash(md, S1, len + (slen & 1), seed1, seed1_len, seed2,
David Benjaminaf032d62014-12-22 10:42:51 -0500271 seed2_len, seed3, seed3_len, tmp, olen)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800272 goto err;
273 }
274 S1 += len;
275 for (i = 0; i < olen; i++) {
David Benjaminaf032d62014-12-22 10:42:51 -0500276 out[i] ^= tmp[i];
Adam Langleyfcf25832014-12-18 17:42:32 -0800277 }
278 }
279 }
280 ret = 1;
281
282err:
David Benjaminaf032d62014-12-22 10:42:51 -0500283 OPENSSL_cleanse(tmp, olen);
284 OPENSSL_free(tmp);
Adam Langleyfcf25832014-12-18 17:42:32 -0800285 return ret;
286}
287
David Benjaminaf032d62014-12-22 10:42:51 -0500288static int tls1_generate_key_block(SSL *s, uint8_t *km, int num) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800289 return tls1_PRF(ssl_get_algorithm2(s), TLS_MD_KEY_EXPANSION_CONST,
290 TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random,
291 SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE,
292 s->session->master_key, s->session->master_key_length, km,
David Benjaminaf032d62014-12-22 10:42:51 -0500293 num);
Adam Langleyfcf25832014-12-18 17:42:32 -0800294}
Adam Langley95c29f32014-06-20 12:00:00 -0700295
Adam Langleyc9fb3752014-06-20 12:00:00 -0700296/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
297 * returns 0 on malloc error. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800298static int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx) {
299 if (*aead_ctx != NULL) {
300 EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx);
301 } else {
302 *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
303 if (*aead_ctx == NULL) {
304 OPENSSL_PUT_ERROR(SSL, tls1_aead_ctx_init, ERR_R_MALLOC_FAILURE);
305 return 0;
306 }
307 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700308
Adam Langleyfcf25832014-12-18 17:42:32 -0800309 return 1;
310}
Adam Langleyc9fb3752014-06-20 12:00:00 -0700311
Adam Langleyfcf25832014-12-18 17:42:32 -0800312static void tls1_cleanup_enc_ctx(EVP_CIPHER_CTX **ctx) {
313 if (*ctx != NULL) {
314 EVP_CIPHER_CTX_free(*ctx);
315 }
316 *ctx = NULL;
317}
Adam Langley88333ef2014-10-15 20:13:35 -0700318
Adam Langleyfcf25832014-12-18 17:42:32 -0800319static void tls1_cleanup_hash_ctx(EVP_MD_CTX **ctx) {
320 if (*ctx != NULL) {
321 EVP_MD_CTX_destroy(*ctx);
322 }
323 *ctx = NULL;
324}
Adam Langley88333ef2014-10-15 20:13:35 -0700325
Adam Langleyc9fb3752014-06-20 12:00:00 -0700326static int tls1_change_cipher_state_aead(SSL *s, char is_read,
Adam Langleyfcf25832014-12-18 17:42:32 -0800327 const uint8_t *key, unsigned key_len,
328 const uint8_t *iv, unsigned iv_len,
329 const uint8_t *mac_secret,
330 unsigned mac_secret_len) {
331 const EVP_AEAD *aead = s->s3->tmp.new_aead;
332 SSL_AEAD_CTX *aead_ctx;
David Benjaminea72bd02014-12-21 21:27:41 -0500333 /* merged_key is used to merge the MAC, cipher, and IV keys for an AEAD which
334 * simulates pre-AEAD cipher suites. */
335 uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
Adam Langley9447dff2014-06-24 17:29:06 -0700336
Adam Langleyfcf25832014-12-18 17:42:32 -0800337 if (is_read) {
338 tls1_cleanup_enc_ctx(&s->enc_read_ctx);
339 tls1_cleanup_hash_ctx(&s->read_hash);
340 } else {
341 tls1_cleanup_enc_ctx(&s->enc_write_ctx);
342 tls1_cleanup_hash_ctx(&s->write_hash);
343 }
Adam Langley88333ef2014-10-15 20:13:35 -0700344
Adam Langleyfcf25832014-12-18 17:42:32 -0800345 if (mac_secret_len > 0) {
346 /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
347 * suites). */
David Benjaminea72bd02014-12-21 21:27:41 -0500348 if (mac_secret_len + key_len + iv_len > sizeof(merged_key)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800349 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead,
350 ERR_R_INTERNAL_ERROR);
351 return 0;
352 }
David Benjaminea72bd02014-12-21 21:27:41 -0500353 memcpy(merged_key, mac_secret, mac_secret_len);
354 memcpy(merged_key + mac_secret_len, key, key_len);
355 memcpy(merged_key + mac_secret_len + key_len, iv, iv_len);
356 key = merged_key;
Adam Langleyfcf25832014-12-18 17:42:32 -0800357 key_len += mac_secret_len;
David Benjaminea72bd02014-12-21 21:27:41 -0500358 key_len += iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800359 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700360
Adam Langleyfcf25832014-12-18 17:42:32 -0800361 if (is_read) {
362 if (!tls1_aead_ctx_init(&s->aead_read_ctx)) {
363 return 0;
364 }
365 aead_ctx = s->aead_read_ctx;
366 } else {
367 if (!tls1_aead_ctx_init(&s->aead_write_ctx)) {
368 return 0;
369 }
370 aead_ctx = s->aead_write_ctx;
371 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700372
Adam Langleyfcf25832014-12-18 17:42:32 -0800373 if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len,
374 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */)) {
375 OPENSSL_free(aead_ctx);
376 if (is_read) {
377 s->aead_read_ctx = NULL;
378 } else {
379 s->aead_write_ctx = NULL;
380 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700381
Adam Langleyfcf25832014-12-18 17:42:32 -0800382 return 0;
383 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700384
David Benjaminea72bd02014-12-21 21:27:41 -0500385 if (mac_secret_len == 0) {
386 /* For a real AEAD, the IV is the fixed part of the nonce. */
387 if (iv_len > sizeof(aead_ctx->fixed_nonce)) {
388 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
389 return 0;
390 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800391
David Benjaminea72bd02014-12-21 21:27:41 -0500392 memcpy(aead_ctx->fixed_nonce, iv, iv_len);
393 aead_ctx->fixed_nonce_len = iv_len;
394 aead_ctx->variable_nonce_included_in_record =
Adam Langleyfcf25832014-12-18 17:42:32 -0800395 (s->s3->tmp.new_cipher->algorithm2 &
396 SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
David Benjaminea72bd02014-12-21 21:27:41 -0500397 aead_ctx->random_variable_nonce = 0;
398 aead_ctx->omit_length_in_ad = 0;
399 } else {
400 aead_ctx->fixed_nonce_len = 0;
401 aead_ctx->variable_nonce_included_in_record = 1;
402 aead_ctx->random_variable_nonce = 1;
403 aead_ctx->omit_length_in_ad = 1;
404 }
405 aead_ctx->variable_nonce_len = s->s3->tmp.new_variable_iv_len;
406
Adam Langleyfcf25832014-12-18 17:42:32 -0800407 if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
408 EVP_AEAD_nonce_length(aead)) {
409 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
410 return 0;
411 }
412 aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
413
414 return 1;
415}
416
417static void tls1_cleanup_aead_ctx(SSL_AEAD_CTX **ctx) {
418 if (*ctx != NULL) {
419 EVP_AEAD_CTX_cleanup(&(*ctx)->ctx);
420 OPENSSL_free(*ctx);
421 }
422 *ctx = NULL;
423}
Adam Langley88333ef2014-10-15 20:13:35 -0700424
Adam Langleya5fa5b72014-06-20 12:00:00 -0700425/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
426 * states when using EVP_CIPHER. The argument |is_read| is true iff this
427 * function is being called due to reading, as opposed to writing, a
428 * ChangeCipherSpec message. In order to support export ciphersuites,
429 * use_client_keys indicates whether the key material provided is in the
430 * "client write" direction. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800431static int tls1_change_cipher_state_cipher(SSL *s, char is_read,
432 char use_client_keys,
433 const uint8_t *mac_secret,
434 unsigned mac_secret_len,
435 const uint8_t *key, unsigned key_len,
436 const uint8_t *iv, unsigned iv_len) {
437 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
438 EVP_CIPHER_CTX *cipher_ctx;
439 EVP_MD_CTX *mac_ctx;
Adam Langley95c29f32014-06-20 12:00:00 -0700440
Adam Langleyfcf25832014-12-18 17:42:32 -0800441 if (is_read) {
442 tls1_cleanup_aead_ctx(&s->aead_read_ctx);
443 } else {
444 tls1_cleanup_aead_ctx(&s->aead_write_ctx);
445 }
Adam Langley88333ef2014-10-15 20:13:35 -0700446
Adam Langleyfcf25832014-12-18 17:42:32 -0800447 if (is_read) {
448 if (s->enc_read_ctx != NULL && !SSL_IS_DTLS(s)) {
449 EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
450 } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
451 goto err;
452 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700453
Adam Langleyfcf25832014-12-18 17:42:32 -0800454 cipher_ctx = s->enc_read_ctx;
455 mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
456 if (mac_ctx == NULL) {
457 goto err;
458 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700459
Adam Langleyfcf25832014-12-18 17:42:32 -0800460 memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
461 s->s3->read_mac_secret_size = mac_secret_len;
462 } else {
463 /* When updating the write contexts for DTLS, we do not wish to free the
464 * old ones because DTLS stores pointers to them in order to implement
465 * retransmission. */
Adam Langleya5fa5b72014-06-20 12:00:00 -0700466
Adam Langleyfcf25832014-12-18 17:42:32 -0800467 if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) {
468 EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
469 } else {
470 s->enc_write_ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
471 if (s->enc_write_ctx == NULL) {
472 goto err;
473 }
474 }
475 EVP_CIPHER_CTX_init(s->enc_write_ctx);
Adam Langleya5fa5b72014-06-20 12:00:00 -0700476
Adam Langleyfcf25832014-12-18 17:42:32 -0800477 cipher_ctx = s->enc_write_ctx;
478 if (SSL_IS_DTLS(s)) {
479 /* This is the same as ssl_replace_hash, but doesn't
480 * free the old |s->write_hash|. */
481 mac_ctx = EVP_MD_CTX_create();
482 if (!mac_ctx) {
483 goto err;
484 }
485 s->write_hash = mac_ctx;
486 } else {
487 mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
488 if (mac_ctx == NULL) {
489 goto err;
490 }
491 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700492
Adam Langleyfcf25832014-12-18 17:42:32 -0800493 memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
494 s->s3->write_mac_secret_size = mac_secret_len;
495 }
Adam Langley95c29f32014-06-20 12:00:00 -0700496
Adam Langleyfcf25832014-12-18 17:42:32 -0800497 EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, NULL,
498 mac_secret, mac_secret_len);
499 if (!mac_key) {
500 return 0;
501 }
Adam Langley95c29f32014-06-20 12:00:00 -0700502
Adam Langleyfcf25832014-12-18 17:42:32 -0800503 if (!EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key)) {
504 EVP_PKEY_free(mac_key);
505 goto err;
506 }
507 EVP_PKEY_free(mac_key);
Adam Langley95c29f32014-06-20 12:00:00 -0700508
Adam Langleyfcf25832014-12-18 17:42:32 -0800509 if (!EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv,
510 !is_read)) {
511 goto err;
512 }
513
514 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700515
Adam Langley95c29f32014-06-20 12:00:00 -0700516err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800517 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_cipher, ERR_R_MALLOC_FAILURE);
518 return 0;
519}
Adam Langleya5fa5b72014-06-20 12:00:00 -0700520
Adam Langleyfcf25832014-12-18 17:42:32 -0800521int tls1_change_cipher_state(SSL *s, int which) {
522 /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
523 * need to update the read cipherspec. Otherwise we have just written one. */
524 const char is_read = (which & SSL3_CC_READ) != 0;
525 /* use_client_keys is true if we wish to use the keys for the "client write"
526 * direction. This is the case if we're a client sending a ChangeCipherSpec,
527 * or a server reading a client's ChangeCipherSpec. */
528 const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
529 which == SSL3_CHANGE_CIPHER_SERVER_READ;
530 const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
531 const uint8_t *client_write_key, *server_write_key, *key;
532 const uint8_t *client_write_iv, *server_write_iv, *iv;
533 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
534 const EVP_AEAD *aead = s->s3->tmp.new_aead;
David Benjaminea72bd02014-12-21 21:27:41 -0500535 size_t key_len, iv_len, mac_secret_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800536 const uint8_t *key_data;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700537
Adam Langleyfcf25832014-12-18 17:42:32 -0800538 /* Reset sequence number to zero. */
539 if (!SSL_IS_DTLS(s)) {
540 memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
541 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700542
David Benjaminea72bd02014-12-21 21:27:41 -0500543 mac_secret_len = s->s3->tmp.new_mac_secret_len;
544 iv_len = s->s3->tmp.new_fixed_iv_len;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700545
Adam Langleyfcf25832014-12-18 17:42:32 -0800546 if (aead != NULL) {
547 key_len = EVP_AEAD_key_length(aead);
David Benjaminea72bd02014-12-21 21:27:41 -0500548 if (mac_secret_len > 0) {
549 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
550 * the key length reported by |EVP_AEAD_key_length| will include the MAC
551 * and IV key bytes. */
552 if (key_len < mac_secret_len + iv_len) {
553 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
554 return 0;
555 }
556 key_len -= mac_secret_len + iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800557 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800558 } else {
559 key_len = EVP_CIPHER_key_length(cipher);
Adam Langleyfcf25832014-12-18 17:42:32 -0800560 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700561
Adam Langleyfcf25832014-12-18 17:42:32 -0800562 key_data = s->s3->tmp.key_block;
563 client_write_mac_secret = key_data;
564 key_data += mac_secret_len;
565 server_write_mac_secret = key_data;
566 key_data += mac_secret_len;
567 client_write_key = key_data;
568 key_data += key_len;
569 server_write_key = key_data;
570 key_data += key_len;
571 client_write_iv = key_data;
572 key_data += iv_len;
573 server_write_iv = key_data;
574 key_data += iv_len;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700575
Adam Langleyfcf25832014-12-18 17:42:32 -0800576 if (use_client_keys) {
577 mac_secret = client_write_mac_secret;
578 key = client_write_key;
579 iv = client_write_iv;
580 } else {
581 mac_secret = server_write_mac_secret;
582 key = server_write_key;
583 iv = server_write_iv;
584 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700585
Adam Langleyfcf25832014-12-18 17:42:32 -0800586 if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
587 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
588 return 0;
589 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700590
Adam Langleyfcf25832014-12-18 17:42:32 -0800591 if (aead != NULL) {
592 if (!tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
593 mac_secret, mac_secret_len)) {
594 return 0;
595 }
596 } else {
597 if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
598 mac_secret, mac_secret_len, key,
599 key_len, iv, iv_len)) {
600 return 0;
601 }
602 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700603
Adam Langleyfcf25832014-12-18 17:42:32 -0800604 return 1;
605}
Adam Langley95c29f32014-06-20 12:00:00 -0700606
Adam Langleyfcf25832014-12-18 17:42:32 -0800607int tls1_setup_key_block(SSL *s) {
David Benjaminaf032d62014-12-22 10:42:51 -0500608 uint8_t *p;
Adam Langleyfcf25832014-12-18 17:42:32 -0800609 const EVP_CIPHER *c = NULL;
610 const EVP_MD *hash = NULL;
611 const EVP_AEAD *aead = NULL;
612 int num;
David Benjaminea72bd02014-12-21 21:27:41 -0500613 int mac_type = NID_undef;
Adam Langleyfcf25832014-12-18 17:42:32 -0800614 int ret = 0;
David Benjaminea72bd02014-12-21 21:27:41 -0500615 size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len;
Adam Langley95c29f32014-06-20 12:00:00 -0700616
Adam Langley95c29f32014-06-20 12:00:00 -0700617
Adam Langleyfcf25832014-12-18 17:42:32 -0800618 if (s->s3->tmp.key_block_length != 0) {
619 return 1;
620 }
Adam Langley95c29f32014-06-20 12:00:00 -0700621
David Benjaminea72bd02014-12-21 21:27:41 -0500622 if (s->session->cipher == NULL) {
623 goto cipher_unavailable_err;
624 }
625
626 /* TODO(davidben): Make DTLS record-layer code EVP_AEAD-aware. */
627 if (!SSL_IS_DTLS(s)) {
628 if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
629 s->session->cipher,
630 ssl3_version_from_wire(s, s->version))) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800631 goto cipher_unavailable_err;
632 }
633 key_len = EVP_AEAD_key_length(aead);
David Benjaminea72bd02014-12-21 21:27:41 -0500634 variable_iv_len = EVP_AEAD_nonce_length(aead);
635 if (mac_secret_len > 0) {
636 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
637 * the key length reported by |EVP_AEAD_key_length| will include the MAC
638 * key bytes and initial implicit IV. */
639 if (key_len < mac_secret_len + fixed_iv_len) {
640 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
641 return 0;
642 }
643 key_len -= mac_secret_len + fixed_iv_len;
644 } else {
645 /* The nonce is split into a fixed portion and a variable portion. */
646 if (variable_iv_len < fixed_iv_len) {
647 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
648 return 0;
649 }
650 variable_iv_len -= fixed_iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800651 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800652 } else {
653 if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type,
David Benjaminea72bd02014-12-21 21:27:41 -0500654 &mac_secret_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800655 goto cipher_unavailable_err;
656 }
657 key_len = EVP_CIPHER_key_length(c);
David Benjaminea72bd02014-12-21 21:27:41 -0500658 fixed_iv_len = EVP_CIPHER_iv_length(c);
659 variable_iv_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800660 }
Adam Langley95c29f32014-06-20 12:00:00 -0700661
David Benjaminea72bd02014-12-21 21:27:41 -0500662 assert(mac_secret_len < 256);
663 assert(fixed_iv_len < 256);
664 assert(variable_iv_len < 256);
665
Adam Langleyfcf25832014-12-18 17:42:32 -0800666 s->s3->tmp.new_aead = aead;
667 s->s3->tmp.new_sym_enc = c;
668 s->s3->tmp.new_hash = hash;
669 s->s3->tmp.new_mac_pkey_type = mac_type;
David Benjaminea72bd02014-12-21 21:27:41 -0500670 s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
671 s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
672 s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700673
David Benjaminea72bd02014-12-21 21:27:41 -0500674 num = key_len + mac_secret_len + fixed_iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800675 num *= 2;
Adam Langley95c29f32014-06-20 12:00:00 -0700676
Adam Langleyfcf25832014-12-18 17:42:32 -0800677 ssl3_cleanup_key_block(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700678
David Benjaminaf032d62014-12-22 10:42:51 -0500679 p = (uint8_t *)OPENSSL_malloc(num);
680 if (p == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800681 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE);
682 goto err;
683 }
Adam Langley95c29f32014-06-20 12:00:00 -0700684
Adam Langleyfcf25832014-12-18 17:42:32 -0800685 s->s3->tmp.key_block_length = num;
David Benjaminaf032d62014-12-22 10:42:51 -0500686 s->s3->tmp.key_block = p;
Adam Langley95c29f32014-06-20 12:00:00 -0700687
David Benjaminaf032d62014-12-22 10:42:51 -0500688 if (!tls1_generate_key_block(s, p, num)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800689 goto err;
690 }
Adam Langley95c29f32014-06-20 12:00:00 -0700691
Adam Langleyfcf25832014-12-18 17:42:32 -0800692 if (!SSL_USE_EXPLICIT_IV(s) &&
693 (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) {
694 /* enable vulnerability countermeasure for CBC ciphers with known-IV
695 * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */
696 s->s3->need_record_splitting = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700697
Adam Langleyfcf25832014-12-18 17:42:32 -0800698 if (s->session->cipher != NULL &&
699 s->session->cipher->algorithm_enc == SSL_RC4) {
700 s->s3->need_record_splitting = 0;
701 }
702 }
703
704 ret = 1;
705
Adam Langley95c29f32014-06-20 12:00:00 -0700706err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800707 return ret;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700708
709cipher_unavailable_err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800710 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block,
711 SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
712 return 0;
713}
Adam Langley95c29f32014-06-20 12:00:00 -0700714
Adam Langleyfcf25832014-12-18 17:42:32 -0800715/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|,
716 * respectively.
Adam Langley95c29f32014-06-20 12:00:00 -0700717 *
718 * Returns:
719 * 0: (in non-constant time) if the record is publically invalid (i.e. too
720 * short etc).
721 * 1: if the record's padding is valid / the encryption was successful.
722 * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
Adam Langleyfcf25832014-12-18 17:42:32 -0800723 * an internal error occured. */
724int tls1_enc(SSL *s, int send) {
725 SSL3_RECORD *rec;
726 EVP_CIPHER_CTX *ds;
727 unsigned long l;
728 int bs, i, j, k, pad = 0, ret, mac_size = 0;
729 const EVP_CIPHER *enc;
730 const SSL_AEAD_CTX *aead;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700731
Adam Langleyfcf25832014-12-18 17:42:32 -0800732 if (send) {
733 rec = &s->s3->wrec;
734 aead = s->aead_write_ctx;
735 } else {
736 rec = &s->s3->rrec;
737 aead = s->aead_read_ctx;
738 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700739
Adam Langleyfcf25832014-12-18 17:42:32 -0800740 if (aead) {
David Benjaminea72bd02014-12-21 21:27:41 -0500741 uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH];
Adam Langleyfcf25832014-12-18 17:42:32 -0800742 unsigned nonce_used;
David Benjaminea72bd02014-12-21 21:27:41 -0500743 size_t n, ad_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700744
Adam Langleyfcf25832014-12-18 17:42:32 -0800745 seq = send ? s->s3->write_sequence : s->s3->read_sequence;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700746
Adam Langleyfcf25832014-12-18 17:42:32 -0800747 if (SSL_IS_DTLS(s)) {
748 uint8_t dtlsseq[9], *p = dtlsseq;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700749
Adam Langleyfcf25832014-12-18 17:42:32 -0800750 s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
751 memcpy(p, &seq[2], 6);
752 memcpy(ad, dtlsseq, 8);
753 } else {
754 memcpy(ad, seq, 8);
755 for (i = 7; i >= 0; i--) {
756 ++seq[i];
757 if (seq[i] != 0) {
758 break;
759 }
760 }
761 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700762
Adam Langleyfcf25832014-12-18 17:42:32 -0800763 ad[8] = rec->type;
764 ad[9] = (uint8_t)(s->version >> 8);
765 ad[10] = (uint8_t)(s->version);
Adam Langleyc9fb3752014-06-20 12:00:00 -0700766
David Benjaminea72bd02014-12-21 21:27:41 -0500767 if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) {
768 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -0800769 return -1; /* internal error - should never happen. */
770 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700771
Adam Langleyfcf25832014-12-18 17:42:32 -0800772 memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
773 nonce_used = aead->fixed_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700774
Adam Langleyfcf25832014-12-18 17:42:32 -0800775 if (send) {
776 size_t len = rec->length;
777 size_t eivlen = 0;
778 in = rec->input;
779 out = rec->data;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700780
David Benjaminea72bd02014-12-21 21:27:41 -0500781 uint8_t *variable_nonce = nonce + nonce_used;
782 if (aead->random_variable_nonce) {
783 assert(aead->variable_nonce_included_in_record);
784 if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) {
785 return -1;
786 }
787 } else {
788 /* When sending we use the sequence number as the variable part of the
789 * nonce. */
790 if (aead->variable_nonce_len != 8) {
791 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
792 return -1;
793 }
794 memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800795 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800796 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700797
Adam Langleyfcf25832014-12-18 17:42:32 -0800798 /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
799 * order to leave space for the variable nonce. Thus we can copy the
800 * sequence number bytes into place without overwriting any of the
801 * plaintext. */
802 if (aead->variable_nonce_included_in_record) {
David Benjaminea72bd02014-12-21 21:27:41 -0500803 memcpy(out, variable_nonce, aead->variable_nonce_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800804 len -= aead->variable_nonce_len;
805 eivlen = aead->variable_nonce_len;
806 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700807
David Benjaminea72bd02014-12-21 21:27:41 -0500808 if (aead->omit_length_in_ad) {
809 ad_len = 11;
810 } else {
811 ad[11] = len >> 8;
812 ad[12] = len & 0xff;
813 ad_len = 13;
814 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700815
Adam Langleyfcf25832014-12-18 17:42:32 -0800816 if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
David Benjaminea72bd02014-12-21 21:27:41 -0500817 nonce, nonce_used, in + eivlen, len, ad, ad_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800818 return -1;
819 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700820
Adam Langleyfcf25832014-12-18 17:42:32 -0800821 if (aead->variable_nonce_included_in_record) {
822 n += aead->variable_nonce_len;
823 }
824 } else {
825 /* receive */
826 size_t len = rec->length;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700827
Adam Langleyfcf25832014-12-18 17:42:32 -0800828 if (rec->data != rec->input) {
David Benjaminea72bd02014-12-21 21:27:41 -0500829 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -0800830 return -1; /* internal error - should never happen. */
831 }
832 out = in = rec->input;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700833
Adam Langleyfcf25832014-12-18 17:42:32 -0800834 if (len < aead->variable_nonce_len) {
835 return 0;
836 }
837 memcpy(nonce + nonce_used,
838 aead->variable_nonce_included_in_record ? in : ad,
839 aead->variable_nonce_len);
840 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700841
Adam Langleyfcf25832014-12-18 17:42:32 -0800842 if (aead->variable_nonce_included_in_record) {
843 in += aead->variable_nonce_len;
844 len -= aead->variable_nonce_len;
845 out += aead->variable_nonce_len;
846 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700847
David Benjaminea72bd02014-12-21 21:27:41 -0500848 if (aead->omit_length_in_ad) {
849 ad_len = 11;
850 } else {
851 if (len < aead->tag_len) {
852 return 0;
853 }
854 size_t plaintext_len = len - aead->tag_len;
855
856 ad[11] = plaintext_len >> 8;
857 ad[12] = plaintext_len & 0xff;
858 ad_len = 13;
Adam Langleyfcf25832014-12-18 17:42:32 -0800859 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700860
David Benjaminea72bd02014-12-21 21:27:41 -0500861 if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in,
862 len, ad, ad_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800863 return -1;
864 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700865
Adam Langleyfcf25832014-12-18 17:42:32 -0800866 rec->data = rec->input = out;
867 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700868
Adam Langleyfcf25832014-12-18 17:42:32 -0800869 rec->length = n;
870 return 1;
871 }
Adam Langley95c29f32014-06-20 12:00:00 -0700872
Adam Langleyfcf25832014-12-18 17:42:32 -0800873 if (send) {
874 ds = s->enc_write_ctx;
875 rec = &(s->s3->wrec);
876 if (s->enc_write_ctx == NULL) {
877 enc = NULL;
878 } else {
879 int ivlen;
880 enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
881 /* For TLSv1.1 and later explicit IV */
882 if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) {
883 ivlen = EVP_CIPHER_iv_length(enc);
884 } else {
885 ivlen = 0;
886 }
Adam Langley95c29f32014-06-20 12:00:00 -0700887
Adam Langleyfcf25832014-12-18 17:42:32 -0800888 if (ivlen > 1) {
889 if (rec->data != rec->input) {
890 /* we can't write into the input stream:
891 * Can this ever happen?? (steve)
892 */
893 fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__,
894 __LINE__);
895 } else if (!RAND_bytes(rec->input, ivlen)) {
896 return -1;
897 }
898 }
899 }
900 } else {
901 ds = s->enc_read_ctx;
902 rec = &(s->s3->rrec);
903 if (s->enc_read_ctx == NULL) {
904 enc = NULL;
905 } else {
906 enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
907 }
908 }
Adam Langley95c29f32014-06-20 12:00:00 -0700909
Adam Langleyfcf25832014-12-18 17:42:32 -0800910 if (s->session == NULL || ds == NULL || enc == NULL) {
911 memmove(rec->data, rec->input, rec->length);
912 rec->input = rec->data;
913 ret = 1;
914 } else {
915 l = rec->length;
916 bs = EVP_CIPHER_block_size(ds->cipher);
Adam Langley95c29f32014-06-20 12:00:00 -0700917
Adam Langleyfcf25832014-12-18 17:42:32 -0800918 if (bs != 1 && send) {
919 i = bs - ((int)l % bs);
Adam Langley95c29f32014-06-20 12:00:00 -0700920
Adam Langleyfcf25832014-12-18 17:42:32 -0800921 /* Add weird padding of upto 256 bytes */
922 /* we need to add 'i' padding bytes of value j */
923 j = i - 1;
924 for (k = (int)l; k < (int)(l + i); k++) {
925 rec->input[k] = j;
926 }
927 l += i;
928 rec->length += i;
929 }
Adam Langley95c29f32014-06-20 12:00:00 -0700930
Adam Langleyfcf25832014-12-18 17:42:32 -0800931 if (!send && (l == 0 || l % bs != 0)) {
932 return 0;
933 }
Adam Langley95c29f32014-06-20 12:00:00 -0700934
Adam Langleyfcf25832014-12-18 17:42:32 -0800935 if (!EVP_Cipher(ds, rec->data, rec->input, l)) {
936 return -1;
937 }
Adam Langley95c29f32014-06-20 12:00:00 -0700938
Adam Langleyfcf25832014-12-18 17:42:32 -0800939 ret = 1;
940 if (EVP_MD_CTX_md(s->read_hash) != NULL) {
941 mac_size = EVP_MD_CTX_size(s->read_hash);
942 }
Adam Langley95c29f32014-06-20 12:00:00 -0700943
Adam Langleyfcf25832014-12-18 17:42:32 -0800944 if (bs != 1 && !send) {
945 ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
946 }
947 if (pad && !send) {
948 rec->length -= pad;
949 }
950 }
951 return ret;
952}
Adam Langley95c29f32014-06-20 12:00:00 -0700953
Adam Langleyfcf25832014-12-18 17:42:32 -0800954int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
955 unsigned int ret;
956 EVP_MD_CTX ctx, *d = NULL;
957 int i;
Adam Langley95c29f32014-06-20 12:00:00 -0700958
Adam Langleyfcf25832014-12-18 17:42:32 -0800959 if (s->s3->handshake_buffer &&
960 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
961 return 0;
962 }
963
964 for (i = 0; i < SSL_MAX_DIGEST; i++) {
965 if (s->s3->handshake_dgst[i] &&
966 EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
967 d = s->s3->handshake_dgst[i];
968 break;
969 }
970 }
971
972 if (!d) {
973 OPENSSL_PUT_ERROR(SSL, tls1_cert_verify_mac, SSL_R_NO_REQUIRED_DIGEST);
974 return 0;
975 }
976
977 EVP_MD_CTX_init(&ctx);
978 EVP_MD_CTX_copy_ex(&ctx, d);
979 EVP_DigestFinal_ex(&ctx, out, &ret);
980 EVP_MD_CTX_cleanup(&ctx);
981
982 return ret;
983}
Adam Langley95c29f32014-06-20 12:00:00 -0700984
Adam Langley1258b6a2014-06-20 12:00:00 -0700985/* tls1_handshake_digest calculates the current handshake hash and writes it to
986 * |out|, which has space for |out_len| bytes. It returns the number of bytes
987 * written or -1 in the event of an error. This function works on a copy of the
988 * underlying digests so can be called multiple times and prior to the final
989 * update etc. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800990int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
991 const EVP_MD *md;
992 EVP_MD_CTX ctx;
993 int i, err = 0, len = 0;
994 long mask;
Adam Langley95c29f32014-06-20 12:00:00 -0700995
Adam Langleyfcf25832014-12-18 17:42:32 -0800996 EVP_MD_CTX_init(&ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700997
Adam Langleyfcf25832014-12-18 17:42:32 -0800998 for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
999 int hash_size;
1000 unsigned int digest_len;
1001 EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
Adam Langley1258b6a2014-06-20 12:00:00 -07001002
Adam Langleyfcf25832014-12-18 17:42:32 -08001003 if ((mask & ssl_get_algorithm2(s)) == 0) {
1004 continue;
1005 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001006
Adam Langleyfcf25832014-12-18 17:42:32 -08001007 hash_size = EVP_MD_size(md);
1008 if (!hdgst ||
1009 hash_size < 0 ||
1010 (size_t)hash_size > out_len ||
1011 !EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
1012 !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
1013 digest_len != (unsigned int)hash_size /* internal error */) {
1014 err = 1;
1015 break;
1016 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001017
Adam Langleyfcf25832014-12-18 17:42:32 -08001018 out += digest_len;
1019 out_len -= digest_len;
1020 len += digest_len;
1021 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001022
Adam Langleyfcf25832014-12-18 17:42:32 -08001023 EVP_MD_CTX_cleanup(&ctx);
Adam Langley1258b6a2014-06-20 12:00:00 -07001024
Adam Langleyfcf25832014-12-18 17:42:32 -08001025 if (err != 0) {
1026 return -1;
1027 }
1028 return len;
1029}
Adam Langley1258b6a2014-06-20 12:00:00 -07001030
Adam Langleyfcf25832014-12-18 17:42:32 -08001031int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
1032 uint8_t buf[2 * EVP_MAX_MD_SIZE];
Adam Langleyfcf25832014-12-18 17:42:32 -08001033 int err = 0;
1034 int digests_len;
Adam Langley1258b6a2014-06-20 12:00:00 -07001035
Adam Langleyfcf25832014-12-18 17:42:32 -08001036 if (s->s3->handshake_buffer &&
1037 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
1038 return 0;
1039 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001040
Adam Langleyfcf25832014-12-18 17:42:32 -08001041 digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
1042 if (digests_len < 0) {
1043 err = 1;
1044 digests_len = 0;
1045 }
Adam Langley95c29f32014-06-20 12:00:00 -07001046
Adam Langleyfcf25832014-12-18 17:42:32 -08001047 if (!tls1_PRF(ssl_get_algorithm2(s), str, slen, buf, digests_len, NULL, 0,
1048 s->session->master_key, s->session->master_key_length, out,
David Benjaminaf032d62014-12-22 10:42:51 -05001049 12)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001050 err = 1;
1051 }
Adam Langley95c29f32014-06-20 12:00:00 -07001052
Adam Langleyfcf25832014-12-18 17:42:32 -08001053 if (err) {
1054 return 0;
1055 } else {
David Benjaminaf032d62014-12-22 10:42:51 -05001056 return 12;
Adam Langleyfcf25832014-12-18 17:42:32 -08001057 }
1058}
Adam Langley95c29f32014-06-20 12:00:00 -07001059
Adam Langleyfcf25832014-12-18 17:42:32 -08001060int tls1_mac(SSL *ssl, uint8_t *md, int send) {
1061 SSL3_RECORD *rec;
1062 uint8_t *seq;
1063 EVP_MD_CTX *hash;
1064 size_t md_size, orig_len;
1065 int i, ok;
1066 EVP_MD_CTX hmac, *mac_ctx;
1067 uint8_t header[13];
1068 int t;
Adam Langley95c29f32014-06-20 12:00:00 -07001069
Adam Langleyfcf25832014-12-18 17:42:32 -08001070 if (send) {
1071 rec = &ssl->s3->wrec;
1072 seq = &ssl->s3->write_sequence[0];
1073 hash = ssl->write_hash;
1074 } else {
1075 rec = &ssl->s3->rrec;
1076 seq = &ssl->s3->read_sequence[0];
1077 hash = ssl->read_hash;
1078 }
Adam Langley95c29f32014-06-20 12:00:00 -07001079
Adam Langleyfcf25832014-12-18 17:42:32 -08001080 t = EVP_MD_CTX_size(hash);
1081 assert(t >= 0);
1082 md_size = t;
Adam Langley95c29f32014-06-20 12:00:00 -07001083
Adam Langleyfcf25832014-12-18 17:42:32 -08001084 mac_ctx = &hmac;
1085 if (!EVP_MD_CTX_copy(mac_ctx, hash)) {
1086 return -1;
1087 }
Adam Langley95c29f32014-06-20 12:00:00 -07001088
Adam Langleyfcf25832014-12-18 17:42:32 -08001089 if (SSL_IS_DTLS(ssl)) {
1090 uint8_t dtlsseq[8], *p = dtlsseq;
Adam Langley95c29f32014-06-20 12:00:00 -07001091
Adam Langleyfcf25832014-12-18 17:42:32 -08001092 s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p);
1093 memcpy(p, &seq[2], 6);
Adam Langley95c29f32014-06-20 12:00:00 -07001094
Adam Langleyfcf25832014-12-18 17:42:32 -08001095 memcpy(header, dtlsseq, 8);
1096 } else {
1097 memcpy(header, seq, 8);
1098 }
Adam Langley95c29f32014-06-20 12:00:00 -07001099
Adam Langleyfcf25832014-12-18 17:42:32 -08001100 /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
1101 orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
1102 rec->type &= 0xff;
Adam Langley95c29f32014-06-20 12:00:00 -07001103
Adam Langleyfcf25832014-12-18 17:42:32 -08001104 header[8] = rec->type;
1105 header[9] = (uint8_t)(ssl->version >> 8);
1106 header[10] = (uint8_t)(ssl->version);
1107 header[11] = (rec->length) >> 8;
1108 header[12] = (rec->length) & 0xff;
Adam Langley69a01602014-11-17 17:26:55 -08001109
Adam Langleyfcf25832014-12-18 17:42:32 -08001110 if (!send && EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
1111 ssl3_cbc_record_digest_supported(mac_ctx)) {
1112 /* This is a CBC-encrypted record. We must avoid leaking any timing-side
1113 * channel information about how many blocks of data we are hashing because
1114 * that gives an attacker a timing-oracle. */
1115 ok = ssl3_cbc_digest_record(
1116 mac_ctx, md, &md_size, header, rec->input, rec->length + md_size,
1117 orig_len, ssl->s3->read_mac_secret, ssl->s3->read_mac_secret_size,
1118 0 /* not SSLv3 */);
1119 } else {
1120 EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
1121 EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
1122 ok = EVP_DigestSignFinal(mac_ctx, md, &md_size);
1123 }
Adam Langley69a01602014-11-17 17:26:55 -08001124
Adam Langleyfcf25832014-12-18 17:42:32 -08001125 EVP_MD_CTX_cleanup(mac_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001126
Adam Langleyfcf25832014-12-18 17:42:32 -08001127 if (!ok) {
1128 return -1;
1129 }
Adam Langley95c29f32014-06-20 12:00:00 -07001130
Adam Langleyfcf25832014-12-18 17:42:32 -08001131 if (!SSL_IS_DTLS(ssl)) {
1132 for (i = 7; i >= 0; i--) {
1133 ++seq[i];
1134 if (seq[i] != 0) {
1135 break;
1136 }
1137 }
1138 }
Adam Langley95c29f32014-06-20 12:00:00 -07001139
Adam Langleyfcf25832014-12-18 17:42:32 -08001140 return md_size;
1141}
Adam Langley95c29f32014-06-20 12:00:00 -07001142
Adam Langleyfcf25832014-12-18 17:42:32 -08001143int tls1_generate_master_secret(SSL *s, uint8_t *out, uint8_t *p, int len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001144 if (s->s3->tmp.extended_master_secret) {
1145 uint8_t digests[2 * EVP_MAX_MD_SIZE];
1146 int digests_len;
Adam Langley75712922014-10-10 16:23:43 -07001147
Adam Langleyfcf25832014-12-18 17:42:32 -08001148 /* The master secret is based on the handshake hash just after sending the
1149 * ClientKeyExchange. However, we might have a client certificate to send,
1150 * in which case we might need different hashes for the verification and
1151 * thus still need the handshake buffer around. Keeping both a handshake
1152 * buffer *and* running hashes isn't yet supported so, when it comes to
1153 * calculating the Finished hash, we'll have to hash the handshake buffer
1154 * again. */
1155 if (s->s3->handshake_buffer &&
1156 !ssl3_digest_cached_records(s, dont_free_handshake_buffer)) {
1157 return 0;
1158 }
Adam Langley75712922014-10-10 16:23:43 -07001159
Adam Langleyfcf25832014-12-18 17:42:32 -08001160 digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
Adam Langley75712922014-10-10 16:23:43 -07001161
Adam Langleyfcf25832014-12-18 17:42:32 -08001162 if (digests_len == -1) {
1163 return 0;
1164 }
Adam Langley75712922014-10-10 16:23:43 -07001165
David Benjaminaf032d62014-12-22 10:42:51 -05001166 if (!tls1_PRF(ssl_get_algorithm2(s), TLS_MD_EXTENDED_MASTER_SECRET_CONST,
1167 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
1168 digests_len, NULL, 0, p, len, s->session->master_key,
1169 SSL_MAX_MASTER_KEY_LENGTH)) {
1170 return 0;
1171 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001172 } else {
David Benjaminaf032d62014-12-22 10:42:51 -05001173 if (!tls1_PRF(ssl_get_algorithm2(s), TLS_MD_MASTER_SECRET_CONST,
1174 TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random,
1175 SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE, p,
1176 len, s->session->master_key, SSL_MAX_MASTER_KEY_LENGTH)) {
1177 return 0;
1178 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001179 }
Adam Langley95c29f32014-06-20 12:00:00 -07001180
Adam Langleyfcf25832014-12-18 17:42:32 -08001181 return SSL3_MASTER_SECRET_SIZE;
1182}
Adam Langley95c29f32014-06-20 12:00:00 -07001183
Adam Langleyfcf25832014-12-18 17:42:32 -08001184int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen,
1185 const char *label, size_t llen,
1186 const uint8_t *context, size_t contextlen,
1187 int use_context) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001188 uint8_t *val = NULL;
1189 size_t vallen, currentvalpos;
1190 int ret;
Adam Langley95c29f32014-06-20 12:00:00 -07001191
Adam Langleyfcf25832014-12-18 17:42:32 -08001192 /* construct PRF arguments we construct the PRF argument ourself rather than
1193 * passing separate values into the TLS PRF to ensure that the concatenation
1194 * of values does not create a prohibited label. */
1195 vallen = llen + SSL3_RANDOM_SIZE * 2;
1196 if (use_context) {
1197 vallen += 2 + contextlen;
1198 }
Adam Langley95c29f32014-06-20 12:00:00 -07001199
Adam Langleyfcf25832014-12-18 17:42:32 -08001200 val = OPENSSL_malloc(vallen);
1201 if (val == NULL) {
1202 goto err2;
1203 }
Adam Langley95c29f32014-06-20 12:00:00 -07001204
Adam Langleyfcf25832014-12-18 17:42:32 -08001205 currentvalpos = 0;
1206 memcpy(val + currentvalpos, (uint8_t *)label, llen);
1207 currentvalpos += llen;
1208 memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
1209 currentvalpos += SSL3_RANDOM_SIZE;
1210 memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
1211 currentvalpos += SSL3_RANDOM_SIZE;
Adam Langley95c29f32014-06-20 12:00:00 -07001212
Adam Langleyfcf25832014-12-18 17:42:32 -08001213 if (use_context) {
1214 val[currentvalpos] = (contextlen >> 8) & 0xff;
1215 currentvalpos++;
1216 val[currentvalpos] = contextlen & 0xff;
1217 currentvalpos++;
1218 if (contextlen > 0 || context != NULL) {
1219 memcpy(val + currentvalpos, context, contextlen);
1220 }
1221 }
Adam Langley95c29f32014-06-20 12:00:00 -07001222
Adam Langleyfcf25832014-12-18 17:42:32 -08001223 /* disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
1224 * label len) = 15, so size of val > max(prohibited label len) = 15 and the
1225 * comparisons won't have buffer overflow. */
1226 if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
1227 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0 ||
1228 memcmp(val, TLS_MD_SERVER_FINISH_CONST,
1229 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0 ||
1230 memcmp(val, TLS_MD_MASTER_SECRET_CONST,
1231 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0 ||
1232 memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
1233 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) {
1234 goto err1;
1235 }
Adam Langley95c29f32014-06-20 12:00:00 -07001236
Adam Langleyfcf25832014-12-18 17:42:32 -08001237 ret = tls1_PRF(ssl_get_algorithm2(s), val, vallen, NULL, 0, NULL, 0,
1238 s->session->master_key, s->session->master_key_length, out,
David Benjaminaf032d62014-12-22 10:42:51 -05001239 olen);
Adam Langley95c29f32014-06-20 12:00:00 -07001240
Adam Langleyfcf25832014-12-18 17:42:32 -08001241 goto out;
1242
Adam Langley95c29f32014-06-20 12:00:00 -07001243err1:
Adam Langleyfcf25832014-12-18 17:42:32 -08001244 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material,
1245 SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
1246 ret = 0;
1247 goto out;
Adam Langley95c29f32014-06-20 12:00:00 -07001248
Adam Langleyfcf25832014-12-18 17:42:32 -08001249err2:
1250 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE);
1251 ret = 0;
1252
1253out:
Adam Langleyfcf25832014-12-18 17:42:32 -08001254 if (val != NULL) {
1255 OPENSSL_free(val);
1256 }
1257
1258 return ret;
1259}
1260
1261int tls1_alert_code(int code) {
1262 switch (code) {
1263 case SSL_AD_CLOSE_NOTIFY:
1264 return SSL3_AD_CLOSE_NOTIFY;
1265
1266 case SSL_AD_UNEXPECTED_MESSAGE:
1267 return SSL3_AD_UNEXPECTED_MESSAGE;
1268
1269 case SSL_AD_BAD_RECORD_MAC:
1270 return SSL3_AD_BAD_RECORD_MAC;
1271
1272 case SSL_AD_DECRYPTION_FAILED:
1273 return TLS1_AD_DECRYPTION_FAILED;
1274
1275 case SSL_AD_RECORD_OVERFLOW:
1276 return TLS1_AD_RECORD_OVERFLOW;
1277
1278 case SSL_AD_DECOMPRESSION_FAILURE:
1279 return SSL3_AD_DECOMPRESSION_FAILURE;
1280
1281 case SSL_AD_HANDSHAKE_FAILURE:
1282 return SSL3_AD_HANDSHAKE_FAILURE;
1283
1284 case SSL_AD_NO_CERTIFICATE:
1285 return -1;
1286
1287 case SSL_AD_BAD_CERTIFICATE:
1288 return SSL3_AD_BAD_CERTIFICATE;
1289
1290 case SSL_AD_UNSUPPORTED_CERTIFICATE:
1291 return SSL3_AD_UNSUPPORTED_CERTIFICATE;
1292
1293 case SSL_AD_CERTIFICATE_REVOKED:
1294 return SSL3_AD_CERTIFICATE_REVOKED;
1295
1296 case SSL_AD_CERTIFICATE_EXPIRED:
1297 return SSL3_AD_CERTIFICATE_EXPIRED;
1298
1299 case SSL_AD_CERTIFICATE_UNKNOWN:
1300 return SSL3_AD_CERTIFICATE_UNKNOWN;
1301
1302 case SSL_AD_ILLEGAL_PARAMETER:
1303 return SSL3_AD_ILLEGAL_PARAMETER;
1304
1305 case SSL_AD_UNKNOWN_CA:
1306 return TLS1_AD_UNKNOWN_CA;
1307
1308 case SSL_AD_ACCESS_DENIED:
1309 return TLS1_AD_ACCESS_DENIED;
1310
1311 case SSL_AD_DECODE_ERROR:
1312 return TLS1_AD_DECODE_ERROR;
1313
1314 case SSL_AD_DECRYPT_ERROR:
1315 return TLS1_AD_DECRYPT_ERROR;
1316 case SSL_AD_EXPORT_RESTRICTION:
1317 return TLS1_AD_EXPORT_RESTRICTION;
1318
1319 case SSL_AD_PROTOCOL_VERSION:
1320 return TLS1_AD_PROTOCOL_VERSION;
1321
1322 case SSL_AD_INSUFFICIENT_SECURITY:
1323 return TLS1_AD_INSUFFICIENT_SECURITY;
1324
1325 case SSL_AD_INTERNAL_ERROR:
1326 return TLS1_AD_INTERNAL_ERROR;
1327
1328 case SSL_AD_USER_CANCELLED:
1329 return TLS1_AD_USER_CANCELLED;
1330
1331 case SSL_AD_NO_RENEGOTIATION:
1332 return TLS1_AD_NO_RENEGOTIATION;
1333
1334 case SSL_AD_UNSUPPORTED_EXTENSION:
1335 return TLS1_AD_UNSUPPORTED_EXTENSION;
1336
1337 case SSL_AD_CERTIFICATE_UNOBTAINABLE:
1338 return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
1339
1340 case SSL_AD_UNRECOGNIZED_NAME:
1341 return TLS1_AD_UNRECOGNIZED_NAME;
1342
1343 case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
1344 return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
1345
1346 case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
1347 return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
1348
1349 case SSL_AD_UNKNOWN_PSK_IDENTITY:
1350 return TLS1_AD_UNKNOWN_PSK_IDENTITY;
1351
1352 case SSL_AD_INAPPROPRIATE_FALLBACK:
1353 return SSL3_AD_INAPPROPRIATE_FALLBACK;
1354
1355 default:
1356 return -1;
1357 }
1358}