DOCUMENTATION / PART 5 — TECHNIQUE REFERENCE5.8

5.8 The radio families that are not LTE or 5G

Most cellular security writing stops at LTE and 5G. This toolkit does not, because the same subscribers are on the other radios at the same time, and because the narrowband and satellite variants are where the constraints are interesting.

5.8.1 NB-IoT and Cat-M1

Need: nothing. Narrowband IoT is LTE with the bandwidth turned down to a single resource block, which changes the arithmetic and the attack surface but not the protocol family.

modules/45_iot.sh --nprach                                  # NPRACH configuration walk
modules/45_iot.sh --nprach-decode <hex>                     # read nprach-ConfigSIB-NB out of a SIB2-NB
modules/45_iot.sh --npss-nss 1                              # PCI -> N_ID(1)/N_ID(2)
modules/45_iot.sh --decode-sib1 <hex>                       # SystemInformationBlockType1-NB
modules/45_iot.sh --decode-mib <hex>                        # MIB-NB, 5 octets / 34 bits
modules/45_iot.sh --to-mhz <nprfcn>                         # refuses: the table is per-band
modules/45_iot.sh --nprach-verify

--nprach is the page worth reading: the preamble format, n_init, the subcarrier offset and the number of groups are what a device must agree with the cell about, and every one of them is derivable from the SIB the cell broadcasts. --to-mhz is the honest refusal in this module: TS 36.104's NPRFCN table is per-band and this tree does not carry it, so the verb refuses rather than returning a plausible-looking frequency.

What you read: the NPRACH parameters, the PCI decomposition, and for a MIB/SIB1 the fields with their bit widths.

When it refuses: n_init outside 0..11 is refused with the clause that bounds it; --to-mhz always refuses with the reason.

Read next: §5.1.1 for the parent technology's broadcast.

5.8.2 GPRS, EDGE and GEA

Need: nothing. GPRS ciphering is the part of 2G that most audits skip, and it contains the same pattern as the voice side: a null algorithm, a broken one, and a table nobody reads.

modules/50_gprs.sh --gea-table                       # per-algorithm clause, sizes, implemented?
modules/50_gprs.sh --gea 3                           # one algorithm with its standing
modules/50_gprs.sh --gea-crypt 3 0011223344556677 00000000 4142434445464748
# gamma e5a60b578241ff6e / ciphertext a4e44813c707b826
modules/50_gprs.sh --gea-kat                         # published test vectors, one row each
modules/50_gprs.sh --apn-encode internet.mnc260.mcc310.gprs
modules/50_gprs.sh --apn-ie <apn>                    # the APN IE itself (IEI 28)

The cipher is implemented for real rather than tabulated: --gea-crypt produces a keystream and ciphertext for a given Kc, and --gea-kat runs the published GEA3/GEA4 vectors as known-answer tests so the implementation is checkable. The APN verbs are there because the APN is where a private network names itself.

What you read: the algorithm's clause and standing, the keystream for a chosen input, and the APN's label coding.

When it refuses: GEA3 takes a 64-bit Kc and refuses a 128-bit one by name — the message says which algorithm wanted which key size, because the alternative is a silently truncated key.

Read next: §5.1.4, which is the voice-side equivalent of the same table.

5.8.3 Non-terrestrial networks

Need: nothing. A satellite cell is a cell with a 600 km timing advance problem, and that problem is the whole technique surface.

modules/49_ntn.sh --doppler 1575420000 7500 30    # Doppler for a closing velocity at an angle
modules/49_ntn.sh --range 600                      # one-way and round-trip delay
modules/49_ntn.sh --ta 600                         # TA units needed vs the LTE TA range
modules/49_ntn.sh --koffset 20 15                  # K_offset in reference slots
modules/49_ntn.sh --ntn-reselect                    # which cell the UE reselects to
modules/49_ntn.sh --scan-plan                       # the three signals that say NTN
modules/49_ntn.sh --fakecell-plan                   # what broadcasting a satellite cell needs

--ta is the number that matters: a geostationary round trip needs far more timing advance than the terrestrial TA field can express, which is why NTN has its own timing-advance mechanisms and why a fake satellite cell fails in a specific, statable way. --fakecell-plan states that failure rather than pretending the cell can be stood up.

What you read: Doppler shift, delay, TA requirement versus the field's range, and the reselection outcome.

