5G/NR - User Plane Integrity Protection
User Plane Integrity Protection

 

In LTE, user data on the radio interface is ciphered, but it is not integrity protected. Only the signalling on SRBs carries a MAC-I. Then you may ask: if nobody can read the ciphered data, why should we care whether somebody changes it?

The short answer is that ciphering hides the content, but it does not tell the receiver whether the content was modified on the way. NR fixed this gap. In 5G, PDCP can integrity protect a DRB in the same way it protects an SRB. It appends a 32 bit MAC-I to every PDCP Data PDU of that DRB.

But this is not switched on for every DRB. It costs packet overhead and processing power, so the network decides it per PDU session. The SMF provides a UP security policy, the gNB applies it, and the UE simply follows the indication in RRC. This note follows that chain from the reason behind it down to the PDCP PDU and the trace.

The specification text quoted here is from TS 33.501 v20.3.0, TS 38.331 v19.4.0, TS 38.413 v19.4.0 and TS 38.323 v19.1.0. For the overall 5G security framework, see Security for 5G, and for the AS security activation itself, see Security Mode Setup.

Why Do We Need User Plane Integrity ?

At first, ciphering alone looks like enough protection. If an attacker cannot read the packet, what useful thing can the attacker do with it? The problem is that an attacker does not always need to read a packet to change its meaning.

The ciphering algorithms used in LTE and NR work as stream ciphers. The algorithm generates a keystream from the key, COUNT, BEARER and DIRECTION, and the transmitter XORs the keystream with the plaintext. So if somebody flips one bit in the ciphertext, the same bit flips in the plaintext after deciphering. The receiver has no way to notice it, because the deciphering itself never fails. It always produces some output.

This sounds harmless when the content is unknown. But many parts of a user packet are predictable. An IP header, a DNS query toward a well known resolver address or a fixed protocol field sits at a known offset with a value that can be guessed. If the attacker can guess the plaintext at a position, the attacker can XOR in the difference and turn it into a value of its own choice. This is the idea behind the published LTE attack known as aLTEr. In that attack, a fake relay between the UE and the eNB changes the DNS server address inside ciphered user packets, and the UE gets redirected to a malicious server.

An integrity check closes this hole. The receiver computes its own MAC over the packet and compares it with the received MAC-I. A single flipped bit gives a different MAC, and the receiver discards the packet. The attacker cannot build a correct MAC-I without KUPint.

LTE already had this protection for signalling. SRBs carry a MAC-I in every PDCP PDU. What NR added is the option to apply the same mechanism to DRBs. TS 33.501 makes it mandatory for the UE and the gNB to support it, but optional to use.

  • Ciphering hides the content but does not detect modification : a flipped ciphertext bit becomes a flipped plaintext bit
  • Predictable fields make that modification useful : IP headers and DNS addresses can be rewritten without reading the packet
  • NR adds integrity protection for DRBs : the same MAC-I mechanism LTE used only for SRBs

Why Not Always On ?

If user plane integrity protection fixes a real attack, why does the specification make it optional to use? The reason is cost. TS 33.501 says it directly in a note: integrity protection of the user plane adds packet overhead and increases the processing load in both the UE and the gNB.

Look at the overhead first. Every protected PDCP Data PDU gets a 32 bit MAC-I, which is 4 bytes. On a 1500 byte IP packet this is about 0.27 % and nobody would notice it. But on a small packet the ratio grows quickly. A voice packet compressed with ROHC can be only a few tens of bytes, and there 4 bytes can be around 10 % of the PDU.

The processing cost is the bigger issue. The UE computes a MAC for every uplink PDU and verifies one for every downlink PDU. At a few Gbps, this means hundreds of thousands of NIA operations per second, on top of ciphering. A modem can do this only if the integrity algorithm runs in dedicated hardware at full line rate. This is the reason early UEs were allowed to support integrity protection only up to a low data rate. I will come back to this in Maximum Integrity Protected Data Rate.

