139beb93cSSam Leffler /*
2f05cddf9SRui Paulo * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
3*4bc52338SCy Schubert * Copyright (c) 2006-2019, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler *
5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo * See README for more details.
739beb93cSSam Leffler */
839beb93cSSam Leffler
939beb93cSSam Leffler #include "includes.h"
1039beb93cSSam Leffler
1139beb93cSSam Leffler #include "common.h"
12e28a4053SRui Paulo #include "crypto/sha1.h"
13e28a4053SRui Paulo #include "crypto/tls.h"
1439beb93cSSam Leffler #include "tlsv1_common.h"
1539beb93cSSam Leffler #include "tlsv1_record.h"
1639beb93cSSam Leffler #include "tlsv1_server.h"
1739beb93cSSam Leffler #include "tlsv1_server_i.h"
1839beb93cSSam Leffler
1939beb93cSSam Leffler /* TODO:
2039beb93cSSam Leffler * Support for a message fragmented across several records (RFC 2246, 6.2.1)
2139beb93cSSam Leffler */
2239beb93cSSam Leffler
2339beb93cSSam Leffler
tlsv1_server_log(struct tlsv1_server * conn,const char * fmt,...)245b9c547cSRui Paulo void tlsv1_server_log(struct tlsv1_server *conn, const char *fmt, ...)
255b9c547cSRui Paulo {
265b9c547cSRui Paulo va_list ap;
275b9c547cSRui Paulo char *buf;
285b9c547cSRui Paulo int buflen;
295b9c547cSRui Paulo
305b9c547cSRui Paulo va_start(ap, fmt);
315b9c547cSRui Paulo buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
325b9c547cSRui Paulo va_end(ap);
335b9c547cSRui Paulo
345b9c547cSRui Paulo buf = os_malloc(buflen);
355b9c547cSRui Paulo if (buf == NULL)
365b9c547cSRui Paulo return;
375b9c547cSRui Paulo va_start(ap, fmt);
385b9c547cSRui Paulo vsnprintf(buf, buflen, fmt, ap);
395b9c547cSRui Paulo va_end(ap);
405b9c547cSRui Paulo
415b9c547cSRui Paulo wpa_printf(MSG_DEBUG, "TLSv1: %s", buf);
425b9c547cSRui Paulo if (conn->log_cb)
435b9c547cSRui Paulo conn->log_cb(conn->log_cb_ctx, buf);
445b9c547cSRui Paulo
455b9c547cSRui Paulo os_free(buf);
465b9c547cSRui Paulo }
475b9c547cSRui Paulo
485b9c547cSRui Paulo
tlsv1_server_alert(struct tlsv1_server * conn,u8 level,u8 description)4939beb93cSSam Leffler void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
5039beb93cSSam Leffler {
5139beb93cSSam Leffler conn->alert_level = level;
5239beb93cSSam Leffler conn->alert_description = description;
5339beb93cSSam Leffler }
5439beb93cSSam Leffler
5539beb93cSSam Leffler
tlsv1_server_derive_keys(struct tlsv1_server * conn,const u8 * pre_master_secret,size_t pre_master_secret_len)5639beb93cSSam Leffler int tlsv1_server_derive_keys(struct tlsv1_server *conn,
5739beb93cSSam Leffler const u8 *pre_master_secret,
5839beb93cSSam Leffler size_t pre_master_secret_len)
5939beb93cSSam Leffler {
6039beb93cSSam Leffler u8 seed[2 * TLS_RANDOM_LEN];
6139beb93cSSam Leffler u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
6239beb93cSSam Leffler u8 *pos;
6339beb93cSSam Leffler size_t key_block_len;
6439beb93cSSam Leffler
6539beb93cSSam Leffler if (pre_master_secret) {
6639beb93cSSam Leffler wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
6739beb93cSSam Leffler pre_master_secret, pre_master_secret_len);
6839beb93cSSam Leffler os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
6939beb93cSSam Leffler os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
7039beb93cSSam Leffler TLS_RANDOM_LEN);
71f05cddf9SRui Paulo if (tls_prf(conn->rl.tls_version,
72f05cddf9SRui Paulo pre_master_secret, pre_master_secret_len,
7339beb93cSSam Leffler "master secret", seed, 2 * TLS_RANDOM_LEN,
7439beb93cSSam Leffler conn->master_secret, TLS_MASTER_SECRET_LEN)) {
7539beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
7639beb93cSSam Leffler "master_secret");
7739beb93cSSam Leffler return -1;
7839beb93cSSam Leffler }
7939beb93cSSam Leffler wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
8039beb93cSSam Leffler conn->master_secret, TLS_MASTER_SECRET_LEN);
8139beb93cSSam Leffler }
8239beb93cSSam Leffler
8339beb93cSSam Leffler os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
8439beb93cSSam Leffler os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
8539beb93cSSam Leffler key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
8639beb93cSSam Leffler conn->rl.iv_size);
87f05cddf9SRui Paulo if (tls_prf(conn->rl.tls_version,
88f05cddf9SRui Paulo conn->master_secret, TLS_MASTER_SECRET_LEN,
8939beb93cSSam Leffler "key expansion", seed, 2 * TLS_RANDOM_LEN,
9039beb93cSSam Leffler key_block, key_block_len)) {
9139beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
9239beb93cSSam Leffler return -1;
9339beb93cSSam Leffler }
9439beb93cSSam Leffler wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
9539beb93cSSam Leffler key_block, key_block_len);
9639beb93cSSam Leffler
9739beb93cSSam Leffler pos = key_block;
9839beb93cSSam Leffler
9939beb93cSSam Leffler /* client_write_MAC_secret */
10039beb93cSSam Leffler os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
10139beb93cSSam Leffler pos += conn->rl.hash_size;
10239beb93cSSam Leffler /* server_write_MAC_secret */
10339beb93cSSam Leffler os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
10439beb93cSSam Leffler pos += conn->rl.hash_size;
10539beb93cSSam Leffler
10639beb93cSSam Leffler /* client_write_key */
10739beb93cSSam Leffler os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
10839beb93cSSam Leffler pos += conn->rl.key_material_len;
10939beb93cSSam Leffler /* server_write_key */
11039beb93cSSam Leffler os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
11139beb93cSSam Leffler pos += conn->rl.key_material_len;
11239beb93cSSam Leffler
11339beb93cSSam Leffler /* client_write_IV */
11439beb93cSSam Leffler os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
11539beb93cSSam Leffler pos += conn->rl.iv_size;
11639beb93cSSam Leffler /* server_write_IV */
11739beb93cSSam Leffler os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
11839beb93cSSam Leffler pos += conn->rl.iv_size;
11939beb93cSSam Leffler
12039beb93cSSam Leffler return 0;
12139beb93cSSam Leffler }
12239beb93cSSam Leffler
12339beb93cSSam Leffler
12439beb93cSSam Leffler /**
12539beb93cSSam Leffler * tlsv1_server_handshake - Process TLS handshake
12639beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
12739beb93cSSam Leffler * @in_data: Input data from TLS peer
12839beb93cSSam Leffler * @in_len: Input data length
12939beb93cSSam Leffler * @out_len: Length of the output buffer.
13039beb93cSSam Leffler * Returns: Pointer to output data, %NULL on failure
13139beb93cSSam Leffler */
tlsv1_server_handshake(struct tlsv1_server * conn,const u8 * in_data,size_t in_len,size_t * out_len)13239beb93cSSam Leffler u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
13339beb93cSSam Leffler const u8 *in_data, size_t in_len,
13439beb93cSSam Leffler size_t *out_len)
13539beb93cSSam Leffler {
13639beb93cSSam Leffler const u8 *pos, *end;
13739beb93cSSam Leffler u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
13839beb93cSSam Leffler size_t in_msg_len;
139f05cddf9SRui Paulo int used;
14039beb93cSSam Leffler
14139beb93cSSam Leffler if (in_data == NULL || in_len == 0) {
14239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
14339beb93cSSam Leffler return NULL;
14439beb93cSSam Leffler }
14539beb93cSSam Leffler
14639beb93cSSam Leffler pos = in_data;
14739beb93cSSam Leffler end = in_data + in_len;
14839beb93cSSam Leffler in_msg = os_malloc(in_len);
14939beb93cSSam Leffler if (in_msg == NULL)
15039beb93cSSam Leffler return NULL;
15139beb93cSSam Leffler
15239beb93cSSam Leffler /* Each received packet may include multiple records */
15339beb93cSSam Leffler while (pos < end) {
15439beb93cSSam Leffler in_msg_len = in_len;
155f05cddf9SRui Paulo used = tlsv1_record_receive(&conn->rl, pos, end - pos,
156f05cddf9SRui Paulo in_msg, &in_msg_len, &alert);
157f05cddf9SRui Paulo if (used < 0) {
15839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
15939beb93cSSam Leffler "record failed");
16039beb93cSSam Leffler tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
16139beb93cSSam Leffler goto failed;
16239beb93cSSam Leffler }
163f05cddf9SRui Paulo if (used == 0) {
164f05cddf9SRui Paulo /* need more data */
165f05cddf9SRui Paulo wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
166f05cddf9SRui Paulo "yet supported");
167*4bc52338SCy Schubert tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
168*4bc52338SCy Schubert TLS_ALERT_INTERNAL_ERROR);
169f05cddf9SRui Paulo goto failed;
170f05cddf9SRui Paulo }
17139beb93cSSam Leffler ct = pos[0];
17239beb93cSSam Leffler
17339beb93cSSam Leffler in_pos = in_msg;
17439beb93cSSam Leffler in_end = in_msg + in_msg_len;
17539beb93cSSam Leffler
17639beb93cSSam Leffler /* Each received record may include multiple messages of the
17739beb93cSSam Leffler * same ContentType. */
17839beb93cSSam Leffler while (in_pos < in_end) {
17939beb93cSSam Leffler in_msg_len = in_end - in_pos;
18039beb93cSSam Leffler if (tlsv1_server_process_handshake(conn, ct, in_pos,
18139beb93cSSam Leffler &in_msg_len) < 0)
18239beb93cSSam Leffler goto failed;
18339beb93cSSam Leffler in_pos += in_msg_len;
18439beb93cSSam Leffler }
18539beb93cSSam Leffler
186f05cddf9SRui Paulo pos += used;
18739beb93cSSam Leffler }
18839beb93cSSam Leffler
18939beb93cSSam Leffler os_free(in_msg);
19039beb93cSSam Leffler in_msg = NULL;
19139beb93cSSam Leffler
19239beb93cSSam Leffler msg = tlsv1_server_handshake_write(conn, out_len);
19339beb93cSSam Leffler
19439beb93cSSam Leffler failed:
19539beb93cSSam Leffler os_free(in_msg);
19639beb93cSSam Leffler if (conn->alert_level) {
19739beb93cSSam Leffler if (conn->state == FAILED) {
19839beb93cSSam Leffler /* Avoid alert loops */
19939beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
20039beb93cSSam Leffler os_free(msg);
20139beb93cSSam Leffler return NULL;
20239beb93cSSam Leffler }
20339beb93cSSam Leffler conn->state = FAILED;
20439beb93cSSam Leffler os_free(msg);
20539beb93cSSam Leffler msg = tlsv1_server_send_alert(conn, conn->alert_level,
20639beb93cSSam Leffler conn->alert_description,
20739beb93cSSam Leffler out_len);
208*4bc52338SCy Schubert conn->write_alerts++;
20939beb93cSSam Leffler }
21039beb93cSSam Leffler
21139beb93cSSam Leffler return msg;
21239beb93cSSam Leffler }
21339beb93cSSam Leffler
21439beb93cSSam Leffler
21539beb93cSSam Leffler /**
21639beb93cSSam Leffler * tlsv1_server_encrypt - Encrypt data into TLS tunnel
21739beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
21839beb93cSSam Leffler * @in_data: Pointer to plaintext data to be encrypted
21939beb93cSSam Leffler * @in_len: Input buffer length
22039beb93cSSam Leffler * @out_data: Pointer to output buffer (encrypted TLS data)
22139beb93cSSam Leffler * @out_len: Maximum out_data length
22239beb93cSSam Leffler * Returns: Number of bytes written to out_data, -1 on failure
22339beb93cSSam Leffler *
22439beb93cSSam Leffler * This function is used after TLS handshake has been completed successfully to
22539beb93cSSam Leffler * send data in the encrypted tunnel.
22639beb93cSSam Leffler */
tlsv1_server_encrypt(struct tlsv1_server * conn,const u8 * in_data,size_t in_len,u8 * out_data,size_t out_len)22739beb93cSSam Leffler int tlsv1_server_encrypt(struct tlsv1_server *conn,
22839beb93cSSam Leffler const u8 *in_data, size_t in_len,
22939beb93cSSam Leffler u8 *out_data, size_t out_len)
23039beb93cSSam Leffler {
23139beb93cSSam Leffler size_t rlen;
23239beb93cSSam Leffler
23339beb93cSSam Leffler wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
23439beb93cSSam Leffler in_data, in_len);
23539beb93cSSam Leffler
23639beb93cSSam Leffler if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
237f05cddf9SRui Paulo out_data, out_len, in_data, in_len, &rlen) < 0) {
23839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
23939beb93cSSam Leffler tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
24039beb93cSSam Leffler TLS_ALERT_INTERNAL_ERROR);
24139beb93cSSam Leffler return -1;
24239beb93cSSam Leffler }
24339beb93cSSam Leffler
24439beb93cSSam Leffler return rlen;
24539beb93cSSam Leffler }
24639beb93cSSam Leffler
24739beb93cSSam Leffler
24839beb93cSSam Leffler /**
24939beb93cSSam Leffler * tlsv1_server_decrypt - Decrypt data from TLS tunnel
25039beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
25139beb93cSSam Leffler * @in_data: Pointer to input buffer (encrypted TLS data)
25239beb93cSSam Leffler * @in_len: Input buffer length
25339beb93cSSam Leffler * @out_data: Pointer to output buffer (decrypted data from TLS tunnel)
25439beb93cSSam Leffler * @out_len: Maximum out_data length
25539beb93cSSam Leffler * Returns: Number of bytes written to out_data, -1 on failure
25639beb93cSSam Leffler *
25739beb93cSSam Leffler * This function is used after TLS handshake has been completed successfully to
25839beb93cSSam Leffler * receive data from the encrypted tunnel.
25939beb93cSSam Leffler */
tlsv1_server_decrypt(struct tlsv1_server * conn,const u8 * in_data,size_t in_len,u8 * out_data,size_t out_len)26039beb93cSSam Leffler int tlsv1_server_decrypt(struct tlsv1_server *conn,
26139beb93cSSam Leffler const u8 *in_data, size_t in_len,
26239beb93cSSam Leffler u8 *out_data, size_t out_len)
26339beb93cSSam Leffler {
26439beb93cSSam Leffler const u8 *in_end, *pos;
265f05cddf9SRui Paulo int used;
266f05cddf9SRui Paulo u8 alert, *out_end, *out_pos, ct;
26739beb93cSSam Leffler size_t olen;
26839beb93cSSam Leffler
26939beb93cSSam Leffler pos = in_data;
27039beb93cSSam Leffler in_end = in_data + in_len;
27139beb93cSSam Leffler out_pos = out_data;
27239beb93cSSam Leffler out_end = out_data + out_len;
27339beb93cSSam Leffler
27439beb93cSSam Leffler while (pos < in_end) {
275f05cddf9SRui Paulo ct = pos[0];
276f05cddf9SRui Paulo olen = out_end - out_pos;
277f05cddf9SRui Paulo used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
278f05cddf9SRui Paulo out_pos, &olen, &alert);
279f05cddf9SRui Paulo if (used < 0) {
2805b9c547cSRui Paulo tlsv1_server_log(conn, "Record layer processing failed");
281f05cddf9SRui Paulo tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
282f05cddf9SRui Paulo return -1;
283f05cddf9SRui Paulo }
284f05cddf9SRui Paulo if (used == 0) {
285f05cddf9SRui Paulo /* need more data */
286f05cddf9SRui Paulo wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
287f05cddf9SRui Paulo "yet supported");
288f05cddf9SRui Paulo tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
289f05cddf9SRui Paulo return -1;
290f05cddf9SRui Paulo }
291f05cddf9SRui Paulo
292f05cddf9SRui Paulo if (ct == TLS_CONTENT_TYPE_ALERT) {
293f05cddf9SRui Paulo if (olen < 2) {
2945b9c547cSRui Paulo tlsv1_server_log(conn, "Alert underflow");
295f05cddf9SRui Paulo tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
296f05cddf9SRui Paulo TLS_ALERT_DECODE_ERROR);
297f05cddf9SRui Paulo return -1;
298f05cddf9SRui Paulo }
2995b9c547cSRui Paulo tlsv1_server_log(conn, "Received alert %d:%d",
300f05cddf9SRui Paulo out_pos[0], out_pos[1]);
301*4bc52338SCy Schubert conn->read_alerts++;
302f05cddf9SRui Paulo if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
303f05cddf9SRui Paulo /* Continue processing */
304f05cddf9SRui Paulo pos += used;
305f05cddf9SRui Paulo continue;
306f05cddf9SRui Paulo }
307f05cddf9SRui Paulo
308f05cddf9SRui Paulo tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
309f05cddf9SRui Paulo out_pos[1]);
310f05cddf9SRui Paulo return -1;
311f05cddf9SRui Paulo }
312f05cddf9SRui Paulo
313f05cddf9SRui Paulo if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
3145b9c547cSRui Paulo tlsv1_server_log(conn, "Unexpected content type 0x%x",
3155b9c547cSRui Paulo pos[0]);
31639beb93cSSam Leffler tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
31739beb93cSSam Leffler TLS_ALERT_UNEXPECTED_MESSAGE);
31839beb93cSSam Leffler return -1;
31939beb93cSSam Leffler }
32039beb93cSSam Leffler
3215b9c547cSRui Paulo #ifdef CONFIG_TESTING_OPTIONS
3225b9c547cSRui Paulo if ((conn->test_flags &
3235b9c547cSRui Paulo (TLS_BREAK_VERIFY_DATA | TLS_BREAK_SRV_KEY_X_HASH |
3245b9c547cSRui Paulo TLS_BREAK_SRV_KEY_X_SIGNATURE)) &&
3255b9c547cSRui Paulo !conn->test_failure_reported) {
3265b9c547cSRui Paulo tlsv1_server_log(conn, "TEST-FAILURE: Client ApplData received after invalid handshake");
3275b9c547cSRui Paulo conn->test_failure_reported = 1;
3285b9c547cSRui Paulo }
3295b9c547cSRui Paulo #endif /* CONFIG_TESTING_OPTIONS */
3305b9c547cSRui Paulo
33139beb93cSSam Leffler out_pos += olen;
33239beb93cSSam Leffler if (out_pos > out_end) {
33339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
33439beb93cSSam Leffler "for processing the received record");
33539beb93cSSam Leffler tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
33639beb93cSSam Leffler TLS_ALERT_INTERNAL_ERROR);
33739beb93cSSam Leffler return -1;
33839beb93cSSam Leffler }
33939beb93cSSam Leffler
340f05cddf9SRui Paulo pos += used;
34139beb93cSSam Leffler }
34239beb93cSSam Leffler
34339beb93cSSam Leffler return out_pos - out_data;
34439beb93cSSam Leffler }
34539beb93cSSam Leffler
34639beb93cSSam Leffler
34739beb93cSSam Leffler /**
34839beb93cSSam Leffler * tlsv1_server_global_init - Initialize TLSv1 server
34939beb93cSSam Leffler * Returns: 0 on success, -1 on failure
35039beb93cSSam Leffler *
35139beb93cSSam Leffler * This function must be called before using any other TLSv1 server functions.
35239beb93cSSam Leffler */
tlsv1_server_global_init(void)35339beb93cSSam Leffler int tlsv1_server_global_init(void)
35439beb93cSSam Leffler {
35539beb93cSSam Leffler return crypto_global_init();
35639beb93cSSam Leffler }
35739beb93cSSam Leffler
35839beb93cSSam Leffler
35939beb93cSSam Leffler /**
36039beb93cSSam Leffler * tlsv1_server_global_deinit - Deinitialize TLSv1 server
36139beb93cSSam Leffler *
36239beb93cSSam Leffler * This function can be used to deinitialize the TLSv1 server that was
36339beb93cSSam Leffler * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions
36439beb93cSSam Leffler * can be called after this before calling tlsv1_server_global_init() again.
36539beb93cSSam Leffler */
tlsv1_server_global_deinit(void)36639beb93cSSam Leffler void tlsv1_server_global_deinit(void)
36739beb93cSSam Leffler {
36839beb93cSSam Leffler crypto_global_deinit();
36939beb93cSSam Leffler }
37039beb93cSSam Leffler
37139beb93cSSam Leffler
37239beb93cSSam Leffler /**
37339beb93cSSam Leffler * tlsv1_server_init - Initialize TLSv1 server connection
37439beb93cSSam Leffler * @cred: Pointer to server credentials from tlsv1_server_cred_alloc()
37539beb93cSSam Leffler * Returns: Pointer to TLSv1 server connection data or %NULL on failure
37639beb93cSSam Leffler */
tlsv1_server_init(struct tlsv1_credentials * cred)37739beb93cSSam Leffler struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
37839beb93cSSam Leffler {
37939beb93cSSam Leffler struct tlsv1_server *conn;
38039beb93cSSam Leffler size_t count;
38139beb93cSSam Leffler u16 *suites;
38239beb93cSSam Leffler
38339beb93cSSam Leffler conn = os_zalloc(sizeof(*conn));
38439beb93cSSam Leffler if (conn == NULL)
38539beb93cSSam Leffler return NULL;
38639beb93cSSam Leffler
38739beb93cSSam Leffler conn->cred = cred;
38839beb93cSSam Leffler
38939beb93cSSam Leffler conn->state = CLIENT_HELLO;
39039beb93cSSam Leffler
39139beb93cSSam Leffler if (tls_verify_hash_init(&conn->verify) < 0) {
39239beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
39339beb93cSSam Leffler "hash");
39439beb93cSSam Leffler os_free(conn);
39539beb93cSSam Leffler return NULL;
39639beb93cSSam Leffler }
39739beb93cSSam Leffler
39839beb93cSSam Leffler count = 0;
39939beb93cSSam Leffler suites = conn->cipher_suites;
4005b9c547cSRui Paulo suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
4015b9c547cSRui Paulo suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
4025b9c547cSRui Paulo suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
40339beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
4045b9c547cSRui Paulo suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
4055b9c547cSRui Paulo suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
4065b9c547cSRui Paulo suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
40739beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
4085b9c547cSRui Paulo suites[count++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
40939beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
41039beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
41139beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
41239beb93cSSam Leffler conn->num_cipher_suites = count;
41339beb93cSSam Leffler
41439beb93cSSam Leffler return conn;
41539beb93cSSam Leffler }
41639beb93cSSam Leffler
41739beb93cSSam Leffler
tlsv1_server_clear_data(struct tlsv1_server * conn)41839beb93cSSam Leffler static void tlsv1_server_clear_data(struct tlsv1_server *conn)
41939beb93cSSam Leffler {
42039beb93cSSam Leffler tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
42139beb93cSSam Leffler tlsv1_record_change_write_cipher(&conn->rl);
42239beb93cSSam Leffler tlsv1_record_change_read_cipher(&conn->rl);
42339beb93cSSam Leffler tls_verify_hash_free(&conn->verify);
42439beb93cSSam Leffler
42539beb93cSSam Leffler crypto_public_key_free(conn->client_rsa_key);
42639beb93cSSam Leffler conn->client_rsa_key = NULL;
42739beb93cSSam Leffler
42839beb93cSSam Leffler os_free(conn->session_ticket);
42939beb93cSSam Leffler conn->session_ticket = NULL;
43039beb93cSSam Leffler conn->session_ticket_len = 0;
43139beb93cSSam Leffler conn->use_session_ticket = 0;
43239beb93cSSam Leffler
43339beb93cSSam Leffler os_free(conn->dh_secret);
43439beb93cSSam Leffler conn->dh_secret = NULL;
43539beb93cSSam Leffler conn->dh_secret_len = 0;
43639beb93cSSam Leffler }
43739beb93cSSam Leffler
43839beb93cSSam Leffler
43939beb93cSSam Leffler /**
44039beb93cSSam Leffler * tlsv1_server_deinit - Deinitialize TLSv1 server connection
44139beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
44239beb93cSSam Leffler */
tlsv1_server_deinit(struct tlsv1_server * conn)44339beb93cSSam Leffler void tlsv1_server_deinit(struct tlsv1_server *conn)
44439beb93cSSam Leffler {
44539beb93cSSam Leffler tlsv1_server_clear_data(conn);
44639beb93cSSam Leffler os_free(conn);
44739beb93cSSam Leffler }
44839beb93cSSam Leffler
44939beb93cSSam Leffler
45039beb93cSSam Leffler /**
45139beb93cSSam Leffler * tlsv1_server_established - Check whether connection has been established
45239beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
45339beb93cSSam Leffler * Returns: 1 if connection is established, 0 if not
45439beb93cSSam Leffler */
tlsv1_server_established(struct tlsv1_server * conn)45539beb93cSSam Leffler int tlsv1_server_established(struct tlsv1_server *conn)
45639beb93cSSam Leffler {
45739beb93cSSam Leffler return conn->state == ESTABLISHED;
45839beb93cSSam Leffler }
45939beb93cSSam Leffler
46039beb93cSSam Leffler
46139beb93cSSam Leffler /**
46239beb93cSSam Leffler * tlsv1_server_prf - Use TLS-PRF to derive keying material
46339beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
46439beb93cSSam Leffler * @label: Label (e.g., description of the key) for PRF
465*4bc52338SCy Schubert * @context: Optional extra upper-layer context (max len 2^16)
466*4bc52338SCy Schubert * @context_len: The length of the context value
46739beb93cSSam Leffler * @server_random_first: seed is 0 = client_random|server_random,
46839beb93cSSam Leffler * 1 = server_random|client_random
46939beb93cSSam Leffler * @out: Buffer for output data from TLS-PRF
47039beb93cSSam Leffler * @out_len: Length of the output buffer
47139beb93cSSam Leffler * Returns: 0 on success, -1 on failure
47239beb93cSSam Leffler */
tlsv1_server_prf(struct tlsv1_server * conn,const char * label,const u8 * context,size_t context_len,int server_random_first,u8 * out,size_t out_len)47339beb93cSSam Leffler int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
474*4bc52338SCy Schubert const u8 *context, size_t context_len,
47539beb93cSSam Leffler int server_random_first, u8 *out, size_t out_len)
47639beb93cSSam Leffler {
477*4bc52338SCy Schubert u8 *seed, *pos;
478*4bc52338SCy Schubert size_t seed_len = 2 * TLS_RANDOM_LEN;
479*4bc52338SCy Schubert int res;
48039beb93cSSam Leffler
48139beb93cSSam Leffler if (conn->state != ESTABLISHED)
48239beb93cSSam Leffler return -1;
48339beb93cSSam Leffler
484*4bc52338SCy Schubert if (context_len > 65535)
485*4bc52338SCy Schubert return -1;
486*4bc52338SCy Schubert
487*4bc52338SCy Schubert if (context)
488*4bc52338SCy Schubert seed_len += 2 + context_len;
489*4bc52338SCy Schubert
490*4bc52338SCy Schubert seed = os_malloc(seed_len);
491*4bc52338SCy Schubert if (!seed)
492*4bc52338SCy Schubert return -1;
493*4bc52338SCy Schubert
49439beb93cSSam Leffler if (server_random_first) {
49539beb93cSSam Leffler os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
49639beb93cSSam Leffler os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
49739beb93cSSam Leffler TLS_RANDOM_LEN);
49839beb93cSSam Leffler } else {
49939beb93cSSam Leffler os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
50039beb93cSSam Leffler os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
50139beb93cSSam Leffler TLS_RANDOM_LEN);
50239beb93cSSam Leffler }
50339beb93cSSam Leffler
504*4bc52338SCy Schubert if (context) {
505*4bc52338SCy Schubert pos = seed + 2 * TLS_RANDOM_LEN;
506*4bc52338SCy Schubert WPA_PUT_BE16(pos, context_len);
507*4bc52338SCy Schubert pos += 2;
508*4bc52338SCy Schubert os_memcpy(pos, context, context_len);
509*4bc52338SCy Schubert }
510*4bc52338SCy Schubert
511*4bc52338SCy Schubert res = tls_prf(conn->rl.tls_version,
512f05cddf9SRui Paulo conn->master_secret, TLS_MASTER_SECRET_LEN,
513*4bc52338SCy Schubert label, seed, seed_len, out, out_len);
514*4bc52338SCy Schubert os_free(seed);
515*4bc52338SCy Schubert return res;
51639beb93cSSam Leffler }
51739beb93cSSam Leffler
51839beb93cSSam Leffler
51939beb93cSSam Leffler /**
52039beb93cSSam Leffler * tlsv1_server_get_cipher - Get current cipher name
52139beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
52239beb93cSSam Leffler * @buf: Buffer for the cipher name
52339beb93cSSam Leffler * @buflen: buf size
52439beb93cSSam Leffler * Returns: 0 on success, -1 on failure
52539beb93cSSam Leffler *
52639beb93cSSam Leffler * Get the name of the currently used cipher.
52739beb93cSSam Leffler */
tlsv1_server_get_cipher(struct tlsv1_server * conn,char * buf,size_t buflen)52839beb93cSSam Leffler int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
52939beb93cSSam Leffler size_t buflen)
53039beb93cSSam Leffler {
53139beb93cSSam Leffler char *cipher;
53239beb93cSSam Leffler
53339beb93cSSam Leffler switch (conn->rl.cipher_suite) {
53439beb93cSSam Leffler case TLS_RSA_WITH_RC4_128_MD5:
53539beb93cSSam Leffler cipher = "RC4-MD5";
53639beb93cSSam Leffler break;
53739beb93cSSam Leffler case TLS_RSA_WITH_RC4_128_SHA:
53839beb93cSSam Leffler cipher = "RC4-SHA";
53939beb93cSSam Leffler break;
54039beb93cSSam Leffler case TLS_RSA_WITH_DES_CBC_SHA:
54139beb93cSSam Leffler cipher = "DES-CBC-SHA";
54239beb93cSSam Leffler break;
54339beb93cSSam Leffler case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
54439beb93cSSam Leffler cipher = "DES-CBC3-SHA";
54539beb93cSSam Leffler break;
5465b9c547cSRui Paulo case TLS_DHE_RSA_WITH_DES_CBC_SHA:
5475b9c547cSRui Paulo cipher = "DHE-RSA-DES-CBC-SHA";
5485b9c547cSRui Paulo break;
5495b9c547cSRui Paulo case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
5505b9c547cSRui Paulo cipher = "DHE-RSA-DES-CBC3-SHA";
5515b9c547cSRui Paulo break;
5525b9c547cSRui Paulo case TLS_DH_anon_WITH_RC4_128_MD5:
5535b9c547cSRui Paulo cipher = "ADH-RC4-MD5";
5545b9c547cSRui Paulo break;
5555b9c547cSRui Paulo case TLS_DH_anon_WITH_DES_CBC_SHA:
5565b9c547cSRui Paulo cipher = "ADH-DES-SHA";
5575b9c547cSRui Paulo break;
5585b9c547cSRui Paulo case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
5595b9c547cSRui Paulo cipher = "ADH-DES-CBC3-SHA";
5605b9c547cSRui Paulo break;
5615b9c547cSRui Paulo case TLS_RSA_WITH_AES_128_CBC_SHA:
5625b9c547cSRui Paulo cipher = "AES-128-SHA";
5635b9c547cSRui Paulo break;
5645b9c547cSRui Paulo case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
5655b9c547cSRui Paulo cipher = "DHE-RSA-AES-128-SHA";
5665b9c547cSRui Paulo break;
56739beb93cSSam Leffler case TLS_DH_anon_WITH_AES_128_CBC_SHA:
56839beb93cSSam Leffler cipher = "ADH-AES-128-SHA";
56939beb93cSSam Leffler break;
57039beb93cSSam Leffler case TLS_RSA_WITH_AES_256_CBC_SHA:
57139beb93cSSam Leffler cipher = "AES-256-SHA";
57239beb93cSSam Leffler break;
5735b9c547cSRui Paulo case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
5745b9c547cSRui Paulo cipher = "DHE-RSA-AES-256-SHA";
5755b9c547cSRui Paulo break;
5765b9c547cSRui Paulo case TLS_DH_anon_WITH_AES_256_CBC_SHA:
5775b9c547cSRui Paulo cipher = "ADH-AES-256-SHA";
5785b9c547cSRui Paulo break;
5795b9c547cSRui Paulo case TLS_RSA_WITH_AES_128_CBC_SHA256:
5805b9c547cSRui Paulo cipher = "AES-128-SHA256";
5815b9c547cSRui Paulo break;
5825b9c547cSRui Paulo case TLS_RSA_WITH_AES_256_CBC_SHA256:
5835b9c547cSRui Paulo cipher = "AES-256-SHA256";
5845b9c547cSRui Paulo break;
5855b9c547cSRui Paulo case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
5865b9c547cSRui Paulo cipher = "DHE-RSA-AES-128-SHA256";
5875b9c547cSRui Paulo break;
5885b9c547cSRui Paulo case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
5895b9c547cSRui Paulo cipher = "DHE-RSA-AES-256-SHA256";
5905b9c547cSRui Paulo break;
5915b9c547cSRui Paulo case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
5925b9c547cSRui Paulo cipher = "ADH-AES-128-SHA256";
5935b9c547cSRui Paulo break;
5945b9c547cSRui Paulo case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
5955b9c547cSRui Paulo cipher = "ADH-AES-256-SHA256";
59639beb93cSSam Leffler break;
59739beb93cSSam Leffler default:
59839beb93cSSam Leffler return -1;
59939beb93cSSam Leffler }
60039beb93cSSam Leffler
60139beb93cSSam Leffler if (os_strlcpy(buf, cipher, buflen) >= buflen)
60239beb93cSSam Leffler return -1;
60339beb93cSSam Leffler return 0;
60439beb93cSSam Leffler }
60539beb93cSSam Leffler
60639beb93cSSam Leffler
60739beb93cSSam Leffler /**
60839beb93cSSam Leffler * tlsv1_server_shutdown - Shutdown TLS connection
60939beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
61039beb93cSSam Leffler * Returns: 0 on success, -1 on failure
61139beb93cSSam Leffler */
tlsv1_server_shutdown(struct tlsv1_server * conn)61239beb93cSSam Leffler int tlsv1_server_shutdown(struct tlsv1_server *conn)
61339beb93cSSam Leffler {
61439beb93cSSam Leffler conn->state = CLIENT_HELLO;
61539beb93cSSam Leffler
61639beb93cSSam Leffler if (tls_verify_hash_init(&conn->verify) < 0) {
61739beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
61839beb93cSSam Leffler "hash");
61939beb93cSSam Leffler return -1;
62039beb93cSSam Leffler }
62139beb93cSSam Leffler
62239beb93cSSam Leffler tlsv1_server_clear_data(conn);
62339beb93cSSam Leffler
62439beb93cSSam Leffler return 0;
62539beb93cSSam Leffler }
62639beb93cSSam Leffler
62739beb93cSSam Leffler
62839beb93cSSam Leffler /**
62939beb93cSSam Leffler * tlsv1_server_resumed - Was session resumption used
63039beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
63139beb93cSSam Leffler * Returns: 1 if current session used session resumption, 0 if not
63239beb93cSSam Leffler */
tlsv1_server_resumed(struct tlsv1_server * conn)63339beb93cSSam Leffler int tlsv1_server_resumed(struct tlsv1_server *conn)
63439beb93cSSam Leffler {
63539beb93cSSam Leffler return 0;
63639beb93cSSam Leffler }
63739beb93cSSam Leffler
63839beb93cSSam Leffler
63939beb93cSSam Leffler /**
640325151a3SRui Paulo * tlsv1_server_get_random - Get random data from TLS connection
64139beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
642325151a3SRui Paulo * @keys: Structure of random data (filled on success)
64339beb93cSSam Leffler * Returns: 0 on success, -1 on failure
64439beb93cSSam Leffler */
tlsv1_server_get_random(struct tlsv1_server * conn,struct tls_random * keys)645325151a3SRui Paulo int tlsv1_server_get_random(struct tlsv1_server *conn, struct tls_random *keys)
64639beb93cSSam Leffler {
64739beb93cSSam Leffler os_memset(keys, 0, sizeof(*keys));
64839beb93cSSam Leffler if (conn->state == CLIENT_HELLO)
64939beb93cSSam Leffler return -1;
65039beb93cSSam Leffler
65139beb93cSSam Leffler keys->client_random = conn->client_random;
65239beb93cSSam Leffler keys->client_random_len = TLS_RANDOM_LEN;
65339beb93cSSam Leffler
65439beb93cSSam Leffler if (conn->state != SERVER_HELLO) {
65539beb93cSSam Leffler keys->server_random = conn->server_random;
65639beb93cSSam Leffler keys->server_random_len = TLS_RANDOM_LEN;
65739beb93cSSam Leffler }
65839beb93cSSam Leffler
65939beb93cSSam Leffler return 0;
66039beb93cSSam Leffler }
66139beb93cSSam Leffler
66239beb93cSSam Leffler
66339beb93cSSam Leffler /**
66439beb93cSSam Leffler * tlsv1_server_get_keyblock_size - Get TLS key_block size
66539beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
66639beb93cSSam Leffler * Returns: Size of the key_block for the negotiated cipher suite or -1 on
66739beb93cSSam Leffler * failure
66839beb93cSSam Leffler */
tlsv1_server_get_keyblock_size(struct tlsv1_server * conn)66939beb93cSSam Leffler int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
67039beb93cSSam Leffler {
67139beb93cSSam Leffler if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
67239beb93cSSam Leffler return -1;
67339beb93cSSam Leffler
67439beb93cSSam Leffler return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
67539beb93cSSam Leffler conn->rl.iv_size);
67639beb93cSSam Leffler }
67739beb93cSSam Leffler
67839beb93cSSam Leffler
67939beb93cSSam Leffler /**
68039beb93cSSam Leffler * tlsv1_server_set_cipher_list - Configure acceptable cipher suites
68139beb93cSSam Leffler * @conn: TLSv1 server connection data from tlsv1_server_init()
68239beb93cSSam Leffler * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
68339beb93cSSam Leffler * (TLS_CIPHER_*).
68439beb93cSSam Leffler * Returns: 0 on success, -1 on failure
68539beb93cSSam Leffler */
tlsv1_server_set_cipher_list(struct tlsv1_server * conn,u8 * ciphers)68639beb93cSSam Leffler int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
68739beb93cSSam Leffler {
68839beb93cSSam Leffler size_t count;
68939beb93cSSam Leffler u16 *suites;
69039beb93cSSam Leffler
69139beb93cSSam Leffler /* TODO: implement proper configuration of cipher suites */
69239beb93cSSam Leffler if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
69339beb93cSSam Leffler count = 0;
69439beb93cSSam Leffler suites = conn->cipher_suites;
69539beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
69639beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
69739beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
69839beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
69939beb93cSSam Leffler suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
70039beb93cSSam Leffler suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
70139beb93cSSam Leffler suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
70239beb93cSSam Leffler suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
70339beb93cSSam Leffler suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
70439beb93cSSam Leffler suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
70539beb93cSSam Leffler conn->num_cipher_suites = count;
70639beb93cSSam Leffler }
70739beb93cSSam Leffler
70839beb93cSSam Leffler return 0;
70939beb93cSSam Leffler }
71039beb93cSSam Leffler
71139beb93cSSam Leffler
tlsv1_server_set_verify(struct tlsv1_server * conn,int verify_peer)71239beb93cSSam Leffler int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
71339beb93cSSam Leffler {
71439beb93cSSam Leffler conn->verify_peer = verify_peer;
71539beb93cSSam Leffler return 0;
71639beb93cSSam Leffler }
71739beb93cSSam Leffler
71839beb93cSSam Leffler
tlsv1_server_set_session_ticket_cb(struct tlsv1_server * conn,tlsv1_server_session_ticket_cb cb,void * ctx)71939beb93cSSam Leffler void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
72039beb93cSSam Leffler tlsv1_server_session_ticket_cb cb,
72139beb93cSSam Leffler void *ctx)
72239beb93cSSam Leffler {
72339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
72439beb93cSSam Leffler cb, ctx);
72539beb93cSSam Leffler conn->session_ticket_cb = cb;
72639beb93cSSam Leffler conn->session_ticket_cb_ctx = ctx;
72739beb93cSSam Leffler }
7285b9c547cSRui Paulo
7295b9c547cSRui Paulo
tlsv1_server_set_log_cb(struct tlsv1_server * conn,void (* cb)(void * ctx,const char * msg),void * ctx)7305b9c547cSRui Paulo void tlsv1_server_set_log_cb(struct tlsv1_server *conn,
7315b9c547cSRui Paulo void (*cb)(void *ctx, const char *msg), void *ctx)
7325b9c547cSRui Paulo {
7335b9c547cSRui Paulo conn->log_cb = cb;
7345b9c547cSRui Paulo conn->log_cb_ctx = ctx;
7355b9c547cSRui Paulo }
7365b9c547cSRui Paulo
7375b9c547cSRui Paulo
tlsv1_server_get_failed(struct tlsv1_server * conn)738*4bc52338SCy Schubert int tlsv1_server_get_failed(struct tlsv1_server *conn)
739*4bc52338SCy Schubert {
740*4bc52338SCy Schubert return conn->state == FAILED;
741*4bc52338SCy Schubert }
742*4bc52338SCy Schubert
743*4bc52338SCy Schubert
tlsv1_server_get_read_alerts(struct tlsv1_server * conn)744*4bc52338SCy Schubert int tlsv1_server_get_read_alerts(struct tlsv1_server *conn)
745*4bc52338SCy Schubert {
746*4bc52338SCy Schubert return conn->read_alerts;
747*4bc52338SCy Schubert }
748*4bc52338SCy Schubert
749*4bc52338SCy Schubert
tlsv1_server_get_write_alerts(struct tlsv1_server * conn)750*4bc52338SCy Schubert int tlsv1_server_get_write_alerts(struct tlsv1_server *conn)
751*4bc52338SCy Schubert {
752*4bc52338SCy Schubert return conn->write_alerts;
753*4bc52338SCy Schubert }
754*4bc52338SCy Schubert
755*4bc52338SCy Schubert
7565b9c547cSRui Paulo #ifdef CONFIG_TESTING_OPTIONS
tlsv1_server_set_test_flags(struct tlsv1_server * conn,u32 flags)7575b9c547cSRui Paulo void tlsv1_server_set_test_flags(struct tlsv1_server *conn, u32 flags)
7585b9c547cSRui Paulo {
7595b9c547cSRui Paulo conn->test_flags = flags;
7605b9c547cSRui Paulo }
7615b9c547cSRui Paulo
7625b9c547cSRui Paulo
7635b9c547cSRui Paulo static const u8 test_tls_prime15[1] = {
7645b9c547cSRui Paulo 15
7655b9c547cSRui Paulo };
7665b9c547cSRui Paulo
7675b9c547cSRui Paulo static const u8 test_tls_prime511b[64] = {
7685b9c547cSRui Paulo 0x50, 0xfb, 0xf1, 0xae, 0x01, 0xf1, 0xfe, 0xe6,
7695b9c547cSRui Paulo 0xe1, 0xae, 0xdc, 0x1e, 0xbe, 0xfb, 0x9e, 0x58,
7705b9c547cSRui Paulo 0x9a, 0xd7, 0x54, 0x9d, 0x6b, 0xb3, 0x78, 0xe2,
7715b9c547cSRui Paulo 0x39, 0x7f, 0x30, 0x01, 0x25, 0xa1, 0xf9, 0x7c,
7725b9c547cSRui Paulo 0x55, 0x0e, 0xa1, 0x15, 0xcc, 0x36, 0x34, 0xbb,
7735b9c547cSRui Paulo 0x6c, 0x8b, 0x64, 0x45, 0x15, 0x7f, 0xd3, 0xe7,
7745b9c547cSRui Paulo 0x31, 0xc8, 0x8e, 0x56, 0x8e, 0x95, 0xdc, 0xea,
7755b9c547cSRui Paulo 0x9e, 0xdf, 0xf7, 0x56, 0xdd, 0xb0, 0x34, 0xdb
7765b9c547cSRui Paulo };
7775b9c547cSRui Paulo
7785b9c547cSRui Paulo static const u8 test_tls_prime767b[96] = {
7795b9c547cSRui Paulo 0x4c, 0xdc, 0xb8, 0x21, 0x20, 0x9d, 0xe8, 0xa3,
7805b9c547cSRui Paulo 0x53, 0xd9, 0x1c, 0x18, 0xc1, 0x3a, 0x58, 0x67,
7815b9c547cSRui Paulo 0xa7, 0x85, 0xf9, 0x28, 0x9b, 0xce, 0xc0, 0xd1,
7825b9c547cSRui Paulo 0x05, 0x84, 0x61, 0x97, 0xb2, 0x86, 0x1c, 0xd0,
7835b9c547cSRui Paulo 0xd1, 0x96, 0x23, 0x29, 0x8c, 0xc5, 0x30, 0x68,
7845b9c547cSRui Paulo 0x3e, 0xf9, 0x05, 0xba, 0x60, 0xeb, 0xdb, 0xee,
7855b9c547cSRui Paulo 0x2d, 0xdf, 0x84, 0x65, 0x49, 0x87, 0x90, 0x2a,
7865b9c547cSRui Paulo 0xc9, 0x8e, 0x34, 0x63, 0x6d, 0x9a, 0x2d, 0x32,
7875b9c547cSRui Paulo 0x1c, 0x46, 0xd5, 0x4e, 0x20, 0x20, 0x90, 0xac,
7885b9c547cSRui Paulo 0xd5, 0x48, 0x79, 0x99, 0x0c, 0xe6, 0xed, 0xbf,
7895b9c547cSRui Paulo 0x79, 0xc2, 0x47, 0x50, 0x95, 0x38, 0x38, 0xbc,
7905b9c547cSRui Paulo 0xde, 0xb0, 0xd2, 0xe8, 0x97, 0xcb, 0x22, 0xbb
7915b9c547cSRui Paulo };
7925b9c547cSRui Paulo
7935b9c547cSRui Paulo static const u8 test_tls_prime58[128] = {
7945b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7955b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7965b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7975b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7985b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7995b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8005b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8015b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8025b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8035b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8045b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8055b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8065b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8075b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8085b9c547cSRui Paulo 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8095b9c547cSRui Paulo 0x03, 0xc1, 0xba, 0xc8, 0x25, 0xbe, 0x2d, 0xf3
8105b9c547cSRui Paulo };
8115b9c547cSRui Paulo
8125b9c547cSRui Paulo static const u8 test_tls_non_prime[] = {
8135b9c547cSRui Paulo /*
8145b9c547cSRui Paulo * This is not a prime and the value has the following factors:
8155b9c547cSRui Paulo * 13736783488716579923 * 16254860191773456563 * 18229434976173670763 *
8165b9c547cSRui Paulo * 11112313018289079419 * 10260802278580253339 * 12394009491575311499 *
8175b9c547cSRui Paulo * 12419059668711064739 * 14317973192687985827 * 10498605410533203179 *
8185b9c547cSRui Paulo * 16338688760390249003 * 11128963991123878883 * 12990532258280301419 *
8195b9c547cSRui Paulo * 3
8205b9c547cSRui Paulo */
8215b9c547cSRui Paulo 0x0C, 0x8C, 0x36, 0x9C, 0x6F, 0x71, 0x2E, 0xA7,
8225b9c547cSRui Paulo 0xAB, 0x32, 0xD3, 0x0F, 0x68, 0x3D, 0xB2, 0x6D,
8235b9c547cSRui Paulo 0x81, 0xDD, 0xC4, 0x84, 0x0D, 0x9C, 0x6E, 0x36,
8245b9c547cSRui Paulo 0x29, 0x70, 0xF3, 0x1E, 0x9A, 0x42, 0x0B, 0x67,
8255b9c547cSRui Paulo 0x82, 0x6B, 0xB1, 0xF2, 0xAF, 0x55, 0x28, 0xE7,
8265b9c547cSRui Paulo 0xDB, 0x67, 0x6C, 0xF7, 0x6B, 0xAC, 0xAC, 0xE5,
8275b9c547cSRui Paulo 0xF7, 0x9F, 0xD4, 0x63, 0x55, 0x70, 0x32, 0x7C,
8285b9c547cSRui Paulo 0x70, 0xFB, 0xAF, 0xB8, 0xEB, 0x37, 0xCF, 0x3F,
8295b9c547cSRui Paulo 0xFE, 0x94, 0x73, 0xF9, 0x7A, 0xC7, 0x12, 0x2E,
8305b9c547cSRui Paulo 0x9B, 0xB4, 0x7D, 0x08, 0x60, 0x83, 0x43, 0x52,
8315b9c547cSRui Paulo 0x83, 0x1E, 0xA5, 0xFC, 0xFA, 0x87, 0x12, 0xF4,
8325b9c547cSRui Paulo 0x64, 0xE2, 0xCE, 0x71, 0x17, 0x72, 0xB6, 0xAB
8335b9c547cSRui Paulo };
8345b9c547cSRui Paulo
8355b9c547cSRui Paulo #endif /* CONFIG_TESTING_OPTIONS */
8365b9c547cSRui Paulo
8375b9c547cSRui Paulo
tlsv1_server_get_dh_p(struct tlsv1_server * conn,const u8 ** dh_p,size_t * dh_p_len)8385b9c547cSRui Paulo void tlsv1_server_get_dh_p(struct tlsv1_server *conn, const u8 **dh_p,
8395b9c547cSRui Paulo size_t *dh_p_len)
8405b9c547cSRui Paulo {
8415b9c547cSRui Paulo *dh_p = conn->cred->dh_p;
8425b9c547cSRui Paulo *dh_p_len = conn->cred->dh_p_len;
8435b9c547cSRui Paulo
8445b9c547cSRui Paulo #ifdef CONFIG_TESTING_OPTIONS
8455b9c547cSRui Paulo if (conn->test_flags & TLS_DHE_PRIME_511B) {
8465b9c547cSRui Paulo tlsv1_server_log(conn, "TESTING: Use short 511-bit prime with DHE");
8475b9c547cSRui Paulo *dh_p = test_tls_prime511b;
8485b9c547cSRui Paulo *dh_p_len = sizeof(test_tls_prime511b);
8495b9c547cSRui Paulo } else if (conn->test_flags & TLS_DHE_PRIME_767B) {
8505b9c547cSRui Paulo tlsv1_server_log(conn, "TESTING: Use short 767-bit prime with DHE");
8515b9c547cSRui Paulo *dh_p = test_tls_prime767b;
8525b9c547cSRui Paulo *dh_p_len = sizeof(test_tls_prime767b);
8535b9c547cSRui Paulo } else if (conn->test_flags & TLS_DHE_PRIME_15) {
8545b9c547cSRui Paulo tlsv1_server_log(conn, "TESTING: Use bogus 15 \"prime\" with DHE");
8555b9c547cSRui Paulo *dh_p = test_tls_prime15;
8565b9c547cSRui Paulo *dh_p_len = sizeof(test_tls_prime15);
8575b9c547cSRui Paulo } else if (conn->test_flags & TLS_DHE_PRIME_58B) {
8585b9c547cSRui Paulo tlsv1_server_log(conn, "TESTING: Use short 58-bit prime in long container with DHE");
8595b9c547cSRui Paulo *dh_p = test_tls_prime58;
8605b9c547cSRui Paulo *dh_p_len = sizeof(test_tls_prime58);
8615b9c547cSRui Paulo } else if (conn->test_flags & TLS_DHE_NON_PRIME) {
8625b9c547cSRui Paulo tlsv1_server_log(conn, "TESTING: Use claim non-prime as the DHE prime");
8635b9c547cSRui Paulo *dh_p = test_tls_non_prime;
8645b9c547cSRui Paulo *dh_p_len = sizeof(test_tls_non_prime);
8655b9c547cSRui Paulo }
8665b9c547cSRui Paulo #endif /* CONFIG_TESTING_OPTIONS */
8675b9c547cSRui Paulo }
868