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