xref: /linux/drivers/net/ovpn/proto.h (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*  OpenVPN data channel offload
3  *
4  *  Copyright (C) 2020-2025 OpenVPN, Inc.
5  *
6  *  Author:	Antonio Quartulli <antonio@openvpn.net>
7  *		James Yonan <james@openvpn.net>
8  */
9 
10 #ifndef _NET_OVPN_PROTO_H_
11 #define _NET_OVPN_PROTO_H_
12 
13 #include "main.h"
14 
15 #include <linux/bitfield.h>
16 #include <linux/skbuff.h>
17 
18 /* When the OpenVPN protocol is ran in AEAD mode, use
19  * the OpenVPN packet ID as the AEAD nonce:
20  *
21  *    00000005 521c3b01 4308c041
22  *    [seq # ] [  nonce_tail   ]
23  *    [     12-byte full IV    ] -> OVPN_NONCE_SIZE
24  *    [4-bytes                   -> OVPN_NONCE_WIRE_SIZE
25  *    on wire]
26  */
27 
28 /* nonce size (96bits) as required by AEAD ciphers */
29 #define OVPN_NONCE_SIZE			12
30 /* last 8 bytes of AEAD nonce: provided by userspace and usually derived
31  * from key material generated during TLS handshake
32  */
33 #define OVPN_NONCE_TAIL_SIZE		8
34 
35 /* OpenVPN nonce size reduced by 8-byte nonce tail -- this is the
36  * size of the AEAD Associated Data (AD) sent over the wire
37  * and is normally the head of the IV
38  */
39 #define OVPN_NONCE_WIRE_SIZE (OVPN_NONCE_SIZE - OVPN_NONCE_TAIL_SIZE)
40 
41 #define OVPN_OPCODE_SIZE		4 /* DATA_V2 opcode size */
42 #define OVPN_OPCODE_KEYID_MASK		0x07000000
43 #define OVPN_OPCODE_PKTTYPE_MASK	0xF8000000
44 #define OVPN_OPCODE_PEERID_MASK		0x00FFFFFF
45 
46 /* packet opcodes of interest to us */
47 #define OVPN_DATA_V1			6 /* data channel v1 packet */
48 #define OVPN_DATA_V2			9 /* data channel v2 packet */
49 
50 #define OVPN_PEER_ID_UNDEF		0x00FFFFFF
51 
52 /**
53  * ovpn_opcode_from_skb - extract OP code from skb at specified offset
54  * @skb: the packet to extract the OP code from
55  * @offset: the offset in the data buffer where the OP code is located
56  *
57  * Note: this function assumes that the skb head was pulled enough
58  * to access the first 4 bytes.
59  *
60  * Return: the OP code
61  */
ovpn_opcode_from_skb(const struct sk_buff * skb,u16 offset)62 static inline u8 ovpn_opcode_from_skb(const struct sk_buff *skb, u16 offset)
63 {
64 	u32 opcode = be32_to_cpu(*(__be32 *)(skb->data + offset));
65 
66 	return FIELD_GET(OVPN_OPCODE_PKTTYPE_MASK, opcode);
67 }
68 
69 /**
70  * ovpn_peer_id_from_skb - extract peer ID from skb at specified offset
71  * @skb: the packet to extract the OP code from
72  * @offset: the offset in the data buffer where the OP code is located
73  *
74  * Note: this function assumes that the skb head was pulled enough
75  * to access the first 4 bytes.
76  *
77  * Return: the peer ID
78  */
ovpn_peer_id_from_skb(const struct sk_buff * skb,u16 offset)79 static inline u32 ovpn_peer_id_from_skb(const struct sk_buff *skb, u16 offset)
80 {
81 	u32 opcode = be32_to_cpu(*(__be32 *)(skb->data + offset));
82 
83 	return FIELD_GET(OVPN_OPCODE_PEERID_MASK, opcode);
84 }
85 
86 /**
87  * ovpn_key_id_from_skb - extract key ID from the skb head
88  * @skb: the packet to extract the key ID code from
89  *
90  * Note: this function assumes that the skb head was pulled enough
91  * to access the first 4 bytes.
92  *
93  * Return: the key ID
94  */
ovpn_key_id_from_skb(const struct sk_buff * skb)95 static inline u8 ovpn_key_id_from_skb(const struct sk_buff *skb)
96 {
97 	u32 opcode = be32_to_cpu(*(__be32 *)skb->data);
98 
99 	return FIELD_GET(OVPN_OPCODE_KEYID_MASK, opcode);
100 }
101 
102 /**
103  * ovpn_opcode_compose - combine OP code, key ID and peer ID to wire format
104  * @opcode: the OP code
105  * @key_id: the key ID
106  * @peer_id: the peer ID
107  *
108  * Return: a 4 bytes integer obtained combining all input values following the
109  * OpenVPN wire format. This integer can then be written to the packet header.
110  */
ovpn_opcode_compose(u8 opcode,u8 key_id,u32 peer_id)111 static inline u32 ovpn_opcode_compose(u8 opcode, u8 key_id, u32 peer_id)
112 {
113 	return FIELD_PREP(OVPN_OPCODE_PKTTYPE_MASK, opcode) |
114 	       FIELD_PREP(OVPN_OPCODE_KEYID_MASK, key_id) |
115 	       FIELD_PREP(OVPN_OPCODE_PEERID_MASK, peer_id);
116 }
117 
118 #endif /* _NET_OVPN_OVPNPROTO_H_ */
119