DSi Wifi rev-engineering

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Oops, I've found a logging error where 3-step WINDOW-read had collided with a WMI-event:

Code: Select all

   bad:
Read  Mem[00520001] = 00520000                    ;this is a logging error (the 3-step MemRead had collided with REGDOMAIN event)
Read  Func[1:00400] = Len:0001x0010 00 00 04 00 0F 00 0F 00 00 00 00 00 00 BC 1A 91
Read  Func[1:00474] = Len:0001x0004 A0 B2 52 00   ;this is final step of above mis-logged MemRead
Write Mem[0052B2A0] = 00000002
   correct:
Read  Mem[005200...                               ;ReadMem addr.msbs (then gets interrupted by event...)
Read  Func[1:00F80] = Len:0001x0080 01 02 0E 00 08 00 06 10 48 03 00 80 02 06 00 00 00 00 00 00   ;REGDOMAIN event
Write Func[1:0047C] = Len:0001x0001 00            ;ReadMem addr.lsb ;[......00]
Read  Func[1:00400] = Len:0001x0010 00 00 04 00 0F 00 0F 00 00 00 00 00 00 3C 1A 11
Read  Func[1:00474] = Len:0001x0004 A0 B2 52 00   ;ReadMem data  ;Mem[00520000] = 0052B2A0
Write Mem[0052B2A0] = 00000002
The problem happened only in that one location, and no idea why Nintendo/Atheros had interrupted the read, it wouldn't make much of a difference to process the event after completing the read.

The good news is that everything up to including the above event & mem accesses are same as wifi initialization in launcher - which is already implemented in unlaunch, so I've cleaned up the unlaunch code a bit, and then I can re-use it in wifiboot.

Two small differences that I have spotted are (probably more related to AR6002 vs AR6013, rather than Launcher vs Browser):
With Launcher/AR6002, I had observed WLAN_SYSTEM_SLEEP [0040C4h]=1Ch/1Dh, but in Browser/AR6013 it's 0Ch/0Dh, maybe the bit4 is initially zero (or completely missing) in newer hardware.
With Launcher/AR6002, I got REGDOMAIN value 80000188h, but Browser/AR6013 gets 80000348h. With that difference, it's more clear what the value is supposed to mean (in the wifi firmware "RGBD" DataSet, 0188h is "JP" and 0348h is "US") (which is both wrong because I am elsewhere, and I have a european console anyways; also, the REGDOMAIN is thrown only after initialization, ie. there is no further such event with actual country code after connecting to an access point) (bottom line is that they must have hardcoded the firmwares with random country codes... or stored random country codes in the wifi EEPROM).

After the above stuff, Launcher is sending a WMI_SET_SCAN_PARAMS_CMD for whatever reason, and does then complete the wifi init by disabling wifi IRQs.

And the Browser is instead sending four other WMI commands, and then repeatedly sends six WMI commands (per channel scanned) until receiving a beacon matching to the access points in system settings. At that point it's sending a dozen more commands for connecting to the access point.
That's all looking very simple (much easier as for NDS wifi, where one had to construct the scanning/connect managment frames manually).

And if that's working, next would be exchanging four DHCP data packets. And if that's working... ideally, all other data packets might be already working, too - and the project would be finished (much earlier than expected).
On the other hand, things like error handling and retries might cause unexpected extra troubles, so it might take some more weeks/months until everything is stable.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Things are getting better, and worse.

The good thing is that I've got a better understanding of the MBOX Transfer headers.

Leaving apart the initial six handshakes: All further MBOX blocks with [00h]=00h are essentially ACK's for confirming that one has written a Command or Data packet (or maybe confirming that it was written AND processed).
That feature appears to be optional, depending [01h] of the written Command/Data. If it's 00h then no ACK is generated, if it's 01h then one ACK is generated for Commands, and - oddly - two ACKs for Data.
For Commands it's always [01h]=01h (=want ACK), but it might be possible to disable ACKs via [01h]=00h (not tested yet).
For Data it's sometimes [01h]=01h, and sometimes [01h]=00h, even for identical data packet types (eg. some http GET's are sent with ACK requested, and other http GET's without).

The bad thing is BYTE[04h] of received stuff is containing a Length of Extra Data appended at the end of the MBOX. This is usually 08h or 0Ch bytes (or maybe 00h exist, too, don't remember exactly).
For example, one can see that in WMIX_HB_CHALLENGE_RESP_EVENT, the event parameters have fixed length (8 bytes). But the total length at [02h] varies (0016h or 001Ah), and the extra length varies accodingly (08h or 0Ch).
That extra data does usually (or always) start with 02h,06h. And it's then followed by 6 or 10 bytes with whatever content.

Discovering those unknown purpose extra bytes is a bit unpleasant. I had just thought that I had understood the protocol - and then that! : /

The BYTE[05h] of received stuff might be some flags (or a negative value?). One theory is that one of the flags might indicate that the MBOX contains at least one more packet(s) - so one could issue further MBOX reads until the flag goes off.
At least the log does look a bit like that (there are some continous MBOX reads without checking the [1:00400] status bytes). Other theory would be that the ARM-CPU-IRQ flag is checked instead of [1:00400], but I think IRQ acknowledges should be then visible in the log.

I've also started looking at the old NDS wifi source code. It's mostly the ARM7 code that would need to be changed for DSi wifi. And at least half of that code could be probably completely removed. The trick would be not to remove important & still needed parts.
And the other issue is that most of the NDS code is IRQ driven - which is good - but it's also making the program flow a good bit more confusing (as opposed to a much easier design like using a simple loop for channel-scanning, followed by a mainloop for forwarding data to ARM9).
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

PS. Here's a newer version of the wifi-log.txt file, with several annotations, and with 80h-byte padding removed in most cases (at least in the first half of the log) (some of the larger data packets still have the padding, and the DBGLOG events do so, too).
wifi-v2.txt
(249.99 KiB) Downloaded 720 times
EDIT: Grumph, some of the scanning events contain "01 00 xx xx FF FF 04 10 ..." in MBOX.
That's with [04h]=FFh, in that special case [04h] is apparently something other than length of Extra Data.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

I've implemented channel scanning and access point connection in past some days. The first thing done was removing the whole ARM7 code from wificode/dswifi, as well as W_xxx constants for the NDS-WIFI hardware registers. That worked surprisingly well, throwing only a few errors on missing 'public' functions/constants:

Code: Select all

  arm7_installWifiFIFO
  arm7_wifiValue32Handler   ;this includes Init (from ARM9 via FIFO)
  arm7_Wifi_Update
  arm7_Wifi_Deinit
  arm7_Wifi_Interrupt
  IRQ_WIFI (add IRQ2_DSI_WIFI, and don't forget adding IRQ2_ALL)
For the DSi, I've made a new "Init" function, it's basically a copy of the wifi init code from unlaunch, except without wifi firmware uploading in the BMI stage. However, I guess I can remove that whole stuff in final version as unlaunch (or launcher) are already doing the same initialization, so it would be pointless to repeat the same initialization in the .dsi title (although the DSi browser is doing right that, but pointless is a also good term to describe the DSi browser after all).

Next, I've sent a few WMI init commands (as done by the browser), and then the WMI commands for channel scanning, and passed the scanning's WMI events to the old ARM7 code (here resurrection a code snipped from the removed ARM7 stuff). That worked so well that the ARM9 did display the name of my access point right away (which I am still buffled about, I didn't even have had the Wifi_Update function implemented at that time, which, I thought it were needed to setup some state variables for being in scanning mode).

Then I've added WMI connect commands, and changed them to use the channel number and access point details from the scanning steps (and matching wifi password from wifi FLASH memory). And learned some things alongsides:
-- Connect error (eg. bad password) throws DISCONNECT event (instead of CONNECT event).
-- My DSi has only channel 1-11 enabled (trying to scan channel 12,13,14 via SET_CHANNEL_PARAMS throws CMDERROR event).
-- WEP uses only key0, but seems to require dummy CIPHER values for WEP key1-3 (else CONNECT throws ERROR_REPORT event).
-- Receiving data/events bigger than one 80h-byte-block does require "CMD12" enabled in SDIO_STOP_INTERNAL_ACTION bit8 (although, CMD12 shouldn't actually exist for SDIO; ie. the bit probably rather means "stop at end" than literally sending CMD12 in this case).

Obscure 8 or 12 bytes appended at the end of the received data:
The 8 bytes are containing lookahead for the next MBOX packet (so one won't need to manually read the RX_LOOKAHEAD0 register). That's good for knowing if one can read another MBOX packet right away (and also for knowing the length of that packet). The 8 bytes are "02h,06h, AAh, lookahead[4], 55h". If there's no lookahead available yet, then the 8 bytes are often appened nonetheless, but with 00h/00h instead of AAh/55h (and with garbage[4] instead of lookahead[4]).

The other 4 bytes (the first 4 bytes when having 12 bytes appended) contain ACK info, either cmd.ack or data.ack. I am not entirely sure what is ack'ed there (cmd/data received, or cmd/data received AND processed AND delivered). But... whatever it's meant to mean... I am taking it as confirmation that one can send more cmd/data after the corresponding cmd.ack/data.ack. That's useful because the Function 1 status registers contain a lot of info on RX state (flags, lookahead, etc), but little info on TX state (I've merely found a TX overflow flag, which would mean that one would NEED to send data for determining if an overflow would occur).

The length of above 8 or 12 bytes is indicated as [04h]=08h or [04h]=0Ch. And, unlike as one might expect, absence of that bytes isn't indicated by [04h]=00h. Instead, that's indicated as [01h]=00h and [04h]=garbage. Which, I think it's really just garbage, it's often [04h]=00h, or sometimes [04h]=FFh, and I've even seen [04h]=5Eh once.

Next stuff on Todo list
Scanning and connection are working fine so far (and they are meanwhile already done on IRQ level). Next will be forwarding Data packets to/from ARM9. I hope to get that working tomorrow (or even today). It looks easy enough, the main issue is parsing the MBOX headers to NDS-style headers for the ARM9 code. The extra obstacle is that ARM9 packets are stored in ring-buffers, which may need address wrapping once and then.

For the packet size, officially, wifi frame bodies can be up to 2312 (908h) bytes, plus some header/checksum bytes. I was concerned that this could conflict with the MBOX size of 800h bytes, possibly needing to split larger packets somehow. But I do now think the issue doesn't exist in practice, because the network MTU is usually set to about 1400 bytes (DSi firmware allows to select 1500 bytes as maximum). MTU is short for "Max Transmission Unit".

And some confusing oddities
Apropos weird abbreviations. The RSSI (Received Signal Strength Indicator) in the MBOX header appears to be actually what Atheros is referring to as SNR (Signal to Noise Ratio). RSSI and SNR are widely used confusing terms expressed in decibels (whereas, my understanding is that "decibel" is tech slang for "meaningless virtual unit"; similar to percents, but leaving it unspecified whether the units are counted in per cents, or per volt, or per watt, or per milliwatt, or per whatver). The best SNR explanatation that I've found is explaining that the Signal to Noise Ratio "isn't actually a ratio" (it's an offset between signal level and noise level, ie. computed by substracting two values, not by dividing them).

The relation between RSSI and SNR can be seen in the WMI_BSSINFO_EVENT structure. Or actually, there are two structures:
An old 10h-byte structure with both RSSI and SNR (this format is used by DSi).
A new 0Ch-byte structure with SNR only (this format is implemented in DSi, too, but seems to be left unused).
For the new 0Ch-byte format, Atheros does advise to compute the missing RSSI value as "rssi=snr-95" (in result, RSSI should be a negative number, assuming SNR being 0..60). Going by the values spotted in the wifi log, the same formula is also used for the old 10h-byte format, though with a weird and possibly bugged corner case:

The SNR is/was believed to be in range 0..60 (00h..3Ch) on Atheros hardware. But I've also spotted a BSSINFO event with SNR=FCh, which, I guess it's meant to be "-4" (even though that would mean that the signal was weaker than the noise level; or at least weaker than the virtually assumed noise). On the other hand, Atheros seems to see SNR=FCh as "+252", at least they somehow ended up with storing RSSI=009Dh in the 10h-byte event structure (I guess they just didn't know about using 8bit-to-16bit sign-extension, either that, or somebody is operating a megawatt Wifi network in the closer neighborhood, on one of the Jupiter moons, for example).
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: DSi Wifi rev-engineering

Post by tepples »

A "bel" is a 10 to 1 ratio in power. A "decibel" is one-tenth of a bel, or a 10^.1 = 1.26:1 ratio in power. If the signal to noise ratio is 6 decibels, then the signal power divided by the noise power is 10^.6 = 3.98:1.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

I've looked at the wikipedia page after writing the above post, too. As I understand it now: The difference between "percent" and "decibel" is that percents are linear, and decibels are logarithmic (ie. 2db is more than twice as much as 1db) (*).
Ah, then, that sounds as if SNR is actually a "ratio" despite of having it calculated by subtracting "signal-noise". Hmmm, that logarithmic stuff is confusing and exceeds my daily add/sub/shift/and/or/xor maths.

Okay, and a difference of 256db means factor 10^(25.6)? Then, that's funny, with the wrong sign-extension, the difference between -4db and +252db is 256db. And, assuming that an average access point is using 1 watt for transmitting signals... the BSSINFO event from Atheros is telling me that there's a "39810 billion terawatt" access point right next door? That might be reason of concern for most people living on this planet (coincidentally, the energy emitted by the sun is just about 10x higher).

But back to DSi Wifi: The code for sending TX Data is theoretically working now (still untested because I have no code for receving RX Data responses yet). I am hoping that it will be up to 25 times faster than the old 2Mbit/s NDS wifi. Or maybe 10^25.6 times faster. Or so. Something like that. Just hope that it won't end up being slower than before!

(*) and the other differences are that the reference point is called "100%" for percents, and 1db "0db"for decibels; and that it isn't frowned upon to exceed the reference point in the latter case.
Last edited by nocash on Sun Dec 09, 2018 5:15 pm, edited 2 times in total.
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: DSi Wifi rev-engineering

Post by lidnariq »

nocash wrote:And, assuming that an average access point is using 1 watt for transmitting signals
802.11 power ratings are usually measured in dBuV, decibels relative to 1 microvolt transmitted/received signal.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Does that make a difference on the estimated power consumption? I guess that the transmitter energy is something in range of watts, even if the receiver sees only some microwatts or microvolts of that signal. But either way, factor X for received power implies factor X for transmitted power, doesn't it?

That, assuming that the access point is really located somewhere next door (if it's more than a few 100 meters away, then it's probably broadcasting using the power of more than a thousand of suns).
Last edited by nocash on Sun Dec 09, 2018 3:53 pm, edited 1 time in total.
lidnariq
Posts: 11430
Joined: Sun Apr 13, 2008 11:12 am

Re: DSi Wifi rev-engineering

Post by lidnariq »

Decibels (and Bels) are always a relative measurement: there's no universal 0. You can't talk about 1 dB as some absolute quantity: instead you have to have a defined 0 reference.

Hence dBuV. The ratio relative to 1 microvolt.

802.11 access points transmit somewhere around 100mW. q.v. https://wlan1nde.wordpress.com/2014/11/ ... ower-etsi/

And the numbers exposed to the end user are usually actually displayed as the absolute value of the dBmW - "90" means "-90dBmW"
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Success! And Failure!
Data RX/TX is implemented & sending/receiving DHCP packets is working. After passing the DHCP stage, it's been waiting for a .nds/.dsi file to be uploaded from PC to DSi via UDP/TCP packets, and that upload worked right away, too.
Only, the DSi transfer speed doesn't look any faster than old NDS wifi, well, at least it doesn't look much slower either (I'll need to display some "Kbyte/second" indicator to be sure). Anyways, it's definetly miles away from being 25x faster.
The issue might be just that my 32bit ARM7 code is too slow because it's using code/data in uncached Main RAM, that could be fixed by using faster memory & more DMA transfers. If that doesn't help then it might be related to atheros bitrate/fixrates/framerate/pstream settings or the like. Or maybe some IRQ handlers aren't called often enough to process incoming data.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

NDS-Wifi upload speed is about 110 Kbyte/s (ideally should be 200Kbyte/s).
DSi-Wifi upload speed is about 150 Kbyte/s (ideally should be 5000Kbyte/s).

That's both not so good. At least DSi is slightly "faster" than NDS, but it's ways slower than it should be. One problem is that if I try to use DMA or faster memory, then transfers stop working, or become unreliable/slower. I thinks that's related to the SDIO hardware: SDIO commands can have multiple 80h-byte blocks, and it seems that one must wait for "something" between separate blocks.
As for "something", that's unfortunately unknown. Looking at DSi browser, it's using NDMA with SDIO_DATA32 mode for dealing with multiple blocks, so that's probably the way to go, hoping that NDMA will automatically use the correct timings. If there's a way to poll any "next block ready" flags for manual timings then I don't know about it yet.

For now, I switched to some other stuff: The code is now auto-detecting if the DSi's SDIO registers exist (and are enabled), and automatically switches between NDS-Wifi and DSi-Wifi accordingly. That's working... but brought up another small problem: The program currently tends to hang after upload's on NDS consoles (or DSi's in NDS mode). I didn't have had that problem some months ago, looks as if some newer changes have broken NDS compatibility.

Next Problem: My new DSi-Wifi code was for WEP only, so I've logged initialization for open networks and WPA networks today.
Open network is simple: It does simply skip the four ADD_CIPHER_KEY commands, and sends the CONNECT command (with only three parameter bytes different as than for WEP).

WPA network is nightmarish. It's ways more complicated than WEP. For WEP one just uses ADD_CIPHER_KEY and CONNECT, and everything is done automatically. Theoretically, WPA should work the same, but instead, it's using CONNECT (without setting any cipher keys yet), and then it's using twelve Data RX/TX commands for manually exchanging data with the access point, and throws in two ADD_CIPHER_KEY commands inbetween of that data transfers. And worst, the WPA password doesn't show up anywhere in that process, apparently one is supposed to encrypt the password manually (or convert it to SHA256 or so) (the ADD_CIPHER_KEY commands have key length set to 32 bytes, despite of the actual ASCII password being shorter).

Below is the WPA connection sequence. Please let me know if somebody can make sense of it, or can point me on helpful documents or source code! The CMD/EVENT stuff is more or less clear (apart from ADD_CIPHER_KEY_CMD not containing plaintext passwords). But I've no idea what the twelve "Data #1..#12" packets are supposed for. At the moment, I am feeling a bit overhelmed by unexpected problems - I hope some of it will sort out tomorrow.

Code: Select all

connection details:
 access point:     fritzbox (with SSID "ead")
 encryption:       WPA-PSK(TKIP)
 password:         ernstaugustdeich
 modus:            infrastruktur
 groupkeyinterval: 3600 seconds
 MAC for DSi       mm mm mm mm mm mm
 MAC for AP        aa aa aa aa aa aa
 MAC for router    bb bb bb bb bb bb

MBOX traffic for sdio_connect sequence:
 (preceeded by usual channel scanning stuff)
 Write WMI_TARGET_ERROR_REPORT_BITMASK_CMD +2008h    01 01 06 00 08 20  22 00 7F 00 00 00
 Write WMI_SET_BSS_FILTER_CMD                        01 01 0A 00 00 00  09 00 00 00 00 00 00 00 00 00
 Write WMI_SET_PROBED_SSID_CMD                       01 01 25 00 00 00  0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 Write WMI_SET_SCAN_PARAMS_CMD                       01 01 16 00 00 00  08 00 FF FF FF FF FF FF C8 00 C8 00 00 05 C8 00 00 00 00 00 00 00
 Write WMI_SET_CHANNEL_PARAMS_CMD                    01 01 08 00 00 00  11 00 00 00 02 01 9E 09
 Write WMI_SET_BITRATE_CMD                           01 01 05 00 00 00  00 F0 FF 00 00
 Write WMI_SET_AP_PS_CMD                             01 01 06 00 00 00  48 00 01 A4 F7 FF
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 00
 Write WMI_SET_POWER_MODE_CMD                        01 01 03 00 00 00  12 00 02
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 00
 Write WMI_CREATE_PSTREAM_CMD                        01 01 41 00 00 00  05 00 14 00 00 00 14 00 00 00 7F 96 98 00 FF FF FF FF 00 00 00 00 00 45 01 00 00 45 01 00 00 45 01 00 00 00 00 00 00 00 00 00 80 8D 5B 00 00 20 00 00 00 00 00 00 D0 80 D0 00 00 02 FF 01 00 05 00
 Write WMI_SET_WSC_STATUS_CMD                        01 01 03 00 00 00  41 00 00
 Write WMI_SET_DISCONNECT_TIMEOUT(_CMD)              01 01 03 00 00 00  0D 00 02
 Write WMI_SET_TKIP_COUNTERMEASURES_CMD  !!!         01 01 03 00 00 00  20 00 00
 Write WMI_SET_BSS_FILTER_CMD                        01 01 0A 00 00 00  09 00 00 00 00 00 00 00 00 00
 Write WMI_SET_SCAN_PARAMS_CMD                       01 01 16 00 00 00  08 00 FF FF FF FF FF FF C8 00 C8 00 00 05 C8 00 00 00 00 00 00 00
 Write WMI_SET_CHANNEL_PARAMS_CMD +2008h             01 01 08 00 08 20  11 00 00 00 02 01 9E 09
 Write WMI_SET_KEEPALIVE_CMD                         01 01 03 00 00 00  3D 00 00
 Write WMI_CONNECT_CMD      ;<----------             01 01 36 00 00 00  01 00 01 01 03 03 00 03 00 03 65 61 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9E 09 aa aa aa aa aa aa 00 00 00 00   ;connect to "ead"
 Read  WMIX_DBGLOG_EVENT                             01 00 E2 05 00 00  10 10 08 30 00 00 00 00 00 00 F1 05 2C 44 08 30 00 00 2C 06 29 84 07 00 00 00 14 00 00 00 2C 06 06 A4 ...
 Write WMIX_HB_CHALLENGE_RESP_CMD          +0101h    01 01 0E 00 01 01  2E 00 08 20 00 00 02 00 00 00 00 00 00 00
 Read  WMIX_HB_CHALLENGE_RESP_EVENT                  01 02 16 00 08 00  10 10 07 30 00 00 02 00 00 00 00 00 00 00 02 06 00 00 02 0C 00 00
 Delay 0009 till IRQ
 Read  WMI_CONNECT_EVENT    ;<----------             01 02 7F 00 08 00  02 10 9E 09 aa aa aa aa aa aa 64 00 64 00 01 00 00 00 1A 31 16 DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00 11 04 01 00 00 03 65 61 64 01 08 82 84 8B 0C 12 96 18 24 32 04 30 48 60 6C DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 51 04 00 00 01 C0 01 08 82 84 8B 0C 12 96 18 24 32 04 30 48 60 6C 00 02 06 00 00 00 00 00 00    ;for "ead"
 Read  Data #1 read                                  02 02 83 00 08 F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 00 89 00 20 00 00 00 00 00 00 00 01 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 06 00 A5 A5 01 00 00
 Write Data #2 write                                 02 00 93 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 83 AA AA 03 00 00 00 88 8E 01 03 00 77 FE 01 09 00 20 00 00 00 00 00 00 00 01 B1 F9 1C 00 66 00 55 8F 42 F7 07 F4 00 01 10 01 01 27 40 00 00 00 00 00 7F 06 9C 6C FF 2F B6 C7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 1E 61 E7 C3 1F CF 0D 88 9F 7B E9 27 4B 80 AA 00 18 DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02
 Read  Data #3 read                                  02 02 A1 00 0C F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 85 AA AA 03 00 00 00 88 8E 01 03 00 79 FE 01 C9 00 20 00 00 00 00 00 00 00 02 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 7A 4F 98 41 29 D5 BF 43 04 58 74 E2 3E 8E 10 00 1A DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00 01 02 02 01 02 06 00 14 00 0A 00 00
 Write Data #4 write                                 02 00 7B 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 01 09 00 20 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 53 EE 13 CE 18 28 7C 50 87 C1 78 54 67 E4 B7 00 00
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #5 write n/a +0204h                      02 01 02 00 00 00  04 02
 Write Data #6 write n/a +0204h                      02 00 02 00 00 00  04 02
 Write WMI_ADD_CIPHER_KEY_CMD      ;<---             01 01 2F 00 00 00  16 00 00 03 00 20 00 00 00 00 00 00 00 00 07 A2 68 3A DF B2 B5 29 2F 82 70 8E 0F C0 CB 0E 9B 5F AE 0F 0F EB 79 18 F2 BC 3A FA EA 12 FB 3C 03
 Read   (handshake with len=0Eh) (acklen=4) (!!!)    00 02 0E 00 0E 00  01 04 01 01 02 01 02 06 00 00 00 00 00 00  ;(this isn't WPA related, just interesting because it does deliver a "Cmd.ack" and "Data.ack" in the same packet)
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Read  Data #7 read                                  02 02 A3 00 08 F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 8B AA AA 03 00 00 00 88 8E 01 03 00 7F FE 03 A1 00 20 00 00 00 00 00 00 00 03 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D8 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 DA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8B 0D 67 18 1E B2 81 48 02 9D 84 6A 0B DC 03 48 00 20 04 4C 38 D8 37 85 D8 75 D2 C7 AD 15 F9 F8 32 78 96 BE 01 97 0C 5F 9F A9 6E B6 9C 5B 3C 3C 5B 16 02 06 00 DB 2A 92 8A 00
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #8 write n/a +020Dh                      02 00 02 00 00 00  0D 02
 Write Data #9 write n/a +0209h                      02 00 02 00 00 00  09 02
 Write WMI_ADD_CIPHER_KEY_CMD      ;<---             01 01 2F 00 00 00  16 00 02 03 01 20 00 00 00 00 00 00 00 00 44 9B 5A DC 41 27 79 2E ED 65 AA 1F D3 65 36 2F 02 A4 1B DD B8 2B 2F 39 84 D0 69 6F 46 E4 55 53 03
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #10 write                                02 00 7B 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 03 21 00 20 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 A2 B7 B0 78 07 D3 67 C8 1B C9 ED 4B 55 20 E1 00 00
 Delay 001A till IRQ
 Read  WMI_NEIGHBOR_REPORT_EVENT                     01 02 16 00 0C 00  08 10 01 aa aa aa aa aa aa 00 01 02 02 01 02 06 00 00 1A 31 16 00
 Delay 0010 till heartbeat
 Write WMIX_HB_CHALLENGE_RESP_CMD          +0101h    01 01 0E 00 01 01  2E 00 08 20 00 00 03 00 00 00 00 00 00 00
 Read  WMIX_HB_CHALLENGE_RESP_EVENT                  01 02 16 00 08 00  10 10 07 30 00 00 03 00 00 00 00 00 00 00 02 06 00 00 1A 31 16 00
 Delay 0006 till IRQ
 Read  Data #11 read                                 02 02 4E 00 08 00  3B 00 01 00 5E 00 00 01 bb bb bb bb bb bb 00 36 AA AA 03 00 00 00 08 00 46 00 00 20 00 00 40 00 01 02 43 2D C0 A8 01 01 E0 00 00 01 94 04 00 00 11 0A EE F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 06 00 CC 65 A2 27 00
 Delay 000B till IRQ
 Read  Data #12 read                                 02 02 40 00 08 7F  3C 00 01 00 5E 7F FF FA bb bb bb bb bb bb 00 28 AA AA 03 00 00 00 08 00 46 00 00 20 00 00 40 00 01 02 33 2E C0 A8 01 07 EF FF FF FA 94 04 00 00 16 00 FA 04 EF FF FF FA 02 06 00 25 16 2F E3 00
 (followed by usual DHCP stuff)
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

I've logged WPA2-PCK-AES, too. It's very similar to the above WPA-PCK-TKIP log, up to even issuing the TKIP countermeasures command. Differences spotted are: Some changed bytes in CONNECT command. The two CIPHER keys are only 16bytes for WPA2-AES (unlike 32bytes for WPA-TKIP). And the "Data #7 read" and "Data #10 write" are missing in the WPA2 log.

I haven't found a good reference to nail down the Data stuff. Though it's probably described somewhere in some x-hundred pages IEEE document. Some vague info that I've gathered is that WPA and/WPA2 are using a 4-stage handshake; that might be related to Data #1..#4? Those four packets have protocol ID 888Eh (after the SNAP/LLC header), which seem to be related to something called EAPOL or IEEE 802.1X.

Data #7 and #10 do also have ID 888Eh, but they exist for WPA only (not WPA2), so WPA looks more like a 6-stage handshake, not 4-stage.

Then Data #5,#6,#8,#9 writes aren't having any data body, and don't even have src/dst MAC addresses. They do merely have the unknown halfword, which is usually 0000h (or 1C00h for ARP packets?), and in this case it's 0204,020Dh,0209h. One guess would be that it does clear all cached RX/TX packets. Or maybe changing filtering, selecting which packets are desired to be received? Or maybe it does activate encryption of the following packets.

Data #11,#12 reads do receive something, but the browser doesn't seem to take any actions in response (like sending reply data, or sending WMI commands). Instead, the browser is just sending the DHCP packets in the next step, so it looks as if one could just ignore data #11..#12. Hmmm, for WPA2, there's also another data read inserted, preceeding #11.

So, the important part would be understanding Data #1..#4 (and #7,#10 if present), knowing the meaning of the bytes after the SNAP/LLC header (after the "AA AA 03 .." bytes), and knowing what to do with those bytes, like passing them through SHA-something maybe (or some document mentioned MD5 being WPA related). Uhm, or is that key-initialization step more likely being done through AES and TKIP, for WPA2-AES and WPA-TKIP accordingly?

AES would be easy as DSi is using that elsewhere, too, so I am familar with it. For TKIP I've no idea what it's doing internally, and how to implement it in software (or is it just a variation of the RC4 (WEP) cipher? that would be relative easy).
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

I've tried to break down the data packets, there seem to be several 32-byte fields (or maybe they contain two 16-byte fields or whatever).

And the four WPA2 data packets:

Code: Select all

---------------------------------------------------------------------------------------------------------
WPA2 Data #1 read
  8    WMI header (02 02 83 00 08 F4  32 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  12   ?  02 00 8A 00 10 00 00 00 00 00 00 00
  1    ?  01
  32   ?  32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90
  32   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  16   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2    ?  00 00
  8    WMI handshake info (02 06 00 3B 3B 00 00 00)
---------------------------------------------------------------------------------------------------------
<snip> EDIT: see next post for better break down
And the six WPA data packets:

Code: Select all

---------------------------------------------------------------------------------------------------------
WPA Data #1 read
  8    WMI header (02 02 83 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03              ;version, type?
  2    Length (00 5F)
  12      FE 00 89 00 20 00 00 00 00 00 00 00
  1    ?  01
  32   ?  0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9
  32   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  16   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2    ?  00 00
  8    WMI handshake (02 06 00 A5 A5 01 00 00)
---------------------------------------------------------------------------------------------------------
<snip> EDIT: see next post for better break down
I've had a look at IEEE 802.1X-2001 and IEEE 802.1X-2010, but didn't spot any eye-catching tables that would match up with the data packets. The documents contain several references to RFC documents, so maybe the required info is hiding there. And the 2001 version mentions MD5, the newer 2010 version does doesn't mention MD5 at all, so that file seems to be useless (and to new for the DSi anyways). There should be also a IEEE 802.1X-2004 version, and possibly also -2007, but they don't seem to be available for downlaod; at least not on webpages compatible with my PC : /
Last edited by nocash on Wed Dec 12, 2018 7:29 pm, edited 1 time in total.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Ah, now I've found the matching specification:
IEEE Std 802.11i-2004
I still had that in a file on my harddisk from NDS-Wifi days, and it's called "11i" (not "1x").

Now the WPA2 packets look as so:

Code: Select all

---------------------------------------------------------------------------------------------------------
WPA2 Data #1 read
  8    WMI header (02 02 83 00 08 F4  32 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (02)
  2    Key Information    (00 8A)
  2    Key Length         (00 10)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  2    Key Data Length    (00 00)
  8    WMI handshake info (02 06 00 3B 3B 00 00 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #2 write
  8    WMI header (02 00 91 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 81)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 75)
  1    Descriptor Type    (02)
  2    Key Information    (01 0A)
  2    Key Length         (00 00)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (A8 DC C3 00 67 00 55 8F 49 F7 07 F4 00 01 10 01 60 16 15 00 00 00 00 00 7F 06 9C 6C FF 2F 61 22)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (B9 FA 85 43 28 AC 29 67 36 A8 1E 44 6E 69 08 E9)
  2    Key Data Length    (00 16)
  ..   Key Data           (30 14 01 00 00 0F AC 04 01 00 00 0F AC 04 01 00 00 0F AC 02 00 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #3 read
  8    WMI header (02 02 BF 00 0C F4  33 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 A3)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 97)
  1    Descriptor Type    (02)
  2    Key Information    (13 CA)
  2    Key Length         (00 10)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90)  ;<-- same as in #1
  16   EAPOL Key IV       (A6 A6 A6 A6 A6 A6 A6 A6 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (05 85 CB E1 56 2B 42 10 A8 5D 54 F8 2A ED 50 4D)
  2    Key Data Length    (00 38)
  ..   Key Data           (34 FC 74 21 0D BB C0 B9 89 E2 D9 D4 B4 58 E1 67 7B D0 9B BC 31 C8 42 0A 97 0D AD A1 11 7A E3 48 48 BF B5 FB 48 69 45 D0 CF F1 49 24 EE 90 D8 5B 61 7B 3E 31 67 24 E9 41)
  4    WMI handshake info (01 02 02 01)
  8    WMI handshake info (02 06 00 2F 00 DD 1E 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #4 write
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (02)
  2    Key Information    (03 0A)
  2    Key Length         (00 00)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (DE 4B 9C F1 B8 C3 D3 D0 04 2F 49 8B 97 12 23 C2)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------
And WPA packets are also matching the same format (yet with different "descriptor type", "key information", and different "key length"):

Code: Select all

---------------------------------------------------------------------------------------------------------
WPA Data #1 read -- matches "IEEE Std 802.11i-2004"
  8    WMI header (02 02 83 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03              ;version, type?
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (00 89)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  2    Key Data Length    (00 00)
  8    WMI handshake (02 06 00 A5 A5 01 00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #2 write
  8    WMI header (02 00 93 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 83)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?                  (01 03)
  2    Length             (00 77)
  1    Descriptor Type    (FE)
  2    Key Information    (01 09)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (B1 F9 1C 00 66 00 55 8F 42 F7 07 F4 00 01 10 01 01 27 40 00 00 00 00 00 7F 06 9C 6C FF 2F B6 C7)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (1B 1E 61 E7 C3 1F CF 0D 88 9F 7B E9 27 4B 80 AA)
  2    Key Data Length    (00 18)
  24   Key Data           (DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02)
---------------------------------------------------------------------------------------------------------
WPA Data #3 read
  8    WMI header (02 02 A1 00 0C F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 85)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 79)
  1    Descriptor Type    (FE)
  2    Key Information    (01 C9)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9)  ;<-- same as in #1
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (30 7A 4F 98 41 29 D5 BF 43 04 58 74 E2 3E 8E 10)
  2    Key Data Length    (00 1A)
  26   Key Data           (DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00)
  4    WMI handshake (01 02 02 01)
  8    WMI handshake (02 06 00 14 00 0A 00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #4 write
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (01 09)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (95 53 EE 13 CE 18 28 7C 50 87 C1 78 54 67 E4 B7)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #7 read (this NOT for WPA2 !!!)
  8    WMI header (02 02 A3 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 8B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 7F)
  1    Descriptor Type    (FE)
  2    Key Information    (03 A1)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 03)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D8)
  16   EAPOL Key IV       (9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 DA)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (8B 0D 67 18 1E B2 81 48 02 9D 84 6A 0B DC 03 48)
  2    Key Data Length    (00 20)
  26   Key Data           (04 4C 38 D8 37 85 D8 75 D2 C7 AD 15 F9 F8 32 78 96 BE 01 97 0C 5F 9F A9 6E B6 9C 5B 3C 3C 5B 16)
  8    WMI handshake (02 06 00 DB 2A 92 8A 00)
---------------------------------------------------------------------------------------------------------
WPA Data #10 write (this NOT for WPA2 !!!)
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (03 21)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 03)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (70 A2 B7 B0 78 07 D3 67 C8 1B C9 ED 4B 55 20 E1)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: DSi Wifi rev-engineering

Post by nocash »

Some recent findings and ups & downs... if it's too much blah-blah-text: Just skip to the "Todo" part (and best give some advice about the missing cipher).

PDF's are always ugly, and I know that the format isn't made for screen-viewing, but IEEE Std 802.11i-2004 is even uglier as it has enabled all nag & gag features: It's using super-small font, and automatically defaults to using a window with only half screen height, and prevents scrolling across page boundaries, and invokes sudden monster-zooming when accidentally hitting the mouse button - I really don't what the features are good for, and why anyone would enable them, except maybe for mimmicking open standards and/or for claiming ownership of something without actually sharing legible information : /
Hmmmm, the only way to view sections of the document seems to be to copy/paste separate pages into a text editor, and then manually fix the formatting & indents.
Well, and the actual content of the document... the stuff that I am interested in is somewhere in the middle of the doc, but it isn't described very well. It's kinda useless, unless when combining it with the reference code in the appendices. And even then, the reference code doesn't match up with the descriptions in the document. And the wonderful reference code kinda looks as if was neever tested in practice (like passing 6 parameters to a function that accepts only 5 parameters).
The descriptions in the other chapters are also somewhat unclear and bugged, in one place they've declared to compute a MIC (=checksum) starting "at including bit0-2" of a big-endian number (hah?) (interesting problem, that could mean anything, but the answer to that problem turned out to be irrelevant - because, what they've really meant was starting "at including the 5 bytes preceedng" that big-endian number).
The two sections worth reading are the glossary and the hex numbers shown in test cases; that two sections are containing more practially/useful info than the rest of the document.

Keys, there are lots of keys used, and it took some days to get a rough idea what they are used for (and if or how they do relate to the actual wifi password).
The first key needed is the 32-byte PSK: This is calculated by passing the Password and SSID through some SHA1-HMAC function. In total it does requires 8192 executions of the SHA1-HMAC function, which can get quite slow, especially when doing it on ARM7 side. If needed, the calculation could be made about twice as fast by pre-computing the HMAC key only once per 4096 calculations. But, the good thing is that Nintendo has fortunately pre-compted the KSK, and stored it in Wifi-FLASH (alongsides with the original password).
The next key needed is the 32-byte PMK, which is just the same as the PSK, so that one is easy. The next key is 48-byte PTK, this is also computed using three or four SHA1-HMAC's across the PSK (aka PMK) and the BSSID and DSi MAC address, and the two "Nonce" values from the Data #1 and #2 packets.
And then, 16-byte KCK, KEK, and TK are simply the first, middle, last 16-byte fragments of the 48-byte PTK. I've meanwhile managed to compute all those keys, and to use the KCK to verify the SHA1-HMAC (aka MIC checksum) in the Data #2 packet.

Some Oddities are that the reference code implies using SHA1-HMAC for WPA and WPA2, but other sections of the document suggest using MD5-HMAC for WPA, which, I guess that's actually so, and it's making things a bit more difficult as the DSi BIOS has a SHA1 function, but no MD5 function, so I'll have to code MD5 myself (a bit uncomfortable, and consuming lots of memory when using unrolled code).
Yet elsewhere, the document suggests the MIC values not being computed via SHA1 nor MD5, but rather by a scary function named Michael (which, I guess that's just nonsense, or maybe it applies only for the lower-level data-traffic, but not for the initial key-handshake needed for DSi). Anyways, it makes me wonder if the IEEE people were some kind of fundamentalists, threatening the archangel to rightfully kill you with his sword, if you were sneaking for free internet from their precious wifi-network.

RSA: One thing that is intensely used on DSi is RSA. And, interestingly, WPA/WPA2 are badly missing any such private/public key mechanism. That's weird, maybe RSA wasn't so popular back in 2004? Or hardware was too slow? Probably not. WPA and WPA2 do use "different" encryption keys per user, but they differ only in relation to the MAC addresses and Nonce values exchanged in the unencrypted handshake. Well, and on the SSID and Password, but that are usually known to all members of the network (ie. friends & family & roommates & neighbors). Of course, the other network members are "not supposed" to use your handshake data, but if they wanted to spy on you, then I can't see anything that would prevent them from doing so.
In that context, WPA and WPA2 don't give so much more privacy than open networks, the main "benefit" is preventing people without passwords from using the internet for free.
On the other hand, wired LAN isn't encrypted either, so that's having similar privacy issues.

Firmware: I also had a look at the AR6002 wifi-firmware, checking if it's really not supporting automatic connection: There's a MD5-HMAC function in there, but it's left unused, and doesn't even have it's function vectors installed (and SHA1-HMAC is missing completely). So it looks as if they were originally planning to add auto-connection on firmware-side, and then moved the code to driver-side, which might have some advantages (if one were having a "driver+fimware" combo), but it's not so comfortable on the DSi (with driverless "romimage+firmware" combo).

Todo: I still need one of the actual keys for ADD_CIPHER. The first ADD_CIPHER command is simply using KEK TK (the last bytes of the PTK). But I haven't yet found out where the bytes for second ADD_CIPHER are from. Maybe it's from the TK KEK (but it doesn't match up)? Or from the GMK and GTK stuff mentioned in the docs? Though I've no idea if GMK/GTK exist in the 4-way handshake seen in the WPA2 log at all (they might exist only in 6-way handshake seen in WPA log). Or the missing cipher might come from the "Key Data" field in the handshake packets...
I've no clue what that "Key Data" is supposed to be used for. Comparing the official docs with the values spotted in Data #2 packet:

Code: Select all

  1st byte - Should be DDh - that's true for WPA log, but not so for WPA2 log
  2nd byte - Should be Length - that's true
  3rd-5th byte - Should be OUI value 00-0F-AC - that's wrong (WPA has 00-50-F2 in there, and WPA2 does have 00-0F-AC, but that's in 5th-7th byte)
  6th byte - Should be a cipher suite, whatever why one would need that value
  7th-last byte - Should be whatver/unspecified (in practice it's just repeating the above whatever OUI stuff)
Okay, that looks all wrong, and almost certainly totally useless. However, Data #3 has some more "Key Data" in there (about 38h bytes), and it's encrypted. I just don't know if it's worth decrypting. If it's the same useless OUI stuff then it could just be ignored. Some of the extra bytes might be a 16-byte AES-CTR-MAC checksum (which could be ignored, too). Well, and maybe the missing cipher key is in the remaining bytes, or maybe not.
I am afraid that I'll need to give it a try, and check how the decrypted data looks like. In theory, ARM7 has AES decryption hardware, but it does (probably) require endian-adjustment, and Nintendo's AES-CTR-MAC implementation seems to be a bit non-standard, so it might be unable to decrypt anything at all - and might require to implement AES decryption by software : /
Post Reply