Skip to content

Commit dbd5995

Browse files
committed
OpenVPN Protocol extensions update.
1. Added specific details on DATA_V2/peer-id/float support. 2. For AEAD mode, emphasized that the leading 8 bytes (4 bytes for DATA_V2/peer-id and 4 for packet ID) is all included in the AD. 3. Added specific details on protocol negotiation where the client indicates protocol extension availability with IV_x parameters in the peer info string, and the server responds by pushing directives to the client to enable the feature. 4. Added "TCP nonlinear mode" section, a new protocol extension that is needed by multithreaded TCP servers.
1 parent a80508a commit dbd5995

File tree

1 file changed

+110
-8
lines changed

1 file changed

+110
-8
lines changed

doc/openvpn-protocol-extensions.txt

+110-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,37 @@
11
OpenVPN Protocol extensions
2+
2015-01-06
23

34
1. DATA_V2 opcode with 24-bit peer ID
45

6+
* The DATA_V2 opcode is 9.
7+
* The DATA_V2 opcode/key_id byte is followed by 3 additional
8+
(network endian) bytes indicating the peer ID.
9+
* If a 4-byte DATA_V2 header is passed through ntohl,
10+
the resulting high 8 bits will be the DATA_V2 opcode/key_id,
11+
and the lower 24 bits will be the peer ID.
12+
* A disabled peer ID is denoted by 0xFFFFFF.
13+
* Server tells the client to use DATA_V2/peer_id by pushing
14+
the directive "peer-id ID" where ID is a decimal integer
15+
in the range [-1, 16777215]. Setting the peer ID to -1
16+
transmits DATA_V2 packets with the peer ID field set to
17+
0xFFFFFF. Setting the peer_id to -1 is the same as
18+
setting it to 16777215 (i.e. 0xFFFFFF).
19+
* Client never transmits DATA_V2 packets unless the server
20+
has pushed a "peer-id" directive.
21+
* Server never pushes a "peer-id" directive unless the
22+
client has indicated its support for DATA_V2 by
23+
including "IV_PROTO=2" in the peer info data.
24+
* When DATA_V2 is used for "float" functionality, the server
25+
must perform the following checks before allowing
26+
a client to float, i.e. to assume a new source address.
27+
(a) verify integrity (HMAC or GCM auth tag, replay
28+
protection, etc.) of the DATA_V2 packet, and
29+
(b) ensure that the float doesn't clobber a pre-existing
30+
client (i.e. if the address floated to is already
31+
owned by another client) unless it can be verified
32+
that the pre-existing client is a previous instance
33+
of the floating client.
34+
535
2. AEAD mode
636

737
To support AEAD crypto modes such as AES-GCM, some protocol
@@ -33,25 +63,42 @@ OpenVPN Protocol extensions
3363

3464
[ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ]
3565
[ 4 bytes ] [ 4 bytes ] [ 16 bytes ]
66+
[ AEAD additional data (AD) ]
3667

3768
Static Key wire protocol:
3869

3970
[ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ]
4071
[ AEAD nonce ]
4172
[ 4 bytes ] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ]
73+
[ AEAD additional data (AD) ]
74+
75+
Note that the AEAD additional data (AD) includes all data
76+
preceding the AEAD Auth tag including the DATA_V2/peer_id
77+
opcode and packet ID.
4278

43-
Note that because the HMAC keying material used to derive the
44-
last 8 bytes of the AEAD nonce is negotiated once per key
79+
Also, note that because the HMAC keying material used to derive
80+
the last 8 bytes of the AEAD nonce is negotiated once per key
4581
as part of the control channel handshake, we can omit it from the
4682
data channel packets, thereby saving 8 bytes per packet. So
4783
only the 4-byte Packet ID component of the nonce must be
4884
transmitted with every packet.
4985

