Skip to content

3DS ROMs (NCSD) converted from CIA with seed crypto are only partially decrypted #7

@davidmorom

Description

@davidmorom

Thanks to @DocJr90 on another project's issue, I found a bug that affects 3DS (NCSD) ROMs converted from CIA retaining the seed crypto. On the parse_ncsd function the titleid byte array is reversed inside the for block that loops trough every NCCH, so, for NCCHs with even index, the seed is found and the file is correctly decrypted, but for NCCHs with odd index the titleid is reversed, the seed is not found and the file is incorrectly decrypted.

The byte reversal should be done only once, outside the loop. The following patch fixes the issue:

diff -u a/main.rs b/main.rs
--- a/main.rs	2025-03-31 10:29:53.524481000 +0200
+++ b/main.rs	2025-03-31 09:44:59.034743000 +0200
@@ -303,11 +303,11 @@
     let mut tmp: [u8; 512] = [0u8; 512];
     cia.read(&mut tmp);
     let mut header: NcsdHdr = unsafe { std::mem::transmute(tmp) };
+    header.titleid.reverse();
     for idx in 0..header.offset_sizetable.len() {
         if header.offset_sizetable[idx].offset != 0 {
             cia.cidx = idx as u16;
             cia.content_id = idx as u32;
-            header.titleid.reverse();
             parse_ncch(cia, (header.offset_sizetable[idx].offset * MEDIA_UNIT_SIZE).clone().into(), header.titleid);
         }
     }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions