1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ssl/t1_enc.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    openssl-core@openssl.org.
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* ====================================================================
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Copyright 2005 Nokia. All rights reserved.
113221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
114221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * The portions of the attached software ("Contribution") is developed by
115221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Nokia Corporation and is licensed pursuant to the OpenSSL open source
116221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * license.
117221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
118221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * The Contribution, originally written by Mika Kousa and Pasi Eronen of
119221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * support (see RFC 4279) to OpenSSL.
121221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * No patent licenses or other rights except those expressly stated in
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * the OpenSSL open source license shall be deemed granted or received
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * expressly, by implication, estoppel, or otherwise.
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * No assurances are provided by Nokia that the Contribution does not
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * infringe the patent or other intellectual property rights of any third
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * party or that the license provides you with all the necessary rights
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * to make use of the Contribution.
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom *
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom * OTHERWISE.
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom */
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "ssl_locl.h"
140e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#ifndef OPENSSL_NO_COMP
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/comp.h>
142e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/evp.h>
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/hmac.h>
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/md5.h>
146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/rand.h>
147e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#ifdef KSSL_DEBUG
148e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#include <openssl/des.h>
149e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* seed1 through seed5 are virtually concatenated */
1523d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstromstatic int tls1_P_hash(const EVP_MD *md, const unsigned char *sec,
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int sec_len,
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const void *seed1, int seed1_len,
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const void *seed2, int seed2_len,
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const void *seed3, int seed3_len,
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const void *seed4, int seed4_len,
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			const void *seed5, int seed5_len,
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			unsigned char *out, int olen)
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
16143c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom	int chunk;
162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t j;
163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX ctx, ctx_tmp;
164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_PKEY *mac_key;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char A1[EVP_MAX_MD_SIZE];
166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t A1_len;
1673d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	int ret = 0;
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	chunk=EVP_MD_size(md);
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_assert(chunk >= 0);
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_init(&ctx);
173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_init(&ctx_tmp);
174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len);
177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!mac_key)
178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		goto err;
179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
1803d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
1823d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
1843d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
1863d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
1883d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
1903d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
1923d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
1943d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	for (;;)
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		/* Reinit mac contexts */
199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!EVP_DigestSignInit(&ctx,NULL,md, NULL, mac_key))
2003d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!EVP_DigestSignInit(&ctx_tmp,NULL,md, NULL, mac_key))
2023d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!EVP_DigestSignUpdate(&ctx,A1,A1_len))
2043d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!EVP_DigestSignUpdate(&ctx_tmp,A1,A1_len))
2063d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (seed1 && !EVP_DigestSignUpdate(&ctx,seed1,seed1_len))
2083d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (seed2 && !EVP_DigestSignUpdate(&ctx,seed2,seed2_len))
2103d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (seed3 && !EVP_DigestSignUpdate(&ctx,seed3,seed3_len))
2123d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (seed4 && !EVP_DigestSignUpdate(&ctx,seed4,seed4_len))
2143d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (seed5 && !EVP_DigestSignUpdate(&ctx,seed5,seed5_len))
2163d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (olen > chunk)
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!EVP_DigestSignFinal(&ctx,out,&j))
2213d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			out+=j;
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			olen-=j;
224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* calc the next A1 value */
225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!EVP_DigestSignFinal(&ctx_tmp,A1,&A1_len))
2263d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else	/* last one */
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!EVP_DigestSignFinal(&ctx,A1,&A1_len))
2313d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memcpy(out,A1,olen);
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			break;
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
2363d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	ret = 1;
2373d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstromerr:
238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_PKEY_free(mac_key);
239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_cleanup(&ctx);
240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	EVP_MD_CTX_cleanup(&ctx_tmp);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(A1,sizeof(A1));
2423d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	return ret;
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* seed1 through seed5 are virtually concatenated */
2463d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstromstatic int tls1_PRF(long digest_mask,
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const void *seed1, int seed1_len,
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const void *seed2, int seed2_len,
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const void *seed3, int seed3_len,
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const void *seed4, int seed4_len,
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const void *seed5, int seed5_len,
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     const unsigned char *sec, int slen,
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		     unsigned char *out1,
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		     unsigned char *out2, int olen)
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int len,i,idx,count;
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const unsigned char *S1;
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long m;
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_MD *md;
2603d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	int ret = 0;
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	/* Count number of digests and partition sec evenly */
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	count=0;
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) count++;
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	len=slen/count;
268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (count == 1)
269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		slen = 0;
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	S1=sec;
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	memset(out1,0,olen);
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (idx=0;ssl_get_handshake_digest(idx,&m,&md);idx++) {
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if ((m<<TLS1_PRF_DGST_SHIFT) & digest_mask) {
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (!md) {
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSLerr(SSL_F_TLS1_PRF,
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				SSL_R_UNSUPPORTED_DIGEST_TYPE);
2773d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
2793d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			if (!tls1_P_hash(md ,S1,len+(slen&1),
2803d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					seed1,seed1_len,seed2,seed2_len,seed3,seed3_len,seed4,seed4_len,seed5,seed5_len,
2813d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					out2,olen))
2823d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err;
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			S1+=len;
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			for (i=0; i<olen; i++)
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				out1[i]^=out2[i];
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
2903d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	ret = 1;
2913d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstromerr:
2923d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	return ret;
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
2943d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstromstatic int tls1_generate_key_block(SSL *s, unsigned char *km,
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     unsigned char *tmp, int num)
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
2973d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	int ret;
298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	ret = tls1_PRF(ssl_get_algorithm2(s),
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 TLS_MD_KEY_EXPANSION_CONST,TLS_MD_KEY_EXPANSION_CONST_SIZE,
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 s->s3->server_random,SSL3_RANDOM_SIZE,
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 s->s3->client_random,SSL3_RANDOM_SIZE,
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		 NULL,0,NULL,0,
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 s->session->master_key,s->session->master_key_length,
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 km,tmp,num);
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("tls1_generate_key_block() ==> %d byte master_key =\n\t",
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                s->session->master_key_length);
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        int i;
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        for (i=0; i < s->session->master_key_length; i++)
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                {
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                printf("%02X", s->session->master_key[i]);
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                }
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        printf("\n");  }
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif    /* KSSL_DEBUG */
3163d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	return ret;
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_change_cipher_state(SSL *s, int which)
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	static const unsigned char empty[]="";
32243c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom	unsigned char *p,*mac_secret;
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char *exp_label;
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char tmp1[EVP_MAX_KEY_LENGTH];
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char tmp2[EVP_MAX_KEY_LENGTH];
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char iv1[EVP_MAX_IV_LENGTH*2];
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char iv2[EVP_MAX_IV_LENGTH*2];
32843c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom	unsigned char *ms,*key,*iv;
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int client_write;
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX *dd;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_CIPHER *c;
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_COMP
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const SSL_COMP *comp;
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_MD *m;
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int mac_type;
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int *mac_secret_size;
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_CTX *mac_ctx;
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_PKEY *mac_key;
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int is_export,n,i,j,k,exp_label_len,cl;
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int reuse_dd = 0;
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher);
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	c=s->s3->tmp.new_sym_enc;
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	m=s->s3->tmp.new_hash;
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	mac_type = s->s3->tmp.new_mac_pkey_type;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_COMP
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	comp=s->s3->tmp.new_compression;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("tls1_change_cipher_state(which= %d) w/\n", which);
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	printf("\talg= %ld/%ld, comp= %p\n",
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	       s->s3->tmp.new_cipher->algorithm_mkey,
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	       s->s3->tmp.new_cipher->algorithm_auth,
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	       comp);
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c);
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n",
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                c->nid,c->block_size,c->key_len,c->iv_len);
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length);
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        int i;
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        for (i=0; i<s->s3->tmp.key_block_length; i++)
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("%02x", key_block[i]);  printf("\n");
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (which & SSL3_CC_READ)
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM;
372392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM;
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->enc_read_ctx != NULL)
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			reuse_dd = 1;
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* make sure it's intialized in case we exit later with an error */
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CIPHER_CTX_init(s->enc_read_ctx);
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dd= s->enc_read_ctx;
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		mac_ctx=ssl_replace_hash(&s->read_hash,NULL);
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_COMP
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->expand != NULL)
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMP_CTX_free(s->expand);
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->expand=NULL;
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (comp != NULL)
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->expand=COMP_CTX_new(comp->method);
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->expand == NULL)
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err2;
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->s3->rrec.comp == NULL)
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->rrec.comp=(unsigned char *)
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->s3->rrec.comp == NULL)
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err;
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 		if (s->version != DTLS1_VERSION)
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memset(&(s->s3->read_sequence[0]),0,8);
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		mac_secret= &(s->s3->read_mac_secret[0]);
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		mac_secret_size=&(s->s3->read_mac_secret_size);
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC)
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM;
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM;
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->enc_write_ctx != NULL)
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			reuse_dd = 1;
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			goto err;
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* make sure it's intialized in case we exit later with an error */
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			EVP_CIPHER_CTX_init(s->enc_write_ctx);
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dd= s->enc_write_ctx;
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		mac_ctx = ssl_replace_hash(&s->write_hash,NULL);
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_COMP
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->compress != NULL)
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			COMP_CTX_free(s->compress);
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->compress=NULL;
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (comp != NULL)
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			s->compress=COMP_CTX_new(comp->method);
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->compress == NULL)
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR);
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				goto err2;
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* this is done by dtls1_reset_seq_numbers for DTLS1_VERSION */
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 		if (s->version != DTLS1_VERSION)
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			memset(&(s->s3->write_sequence[0]),0,8);
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		mac_secret= &(s->s3->write_mac_secret[0]);
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		mac_secret_size = &(s->s3->write_mac_secret_size);
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (reuse_dd)
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		EVP_CIPHER_CTX_cleanup(dd);
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p=s->s3->tmp.key_block;
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	i=*mac_secret_size=s->s3->tmp.new_mac_secret_size;
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	cl=EVP_CIPHER_key_length(c);
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ?
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	               cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl;
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Was j=(exp)?5:EVP_CIPHER_key_length(c); */
459392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* If GCM mode only part of IV comes from PRF */
460392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
461392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		k = EVP_GCM_TLS_FIXED_IV_LEN;
462392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
463392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		k=EVP_CIPHER_iv_length(c);
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (	(which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(which == SSL3_CHANGE_CIPHER_SERVER_READ))
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ms=  &(p[ 0]); n=i+i;
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		key= &(p[ n]); n+=j+j;
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iv=  &(p[ n]); n+=k+k;
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST;
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE;
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		client_write=1;
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		n=i;
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ms=  &(p[ n]); n+=i+j;
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		key= &(p[ n]); n+=j+k;
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		iv=  &(p[ n]); n+=k;
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST;
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE;
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		client_write=0;
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (n > s->s3->tmp.key_block_length)
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR);
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err2;
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	memcpy(mac_secret,ms,i);
492392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
493392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!(EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER))
494392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
495392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		mac_key = EVP_PKEY_new_mac_key(mac_type, NULL,
496392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				mac_secret,*mac_secret_size);
497392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_DigestSignInit(mac_ctx,NULL,m,NULL,mac_key);
498392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_PKEY_free(mac_key);
499392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("which = %04X\nmac key=",which);
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); }
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (is_export)
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* In here I set both the read and write key/iv to the
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * same value since only the correct one will be used :-).
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
509392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (!tls1_PRF(ssl_get_algorithm2(s),
5103d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				exp_label,exp_label_len,
5113d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				s->s3->client_random,SSL3_RANDOM_SIZE,
5123d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				s->s3->server_random,SSL3_RANDOM_SIZE,
5133d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				NULL,0,NULL,0,
5143d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				key,j,tmp1,tmp2,EVP_CIPHER_key_length(c)))
5153d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			goto err2;
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		key=tmp1;
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (k > 0)
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
520392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (!tls1_PRF(ssl_get_algorithm2(s),
5213d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					TLS_MD_IV_BLOCK_CONST,TLS_MD_IV_BLOCK_CONST_SIZE,
5223d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					s->s3->client_random,SSL3_RANDOM_SIZE,
5233d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					s->s3->server_random,SSL3_RANDOM_SIZE,
5243d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					NULL,0,NULL,0,
5253d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom					empty,0,iv1,iv2,k*2))
5263d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom				goto err2;
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (client_write)
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				iv=iv1;
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			else
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				iv= &(iv1[k]);
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->session->key_arg_length=0;
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
537221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        int i;
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n");
539221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]);
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("\n");
541221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]);
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("\n");
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
546392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
547392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
548392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CipherInit_ex(dd,c,NULL,key,NULL,(which & SSL3_CC_WRITE));
549392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv);
550392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
551392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	else
552392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
553392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
554392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */
555392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if ((EVP_CIPHER_flags(c)&EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size)
556392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY,
557392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				*mac_secret_size,mac_secret);
558392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("which = %04X\nkey=",which);
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("\niv=");
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); }
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("\n");
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(tmp1,sizeof(tmp1));
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(tmp2,sizeof(tmp1));
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(iv1,sizeof(iv1));
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	OPENSSL_cleanse(iv2,sizeof(iv2));
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE);
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr2:
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(0);
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_setup_key_block(SSL *s)
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
5803d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	unsigned char *p1,*p2=NULL;
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_CIPHER *c;
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_MD *hash;
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int num;
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	SSL_COMP *comp;
585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int mac_type= NID_undef,mac_secret_size=0;
5863d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	int ret=0;
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf ("tls1_setup_key_block()\n");
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (s->s3->tmp.key_block_length != 0)
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(1);
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!ssl_cipher_get_evp(s->session,&c,&hash,&mac_type,&mac_secret_size,&comp))
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->s3->tmp.new_sym_enc=c;
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->s3->tmp.new_hash=hash;
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	s->s3->tmp.new_mac_pkey_type = mac_type;
604221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	s->s3->tmp.new_mac_secret_size = mac_secret_size;
605221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	num=EVP_CIPHER_key_length(c)+mac_secret_size+EVP_CIPHER_iv_length(c);
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	num*=2;
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ssl3_cleanup_key_block(s);
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL)
6113d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		{
6123d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
6143d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		}
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->s3->tmp.key_block_length=num;
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	s->s3->tmp.key_block=p1;
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
6193d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL)
6203d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		{
6213d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE);
6223d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
6233d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		}
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("client random\n");
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); }
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("server random\n");
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); }
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("pre-master\n");
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); }
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
6333d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	if (!tls1_generate_key_block(s,p1,p2,num))
6343d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		goto err;
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("\nkey block\n");
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{ int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); }
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
640392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
641392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		&& s->method->version <= TLS1_VERSION)
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* enable vulnerability countermeasure for CBC ciphers with
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 */
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->s3->need_empty_fragments = 1;
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->session->cipher != NULL)
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->session->cipher->algorithm_enc == SSL_eNULL)
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->need_empty_fragments = 0;
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_RC4
654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (s->session->cipher->algorithm_enc == SSL_RC4)
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				s->s3->need_empty_fragments = 0;
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
6603d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	ret = 1;
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
6623d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	if (p2)
6633d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		{
6643d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		OPENSSL_cleanse(p2,num);
6653d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		OPENSSL_free(p2);
6663d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		}
6673d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom	return(ret);
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_enc(SSL *s, int send)
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	SSL3_RECORD *rec;
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_CIPHER_CTX *ds;
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long l;
675392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int bs,i,ii,j,k,pad=0;
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const EVP_CIPHER *enc;
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (send)
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
680221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (EVP_MD_CTX_md(s->write_hash))
681221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
682392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			int n=EVP_MD_CTX_size(s->write_hash);
683221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			OPENSSL_assert(n >= 0);
684221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ds=s->enc_write_ctx;
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rec= &(s->s3->wrec);
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->enc_write_ctx == NULL)
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			enc=NULL;
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
690392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
691392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			int ivlen;
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			enc=EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
693392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			/* For TLSv1.1 and later explicit IV */
694392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (s->version >= TLS1_1_VERSION
695392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				&& EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
696392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				ivlen = EVP_CIPHER_iv_length(enc);
697392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
698392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				ivlen = 0;
699392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (ivlen > 1)
700392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
701392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if ( rec->data != rec->input)
702392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					/* we can't write into the input stream:
703392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					 * Can this ever happen?? (steve)
704392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					 */
705392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					fprintf(stderr,
706392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						"%s:%d: rec->data != rec->input\n",
707392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						__FILE__, __LINE__);
708392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				else if (RAND_bytes(rec->input, ivlen) <= 0)
709392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
710392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
711392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
715221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (EVP_MD_CTX_md(s->read_hash))
716221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
717392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			int n=EVP_MD_CTX_size(s->read_hash);
718221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			OPENSSL_assert(n >= 0);
719221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ds=s->enc_read_ctx;
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rec= &(s->s3->rrec);
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (s->enc_read_ctx == NULL)
723656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			enc=NULL;
724656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
725656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			enc=EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
726656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
727656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
728656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
729656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf("tls1_enc(%d)\n", send);
730656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif    /* KSSL_DEBUG */
731656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
732656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((s->session == NULL) || (ds == NULL) ||
733656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(enc == NULL))
734656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
735656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memmove(rec->data,rec->input,rec->length);
736656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rec->input=rec->data;
737656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
738656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
739656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
740656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		l=rec->length;
741656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		bs=EVP_CIPHER_block_size(ds->cipher);
742656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
743392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER)
744392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
745392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			unsigned char buf[13],*seq;
746392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
747392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			seq = send?s->s3->write_sequence:s->s3->read_sequence;
748392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
749392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
750392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
751392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				unsigned char dtlsseq[9],*p=dtlsseq;
752392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
753392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				s2n(send?s->d1->w_epoch:s->d1->r_epoch,p);
754392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				memcpy(p,&seq[2],6);
755392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				memcpy(buf,dtlsseq,8);
756392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
757392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			else
758392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
759392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				memcpy(buf,seq,8);
760392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				for (i=7; i>=0; i--)	/* increment */
761392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					{
762392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					++seq[i];
763392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					if (seq[i] != 0) break;
764392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					}
765392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
766392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
767392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			buf[8]=rec->type;
768392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			buf[9]=(unsigned char)(s->version>>8);
769392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			buf[10]=(unsigned char)(s->version);
770392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			buf[11]=rec->length>>8;
771392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			buf[12]=rec->length&0xff;
772392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf);
773392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (send)
774392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
775392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				l+=pad;
776392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				rec->length+=pad;
777392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
778392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
779392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		else if ((bs != 1) && send)
780656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
781656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i=bs-((int)l%bs);
782656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
783656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* Add weird padding of upto 256 bytes */
784656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
785656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* we need to add 'i' padding bytes of value j */
786656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			j=i-1;
787656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG)
788656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
789656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
790656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					j++;
791656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
792656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			for (k=(int)l; k<(int)(l+i); k++)
793656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				rec->input[k]=j;
794656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			l+=i;
795656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rec->length+=i;
796656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
797656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
798656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
799656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
800656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                unsigned long ui;
801656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n",
802221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                        ds,rec->data,rec->input,l);
803221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		printf("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n",
804656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        ds->buf_len, ds->cipher->key_len,
805221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                        DES_KEY_SZ, DES_SCHEDULE_SZ,
806656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        ds->cipher->iv_len);
807656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		printf("\t\tIV: ");
808656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (i=0; i<ds->cipher->iv_len; i++) printf("%02X", ds->iv[i]);
809656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		printf("\n");
810656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		printf("\trec->input=");
811656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (ui=0; ui<l; ui++) printf(" %02x", rec->input[ui]);
812656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		printf("\n");
813656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
814656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
815656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
816656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if (!send)
817656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
818656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (l == 0 || l%bs != 0)
819656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
820392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				if (s->version >= TLS1_1_VERSION)
821392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					return -1;
822656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				SSLerr(SSL_F_TLS1_ENC,SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
823656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_DECRYPTION_FAILED);
824656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return 0;
825656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
826656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
827656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
828392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		i = EVP_Cipher(ds,rec->data,rec->input,l);
829392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_CUSTOM_CIPHER)
830392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						?(i<0)
831392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom						:(i==0))
832392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			return -1;	/* AEAD can fail to verify MAC */
833392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send)
834392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
835392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
836392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
837392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
838392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
839656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
840656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
841656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
842221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                unsigned long i;
843656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                printf("\trec->data=");
844221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		for (i=0; i<l; i++)
845221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                        printf(" %02x", rec->data[i]);  printf("\n");
846656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                }
847656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
848656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
849656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((bs != 1) && !send)
850656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
851656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ii=i=rec->data[l-1]; /* padding_length */
852656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			i++;
853656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* NB: if compression is in operation the first packet
854656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * may not be of even length so the padding bug check
855656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * cannot be performed. This bug workaround has been
856656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * around since SSLeay so hopefully it is either fixed
857656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * now or no buggy implementation supports compression
858656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * [steve]
859656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 */
860656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if ( (s->options&SSL_OP_TLS_BLOCK_PADDING_BUG)
861656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				&& !s->expand)
862656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
863656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* First packet is even in size, so check */
864656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if ((memcmp(s->s3->read_sequence,
865656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					"\0\0\0\0\0\0\0\0",8) == 0) && !(ii & 1))
866656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					s->s3->flags|=TLS1_FLAGS_TLS_PADDING_BUG;
867656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG)
868656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					i--;
869656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
870656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			/* TLS 1.0 does not bound the number of padding bytes by the block size.
871656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			 * All of them must have value 'padding_length'. */
872656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (i > (int)rec->length)
873656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
874656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				/* Incorrect padding. SSLerr() and ssl3_alert are done
875656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				 * by caller: we don't want to reveal whether this is
876656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				 * a decryption error or a MAC verification failure
877656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				 * (see http://www.openssl.org/~bodo/tls-cbc.txt) */
878656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				return -1;
879656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
880656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			for (j=(int)(l-i); j<(int)l; j++)
881656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
882656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				if (rec->data[j] != ii)
883656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					{
884656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					/* Incorrect padding */
885656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					return -1;
886656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					}
887656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
888392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rec->length -=i;
889392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			if (s->version >= TLS1_1_VERSION
890392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				&& EVP_CIPHER_CTX_mode(ds) == EVP_CIPH_CBC_MODE)
891392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				{
892eb16853f1084abf2770588727ef99c6a244abc50Brian Carlstrom				if (bs > (int)rec->length)
893eb16853f1084abf2770588727ef99c6a244abc50Brian Carlstrom					return -1;
894392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				rec->data += bs;    /* skip the explicit IV */
895392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				rec->input += bs;
896392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				rec->length -= bs;
897392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				}
898656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
899392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (pad && !send)
900392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			rec->length -= pad;
901656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
902656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
903656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
904221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out)
905656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
906656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int ret;
907221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_CTX ctx, *d=NULL;
908221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i;
909221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
910221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (s->s3->handshake_buffer)
911221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!ssl3_digest_cached_records(s))
912221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
913221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
914221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i=0;i<SSL_MAX_DIGEST;i++)
915221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
916221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		  if (s->s3->handshake_dgst[i]&&EVP_MD_CTX_type(s->s3->handshake_dgst[i])==md_nid)
917221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		  	{
918221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		  	d=s->s3->handshake_dgst[i];
919221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			break;
920221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
921221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
922221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!d) {
923221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC,SSL_R_NO_REQUIRED_DIGEST);
924221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
925221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
926656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
927656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_init(&ctx);
928221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_CTX_copy_ex(&ctx,d);
929656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_DigestFinal_ex(&ctx,out,&ret);
930656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_cleanup(&ctx);
931656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return((int)ret);
932656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
933656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
934221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromint tls1_final_finish_mac(SSL *s,
935656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     const char *str, int slen, unsigned char *out)
936656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
937656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned int i;
938656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX ctx;
939221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	unsigned char buf[2*EVP_MAX_MD_SIZE];
940656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *q,buf2[12];
941221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int idx;
942221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	long mask;
943221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int err=0;
944221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const EVP_MD *md;
945656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
946656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	q=buf;
947221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
948221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (s->s3->handshake_buffer)
949221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (!ssl3_digest_cached_records(s))
950221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return 0;
951656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
952656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_init(&ctx);
953221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
954221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (idx=0;ssl_get_handshake_digest(idx,&mask,&md);idx++)
955221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
956392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if (mask & ssl_get_algorithm2(s))
957221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
958221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			int hashsize = EVP_MD_size(md);
959221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (hashsize < 0 || hashsize > (int)(sizeof buf - (size_t)(q-buf)))
960221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
961221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				/* internal error: 'buf' is too small for this cipersuite! */
962221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				err = 1;
963221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
964221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			else
965221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				{
966221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				EVP_MD_CTX_copy_ex(&ctx,s->s3->handshake_dgst[idx]);
967221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				EVP_DigestFinal_ex(&ctx,q,&i);
968221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				if (i != (unsigned int)hashsize) /* can't really happen */
969221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom					err = 1;
970221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				q+=i;
971221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom				}
972221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
973221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
974221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
975392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!tls1_PRF(ssl_get_algorithm2(s),
9763d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			str,slen, buf,(int)(q-buf), NULL,0, NULL,0, NULL,0,
9773d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			s->session->master_key,s->session->master_key_length,
9783d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom			out,buf2,sizeof buf2))
9793d3a1b8fcf46ca3bdb3d8f09acd6ef604624a30dBrian Carlstrom		err = 1;
980656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	EVP_MD_CTX_cleanup(&ctx);
981656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
982221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (err)
983221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return 0;
984221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	else
985221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return sizeof buf2;
986656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
987656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
988656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_mac(SSL *ssl, unsigned char *md, int send)
989656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
990656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	SSL3_RECORD *rec;
99143c12e3d4f9bbbbd4a8ba7b149686437514bc6b6Brian Carlstrom	unsigned char *seq;
992221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_CTX *hash;
993221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	size_t md_size;
994656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int i;
995221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_MD_CTX hmac, *mac_ctx;
996656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char buf[5];
997221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int stream_mac = (send?(ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM):(ssl->mac_flags&SSL_MAC_FLAG_READ_MAC_STREAM));
998221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int t;
999656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1000656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (send)
1001656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1002656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rec= &(ssl->s3->wrec);
1003656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		seq= &(ssl->s3->write_sequence[0]);
1004656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		hash=ssl->write_hash;
1005656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1006656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1007656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1008656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rec= &(ssl->s3->rrec);
1009656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		seq= &(ssl->s3->read_sequence[0]);
1010656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		hash=ssl->read_hash;
1011656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1012656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1013221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	t=EVP_MD_CTX_size(hash);
1014221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_assert(t >= 0);
1015221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	md_size=t;
1016656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1017656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buf[0]=rec->type;
1018221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	buf[1]=(unsigned char)(ssl->version>>8);
1019221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	buf[2]=(unsigned char)(ssl->version);
1020656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buf[3]=rec->length>>8;
1021656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	buf[4]=rec->length&0xff;
1022656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1023656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
1024221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (stream_mac)
1025221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
1026221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			mac_ctx = hash;
1027221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
1028221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		else
1029221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
1030221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			EVP_MD_CTX_copy(&hmac,hash);
1031221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			mac_ctx = &hmac;
1032221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
1033656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1034221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER)
1035656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1036656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		unsigned char dtlsseq[8],*p=dtlsseq;
1037221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1038656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
1039656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		memcpy (p,&seq[2],6);
1040656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1041221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVP_DigestSignUpdate(mac_ctx,dtlsseq,8);
1042656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1043656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
1044221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		EVP_DigestSignUpdate(mac_ctx,seq,8);
1045656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1046221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_DigestSignUpdate(mac_ctx,buf,5);
1047221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	EVP_DigestSignUpdate(mac_ctx,rec->input,rec->length);
1048221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	t=EVP_DigestSignFinal(mac_ctx,md,&md_size);
1049221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	OPENSSL_assert(t > 0);
1050221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1051221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!stream_mac) EVP_MD_CTX_cleanup(&hmac);
1052656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
1053656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("sec=");
1054656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
1055656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("seq=");
1056656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
1057656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("buf=");
1058656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
1059656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectprintf("rec=");
1060656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
1061656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1062656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1063221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
1064656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1065656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		for (i=7; i>=0; i--)
1066656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
1067656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			++seq[i];
1068656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if (seq[i] != 0) break;
1069656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
1070656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1071656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1072656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef TLS_DEBUG
1073656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",md[z]); printf("\n"); }
1074656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
1075656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(md_size);
1076656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1077656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1078656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
1079656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	     int len)
1080656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1081656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH];
1082221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	const void *co = NULL, *so = NULL;
1083221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int col = 0, sol = 0;
1084656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1085392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1086656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
1087221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	printf ("tls1_generate_master_secret(%p,%p, %p, %d)\n", s,out, p,len);
1088656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
1089656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1090221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef TLSEXT_TYPE_opaque_prf_input
1091221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (s->s3->client_opaque_prf_input != NULL && s->s3->server_opaque_prf_input != NULL &&
1092221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    s->s3->client_opaque_prf_input_len > 0 &&
1093221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	    s->s3->client_opaque_prf_input_len == s->s3->server_opaque_prf_input_len)
1094221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
1095221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		co = s->s3->client_opaque_prf_input;
1096221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		col = s->s3->server_opaque_prf_input_len;
1097221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		so = s->s3->server_opaque_prf_input;
1098221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		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) */
1099221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
1100221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
1101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1102392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	tls1_PRF(ssl_get_algorithm2(s),
1103221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		TLS_MD_MASTER_SECRET_CONST,TLS_MD_MASTER_SECRET_CONST_SIZE,
1104221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		s->s3->client_random,SSL3_RANDOM_SIZE,
1105221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		co, col,
1106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		s->s3->server_random,SSL3_RANDOM_SIZE,
1107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		so, sol,
1108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		p,len,
1109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		s->session->master_key,buff,sizeof buff);
1110392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef SSL_DEBUG
1111392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fprintf(stderr, "Premaster Secret:\n");
1112392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_dump_fp(stderr, (char *)p, len);
1113392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fprintf(stderr, "Client Random:\n");
1114392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE);
1115392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fprintf(stderr, "Server Random:\n");
1116392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE);
1117392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fprintf(stderr, "Master Secret:\n");
1118392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
1119392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
1120221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
1121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef KSSL_DEBUG
1122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	printf ("tls1_generate_master_secret() complete\n");
1123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif	/* KSSL_DEBUG */
1124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(SSL3_MASTER_SECRET_SIZE);
1125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
1127392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
1128392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 const char *label, size_t llen, const unsigned char *context,
1129392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 size_t contextlen, int use_context)
1130392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
1131392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char *buff;
1132392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char *val = NULL;
1133392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t vallen, currentvalpos;
1134392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	int rv;
1135392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1136392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef KSSL_DEBUG
1137392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	printf ("tls1_export_keying_material(%p,%p,%d,%s,%d,%p,%d)\n", s, out, olen, label, llen, p, plen);
1138392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif	/* KSSL_DEBUG */
1139392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1140392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	buff = OPENSSL_malloc(olen);
1141392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (buff == NULL) goto err2;
1142392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1143392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* construct PRF arguments
1144392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * we construct the PRF argument ourself rather than passing separate
1145392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * values into the TLS PRF to ensure that the concatenation of values
1146392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * does not create a prohibited label.
1147392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
1148392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	vallen = llen + SSL3_RANDOM_SIZE * 2;
1149392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (use_context)
1150392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1151392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		vallen += 2 + contextlen;
1152392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1153392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1154392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	val = OPENSSL_malloc(vallen);
1155392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (val == NULL) goto err2;
1156392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	currentvalpos = 0;
1157392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	memcpy(val + currentvalpos, (unsigned char *) label, llen);
1158392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	currentvalpos += llen;
1159392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE);
1160392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	currentvalpos += SSL3_RANDOM_SIZE;
1161392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE);
1162392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	currentvalpos += SSL3_RANDOM_SIZE;
1163392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1164392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (use_context)
1165392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
1166392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		val[currentvalpos] = (contextlen >> 8) & 0xff;
1167392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		currentvalpos++;
1168392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		val[currentvalpos] = contextlen & 0xff;
1169392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		currentvalpos++;
1170392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		if ((contextlen > 0) || (context != NULL))
1171392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			{
1172392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			memcpy(val + currentvalpos, context, contextlen);
1173392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom			}
1174392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
1175392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1176392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* disallow prohibited labels
1177392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * note that SSL3_RANDOM_SIZE > max(prohibited label len) =
1178392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * 15, so size of val > max(prohibited label len) = 15 and the
1179392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 * comparisons won't have buffer overflow
1180392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	 */
1181392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST,
1182392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) goto err1;
1183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (memcmp(val, TLS_MD_SERVER_FINISH_CONST,
1184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) goto err1;
1185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (memcmp(val, TLS_MD_MASTER_SECRET_CONST,
1186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) goto err1;
1187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
1188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
1189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
1191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      val, vallen,
1192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      NULL, 0,
1193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      NULL, 0,
1194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      NULL, 0,
1195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      NULL, 0,
1196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      s->session->master_key,s->session->master_key_length,
1197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		      out,buff,olen);
1198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef KSSL_DEBUG
1200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	printf ("tls1_export_keying_material() complete\n");
1201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif	/* KSSL_DEBUG */
1202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	goto ret;
1203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromerr1:
1204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL);
1205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	rv = 0;
1206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	goto ret;
1207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromerr2:
1208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE);
1209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	rv = 0;
1210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromret:
1211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (buff != NULL) OPENSSL_free(buff);
1212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (val != NULL) OPENSSL_free(val);
1213392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return(rv);
1214392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
1215392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
1216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint tls1_alert_code(int code)
1217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
1218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch (code)
1219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
1220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_CLOSE_NOTIFY:	return(SSL3_AD_CLOSE_NOTIFY);
1221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_UNEXPECTED_MESSAGE:	return(SSL3_AD_UNEXPECTED_MESSAGE);
1222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_BAD_RECORD_MAC:	return(SSL3_AD_BAD_RECORD_MAC);
1223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_DECRYPTION_FAILED:	return(TLS1_AD_DECRYPTION_FAILED);
1224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_RECORD_OVERFLOW:	return(TLS1_AD_RECORD_OVERFLOW);
1225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_DECOMPRESSION_FAILURE:return(SSL3_AD_DECOMPRESSION_FAILURE);
1226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_HANDSHAKE_FAILURE:	return(SSL3_AD_HANDSHAKE_FAILURE);
1227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_NO_CERTIFICATE:	return(-1);
1228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_BAD_CERTIFICATE:	return(SSL3_AD_BAD_CERTIFICATE);
1229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_UNSUPPORTED_CERTIFICATE:return(SSL3_AD_UNSUPPORTED_CERTIFICATE);
1230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_CERTIFICATE_REVOKED:return(SSL3_AD_CERTIFICATE_REVOKED);
1231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_CERTIFICATE_EXPIRED:return(SSL3_AD_CERTIFICATE_EXPIRED);
1232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_CERTIFICATE_UNKNOWN:return(SSL3_AD_CERTIFICATE_UNKNOWN);
1233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_ILLEGAL_PARAMETER:	return(SSL3_AD_ILLEGAL_PARAMETER);
1234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_UNKNOWN_CA:		return(TLS1_AD_UNKNOWN_CA);
1235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_ACCESS_DENIED:	return(TLS1_AD_ACCESS_DENIED);
1236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_DECODE_ERROR:	return(TLS1_AD_DECODE_ERROR);
1237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_DECRYPT_ERROR:	return(TLS1_AD_DECRYPT_ERROR);
1238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_EXPORT_RESTRICTION:	return(TLS1_AD_EXPORT_RESTRICTION);
1239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_PROTOCOL_VERSION:	return(TLS1_AD_PROTOCOL_VERSION);
1240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_INSUFFICIENT_SECURITY:return(TLS1_AD_INSUFFICIENT_SECURITY);
1241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_INTERNAL_ERROR:	return(TLS1_AD_INTERNAL_ERROR);
1242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_USER_CANCELLED:	return(TLS1_AD_USER_CANCELLED);
1243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case SSL_AD_NO_RENEGOTIATION:	return(TLS1_AD_NO_RENEGOTIATION);
1244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_UNSUPPORTED_EXTENSION: return(TLS1_AD_UNSUPPORTED_EXTENSION);
1245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_CERTIFICATE_UNOBTAINABLE: return(TLS1_AD_CERTIFICATE_UNOBTAINABLE);
1246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_UNRECOGNIZED_NAME:	return(TLS1_AD_UNRECOGNIZED_NAME);
1247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: return(TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE);
1248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: return(TLS1_AD_BAD_CERTIFICATE_HASH_VALUE);
1249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	case SSL_AD_UNKNOWN_PSK_IDENTITY:return(TLS1_AD_UNKNOWN_PSK_IDENTITY);
1250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#if 0 /* not appropriate for TLS, not used for DTLS */
1251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: return
1252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					  (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
1253e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu#endif
1254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default:			return(-1);
1255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
1256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
1257