Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working on the AEAD description #135

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 69 additions & 18 deletions draft-sharabayko-srt.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ informative:
RFC6528:
RFC8312:
RFC4987:
RFC7714:
RFC9000:
RFC9114:
GuAnAO:
Expand Down Expand Up @@ -2992,55 +2993,105 @@ with a key establishment method.

## Overview

SRT implements encryption using AES {{AES}} in counter mode (AES-CTR) {{SP800-38A}} with a short-lived key
SRT implements encryption using AES {{AES}} in Counter Mode (AES-CTR) {{SP800-38A}}
and in Galois/Counter Mode (AES-GCM, starting from SRT v1.6.0) {{RFC7714}} with a short-lived key
to encrypt and decrypt the media stream. The AES-CTR cipher is suitable for continuous stream encryption
that permits decryption from any point, without access to start of the stream (random access),
and for the same reason tolerates packet loss. It also offers strong confidentiality when the counter is managed properly.
The AES-GCM mode can provide an additional lavel of security by ensuring the data is not altered.

SRT uses key lengths (KLen) of 128, 192, and 256 bits based on the configuration exchanged in the KM packet
({{sec-ctrlpkt-km}}).

### Encryption Scope

SRT encrypts only the payload of SRT data packets ({{data-pkt}}), while the header is left unencrypted.
The unencrypted header contains the Packet Sequence Number field used to keep the synchronization
of the cipher counter between the encrypting sender and the decrypting receiver.
No constraints apply to the payload of SRT data packets as no padding of the payload is required by counter mode ciphers.
Message authentication in case of AES-GCM mode is performed both for payload and data packet header.

### AES Counter

The counter for AES-CTR is the size of the cipher's block, i.e. 128 bits. It is derived from
a 128-bit sequence consisting of
The counter both for AES-CTR and AES-GCM is the size of the cipher's block, i.e. 128 bits. It is derived from
the Initialisation Vector (IV) submitted for the AES encryption of the payload and the block counter used by the AES engine internally
to count blocks in the packet payload.

- a block counter in the least significant 16 bits which counts the blocks in a packet;
#### AES-CTR Initialisation Vector (IV)

- a packet index, based on the packet sequence number in the SRT header, in the next 32 bits;
The Initialisation Vector (IV) for the AES-CTR encryption mode is derived by using the "exclusive-OR"
operation on the first 112 bits of the Salt provided in the Keying Material ({{sec-ctrlpkt-km}})
with the packet sequence number (PktSeqNo) in the SRT header, and left-shifting the resulting value by 16 bits:

- eighty zeroed bits.
~~~~~~~~~~~
IV = (MSB(112, Salt) XOR PktSeqNo) << 16
~~~~~~~~~~~

The upper 112 bits of this sequence are XORed with an Initialization Vector (IV)
to produce a unique counter for each crypto block. The IV is derived from the Salt
provided in the Keying Material ({{sec-ctrlpkt-km}}):
Thus the counter (keystream) used by the AES engine is the 128-bit value obtained by concatenating the IV with the block counter ("ctr"):

~~~~
IV = MSB(112, Salt): Most significant 112 bits of the salt.
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 bytes
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ ^
* | 0s | PktSeqNo | 0s | |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
* XOR | IV
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ |
* | nonce = MSB(112, Salt) + |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+ v
* (+)
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
* | 0s | ctr |
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
~~~~

To avoid using the same keystream twice the payload size MUST be less than 2^16 blocks of 128 bits.

#### AES-GCM Initialisation Vector (IV)

The Initialisation Vector (IV) for the AES-GCM encryption mode is derived
by exclusive ORing the first 96 bits of the Salt provided in the Keying Material ({{sec-ctrlpkt-km}})
with the packet sequence number (PktSeqNo) in the SRT header:

~~~~~~~~~~~
IV = MSB(96, Salt) XOR PktSeqNo
~~~~~~~~~~~

Each outbound packet uses a 12-octet IV and an encryption key to form two outputs ({{RFC7714}}):
- a 16-octet first key block, which is used in forming the authentication tag, and
- a keystream of octets, formed in blocks of 16 octets each.

With an IV taking 96 bits, there are always 128-96=32 bits for the block counter until it wraps around.

### Stream Encrypting Key (SEK)

The key used for AES-CTR encryption is called the "Stream Encrypting Key" (SEK). It is used for
up to 2^25 packets with further rekeying.
The short-lived SEK is generated by the sender using a pseudo-random number generator (PRNG),
The key used for the AES encryption is called the "Stream Encrypting Key" (SEK).
It is used for encrypting a limited number of packets with further rekeying.
The short-lived SEK of length KLen is generated by the sender using a pseudo-random number generator (PRNG),
and transmitted within the stream, wrapped with another longer-term key,
the Key Encrypting Key (KEK), using a known AES key wrap protocol.

For connection-oriented transport such as SRT, there is no need to periodically transmit
the short-lived key since no additional party can join a stream in progress. The keying material
is transmitted within the connection handshake packets, and for a short period
when rekeying occurs.
~~~~~~~~~~~
SEK = PRNG(KLen)
~~~~~~~~~~~

The KLen can be 128, 192, and 256 bits based on the configuration exchanged in the KM packet
({{sec-ctrlpkt-km}}).

For connection-oriented transport such as SRT, the short-lived key is transmitted during the handshake.
It is therefore available thoughout the whole duration of a connection. Hence there is no need to periodically transmit
the short-lived key for some additional party that could have joined a stream in progress, and waiting for the key
to be transmitted again before being able to decrypt the received payload.

However, from the security point of view, the short-lived key has to be changed periodically to limit the amount of data encrypted with it
before the key can be compromised. The key is changed after a certain number of packets have been encrypted with the current key.
The recommended number of packets encrypted with the same key is 2^25 packets with further rekeying ({{sec-crypt-km-refresh}}).

### Key Encrypting Key (KEK)

The Key Encrypting Key (KEK) is derived from a secret (passphrase) shared between the sender and the receiver.
The KEK provides access to the Stream Encrypting Key, which in turn provides access
to the protected payload of SRT data packets. The KEK has to be at least as long as the SEK.
to the protected payload of SRT data packets. Formally, the KEK has to be at least as long as the SEK.
In SRT, the KEK and SEK have equal lengths (KLen).

The KEK is generated by a password-based key generation function (PBKDF2) {{RFC8018}},
using the passphrase, a number of iterations (2048), a keyed-hash (HMAC-SHA1) {{RFC2104}}, and
Expand Down
Loading