18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
21f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
3818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt * Copyright (c) 2006-2014, 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
24818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid tlsv1_server_log(struct tlsv1_server *conn, const char *fmt, ...)
25818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{
26818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	va_list ap;
27818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	char *buf;
28818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	int buflen;
29818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
30818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	va_start(ap, fmt);
31818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
32818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	va_end(ap);
33818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
34818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	buf = os_malloc(buflen);
35818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	if (buf == NULL)
36818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		return;
37818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	va_start(ap, fmt);
38818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	vsnprintf(buf, buflen, fmt, ap);
39818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	va_end(ap);
40818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
41818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: %s", buf);
42818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	if (conn->log_cb)
43818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		conn->log_cb(conn->log_cb_ctx, buf);
44818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
45818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	os_free(buf);
46818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt}
47818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
48818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->alert_level = level;
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->alert_description = description;
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_derive_keys(struct tlsv1_server *conn,
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *pre_master_secret,
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     size_t pre_master_secret_len)
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 seed[2 * TLS_RANDOM_LEN];
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *pos;
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t key_block_len;
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pre_master_secret) {
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				pre_master_secret, pre_master_secret_len);
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  TLS_RANDOM_LEN);
711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (tls_prf(conn->rl.tls_version,
721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			    pre_master_secret, pre_master_secret_len,
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    "master secret", seed, 2 * TLS_RANDOM_LEN,
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    conn->master_secret, TLS_MASTER_SECRET_LEN)) {
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "master_secret");
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				conn->master_secret, TLS_MASTER_SECRET_LEN);
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     conn->rl.iv_size);
871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (tls_prf(conn->rl.tls_version,
881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    conn->master_secret, TLS_MASTER_SECRET_LEN,
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    "key expansion", seed, 2 * TLS_RANDOM_LEN,
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    key_block, key_block_len)) {
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			key_block, key_block_len);
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = key_block;
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* client_write_MAC_secret */
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.hash_size;
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* server_write_MAC_secret */
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.hash_size;
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* client_write_key */
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.key_material_len;
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* server_write_key */
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.key_material_len;
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* client_write_IV */
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.iv_size;
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* server_write_IV */
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += conn->rl.iv_size;
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_handshake - Process TLS handshake
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Input data from TLS peer
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input data length
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Length of the output buffer.
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to output data, %NULL on failure
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * tlsv1_server_handshake(struct tlsv1_server *conn,
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    const u8 *in_data, size_t in_len,
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    size_t *out_len)
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *pos, *end;
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t in_msg_len;
1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int used;
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (in_data == NULL || in_len == 0) {
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = in_data;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	end = in_data + in_len;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	in_msg = os_malloc(in_len);
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (in_msg == NULL)
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Each received packet may include multiple records */
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos < end) {
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		in_msg_len = in_len;
1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		used = tlsv1_record_receive(&conn->rl, pos, end - pos,
1561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					    in_msg, &in_msg_len, &alert);
1571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (used < 0) {
1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "record failed");
1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto failed;
1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (used == 0) {
1641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* need more data */
1651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
1661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "yet supported");
1671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
1681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto failed;
1691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ct = pos[0];
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		in_pos = in_msg;
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		in_end = in_msg + in_msg_len;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Each received record may include multiple messages of the
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * same ContentType. */
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (in_pos < in_end) {
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			in_msg_len = in_end - in_pos;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (tlsv1_server_process_handshake(conn, ct, in_pos,
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt							   &in_msg_len) < 0)
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				goto failed;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			in_pos += in_msg_len;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos += used;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(in_msg);
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	in_msg = NULL;
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	msg = tlsv1_server_handshake_write(conn, out_len);
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfailed:
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(in_msg);
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn->alert_level) {
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (conn->state == FAILED) {
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Avoid alert loops */
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(msg);
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return NULL;
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conn->state = FAILED;
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(msg);
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		msg = tlsv1_server_send_alert(conn, conn->alert_level,
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      conn->alert_description,
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      out_len);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return msg;
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_encrypt - Encrypt data into TLS tunnel
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Pointer to plaintext data to be encrypted
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input buffer length
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Pointer to output buffer (encrypted TLS data)
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Maximum out_data length
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to out_data, -1 on failure
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used after TLS handshake has been completed successfully to
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * send data in the encrypted tunnel.
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_encrypt(struct tlsv1_server *conn,
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 const u8 *in_data, size_t in_len,
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 u8 *out_data, size_t out_len)
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t rlen;
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			in_data, in_len);
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      out_data, out_len, in_data, in_len, &rlen) < 0) {
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   TLS_ALERT_INTERNAL_ERROR);
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return rlen;
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_decrypt - Decrypt data from TLS tunnel
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Pointer to input buffer (encrypted TLS data)
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_len: Input buffer length
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Pointer to output buffer (decrypted data from TLS tunnel)
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Maximum out_data length
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to out_data, -1 on failure
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used after TLS handshake has been completed successfully to
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * receive data from the encrypted tunnel.
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_decrypt(struct tlsv1_server *conn,
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 const u8 *in_data, size_t in_len,
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 u8 *out_data, size_t out_len)
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *in_end, *pos;
2631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int used;
2641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 alert, *out_end, *out_pos, ct;
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t olen;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos = in_data;
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	in_end = in_data + in_len;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	out_pos = out_data;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	out_end = out_data + out_len;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (pos < in_end) {
2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ct = pos[0];
2741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		olen = out_end - out_pos;
2751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
2761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					    out_pos, &olen, &alert);
2771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (used < 0) {
278818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			tlsv1_server_log(conn, "Record layer processing failed");
2791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
2811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (used == 0) {
2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/* need more data */
2841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "yet supported");
2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
2871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
2881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ct == TLS_CONTENT_TYPE_ALERT) {
2911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (olen < 2) {
292818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt				tlsv1_server_log(conn, "Alert underflow");
2931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
2941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						   TLS_ALERT_DECODE_ERROR);
2951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return -1;
2961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
297818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			tlsv1_server_log(conn, "Received alert %d:%d",
298818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					 out_pos[0], out_pos[1]);
2991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
3001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				/* Continue processing */
3011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				pos += used;
3021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
3031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			}
3041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					   out_pos[1]);
3071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
3081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
3091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
311818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			tlsv1_server_log(conn, "Unexpected content type 0x%x",
312818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt					 pos[0]);
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   TLS_ALERT_UNEXPECTED_MESSAGE);
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
318818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
319b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		if ((conn->test_flags &
320818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		     (TLS_BREAK_VERIFY_DATA | TLS_BREAK_SRV_KEY_X_HASH |
321818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		      TLS_BREAK_SRV_KEY_X_SIGNATURE)) &&
322818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		    !conn->test_failure_reported) {
323818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			tlsv1_server_log(conn, "TEST-FAILURE: Client ApplData received after invalid handshake");
324818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			conn->test_failure_reported = 1;
325818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt		}
326818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
327818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		out_pos += olen;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (out_pos > out_end) {
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "for processing the received record");
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   TLS_ALERT_INTERNAL_ERROR);
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		pos += used;
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return out_pos - out_data;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_global_init - Initialize TLSv1 server
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function must be called before using any other TLSv1 server functions.
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_global_init(void)
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return crypto_global_init();
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_global_deinit - Deinitialize TLSv1 server
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to deinitialize the TLSv1 server that was
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * can be called after this before calling tlsv1_server_global_init() again.
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_global_deinit(void)
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	crypto_global_deinit();
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_init - Initialize TLSv1 server connection
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @cred: Pointer to server credentials from tlsv1_server_cred_alloc()
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to TLSv1 server connection data or %NULL on failure
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct tlsv1_server *conn;
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t count;
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 *suites;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn = os_zalloc(sizeof(*conn));
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn == NULL)
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->cred = cred;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->state = CLIENT_HELLO;
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tls_verify_hash_init(&conn->verify) < 0) {
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "hash");
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(conn);
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = 0;
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites = conn->cipher_suites;
397818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
398818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
399818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
401818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
402818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
403818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
405818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	suites[count++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->num_cipher_suites = count;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return conn;
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tlsv1_server_clear_data(struct tlsv1_server *conn)
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tlsv1_record_change_write_cipher(&conn->rl);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tlsv1_record_change_read_cipher(&conn->rl);
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tls_verify_hash_free(&conn->verify);
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	crypto_public_key_free(conn->client_rsa_key);
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->client_rsa_key = NULL;
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conn->session_ticket);
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->session_ticket = NULL;
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->session_ticket_len = 0;
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->use_session_ticket = 0;
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conn->dh_secret);
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->dh_secret = NULL;
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->dh_secret_len = 0;
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_deinit - Deinitialize TLSv1 server connection
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_deinit(struct tlsv1_server *conn)
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tlsv1_server_clear_data(conn);
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conn);
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_established - Check whether connection has been established
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if connection is established, 0 if not
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_established(struct tlsv1_server *conn)
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return conn->state == ESTABLISHED;
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_prf - Use TLS-PRF to derive keying material
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @label: Label (e.g., description of the key) for PRF
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @server_random_first: seed is 0 = client_random|server_random,
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 1 = server_random|client_random
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out: Buffer for output data from TLS-PRF
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_len: Length of the output buffer
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     int server_random_first, u8 *out, size_t out_len)
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 seed[2 * TLS_RANDOM_LEN];
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn->state != ESTABLISHED)
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (server_random_first) {
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  TLS_RANDOM_LEN);
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  TLS_RANDOM_LEN);
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return tls_prf(conn->rl.tls_version,
4871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		       conn->master_secret, TLS_MASTER_SECRET_LEN,
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_cipher - Get current cipher name
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for the cipher name
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: buf size
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Get the name of the currently used cipher.
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    size_t buflen)
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *cipher;
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (conn->rl.cipher_suite) {
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_RC4_128_MD5:
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "RC4-MD5";
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_RC4_128_SHA:
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "RC4-SHA";
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_DES_CBC_SHA:
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "DES-CBC-SHA";
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "DES-CBC3-SHA";
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_DH_anon_WITH_AES_128_CBC_SHA:
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "ADH-AES-128-SHA";
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_AES_256_CBC_SHA:
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "AES-256-SHA";
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case TLS_RSA_WITH_AES_128_CBC_SHA:
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		cipher = "AES-128-SHA";
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strlcpy(buf, cipher, buflen) >= buflen)
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_shutdown - Shutdown TLS connection
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_shutdown(struct tlsv1_server *conn)
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->state = CLIENT_HELLO;
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (tls_verify_hash_init(&conn->verify) < 0) {
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "hash");
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	tlsv1_server_clear_data(conn);
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_resumed - Was session resumption used
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if current session used session resumption, 0 if not
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_resumed(struct tlsv1_server *conn)
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_keys - Get master key and random data from TLS connection
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @keys: Structure of key/random data (filled on success)
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(keys, 0, sizeof(*keys));
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn->state == CLIENT_HELLO)
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	keys->client_random = conn->client_random;
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	keys->client_random_len = TLS_RANDOM_LEN;
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn->state != SERVER_HELLO) {
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keys->server_random = conn->server_random;
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keys->server_random_len = TLS_RANDOM_LEN;
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keys->master_key = conn->master_secret;
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keys->master_key_len = TLS_MASTER_SECRET_LEN;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_get_keyblock_size - Get TLS key_block size
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Size of the key_block for the negotiated cipher suite or -1 on
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * failure
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    conn->rl.iv_size);
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tlsv1_server_set_cipher_list - Configure acceptable cipher suites
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @conn: TLSv1 server connection data from tlsv1_server_init()
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (TLS_CIPHER_*).
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t count;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u16 *suites;
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: implement proper configuration of cipher suites */
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		count = 0;
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites = conn->cipher_suites;
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conn->num_cipher_suites = count;
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->verify_peer = verify_peer;
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					tlsv1_server_session_ticket_cb cb,
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					void *ctx)
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   cb, ctx);
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->session_ticket_cb = cb;
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conn->session_ticket_cb_ctx = ctx;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
661818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
662818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
663818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid tlsv1_server_set_log_cb(struct tlsv1_server *conn,
664818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt			     void (*cb)(void *ctx, const char *msg), void *ctx)
665818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{
666818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	conn->log_cb = cb;
667818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	conn->log_cb_ctx = ctx;
668818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt}
669818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
670818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt
671818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
672818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtvoid tlsv1_server_set_test_flags(struct tlsv1_server *conn, u32 flags)
673818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{
674818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt	conn->test_flags = flags;
675818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt}
676b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
677b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
678b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic const u8 test_tls_prime15[1] = {
679b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	15
680b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt};
681b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
682b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic const u8 test_tls_prime511b[64] = {
683b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x50, 0xfb, 0xf1, 0xae, 0x01, 0xf1, 0xfe, 0xe6,
684b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xe1, 0xae, 0xdc, 0x1e, 0xbe, 0xfb, 0x9e, 0x58,
685b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x9a, 0xd7, 0x54, 0x9d, 0x6b, 0xb3, 0x78, 0xe2,
686b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x39, 0x7f, 0x30, 0x01, 0x25, 0xa1, 0xf9, 0x7c,
687b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x55, 0x0e, 0xa1, 0x15, 0xcc, 0x36, 0x34, 0xbb,
688b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x6c, 0x8b, 0x64, 0x45, 0x15, 0x7f, 0xd3, 0xe7,
689b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x31, 0xc8, 0x8e, 0x56, 0x8e, 0x95, 0xdc, 0xea,
690b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x9e, 0xdf, 0xf7, 0x56, 0xdd, 0xb0, 0x34, 0xdb
691b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt};
692b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
693b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic const u8 test_tls_prime767b[96] = {
694b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x4c, 0xdc, 0xb8, 0x21, 0x20, 0x9d, 0xe8, 0xa3,
695b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x53, 0xd9, 0x1c, 0x18, 0xc1, 0x3a, 0x58, 0x67,
696b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xa7, 0x85, 0xf9, 0x28, 0x9b, 0xce, 0xc0, 0xd1,
697b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x05, 0x84, 0x61, 0x97, 0xb2, 0x86, 0x1c, 0xd0,
698b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xd1, 0x96, 0x23, 0x29, 0x8c, 0xc5, 0x30, 0x68,
699b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x3e, 0xf9, 0x05, 0xba, 0x60, 0xeb, 0xdb, 0xee,
700b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x2d, 0xdf, 0x84, 0x65, 0x49, 0x87, 0x90, 0x2a,
701b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xc9, 0x8e, 0x34, 0x63, 0x6d, 0x9a, 0x2d, 0x32,
702b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x1c, 0x46, 0xd5, 0x4e, 0x20, 0x20, 0x90, 0xac,
703b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xd5, 0x48, 0x79, 0x99, 0x0c, 0xe6, 0xed, 0xbf,
704b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x79, 0xc2, 0x47, 0x50, 0x95, 0x38, 0x38, 0xbc,
705b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xde, 0xb0, 0xd2, 0xe8, 0x97, 0xcb, 0x22, 0xbb
706b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt};
707b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
708b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic const u8 test_tls_prime58[128] = {
709b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x03, 0xc1, 0xba, 0xc8, 0x25, 0xbe, 0x2d, 0xf3
725b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt};
726b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
727b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtstatic const u8 test_tls_non_prime[] = {
728b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	/*
729b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * This is not a prime and the value has the following factors:
730b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * 13736783488716579923 * 16254860191773456563 * 18229434976173670763 *
731b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * 11112313018289079419 * 10260802278580253339 * 12394009491575311499 *
732b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * 12419059668711064739 * 14317973192687985827 * 10498605410533203179 *
733b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * 16338688760390249003 * 11128963991123878883 * 12990532258280301419 *
734b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 * 3
735b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	 */
736b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x0C, 0x8C, 0x36, 0x9C, 0x6F, 0x71, 0x2E, 0xA7,
737b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xAB, 0x32, 0xD3, 0x0F, 0x68, 0x3D, 0xB2, 0x6D,
738b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x81, 0xDD, 0xC4, 0x84, 0x0D, 0x9C, 0x6E, 0x36,
739b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x29, 0x70, 0xF3, 0x1E, 0x9A, 0x42, 0x0B, 0x67,
740b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x82, 0x6B, 0xB1, 0xF2, 0xAF, 0x55, 0x28, 0xE7,
741b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xDB, 0x67, 0x6C, 0xF7, 0x6B, 0xAC, 0xAC, 0xE5,
742b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xF7, 0x9F, 0xD4, 0x63, 0x55, 0x70, 0x32, 0x7C,
743b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x70, 0xFB, 0xAF, 0xB8, 0xEB, 0x37, 0xCF, 0x3F,
744b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0xFE, 0x94, 0x73, 0xF9, 0x7A, 0xC7, 0x12, 0x2E,
745b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x9B, 0xB4, 0x7D, 0x08, 0x60, 0x83, 0x43, 0x52,
746b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x83, 0x1E, 0xA5, 0xFC, 0xFA, 0x87, 0x12, 0xF4,
747b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	0x64, 0xE2, 0xCE, 0x71, 0x17, 0x72, 0xB6, 0xAB
748b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt};
749b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
750818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
751b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
752b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
753b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidtvoid tlsv1_server_get_dh_p(struct tlsv1_server *conn, const u8 **dh_p,
754b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt			   size_t *dh_p_len)
755b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt{
756b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	*dh_p = conn->cred->dh_p;
757b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	*dh_p_len = conn->cred->dh_p_len;
758b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
759b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS
760b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	if (conn->test_flags & TLS_DHE_PRIME_511B) {
761b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		tlsv1_server_log(conn, "TESTING: Use short 511-bit prime with DHE");
762b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p = test_tls_prime511b;
763b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p_len = sizeof(test_tls_prime511b);
764b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	} else if (conn->test_flags & TLS_DHE_PRIME_767B) {
765b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		tlsv1_server_log(conn, "TESTING: Use short 767-bit prime with DHE");
766b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p = test_tls_prime767b;
767b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p_len = sizeof(test_tls_prime767b);
768b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	} else if (conn->test_flags & TLS_DHE_PRIME_15) {
769b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		tlsv1_server_log(conn, "TESTING: Use bogus 15 \"prime\" with DHE");
770b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p = test_tls_prime15;
771b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p_len = sizeof(test_tls_prime15);
772b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	} else if (conn->test_flags & TLS_DHE_PRIME_58B) {
773b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		tlsv1_server_log(conn, "TESTING: Use short 58-bit prime in long container with DHE");
774b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p = test_tls_prime58;
775b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p_len = sizeof(test_tls_prime58);
776b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	} else if (conn->test_flags & TLS_DHE_NON_PRIME) {
777b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		tlsv1_server_log(conn, "TESTING: Use claim non-prime as the DHE prime");
778b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p = test_tls_non_prime;
779b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		*dh_p_len = sizeof(test_tls_non_prime);
780b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	}
781b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */
782b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt}
783