Skip to content

Commit

Permalink
Add specification for epoch data keys
Browse files Browse the repository at this point in the history
  • Loading branch information
schwabe committed Sep 24, 2024
1 parent 1d4d8ff commit b4d052b
Showing 1 changed file with 273 additions and 28 deletions.
301 changes: 273 additions & 28 deletions openvpn-wire-protocol.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="US-ASCII"?>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced.
Expand Down Expand Up @@ -1295,8 +1295,9 @@ available) to drop revoked keys.)</li>
for Peer-ID.
</t>
<t>
For details about this opcode see sections about <xref target="dataaead">AEAD</xref>
and <xref target="datacbc">CBC/OFB/CTR</xref> packet format.
For details about this opcode see the sections <xref target="dataaead">AEAD</xref>,
<xref target="dataaeadv3">AEAD</xref>, and <xref target="datacbc">CBC/OFB/CTR</xref>
packet format.
</t>
</section>
<section title="[OPCODE ID 6] DATA_V1">
Expand Down Expand Up @@ -1531,6 +1532,7 @@ struct datakeys {

key_c2s and auth_c2s are used to encrypt/authenticate data from client to server
and key_s2c and auth_s2c are used to encrypt/authenticate from server to client.
Server and client in this context is TLS server and TLS client of the connection.
</t>
<t>
This key structure is normally generated by using <xref target="RFC5705">RFC 5705 key material exporter</xref>
Expand All @@ -1541,6 +1543,111 @@ struct datakeys {
PRF.
</t>
</section>
<section anchor="epochkeys" title="OpenVPN epoch data channel keys">
<t>
Recent advances in cryptography research have shown that GCM ciphers, most notably AES-GCM have
theoretical vulnerabilities when AES-GCM is used with the same key with to many block encryption
invocations. See <xref target="usage-limits-aead-draft">Usage Limits on AEAD Algorithms</xref> and the
referenced research papers in that document like <xref target="AEAD-LIMITS"/> for more information.
</t>
<t>
To avoid using the same encryption key for too many packets without requiring to do a full renegotiation
OpenVPN uses epoch data channel keys. The term epoch is used to avoid confusion with the already
existing term key-id and since <xref target="RFC9147">DTLS 1.3</xref> uses the same terminology.
</t>
<t>
A sender should calculate a safe amount of packets to send/number of encryption that can be done.
The actual number depends on the cipher being used. From <xref target="usage-limits-aead-draft"> current
standards</xref>, there is no limit to consider for Chacha20-Poly1305, so a sender can use the full
48 bit of epoch counter before moving to a new epoch. For AES-GCM, the limit is 2^32.5 when using
a packet size of 1500 using this document and the safety margin of 2^-50 but the
<xref target="RFC8446">TLS 1.3</xref> standard uses a higher safety margin of 2^-57 which
translates to 2^24.5 for maximum TLS record sizes (2^14 or 16kB). OpenVPN implementations should
choose the same (higher) safety margin as TLS.

</t>
<t>
Example calculation:

Using limits documents and p=2^-57 and L=2**14:

<artwork>q &lt;= (p^(1/2) * 2^(129/2) - 1) / (L + 1)></artwork>

gives use basically limit that TLS uses:
<artwork> q &lt;= 24^(24.9999) </artwork>


When using L = 2^12 (packet/buffer size of 1500 rounded up to the nearest power of 2)
we get:

<artwork> q &lt;= 2^(26.999) </artwork>

</t>
<t>
The following table gives an overview of the limits for AES-GCM invocations when calculating them with above formula
</t>
<texttable>
<ttcol>packet size</ttcol>

<ttcol>Maximum number of packets</ttcol>
<c> 1500 </c>
<c> 28.4 </c>

<c> 1600 </c>
<c> 28.35 </c>

<c>2048</c>
<c>2^28</c>

<c>4096</c>
<c>2^27</c>

<c>9000</c>
<c>2^25.8</c>

<c>16384</c>
<c>2^25</c>

<c>65336</c>
<c>2^23</c>
</texttable>
<t>
Implementations have to ensure to calculate the limit with the actual maximum size that they are
willing to send a packet with and not only with the current MTU size. E.g. the current OpenVPN
implementation will always try to send up to the internal buffer size of 1600 byte in the default
configuration.
</t>

<t>
The receiver should count the number of packets that have been received but failed verification.
The number of packets that fail verification and we can tolerate is again specified differently
for DTLS 1.3 and the data usage limit document. For OpenVPN we set the number to 2^36 for all
ciphers, the same DTLS 1.3. An implementation may chose a lower number.
</t>
<t>
When receiving an authenticated packet with a higher epoch than the currently used one, the
receiver of this packet should also switch to the same epoch. OpenVPN chooses this approach over
the alternative that epochs are managed separately for both peers, to simplify key and also to
allow the receiver to trigger using a new encryption key.
</t>
<t>
Epoch key generation. The epoch key generation is inspired by the TLS key generation and
<xref target="RFC5869">HMAC-based Key Derivation Function (HKDF)</xref>
and the definition of HDKF-Expand-Label in TLS 1.3.

For OpenVPN the epoch 0 key E0 is the OpenVPN key, for any further key, the key derivation is
<artwork> E_N+1 = HKDF-Expand-Label(E_N, "OpenVPN data key update", "", 256)</artwork>


The per epoch data channel key is derived via
<artwork> K_i = HKDF-Expand-Label(E_i, "OpenVPN epoch key", "", 256) </artwork>


The epoch K_i will then be used for the actual data encryption, the keys is are first
bytes from key_c2s and key_s2c respectively. And the implicit_iv is formed from the
first 96 bit (12 bytes) from auth_c2s and auth_s2c respectively.
</t>
</section>
<section title="Peer-ID">
<t>
The purpose of this feature is to allow a client to float between various client
Expand Down Expand Up @@ -1628,44 +1735,27 @@ struct datakeys {
<section anchor="dataaead" title="AEAD encrypted data channel packet">

<t>
AEAD format with tag at the start:
This specificies the first version of AEAD data format that OpenVPN implements.
It has the AEAD tag at the start.

<figure>
<sourcecode>
struct aead_packet {
int opcode:5;
int key_id:3;
int peer_id:24;
uint32_t/uint_64_t packet_id;
uint32_t packet_id;
uint8_t[16] authentication_tag;
uint8_t* encrypted_payload;
}
</sourcecode>
</figure>
</t>

<t>
AEAD format with tag at the end:

<figure>
<sourcecode>
struct aead_packet {
int opcode:5;
int key_id:3;
int peer_id:24;
uint32_t/uint64_t packet_id;
uint8_t* encrypted_payload;
uint8_t[16] authentication_tag;
}
</sourcecode>
</figure>
</t>

<t>
The packet_id together with the implicit IV forms the IV for
decryption. The packet_id is also used for the replay protection.

When 64 bit packet ids are enabled, the size becomes 64 bit.
</t>

<t>
Expand Down Expand Up @@ -1697,9 +1787,78 @@ authenticated_data_v2 = opcode| key_id | peer_id | packet_id | payload
</t>

<t>
The tag size is always 128 bit (16 bytes). (Same size as in TLS). If the
protocol flag for AEAD tag at the end is in effect, the AEAD tag is at the end
of the packet rather than at the start.
The tag size is always 128 bit (16 bytes). (Same size as in TLS).
</t>
</section>
<section anchor="dataaeadv3" title="AEAD encrypted data channel packet with 64bit counters">

<t>
This is the modern version of the AEAD data format in OpenVPN. The differences to the older
format are:
<ul>
<li>AEAD tag at the end of the packet</li>
<li>64 bit packet id </li>
<li>IV constructed with XOR instead of contactination </li>
<li>Support of multiple key generations (epochs) </li>
</ul>

The packet format with 64bit counter looks like this:
<figure>
<sourcecode>
struct aead_packet {
int opcode:5;
int key_id:3;
int peer_id:24;
uint_64_t packet_id;
uint8_t* encrypted_payload;
uint8_t[16] authentication_tag;
}
</sourcecode>
</figure>
</t>

<t>
The packet id is split into 16 bit bits of epoch and 48bit of counter for
that epoch. Each epoch uses a different a encryption/decryption key and a different
implicit_iv.
<figure>
<sourcecode>
struct packet_id {
uint epoch:16;
uint epoch_counter:48;
}
</sourcecode>
</figure>
</t>

<t>
The epoch_counter of the packet_id together with the implicit IV for the epoch
forms the IV for decryption. The epoch_counter is also used for the replay
protection. Implementation are encouraged to a have a per epoch replay protection.
Using the whole packet_id as flat 64bit counter for replay protection will work as well
but will reject reordered packets from the older epoch when a (valid) packet
the epoch changes
</t>

<t>
The 96bit IV is constructed by using the 96 bit of implicit IV belonging to the epoch
and doing an XOR with the 48 bit epoch_counter.
<sourcecode>IV = epoch_counter XOR implicit_iv_epoch</sourcecode>
</t>

<t>
This data format is only defined for DATA_V2 packets and therefore
the authenticated data <em>includes</em> opcode, key_id and peer_id.
</t>

<t>
<sourcecode>
authenticated_data_v2 = opcode| key_id | peer_id | packet_id | payload
</sourcecode>
</t>

<t>
The tag size is always 128 bit (16 bytes) appended to the end of encrypted data (Same size as in TLS).
</t>
</section>
<section anchor="datacbc" title="CBC/OFB/CTR encrypted packet">
Expand Down Expand Up @@ -2047,7 +2206,9 @@ INFO,EXTRA
</middle>

<back>
<references title="Normative References">

<!-- RFC references: https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml -->
<references title="Normative References">
<reference anchor="rogaway2006provable">
<front><title>A provable-security treatment of the key-wrap problem</title><author surname="Rogaway" fullname="Phillip Rogaway" /><author surname="Shrimpton" fullname="Thomas Shrimpton" /><date year="2006" />
</front></reference>
Expand All @@ -2056,6 +2217,74 @@ INFO,EXTRA

<reference anchor="nistgcm"><front><title>Sp 800-38d. recommendation for block cipher modes of operation: Galois/counter mode (gcm) and gmac</title><author surname="Dworkin" fullname="Morris J Dworkin" /><date year="2007" /></front></reference>


<reference anchor="RFC8446" target="https://www.rfc-editor.org/info/rfc8446">
<front>
<title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
<author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
<date month="August" year="2018"/>
<abstract>
<t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
<t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="8446"/>
<seriesInfo name="DOI" value="10.17487/RFC8446"/>
</reference>


<reference anchor="RFC9147" target="https://www.rfc-editor.org/info/rfc9147">
<front>
<title>The Datagram Transport Layer Security (DTLS) Protocol Version 1.3</title>
<author fullname="E. Rescorla" initials="E." surname="Rescorla"/>
<author fullname="H. Tschofenig" initials="H." surname="Tschofenig"/>
<author fullname="N. Modadugu" initials="N." surname="Modadugu"/>
<date month="April" year="2022"/>
<abstract>
<t>This document specifies version 1.3 of the Datagram Transport Layer Security (DTLS) protocol. DTLS 1.3 allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
<t>The DTLS 1.3 protocol is based on the Transport Layer Security (TLS) 1.3 protocol and provides equivalent security guarantees with the exception of order protection / non-replayability. Datagram semantics of the underlying transport are preserved by the DTLS protocol.</t>
<t>This document obsoletes RFC 6347.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="9147"/>
<seriesInfo name="DOI" value="10.17487/RFC9147"/>
</reference>
<reference anchor="usage-limits-aead-draft" target="https://datatracker.ietf.org/doc/html/draft-wood-cfrg-aead-limits-00">
<front>
<title>Usage Limits on AEAD Algorithms</title>
<author fullname="Felix Günther" initials="F." surname="Günther">
<organization>ETH Zurich</organization>
</author>
<author fullname="Martin Thomson" initials="M." surname="Thomson">
<organization>Mozilla</organization>
</author>
<author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
<organization>Cloudflare</organization>
</author>
<date day="20" month="May" year="2020"/>
<abstract>
<t>An Authenticated Encryption with Associated Data (AEAD) algorithm provides confidentiality and integrity. Excessive use of the same key can give an attacker advantages in breaking these properties. This document provides simple guidance for users of common AEAD functions about how to limit the use of keys in order to bound the advantage given to an attacker.</t>
</abstract>
</front>
<seriesInfo name="Internet-Draft" value="draft-wood-cfrg-aead-limits-00"/>
</reference>


<reference anchor="RFC5869" target="https://www.rfc-editor.org/info/rfc5869">
<front>
<title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title>
<author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/>
<author fullname="P. Eronen" initials="P." surname="Eronen"/>
<date month="May" year="2010"/>
<abstract>
<t>This document specifies a simple Hashed Message Authentication Code (HMAC)-based key derivation function (HKDF), which can be used as a building block in various protocols and applications. The key derivation function (KDF) is intended to support a wide range of applications and requirements, and is conservative in its use of cryptographic hash functions. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
</abstract>
</front>
<seriesInfo name="RFC" value="5869"/>
<seriesInfo name="DOI" value="10.17487/RFC5869"/>
</reference>


<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.2104.xml"?-->
&RFC2104;

Expand All @@ -2071,8 +2300,24 @@ INFO,EXTRA
<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.5705.xml"?-->
&RFC5705;

<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8452.xml"?-->
<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC.8452.xml"?-->
&RFC8452;

</references>
<references title='Informative References'>
<reference anchor="AEAD-LIMITS" target="http://www.isg.rhul.ac.uk/~kp/TLS-AEbounds.pdf">
<front>
<title>Limits on Authenticated Encryption Use in TLS</title>
<author initials="A." surname="Luykx">
<organization></organization>
</author>
<author initials="K." surname="Paterson">
<organization></organization>
</author>
<date year="2016"/>
</front>
</reference>
</references>

</back>
</rfc>

0 comments on commit b4d052b

Please sign in to comment.