>
Home5G NRPDCP โ€” Packet Data ConvergenceCiphering & Integrity
๐Ÿ›ก๏ธ PDCP โ€” Packet Data ConvergenceAdvanced

Ciphering & Integrity Protection in 5G NR

How PDCP applies encryption and integrity using COUNT (HFN + SN) and the NEA/NIA algorithms.

📚 3GPP-basedTS 38.323TS 33.501

The radio link is public — anyone with a receiver tuned to the right frequency can hear every bit you transmit — so PDCP encrypts what you send and stamps it so any tampering is detectable. Ciphering keeps the payload confidential; integrity protection proves a message genuinely came from the peer and was not altered or replayed in flight. The layer-level behaviour lives in TS 38.323; the algorithms, keys and the rule that a keystream must never repeat live in TS 33.501.

Introduction

PDCP security is the pair of cryptographic operations — ciphering (confidentiality) and integrity protection (authenticity) — that the Packet Data Convergence Protocol applies to every SRB and, where configured, every DRB. It is the access-stratum (AS) layer of protection: the last thing done to a PDU before it hits the lower layers on transmit, and the first thing undone on receive.

In the UE/network lifecycle it switches on at a precise moment. Immediately after authentication, the gNB runs the AS Security Mode Command / Complete handshake; from that point every RRC message is integrity-protected and ciphered, and user-plane bearers are ciphered (and optionally integrity-protected). Before that handshake, SRBs run effectively in the clear. Every re-key — notably at handover — refreshes the keys and restarts the counters.

Because security is a well-defined chain — negotiate algorithms, derive keys, build COUNT, cipher/verify per PDU — most security faults localise to one link: a de-synchronised HFN, a wrong key derivation input, a bidding-down attempt, or an integrity mismatch on a specific bearer. Walking the chain step by step is what turns "the UE dropped the connection" into a specific, testable cause.

Why PDCP security is needed

💡

In plain words: sending on the radio is like shouting across a crowded square. Ciphering is speaking in a private code so eavesdroppers hear only noise; integrity protection is sealing each note with a tamper-evident wax stamp so the recipient can tell it really came from you and nobody swapped the words on the way. You want both: a secret message that could still be forged is dangerous, and a stamped message anyone can read leaks its contents.

Concretely, the air interface is a shared broadcast medium with no physical privacy, so two attacks must be defeated. A passive eavesdropper can record every bit — confidentiality (ciphering) is what stops that from being useful. An active attacker can inject, modify, or replay messages — integrity protection is what detects that, and it is why signalling must never be forgeable: a forged RRCReconfiguration could redirect a UE to a rogue cell. PDCP is the natural home for both because it is the top of the AS user/control-plane stack, above RLC/MAC, so it protects the whole PDU end-to-end across the radio.

Two Distinct Security Jobs

People routinely conflate them, but ciphering and integrity protection are separate operations, with separate algorithm identities, separate keys, and separate consequences when they fail. Ciphering answers "can an eavesdropper read this?"; integrity answers "was this message forged, modified, or replayed?" A packet can be ciphered but not integrity-protected (typical for user data), or integrity-protected but not ciphered (rare but legal), or — on signalling — both at once.

What

Ciphering XORs the payload with a keystream so the bits on air are unreadable without the key. Integrity protection computes a 32-bit MAC-I tag over the message so any change is detected by the receiver.

Why

Confidentiality stops passive eavesdropping; integrity stops active attacks — injection, modification and replay of signalling. A forged RRCReconfiguration could redirect a UE to a rogue cell, so the control plane must never be forgeable.

How

Both are keyed functions driven by the same input set — KEY, COUNT, BEARER, DIRECTION and (for ciphering) LENGTH. AS-level security is switched on by the RRC Security Mode procedure and applies from that point onward.

🎯

Scope rule: integrity protection is mandatory for SRBs (signalling must never be forgeable). User-plane (DRB) integrity is supported in NR and configured per DRB — a genuine NR addition over LTE, where UP integrity did not exist. Ciphering is applied to both SRBs and DRBs when security is active. The NEA0 null algorithm is how you say "encryption is on, but producing no confidentiality" — it is still a negotiated choice, not the absence of one.

The Algorithm Families: NEA and NIA

NR defines two algorithm families, each with four members. The NEA family (NR Encryption Algorithm) does confidentiality — the "E"; the NIA family (NR Integrity Algorithm) does integrity — the "I". The trailing digit selects the underlying cryptographic core, and the two families deliberately share those cores so that a device only implements one crypto primitive per number and reuses it for both roles.

Ciphering (NEA)Integrity (NIA)Core algorithmMode / constructionNotes
NEA0NIA0NULLNo protection. NEA0 leaves data in the clear; NIA0 produces an all-zero MAC-I. Used before security activation, and for unauthenticated emergency calls only.
NEA1NIA1SNOW 3GStream cipher / keyed MACInherited from LTE (128-EEA1 / 128-EIA1 lineage). A word-oriented stream generator.
NEA2NIA2AES (128-bit)AES-CTR (cipher) / AES-CMAC (integrity)The most widely mandated core. AES in counter mode for keystream; CMAC for the tag.
NEA3NIA3ZUCStream cipher / keyed MACWord-oriented stream cipher; commonly deployed in markets where ZUC is preferred.

All defined algorithms use a 128-bit key. (The security architecture reserves headroom for 256-bit variants in future releases, but the Release-15/16 AS algorithms are 128-bit.) The gNB and UE negotiate which pair to use during the AS Security Mode Command / Complete exchange, picking the most preferred algorithm that both endpoints support, drawn from the UE's UE Security Capabilities. The null members are special: NEA0 is legitimate for any bearer when confidentiality is not required, whereas NIA0 is tightly restricted — using a null integrity algorithm on ordinary signalling would defeat the entire point of integrity protection, so it is confined to unauthenticated emergency scenarios.

📘

Spec note: the algorithm identities are 4-bit values carried in RRC. Ciphering and integrity are chosen independently — a connection can run, say, NEA2 for ciphering and NIA2 for integrity, but nothing forces the digits to match.

COUNT = HFN + PDCP SN, and the Golden Rule

The single most important input to both functions is COUNT, a 32-bit value that must be different for every PDCP PDU sent on a given bearer in a given direction under a given key. It is built by concatenating two fields: the Hyper Frame Number (HFN) in the most-significant bits, and the PDCP Sequence Number (SN) in the least-significant bits.

COUNT (32 bits) = HFNPDCP SN     where |HFN| + |SN| = 32

The SN is what actually travels in the PDCP header — either 12 or 18 bits, configured per bearer via pdcp-SN-SizeUL / pdcp-SN-SizeDL. The HFN is never transmitted: it is a counter each side maintains locally that increments by one every time the SN wraps around from its maximum back to zero. With a 12-bit SN the HFN is 20 bits wide; with an 18-bit SN the HFN is 14 bits wide — in both cases the pair totals exactly 32 bits.

Why does this matter so much? For a stream cipher, the keystream is a deterministic function of the key and the inputs. If two different plaintexts are ever XORed with the same keystream, an attacker who XORs the two ciphertexts together cancels the keystream and recovers the XOR of the two plaintexts — a catastrophic break. So the golden rule is: COUNT must never repeat under the same key on the same bearer and direction. Because COUNT is 32 bits, roughly four billion PDUs can be protected before it would wrap. Long before that point the network triggers a re-key (a fresh K_gNB), and the sending PDCP entity is required to detect the impending wrap and stop rather than let COUNT roll over and reuse a keystream.

🎯

The HFN de-sync trap: because the HFN is inferred, not sent, if the two ends ever disagree on how many times the SN has wrapped, their COUNTs diverge and every subsequent packet fails to decipher or fails its integrity check. Robust SN handling and re-establishment exist precisely to keep the two HFNs locked together.