There is one more point. Some traffic does not need this protection very much. An application that already uses TLS or IPsec end to end gets integrity protection at a higher layer. Adding MAC-I on the radio link then protects the same bytes twice. So the network needs a way to say which traffic deserves it and which does not.

The answer in 5G is to make it a per PDU session decision, driven by the core network. The next section shows who makes that decision.

  • MAC-I adds 4 bytes to every protected PDCP Data PDU : negligible for large packets, noticeable for small ones
  • Processing load scales with the packet rate : full rate protection needs hardware support in the modem
  • Support is mandatory, use is optional : the network turns it on only where it is worth the cost

Who Decides - UP Security Policy

The UE does not decide whether a DRB is integrity protected, and the gNB does not decide it alone either. The decision starts in the SMF, because the SMF knows the PDU session, the DNN and the slice. It can take the policy from the subscription data in UDM or from its own local configuration.

The SMF sends the UP security policy to the gNB during PDU session establishment. The policy carries two separate indications, one for integrity protection and one for confidentiality. Each of them takes one of three values: Required, Preferred or Not needed. The same policy applies to all DRBs of that PDU session.

The values look simple, but the gNB behaviour is different for each one. The table below summarises the rules in TS 33.501 clause 6.6.1.

 

Integrity Protection Indication

What the gNB does

If the gNB cannot do it

Required

Activates integrity protection for every DRB of the PDU session. The gNB shall not overrule it.

Rejects the UP resources for the PDU session and indicates the cause to the SMF.

Preferred

Activates it if it can, for example when the UE supported rate and the gNB load allow it.

Sets up the PDU session without it, and reports not-performed.

Not needed

Does not activate it. The gNB shall not overrule it.

Not applicable.

 

So Required and Not needed leave no choice to the gNB. Only Preferred gives the gNB a real decision. This is also why the gNB reports a result back. With Preferred, the SMF cannot know what happened unless the gNB tells it.

One special case is worth knowing. For an unauthenticated IMS emergency session, the SMF shall indicate Not needed for both integrity and confidentiality. This matches the AS side, where NIA0 is allowed only for that case. TS 38.331 also says that when nia0 is used for SRBs, integrity protection is disabled for DRBs.

Another point is the granularity. The policy is per PDU session, but RRC configures integrity per DRB. TS 38.331 closes this gap with a rule: the network configures all DRBs with the same PDU session ID with the same integrityProtection value. So in practice you would never see one DRB of a session protected and another DRB of the same session unprotected.

  • The SMF owns the decision : it sends one UP security policy per PDU session
  • Only Preferred leaves a choice to the gNB : Required and Not needed must be followed as they are
  • All DRBs of one PDU session share the same setting : the policy is per session even though RRC configures per DRB

Overall Procedure

Now let's put the pieces into one sequence. The policy travels from the SMF to the gNB over NGAP, and the activation travels from the gNB to the UE over RRC. The UE also contributes one piece of information at the very start: how fast it can run integrity protection.

Figure 1 shows a PDU session establishment with the security related information marked on each message. Service based messages between the AMF and the SMF are simplified to their operation names. For now, just pay attention to three things: the UE rate in step 1, the Security Indication in step 5 and the Security Result in step 9.

User plane integrity protection activation during PDU session establishment UE sends its integrity protection maximum data rate in the PDU Session Establishment Request. The SMF sets the UP security policy and sends it as Security Indication to the gNB in PDU SESSION RESOURCE SETUP REQUEST. The gNB decides, configures integrityProtection in PDCP-Config with RRCReconfiguration, and reports the Security Result back to the SMF. UE gNB AMF SMF 1. PDU Session Establishment Request (NAS) Integrity protection maximum data rate UL / DL 2. Nsmf_PDUSession_CreateSMContext 3. SMF sets UP security policy Required / Preferred / Not needed 4. N1N2MessageTransfer 5. PDU SESSION RESOURCE SETUP REQUEST Security Indication 6. gNB checks policy, UE rate and its own resources 7. RRCReconfiguration PDCP-Config: integrityProtection UE derives KUPint and adds MAC-I 8. RRCReconfigurationComplete 9. PDU SESSION RESOURCE SETUP RESPONSE Security Result 10. Nsmf_PDUSession_UpdateSMContext Simplified. Red labels mark the information related to UP integrity protection.

