Views: 1,611,768 | Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search | 12-03-24 05:30 PM |
Guest: |
0 users reading Accessing the NAND (via fopen / opendir) | 5 bots |
Main - Homebrew discussion - Accessing the NAND (via fopen / opendir) | Hide post layouts | New reply |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 17/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Posted by profi200 I just came here to ask exactly this, and there already is the answer. Thanks a million times! I'll try it and will let you know if I figured it out. |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 18/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Posted by profi200 Okay, I guess I need some more help. For the CTR partitions, calculating the SHA256 hash and using the first 16 byte of that as CTR works, and is by far the superior method. However, I seem to can't get a usable result with the SHA1 hash for the TWL partitions. What I did to find out about the correct endianness is: * Generate a TWLN xorpad (with the SHA1 CTR, otherwise same as I would generate a CTRNAND xorpad. * Dump the encrypted TWLN partition. * Reorder the encrypted TWLN partition to change endianness - that means reversing the order of bytes on blocks of 2, 4, 8 or 16 bytes. Then use the xorpad, hoping to get a result with some recognizable data. So far, I had no success. Is anything wrong with my method? Maybe I even need new AES routines to be able to decrypt that? The new SHA1 hash algorithm is tested (it's from the same source as my SHA256 algorithms), and of course I'm always using a fresh copy of the encrypted TWLN before reordering. I'm using the offset from the start of the NAND (for the ctr_add function), same as I do for the CTRNAND. |
profi200 |
| ||
Member Who knows? Level: 19 Posts: 18/70 EXP: 34568 Next: 1209 Since: 05-21-15 From: Germany Last post: 3005 days ago Last view: 2873 days ago |
- Keyslot is 3 for both twln and p.
- CTR is the first 16 bytes of the SHA1 hash. Needs to be set with reversed word order and little endian. - The en-/decryption params are little endian and reversed word order too. |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 19/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Posted by profi200 Okay, now I'm pretty sure I got everything correctly. I used http://3dbrew.org/wiki/AES_Registers and doublechecked that with my crypto library "original version by megazig" (or here) . Keyslot is 0x3, too. Now, to even enable little endian / reversed order decryption, I had to change the code in the crypto library, from: void _decrypt(uint32_t value, void* inbuf, void* outbuf, size_t blocks)
to... (changes not on Github) (value has the bit set for AES CTR)
{ *REG_AESCNT = 0; *REG_AESBLKCNT = blocks << 16; *REG_AESCNT = value | AES_CNT_START | AES_CNT_INPUT_ORDER | AES_CNT_OUTPUT_ORDER | AES_CNT_INPUT_ENDIAN | AES_CNT_OUTPUT_ENDIAN | AES_CNT_FLUSH_READ | AES_CNT_FLUSH_WRITE; aes_fifos(inbuf, outbuf, blocks); } void _decrypt(uint32_t value, void* inbuf, void* outbuf, size_t blocks)
(I know, that breaks everything else, but it is just for testing)
{ *REG_AESCNT = 0; *REG_AESBLKCNT = blocks << 16; *REG_AESCNT = value | AES_CNT_START | AES_CNT_OUTPUT_ORDER | AES_CNT_OUTPUT_ENDIAN | AES_CNT_FLUSH_READ | AES_CNT_FLUSH_WRITE; aes_fifos(inbuf, outbuf, blocks); } The setctr function handles everything correctly (if I give the correct order / endian modes). No change needed: void set_ctr(int mode, void* iv)
{ uint32_t * _iv = (uint32_t*)iv; *REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN|AES_CNT_INPUT_ORDER)) | (mode << 23); if (mode & AES_NORMAL_INPUT) { *(REG_AESCTR + 0) = _iv[3]; *(REG_AESCTR + 1) = _iv[2]; *(REG_AESCTR + 2) = _iv[1]; *(REG_AESCTR + 3) = _iv[0]; } else { *(REG_AESCTR + 0) = _iv[0]; *(REG_AESCTR + 1) = _iv[1]; *(REG_AESCTR + 2) = _iv[2]; *(REG_AESCTR + 3) = _iv[3]; } } Now, the crypto.h / crypto.c library looks like it has been tampered with (or edited by too many people), even before I made my additional change. I guess it should still be usable. As I said, decrypting the CTRNAND works with the same routines. For TWL, I calculated the CTR via SHA-1 (only the first 16 bytes), changed the keyslot, changed the set mode to reversed and little endian (same for decryption mode, see above). Other than that, everything stays the same. I also tried incrementing the counter in a different way once, but that doesn't help either. Usable output should be pretty easy to recognize as I have the offsets for the start of the FAT16 / FAT12 images. In other words, the first 16 bytes are enough to decide if everything is okay (I looked further, of course). So, why I'm writing all this? It still doesn't give usable output :|. Even with my method from before (this time generating xorpads correctly), I do not get anything useful. Do you have any additional ideas? Maybe there is some interim result that I could check somewhere, so that I can be sure my implementation is correct at least to that point? And did someone already manage to decrypt the TWLNAND without resorting to archives? And maybe there's some place on the web where there's mroe information about TWL decryption (didn't find anything usable on 3Dbrew). EDIT: Maybe there are prerequisites to being able to decrypt the TWL? http://3dbrew.org/wiki/AES_Registers#Keyslots I stumbled over the 'NATIVE_FIRM hard-boot' in that table, and 'probably unset' in table right above. If that is useful information, I'm using Brahma as a loader. EDIT2: Okay, I dug a little deeper and found this: http://dsibrew.org/wiki/Bootloader
Could that mean I need to retrieve and set the KeyY? (that wasn't needed for CTRNAND decyption) Sorry for the long post, too. |
profi200 |
| ||
Member Who knows? Level: 19 Posts: 19/70 EXP: 34568 Next: 1209 Since: 05-21-15 From: Germany Last post: 3005 days ago Last view: 2873 days ago |
No.
https://gist.github.com/profi200/469f9fac6a394d23e8e1 Very old code but it worked. I just slapped some comments in it. The way i calculated the CTR with the offset is really shit and could overflow. For me it worked. |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 20/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Posted by profi200 Alright, thanks a ton, again. From the first look I think my error was that I did not manually change the endianness ("EndianSwap") of the CTR (I did, in some of my experiments, but in those I did other things wrong). I'll have to thoroughly look it through. BTW: I already made a local copy, just in case that gist was only temporary. Update: I got it. What I needed to do was to manually reverse the word order and endian (in fact, reversing it byte by byte) for the SHA-1 hash before doing anything else. Then increment it and start decoding. If I do it any other way (ie. use the AES parameters to handle endian in setctr), the add ctr function doesn't work in the correct way. So, what I got wrong was the incrementation - I thought that should work the same, regardless of endian / order. I also had to change word order / endian (via the respective parameters, not for the data) for the actual decryption, but that I had before. Thank you again! The set AES bits 12 and 13, btw, don't seem to do anything, and they are undocumented on 3dbrew. |
profi200 |
| ||
Member Who knows? Level: 19 Posts: 20/70 EXP: 34568 Next: 1209 Since: 05-21-15 From: Germany Last post: 3005 days ago Last view: 2873 days ago |
I don't know what these bits do. Apparently it is from reverse engineering Nintendos code. I just used the knowledge and some of Normmats code as base. |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 21/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Okay, one last question about that code: Does it decrypt the AGBSAVE correctly? It's difficult to test if it does. A comment in the rxTools source code says it (decrypting AGBSAVE) doesn't work that way. Personally, I'd have suspected that it requires the same method as the TWL partitions, not the same as the CTR partitions. |
profi200 |
| ||
Member Who knows? Level: 19 Posts: 21/70 EXP: 34568 Next: 1209 Since: 05-21-15 From: Germany Last post: 3005 days ago Last view: 2873 days ago |
It's handled like a CTR partition and it can only be properly decrypted if it exist logically. The AGB_FIRM savegame area is just blank if no GBA game ever was running.
The code i linked works for all partitions. The AGB_FIRM savegame should contain the latest savegame(s) of the games you played in plaintext (after decrypting). |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 22/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
I never ran a GBA game, so it's all zeroes in there, and if I try to decrypt I essentially get a xorpad . Anyways, testers say it's fine, too! |
d0k3 |
| ||
Member Normal user Level: 20 Posts: 23/75 EXP: 38262 Next: 4177 Since: 06-04-15 Last post: 3263 days ago Last view: 3010 days ago |
Alright, back again. I've got some trouble accessing the NAND CID via the GW browser method. In short, I can not access that memory (0x01FFCD80) without the 3DS freezing. Works fine on Brahma though.
Is there any alternative method of retrieving the NAND CID that could work? More info (but maybe nothing too useful) here: https://github.com/d0k3/Decrypt9/issues/14 And more info... I already searched for information, and there seems to be a GetNandCid() function somewhere: http://3dbrew.org/wiki/FSPXI:GetNandCid http://3dbrew.org/wiki/Filesystem_services ... but how to access this? No idea. |
Main - Homebrew discussion - Accessing the NAND (via fopen / opendir) | Hide post layouts | New reply |
Page rendered in 0.027 seconds. (2048KB of memory used) MySQL - queries: 28, rows: 85/85, time: 0.008 seconds. Acmlmboard 2.064 (2018-07-20) © 2005-2008 Acmlm, Xkeeper, blackhole89 et al. |