Inputs to the Security Functions

Both ciphering and integrity are functions of the same core inputs. Vary any one of them and the keystream (or the tag) changes completely — which is exactly how a single key safely protects billions of packets across both directions of multiple bearers without ever reusing a keystream.

COUNT composition (32 bits) HFN (20 or 14 bits, not sent) SN (12 or 18) MSB ← carried in local counter        carried in PDCP header → LSB KEY (128-bit) COUNT (HFN ‖ SN) BEARER (bearer ID) DIRECTION (1 bit UL/DL) LENGTH / MESSAGE NEA / NIA cipher / integrity algorithm core keystream ⊕ data= ciphertext MAC-I (32-bit)appended to PDU
Figure 1. COUNT is HFN concatenated with the PDCP SN. It joins KEY, BEARER, DIRECTION and LENGTH/MESSAGE as inputs to the NEA/NIA core, which yields either a keystream (ciphering) or a 32-bit MAC-I (integrity).
InputWidthRole
KEY128 bitsThe secret — K_RRCenc / K_RRCint / K_UPenc / K_UPint. The choice of key selects confidentiality vs integrity, and SRB vs DRB.
COUNT32 bitsHFNSN. Makes every PDU's keystream/tag unique so a keystream is never reused under a key.
BEARER5 bitsThe bearer identity, so two bearers sharing the same COUNT value never share a keystream.
DIRECTION1 bitUplink = 0 / downlink = 1, so UL and DL of the same bearer never collide on the same keystream.
LENGTH / MESSAGEvariableFor ciphering, the number of keystream bits to generate; for integrity, the message itself is fed in and the LENGTH governs how much is covered.

Note the elegant division of labour: COUNT ensures uniqueness over time, BEARER ensures uniqueness across bearers, and DIRECTION ensures uniqueness across the two directions. Together they guarantee that the (key, input) tuple — and therefore the keystream — is unique for every single protected PDU in the whole connection.

How Ciphering and Integrity Actually Run

On transmit, PDCP applies the two operations in a fixed order: integrity first, then ciphering. The integrity algorithm (NIA) runs over the PDCP SDU plus the input parameters and produces a 32-bit MAC-I (Message Authentication Code for Integrity), which is appended to the data. Ciphering (NEA) then generates a keystream of the required LENGTH and XORs it onto the data part — including the appended MAC-I — while the PDCP header itself is left in the clear so the receiver can read the SN before deciphering. This is the "integrity then cipher" ordering: the tag is computed over the plaintext, then encrypted along with it.

✅ Debugging steps (transmit path)

  • Confirm integrity ran before ciphering — the MAC-I must be over the plaintext SDU, then enciphered with it.
  • Verify the PDCP header (with the SN) is left in the clear; if it were ciphered the receiver could not reconstruct COUNT.
  • Check the COUNT used = local HFN ‖ the SN placed in the header, and that it advances by one per PDU with no gaps or reuse.
  • Confirm the correct key is selected for the bearer type (K_RRCint/K_RRCenc for SRBs, K_UPint/K_UPenc for DRBs).

⚠ Common causes of failure (transmit path)

  • Wrong operation order (cipher-then-integrity) so the peer's decipher-then-verify never matches.
  • Local HFN advanced incorrectly on SN wrap, producing a wrong COUNT and an unrecoverable keystream at the peer.
  • Wrong key selected (UP vs CP, or a stale pre-re-key key), so every PDU fails at the receiver.
  • COUNT about to wrap but the entity did not stop/re-key — keystream reuse risk.

On receive, the order reverses: the entity deciphers first, then verifies integrity. It uses the received SN plus its locally maintained HFN to reconstruct COUNT, regenerates the keystream, XORs to recover the plaintext (which restores the MAC-I), then recomputes the tag over the recovered message to obtain an expected value called XMAC-I. If XMAC-I equals the received MAC-I, the message is authentic. If they differ, the PDU has been altered, injected, or deciphered against the wrong COUNT.

