Skip to content

linouxis9/oxirush-nas

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oxirush-nas

Crates.io Documentation License

A fast, memory-safe library for encoding and decoding 5G NAS (Non-Access Stratum) messages in Rust, per 3GPP TS 24.501.

Part of the OxiRush project — a 5G Core Network testing framework.

Features

  • Complete 5G NAS codec — all 5GMM and 5GSM message types from TS 24.501
  • 100+ Information Elements — full TLV/TV/V/LV wire-format codec via Encode/Decode traits
  • Typed IE accessors — zero-cost enums and builder helpers over raw bytes (no manual bit manipulation)
  • Human-readable display — Wireshark-style fmt::Display for all messages
  • Structural validation helpers — core TS 24.501 checks with error/warning severity levels
  • NAS security envelope (optional) — integrity + ciphering per TS 33.501, with NAS COUNT tracking
  • Serde support (optional) — JSON serialization for typed IE structs
  • Round-trip preservation — decode then re-encode preserves supported fields and unknown IE payloads, with byte-exact coverage verified by the test suite

Quick start

[dependencies]
oxirush-nas = "0.3"

Feature flags

Feature Description
security NAS security envelope (protect/unprotect) via oxirush-security
serde JSON serialization with serde::Serialize/Deserialize
oxirush-nas = { version = "0.3", features = ["security", "serde"] }

Usage

Decode and encode a NAS message

use oxirush_nas::{decode_nas_5gs_message, encode_nas_5gs_message, Validate};

// Decode a Registration Request from raw bytes
let bytes = hex::decode(
    "7e004179000d0199f9070000000000000010022e08a020000000000000"
).unwrap();
let msg = decode_nas_5gs_message(&bytes).unwrap();

// Wireshark-style display
println!("{msg}");
// => 5GMM RegistrationRequest (Initial) SUCI: 208-93-0000000000 ...

// Structural validation helpers for common TS 24.501 rules
assert!(msg.validate().is_empty());

// Round-trip encode
assert_eq!(bytes, encode_nas_5gs_message(&msg).unwrap());

Typed IE accessors

use oxirush_nas::{decode_nas_5gs_message, Nas5gsMessage, Nas5gmmMessage};
use oxirush_nas::ie::*;

let bytes = hex::decode(
    "7e004179000d0199f9070000000000000010022e08a020000000000000"
).unwrap();
let msg = decode_nas_5gs_message(&bytes).unwrap();
if let Nas5gsMessage::Gmm(_, Nas5gmmMessage::RegistrationRequest(reg)) = &msg {
    // Registration type as a typed enum
    assert_eq!(reg.fgs_registration_type.registration_type(),
               Some(RegistrationType::InitialRegistration));

    // Mobile identity variant
    assert_eq!(reg.fgs_mobile_identity.identity_type(),
               Some(MobileIdentityType::Suci));

    // Extract PLMN
    if let Some(plmn) = reg.fgs_mobile_identity.plmn() {
        println!("MCC={}, MNC={}", plmn.mcc_string(), plmn.mnc_string());
    }
}

Build a NAS message from scratch

use oxirush_nas::ie::GmmCause;
use oxirush_nas::messages::NasRegistrationReject;
use oxirush_nas::*;

// Build a RegistrationReject with cause code
let reject = NasRegistrationReject::new(
    NasFGmmCause::from_cause(GmmCause::IllegalUe),
);
let msg = Nas5gsMessage::new_5gmm(Nas5gmmMessage::RegistrationReject(reject));
let wire_bytes = encode_nas_5gs_message(&msg).unwrap();

NAS security envelope (requires security feature)

use oxirush_nas::{
    Direction, Nas5gmmMessage, Nas5gsMessage, Nas5gsSecurityHeaderType, NasFGmmCause,
    NasSecurityContext,
};
use oxirush_nas::ie::{IntegrityAlgorithm, CipheringAlgorithm};
use oxirush_nas::ie::GmmCause;
use oxirush_nas::messages::NasRegistrationReject;

let knas_int = [0u8; 16];
let knas_enc = [0u8; 16];
let msg = Nas5gsMessage::new_5gmm(Nas5gmmMessage::RegistrationReject(
    NasRegistrationReject::new(NasFGmmCause::from_cause(GmmCause::IllegalUe)),
));

let mut ctx = NasSecurityContext::new(
    knas_int, knas_enc,
    IntegrityAlgorithm::NIA2,
    CipheringAlgorithm::NEA2,
);

// Protect outbound (integrity + ciphering)
let protected = ctx.protect(
    &msg,
    Nas5gsSecurityHeaderType::IntegrityProtectedAndCiphered,
    Direction::Downlink,
).unwrap();

// Unprotect inbound (MAC verify + decipher + decode)
let (decoded, sht) = ctx.unprotect(&protected, Direction::Downlink).unwrap();
assert_eq!(sht, Nas5gsSecurityHeaderType::IntegrityProtectedAndCiphered);
assert!(matches!(
    decoded,
    Nas5gsMessage::Gmm(_, Nas5gmmMessage::RegistrationReject(_))
));

Architecture

                        +-----------+
                        |  lib.rs   |   re-exports everything
                        +-----+-----+
                              |
          +--------+----------+----------+---------+
          |        |          |          |         |
      types.rs  messages.rs  ie.rs  display.rs  validate.rs
      (Layer 1)  (Layer 2)  (Layer 3)
Module Description
[types] Wire-level codec — Encode/Decode traits, 100+ IE structs (TLV/TV/V/LV formats)
[messages] NAS message structs with IEI dispatch, encode_nas_5gs_message()/decode_nas_5gs_message()
[ie] Typed IE accessors — zero-cost enums, parsers, and builder helpers
[display] fmt::Display implementations for Wireshark-style message formatting
[validate] Structural validation per TS 24.501 (errors + warnings)
[security] NAS security envelope — protect/unprotect with NAS COUNT tracking (feature-gated)

Three-layer design

  • Layer 1 (types) — raw binary IE structs generated by macros. Each struct has a pub value field and implements Encode/Decode for the wire format (V, LV, LV-E, TV, TLV, TLV-E per TS 24.007 §11.2).
  • Layer 2 (messages) — NAS message structs generated by the nas_message! macro. Mandatory fields in the constructor, optional fields via set_*() builder methods. Decode dispatches on IEI bytes.
  • Layer 3 (ie) — typed zero-cost wrappers. Enums like RegistrationType, GmmCause, CipheringAlgorithm replace manual bit manipulation. from_*() constructors and accessor methods on the raw IE structs.

3GPP references

  • TS 24.501 — 5G NAS protocol (message definitions, IE formats, procedures)
  • TS 24.007 — IE encoding formats (V, LV, TLV, etc.)
  • TS 33.501 — 5G security architecture (NAS security, key derivation, algorithms)

Documentation

Full API reference: https://docs.rs/oxirush-nas

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Sign off your commits (git commit -s)
  4. Open a Pull Request

Developer Certificate of Origin (DCO)

By contributing to this project, you agree to the Developer Certificate of Origin (DCO). This means that you have the right to submit your contributions and you agree to license them according to the project's license.

All commits should be signed-off with git commit -s to indicate your agreement to the DCO.

License

Copyright 2025-2026 Valentin D'Emmanuele

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Acknowledgements

OxiRush is inspired by PacketRusher, reimplemented in Rust for improved performance and safety.

About

A fast, memory-safe library for encoding and decoding 5G NAS (Non-Access Stratum) messages in Rust, per 3GPP TS 24.501.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages