0
0
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:
James Yonan 2015-01-06 17:14:31 -07:00
parent c2c7292a70
commit a80508ab21

View 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.