xref: /dflybsd-src/crypto/libressl/ssl/tls12_key_schedule.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez  * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
4*de0e0e4dSAntonio Huete Jimenez  *
5*de0e0e4dSAntonio Huete Jimenez  * Permission to use, copy, modify, and distribute this software for any
6*de0e0e4dSAntonio Huete Jimenez  * purpose with or without fee is hereby granted, provided that the above
7*de0e0e4dSAntonio Huete Jimenez  * copyright notice and this permission notice appear in all copies.
8*de0e0e4dSAntonio Huete Jimenez  *
9*de0e0e4dSAntonio Huete Jimenez  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*de0e0e4dSAntonio Huete Jimenez  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*de0e0e4dSAntonio Huete Jimenez  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*de0e0e4dSAntonio Huete Jimenez  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*de0e0e4dSAntonio Huete Jimenez  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*de0e0e4dSAntonio Huete Jimenez  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*de0e0e4dSAntonio Huete Jimenez  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*de0e0e4dSAntonio Huete Jimenez  */
17*de0e0e4dSAntonio Huete Jimenez 
18*de0e0e4dSAntonio Huete Jimenez #include <stdlib.h>
19*de0e0e4dSAntonio Huete Jimenez 
20*de0e0e4dSAntonio Huete Jimenez #include <openssl/evp.h>
21*de0e0e4dSAntonio Huete Jimenez 
22*de0e0e4dSAntonio Huete Jimenez #include "bytestring.h"
23*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
24*de0e0e4dSAntonio Huete Jimenez 
25*de0e0e4dSAntonio Huete Jimenez struct tls12_key_block {
26*de0e0e4dSAntonio Huete Jimenez 	CBS client_write_mac_key;
27*de0e0e4dSAntonio Huete Jimenez 	CBS server_write_mac_key;
28*de0e0e4dSAntonio Huete Jimenez 	CBS client_write_key;
29*de0e0e4dSAntonio Huete Jimenez 	CBS server_write_key;
30*de0e0e4dSAntonio Huete Jimenez 	CBS client_write_iv;
31*de0e0e4dSAntonio Huete Jimenez 	CBS server_write_iv;
32*de0e0e4dSAntonio Huete Jimenez 
33*de0e0e4dSAntonio Huete Jimenez 	uint8_t *key_block;
34*de0e0e4dSAntonio Huete Jimenez 	size_t key_block_len;
35*de0e0e4dSAntonio Huete Jimenez };
36*de0e0e4dSAntonio Huete Jimenez 
37*de0e0e4dSAntonio Huete Jimenez struct tls12_key_block *
tls12_key_block_new(void)38*de0e0e4dSAntonio Huete Jimenez tls12_key_block_new(void)
39*de0e0e4dSAntonio Huete Jimenez {
40*de0e0e4dSAntonio Huete Jimenez 	return calloc(1, sizeof(struct tls12_key_block));
41*de0e0e4dSAntonio Huete Jimenez }
42*de0e0e4dSAntonio Huete Jimenez 
43*de0e0e4dSAntonio Huete Jimenez static void
tls12_key_block_clear(struct tls12_key_block * kb)44*de0e0e4dSAntonio Huete Jimenez tls12_key_block_clear(struct tls12_key_block *kb)
45*de0e0e4dSAntonio Huete Jimenez {
46*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->client_write_mac_key, NULL, 0);
47*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->server_write_mac_key, NULL, 0);
48*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->client_write_key, NULL, 0);
49*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->server_write_key, NULL, 0);
50*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->client_write_iv, NULL, 0);
51*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&kb->server_write_iv, NULL, 0);
52*de0e0e4dSAntonio Huete Jimenez 
53*de0e0e4dSAntonio Huete Jimenez 	freezero(kb->key_block, kb->key_block_len);
54*de0e0e4dSAntonio Huete Jimenez 	kb->key_block = NULL;
55*de0e0e4dSAntonio Huete Jimenez 	kb->key_block_len = 0;
56*de0e0e4dSAntonio Huete Jimenez }
57*de0e0e4dSAntonio Huete Jimenez 
58*de0e0e4dSAntonio Huete Jimenez void
tls12_key_block_free(struct tls12_key_block * kb)59*de0e0e4dSAntonio Huete Jimenez tls12_key_block_free(struct tls12_key_block *kb)
60*de0e0e4dSAntonio Huete Jimenez {
61*de0e0e4dSAntonio Huete Jimenez 	if (kb == NULL)
62*de0e0e4dSAntonio Huete Jimenez 		return;
63*de0e0e4dSAntonio Huete Jimenez 
64*de0e0e4dSAntonio Huete Jimenez 	tls12_key_block_clear(kb);
65*de0e0e4dSAntonio Huete Jimenez 
66*de0e0e4dSAntonio Huete Jimenez 	freezero(kb, sizeof(struct tls12_key_block));
67*de0e0e4dSAntonio Huete Jimenez }
68*de0e0e4dSAntonio Huete Jimenez 
69*de0e0e4dSAntonio Huete Jimenez void
tls12_key_block_client_write(struct tls12_key_block * kb,CBS * mac_key,CBS * key,CBS * iv)70*de0e0e4dSAntonio Huete Jimenez tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key,
71*de0e0e4dSAntonio Huete Jimenez     CBS *key, CBS *iv)
72*de0e0e4dSAntonio Huete Jimenez {
73*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->client_write_mac_key, mac_key);
74*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->client_write_key, key);
75*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->client_write_iv, iv);
76*de0e0e4dSAntonio Huete Jimenez }
77*de0e0e4dSAntonio Huete Jimenez 
78*de0e0e4dSAntonio Huete Jimenez void
tls12_key_block_server_write(struct tls12_key_block * kb,CBS * mac_key,CBS * key,CBS * iv)79*de0e0e4dSAntonio Huete Jimenez tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key,
80*de0e0e4dSAntonio Huete Jimenez     CBS *key, CBS *iv)
81*de0e0e4dSAntonio Huete Jimenez {
82*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->server_write_mac_key, mac_key);
83*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->server_write_key, key);
84*de0e0e4dSAntonio Huete Jimenez 	CBS_dup(&kb->server_write_iv, iv);
85*de0e0e4dSAntonio Huete Jimenez }
86*de0e0e4dSAntonio Huete Jimenez 
87*de0e0e4dSAntonio Huete Jimenez int
tls12_key_block_generate(struct tls12_key_block * kb,SSL * s,const EVP_AEAD * aead,const EVP_CIPHER * cipher,const EVP_MD * mac_hash)88*de0e0e4dSAntonio Huete Jimenez tls12_key_block_generate(struct tls12_key_block *kb, SSL *s,
89*de0e0e4dSAntonio Huete Jimenez     const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash)
90*de0e0e4dSAntonio Huete Jimenez {
91*de0e0e4dSAntonio Huete Jimenez 	size_t mac_key_len = 0, key_len = 0, iv_len = 0;
92*de0e0e4dSAntonio Huete Jimenez 	uint8_t *key_block = NULL;
93*de0e0e4dSAntonio Huete Jimenez 	size_t key_block_len = 0;
94*de0e0e4dSAntonio Huete Jimenez 	CBS cbs;
95*de0e0e4dSAntonio Huete Jimenez 
96*de0e0e4dSAntonio Huete Jimenez 	/*
97*de0e0e4dSAntonio Huete Jimenez 	 * Generate a TLSv1.2 key block and partition into individual secrets,
98*de0e0e4dSAntonio Huete Jimenez 	 * as per RFC 5246 section 6.3.
99*de0e0e4dSAntonio Huete Jimenez 	 */
100*de0e0e4dSAntonio Huete Jimenez 
101*de0e0e4dSAntonio Huete Jimenez 	tls12_key_block_clear(kb);
102*de0e0e4dSAntonio Huete Jimenez 
103*de0e0e4dSAntonio Huete Jimenez 	/* Must have AEAD or cipher/MAC pair. */
104*de0e0e4dSAntonio Huete Jimenez 	if (aead == NULL && (cipher == NULL || mac_hash == NULL))
105*de0e0e4dSAntonio Huete Jimenez 		goto err;
106*de0e0e4dSAntonio Huete Jimenez 
107*de0e0e4dSAntonio Huete Jimenez 	if (aead != NULL) {
108*de0e0e4dSAntonio Huete Jimenez 		key_len = EVP_AEAD_key_length(aead);
109*de0e0e4dSAntonio Huete Jimenez 
110*de0e0e4dSAntonio Huete Jimenez 		/* AEAD fixed nonce length. */
111*de0e0e4dSAntonio Huete Jimenez 		if (aead == EVP_aead_aes_128_gcm() ||
112*de0e0e4dSAntonio Huete Jimenez 		    aead == EVP_aead_aes_256_gcm())
113*de0e0e4dSAntonio Huete Jimenez 			iv_len = 4;
114*de0e0e4dSAntonio Huete Jimenez 		else if (aead == EVP_aead_chacha20_poly1305())
115*de0e0e4dSAntonio Huete Jimenez 			iv_len = 12;
116*de0e0e4dSAntonio Huete Jimenez 		else
117*de0e0e4dSAntonio Huete Jimenez 			goto err;
118*de0e0e4dSAntonio Huete Jimenez 	} else if (cipher != NULL && mac_hash != NULL) {
119*de0e0e4dSAntonio Huete Jimenez 		/*
120*de0e0e4dSAntonio Huete Jimenez 		 * A negative integer return value will be detected via the
121*de0e0e4dSAntonio Huete Jimenez 		 * EVP_MAX_* checks against the size_t variables below.
122*de0e0e4dSAntonio Huete Jimenez 		 */
123*de0e0e4dSAntonio Huete Jimenez 		mac_key_len = EVP_MD_size(mac_hash);
124*de0e0e4dSAntonio Huete Jimenez 		key_len = EVP_CIPHER_key_length(cipher);
125*de0e0e4dSAntonio Huete Jimenez 		iv_len = EVP_CIPHER_iv_length(cipher);
126*de0e0e4dSAntonio Huete Jimenez 
127*de0e0e4dSAntonio Huete Jimenez 		/* Special handling for GOST... */
128*de0e0e4dSAntonio Huete Jimenez 		if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC)
129*de0e0e4dSAntonio Huete Jimenez 			mac_key_len = 32;
130*de0e0e4dSAntonio Huete Jimenez 	}
131*de0e0e4dSAntonio Huete Jimenez 
132*de0e0e4dSAntonio Huete Jimenez 	if (mac_key_len > EVP_MAX_MD_SIZE)
133*de0e0e4dSAntonio Huete Jimenez 		goto err;
134*de0e0e4dSAntonio Huete Jimenez 	if (key_len > EVP_MAX_KEY_LENGTH)
135*de0e0e4dSAntonio Huete Jimenez 		goto err;
136*de0e0e4dSAntonio Huete Jimenez 	if (iv_len > EVP_MAX_IV_LENGTH)
137*de0e0e4dSAntonio Huete Jimenez 		goto err;
138*de0e0e4dSAntonio Huete Jimenez 
139*de0e0e4dSAntonio Huete Jimenez 	key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len;
140*de0e0e4dSAntonio Huete Jimenez 	if ((key_block = calloc(1, key_block_len)) == NULL)
141*de0e0e4dSAntonio Huete Jimenez 		goto err;
142*de0e0e4dSAntonio Huete Jimenez 
143*de0e0e4dSAntonio Huete Jimenez 	if (!tls1_generate_key_block(s, key_block, key_block_len))
144*de0e0e4dSAntonio Huete Jimenez 		goto err;
145*de0e0e4dSAntonio Huete Jimenez 
146*de0e0e4dSAntonio Huete Jimenez 	kb->key_block = key_block;
147*de0e0e4dSAntonio Huete Jimenez 	kb->key_block_len = key_block_len;
148*de0e0e4dSAntonio Huete Jimenez 	key_block = NULL;
149*de0e0e4dSAntonio Huete Jimenez 	key_block_len = 0;
150*de0e0e4dSAntonio Huete Jimenez 
151*de0e0e4dSAntonio Huete Jimenez 	/* Partition key block into individual secrets. */
152*de0e0e4dSAntonio Huete Jimenez 	CBS_init(&cbs, kb->key_block, kb->key_block_len);
153*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len))
154*de0e0e4dSAntonio Huete Jimenez 		goto err;
155*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len))
156*de0e0e4dSAntonio Huete Jimenez 		goto err;
157*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len))
158*de0e0e4dSAntonio Huete Jimenez 		goto err;
159*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len))
160*de0e0e4dSAntonio Huete Jimenez 		goto err;
161*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len))
162*de0e0e4dSAntonio Huete Jimenez 		goto err;
163*de0e0e4dSAntonio Huete Jimenez 	if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len))
164*de0e0e4dSAntonio Huete Jimenez 		goto err;
165*de0e0e4dSAntonio Huete Jimenez 	if (CBS_len(&cbs) != 0)
166*de0e0e4dSAntonio Huete Jimenez 		goto err;
167*de0e0e4dSAntonio Huete Jimenez 
168*de0e0e4dSAntonio Huete Jimenez 	return 1;
169*de0e0e4dSAntonio Huete Jimenez 
170*de0e0e4dSAntonio Huete Jimenez  err:
171*de0e0e4dSAntonio Huete Jimenez 	tls12_key_block_clear(kb);
172*de0e0e4dSAntonio Huete Jimenez 	freezero(key_block, key_block_len);
173*de0e0e4dSAntonio Huete Jimenez 
174*de0e0e4dSAntonio Huete Jimenez 	return 0;
175*de0e0e4dSAntonio Huete Jimenez }
176