Difference between revisions of "StreetPass"

From 3dbrew
Jump to navigation Jump to search
m (Typos and clarification)
(46 intermediate revisions by 6 users not shown)
Line 1: Line 1:
'''StreetPass''' is a feature that allow your 3DS to connect with other 3DS using WiFi in standby mode.
+
'''StreetPass''' is a feature that allows your 3DS to connect with other 3DS consoles using WiFi in standby mode.
It can be used to share Mii(s) on Mii Plaza for example. Games' StreetPass data is stored on [[SD_Filesystem|SD card]] under [[extdata]], while Mii Plaza StreetPass data is stored on NAND. Not all StreetPass data is stored on SD card: "StreetPass Management" can still be used without a SD card inserted. Wifi infrastructure with APs are used to communicate, like WMB and multi-player.
+
It can be used to share Mii(s) on Mii Plaza for example. Applications' StreetPass data are stored in the CECD module's NAND savegame, applications can move received StreetPass data to an arbitrary savegame. Wifi infrastructure with APs are used to communicate where the data-frames are encrypted with WPA2 CCMP, like [[NWM_Services|UDS]]/[[Download Play]].
StreetPass in sleepmode can work without SD card inserted. Games' Streetpass data are temporarily stored in NAND, and when the games process the StreetPass data they move that data to extdata on SD card.
 
  
 
== WiFi Probe Request Frame ==
 
== WiFi Probe Request Frame ==
  
Whenever the 3DS is woken from sleep (or turned on), and WiFi is enabled, it sends out a 802.11 Probe Request which include all saved access points, as well a probe to an SSID containing an arbitrary string of data, such as "ic[kSvm9s@*cYD>/~IEVj\(fGG;qDo8j". The probe may be related to the 3DS looking for Nintendo Zone APs. This string changes at least daily, and most likely every time the device is woken up.
+
Whenever the 3DS is woken from sleep (or turned on), and WiFi is enabled, it sends out a 802.11 Probe Request which include all saved access points, as well a probe to an SSID containing an arbitrary string of data, such as "ic[kSvm9s@*cYD>/~IEVj\(fGG;qDo8j". This string changes at least daily, and most likely every time the device is woken up.
  
The MAC address used for these probes is the static MAC address found in the Settings application. Unlike the StreetPass MAC address, it will not change over time. This MAC address OUI also differs from the one used in StreetPass.
+
The MAC address used for these probes is the static MAC address found in the System Settings application. Unlike the StreetPass MAC address, it will not change over time. This MAC address OUI also differs from the one used in StreetPass.
  
== StreetPass Probe Frame ==
+
== CCMP Key ==
 +
The StreetPass local-WLAN CCMP data-encryption key is generated by the StreetPass CECD module, where the CCMP key is the 16-byte output from encrypting an all-zero block with AES-CTR via [[PS:EncryptDecryptAes]], with keytype6. The CTR is the first 0x10-bytes from a SHA1-HMAC hash. The SHA1-HMAC key is a 17-byte text string including the NULL-terminator, a seperate HMAC key is used for retail/dev-units, this is determined via [[Configuration_Memory#ENVINFO|ENVINFO]] bit0. The data hashed with SHA1-HMAC is a 0x1C-byte buffer, which is described below.
  
Using Wireshark tool with a WiFi card in monitor mode allow you to see the data used to scan for other 3DS in the range. The below is a broadcast probe request from an 3DS while in standby mode, with SSID "Nintendo_3DS_continuous_scan_000". This frame also contains a custom Nintendo tag, the contents of this tag from different 3ds captures don't match. Probe responses contain the same Nintendo tag data as the probe requests from the same 3DS. The MAC address used in sleepmode seems to change every time there's a streetpass hit, as well as the last 8-bytes of the Nintendo tag data? The MAC address + 8 byte ID for StreetPass is seen to change every time the user enters and exits and Settings application.
+
=== Hash Block ===
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
| 0x0
 +
| 0x8
 +
| 8-byte StreetPass consoleID for the host, from the probe frames.
 +
|-
 +
| 0x8
 +
| 0x8
 +
| 8-byte StreetPass consoleID for the client, from the probe frames.
 +
|-
 +
| 0x10
 +
| 0x6
 +
| MAC address for host.
 +
|-
 +
| 0x16
 +
| 0x6
 +
| MAC address for client.
 +
|}
 +
 
 +
== StreetPass Exchange ==
 +
 
 +
While StreetPass is enabled, the 3DS constantly sends out Probe Requests with an SSID of "Nintendo_3DS_continuous_scan_000". Unlike beacons, which are actively advertising the device's presence, the 3DS is essentially actively looking for other 3DSes. This design is likely to limit impact to non-3DS WiFi capable devices. Each Probe Request contains basic information about that 3DS, including an identifier, and active StreetPass services. If another 3DS is in range, the second 3DS (#2) will respond with a Probe Response, to which the original 3DS (#1), and of the receiving device with every frame thereafter, will respond with an 802.11 Acknowledgement. 3DS(#1) then sends an 802.11 Action frame, as well as an additional Probe Request. The second 3DS sends back another Probe Response that begins the encrypted exchange between the two devices, no authentication/association is done here.
 +
 
 +
The MAC address used in sleep-mode seems to change every time there's a StreetPass hit, as well as the last 8-bytes(StreetPass consoleID) of the Nintendo tag data. The MAC address + 8-byte StreetPass consoleID is seen to change every time the user enters and exits and Settings application if they have not had a StreetPass in an observed time period of 24 hours. It is uncertain how the 3DS determines when it can do a StreetPass again with another 3DS, or what information is actually used to track that. It may be related to how long that 3DS was in range constantly/out of range. 3DSes that are constantly in range of each other in sleep-mode, usually do StreetPass every 11 hours.
 +
 
 +
=== Probe Request Frame ===
 +
 
 +
Using Wireshark tool with a WiFi card in monitor mode allow you to see the data used to scan for other 3DS in the range. The below is a broadcast probe request from an 3DS while in standby mode, with SSID "Nintendo_3DS_continuous_scan_000". This SSID remains consistent across all 3DS units. This frame also contains a custom variable length Nintendo tag, which contains information regarding the offered StreetPass services. The sequence numbers for these probe request increment by 3 for every probe, until another 3DS responds with a probe response.
  
 
   0000  00 00 1a 00 2f 48 00 00 19 7d 19 de 2a 00 00 00  ..../H...}..*...
 
   0000  00 00 1a 00 2f 48 00 00 19 7d 19 de 2a 00 00 00  ..../H...}..*...
