Milestone 1: ingest (containers, keys, NCA, ExeFS, RomFS)¶
Objective¶
Open a user-supplied encrypted game (XCI/NSP) with the user's prod.keys and expose the Program NCA's ExeFS
(main, rtld, sdk, subsdk*, main.npdm) and RomFS file table. Foundation for analysis/rewrite (milestone 2).
Files¶
Cargo.toml,.gitignore(blocks keys/games/NCAs from being committed)crates/napple-core/src/domain/{error,keys}.rs: errors (never contain key material);KeySet(zeroized on drop, redacted Debug, 1 MiB cap, derives missingheader_key/titlekek_XX/key_area_key_*_XXfrom source keys)crates/napple-core/src/infrastructure/{io,pfs,xci,ticket,nca,romfs}.rs: adapterscrates/napple-core/src/application/ingest.rs:ingestuse casecrates/napple-cli/src/main.rs:napple ingest <game> -k <prod.keys>crates/napple-core/tests/ingest.rs: synthetic-fixture tests
Logic¶
PFS0/HFS0 parse -> NCA3 header (AES-XTS, Nintendo big-endian sector tweak) -> key area (ECB) or ticket titlekey (titlekek) -> AES-CTR section view with random access (counter = section ctr || offset>>4) -> PFS0 master-hash check (doubles as key-correctness check) -> ExeFS read; IVFC data level -> RomFS dir/file tables.
Decisions¶
- Rust (safety on hostile input, speed, static binary, iOS-ready). Readers are
Sourcetrait objects with range-checked reads; nounsafe. - Hostile-input limits: file-count/strtab caps, name validation (no
/,\, NUL,..), RomFS depth and entry budget. - Update-only/unsupported NCAs are skipped, missing keys abort with the key's name.
Risks / pending¶
- Validated against one retail NSP (Link's Awakening, keys from firmware 22.1.0): PFS0 master hash verified, 6 ExeFS files and 3836 RomFS entries listed, ~0.1 s. Still unvalidated: XCI, rights-id-less NCAs, other key generations, NSO contents (not yet parsed). The first real run exposed a ticket body-offset bug (signature padding 0x13C, not 0x140) that the synthetic fixtures had mirrored.
- Synthetic fixtures only prove consistency. Fixtures are built by the same author as the parser, so they prove consistency, not compatibility. Needs a real game + firmware keys (owner will provide). Likeliest fault points: CTR counter layout, key-generation index, derived-key formulas, ticket offsets.
- Not implemented: NSZ, BKTR/updates, NCA0/2, XTS sections, personalized tickets, IVFC full verification.
- Whole-file ExeFS reads are in memory (small); RomFS is streamed.
Tests¶
cargo test: 11 passing (key parsing/redaction; NSP key-area, NSP ticket, XCI; wrong header/area key; tampered
hash; missing key; path traversal; truncated/garbage inputs). Recommended next: run against 1 retail NSP and 1 XCI.