Kodewerx
https://www.kodewerx.org/forum/

DS Game Card Encryption
https://www.kodewerx.org/forum/viewtopic.php?f=11&t=3971
Page 2 of 2

Author:  spinal [ Sun Oct 28, 2007 1:53 pm ]
Post subject:  Re: DS Game Card Encryption

It would go great in my menu (as an external app), being able to reset the card for no other reason than to have something that does that.

Author:  dshttpbackup [ Mon Feb 16, 2009 9:04 pm ]
Post subject:  Patches to Parasyte's library for loading an NDS ROM

thank you Parasyte for such a kickass library! It works really well!

i made two minor patches to get it all to work with libnds 1.3.1.

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
--- cardcrypt.c.old Mon Feb 16 22:51:50 2009
+++ cardcrypt.c Mon Feb 16 19:34:23 2009
@@ -19,13 +19,37 @@
*/


+/**
+ *dshttpbackup added this comment blcok.
+ *
+ * SYNOPSIS:
+ *
+ * quoting Parasyte on
+ * <a href="http://www.kodewerx.org/forum/viewtopic.php?f=11&t=3971"this site</a>:
+ *
+// Define memory locations for CardInit() outputs
+#define CARDID ((u32*)0x027FF800)
+#define SECURE_CARDID ((u32*)0x027FF804)
+#define INGAME_CARDID ((u32*)0x027FFC00)
+#define HEADER ((NDS_HEADER*)0x027FFE00)
+
+CardInit(HEADER, CARDID, SECURE_CARDID, INGAME_CARDID); // Initialize the cardcrypt lib, returns 0 on success, else an error code.
+
+Then simply call CardRead() to read anywhere from the card. The only limitations are that the source address must be aligned to 512 bytes, and the length must be a multiple of 512 bytes.
+
+For bonus points, you can also encrypt secure area data using CardEncryptARM9Secure().
+ */
+
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/time.h>
#include "blowfish.h"
#include "cardcrypt.h"
#include "nds/arm9/console.h"

+#include "parasyte-card.h"

