18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 21f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246) 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/sha1.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_record.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tlsv1_server_i.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* TODO: 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Support for a message fragmented across several records (RFC 2246, 6.2.1) 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description) 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->alert_level = level; 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->alert_description = description; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_derive_keys(struct tlsv1_server *conn, 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pre_master_secret, 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pre_master_secret_len) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 seed[2 * TLS_RANDOM_LEN]; 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 key_block[TLS_MAX_KEY_BLOCK_LEN]; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_block_len; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pre_master_secret) { 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret", 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pre_master_secret, pre_master_secret_len); 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random, 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_RANDOM_LEN); 461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pre_master_secret, pre_master_secret_len, 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "master secret", seed, 2 * TLS_RANDOM_LEN, 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN)) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive " 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "master_secret"); 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret", 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN); 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN); 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len + 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->rl.iv_size); 621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf(conn->rl.tls_version, 631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key expansion", seed, 2 * TLS_RANDOM_LEN, 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_block, key_block_len)) { 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block"); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block", 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key_block, key_block_len); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = key_block; 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* client_write_MAC_secret */ 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.hash_size; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* server_write_MAC_secret */ 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size); 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.hash_size; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* client_write_key */ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.key_material_len; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* server_write_key */ 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len); 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.key_material_len; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* client_write_IV */ 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.iv_size; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* server_write_IV */ 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += conn->rl.iv_size; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_handshake - Process TLS handshake 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Input data from TLS peer 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input data length 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Length of the output buffer. 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to output data, %NULL on failure 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_handshake(struct tlsv1_server *conn, 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t in_len, 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *out_len) 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t in_msg_len; 1141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int used; 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data == NULL || in_len == 0) { 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: No input data to server"); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = in_data + in_len; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_msg = os_malloc(in_len); 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_msg == NULL) 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Each received packet may include multiple records */ 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < end) { 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_msg_len = in_len; 1301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt used = tlsv1_record_receive(&conn->rl, pos, end - pos, 1311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt in_msg, &in_msg_len, &alert); 1321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (used < 0) { 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Processing received " 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "record failed"); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (used == 0) { 1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* need more data */ 1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not " 1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "yet supported"); 1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert); 1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto failed; 1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ct = pos[0]; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_pos = in_msg; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_end = in_msg + in_msg_len; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Each received record may include multiple messages of the 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * same ContentType. */ 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (in_pos < in_end) { 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_msg_len = in_end - in_pos; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_server_process_handshake(conn, ct, in_pos, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &in_msg_len) < 0) 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto failed; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_pos += in_msg_len; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += used; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(in_msg); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_msg = NULL; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = tlsv1_server_handshake_write(conn, out_len); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed: 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(in_msg); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->alert_level) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state == FAILED) { 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Avoid alert loops */ 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop"); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = FAILED; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(msg); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = tlsv1_server_send_alert(conn, conn->alert_level, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->alert_description, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_len); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return msg; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_encrypt - Encrypt data into TLS tunnel 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Pointer to plaintext data to be encrypted 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input buffer length 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Pointer to output buffer (encrypted TLS data) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Maximum out_data length 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to out_data, -1 on failure 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used after TLS handshake has been completed successfully to 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * send data in the encrypted tunnel. 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_encrypt(struct tlsv1_server *conn, 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t in_len, 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out_data, size_t out_len) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t rlen; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData", 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_data, in_len); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA, 2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt out_data, out_len, in_data, in_len, &rlen) < 0) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record"); 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return rlen; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_decrypt - Decrypt data from TLS tunnel 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Pointer to input buffer (encrypted TLS data) 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input buffer length 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Pointer to output buffer (decrypted data from TLS tunnel) 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Maximum out_data length 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to out_data, -1 on failure 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used after TLS handshake has been completed successfully to 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * receive data from the encrypted tunnel. 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_decrypt(struct tlsv1_server *conn, 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_data, size_t in_len, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out_data, size_t out_len) 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in_end, *pos; 2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt int used; 2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 alert, *out_end, *out_pos, ct; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t olen; 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = in_data; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_end = in_data + in_len; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_pos = out_data; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_end = out_data + out_len; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < in_end) { 2481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ct = pos[0]; 2491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt olen = out_end - out_pos; 2501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt used = tlsv1_record_receive(&conn->rl, pos, in_end - pos, 2511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt out_pos, &olen, &alert); 2521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (used < 0) { 2531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing " 2541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "failed"); 2551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert); 2561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (used == 0) { 2591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* need more data */ 2601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not " 2611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "yet supported"); 2621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert); 2631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ct == TLS_CONTENT_TYPE_ALERT) { 2671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (olen < 2) { 2681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Alert " 2691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "underflow"); 2701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt TLS_ALERT_DECODE_ERROR); 2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d", 2751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt out_pos[0], out_pos[1]); 2761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) { 2771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* Continue processing */ 2781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += used; 2791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt continue; 2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt out_pos[1]); 2841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return -1; 2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 2871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) { 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type " 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%x", pos[0]); 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_UNEXPECTED_MESSAGE); 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_pos += olen; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_pos > out_end) { 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough " 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for processing the received record"); 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_ALERT_INTERNAL_ERROR); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += used; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_pos - out_data; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_global_init - Initialize TLSv1 server 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function must be called before using any other TLSv1 server functions. 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_global_init(void) 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return crypto_global_init(); 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_global_deinit - Deinitialize TLSv1 server 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to deinitialize the TLSv1 server that was 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called after this before calling tlsv1_server_global_init() again. 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_global_deinit(void) 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_global_deinit(); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_init - Initialize TLSv1 server connection 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cred: Pointer to server credentials from tlsv1_server_cred_alloc() 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to TLSv1 server connection data or %NULL on failure 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred) 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tlsv1_server *conn; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 *suites; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->cred = cred; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_HELLO; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_verify_hash_init(&conn->verify) < 0) { 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify " 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash"); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites = conn->cipher_suites; 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA; 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_RC4_128_SHA; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_RC4_128_MD5; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->num_cipher_suites = count; 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tlsv1_server_clear_data(struct tlsv1_server *conn) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL); 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_record_change_write_cipher(&conn->rl); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_record_change_read_cipher(&conn->rl); 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_verify_hash_free(&conn->verify); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt crypto_public_key_free(conn->client_rsa_key); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->client_rsa_key = NULL; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->session_ticket); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket = NULL; 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_len = 0; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->use_session_ticket = 0; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->dh_secret); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret = NULL; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->dh_secret_len = 0; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_deinit - Deinitialize TLSv1 server connection 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_deinit(struct tlsv1_server *conn) 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_clear_data(conn); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_established - Check whether connection has been established 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if connection is established, 0 if not 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_established(struct tlsv1_server *conn) 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->state == ESTABLISHED; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_prf - Use TLS-PRF to derive keying material 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @label: Label (e.g., description of the key) for PRF 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @server_random_first: seed is 0 = client_random|server_random, 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1 = server_random|client_random 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out: Buffer for output data from TLS-PRF 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Length of the output buffer 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_prf(struct tlsv1_server *conn, const char *label, 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server_random_first, u8 *out, size_t out_len) 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 seed[2 * TLS_RANDOM_LEN]; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state != ESTABLISHED) 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (server_random_first) { 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_RANDOM_LEN); 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN); 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random, 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TLS_RANDOM_LEN); 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return tls_prf(conn->rl.tls_version, 4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt conn->master_secret, TLS_MASTER_SECRET_LEN, 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt label, seed, 2 * TLS_RANDOM_LEN, out, out_len); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_cipher - Get current cipher name 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the cipher name 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: buf size 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Get the name of the currently used cipher. 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf, 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen) 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *cipher; 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (conn->rl.cipher_suite) { 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_RC4_128_MD5: 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "RC4-MD5"; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_RC4_128_SHA: 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "RC4-SHA"; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_DES_CBC_SHA: 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "DES-CBC-SHA"; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_3DES_EDE_CBC_SHA: 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "DES-CBC3-SHA"; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_DH_anon_WITH_AES_128_CBC_SHA: 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "ADH-AES-128-SHA"; 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_AES_256_CBC_SHA: 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "AES-256-SHA"; 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case TLS_RSA_WITH_AES_128_CBC_SHA: 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cipher = "AES-128-SHA"; 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strlcpy(buf, cipher, buflen) >= buflen) 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_shutdown - Shutdown TLS connection 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_shutdown(struct tlsv1_server *conn) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->state = CLIENT_HELLO; 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_verify_hash_init(&conn->verify) < 0) { 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify " 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash"); 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_clear_data(conn); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_resumed - Was session resumption used 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if current session used session resumption, 0 if not 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_resumed(struct tlsv1_server *conn) 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_keys - Get master key and random data from TLS connection 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @keys: Structure of key/random data (filled on success) 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys) 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state == CLIENT_HELLO) 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random = conn->client_random; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->client_random_len = TLS_RANDOM_LEN; 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state != SERVER_HELLO) { 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random = conn->server_random; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->server_random_len = TLS_RANDOM_LEN; 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->master_key = conn->master_secret; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys->master_key_len = TLS_MASTER_SECRET_LEN; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_keyblock_size - Get TLS key_block size 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Size of the key_block for the negotiated cipher suite or -1 on 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_keyblock_size(struct tlsv1_server *conn) 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO) 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2 * (conn->rl.hash_size + conn->rl.key_material_len + 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->rl.iv_size); 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_set_cipher_list - Configure acceptable cipher suites 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init() 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (TLS_CIPHER_*). 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers) 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t count; 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u16 *suites; 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: implement proper configuration of cipher suites */ 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) { 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count = 0; 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites = conn->cipher_suites; 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA; 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA; 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA; 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_RC4_128_SHA; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_RSA_WITH_RC4_128_MD5; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA; 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->num_cipher_suites = count; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer) 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify_peer = verify_peer; 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn, 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tlsv1_server_session_ticket_cb cb, 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *ctx) 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)", 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cb, ctx); 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb = cb; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->session_ticket_cb_ctx = ctx; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 621