Figure 1. User plane integrity protection is decided in the SMF, enforced in the gNB and only executed in the UE. The UE contributes its maximum supported rate, but it never chooses whether a DRB is protected.

  • Step 1 : the UE tells the network how fast it can run user plane integrity protection, separately for UL and DL. The gNB only relays this NAS message.
  • Step 3 : the SMF sets the UP security policy for the PDU session from the subscription data or from its local configuration.
  • Step 5 : the policy reaches the gNB as the Security Indication IE inside the PDU Session Resource Setup Request Transfer. The UE rate travels with it as the Maximum Integrity Protected Data Rate.
  • Step 6 and 7 : the gNB makes the final decision and tells the UE with integrityProtection in PDCP-Config. This RRCReconfiguration also carries the NAS PDU Session Establishment Accept.
  • Step 9 : the gNB reports what it actually did with the Security Result IE, performed or not-performed.

The activation always comes after AS security is active. TS 33.501 clause 6.6.2 says this RRCReconfiguration for adding DRBs shall be performed only after RRC security has been activated with the AS Security Mode Command. The integrity algorithm is the one already selected in that Security Mode Command. Nothing new is negotiated for the user plane.

NAS and NGAP Parameters

Two interfaces carry the policy information before the UE sees anything in RRC. NAS carries what the UE can do, and NGAP carries what the network wants together with what the gNB actually did. If you are debugging why a DRB came up without integrity protection, these are the places to look first.

UE Side - Integrity Protection Maximum Data Rate

The UE includes the Integrity protection maximum data rate IE in the PDU SESSION ESTABLISHMENT REQUEST, defined in TS 24.501. It has one value for uplink and one for downlink. The two values that matter for this discussion are 64 kbps and full data rate, and they map onto the two NGAP values shown below.

The value is per UE, not per PDU session, even though it is sent in a session level message. Suppose the SMF policy requires integrity protection, but this rate is too low for the service. Then the network can reject the session with 5GSM cause #82, "Maximum data rate per UE for user-plane integrity protection is too low".

Network Side - Security Indication and Security Result

On NGAP, the AMF passes the SMF policy to the gNB as the Security Indication IE. It sits in the PDU Session Resource Setup Request Transfer, which is the SMF container inside PDU SESSION RESOURCE SETUP REQUEST. The gNB answers with the Security Result IE in the PDU Session Resource Setup Response Transfer.

Following is the ASN.1 from TS 38.413. There are several definitions here, but only two of them carry the decision itself: integrityProtectionIndication going down and integrityProtectionResult coming back.

Following is based on 38.413 v19.4.0 (Release 19)

SecurityIndication ::= SEQUENCE {
    integrityProtectionIndication           IntegrityProtectionIndication,
    confidentialityProtectionIndication     ConfidentialityProtectionIndication,
    maximumIntegrityProtectedDataRate-UL    MaximumIntegrityProtectedDataRate       OPTIONAL,
    -- The above IE shall be present if the Integrity Protection Indication IE is set to the value "required" or "preferred"
    iE-Extensions       ProtocolExtensionContainer { {SecurityIndication-ExtIEs} }  OPTIONAL,
    ...
}

SecurityIndication-ExtIEs NGAP-PROTOCOL-EXTENSION ::= {
    { ID id-MaximumIntegrityProtectedDataRate-DL    CRITICALITY ignore  EXTENSION MaximumIntegrityProtectedDataRate PRESENCE optional},
    ...
}

IntegrityProtectionIndication ::= ENUMERATED {
    required,
    preferred,
    not-needed,
    ...
}

MaximumIntegrityProtectedDataRate ::= ENUMERATED {
    bitrate64kbs,
    maximum-UE-rate,
    ...
}

