Field Guide · term

Also known as: ES, encryption sync, message indicator

The P25 Encryption Sync (ES) is the field an encrypted P25 voice call publishes so a receiver holding the key can decrypt it — and so any monitor can identify the encryption.1 It carries three things: the Message Indicator (MI), a 72-bit per-call cryptographic sync vector that seeds the keystream generator (the initialization vector); the ALGID (algorithm ID) naming the cipher; and the KID (key ID) selecting which key in the radio’s keyset the call uses. Like SDRTrunk, GopherTrunk reads these to label a call as encrypted — algorithm and key — without decrypting it.

Message Indicator · 72 bits (IV) ALGID KID · 16 bits inner Hamming(10,6,3) → outer RS(24,16,9), t=4 → corrected ALGID/KID uncorrectable ES ⇒ low-confidence, not surfaced
The ES packs the MI, ALGID, and KID, then wraps them in two FEC layers; the outer RS(24,16) is what keeps a marginal channel from producing a plausible-looking but wrong algorithm ID.

Where it rides and how it is protected

The ES travels in an LDU2 — the second of the two voice frames a P25 call alternates — using the same six 40-bit slots an LDU1 uses for its Link Control word. Those slots carry an inner shortened Hamming(10,6,3) code across the 24 codewords, exactly as Link Control does. Above that sits an outer Reed-Solomon RS(24,16,9) code (t = 4 symbols), which GopherTrunk’s ParseEncryptionSync runs after the Hamming layer to correct the residual symbol errors that would otherwise smear the algorithm ID under marginal SNR. If more than four symbol errors survive the inner layer, the RS code fails and the parser returns ErrEncryptionSyncUncorrectable — the decoded algorithm and key are then low-confidence and are not surfaced as a real encryption change.

The fields

internal/radio/p25/phase1/encryption_sync.go decodes the 12-octet ES content:

Octets Field Meaning
0–8 Message Indicator 72-bit per-call IV that seeds the keystream
9 Algorithm ID cipher in use (0x80 = clear/unencrypted)
10–11 Key ID which key in the keyset the call uses

A monitor uses the MI even when it cannot decrypt: the MI advances predictably across the call, so it also serves as a sanity check that the crypto framing is being tracked correctly. Because a bit-error in a traffic-channel ES smears the algorithm ID roughly uniformly across 0x000xFF, GopherTrunk gates surfacing on the ALGID being a registered value — an out-of-set ALGID is provably a mis-decode and is dropped rather than shown as a fabricated algorithm.

Relevance to SDR

Reading the ES is how GopherTrunk answers the operator’s first question about an encrypted call — what algorithm and key? — which drives call-log fields, the encryption indicator in the UI, and any decrypt attempt in the crypto lab. The ALGID tells whether the traffic is clear or protected; the MI feeds the keystream generator if a key is available; and the KID lets an operator correlate calls that share a key, which is exactly the metadata OTAR rekeying changes over time. The two-layer FEC is what makes this metadata trustworthy off-air, so GopherTrunk decodes both layers before believing an ALGID.

Sources

  1. Project 25 — Wikipedia, on the P25 standard and its encryption services. ES layout and FEC follow TIA-102.AABF/AACE as the project’s working model. 

See also