18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLSv1 Record Protocol 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/md5.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha256.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_set_cipher_suite - TLS record layer: Set cipher suite 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rl: Pointer to TLS record layer data 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cipher_suite: New cipher suite 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to prepare TLS record layer for cipher suite change. 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_change_write_cipher() and 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_change_read_cipher() functions can then be used to change the 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * currently used ciphers. 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl, 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 cipher_suite) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_suite *suite; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_cipher_data *data; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x", 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher_suite); 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->cipher_suite = cipher_suite; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suite = tls_get_cipher_suite(cipher_suite); 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite == NULL) 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (suite->hash == TLS_HASH_MD5) { 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_size = MD5_MAC_LEN; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (suite->hash == TLS_HASH_SHA) { 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_size = SHA1_MAC_LEN; 501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (suite->hash == TLS_HASH_SHA256) { 511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA256; 521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rl->hash_size = SHA256_MAC_LEN; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = tls_get_cipher_data(suite->cipher); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->key_material_len = data->key_material; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->iv_size = data->block_size; 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->cipher_alg = data->alg; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_change_write_cipher - TLS record layer: Change write cipher 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rl: Pointer to TLS record layer data 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success (cipher changed), -1 on failure 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function changes TLS record layer to use the new cipher suite 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured with tlsv1_record_set_cipher_suite() for writing. 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite " 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%04x", rl->cipher_suite); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->write_cipher_suite = rl->cipher_suite; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN); 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->write_cbc) { 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_cipher_deinit(rl->write_cbc); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->write_cbc = NULL; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->cipher_alg != CRYPTO_CIPHER_NULL) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->write_cbc = crypto_cipher_init(rl->cipher_alg, 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->write_iv, rl->write_key, 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->key_material_len); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->write_cbc == NULL) { 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize " 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher"); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_change_read_cipher - TLS record layer: Change read cipher 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rl: Pointer to TLS record layer data 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success (cipher changed), -1 on failure 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function changes TLS record layer to use the new cipher suite 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configured with tlsv1_record_set_cipher_suite() for reading. 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite " 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%04x", rl->cipher_suite); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->read_cipher_suite = rl->cipher_suite; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->read_cbc) { 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_cipher_deinit(rl->read_cbc); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->read_cbc = NULL; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->cipher_alg != CRYPTO_CIPHER_NULL) { 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->read_cbc = crypto_cipher_init(rl->cipher_alg, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->read_iv, rl->read_key, 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->key_material_len); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->read_cbc == NULL) { 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize " 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "cipher"); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_send - TLS record layer: Send a message 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rl: Pointer to TLS record layer data 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @content_type: Content type (TLS_CONTENT_TYPE_*) 1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @buf: Buffer for the generated TLS message (needs to have extra space for 1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * header, IV (TLS v1.1), and HMAC) 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf_size: Maximum buf size 1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @payload: Payload to be sent 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @payload_len: Length of the payload 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Buffer for returning the used buf length 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function fills in the TLS record layer header, adds HMAC, and encrypts 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the data using the current write cipher. 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf, 1511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t buf_size, const u8 *payload, size_t payload_len, 1521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t *out_len) 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos, *ct_start, *length, *cpayload; 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_hash *hmac; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t clen; 1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int explicit_iv; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = buf; 1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + TLS_RECORD_HEADER_LEN > buf + buf_size) 1611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ContentType type */ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ct_start = pos; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = content_type; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* ProtocolVersion version */ 1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE16(pos, rl->tls_version); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* uint16 length */ 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt length = pos; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(length, payload_len); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cpayload = pos; 1751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt explicit_iv = rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL && 1761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rl->iv_size && rl->tls_version >= TLS_VERSION_1_1; 1771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (explicit_iv) { 1781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* opaque IV[Cipherspec.block_length] */ 1791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + rl->iv_size > buf + buf_size) 1801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 1831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Use random number R per the RFC 4346, 6.2.3.2 CBC Block 1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Cipher option 2a. 1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (os_get_random(pos, rl->iv_size)) 1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += rl->iv_size; 1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * opaque fragment[TLSPlaintext.length] 1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * (opaque content[TLSCompressed.length] in GenericBlockCipher) 1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (pos + payload_len > buf + buf_size) 1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memmove(pos, payload, payload_len); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += payload_len; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) { 2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * MAC calculated over seq_num + TLSCompressed.type + 2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLSCompressed.version + TLSCompressed.length + 2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLSCompressed.fragment 2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret, 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_size); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac == NULL) { 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to initialize HMAC"); 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* type + version + length + fragment */ 2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_update(hmac, ct_start, TLS_RECORD_HEADER_LEN); 2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_update(hmac, payload, payload_len); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clen = buf + buf_size - pos; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (clen < rl->hash_size) { 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not " 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "enough room for MAC"); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_finish(hmac, NULL, NULL); 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_hash_finish(hmac, pos, &clen) < 0) { 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to calculate HMAC"); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC", 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, clen); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += clen; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->iv_size) { 2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t len = pos - cpayload; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pad; 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pad = (len + 1) % rl->iv_size; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pad) 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pad = rl->iv_size - pad; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + pad + 1 > buf + buf_size) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No room for " 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "block cipher padding"); 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, pad, pad + 1); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += pad + 1; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (crypto_cipher_encrypt(rl->write_cbc, cpayload, 2501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt cpayload, pos - cpayload) < 0) 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(length, pos - length - 2); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN); 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_len = pos - buf; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_record_receive - TLS record layer: Process a received message 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rl: Pointer to TLS record layer data 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Received data 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Length of the received data 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Buffer for output data (must be at least as long as in_data) 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Set to maximum out_data length by caller; used to return the 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * length of the used data 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @alert: Buffer for returning an alert value on failure 2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: Number of bytes used from in_data on success, 0 if record was not 2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * complete (more data needed), or -1 on failure 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function decrypts the received message, verifies HMAC and TLS record 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * layer header. 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_record_receive(struct tlsv1_record_layer *rl, 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t in_len, 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out_data, size_t *out_len, u8 *alert) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, rlen, hlen; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 padlen; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_hash *hmac; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 len[2], hash[100]; 2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int force_mac_error = 0; 2871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 ct; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_len < TLS_RECORD_HEADER_LEN) { 2901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu) - " 2911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "need more data", 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) in_len); 2931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received", 2941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt in_data, in_len); 2951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ct = in_data[0]; 2991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt rlen = WPA_GET_BE16(in_data + 3); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d " 3011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "length %d", ct, in_data[1], in_data[2], (int) rlen); 3021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 3041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.0 and v1.1 RFCs were not exactly clear on the use of the 3051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * protocol version in record layer. As such, accept any {03,xx} value 3061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * to remain compatible with existing implementations. 3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 3081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (in_data[1] != 0x03) { 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version " 3101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "%u.%u", in_data[1], in_data[2]); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_PROTOCOL_VERSION; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLSCiphertext must not be more than 2^14+2048 bytes */ 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TLS_RECORD_HEADER_LEN + rlen > 18432) { 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)", 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (TLS_RECORD_HEADER_LEN + rlen)); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_RECORD_OVERFLOW; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_data += TLS_RECORD_HEADER_LEN; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len -= TLS_RECORD_HEADER_LEN; 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rlen > in_len) { 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included " 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(rlen=%lu > in_len=%lu)", 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) rlen, (unsigned long) in_len); 3301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return 0; 3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received", 3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt in_data, rlen); 3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ct != TLS_CONTENT_TYPE_HANDSHAKE && 3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC && 3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ct != TLS_CONTENT_TYPE_ALERT && 3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ct != TLS_CONTENT_TYPE_APPLICATION_DATA) { 3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Ignore record with unknown " 3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "content type 0x%x", ct); 3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *alert = TLS_ALERT_UNEXPECTED_MESSAGE; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len = rlen; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*out_len < in_len) { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for " 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "processing received record"); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_INTERNAL_ERROR; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) { 3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt size_t plen; 3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (crypto_cipher_decrypt(rl->read_cbc, in_data, 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data, in_len) < 0) { 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_DECRYPTION_FAILED; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt plen = in_len; 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Record Layer - Decrypted " 3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "data", out_data, plen); 3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rl->iv_size) { 3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.0 defines different alert values for various 3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * failures. That may information to aid in attacks, so 3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * use the same bad_record_mac alert regardless of the 3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * issues. 3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * In addition, instead of returning immediately on 3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * error, run through the MAC check to make timing 3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * attacks more difficult. 3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (rl->tls_version >= TLS_VERSION_1_1) { 3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Remove opaque IV[Cipherspec.block_length] */ 3801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (plen < rl->iv_size) { 3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1.1: Not " 3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "enough room for IV"); 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error = 1; 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto check_mac; 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memmove(out_data, out_data + rl->iv_size, 3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt plen - rl->iv_size); 3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt plen -= rl->iv_size; 3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Verify and remove padding */ 3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (plen == 0) { 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record" 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (no pad)"); 3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error = 1; 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto check_mac; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt padlen = out_data[plen - 1]; 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (padlen >= plen) { 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad " 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "length (%u, plen=%lu) in " 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received record", 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt padlen, (unsigned long) plen); 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error = 1; 4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto check_mac; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt for (i = plen - padlen - 1; i < plen - 1; i++) { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_data[i] != padlen) { 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLSv1: Invalid pad in " 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "received record", 4121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt out_data + plen - padlen - 4131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 1, padlen + 1); 4141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error = 1; 4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto check_mac; 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt plen -= padlen + 1; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Record Layer - " 4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "Decrypted data with IV and padding " 4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "removed", out_data, plen); 4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt check_mac: 4271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (plen < rl->hash_size) { 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no " 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash value"); 4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *alert = TLS_ALERT_BAD_RECORD_MAC; 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt plen -= rl->hash_size; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret, 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rl->hash_size); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac == NULL) { 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to initialize HMAC"); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_INTERNAL_ERROR; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN); 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* type + version + length + fragment */ 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3); 4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt WPA_PUT_BE16(len, plen); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_hash_update(hmac, len, 2); 4501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt crypto_hash_update(hmac, out_data, plen); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hlen = sizeof(hash); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (crypto_hash_finish(hmac, hash, &hlen) < 0) { 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed " 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to calculate HMAC"); 4551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *alert = TLS_ALERT_INTERNAL_ERROR; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hlen != rl->hash_size || 459c28170251eb54dbf64a9074a07fee377587425b2Dmitry Shmidt os_memcmp_const(hash, out_data + plen, hlen) != 0 || 4601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error) { 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in " 4621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "received message (force_mac_error=%d)", 4631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt force_mac_error); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_BAD_RECORD_MAC; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 4681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *out_len = plen; 4691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else { 4701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memcpy(out_data, in_data, in_len); 4711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *out_len = in_len; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLSCompressed must not be more than 2^14+1024 bytes */ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (TLS_RECORD_HEADER_LEN + *out_len > 17408) { 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)", 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len)); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *alert = TLS_ALERT_RECORD_OVERFLOW; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN); 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return TLS_RECORD_HEADER_LEN + rlen; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 486