SecurityResult ::= SEQUENCE {
    integrityProtectionResult           IntegrityProtectionResult,
    confidentialityProtectionResult     ConfidentialityProtectionResult,
    iE-Extensions       ProtocolExtensionContainer { {SecurityResult-ExtIEs} }  OPTIONAL,
    ...
}

IntegrityProtectionResult ::= ENUMERATED {
    performed,
    not-performed,
    ...
}

One thing you would notice is the asymmetry between UL and DL. The UL rate is in the root of SecurityIndication, but the DL rate is in an extension container. My guess is that the DL rate was added after the first version of the IE was frozen, so it had to go into the extension. I haven't checked the change history to confirm this, so take it as a guess.

Also note the comment under maximumIntegrityProtectedDataRate-UL. The rate is mandatory when the indication is required or preferred. This makes sense, because the gNB cannot decide whether to protect a DRB without knowing whether the UE can keep up.

  • NAS carries the UE capability : Integrity protection maximum data rate in PDU SESSION ESTABLISHMENT REQUEST
  • NGAP carries the policy down : Security Indication in the PDU Session Resource Setup Request Transfer
  • NGAP carries the result up : Security Result with performed or not-performed

RRC Configuration

On the RRC side there is surprisingly little to configure. The algorithm is already known from the AS Security Mode Command, and the key is derived from KgNB. So the only thing the gNB has to tell the UE is whether a given DRB uses integrity protection or not.

This is done with one field, integrityProtection, in the drb part of PDCP-Config. Following is the full PDCP-Config IE. There are many parameters in this block, but only integrityProtection matters for this discussion.

Following is based on 38.331 v19.4.0 (Release 19)