✅ Debugging steps (receive path)

  • Reconstruct COUNT from the received SN and local HFN; confirm both ends agree on the HFN (the classic de-sync check).
  • On garbage plaintext, suspect a wrong keystream first — usually a wrong COUNT/HFN or wrong key, not link errors.
  • On XMAC-IMAC-I, confirm whether it is a genuine tamper/replay or simply a COUNT/key de-sync producing a bad tag.
  • For SRBs, check whether repeated failures are being escalated to RRC as a security event.

⚠ Common causes of failure (receive path)

  • HFN de-synchronisation — wrong COUNT → wrong keystream → garbage plaintext and a failed integrity check (two symptoms, one root cause).
  • Stale key after a handover/re-key not yet applied on this side.
  • Genuine man-in-the-middle injection or replay of an old COUNT.
  • SN size misconfigured (12 vs 18 bit) so header parsing and COUNT reconstruction are off.
🔐

MAC-I on failure: when XMAC-IMAC-I, PDCP discards the PDU and indicates the integrity check failure to upper layers. For an SRB this is a security event: RRC treats a failed check on signalling as a possible man-in-the-middle or key de-synchronisation, and it can trigger RRC re-establishment rather than trusting the connection.

Because ciphering is a symmetric XOR, exactly the same operation enciphers and deciphers — the sender XORs plaintext with keystream to get ciphertext, the receiver XORs ciphertext with the identical keystream to get plaintext back. This is why COUNT synchronisation is everything: if the receiver reconstructs the wrong COUNT (a wrong HFN), it generates the wrong keystream, deciphering produces garbage, and the integrity check then fails on top — two symptoms of one root cause.

Reading a security event in the logs

Security shows up in the trace at two moments: the activation handshake (algorithms selected, keys derived) and any per-PDU integrity failure. The block below stitches both together so you can see the fields that matter.

Representative UE/gNB PDCP-security log — illustrative, values vary by vendor/build:

RRC SecurityModeCommand: cipheringAlgorithm=nea2, integrityProtAlgorithm=nia2 PDCP KEYS derived from K_gNB: K_RRCenc(nea2), K_RRCint(nia2), K_UPenc(nea2), K_UPint(nia2) SMC integrity check: XMAC-I=0x8FA31C77, MAC-I=0x8FA31C77 -> PASS (command trusted) PDCP TX SRB1: dir=UL(0), bearer=1, SN=42, HFN=0x00003, COUNT=0x0000302A, MAC-I=0x1B77C2A0 PDCP RX SRB1: dir=DL(1), bearer=1, SN=17, HFN_local=0x00005, COUNT=0x00050011 PDCP RX SRB1: integrity XMAC-I=0x44D90E12 vs MAC-I=0x0000AA31 -> FAIL (discard; report to RRC)
FieldMeaningExample (from log)Check
cipheringAlgorithmSelected NEA for confidentiality.nea2Must be a member of the UE's UE Security Capabilities; nea0 after SMC on signalling is suspicious.
integrityProtAlgorithmSelected NIA for integrity.nia2Must not be nia0 on ordinary SRBs — that would defeat integrity (bidding-down flag).
SMC integrity checkXMAC-I vs MAC-I on the SecurityModeCommand itself.PASSMust PASS before the UE acts — this is the anti-bidding-down gate.
SN / HFN / COUNTHeader SN, local HFN, reconstructed 32-bit COUNT.SN=17, HFN=5Both ends must agree on HFN; divergence is the classic de-sync.
MAC-I / XMAC-IReceived tag vs locally recomputed tag.FAIL (mismatch)Mismatch → discard + report to RRC; decide tamper vs COUNT/key de-sync.

Where Each Applies, and the Four AS Keys

Ciphering and integrity are not applied uniformly — they follow the bearer type and the network's configuration. The table below summarises the NR rules from TS 33.501.

