# Key update of pairwise keys in Group OSCORE [toc] ## Motivation Most the key usage limits do not need a particular care in Group OSCORE. * When the 'q' limit is passed for any of the group/pairwise Sender Keys, a group member asks the Group Manager for a new Sender ID. Whatever exactly happens after that, the endpoint ends up with a new Sender Key and the problem is solved. * The 'v' limit is practically unreachable for the group Recipient Key before a group rekeying happens anyway according to a reasonable period. This is thanks to the signature included in messages protected to the group mode. However, like in OSCORE, the 'v' limit can be reached with respect to any of the pairwise Recipient Keys. Hence the need for efficiently rekeying the two pairwise keys involved, without affecting the whole group. ## Rationale When rekeying the pairwise keys of two specific group members, nothing has to change for the Security Context and for other group members. * For those two specific group members, their authentication credentials remain the same and their DH secret remains the same. * For any group member including those two ones, the group-Sender/Recipient keys, the Master Secret/Salt, as well as the ID Context (Group ID) remain the same. When 'v' decryptions have failed using a pairwise Recipient Key, an endpoint starts a protocol very similar to the extended Appendix B.2, where the goal is to establish new pairwise keys with the other endpoint, but keeping the same ID Context. This new protocol reuses principles from KUDOS. When sending a message for this protocol, the 'd' flag bit of the OSCORE option is set, in order to signal the transport of a Nonce. Such a message will not be interpreted as a KUDOS message, since the recipient retrieves a Security Context that it recognizes to be for Group OSCORE. Hence, it is clear for the recipient that this is about updating the Group OSCORE pairwise keys with the other peer. The exchanged key update messages are protected with the pairwise mode of Group OSCORE. ### Interleaved Group Rekeying If any of the two peers detects that a group rekeying has happened while performing this update of pairwise keys with one another, the peer aborts this key update and the group rekeying prevails. Eventually, the two peers will have established new pairwise keys to use anyway, based on the new ID Context and Sender/Recipient key established as a result of the group rekeying. ### Preserving Observations Like in KUDOS (see draft-ietf-core-oscore-key-update), the two peers can negotiate on whether to preserve their ongoing observations beyond the update of their pairwise keys. That is, a peer can express its wish to preserve the ongoing observations with the other peer, by setting to 1 the 'b' bit ("Preserve Observations") in the X byte of the OSCORE Option when sending a key update message. Like in KUDOS, if both peers agree on preserving their ongoing observations, each peer updates its Partial IV to be greater than the highest one that it is using as Partial IV for an ongoing observation as client with the other peer. ## Notation and definitions * P_SK : Pairwise Sender Key * P_RK : Pairwise Recipient Key * ^ : used to encrypt/decrypt this message * X1 and X2 denote the X byte included in the OSCORE Option right before the Nonce field, in the first and second key update message, respectively. The byte X has the same encoding as defined in the KUDOS document draft-ietf-core-oscore-key-update, with one difference: its bit 'p' ("No Forward Secrecy") MUST be set to 0 when using this protocol. * N1 and N2 denote the Nonce field included in the OSCORE Option, in the first and second key update message, respectively. * "P_SK : (Z, ...)" : The pairwise key P_SK was generated by using (Z, ...) as information in the 'id_context' element of the 'info' parameter in HKDF. When only one piece of information Z is specified, e.g., "P_SK : (GID)", then the pairwise key is generated as per https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16#section-2.4.1 . This is the case when computing the original pairwise keys with another peer. When more than one piece of information Z is specified, e.g., "P_SK : (GID, N1), then a pairwise sender key is generated by means of the function update_sen_pwk(Z, ...), while a pairwise recipient key is generated by means of the function update_rec_pwk(Z, ...). * update_sen_pwk( (Z, ...) ) : this function returns a pairwise sender key, generated according to the information elements (Z, ...) provided as input. The returned pairwise sender key is generated as: ``` Pairwise Sender Key = HKDF(Sender Key, IKM-Sender, info, L) ``` where * HKDF, 'Sender Key', 'IKM-Sender' and 'L' are as defined in https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16#section-2.4.1 * 'info' is as defined in https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16#section-2.4.1 , with the difference that its 'id_context' element is built as follows. The 'id_context' CBOR byte string has as value the byte serialization of a CBOR sequence. Each element of the CBOR sequence is a CBOR byte string. The i-th CBOR byte string in the CBOR sequence has as value the i-th argument of the update_sen_pwk() function. * update_rec_pwk( (Z, ...) ) : this function returns a pairwise recipient key, generated according to the information elements (Z, ...) provided as input. The returned pairwise recipient key is generated as: ``` Pairwise Recipient Key = HKDF(Recipient Key, IKM-Recipient, info, L) ``` where * HKDF, 'Recipient Key', 'IKM-Recipient' and 'L' are as defined in https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16#section-2.4.1 * 'info' is as defined in https://datatracker.ietf.org/doc/html/draft-ietf-core-oscore-groupcomm-16#section-2.4.1 , with the difference that its 'id_context' element is built as follows. The 'id_context' CBOR byte string has as value the byte serialization of a CBOR sequence. Each element of the CBOR sequence is a CBOR byte string. The i-th CBOR byte string in the CBOR sequence has as value the i-th argument of the update_rec_pwk() function. ## Client-initiated version ``` CLIENT (initiator) SERVER (responder) P_SK : (GID) P_SK : (GID) P_RK : (GID) P_RK : (GID) Generate N1 Request #1 ^ P_SK : (GID, X1, N1) ---------------------> P_SK : (GID) P_RK : (GID) OSCORE Option: ^ P_RK : (GID, X1, N1) Group flag : 0 ... Nonce flag : 1 ... Partial IV : 0 ... kid context: GID ... X1 Nonce : N1 ... kid : KID_C (*) Generate N2 Response #1 P_SK : (GID, X1, N1) <--------------------- ^ P_SK : (GID, X1, N1, ^ P_RK : (GID, X1, N1, OSCORE Option: X2, N2) X2, N2) Group flag : 0 P_RK : (GID, X1, N1) ... Nonce flag : 1 ... X2 Nonce : N2 ... (*) Request #2 ^ P_SK : (GID, X1, N1, ---------------------> P_SK : (GID, X1, N1, X2, N2) OSCORE Option: X2, N2) P_RK : (GID, X1, N1, Group flag : 0 ^ P_RK : (GID, X1, N1, X2, N2) ... X2, N2) Nonce flag : 0 ... Partial IV : 1 ... kid context: GID ... kid : KID_C Discard P_SK : (GID) Discard P_RK : (GID) (*) Response #2 P_SK : (GID, X1, N1, <--------------------- ^ P_SK : (GID, X1, N1, X2, N2) OSCORE Option: X2, N2) ^ P_RK : (GID, X1, N1, Group flag : 0 P_RK : (GID, X1, N1, X2, N2) ... X2, N2) Nonce flag : 0 ... (*) Discard P_SK : (GID) Discard P_RK : (GID) (*) Abort if the incoming message was decrypted with a Security Context older than the most recent one. Also, abort if the outgoing message Response #1, Request #2 or Response #2 is going to be encrypted with a Security Context different than the one used to decrypt the immediately previous incoming message. ``` Just for the sake of the argument, if the protocol could continue after a group rekeying occurred between the reception of Request #1 and the sending of Response #1, that would open for the risk that the server reuses the same (key, AEAD nonce) pair in Response #1 and Response #2. As per how Group OSCORE works, this would be already handled, since Response #1 would be protected by using a Security Context different than the one used to protect the corresponding Request #1. Therefore, the server includes its Partial IV in Response #1, hence avoiding the reuse of the same (key, AEAD nonce) pair in outgoing messages following Response #1. ## Server-initiated version ``` CLIENT (responder) SERVER (initiator) P_SK : (GID) P_SK : (GID) P_RK : (GID) P_RK : (GID) Request #1 ^ P_SK : (GID) ---------------------> P_SK : (GID) P_RK : (GID) OSCORE Option: ^ P_RK : (GID) Group flag : 0 ... Nonce flag : 0 ... Partial IV : 0 ... kid context: GID ... kid : KID_C Generate N1 Response #1 P_SK : (GID) <--------------------- ^ P_SK : (GID, X1, N1) ^ P_RK : (GID, X1, N1) OSCORE Option: P_RK : (GID) Group flag : 0 ... Nonce flag : 1 ... X1 Nonce : N1 ... Generate N2 (*) Request #2 ^ P_SK : (GID, X1, N1, ---------------------> P_SK : (GID, N1) X2, N2) OSCORE Option: ^ P_RK : (GID, X1, N1, P_RK : (GID, N1) Group flag : 0 X2, N2) ... Nonce flag : 1 ... Partial IV : 1 ... kid context: GID ... X2 Nonce : N2 ... kid : KID_C (*) Response #2 P_SK : (GID, X1, N1, <--------------------- ^ P_SK : (GID, X1, N1, X2, N2) OSCORE Option: X2, N2) ^ P_RK : (GID, X1, N1, Group flag : 0 P_RK : (GID, X1, N1, X2, N2) ... X2, N2) Nonce flag : 0 ... Discard P_SK : (GID) Discard P_RK : (GID) (*) Request #3 ^ P_SK : (GID, X1, N1, ---------------------> P_SK : (GID, X1, N1, X2, N2) OSCORE Option: X2, N2) P_RK : (GID, X1, N1, Group flag : 0 ^ P_RK : (GID, X1, N1, X2, N2) ... X2, N2) Partial IV : 2 ... kid context: GID ... kid : KID_C Discard P_SK : (GID) Discard P_RK : (GID) (*) Abort if the incoming message was decrypted with a Security Context older than the most recent one. Also, abort if the outgoing message Request #2, Response #2, Request #3 is going to be encrypted with a Security Context different than the one used to decrypt the immediately previous incoming message. ``` Note that, in an OSCORE group enforcing access control (see draft-ietf-ace-key-groupcomm-oscore), this key update cannot be initiated with a request by a group member which has only the role of RESPONDER --- although it has all the means to do it --- since other group members would discard its request. That endpoint can instead upload a new public key at the Group Manager, hence forcing all group members to compute a new DH secret with it, which would differently cause a recomputing of pairwise keys with that endpoint anyway. As an alternative, when receiving a request that is non safe to decrypt due to the reached key usage limit 'v', that group member can respond with a protected 5.03 (Service Unavailable) acting as the Response #1 above, thus starting the server-initiated version of this protocol. This builds on the rationale that, by knowing that the decryption key is not good to use, the decryption was skipped altogether, hence the outcome can be seen not as an "OSCORE error" like those listed in Section 8.3 of RFC 8613. Hence it is acceptable, to send back an encrypted response, which here can especially act as the first key update message. This might require some implementation tweak, since the "OSCORE layer" would need to protect a self-made response, instead of what normally happens when a response to protect is provided by the application.