When it refuses: a velocity or angle it cannot interpret; --fakecell-plan does not refuse but reports the preconditions it cannot satisfy.

Read next: §5.7.1, since the TA arithmetic is the same instrument with a much bigger number.

5.8.4 NR sidelink and V2X

Need: nothing. Sidelink is UE-to-UE, which means the security question changes: there is no network in the middle to trust.

modules/51_sidelink.sh --subchannels 106 10       # 10 subchannels of 10 PRBs, remainder 6
modules/51_sidelink.sh --freq-bits 10             # SCI-1A frequency resource field width
modules/51_sidelink.sh --pfi 1                    # PC5 QoS flow identifier
modules/51_sidelink.sh --l2id 001122               # 24-bit Layer-2 ID
modules/51_sidelink.sh --sci1a                     # refuses: the widths are not in this tree
modules/51_sidelink.sh --its                       # ETSI/1609.2 certificate roles
modules/51_sidelink.sh --relay-check conf.txt      # UE-to-network relay configuration findings

--sci1a refusing is the module being honest about scope: the SCI-1A field widths depend on parameters this tree does not carry, so it refuses instead of encoding a plausible guess. --relay-check is the practical verb — a UE acting as a relay for another is a policy decision, and misconfigured relays are how a sidelink deployment leaks traffic between fleets.

What you read: subchannel arithmetic, the L2 identity, and for --its the certificate roles (reference only; the module states it has no validator).

When it refuses: --sci1a always; a bandwidth/subchannel pair that leaves a remainder larger than a subchannel.

Read next: §5.8.3 for the other non-terrestrial-adjacent radio, and §4.13 for the module pages.

5.8.5 TETRA, DMR and GSM-R

Need: nothing. The radios that are not cellular but carry the same people.

modules/53_non3gpp.sh --tetra                 # TETRA frame and band reference (EN 300 392)
modules/53_non3gpp.sh --tea TEA2              # cipher description and standing
modules/53_non3gpp.sh --dmr                   # DMR reference (TS 102 361)
modules/53_non3gpp.sh --gsmr                  # GSM-R band and feature reference (EN 301 515)
modules/53_non3gpp.sh --tdma 56.67 4          # slot arithmetic from a stated frame length
modules/53_non3gpp.sh --frame-math 255 2 4 36000   # derive the frame length from the air interface
modules/53_non3gpp.sh --classify 25           # technology from channel spacing

--classify is the identification verb: 25 kHz with 4-slot TDMA is TETRA, 12.5 kHz is DMR, 200 kHz is GSM. --frame-math is the reason this module is more than a table: given symbols per slot, bits per symbol, slots and bit rate, it derives the frame length, which is how a new or undocumented system gets measured rather than guessed at.

What you read: for a technology, its frame structure and cipher standing; for --classify, the most likely technology and the evidence for it.

When it refuses: a frame length of zero, a bit rate that does not divide.

Read next: §5.1.1, since these systems broadcast their own equivalent of a SIB and the same reading discipline applies.

5.8.6 Open RAN

Need: nothing to read the authority model; a network path for RIC interaction. O-RAN moves control into xApps on a RIC, which means the security question is "what is an xApp allowed to do, and who checked".

modules/48_oran.sh --interfaces        # E2/A1/O1/O2/F1/E1/fronthaul map
modules/48_oran.sh --e2sm              # E2 service models
modules/48_oran.sh --assess conf.txt   # deployment findings from a KEY=VALUE config
modules/48_oran.sh --xapp-authority tsv
modules/48_oran.sh --a1-put policy 1 scope '{}'   # a forged A1 policy PUT
modules/48_oran.sh --qos-policy                    # a complete A1 QoS policy body
modules/48_oran.sh --qos-policy-check policy.json  # validate it; unknown keys are reported

--xapp-authority is the page: per loaded xApp, what it can actually reach, which is rarely what its documentation says. --a1-put builds the policy write that a compromised xApp would send — the finding is not that the message can be built but that the A1 interface accepts a policy from anything that can reach it. --qos-policy-check exists so a policy body can be validated against the schema before it is pushed at anything.

What you read: the interfaces and service models, the authority table, and for --assess the findings with the config key behind each.

When it refuses: a config path that does not exist (it says no such config), an unknown key in a policy body (reported, not silently dropped).

Read next: §5.4.3, since the RIC sits beside the same service-based core.