0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-19 19:52:15 +02:00

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.
This commit is contained in:
James Yonan 2015-01-06 17:16:06 -07:00
parent a80508ab21
commit dbd5995d7a

View File

@ -1,7 +1,37 @@
OpenVPN Protocol extensions
2015-01-06
1. DATA_V2 opcode with 24-bit peer ID
* The DATA_V2 opcode is 9.
* The DATA_V2 opcode/key_id byte is followed by 3 additional
(network endian) bytes indicating the peer ID.
* If a 4-byte DATA_V2 header is passed through ntohl,
the resulting high 8 bits will be the DATA_V2 opcode/key_id,
and the lower 24 bits will be the peer ID.
* A disabled peer ID is denoted by 0xFFFFFF.
* Server tells the client to use DATA_V2/peer_id by pushing
the directive "peer-id ID" where ID is a decimal integer
in the range [-1, 16777215]. Setting the peer ID to -1
transmits DATA_V2 packets with the peer ID field set to
0xFFFFFF. Setting the peer_id to -1 is the same as
setting it to 16777215 (i.e. 0xFFFFFF).
* Client never transmits DATA_V2 packets unless the server
has pushed a "peer-id" directive.
* Server never pushes a "peer-id" directive unless the
client has indicated its support for DATA_V2 by
including "IV_PROTO=2" in the peer info data.
* When DATA_V2 is used for "float" functionality, the server
must perform the following checks before allowing
a client to float, i.e. to assume a new source address.
(a) verify integrity (HMAC or GCM auth tag, replay
protection, etc.) of the DATA_V2 packet, and
(b) ensure that the float doesn't clobber a pre-existing
client (i.e. if the address floated to is already
owned by another client) unless it can be verified
that the pre-existing client is a previous instance
of the floating client.
2. AEAD mode
To support AEAD crypto modes such as AES-GCM, some protocol
@ -33,25 +63,42 @@ OpenVPN Protocol extensions
[ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ]
[ 4 bytes ] [ 4 bytes ] [ 16 bytes ]
[ AEAD additional data (AD) ]
Static Key wire protocol:
[ DATA_V2 opcode ] [ Packet ID ] [ Nonce tail (random) ] [ AEAD Auth tag ] [ ciphertext ]
[ AEAD nonce ]
[ 4 bytes ] [ 8 bytes ] [ 4 bytes ] [ 16 bytes ]
[ AEAD additional data (AD) ]
Note that because the HMAC keying material used to derive the
last 8 bytes of the AEAD nonce is negotiated once per key
Note that the AEAD additional data (AD) includes all data
preceding the AEAD Auth tag including the DATA_V2/peer_id
opcode and packet ID.
Also, note that because the HMAC keying material used to derive
the last 8 bytes of the AEAD nonce is negotiated once per key
as part of the control channel handshake, we can omit it from the
data channel packets, thereby saving 8 bytes per packet. So
only the 4-byte Packet ID component of the nonce must be
transmitted with every packet.
Also note that that the TLS wire protocol overhead is only 24
bytes, including the new 4 byte DATA_V2 opcode that includes
the Peer ID! Compare that with traditional AES-CBC mode and
DATA_V1 opcode: 1 (DATA_V1 opcode) + 20 (HMAC-SHA1 hash)
+ 8 (IV) + 4 (Packet ID) + 1-8 (PKCS#7 padding) = 34-41 bytes.
When negotiating AEAD mode, the client indicates its support
of AES-128-GCM, AES-192-GCM, and AES-192-GCM by including:
IV_NCP=2
in the peer info string (NCP stands for Negotiable Crypto
Parameters).
When the IV_NCP value is 2 or higher, it indicates that
the server may push an AEAD "cipher" directive, e.g.:
push "cipher AES-128-GCM"
In the future, the IV_NCP value (2 in the current
implementation) may be increased to indicate the
availability of additional negotiable ciphers.
3. Compression V2
@ -78,7 +125,7 @@ OpenVPN Protocol extensions
c. Compression occurred (2 bytes of overhead):
[ 0x50 ] [ compression Alg ID ] [ compressed IP/Ethernet packet ]
[ 0x50 ] [ compression Alg ID byte ] [ compressed IP/Ethernet packet ]
Compression Alg ID is one-byte algorithm identifier
for LZ4 (0x1), LZO (0x2), or Snappy (0x3).
@ -94,3 +141,58 @@ OpenVPN Protocol extensions
3. This technique does not require any byte swapping with
the tail of the packet which can potentially incur an
expensive cache miss.
When negotiating Compression V2 mode, the client indicates its
support by including the following in the peer info string:
IV_LZ4v2=1 -> LZ4 compression available in V2 format
IV_COMP_STUBv2=1 -> stub compression available in V2 format
(i.e. disable compression but still
retain compression framing)
In response, the server can push to the client:
push "compress lz4-v2" -> enable LZ4 compression in V2 format
or
push "compress stub-v2" -> disable compression but retain
compression framing in V2 format
4. TCP nonlinear mode
The OpenVPN 2.x packet ID and replay protection code, when running
in TCP mode, requires that the packet ID follows a linearly
incrementing sequence, i.e. 1, 2, 2, 3, ... This was a reasonable
requirement, since the reliable nature of TCP guaranteed that a
linear sequence of packet IDs transmitted by the sender would be
received in the same order by the receiver.
However, recent work has shown that multithreaded OpenVPN servers
may not be able to guarantee TCP packet ID linearity (on the
transmit side) without incurring a performance penalty. This
is because the packet ID for transmitted packets must be allocated
before the packet is encrypted, while a multithreaded OpenVPN server
might be concurrently encrypting and transmitting multiple packets
using different threads, where the order that the threads complete
encryption and transmit the packet is non-deterministic. This
non-deterministic ordering of packets over the TCP session means
that the client might see out-of-order packets and a non-linear
packet ID progression, just as clients now see with UDP.
My proposed solution to the issue is to relax the Packet ID
validation on the receiver side to allow non-linear packet ID
sequences, even in TCP mode. This essentially means that the
packet ID validation logic is now the same for both UDP and TCP.
The client indicates its ability to process non-linear packet
ID sequences in TCP mode by including the following in the
peer info string:
IV_TCPNL=1 -> TCP non-linear receiver supported
When the server receives a IV_TCPNL setting of 1 from the
client, it may transmit out-of-order packets in TCP mode.
Otherwise, servers must use other means (such as using thread
synchronization primitives) to ensure strictly linear packet
ID ordering in TCP mode.