BearerCipheringIntegrity
SRB (RRC signalling)Applied when security active (may be NEA0)Mandatory — signalling must not be forgeable
DRB (user data)Applied when security active (may be NEA0)Supported per DRB, configured by the network (NR-specific; off unless enabled)

All four AS security keys derive from K_gNB, which itself descends from the NAS key hierarchy (K_AMF and above). From K_gNB the gNB and UE each derive four separate keys so that confidentiality and integrity, and control plane and user plane, are cryptographically isolated from one another.

KeyProtectsFunction
K_RRCencSRBs (RRC signalling)Ciphering (uses the selected NEA)
K_RRCintSRBs (RRC signalling)Integrity (uses the selected NIA)
K_UPencDRBs (user data)Ciphering (uses the selected NEA)
K_UPintDRBs (user data)Integrity, when UP integrity is configured

Each of the four keys is derived from K_gNB using the selected algorithm identity as a derivation input — so changing the negotiated NEA/NIA changes the keys, and every re-key at handover (via a fresh K_gNB*) automatically refreshes all four, which is also what resets COUNT and keeps it from ever wrapping under one key. The full chain from K_AMF down to these four keys is covered in the Security Key Hierarchy.

🎯

Isolation intuition: four keys mean a weakness or exposure in one context — say user-plane ciphering — does not hand an attacker the ability to forge signalling. Control plane and user plane, confidentiality and integrity, are kept apart by design, and each is bound to the specific algorithm negotiated for it.

Activation, Selection, and Replay Protection

Security does not switch on silently and it does not switch on by guesswork. The AS Security Mode Command / Complete handshake is where the gNB tells the UE exactly which NEA and NIA to use, chosen as the most-preferred algorithms both support from the reported UE Security Capabilities. Crucially, that first SecurityModeCommand message is itself integrity-protected with the newly derived K_RRCint and the chosen NIA — so the UE validates the command before acting on it, which prevents a bidding-down attack where an attacker tries to force weak or null algorithms. Until the handshake completes, SRBs run effectively unprotected (conceptually NEA0/NIA0); afterwards the negotiated algorithms and the four derived keys are in force for the rest of the connection unless a re-key occurs.

✅ Debugging steps (activation)

  • Confirm the SecurityModeCommand's own integrity check passed with K_RRCint before the UE applied any algorithm.
  • Check the selected NEA/NIA are both present in the reported UE Security Capabilities.
  • Verify the UE returned SecurityModeComplete (not SecurityModeFailure) and that subsequent SRBs are ciphered + integrity-protected.

⚠ Common causes of failure (activation)

  • SecurityModeFailure because the command's integrity check failed — wrong key derivation or a bidding-down attempt.
  • Selected algorithm not in the UE's capabilities (misconfigured allowed-algorithm list).
  • nia0 pushed on ordinary signalling — a downgrade attack the integrity-protected SMC is designed to block.

Replay protection is the third pillar alongside confidentiality and integrity. An attacker who cannot read or modify a message can still try to re-send a captured valid message to cause an unwanted action. NR defeats this by binding the MAC-I to the COUNT: because COUNT increases monotonically and never repeats under a key, a replayed PDU carries an old COUNT that the receiver has already moved past. The recomputed XMAC-I either fails to match (the receiver is now using a higher COUNT) or the PDU falls outside the PDCP reordering/duplicate-detection window and is discarded. In other words, integrity + the monotonic COUNT together give replay protection for free — which is precisely why integrity must be mandatory on signalling.

📘

Failure handling, precisely: a failed integrity check is never silently ignored. PDCP discards the PDU and reports the failure to RRC. Repeated failures on an SRB indicate a man-in-the-middle attempt or an HFN/key de-synchronisation and are handled as a security event — typically RRC re-establishment. On a DRB with UP integrity, a failed PDU is likewise discarded so corrupted or forged user data never reaches the application.