u8 device_tab[8] = { // 0x0000002A
0xE8, 0x4D, 0x5A, 0xB1, 0x17, 0x8F, 0x99, 0xD5
@@ -793,8 +817,28 @@
CardSecureRead_bnk = 0;
CardTransferHandler_mode = 0;

+
+
+ /////////////////////////////////////////
+ //this section modified by dshttpbackup//
+
// Copy RTC data
- memcpy(rtc_time, IPC->time.curtime, 8);
+
+ //old: memcpy(rtc_time, IPC->time.curtime, 8);
+
+ struct timeval tmp;
+ gettimeofday(&tmp, NULL);
+
+ // copy tmp.tv_sec to rtc_time's first half
+ rtc_time[0] = (u32) tmp.tv_sec;
+
+ // copy tmp.tv_usec to rtc_time's second half
+ rtc_time[1] = (u32) tmp.tv_usec;
+
+ //this section modified by dshttpbackup//
+ /////////////////////////////////////////
+
+

// Clear ARM9 secure area buffer
memset(arm9_secure, 0, 0x8000);


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

--- parasyte-card.h.old Mon Feb 16 22:52:43 2009
+++ parasyte-card.h Mon Feb 16 19:09:49 2009
@@ -1,10 +1,10 @@
-#define CARD_ACTIVATE (1 << 31) // Start/Stop
-#define CARD_WR (1 << 30) // Write Enable
-#define CARD_nRESET (1 << 29) // Reset
+//#define CARD_ACTIVATE (1 << 31) // Start/Stop
+//#define CARD_WR (1 << 30) // Write Enable
+//#define CARD_nRESET (1 << 29) // Reset
#define CARD_TRM (1 << 28) // Trimmed commands
#define CARD_CT (1 << 27) // Unknown
#define CARD_BLOCKS(n) (((n) & 7) << 24) // Block size
-#define CARD_DATA_READY (1 << 23) // Data is on the bus, ready to read
+//#define CARD_DATA_READY (1 << 23) // Data is on the bus, re
ady to read
#define CARD_CS (1 << 22) // Command Security
#define CARD_L2(n) (((n) & 0x3F) << 16) // Latency 2
#define CARD_SCR (1 << 15) // Security Register

Author:  jleemero [ Mon Feb 16, 2009 9:55 pm ]
Post subject:  Re: DS Game Card Encryption

2 years.
2 years since the last post.


What you have there is actually useful and productive, which is why I'm not pissed at you.
But you ought to just throw this in it's only little thread.


2 years...

Author:  Parasyte [ Tue Feb 17, 2009 7:06 pm ]
Post subject:  Re: DS Game Card Encryption

(Ignore jleemero; he doesn't understand the concept that there is no concept of "bumping" threads.)

Thanks for the patch, dshttpbackup! I might just have to put this little lib together and host it on http://hg.kodewerx.org/ for just these sorts of occasions.

Author:  jleemero [ Tue Feb 17, 2009 7:20 pm ]
Post subject:  Re: DS Game Card Encryption

2 Years God Dammit!

Author:  HyperHacker [ Tue Feb 17, 2009 9:45 pm ]
Post subject:  Re: DS Game Card Encryption

Who cares? It's useful.

Author:  jleemero [ Tue Feb 17, 2009 10:43 pm ]
Post subject:  Re: DS Game Card Encryption

HyperHacker wrote:
Who cares? It's useful.

I'm aware.
It still tingles though.

Author:  dshttpbackup [ Sun Feb 22, 2009 11:32 am ]
Post subject:  Re: DS Game Card Encryption

Parasyte wrote:
Thanks for the patch, dshttpbackup! I might just have to put this little lib together and host it on http://hg.kodewerx.org/ for just these sorts of occasions.


you are welcome. you may have and use the patches as you see fit of course. ...i think the original code was gpl, anyway...

Author:  Parasyte [ Sun Feb 22, 2009 12:18 pm ]
Post subject:  Re: DS Game Card Encryption

Yes, it was originally released under GPL. But I think it would be more useful to people if it was relicensed under the LGPL. This will leave the source in an interesting state; the code in this thread will remain available under the GPL. Any relicensed version will be considered a fork.

Author:  XY.Yang [ Thu Nov 19, 2009 11:00 pm ]
Post subject:  Re: DS Game Card Encryption

I have compiled the cardcrypt.c with PALIB and devkitARM to builded a NDS file and copy it to a R4 card, choose and run the compiled NDS file after pull-on NDS with moonshl2, all the returned data (game tile ,card size , arm9 size, logo_crc16 etc) are 0xff. what is wrong with me?

Author:  HyperHacker [ Thu Nov 19, 2009 11:49 pm ]
Post subject:  Re: DS Game Card Encryption

Well there are a number of possible issues:
1) This code is very old and updates to the DS devkit have a tendency to break things. It might need to be changed.
2) PALib is known to be stupid and break things.
3) I'm not sure what you're trying to do. Are you...
-Trying to read the R4 ROM? Being a flash cart it might behave differently, likely in a deliberate attempt to stop this.
-Trying to read a cartridge that was inserted before powering on? This won't work because the startup BIOS has already put the cartridge in encrypted mode. To talk to it you'd need the seeds it leaves in memory, which have already been removed before your program runs.
-Inserting a cartridge before attempting any access? That should work, but you may be doing it wrong.

Author:  Parasyte [ Fri Nov 20, 2009 3:28 pm ]
Post subject:  Re: DS Game Card Encryption

The cart must be ejected and then re-inserted before initializing the cart read/decrypt lib. This will effectively reset the encryption logic on the card itself. To my knowledge, there is no way to do this in software.

Author:  XY.Yang [ Mon Nov 23, 2009 12:17 am ]
Post subject:  Re: DS Game Card Encryption

Well, Thanks for help. I have used this code to authorized my R4 card, but the result is failed!. And I want to know how NDS authorize the game card (as PASSME). Did the code cardcrypt.c show the process?

Author:  Parasyte [ Mon Nov 23, 2009 5:16 pm ]
Post subject:  Re: DS Game Card Encryption

Keep in mind that the card may use one of the "workarounds" defined in gbatek (Section "Avoiding Secure Area Encryption") -- this code will fail on such cards. It will also fail on "PassMe" cards that redirect parts of the header to the GBA slot.

Author:  XY.Yang [ Sun Nov 29, 2009 8:12 pm ]
Post subject:  Re: DS Game Card Encryption

In function CardRead(u8 *buffer, u32 addr, u32 size), it will send 0xB7AAAAAAAA000000 to read data from game card, and is the command encrypted by key2? I found the function calls cardPolledTransfer() to send raw command. why?

Author:  Parasyte [ Tue Dec 01, 2009 5:35 pm ]
Post subject:  Re: DS Game Card Encryption

The 0xB7 read command is only encrypted at the hardware level. cardPolledTransfer() is used to read the requested data synchronously. (Without interrupts.)

Author:  NEo_Bazz [ Mon Dec 07, 2009 10:06 pm ]
Post subject:  Re: DS Game Card Encryption

Did I hear 'old post'?

Author:  HyperHacker [ Mon Dec 07, 2009 10:13 pm ]
Post subject:  Re: DS Game Card Encryption

No, no you did not.

Author:  XY.Yang [ Thu Dec 10, 2009 8:02 pm ]
Post subject:  Re: DS Game Card Encryption

Firstly, thanks for all's answers.

And now I have dumped the data from NDS slot-1, and Gamecode is 41 53 4D 41 (pls see Header Overview part of GBATEK), and NDS send 3C 99 8B 22 92 DA 6F D2 to activate key1 encryption mode, and followed 8 bytes data from NDS are C8 EF E3 6C DD FF 08 DC . I think it is activate key2 encryption command, but used here's code I can not decrypted to 4llllmmmnnnkkkkk format , what 's wrong?

Author:  XY.Yang [ Fri Dec 11, 2009 12:22 am ]
Post subject:  Re: DS Game Card Encryption

woooooooooooooooooo, I resolved it. Fuck a foolish mistake. The code is very good!

Author:  Parasyte [ Fri Dec 11, 2009 4:44 pm ]
Post subject:  Re: DS Game Card Encryption

I have no idea how accurate the information in GBAtek is; I just know that the code was not written based upon it, and that it does work.

Author:  HyperHacker [ Fri Dec 11, 2009 10:23 pm ]
Post subject:  Re: DS Game Card Encryption

Parasyte wrote:
it does work.
I can vouch for this. :P

Author:  XY.Yang [ Sun Dec 13, 2009 11:14 pm ]
Post subject:  Re: DS Game Card Encryption

Belows are key2 encrypt/decrypt codes I have changed . The result is OK.

u64 HardCrypt_Reverse(u64 key) {
int i, j;
u64 tmp = 0;

j = 38;
for (i = 0; i < 39; i++) {
// tmp |= (((j >= 0) ? (key >> j) : (key << -j)) & (1LL << i));
// j -= 2;
tmp |= ((key >> i) & 1) << (38 - i);
}

return tmp;
}


Belows are the callback function:

void HardCrypt_Key2Enc(u8* Data, u32 cnt)
{
for (u32 i =0; i < cnt; i++)
{
key2_seed = HardCrypt_Update();
Data[i] = (Data[i]^key2_seed ) & 0xff;
}


After NDS sends 3CIIIJJJXKKKKKXXh command, all following comands' returns value must be 910h + [value], and the value is key2 encrypted including 910h dummy data.

Author:  Parasyte [ Mon Jun 28, 2010 5:12 pm ]
Post subject:  Re: DS Game Card Encryption

I've included your change to HardCrypt_Reverse() in a private source repository for this code. (I'm starting to rewrite it as a static library, and fix the code so it makes sense. Also writing a test suite for it, since it's real easy to break the code by making small changes; and the rewrite is going to be a whole lot of big changes.)

I think I know what you mean by "910h dummy data" ... It's not a fixed number of bytes. The number of dummy clocks is defined in the card control register; the L1 and L2 bits.

It's clocked kind of like this: When the "TRM" bit is set (no idea what "TRM" means ... I've heard "trimmed commands" and other things... any ideas?), L1 is clocked, followed by L2, then 512-bytes of data... followed by another L2 and another 512 bytes of data ... etc. until you're finished reading the requested number of pages (which is also set in the same ROM control register).

