Skip to main content

OpenVPN Protocol

/* * OpenVPN Protocol, taken from ssl.h in OpenVPN source code. * * TCP/UDP Packet: This represents the top-level encapsulation. * * TCP/UDP packet format: * * Packet length (16 bits, unsigned) -- TCP only, always sent as * plaintext. Since TCP is a stream protocol, the packet * length words define the packetization of the stream. * * Packet opcode/key_id (8 bits) -- TLS only, not used in * pre-shared secret mode. * packet message type, a P_* constant (high 5 bits) * key_id (low 3 bits, see key_id in struct tls_session * below for comment). The key_id refers to an * already negotiated TLS session. OpenVPN seamlessly * renegotiates the TLS session by using a new key_id * for the new session. Overlap (controlled by * user definable parameters) between old and new TLS * sessions is allowed, providing a seamless transition * during tunnel operation. * * Payload (n bytes), which may be a P_CONTROL, P_ACK, or P_DATA * message. * * Message types: * * P_CONTROL_HARD_RESET_CLIENT_V1 -- Key method 1, initial key from * client, forget previous state. * * P_CONTROL_HARD_RESET_SERVER_V1 -- Key method 1, initial key * from server, forget previous state. * * P_CONTROL_SOFT_RESET_V1 -- New key, with a graceful transition * from old to new key in the sense that a transition window * exists where both the old or new key_id can be used. OpenVPN * uses two different forms of key_id. The first form is 64 bits * and is used for all P_CONTROL messages. P_DATA messages on the * other hand use a shortened key_id of 3 bits for efficiency * reasons since the vast majority of OpenVPN packets in an * active tunnel will be P_DATA messages. The 64 bit form * is referred to as a session_id, while the 3 bit form is * referred to as a key_id. * * P_CONTROL_V1 -- Control channel packet (usually TLS ciphertext). * * P_ACK_V1 -- Acknowledgement for P_CONTROL packets received. * * P_DATA_V1 -- Data channel packet containing actual tunnel data * ciphertext. * * P_CONTROL_HARD_RESET_CLIENT_V2 -- Key method 2, initial key from * client, forget previous state. * * P_CONTROL_HARD_RESET_SERVER_V2 -- Key method 2, initial key from * server, forget previous state. * * P_CONTROL* and P_ACK Payload: The P_CONTROL message type * indicates a TLS ciphertext packet which has been encapsulated * inside of a reliability layer. The reliability layer is * implemented as a straightforward ACK and retransmit model. * * P_CONTROL message format: * * local session_id (random 64 bit value to identify TLS session). * HMAC signature of entire encapsulation header for integrity * check if --tls-auth is specified (usually 16 or 20 bytes). * packet-id for replay protection (4 or 8 bytes, includes * sequence number and optional time_t timestamp). * P_ACK packet_id array length (1 byte). * P_ACK packet-id array (if length > 0). * P_ACK remote session_id (if length > 0). * message packet-id (4 bytes). * TLS payload ciphertext (n bytes) (only for P_CONTROL). * * Once the TLS session has been initialized and authenticated, * the TLS channel is used to exchange random key material for * bidirectional cipher and HMAC keys which will be * used to secure actual tunnel packets. OpenVPN currently * implements two key methods. Key method 1 directly * derives keys using random bits obtained from the RAND_bytes * OpenSSL function. Key method 2 mixes random key material * from both sides of the connection using the TLS PRF mixing * function. Key method 2 is the preferred method and is the default * for OpenVPN 2.0. * * TLS plaintext content: * * TLS plaintext packet (if key_method == 1): * * Cipher key length in bytes (1 byte). * Cipher key (n bytes). * HMAC key length in bytes (1 byte). * HMAC key (n bytes). * Options string (n bytes, null terminated, client/server options * string should match). * * TLS plaintext packet (if key_method == 2): * * Literal 0 (4 bytes). * key_method type (1 byte). * key_source structure (pre_master only defined for client -> * server). * options_string_length, including null (2 bytes). * Options string (n bytes, null terminated, client/server options * string must match). * [The username/password data below is optional, record can end * at this point.] * username_string_length, including null (2 bytes). * Username string (n bytes, null terminated). * password_string_length, including null (2 bytes). * Password string (n bytes, null terminated). * * The P_DATA payload represents encrypted, encapsulated tunnel * packets which tend to be either IP packets or Ethernet frames. * This is essentially the "payload" of the VPN. * * P_DATA message content: * HMAC of ciphertext IV + ciphertext (if not disabled by * --auth none). * Ciphertext IV (size is cipher-dependent, if not disabled by * --no-iv). * Tunnel packet ciphertext. * * P_DATA plaintext * packet_id (4 or 8 bytes, if not disabled by --no-replay). * In SSL/TLS mode, 4 bytes are used because the implementation * can force a TLS renegotation before 2^32 packets are sent. * In pre-shared key mode, 8 bytes are used (sequence number * and time_t value) to allow long-term key usage without * packet_id collisions. * User plaintext (n bytes). * * Notes: * (1) ACK messages can be encoded in either the dedicated * P_ACK record or they can be prepended to a P_CONTROL message. * (2) P_DATA and P_CONTROL/P_ACK use independent packet-id * sequences because P_DATA is an unreliable channel while * P_CONTROL/P_ACK is a reliable channel. Each use their * own independent HMAC keys. * (3) Note that when --tls-auth is used, all message types are * protected with an HMAC signature, even the initial packets * of the TLS handshake. This makes it easy for OpenVPN to * throw away bogus packets quickly, without wasting resources * on attempting a TLS handshake which will ultimately fail.