1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ssl/t1_enc.c */
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * All rights reserved.
4c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This package is an SSL implementation written
6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * by Eric Young (eay@cryptsoft.com).
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The implementation was written so as to conform with Netscapes SSL.
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This library is free for commercial and non-commercial use as long as
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the following conditions are aheared to.  The following conditions
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * apply to all code found in this distribution, be it the RC4, RSA,
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * included with this distribution is covered by the same copyright terms
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Copyright remains Eric Young's, and as such any Copyright notices in
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * the code are not to be removed.
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * If this package is used in a product, Eric Young should be given attribution
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * as the author of the parts of the library used.
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This can be in the form of a textual message at program startup or
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * in documentation (online or textual) provided with the package.
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the copyright
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in the
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    documentation and/or other materials provided with the distribution.
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this software
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    must display the following acknowledgement:
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes cryptographic software written by
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *     Eric Young (eay@cryptsoft.com)"
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    The word 'cryptographic' can be left out if the rouines from the library
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    being used are not cryptographic related :-).
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. If you include any Windows specific code (or a derivative thereof) from
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the apps directory (application code) you must include an acknowledgement:
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SUCH DAMAGE.
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * The licence and distribution terms for any publically available version or
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * derivative of this code cannot be changed.  i.e. this code cannot simply be
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * copied and put under another distribution licence
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * [including the GNU Public Licence.]
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org/* ====================================================================
59480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Redistribution and use in source and binary forms, with or without
62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * modification, are permitted provided that the following conditions
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * are met:
64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 1. Redistributions of source code must retain the above copyright
66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer.
67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    notice, this list of conditions and the following disclaimer in
70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    the documentation and/or other materials provided with the
71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    distribution.
72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 3. All advertising materials mentioning features or use of this
74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    software must display the following acknowledgment:
75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    endorse or promote products derived from this software without
80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    prior written permission. For written permission, please contact
81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    openssl-core@openssl.org.
82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 5. Products derived from this software may not be called "OpenSSL"
84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    nor may "OpenSSL" appear in their names without prior written
85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    permission of the OpenSSL Project.
86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * 6. Redistributions of any form whatsoever must retain the following
88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    acknowledgment:
89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    "This product includes software developed by the OpenSSL Project
90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * OF THE POSSIBILITY OF SUCH DAMAGE.
104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * ====================================================================
105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * This product includes cryptographic software written by Eric Young
107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * (eay@cryptsoft.com).  This product includes software written by Tim
108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org * Hudson (tjh@cryptsoft.com).
109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org *
110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org */
111480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* ====================================================================
112480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Copyright 2005 Nokia. All rights reserved.
113480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
114480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * The portions of the attached software ("Contribution") is developed by
115480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * license.
117480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
118480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * support (see RFC 4279) to OpenSSL.
121480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
122480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * No patent licenses or other rights except those expressly stated in
123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * the OpenSSL open source license shall be deemed granted or received
124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * expressly, by implication, estoppel, or otherwise.
125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * No assurances are provided by Nokia that the Contribution does not
127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * infringe the patent or other intellectual property rights of any third
128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * party or that the license provides you with all the necessary rights
129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * to make use of the Contribution.
130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org *
131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org * OTHERWISE.
136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org */
137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <stdio.h>
139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include "ssl_locl.h"
140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_COMP
141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/comp.h>
142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/evp.h>
144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/hmac.h>
145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/md5.h>
1462c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#include <openssl/rand.h>
147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#include <openssl/des.h>
149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
151480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* seed1 through seed5 are virtually concatenated */
152480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
153480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			int sec_len,
154480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			const void *seed1, int seed1_len,
155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			const void *seed2, int seed2_len,
156480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			const void *seed3, int seed3_len,
157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			const void *seed4, int seed4_len,
158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			const void *seed5, int seed5_len,
159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			unsigned char *out, int olen)
160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
161480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int chunk;
1622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	size_t j;
1632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX ctx, ctx_tmp;
1642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_PKEY *mac_key;
165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned char A1[EVP_MAX_MD_SIZE];
1662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	size_t A1_len;
167480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret = 0;
168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	chunk=EVP_MD_size(md);
170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	OPENSSL_assert(chunk >= 0);
171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_init(&ctx);
1732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_init(&ctx_tmp);
1742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
1752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
1762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
1772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!mac_key)
1782c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		goto err;
1792c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1812c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1852c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1872c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
1932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for (;;)
197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		/* Reinit mac contexts */
1992c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2012c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
202480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2032c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
204480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2052c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
206480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2072c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
208480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
210480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
212480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
2152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
216480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			goto err;
217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (olen > chunk)
219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
2202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (!EVP_DigestSignFinal(&ctx,out,&j))
221480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			out+=j;
223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			olen-=j;
2242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			/* calc the next A1 value */
2252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
226480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else	/* last one */
229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
2302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			memcpy(out,A1,olen);
233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			break;
234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = 1;
237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgerr:
2382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_PKEY_free(mac_key);
2392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_cleanup(&ctx);
2402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	EVP_MD_CTX_cleanup(&ctx_tmp);
241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	OPENSSL_cleanse(A1,sizeof(A1));
242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
245480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org/* seed1 through seed5 are virtually concatenated */
246480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tls1_PRF(long digest_mask,
247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const void *seed1, int seed1_len,
248480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const void *seed2, int seed2_len,
249480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const void *seed3, int seed3_len,
250480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const void *seed4, int seed4_len,
251480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const void *seed5, int seed5_len,
252480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     const unsigned char *sec, int slen,
253480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		     unsigned char *out1,
254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		     unsigned char *out2, int olen)
255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
256480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int len,i,idx,count;
257480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const unsigned char *S1;
258480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	long m;
259480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const EVP_MD *md;
260480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret = 0;
261480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
262480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	/* Count number of digests and partition sec evenly */
263480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	count=0;
264480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
265480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
266480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
267480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	len=slen/count;
2682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (count == 1)
2692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		slen = 0;
270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	S1=sec;
271480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	memset(out1,0,olen);
272480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
273480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) {
274480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!md) {
275480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				SSLerr(SSL_F_TLS1_PRF,
276480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				SSL_R_UNSUPPORTED_DIGEST_TYPE);
277480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
278480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
279480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (!tls1_P_hash(md ,S1,len+(slen&1),
280480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
281480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					out2,olen))
282480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				goto err;
283480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			S1+=len;
284480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			for (i=0; i<olen; i++)
285480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
286480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				out1[i]^=out2[i];
287480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
288480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
289c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
290480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = 1;
291480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgerr:
292480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
293480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org}
294480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgstatic int tls1_generate_key_block(SSL *s, unsigned char *km,
295c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     unsigned char *tmp, int num)
296c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret;
2982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	ret = tls1_PRF(ssl_get_algorithm2(s),
299480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
300480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 s->s3->server_random,SSL3_RANDOM_SIZE,
301480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 s->s3->client_random,SSL3_RANDOM_SIZE,
302480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		 NULL,0,NULL,0,
303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 s->session->master_key,s->session->master_key_length,
304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 km,tmp,num);
305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                s->session->master_key_length);
308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        int i;
310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        for (i=0; i < s->session->master_key_length; i++)
311c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                {
312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                printf("%02X", s->session->master_key[i]);
313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org                }
314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org        printf("\n");  }
315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif    /* KSSL_DEBUG */
316480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return ret;
317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
319219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org/* tls1_aead_ctx_init allocates |*aead_ctx|, if needed and returns 1. It
320219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * returns 0 on malloc error. */
321219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgstatic int tls1_aead_ctx_init(SSL_AEAD_CTX **aead_ctx)
322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
323219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (*aead_ctx != NULL)
324219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_AEAD_CTX_cleanup(&(*aead_ctx)->ctx);
325219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
326219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
327219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		*aead_ctx = (SSL_AEAD_CTX*) OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
328219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (*aead_ctx == NULL)
329219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
330219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			SSLerr(SSL_F_TLS1_AEAD_CTX_INIT, ERR_R_MALLOC_FAILURE);
331219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
332219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
333219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
335219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 1;
336219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	}
337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
338219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgstatic int tls1_change_cipher_state_aead(SSL *s, char is_read,
339219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *key, unsigned key_len,
340219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *iv, unsigned iv_len)
341c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
342219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_AEAD *aead = s->s3->tmp.new_aead;
343219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	SSL_AEAD_CTX *aead_ctx;
344219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
345219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_read)
346219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
347219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!tls1_aead_ctx_init(&s->aead_read_ctx))
348219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
349219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		aead_ctx = s->aead_read_ctx;
350219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
351219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
352219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
353219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!tls1_aead_ctx_init(&s->aead_write_ctx))
354219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
355219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		aead_ctx = s->aead_write_ctx;
356219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
358219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len,
359219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			       EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */))
360219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		return 0;
361219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (iv_len > sizeof(aead_ctx->fixed_nonce))
362219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
363219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, ERR_R_INTERNAL_ERROR);
364219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		return 0;
365219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
366219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	memcpy(aead_ctx->fixed_nonce, iv, iv_len);
367219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	aead_ctx->fixed_nonce_len = iv_len;
368219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	aead_ctx->variable_nonce_len = 8;  /* always the case, currently. */
369219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	aead_ctx->variable_nonce_included_in_record =
370219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		(s->s3->tmp.new_cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
371219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead))
372219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
373219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_AEAD, ERR_R_INTERNAL_ERROR);
374219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		return 0;
375219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
376219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	aead_ctx->tag_len = EVP_AEAD_max_overhead(aead);
377219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
378219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 1;
379219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	}
380219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
381219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org/* tls1_change_cipher_state_cipher performs the work needed to switch cipher
382219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * states when using EVP_CIPHER. The argument |is_read| is true iff this
383219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * function is being called due to reading, as opposed to writing, a
384219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * ChangeCipherSpec message. In order to support export ciphersuites,
385219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * use_client_keys indicates whether the key material provided is in the
386219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org * "client write" direction. */
387219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgstatic int tls1_change_cipher_state_cipher(
388219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	SSL *s, char is_read, char use_client_keys,
389219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *mac_secret, unsigned mac_secret_len,
390219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *key, unsigned key_len,
391219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *iv, unsigned iv_len)
392219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	{
393219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
394219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0;
395219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	EVP_CIPHER_CTX *cipher_ctx;
396219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	EVP_MD_CTX *mac_ctx;
397219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	char is_aead_cipher;
398219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
399219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned char export_tmp1[EVP_MAX_KEY_LENGTH];
400219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned char export_tmp2[EVP_MAX_KEY_LENGTH];
401219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned char export_iv1[EVP_MAX_IV_LENGTH * 2];
402219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned char export_iv2[EVP_MAX_IV_LENGTH * 2];
403219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
404219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_read)
405c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
406480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
407480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
4082c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		else
409480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
410480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
411c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->enc_read_ctx != NULL)
412219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
413c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
414c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			goto err;
415c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
416c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* make sure it's intialized in case we exit later with an error */
417c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			EVP_CIPHER_CTX_init(s->enc_read_ctx);
418219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
419219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		cipher_ctx = s->enc_read_ctx;
420219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		mac_ctx = ssl_replace_hash(&s->read_hash, NULL);
421219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
422219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		memcpy(s->s3->read_mac_secret, mac_secret, mac_secret_len);
423219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		s->s3->read_mac_secret_size = mac_secret_len;
424219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
425219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
426219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
427219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
428219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
429219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
430219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
431219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
432219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (s->enc_write_ctx != NULL)
433219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
434219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
435219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			goto err;
436219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
437219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			/* make sure it's intialized in case we exit later with an error */
438219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			EVP_CIPHER_CTX_init(s->enc_write_ctx);
439219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
440219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		cipher_ctx = s->enc_write_ctx;
441219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		mac_ctx = ssl_replace_hash(&s->write_hash, NULL);
442219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
443219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		memcpy(s->s3->write_mac_secret, mac_secret, mac_secret_len);
444219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		s->s3->write_mac_secret_size = mac_secret_len;
445219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
446219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
447219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_export)
448219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
449219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		/* In here I set both the read and write key/iv to the
450219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		 * same value since only the correct one will be used :-).
451219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		 */
452219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		const unsigned char *label;
453219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		unsigned label_len;
454219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
455219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (use_client_keys)
456219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
457219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			label = (const unsigned char*) TLS_MD_CLIENT_WRITE_KEY_CONST;
458219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
459219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
460219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
461219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
462219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			label = (const unsigned char*) TLS_MD_SERVER_WRITE_KEY_CONST;
463219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
464219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
465219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
466219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!tls1_PRF(ssl_get_algorithm2(s),
467219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				label, label_len,
468219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				s->s3->client_random, SSL3_RANDOM_SIZE,
469219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				s->s3->server_random, SSL3_RANDOM_SIZE,
470219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				NULL, 0, NULL, 0,
471219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				key /* secret */, key_len /* secret length */,
472219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				export_tmp1 /* output */,
473219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				export_tmp2 /* scratch space */,
474219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				EVP_CIPHER_key_length(s->s3->tmp.new_sym_enc) /* output length */))
475219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
476219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key = export_tmp1;
477219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
478219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (iv_len > 0)
479219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
480219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			static const unsigned char empty[] = "";
481219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
482219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (!tls1_PRF(ssl_get_algorithm2(s),
483219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE,
484219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					s->s3->client_random, SSL3_RANDOM_SIZE,
485219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					s->s3->server_random, SSL3_RANDOM_SIZE,
486219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					NULL, 0, NULL, 0,
487219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					empty /* secret */ ,0 /* secret length */,
488219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					export_iv1 /* output */,
489219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					export_iv2 /* scratch space */,
490219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					iv_len * 2 /* output length */))
491219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return 0;
492219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
493219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (use_client_keys)
494219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				iv = export_iv1;
495219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			else
496219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				iv = &export_iv1[iv_len];
497219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
498219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
499219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
500219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* is_aead_cipher indicates whether the EVP_CIPHER implements an AEAD
501219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	 * interface. This is different from the newer EVP_AEAD interface. */
502219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	is_aead_cipher = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0;
503219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
504219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (!is_aead_cipher)
505219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
506219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_PKEY *mac_key =
507219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type,
508219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					     NULL, mac_secret, mac_secret_len);
509219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!mac_key)
510219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
511219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key);
512219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_PKEY_free(mac_key);
513219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
514219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
515219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
516219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
517219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key,
518219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				  NULL /* iv */, !is_read);
519219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, iv_len, (void*) iv);
520219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
521219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
522219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, !is_read);
523219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
524219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
525219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_aead_cipher && mac_secret_len > 0)
526219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY,
527219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				    mac_secret_len, (void*) mac_secret);
528219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
529219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_export)
530219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
531219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		OPENSSL_cleanse(export_tmp1, sizeof(export_tmp1));
532219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		OPENSSL_cleanse(export_tmp2, sizeof(export_tmp1));
533219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		OPENSSL_cleanse(export_iv1, sizeof(export_iv1));
534219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		OPENSSL_cleanse(export_iv2, sizeof(export_iv2));
535219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
536219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
537219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 1;
538219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
539219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgerr:
540219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE_CIPHER, ERR_R_MALLOC_FAILURE);
541219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 0;
542219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	}
543219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
544219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgint tls1_change_cipher_state(SSL *s, int which)
545219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	{
546219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* is_read is true if we have just read a ChangeCipherSpec message -
547219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	 * i.e. we need to update the read cipherspec. Otherwise we have just
548219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	 * written one. */
549219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const char is_read = (which & SSL3_CC_READ) != 0;
550219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* use_client_keys is true if we wish to use the keys for the "client
551219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	 * write" direction. This is the case if we're a client sending a
552219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	 * ChangeCipherSpec, or a server reading a client's ChangeCipherSpec. */
553219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const char use_client_keys = which == SSL3_CHANGE_CIPHER_CLIENT_WRITE ||
554219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				     which == SSL3_CHANGE_CIPHER_SERVER_READ;
555219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *client_write_mac_secret, *server_write_mac_secret, *mac_secret;
556219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *client_write_key, *server_write_key, *key;
557219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *client_write_iv, *server_write_iv, *iv;
558219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_CIPHER *cipher = s->s3->tmp.new_sym_enc;
559219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_AEAD *aead = s->s3->tmp.new_aead;
560219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned key_len, iv_len, mac_secret_len;
561219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const unsigned char *key_data;
562219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0;
563219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
564219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* Update compression contexts. */
565c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_COMP
566219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const SSL_COMP *comp = s->s3->tmp.new_compression;
567219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
568219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (is_read)
569219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
570c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->expand != NULL)
571c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
572c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			COMP_CTX_free(s->expand);
573219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s->expand = NULL;
574c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
575c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (comp != NULL)
576c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
577c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			s->expand=COMP_CTX_new(comp->method);
578c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (s->expand == NULL)
579c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
580c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
581219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return 0;
582c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
583c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (s->s3->rrec.comp == NULL)
584219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				s->s3->rrec.comp =
585219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					(unsigned char *)OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
586c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (s->s3->rrec.comp == NULL)
587c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				goto err;
588c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
589c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
590c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
591c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
592c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->compress != NULL)
593c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
594c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			COMP_CTX_free(s->compress);
595219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s->compress = NULL;
596c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
597c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (comp != NULL)
598c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
599219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s->compress = COMP_CTX_new(comp->method);
600c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (s->compress == NULL)
601c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
602c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
603219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return 0;
604c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
605c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
606c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
607219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org#endif  /* OPENSSL_NO_COMP */
608c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
609219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* Reset sequence number to zero. */
610219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	memset(is_read ? s->s3->read_sequence : s->s3->write_sequence, 0, 8);
611c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
612219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	/* key_arg is used for SSLv2. We don't need it for TLS. */
613219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	s->session->key_arg_length = 0;
614480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
615219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	mac_secret_len = s->s3->tmp.new_mac_secret_size;
616219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
617219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (aead != NULL)
618c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
619219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key_len = EVP_AEAD_key_length(aead);
620219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->s3->tmp.new_cipher);
621c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
622c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
623c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
624219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key_len = EVP_CIPHER_key_length(cipher);
625219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (is_export && key_len > SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher))
626219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			key_len = SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher);
627c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
628219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE)
629219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
630219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
631219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			iv_len = EVP_CIPHER_iv_length(cipher);
632c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
633c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
634219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	key_data = s->s3->tmp.key_block;
635219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	client_write_mac_secret = key_data; key_data += mac_secret_len;
636219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	server_write_mac_secret = key_data; key_data += mac_secret_len;
637219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	client_write_key =        key_data; key_data += key_len;
638219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	server_write_key =        key_data; key_data += key_len;
639219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	client_write_iv  =        key_data; key_data += iv_len;
640219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	server_write_iv  =        key_data; key_data += iv_len;
6412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
642219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (use_client_keys)
6432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		{
644219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		mac_secret = client_write_mac_secret;
645219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key = client_write_key;
646219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		iv = client_write_iv;
6472c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		}
648219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
649c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
650219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		mac_secret = server_write_mac_secret;
651219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key = server_write_key;
652219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		iv = server_write_iv;
653c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
654c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
655219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length)
6562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		{
657219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
658219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		return 0;
6592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		}
6602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
661219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (aead != NULL)
662219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
663219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!tls1_change_cipher_state_aead(s, is_read,
664219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org						   key, key_len, iv, iv_len))
665219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
666219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
667219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
668219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
669219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!tls1_change_cipher_state_cipher(s, is_read, use_client_keys,
670219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org						     mac_secret, mac_secret_len,
671219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org						     key, key_len,
672219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org						     iv, iv_len))
673219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return 0;
674219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
675c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
676219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 1;
677c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr:
678219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
679219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 0;
680c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
681c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
682c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint tls1_setup_key_block(SSL *s)
683c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
684480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned char *p1,*p2=NULL;
685219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_CIPHER *c = NULL;
686219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_MD *hash = NULL;
687219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const EVP_AEAD *aead = NULL;
688c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int num;
689c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	SSL_COMP *comp;
690480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int mac_type= NID_undef,mac_secret_size=0;
691480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int ret=0;
692219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	unsigned key_len, iv_len;
693c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
694c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
695c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	printf ("tls1_setup_key_block()\n");
696c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif	/* KSSL_DEBUG */
697c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
698c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (s->s3->tmp.key_block_length != 0)
699c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		return(1);
700c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
701219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (!ssl_cipher_get_comp(s->session, &comp))
702219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		goto cipher_unavailable_err;
703219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
704219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (s->session->cipher &&
705219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	    (s->session->cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_AEAD))
706c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
707219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!ssl_cipher_get_evp_aead(s->session, &aead))
708219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			goto cipher_unavailable_err;
709219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key_len = EVP_AEAD_key_length(aead);
710219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		iv_len = SSL_CIPHER_AEAD_FIXED_NONCE_LEN(s->session->cipher);
711219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
712219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
713219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
714219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size))
715219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			goto cipher_unavailable_err;
716219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		key_len = EVP_CIPHER_key_length(c);
717219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
718219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
719219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			iv_len = EVP_GCM_TLS_FIXED_IV_LEN;
720219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
721219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			iv_len = EVP_CIPHER_iv_length(c);
722c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
723c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
724219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	s->s3->tmp.new_aead=aead;
725c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	s->s3->tmp.new_sym_enc=c;
726c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	s->s3->tmp.new_hash=hash;
727480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	s->s3->tmp.new_mac_pkey_type = mac_type;
728480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	s->s3->tmp.new_mac_secret_size = mac_secret_size;
729219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
730219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	num=key_len+mac_secret_size+iv_len;
731c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	num*=2;
732c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
733c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	ssl3_cleanup_key_block(s);
734c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
735c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
736480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
737480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
738c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		goto err;
739480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
740c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
741c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	s->s3->tmp.key_block_length=num;
742c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	s->s3->tmp.key_block=p1;
743c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
744480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
745480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
746480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
747480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
748480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
749c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
750c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef TLS_DEBUG
751c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("client random\n");
752c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); }
753c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("server random\n");
754c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); }
755c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("pre-master\n");
756c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
757c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
758480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!tls1_generate_key_block(s,p1,p2,num))
759480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		goto err;
760c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef TLS_DEBUG
761c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("\nkey block\n");
762c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
763c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
764c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
7652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
7662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		&& s->method->version <= TLS1_VERSION)
767c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
768c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		/* enable vulnerability countermeasure for CBC ciphers with
769c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
770c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		 */
771c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		s->s3->need_empty_fragments = 1;
772c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
773c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->session->cipher != NULL)
774c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
775480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (s->session->cipher->algorithm_enc == SSL_eNULL)
776c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				s->s3->need_empty_fragments = 0;
777c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
778c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifndef OPENSSL_NO_RC4
779480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (s->session->cipher->algorithm_enc == SSL_RC4)
780c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				s->s3->need_empty_fragments = 0;
781c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
782c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
783c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
784c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
785480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	ret = 1;
786c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgerr:
787480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (p2)
788480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
789480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		OPENSSL_cleanse(p2,num);
790480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		OPENSSL_free(p2);
791480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
792480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	return(ret);
793219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
794219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.orgcipher_unavailable_err:
795219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
796219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	return 0;
797c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
798c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
7997453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org/* tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively.
8007453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *
8017453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org * Returns:
8027453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *   0: (in non-constant time) if the record is publically invalid (i.e. too
8037453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *       short etc).
8047453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *   1: if the record's padding is valid / the encryption was successful.
8057453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *   -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
8067453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org *       an internal error occured.
8077453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org */
808c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint tls1_enc(SSL *s, int send)
809c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
810c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	SSL3_RECORD *rec;
811c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_CIPHER_CTX *ds;
812c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned long l;
8137453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	int bs,i,j,k,pad=0,ret,mac_size=0;
814c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	const EVP_CIPHER *enc;
815219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	const SSL_AEAD_CTX *aead;
816219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
817219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (send)
818219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		rec = &s->s3->wrec;
819219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
820219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		rec = &s->s3->rrec;
821219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
822219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (send)
823219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		aead = s->aead_write_ctx;
824219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	else
825219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		aead = s->aead_read_ctx;
826219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
827219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org	if (aead)
828219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		{
829219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		unsigned char ad[13], *seq, *in, *out, nonce[16];
830219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		unsigned nonce_used;
831219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		ssize_t n;
832219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
833219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		seq = send ? s->s3->write_sequence : s->s3->read_sequence;
834219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
835219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
836219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
837219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			unsigned char dtlsseq[9], *p = dtlsseq;
838219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
839219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p);
840219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			memcpy(p, &seq[2], 6);
841219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			memcpy(ad, dtlsseq, 8);
842219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
843219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
844219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
845219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			memcpy(ad, seq, 8);
846219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			for (i=7; i>=0; i--)	/* increment */
847219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				{
848219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				++seq[i];
849219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				if (seq[i] != 0)
850219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					break;
851219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				}
852219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
853219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
854219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		ad[8]  = rec->type;
855219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		ad[9]  = (unsigned char)(s->version>>8);
856219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		ad[10] = (unsigned char)(s->version);
857219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
858219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (aead->fixed_nonce_len + aead->variable_nonce_len > sizeof(nonce) ||
859219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		    aead->variable_nonce_len > 8)
860219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return -1;  /* internal error - should never happen. */
861219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
862219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
863219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		nonce_used = aead->fixed_nonce_len;
864219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
865219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (send)
866219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
867219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			size_t len = rec->length;
868219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			size_t eivlen = 0;
869219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			in = rec->input;
870219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			out = rec->data;
871219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
872219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			/* When sending we use the sequence number as the
873219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			 * variable part of the nonce. */
874219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (aead->variable_nonce_len > 8)
875219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return -1;
876219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			memcpy(nonce + nonce_used, ad, aead->variable_nonce_len);
877219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			nonce_used += aead->variable_nonce_len;
878219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
879219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			/* in do_ssl3_write, rec->input is moved forward by
880219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			 * variable_nonce_len in order to leave space for the
881219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			 * variable nonce. Thus we can copy the sequence number
882219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			 * bytes into place without overwriting any of the
883219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			 * plaintext. */
884219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (aead->variable_nonce_included_in_record)
885219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				{
886219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				memcpy(out, ad, aead->variable_nonce_len);
887219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				len -= aead->variable_nonce_len;
888219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				eivlen = aead->variable_nonce_len;
889219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				}
890219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
891219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			ad[11] = len >> 8;
892219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			ad[12] = len & 0xff;
893219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
894219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			n = EVP_AEAD_CTX_seal(&aead->ctx,
895219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					      out + eivlen, len + aead->tag_len,
896219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					      nonce, nonce_used,
897219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					      in + eivlen, len,
898219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					      ad, sizeof(ad));
899219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (n >= 0 && aead->variable_nonce_included_in_record)
900219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				n += aead->variable_nonce_len;
901219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
902219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		else
903219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			{
904219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			/* receive */
905219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			size_t len = rec->length;
906219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
907219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (rec->data != rec->input)
908219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return -1;  /* internal error - should never happen. */
909219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			out = in = rec->input;
910219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
911219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (len < aead->variable_nonce_len)
912219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return 0;
913219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			memcpy(nonce + nonce_used,
914219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			       aead->variable_nonce_included_in_record ? in : ad,
915219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			       aead->variable_nonce_len);
916219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			nonce_used += aead->variable_nonce_len;
917219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
918219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (aead->variable_nonce_included_in_record)
919219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				{
920219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				in += aead->variable_nonce_len;
921219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				len -= aead->variable_nonce_len;
922219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				out += aead->variable_nonce_len;
923219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				}
924219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
925219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			if (len < aead->tag_len)
926219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org				return 0;
927219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			len -= aead->tag_len;
928219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
929219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			ad[11] = len >> 8;
930219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			ad[12] = len & 0xff;
931219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
932219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			n = EVP_AEAD_CTX_open(&aead->ctx, out, len, nonce, nonce_used,
933219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org					      in, len + aead->tag_len, ad, sizeof(ad));
934219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
935219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			rec->data = rec->input = out;
936219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			}
937219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org
938219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		if (n == -1)
939219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org			return -1;
940219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		rec->length = n;
941219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		return 1;
942219af2cde3d824e82b72b3efc070f3a14fbe3c10agl@chromium.org		}
943c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
944c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (send)
945c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
946480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (EVP_MD_CTX_md(s->write_hash))
947480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
9482c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			int n=EVP_MD_CTX_size(s->write_hash);
949480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			OPENSSL_assert(n >= 0);
950480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
951c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ds=s->enc_write_ctx;
952c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		rec= &(s->s3->wrec);
953c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->enc_write_ctx == NULL)
954c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			enc=NULL;
955c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
9562c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			{
9572c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			int ivlen;
958c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
9592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			/* For TLSv1.1 and later explicit IV */
9602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (s->version >= TLS1_1_VERSION
9612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				&& EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
9622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				ivlen = EVP_CIPHER_iv_length(enc);
9632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			else
9642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				ivlen = 0;
9652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (ivlen > 1)
9662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				{
9672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				if ( rec->data != rec->input)
9682c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					/* we can't write into the input stream:
9692c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					 * Can this ever happen?? (steve)
9702c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					 */
9712c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					fprintf(stderr,
9722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org						"%s:%d: rec->data != rec->input\n",
9732c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org						__FILE__, __LINE__);
9742c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				else if (RAND_bytes(rec->input, ivlen) <= 0)
9752c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					return -1;
9762c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				}
9772c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			}
978c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
979c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
980c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
981480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (EVP_MD_CTX_md(s->read_hash))
982480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
9832c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			int n=EVP_MD_CTX_size(s->read_hash);
984480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			OPENSSL_assert(n >= 0);
985480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
986c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		ds=s->enc_read_ctx;
987c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		rec= &(s->s3->rrec);
988c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (s->enc_read_ctx == NULL)
989c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			enc=NULL;
990c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		else
991c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
992c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
993c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
994c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
995c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	printf("tls1_enc(%d)\n", send);
996c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif    /* KSSL_DEBUG */
997c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
9987453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	if ((s->session == NULL) || (ds == NULL) || (enc == NULL))
999c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1000c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		memmove(rec->data,rec->input,rec->length);
1001c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		rec->input=rec->data;
10027453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		ret = 1;
1003c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1004c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1005c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1006c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		l=rec->length;
1007c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		bs=EVP_CIPHER_block_size(ds->cipher);
1008c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
10092c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
10102c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			{
10112c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			unsigned char buf[13],*seq;
10122c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
10132c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			seq = send?s->s3->write_sequence:s->s3->read_sequence;
10142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
10152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
10162c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				{
10172c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				unsigned char dtlsseq[9],*p=dtlsseq;
10182c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
10192c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				s2n(send?s->d1->w_epoch:s->d1->r_epoch,p);
10202c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				memcpy(p,&seq[2],6);
10212c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				memcpy(buf,dtlsseq,8);
10222c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				}
10232c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			else
10242c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				{
10252c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				memcpy(buf,seq,8);
10262c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				for (i=7; i>=0; i--)	/* increment */
10272c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					{
10282c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					++seq[i];
10292c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					if (seq[i] != 0) break;
10302c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org					}
10312c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				}
10322c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
10332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			buf[8]=rec->type;
10342c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			buf[9]=(unsigned char)(s->version>>8);
10352c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			buf[10]=(unsigned char)(s->version);
10362c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			buf[11]=rec->length>>8;
10372c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			buf[12]=rec->length&0xff;
10382c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf);
10392c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			if (send)
10402c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				{
10412c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				l+=pad;
10422c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				rec->length+=pad;
10432c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org				}
10442c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			}
10452c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		else if ((bs != 1) && send)
1046c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1047c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			i=bs-((int)l%bs);
1048c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1049c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* Add weird padding of upto 256 bytes */
1050c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1051c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			/* we need to add 'i' padding bytes of value j */
1052c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			j=i-1;
1053c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
1054c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
1055c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
1056c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					j++;
1057c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
1058c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			for (k=(int)l; k<(int)(l+i); k++)
1059c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				rec->input[k]=j;
1060c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			l+=i;
1061c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			rec->length+=i;
1062c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1063c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1064c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
1065c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
10667453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		unsigned long ui;
1067c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
10687453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ds,rec->data,rec->input,l);
1069480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
10707453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ds->buf_len, ds->cipher->key_len,
10717453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			DES_KEY_SZ, DES_SCHEDULE_SZ,
10727453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ds->cipher->iv_len);
1073c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		printf("\t\tIV: ");
1074c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
1075c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		printf("\n");
1076c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		printf("\trec->input=");
1077c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
1078c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		printf("\n");
1079c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1080c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif	/* KSSL_DEBUG */
1081c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1082c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if (!send)
1083c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1084c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (l == 0 || l%bs != 0)
1085c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				return 0;
1086c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1087c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
10882c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		i = EVP_Cipher(ds,rec->data,rec->input,l);
10892c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if ((EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_CUSTOM_CIPHER)
10902c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org						?(i<0)
10912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org						:(i==0))
10922c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			return -1;	/* AEAD can fail to verify MAC */
10932c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
10942c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			{
10952c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
10962c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
10972c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
10982c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			}
1099c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
1101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
11027453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		unsigned long i;
11037453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		printf("\trec->data=");
1104480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		for (i=0; i<l; i++)
11057453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			printf(" %02x", rec->data[i]);  printf("\n");
11067453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		}
1107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif	/* KSSL_DEBUG */
1108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
11097453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		ret = 1;
11107453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		if (EVP_MD_CTX_md(s->read_hash) != NULL)
11117453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			mac_size = EVP_MD_CTX_size(s->read_hash);
1112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		if ((bs != 1) && !send)
11137453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ret = tls1_cbc_remove_padding(s, rec, bs, mac_size);
11142c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (pad && !send)
11152c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org			rec->length -= pad;
1116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
11177453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	return ret;
1118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
11197453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org
1120480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
1121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned int ret;
1123480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_MD_CTX ctx, *d=NULL;
1124480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int i;
1125480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1126480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (s->s3->handshake_buffer)
1127480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ssl3_digest_cached_records(s))
1128480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1129480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1130480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (i=0;i<SSL_MAX_DIGEST;i++)
1131480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1132480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid)
1133480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		  	{
1134480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		  	d=s->s3->handshake_dgst[i];
1135480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			break;
1136480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1137480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1138480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (!d) {
1139480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST);
1140480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1141480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	}
1142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_MD_CTX_init(&ctx);
1144480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_MD_CTX_copy_ex(&ctx,d);
1145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_DigestFinal_ex(&ctx,out,&ret);
1146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_MD_CTX_cleanup(&ctx);
1147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return((int)ret);
1148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1150480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgint tls1_final_finish_mac(SSL *s,
1151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     const char *str, int slen, unsigned char *out)
1152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned int i;
1154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_MD_CTX ctx;
1155480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned char buf[2*EVP_MAX_MD_SIZE];
1156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned char *q,buf2[12];
1157480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int idx;
1158480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	long mask;
1159480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int err=0;
1160480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const EVP_MD *md;
1161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	q=buf;
1163480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1164480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (s->s3->handshake_buffer)
1165480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		if (!ssl3_digest_cached_records(s))
1166480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			return 0;
1167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_MD_CTX_init(&ctx);
1169480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1170480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
1171480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
11722c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org		if (mask & ssl_get_algorithm2(s))
1173480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			{
1174480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			int hashsize = EVP_MD_size(md);
1175480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
1176480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1177480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				/* internal error: 'buf' is too small for this cipersuite! */
1178480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				err = 1;
1179480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1180480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			else
1181480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				{
1182480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
1183480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				EVP_DigestFinal_ex(&ctx,q,&i);
1184480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				if (i != (unsigned int)hashsize) /* can't really happen */
1185480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org					err = 1;
1186480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				q+=i;
1187480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org				}
1188480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			}
1189480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1190480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
11912c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	if (!tls1_PRF(ssl_get_algorithm2(s),
1192480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
1193480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			s->session->master_key,s->session->master_key_length,
1194480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			out,buf2,sizeof buf2))
1195480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		err = 1;
1196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	EVP_MD_CTX_cleanup(&ctx);
1197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1198480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (err)
1199480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return 0;
1200480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	else
1201480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		return sizeof buf2;
1202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint tls1_mac(SSL *ssl, unsigned char *md, int send)
1205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	SSL3_RECORD *rec;
1207480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	unsigned char *seq;
1208480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_MD_CTX *hash;
12097453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	size_t md_size, orig_len;
1210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	int i;
1211480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	EVP_MD_CTX hmac, *mac_ctx;
12127453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	unsigned char header[13];
1213480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
1214480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int t;
1215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if (send)
1217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		rec= &(ssl->s3->wrec);
1219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		seq= &(ssl->s3->write_sequence[0]);
1220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		hash=ssl->write_hash;
1221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
1223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		rec= &(ssl->s3->rrec);
1225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		seq= &(ssl->s3->read_sequence[0]);
1226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		hash=ssl->read_hash;
1227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1229480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	t=EVP_MD_CTX_size(hash);
1230480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	OPENSSL_assert(t >= 0);
1231480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	md_size=t;
1232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
1234480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (stream_mac)
1235480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1236480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			mac_ctx = hash;
1237480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1238480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		else
1239480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1240480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			EVP_MD_CTX_copy(&hmac,hash);
1241480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org			mac_ctx = &hmac;
1242480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1244480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
1245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		unsigned char dtlsseq[8],*p=dtlsseq;
1247480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
1249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		memcpy (p,&seq[2],6);
1250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
12517453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		memcpy(header, dtlsseq, 8);
1252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
12547453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		memcpy(header, seq, 8);
1255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
12567453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	/* kludge: tls1_cbc_remove_padding passes padding length in rec->type */
12577453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	orig_len = rec->length+md_size+((unsigned int)rec->type>>8);
12587453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	rec->type &= 0xff;
12597453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org
12607453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	header[8]=rec->type;
12617453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	header[9]=(unsigned char)(ssl->version>>8);
12627453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	header[10]=(unsigned char)(ssl->version);
12637453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	header[11]=(rec->length)>>8;
12647453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	header[12]=(rec->length)&0xff;
12657453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org
12667453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	if (!send &&
12677453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	    EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
12687453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	    ssl3_cbc_record_digest_supported(mac_ctx))
12697453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		{
12707453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		/* This is a CBC-encrypted record. We must avoid leaking any
12717453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		 * timing-side channel information about how many blocks of
12727453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		 * data we are hashing because that gives an attacker a
12737453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		 * timing-oracle. */
12747453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		ssl3_cbc_digest_record(
12757453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			mac_ctx,
12767453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			md, &md_size,
12777453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			header, rec->input,
12787453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			rec->length + md_size, orig_len,
12797453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ssl->s3->read_mac_secret,
12807453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			ssl->s3->read_mac_secret_size,
12817453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			0 /* not SSLv3 */);
12827453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		}
12837453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	else
12847453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		{
12857453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		EVP_DigestSignUpdate(mac_ctx,header,sizeof(header));
12867453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
12877453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
12887453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		OPENSSL_assert(t > 0);
12897453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#ifdef OPENSSL_FIPS
12907453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		if (!send && FIPS_mode())
12917453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org			tls_fips_digest_extra(
12927453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	    				ssl->enc_read_ctx,
12937453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org					mac_ctx, rec->input,
12947453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org					rec->length, orig_len);
12957453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org#endif
12967453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		}
1297480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
12987453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org	if (!stream_mac)
12997453c6c0666947e06d87565404f4397a4b387f91digit@chromium.org		EVP_MD_CTX_cleanup(&hmac);
1300c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef TLS_DEBUG
1301c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("sec=");
1302c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
1303c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("seq=");
1304c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
1305c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("buf=");
1306c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
1307c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgprintf("rec=");
1308c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
1309c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
1310c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1311480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
1312c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1313c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for (i=7; i>=0; i--)
1314c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
1315c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			++seq[i];
1316c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (seq[i] != 0) break;
1317c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
1318c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1319c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1320c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef TLS_DEBUG
1321c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
1322c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
1323c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return(md_size);
1324c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1325c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1326c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
1327c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	     int len)
1328c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1329c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
1330480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	const void *co = NULL, *so = NULL;
1331480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	int col = 0, sol = 0;
1332c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
13332c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org
1334c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
1335480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
1336c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif	/* KSSL_DEBUG */
1337c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
1338480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#ifdef TLSEXT_TYPE_opaque_prf_input
1339480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL &&
1340480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	    s->s3->client_opaque_prf_input_len > 0 &&
1341480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	    s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len)
1342480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		{
1343480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		co = s->s3->client_opaque_prf_input;
1344480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		col = s->s3->server_opaque_prf_input_len;
1345480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		so = s->s3->server_opaque_prf_input;
1346480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		sol = s->s3->client_opaque_prf_input_len; /* must be same as col (see draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) */
1347480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		}
1348480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#endif
1349480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
13502c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	tls1_PRF(ssl_get_algorithm2(s),
1351480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
1352480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		s->s3->client_random,SSL3_RANDOM_SIZE,
1353480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		co, col,
1354480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		s->s3->server_random,SSL3_RANDOM_SIZE,
1355480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		so, sol,
1356480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org		p,len,
1357c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		s->session->master_key,buff,sizeof buff);
13582c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#ifdef SSL_DEBUG
13592c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	fprintf(stderr, "Premaster Secret:\n");
13602c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	BIO_dump_fp(stderr, (char *)p, len);
13612c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	fprintf(stderr, "Client Random:\n");
13622c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
13632c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	fprintf(stderr, "Server Random:\n");
13642c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
13652c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	fprintf(stderr, "Master Secret:\n");
13662c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org	BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
13672c4508dfe2bc5b6296c01114ed11ddc64b7718c6digit@chromium.org#endif
1368480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org
1369c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#ifdef KSSL_DEBUG
1370c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	printf ("tls1_generate_master_secret() complete\n");
1371c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif	/* KSSL_DEBUG */
1372c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	return(SSL3_MASTER_SECRET_SIZE);
1373c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1374c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
13752e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.orgint tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
13762e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 const char *label, size_t llen, const unsigned char *context,
13772e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 size_t contextlen, int use_context)
13782e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	{
13792e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	unsigned char *buff;
13802e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	unsigned char *val = NULL;
13812e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	size_t vallen, currentvalpos;
13822e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	int rv;
13832e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
13842e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org#ifdef KSSL_DEBUG
13852e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
13862e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org#endif	/* KSSL_DEBUG */
13872e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
13882e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	buff = OPENSSL_malloc(olen);
13892e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (buff == NULL) goto err2;
13902e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
13912e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	/* construct PRF arguments
13922e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * we construct the PRF argument ourself rather than passing separate
13932e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * values into the TLS PRF to ensure that the concatenation of values
13942e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * does not create a prohibited label.
13952e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 */
13962e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	vallen = llen + SSL3_RANDOM_SIZE * 2;
13972e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (use_context)
13982e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		{
13992e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		vallen += 2 + contextlen;
14002e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		}
14012e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
14022e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	val = OPENSSL_malloc(vallen);
14032e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (val == NULL) goto err2;
14042e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	currentvalpos = 0;
14052e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	memcpy(val + currentvalpos, (unsigned char *) label, llen);
14062e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	currentvalpos += llen;
14072e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
14082e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	currentvalpos += SSL3_RANDOM_SIZE;
14092e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
14102e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	currentvalpos += SSL3_RANDOM_SIZE;
14112e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
14122e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (use_context)
14132e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		{
14142e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		val[currentvalpos] = (contextlen >> 8) & 0xff;
14152e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		currentvalpos++;
14162e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		val[currentvalpos] = contextlen & 0xff;
14172e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		currentvalpos++;
14182e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		if ((contextlen > 0) || (context != NULL))
14192e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org			{
14202e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org			memcpy(val + currentvalpos, context, contextlen);
14212e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org			}
14222e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		}
14232e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
14242e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	/* disallow prohibited labels
14252e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
14262e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * 15, so size of val > max(prohibited label len) = 15 and the
14272e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 * comparisons won't have buffer overflow
14282e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	 */
14292e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
14302e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
14312e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
14322e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
14332e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
14342e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
14352e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
14362e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
14372e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
14382e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
14392e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      val, vallen,
14402e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      NULL, 0,
14412e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      NULL, 0,
14422e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      NULL, 0,
14432e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      NULL, 0,
14442e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      s->session->master_key,s->session->master_key_length,
14452e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org		      out,buff,olen);
14462e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
14472e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org#ifdef KSSL_DEBUG
14482e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	printf ("tls1_export_keying_material() complete\n");
14492e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org#endif	/* KSSL_DEBUG */
14502e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	goto ret;
14512e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.orgerr1:
14522e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
14532e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	rv = 0;
14542e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	goto ret;
14552e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.orgerr2:
14562e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
14572e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	rv = 0;
14582e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.orgret:
14592e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (buff != NULL) OPENSSL_free(buff);
14602e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	if (val != NULL) OPENSSL_free(val);
14612e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	return(rv);
14622e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org	}
14632e9fc9b0d30b32a0a70e52eabf801668028d796fhclam@chromium.org
1464c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgint tls1_alert_code(int code)
1465c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
1466c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	switch (code)
1467c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
1468c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
1469c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
1470c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
1471c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
1472c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
1473c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
1474c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
1475c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_NO_CERTIFICATE:	return(-1);
1476c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
1477c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
1478c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
1479c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
1480c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
1481c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
1482c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_UNKNOWN_CA:		return(TLS1_AD_UNKNOWN_CA);
1483c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_ACCESS_DENIED:	return(TLS1_AD_ACCESS_DENIED);
1484c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_DECODE_ERROR:	return(TLS1_AD_DECODE_ERROR);
1485c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_DECRYPT_ERROR:	return(TLS1_AD_DECRYPT_ERROR);
1486c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_EXPORT_RESTRICTION:	return(TLS1_AD_EXPORT_RESTRICTION);
1487c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_PROTOCOL_VERSION:	return(TLS1_AD_PROTOCOL_VERSION);
1488c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY);
1489c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
1490c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_USER_CANCELLED:	return(TLS1_AD_USER_CANCELLED);
1491c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
1492480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
1493480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
1494480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_UNRECOGNIZED_NAME:	return(TLS1_AD_UNRECOGNIZED_NAME);
1495480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
1496480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
1497480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
1498480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org#if 0 /* not appropriate for TLS, not used for DTLS */
1499c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
1500c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
1501c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#endif
1502c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	default:			return(-1);
1503c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
1504c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
1505