blob: 6cf8fb608ebd4e05920ef26dfc2c69d75ea12906 [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
David Benjamin1f5e1152014-12-23 09:23:32 -0500150/* tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246,
151 * section 5. It writes |out_len| bytes to |out|, using |md| as the hash and
152 * |secret| as the secret. |seed1| through |seed3| are concatenated to form the
153 * seed parameter. It returns one on success and zero on failure. */
154static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md,
155 const uint8_t *secret, size_t secret_len,
156 const uint8_t *seed1, size_t seed1_len,
157 const uint8_t *seed2, size_t seed2_len,
158 const uint8_t *seed3, size_t seed3_len) {
159 size_t chunk;
160 HMAC_CTX ctx, ctx_tmp, ctx_init;
Adam Langleyfcf25832014-12-18 17:42:32 -0800161 uint8_t A1[EVP_MAX_MD_SIZE];
David Benjamin1f5e1152014-12-23 09:23:32 -0500162 unsigned A1_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800163 int ret = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700164
Adam Langleyfcf25832014-12-18 17:42:32 -0800165 chunk = EVP_MD_size(md);
Adam Langley95c29f32014-06-20 12:00:00 -0700166
David Benjamin1f5e1152014-12-23 09:23:32 -0500167 HMAC_CTX_init(&ctx);
168 HMAC_CTX_init(&ctx_tmp);
169 HMAC_CTX_init(&ctx_init);
170 if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) ||
171 !HMAC_CTX_copy_ex(&ctx, &ctx_init) ||
172 (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) ||
173 (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) ||
174 (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len)) ||
175 !HMAC_Final(&ctx, A1, &A1_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800176 goto err;
177 }
178
179 for (;;) {
David Benjamin1f5e1152014-12-23 09:23:32 -0500180 /* Reinit mac contexts. */
181 if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) ||
182 !HMAC_Update(&ctx, A1, A1_len) ||
183 (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) ||
184 (seed1_len && !HMAC_Update(&ctx, seed1, seed1_len)) ||
185 (seed2_len && !HMAC_Update(&ctx, seed2, seed2_len)) ||
186 (seed3_len && !HMAC_Update(&ctx, seed3, seed3_len))) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800187 goto err;
188 }
189
David Benjamin1f5e1152014-12-23 09:23:32 -0500190 if (out_len > chunk) {
191 unsigned len;
192 if (!HMAC_Final(&ctx, out, &len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800193 goto err;
194 }
David Benjamin1f5e1152014-12-23 09:23:32 -0500195 assert(len == chunk);
196 out += len;
197 out_len -= len;
198 /* Calculate the next A1 value. */
199 if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800200 goto err;
201 }
202 } else {
David Benjamin1f5e1152014-12-23 09:23:32 -0500203 /* Last chunk. */
204 if (!HMAC_Final(&ctx, A1, &A1_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800205 goto err;
206 }
David Benjamin1f5e1152014-12-23 09:23:32 -0500207 memcpy(out, A1, out_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800208 break;
209 }
210 }
211
212 ret = 1;
213
Adam Langley95c29f32014-06-20 12:00:00 -0700214err:
David Benjamin1f5e1152014-12-23 09:23:32 -0500215 HMAC_CTX_cleanup(&ctx);
216 HMAC_CTX_cleanup(&ctx_tmp);
217 HMAC_CTX_cleanup(&ctx_init);
Adam Langleyfcf25832014-12-18 17:42:32 -0800218 OPENSSL_cleanse(A1, sizeof(A1));
219 return ret;
Adam Langley95c29f32014-06-20 12:00:00 -0700220}
Adam Langley9447dff2014-06-24 17:29:06 -0700221
David Benjamin41ac9792014-12-23 10:41:06 -0500222int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
223 size_t secret_len, const char *label, size_t label_len,
224 const uint8_t *seed1, size_t seed1_len,
225 const uint8_t *seed2, size_t seed2_len) {
David Benjamin1f5e1152014-12-23 09:23:32 -0500226 size_t idx, len, count, i;
Adam Langleyfcf25832014-12-18 17:42:32 -0800227 const uint8_t *S1;
228 long m;
229 const EVP_MD *md;
230 int ret = 0;
David Benjaminaf032d62014-12-22 10:42:51 -0500231 uint8_t *tmp;
232
David Benjamin1f5e1152014-12-23 09:23:32 -0500233 if (out_len == 0) {
David Benjaminaf032d62014-12-22 10:42:51 -0500234 return 1;
235 }
236
237 /* Allocate a temporary buffer. */
David Benjamin1f5e1152014-12-23 09:23:32 -0500238 tmp = OPENSSL_malloc(out_len);
David Benjaminaf032d62014-12-22 10:42:51 -0500239 if (tmp == NULL) {
David Benjamin41ac9792014-12-23 10:41:06 -0500240 OPENSSL_PUT_ERROR(SSL, tls1_prf, ERR_R_MALLOC_FAILURE);
David Benjaminaf032d62014-12-22 10:42:51 -0500241 return 0;
242 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800243
David Benjamin1f5e1152014-12-23 09:23:32 -0500244 /* Count number of digests and partition |secret| evenly. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800245 count = 0;
246 for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
David Benjamin41ac9792014-12-23 10:41:06 -0500247 if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800248 count++;
249 }
250 }
David Benjamin1f5e1152014-12-23 09:23:32 -0500251 /* TODO(davidben): The only case where count isn't 1 is the old MD5/SHA-1
252 * combination. The logic around multiple handshake digests can probably be
253 * simplified. */
254 assert(count == 1 || count == 2);
255 len = secret_len / count;
Adam Langleyfcf25832014-12-18 17:42:32 -0800256 if (count == 1) {
David Benjamin1f5e1152014-12-23 09:23:32 -0500257 secret_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800258 }
David Benjamin1f5e1152014-12-23 09:23:32 -0500259 S1 = secret;
260 memset(out, 0, out_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800261 for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) {
David Benjamin41ac9792014-12-23 10:41:06 -0500262 if ((m << TLS1_PRF_DGST_SHIFT) & ssl_get_algorithm2(s)) {
David Benjamin1f5e1152014-12-23 09:23:32 -0500263 /* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
264 * two halves with an overlapping byte. */
265 if (!tls1_P_hash(tmp, out_len, md, S1, len + (secret_len & 1),
266 (const uint8_t *)label, label_len, seed1, seed1_len,
267 seed2, seed2_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800268 goto err;
269 }
270 S1 += len;
David Benjamin1f5e1152014-12-23 09:23:32 -0500271 for (i = 0; i < out_len; i++) {
David Benjaminaf032d62014-12-22 10:42:51 -0500272 out[i] ^= tmp[i];
Adam Langleyfcf25832014-12-18 17:42:32 -0800273 }
274 }
275 }
276 ret = 1;
277
278err:
David Benjamin1f5e1152014-12-23 09:23:32 -0500279 OPENSSL_cleanse(tmp, out_len);
David Benjaminaf032d62014-12-22 10:42:51 -0500280 OPENSSL_free(tmp);
Adam Langleyfcf25832014-12-18 17:42:32 -0800281 return ret;
282}
283
David Benjamin1f5e1152014-12-23 09:23:32 -0500284static int tls1_generate_key_block(SSL *s, uint8_t *out, size_t out_len) {
David Benjamin41ac9792014-12-23 10:41:06 -0500285 return s->enc_method->prf(s, out, out_len, s->session->master_key,
286 s->session->master_key_length,
287 TLS_MD_KEY_EXPANSION_CONST,
288 TLS_MD_KEY_EXPANSION_CONST_SIZE,
289 s->s3->server_random, SSL3_RANDOM_SIZE,
290 s->s3->client_random,
291 SSL3_RANDOM_SIZE);
Adam Langleyfcf25832014-12-18 17:42:32 -0800292}
Adam Langley95c29f32014-06-20 12:00:00 -0700293
Adam Langleyc9fb3752014-06-20 12:00:00 -0700294/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
295 * returns 0 on malloc error. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800296static int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx) {
297 if (*aead_ctx != NULL) {
298 EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx);
299 } else {
300 *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
301 if (*aead_ctx == NULL) {
302 OPENSSL_PUT_ERROR(SSL, tls1_aead_ctx_init, ERR_R_MALLOC_FAILURE);
303 return 0;
304 }
305 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700306
Adam Langleyfcf25832014-12-18 17:42:32 -0800307 return 1;
308}
Adam Langleyc9fb3752014-06-20 12:00:00 -0700309
Adam Langleyfcf25832014-12-18 17:42:32 -0800310static void tls1_cleanup_enc_ctx(EVP_CIPHER_CTX **ctx) {
311 if (*ctx != NULL) {
312 EVP_CIPHER_CTX_free(*ctx);
313 }
314 *ctx = NULL;
315}
Adam Langley88333ef2014-10-15 20:13:35 -0700316
Adam Langleyfcf25832014-12-18 17:42:32 -0800317static void tls1_cleanup_hash_ctx(EVP_MD_CTX **ctx) {
318 if (*ctx != NULL) {
319 EVP_MD_CTX_destroy(*ctx);
320 }
321 *ctx = NULL;
322}
Adam Langley88333ef2014-10-15 20:13:35 -0700323
Adam Langleyc9fb3752014-06-20 12:00:00 -0700324static int tls1_change_cipher_state_aead(SSL *s, char is_read,
Adam Langleyfcf25832014-12-18 17:42:32 -0800325 const uint8_t *key, unsigned key_len,
326 const uint8_t *iv, unsigned iv_len,
327 const uint8_t *mac_secret,
328 unsigned mac_secret_len) {
329 const EVP_AEAD *aead = s->s3->tmp.new_aead;
330 SSL_AEAD_CTX *aead_ctx;
David Benjaminea72bd02014-12-21 21:27:41 -0500331 /* merged_key is used to merge the MAC, cipher, and IV keys for an AEAD which
332 * simulates pre-AEAD cipher suites. */
333 uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
Adam Langley9447dff2014-06-24 17:29:06 -0700334
Adam Langleyfcf25832014-12-18 17:42:32 -0800335 if (is_read) {
336 tls1_cleanup_enc_ctx(&s->enc_read_ctx);
337 tls1_cleanup_hash_ctx(&s->read_hash);
338 } else {
339 tls1_cleanup_enc_ctx(&s->enc_write_ctx);
340 tls1_cleanup_hash_ctx(&s->write_hash);
341 }
Adam Langley88333ef2014-10-15 20:13:35 -0700342
Adam Langleyfcf25832014-12-18 17:42:32 -0800343 if (mac_secret_len > 0) {
344 /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
345 * suites). */
David Benjaminea72bd02014-12-21 21:27:41 -0500346 if (mac_secret_len + key_len + iv_len > sizeof(merged_key)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800347 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead,
348 ERR_R_INTERNAL_ERROR);
349 return 0;
350 }
David Benjaminea72bd02014-12-21 21:27:41 -0500351 memcpy(merged_key, mac_secret, mac_secret_len);
352 memcpy(merged_key + mac_secret_len, key, key_len);
353 memcpy(merged_key + mac_secret_len + key_len, iv, iv_len);
354 key = merged_key;
Adam Langleyfcf25832014-12-18 17:42:32 -0800355 key_len += mac_secret_len;
David Benjaminea72bd02014-12-21 21:27:41 -0500356 key_len += iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800357 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700358
Adam Langleyfcf25832014-12-18 17:42:32 -0800359 if (is_read) {
360 if (!tls1_aead_ctx_init(&s->aead_read_ctx)) {
361 return 0;
362 }
363 aead_ctx = s->aead_read_ctx;
364 } else {
365 if (!tls1_aead_ctx_init(&s->aead_write_ctx)) {
366 return 0;
367 }
368 aead_ctx = s->aead_write_ctx;
369 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700370
Adam Langleyfcf25832014-12-18 17:42:32 -0800371 if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len,
372 EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */)) {
373 OPENSSL_free(aead_ctx);
374 if (is_read) {
375 s->aead_read_ctx = NULL;
376 } else {
377 s->aead_write_ctx = NULL;
378 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700379
Adam Langleyfcf25832014-12-18 17:42:32 -0800380 return 0;
381 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700382
David Benjaminea72bd02014-12-21 21:27:41 -0500383 if (mac_secret_len == 0) {
384 /* For a real AEAD, the IV is the fixed part of the nonce. */
385 if (iv_len > sizeof(aead_ctx->fixed_nonce)) {
386 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
387 return 0;
388 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800389
David Benjaminea72bd02014-12-21 21:27:41 -0500390 memcpy(aead_ctx->fixed_nonce, iv, iv_len);
391 aead_ctx->fixed_nonce_len = iv_len;
392 aead_ctx->variable_nonce_included_in_record =
Adam Langleyfcf25832014-12-18 17:42:32 -0800393 (s->s3->tmp.new_cipher->algorithm2 &
394 SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
David Benjaminea72bd02014-12-21 21:27:41 -0500395 aead_ctx->random_variable_nonce = 0;
396 aead_ctx->omit_length_in_ad = 0;
397 } else {
398 aead_ctx->fixed_nonce_len = 0;
399 aead_ctx->variable_nonce_included_in_record = 1;
400 aead_ctx->random_variable_nonce = 1;
401 aead_ctx->omit_length_in_ad = 1;
402 }
403 aead_ctx->variable_nonce_len = s->s3->tmp.new_variable_iv_len;
404
Adam Langleyfcf25832014-12-18 17:42:32 -0800405 if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len !=
406 EVP_AEAD_nonce_length(aead)) {
407 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
408 return 0;
409 }
410 aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
411
412 return 1;
413}
414
415static void tls1_cleanup_aead_ctx(SSL_AEAD_CTX **ctx) {
416 if (*ctx != NULL) {
417 EVP_AEAD_CTX_cleanup(&(*ctx)->ctx);
418 OPENSSL_free(*ctx);
419 }
420 *ctx = NULL;
421}
Adam Langley88333ef2014-10-15 20:13:35 -0700422
Adam Langleya5fa5b72014-06-20 12:00:00 -0700423/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
424 * states when using EVP_CIPHER. The argument |is_read| is true iff this
425 * function is being called due to reading, as opposed to writing, a
426 * ChangeCipherSpec message. In order to support export ciphersuites,
427 * use_client_keys indicates whether the key material provided is in the
428 * "client write" direction. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800429static int tls1_change_cipher_state_cipher(SSL *s, char is_read,
430 char use_client_keys,
431 const uint8_t *mac_secret,
432 unsigned mac_secret_len,
433 const uint8_t *key, unsigned key_len,
434 const uint8_t *iv, unsigned iv_len) {
435 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
436 EVP_CIPHER_CTX *cipher_ctx;
437 EVP_MD_CTX *mac_ctx;
Adam Langley95c29f32014-06-20 12:00:00 -0700438
Adam Langleyfcf25832014-12-18 17:42:32 -0800439 if (is_read) {
440 tls1_cleanup_aead_ctx(&s->aead_read_ctx);
441 } else {
442 tls1_cleanup_aead_ctx(&s->aead_write_ctx);
443 }
Adam Langley88333ef2014-10-15 20:13:35 -0700444
Adam Langleyfcf25832014-12-18 17:42:32 -0800445 if (is_read) {
446 if (s->enc_read_ctx != NULL && !SSL_IS_DTLS(s)) {
447 EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
448 } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) {
449 goto err;
450 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700451
Adam Langleyfcf25832014-12-18 17:42:32 -0800452 cipher_ctx = s->enc_read_ctx;
453 mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
454 if (mac_ctx == NULL) {
455 goto err;
456 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700457
Adam Langleyfcf25832014-12-18 17:42:32 -0800458 memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
459 s->s3->read_mac_secret_size = mac_secret_len;
460 } else {
461 /* When updating the write contexts for DTLS, we do not wish to free the
462 * old ones because DTLS stores pointers to them in order to implement
463 * retransmission. */
Adam Langleya5fa5b72014-06-20 12:00:00 -0700464
Adam Langleyfcf25832014-12-18 17:42:32 -0800465 if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) {
466 EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
467 } else {
468 s->enc_write_ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
469 if (s->enc_write_ctx == NULL) {
470 goto err;
471 }
472 }
473 EVP_CIPHER_CTX_init(s->enc_write_ctx);
Adam Langleya5fa5b72014-06-20 12:00:00 -0700474
Adam Langleyfcf25832014-12-18 17:42:32 -0800475 cipher_ctx = s->enc_write_ctx;
476 if (SSL_IS_DTLS(s)) {
477 /* This is the same as ssl_replace_hash, but doesn't
478 * free the old |s->write_hash|. */
479 mac_ctx = EVP_MD_CTX_create();
480 if (!mac_ctx) {
481 goto err;
482 }
483 s->write_hash = mac_ctx;
484 } else {
485 mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
486 if (mac_ctx == NULL) {
487 goto err;
488 }
489 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700490
Adam Langleyfcf25832014-12-18 17:42:32 -0800491 memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
492 s->s3->write_mac_secret_size = mac_secret_len;
493 }
Adam Langley95c29f32014-06-20 12:00:00 -0700494
Adam Langleyfcf25832014-12-18 17:42:32 -0800495 EVP_PKEY *mac_key = EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, NULL,
496 mac_secret, mac_secret_len);
497 if (!mac_key) {
498 return 0;
499 }
Adam Langley95c29f32014-06-20 12:00:00 -0700500
Adam Langleyfcf25832014-12-18 17:42:32 -0800501 if (!EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key)) {
502 EVP_PKEY_free(mac_key);
503 goto err;
504 }
505 EVP_PKEY_free(mac_key);
Adam Langley95c29f32014-06-20 12:00:00 -0700506
Adam Langleyfcf25832014-12-18 17:42:32 -0800507 if (!EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv,
508 !is_read)) {
509 goto err;
510 }
511
512 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700513
Adam Langley95c29f32014-06-20 12:00:00 -0700514err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800515 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_cipher, ERR_R_MALLOC_FAILURE);
516 return 0;
517}
Adam Langleya5fa5b72014-06-20 12:00:00 -0700518
Adam Langleyfcf25832014-12-18 17:42:32 -0800519int tls1_change_cipher_state(SSL *s, int which) {
520 /* is_read is true if we have just read a ChangeCipherSpec message - i.e. we
521 * need to update the read cipherspec. Otherwise we have just written one. */
522 const char is_read = (which & SSL3_CC_READ) != 0;
523 /* use_client_keys is true if we wish to use the keys for the "client write"
524 * direction. This is the case if we're a client sending a ChangeCipherSpec,
525 * or a server reading a client's ChangeCipherSpec. */
526 const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
527 which == SSL3_CHANGE_CIPHER_SERVER_READ;
528 const uint8_t *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
529 const uint8_t *client_write_key, *server_write_key, *key;
530 const uint8_t *client_write_iv, *server_write_iv, *iv;
531 const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
532 const EVP_AEAD *aead = s->s3->tmp.new_aead;
David Benjaminea72bd02014-12-21 21:27:41 -0500533 size_t key_len, iv_len, mac_secret_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800534 const uint8_t *key_data;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700535
Adam Langleyfcf25832014-12-18 17:42:32 -0800536 /* Reset sequence number to zero. */
537 if (!SSL_IS_DTLS(s)) {
538 memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
539 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700540
David Benjaminea72bd02014-12-21 21:27:41 -0500541 mac_secret_len = s->s3->tmp.new_mac_secret_len;
542 iv_len = s->s3->tmp.new_fixed_iv_len;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700543
Adam Langleyfcf25832014-12-18 17:42:32 -0800544 if (aead != NULL) {
545 key_len = EVP_AEAD_key_length(aead);
David Benjaminea72bd02014-12-21 21:27:41 -0500546 if (mac_secret_len > 0) {
547 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
548 * the key length reported by |EVP_AEAD_key_length| will include the MAC
549 * and IV key bytes. */
550 if (key_len < mac_secret_len + iv_len) {
551 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
552 return 0;
553 }
554 key_len -= mac_secret_len + iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800555 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800556 } else {
557 key_len = EVP_CIPHER_key_length(cipher);
Adam Langleyfcf25832014-12-18 17:42:32 -0800558 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700559
Adam Langleyfcf25832014-12-18 17:42:32 -0800560 key_data = s->s3->tmp.key_block;
561 client_write_mac_secret = key_data;
562 key_data += mac_secret_len;
563 server_write_mac_secret = key_data;
564 key_data += mac_secret_len;
565 client_write_key = key_data;
566 key_data += key_len;
567 server_write_key = key_data;
568 key_data += key_len;
569 client_write_iv = key_data;
570 key_data += iv_len;
571 server_write_iv = key_data;
572 key_data += iv_len;
Adam Langleya5fa5b72014-06-20 12:00:00 -0700573
Adam Langleyfcf25832014-12-18 17:42:32 -0800574 if (use_client_keys) {
575 mac_secret = client_write_mac_secret;
576 key = client_write_key;
577 iv = client_write_iv;
578 } else {
579 mac_secret = server_write_mac_secret;
580 key = server_write_key;
581 iv = server_write_iv;
582 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700583
Adam Langleyfcf25832014-12-18 17:42:32 -0800584 if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
585 OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
586 return 0;
587 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700588
Adam Langleyfcf25832014-12-18 17:42:32 -0800589 if (aead != NULL) {
590 if (!tls1_change_cipher_state_aead(s, is_read, key, key_len, iv, iv_len,
591 mac_secret, mac_secret_len)) {
592 return 0;
593 }
594 } else {
595 if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
596 mac_secret, mac_secret_len, key,
597 key_len, iv, iv_len)) {
598 return 0;
599 }
600 }
Adam Langleya5fa5b72014-06-20 12:00:00 -0700601
Adam Langleyfcf25832014-12-18 17:42:32 -0800602 return 1;
603}
Adam Langley95c29f32014-06-20 12:00:00 -0700604
Adam Langleyfcf25832014-12-18 17:42:32 -0800605int tls1_setup_key_block(SSL *s) {
David Benjaminaf032d62014-12-22 10:42:51 -0500606 uint8_t *p;
Adam Langleyfcf25832014-12-18 17:42:32 -0800607 const EVP_CIPHER *c = NULL;
608 const EVP_MD *hash = NULL;
609 const EVP_AEAD *aead = NULL;
David Benjaminea72bd02014-12-21 21:27:41 -0500610 int mac_type = NID_undef;
Adam Langleyfcf25832014-12-18 17:42:32 -0800611 int ret = 0;
David Benjaminea72bd02014-12-21 21:27:41 -0500612 size_t mac_secret_len, fixed_iv_len, variable_iv_len, key_len;
David Benjamin1f5e1152014-12-23 09:23:32 -0500613 size_t key_block_len;
Adam Langley95c29f32014-06-20 12:00:00 -0700614
Adam Langley95c29f32014-06-20 12:00:00 -0700615
Adam Langleyfcf25832014-12-18 17:42:32 -0800616 if (s->s3->tmp.key_block_length != 0) {
617 return 1;
618 }
Adam Langley95c29f32014-06-20 12:00:00 -0700619
David Benjaminea72bd02014-12-21 21:27:41 -0500620 if (s->session->cipher == NULL) {
621 goto cipher_unavailable_err;
622 }
623
624 /* TODO(davidben): Make DTLS record-layer code EVP_AEAD-aware. */
625 if (!SSL_IS_DTLS(s)) {
626 if (!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
627 s->session->cipher,
628 ssl3_version_from_wire(s, s->version))) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800629 goto cipher_unavailable_err;
630 }
631 key_len = EVP_AEAD_key_length(aead);
David Benjaminea72bd02014-12-21 21:27:41 -0500632 variable_iv_len = EVP_AEAD_nonce_length(aead);
633 if (mac_secret_len > 0) {
634 /* For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites)
635 * the key length reported by |EVP_AEAD_key_length| will include the MAC
636 * key bytes and initial implicit IV. */
637 if (key_len < mac_secret_len + fixed_iv_len) {
638 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
639 return 0;
640 }
641 key_len -= mac_secret_len + fixed_iv_len;
642 } else {
643 /* The nonce is split into a fixed portion and a variable portion. */
644 if (variable_iv_len < fixed_iv_len) {
645 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
646 return 0;
647 }
648 variable_iv_len -= fixed_iv_len;
Adam Langleyfcf25832014-12-18 17:42:32 -0800649 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800650 } else {
651 if (!ssl_cipher_get_evp(s->session, &c, &hash, &mac_type,
David Benjaminea72bd02014-12-21 21:27:41 -0500652 &mac_secret_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800653 goto cipher_unavailable_err;
654 }
655 key_len = EVP_CIPHER_key_length(c);
David Benjaminea72bd02014-12-21 21:27:41 -0500656 fixed_iv_len = EVP_CIPHER_iv_length(c);
657 variable_iv_len = 0;
Adam Langleyfcf25832014-12-18 17:42:32 -0800658 }
Adam Langley95c29f32014-06-20 12:00:00 -0700659
David Benjaminea72bd02014-12-21 21:27:41 -0500660 assert(mac_secret_len < 256);
661 assert(fixed_iv_len < 256);
662 assert(variable_iv_len < 256);
663
Adam Langleyfcf25832014-12-18 17:42:32 -0800664 s->s3->tmp.new_aead = aead;
665 s->s3->tmp.new_sym_enc = c;
666 s->s3->tmp.new_hash = hash;
667 s->s3->tmp.new_mac_pkey_type = mac_type;
David Benjaminea72bd02014-12-21 21:27:41 -0500668 s->s3->tmp.new_mac_secret_len = (uint8_t)mac_secret_len;
669 s->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
670 s->s3->tmp.new_variable_iv_len = (uint8_t)variable_iv_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700671
David Benjamin1f5e1152014-12-23 09:23:32 -0500672 key_block_len = key_len + mac_secret_len + fixed_iv_len;
673 key_block_len *= 2;
Adam Langley95c29f32014-06-20 12:00:00 -0700674
Adam Langleyfcf25832014-12-18 17:42:32 -0800675 ssl3_cleanup_key_block(s);
Adam Langley95c29f32014-06-20 12:00:00 -0700676
David Benjamin1f5e1152014-12-23 09:23:32 -0500677 p = (uint8_t *)OPENSSL_malloc(key_block_len);
David Benjaminaf032d62014-12-22 10:42:51 -0500678 if (p == NULL) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800679 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE);
680 goto err;
681 }
Adam Langley95c29f32014-06-20 12:00:00 -0700682
David Benjamin1f5e1152014-12-23 09:23:32 -0500683 s->s3->tmp.key_block_length = key_block_len;
David Benjaminaf032d62014-12-22 10:42:51 -0500684 s->s3->tmp.key_block = p;
Adam Langley95c29f32014-06-20 12:00:00 -0700685
David Benjamin1f5e1152014-12-23 09:23:32 -0500686 if (!tls1_generate_key_block(s, p, key_block_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800687 goto err;
688 }
Adam Langley95c29f32014-06-20 12:00:00 -0700689
Adam Langleyfcf25832014-12-18 17:42:32 -0800690 if (!SSL_USE_EXPLICIT_IV(s) &&
691 (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) {
692 /* enable vulnerability countermeasure for CBC ciphers with known-IV
693 * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */
694 s->s3->need_record_splitting = 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700695
Adam Langleyfcf25832014-12-18 17:42:32 -0800696 if (s->session->cipher != NULL &&
697 s->session->cipher->algorithm_enc == SSL_RC4) {
698 s->s3->need_record_splitting = 0;
699 }
700 }
701
702 ret = 1;
703
Adam Langley95c29f32014-06-20 12:00:00 -0700704err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800705 return ret;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700706
707cipher_unavailable_err:
Adam Langleyfcf25832014-12-18 17:42:32 -0800708 OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block,
709 SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
710 return 0;
711}
Adam Langley95c29f32014-06-20 12:00:00 -0700712
Adam Langleyfcf25832014-12-18 17:42:32 -0800713/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|,
714 * respectively.
Adam Langley95c29f32014-06-20 12:00:00 -0700715 *
716 * Returns:
717 * 0: (in non-constant time) if the record is publically invalid (i.e. too
718 * short etc).
719 * 1: if the record's padding is valid / the encryption was successful.
720 * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
Adam Langleyfcf25832014-12-18 17:42:32 -0800721 * an internal error occured. */
722int tls1_enc(SSL *s, int send) {
723 SSL3_RECORD *rec;
724 EVP_CIPHER_CTX *ds;
725 unsigned long l;
726 int bs, i, j, k, pad = 0, ret, mac_size = 0;
727 const EVP_CIPHER *enc;
728 const SSL_AEAD_CTX *aead;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700729
Adam Langleyfcf25832014-12-18 17:42:32 -0800730 if (send) {
731 rec = &s->s3->wrec;
732 aead = s->aead_write_ctx;
733 } else {
734 rec = &s->s3->rrec;
735 aead = s->aead_read_ctx;
736 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700737
Adam Langleyfcf25832014-12-18 17:42:32 -0800738 if (aead) {
David Benjaminea72bd02014-12-21 21:27:41 -0500739 uint8_t ad[13], *seq, *in, *out, nonce[EVP_AEAD_MAX_NONCE_LENGTH];
Adam Langleyfcf25832014-12-18 17:42:32 -0800740 unsigned nonce_used;
David Benjaminea72bd02014-12-21 21:27:41 -0500741 size_t n, ad_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700742
Adam Langleyfcf25832014-12-18 17:42:32 -0800743 seq = send ? s->s3->write_sequence : s->s3->read_sequence;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700744
Adam Langleyfcf25832014-12-18 17:42:32 -0800745 if (SSL_IS_DTLS(s)) {
746 uint8_t dtlsseq[9], *p = dtlsseq;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700747
Adam Langleyfcf25832014-12-18 17:42:32 -0800748 s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
749 memcpy(p, &seq[2], 6);
750 memcpy(ad, dtlsseq, 8);
751 } else {
752 memcpy(ad, seq, 8);
753 for (i = 7; i >= 0; i--) {
754 ++seq[i];
755 if (seq[i] != 0) {
756 break;
757 }
758 }
759 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700760
Adam Langleyfcf25832014-12-18 17:42:32 -0800761 ad[8] = rec->type;
762 ad[9] = (uint8_t)(s->version >> 8);
763 ad[10] = (uint8_t)(s->version);
Adam Langleyc9fb3752014-06-20 12:00:00 -0700764
David Benjaminea72bd02014-12-21 21:27:41 -0500765 if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce)) {
766 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -0800767 return -1; /* internal error - should never happen. */
768 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700769
Adam Langleyfcf25832014-12-18 17:42:32 -0800770 memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
771 nonce_used = aead->fixed_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700772
Adam Langleyfcf25832014-12-18 17:42:32 -0800773 if (send) {
774 size_t len = rec->length;
775 size_t eivlen = 0;
776 in = rec->input;
777 out = rec->data;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700778
David Benjaminea72bd02014-12-21 21:27:41 -0500779 uint8_t *variable_nonce = nonce + nonce_used;
780 if (aead->random_variable_nonce) {
781 assert(aead->variable_nonce_included_in_record);
782 if (!RAND_bytes(nonce + nonce_used, aead->variable_nonce_len)) {
783 return -1;
784 }
785 } else {
786 /* When sending we use the sequence number as the variable part of the
787 * nonce. */
788 if (aead->variable_nonce_len != 8) {
789 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
790 return -1;
791 }
792 memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800793 }
Adam Langleyfcf25832014-12-18 17:42:32 -0800794 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700795
Adam Langleyfcf25832014-12-18 17:42:32 -0800796 /* in do_ssl3_write, rec->input is moved forward by variable_nonce_len in
797 * order to leave space for the variable nonce. Thus we can copy the
798 * sequence number bytes into place without overwriting any of the
799 * plaintext. */
800 if (aead->variable_nonce_included_in_record) {
David Benjaminea72bd02014-12-21 21:27:41 -0500801 memcpy(out, variable_nonce, aead->variable_nonce_len);
Adam Langleyfcf25832014-12-18 17:42:32 -0800802 len -= aead->variable_nonce_len;
803 eivlen = aead->variable_nonce_len;
804 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700805
David Benjaminea72bd02014-12-21 21:27:41 -0500806 if (aead->omit_length_in_ad) {
807 ad_len = 11;
808 } else {
809 ad[11] = len >> 8;
810 ad[12] = len & 0xff;
811 ad_len = 13;
812 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700813
Adam Langleyfcf25832014-12-18 17:42:32 -0800814 if (!EVP_AEAD_CTX_seal(&aead->ctx, out + eivlen, &n, len + aead->tag_len,
David Benjaminea72bd02014-12-21 21:27:41 -0500815 nonce, nonce_used, in + eivlen, len, ad, ad_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800816 return -1;
817 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700818
Adam Langleyfcf25832014-12-18 17:42:32 -0800819 if (aead->variable_nonce_included_in_record) {
820 n += aead->variable_nonce_len;
821 }
822 } else {
823 /* receive */
824 size_t len = rec->length;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700825
Adam Langleyfcf25832014-12-18 17:42:32 -0800826 if (rec->data != rec->input) {
David Benjaminea72bd02014-12-21 21:27:41 -0500827 OPENSSL_PUT_ERROR(SSL, tls1_enc, ERR_R_INTERNAL_ERROR);
Adam Langleyfcf25832014-12-18 17:42:32 -0800828 return -1; /* internal error - should never happen. */
829 }
830 out = in = rec->input;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700831
Adam Langleyfcf25832014-12-18 17:42:32 -0800832 if (len < aead->variable_nonce_len) {
833 return 0;
834 }
835 memcpy(nonce + nonce_used,
836 aead->variable_nonce_included_in_record ? in : ad,
837 aead->variable_nonce_len);
838 nonce_used += aead->variable_nonce_len;
Adam Langleyc9fb3752014-06-20 12:00:00 -0700839
Adam Langleyfcf25832014-12-18 17:42:32 -0800840 if (aead->variable_nonce_included_in_record) {
841 in += aead->variable_nonce_len;
842 len -= aead->variable_nonce_len;
843 out += aead->variable_nonce_len;
844 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700845
David Benjaminea72bd02014-12-21 21:27:41 -0500846 if (aead->omit_length_in_ad) {
847 ad_len = 11;
848 } else {
849 if (len < aead->tag_len) {
850 return 0;
851 }
852 size_t plaintext_len = len - aead->tag_len;
853
854 ad[11] = plaintext_len >> 8;
855 ad[12] = plaintext_len & 0xff;
856 ad_len = 13;
Adam Langleyfcf25832014-12-18 17:42:32 -0800857 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700858
David Benjaminea72bd02014-12-21 21:27:41 -0500859 if (!EVP_AEAD_CTX_open(&aead->ctx, out, &n, rec->length, nonce, nonce_used, in,
860 len, ad, ad_len)) {
Adam Langleyfcf25832014-12-18 17:42:32 -0800861 return -1;
862 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700863
Adam Langleyfcf25832014-12-18 17:42:32 -0800864 rec->data = rec->input = out;
865 }
Adam Langleyc9fb3752014-06-20 12:00:00 -0700866
Adam Langleyfcf25832014-12-18 17:42:32 -0800867 rec->length = n;
868 return 1;
869 }
Adam Langley95c29f32014-06-20 12:00:00 -0700870
Adam Langleyfcf25832014-12-18 17:42:32 -0800871 if (send) {
872 ds = s->enc_write_ctx;
873 rec = &(s->s3->wrec);
874 if (s->enc_write_ctx == NULL) {
875 enc = NULL;
876 } else {
877 int ivlen;
878 enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
879 /* For TLSv1.1 and later explicit IV */
880 if (SSL_USE_EXPLICIT_IV(s) && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) {
881 ivlen = EVP_CIPHER_iv_length(enc);
882 } else {
883 ivlen = 0;
884 }
Adam Langley95c29f32014-06-20 12:00:00 -0700885
Adam Langleyfcf25832014-12-18 17:42:32 -0800886 if (ivlen > 1) {
887 if (rec->data != rec->input) {
888 /* we can't write into the input stream:
889 * Can this ever happen?? (steve)
890 */
891 fprintf(stderr, "%s:%d: rec->data != rec->input\n", __FILE__,
892 __LINE__);
893 } else if (!RAND_bytes(rec->input, ivlen)) {
894 return -1;
895 }
896 }
897 }
898 } else {
899 ds = s->enc_read_ctx;
900 rec = &(s->s3->rrec);
901 if (s->enc_read_ctx == NULL) {
902 enc = NULL;
903 } else {
904 enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
905 }
906 }
Adam Langley95c29f32014-06-20 12:00:00 -0700907
Adam Langleyfcf25832014-12-18 17:42:32 -0800908 if (s->session == NULL || ds == NULL || enc == NULL) {
909 memmove(rec->data, rec->input, rec->length);
910 rec->input = rec->data;
911 ret = 1;
912 } else {
913 l = rec->length;
914 bs = EVP_CIPHER_block_size(ds->cipher);
Adam Langley95c29f32014-06-20 12:00:00 -0700915
Adam Langleyfcf25832014-12-18 17:42:32 -0800916 if (bs != 1 && send) {
917 i = bs - ((int)l % bs);
Adam Langley95c29f32014-06-20 12:00:00 -0700918
Adam Langleyfcf25832014-12-18 17:42:32 -0800919 /* Add weird padding of upto 256 bytes */
920 /* we need to add 'i' padding bytes of value j */
921 j = i - 1;
922 for (k = (int)l; k < (int)(l + i); k++) {
923 rec->input[k] = j;
924 }
925 l += i;
926 rec->length += i;
927 }
Adam Langley95c29f32014-06-20 12:00:00 -0700928
Adam Langleyfcf25832014-12-18 17:42:32 -0800929 if (!send && (l == 0 || l % bs != 0)) {
930 return 0;
931 }
Adam Langley95c29f32014-06-20 12:00:00 -0700932
Adam Langleyfcf25832014-12-18 17:42:32 -0800933 if (!EVP_Cipher(ds, rec->data, rec->input, l)) {
934 return -1;
935 }
Adam Langley95c29f32014-06-20 12:00:00 -0700936
Adam Langleyfcf25832014-12-18 17:42:32 -0800937 ret = 1;
938 if (EVP_MD_CTX_md(s->read_hash) != NULL) {
939 mac_size = EVP_MD_CTX_size(s->read_hash);
940 }
Adam Langley95c29f32014-06-20 12:00:00 -0700941
Adam Langleyfcf25832014-12-18 17:42:32 -0800942 if (bs != 1 && !send) {
943 ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
944 }
945 if (pad && !send) {
946 rec->length -= pad;
947 }
948 }
949 return ret;
950}
Adam Langley95c29f32014-06-20 12:00:00 -0700951
Adam Langleyfcf25832014-12-18 17:42:32 -0800952int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
953 unsigned int ret;
954 EVP_MD_CTX ctx, *d = NULL;
955 int i;
Adam Langley95c29f32014-06-20 12:00:00 -0700956
Adam Langleyfcf25832014-12-18 17:42:32 -0800957 if (s->s3->handshake_buffer &&
958 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
959 return 0;
960 }
961
962 for (i = 0; i < SSL_MAX_DIGEST; i++) {
963 if (s->s3->handshake_dgst[i] &&
964 EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
965 d = s->s3->handshake_dgst[i];
966 break;
967 }
968 }
969
970 if (!d) {
971 OPENSSL_PUT_ERROR(SSL, tls1_cert_verify_mac, SSL_R_NO_REQUIRED_DIGEST);
972 return 0;
973 }
974
975 EVP_MD_CTX_init(&ctx);
976 EVP_MD_CTX_copy_ex(&ctx, d);
977 EVP_DigestFinal_ex(&ctx, out, &ret);
978 EVP_MD_CTX_cleanup(&ctx);
979
980 return ret;
981}
Adam Langley95c29f32014-06-20 12:00:00 -0700982
Adam Langley1258b6a2014-06-20 12:00:00 -0700983/* tls1_handshake_digest calculates the current handshake hash and writes it to
984 * |out|, which has space for |out_len| bytes. It returns the number of bytes
985 * written or -1 in the event of an error. This function works on a copy of the
986 * underlying digests so can be called multiple times and prior to the final
987 * update etc. */
Adam Langleyfcf25832014-12-18 17:42:32 -0800988int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
989 const EVP_MD *md;
990 EVP_MD_CTX ctx;
David Benjamin1f5e1152014-12-23 09:23:32 -0500991 int err = 0, len = 0;
992 size_t i;
Adam Langleyfcf25832014-12-18 17:42:32 -0800993 long mask;
Adam Langley95c29f32014-06-20 12:00:00 -0700994
Adam Langleyfcf25832014-12-18 17:42:32 -0800995 EVP_MD_CTX_init(&ctx);
Adam Langley95c29f32014-06-20 12:00:00 -0700996
Adam Langleyfcf25832014-12-18 17:42:32 -0800997 for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
David Benjamin1f5e1152014-12-23 09:23:32 -0500998 size_t hash_size;
Adam Langleyfcf25832014-12-18 17:42:32 -0800999 unsigned int digest_len;
1000 EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
Adam Langley1258b6a2014-06-20 12:00:00 -07001001
Adam Langleyfcf25832014-12-18 17:42:32 -08001002 if ((mask & ssl_get_algorithm2(s)) == 0) {
1003 continue;
1004 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001005
Adam Langleyfcf25832014-12-18 17:42:32 -08001006 hash_size = EVP_MD_size(md);
1007 if (!hdgst ||
David Benjamin1f5e1152014-12-23 09:23:32 -05001008 hash_size > out_len ||
Adam Langleyfcf25832014-12-18 17:42:32 -08001009 !EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
1010 !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
David Benjamin1f5e1152014-12-23 09:23:32 -05001011 digest_len != hash_size /* internal error */) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001012 err = 1;
1013 break;
1014 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001015
Adam Langleyfcf25832014-12-18 17:42:32 -08001016 out += digest_len;
1017 out_len -= digest_len;
1018 len += digest_len;
1019 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001020
Adam Langleyfcf25832014-12-18 17:42:32 -08001021 EVP_MD_CTX_cleanup(&ctx);
Adam Langley1258b6a2014-06-20 12:00:00 -07001022
Adam Langleyfcf25832014-12-18 17:42:32 -08001023 if (err != 0) {
1024 return -1;
1025 }
1026 return len;
1027}
Adam Langley1258b6a2014-06-20 12:00:00 -07001028
Adam Langleyfcf25832014-12-18 17:42:32 -08001029int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
1030 uint8_t buf[2 * EVP_MAX_MD_SIZE];
Adam Langleyfcf25832014-12-18 17:42:32 -08001031 int err = 0;
1032 int digests_len;
Adam Langley1258b6a2014-06-20 12:00:00 -07001033
Adam Langleyfcf25832014-12-18 17:42:32 -08001034 if (s->s3->handshake_buffer &&
1035 !ssl3_digest_cached_records(s, free_handshake_buffer)) {
1036 return 0;
1037 }
Adam Langley1258b6a2014-06-20 12:00:00 -07001038
Adam Langleyfcf25832014-12-18 17:42:32 -08001039 digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
1040 if (digests_len < 0) {
1041 err = 1;
1042 digests_len = 0;
1043 }
Adam Langley95c29f32014-06-20 12:00:00 -07001044
David Benjamin41ac9792014-12-23 10:41:06 -05001045 if (!s->enc_method->prf(s, out, 12, s->session->master_key,
1046 s->session->master_key_length, str, slen, buf,
1047 digests_len, NULL, 0)) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001048 err = 1;
1049 }
Adam Langley95c29f32014-06-20 12:00:00 -07001050
Adam Langleyfcf25832014-12-18 17:42:32 -08001051 if (err) {
1052 return 0;
1053 } else {
David Benjaminaf032d62014-12-22 10:42:51 -05001054 return 12;
Adam Langleyfcf25832014-12-18 17:42:32 -08001055 }
1056}
Adam Langley95c29f32014-06-20 12:00:00 -07001057
Adam Langleyfcf25832014-12-18 17:42:32 -08001058int tls1_mac(SSL *ssl, uint8_t *md, int send) {
1059 SSL3_RECORD *rec;
1060 uint8_t *seq;
1061 EVP_MD_CTX *hash;
1062 size_t md_size, orig_len;
1063 int i, ok;
1064 EVP_MD_CTX hmac, *mac_ctx;
1065 uint8_t header[13];
1066 int t;
Adam Langley95c29f32014-06-20 12:00:00 -07001067
Adam Langleyfcf25832014-12-18 17:42:32 -08001068 if (send) {
1069 rec = &ssl->s3->wrec;
1070 seq = &ssl->s3->write_sequence[0];
1071 hash = ssl->write_hash;
1072 } else {
1073 rec = &ssl->s3->rrec;
1074 seq = &ssl->s3->read_sequence[0];
1075 hash = ssl->read_hash;
1076 }
Adam Langley95c29f32014-06-20 12:00:00 -07001077
Adam Langleyfcf25832014-12-18 17:42:32 -08001078 t = EVP_MD_CTX_size(hash);
1079 assert(t >= 0);
1080 md_size = t;
Adam Langley95c29f32014-06-20 12:00:00 -07001081
Adam Langleyfcf25832014-12-18 17:42:32 -08001082 mac_ctx = &hmac;
1083 if (!EVP_MD_CTX_copy(mac_ctx, hash)) {
1084 return -1;
1085 }
Adam Langley95c29f32014-06-20 12:00:00 -07001086
Adam Langleyfcf25832014-12-18 17:42:32 -08001087 if (SSL_IS_DTLS(ssl)) {
1088 uint8_t dtlsseq[8], *p = dtlsseq;
Adam Langley95c29f32014-06-20 12:00:00 -07001089
Adam Langleyfcf25832014-12-18 17:42:32 -08001090 s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p);
1091 memcpy(p, &seq[2], 6);
Adam Langley95c29f32014-06-20 12:00:00 -07001092
Adam Langleyfcf25832014-12-18 17:42:32 -08001093 memcpy(header, dtlsseq, 8);
1094 } else {
1095 memcpy(header, seq, 8);
1096 }
Adam Langley95c29f32014-06-20 12:00:00 -07001097
Adam Langleyfcf25832014-12-18 17:42:32 -08001098 /* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
1099 orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8);
1100 rec->type &= 0xff;
Adam Langley95c29f32014-06-20 12:00:00 -07001101
Adam Langleyfcf25832014-12-18 17:42:32 -08001102 header[8] = rec->type;
1103 header[9] = (uint8_t)(ssl->version >> 8);
1104 header[10] = (uint8_t)(ssl->version);
1105 header[11] = (rec->length) >> 8;
1106 header[12] = (rec->length) & 0xff;
Adam Langley69a01602014-11-17 17:26:55 -08001107
Adam Langleyfcf25832014-12-18 17:42:32 -08001108 if (!send && EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
1109 ssl3_cbc_record_digest_supported(mac_ctx)) {
1110 /* This is a CBC-encrypted record. We must avoid leaking any timing-side
1111 * channel information about how many blocks of data we are hashing because
1112 * that gives an attacker a timing-oracle. */
1113 ok = ssl3_cbc_digest_record(
1114 mac_ctx, md, &md_size, header, rec->input, rec->length + md_size,
1115 orig_len, ssl->s3->read_mac_secret, ssl->s3->read_mac_secret_size,
1116 0 /* not SSLv3 */);
1117 } else {
1118 EVP_DigestSignUpdate(mac_ctx, header, sizeof(header));
1119 EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length);
1120 ok = EVP_DigestSignFinal(mac_ctx, md, &md_size);
1121 }
Adam Langley69a01602014-11-17 17:26:55 -08001122
Adam Langleyfcf25832014-12-18 17:42:32 -08001123 EVP_MD_CTX_cleanup(mac_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001124
Adam Langleyfcf25832014-12-18 17:42:32 -08001125 if (!ok) {
1126 return -1;
1127 }
Adam Langley95c29f32014-06-20 12:00:00 -07001128
Adam Langleyfcf25832014-12-18 17:42:32 -08001129 if (!SSL_IS_DTLS(ssl)) {
1130 for (i = 7; i >= 0; i--) {
1131 ++seq[i];
1132 if (seq[i] != 0) {
1133 break;
1134 }
1135 }
1136 }
Adam Langley95c29f32014-06-20 12:00:00 -07001137
Adam Langleyfcf25832014-12-18 17:42:32 -08001138 return md_size;
1139}
Adam Langley95c29f32014-06-20 12:00:00 -07001140
David Benjamin31b1d812014-12-23 10:01:09 -05001141int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
1142 size_t premaster_len) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001143 if (s->s3->tmp.extended_master_secret) {
1144 uint8_t digests[2 * EVP_MAX_MD_SIZE];
1145 int digests_len;
Adam Langley75712922014-10-10 16:23:43 -07001146
Adam Langleyfcf25832014-12-18 17:42:32 -08001147 /* The master secret is based on the handshake hash just after sending the
1148 * ClientKeyExchange. However, we might have a client certificate to send,
1149 * in which case we might need different hashes for the verification and
1150 * thus still need the handshake buffer around. Keeping both a handshake
1151 * buffer *and* running hashes isn't yet supported so, when it comes to
1152 * calculating the Finished hash, we'll have to hash the handshake buffer
1153 * again. */
1154 if (s->s3->handshake_buffer &&
1155 !ssl3_digest_cached_records(s, dont_free_handshake_buffer)) {
1156 return 0;
1157 }
Adam Langley75712922014-10-10 16:23:43 -07001158
Adam Langleyfcf25832014-12-18 17:42:32 -08001159 digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
Adam Langleyfcf25832014-12-18 17:42:32 -08001160 if (digests_len == -1) {
1161 return 0;
1162 }
Adam Langley75712922014-10-10 16:23:43 -07001163
David Benjamin41ac9792014-12-23 10:41:06 -05001164 if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
1165 premaster_len, TLS_MD_EXTENDED_MASTER_SECRET_CONST,
1166 TLS_MD_EXTENDED_MASTER_SECRET_CONST_SIZE, digests,
1167 digests_len, NULL, 0)) {
David Benjaminaf032d62014-12-22 10:42:51 -05001168 return 0;
1169 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001170 } else {
David Benjamin41ac9792014-12-23 10:41:06 -05001171 if (!s->enc_method->prf(s, out, SSL3_MASTER_SECRET_SIZE, premaster,
1172 premaster_len, TLS_MD_MASTER_SECRET_CONST,
1173 TLS_MD_MASTER_SECRET_CONST_SIZE,
1174 s->s3->client_random, SSL3_RANDOM_SIZE,
1175 s->s3->server_random, SSL3_RANDOM_SIZE)) {
David Benjaminaf032d62014-12-22 10:42:51 -05001176 return 0;
1177 }
Adam Langleyfcf25832014-12-18 17:42:32 -08001178 }
Adam Langley95c29f32014-06-20 12:00:00 -07001179
Adam Langleyfcf25832014-12-18 17:42:32 -08001180 return SSL3_MASTER_SECRET_SIZE;
1181}
Adam Langley95c29f32014-06-20 12:00:00 -07001182
Adam Langleyfcf25832014-12-18 17:42:32 -08001183int tls1_export_keying_material(SSL *s, uint8_t *out, size_t olen,
1184 const char *label, size_t llen,
1185 const uint8_t *context, size_t contextlen,
1186 int use_context) {
Adam Langleyfcf25832014-12-18 17:42:32 -08001187 uint8_t *val = NULL;
1188 size_t vallen, currentvalpos;
1189 int ret;
Adam Langley95c29f32014-06-20 12:00:00 -07001190
Adam Langleyfcf25832014-12-18 17:42:32 -08001191 /* construct PRF arguments we construct the PRF argument ourself rather than
1192 * passing separate values into the TLS PRF to ensure that the concatenation
1193 * of values does not create a prohibited label. */
1194 vallen = llen + SSL3_RANDOM_SIZE * 2;
1195 if (use_context) {
1196 vallen += 2 + contextlen;
1197 }
Adam Langley95c29f32014-06-20 12:00:00 -07001198
Adam Langleyfcf25832014-12-18 17:42:32 -08001199 val = OPENSSL_malloc(vallen);
1200 if (val == NULL) {
1201 goto err2;
1202 }
Adam Langley95c29f32014-06-20 12:00:00 -07001203
Adam Langleyfcf25832014-12-18 17:42:32 -08001204 currentvalpos = 0;
1205 memcpy(val + currentvalpos, (uint8_t *)label, llen);
1206 currentvalpos += llen;
1207 memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
1208 currentvalpos += SSL3_RANDOM_SIZE;
1209 memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
1210 currentvalpos += SSL3_RANDOM_SIZE;
Adam Langley95c29f32014-06-20 12:00:00 -07001211
Adam Langleyfcf25832014-12-18 17:42:32 -08001212 if (use_context) {
1213 val[currentvalpos] = (contextlen >> 8) & 0xff;
1214 currentvalpos++;
1215 val[currentvalpos] = contextlen & 0xff;
1216 currentvalpos++;
1217 if (contextlen > 0 || context != NULL) {
1218 memcpy(val + currentvalpos, context, contextlen);
1219 }
1220 }
Adam Langley95c29f32014-06-20 12:00:00 -07001221
Adam Langleyfcf25832014-12-18 17:42:32 -08001222 /* disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited
1223 * label len) = 15, so size of val > max(prohibited label len) = 15 and the
1224 * comparisons won't have buffer overflow. */
1225 if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
1226 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0 ||
1227 memcmp(val, TLS_MD_SERVER_FINISH_CONST,
1228 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0 ||
1229 memcmp(val, TLS_MD_MASTER_SECRET_CONST,
1230 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0 ||
1231 memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
1232 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) {
1233 goto err1;
1234 }
Adam Langley95c29f32014-06-20 12:00:00 -07001235
David Benjamin41ac9792014-12-23 10:41:06 -05001236 /* SSL_export_keying_material is not implemented for SSLv3, so passing
1237 * everything through the label parameter works. */
1238 assert(s->version != SSL3_VERSION);
1239 ret = s->enc_method->prf(s, out, olen, s->session->master_key,
1240 s->session->master_key_length, (const char *)val,
1241 vallen, NULL, 0, NULL, 0);
Adam Langleyfcf25832014-12-18 17:42:32 -08001242 goto out;
1243
Adam Langley95c29f32014-06-20 12:00:00 -07001244err1:
Adam Langleyfcf25832014-12-18 17:42:32 -08001245 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material,
1246 SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
1247 ret = 0;
1248 goto out;
Adam Langley95c29f32014-06-20 12:00:00 -07001249
Adam Langleyfcf25832014-12-18 17:42:32 -08001250err2:
1251 OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE);
1252 ret = 0;
1253
1254out:
Adam Langleyfcf25832014-12-18 17:42:32 -08001255 if (val != NULL) {
1256 OPENSSL_free(val);
1257 }
1258
1259 return ret;
1260}
1261
1262int tls1_alert_code(int code) {
1263 switch (code) {
1264 case SSL_AD_CLOSE_NOTIFY:
1265 return SSL3_AD_CLOSE_NOTIFY;
1266
1267 case SSL_AD_UNEXPECTED_MESSAGE:
1268 return SSL3_AD_UNEXPECTED_MESSAGE;
1269
1270 case SSL_AD_BAD_RECORD_MAC:
1271 return SSL3_AD_BAD_RECORD_MAC;
1272
1273 case SSL_AD_DECRYPTION_FAILED:
1274 return TLS1_AD_DECRYPTION_FAILED;
1275
1276 case SSL_AD_RECORD_OVERFLOW:
1277 return TLS1_AD_RECORD_OVERFLOW;
1278
1279 case SSL_AD_DECOMPRESSION_FAILURE:
1280 return SSL3_AD_DECOMPRESSION_FAILURE;
1281
1282 case SSL_AD_HANDSHAKE_FAILURE:
1283 return SSL3_AD_HANDSHAKE_FAILURE;
1284
1285 case SSL_AD_NO_CERTIFICATE:
1286 return -1;
1287
1288 case SSL_AD_BAD_CERTIFICATE:
1289 return SSL3_AD_BAD_CERTIFICATE;
1290
1291 case SSL_AD_UNSUPPORTED_CERTIFICATE:
1292 return SSL3_AD_UNSUPPORTED_CERTIFICATE;
1293
1294 case SSL_AD_CERTIFICATE_REVOKED:
1295 return SSL3_AD_CERTIFICATE_REVOKED;
1296
1297 case SSL_AD_CERTIFICATE_EXPIRED:
1298 return SSL3_AD_CERTIFICATE_EXPIRED;
1299
1300 case SSL_AD_CERTIFICATE_UNKNOWN:
1301 return SSL3_AD_CERTIFICATE_UNKNOWN;
1302
1303 case SSL_AD_ILLEGAL_PARAMETER:
1304 return SSL3_AD_ILLEGAL_PARAMETER;
1305
1306 case SSL_AD_UNKNOWN_CA:
1307 return TLS1_AD_UNKNOWN_CA;
1308
1309 case SSL_AD_ACCESS_DENIED:
1310 return TLS1_AD_ACCESS_DENIED;
1311
1312 case SSL_AD_DECODE_ERROR:
1313 return TLS1_AD_DECODE_ERROR;
1314
1315 case SSL_AD_DECRYPT_ERROR:
1316 return TLS1_AD_DECRYPT_ERROR;
1317 case SSL_AD_EXPORT_RESTRICTION:
1318 return TLS1_AD_EXPORT_RESTRICTION;
1319
1320 case SSL_AD_PROTOCOL_VERSION:
1321 return TLS1_AD_PROTOCOL_VERSION;
1322
1323 case SSL_AD_INSUFFICIENT_SECURITY:
1324 return TLS1_AD_INSUFFICIENT_SECURITY;
1325
1326 case SSL_AD_INTERNAL_ERROR:
1327 return TLS1_AD_INTERNAL_ERROR;
1328
1329 case SSL_AD_USER_CANCELLED:
1330 return TLS1_AD_USER_CANCELLED;
1331
1332 case SSL_AD_NO_RENEGOTIATION:
1333 return TLS1_AD_NO_RENEGOTIATION;
1334
1335 case SSL_AD_UNSUPPORTED_EXTENSION:
1336 return TLS1_AD_UNSUPPORTED_EXTENSION;
1337
1338 case SSL_AD_CERTIFICATE_UNOBTAINABLE:
1339 return TLS1_AD_CERTIFICATE_UNOBTAINABLE;
1340
1341 case SSL_AD_UNRECOGNIZED_NAME:
1342 return TLS1_AD_UNRECOGNIZED_NAME;
1343
1344 case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
1345 return TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
1346
1347 case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
1348 return TLS1_AD_BAD_CERTIFICATE_HASH_VALUE;
1349
1350 case SSL_AD_UNKNOWN_PSK_IDENTITY:
1351 return TLS1_AD_UNKNOWN_PSK_IDENTITY;
1352
1353 case SSL_AD_INAPPROPRIATE_FALLBACK:
1354 return SSL3_AD_INAPPROPRIATE_FALLBACK;
1355
1356 default:
1357 return -1;
1358 }
1359}