Skip to main content

packet_counter

Function packet_counter 

Source
pub fn packet_counter(salt: &[u8; 16], pkt_seq_no: u32) -> [u8; 16]
Available on crate feature crypto only.
Expand description

Compute the 128-bit AES-CTR initial counter for one data packet.

This follows the reference SRT construction (libsrt haicrypt/hcrypt.h, hcrypt_SetCtrIV), which is what real SRT peers use on the wire:

memset(iv, 0, 16);              // all 16 bytes zeroed
memcpy(&iv[10], &pki, 4);       // 32-bit packet index at bytes [10..14]
iv[0..14] ^= salt[0..14];       // XOR MSB(112, Salt) across the top 14 bytes
// iv[14..16] = per-packet AES-block counter, starts 0
//
//  byte:  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
//        +-----------------------+-----------+-----+
//        |          0s           |    pki    | ctr |
//        +-----------------------+-----------+-----+

On the draft’s IV = (MSB(112, Salt) << 2) XOR PktSeqNo (§6.2.2/§6.3.2): the << 2 is a known artifact/typo of the draft text — the reference implementation does no left shift. Implementing the << 2 literally produces a keystream no real SRT peer can decrypt, so this function follows hcrypt_SetCtrIV (which is equivalent to §6.1.2’s field layout: packet index in bits [47:16], block counter in [15:0]). See the module doc’s “conflicting IV formula” note.

The low 16 bits (counter[14..16]) are the per-packet AES-block counter, left at 0 here — a standard 128-bit big-endian CTR increments the whole counter per block, which only touches these low bits as long as a single packet’s payload stays under 2^16 AES blocks (1 MiB); every SRT payload (bounded by a UDP datagram) is far smaller.

pkt_seq_no is the data packet’s 31-bit Packet Sequence Number (draft-sharabayko-srt-01 §3.1); bit 31 (the F header bit) is never part of it.