PDCP-Config ::=         SEQUENCE {
    drb                     SEQUENCE {
        discardTimer            ENUMERATED {ms10, ms20, ms30, ms40, ms50, ms60, ms75, ms100, ms150, ms200,
                                            ms250, ms300, ms500, ms750, ms1500, infinity}       OPTIONAL, -- Cond Setup
        pdcp-SN-SizeUL          ENUMERATED {len12bits, len18bits}                               OPTIONAL, -- Cond Setup1
        pdcp-SN-SizeDL          ENUMERATED {len12bits, len18bits}                               OPTIONAL, -- Cond Setup2
        headerCompression       CHOICE {
            notUsed                 NULL,
            rohc                    SEQUENCE {
                maxCID                  INTEGER (1..16383)                                      DEFAULT 15,
                profiles                SEQUENCE {
                    profile0x0001           BOOLEAN,
                    profile0x0002           BOOLEAN,
                    profile0x0003           BOOLEAN,
                    profile0x0004           BOOLEAN,
                    profile0x0006           BOOLEAN,
                    profile0x0101           BOOLEAN,
                    profile0x0102           BOOLEAN,
                    profile0x0103           BOOLEAN,
                    profile0x0104           BOOLEAN
                },
                drb-ContinueROHC            ENUMERATED { true }                                 OPTIONAL    -- Need N
            },
            uplinkOnlyROHC          SEQUENCE {
                maxCID                  INTEGER (1..16383)                                      DEFAULT 15,
                profiles                SEQUENCE {
                    profile0x0006           BOOLEAN
                },
                drb-ContinueROHC            ENUMERATED { true }                                 OPTIONAL    -- Need N
            },
            ...
        },
        integrityProtection     ENUMERATED { enabled }                                          OPTIONAL,   -- Cond ConnectedTo5GC1
        statusReportRequired    ENUMERATED { true }                                             OPTIONAL,   -- Cond Rlc-AM-UM
        outOfOrderDelivery      ENUMERATED { true }                                             OPTIONAL    -- Need R
    }                                                                                           OPTIONAL,   -- Cond DRB
    moreThanOneRLC          SEQUENCE {
        primaryPath             SEQUENCE {
            cellGroup               CellGroupId                                                 OPTIONAL,   -- Need R
            logicalChannel          LogicalChannelIdentity                                      OPTIONAL    -- Need R
        },
        ul-DataSplitThreshold   UL-DataSplitThreshold                                           OPTIONAL,   -- Cond SplitBearer
        pdcp-Duplication            BOOLEAN                                                     OPTIONAL    -- Need R
    }                                                                                           OPTIONAL,   -- Cond MoreThanOneRLC

    t-Reordering                ENUMERATED {
                                    ms0, ms1, ms2, ms4, ms5, ms8, ms10, ms15, ms20, ms30, ms40,
                                    ms50, ms60, ms80, ms100, ms120, ms140, ms160, ms180, ms200, ms220,
                                    ms240, ms260, ms280, ms300, ms500, ms750, ms1000, ms1250,
                                    ms1500, ms1750, ms2000, ms2250, ms2500, ms2750,
                                    ms3000, spare28, spare27, spare26, spare25, spare24,
                                    spare23, spare22, spare21, spare20,
                                    spare19, spare18, spare17, spare16, spare15, spare14,
                                    spare13, spare12, spare11, spare10, spare09,
                                    spare08, spare07, spare06, spare05, spare04, spare03,
                                    spare02, spare01 }                                          OPTIONAL, -- Need S
    ...,
    [[
    cipheringDisabled       ENUMERATED {true}                                                   OPTIONAL    -- Cond ConnectedTo5GC
    ]],
    [[
    discardTimerExt-r16     SetupRelease { DiscardTimerExt-r16 }                                OPTIONAL,    -- Cond DRB2
    moreThanTwoRLC-DRB-r16  SEQUENCE {
        splitSecondaryPath-r16  LogicalChannelIdentity                                          OPTIONAL,   -- Cond SplitBearer2
        duplicationState-r16    SEQUENCE (SIZE (3)) OF BOOLEAN                                  OPTIONAL    -- Need S
    }                                                                                           OPTIONAL,   -- Cond MoreThanTwoRLC-DRB
    ethernetHeaderCompression-r16  SetupRelease { EthernetHeaderCompression-r16 }               OPTIONAL    -- Need M
    ]],
    [[
    survivalTimeStateSupport-r17   ENUMERATED {true}                                            OPTIONAL,   -- Cond Drb-Duplication
    uplinkDataCompression-r17      SetupRelease { UplinkDataCompression-r17 }                   OPTIONAL,   -- Cond Rlc-AM
    discardTimerExt2-r17           SetupRelease { DiscardTimerExt2-r17 }                        OPTIONAL,   -- Need M
    initialRX-DELIV-r17            BIT STRING (SIZE (32))                                       OPTIONAL    -- Cond MRB-Initialization
    ]],
    [[
    pdu-SetDiscard-r18             ENUMERATED {true}                                            OPTIONAL,   -- Need R
    discardTimerForLowImportance-r18   SetupRelease { DiscardTimerForLowImportance-r18 }        OPTIONAL,   -- Cond DRB2
    primaryPathOnIndirectPath-r18  ENUMERATED {true}                                            OPTIONAL,   -- Cond SplitBearerMP
    sn-GapReport-r18               ENUMERATED {true}                                            OPTIONAL    -- Need R
    ]],
    [[
    remainingTimeThresholdRLC-ReTx-r19              RLC-AM-RemainingTimeThreshold-r19           OPTIONAL,   -- Cond RLC-AM
    remainingTimeThresholdRLC-Polling-r19           RLC-AM-RemainingTimeThreshold-r19           OPTIONAL    -- Cond RLC-AM
    ]]
}

The field is a single ENUMERATED with one value, enabled. If the field is present, the DRB is integrity protected. If it is absent, it is not. Compare it with cipheringDisabled a few lines below, which works the other way round. Ciphering is on by default and has to be switched off, while integrity is off by default and has to be switched on.

Then you may ask whether the gNB can turn it on later for a DRB that is already running. The answer is no. The field description says the value cannot be changed after the DRB is set up. TS 38.331 adds in a note that enabling or disabling integrity protection can be changed only by releasing and adding the DRB.