Summary

PDCP security is two independent keyed operations — ciphering (NEA0NEA3) for confidentiality and integrity protection (NIA0NIA3) for authenticity — both driven by the same inputs: KEY, COUNT (HFNSN), BEARER, DIRECTION, and LENGTH/MESSAGE. The golden rule is that COUNT must never repeat under one key on a bearer/direction, which is why the network re-keys long before the 32-bit counter can wrap and why an HFN de-sync breaks everything at once.

To root-cause a security fault, walk the chain: did the SecurityModeCommand's own integrity check pass; were the negotiated NEA/NIA in the UE's capabilities; do both ends agree on HFN (so COUNT reconstructs correctly); is the right one of the four keys (K_RRCenc/K_RRCint/K_UPenc/K_UPint) in use; and on a MAC-IXMAC-I mismatch, is it tamper/replay or simply a COUNT/key de-sync. Integrity is mandatory on SRBs and per-DRB in NR, and the monotonic COUNT bound into the tag gives replay protection for free.

Quick Q&A

Q&A Interview quickfire

Q. Which algorithms exist, and what is NEA0?

A. Ciphering: NEA0 (NULL), NEA1 (SNOW 3G), NEA2 (AES, in CTR mode), NEA3 (ZUC). Integrity: NIA0NIA3 with the same cores (AES here uses CMAC). NEA0 is the null cipher — data in the clear — used before security activation or for emergency cases. All defined algorithms use a 128-bit key.

Q. What is COUNT, and why must it never repeat under a key?

A. COUNT is 32 bits = HFN (upper, maintained locally, never sent) concatenated with the PDCP SN (lower, 12 or 18 bits, carried in the header). If two plaintexts are ever XORed with the same keystream, XORing the two ciphertexts cancels the keystream and leaks the plaintext XOR — a total break. So the network re-keys well before COUNT can wrap.

Q. What are the inputs to ciphering/integrity, and why so many?

A. KEY, COUNT (HFN+SN), BEARER, DIRECTION (1 bit UL/DL), and LENGTH/MESSAGE. COUNT gives uniqueness over time, BEARER across bearers, DIRECTION across UL/DL — so the keystream/tag is unique for every PDU and a keystream is never reused.

Q. Is integrity mandatory, and how big is the MAC-I?

A. Integrity is mandatory on SRBs and supported per-DRB in NR (UP integrity is an NR addition). The MAC-I is 32 bits, appended to the data on transmit. On transmit the order is integrity-then-cipher; on receive it is decipher-then-verify.

Q. What happens on an integrity check failure?

A. The receiver computes XMAC-I and compares it to the received MAC-I. On mismatch the PDU is discarded and the failure is reported to RRC; on signalling this is a security event that can trigger re-establishment. The monotonic COUNT bound into the tag also gives replay protection.

Q. How does the network pick the algorithms without being downgraded?

A. Via the AS SecurityModeCommand, which selects the most-preferred NEA/NIA both sides support from the UE Security Capabilities. That command is itself integrity-protected with K_RRCint, so the UE verifies it before acting — blocking bidding-down to weak or null algorithms.

🔀

LTE ↔ NR: the structure is deliberately familiar — LTE's EEA/EIA families (128-EEA0/1/2/3, 128-EIA0/1/2/3) map one-to-one onto NR's NEA/NIA over the same cores (NULL, SNOW 3G, AES, ZUC), and both build a 32-bit COUNT from HFNSN. The big NR addition is user-plane integrity (K_UPint / per-DRB UP integrity), which LTE simply did not have — in LTE integrity was for signalling only. NR also carries the AES ciphering in CTR mode and AES integrity as CMAC, exactly as LTE did, so the primitives are shared while the scope widens.

Where security connects next

These keys and algorithms don't appear from nowhere and aren't switched on silently — trace where the keys come from and how the network turns protection on, then see the layer that carries the ciphered, integrity-stamped PDUs.