Draft: draft-ietf-sframe-enc

Commentary: Needs rebasing .
Each SFrame encryption or decryption operation is premised on a
single secret "base\_key", which is labeled with an integer KID value
signaled in the SFrame header.
Each SFrame encryption or decryption operation is premised on a
single secret "base_key", which is labeled with an integer KID value
signaled in the SFrame header.
The sender and receivers need to agree on which key should be used
for a given KID.  The process for provisioning keys and their KID
values is beyond the scope of this specification, but its security
properties will bound the assurances that SFrame provides.  For
example, if SFrame is used to provide E2E security against
intermediary media nodes, then SFrame keys MUST be negotiated in a
way that does not make them accessible to these intermediaries.
For each known KID value, the client stores the corresponding
symmetric key "base\_key".  For keys that can be used for encryption,
the client also stores the next counter value CTR to be used when
encrypting (initially 0).
When encrypting a frame, the application specifies which KID is to be
used, and the counter is incremented after successful encryption.
When decrypting, the "base\_key" for decryption is selected from the
available keys using the KID value in the SFrame Header.
The sender and receivers need to agree on which key should be used
for a given KID.  The process for provisioning keys and their KID
values is beyond the scope of this specification, but its security
properties will bound the assurances that SFrame provides.  For
example, if SFrame is used to provide E2E security against
intermediary media nodes, then SFrame keys need to be negotiated in a
way that does not make them accessible to these intermediaries.
For each known KID value, the client stores the corresponding
symmetric key "base_key".  For keys that can be used for encryption,
the client also stores the next counter value CTR to be used when
encrypting (initially 0).
When encrypting a plaintext, the application specifies which KID is
to be used, and the counter is incremented after successful
encryption.  When decrypting, the "base_key" for decryption is
selected from the available keys using the KID value in the SFrame
Header.
Note that the set of available keys might change over the lifetime of
a real-time session.  In such cases, the client will need to manage
key usage to avoid media loss due to a key being used to encrypt
before all receivers are able to use it to decrypt.  For example, an
application may make decryption-only keys available immediately, but
delay the use of encryption-only keys until (a) all receivers have
acknowledged receipt of the new key or (b) a timeout expires.
Note that the set of available keys might change over the lifetime of
a real-time session.  In such cases, the client will need to manage
key usage to avoid media loss due to a key being used to encrypt
before all receivers are able to use it to decrypt.  For example, an
application may make decryption-only keys available immediately, but
delay the use of keys for encryption until (a) all receivers have
acknowledged receipt of the new key or (b) a timeout expires.
After encoding the frame and before packetizing it, the necessary
media metadata will be moved out of the encoded frame buffer, to be
used later in the RTP generic frame header extension.  The encoded
frame, the metadata buffer and the frame counter are passed to SFrame
encryptor.
SFrame encryption uses the AEAD encryption algorithm for the
ciphersuite in use.  The key for the encryption is the "sframe\_key"
and the nonce is formed by XORing the "sframe\_salt" with the current
counter, encoded as a big-endian integer of length "AEAD.Nn".
The encryptor forms an SFrame header using the S, CTR, and KID values
provided.  The encoded header is provided as AAD to the AEAD
encryption operation, with any frame metadata appended.
SFrame encryption uses the AEAD encryption algorithm for the
ciphersuite in use.  The key for the encryption is the "sframe_key"
and the nonce is formed by XORing the "sframe_salt" with the current
counter, encoded as a big-endian integer of length "AEAD.Nn".
The encryptor forms an SFrame header using the CTR, and KID values
provided.  The encoded header is provided as AAD to the AEAD
encryption operation, together with application-provided metadata
about the encrypted media.
The metadata input to encryption allows for frame metadata to be
authenticated when SFrame is applied per-frame.  After encoding the
frame and before packetizing it, the necessary media metadata will be
moved out of the encoded frame buffer, to be sent in some channel
visibile to the SFU (e.g., an RTP header extension).
The receiving clients buffer all packets that belongs to the same
frame using the frame beginning and ending marks in the generic RTP
frame header extension, and once all packets are available, it passes
it to SFrame for decryption.  The KID field in the SFrame header is
used to find the right key for the encrypted frame.
For frames that are failed to decrypt because there is key available
for the KID in the SFrame header, the client MAY buffer the frame and
retry decryption once a key with that KID is received.
Before decrypting, a client needs to assemble a full SFrame
ciphertext.  When SFrame is applied per-packet, this is done by
extracting the payload of a decrypted SRTP packet.  When SFrame is
applied per-frame, the receiving client buffers all packets that
belongs to the same frame using the frame beginning and ending marks
in the generic RTP frame header extension.  Once all packets are
available and in order, the receiver forms an SFrame ciphertext by
concatenating their payloads, then passes the ciphertext to SFrame
for decryption.
The KID field in the SFrame header is used to find the right key and
salt for the encrypted frame, and the CTR field is used to construct
the nonce.
If a ciphertext fails to decrypt because there is no key available
for the KID in the SFrame header, the client MAY buffer the
ciphertext and retry decryption once a key with that KID is received.
In SFrame, we derive per-sender "base\_key" values from the group
secret for an epoch, and use the KID field to signal the epoch and
sender index.  First, we use the MLS exporter to compute a shared
SFrame secret for the epoch.
In SFrame, we derive per-sender "base_key" values from the group
secret for an epoch, and use the KID field to signal the epoch and
sender index.  First, we use the MLS exporter to compute a shared
SFrame secret for the epoch.