The condition ConnectedTo5GC1 is also worth reading. The field is optionally present if the UE is connected to NR/5GC, or if the UE supports user plane integrity protection when connected to E-UTRA/EPC as specified in TS 33.401. So the same field also serves an NR PDCP bearer in EN-DC, when the UE supports that option.

What about the algorithm? There is no separate algorithm for the user plane. TS 38.331 says the integrity protection algorithm is common for the SRBs and for the DRBs configured with integrity protection. It comes from SecurityAlgorithmConfig, which the gNB sends in the SecurityModeCommand.

  • One field turns it on : integrityProtection enabled in the drb part of PDCP-Config
  • The setting is fixed for the lifetime of the DRB : changing it needs a DRB release and add
  • The algorithm is shared with the SRBs : it is the one selected in the AS Security Mode Command

What Happens in PDCP ?

Once integrityProtection is configured, the work moves into PDCP. The interesting questions here are which bytes are protected, which bytes are ciphered, and in which order the two operations happen. The answer is not obvious, because the two operations do not cover the same part of the PDU.

Figure 2 shows a PDCP Data PDU of a DRB with integrity protection and ciphering both active. The bar is the PDU as it goes to RLC. The bracket above it marks the part covered by integrity protection, and the bracket below marks the part that is ciphered.

PDCP Data PDU of a DRB with integrity protection The PDU consists of PDCP header, SDAP header, data and a 32 bit MAC-I. Integrity protection covers the PDCP header, SDAP header and data before ciphering. Ciphering covers the data and the MAC-I, but not the PDCP header or the SDAP header. Integrity protected : PDCP header + data part, computed before ciphering PDCP header D/C, R, PDCP SN SDAP header if configured Data IP packet, after ROHC if configured MAC-I 32 bits Ciphered : data + MAC-I, SDAP header excluded NIA inputs KEY = KUPint, derived from KgNB with N-UP-int-alg = 0x06 COUNT = 32 bit PDCP COUNT of this PDU BEARER = RB identity - 1 DIRECTION = uplink or downlink MESSAGE = PDCP header and data part before ciphering MAC-I is present for a DRB only when integrityProtection is configured.

Figure 2. Integrity protection is computed first and covers the header in the clear. Ciphering comes second and also hides the MAC-I, so a modified header or a modified payload both fail the check at the receiver.

  • Integrity covers the PDCP header : the PDCP SN is sent in the clear, but changing it breaks the MAC-I
  • Integrity is computed before ciphering : TS 38.323 clause 5.9 protects the PDU header and the data part before ciphering
  • Ciphering covers the MAC-I as well : TS 38.323 clause 5.8 ciphers the MAC-I and the data part, except the SDAP header
  • No MAC-I field without integrityProtection : SRBs always carry a MAC-I field, padded with zeros if needed, but a DRB carries it only when configured

The key KUPint comes from the same key derivation function as the other AS keys. TS 33.501 Annex A.8 uses FC = 0x69, the algorithm type distinguisher N-UP-int-alg = 0x06 and the algorithm identity as input, with KgNB as the key. The 128 least significant bits of the 256 bit output become KUPint. The UE and the gNB derive it only when the first protected DRB is activated, if they do not have it yet.

BEARER needs a short comment. It is RB identity minus 1, so DRB 1 gives BEARER = 0, and SRB1 also gives BEARER = 0. This would look like a collision. But the SRB uses KRRCint and the DRB uses KUPint, so the two inputs never produce the same keystream or MAC.

Now what happens when the check fails? TS 33.501 clause 6.6.4.2 says that a PDCP PDU with a faulty or missing MAC-I after the start of integrity protection shall be discarded. TS 38.323 also says PDCP indicates the integrity verification failure to the upper layer. For SRB1 and SRB2, TS 38.331 uses this indication as a trigger for RRC re-establishment. I couldn't find an equivalent RRC action for a DRB failure in TS 38.331. So my understanding is that a DRB integrity failure shows up only as a discarded packet, and any further reaction is up to the implementation.