50-
Also note that that the TLS wire protocol overhead is only 24
51-
bytes, including the new 4 byte DATA_V2 opcode that includes
52-
the Peer ID! Compare that with traditional AES-CBC mode and
53-
DATA_V1 opcode: 1 (DATA_V1 opcode) + 20 (HMAC-SHA1 hash)
54-
+ 8 (IV) + 4 (Packet ID) + 1-8 (PKCS#7 padding) = 34-41 bytes.
86+
When negotiating AEAD mode, the client indicates its support
87+
of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including:
88+
89+
IV_NCP=2
90+
91+
in the peer info string (NCP stands for Negotiable Crypto
92+
Parameters).
93+
94+
When the IV_NCP value is 2 or higher, it indicates that
95+
the server may push an AEAD "cipher" directive, e.g.:
96+
97+
push "cipher AES-128-GCM"
98+
99+
In the future, the IV_NCP value (2 in the current
100+
implementation) may be increased to indicate the
101+
availability of additional negotiable ciphers.
55102

56103
3. Compression V2
57104

@@ -78,7 +125,7 @@ OpenVPN Protocol extensions
78125

79126
c. Compression occurred (2 bytes of overhead):
80127

81-
[ 0x50 ] [ compression Alg ID ] [ compressed IP/Ethernet packet ]
128+
[ 0x50 ] [ compression Alg ID byte ] [ compressed IP/Ethernet packet ]
82129

83130
Compression Alg ID is one-byte algorithm identifier
84131
for LZ4 (0x1), LZO (0x2), or Snappy (0x3).
@@ -94,3 +141,58 @@ OpenVPN Protocol extensions
94141
3. This technique does not require any byte swapping with
95142
the tail of the packet which can potentially incur an
96143
expensive cache miss.
144+
145+
When negotiating Compression V2 mode, the client indicates its
146+
support by including the following in the peer info string:
147+
148+
IV_LZ4v2=1 -> LZ4 compression available in V2 format
149+
IV_COMP_STUBv2=1 -> stub compression available in V2 format
150+
(i.e. disable compression but still
151+
retain compression framing)
152+
153+
In response, the server can push to the client:
154+
155+
push "compress lz4-v2" -> enable LZ4 compression in V2 format
156+
157+
or
158+
159+
push "compress stub-v2" -> disable compression but retain
160+
compression framing in V2 format
161+
162+
4. TCP nonlinear mode
163+
164+
The OpenVPN 2.x packet ID and replay protection code, when running
165+
in TCP mode, requires that the packet ID follows a linearly
166+
incrementing sequence, i.e. 1, 2, 2, 3, ... This was a reasonable
167+
requirement, since the reliable nature of TCP guaranteed that a
168+
linear sequence of packet IDs transmitted by the sender would be
169+
received in the same order by the receiver.
170+
171+
However, recent work has shown that multithreaded OpenVPN servers
172+
may not be able to guarantee TCP packet ID linearity (on the
173+
transmit side) without incurring a performance penalty. This
174+
is because the packet ID for transmitted packets must be allocated
175+
before the packet is encrypted, while a multithreaded OpenVPN server
176+
might be concurrently encrypting and transmitting multiple packets
177+
using different threads, where the order that the threads complete
178+
encryption and transmit the packet is non-deterministic. This
179+
non-deterministic ordering of packets over the TCP session means
180+
that the client might see out-of-order packets and a non-linear
181+
packet ID progression, just as clients now see with UDP.
182+
183+
My proposed solution to the issue is to relax the Packet ID
184+
validation on the receiver side to allow non-linear packet ID
185+
sequences, even in TCP mode. This essentially means that the
186+
packet ID validation logic is now the same for both UDP and TCP.
187+
188+
The client indicates its ability to process non-linear packet
189+
ID sequences in TCP mode by including the following in the
190+
peer info string:
191+
192+
IV_TCPNL=1 -> TCP non-linear receiver supported
193+
194+
When the server receives a IV_TCPNL setting of 1 from the
195+
client, it may transmit out-of-order packets in TCP mode.
196+
Otherwise, servers must use other means (such as using thread
197+
synchronization primitives) to ensure strictly linear packet
198+
ID ordering in TCP mode.

0 commit comments

Comments
 (0)