Skip to content

Commit 05191d8

Browse files
committed
Merge branch 'in-kernel-support-for-the-tls-alert-protocol'
Chuck Lever says: ==================== In-kernel support for the TLS Alert protocol IMO the kernel doesn't need user space (ie, tlshd) to handle the TLS Alert protocol. Instead, a set of small helper functions can be used to handle sending and receiving TLS Alerts for in-kernel TLS consumers. ==================== Merged on top of a tag in case it's needed in the NFS tree. Link: https://lore.kernel.org/r/169047923706.5241.1181144206068116926.stgit@oracle-102.nfsv4bat.org Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 222a6c4 + b470985 commit 05191d8

File tree

13 files changed

+431
-46
lines changed

13 files changed

+431
-46
lines changed

drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <crypto/internal/hash.h>
2323
#include <linux/tls.h>
2424
#include <net/tls.h>
25+
#include <net/tls_prot.h>
2526
#include <net/tls_toe.h>
2627

2728
#include "t4fw_api.h"

include/net/handshake.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,10 @@ int tls_server_hello_x509(const struct tls_handshake_args *args, gfp_t flags);
4040
int tls_server_hello_psk(const struct tls_handshake_args *args, gfp_t flags);
4141

4242
bool tls_handshake_cancel(struct sock *sk);
43+
void tls_handshake_close(struct socket *sock);
44+
45+
u8 tls_get_record_type(const struct sock *sk, const struct cmsghdr *msg);
46+
void tls_alert_recv(const struct sock *sk, const struct msghdr *msg,
47+
u8 *level, u8 *description);
4348

4449
#endif /* _NET_HANDSHAKE_H */

include/net/tls.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ extern const struct tls_cipher_size_desc tls_cipher_size_desc[];
6969

7070
#define TLS_CRYPTO_INFO_READY(info) ((info)->cipher_type)
7171

72-
#define TLS_RECORD_TYPE_ALERT 0x15
73-
#define TLS_RECORD_TYPE_HANDSHAKE 0x16
74-
#define TLS_RECORD_TYPE_DATA 0x17
75-
7672
#define TLS_AAD_SPACE_SIZE 13
7773

7874
#define MAX_IV_SIZE 16

include/net/tls_prot.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
2+
/*
3+
* Copyright (c) 2023, Oracle and/or its affiliates.
4+
*
5+
* TLS Protocol definitions
6+
*
7+
* From https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
8+
*/
9+
10+
#ifndef _TLS_PROT_H
11+
#define _TLS_PROT_H
12+
13+
/*
14+
* TLS Record protocol: ContentType
15+
*/
16+
enum {
17+
TLS_RECORD_TYPE_CHANGE_CIPHER_SPEC = 20,
18+
TLS_RECORD_TYPE_ALERT = 21,
19+
TLS_RECORD_TYPE_HANDSHAKE = 22,
20+
TLS_RECORD_TYPE_DATA = 23,
21+
TLS_RECORD_TYPE_HEARTBEAT = 24,
22+
TLS_RECORD_TYPE_TLS12_CID = 25,
23+
TLS_RECORD_TYPE_ACK = 26,
24+
};
25+
26+
/*
27+
* TLS Alert protocol: AlertLevel
28+
*/
29+
enum {
30+
TLS_ALERT_LEVEL_WARNING = 1,
31+
TLS_ALERT_LEVEL_FATAL = 2,
32+
};
33+
34+
/*
35+
* TLS Alert protocol: AlertDescription
36+
*/
37+
enum {
38+
TLS_ALERT_DESC_CLOSE_NOTIFY = 0,
39+
TLS_ALERT_DESC_UNEXPECTED_MESSAGE = 10,
40+
TLS_ALERT_DESC_BAD_RECORD_MAC = 20,
41+
TLS_ALERT_DESC_RECORD_OVERFLOW = 22,
42+
TLS_ALERT_DESC_HANDSHAKE_FAILURE = 40,
43+
TLS_ALERT_DESC_BAD_CERTIFICATE = 42,
44+
TLS_ALERT_DESC_UNSUPPORTED_CERTIFICATE = 43,
45+
TLS_ALERT_DESC_CERTIFICATE_REVOKED = 44,
46+
TLS_ALERT_DESC_CERTIFICATE_EXPIRED = 45,
47+
TLS_ALERT_DESC_CERTIFICATE_UNKNOWN = 46,
48+
TLS_ALERT_DESC_ILLEGAL_PARAMETER = 47,
49+
TLS_ALERT_DESC_UNKNOWN_CA = 48,
50+
TLS_ALERT_DESC_ACCESS_DENIED = 49,
51+
TLS_ALERT_DESC_DECODE_ERROR = 50,
52+
TLS_ALERT_DESC_DECRYPT_ERROR = 51,
53+
TLS_ALERT_DESC_TOO_MANY_CIDS_REQUESTED = 52,
54+
TLS_ALERT_DESC_PROTOCOL_VERSION = 70,
55+
TLS_ALERT_DESC_INSUFFICIENT_SECURITY = 71,
56+
TLS_ALERT_DESC_INTERNAL_ERROR = 80,
57+
TLS_ALERT_DESC_INAPPROPRIATE_FALLBACK = 86,
58+
TLS_ALERT_DESC_USER_CANCELED = 90,
59+
TLS_ALERT_DESC_MISSING_EXTENSION = 109,
60+
TLS_ALERT_DESC_UNSUPPORTED_EXTENSION = 110,
61+
TLS_ALERT_DESC_UNRECOGNIZED_NAME = 112,
62+
TLS_ALERT_DESC_BAD_CERTIFICATE_STATUS_RESPONSE = 113,
63+
TLS_ALERT_DESC_UNKNOWN_PSK_IDENTITY = 115,
64+
TLS_ALERT_DESC_CERTIFICATE_REQUIRED = 116,
65+
TLS_ALERT_DESC_NO_APPLICATION_PROTOCOL = 120,
66+
};
67+
68+
#endif /* _TLS_PROT_H */

