Files
gps-denied-onboard/_docs/01_solution/security_analysis.md
T

22 KiB
Raw Blame History

Security Analysis

Operational Context

This system runs on a UAV operating in a conflict zone (eastern Ukraine). The UAV could be shot down and physically captured. GPS denial/spoofing is the premise. The Jetson Orin Nano stores satellite imagery, flight plans, and captured photos. Security must assume the worst case: physical access by an adversary.

Threat Model

Asset Inventory

Asset Sensitivity Location Notes
Captured camera imagery HIGH Jetson storage Reconnaissance data — reveals what was surveyed
Satellite tile cache MEDIUM Jetson storage Reveals operational area and areas of interest
Flight plan / route HIGH Jetson memory + storage Reveals mission objectives and launch/landing sites
Computed GPS positions HIGH Jetson memory, SSE stream Real-time position data of UAV and surveyed targets
Google Maps API key MEDIUM Offline prep machine only Used pre-flight, NOT stored on Jetson
TensorRT model weights LOW Jetson storage LiteSAM/XFeat — publicly available models
cuVSLAM binary LOW Jetson storage NVIDIA proprietary but freely distributed
IMU calibration data LOW Jetson storage Device-specific calibration
System configuration MEDIUM Jetson storage API endpoints, tile paths, fusion parameters

Threat Actors

Actor Capability Motivation Likelihood
Adversary military (physical capture) Full physical access after UAV loss Extract intelligence: imagery, flight plans, operational area HIGH
Electronic warfare unit GPS spoofing/jamming, RF jamming Disrupt navigation, force UAV off course HIGH (GPS denial is the premise)
Network attacker (ground station link) Intercept/inject on UAV-to-ground comms Steal position data, inject false commands MEDIUM
Insider / rogue operator Authorized access to system Data exfiltration, mission sabotage LOW
Supply chain attacker Tampered satellite tiles or model weights Feed corrupted reference data → position errors LOW

Attack Vectors

Vector Target Asset Actor Impact Likelihood
Physical extraction of storage All stored data Adversary (capture) Full intelligence compromise HIGH
GPS spoofing Position estimate EW unit Already mitigated — system is GPS-denied by design N/A
IMU acoustic injection IMU data → ESKF EW unit Drift injection, subtle position errors LOW
Camera blinding/spoofing VO + satellite matching EW unit VO failure, incorrect satellite matches LOW
Adversarial ground patterns Satellite matching Adversary Physical patches on ground fool feature matching VERY LOW
SSE stream interception Position data Network attacker Real-time position leak MEDIUM
API command injection Flight session control Network attacker Start/stop/manipulate sessions MEDIUM
Corrupted satellite tiles Satellite matching Supply chain Systematic position errors LOW
Model weight tampering Matching accuracy Supply chain Degraded matching → higher drift LOW

Per-Component Security Requirements and Controls

1. Data at Rest (Jetson Storage)

Requirement Risk Level Control Implementation
Protect captured imagery from extraction after capture CRITICAL Full-disk encryption (LUKS) JetPack LUKS support with ENC_ROOTFS=1. Use OP-TEE Trusted Application for key management. Modify luks-srv to NOT auto-decrypt — require hardware token or secure erase trigger
Protect satellite tiles and flight plans HIGH Same LUKS encryption Included in full-disk encryption scope
Enable rapid secure erase on capture/crash CRITICAL Tamper-triggered wipe Hardware dead-man switch: if UAV telemetry lost for N seconds OR accelerometer detects crash impact → trigger cryptsetup luksErase on all LUKS volumes. Destroys key material in <1 second — data becomes unrecoverable
Prevent cold-boot key extraction HIGH Minimize key residency in RAM ESKF state and position history cleared from memory when session ends. Avoid writing position logs to disk unless encrypted

2. Secure Boot

Requirement Risk Level Control Implementation
Prevent unauthorized code execution HIGH NVIDIA Secure Boot with PKC fuse burning Burn SecurityMode fuse (odm_production_mode=0x1) on production Jetsons. Sign all boot images with PKC key pair. Generate keys via HSM
Prevent firmware rollback MEDIUM Ratchet fuses Configure anti-rollback fuses in fuse configuration XML
Debug port lockdown HIGH Disable JTAG/debug after production Burn debug-disable fuses. Irreversible — production units only

3. API & Communication (FastAPI + SSE)

Requirement Risk Level Control Implementation
Authenticate API clients HIGH JWT bearer token Pre-shared secret between ground station and Jetson. Generate JWT at session start. Short expiry (flight duration). HTTPBearer scheme in FastAPI
Encrypt SSE stream HIGH TLS 1.3 Uvicorn with TLS certificate (self-signed for field use, pre-installed on ground station). All SSE position data encrypted in transit
Prevent unauthorized session control HIGH JWT + endpoint authorization Session start/stop/anchor endpoints require valid JWT. Rate-limit via slowapi
Prevent replay attacks MEDIUM JWT exp + jti claims Token expiry per-flight. Unique token ID (jti) tracked to prevent reuse
Limit API surface MEDIUM Minimal endpoint exposure Only expose: POST /sessions, GET /sessions/{id}/stream (SSE), POST /sessions/{id}/anchor, DELETE /sessions/{id}. No admin/debug endpoints in production

4. Visual Odometry (cuVSLAM)

Requirement Risk Level Control Implementation
Detect camera feed tampering LOW Sanity checks on frame consistency If consecutive frames show implausible motion (>500m displacement at 3fps), flag as suspicious. ESKF covariance spike triggers satellite re-localization
Protect against VO poisoning LOW Cross-validate VO with IMU ESKF fusion inherently cross-validates: IMU and VO disagreement raises covariance, triggers satellite matching. No single sensor can silently corrupt position

5. Satellite Image Matching

Requirement Risk Level Control Implementation
Verify tile integrity MEDIUM SHA-256 checksums per tile During offline preprocessing: compute SHA-256 for each tile pair. Store checksums in signed manifest. At runtime: verify checksum on tile load
Prevent adversarial tile injection MEDIUM Signed tile manifest Offline tool signs manifest with private key. Jetson verifies signature with embedded public key before accepting tile set
Detect satellite match outliers MEDIUM RANSAC inlier ratio threshold If RANSAC inlier ratio <30%, reject match as unreliable. ESKF treats as no-measurement rather than bad measurement
Protect against ground-based adversarial patterns VERY LOW Multi-tile consensus Match against multiple overlapping tiles. Physical adversarial patches affect local area — consensus voting across tiles detects anomalies

6. Sensor Fusion (ESKF)

Requirement Risk Level Control Implementation
Prevent single-sensor corruption of position HIGH Adaptive noise + outlier rejection Mahalanobis distance test on each measurement. Reject updates >5σ from predicted state. No single measurement can cause >50m position jump
Detect systematic drift MEDIUM Satellite matching rate monitoring If satellite matches consistently disagree with VO by >100m, flag integrity warning to operator
Protect fusion state LOW In-memory only, no persistence ESKF state never written to disk. Lost on power-off — no forensic recovery

7. Offline Preprocessing (Developer Machine)

Requirement Risk Level Control Implementation
Protect Google Maps API key MEDIUM Environment variable, never in code .env file excluded from version control. API key used only on developer machine, never deployed to Jetson
Validate downloaded tiles LOW Source verification Download only from Google Maps Tile API via HTTPS. Verify TLS certificate chain
Secure tile transfer to Jetson MEDIUM Signed + encrypted transfer Transfer tile set + signed manifest via encrypted channel (SCP/SFTP). Verify manifest signature on Jetson before accepting

Security Controls Summary

Authentication & Authorization

  • Mechanism: Pre-shared JWT secret between ground station and Jetson
  • Scope: All API endpoints require valid JWT bearer token
  • Session model: One JWT per flight session, expires at session end
  • No user management on Jetson — single-operator system, auth is device-to-device

Data Protection

State Protection Tool
At rest (Jetson storage) LUKS full-disk encryption JetPack LUKS + OP-TEE
In transit (SSE stream) TLS 1.3 Uvicorn SSL
In memory (ESKF state) No persistence, cleared on session end Application logic
On capture (emergency) Tamper-triggered LUKS key erase Hardware dead-man switch + cryptsetup luksErase

Secure Communication

  • Ground station ↔ Jetson: TLS 1.3 (self-signed cert, pre-installed)
  • No internet connectivity during flight — no external attack surface
  • RF link security is out of scope (handled by UAV communication system)

Logging & Monitoring

What Where Retention
API access logs (request count, errors) In-memory ring buffer Current session only, not persisted
Security events (auth failures, integrity warnings) In-memory + SSE alert to operator Current session only
Position history In-memory for refinement, SSE to ground station NOT persisted on Jetson after session end
Crash/tamper events Trigger secure erase, no logging N/A — priority is data destruction

Design principle: Minimize data persistence on Jetson. The ground station is the system of record. Jetson stores only what's needed for the current flight — satellite tiles (encrypted at rest) and transient processing state (memory only).

Protected Code Execution (OP-TEE / ARM TrustZone)

Overview

