NFC services: Difference between revisions
mNo edit summary |
|||
(8 intermediate revisions by 2 users not shown) | |||
Line 259: | Line 259: | ||
= nfp services = | = nfp services = | ||
These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol) | These are used for amiibo support (nfp = Nintendo Figurine Protocol, internal name for amiibo protocol). | ||
Check [[Error codes]] for result codes that these commands may return on error. | |||
== nfp:user == | == nfp:user == | ||
Line 527: | Line 529: | ||
==== GetAll ==== | ==== GetAll ==== | ||
Takes an input [[#DeviceHandle]], a type-0x1A output buffer containing [[#NfpData]], no output. | Takes an input [[#DeviceHandle]], a type-0x1A output buffer containing [[#NfpData]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the internal [[#Amiibo settings]] to the output data. The last write date is not validated here (unlike with [[#GetCommonInfo]]). | |||
==== SetAll ==== | ==== SetAll ==== | ||
Takes an input [[#DeviceHandle]], a type-0x19 input buffer containing [[#NfpData]], no output. | Takes an input [[#DeviceHandle]], a type-0x19 input buffer containing [[#NfpData]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the input data to the internal [[#Amiibo settings]]. No flushing / writing to the amiibo is done in this command. | |||
==== FlushDebug ==== | ==== FlushDebug ==== | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0. | |||
==== BreakTag ==== | ==== BreakTag ==== | ||
Takes an input [[#DeviceHandle]], an input u32 [[#BreakType]], no output. | Takes an input [[#DeviceHandle]], an input u32 [[#BreakType]], no output. | ||
Calls an internal function with the input [[#BreakType]]. This first reads amiibo data (like [[#Mount]] and other commands), then saves the read amiibo in the [[#Backup data]], then depending on the type performs some logic (this changes are thus not saved in the backup), and finally flushes the modified amiibo (writes it to the figurine). | |||
[[#BreakType]] 0 does nothing (it is used as a flushing command, used by many other commands). | |||
[[#BreakType]] 1 breaks the data SHA256 HMAC hash (doing "raw_fmt->data_sha256_hmac_hash[0] ^= 0x80u;", see [[#Amiibo settings]]) | |||
[[#BreakType]] 2 sets the amiibo header magic (see [[#Amiibo settings]]) to 0x00 (which beaks the figurine since this magic is checked to be 0xA5 in several places). | |||
==== ReadBackupData ==== | ==== ReadBackupData ==== | ||
Takes an input [[#DeviceHandle]], a type-0x6 output buffer, and an output u32 (read_size). | Takes an input [[#DeviceHandle]], a type-0x6 output buffer, and an output u32 (read_size). | ||
This reads from the raw [[#Backup data]]. | |||
==== WriteBackupData ==== | ==== WriteBackupData ==== | ||
Takes an input [[#DeviceHandle]], a type-0x5 input buffer, no output. | Takes an input [[#DeviceHandle]], a type-0x5 input buffer, no output. | ||
The buffer size must be less or equal than 0x1FBD20. | This writes directly to the raw [[#Backup data]]. The buffer size must be less or equal than the backup data size (0x1FBD20). | ||
==== WriteNtf ==== | ==== WriteNtf ==== | ||
Line 558: | Line 582: | ||
Takes a PID, an [[AM_services|AppletResourceUserId]], an u64 placeholder for the PID, a type-0x5 input buffer containing an array of [[#RequiredMcuVersionData]], no output. | Takes a PID, an [[AM_services|AppletResourceUserId]], an u64 placeholder for the PID, a type-0x5 input buffer containing an array of [[#RequiredMcuVersionData]], no output. | ||
Internally this is mostly the same for each service | Internally this is mostly the same for each service. | ||
The input PID is internally used to get the process application ID when needed. | |||
=== Finalize* === | === Finalize* === | ||
No input/output. | No input/output. | ||
Internally this is mostly the same for each service | Internally this is mostly the same for each service. | ||
=== ListDevices === | === ListDevices === | ||
Line 580: | Line 606: | ||
=== Mount === | === Mount === | ||
Takes an input [[#DeviceHandle]], an input u32 [[#ModelType]] and an input u32 [[#MountTarget]], no output. | Takes an input [[#DeviceHandle]], an input u32 [[#ModelType]] and an input u32 [[#MountTarget]], no output. | ||
Creates an internal object that manages mounted amiibo data. This step loads the amiibo [[#Raw format]], saves it in [[#Backup data]], and converts/decrypts it internally into a [[#Plain format]]. | |||
=== Unmount === | === Unmount === | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Requires the amiibo to be mounted. Disposes the internal object that manages mounted amiibo data. | |||
=== OpenApplicationArea === | === OpenApplicationArea === | ||
Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output. | Takes an input [[#DeviceHandle]] and an input u32 [[#Access ID]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist (checks the [[#Amiibo flag]]). Just sets an internal flag to 1 if the provided access ID and the application area access ID match. | |||
=== GetApplicationArea === | === GetApplicationArea === | ||
Takes an input [[#DeviceHandle]] and a type-0x6 output buffer, returns an output u32 size. | Takes an input [[#DeviceHandle]] and a type-0x6 output [[#Application area]] data buffer, returns an output u32 size. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]). | |||
Reads the buffer data in the application area and returns the size read from the application area. | Reads the buffer data in the application area and returns the size read from the application area. | ||
=== SetApplicationArea === | === SetApplicationArea === | ||
Takes an input [[#DeviceHandle]] and a type-0x5 input buffer, no output. | Takes an input [[#DeviceHandle]] and a type-0x5 input [[#Application area]] data buffer, no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]). | |||
Writes the buffer data in the application area. The remaining data out of the total 0xD8-bytes is filled with randomly generated bytes. | |||
=== Flush === | === Flush === | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Performs CRC verifications, updates write counters (see [[#Amiibo settings]]) and then calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0. | |||
=== Restore === | === Restore === | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Reloads amiibo data (same internal functions as [[#Mount]]) and writes the data to the amiibo again. If reading the amiibo fails, it tries to load the [[#Raw data]] from the [[#Backup data]]. | |||
=== CreateApplicationArea === | === CreateApplicationArea === | ||
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output. | Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input [[#Application area]] data buffer, no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Sets the new application ID / access ID values (even if an application area already existed), updates CRC values, updates write counters (see [[#Amiibo settings]]), copies input data, fills remaining space with random bytes, and then calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0. | |||
=== GetTagInfo === | === GetTagInfo === | ||
Line 620: | Line 657: | ||
=== GetRegisterInfo === | === GetRegisterInfo === | ||
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]]. | Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfo]]. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the internal [[#Amiibo settings]] to the output info. | |||
=== GetCommonInfo === | === GetCommonInfo === | ||
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]]. | Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#CommonInfo]]. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Converts data from the internal [[#Amiibo settings]] to the output info. The last write date is validated, defaulting it to 2000-1-1 if the validation fails. | |||
=== GetModelInfo === | === GetModelInfo === | ||
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]]. | Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#ModelInfo]]. | ||
Requires the amiibo to be mounted with [[#MountType]] ROM. | |||
Just converts data from the internal [[#Amiibo settings]] to the output info. | |||
=== AttachActivateEvent === | === AttachActivateEvent === | ||
Line 643: | Line 692: | ||
Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]]. | Takes an input [[#DeviceHandle]], returns an output u32 [[#DeviceState]]. | ||
The returned state is | The returned state is mapped from the internal state value through lookup tables. nfp services uses the same table, mifare uses a separate one, and the nfc services use another separate table. | ||
=== GetNpadId === | === GetNpadId === | ||
Line 651: | Line 700: | ||
Takes an input [[#DeviceHandle]], returns an output u32 size. | Takes an input [[#DeviceHandle]], returns an output u32 size. | ||
Returns a hardcoded value of 0xD8. | |||
=== AttachAvailabilityChangeEvent === | === AttachAvailabilityChangeEvent === | ||
Line 659: | Line 708: | ||
=== RecreateApplicationArea === | === RecreateApplicationArea === | ||
Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input buffer, no output. | Takes an input [[#DeviceHandle]], an input u32 [[#Access ID]] and a type-0x5 input [[#Application area]] data buffer, no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM, and the application area to exist and be opened (see [[#OpenApplicationArea]]). | |||
Performs the same logic as [[#SetApplicationArea]] but without checking the current access ID, just overwriting it. | |||
=== Format === | === Format === | ||
Line 668: | Line 719: | ||
=== GetAdminInfo === | === GetAdminInfo === | ||
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]]. | Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#AdminInfo]]. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the internal [[#Amiibo settings]] to the output info. | |||
=== GetRegisterInfoPrivate === | === GetRegisterInfoPrivate === | ||
Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]]. | Takes an input [[#DeviceHandle]] and a type-0x1A output buffer containing a [[#RegisterInfoPrivate]]. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the internal [[#Amiibo settings]] to the output info. | |||
=== SetRegisterInfoPrivate === | === SetRegisterInfoPrivate === | ||
Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]]. | Takes an input [[#DeviceHandle]] and a type-0x19 input buffer containing a [[#RegisterInfoPrivate]]. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just converts data from the input info to the internal [[#Amiibo settings]]. No flushing / writing to the amiibo is done in this command. | |||
=== DeleteRegisterInfo === | === DeleteRegisterInfo === | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
All [[#RegisterInfo]]-related fields in the internal [[#Amiibo settings]] are filled with random bytes, and the amiibo-initialized [[#Amiibo flag]] is removed. Finally, it calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0. | |||
=== DeleteApplicationArea === | === DeleteApplicationArea === | ||
Takes an input [[#DeviceHandle]], no output. | Takes an input [[#DeviceHandle]], no output. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
All [[#Application area]]-related fields in the internal [[#Amiibo settings]] are filled with random bytes, and the corresponding [[#Amiibo flag]] is removed. Finally, it calls internally the same function as [[#BreakTag]] with [[#BreakType]] 0. | |||
=== ExistsApplicationArea === | === ExistsApplicationArea === | ||
Takes an input [[#DeviceHandle]], returns an output u8/bool. | Takes an input [[#DeviceHandle]], returns an output u8/bool. | ||
Requires the amiibo to be mounted with [[#MountType]] RAM. | |||
Just returns whether the corresponding [[#Amiibo flag]] in the internal [[#Amiibo settings]] is set. | |||
= RequiredMcuVersionData = | = RequiredMcuVersionData = | ||
Line 695: | Line 770: | ||
= TestWaveType = | = TestWaveType = | ||
This is u32 enum "nn::nfc::TestWaveType". | This is u32 enum "nn::nfc::TestWaveType". | ||
= MifareKey = | |||
This is a 0x10-byte struct. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || MifareCommand | |||
|- | |||
| 0x1 || 0x1 || Unknown | |||
|- | |||
| 0x2 || 0x6 || Padding | |||
|- | |||
| 0x8 || 0x6 || Key data | |||
|- | |||
| 0xE || 0x2 || Padding | |||
|} | |||
= MifareReadBlockData = | = MifareReadBlockData = | ||
This is "nn::nfc::MifareReadBlockData". This is a 0x18-byte struct. | This is "nn::nfc::MifareReadBlockData". This is a 0x18-byte struct. | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x10 || Data | |||
|- | |||
| 0x10 || 0x1 || Block index | |||
|- | |||
| 0x11 || 0x7 || Padding | |||
|} | |||
= MifareReadBlockParameter = | = MifareReadBlockParameter = | ||
This is "nn::nfc::MifareReadBlockParameter". This is a 0x18-byte struct. | This is "nn::nfc::MifareReadBlockParameter". This is a 0x18-byte struct. | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || Block index | |||
|- | |||
| 0x1 || 0x7 || Padding | |||
|- | |||
| 0x8 || 0x10 || [[#MifareKey]] | |||
|} | |||
= MifareWriteBlockParameter = | = MifareWriteBlockParameter = | ||
This is "nn::nfc::MifareWriteBlockParameter". This is a 0x28-byte struct. | This is "nn::nfc::MifareWriteBlockParameter". This is a 0x28-byte struct. | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x10 || Data | |||
|- | |||
| 0x10 || 0x1 || Block index | |||
|- | |||
| 0x11 || 0x7 || Padding | |||
|- | |||
| 0x18 || 0x10 || [[#MifareKey]] | |||
|} | |||
= State = | = State = | ||
Line 733: | Line 861: | ||
|- | |- | ||
| 5 || Unavailable | | 5 || Unavailable | ||
|} | |} | ||
State 5 is not used/exposed with all nfc commands :it is only used with nfp and mifare, see [[#GetDeviceState]]. | |||
= ModelType = | = ModelType = | ||
Line 750: | Line 878: | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
|- | |- | ||
! | ! Bit || Mask || Description | ||
|- | |- | ||
| 1 || ROM | | 0 || 1 || ROM | ||
|- | |- | ||
| 2 || RAM | | 1 || 2 || RAM | ||
|} | |} | ||
Line 805: | Line 931: | ||
| 0x58 || 0x4 || First write date (see [[#Date]]) | | 0x58 || 0x4 || First write date (see [[#Date]]) | ||
|- | |- | ||
| 0x5C || 0x29 || Amiibo name (NUL-terminated string) | | 0x5C || 0x29 || Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16) | ||
|- | |- | ||
| 0x85 || 0x1 || | | 0x85 || 0x1 || Font region (masked bits from [[#Amiibo settings]]) | ||
|- | |- | ||
| 0x86 || 0x7A || Reserved | | 0x86 || 0x7A || Reserved | ||
Line 839: | Line 965: | ||
! Offset || Size || Description | ! Offset || Size || Description | ||
|- | |- | ||
| 0x0 || | | 0x0 || 0x3 || Character ID (same as in [[#Amiibo ID]]) | ||
|- | |- | ||
| | | 0x3 || 0x1 || Series ID (same as in [[#Amiibo ID]]) | ||
|- | |- | ||
| | | 0x4 || 0x2 || Numbering ID (byte-swapped value in [[#Amiibo ID]]) | ||
|- | |- | ||
| | | 0x6 || 0x1 || NFP type (same as in [[#Amiibo ID]]) | ||
|- | |- | ||
| | | 0x7 || 0x39 || Reserved | ||
|} | |||
= Application area version = | |||
Note: unofficial name. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Value || Description | |||
|- | |||
| 0xFF || Invalid (application area does not exist) | |||
|- | |- | ||
| | | 0 || Nintendo 3DS | ||
|- | |||
| 1 || Nintendo Wii U | |||
|- | |||
| 2 || Nintendo 3DS (v2?) | |||
|- | |||
| 3 || Nintendo Switch | |||
|} | |} | ||
This value corresponds to hex-digit 7 of application IDs (3DS and Wii U title IDs have 0/1 at that position). | |||
NFC computes it by taking (app_id_be >> 36) & 0xF. | |||
Since Switch games do not follow this trend, the application ID in [[#Amiibo settings]] is stored as bswap64(application_id & 0xFFFFFFFF0FFFFFFF | 0x30000000) by [[#CreateApplicationArea]], force-setting the hex-digit (presumably so that older consoles will recognize it). | |||
= AdminInfo = | = AdminInfo = | ||
Line 859: | Line 1,008: | ||
! Offset || Size || Description | ! Offset || Size || Description | ||
|- | |- | ||
| 0x0 || 0x8 || | | 0x0 || 0x8 || Application ID of the game owning the application area (original value, see [[#Amiibo settings]]) | ||
|- | |- | ||
| 0x8 || 0x4 || [[#Access ID]] | | 0x8 || 0x4 || [[#Amiibo settings]] [[#Access ID]] (byte-swapped) | ||
|- | |- | ||
| 0xC || 0x2 || CRC32 change counter | | 0xC || 0x2 || [[#Amiibo settings]] terminal ID CRC32 change counter | ||
|- | |- | ||
| 0xE || 0x1 || | | 0xE || 0x1 || [[#Amiibo settings]] flags, bit-shifted: bit0=[[#Amiibo flag]] bit4 and so on | ||
|- | |- | ||
| 0xF || 0x1 || Unknown, hardcoded to | | 0xF || 0x1 || Unknown, hardcoded to 0x02 (tag type? amiibo version?) | ||
|- | |- | ||
| 0x10 || 0x1 || | | 0x10 || 0x1 || [[#Application area version]] | ||
|- | |- | ||
| 0x11 || 0x7 || Padding | | 0x11 || 0x7 || Padding | ||
Line 889: | Line 1,038: | ||
| 0x44 || 0x4 || First write date (see [[#Date]]) | | 0x44 || 0x4 || First write date (see [[#Date]]) | ||
|- | |- | ||
| 0x48 || 0x29 || Amiibo name (NUL-terminated string) | | 0x48 || 0x29 || Amiibo name (NUL-terminated UTF-8 string, converted from UTF-16) | ||
|- | |- | ||
| 0x71 || 0x1 || | | 0x71 || 0x1 || Font region | ||
|- | |- | ||
| 0x72 || 0x8E || Reserved | | 0x72 || 0x8E || Reserved | ||
Line 898: | Line 1,047: | ||
= NfpData = | = NfpData = | ||
This is "nn::nfp::NfpData". This is a 0x298-byte struct. | This is "nn::nfp::NfpData". This is a 0x298-byte struct. | ||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || [[#Amiibo header]] magic (Always 0xA5) | |||
|- | |||
| 0x1 || 0x1 || Reserved | |||
|- | |||
| 0x2 || 0x2 || [[#Amiibo header]] write counter (byte-swapped) | |||
|- | |||
| 0x4 || 0x4 || [[#Amiibo settings]] terminal ID CRC32 (byte-swapped) | |||
|- | |||
| 0x8 || 0x38 || Reserved | |||
|- | |||
| 0x40 || 0x40 || Same contents as [[#CommonInfo]] | |||
|- | |||
| 0x80 || 0x5C || [[#Amiibo settings]] mii Ver3StoreData, format used in 3DS (see https://www.3dbrew.org/wiki/Mii#Mii_format) | |||
|- | |||
| 0xDC || 0x2 || Padding | |||
|- | |||
| 0xDE || 0x2 || [[#Amiibo settings]] mii CRC16 | |||
|- | |||
| 0xE0 || 0x8 || [[#Amiibo settings]] mii StoreDataExtension | |||
|- | |||
| 0xE8 || 0x4 || First write date (see [[#Date]]) | |||
|- | |||
| 0xEC || 0x16 (2*11) || Amiibo name (NUL-terminated UTF-16 string, byte-swapped from [[#Amiibo settings]]) | |||
|- | |||
| 0x102 || 0x1 || [[#Amiibo settings]] font region | |||
|- | |||
| 0x103 || 0x1 || Unknown, normally zero | |||
|- | |||
| 0x104 || 0x4 || [[#Amiibo settings]] mii CRC32 (byte-swapped) | |||
|- | |||
| 0x108 || 0x14 || [[#Amiibo settings]] unknown 0x14 bytes, normally zero | |||
|- | |||
| 0x11c || 0x64 || Reserved | |||
|- | |||
| 0x180 || 0x8 || [[#Amiibo settings]] modified application ID (byte-swapped) | |||
|- | |||
| 0x188 || 0x4 || [[#Amiibo settings]] [[#Access ID]] (byte-swapped) | |||
|- | |||
| 0x18c || 0x2 || [[#Amiibo settings]] terminal ID CRC32 change counter (byte-swapped) | |||
|- | |||
| 0x18e || 0x1 || [[#Amiibo settings]] flags (bit-shifted, same as with [[#AdminInfo]]) | |||
|- | |||
| 0x18f || 0x1 || Hardcoded to 0x02 (tag type? amiibo version?) | |||
|- | |||
| 0x190 || 0x1 || [[#Application area version]] | |||
|- | |||
| 0x191 || 0x1 || Application ID byte (see [[#Amiibo settings]]) | |||
|- | |||
| 0x192 || 0x2E || Reserved | |||
|- | |||
| 0x1c0 || 0xD8 || [[#Application area]] | |||
|} | |||
= BreakType = | = BreakType = | ||
This is "nn::nfp::BreakType". | This is "nn::nfp::BreakType". For more details, see [[#BreakTag]]. | ||
{| class="wikitable" border="1" | {| class="wikitable" border="1" | ||
Line 906: | Line 1,112: | ||
! Value || Description | ! Value || Description | ||
|- | |- | ||
| 0 || | | 0 || Does no breaking, just flushes | ||
|- | |- | ||
| 1 || | | 1 || Breaks the amiibo data SHA256 HMAC hash (see [[#Plain format]]) | ||
|- | |- | ||
| 2 || | | 2 || Breaks the amiibo header magic (see [[#Amiibo header]]) | ||
|} | |} | ||
= WriteType = | = WriteType = | ||
Line 927: | Line 1,131: | ||
|} | |} | ||
= Access ID = | = Application area = | ||
This is a 0xD8 byte region for per-game amiibo savedata. Only one game may use the application area. | |||
== Access ID == | |||
Access IDs are game-unique u32s used to access the amiibo application area. | Access IDs are game-unique u32s used to access the amiibo application area. | ||
== Nintendo 3DS titles == | |||
For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData. | For a list of Nintendo 3DS access IDs, see https://www.3dbrew.org/wiki/Amiibo#Games_using_Amiibo_AppData. | ||
Line 939: | Line 1,149: | ||
|- | |- | ||
| Splatoon 2 || 0x10162B00 | | Splatoon 2 || 0x10162B00 | ||
|- | |||
| Shovel Knight: Treasure Trove || 0x1016E100 | |||
|- | |- | ||
| The Legend of Zelda: Breath of the Wild || 0x1019C800 | | The Legend of Zelda: Breath of the Wild || 0x1019C800 | ||
Line 948: | Line 1,160: | ||
| The Legend of Zelda: Link's Awakening || 0x3B440400 | | The Legend of Zelda: Link's Awakening || 0x3B440400 | ||
|} | |} | ||
= Backup data = | |||
Note: unofficial name. | |||
Backup data is stored at [[Flash_Filesystem#SystemSaveData|data]]:/nfp_backup.dat. It has a total size of 0x1FBD20 bytes, and has the following format: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x20 || [[#Backup header]] | |||
|- | |||
| 0x20 || 0x7D00 (0x20*1000) || [[#Backup entry header]] array | |||
|- | |||
| 0x7D20 || 0x1F4000 (0x800*1000) || [[#Backup entry data]] array | |||
|} | |||
There is a maximum of 1000 entries. This can be accessed by [[#ReadBackupData]] and [[#WriteBackupData]] commands. | |||
== Backup header == | |||
Note: unofficial name. | |||
This is 0x20 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x2 || Unknown (zero?) | |||
|- | |||
| 0x2 || 0x2 || Entry count | |||
|- | |||
| 0x4 || 0x2 || Next free entry index | |||
|- | |||
| 0x6 || 0x2 || Unknown (zero?) | |||
|- | |||
| 0x8 || 0x8 || Unknown (zero?) | |||
|- | |||
| 0x10 || 0x8 || Unknown (zero?) | |||
|- | |||
| 0x18 || 0x4 || Unknown (zero?) | |||
|- | |||
| 0x1C || 0x4 || CRC32 of the 0x1C bytes above | |||
|} | |||
== Backup entry header == | |||
Note: unofficial name. | |||
This is 0x20 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || UUID length | |||
|- | |||
| 0x1 || 0xA || UUID | |||
|- | |||
| 0xB || 0x1 || Padding | |||
|- | |||
| 0xC || 0x2 || Packed date (when this entry was written) | |||
|- | |||
| 0xE || 0xE || Unknown (zero?) | |||
|- | |||
| 0x1C || 0x4 || CRC32 of the 0x1C bytes above | |||
|} | |||
== Backup entry data == | |||
Note: unofficial name. | |||
This is a 0x800 bytes (per-entry data). | |||
NFC writes here the amiibo [[#Raw format]], while the remaining 0x5E4 bytes are unused. | |||
= Amiibo = | |||
== Raw format == | |||
Note: unofficial name. | |||
This is 0x21C bytes. | |||
This is the raw format initially read by NFC (as well as other amiibo dumping tools). It has the following format: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x8 || [[#NTAG215 data 1]] | |||
|- | |||
| 0x8 || 0x8 || [[#NTAG215 data 2]] | |||
|- | |||
| 0x10 || 0x4 || [[#Amiibo header]] | |||
|- | |||
| 0x14 || 0x20 || Encrypted section 1 | |||
|- | |||
| 0x34 || 0x20 || Tag SHA256 HMAC hash: hash over plain tag data, see [[#Plain format]] | |||
|- | |||
| 0x54 || 0x2C || [[#Amiibo ID entry]] | |||
|- | |||
| 0x80 || 0x20 || Data SHA256 HMAC hash: hash over plain data, see [[#Plain format]] | |||
|- | |||
| 0xA0 || 0x114 || Encrypted section 2 | |||
|- | |||
| 0x1B4 || 0x54 || Encrypted section 3 | |||
|- | |||
| 0x208 || 0x4 || [[#NTAG215 dynamic lock]] | |||
|- | |||
| 0x20C || 0x10 || [[#NTAG215 config]] | |||
|} | |||
All non-NTAG215 fields are specific of amiibo (located in the user memory pages of the tag). For more details on the page layout, see https://www.3dbrew.org/wiki/Amiibo. | |||
The three encrypted sections combined in order (a total of 0x188 bytes) are decrypted to get the [[#Amiibo settings]] and the [[#Application area]], in that order. | |||
== Plain format == | |||
This is 0x21C bytes. | |||
Note: unofficial name. | |||
This format contains reordered and decrypted amiibo data: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x8 || [[#NTAG215 data 2]] | |||
|- | |||
| 0x8 || 0x20 || Data SHA256 HMAC hash: hash over 0x1DF bytes, starting at offset 0x29 ([[#Amiibo header]] write counter) until [[#Amiibo ID entry]] | |||
|- | |||
| 0x28 || 0x4 || [[#Amiibo header]] | |||
|- | |||
| 0x2C || 0xB0 || [[#Amiibo settings]] | |||
|- | |||
| 0xDC || 0xD8 || [[#Application area]] | |||
|- | |||
| 0x1B4 || 0x20 || Tag SHA256 HMAC hash: hash over 0x34 bytes below ([[#NTAG215 data 1]] and [[#Amiibo ID entry]]) | |||
|- | |||
| 0x1D4 || 0x8 || [[#NTAG215 data 1]] | |||
|- | |||
| 0x1DC || 0x2C || [[#Amiibo ID entry]] | |||
|- | |||
| 0x208 || 0x4 || [[#NTAG215 dynamic lock]] | |||
|- | |||
| 0x20C || 0x10 || [[#NTAG215 config]] | |||
|} | |||
When converting from [[#Raw format]] to [[#Plain format]], both SHA256 HMAC hashes are tested, otherwise an error is returned internally. | |||
== NTAG215 data 1 == | |||
This is 0x8 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x8 || NTAG215 9-byte manufacturer serial number (first 8 bytes) | |||
|} | |||
== NTAG215 data 2 == | |||
This is 0x8 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || NTAG215 9-byte manufacturer serial number (last byte) | |||
|- | |||
| 0x1 || 0x1 || Internal | |||
|- | |||
| 0x2 || 0x2 || Static lock bytes | |||
|- | |||
| 0x4 || 0x4 || Capability Container (CC) bytes | |||
|} | |||
NFC checks that the static lock bytes match 0xE00F when converting from [[#Raw format]] to [[#Plain format]]. | |||
== NTAG215 dynamic lock == | |||
This is 0x4 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x3 || Dynamic lock bytes | |||
|- | |||
| 0x3 || 0x1 || RFUI | |||
|} | |||
NFC checks the dynamic lock state when converting from [[#Raw format]] to [[#Plain format]]. | |||
== NTAG215 config == | |||
This is 0x10 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x4 || CFG0 | |||
|- | |||
| 0x4 || 0x4 || CFG1 | |||
|- | |||
| 0x8 || 0x4 || PWD | |||
|- | |||
| 0xC || 0x2 || PACK | |||
|- | |||
| 0xE || 0x2 || RFUI | |||
|} | |||
NFC checks that the CFG0 and CFG1 match 0x4000000 and 0x5F when converting from [[#Raw format]] to [[#Plain format]]. | |||
== Amiibo header == | |||
This is 0x4 bytes. | |||
Note: unofficial name. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || Magic (0xA5) | |||
|- | |||
| 0x1 || 0x2 || Write counter (big-endian) | |||
|- | |||
| 0x3 || 0x1 || Version (0x00) | |||
|} | |||
== Amiibo ID == | |||
This is 0x8 bytes. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x3 || Character ID: bits0-9 = game ID, bits10-15 = character ID, bits16-23 = character variant | |||
|- | |||
| 0x3 || 0x1 || Series ID | |||
|- | |||
| 0x4 || 0x2 || Numbering ID (big-endian) | |||
|- | |||
| 0x6 || 0x1 || NFP type (figurine type) | |||
|- | |||
| 0x7 || 0x1 || Version? (0x02) | |||
|} | |||
== Amiibo ID entry == | |||
This is 0x2C bytes. | |||
Note: unofficial name. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x8 || [[#Amiibo ID]] | |||
|- | |||
| 0x8 || 0x4 || Unknown | |||
|- | |||
| 0xC || 0x20 || Unknown, maybe some hash | |||
|} | |||
== Amiibo flag == | |||
{| class="wikitable" border="1" | |||
|- | |||
! Bit || Mask || Description | |||
|- | |||
| 4 || 0x10 || Initialized in console settings | |||
|- | |||
| 5 || 0x20 || Application area exists (was created by some game) | |||
|} | |||
== Amiibo date == | |||
This is a date packed in 2 bytes: | |||
{| class="wikitable" border="1" | |||
|- | |||
! Bits || Description | |||
|- | |||
| 0-4 || Day | |||
|- | |||
| 5-8 || Month | |||
|- | |||
| 9-15 || Year (relative to 2000) | |||
|} | |||
== Amiibo settings == | |||
This is 0xB0 bytes. | |||
Note: unofficial name. | |||
{| class="wikitable" border="1" | |||
|- | |||
! Offset || Size || Description | |||
|- | |||
| 0x0 || 0x1 || Font region (bits0-3) and [[#Amiibo flag]] (bits4-7) | |||
|- | |||
| 0x1 || 0x1 || Country code ID | |||
|- | |||
| 0x2 || 0x2 || Counter of the times the terminal ID CRC32 has changed (big-endian) | |||
|- | |||
| 0x4 || 0x2 || First write date (big-endian, see [[#Amiibo date]] for format in little-endian) | |||
|- | |||
| 0x6 || 0x2 || Last write date (big-endian, see [[#Amiibo date]] for format in little-endian) | |||
|- | |||
| 0x8 || 0x4 || CRC32 of NFC terminal ID (8 bytes, see below) (big-endian) | |||
|- | |||
| 0xC || 0x14 (2*10) || Amiibo name (UTF16-BE, not null-terminated) | |||
|- | |||
| 0x20 || 0x5C || Mii in Ver3StoreData format, see https://www.3dbrew.org/wiki/Mii#Mii_format | |||
|- | |||
| 0x7C || 0x2 || Unused/padding | |||
|- | |||
| 0x7E || 0x2 || CRC16 of the mii data (0x60 bytes, last 4-bytes zeroed) | |||
|- | |||
| 0x80 || 0x8 || Application ID of the game owning the application area (big-endian) (modified, see [[#Application area version]]) | |||
|- | |||
| 0x88 || 0x2 || Write counter (big-endian) | |||
|- | |||
| 0x8A || 0x4 || Access ID of the game owning the application area (big-endian) | |||
|- | |||
| 0x8E || 0x1 || Application ID byte: (Application ID >> 28) & 0xFF | |||
|- | |||
| 0x8F || 0x1 || Unknown1 | |||
|- | |||
| 0x90 || 0x8 || Mii StoreDataExtension | |||
|- | |||
| 0x98 || 0x14 || Unknown2 | |||
|- | |||
| 0xAC || 0x4 || CRC32 of mii data (Ver3StoreData + pad + CRC16) + Application ID byte + Unknown1 + StoreDataExtension + Unknown2 (total of 0x7E bytes) (big-endian) | |||
|} | |||
The country code ID is zeroed when calling [[#SetRegisterInfoPrivate]]. | |||
The application ID byte contains the original application ID hex-digit (only used for Switch games, see [[#Application area version]]), so it can be to restore the original value (which is needed for [[#GetAdminInfo]]). | |||
The terminal ID is a randomly-generated 8-byte value that is re-generated every time [[#Initialize]] is called (thus every nfc/nfp/mifare session), and saved at [[Flash_Filesystem#SystemSaveData|data]]:/nfc_terminal_id.dat. | |||
= Play report = | |||
In nfp [[#Unmount]] and [[#Format]] commands, and if [[System Settings|setting]] <code>nfp!play_report</code> is true, a [[BCAT services|play report]] is sent with the following fields: <code>Uid</code>, <code>CharacterId</code>, <code>NumberingId</code>, <code>SeriesId</code>, <code>NfpType</code> (from the current [[#Amiibo ID]]), <code>ApplicationId</code>, <code>AccessInfo</code>, <code>DeviceType</code>. | |||
[[Category:Services]] | [[Category:Services]] |