Author:  Parasyte [ Tue Jun 29, 2010 5:41 pm ]
Post subject:  Re: DS Game Card Encryption

The most likely explanation for "TRM" that I'm able to find is "Tamper Resistant Mode" ... Basically, the bit, when enabled, causes the NDS hardware to advance the Blowfish state machine inside the ROM with dummy clocks configured by the L1 and L2 bits.

If the state machine is not enabled when this bit is set (i.e. when the card is not currently running in "Tamper Resistant Mode") the NDS will still issue the dummy clocks with L1/L2. The NDS will be discarding valid data during those clock cycles.

Author:  Parasyte [ Wed Jul 14, 2010 8:26 pm ]
Post subject:  Re: DS Game Card Encryption

GBAtek is very inaccurate in regards to the "ROM chip ID/card ID."

It is mostly correct on the format of the ID, which goes as follows:
Card ID: xxxxssmm
  • mm - Manufacturer ID (0x80 - Matrix Memory, 0xAE = OKI Semiconductor, 0xC2 = Macronix)
  • ss - Chip size in megabytes minus 1 (eg. 0Fh = 16MB)
  • xxxx - ID bit flags:
    • Bit-0: Unknown (See: The Legend of Zelda: Spirit Tracks)
    • Bit-13: Unknown (See: Dementium II, The Legend of Zelda: Spirit Tracks)
    • Bit-14: Unknown (See: Dementium II, Foto Showdown, My Healthy Cooking Coach, System Flaw, The Legend of Zelda: Spirit Tracks)
    • Bit-15: ROM speed select (0 = fastrom, 1 = slowrom)

Some additional notes on the the ID:
  • The Manufacturer ID is defined by JEDEC. According to the standard, 0x80 is an invalid MFR. ID. However, I have a number of cards which claim exactly that. According to this awesome site, the SlowROM chip used in "Akachan wa Doko Kara Kuru no?" is manufactured by Matrix Memory.
  • The only card I've seen that reports an MFR. ID of 0xAE is Dementium II. It's listed as OKI Semiconductor by the JEDEC standard, but I haven't been able to verify that. The SlowROM chip used in Dementium II is unmarked.
  • Bit-14 almost looks like a DSi-mode flag. Except that Dementium II and Spirit Tracks also has it set, and neither game supports DSi-mode.
  • The ROM speed select offers two capabilities, which I've dubbed "fastrom" and "slowrom"; see below.

GBAtek fails to mention all of the following facts:

  • FastROM cards are, well, pretty fast! They can be clocked at (or above!) 6.7 MHz. SlowROM cards can only operate stably at (or below) 4.2 MHz.
  • SlowROM cards are "self-clocking".
  • SlowROM cards *require* the timeout period specified in the ROM Header (which is a 2-byte value at offset 0x6E) in order to complete their self-clocking operation. FastROM cards don't care about the timeout.
  • SlowROM cards require a slightly modified protocol to operate during the "TRM" phase; see below.
  • SlowROM cards have a maximum read size of 512-bytes (0.5 KB). FastROM cards typically have a maximum read size of 4,096-bytes (4 KB). The NDS itself has a read size limit of 16,384-bytes (16 KB).

The "modified" protocol goes something like this:
  1. The TRM bit is not set.
  2. The blowfish-encrypted command is first committed to the card without reading any data back.
  3. Wait for the timeout period.
  4. The same blowfish-encrypted command is sent again, this time reading data back.