Line 22: Line 54:
 
   0070  00 f0 08 c8 34 6e 05 0f c9 c6 80 5b 6f bc 5a    ....4n.....[o.Z
 
   0070  00 f0 08 c8 34 6e 05 0f c9 c6 80 5b 6f bc 5a    ....4n.....[o.Z
  
It is uncertain how the 3DS determines when it can do a StreetPass again with another 3DS, or what information is actually used to track that. It may be related to how long that 3DS was in range constantly/out of range. 3DSes that are constantly in range of each other in sleepmode, usually do StreetPass every <12 hours?
+
==== Nintendo Tag Format ====
 
 
When in standby mode the old DS WiFi is used, which includes SpotPass and StreetPass, but in "active" mode the regular DSi WiFi bus is used.
 
 
 
=== Nintendo Tag Format ===
 
  
The Nintendo tag always begins at the 0x50 offset if observing a captured frame. The offsets mentioned in the table below start at the beginning of the Nintendo tag ID, which is variable in length.
+
The offsets, in bytes, mentioned in the table below start at the beginning of the Nintendo tag ID, which is variable in length, and can be found right after the Vendor Specific OUI type of the 802.11 frame, which is often seen as a byte of "01". Each one of the elements are discussed in more detail after the table. Note that this table represents a current theory on what each of the fields represent, with the argument stated in the corresponding sections.
  
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 34: Line 62:
 
!  Offset
 
!  Offset
 
!  Length
 
!  Length
 +
!  Purpose
 
!  Description
 
!  Description
 +
!  Example
 +
|-
 +
|  0x00
 +
|  0x01
 +
|  '''Protocol Identification'''
 +
|  May be for protocol identification. All captures thus far show this value at 17, hexadecimal 11.
 +
| 11
 +
|-
 +
|  0x01
 +
|  0x01
 +
|  '''StreetPass Service Length'''
 +
|  Length in bytes of only the StreetPass Services field.
 +
|  05
 +
|-
 +
|  0x02
 +
|  0x05
 +
|  '''StreetPass Services'''
 +
|  Starting at the 0x02 offset, it appears to be a list of StreetPass services, each in length of 5 bytes. This continues on depending on the number of services the user has enabled at the time.
 +
|  00 02 08 00 00
 
|-
 
|-
|  0x0
 
 
|  varies
 
|  varies
|  Unknown, but may include active Streetpass services. This remains static between street passes, reboots, and Settings app interaction.
+
0x02
 +
|  '''Unknown'''
 +
|  At the end of the StreetPass Services field is a two byte field that is the same among all devices thus far. Its purpose is unknown.
 +
|  f0 08
 
|-
 
|-
|  -0x8
+
|  -0x08
0x8
+
0x08
Some random StreetPass ID. Seen to change after every time the Settings app is used. Also may change after each StreetPass hit and system power-off?
+
'''StreetPass consoleID'''
 +
Seen to change when the Settings app is used if there has not been a StreetPass tag recently. Also may change after each StreetPass hit and system power-off?
 +
|  c8 34 6e 05 0f c9 c6 80
 
|}
 
|}
  
==== Identification String ====
+
===== Protocol Version =====
 +
 
 +
Appears to represent a protocol version, or device identification. This field remains consistent on all devices, despite variable enabled StreetPass services or length of the tag. Could also represent region.
 +
 
 +
===== StreetPass Service Length =====
 +
 
 +
This field is used to indicate the length of the StreetPass Services field. Removing and adding services has shown this field to increment and decrement in 5 bytes, or 11 bytes depending on the game. The StreetPass Services field has then expanded or reduced accordingly.
 +
 
 +
===== StreetPass Services =====
 +
 
 +
The third field in the protocol header appears to be an arbitrary length list of StreetPass services enabled on the device. Each StreetPass service seems to be identified by a 5-byte ID. If you enable or disable services, the number of 5-byte IDs grows and shrinks within this list. Observed service IDs include:
 +
 
 +
  Mii Plaza: 00 02 08 00 00
 +
  Ridge Racer: 00 03 58 00 30
 +
  Sims 3: 00 03 65 00 30
 +
  Street Fighter: 00 03 05 00 02 (FF FF FF FF FF FF)
 +
 
 +
The first 4 bytes are the titleID of the service, the last byte seems to contain flags.
 +
 
 +
The last byte (flags) have been observed between those possibilities :
 +
 
 +
  00000000
 +
  00000010
 +
  00010000
 +
  00100000
 +
  00110000
 +
  00110010
 +
 
 +
Only the bits 2,5,6 were used.
 +
When set, the bit n°2 indicates the presence of a followinf 6-byte field filled with 0xff.
 +
 
 +
Some services have a 6-byte field succeeding the StreetPass service that is just FF bytes (e.g. FF FF FF FF FF FF). The purpose of these is unknown, although may be used as data for a service, or as separator of some sort for different types of StreetPass services.
 +
 
 +
Observed services (leading titleID 0x00 removed, 6*0xff ignored) on 68K probe requests between 2013-08-24 and 2014-06-29 in various european locations.
  
Unknown at the moment, but the length appears to vary from 3DS to 3DS.
+
The fact that a same titleID can have different flags should be noted.
  
==== StreetPass ID ====
+
  0db6-00100000 5
 +
  0db6-00110000 20
  