The Jetson Orin Nano Super supports hardware-enforced protected code execution via ARM TrustZone and OP-TEE v4.2.0 (included in Jetson Linux 36.3+). TrustZone partitions the processor into two isolated worlds:

  • Secure World (TEE): Runs at ARMv8 secure EL-1 (OS) and EL-0 (apps). Code here cannot be read or tampered with from the normal world. OP-TEE is the secure OS.
  • Normal World: Standard Linux (JetPack). Our Python application, cuVSLAM, FastAPI all run here.

Trusted Applications (TAs) execute inside the secure world and are invoked by Client Applications (CAs) in the normal world via the GlobalPlatform TEE Client API.

Architecture on Jetson Orin Nano

┌─────────────────────────────────────────────────┐
│          NORMAL WORLD (Linux / JetPack)          │
│                                                   │
│  Client Application (CA)                          │
│  ↕ libteec.so (TEE Client API)                   │
│  ↕ OP-TEE Linux Kernel Driver                    │
│  ↕ ARM Trusted Firmware (ATF) / Monitor          │
├─────────────────────────────────────────────────┤
│          SECURE WORLD (OP-TEE v4.2.0)            │
│                                                   │
│  OP-TEE OS (ARMv8 S-EL1)                        │
│  ├── jetson-user-key PTA (key management)        │
│  ├── luks TA (disk encryption passphrase)        │
│  ├── hwkey-agent TA (encrypt/decrypt data)       │
│  ├── PKCS #11 TA (crypto token interface)        │
│  └── Custom TAs (our application-specific TAs)   │
│                                                   │
│  Hardware: Security Engine (SE), HW RNG, Fuses   │
│  TZ-DRAM: Dedicated memory carveout              │
└─────────────────────────────────────────────────┘

Key Hierarchy (Hardware-Backed)

The Jetson Orin Nano provides a hardware-rooted key hierarchy via the Security Engine (SE) and Encrypted Key Blob (EKB):

OEM_K1 fuse (256-bit AES, burned into hardware, cannot be read by software)
    │
    ├── EKB_RK (EKB Root Key, derived via AES-128-ECB from OEM_K1 + FV)
    │   ├── EKB_EK (encryption key for EKB content)
    │   └── EKB_AK (authentication key for EKB content)
    │
    ├── HUK (Hardware Unique Key, per-device, derived via NIST-SP-800-108)
    │   └── SSK (Secure Storage Key, per-device, generated at OP-TEE boot)
    │       ├── TSK (TA Storage Key, per-TA)
    │       └── FEK (File Encryption Key, per-file)
    │
    └── LUKS passphrase (derived from disk encryption key stored in EKB)

Fuse keys are loaded into SE keyslots during early boot (before OP-TEE starts). Software cannot read keys from keyslots — only derive new keys through the SE. After use, keyslots should be cleared via tegra_se_clear_aes_keyslots().

What to Run in the Secure World (Our Use Cases)

Use Case TA Type Purpose
LUKS disk encryption Built-in luks TA Generate one-time passphrase at boot to unlock encrypted rootfs. Keys never leave secure world
Tile manifest verification Custom User TA Verify SHA-256 signatures of satellite tile manifests. Signing key stored in EKB, accessible only in secure world
JWT secret storage Custom User TA or hwkey-agent TA Store JWT signing secret in EKB. Sign/verify JWTs inside secure world — secret never exposed to Linux
Secure erase trigger Custom User TA Receive tamper signal → invoke cryptsetup luksErase via CA. Key erase logic runs in secure world to prevent normal-world interference
TLS private key protection PKCS #11 TA Store TLS private key in OP-TEE secure storage. Uvicorn uses PKCS #11 interface to perform TLS handshake without key leaving secure world

How to Enable Protected Code Execution

Step 1: Burn OEM_K1 Fuse (One-Time, Irreversible)

# Generate 256-bit OEM_K1 key (use HSM in production)
openssl rand -hex 32 > oem_k1_key.txt

# Create fuse configuration XML with OEM_K1
# Burn fuse via odmfuse.sh (IRREVERSIBLE)
sudo ./odmfuse.sh -i <fuse_config.xml> <board_name>

After burning SecurityMode fuse (odm_production_mode=0x1), all further fuse writes are blocked. OEM_K1 becomes permanently embedded in hardware.

Step 2: Generate and Flash EKB

# Generate user keys (disk encryption key, JWT secret, tile signing key)
openssl rand -hex 16 > disk_enc_key.txt
openssl rand -hex 32 > jwt_secret.txt
openssl rand -hex 32 > tile_signing_key.txt

# Generate EKB binary
python3 gen_ekb.py -chip t234 \
  -oem_k1_key oem_k1_key.txt \
  -in_sym_key uefi_enc_key.txt \
  -in_sym_key2 disk_enc_key.txt \
  -in_auth_key uefi_var_auth_key.txt \
  -out eks_t234.img

