1189251Ssam/*
2214734Srpaulo * TLS interface functions and an internal TLS implementation
3252726Srpaulo * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
4189251Ssam *
5252726Srpaulo * This software may be distributed under the terms of the BSD license.
6252726Srpaulo * See README for more details.
7189251Ssam *
8189251Ssam * This file interface functions for hostapd/wpa_supplicant to use the
9189251Ssam * integrated TLSv1 implementation.
10189251Ssam */
11189251Ssam
12189251Ssam#include "includes.h"
13189251Ssam
14189251Ssam#include "common.h"
15189251Ssam#include "tls.h"
16189251Ssam#include "tls/tlsv1_client.h"
17189251Ssam#include "tls/tlsv1_server.h"
18189251Ssam
19189251Ssam
20189251Ssamstatic int tls_ref_count = 0;
21189251Ssam
22189251Ssamstruct tls_global {
23189251Ssam	int server;
24189251Ssam	struct tlsv1_credentials *server_cred;
25189251Ssam	int check_crl;
26189251Ssam};
27189251Ssam
28189251Ssamstruct tls_connection {
29189251Ssam	struct tlsv1_client *client;
30189251Ssam	struct tlsv1_server *server;
31189251Ssam};
32189251Ssam
33189251Ssam
34189251Ssamvoid * tls_init(const struct tls_config *conf)
35189251Ssam{
36189251Ssam	struct tls_global *global;
37189251Ssam
38189251Ssam	if (tls_ref_count == 0) {
39189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
40189251Ssam		if (tlsv1_client_global_init())
41189251Ssam			return NULL;
42189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
43189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
44189251Ssam		if (tlsv1_server_global_init())
45189251Ssam			return NULL;
46189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
47189251Ssam	}
48189251Ssam	tls_ref_count++;
49189251Ssam
50189251Ssam	global = os_zalloc(sizeof(*global));
51189251Ssam	if (global == NULL)
52189251Ssam		return NULL;
53189251Ssam
54189251Ssam	return global;
55189251Ssam}
56189251Ssam
57189251Ssamvoid tls_deinit(void *ssl_ctx)
58189251Ssam{
59189251Ssam	struct tls_global *global = ssl_ctx;
60189251Ssam	tls_ref_count--;
61189251Ssam	if (tls_ref_count == 0) {
62189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
63189251Ssam		tlsv1_client_global_deinit();
64189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
65189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
66189251Ssam		tlsv1_cred_free(global->server_cred);
67189251Ssam		tlsv1_server_global_deinit();
68189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
69189251Ssam	}
70189251Ssam	os_free(global);
71189251Ssam}
72189251Ssam
73189251Ssam
74189251Ssamint tls_get_errors(void *tls_ctx)
75189251Ssam{
76189251Ssam	return 0;
77189251Ssam}
78189251Ssam
79189251Ssam
80189251Ssamstruct tls_connection * tls_connection_init(void *tls_ctx)
81189251Ssam{
82189251Ssam	struct tls_connection *conn;
83189251Ssam	struct tls_global *global = tls_ctx;
84189251Ssam
85189251Ssam	conn = os_zalloc(sizeof(*conn));
86189251Ssam	if (conn == NULL)
87189251Ssam		return NULL;
88189251Ssam
89189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
90189251Ssam	if (!global->server) {
91189251Ssam		conn->client = tlsv1_client_init();
92189251Ssam		if (conn->client == NULL) {
93189251Ssam			os_free(conn);
94189251Ssam			return NULL;
95189251Ssam		}
96189251Ssam	}
97189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
98189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
99189251Ssam	if (global->server) {
100189251Ssam		conn->server = tlsv1_server_init(global->server_cred);
101189251Ssam		if (conn->server == NULL) {
102189251Ssam			os_free(conn);
103189251Ssam			return NULL;
104189251Ssam		}
105189251Ssam	}
106189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
107189251Ssam
108189251Ssam	return conn;
109189251Ssam}
110189251Ssam
111189251Ssam
112189251Ssamvoid tls_connection_deinit(void *tls_ctx, struct tls_connection *conn)
113189251Ssam{
114189251Ssam	if (conn == NULL)
115189251Ssam		return;
116189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
117189251Ssam	if (conn->client)
118189251Ssam		tlsv1_client_deinit(conn->client);
119189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
120189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
121189251Ssam	if (conn->server)
122189251Ssam		tlsv1_server_deinit(conn->server);
123189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
124189251Ssam	os_free(conn);
125189251Ssam}
126189251Ssam
127189251Ssam
128189251Ssamint tls_connection_established(void *tls_ctx, struct tls_connection *conn)
129189251Ssam{
130189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
131189251Ssam	if (conn->client)
132189251Ssam		return tlsv1_client_established(conn->client);
133189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
134189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
135189251Ssam	if (conn->server)
136189251Ssam		return tlsv1_server_established(conn->server);
137189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
138189251Ssam	return 0;
139189251Ssam}
140189251Ssam
141189251Ssam
142189251Ssamint tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
143189251Ssam{
144189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
145189251Ssam	if (conn->client)
146189251Ssam		return tlsv1_client_shutdown(conn->client);
147189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
148189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
149189251Ssam	if (conn->server)
150189251Ssam		return tlsv1_server_shutdown(conn->server);
151189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
152189251Ssam	return -1;
153189251Ssam}
154189251Ssam
155189251Ssam
156189251Ssamint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
157189251Ssam			      const struct tls_connection_params *params)
158189251Ssam{
159189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
160189251Ssam	struct tlsv1_credentials *cred;
161189251Ssam
162189251Ssam	if (conn->client == NULL)
163189251Ssam		return -1;
164189251Ssam
165189251Ssam	cred = tlsv1_cred_alloc();
166189251Ssam	if (cred == NULL)
167189251Ssam		return -1;
168189251Ssam
169189251Ssam	if (tlsv1_set_ca_cert(cred, params->ca_cert,
170189251Ssam			      params->ca_cert_blob, params->ca_cert_blob_len,
171189251Ssam			      params->ca_path)) {
172189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
173189251Ssam			   "certificates");
174189251Ssam		tlsv1_cred_free(cred);
175189251Ssam		return -1;
176189251Ssam	}
177189251Ssam
178189251Ssam	if (tlsv1_set_cert(cred, params->client_cert,
179189251Ssam			   params->client_cert_blob,
180189251Ssam			   params->client_cert_blob_len)) {
181189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to configure client "
182189251Ssam			   "certificate");
183189251Ssam		tlsv1_cred_free(cred);
184189251Ssam		return -1;
185189251Ssam	}
186189251Ssam
187189251Ssam	if (tlsv1_set_private_key(cred, params->private_key,
188189251Ssam				  params->private_key_passwd,
189189251Ssam				  params->private_key_blob,
190189251Ssam				  params->private_key_blob_len)) {
191189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to load private key");
192189251Ssam		tlsv1_cred_free(cred);
193189251Ssam		return -1;
194189251Ssam	}
195189251Ssam
196189251Ssam	if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
197189251Ssam			       params->dh_blob_len)) {
198189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
199189251Ssam		tlsv1_cred_free(cred);
200189251Ssam		return -1;
201189251Ssam	}
202189251Ssam
203189251Ssam	if (tlsv1_client_set_cred(conn->client, cred) < 0) {
204189251Ssam		tlsv1_cred_free(cred);
205189251Ssam		return -1;
206189251Ssam	}
207189251Ssam
208252726Srpaulo	tlsv1_client_set_time_checks(
209252726Srpaulo		conn->client, !(params->flags & TLS_CONN_DISABLE_TIME_CHECKS));
210252726Srpaulo
211189251Ssam	return 0;
212189251Ssam#else /* CONFIG_TLS_INTERNAL_CLIENT */
213189251Ssam	return -1;
214189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
215189251Ssam}
216189251Ssam
217189251Ssam
218189251Ssamint tls_global_set_params(void *tls_ctx,
219189251Ssam			  const struct tls_connection_params *params)
220189251Ssam{
221189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
222189251Ssam	struct tls_global *global = tls_ctx;
223189251Ssam	struct tlsv1_credentials *cred;
224189251Ssam
225189251Ssam	/* Currently, global parameters are only set when running in server
226189251Ssam	 * mode. */
227189251Ssam	global->server = 1;
228189251Ssam	tlsv1_cred_free(global->server_cred);
229189251Ssam	global->server_cred = cred = tlsv1_cred_alloc();
230189251Ssam	if (cred == NULL)
231189251Ssam		return -1;
232189251Ssam
233189251Ssam	if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
234189251Ssam			      params->ca_cert_blob_len, params->ca_path)) {
235189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
236189251Ssam			   "certificates");
237189251Ssam		return -1;
238189251Ssam	}
239189251Ssam
240189251Ssam	if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
241189251Ssam			   params->client_cert_blob_len)) {
242189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to configure server "
243189251Ssam			   "certificate");
244189251Ssam		return -1;
245189251Ssam	}
246189251Ssam
247189251Ssam	if (tlsv1_set_private_key(cred, params->private_key,
248189251Ssam				  params->private_key_passwd,
249189251Ssam				  params->private_key_blob,
250189251Ssam				  params->private_key_blob_len)) {
251189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to load private key");
252189251Ssam		return -1;
253189251Ssam	}
254189251Ssam
255189251Ssam	if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
256189251Ssam			       params->dh_blob_len)) {
257189251Ssam		wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
258189251Ssam		return -1;
259189251Ssam	}
260189251Ssam
261189251Ssam	return 0;
262189251Ssam#else /* CONFIG_TLS_INTERNAL_SERVER */
263189251Ssam	return -1;
264189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
265189251Ssam}
266189251Ssam
267189251Ssam
268189251Ssamint tls_global_set_verify(void *tls_ctx, int check_crl)
269189251Ssam{
270189251Ssam	struct tls_global *global = tls_ctx;
271189251Ssam	global->check_crl = check_crl;
272189251Ssam	return 0;
273189251Ssam}
274189251Ssam
275189251Ssam
276189251Ssamint tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
277189251Ssam			      int verify_peer)
278189251Ssam{
279189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
280189251Ssam	if (conn->server)
281189251Ssam		return tlsv1_server_set_verify(conn->server, verify_peer);
282189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
283189251Ssam	return -1;
284189251Ssam}
285189251Ssam
286189251Ssam
287189251Ssamint tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
288189251Ssam			    struct tls_keys *keys)
289189251Ssam{
290189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
291189251Ssam	if (conn->client)
292189251Ssam		return tlsv1_client_get_keys(conn->client, keys);
293189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
294189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
295189251Ssam	if (conn->server)
296189251Ssam		return tlsv1_server_get_keys(conn->server, keys);
297189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
298189251Ssam	return -1;
299189251Ssam}
300189251Ssam
301189251Ssam
302189251Ssamint tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
303189251Ssam		       const char *label, int server_random_first,
304189251Ssam		       u8 *out, size_t out_len)
305189251Ssam{
306189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
307189251Ssam	if (conn->client) {
308189251Ssam		return tlsv1_client_prf(conn->client, label,
309189251Ssam					server_random_first,
310189251Ssam					out, out_len);
311189251Ssam	}
312189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
313189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
314189251Ssam	if (conn->server) {
315189251Ssam		return tlsv1_server_prf(conn->server, label,
316189251Ssam					server_random_first,
317189251Ssam					out, out_len);
318189251Ssam	}
319189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
320189251Ssam	return -1;
321189251Ssam}
322189251Ssam
323189251Ssam
324214734Srpaulostruct wpabuf * tls_connection_handshake(void *tls_ctx,
325214734Srpaulo					 struct tls_connection *conn,
326214734Srpaulo					 const struct wpabuf *in_data,
327214734Srpaulo					 struct wpabuf **appl_data)
328189251Ssam{
329252726Srpaulo	return tls_connection_handshake2(tls_ctx, conn, in_data, appl_data,
330252726Srpaulo					 NULL);
331252726Srpaulo}
332252726Srpaulo
333252726Srpaulo
334252726Srpaulostruct wpabuf * tls_connection_handshake2(void *tls_ctx,
335252726Srpaulo					  struct tls_connection *conn,
336252726Srpaulo					  const struct wpabuf *in_data,
337252726Srpaulo					  struct wpabuf **appl_data,
338252726Srpaulo					  int *need_more_data)
339252726Srpaulo{
340189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
341214734Srpaulo	u8 *res, *ad;
342214734Srpaulo	size_t res_len, ad_len;
343214734Srpaulo	struct wpabuf *out;
344214734Srpaulo
345189251Ssam	if (conn->client == NULL)
346189251Ssam		return NULL;
347189251Ssam
348214734Srpaulo	ad = NULL;
349214734Srpaulo	res = tlsv1_client_handshake(conn->client,
350214734Srpaulo				     in_data ? wpabuf_head(in_data) : NULL,
351214734Srpaulo				     in_data ? wpabuf_len(in_data) : 0,
352252726Srpaulo				     &res_len, &ad, &ad_len, need_more_data);
353214734Srpaulo	if (res == NULL)
354214734Srpaulo		return NULL;
355214734Srpaulo	out = wpabuf_alloc_ext_data(res, res_len);
356214734Srpaulo	if (out == NULL) {
357214734Srpaulo		os_free(res);
358214734Srpaulo		os_free(ad);
359214734Srpaulo		return NULL;
360214734Srpaulo	}
361214734Srpaulo	if (appl_data) {
362214734Srpaulo		if (ad) {
363214734Srpaulo			*appl_data = wpabuf_alloc_ext_data(ad, ad_len);
364214734Srpaulo			if (*appl_data == NULL)
365214734Srpaulo				os_free(ad);
366214734Srpaulo		} else
367214734Srpaulo			*appl_data = NULL;
368214734Srpaulo	} else
369214734Srpaulo		os_free(ad);
370189251Ssam
371214734Srpaulo	return out;
372189251Ssam#else /* CONFIG_TLS_INTERNAL_CLIENT */
373189251Ssam	return NULL;
374189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
375189251Ssam}
376189251Ssam
377189251Ssam
378214734Srpaulostruct wpabuf * tls_connection_server_handshake(void *tls_ctx,
379214734Srpaulo						struct tls_connection *conn,
380214734Srpaulo						const struct wpabuf *in_data,
381214734Srpaulo						struct wpabuf **appl_data)
382189251Ssam{
383189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
384214734Srpaulo	u8 *res;
385214734Srpaulo	size_t res_len;
386214734Srpaulo	struct wpabuf *out;
387214734Srpaulo
388189251Ssam	if (conn->server == NULL)
389189251Ssam		return NULL;
390189251Ssam
391214734Srpaulo	if (appl_data)
392214734Srpaulo		*appl_data = NULL;
393214734Srpaulo
394214734Srpaulo	res = tlsv1_server_handshake(conn->server, wpabuf_head(in_data),
395214734Srpaulo				     wpabuf_len(in_data), &res_len);
396214734Srpaulo	if (res == NULL && tlsv1_server_established(conn->server))
397214734Srpaulo		return wpabuf_alloc(0);
398214734Srpaulo	if (res == NULL)
399214734Srpaulo		return NULL;
400214734Srpaulo	out = wpabuf_alloc_ext_data(res, res_len);
401214734Srpaulo	if (out == NULL) {
402214734Srpaulo		os_free(res);
403214734Srpaulo		return NULL;
404189251Ssam	}
405214734Srpaulo
406189251Ssam	return out;
407189251Ssam#else /* CONFIG_TLS_INTERNAL_SERVER */
408189251Ssam	return NULL;
409189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
410189251Ssam}
411189251Ssam
412189251Ssam
413214734Srpaulostruct wpabuf * tls_connection_encrypt(void *tls_ctx,
414214734Srpaulo				       struct tls_connection *conn,
415214734Srpaulo				       const struct wpabuf *in_data)
416189251Ssam{
417189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
418189251Ssam	if (conn->client) {
419214734Srpaulo		struct wpabuf *buf;
420214734Srpaulo		int res;
421214734Srpaulo		buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
422214734Srpaulo		if (buf == NULL)
423214734Srpaulo			return NULL;
424214734Srpaulo		res = tlsv1_client_encrypt(conn->client, wpabuf_head(in_data),
425214734Srpaulo					   wpabuf_len(in_data),
426214734Srpaulo					   wpabuf_mhead(buf),
427214734Srpaulo					   wpabuf_size(buf));
428214734Srpaulo		if (res < 0) {
429214734Srpaulo			wpabuf_free(buf);
430214734Srpaulo			return NULL;
431214734Srpaulo		}
432214734Srpaulo		wpabuf_put(buf, res);
433214734Srpaulo		return buf;
434189251Ssam	}
435189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
436189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
437189251Ssam	if (conn->server) {
438214734Srpaulo		struct wpabuf *buf;
439214734Srpaulo		int res;
440214734Srpaulo		buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
441214734Srpaulo		if (buf == NULL)
442214734Srpaulo			return NULL;
443214734Srpaulo		res = tlsv1_server_encrypt(conn->server, wpabuf_head(in_data),
444214734Srpaulo					   wpabuf_len(in_data),
445214734Srpaulo					   wpabuf_mhead(buf),
446214734Srpaulo					   wpabuf_size(buf));
447214734Srpaulo		if (res < 0) {
448214734Srpaulo			wpabuf_free(buf);
449214734Srpaulo			return NULL;
450214734Srpaulo		}
451214734Srpaulo		wpabuf_put(buf, res);
452214734Srpaulo		return buf;
453189251Ssam	}
454189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
455214734Srpaulo	return NULL;
456189251Ssam}
457189251Ssam
458189251Ssam
459214734Srpaulostruct wpabuf * tls_connection_decrypt(void *tls_ctx,
460214734Srpaulo				       struct tls_connection *conn,
461214734Srpaulo				       const struct wpabuf *in_data)
462189251Ssam{
463252726Srpaulo	return tls_connection_decrypt2(tls_ctx, conn, in_data, NULL);
464252726Srpaulo}
465252726Srpaulo
466252726Srpaulo
467252726Srpaulostruct wpabuf * tls_connection_decrypt2(void *tls_ctx,
468252726Srpaulo					struct tls_connection *conn,
469252726Srpaulo					const struct wpabuf *in_data,
470252726Srpaulo					int *need_more_data)
471252726Srpaulo{
472252726Srpaulo	if (need_more_data)
473252726Srpaulo		*need_more_data = 0;
474252726Srpaulo
475189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
476189251Ssam	if (conn->client) {
477252726Srpaulo		return tlsv1_client_decrypt(conn->client, wpabuf_head(in_data),
478252726Srpaulo					    wpabuf_len(in_data),
479252726Srpaulo					    need_more_data);
480189251Ssam	}
481189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
482189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
483189251Ssam	if (conn->server) {
484214734Srpaulo		struct wpabuf *buf;
485214734Srpaulo		int res;
486214734Srpaulo		buf = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
487214734Srpaulo		if (buf == NULL)
488214734Srpaulo			return NULL;
489214734Srpaulo		res = tlsv1_server_decrypt(conn->server, wpabuf_head(in_data),
490214734Srpaulo					   wpabuf_len(in_data),
491214734Srpaulo					   wpabuf_mhead(buf),
492214734Srpaulo					   wpabuf_size(buf));
493214734Srpaulo		if (res < 0) {
494214734Srpaulo			wpabuf_free(buf);
495214734Srpaulo			return NULL;
496214734Srpaulo		}
497214734Srpaulo		wpabuf_put(buf, res);
498214734Srpaulo		return buf;
499189251Ssam	}
500189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
501214734Srpaulo	return NULL;
502189251Ssam}
503189251Ssam
504189251Ssam
505189251Ssamint tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
506189251Ssam{
507189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
508189251Ssam	if (conn->client)
509189251Ssam		return tlsv1_client_resumed(conn->client);
510189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
511189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
512189251Ssam	if (conn->server)
513189251Ssam		return tlsv1_server_resumed(conn->server);
514189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
515189251Ssam	return -1;
516189251Ssam}
517189251Ssam
518189251Ssam
519189251Ssamint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
520189251Ssam				   u8 *ciphers)
521189251Ssam{
522189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
523189251Ssam	if (conn->client)
524189251Ssam		return tlsv1_client_set_cipher_list(conn->client, ciphers);
525189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
526189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
527189251Ssam	if (conn->server)
528189251Ssam		return tlsv1_server_set_cipher_list(conn->server, ciphers);
529189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
530189251Ssam	return -1;
531189251Ssam}
532189251Ssam
533189251Ssam
534189251Ssamint tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
535189251Ssam		   char *buf, size_t buflen)
536189251Ssam{
537189251Ssam	if (conn == NULL)
538189251Ssam		return -1;
539189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
540189251Ssam	if (conn->client)
541189251Ssam		return tlsv1_client_get_cipher(conn->client, buf, buflen);
542189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
543189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
544189251Ssam	if (conn->server)
545189251Ssam		return tlsv1_server_get_cipher(conn->server, buf, buflen);
546189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
547189251Ssam	return -1;
548189251Ssam}
549189251Ssam
550189251Ssam
551189251Ssamint tls_connection_enable_workaround(void *tls_ctx,
552189251Ssam				     struct tls_connection *conn)
553189251Ssam{
554189251Ssam	return -1;
555189251Ssam}
556189251Ssam
557189251Ssam
558189251Ssamint tls_connection_client_hello_ext(void *tls_ctx, struct tls_connection *conn,
559189251Ssam				    int ext_type, const u8 *data,
560189251Ssam				    size_t data_len)
561189251Ssam{
562189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
563189251Ssam	if (conn->client) {
564189251Ssam		return tlsv1_client_hello_ext(conn->client, ext_type,
565189251Ssam					      data, data_len);
566189251Ssam	}
567189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
568189251Ssam	return -1;
569189251Ssam}
570189251Ssam
571189251Ssam
572189251Ssamint tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn)
573189251Ssam{
574189251Ssam	return 0;
575189251Ssam}
576189251Ssam
577189251Ssam
578189251Ssamint tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn)
579189251Ssam{
580189251Ssam	return 0;
581189251Ssam}
582189251Ssam
583189251Ssam
584189251Ssamint tls_connection_get_write_alerts(void *tls_ctx,
585189251Ssam				    struct tls_connection *conn)
586189251Ssam{
587189251Ssam	return 0;
588189251Ssam}
589189251Ssam
590189251Ssam
591189251Ssamint tls_connection_get_keyblock_size(void *tls_ctx,
592189251Ssam				     struct tls_connection *conn)
593189251Ssam{
594189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
595189251Ssam	if (conn->client)
596189251Ssam		return tlsv1_client_get_keyblock_size(conn->client);
597189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
598189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
599189251Ssam	if (conn->server)
600189251Ssam		return tlsv1_server_get_keyblock_size(conn->server);
601189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
602189251Ssam	return -1;
603189251Ssam}
604189251Ssam
605189251Ssam
606189251Ssamunsigned int tls_capabilities(void *tls_ctx)
607189251Ssam{
608189251Ssam	return 0;
609189251Ssam}
610189251Ssam
611189251Ssam
612189251Ssamint tls_connection_set_session_ticket_cb(void *tls_ctx,
613189251Ssam					 struct tls_connection *conn,
614189251Ssam					 tls_session_ticket_cb cb,
615189251Ssam					 void *ctx)
616189251Ssam{
617189251Ssam#ifdef CONFIG_TLS_INTERNAL_CLIENT
618189251Ssam	if (conn->client) {
619189251Ssam		tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
620189251Ssam		return 0;
621189251Ssam	}
622189251Ssam#endif /* CONFIG_TLS_INTERNAL_CLIENT */
623189251Ssam#ifdef CONFIG_TLS_INTERNAL_SERVER
624189251Ssam	if (conn->server) {
625189251Ssam		tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
626189251Ssam		return 0;
627189251Ssam	}
628189251Ssam#endif /* CONFIG_TLS_INTERNAL_SERVER */
629189251Ssam	return -1;
630189251Ssam}
631