When there's a StreetPass hit, and no StreetPass data changed on either of the 3DSes, no data is transferred besides probes? Perhaps there's some ID in the Nintendo tag that gets updated every-time the 3DS' StreetPass data changes? After turning off power, then powering on and entering sleepmode, the MAC doesn't change from prior to power off but the last 8-bytes of the Nintendo tag changes. This tag has been seen to not be sequential over time. After one of the new StreetPass content is handled, (running one of the StreetPass titles etc) the 8bytes in the Nintendo tag changes?
+
{| class="wikitable" border="1"
 +
|-
 +
!  Occurrences
 +
!  TitleID
 +
!  Flags
 +
|-
 +
| 131
 +
| 0208
 +
| 00000000
 +
|-
 +
| 58
 +
| 0516
 +
| 00010000
 +
|-
 +
| 56
 +
| 053f
 +
| 00100000
 +
|-
 +
| 55
 +
| 0306
 +
| 00100000
 +
|-
 +
| 44
 +
| 0862
 +
| 00110000
 +
|-
 +
| 26
 +
| 09f1
 +
| 00110000
 +
|-
 +
| 20
 +
| 0db6
 +
| 00110000
 +
|-
 +
| 18
 +
| 0516
 +
| 00110000
 +
|-
 +
| 18
 +
| 0205
 +
| 00110010
 +
|-
 +
| 17
 +
| 0ec4
 +
| 00110000
 +
|-
 +
| 17
 +
| 0300
 +
| 00110000
 +
|-
 +
| 16
 +
| 055d
 +
| 00110000
 +
|-
 +
| 13
 +
| 08d3
 +
| 00010000
 +
|-
 +
| 13
 +
| 053b
 +
| 00100000
 +
|-
 +
| 12
 +
| 0916
 +
| 00100000
 +
|-
 +
| 12
 +
| 07ad
 +
| 00100000
 +
|-
 +
| 12
 +
| 0306
 +
| 00110000
 +
|-
 +
| 12
 +
| 0300
 +
| 00100000
 +
|-
 +
| 11
 +
| 0916
 +
| 00110000
 +
|-
 +
| 9
 +
| 0b1d
 +
| 00110000
 +
|-
 +
| 8
 +
| 0ec4
 +
| 00100000
 +
|-
 +
| 7
 +
| 080f
 +
| 00110000
 +
|-
 +
| 7
 +
| 07c8
 +
| 00100000
 +
|-
 +
| 6
 +
| 038a
 +
| 00100000
 +
|-
 +
| 5
 +
| 0f30
 +
| 00110000
 +
|-
 +
| 5
 +
| 0db6
 +
| 00100000
 +
|-
 +
| 5
 +
| 0910
 +
| 00110000
 +
|-
 +
| 5
 +
| 0862
 +
| 00100000
 +
|-
 +
| 5
 +
| 053f
 +
| 00110000
 +
|-
 +
| 5
 +
| 0522
 +
| 00110000
 +
|-
 +
| 4
 +
| 07ad
 +
| 00110000
 +
|-
 +
| 3
 +
| 0ae2
 +
| 00110000
 +
|-
 +
| 3
 +
| 09f1
 +
| 00100000
 +
|-
 +
| 3
 +
| 08c5
 +
| 00110000
 +
|-
 +
| 3
 +
| 038c
 +
| 00000000
 +
|-
 +
| 3
 +
| 033b
 +
| 00100000
 +
|-
 +
| 3
 +
| 030b
 +
| 00100000
 +
|-
 +
| 2
 +
| 0ba9
 +
| 00110000
 +
|-
 +
| 2
 +
| 0a53
 +
| 00110000
 +
|-
 +
| 2
 +
| 08d3
 +
| 00100000
 +
|-
 +
| 2
 +
| 07ad
 +
| 00010000
 +
|-
 +
| 2
 +
| 0751
 +
| 00110000
 +
|-
 +
| 2
 +
| 0402
 +
| 00100000
 +
|-
 +
| 1
 +
| 0f82
 +
| 00110000
 +
|-
 +
| 1
 +
| 0f5b
 +
| 00110000
 +
|-
 +
| 1
 +
| 0e7f
 +
| 00110000
 +
|-
 +
| 1
 +
| 0bff
 +
| 00110000
 +
|-
 +
| 1
 +
| 0b1d
 +
| 00100000
 +
|-
 +
| 1
 +
| 0ad6
 +
| 00010000
 +
|-
 +
| 1
 +
| 0a90
 +
| 00110000
 +
|-
 +
| 1
 +
| 0a05
 +
| 00100000
 +
|-
 +
| 1
 +
| 073c
 +
| 00110000
 +
|-
 +
| 1
 +
| 06da
 +
| 00100000
 +
|-
 +
| 1
 +
| 05aa
 +
| 00110000
 +
|-
 +
| 1
 +
| 05a5
 +
| 00110000
 +
|-
 +
| 1
 +
| 053b
 +
| 00110000
 +
|-
 +
| 1
 +
| 04ca
 +
| 00110000
 +
|-
 +
| 1
 +
| 038a
 +
| 00110000
 +
|-
 +
| 1
 +
| 033b
 +
| 00110000
 +
|-
 +
| 1
 +
| 030b
 +
| 00110000
 +
|-
 +
| 1
 +
| 0305
 +
| 00000010
 +
|}
 +
 
 +
===== Unknown 2-byte Field =====
 +
 
 +
The purpose of this field is not known yet. It has remained the same across all devices thus far. The value has always been observed as '''f008'''.
 +
 
 +
===== StreetPass consoleID =====
 +
 
 +
When there's a StreetPass hit, and no StreetPass data changed on either of the 3DSes, no data is transferred besides probes? After turning off power, then powering on and entering sleepmode, the MAC doesn't change from prior to power off but the last 8-bytes of the Nintendo tag changes. This tag has been seen to not be sequential over time. After one of the new StreetPass content is handled, (running one of the StreetPass titles etc) this 8-byte StreetPass consoleID changes?
 +
 
 +
=== Initial Probe Response Frame ===
 +
 
 +