Maximum Integrity Protected Data Rate

This is the part that explains why the NAS and NGAP IEs carry a data rate at all. The question is simple: what if the UE modem can run NIA at only a low rate, but the session needs much more than that?

The answer has changed over time. The current TS 33.501 says the UE shall support integrity protection of user data at any data rate, up to and including the highest data rate supported by the UE. So for a UE built to this text, full data rate is the expected value.

But the early 5G UEs were not built to this text. My understanding is that the Release 15 requirement was only 64 kbps. Full rate came later with a Release 16 change in 2020. The TS 33.501 change history records it as "Update to User Plane Integrity Protection". 64 kbps is enough for signalling like traffic or a voice codec, but not for normal data. This is why the bitrate64kbs value exists in NGAP, and why the network has to ask the UE in every PDU session establishment.

So the gNB has two inputs when the policy is Required or Preferred: the policy itself and the UE maximum rate. With Preferred and a 64 kbps UE, a typical choice is to skip integrity protection for a broadband session and report not-performed. With Required and a 64 kbps UE, there is no good choice. The SMF can reject the session with cause #82, or the gNB can reject the UP resources.

The table below lists the combinations. The 64 kbps column depends on the implementation. The rule in TS 33.501 stops at one level: the gNB activates protection according to the policy, within what the UE supports.

 

Policy

UE rate full

UE rate 64 kbps

Required

Protected

Depends on the implementation and the session rate. If the gNB cannot comply, it rejects the UP resources.

Preferred

Protected, if the gNB has the capacity

Usually not protected for a broadband session

Not needed

Not protected

Not protected

 

There is one more reason why an operator may still choose Preferred or Not needed. The gNB carries the same processing cost as the UE, multiplied by every protected UE in the cell. A UE that supports full rate does not make the gNB cost go away.

  • The UE rate is an input to the gNB decision : bitrate64kbs or maximum-UE-rate on NGAP
  • Current TS 33.501 expects full rate support : older UEs may still report 64 kbps
  • Required with a 64 kbps UE can end in rejection : 5GSM cause #82 is defined for this case

Handover and Dual Connectivity

So far everything happened in one gNB. Then what happens when the UE moves, or when two nodes serve the same PDU session? The policy has to travel with the UE, and every node that terminates a DRB has to apply it in the same way.

Xn Handover and Path Switch

At an Xn handover, the source gNB includes the UE UP security policy in the HANDOVER REQUEST. The target applies the same rules as at session setup. If the policy is Required and the target cannot comply, it rejects that PDU session. For the accepted sessions, the target activates integrity protection per DRB and indicates it in the handover command.

With Preferred, TS 33.501 notes that the activation can change across the handover. A DRB protected in the source cell can come up unprotected in the target cell, and the other way round. Then how does this fit the rule that the setting cannot change for a DRB? I think the target does it by releasing and adding the DRB, or with a full configuration, because TS 38.331 allows the change only that way. I haven't checked this in a real handover log.

Then you may ask what stops a compromised source gNB from sending a weaker policy to the target. This is the job of the path switch. The target sends the policy it received to the SMF in the PATH SWITCH REQUEST, inside User Plane Security Information. The SMF compares it with its own stored copy. If they differ, the SMF sends the correct policy back in the PATH SWITCH REQUEST ACKNOWLEDGE, logs the event and may raise an alarm. The target then runs an intra-cell handover to activate or deactivate integrity protection as the SMF says.

At an N2 handover this check is not needed in the same way. The SMF sends the policy to the target gNB through the target AMF directly, so a source gNB never relays it.

Dual Connectivity and ng-eNB

Dual connectivity adds one more problem. Within one PDU session, some DRBs can terminate in the MN and others in the SN. But all DRBs of one session must have the same integrity setting. TS 33.501 solves this by letting the MN decide and tell the SN. The SN then follows the MN decision for any DRB offloaded to it.

