blob: dd8ccb0e40b3696767003a2ebad833710c374669 [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;
333 /* mac_key_and_key is used to merge the MAC and cipher keys for an AEAD which
334 * simulates pre-AEAD cipher suites. It needs to be large enough to cope with
335 * the largest pair of keys. */
336 uint8_t mac_key_and_key[32 /* HMAC(SHA256) */ + 32 /* AES-256 */];
Adam Langley9447dff2014-06-24 17:29:06 -0700337
Adam Langleyfcf25832014-12-18 17:42:32 -0800338 if (is_read) {
339 tls1_cleanup_enc_ctx(&s->enc_read_ctx);
340 tls1_cleanup_hash_ctx(&s->read_hash);
341 } else {
342 tls1_cleanup_enc_ctx(&s->enc_write_ctx);
343 tls1_cleanup_hash_ctx(&s->write_hash);
344 }
Adam Langley88333ef2014-10-15 20:13:35 -0700345
Adam Langleyfcf25832014-12-18 17:42:32 -0800346 if (mac_secret_len > 0) {
347 /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
348 * suites). */
349 if (mac_secret_len + key_len > sizeof(mac_key_and_key)) {
350 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead,
351 ERR_R_INTERNAL_ERROR);
352 return 0;
353 }
354 memcpy(mac_key_and_key, mac_secret, mac_secret_len);
355 memcpy(mac_key_and_key + mac_secret_len, key, key_len);
356 key = mac_key_and_key;
357 key_len += mac_secret_len;
358 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700359
Adam Langleyfcf25832014-12-18 17:42:32 -0800360 if (is_read) {
361 if (!tls1_aead_ctx_init(&s->aead_read_ctx)) {
362 return 0;
363 }
364 aead_ctx = s->aead_read_ctx;
365 } else {
366 if (!tls1_aead_ctx_init(&s->aead_write_ctx)) {
367 return 0;
368 }
369 aead_ctx = s->aead_write_ctx;
370 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700371
Adam Langleyfcf25832014-12-18 17:42:32 -0800372 if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len,
373 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */)) {
374 OPENSSL_free(aead_ctx);
375 if (is_read) {
376 s->aead_read_ctx = NULL;
377 } else {
378 s->aead_write_ctx = NULL;
379 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700380
Adam Langleyfcf25832014-12-18 17:42:32 -0800381 return 0;
382 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700383
Adam Langleyfcf25832014-12-18 17:42:32 -0800384 if (iv_len > sizeof(aead_ctx->fixed_nonce)) {
385 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
386 return 0;
387 }
388
389 memcpy(aead_ctx->fixed_nonce, iv, iv_len);
390 aead_ctx->fixed_nonce_len = iv_len;
391 aead_ctx->variable_nonce_len = 8; /* correct for all true AEADs so far. */
392 if (s->s3->tmp.new_cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_STATEFUL_AEAD) {
393 aead_ctx->variable_nonce_len = 0;
394 }
395
396 aead_ctx->variable_nonce_included_in_record =
397 (s->s3->tmp.new_cipher->algorithm2 &
398 SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
399 if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
400 EVP_AEAD_nonce_length(aead)) {
401 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
402 return 0;
403 }
404 aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
405
406 return 1;
407}
408
409static void tls1_cleanup_aead_ctx(SSL_AEAD_CTX **ctx) {
410 if (*ctx != NULL) {
411 EVP_AEAD_CTX_cleanup(&(*ctx)->ctx);
412 OPENSSL_free(*ctx);
413 }
414 *ctx = NULL;
415}
Adam Langley88333ef2014-10-15 20:13:35 -0700416
Adam Langleya5fa5b72014-06-20 12:00:00 -0700417/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
418 * states when using EVP_CIPHER. The argument |is_read| is true iff this
419 * function is being called due to reading, as opposed to writing, a
420 * ChangeCipherSpec message. In order to support export ciphersuites,
421 * use_client_keys indicates whether the key material provided is in the
422 * "client write" direction. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800423static int tls1_change_cipher_state_cipher(SSL *s, char is_read,
424 char use_client_keys,
425 const uint8_t *mac_secret,
426 unsigned mac_secret_len,
427 const uint8_t *key, unsigned key_len,
428 const uint8_t *iv, unsigned iv_len) {
429 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
430 EVP_CIPHER_CTX *cipher_ctx;
431 EVP_MD_CTX *mac_ctx;
Adam Langley95c29f32014-06-20 12:00:00 -0700432
Adam Langleyfcf25832014-12-18 17:42:32 -0800433 if (is_read) {
434 tls1_cleanup_aead_ctx(&s->aead_read_ctx);
435 } else {
436 tls1_cleanup_aead_ctx(&s->aead_write_ctx);
437 }
Adam Langley88333ef2014-10-15 20:13:35 -0700438
Adam Langleyfcf25832014-12-18 17:42:32 -0800439 if (is_read) {
440 if (s->enc_read_ctx != NULL && !SSL_IS_DTLS(s)) {
441 EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
442 } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
443 goto err;
444 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700445
Adam Langleyfcf25832014-12-18 17:42:32 -0800446 cipher_ctx = s->enc_read_ctx;
447 mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
448 if (mac_ctx == NULL) {
449 goto err;
450 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700451
Adam Langleyfcf25832014-12-18 17:42:32 -0800452 memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
453 s->s3->read_mac_secret_size = mac_secret_len;
454 } else {
455 /* When updating the write contexts for DTLS, we do not wish to free the
456 * old ones because DTLS stores pointers to them in order to implement
457 * retransmission. */
Adam Langleya5fa5b72014-06-20 12:00:00 -0700458
Adam Langleyfcf25832014-12-18 17:42:32 -0800459 if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) {
460 EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
461 } else {
462 s->enc_write_ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
463 if (s->enc_write_ctx == NULL) {
464 goto err;
465 }
466 }
467 EVP_CIPHER_CTX_init(s->enc_write_ctx);
Adam Langleya5fa5b72014-06-20 12:00:00 -0700468
Adam Langleyfcf25832014-12-18 17:42:32 -0800469 cipher_ctx = s->enc_write_ctx;
470 if (SSL_IS_DTLS(s)) {
471 /* This is the same as ssl_replace_hash, but doesn't
472 * free the old |s->write_hash|. */
473 mac_ctx = EVP_MD_CTX_create();
474 if (!mac_ctx) {
475 goto err;
476 }
477 s->write_hash = mac_ctx;
478 } else {
479 mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
480 if (mac_ctx == NULL) {
481 goto err;
482 }
483 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700484
Adam Langleyfcf25832014-12-18 17:42:32 -0800485 memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
486 s->s3->write_mac_secret_size = mac_secret_len;
487 }
Adam Langley95c29f32014-06-20 12:00:00 -0700488
Adam Langleyfcf25832014-12-18 17:42:32 -0800489 EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, NULL,
490 mac_secret, mac_secret_len);
491 if (!mac_key) {
492 return 0;
493 }
Adam Langley95c29f32014-06-20 12:00:00 -0700494
Adam Langleyfcf25832014-12-18 17:42:32 -0800495 if (!EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key)) {
496 EVP_PKEY_free(mac_key);
497 goto err;
498 }
499 EVP_PKEY_free(mac_key);
Adam Langley95c29f32014-06-20 12:00:00 -0700500
Adam Langleyfcf25832014-12-18 17:42:32 -0800501 if (!EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv,
502 !is_read)) {
503 goto err;
504 }
505
506 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700507
Adam Langley95c29f32014-06-20 12:00:00 -0700508err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800509 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_cipher, ERR_R_MALLOC_FAILURE);
510 return 0;
511}
Adam Langleya5fa5b72014-06-20 12:00:00 -0700512
Adam Langleyfcf25832014-12-18 17:42:32 -0800513int tls1_change_cipher_state(SSL *s, int which) {
514 /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
515 * need to update the read cipherspec. Otherwise we have just written one. */
516 const char is_read = (which & SSL3_CC_READ) != 0;
517 /* use_client_keys is true if we wish to use the keys for the "client write"
518 * direction. This is the case if we're a client sending a ChangeCipherSpec,
519 * or a server reading a client's ChangeCipherSpec. */
520 const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
521 which == SSL3_CHANGE_CIPHER_SERVER_READ;
522 const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
523 const uint8_t *client_write_key, *server_write_key, *key;
524 const uint8_t *client_write_iv, *server_write_iv, *iv;
525 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
526 const EVP_AEAD *aead = s->s3->tmp.new_aead;
527 unsigned key_len, iv_len, mac_secret_len;
528 const uint8_t *key_data;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700529
Adam Langleyfcf25832014-12-18 17:42:32 -0800530 /* Reset sequence number to zero. */
531 if (!SSL_IS_DTLS(s)) {
532 memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
533 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700534
Adam Langleyfcf25832014-12-18 17:42:32 -0800535 mac_secret_len = s->s3->tmp.new_mac_secret_size;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700536
Adam Langleyfcf25832014-12-18 17:42:32 -0800537 if (aead != NULL) {
538 key_len = EVP_AEAD_key_length(aead);
539 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
540 * the key length reported by |EVP_AEAD_key_length| will include the MAC
541 * key bytes. */
542 if (key_len < mac_secret_len) {
543 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
544 return 0;
545 }
546 key_len -= mac_secret_len;
547 iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->s3->tmp.new_cipher);
548 } else {
549 key_len = EVP_CIPHER_key_length(cipher);
550 iv_len = EVP_CIPHER_iv_length(cipher);
551 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700552
Adam Langleyfcf25832014-12-18 17:42:32 -0800553 key_data = s->s3->tmp.key_block;
554 client_write_mac_secret = key_data;
555 key_data += mac_secret_len;
556 server_write_mac_secret = key_data;
557 key_data += mac_secret_len;
558 client_write_key = key_data;
559 key_data += key_len;
560 server_write_key = key_data;
561 key_data += key_len;
562 client_write_iv = key_data;
563 key_data += iv_len;
564 server_write_iv = key_data;
565 key_data += iv_len;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700566
Adam Langleyfcf25832014-12-18 17:42:32 -0800567 if (use_client_keys) {
568 mac_secret = client_write_mac_secret;
569 key = client_write_key;
570 iv = client_write_iv;
571 } else {
572 mac_secret = server_write_mac_secret;
573 key = server_write_key;
574 iv = server_write_iv;
575 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700576
Adam Langleyfcf25832014-12-18 17:42:32 -0800577 if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
578 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
579 return 0;
580 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700581
Adam Langleyfcf25832014-12-18 17:42:32 -0800582 if (aead != NULL) {
583 if (!tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
584 mac_secret, mac_secret_len)) {
585 return 0;
586 }
587 } else {
588 if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
589 mac_secret, mac_secret_len, key,
590 key_len, iv, iv_len)) {
591 return 0;
592 }
593 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700594
Adam Langleyfcf25832014-12-18 17:42:32 -0800595 return 1;
596}
Adam Langley95c29f32014-06-20 12:00:00 -0700597
Adam Langleyfcf25832014-12-18 17:42:32 -0800598int tls1_setup_key_block(SSL *s) {
David Benjaminaf032d62014-12-22 10:42:51 -0500599 uint8_t *p;
Adam Langleyfcf25832014-12-18 17:42:32 -0800600 const EVP_CIPHER *c = NULL;
601 const EVP_MD *hash = NULL;
602 const EVP_AEAD *aead = NULL;
603 int num;
604 int mac_type = NID_undef, mac_secret_size = 0;
605 int ret = 0;
606 unsigned key_len, iv_len;
Adam Langley95c29f32014-06-20 12:00:00 -0700607
Adam Langley95c29f32014-06-20 12:00:00 -0700608
Adam Langleyfcf25832014-12-18 17:42:32 -0800609 if (s->s3->tmp.key_block_length != 0) {
610 return 1;
611 }
Adam Langley95c29f32014-06-20 12:00:00 -0700612
Adam Langleyfcf25832014-12-18 17:42:32 -0800613 if (s->session->cipher &&
614 ((s->session->cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD) ||
615 (s->session->cipher->algorithm2 &
616 SSL_CIPHER_ALGORITHM2_STATEFUL_AEAD))) {
617 if (!ssl_cipher_get_evp_aead(s->session, &aead)) {
618 goto cipher_unavailable_err;
619 }
620 key_len = EVP_AEAD_key_length(aead);
621 iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
622 if ((s->session->cipher->algorithm2 &
623 SSL_CIPHER_ALGORITHM2_STATEFUL_AEAD) &&
624 !ssl_cipher_get_mac(s->session, &hash, &mac_type, &mac_secret_size)) {
625 goto cipher_unavailable_err;
626 }
627 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
628 * the key length reported by |EVP_AEAD_key_length| will include the MAC
629 * key bytes. */
630 if (key_len < (size_t)mac_secret_size) {
631 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
632 return 0;
633 }
634 key_len -= mac_secret_size;
635 } else {
636 if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type,
637 &mac_secret_size)) {
638 goto cipher_unavailable_err;
639 }
640 key_len = EVP_CIPHER_key_length(c);
641 iv_len = EVP_CIPHER_iv_length(c);
642 }
Adam Langley95c29f32014-06-20 12:00:00 -0700643
Adam Langleyfcf25832014-12-18 17:42:32 -0800644 s->s3->tmp.new_aead = aead;
645 s->s3->tmp.new_sym_enc = c;
646 s->s3->tmp.new_hash = hash;
647 s->s3->tmp.new_mac_pkey_type = mac_type;
648 s->s3->tmp.new_mac_secret_size = mac_secret_size;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700649
Adam Langleyfcf25832014-12-18 17:42:32 -0800650 num = key_len + mac_secret_size + iv_len;
651 num *= 2;
Adam Langley95c29f32014-06-20 12:00:00 -0700652
Adam Langleyfcf25832014-12-18 17:42:32 -0800653 ssl3_cleanup_key_block(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700654
David Benjaminaf032d62014-12-22 10:42:51 -0500655 p = (uint8_t *)OPENSSL_malloc(num);
656 if (p == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800657 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE);
658 goto err;
659 }
Adam Langley95c29f32014-06-20 12:00:00 -0700660
Adam Langleyfcf25832014-12-18 17:42:32 -0800661 s->s3->tmp.key_block_length = num;
David Benjaminaf032d62014-12-22 10:42:51 -0500662 s->s3->tmp.key_block = p;
Adam Langley95c29f32014-06-20 12:00:00 -0700663
David Benjaminaf032d62014-12-22 10:42:51 -0500664 if (!tls1_generate_key_block(s, p, num)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800665 goto err;
666 }
Adam Langley95c29f32014-06-20 12:00:00 -0700667
Adam Langleyfcf25832014-12-18 17:42:32 -0800668 if (!SSL_USE_EXPLICIT_IV(s) &&
669 (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) {
670 /* enable vulnerability countermeasure for CBC ciphers with known-IV
671 * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */
672 s->s3->need_record_splitting = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700673
Adam Langleyfcf25832014-12-18 17:42:32 -0800674 if (s->session->cipher != NULL &&
675 s->session->cipher->algorithm_enc == SSL_RC4) {
676 s->s3->need_record_splitting = 0;
677 }
678 }
679
680 ret = 1;
681
Adam Langley95c29f32014-06-20 12:00:00 -0700682err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800683 return ret;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700684
685cipher_unavailable_err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800686 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block,
687 SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
688 return 0;
689}
Adam Langley95c29f32014-06-20 12:00:00 -0700690
Adam Langleyfcf25832014-12-18 17:42:32 -0800691/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|,
692 * respectively.
Adam Langley95c29f32014-06-20 12:00:00 -0700693 *
694 * Returns:
695 * 0: (in non-constant time) if the record is publically invalid (i.e. too
696 * short etc).
697 * 1: if the record's padding is valid / the encryption was successful.
698 * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
Adam Langleyfcf25832014-12-18 17:42:32 -0800699 * an internal error occured. */
700int tls1_enc(SSL *s, int send) {
701 SSL3_RECORD *rec;
702 EVP_CIPHER_CTX *ds;
703 unsigned long l;
704 int bs, i, j, k, pad = 0, ret, mac_size = 0;
705 const EVP_CIPHER *enc;
706 const SSL_AEAD_CTX *aead;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700707
Adam Langleyfcf25832014-12-18 17:42:32 -0800708 if (send) {
709 rec = &s->s3->wrec;
710 aead = s->aead_write_ctx;
711 } else {
712 rec = &s->s3->rrec;
713 aead = s->aead_read_ctx;
714 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700715
Adam Langleyfcf25832014-12-18 17:42:32 -0800716 if (aead) {
717 uint8_t ad[13], *seq, *in, *out, nonce[16];
718 unsigned nonce_used;
719 size_t n;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700720
Adam Langleyfcf25832014-12-18 17:42:32 -0800721 seq = send ? s->s3->write_sequence : s->s3->read_sequence;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700722
Adam Langleyfcf25832014-12-18 17:42:32 -0800723 if (SSL_IS_DTLS(s)) {
724 uint8_t dtlsseq[9], *p = dtlsseq;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700725
Adam Langleyfcf25832014-12-18 17:42:32 -0800726 s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
727 memcpy(p, &seq[2], 6);
728 memcpy(ad, dtlsseq, 8);
729 } else {
730 memcpy(ad, seq, 8);
731 for (i = 7; i >= 0; i--) {
732 ++seq[i];
733 if (seq[i] != 0) {
734 break;
735 }
736 }
737 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700738
Adam Langleyfcf25832014-12-18 17:42:32 -0800739 ad[8] = rec->type;
740 ad[9] = (uint8_t)(s->version >> 8);
741 ad[10] = (uint8_t)(s->version);
Adam Langleyc9fb3752014-06-20 12:00:00 -0700742
Adam Langleyfcf25832014-12-18 17:42:32 -0800743 if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce) ||
744 aead->variable_nonce_len > 8) {
745 return -1; /* internal error - should never happen. */
746 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700747
Adam Langleyfcf25832014-12-18 17:42:32 -0800748 memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
749 nonce_used = aead->fixed_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700750
Adam Langleyfcf25832014-12-18 17:42:32 -0800751 if (send) {
752 size_t len = rec->length;
753 size_t eivlen = 0;
754 in = rec->input;
755 out = rec->data;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700756
Adam Langleyfcf25832014-12-18 17:42:32 -0800757 /* When sending we use the sequence number as the variable part of the
758 * nonce. */
759 if (aead->variable_nonce_len > 8) {
760 return -1;
761 }
762 memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
763 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700764
Adam Langleyfcf25832014-12-18 17:42:32 -0800765 /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
766 * order to leave space for the variable nonce. Thus we can copy the
767 * sequence number bytes into place without overwriting any of the
768 * plaintext. */
769 if (aead->variable_nonce_included_in_record) {
770 memcpy(out, ad, aead->variable_nonce_len);
771 len -= aead->variable_nonce_len;
772 eivlen = aead->variable_nonce_len;
773 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700774
Adam Langleyfcf25832014-12-18 17:42:32 -0800775 ad[11] = len >> 8;
776 ad[12] = len & 0xff;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700777
Adam Langleyfcf25832014-12-18 17:42:32 -0800778 if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
779 nonce, nonce_used, in + eivlen, len, ad,
780 sizeof(ad))) {
781 return -1;
782 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700783
Adam Langleyfcf25832014-12-18 17:42:32 -0800784 if (aead->variable_nonce_included_in_record) {
785 n += aead->variable_nonce_len;
786 }
787 } else {
788 /* receive */
789 size_t len = rec->length;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700790
Adam Langleyfcf25832014-12-18 17:42:32 -0800791 if (rec->data != rec->input) {
792 return -1; /* internal error - should never happen. */
793 }
794 out = in = rec->input;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700795
Adam Langleyfcf25832014-12-18 17:42:32 -0800796 if (len < aead->variable_nonce_len) {
797 return 0;
798 }
799 memcpy(nonce + nonce_used,
800 aead->variable_nonce_included_in_record ? in : ad,
801 aead->variable_nonce_len);
802 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700803
Adam Langleyfcf25832014-12-18 17:42:32 -0800804 if (aead->variable_nonce_included_in_record) {
805 in += aead->variable_nonce_len;
806 len -= aead->variable_nonce_len;
807 out += aead->variable_nonce_len;
808 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700809
Adam Langleyfcf25832014-12-18 17:42:32 -0800810 if (len < aead->tag_len) {
811 return 0;
812 }
813 len -= aead->tag_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700814
Adam Langleyfcf25832014-12-18 17:42:32 -0800815 ad[11] = len >> 8;
816 ad[12] = len & 0xff;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700817
Adam Langleyfcf25832014-12-18 17:42:32 -0800818 if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, len, nonce, nonce_used, in,
819 len + aead->tag_len, ad, sizeof(ad))) {
820 return -1;
821 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700822
Adam Langleyfcf25832014-12-18 17:42:32 -0800823 rec->data = rec->input = out;
824 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700825
Adam Langleyfcf25832014-12-18 17:42:32 -0800826 rec->length = n;
827 return 1;
828 }
Adam Langley95c29f32014-06-20 12:00:00 -0700829
Adam Langleyfcf25832014-12-18 17:42:32 -0800830 if (send) {
831 ds = s->enc_write_ctx;
832 rec = &(s->s3->wrec);
833 if (s->enc_write_ctx == NULL) {
834 enc = NULL;
835 } else {
836 int ivlen;
837 enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
838 /* For TLSv1.1 and later explicit IV */
839 if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) {
840 ivlen = EVP_CIPHER_iv_length(enc);
841 } else {
842 ivlen = 0;
843 }
Adam Langley95c29f32014-06-20 12:00:00 -0700844
Adam Langleyfcf25832014-12-18 17:42:32 -0800845 if (ivlen > 1) {
846 if (rec->data != rec->input) {
847 /* we can't write into the input stream:
848 * Can this ever happen?? (steve)
849 */
850 fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__,
851 __LINE__);
852 } else if (!RAND_bytes(rec->input, ivlen)) {
853 return -1;
854 }
855 }
856 }
857 } else {
858 ds = s->enc_read_ctx;
859 rec = &(s->s3->rrec);
860 if (s->enc_read_ctx == NULL) {
861 enc = NULL;
862 } else {
863 enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
864 }
865 }
Adam Langley95c29f32014-06-20 12:00:00 -0700866
Adam Langleyfcf25832014-12-18 17:42:32 -0800867 if (s->session == NULL || ds == NULL || enc == NULL) {
868 memmove(rec->data, rec->input, rec->length);
869 rec->input = rec->data;
870 ret = 1;
871 } else {
872 l = rec->length;
873 bs = EVP_CIPHER_block_size(ds->cipher);
Adam Langley95c29f32014-06-20 12:00:00 -0700874
Adam Langleyfcf25832014-12-18 17:42:32 -0800875 if (bs != 1 && send) {
876 i = bs - ((int)l % bs);
Adam Langley95c29f32014-06-20 12:00:00 -0700877
Adam Langleyfcf25832014-12-18 17:42:32 -0800878 /* Add weird padding of upto 256 bytes */
879 /* we need to add 'i' padding bytes of value j */
880 j = i - 1;
881 for (k = (int)l; k < (int)(l + i); k++) {
882 rec->input[k] = j;
883 }
884 l += i;
885 rec->length += i;
886 }
Adam Langley95c29f32014-06-20 12:00:00 -0700887
Adam Langleyfcf25832014-12-18 17:42:32 -0800888 if (!send && (l == 0 || l % bs != 0)) {
889 return 0;
890 }
Adam Langley95c29f32014-06-20 12:00:00 -0700891
Adam Langleyfcf25832014-12-18 17:42:32 -0800892 if (!EVP_Cipher(ds, rec->data, rec->input, l)) {
893 return -1;
894 }
Adam Langley95c29f32014-06-20 12:00:00 -0700895
Adam Langleyfcf25832014-12-18 17:42:32 -0800896 ret = 1;
897 if (EVP_MD_CTX_md(s->read_hash) != NULL) {
898 mac_size = EVP_MD_CTX_size(s->read_hash);
899 }
Adam Langley95c29f32014-06-20 12:00:00 -0700900
Adam Langleyfcf25832014-12-18 17:42:32 -0800901 if (bs != 1 && !send) {
902 ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
903 }
904 if (pad && !send) {
905 rec->length -= pad;
906 }
907 }
908 return ret;
909}
Adam Langley95c29f32014-06-20 12:00:00 -0700910
Adam Langleyfcf25832014-12-18 17:42:32 -0800911int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
912 unsigned int ret;
913 EVP_MD_CTX ctx, *d = NULL;
914 int i;
Adam Langley95c29f32014-06-20 12:00:00 -0700915
Adam Langleyfcf25832014-12-18 17:42:32 -0800916 if (s->s3->handshake_buffer &&
917 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
918 return 0;
919 }
920
921 for (i = 0; i < SSL_MAX_DIGEST; i++) {
922 if (s->s3->handshake_dgst[i] &&
923 EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
924 d = s->s3->handshake_dgst[i];
925 break;
926 }
927 }
928
929 if (!d) {
930 OPENSSL_PUT_ERROR(SSL, tls1_cert_verify_mac, SSL_R_NO_REQUIRED_DIGEST);
931 return 0;
932 }
933
934 EVP_MD_CTX_init(&ctx);
935 EVP_MD_CTX_copy_ex(&ctx, d);
936 EVP_DigestFinal_ex(&ctx, out, &ret);
937 EVP_MD_CTX_cleanup(&ctx);
938
939 return ret;
940}
Adam Langley95c29f32014-06-20 12:00:00 -0700941
Adam Langley1258b6a2014-06-20 12:00:00 -0700942/* tls1_handshake_digest calculates the current handshake hash and writes it to
943 * |out|, which has space for |out_len| bytes. It returns the number of bytes
944 * written or -1 in the event of an error. This function works on a copy of the
945 * underlying digests so can be called multiple times and prior to the final
946 * update etc. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800947int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
948 const EVP_MD *md;
949 EVP_MD_CTX ctx;
950 int i, err = 0, len = 0;
951 long mask;
Adam Langley95c29f32014-06-20 12:00:00 -0700952
Adam Langleyfcf25832014-12-18 17:42:32 -0800953 EVP_MD_CTX_init(&ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700954
Adam Langleyfcf25832014-12-18 17:42:32 -0800955 for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
956 int hash_size;
957 unsigned int digest_len;
958 EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
Adam Langley1258b6a2014-06-20 12:00:00 -0700959
Adam Langleyfcf25832014-12-18 17:42:32 -0800960 if ((mask & ssl_get_algorithm2(s)) == 0) {
961 continue;
962 }
Adam Langley1258b6a2014-06-20 12:00:00 -0700963
Adam Langleyfcf25832014-12-18 17:42:32 -0800964 hash_size = EVP_MD_size(md);
965 if (!hdgst ||
966 hash_size < 0 ||
967 (size_t)hash_size > out_len ||
968 !EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
969 !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
970 digest_len != (unsigned int)hash_size /* internal error */) {
971 err = 1;
972 break;
973 }
Adam Langley1258b6a2014-06-20 12:00:00 -0700974
Adam Langleyfcf25832014-12-18 17:42:32 -0800975 out += digest_len;
976 out_len -= digest_len;
977 len += digest_len;
978 }
Adam Langley1258b6a2014-06-20 12:00:00 -0700979
Adam Langleyfcf25832014-12-18 17:42:32 -0800980 EVP_MD_CTX_cleanup(&ctx);
Adam Langley1258b6a2014-06-20 12:00:00 -0700981
Adam Langleyfcf25832014-12-18 17:42:32 -0800982 if (err != 0) {
983 return -1;
984 }
985 return len;
986}
Adam Langley1258b6a2014-06-20 12:00:00 -0700987
Adam Langleyfcf25832014-12-18 17:42:32 -0800988int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
989 uint8_t buf[2 * EVP_MAX_MD_SIZE];
Adam Langleyfcf25832014-12-18 17:42:32 -0800990 int err = 0;
991 int digests_len;
Adam Langley1258b6a2014-06-20 12:00:00 -0700992
Adam Langleyfcf25832014-12-18 17:42:32 -0800993 if (s->s3->handshake_buffer &&
994 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
995 return 0;
996 }
Adam Langley1258b6a2014-06-20 12:00:00 -0700997
Adam Langleyfcf25832014-12-18 17:42:32 -0800998 digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
999 if (digests_len < 0) {
1000 err = 1;
1001 digests_len = 0;
1002 }
Adam Langley95c29f32014-06-20 12:00:00 -07001003
Adam Langleyfcf25832014-12-18 17:42:32 -08001004 if (!tls1_PRF(ssl_get_algorithm2(s), str, slen, buf, digests_len, NULL, 0,
1005 s->session->master_key, s->session->master_key_length, out,
David Benjaminaf032d62014-12-22 10:42:51 -05001006 12)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001007 err = 1;
1008 }
Adam Langley95c29f32014-06-20 12:00:00 -07001009
Adam Langleyfcf25832014-12-18 17:42:32 -08001010 if (err) {
1011 return 0;
1012 } else {
David Benjaminaf032d62014-12-22 10:42:51 -05001013 return 12;
Adam Langleyfcf25832014-12-18 17:42:32 -08001014 }
1015}
Adam Langley95c29f32014-06-20 12:00:00 -07001016
Adam Langleyfcf25832014-12-18 17:42:32 -08001017int tls1_mac(SSL *ssl, uint8_t *md, int send) {
1018 SSL3_RECORD *rec;
1019 uint8_t *seq;
1020 EVP_MD_CTX *hash;
1021 size_t md_size, orig_len;
1022 int i, ok;
1023 EVP_MD_CTX hmac, *mac_ctx;
1024 uint8_t header[13];
1025 int t;
Adam Langley95c29f32014-06-20 12:00:00 -07001026
Adam Langleyfcf25832014-12-18 17:42:32 -08001027 if (send) {
1028 rec = &ssl->s3->wrec;
1029 seq = &ssl->s3->write_sequence[0];
1030 hash = ssl->write_hash;
1031 } else {
1032 rec = &ssl->s3->rrec;
1033 seq = &ssl->s3->read_sequence[0];
1034 hash = ssl->read_hash;
1035 }
Adam Langley95c29f32014-06-20 12:00:00 -07001036
Adam Langleyfcf25832014-12-18 17:42:32 -08001037 t = EVP_MD_CTX_size(hash);
1038 assert(t >= 0);
1039 md_size = t;
Adam Langley95c29f32014-06-20 12:00:00 -07001040
Adam Langleyfcf25832014-12-18 17:42:32 -08001041 mac_ctx = &hmac;
1042 if (!EVP_MD_CTX_copy(mac_ctx, hash)) {
1043 return -1;
1044 }
Adam Langley95c29f32014-06-20 12:00:00 -07001045
Adam Langleyfcf25832014-12-18 17:42:32 -08001046 if (SSL_IS_DTLS(ssl)) {
1047 uint8_t dtlsseq[8], *p = dtlsseq;
Adam Langley95c29f32014-06-20 12:00:00 -07001048
Adam Langleyfcf25832014-12-18 17:42:32 -08001049 s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p);
1050 memcpy(p, &seq[2], 6);
Adam Langley95c29f32014-06-20 12:00:00 -07001051
Adam Langleyfcf25832014-12-18 17:42:32 -08001052 memcpy(header, dtlsseq, 8);
1053 } else {
1054 memcpy(header, seq, 8);
1055 }
Adam Langley95c29f32014-06-20 12:00:00 -07001056
Adam Langleyfcf25832014-12-18 17:42:32 -08001057 /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
1058 orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
1059 rec->type &= 0xff;
Adam Langley95c29f32014-06-20 12:00:00 -07001060
Adam Langleyfcf25832014-12-18 17:42:32 -08001061 header[8] = rec->type;
1062 header[9] = (uint8_t)(ssl->version >> 8);
1063 header[10] = (uint8_t)(ssl->version);
1064 header[11] = (rec->length) >> 8;
1065 header[12] = (rec->length) & 0xff;
Adam Langley69a01602014-11-17 17:26:55 -08001066
Adam Langleyfcf25832014-12-18 17:42:32 -08001067 if (!send && EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
1068 ssl3_cbc_record_digest_supported(mac_ctx)) {
1069 /* This is a CBC-encrypted record. We must avoid leaking any timing-side
1070 * channel information about how many blocks of data we are hashing because
1071 * that gives an attacker a timing-oracle. */
1072 ok = ssl3_cbc_digest_record(
1073 mac_ctx, md, &md_size, header, rec->input, rec->length + md_size,
1074 orig_len, ssl->s3->read_mac_secret, ssl->s3->read_mac_secret_size,
1075 0 /* not SSLv3 */);
1076 } else {
1077 EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
1078 EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
1079 ok = EVP_DigestSignFinal(mac_ctx, md, &md_size);
1080 }
Adam Langley69a01602014-11-17 17:26:55 -08001081
Adam Langleyfcf25832014-12-18 17:42:32 -08001082 EVP_MD_CTX_cleanup(mac_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001083
Adam Langleyfcf25832014-12-18 17:42:32 -08001084 if (!ok) {
1085 return -1;
1086 }
Adam Langley95c29f32014-06-20 12:00:00 -07001087
Adam Langleyfcf25832014-12-18 17:42:32 -08001088 if (!SSL_IS_DTLS(ssl)) {
1089 for (i = 7; i >= 0; i--) {
1090 ++seq[i];
1091 if (seq[i] != 0) {
1092 break;
1093 }
1094 }
1095 }
Adam Langley95c29f32014-06-20 12:00:00 -07001096
Adam Langleyfcf25832014-12-18 17:42:32 -08001097 return md_size;
1098}
Adam Langley95c29f32014-06-20 12:00:00 -07001099
Adam Langleyfcf25832014-12-18 17:42:32 -08001100int tls1_generate_master_secret(SSL *s, uint8_t *out, uint8_t *p, int len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001101 if (s->s3->tmp.extended_master_secret) {
1102 uint8_t digests[2 * EVP_MAX_MD_SIZE];
1103 int digests_len;
Adam Langley75712922014-10-10 16:23:43 -07001104
Adam Langleyfcf25832014-12-18 17:42:32 -08001105 /* The master secret is based on the handshake hash just after sending the
1106 * ClientKeyExchange. However, we might have a client certificate to send,
1107 * in which case we might need different hashes for the verification and
1108 * thus still need the handshake buffer around. Keeping both a handshake
1109 * buffer *and* running hashes isn't yet supported so, when it comes to
1110 * calculating the Finished hash, we'll have to hash the handshake buffer
1111 * again. */
1112 if (s->s3->handshake_buffer &&
1113 !ssl3_digest_cached_records(s, dont_free_handshake_buffer)) {
1114 return 0;
1115 }
Adam Langley75712922014-10-10 16:23:43 -07001116
Adam Langleyfcf25832014-12-18 17:42:32 -08001117 digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
Adam Langley75712922014-10-10 16:23:43 -07001118
Adam Langleyfcf25832014-12-18 17:42:32 -08001119 if (digests_len == -1) {
1120 return 0;
1121 }
Adam Langley75712922014-10-10 16:23:43 -07001122
David Benjaminaf032d62014-12-22 10:42:51 -05001123 if (!tls1_PRF(ssl_get_algorithm2(s), TLS_MD_EXTENDED_MASTER_SECRET_CONST,
1124 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
1125 digests_len, NULL, 0, p, len, s->session->master_key,
1126 SSL_MAX_MASTER_KEY_LENGTH)) {
1127 return 0;
1128 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001129 } else {
David Benjaminaf032d62014-12-22 10:42:51 -05001130 if (!tls1_PRF(ssl_get_algorithm2(s), TLS_MD_MASTER_SECRET_CONST,
1131 TLS_MD_MASTER_SECRET_CONST_SIZE, s->s3->client_random,
1132 SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE, p,
1133 len, s->session->master_key, SSL_MAX_MASTER_KEY_LENGTH)) {
1134 return 0;
1135 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001136 }
Adam Langley95c29f32014-06-20 12:00:00 -07001137
Adam Langleyfcf25832014-12-18 17:42:32 -08001138 return SSL3_MASTER_SECRET_SIZE;
1139}
Adam Langley95c29f32014-06-20 12:00:00 -07001140
Adam Langleyfcf25832014-12-18 17:42:32 -08001141int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen,
1142 const char *label, size_t llen,
1143 const uint8_t *context, size_t contextlen,
1144 int use_context) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001145 uint8_t *val = NULL;
1146 size_t vallen, currentvalpos;
1147 int ret;
Adam Langley95c29f32014-06-20 12:00:00 -07001148
Adam Langleyfcf25832014-12-18 17:42:32 -08001149 /* construct PRF arguments we construct the PRF argument ourself rather than
1150 * passing separate values into the TLS PRF to ensure that the concatenation
1151 * of values does not create a prohibited label. */
1152 vallen = llen + SSL3_RANDOM_SIZE * 2;
1153 if (use_context) {
1154 vallen += 2 + contextlen;
1155 }
Adam Langley95c29f32014-06-20 12:00:00 -07001156
Adam Langleyfcf25832014-12-18 17:42:32 -08001157 val = OPENSSL_malloc(vallen);
1158 if (val == NULL) {
1159 goto err2;
1160 }
Adam Langley95c29f32014-06-20 12:00:00 -07001161
Adam Langleyfcf25832014-12-18 17:42:32 -08001162 currentvalpos = 0;
1163 memcpy(val + currentvalpos, (uint8_t *)label, llen);
1164 currentvalpos += llen;
1165 memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
1166 currentvalpos += SSL3_RANDOM_SIZE;
1167 memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
1168 currentvalpos += SSL3_RANDOM_SIZE;
Adam Langley95c29f32014-06-20 12:00:00 -07001169
Adam Langleyfcf25832014-12-18 17:42:32 -08001170 if (use_context) {
1171 val[currentvalpos] = (contextlen >> 8) & 0xff;
1172 currentvalpos++;
1173 val[currentvalpos] = contextlen & 0xff;
1174 currentvalpos++;
1175 if (contextlen > 0 || context != NULL) {
1176 memcpy(val + currentvalpos, context, contextlen);
1177 }
1178 }
Adam Langley95c29f32014-06-20 12:00:00 -07001179
Adam Langleyfcf25832014-12-18 17:42:32 -08001180 /* disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
1181 * label len) = 15, so size of val > max(prohibited label len) = 15 and the
1182 * comparisons won't have buffer overflow. */
1183 if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
1184 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0 ||
1185 memcmp(val, TLS_MD_SERVER_FINISH_CONST,
1186 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0 ||
1187 memcmp(val, TLS_MD_MASTER_SECRET_CONST,
1188 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0 ||
1189 memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
1190 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) {
1191 goto err1;
1192 }
Adam Langley95c29f32014-06-20 12:00:00 -07001193
Adam Langleyfcf25832014-12-18 17:42:32 -08001194 ret = tls1_PRF(ssl_get_algorithm2(s), val, vallen, NULL, 0, NULL, 0,
1195 s->session->master_key, s->session->master_key_length, out,
David Benjaminaf032d62014-12-22 10:42:51 -05001196 olen);
Adam Langley95c29f32014-06-20 12:00:00 -07001197
Adam Langleyfcf25832014-12-18 17:42:32 -08001198 goto out;
1199
Adam Langley95c29f32014-06-20 12:00:00 -07001200err1:
Adam Langleyfcf25832014-12-18 17:42:32 -08001201 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material,
1202 SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
1203 ret = 0;
1204 goto out;
Adam Langley95c29f32014-06-20 12:00:00 -07001205
Adam Langleyfcf25832014-12-18 17:42:32 -08001206err2:
1207 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE);
1208 ret = 0;
1209
1210out:
Adam Langleyfcf25832014-12-18 17:42:32 -08001211 if (val != NULL) {
1212 OPENSSL_free(val);
1213 }
1214
1215 return ret;
1216}
1217
1218int tls1_alert_code(int code) {
1219 switch (code) {
1220 case SSL_AD_CLOSE_NOTIFY:
1221 return SSL3_AD_CLOSE_NOTIFY;
1222
1223 case SSL_AD_UNEXPECTED_MESSAGE:
1224 return SSL3_AD_UNEXPECTED_MESSAGE;
1225
1226 case SSL_AD_BAD_RECORD_MAC:
1227 return SSL3_AD_BAD_RECORD_MAC;
1228
1229 case SSL_AD_DECRYPTION_FAILED:
1230 return TLS1_AD_DECRYPTION_FAILED;
1231
1232 case SSL_AD_RECORD_OVERFLOW:
1233 return TLS1_AD_RECORD_OVERFLOW;
1234
1235 case SSL_AD_DECOMPRESSION_FAILURE:
1236 return SSL3_AD_DECOMPRESSION_FAILURE;
1237
1238 case SSL_AD_HANDSHAKE_FAILURE:
1239 return SSL3_AD_HANDSHAKE_FAILURE;
1240
1241 case SSL_AD_NO_CERTIFICATE:
1242 return -1;
1243
1244 case SSL_AD_BAD_CERTIFICATE:
1245 return SSL3_AD_BAD_CERTIFICATE;
1246
1247 case SSL_AD_UNSUPPORTED_CERTIFICATE:
1248 return SSL3_AD_UNSUPPORTED_CERTIFICATE;
1249
1250 case SSL_AD_CERTIFICATE_REVOKED:
1251 return SSL3_AD_CERTIFICATE_REVOKED;
1252
1253 case SSL_AD_CERTIFICATE_EXPIRED:
1254 return SSL3_AD_CERTIFICATE_EXPIRED;
1255
1256 case SSL_AD_CERTIFICATE_UNKNOWN:
1257 return SSL3_AD_CERTIFICATE_UNKNOWN;
1258
1259 case SSL_AD_ILLEGAL_PARAMETER:
1260 return SSL3_AD_ILLEGAL_PARAMETER;
1261
1262 case SSL_AD_UNKNOWN_CA:
1263 return TLS1_AD_UNKNOWN_CA;
1264
1265 case SSL_AD_ACCESS_DENIED:
1266 return TLS1_AD_ACCESS_DENIED;
1267
1268 case SSL_AD_DECODE_ERROR:
1269 return TLS1_AD_DECODE_ERROR;
1270
1271 case SSL_AD_DECRYPT_ERROR:
1272 return TLS1_AD_DECRYPT_ERROR;
1273 case SSL_AD_EXPORT_RESTRICTION:
1274 return TLS1_AD_EXPORT_RESTRICTION;
1275
1276 case SSL_AD_PROTOCOL_VERSION:
1277 return TLS1_AD_PROTOCOL_VERSION;
1278
1279 case SSL_AD_INSUFFICIENT_SECURITY:
1280 return TLS1_AD_INSUFFICIENT_SECURITY;
1281
1282 case SSL_AD_INTERNAL_ERROR:
1283 return TLS1_AD_INTERNAL_ERROR;
1284
1285 case SSL_AD_USER_CANCELLED:
1286 return TLS1_AD_USER_CANCELLED;
1287
1288 case SSL_AD_NO_RENEGOTIATION:
1289 return TLS1_AD_NO_RENEGOTIATION;
1290
1291 case SSL_AD_UNSUPPORTED_EXTENSION:
1292 return TLS1_AD_UNSUPPORTED_EXTENSION;
1293
1294 case SSL_AD_CERTIFICATE_UNOBTAINABLE:
1295 return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
1296
1297 case SSL_AD_UNRECOGNIZED_NAME:
1298 return TLS1_AD_UNRECOGNIZED_NAME;
1299
1300 case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
1301 return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
1302
1303 case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
1304 return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
1305
1306 case SSL_AD_UNKNOWN_PSK_IDENTITY:
1307 return TLS1_AD_UNKNOWN_PSK_IDENTITY;
1308
1309 case SSL_AD_INAPPROPRIATE_FALLBACK:
1310 return SSL3_AD_INAPPROPRIATE_FALLBACK;
1311
1312 default:
1313 return -1;
1314 }
1315}