include/trace/events/handshake.h

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,86 @@
66
#define _TRACE_HANDSHAKE_H
77

88
#include <linux/net.h>
9+
#include <net/tls_prot.h>
910
#include <linux/tracepoint.h>
11+
#include <trace/events/net_probe_common.h>
12+
13+
#define TLS_RECORD_TYPE_LIST \
14+
record_type(CHANGE_CIPHER_SPEC) \
15+
record_type(ALERT) \
16+
record_type(HANDSHAKE) \
17+
record_type(DATA) \
18+
record_type(HEARTBEAT) \
19+
record_type(TLS12_CID) \
20+
record_type_end(ACK)
21+
22+
#undef record_type
23+
#undef record_type_end
24+
#define record_type(x) TRACE_DEFINE_ENUM(TLS_RECORD_TYPE_##x);
25+
#define record_type_end(x) TRACE_DEFINE_ENUM(TLS_RECORD_TYPE_##x);
26+
27+
TLS_RECORD_TYPE_LIST
28+
29+
#undef record_type
30+
#undef record_type_end
31+
#define record_type(x) { TLS_RECORD_TYPE_##x, #x },
32+
#define record_type_end(x) { TLS_RECORD_TYPE_##x, #x }
33+
34+
#define show_tls_content_type(type) \
35+
__print_symbolic(type, TLS_RECORD_TYPE_LIST)
36+
37+
TRACE_DEFINE_ENUM(TLS_ALERT_LEVEL_WARNING);
38+
TRACE_DEFINE_ENUM(TLS_ALERT_LEVEL_FATAL);
39+
40+
#define show_tls_alert_level(level) \
41+
__print_symbolic(level, \
42+
{ TLS_ALERT_LEVEL_WARNING, "Warning" }, \
43+
{ TLS_ALERT_LEVEL_FATAL, "Fatal" })
44+
45+
#define TLS_ALERT_DESCRIPTION_LIST \
46+
alert_description(CLOSE_NOTIFY) \
47+
alert_description(UNEXPECTED_MESSAGE) \
48+
alert_description(BAD_RECORD_MAC) \
49+
alert_description(RECORD_OVERFLOW) \
50+
alert_description(HANDSHAKE_FAILURE) \
51+
alert_description(BAD_CERTIFICATE) \
52+
alert_description(UNSUPPORTED_CERTIFICATE) \
53+
alert_description(CERTIFICATE_REVOKED) \
54+
alert_description(CERTIFICATE_EXPIRED) \
55+
alert_description(CERTIFICATE_UNKNOWN) \
56+
alert_description(ILLEGAL_PARAMETER) \
57+
alert_description(UNKNOWN_CA) \
58+
alert_description(ACCESS_DENIED) \
59+
alert_description(DECODE_ERROR) \
60+
alert_description(DECRYPT_ERROR) \
61+
alert_description(TOO_MANY_CIDS_REQUESTED) \
62+
alert_description(PROTOCOL_VERSION) \
63+
alert_description(INSUFFICIENT_SECURITY) \
64+
alert_description(INTERNAL_ERROR) \
65+
alert_description(INAPPROPRIATE_FALLBACK) \
66+
alert_description(USER_CANCELED) \
67+
alert_description(MISSING_EXTENSION) \
68+
alert_description(UNSUPPORTED_EXTENSION) \
69+
alert_description(UNRECOGNIZED_NAME) \
70+
alert_description(BAD_CERTIFICATE_STATUS_RESPONSE) \
71+
alert_description(UNKNOWN_PSK_IDENTITY) \
72+
alert_description(CERTIFICATE_REQUIRED) \
73+
alert_description_end(NO_APPLICATION_PROTOCOL)
74+
75+
#undef alert_description
76+
#undef alert_description_end
77+
#define alert_description(x) TRACE_DEFINE_ENUM(TLS_ALERT_DESC_##x);
78+
#define alert_description_end(x) TRACE_DEFINE_ENUM(TLS_ALERT_DESC_##x);
79+
80+
TLS_ALERT_DESCRIPTION_LIST
81+
82+
#undef alert_description
83+
#undef alert_description_end
84+
#define alert_description(x) { TLS_ALERT_DESC_##x, #x },
85+
#define alert_description_end(x) { TLS_ALERT_DESC_##x, #x }
86+
87+
#define show_tls_alert_description(desc) \
88+
__print_symbolic(desc, TLS_ALERT_DESCRIPTION_LIST)
1089

