1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/*
2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TLSv1 Record Protocol
3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify
6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as
7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation.
8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD
10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license.
11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details.
13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h"
16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h"
18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "md5.h"
19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "sha1.h"
20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "tlsv1_common.h"
21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "tlsv1_record.h"
22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_set_cipher_suite - TLS record layer: Set cipher suite
26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @rl: Pointer to TLS record layer data
27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @cipher_suite: New cipher suite
28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure
29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function is used to prepare TLS record layer for cipher suite change.
31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_change_write_cipher() and
32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_change_read_cipher() functions can then be used to change the
33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * currently used ciphers.
34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				  u16 cipher_suite)
37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const struct tls_cipher_suite *suite;
39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	const struct tls_cipher_data *data;
40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x",
42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		   cipher_suite);
43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->cipher_suite = cipher_suite;
44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	suite = tls_get_cipher_suite(cipher_suite);
46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (suite == NULL)
47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (suite->hash == TLS_HASH_MD5) {
50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5;
51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->hash_size = MD5_MAC_LEN;
52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	} else if (suite->hash == TLS_HASH_SHA) {
53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1;
54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->hash_size = SHA1_MAC_LEN;
55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	data = tls_get_cipher_data(suite->cipher);
58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (data == NULL)
59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->key_material_len = data->key_material;
62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->iv_size = data->block_size;
63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->cipher_alg = data->alg;
64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_change_write_cipher - TLS record layer: Change write cipher
71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @rl: Pointer to TLS record layer data
72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success (cipher changed), -1 on failure
73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function changes TLS record layer to use the new cipher suite
75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * configured with tlsv1_record_set_cipher_suite() for writing.
76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl)
78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite "
80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		   "0x%04x", rl->cipher_suite);
81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->write_cipher_suite = rl->cipher_suite;
82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN);
83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->write_cbc) {
85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_cipher_deinit(rl->write_cbc);
86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->write_cbc = NULL;
87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->write_cbc = crypto_cipher_init(rl->cipher_alg,
90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						   rl->write_iv, rl->write_key,
91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						   rl->key_material_len);
92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (rl->write_cbc == NULL) {
93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "cipher");
95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_change_read_cipher - TLS record layer: Change read cipher
105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @rl: Pointer to TLS record layer data
106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success (cipher changed), -1 on failure
107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function changes TLS record layer to use the new cipher suite
109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * configured with tlsv1_record_set_cipher_suite() for reading.
110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite "
114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		   "0x%04x", rl->cipher_suite);
115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rl->read_cipher_suite = rl->cipher_suite;
116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN);
117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->read_cbc) {
119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_cipher_deinit(rl->read_cbc);
120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->read_cbc = NULL;
121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		rl->read_cbc = crypto_cipher_init(rl->cipher_alg,
124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						  rl->read_iv, rl->read_key,
125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						  rl->key_material_len);
126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (rl->read_cbc == NULL) {
127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "cipher");
129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_send - TLS record layer: Send a message
139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @rl: Pointer to TLS record layer data
140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @content_type: Content type (TLS_CONTENT_TYPE_*)
141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf: Buffer to send (with TLS_RECORD_HEADER_LEN octets reserved in the
142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * beginning for record layer to fill in; payload filled in after this and
143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * extra space in the end for HMAC).
144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @buf_size: Maximum buf size
145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @payload_len: Length of the payload
146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @out_len: Buffer for returning the used buf length
147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure
148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function fills in the TLS record layer header, adds HMAC, and encrypts
150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * the data using the current write cipher.
151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		      size_t buf_size, size_t payload_len, size_t *out_len)
154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 *pos, *ct_start, *length, *payload;
156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	struct crypto_hash *hmac;
157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t clen;
158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos = buf;
160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* ContentType type */
161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	ct_start = pos;
162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	*pos++ = content_type;
163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* ProtocolVersion version */
164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	WPA_PUT_BE16(pos, TLS_VERSION);
165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos += 2;
166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* uint16 length */
167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	length = pos;
168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	WPA_PUT_BE16(length, payload_len);
169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos += 2;
170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* opaque fragment[TLSPlaintext.length] */
172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	payload = pos;
173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	pos += payload_len;
174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					rl->hash_size);
178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (hmac == NULL) {
179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "to initialize HMAC");
181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* type + version + length + fragment */
185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, ct_start, pos - ct_start);
186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		clen = buf + buf_size - pos;
187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (clen < rl->hash_size) {
188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "enough room for MAC");
190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			crypto_hash_finish(hmac, NULL, NULL);
191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (crypto_hash_finish(hmac, pos, &clen) < 0) {
195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "to calculate HMAC");
197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC",
200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			    pos, clen);
201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		pos += clen;
202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (rl->iv_size) {
203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			size_t len = pos - payload;
204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			size_t pad;
205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			pad = (len + 1) % rl->iv_size;
206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (pad)
207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				pad = rl->iv_size - pad;
208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (pos + pad + 1 > buf + buf_size) {
209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				wpa_printf(MSG_DEBUG, "TLSv1: No room for "
210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					   "block cipher padding");
211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				return -1;
212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			}
213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			os_memset(pos, pad, pad + 1);
214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			pos += pad + 1;
215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (crypto_cipher_encrypt(rl->write_cbc, payload,
218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					  payload, pos - payload) < 0)
219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	WPA_PUT_BE16(length, pos - length - 2);
223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN);
224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	*out_len = pos - buf;
226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/**
232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * tlsv1_record_receive - TLS record layer: Process a received message
233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @rl: Pointer to TLS record layer data
234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @in_data: Received data
235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @in_len: Length of the received data
236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @out_data: Buffer for output data (must be at least as long as in_data)
237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @out_len: Set to maximum out_data length by caller; used to return the
238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * length of the used data
239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @alert: Buffer for returning an alert value on failure
240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure
241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *
242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function decrypts the received message, verifies HMAC and TLS record
243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * layer header.
244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */
245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tlsv1_record_receive(struct tlsv1_record_layer *rl,
246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			 const u8 *in_data, size_t in_len,
247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			 u8 *out_data, size_t *out_len, u8 *alert)
248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{
249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	size_t i, rlen, hlen;
250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 padlen;
251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	struct crypto_hash *hmac;
252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	u8 len[2], hash[100];
253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		    in_data, in_len);
256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (in_len < TLS_RECORD_HEADER_LEN) {
258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   (unsigned long) in_len);
260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_DECODE_ERROR;
261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		   "length %d", in_data[0], in_data[1], in_data[2],
266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		   WPA_GET_BE16(in_data + 3));
267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    in_data[0] != TLS_CONTENT_TYPE_ALERT &&
271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	    in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   in_data[0]);
274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_UNEXPECTED_MESSAGE;
275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (WPA_GET_BE16(in_data + 1) != TLS_VERSION) {
279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version "
280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   "%d.%d", in_data[1], in_data[2]);
281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_PROTOCOL_VERSION;
282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	rlen = WPA_GET_BE16(in_data + 3);
286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* TLSCiphertext must not be more than 2^14+2048 bytes */
288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   (unsigned long) (TLS_RECORD_HEADER_LEN + rlen));
291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_RECORD_OVERFLOW;
292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	in_data += TLS_RECORD_HEADER_LEN;
296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	in_len -= TLS_RECORD_HEADER_LEN;
297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rlen > in_len) {
299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   "(rlen=%lu > in_len=%lu)",
301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   (unsigned long) rlen, (unsigned long) in_len);
302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_DECODE_ERROR;
303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	in_len = rlen;
307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (*out_len < in_len) {
309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for "
310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   "processing received record");
311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_INTERNAL_ERROR;
312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	os_memcpy(out_data, in_data, in_len);
316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	*out_len = in_len;
317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (crypto_cipher_decrypt(rl->read_cbc, out_data,
320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					  out_data, in_len) < 0) {
321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*alert = TLS_ALERT_DECRYPTION_FAILED;
322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (rl->iv_size) {
325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (in_len == 0) {
326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				wpa_printf(MSG_DEBUG, "TLSv1: Too short record"
327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					   " (no pad)");
328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				*alert = TLS_ALERT_DECODE_ERROR;
329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				return -1;
330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			}
331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			padlen = out_data[in_len - 1];
332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			if (padlen >= in_len) {
333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad "
334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					   "length (%u, in_len=%lu) in "
335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					   "received record",
336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					   padlen, (unsigned long) in_len);
337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				*alert = TLS_ALERT_DECRYPTION_FAILED;
338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				return -1;
339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			}
340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			for (i = in_len - padlen; i < in_len; i++) {
341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				if (out_data[i] != padlen) {
342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					wpa_hexdump(MSG_DEBUG,
343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						    "TLSv1: Invalid pad in "
344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						    "received record",
345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						    out_data + in_len - padlen,
346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt						    padlen);
347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					*alert = TLS_ALERT_DECRYPTION_FAILED;
348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					return -1;
349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				}
350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			}
351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*out_len -= padlen + 1;
353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_hexdump(MSG_MSGDUMP,
356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			    "TLSv1: Record Layer - Decrypted data",
357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			    out_data, in_len);
358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (*out_len < rl->hash_size) {
360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "hash value");
362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*alert = TLS_ALERT_INTERNAL_ERROR;
363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*out_len -= rl->hash_size;
367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret,
369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt					rl->hash_size);
370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (hmac == NULL) {
371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "to initialize HMAC");
373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*alert = TLS_ALERT_INTERNAL_ERROR;
374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN);
378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		/* type + version + length + fragment */
379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3);
380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		WPA_PUT_BE16(len, *out_len);
381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, len, 2);
382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		crypto_hash_update(hmac, out_data, *out_len);
383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		hlen = sizeof(hash);
384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (crypto_hash_finish(hmac, hash, &hlen) < 0) {
385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "to calculate HMAC");
387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		if (hlen != rl->hash_size ||
390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		    os_memcmp(hash, out_data + *out_len, hlen) != 0) {
391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt				   "received message");
393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			*alert = TLS_ALERT_BAD_RECORD_MAC;
394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			return -1;
395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		}
396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	/* TLSCompressed must not be more than 2^14+1024 bytes */
399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	if (TLS_RECORD_HEADER_LEN + *out_len > 17408) {
400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt			   (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len));
402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		*alert = TLS_ALERT_RECORD_OVERFLOW;
403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt		return -1;
404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	}
405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt
408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt	return 0;
409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}
410