xref: /openbsd-src/lib/libssl/t1_enc.c (revision 387303bbbb9d754b4fb827b18476432ebdba1f40)
1*387303bbSjsing /* $OpenBSD: t1_enc.c,v 1.158 2024/07/20 04:04:23 jsing Exp $ */
25b37fcf3Sryker /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
35b37fcf3Sryker  * All rights reserved.
45b37fcf3Sryker  *
55b37fcf3Sryker  * This package is an SSL implementation written
65b37fcf3Sryker  * by Eric Young (eay@cryptsoft.com).
75b37fcf3Sryker  * The implementation was written so as to conform with Netscapes SSL.
85b37fcf3Sryker  *
95b37fcf3Sryker  * This library is free for commercial and non-commercial use as long as
105b37fcf3Sryker  * the following conditions are aheared to.  The following conditions
115b37fcf3Sryker  * apply to all code found in this distribution, be it the RC4, RSA,
125b37fcf3Sryker  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
135b37fcf3Sryker  * included with this distribution is covered by the same copyright terms
145b37fcf3Sryker  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
155b37fcf3Sryker  *
165b37fcf3Sryker  * Copyright remains Eric Young's, and as such any Copyright notices in
175b37fcf3Sryker  * the code are not to be removed.
185b37fcf3Sryker  * If this package is used in a product, Eric Young should be given attribution
195b37fcf3Sryker  * as the author of the parts of the library used.
205b37fcf3Sryker  * This can be in the form of a textual message at program startup or
215b37fcf3Sryker  * in documentation (online or textual) provided with the package.
225b37fcf3Sryker  *
235b37fcf3Sryker  * Redistribution and use in source and binary forms, with or without
245b37fcf3Sryker  * modification, are permitted provided that the following conditions
255b37fcf3Sryker  * are met:
265b37fcf3Sryker  * 1. Redistributions of source code must retain the copyright
275b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer.
285b37fcf3Sryker  * 2. Redistributions in binary form must reproduce the above copyright
295b37fcf3Sryker  *    notice, this list of conditions and the following disclaimer in the
305b37fcf3Sryker  *    documentation and/or other materials provided with the distribution.
315b37fcf3Sryker  * 3. All advertising materials mentioning features or use of this software
325b37fcf3Sryker  *    must display the following acknowledgement:
335b37fcf3Sryker  *    "This product includes cryptographic software written by
345b37fcf3Sryker  *     Eric Young (eay@cryptsoft.com)"
355b37fcf3Sryker  *    The word 'cryptographic' can be left out if the rouines from the library
365b37fcf3Sryker  *    being used are not cryptographic related :-).
375b37fcf3Sryker  * 4. If you include any Windows specific code (or a derivative thereof) from
385b37fcf3Sryker  *    the apps directory (application code) you must include an acknowledgement:
395b37fcf3Sryker  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
405b37fcf3Sryker  *
415b37fcf3Sryker  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
425b37fcf3Sryker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
435b37fcf3Sryker  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
445b37fcf3Sryker  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
455b37fcf3Sryker  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
465b37fcf3Sryker  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
475b37fcf3Sryker  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
485b37fcf3Sryker  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
495b37fcf3Sryker  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
505b37fcf3Sryker  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
515b37fcf3Sryker  * SUCH DAMAGE.
525b37fcf3Sryker  *
535b37fcf3Sryker  * The licence and distribution terms for any publically available version or
545b37fcf3Sryker  * derivative of this code cannot be changed.  i.e. this code cannot simply be
555b37fcf3Sryker  * copied and put under another distribution licence
565b37fcf3Sryker  * [including the GNU Public Licence.]
575b37fcf3Sryker  */
58da347917Sbeck /* ====================================================================
590a5d6edeSdjm  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60da347917Sbeck  *
61da347917Sbeck  * Redistribution and use in source and binary forms, with or without
62da347917Sbeck  * modification, are permitted provided that the following conditions
63da347917Sbeck  * are met:
64da347917Sbeck  *
65da347917Sbeck  * 1. Redistributions of source code must retain the above copyright
66da347917Sbeck  *    notice, this list of conditions and the following disclaimer.
67da347917Sbeck  *
68da347917Sbeck  * 2. Redistributions in binary form must reproduce the above copyright
69da347917Sbeck  *    notice, this list of conditions and the following disclaimer in
70da347917Sbeck  *    the documentation and/or other materials provided with the
71da347917Sbeck  *    distribution.
72da347917Sbeck  *
73da347917Sbeck  * 3. All advertising materials mentioning features or use of this
74da347917Sbeck  *    software must display the following acknowledgment:
75da347917Sbeck  *    "This product includes software developed by the OpenSSL Project
76da347917Sbeck  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77da347917Sbeck  *
78da347917Sbeck  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79da347917Sbeck  *    endorse or promote products derived from this software without
80da347917Sbeck  *    prior written permission. For written permission, please contact
81da347917Sbeck  *    openssl-core@openssl.org.
82da347917Sbeck  *
83da347917Sbeck  * 5. Products derived from this software may not be called "OpenSSL"
84da347917Sbeck  *    nor may "OpenSSL" appear in their names without prior written
85da347917Sbeck  *    permission of the OpenSSL Project.
86da347917Sbeck  *
87da347917Sbeck  * 6. Redistributions of any form whatsoever must retain the following
88da347917Sbeck  *    acknowledgment:
89da347917Sbeck  *    "This product includes software developed by the OpenSSL Project
90da347917Sbeck  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91da347917Sbeck  *
92da347917Sbeck  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93da347917Sbeck  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94da347917Sbeck  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95da347917Sbeck  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96da347917Sbeck  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97da347917Sbeck  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98da347917Sbeck  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99da347917Sbeck  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100da347917Sbeck  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101da347917Sbeck  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102da347917Sbeck  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103da347917Sbeck  * OF THE POSSIBILITY OF SUCH DAMAGE.
104da347917Sbeck  * ====================================================================
105da347917Sbeck  *
106da347917Sbeck  * This product includes cryptographic software written by Eric Young
107da347917Sbeck  * (eay@cryptsoft.com).  This product includes software written by Tim
108da347917Sbeck  * Hudson (tjh@cryptsoft.com).
109da347917Sbeck  *
110da347917Sbeck  */
1110a5d6edeSdjm /* ====================================================================
1120a5d6edeSdjm  * Copyright 2005 Nokia. All rights reserved.
1130a5d6edeSdjm  *
1140a5d6edeSdjm  * The portions of the attached software ("Contribution") is developed by
1150a5d6edeSdjm  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
1160a5d6edeSdjm  * license.
1170a5d6edeSdjm  *
1180a5d6edeSdjm  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
1190a5d6edeSdjm  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
1200a5d6edeSdjm  * support (see RFC 4279) to OpenSSL.
1210a5d6edeSdjm  *
1220a5d6edeSdjm  * No patent licenses or other rights except those expressly stated in
1230a5d6edeSdjm  * the OpenSSL open source license shall be deemed granted or received
1240a5d6edeSdjm  * expressly, by implication, estoppel, or otherwise.
1250a5d6edeSdjm  *
1260a5d6edeSdjm  * No assurances are provided by Nokia that the Contribution does not
1270a5d6edeSdjm  * infringe the patent or other intellectual property rights of any third
1280a5d6edeSdjm  * party or that the license provides you with all the necessary rights
1290a5d6edeSdjm  * to make use of the Contribution.
1300a5d6edeSdjm  *
1310a5d6edeSdjm  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
1320a5d6edeSdjm  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
1330a5d6edeSdjm  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
1340a5d6edeSdjm  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
1350a5d6edeSdjm  * OTHERWISE.
1360a5d6edeSdjm  */
1375b37fcf3Sryker 
138366dc2a2Sjsing #include <limits.h>
1395b37fcf3Sryker #include <stdio.h>
140c5899dbcSjsing 
141913ec974Sbeck #include <openssl/evp.h>
142913ec974Sbeck #include <openssl/hmac.h>
143da347917Sbeck #include <openssl/md5.h>
144f4dd87b5Sjsing #include <openssl/opensslconf.h>
1455b37fcf3Sryker 
146c9675a23Stb #include "dtls_local.h"
147c9675a23Stb #include "ssl_local.h"
1484b0cebd1Sjsing 
14999a27067Sjsing void
15073a156d5Sjsing tls1_cleanup_key_block(SSL *s)
15199a27067Sjsing {
15202876cc3Sjsing 	tls12_key_block_free(s->s3->hs.tls12.key_block);
15302876cc3Sjsing 	s->s3->hs.tls12.key_block = NULL;
15499a27067Sjsing }
15599a27067Sjsing 
156ee3ff9e0Sjsing /*
157ee3ff9e0Sjsing  * TLS P_hash() data expansion function - see RFC 5246, section 5.
158ee3ff9e0Sjsing  */
1593cc1ff8eSjsing static int
16044bcb26bSjsing tls1_P_hash(const EVP_MD *md, const unsigned char *secret, size_t secret_len,
16144bcb26bSjsing     const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len,
16244bcb26bSjsing     const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len,
16344bcb26bSjsing     const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len)
1645b37fcf3Sryker {
165636af327Sjsing 	unsigned char A1[EVP_MAX_MD_SIZE], hmac[EVP_MAX_MD_SIZE];
166636af327Sjsing 	size_t A1_len, hmac_len;
16721d9aa66Stb 	EVP_MD_CTX *ctx = NULL;
16821d9aa66Stb 	EVP_PKEY *mac_key = NULL;
1690a5d6edeSdjm 	int ret = 0;
170ee3ff9e0Sjsing 	int chunk;
171636af327Sjsing 	size_t i;
1725b37fcf3Sryker 
1735b37fcf3Sryker 	chunk = EVP_MD_size(md);
1740a5d6edeSdjm 	OPENSSL_assert(chunk >= 0);
1755b37fcf3Sryker 
17621d9aa66Stb 	if ((ctx = EVP_MD_CTX_new()) == NULL)
17721d9aa66Stb 		goto err;
178ee3ff9e0Sjsing 
17944bcb26bSjsing 	mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, secret, secret_len);
18021d9aa66Stb 	if (mac_key == NULL)
1810a5d6edeSdjm 		goto err;
18221d9aa66Stb 	if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
1830a5d6edeSdjm 		goto err;
18421d9aa66Stb 	if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
1850a5d6edeSdjm 		goto err;
18621d9aa66Stb 	if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
1870a5d6edeSdjm 		goto err;
18821d9aa66Stb 	if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
1890a5d6edeSdjm 		goto err;
19021d9aa66Stb 	if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
1910a5d6edeSdjm 		goto err;
19221d9aa66Stb 	if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
1935cdd308eSdjm 		goto err;
19421d9aa66Stb 	if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
1950a5d6edeSdjm 		goto err;
1965b37fcf3Sryker 
1973cc1ff8eSjsing 	for (;;) {
19821d9aa66Stb 		if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
1990a5d6edeSdjm 			goto err;
20021d9aa66Stb 		if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
2010a5d6edeSdjm 			goto err;
20221d9aa66Stb 		if (seed1 && !EVP_DigestSignUpdate(ctx, seed1, seed1_len))
2030a5d6edeSdjm 			goto err;
20421d9aa66Stb 		if (seed2 && !EVP_DigestSignUpdate(ctx, seed2, seed2_len))
2050a5d6edeSdjm 			goto err;
20621d9aa66Stb 		if (seed3 && !EVP_DigestSignUpdate(ctx, seed3, seed3_len))
2070a5d6edeSdjm 			goto err;
20821d9aa66Stb 		if (seed4 && !EVP_DigestSignUpdate(ctx, seed4, seed4_len))
2090a5d6edeSdjm 			goto err;
21021d9aa66Stb 		if (seed5 && !EVP_DigestSignUpdate(ctx, seed5, seed5_len))
2110a5d6edeSdjm 			goto err;
21221d9aa66Stb 		if (!EVP_DigestSignFinal(ctx, hmac, &hmac_len))
213636af327Sjsing 			goto err;
2145b37fcf3Sryker 
21544bcb26bSjsing 		if (hmac_len > out_len)
21644bcb26bSjsing 			hmac_len = out_len;
217636af327Sjsing 
218636af327Sjsing 		for (i = 0; i < hmac_len; i++)
219636af327Sjsing 			out[i] ^= hmac[i];
220636af327Sjsing 
221636af327Sjsing 		out += hmac_len;
22244bcb26bSjsing 		out_len -= hmac_len;
223636af327Sjsing 
22444bcb26bSjsing 		if (out_len == 0)
2255b37fcf3Sryker 			break;
226ee3ff9e0Sjsing 
22721d9aa66Stb 		if (!EVP_DigestSignInit(ctx, NULL, md, NULL, mac_key))
228ee3ff9e0Sjsing 			goto err;
22921d9aa66Stb 		if (!EVP_DigestSignUpdate(ctx, A1, A1_len))
230ee3ff9e0Sjsing 			goto err;
23121d9aa66Stb 		if (!EVP_DigestSignFinal(ctx, A1, &A1_len))
232ee3ff9e0Sjsing 			goto err;
2335b37fcf3Sryker 	}
2340a5d6edeSdjm 	ret = 1;
23580d8a045Sjsing 
2360a5d6edeSdjm  err:
2375cdd308eSdjm 	EVP_PKEY_free(mac_key);
23821d9aa66Stb 	EVP_MD_CTX_free(ctx);
239ee3ff9e0Sjsing 
2400f777b12Sjsing 	explicit_bzero(A1, sizeof(A1));
241636af327Sjsing 	explicit_bzero(hmac, sizeof(hmac));
242ee3ff9e0Sjsing 
2430a5d6edeSdjm 	return ret;
2445b37fcf3Sryker }
2455b37fcf3Sryker 
246ddde72fdSjsing int
24744bcb26bSjsing tls1_PRF(SSL *s, const unsigned char *secret, size_t secret_len,
24844bcb26bSjsing     const void *seed1, size_t seed1_len, const void *seed2, size_t seed2_len,
24944bcb26bSjsing     const void *seed3, size_t seed3_len, const void *seed4, size_t seed4_len,
25044bcb26bSjsing     const void *seed5, size_t seed5_len, unsigned char *out, size_t out_len)
2515b37fcf3Sryker {
2520a5d6edeSdjm 	const EVP_MD *md;
25344bcb26bSjsing 	size_t half_len;
2545b37fcf3Sryker 
25544bcb26bSjsing 	memset(out, 0, out_len);
25680d8a045Sjsing 
257d8992f09Sjsing 	if (!ssl_get_handshake_evp_md(s, &md))
258d8992f09Sjsing 		return (0);
259d8992f09Sjsing 
26021d9aa66Stb 	if (EVP_MD_type(md) == NID_md5_sha1) {
2619ce46117Sjsing 		/*
2629ce46117Sjsing 		 * Partition secret between MD5 and SHA1, then XOR result.
2639ce46117Sjsing 		 * If the secret length is odd, a one byte overlap is used.
2649ce46117Sjsing 		 */
26544bcb26bSjsing 		half_len = secret_len - (secret_len / 2);
26644bcb26bSjsing 		if (!tls1_P_hash(EVP_md5(), secret, half_len, seed1, seed1_len,
26744bcb26bSjsing 		    seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
26844bcb26bSjsing 		    seed5, seed5_len, out, out_len))
2699ce46117Sjsing 			return (0);
2709ce46117Sjsing 
27144bcb26bSjsing 		secret += secret_len - half_len;
27244bcb26bSjsing 		if (!tls1_P_hash(EVP_sha1(), secret, half_len, seed1, seed1_len,
27344bcb26bSjsing 		    seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
27444bcb26bSjsing 		    seed5, seed5_len, out, out_len))
275d8992f09Sjsing 			return (0);
276d8992f09Sjsing 
277d8992f09Sjsing 		return (1);
2780a5d6edeSdjm 	}
2793cc1ff8eSjsing 
28044bcb26bSjsing 	if (!tls1_P_hash(md, secret, secret_len, seed1, seed1_len,
28144bcb26bSjsing 	    seed2, seed2_len, seed3, seed3_len, seed4, seed4_len,
28244bcb26bSjsing 	    seed5, seed5_len, out, out_len))
2839ce46117Sjsing 		return (0);
2849ce46117Sjsing 
2859ce46117Sjsing 	return (1);
2869ce46117Sjsing }
2879ce46117Sjsing 
288d7351ddfSjsing int
289b16a1c42Sjsing tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len)
2905b37fcf3Sryker {
291d8992f09Sjsing 	return tls1_PRF(s,
29244bcb26bSjsing 	    s->session->master_key, s->session->master_key_length,
2930a5d6edeSdjm 	    TLS_MD_KEY_EXPANSION_CONST, TLS_MD_KEY_EXPANSION_CONST_SIZE,
2940a5d6edeSdjm 	    s->s3->server_random, SSL3_RANDOM_SIZE,
2950a5d6edeSdjm 	    s->s3->client_random, SSL3_RANDOM_SIZE,
296b16a1c42Sjsing 	    NULL, 0, NULL, 0, key_block, key_block_len);
2975b37fcf3Sryker }
2985b37fcf3Sryker 
299b3d9ef4bSjsing static int
300b3d9ef4bSjsing tls1_change_cipher_state(SSL *s, int is_write)
30192658cc5Sjsing {
302d7351ddfSjsing 	CBS mac_key, key, iv;
303117f8422Sjsing 
304b3d9ef4bSjsing 	/* Use client write keys on client write and server read. */
305b3d9ef4bSjsing 	if ((!s->server && is_write) || (s->server && !is_write)) {
30602876cc3Sjsing 		tls12_key_block_client_write(s->s3->hs.tls12.key_block,
307d7351ddfSjsing 		    &mac_key, &key, &iv);
3083cc1ff8eSjsing 	} else {
30902876cc3Sjsing 		tls12_key_block_server_write(s->s3->hs.tls12.key_block,
310d7351ddfSjsing 		    &mac_key, &key, &iv);
311a802a16aSjsing 	}
312a802a16aSjsing 
313b3d9ef4bSjsing 	if (!is_write) {
3146f7f653bSjsing 		if (!tls12_record_layer_change_read_cipher_state(s->rl,
315d7351ddfSjsing 		    &mac_key, &key, &iv))
316a802a16aSjsing 			goto err;
3178950dd79Sjsing 		if (SSL_is_dtls(s))
3188950dd79Sjsing 			dtls1_reset_read_seq_numbers(s);
319a802a16aSjsing 	} else {
3206f7f653bSjsing 		if (!tls12_record_layer_change_write_cipher_state(s->rl,
321d7351ddfSjsing 		    &mac_key, &key, &iv))
322a802a16aSjsing 			goto err;
3235b37fcf3Sryker 	}
3242935b8f4Sjsing 	return (1);
32580d8a045Sjsing 
326a802a16aSjsing  err:
3275b37fcf3Sryker 	return (0);
3285b37fcf3Sryker }
3295b37fcf3Sryker 
3303cc1ff8eSjsing int
331b3d9ef4bSjsing tls1_change_read_cipher_state(SSL *s)
332b3d9ef4bSjsing {
333b3d9ef4bSjsing 	return tls1_change_cipher_state(s, 0);
334b3d9ef4bSjsing }
335b3d9ef4bSjsing 
336b3d9ef4bSjsing int
337b3d9ef4bSjsing tls1_change_write_cipher_state(SSL *s)
338b3d9ef4bSjsing {
339b3d9ef4bSjsing 	return tls1_change_cipher_state(s, 1);
340b3d9ef4bSjsing }
341b3d9ef4bSjsing 
342b3d9ef4bSjsing int
3433cc1ff8eSjsing tls1_setup_key_block(SSL *s)
3445b37fcf3Sryker {
345d7351ddfSjsing 	struct tls12_key_block *key_block;
3460a5d6edeSdjm 	int mac_type = NID_undef, mac_secret_size = 0;
3472b8e1190Sjsing 	const EVP_CIPHER *cipher = NULL;
3482b8e1190Sjsing 	const EVP_AEAD *aead = NULL;
3492935b8f4Sjsing 	const EVP_MD *handshake_hash = NULL;
3502935b8f4Sjsing 	const EVP_MD *mac_hash = NULL;
3510a5d6edeSdjm 	int ret = 0;
3525b37fcf3Sryker 
353d7351ddfSjsing 	/*
354d7351ddfSjsing 	 * XXX - callers should be changed so that they only call this
355d7351ddfSjsing 	 * function once.
356d7351ddfSjsing 	 */
35702876cc3Sjsing 	if (s->s3->hs.tls12.key_block != NULL)
3585b37fcf3Sryker 		return (1);
3595b37fcf3Sryker 
360*387303bbSjsing 	if (s->s3->hs.cipher == NULL)
361*387303bbSjsing 		return (0);
362*387303bbSjsing 
363*387303bbSjsing 	if ((s->s3->hs.cipher->algorithm_mac & SSL_AEAD) != 0) {
364*387303bbSjsing 		if (!ssl_cipher_get_evp_aead(s, &aead)) {
365c9d7abb7Sbeck 			SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
3662b8e1190Sjsing 			return (0);
3672b8e1190Sjsing 		}
3682b8e1190Sjsing 	} else {
369d7351ddfSjsing 		/* XXX - mac_type and mac_secret_size are now unused. */
370*387303bbSjsing 		if (!ssl_cipher_get_evp(s, &cipher, &mac_hash,
3712935b8f4Sjsing 		    &mac_type, &mac_secret_size)) {
372c9d7abb7Sbeck 			SSLerror(s, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
3735b37fcf3Sryker 			return (0);
3745b37fcf3Sryker 		}
3752b8e1190Sjsing 	}
3762b8e1190Sjsing 
3772935b8f4Sjsing 	if (!ssl_get_handshake_evp_md(s, &handshake_hash))
3782935b8f4Sjsing 		return (0);
3792935b8f4Sjsing 
3806f7f653bSjsing 	tls12_record_layer_set_aead(s->rl, aead);
3816f7f653bSjsing 	tls12_record_layer_set_cipher_hash(s->rl, cipher,
3822935b8f4Sjsing 	    handshake_hash, mac_hash);
383c37fa200Sjsing 
384d7351ddfSjsing 	if ((key_block = tls12_key_block_new()) == NULL)
3855b37fcf3Sryker 		goto err;
386d7351ddfSjsing 	if (!tls12_key_block_generate(key_block, s, aead, cipher, mac_hash))
387d7351ddfSjsing 		goto err;
3885b37fcf3Sryker 
38902876cc3Sjsing 	s->s3->hs.tls12.key_block = key_block;
390d7351ddfSjsing 	key_block = NULL;
3915b37fcf3Sryker 
3926f7f653bSjsing 	if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) &&
3936ba40c14Sjsing 	    s->method->version <= TLS1_VERSION) {
394622d4fa7Sjsing 		/*
395622d4fa7Sjsing 		 * Enable vulnerability countermeasure for CBC ciphers with
3961f9308f9Smarkus 		 * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt)
3971f9308f9Smarkus 		 */
39802876cc3Sjsing 		s->s3->need_empty_fragments = 1;
3991f9308f9Smarkus 
400*387303bbSjsing 		if (s->s3->hs.cipher != NULL) {
401*387303bbSjsing 			if (s->s3->hs.cipher->algorithm_enc == SSL_eNULL)
40202876cc3Sjsing 				s->s3->need_empty_fragments = 0;
4031f9308f9Smarkus 
4041f9308f9Smarkus #ifndef OPENSSL_NO_RC4
405*387303bbSjsing 			if (s->s3->hs.cipher->algorithm_enc == SSL_RC4)
40602876cc3Sjsing 				s->s3->need_empty_fragments = 0;
407da347917Sbeck #endif
4081f9308f9Smarkus 		}
4091f9308f9Smarkus 	}
410da347917Sbeck 
4110a5d6edeSdjm 	ret = 1;
4122b8e1190Sjsing 
4135b37fcf3Sryker  err:
414d7351ddfSjsing 	tls12_key_block_free(key_block);
415d7351ddfSjsing 
4160a5d6edeSdjm 	return (ret);
4175b37fcf3Sryker }
418