The E-UTRA side adds another restriction. A UE indicates support of user plane integrity protection with an ng-eNB by setting the EIA7 bit in the 5G UE Security Capability IE. TS 33.501 notes that a Release 16 or earlier UE does not support it with ng-eNB. Without that bit, an ng-eNB cannot activate integrity protection. In NGEN-DC with Preferred, the MN always deactivates it. In NE-DC, the MN does not offload a protected session to the SN.

The EPC side has its own version too. The ConnectedTo5GC1 condition shown earlier allows integrityProtection for a UE connected to E-UTRA/EPC that supports the TS 33.401 option. This covers the NR leg of EN-DC. The details are in TS 33.401, which I did not go through for this note.

  • The policy travels with the UE : HANDOVER REQUEST on Xn, from the SMF directly on N2
  • The SMF checks the policy after an Xn handover : a mismatch in PATH SWITCH REQUEST is corrected and logged
  • One PDU session has one setting across MN and SN : the MN decides and the SN follows

What to Check in a Trace

When a DRB comes up without integrity protection, the cause can be in four different nodes. So it helps to check the information in the same order it flows: UE capability, SMF policy, gNB decision and RRC configuration.

The checkpoints below follow that order. For each one, the right column says what the value tells you about the final result.

 

Checkpoint

What to verify

PDU SESSION ESTABLISHMENT REQUEST

Integrity protection maximum data rate for UL and DL. A 64 kbps value here can explain a not-performed result.

PDU SESSION RESOURCE SETUP REQUEST

Security Indication: integrityProtectionIndication and the maximum rate UL and DL. This is what the SMF asked for.

SecurityModeCommand

integrityProtAlgorithm. If it is nia0, DRB integrity protection is disabled anyway.

RRCReconfiguration

integrityProtection in PDCP-Config of every DRB of the session. All DRBs of one session should have the same setting.

PDU SESSION RESOURCE SETUP RESPONSE

Security Result: performed or not-performed. It should match the RRC configuration.

PDCP log

4 extra bytes of MAC-I per PDU on the protected DRB. Discarded PDUs with integrity failure point to a key or COUNT problem.

PATH SWITCH REQUEST and ACKNOWLEDGE

User Plane Security Information from the target and any corrected Security Indication from the SMF.

 

The most common surprise in a test is a session where the policy says Preferred and the result says not-performed. That is not an error. It means the gNB used the freedom that Preferred gives it. If the test needs a protected DRB, set the policy to Required in the SMF and make sure the UE reports full data rate.

Another one is integrity failures right after a handover or a re-establishment. In that case, check the COUNT and the key change first. Both sides derive a new KUPint from the new KgNB, and a mismatch there breaks every PDU on the protected DRB at the same time.

  • Follow the information in the order it flows : UE rate, SMF policy, gNB result, RRC field
  • Preferred with not-performed is a valid result : use Required when the test needs protection
  • Failures on every PDU point to keys or COUNT : check the key change after handover or re-establishment

Reference

  • 3GPP TS 33.501 v20.3.0 : Security architecture and procedures for 5G system. Clauses 5.2.3, 5.3.3, 6.6.1, 6.6.2, 6.6.4, 6.7.3, 6.10.4, 10.2.2 and Annex A.8.
  • 3GPP TS 38.331 v19.4.0 : NR RRC Protocol Specification. Clause 5.3.1.2, PDCP-Config field descriptions and conditions, clause 5.3.7.
  • 3GPP TS 38.413 v19.4.0 : NG Application Protocol. SecurityIndication, SecurityResult and UserPlaneSecurityInformation definitions.
  • 3GPP TS 38.323 v19.1.0 : NR PDCP. Clauses 5.8, 5.9 and 6.3.4.
  • 3GPP TS 24.501 v20.1.0 : NAS protocol for 5GS. 5GSM cause #82. Only the cause list and the change history extracted from the document. The clause defining the Integrity protection maximum data rate IE did not extract, so its value encoding is not quoted here.