blob: 4759509e53ebbfc34260446ec90d6b71f0727b62 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002 * TLS v1.0/v1.1/v1.2 server (RFC 2246, RFC 4346, RFC 5246)
Dmitry Shmidt818ea482014-03-10 13:15:21 -07003 * Copyright (c) 2006-2014, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10
11#include "common.h"
12#include "crypto/sha1.h"
13#include "crypto/tls.h"
14#include "tlsv1_common.h"
15#include "tlsv1_record.h"
16#include "tlsv1_server.h"
17#include "tlsv1_server_i.h"
18
19/* TODO:
20 * Support for a message fragmented across several records (RFC 2246, 6.2.1)
21 */
22
23
Dmitry Shmidt818ea482014-03-10 13:15:21 -070024void tlsv1_server_log(struct tlsv1_server *conn, const char *fmt, ...)
25{
26 va_list ap;
27 char *buf;
28 int buflen;
29
30 va_start(ap, fmt);
31 buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
32 va_end(ap);
33
34 buf = os_malloc(buflen);
35 if (buf == NULL)
36 return;
37 va_start(ap, fmt);
38 vsnprintf(buf, buflen, fmt, ap);
39 va_end(ap);
40
41 wpa_printf(MSG_DEBUG, "TLSv1: %s", buf);
42 if (conn->log_cb)
43 conn->log_cb(conn->log_cb_ctx, buf);
44
45 os_free(buf);
46}
47
48
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070049void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
50{
51 conn->alert_level = level;
52 conn->alert_description = description;
53}
54
55
56int tlsv1_server_derive_keys(struct tlsv1_server *conn,
57 const u8 *pre_master_secret,
58 size_t pre_master_secret_len)
59{
60 u8 seed[2 * TLS_RANDOM_LEN];
61 u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
62 u8 *pos;
63 size_t key_block_len;
64
65 if (pre_master_secret) {
66 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
67 pre_master_secret, pre_master_secret_len);
68 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
69 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
70 TLS_RANDOM_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080071 if (tls_prf(conn->rl.tls_version,
72 pre_master_secret, pre_master_secret_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070073 "master secret", seed, 2 * TLS_RANDOM_LEN,
74 conn->master_secret, TLS_MASTER_SECRET_LEN)) {
75 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
76 "master_secret");
77 return -1;
78 }
79 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
80 conn->master_secret, TLS_MASTER_SECRET_LEN);
81 }
82
83 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
84 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
85 key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
86 conn->rl.iv_size);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080087 if (tls_prf(conn->rl.tls_version,
88 conn->master_secret, TLS_MASTER_SECRET_LEN,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070089 "key expansion", seed, 2 * TLS_RANDOM_LEN,
90 key_block, key_block_len)) {
91 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
92 return -1;
93 }
94 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
95 key_block, key_block_len);
96
97 pos = key_block;
98
99 /* client_write_MAC_secret */
100 os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
101 pos += conn->rl.hash_size;
102 /* server_write_MAC_secret */
103 os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
104 pos += conn->rl.hash_size;
105
106 /* client_write_key */
107 os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
108 pos += conn->rl.key_material_len;
109 /* server_write_key */
110 os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
111 pos += conn->rl.key_material_len;
112
113 /* client_write_IV */
114 os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
115 pos += conn->rl.iv_size;
116 /* server_write_IV */
117 os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
118 pos += conn->rl.iv_size;
119
120 return 0;
121}
122
123
124/**
125 * tlsv1_server_handshake - Process TLS handshake
126 * @conn: TLSv1 server connection data from tlsv1_server_init()
127 * @in_data: Input data from TLS peer
128 * @in_len: Input data length
129 * @out_len: Length of the output buffer.
130 * Returns: Pointer to output data, %NULL on failure
131 */
132u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
133 const u8 *in_data, size_t in_len,
134 size_t *out_len)
135{
136 const u8 *pos, *end;
137 u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
138 size_t in_msg_len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800139 int used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700140
141 if (in_data == NULL || in_len == 0) {
142 wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
143 return NULL;
144 }
145
146 pos = in_data;
147 end = in_data + in_len;
148 in_msg = os_malloc(in_len);
149 if (in_msg == NULL)
150 return NULL;
151
152 /* Each received packet may include multiple records */
153 while (pos < end) {
154 in_msg_len = in_len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800155 used = tlsv1_record_receive(&conn->rl, pos, end - pos,
156 in_msg, &in_msg_len, &alert);
157 if (used < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700158 wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
159 "record failed");
160 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
161 goto failed;
162 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800163 if (used == 0) {
164 /* need more data */
165 wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
166 "yet supported");
Hai Shalom74f70d42019-02-11 14:42:39 -0800167 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
168 TLS_ALERT_INTERNAL_ERROR);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800169 goto failed;
170 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700171 ct = pos[0];
172
173 in_pos = in_msg;
174 in_end = in_msg + in_msg_len;
175
176 /* Each received record may include multiple messages of the
177 * same ContentType. */
178 while (in_pos < in_end) {
179 in_msg_len = in_end - in_pos;
180 if (tlsv1_server_process_handshake(conn, ct, in_pos,
181 &in_msg_len) < 0)
182 goto failed;
183 in_pos += in_msg_len;
184 }
185
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800186 pos += used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700187 }
188
189 os_free(in_msg);
190 in_msg = NULL;
191
192 msg = tlsv1_server_handshake_write(conn, out_len);
193
194failed:
195 os_free(in_msg);
196 if (conn->alert_level) {
197 if (conn->state == FAILED) {
198 /* Avoid alert loops */
199 wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
200 os_free(msg);
201 return NULL;
202 }
203 conn->state = FAILED;
204 os_free(msg);
205 msg = tlsv1_server_send_alert(conn, conn->alert_level,
206 conn->alert_description,
207 out_len);
Hai Shalom74f70d42019-02-11 14:42:39 -0800208 conn->write_alerts++;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700209 }
210
211 return msg;
212}
213
214
215/**
216 * tlsv1_server_encrypt - Encrypt data into TLS tunnel
217 * @conn: TLSv1 server connection data from tlsv1_server_init()
218 * @in_data: Pointer to plaintext data to be encrypted
219 * @in_len: Input buffer length
220 * @out_data: Pointer to output buffer (encrypted TLS data)
Dmitry Shmidt29333592017-01-09 12:27:11 -0800221 * @out_len: Maximum out_data length
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700222 * Returns: Number of bytes written to out_data, -1 on failure
223 *
224 * This function is used after TLS handshake has been completed successfully to
225 * send data in the encrypted tunnel.
226 */
227int tlsv1_server_encrypt(struct tlsv1_server *conn,
228 const u8 *in_data, size_t in_len,
229 u8 *out_data, size_t out_len)
230{
231 size_t rlen;
232
233 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
234 in_data, in_len);
235
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700236 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800237 out_data, out_len, in_data, in_len, &rlen) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700238 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
239 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
240 TLS_ALERT_INTERNAL_ERROR);
241 return -1;
242 }
243
244 return rlen;
245}
246
247
248/**
249 * tlsv1_server_decrypt - Decrypt data from TLS tunnel
250 * @conn: TLSv1 server connection data from tlsv1_server_init()
251 * @in_data: Pointer to input buffer (encrypted TLS data)
252 * @in_len: Input buffer length
253 * @out_data: Pointer to output buffer (decrypted data from TLS tunnel)
254 * @out_len: Maximum out_data length
255 * Returns: Number of bytes written to out_data, -1 on failure
256 *
257 * This function is used after TLS handshake has been completed successfully to
258 * receive data from the encrypted tunnel.
259 */
260int tlsv1_server_decrypt(struct tlsv1_server *conn,
261 const u8 *in_data, size_t in_len,
262 u8 *out_data, size_t out_len)
263{
264 const u8 *in_end, *pos;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800265 int used;
266 u8 alert, *out_end, *out_pos, ct;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700267 size_t olen;
268
269 pos = in_data;
270 in_end = in_data + in_len;
271 out_pos = out_data;
272 out_end = out_data + out_len;
273
274 while (pos < in_end) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800275 ct = pos[0];
276 olen = out_end - out_pos;
277 used = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
278 out_pos, &olen, &alert);
279 if (used < 0) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700280 tlsv1_server_log(conn, "Record layer processing failed");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800281 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
282 return -1;
283 }
284 if (used == 0) {
285 /* need more data */
286 wpa_printf(MSG_DEBUG, "TLSv1: Partial processing not "
287 "yet supported");
288 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
289 return -1;
290 }
291
292 if (ct == TLS_CONTENT_TYPE_ALERT) {
293 if (olen < 2) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700294 tlsv1_server_log(conn, "Alert underflow");
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800295 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
296 TLS_ALERT_DECODE_ERROR);
297 return -1;
298 }
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700299 tlsv1_server_log(conn, "Received alert %d:%d",
300 out_pos[0], out_pos[1]);
Hai Shalom74f70d42019-02-11 14:42:39 -0800301 conn->read_alerts++;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800302 if (out_pos[0] == TLS_ALERT_LEVEL_WARNING) {
303 /* Continue processing */
304 pos += used;
305 continue;
306 }
307
308 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
309 out_pos[1]);
310 return -1;
311 }
312
313 if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700314 tlsv1_server_log(conn, "Unexpected content type 0x%x",
315 pos[0]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700316 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
317 TLS_ALERT_UNEXPECTED_MESSAGE);
318 return -1;
319 }
320
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700321#ifdef CONFIG_TESTING_OPTIONS
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700322 if ((conn->test_flags &
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700323 (TLS_BREAK_VERIFY_DATA | TLS_BREAK_SRV_KEY_X_HASH |
324 TLS_BREAK_SRV_KEY_X_SIGNATURE)) &&
325 !conn->test_failure_reported) {
326 tlsv1_server_log(conn, "TEST-FAILURE: Client ApplData received after invalid handshake");
327 conn->test_failure_reported = 1;
328 }
329#endif /* CONFIG_TESTING_OPTIONS */
330
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700331 out_pos += olen;
332 if (out_pos > out_end) {
333 wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
334 "for processing the received record");
335 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
336 TLS_ALERT_INTERNAL_ERROR);
337 return -1;
338 }
339
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800340 pos += used;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700341 }
342
343 return out_pos - out_data;
344}
345
346
347/**
348 * tlsv1_server_global_init - Initialize TLSv1 server
349 * Returns: 0 on success, -1 on failure
350 *
351 * This function must be called before using any other TLSv1 server functions.
352 */
353int tlsv1_server_global_init(void)
354{
355 return crypto_global_init();
356}
357
358
359/**
360 * tlsv1_server_global_deinit - Deinitialize TLSv1 server
361 *
362 * This function can be used to deinitialize the TLSv1 server that was
363 * initialized by calling tlsv1_server_global_init(). No TLSv1 server functions
364 * can be called after this before calling tlsv1_server_global_init() again.
365 */
366void tlsv1_server_global_deinit(void)
367{
368 crypto_global_deinit();
369}
370
371
372/**
373 * tlsv1_server_init - Initialize TLSv1 server connection
374 * @cred: Pointer to server credentials from tlsv1_server_cred_alloc()
375 * Returns: Pointer to TLSv1 server connection data or %NULL on failure
376 */
377struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
378{
379 struct tlsv1_server *conn;
380 size_t count;
381 u16 *suites;
382
383 conn = os_zalloc(sizeof(*conn));
384 if (conn == NULL)
385 return NULL;
386
387 conn->cred = cred;
388
389 conn->state = CLIENT_HELLO;
390
391 if (tls_verify_hash_init(&conn->verify) < 0) {
392 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
393 "hash");
394 os_free(conn);
395 return NULL;
396 }
397
398 count = 0;
399 suites = conn->cipher_suites;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700400 suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
401 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA256;
402 suites[count++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700403 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700404 suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
405 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
406 suites[count++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700407 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700408 suites[count++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700409 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
410 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
411 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
412 conn->num_cipher_suites = count;
413
414 return conn;
415}
416
417
418static void tlsv1_server_clear_data(struct tlsv1_server *conn)
419{
420 tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
421 tlsv1_record_change_write_cipher(&conn->rl);
422 tlsv1_record_change_read_cipher(&conn->rl);
423 tls_verify_hash_free(&conn->verify);
424
425 crypto_public_key_free(conn->client_rsa_key);
426 conn->client_rsa_key = NULL;
427
428 os_free(conn->session_ticket);
429 conn->session_ticket = NULL;
430 conn->session_ticket_len = 0;
431 conn->use_session_ticket = 0;
432
433 os_free(conn->dh_secret);
434 conn->dh_secret = NULL;
435 conn->dh_secret_len = 0;
436}
437
438
439/**
440 * tlsv1_server_deinit - Deinitialize TLSv1 server connection
441 * @conn: TLSv1 server connection data from tlsv1_server_init()
442 */
443void tlsv1_server_deinit(struct tlsv1_server *conn)
444{
445 tlsv1_server_clear_data(conn);
446 os_free(conn);
447}
448
449
450/**
451 * tlsv1_server_established - Check whether connection has been established
452 * @conn: TLSv1 server connection data from tlsv1_server_init()
453 * Returns: 1 if connection is established, 0 if not
454 */
455int tlsv1_server_established(struct tlsv1_server *conn)
456{
457 return conn->state == ESTABLISHED;
458}
459
460
461/**
462 * tlsv1_server_prf - Use TLS-PRF to derive keying material
463 * @conn: TLSv1 server connection data from tlsv1_server_init()
464 * @label: Label (e.g., description of the key) for PRF
465 * @server_random_first: seed is 0 = client_random|server_random,
466 * 1 = server_random|client_random
467 * @out: Buffer for output data from TLS-PRF
468 * @out_len: Length of the output buffer
469 * Returns: 0 on success, -1 on failure
470 */
471int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
472 int server_random_first, u8 *out, size_t out_len)
473{
474 u8 seed[2 * TLS_RANDOM_LEN];
475
476 if (conn->state != ESTABLISHED)
477 return -1;
478
479 if (server_random_first) {
480 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
481 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
482 TLS_RANDOM_LEN);
483 } else {
484 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
485 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
486 TLS_RANDOM_LEN);
487 }
488
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800489 return tls_prf(conn->rl.tls_version,
490 conn->master_secret, TLS_MASTER_SECRET_LEN,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700491 label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
492}
493
494
495/**
496 * tlsv1_server_get_cipher - Get current cipher name
497 * @conn: TLSv1 server connection data from tlsv1_server_init()
498 * @buf: Buffer for the cipher name
499 * @buflen: buf size
500 * Returns: 0 on success, -1 on failure
501 *
502 * Get the name of the currently used cipher.
503 */
504int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
505 size_t buflen)
506{
507 char *cipher;
508
509 switch (conn->rl.cipher_suite) {
510 case TLS_RSA_WITH_RC4_128_MD5:
511 cipher = "RC4-MD5";
512 break;
513 case TLS_RSA_WITH_RC4_128_SHA:
514 cipher = "RC4-SHA";
515 break;
516 case TLS_RSA_WITH_DES_CBC_SHA:
517 cipher = "DES-CBC-SHA";
518 break;
519 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
520 cipher = "DES-CBC3-SHA";
521 break;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800522 case TLS_DHE_RSA_WITH_DES_CBC_SHA:
523 cipher = "DHE-RSA-DES-CBC-SHA";
524 break;
525 case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
526 cipher = "DHE-RSA-DES-CBC3-SHA";
527 break;
528 case TLS_DH_anon_WITH_RC4_128_MD5:
529 cipher = "ADH-RC4-MD5";
530 break;
531 case TLS_DH_anon_WITH_DES_CBC_SHA:
532 cipher = "ADH-DES-SHA";
533 break;
534 case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
535 cipher = "ADH-DES-CBC3-SHA";
536 break;
537 case TLS_RSA_WITH_AES_128_CBC_SHA:
538 cipher = "AES-128-SHA";
539 break;
540 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
541 cipher = "DHE-RSA-AES-128-SHA";
542 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700543 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
544 cipher = "ADH-AES-128-SHA";
545 break;
546 case TLS_RSA_WITH_AES_256_CBC_SHA:
547 cipher = "AES-256-SHA";
548 break;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800549 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
550 cipher = "DHE-RSA-AES-256-SHA";
551 break;
552 case TLS_DH_anon_WITH_AES_256_CBC_SHA:
553 cipher = "ADH-AES-256-SHA";
554 break;
555 case TLS_RSA_WITH_AES_128_CBC_SHA256:
556 cipher = "AES-128-SHA256";
557 break;
558 case TLS_RSA_WITH_AES_256_CBC_SHA256:
559 cipher = "AES-256-SHA256";
560 break;
561 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
562 cipher = "DHE-RSA-AES-128-SHA256";
563 break;
564 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
565 cipher = "DHE-RSA-AES-256-SHA256";
566 break;
567 case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
568 cipher = "ADH-AES-128-SHA256";
569 break;
570 case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
571 cipher = "ADH-AES-256-SHA256";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700572 break;
573 default:
574 return -1;
575 }
576
577 if (os_strlcpy(buf, cipher, buflen) >= buflen)
578 return -1;
579 return 0;
580}
581
582
583/**
584 * tlsv1_server_shutdown - Shutdown TLS connection
585 * @conn: TLSv1 server connection data from tlsv1_server_init()
586 * Returns: 0 on success, -1 on failure
587 */
588int tlsv1_server_shutdown(struct tlsv1_server *conn)
589{
590 conn->state = CLIENT_HELLO;
591
592 if (tls_verify_hash_init(&conn->verify) < 0) {
593 wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
594 "hash");
595 return -1;
596 }
597
598 tlsv1_server_clear_data(conn);
599
600 return 0;
601}
602
603
604/**
605 * tlsv1_server_resumed - Was session resumption used
606 * @conn: TLSv1 server connection data from tlsv1_server_init()
607 * Returns: 1 if current session used session resumption, 0 if not
608 */
609int tlsv1_server_resumed(struct tlsv1_server *conn)
610{
611 return 0;
612}
613
614
615/**
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800616 * tlsv1_server_get_random - Get random data from TLS connection
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700617 * @conn: TLSv1 server connection data from tlsv1_server_init()
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800618 * @keys: Structure of random data (filled on success)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700619 * Returns: 0 on success, -1 on failure
620 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800621int tlsv1_server_get_random(struct tlsv1_server *conn, struct tls_random *keys)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700622{
623 os_memset(keys, 0, sizeof(*keys));
624 if (conn->state == CLIENT_HELLO)
625 return -1;
626
627 keys->client_random = conn->client_random;
628 keys->client_random_len = TLS_RANDOM_LEN;
629
630 if (conn->state != SERVER_HELLO) {
631 keys->server_random = conn->server_random;
632 keys->server_random_len = TLS_RANDOM_LEN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700633 }
634
635 return 0;
636}
637
638
639/**
640 * tlsv1_server_get_keyblock_size - Get TLS key_block size
641 * @conn: TLSv1 server connection data from tlsv1_server_init()
642 * Returns: Size of the key_block for the negotiated cipher suite or -1 on
643 * failure
644 */
645int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
646{
647 if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
648 return -1;
649
650 return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
651 conn->rl.iv_size);
652}
653
654
655/**
656 * tlsv1_server_set_cipher_list - Configure acceptable cipher suites
657 * @conn: TLSv1 server connection data from tlsv1_server_init()
658 * @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
659 * (TLS_CIPHER_*).
660 * Returns: 0 on success, -1 on failure
661 */
662int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
663{
664 size_t count;
665 u16 *suites;
666
667 /* TODO: implement proper configuration of cipher suites */
668 if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
669 count = 0;
670 suites = conn->cipher_suites;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700671 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700672 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
673 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
674 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
675 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700676 suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700677 suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
678 suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
679 suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
680 suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
681 conn->num_cipher_suites = count;
682 }
683
684 return 0;
685}
686
687
688int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
689{
690 conn->verify_peer = verify_peer;
691 return 0;
692}
693
694
695void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
696 tlsv1_server_session_ticket_cb cb,
697 void *ctx)
698{
699 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
700 cb, ctx);
701 conn->session_ticket_cb = cb;
702 conn->session_ticket_cb_ctx = ctx;
703}
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700704
705
706void tlsv1_server_set_log_cb(struct tlsv1_server *conn,
707 void (*cb)(void *ctx, const char *msg), void *ctx)
708{
709 conn->log_cb = cb;
710 conn->log_cb_ctx = ctx;
711}
712
713
Hai Shalom74f70d42019-02-11 14:42:39 -0800714int tlsv1_server_get_failed(struct tlsv1_server *conn)
715{
716 return conn->state == FAILED;
717}
718
719
720int tlsv1_server_get_read_alerts(struct tlsv1_server *conn)
721{
722 return conn->read_alerts;
723}
724
725
726int tlsv1_server_get_write_alerts(struct tlsv1_server *conn)
727{
728 return conn->write_alerts;
729}
730
731
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700732#ifdef CONFIG_TESTING_OPTIONS
733void tlsv1_server_set_test_flags(struct tlsv1_server *conn, u32 flags)
734{
735 conn->test_flags = flags;
736}
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700737
738
739static const u8 test_tls_prime15[1] = {
740 15
741};
742
743static const u8 test_tls_prime511b[64] = {
744 0x50, 0xfb, 0xf1, 0xae, 0x01, 0xf1, 0xfe, 0xe6,
745 0xe1, 0xae, 0xdc, 0x1e, 0xbe, 0xfb, 0x9e, 0x58,
746 0x9a, 0xd7, 0x54, 0x9d, 0x6b, 0xb3, 0x78, 0xe2,
747 0x39, 0x7f, 0x30, 0x01, 0x25, 0xa1, 0xf9, 0x7c,
748 0x55, 0x0e, 0xa1, 0x15, 0xcc, 0x36, 0x34, 0xbb,
749 0x6c, 0x8b, 0x64, 0x45, 0x15, 0x7f, 0xd3, 0xe7,
750 0x31, 0xc8, 0x8e, 0x56, 0x8e, 0x95, 0xdc, 0xea,
751 0x9e, 0xdf, 0xf7, 0x56, 0xdd, 0xb0, 0x34, 0xdb
752};
753
754static const u8 test_tls_prime767b[96] = {
755 0x4c, 0xdc, 0xb8, 0x21, 0x20, 0x9d, 0xe8, 0xa3,
756 0x53, 0xd9, 0x1c, 0x18, 0xc1, 0x3a, 0x58, 0x67,
757 0xa7, 0x85, 0xf9, 0x28, 0x9b, 0xce, 0xc0, 0xd1,
758 0x05, 0x84, 0x61, 0x97, 0xb2, 0x86, 0x1c, 0xd0,
759 0xd1, 0x96, 0x23, 0x29, 0x8c, 0xc5, 0x30, 0x68,
760 0x3e, 0xf9, 0x05, 0xba, 0x60, 0xeb, 0xdb, 0xee,
761 0x2d, 0xdf, 0x84, 0x65, 0x49, 0x87, 0x90, 0x2a,
762 0xc9, 0x8e, 0x34, 0x63, 0x6d, 0x9a, 0x2d, 0x32,
763 0x1c, 0x46, 0xd5, 0x4e, 0x20, 0x20, 0x90, 0xac,
764 0xd5, 0x48, 0x79, 0x99, 0x0c, 0xe6, 0xed, 0xbf,
765 0x79, 0xc2, 0x47, 0x50, 0x95, 0x38, 0x38, 0xbc,
766 0xde, 0xb0, 0xd2, 0xe8, 0x97, 0xcb, 0x22, 0xbb
767};
768
769static const u8 test_tls_prime58[128] = {
770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785 0x03, 0xc1, 0xba, 0xc8, 0x25, 0xbe, 0x2d, 0xf3
786};
787
788static const u8 test_tls_non_prime[] = {
789 /*
790 * This is not a prime and the value has the following factors:
791 * 13736783488716579923 * 16254860191773456563 * 18229434976173670763 *
792 * 11112313018289079419 * 10260802278580253339 * 12394009491575311499 *
793 * 12419059668711064739 * 14317973192687985827 * 10498605410533203179 *
794 * 16338688760390249003 * 11128963991123878883 * 12990532258280301419 *
795 * 3
796 */
797 0x0C, 0x8C, 0x36, 0x9C, 0x6F, 0x71, 0x2E, 0xA7,
798 0xAB, 0x32, 0xD3, 0x0F, 0x68, 0x3D, 0xB2, 0x6D,
799 0x81, 0xDD, 0xC4, 0x84, 0x0D, 0x9C, 0x6E, 0x36,
800 0x29, 0x70, 0xF3, 0x1E, 0x9A, 0x42, 0x0B, 0x67,
801 0x82, 0x6B, 0xB1, 0xF2, 0xAF, 0x55, 0x28, 0xE7,
802 0xDB, 0x67, 0x6C, 0xF7, 0x6B, 0xAC, 0xAC, 0xE5,
803 0xF7, 0x9F, 0xD4, 0x63, 0x55, 0x70, 0x32, 0x7C,
804 0x70, 0xFB, 0xAF, 0xB8, 0xEB, 0x37, 0xCF, 0x3F,
805 0xFE, 0x94, 0x73, 0xF9, 0x7A, 0xC7, 0x12, 0x2E,
806 0x9B, 0xB4, 0x7D, 0x08, 0x60, 0x83, 0x43, 0x52,
807 0x83, 0x1E, 0xA5, 0xFC, 0xFA, 0x87, 0x12, 0xF4,
808 0x64, 0xE2, 0xCE, 0x71, 0x17, 0x72, 0xB6, 0xAB
809};
810
Dmitry Shmidt818ea482014-03-10 13:15:21 -0700811#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700812
813
814void tlsv1_server_get_dh_p(struct tlsv1_server *conn, const u8 **dh_p,
815 size_t *dh_p_len)
816{
817 *dh_p = conn->cred->dh_p;
818 *dh_p_len = conn->cred->dh_p_len;
819
820#ifdef CONFIG_TESTING_OPTIONS
821 if (conn->test_flags & TLS_DHE_PRIME_511B) {
822 tlsv1_server_log(conn, "TESTING: Use short 511-bit prime with DHE");
823 *dh_p = test_tls_prime511b;
824 *dh_p_len = sizeof(test_tls_prime511b);
825 } else if (conn->test_flags & TLS_DHE_PRIME_767B) {
826 tlsv1_server_log(conn, "TESTING: Use short 767-bit prime with DHE");
827 *dh_p = test_tls_prime767b;
828 *dh_p_len = sizeof(test_tls_prime767b);
829 } else if (conn->test_flags & TLS_DHE_PRIME_15) {
830 tlsv1_server_log(conn, "TESTING: Use bogus 15 \"prime\" with DHE");
831 *dh_p = test_tls_prime15;
832 *dh_p_len = sizeof(test_tls_prime15);
833 } else if (conn->test_flags & TLS_DHE_PRIME_58B) {
834 tlsv1_server_log(conn, "TESTING: Use short 58-bit prime in long container with DHE");
835 *dh_p = test_tls_prime58;
836 *dh_p_len = sizeof(test_tls_prime58);
837 } else if (conn->test_flags & TLS_DHE_NON_PRIME) {
838 tlsv1_server_log(conn, "TESTING: Use claim non-prime as the DHE prime");
839 *dh_p = test_tls_non_prime;
840 *dh_p_len = sizeof(test_tls_non_prime);
841 }
842#endif /* CONFIG_TESTING_OPTIONS */
843}