If a 3DS (#2) receives another device's probe request and has not yet tagged that device in an arbitrary amount of time (~12 hours), the receiving 3DS (#2) will respond with a Probe Response frame. The destination MAC address is the StreetPass MAC address of the 3DS (#1) that was transmitting the probe request, while the receiving device sets its StreetPass MAC address as the source address. This is important to note because further exchanges may cease using destination and/or source addresses.
 +
 
 +
In the probe response, the 3DS (#2) appears to offer a channel of 1, 6, or 11. Different channels have been seen offered between the same set of 3DS for each StreetPass. Offered channels, and channel range most likely varies by region.
 +
 
 +
The StreetPass Probe Response frame contains the same Nintendo tag in Probe Requests of the device that is transmitting the Probe Response frame.
 +
 
 +
=== Subsequent Probe Request and Response Frames ===
 +
 
 +
The 3DS (#1) that the Initial Probe Response is directed to will send an 802.11 Action frame back to the device. The sequence numbers at this point stop stepping up by 3, and instead increase by one based from each originating device's SN. It will then send another Probe Request, this time sent directly to the responding 3DS (#2) by specifying its MAC address in the destination field, and setting its own MAC address in the source address field. It also does not have a SSID specified in the frame, except the frame will contain a BSSID with the value of the 3DS (#2) that responded to the initial Probe, and thus acts as the master in the 802.11 exchange.
 +
 
 +
== StreetPass Spoofing ==
 +
 
 +
A streetpass "AP" was spoofed with hostapd by setting the SSID to "Nintendo_3DS_continuous_scan_000", with the extra Nintendo tag from another 3DS' probe request. Like 3DS<>3DS communications, the 3DS didn't authenticate or associate with the host. Streetpass communications use CCMP encryption. Eventually the 3DS stops communicating with the host since the host doesn't reply to any of the data frames, then sends a 802.11 "Action" frame, with category ID 0x7f and Nintendo's vendor ID: 00 1f 32.(However the 3DS keeps communicating with the above process repeatedly)
 +
Communication with two 3DSes are the same as above except there's actual encrypted data sent to/from both consoles, unlike the fake host.
 +
 
 +
==StreetPass Relay==
 +
This feature was implemented in version [[6.2.0-12]].
 +
 
 +
It was probably controlled over the [[SpotPass#policylist]]. When connecting to a Nintendo Zone Hotspot the console will send an additional GET parameter named ''ap''. Adding the following priority to the policylist will instruct the console to upload its data (The level tag can probably be lower and must not be HIGH).
 +
<pre>
 +
  <Priority>
 +
    <TitleId>0004013000003400</TitleId>
 +
    <TaskId>sprelay</TaskId>
 +
    <Level>HIGH</Level>
 +
    <Persistent>false</Persistent>
 +
    <Revive>false</Revive>
 +
  </Priority>
 +
</pre>
 +
 
 +
In the request body there will be a file named ''spr-meta'' and a file per registered StreetPass game ''spr-slotXX'' where XX is an incrementing number. If the game contains not messages in its outbox so the size of the file would be 0 then no file is created and sent but it will still be listed in the spr-meta file.
 +
 
 +
===spr-meta file===
 +
The spr-meta file is a text file which may contain the following content.
 +
<pre>
 +
slotsize: 5
 +
spr-slot01: 3,000EC400,10664
 +
spr-slot02: 2,0007AD00,3648
 +
spr-slot03: 3,00030000,3804
 +
spr-slot04: 1,00051600,0
 +
spr-slot05: 0,00020800,28228
 +
</pre>
 +
The comma seperated list after each spr-slotXX has the following meaning
 +
{| class=wikitable
 +
|unknown||StreetPass ID (Low title ID of the game. May be from a different region like japan.)||Size of the file in bytes
 +
|}
 +
 
 +
===spr-slotXX files===
 +
These are binary files. They begin a with a header with the follwing structure.
 +
{| class=wikitable
 +
!Offset!!Size!!Description
 +
|-
 +
|0x00||0x04||Magic number 0x00006161
 +
|-
 +
|0x04||0x04||Size of the file in bytes including this header
 +
|-
 +
|0x08||0x04||StreetPass ID (Low title ID of the game. May be from a different region like japan.)
 +
|-
 +
|0x0C||0x04||Unknown. Maybe some version field. Always 0x00000001
 +
|-
 +
|0x10||0x04||Number of messages after this header
 +
|}
  
== StreetPass spoofing ==
 
  
A streetpass "AP" was spoofed on a laptop with hostapd by setting the SSID to "Nintendo_3DS_continuous_scan_000", with the extra Nintendo tag from another 3DS' probe request. The SSID and AP can't be easily spoofed with hostapd for streetpass when 3DS is "active", for the random "ic[kSvm9s@*cYD>/~IEVj\(fGG;qDo8j" strings. The 3DS didn't seem to authenticate or associate with the "AP". Streetpass "AP" comms use '''WPA2''' encryption. Eventually the 3DS stops communicating with the fake "AP" since the AP doesn't understand the sent data,(especially since it's encrypted) and sends a 802.11 "Action" frame, with category ID 0x7f and Nintendo's vendor ID: 00 1f 32.(However the 3DS keeps communicating with the above process repeatedly)
 
Communication with two 3DSes are the same as above except there's encrypted data sent to/from both consoles, unlike the fake "AP".
 
  
 
[[Category:Nintendo Software]]
 
[[Category:Nintendo Software]]

Revision as of 19:59, 12 May 2024

StreetPass is a feature that allows your 3DS to connect with other 3DS consoles using WiFi in standby mode. It can be used to share Mii(s) on Mii Plaza for example. Applications' StreetPass data are stored in the CECD module's NAND savegame, applications can move received StreetPass data to an arbitrary savegame. Wifi infrastructure with APs are used to communicate where the data-frames are encrypted with WPA2 CCMP, like UDS/Download Play.

WiFi Probe Request Frame

Whenever the 3DS is woken from sleep (or turned on), and WiFi is enabled, it sends out a 802.11 Probe Request which include all saved access points, as well a probe to an SSID containing an arbitrary string of data, such as "ic[kSvm9s@*cYD>/~IEVj\(fGG;qDo8j". This string changes at least daily, and most likely every time the device is woken up.

The MAC address used for these probes is the static MAC address found in the System Settings application. Unlike the StreetPass MAC address, it will not change over time. This MAC address OUI also differs from the one used in StreetPass.

CCMP Key

The StreetPass local-WLAN CCMP data-encryption key is generated by the StreetPass CECD module, where the CCMP key is the 16-byte output from encrypting an all-zero block with AES-CTR via PS:EncryptDecryptAes, with keytype6. The CTR is the first 0x10-bytes from a SHA1-HMAC hash. The SHA1-HMAC key is a 17-byte text string including the NULL-terminator, a seperate HMAC key is used for retail/dev-units, this is determined via ENVINFO bit0. The data hashed with SHA1-HMAC is a 0x1C-byte buffer, which is described below.

Hash Block

Offset Size Description
0x0 0x8 8-byte StreetPass consoleID for the host, from the probe frames.
0x8 0x8 8-byte StreetPass consoleID for the client, from the probe frames.
0x10 0x6 MAC address for host.
0x16 0x6 MAC address for client.

StreetPass Exchange

While StreetPass is enabled, the 3DS constantly sends out Probe Requests with an SSID of "Nintendo_3DS_continuous_scan_000". Unlike beacons, which are actively advertising the device's presence, the 3DS is essentially actively looking for other 3DSes. This design is likely to limit impact to non-3DS WiFi capable devices. Each Probe Request contains basic information about that 3DS, including an identifier, and active StreetPass services. If another 3DS is in range, the second 3DS (#2) will respond with a Probe Response, to which the original 3DS (#1), and of the receiving device with every frame thereafter, will respond with an 802.11 Acknowledgement. 3DS(#1) then sends an 802.11 Action frame, as well as an additional Probe Request. The second 3DS sends back another Probe Response that begins the encrypted exchange between the two devices, no authentication/association is done here.

The MAC address used in sleep-mode seems to change every time there's a StreetPass hit, as well as the last 8-bytes(StreetPass consoleID) of the Nintendo tag data. The MAC address + 8-byte StreetPass consoleID is seen to change every time the user enters and exits and Settings application if they have not had a StreetPass in an observed time period of 24 hours. It is uncertain how the 3DS determines when it can do a StreetPass again with another 3DS, or what information is actually used to track that. It may be related to how long that 3DS was in range constantly/out of range. 3DSes that are constantly in range of each other in sleep-mode, usually do StreetPass every 11 hours.

Probe Request Frame

Using Wireshark tool with a WiFi card in monitor mode allow you to see the data used to scan for other 3DS in the range. The below is a broadcast probe request from an 3DS while in standby mode, with SSID "Nintendo_3DS_continuous_scan_000". This SSID remains consistent across all 3DS units. This frame also contains a custom variable length Nintendo tag, which contains information regarding the offered StreetPass services. The sequence numbers for these probe request increment by 3 for every probe, until another 3DS responds with a probe response.

 0000   00 00 1a 00 2f 48 00 00 19 7d 19 de 2a 00 00 00  ..../H...}..*...
 0010   12 16 9e 09 a0 00 c9 02 00 00 40 00 00 00 ff ff  ..........@.....
 0020   ff ff ff ff da 6b f7 22 f3 77 ff ff ff ff ff ff  .....k.".w......
 0030   40 77 00 20 4e 69 6e 74 65 6e 64 6f 5f 33 44 53  @w. Nintendo_3DS
 0040   5f 63 6f 6e 74 69 6e 75 6f 75 73 5f 73 63 61 6e  _continuous_scan
 0050   5f 30 30 30 01 08 82 84 8b 0c 12 96 18 24 32 04  _000.........$2.
 0060   30 48 60 6c dd 15 00 1f 32 01 11 05 00 02 08 00  0H`l....2.......
 0070   00 f0 08 c8 34 6e 05 0f c9 c6 80 5b 6f bc 5a     ....4n.....[o.Z

Nintendo Tag Format

The offsets, in bytes, mentioned in the table below start at the beginning of the Nintendo tag ID, which is variable in length, and can be found right after the Vendor Specific OUI type of the 802.11 frame, which is often seen as a byte of "01". Each one of the elements are discussed in more detail after the table. Note that this table represents a current theory on what each of the fields represent, with the argument stated in the corresponding sections.

Offset Length Purpose Description Example
0x00 0x01 Protocol Identification May be for protocol identification. All captures thus far show this value at 17, hexadecimal 11. 11
0x01 0x01 StreetPass Service Length Length in bytes of only the StreetPass Services field. 05
0x02 0x05 StreetPass Services Starting at the 0x02 offset, it appears to be a list of StreetPass services, each in length of 5 bytes. This continues on depending on the number of services the user has enabled at the time. 00 02 08 00 00
varies 0x02 Unknown At the end of the StreetPass Services field is a two byte field that is the same among all devices thus far. Its purpose is unknown. f0 08
-0x08 0x08 StreetPass consoleID Seen to change when the Settings app is used if there has not been a StreetPass tag recently. Also may change after each StreetPass hit and system power-off? c8 34 6e 05 0f c9 c6 80
Protocol Version

Appears to represent a protocol version, or device identification. This field remains consistent on all devices, despite variable enabled StreetPass services or length of the tag. Could also represent region.

StreetPass Service Length

This field is used to indicate the length of the StreetPass Services field. Removing and adding services has shown this field to increment and decrement in 5 bytes, or 11 bytes depending on the game. The StreetPass Services field has then expanded or reduced accordingly.

StreetPass Services

The third field in the protocol header appears to be an arbitrary length list of StreetPass services enabled on the device. Each StreetPass service seems to be identified by a 5-byte ID. If you enable or disable services, the number of 5-byte IDs grows and shrinks within this list. Observed service IDs include:

 Mii Plaza: 00 02 08 00 00
 Ridge Racer: 00 03 58 00 30
 Sims 3: 00 03 65 00 30
 Street Fighter: 00 03 05 00 02 (FF FF FF FF FF FF)

The first 4 bytes are the titleID of the service, the last byte seems to contain flags.

The last byte (flags) have been observed between those possibilities :

 00000000
 00000010
 00010000
 00100000
 00110000
 00110010

Only the bits 2,5,6 were used. When set, the bit n°2 indicates the presence of a followinf 6-byte field filled with 0xff.

Some services have a 6-byte field succeeding the StreetPass service that is just FF bytes (e.g. FF FF FF FF FF FF). The purpose of these is unknown, although may be used as data for a service, or as separator of some sort for different types of StreetPass services.

Observed services (leading titleID 0x00 removed, 6*0xff ignored) on 68K probe requests between 2013-08-24 and 2014-06-29 in various european locations.

The fact that a same titleID can have different flags should be noted.

 0db6-00100000 5
 0db6-00110000 20
Occurrences TitleID Flags
131 0208 00000000
58 0516 00010000
56 053f 00100000
55 0306 00100000
44 0862 00110000
26 09f1 00110000
20 0db6 00110000
18 0516 00110000
18 0205 00110010
17 0ec4 00110000
17 0300 00110000
16 055d 00110000
13 08d3 00010000
13 053b 00100000
12 0916 00100000
12 07ad 00100000
12 0306 00110000
12 0300 00100000
11 0916 00110000
9 0b1d 00110000
8 0ec4 00100000
7 080f 00110000
7 07c8 00100000
6 038a 00100000
5 0f30 00110000
5 0db6 00100000
5 0910 00110000
5 0862 00100000
5 053f 00110000
5 0522 00110000
4 07ad 00110000
3 0ae2 00110000
3 09f1 00100000
3 08c5 00110000
3 038c 00000000
3 033b 00100000
3 030b 00100000
2 0ba9 00110000
2 0a53 00110000
2 08d3 00100000
2 07ad 00010000
2 0751 00110000
2 0402 00100000
1 0f82 00110000
1 0f5b 00110000
1 0e7f 00110000
1 0bff 00110000
1 0b1d 00100000
1 0ad6 00010000
1 0a90 00110000
1 0a05 00100000
1 073c 00110000
1 06da 00100000
1 05aa 00110000
1 05a5 00110000
1 053b 00110000
1 04ca 00110000
1 038a 00110000
1 033b 00110000
1 030b 00110000
1 0305 00000010
Unknown 2-byte Field

The purpose of this field is not known yet. It has remained the same across all devices thus far. The value has always been observed as f008.

StreetPass consoleID

When there's a StreetPass hit, and no StreetPass data changed on either of the 3DSes, no data is transferred besides probes? After turning off power, then powering on and entering sleepmode, the MAC doesn't change from prior to power off but the last 8-bytes of the Nintendo tag changes. This tag has been seen to not be sequential over time. After one of the new StreetPass content is handled, (running one of the StreetPass titles etc) this 8-byte StreetPass consoleID changes?

Initial Probe Response Frame

If a 3DS (#2) receives another device's probe request and has not yet tagged that device in an arbitrary amount of time (~12 hours), the receiving 3DS (#2) will respond with a Probe Response frame. The destination MAC address is the StreetPass MAC address of the 3DS (#1) that was transmitting the probe request, while the receiving device sets its StreetPass MAC address as the source address. This is important to note because further exchanges may cease using destination and/or source addresses.

In the probe response, the 3DS (#2) appears to offer a channel of 1, 6, or 11. Different channels have been seen offered between the same set of 3DS for each StreetPass. Offered channels, and channel range most likely varies by region.

The StreetPass Probe Response frame contains the same Nintendo tag in Probe Requests of the device that is transmitting the Probe Response frame.

Subsequent Probe Request and Response Frames

The 3DS (#1) that the Initial Probe Response is directed to will send an 802.11 Action frame back to the device. The sequence numbers at this point stop stepping up by 3, and instead increase by one based from each originating device's SN. It will then send another Probe Request, this time sent directly to the responding 3DS (#2) by specifying its MAC address in the destination field, and setting its own MAC address in the source address field. It also does not have a SSID specified in the frame, except the frame will contain a BSSID with the value of the 3DS (#2) that responded to the initial Probe, and thus acts as the master in the 802.11 exchange.

StreetPass Spoofing

A streetpass "AP" was spoofed with hostapd by setting the SSID to "Nintendo_3DS_continuous_scan_000", with the extra Nintendo tag from another 3DS' probe request. Like 3DS<>3DS communications, the 3DS didn't authenticate or associate with the host. Streetpass communications use CCMP encryption. Eventually the 3DS stops communicating with the host since the host doesn't reply to any of the data frames, then sends a 802.11 "Action" frame, with category ID 0x7f and Nintendo's vendor ID: 00 1f 32.(However the 3DS keeps communicating with the above process repeatedly) Communication with two 3DSes are the same as above except there's actual encrypted data sent to/from both consoles, unlike the fake host.

StreetPass Relay

This feature was implemented in version 6.2.0-12.

It was probably controlled over the SpotPass#policylist. When connecting to a Nintendo Zone Hotspot the console will send an additional GET parameter named ap. Adding the following priority to the policylist will instruct the console to upload its data (The level tag can probably be lower and must not be HIGH).

  <Priority>
    <TitleId>0004013000003400</TitleId>
    <TaskId>sprelay</TaskId>
    <Level>HIGH</Level>
    <Persistent>false</Persistent>
    <Revive>false</Revive>
  </Priority>

In the request body there will be a file named spr-meta and a file per registered StreetPass game spr-slotXX where XX is an incrementing number. If the game contains not messages in its outbox so the size of the file would be 0 then no file is created and sent but it will still be listed in the spr-meta file.

spr-meta file

The spr-meta file is a text file which may contain the following content.

slotsize: 5
spr-slot01: 3,000EC400,10664
spr-slot02: 2,0007AD00,3648
spr-slot03: 3,00030000,3804
spr-slot04: 1,00051600,0
spr-slot05: 0,00020800,28228

The comma seperated list after each spr-slotXX has the following meaning

unknown StreetPass ID (Low title ID of the game. May be from a different region like japan.) Size of the file in bytes

spr-slotXX files

These are binary files. They begin a with a header with the follwing structure.

Offset Size Description
0x00 0x04 Magic number 0x00006161
0x04 0x04 Size of the file in bytes including this header
0x08 0x04 StreetPass ID (Low title ID of the game. May be from a different region like japan.)
0x0C 0x04 Unknown. Maybe some version field. Always 0x00000001
0x10 0x04 Number of messages after this header