# Flash EKB to EKS partition
# (part of the normal flash process with secure boot enabled)

Step 3: Enable LUKS Disk Encryption

# During flash, set ENC_ROOTFS=1 to encrypt rootfs
export ENC_ROOTFS=1
sudo ./flash.sh <board_name> <storage_device>

The luks TA in OP-TEE derives a passphrase from the disk encryption key in EKB at boot. The passphrase is generated inside the secure world and passed to cryptsetup — it never exists in persistent storage.

Step 4: Develop Custom Trusted Applications

Cross-compile TAs for aarch64 using the Jetson OP-TEE source package:

# Build custom TA (e.g., tile manifest verifier)
make -C <ta_source_dir> \
  CROSS_COMPILE="<toolchain>/bin/aarch64-buildroot-linux-gnu-" \
  TA_DEV_KIT_DIR="<optee_src>/optee/build/t234/export-ta_arm64/" \
  OPTEE_CLIENT_EXPORT="<optee_src>/optee/install/t234/usr" \
  TEEC_EXPORT="<optee_src>/optee/install/t234/usr" \
  -j"$(nproc)"

# Deploy: copy TA to /lib/optee_armtz/ on Jetson
# Deploy: copy CA to /usr/sbin/ on Jetson

TAs conform to the GlobalPlatform TEE Internal Core API. Use the hello_world example from optee_examples as a starting template.

Step 5: Enable Secure Boot

# Generate PKC key pair (use HSM for production)
openssl genrsa -out pkc_key.pem 3072

# Sign and flash secured images
sudo ./flash.sh --sign pkc_key.pem <board_name> <storage_device>

# After verification, burn SecurityMode fuse (IRREVERSIBLE)

Available Crypto Services in Secure World

Service Provider Notes
AES-128/256 encryption/decryption SE hardware Via keyslot-derived keys, never leaves SE
Key derivation (NIST-SP-800-108) jetson-user-key PTA Derive purpose-specific keys from EKB keys
Hardware RNG SE hardware TEE_GenerateRandom() or PTA command
PKCS #11 crypto tokens PKCS #11 TA Standard crypto interface for TLS, signing
SHA-256, HMAC MbedTLS (bundled in optee_os) Software crypto in secure world
RSA/ECC signing GlobalPlatform TEE Crypto API For manifest signature verification

Limitations on Orin Nano

Limitation Impact Workaround
No RPMB support (only AGX Orin has RPMB) Secure storage uses REE FS instead of replay-protected memory Acceptable — LUKS encryption protects data at rest. REE FS secure storage is encrypted by SSK
EKB can only be updated via OTA, not at runtime Cannot rotate keys in flight Pre-provision per-device unique keys at manufacturing time
OP-TEE hello_world reported issues on some Orin Nano units Some users report initialization failures Use JetPack 6.2.2+ which includes fixes. Test thoroughly on target hardware
TZ-DRAM is a fixed carveout Limits secure world memory Keep TAs lightweight — only crypto operations and key management, not data processing

Security Hardening Checklist

  • Burn OEM_K1 fuse with unique per-device key (via HSM)
  • Generate and flash EKB with disk encryption key, JWT secret, tile signing key
  • Enable LUKS full-disk encryption (ENC_ROOTFS=1)
  • Modify luks-srv to NOT auto-decrypt (require explicit trigger or dead-man switch)
  • Burn SecurityMode fuse (odm_production_mode=0x1) — enables secure boot chain
  • Burn debug-disable fuses — disables JTAG
  • Configure anti-rollback ratchet fuses
  • Clear SE keyslots after EKB extraction via tegra_se_clear_aes_keyslots()
  • Deploy custom TAs for JWT signing and tile manifest verification
  • Use PKCS #11 for TLS private key protection
  • Test secure erase trigger end-to-end
  • Run xtest (OP-TEE test suite) on production Jetson to validate TEE

Key Security Risks

Risk Severity Mitigation Status
Physical capture → data extraction CRITICAL Mitigated by LUKS + secure erase. Residual risk: attacker extracts RAM before erase triggers
No auto-decrypt bypass for LUKS HIGH Requires custom luks-srv modification — development effort needed
Self-signed TLS certificates MEDIUM Acceptable for field deployment. Certificate pinning on ground station prevents MITM
cuVSLAM is closed-source LOW Cannot audit for vulnerabilities. Mitigated by running in sandboxed environment, input validation on camera frames
Dead-man switch reliability HIGH Hardware integration required. False triggers (temporary signal loss) must NOT cause premature erase. Needs careful threshold tuning

References