Pretty much every blowfish-encrypted command is handled in a manner similar to that described above on SlowROM cards. TRM is never enabled, meaning the card is not clocked to advance the blowfish state machine; the card does its own internal clocking during the timeout period. After the timeout lapses, the same command is sent again (I'll refer to these "duplicate" commands as dummy commands) but this time, it will actually read back the requested data (if any).

The secure-area bank reads are peculiar, since each secure-area bank is 4 KB in size (and SlowROM cards can only output 0.5 KB at a time). With FastROM cards, it's no problem: Just request which bank you want to read, and read the whole thing. But with SlowROM cards, after the command is committed and the timeout lapses, 8 dummy commands are sent, each reading back 512-bytes. (Remember, each dummy command is exactly the same as the committed command. There is no timeout wait for dummy commands; only after a command is committed.) SlowROM cards not only do their own internal clocking of the blowfish state machine, but they also advance an internal address pointer on their own after reading secure-area banks.

This is something that I mentioned about three years ago but never truly analyzed until now.


Now you can see how far off GBAtek is on this matter:
GBAtek wrote:
2bbbbiiijjjkkkkkh (19B8h) - Get Secure Area Block
KEY1 encrypted command. Used to read a secure area block (bbbb in range 0004h..0007h for addr 4000h..7000h), each block is 4K, so it requires four Get Secure Area commands to receive the whole Secure Area (ROM locations 4000h-7FFFh), the BIOS is reading these blocks in random order.
Normally (if the upper bit of the Chip ID is set): Returns 910h dummy bytes, followed by 200h KEY2 encrypted Secure Area bytes, followed by 18h KEY2 encrypted 00h bytes, then the next 200h KEY2 encrypted Secure Area bytes, again followed by 18h KEY2 encrypted 00h bytes, and so on. That stream is repeated every 10C0h bytes (8x200h data bytes, plus 8x18h zero bytes).
Alternately (if the upper bit of the Chip ID is zero): Returns 910h dummy bytes, followed by 1000h KEY2 encrypted Secure Area bytes, presumably followed by 18h bytes, too.
Aside from above KEY2 encryption (which is done by hardware), the first 2K of the Secure Area is additionally KEY1 encrypted (which must be resolved after transfer by software).

The first inaccuracy in this quote (which is only one of *two* mentions of the ROM speed bit in the card ID. The other mention just says, "4th byte - Bit7: Secure Area Block transfer mode (8x200h or 1000h)" ... hardly enough information to properly handle a SlowROM card) is that "the upper bit of the Chip ID set" is "Normal"! For the record, no, it is not normal. SlowROM cards are the exception; FastROM cards are far more common.

Second, it goes on to explain the normal protocol, while claiming it's what happens when "the upper bit of the Chip ID set".

Third, the "alternate" protocol is just plain wrong; it never reads a full 4 KB bank in one go.

Fourth, it "presumes" the mythical 4 KB read is "followed by 18h bytes, too". This is bad information because the data is never followed by "18h bytes". In fact, those dummy bytes precede the data. And the number of dummy bytes is specified by the L2 parameter of the card control flags.

Fifth, 'bbbb' can be in the range 0004 - FFFF. It's not really useful to use secure-area reads on banks outside of the secure-area, because they are slower than normal reads (it takes a lot of time to clock the blowfish state machine). But it is possible! Reading a bank lower than 4 will read (bank + 8). For example, attempting to read bank 1 will return data for bank 9. Reading a bank number above the upper boundary of the ROM will read from bank 8.

Sixth, because the protocol for SlowROM cards is so different, it takes a great deal more than just "four Get Secure Area commands to receive the whole Secure Area (ROM locations 4000h-7FFFh)". It actually takes: (1 commit command + 8 dummy commands) * 4 banks = 36 commands.


I think that about covers it, for now.

Page 2 of 2 All times are UTC - 8 hours [ DST ]
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/