1190
DECLARE_EVENT_CLASS(handshake_event_class,
1291
TP_PROTO(
@@ -106,6 +185,47 @@ DECLARE_EVENT_CLASS(handshake_error_class,
106185
), \
107186
TP_ARGS(net, req, sk, err))
108187

188+
DECLARE_EVENT_CLASS(handshake_alert_class,
189+
TP_PROTO(
190+
const struct sock *sk,
191+
unsigned char level,
192+
unsigned char description
193+
),
194+
TP_ARGS(sk, level, description),
195+
TP_STRUCT__entry(
196+
/* sockaddr_in6 is always bigger than sockaddr_in */
197+
__array(__u8, saddr, sizeof(struct sockaddr_in6))
198+
__array(__u8, daddr, sizeof(struct sockaddr_in6))
199+
__field(unsigned int, netns_ino)
200+
__field(unsigned long, level)
201+
__field(unsigned long, description)
202+
),
203+
TP_fast_assign(
204+
const struct inet_sock *inet = inet_sk(sk);
205+
206+
memset(__entry->saddr, 0, sizeof(struct sockaddr_in6));
207+
memset(__entry->daddr, 0, sizeof(struct sockaddr_in6));
208+
TP_STORE_ADDR_PORTS(__entry, inet, sk);
209+
210+
__entry->netns_ino = sock_net(sk)->ns.inum;
211+
__entry->level = level;
212+
__entry->description = description;
213+
),
214+
TP_printk("src=%pISpc dest=%pISpc %s: %s",
215+
__entry->saddr, __entry->daddr,
216+
show_tls_alert_level(__entry->level),
217+
show_tls_alert_description(__entry->description)
218+
)
219+
);
220+
#define DEFINE_HANDSHAKE_ALERT(name) \
221+
DEFINE_EVENT(handshake_alert_class, name, \
222+
TP_PROTO( \
223+
const struct sock *sk, \
224+
unsigned char level, \
225+
unsigned char description \
226+
), \
227+
TP_ARGS(sk, level, description))
228+
109229

110230
/*
111231
* Request lifetime events
@@ -154,6 +274,46 @@ DEFINE_HANDSHAKE_ERROR(handshake_cmd_accept_err);
154274
DEFINE_HANDSHAKE_FD_EVENT(handshake_cmd_done);
155275
DEFINE_HANDSHAKE_ERROR(handshake_cmd_done_err);
156276

277+
/*
278+
* TLS Record events
279+
*/
280+
281+
TRACE_EVENT(tls_contenttype,
282+
TP_PROTO(
283+
const struct sock *sk,
284+
unsigned char type
285+
),
286+
TP_ARGS(sk, type),
287+
TP_STRUCT__entry(
288+
/* sockaddr_in6 is always bigger than sockaddr_in */
289+
__array(__u8, saddr, sizeof(struct sockaddr_in6))
290+
__array(__u8, daddr, sizeof(struct sockaddr_in6))
291+
__field(unsigned int, netns_ino)
292+
__field(unsigned long, type)
293+
),
294+
TP_fast_assign(
295+
const struct inet_sock *inet = inet_sk(sk);
296+
297+
memset(__entry->saddr, 0, sizeof(struct sockaddr_in6));
298+
memset(__entry->daddr, 0, sizeof(struct sockaddr_in6));
299+
TP_STORE_ADDR_PORTS(__entry, inet, sk);
300+
301+
__entry->netns_ino = sock_net(sk)->ns.inum;
302+
__entry->type = type;
303+
),
304+
TP_printk("src=%pISpc dest=%pISpc %s",
305+
__entry->saddr, __entry->daddr,
306+
show_tls_content_type(__entry->type)
307+
)
308+
);
309+
310+
/*
311+
* TLS Alert events
312+
*/
313+
314+
DEFINE_HANDSHAKE_ALERT(tls_alert_send);
315+
DEFINE_HANDSHAKE_ALERT(tls_alert_recv);
316+
157317
#endif /* _TRACE_HANDSHAKE_H */
158318

159319
#include <trace/define_trace.h>

net/handshake/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
#
99

1010
obj-y += handshake.o
11-
handshake-y := genl.o netlink.o request.o tlshd.o trace.o
11+
handshake-y := alert.o genl.o netlink.o request.o tlshd.o trace.o
1212

1313
obj-$(CONFIG_NET_HANDSHAKE_KUNIT_TEST) += handshake-test.o

net/handshake/alert.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Handle the TLS Alert protocol
4+
*
5+
* Author: Chuck Lever <[email protected]>
6+
*
7+
* Copyright (c) 2023, Oracle and/or its affiliates.
8+
*/
9+
10+
#include <linux/types.h>
11+
#include <linux/socket.h>
12+
#include <linux/kernel.h>
13+
#include <linux/module.h>
14+
#include <linux/skbuff.h>
15+
#include <linux/inet.h>
16+
17+
#include <net/sock.h>
18+
#include <net/handshake.h>
19+
#include <net/tls.h>
20+
#include <net/tls_prot.h>
21+
22+
#include "handshake.h"
23+
24+
#include <trace/events/handshake.h>
25+
26+
/**
27+
* tls_alert_send - send a TLS Alert on a kTLS socket
28+
* @sock: open kTLS socket to send on
29+
* @level: TLS Alert level
30+
* @description: TLS Alert description
31+
*
32+
* Returns zero on success or a negative errno.
33+
*/
34+
int tls_alert_send(struct socket *sock, u8 level, u8 description)
35+
{
36+
u8 record_type = TLS_RECORD_TYPE_ALERT;
37+
u8 buf[CMSG_SPACE(sizeof(record_type))];
38+
struct msghdr msg = { 0 };
39+
struct cmsghdr *cmsg;
40+
struct kvec iov;
41+
u8 alert[2];
42+
int ret;
43+
44+
trace_tls_alert_send(sock->sk, level, description);
45+
46+
alert[0] = level;
47+
alert[1] = description;
48+
iov.iov_base = alert;
49+
iov.iov_len = sizeof(alert);
50+
51+
memset(buf, 0, sizeof(buf));
52+
msg.msg_control = buf;
53+
msg.msg_controllen = sizeof(buf);
54+
msg.msg_flags = MSG_DONTWAIT;
55+
56+
cmsg = CMSG_FIRSTHDR(&msg);
57+
cmsg->cmsg_level = SOL_TLS;
58+
cmsg->cmsg_type = TLS_SET_RECORD_TYPE;
59+
cmsg->cmsg_len = CMSG_LEN(sizeof(record_type));
60+
memcpy(CMSG_DATA(cmsg), &record_type, sizeof(record_type));
61+
62+
iov_iter_kvec(&msg.msg_iter, ITER_SOURCE, &iov, 1, iov.iov_len);
63+
ret = sock_sendmsg(sock, &msg);
64+
return ret < 0 ? ret : 0;
65+
}
66+
67+
/**
68+
* tls_get_record_type - Look for TLS RECORD_TYPE information
69+
* @sk: socket (for IP address information)
70+
* @cmsg: incoming message to be parsed
71+
*
72+
* Returns zero or a TLS_RECORD_TYPE value.
73+
*/
74+
u8 tls_get_record_type(const struct sock *sk, const struct cmsghdr *cmsg)
75+
{
76+
u8 record_type;
77+
78+
if (cmsg->cmsg_level != SOL_TLS)
79+
return 0;
80+
if (cmsg->cmsg_type != TLS_GET_RECORD_TYPE)
81+
return 0;
82+
83+
record_type = *((u8 *)CMSG_DATA(cmsg));
84+
trace_tls_contenttype(sk, record_type);
85+
return record_type;
86+
}
87+
EXPORT_SYMBOL(tls_get_record_type);
88+
89+
/**
90+
* tls_alert_recv - Parse TLS Alert messages
91+
* @sk: socket (for IP address information)
92+
* @msg: incoming message to be parsed
93+
* @level: OUT - TLS AlertLevel value
94+
* @description: OUT - TLS AlertDescription value
95+
*
96+
*/
97+
void tls_alert_recv(const struct sock *sk, const struct msghdr *msg,
98+
u8 *level, u8 *description)
99+
{
100+
const struct kvec *iov;
101+
u8 *data;
102+
103+
iov = msg->msg_iter.kvec;
104+
data = iov->iov_base;
105+
*level = data[0];
106+
*description = data[1];
107+
108+
trace_tls_alert_recv(sk, *level, *description);
109+
}
110+
EXPORT_SYMBOL(tls_alert_recv);

0 commit comments

Comments
 (0)