mirror of
https://github.com/OpenVPN/openvpn3.git
synced 2024-09-19 19:52:15 +02:00
Added initial OpenVPN Protocol extensions doc.
This commit is contained in:
parent
c2c7292a70
commit
a80508ab21
96
doc/openvpn-protocol-extensions.txt
Normal file
96
doc/openvpn-protocol-extensions.txt
Normal file
@ -0,0 +1,96 @@
|
||||
OpenVPN Protocol extensions
|
||||
|
||||
1. DATA_V2 opcode with 24-bit peer ID
|
||||
|
||||
2. AEAD mode
|
||||
|
||||
To support AEAD crypto modes such as AES-GCM, some protocol
|
||||
changes are in order. AES-GCM, for example, requires a 12
|
||||
byte unique nonce for every packet. I would propose that 4
|
||||
bytes be taken from the Packet ID which increments for every
|
||||
packet and therefore provides uniqueness. The remaining 8
|
||||
bytes would be derived from the random key material that would
|
||||
normally be used to key the HMAC key. This is possible since
|
||||
AEAD modes use a combined key for encryption and integrity
|
||||
checking, therefore the random key material for HMAC is
|
||||
unused and can be repurposed as an AEAD nonce source. The 8
|
||||
byte nonce component derived from the HMAC keying material
|
||||
would remain constant for a given Key State. Only the 4 byte
|
||||
Packet ID would increment for each packet. Because AEAD
|
||||
encryption can be compromised if the nonce ever repeats for
|
||||
a given key, the implementation MUST disable encryption
|
||||
for a key if the 32-bit packet ID wraps. In practical usage,
|
||||
renegotiation usually preempts wrapping, so the
|
||||
disable-encryption-on-wrap feature is a failsafe.
|
||||
|
||||
AEAD Nonce:
|
||||
|
||||
[ Packet ID ] [ HMAC keying material ]
|
||||
[ 4 bytes ] [ 8 bytes ]
|
||||
[ AEAD nonce total: 12 bytes ]
|
||||
|
||||
TLS wire protocol:
|
||||
|
||||
[ DATA_V2 opcode ] [ Packet ID ] [ AEAD Auth tag ] [ ciphertext ]
|
||||
[ 4 bytes ] [ 4 bytes ] [ 16 bytes ]
|
||||
|
||||
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 ]
|
||||
|
||||
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.
|
||||
|
||||
3. Compression V2
|
||||
|
||||
I have observed that compression in many cases, even when
|
||||
enabled, often does not produce packet size reduction
|
||||
because much of the packet data typically generated by web
|
||||
sessions is already compressed. Further, the single byte that
|
||||
precedes the packet and indicates whether or not compression
|
||||
occurred has the unfortunate side effect of misaligning the IP
|
||||
packet in cases where compression did not occur. To remedy this,
|
||||
I propose a Compression V2 header that is optimized for the
|
||||
case where compression does not occur.
|
||||
|
||||
a. No compression occurred and first byte of IP/Ethernet packet
|
||||
is NOT 0x50 (0 bytes of overhead and maintains alignment):
|
||||
|
||||
[ uncompressed IP/Ethernet packet ]
|
||||
|
||||
b. No compression occurred and first byte of IP/Ethernet packet
|
||||
is 0x50 (2 bytes of overhead but unlikely since no known
|
||||
IP packet can begin with 0x50):
|
||||
|
||||
[ 0x50 ] [ 0x00 ] [ uncompressed IP/Ethernet packet ]
|
||||
|
||||
c. Compression occurred (2 bytes of overhead):
|
||||
|
||||
[ 0x50 ] [ compression Alg ID ] [ compressed IP/Ethernet packet ]
|
||||
|
||||
Compression Alg ID is one-byte algorithm identifier
|
||||
for LZ4 (0x1), LZO (0x2), or Snappy (0x3).
|
||||
|
||||
This approach has several beneficial effects:
|
||||
|
||||
1. In the common case where compression does not occur, no
|
||||
compression op is required, therefore there is zero overhead.
|
||||
|
||||
2. When compression does not occur, the IP/Ethernet packet
|
||||
alignment is retained.
|
||||
|
||||
3. This technique does not require any byte swapping with
|
||||
the tail of the packet which can potentially incur an
|
||||
expensive cache miss.
|
Loading…
Reference in New Issue
Block a user