@@ -1187,15 +1187,27 @@ available) to drop revoked keys.)</li>
11871187 renegotiation can start using the CONTROL_V1 OPCODE.
11881188 </t >
11891189 <t >
1190- When the ACK_V1 packet is being sent, the key_id field
1191- MUST be incremented to ensure the connection can still
1192- use the old keys for a shorter time until the transition
1193- has completed. Any following packets need to use the new
1194- key-id until the old key has been removed and the new
1195- key-id replaces it completely. [FIXME/schwabe:THIS IS WRONG)
1190+ This session will be negotiated the same as the inital
1191+ session up to the point that the control channel is
1192+ establish. At this point the control channel of the new
1193+ session will replace the control channel of the old channel.
11961194 </t >
11971195 <t >
1198- [FIXME: Elaborate more on how re-keying happens]
1196+ Unlike in the initial TLS session wih the key-id 0, the client
1197+ will not send PUSH_REQUEST messages to request server to query
1198+ its configuration but continue to use the configuration
1199+ negotiated in the initial TLS session.
1200+ </t >
1201+ <t >
1202+ Whenever a renegotiation happens, the new TLS session will use
1203+ the current key-id increased by one. When the renegotiation
1204+ succeeds, the key-id of the renegotion will also be used for all
1205+ data channel packets and further control channel packet that
1206+ belong/derive from this TLS session. If a renegotiation fails
1207+ and is reattempted, the key-id from the failed attempt will be
1208+ reused for a new renegotiation attempt.
1209+ Only the intial TLS session will use the key-id 0. If the key-id
1210+ reaches 7, the following key-id is 1 when increasing the key-id.
11991211 </t >
12001212 </section >
12011213
@@ -1533,15 +1545,95 @@ struct datakeys {
15331545 key_c2s and auth_c2s are used to encrypt/authenticate data from client to server
15341546 and key_s2c and auth_s2c are used to encrypt/authenticate from server to client.
15351547 </t >
1548+ <section title =" Data channel key generation" >
1549+ <t >
1550+ Every time a OpenVPN control channel session is succesfully established, a data channel key in the above format is
1551+ generated and assigned to the key-id of the control channel.
1552+ </t >
15361553 <t >
15371554 This key structure is normally generated by using <xref target =" RFC5705" >RFC 5705 key material exporter</xref >
15381555 from the Control Channel session with the label <tt >EXPORTER-OpenVPN-datakeys</tt >
15391556 and using the 256 bytes length of the structure.
1557+ </t >
1558+ <t >
1559+ When a client or server lack the support for generating data channel keys using TLS Key material
1560+ export and do not annoounce the support in IV_CIPHER, the server may reject a client. At the same
1561+ time a client that does not get signalled by the server by `key-derivation tls-ekm` or
1562+ `protocol-flags tls-ekm` to use TLS Key material can abort the connection.
1563+ </t >
1564+ <t >
1565+ If support for older server or clients is desired that do not support TLS EKM, client and
1566+ server can fall back to the old mechanism of using the
1567+ <xref target =" openvpnprf" > OpenVPN data channel PRF</xref >.
1568+ </t >
1569+ </section >
1570+ <section anchor =" openvpnprf" title =" OpenVPN data channel PRF" >
1571+ <t >
1572+ This is a deprecated way of deriving the data channel keys. It should be only implemented if
1573+ compatibility with older OpenVPN versions is required that do not support key derivation via
1574+ the RFC5705 key material exporter. It also requires the MD5 algorithm which often
1575+ modern crypto libraries do not readily support anymore.</t >
1576+
1577+ <t >This uses the <tt >key_random</tt >, <tt >random1</tt >, and <tt >random2</tt > from the key
1578+ exchange messages. These will be prefixed with client and server here to indicate from which
1579+ packet these field are coming. Also the session id of the control channel will be used here</t >
1580+
1581+ <t >
1582+ Here TLS_PRF(seed, secret) is the TLS PRF function according to RFC 2246 with
1583+ MD5 and SHA1 as used in TLS 1.0/1.1.
1584+
1585+ <figure >
1586+ <sourcecode >
1587+ seed = "OpenVPN master secret" | client.random1 | server.random1
1588+ secret = client.key_random
1589+ master_secret - TLS_PRF(seed, secret)
15401590
1541- Older clients use the mechanism described in the section OpenVPN data channel
1542- PRF.
1591+ key_seed = "OpenVPN key expansion " | client.random2 | server.random2
1592+ datakeys = TLS_PRF(key_seed, key_seed)
1593+ </sourcecode >
1594+ </figure >
15431595 </t >
1596+ </section >
15441597 </section >
1598+ <section title =" Data channel key rotation" >
1599+ <t >
1600+ Whenever a reneogiation of a key has finshed, a new data channel key is generated.
1601+ This new key will consider the pending key. A pending key is considered valid for
1602+ decryption of packets with that key-id but will not be used for encryption yet.
1603+ </t >
1604+ <t >
1605+ After a set time period the pending key is promoted to being the active key and
1606+ the active key is set to be the retired key (sometimes also referred to as lame
1607+ duck key). The retired key will be used only for decryption but no longer for
1608+ encryption.
1609+ </t >
1610+ <t >
1611+ In the default configuration of OpenVPN, the time period of promoting a key from
1612+ pending to active is calucated as
1613+ <artwork >
1614+ min(handshake_window, renegotiation_time/2)
1615+ </artwork >
1616+ set by the --hand-window and --reneg-sec options, which default to 60 and 3600
1617+ respectively. So the default time to promote a key from pending to active is 60s.
1618+ </t >
1619+ <t >
1620+ This approach to defer using the key with a timeout is done to avoid key
1621+ desynchronisation. It allows installing the new keys with enough lead time
1622+ that at the point that any side switches from pending to active key, the
1623+ other side will have the key already installed as pending key and is able
1624+ to decrypt the packets. Likewise, keeping the old key as retired key for
1625+ some time after the pending key is switched to active ensures that the
1626+ if the peer takes longer to switch the pending key to active key, the
1627+ receiver will still be able to decrypt the packets using the retiring key.
1628+ </t >
1629+ <t >
1630+ Should a renegotiation complete before a pending key is promoted to an active
1631+ key, the pending key will replace the active key and the new pending key will
1632+ be the pending key. Note that that implementations are allowed to
1633+ limit themselves just two key slots with either active/pending or active/retired
1634+ and in this scenario will drop active key without moving it to retired state first.
1635+ </t >
1636+ </section >
15451637 <section title =" Peer-ID" >
15461638 <t >
15471639 The purpose of this feature is to allow a client to float between various client
@@ -1755,33 +1847,6 @@ struct data_packet_xfb {
17551847 <t >For unencrypted data packets the same format as CBC without IV is used.</t >
17561848 </t >
17571849 </section >
1758- <section title =" OpenVPN data channel PRF" >
1759- <t >
1760- This is a deprecated way of deriving the data channel keys. It should be only implemented if
1761- compatibility with older OpenVPN versions is required that do not support key derivation via
1762- the RFC5705 key material exporter. It also requires the MD5 algorithm which often
1763- modern crypto libraries do not readily support anymore.</t >
1764-
1765- <t >This uses the <tt >key_random</tt >, <tt >random1</tt >, and <tt >random2</tt > from the key
1766- exchange messages. These will be prefixed with client and server here to indicate from which
1767- packet these field are coming. Also the session id of the control channel will be used here</t >
1768-
1769- <t >
1770- Here TLS_PRF(seed, secret) is the TLS PRF function according to RFC 2246 with
1771- MD5 and SHA1 as used in TLS 1.0/1.1.
1772-
1773- <figure >
1774- <sourcecode >
1775- seed = "OpenVPN master secret" | client.random1 | server.random1
1776- secret = client.key_random
1777- master_secret - TLS_PRF(seed, secret)
1778-
1779- key_seed = "OpenVPN key expansion " | client.random2 | server.random2
1780- datakeys = TLS_PRF(key_seed, key_seed)
1781- </sourcecode >
1782- </figure >
1783- </t >
1784- </section >
17851850 </section >
17861851 <section title =" Control channel messages" >
17871852 <section title =" Message format" >
0 commit comments