I am bit ashamed of myself for wasting time on converting a high resolution truecolor image into uncompressed and necrophile ascii text, but I seem to have typed up the .png, so here it is:
Code: Select all
##################################.py
from snow20 import SNOW20
from rc4 import RC4
cardrc4keyhalf = 0x4##############################7
cardsnowiv = 0xD##############################4
#cardrc4keyhalf = 0x3##############################9
#cardsnowiv = 0xD##############################4
#cardrc4keyhalf = 0x7##############################C
#cardsnowiv = 0x0##############################A
def tolist(val, nbytes):
return [val >> i & 0xff for i in reversed(range(0, nbytes*8, 8))]
def initsnowstream(snowkey):
snow20stream = SNOW20(snowkey, cardsnowiv)
for _ in xrange(32): #discard 1024 bits of output, each output is 32 bits
snow20stream.next()
return snow20stream
def initrc4stream(snowstream):
tmp = snowstream.next() << 96 | snowstream.next() << 64 | \
snowstream.next() << 32 | snowstream.next()
key = cardrc4keyhalf << 128 | tmp
rc4stream = RC4(tolist(key, 32))
for _ in xrange(256): #discard the first 256 bytes of output
rc4stream.next()
return rc4stream
#sample data from 3dbrew ;http://www.3dbrew.org/wiki/Gamecards
titlekey1 = 0x################ #decrypted from header at bottom of gamecard page
titlekey2 = 0x################
enccmds = [[0xF32C92D85C9D44DED3E0E41DBE7C90D9, 0x00],
[0x696B9D8582FB55D31B68CAFE70C74A95, 0x04],
[0xBAA4812CA0AC9C5D19399530E3ACCCAB, 0x04],
[0x178E427C22D87ADB86387249A97D321A, 0x00],
[0xE06019B1BD5C9130ED6A4D9F4A9E7193, 0x04],
[0x4E0D224862523BBFE2E6255F80E15F37, 0x04],
[0x4CDF93D319FB62D0DB632A45E3E8D84C, 0x04],
[0x9AA5D80551002F955546D296A57F0FEF, 0x04],
[0xC12BA81AEF30DDDBD93FAD5D544C6334, 0x04],
[0x62EC5FB7F420AE1DC6253AE18AFA5BB3, 0x200+4], #+crc
[0xE3FA23AA016BE0C93430D1F42FF41324, 0x200+4]] #+crc
snow20stream = initsnowstream(titlekey1 << 64 | titlekey2)
rc4stream = initrc4stream(snow20stream)
for cmd, datalen in enccmds:
print 'encrypted command: %032X' % (cmd)
dec = reduce(lambda x, y: x<<8 | y, [rc4stream.next() ^ x for x in tolist(cmd, 16)])
print 'decrypted command: %032X' % (dec)
if dec >> (15*8) == 0x83: #"set seed" command, replaces titlekey2 and reinitializes the snow cipher
randseed = dec & 0xFFFFFFFFFFFFFFFF
print 'changing "seed" to %016X' % (randseed)
snow20stream = initsnowstream(titlekey1 << 64 | randseed)
rc4stream = initrc4stream(snow20stream) #after every(?) encrypted command, the rc4 cipher is reinitialized with the next 128 bits of snow output
print 'skipping %d bytes' % (datalen)
for _ in xrange(datalen):
rc4stream.next() #we don't have the returned data in this sample data, so just throw out bytes from the cipher stream
profi200 wrote: ↑Sat May 08, 2021 7:13 amThe unknown lowermost bits int REG_SD_OPTION are a card detection timer. It's the time between inserted status and the "SIGSTATE" status getting set. Not sure how useful it is though because that bit doesn't trigger an IRQ.
I am just trying to test that and measure the timing on DSi, but it doesn't work as expected.
As far as I understood, I set the delay in lower 4bit of SD_CARD_OPTION (Port 4004828h), then acknowledge all IRQs in SD_IRQ_STAT (Port 4004810h), insert the SD card, and wait until IRQ_STAT bit4 gets set (cart newly inserted), and then there is a variable delay until IRQ_STAT bit5 (SIGSTATE) gets set? But, over here, bit4 and bit5 seem to get set exactly at the same time. How did you measure that delay?
It looks as if both bit4 and bit5 might be both affected by the delay, but it's hard to tell since the max delay setting is less than one second (and I couldn't exactly say
when the insert switch gets closed during insertion). My only idea would be rewiring the insert switch signal, so that it could be toggled by software. But you didn't really do that, or did you?
EDIT: Also tried on 3DS, that does also set bit4 and bit5 simultaneously.
Apropos, do you know if the delay occurs only on card insert, or also on power up, or also upon somehow resetting the card controller?
profi200 wrote: ↑Sat May 08, 2021 2:12 pm9 is the value i use and it's the lowest that still works and is within SD/MMC spec. Voltage ramp up time is well within spec in my measurements.
Yeah, that timings are relevant on power up (when the card is already inserted). When actually newly inserting the card, I think the delay is more about eliminating switch bounce (on the insert switch signal), and ensuring that data/clk/cmd pins have properly settled (eg. depending on how quickly and smoothly the user is pushing the card in). I guess card insert would typically need delays much longer than 7.8ms (or you could start to try to access the card instantly, but be prepared to retry for several 100ms in case of errors).
Btw. the 3DS seems to have a separate power supply for the SD card slot (TP13), instead of using the "main" 3.3V supply (TP3). I don't know if or how that supply can be switched on/off by software though.