Changes

5,286 bytes added ,  20:47, 11 April 2024
Line 1: Line 1:  +
{{DEFAULTSORT:dev/crypto}}
 +
[[Category:Wii U Filesystem]]
 
/dev/crypto is the IOSU device node for the cryptographic engine. It can only be opened by the IOSU and it also provides a stripped down library (IOSC) that is implemented on most IOSU modules under the name "crypto_ios_interface".
 
/dev/crypto is the IOSU device node for the cryptographic engine. It can only be opened by the IOSU and it also provides a stripped down library (IOSC) that is implemented on most IOSU modules under the name "crypto_ios_interface".
 
Requests are issued via ioctl()/ioctlv() commands which are then mapped to internal functions inside the IOS-CRYPTO process. This is done using different message queues, each one mapping a subset of commands in a jump table:
 
Requests are issued via ioctl()/ioctlv() commands which are then mapped to internal functions inside the IOS-CRYPTO process. This is done using different message queues, each one mapping a subset of commands in a jump table:
Line 46: Line 48:  
|-
 
|-
 
| 0x01
 
| 0x01
| IOSC_CreateObject()
+
| IOSCError IOSC_CreateObject(u32* key_handle, IOSCObjectType type, IOSCObjectSubType subtype);
 
| IOS_Ioctl(FD, 0x01, in_buf, 0x10, out_buf, 4);
 
| IOS_Ioctl(FD, 0x01, in_buf, 0x10, out_buf, 4);
 
| Creates a new crypto object and returns a handle for it.
 
| Creates a new crypto object and returns a handle for it.
Line 52: Line 54:  
|-
 
|-
 
| 0x02
 
| 0x02
| IOSC_DeleteObject()
+
| IOSCError IOSC_DeleteObject(u32 key_handle);
 
| IOS_Ioctl(FD, 0x02, in_buf, 4, 0, 0);
 
| IOS_Ioctl(FD, 0x02, in_buf, 4, 0, 0);
 
| Deletes a crypto object.
 
| Deletes a crypto object.
Line 58: Line 60:  
|-
 
|-
 
| 0x03
 
| 0x03
| IOSC_ImportSecretKey()
+
| IOSCError IOSC_ImportSecretKey(IOSCSecretKeyHandle importedHandle, IOSCSecretKeyHandle verifyHandle, IOSCSecretKeyHandle decryptHandle, IOSCSecretKeySecurity flag, u8 * signbuffer, u32 signbufferSize, u8 * ivData, u32 ivSize, u8 * keybuffer, u32 keybufferSize);
 
| IOS_Ioctlv(FD, 0x03, 4, 0, vector);
 
| IOS_Ioctlv(FD, 0x03, 4, 0, vector);
 
|  
 
|  
Line 64: Line 66:  
|-
 
|-
 
| 0x04
 
| 0x04
| keyring_deallocate_entry()
+
| IOSCError IOSC_ExportSecretKey(IOSCSecretKeyHandle exportedHandle, IOSCSecretKeyHandle signHandle, IOSCSecretKeyHandle encryptHandle, IOSCSecretKeySecurity security_flag, u8 * signbuffer, u32 signbufferSize, u8 * ivData, u32 ivSize, u8 * keybuffer, u32 keybufferSize);
 
| IOS_Ioctlv(FD, 0x04, 1, 3, vector);
 
| IOS_Ioctlv(FD, 0x04, 1, 3, vector);
 
|  
 
|  
Line 70: Line 72:  
|-
 
|-
 
| 0x05
 
| 0x05
| import_pub_key()
+
| IOSCError IOSC_ImportPublicKey(u8 * publicKeyData, u32 dataSize, u8 * exponent, u32 exponentSize, IOSCPublicKeyHandle publicKeyHandle);
 
| IOS_Ioctlv(FD, 0x05, 3, 0, vector);
 
| IOS_Ioctlv(FD, 0x05, 3, 0, vector);
 
|  
 
|  
Line 76: Line 78:  
|-
 
|-
 
| 0x06
 
| 0x06
| export_root()
+
| IOSCError IOSC_ExportPublicKey(u8 * publicKeyData, u32 dataSize, u8 * exponent, u32 exponentSize, IOSCPublicKeyHandle publicKeyHandle);
 
| IOS_Ioctlv(FD, 0x06, 1, 3, vector);
 
| IOS_Ioctlv(FD, 0x06, 1, 3, vector);
 
|  
 
|  
Line 82: Line 84:  
|-
 
|-
 
| 0x07
 
| 0x07
| compute_shared_key()
+
| IOSCError IOSC_ComputeSharedKey(IOSCSecretKeyHandle privateHandle, IOSCPublicKeyHandle publicHandle, IOSCSecretKeyHandle sharedHandle);
 
| IOS_Ioctl(FD, 0x07, in_buf, 0x10, 0, 0);
 
| IOS_Ioctl(FD, 0x07, in_buf, 0x10, 0, 0);
 
|  
 
|  
Line 88: Line 90:  
|-
 
|-
 
| 0x08
 
| 0x08
| set_device_id()
+
| IOSCError IOSC_SetData(IOSCDataHandle dataHandle, u32 value);
 
| IOS_Ioctlv(FD, 0x08, 2, 0, vector);
 
| IOS_Ioctlv(FD, 0x08, 2, 0, vector);
 
|  
 
|  
Line 94: Line 96:  
|-
 
|-
 
| 0x09
 
| 0x09
| get_device_id()
+
| IOSCError IOSC_GetData(IOSCDataHandle dataHandle, u32 * value);
 
| IOS_Ioctlv(FD, 0x09, 1, 1, vector);
 
| IOS_Ioctlv(FD, 0x09, 1, 1, vector);
 
|  
 
|  
Line 100: Line 102:  
|-
 
|-
 
| 0x0A
 
| 0x0A
| get_key_size()
+
| IOSCError IOSC_GetKeySize(u32 * keySize, IOSCKeyHandle handle);
 
| IOS_Ioctl(FD, 0x0A, in_buf, 4, out_buf, 4);
 
| IOS_Ioctl(FD, 0x0A, in_buf, 4, out_buf, 4);
 
|  
 
|  
Line 106: Line 108:  
|-
 
|-
 
| 0x0B
 
| 0x0B
| get_key_userdata_size()
+
| IOSCError IOSC_GetSignatureSize(u32 * signSize, int handle);
 
| IOS_Ioctl(FD, 0x0B, in_buf, 4, out_buf, 4);
 
| IOS_Ioctl(FD, 0x0B, in_buf, 4, out_buf, 4);
 
|  
 
|  
Line 112: Line 114:  
|-
 
|-
 
| 0x0C
 
| 0x0C
| IOSC_GenerateHash() / IOSC_GenerateHashAsync();
+
| IOSCError IOSC_GenerateHash(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u32 chainingFlag, u8 * hashData, u32 outputSize);</br>int IOSC_GenerateHashAsync(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u32 chainingFlag, u8 * hashData, u32 outputSize, int message_queue_id, IOSRequest* reply);
| IOS_Ioctlv(FD, 0x0C, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0C, 3, 1, vector, queueid, message);
+
| IOS_Ioctlv(FD, 0x0C, 3, 1, vector);</br>IOS_IoctlvAsync(FD, 0x0C, 3, 1, vector, queueid, message);
 
|
 
|
 
| This function has 2 different implementations, one async and the other not.  
 
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0D
 
| 0x0D
| IOSC_Encrypt() / IOSC_EncryptAsync()
+
| IOSCError IOSC_Encrypt(IOSCSecretKeyHandle encryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize);</br>int IOSC_EncryptAsync(IOSCSecretKeyHandle encryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize, int message_queue_id, IOSRequest* reply);
| IOS_Ioctlv(FD, 0x0D, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0D, 3, 1, vector, queueid, message);
+
| IOS_Ioctlv(FD, 0x0D, 3, 1, vector);</br>IOS_IoctlvAsync(FD, 0x0D, 3, 1, vector, queueid, message);
 
|
 
|
 
| This function has 2 different implementations, one async and the other not.  
 
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0E
 
| 0x0E
| IOSC_Decrypt() / IOSC_DecryptAsync()
+
| IOSCError IOSC_Decrypt(IOSCSecretKeyHandle decryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize);</br>int IOSC_DecryptAsync((IOSCSecretKeyHandle decryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize, int message_queue_id, IOSRequest* request);
| IOS_Ioctlv(FD, 0x0E, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0E, 3, 1, vector, queueid, message);
+
| IOS_Ioctlv(FD, 0x0E, 3, 1, vector);</br>IOS_IoctlvAsync(FD, 0x0E, 3, 1, vector, queueid, message);
 
|
 
|
 
| This function has 2 different implementations, one async and the other not.  
 
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0F
 
| 0x0F
| verify_public_key_sign()
+
| IOSCError IOSC_VerifyPublicKeySign(u8 * inputData, u32 inputSize, IOSCPublicKeyHandle publicHandle, u8 * signData, u32 signSize);
 
| IOS_Ioctlv(FD, 0x0F, 3, 0, vector);
 
| IOS_Ioctlv(FD, 0x0F, 3, 0, vector);
 
|  
 
|  
Line 136: Line 138:  
|-
 
|-
 
| 0x10
 
| 0x10
| IOSC_GenerateBlockMAC() / IOSC_GenerateBlockMACAsync()
+
| IOSCError IOSC_GenerateBlockMAC(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u8 * customData, u32 customDataSize, IOSCSecretKeyHandle signerHandle, u32 chainingFlag, u8 * signData, u32 signDataSize);</br>IOSCError IOSC_GenerateBlockMACAsync(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u8 * customData, u32 customDataSize, IOSCSecretKeyHandle signerHandle, u32 chainingFlag, u8 * signData, u32 signDataSize, int message_queue_id, IOSRequest* reply);
| IOS_Ioctlv(FD, 0x10, 4, 1, vector); / IOS_IoctlvAsync(FD, 0x10, 4, 1, vector, queueid, message);
+
| IOS_Ioctlv(FD, 0x10, 4, 1, vector);</br>IOS_IoctlvAsync(FD, 0x10, 4, 1, vector, queueid, message);
 
|  
 
|  
 
| This function has 2 different implementations, one async and the other not.  
 
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x11
 
| 0x11
| verify_cert()
+
| IOSCError IOSC_ImportCertificate(u8 * certData, u32 certSize, IOSCPublicKeyHandle signerHandle, IOSCPublicKeyHandle publicKeyHandle);
 
| IOS_Ioctlv(FD, 0x11, 2, 0, vector);
 
| IOS_Ioctlv(FD, 0x11, 2, 0, vector);
 
|  
 
|  
Line 148: Line 150:  
|-
 
|-
 
| 0x12
 
| 0x12
| get_device_cert()
+
| IOSCError IOSC_GetDeviceCertificate(IOSCEccSignedCert * certificate, u32 certificateSize);
 
| IOS_Ioctl(FD, 0x12, 0, 0, out_buf, 0x180);
 
| IOS_Ioctl(FD, 0x12, 0, 0, out_buf, 0x180);
 
|  
 
|  
Line 154: Line 156:  
|-
 
|-
 
| 0x13
 
| 0x13
| set_title_key_ownership()
+
| IOSCError IOSC_SetOwnership(u32 handle, u32 users);
 
| IOS_Ioctlv(FD, 0x13, 2, 0, vector);
 
| IOS_Ioctlv(FD, 0x13, 2, 0, vector);
 
|  
 
|  
Line 160: Line 162:  
|-
 
|-
 
| 0x14
 
| 0x14
| get_title_key_ownership()
+
| IOSCError IOSC_GetOwnership(u32 handle, u32 * users);
 
| IOS_Ioctlv(FD, 0x14, 1, 1, vector);
 
| IOS_Ioctlv(FD, 0x14, 1, 1, vector);
 
|  
 
|  
Line 166: Line 168:  
|-
 
|-
 
| 0x15
 
| 0x15
| IOSC_GenerateRand()
+
| IOSCError IOSC_GenerateRand(u8 * randBytes, u32 numBytes);
 
| IOS_Ioctl(FD, 0x15, 0, 0, out_buf, out_size);
 
| IOS_Ioctl(FD, 0x15, 0, 0, out_buf, out_size);
 
| Generate random data of an arbitrary size.
 
| Generate random data of an arbitrary size.
Line 172: Line 174:  
|-
 
|-
 
| 0x16
 
| 0x16
| generate_secret_key()
+
| IOSCError IOSC_GenerateKey(IOSCKeyHandle handle);
 
| IOS_Ioctl(FD, 0x16, in_buf, 4, 0, 0);
 
| IOS_Ioctl(FD, 0x16, in_buf, 4, 0, 0);
 
|  
 
|  
Line 178: Line 180:  
|-
 
|-
 
| 0x17
 
| 0x17
| sign()
+
| IOSCError IOSC_GeneratePublicKeySign(u8 * hash, u32 hashLength, IOSCSecretKeyHandle signerHandle, u8 * eccSignature, u32 signatureSize);
 
| IOS_Ioctlv(FD, 0x17, 2, 1, vector);
 
| IOS_Ioctlv(FD, 0x17, 2, 1, vector);
 
|  
 
|  
Line 184: Line 186:  
|-
 
|-
 
| 0x18
 
| 0x18
| IOSC_GenerateCertificate()
+
| IOSCError IOSC_GenerateCertificate(IOSCSecretKeyHandle privateHandle, IOSCCertName certname, IOSCEccSignedCert * certificate, u32 certSize);
 
| IOS_Ioctlv(FD, 0x18, 2, 1, vector);
 
| IOS_Ioctlv(FD, 0x18, 2, 1, vector);
 
|  
 
|  
Line 190: Line 192:  
|-
 
|-
 
| 0x19
 
| 0x19
| Unknown
+
| IOSCError IOSC_CheckDiHashes(u8 * destAddr, u8 * diskRdBuf, u32 h1Index, u32 h2Index, u8 * h3Ptr);
 
| IOS_Ioctl(FD, 0x19, ???, ???, ???, ???);
 
| IOS_Ioctl(FD, 0x19, ???, ???, ???, ???);
 
|  
 
|  
| This command is not mapped by the IOS-CRYPTO process.
+
| This command is not mapped by the IOS-CRYPTO process and has been superseded by IOSC_ReadHashedBlock.
 
|-
 
|-
 
| 0x1A
 
| 0x1A
| odm_encrypt()
+
| odm_encrypt();
 
| IOS_Ioctlv(FD, 0x1A, 3, 2, vector);
 
| IOS_Ioctlv(FD, 0x1A, 3, 2, vector);
 
|  
 
|  
Line 202: Line 204:  
|-
 
|-
 
| 0x1B
 
| 0x1B
| odm_generate_session_key()
+
| odm_generate_session_key();
 
| IOS_Ioctlv(FD, 0x1B, 3, 1, vector);
 
| IOS_Ioctlv(FD, 0x1B, 3, 1, vector);
 
|  
 
|  
Line 208: Line 210:  
|-
 
|-
 
| 0x1C
 
| 0x1C
| get_security_level()
+
| get_security_level();
 
| IOS_Ioctl(FD, 0x1C, 0, 0, out_buf, 4);
 
| IOS_Ioctl(FD, 0x1C, 0, 0, out_buf, 4);
 
| Gets the security level flag from the OTP.  
 
| Gets the security level flag from the OTP.  
Line 214: Line 216:  
|-
 
|-
 
| 0x1D
 
| 0x1D
| cryptoReadHashedBlock()
+
| IOSCError IOSC_ReadHashedBlock(u8 * destAddr, u8 * diskRdBuf, u32 h1Index, u32 h2Index, u8 * h3Ptr);
 
| IOS_Ioctlv(FD, 0x1D, 5, 1, vector);
 
| IOS_Ioctlv(FD, 0x1D, 5, 1, vector);
 
|  
 
|  
Line 220: Line 222:  
|-
 
|-
 
| 0x1E
 
| 0x1E
| read_wii_seeprom_data()
+
| read_wii_seeprom_data();
 
| IOS_Ioctl(FD, 0x1E, 0, 0, out_buf, 0x60);
 
| IOS_Ioctl(FD, 0x1E, 0, 0, out_buf, 0x60);
 
| Reads the old Wii SEEPROM certificate data from OTP's bank 6.
 
| Reads the old Wii SEEPROM certificate data from OTP's bank 6.
Line 226: Line 228:  
|-
 
|-
 
| 0x1F
 
| 0x1F
| generate_wagonu_key()
+
| generate_wagonu_key();
| IOS_Ioctl(FD, 0x1F, ???, ???, ???, ???);
+
| IOS_Ioctl(FD, 0x1F, in_buf, 0x10, 0, 0);
| Generates the 0x12-keyhandle keydata used to encrypt/decrypt data for Wii U to Wii U system transfers.  
+
| Generates the 0x12-keyhandle keydata used to encrypt/decrypt data for Wii U to Wii U system transfers.
|
+
| If in_buf is NULL, a key from SEEPROM is used. If in_buf is not NULL, then it must be a pointer to a user supplied key.
 
|-
 
|-
 
| 0x20
 
| 0x20
| IOSC_EncryptBlocks()
+
| IOSC_EncryptBlocks(IOSCSecretKeyHandle keyHandle, int mode, u8 * ivOrNonce, u32 ivOrNonceSize, u8 * inData, u32 inSize, u8 * outData, u8 * outSize);
 
| IOS_Ioctlv(FD, 0x20, 3, 1, vector);
 
| IOS_Ioctlv(FD, 0x20, 3, 1, vector);
| Software AES encryption, this supports multiple AES-modes(AES-CTR, ...). Used by IOS-PAD to encrypt amiibo data.  
+
| Software AES encryption, this supports multiple AES-modes (AES-CTR, ...). Used by IOS-PAD to encrypt amiibo data.  
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Mode
 +
!  Description
 +
|-
 +
| 0x0
 +
| AES-ECB
 +
|-
 +
| 0x1
 +
| AES-CBC
 +
|-
 +
| 0x2
 +
| AES-CTR
 +
|}
 
|
 
|
 
|-
 
|-
 
| 0x21
 
| 0x21
| IOSC_DecryptBlocks()
+
| IOSC_DecryptBlocks(IOSCSecretKeyHandle keyHandle, int mode, u8 * ivOrNonce, u32 ivOrNonceSize, u8 * inData, u32 inSize, u8 * outData, u8 * outSize);
 
| IOS_Ioctlv(FD, 0x21, 3, 1, vector);
 
| IOS_Ioctlv(FD, 0x21, 3, 1, vector);
 
| Software AES decryption version of the above ioctlv. Used by IOS-PAD to decrypt amiibo data.
 
| Software AES decryption version of the above ioctlv. Used by IOS-PAD to decrypt amiibo data.
Line 244: Line 260:  
|-
 
|-
 
| 0x22
 
| 0x22
| mcp_auth_unk()
+
| set_crypto_thread_priority();
 
| IOS_Ioctl(FD, 0x22, in_buf, 4, 0, 0);
 
| IOS_Ioctl(FD, 0x22, in_buf, 4, 0, 0);
|  
+
| Modifies the IOS-CRYPTO main thread's priority.
 
|  
 
|  
 
|-
 
|-
 
| 0x23
 
| 0x23
| mcp_wagon_archive_unk()
+
| get_wagon_certificate_data();
| IOS_Ioctl(FD, 0x23, in_buf, 0x10, out_buf, 0x200);
+
| IOS_Ioctl(FD, 0x23, in_buf, 0x10, out_buf, out_size);
|  
+
| Gets Wagon certificate data stored inside IOS-CRYPTO.
|  
+
| If the first word in in_buf is 0x00000000, a Root-CA00000003 with 0x400 bytes of size is written to out_buf. If the first word in in_buf is 0x00000001, a Root-CA00000003 MS00000012 with 0x240 bytes of size is written to out_buf.
 
|-
 
|-
 
|}
 
|}
   −
==Key object handles==
+
== Key object handles ==
The above crypto commands use key/crypto object handles. These handles can be either from IOSC_CreateObject(which can then be initialized with import_secret_key in the case of AES), or a built-in handle. The available built-in handles/keyids are listed below.
+
The above crypto commands use key/crypto object handles. These handles can be either from IOSC_CreateObject (which can then be initialized with IOSC_ImportSecretKey in the case of AES), or a built-in handle. The available built-in handles are listed below.
   −
The maximum number of keyobject-handles is 0x80, hence the highest valid keyobject-handle is 0x7F. Keyobject-handles <=0x40 are reserved for built-in handles, the rest are available for user-processes. Commands which write keyobjects' keydata are only allowed to use handles with value >0x40(user-process handles).
+
The maximum number of keyobject-handles is 0x80, hence the highest valid keyobject-handle is 0x7F. Keyobject-handles <=0x40 are reserved for built-in handles, the rest are available for user-processes. Commands which write keyobjects' keydata are only allowed to use handles with value >0x40 (user-process handles).
    
{| class="wikitable sortable"
 
{| class="wikitable sortable"
! ID
+
! Handle
 
! Type
 
! Type
 +
! Owner
 
! Description
 
! Description
 
|-
 
|-
 
| 0x00
 
| 0x00
| ECC-233
+
| ECC-B233
| Unknown private key. Possibly vWii NG ECC key.
+
| IOS-MCP
 +
| IOSC_DEV_SIGNING_KEY_HANDLE
 +
Wii U device private key.
 
|-
 
|-
 
| 0x01
 
| 0x01
 
| NONE
 
| NONE
| Unknown ID (0x04 bytes). Possibly vWii NG ID.
+
| ALL
 +
| IOSC_DEV_ID_HANDLE
 +
Wii U device ID.
 
|-
 
|-
 
| 0x02
 
| 0x02
 
| AES-128
 
| AES-128
| Wii U NAND key.
+
| IOS-FS
 +
| IOSC_FS_ENC_HANDLE
 +
SLC NAND key.
 
|-
 
|-
 
| 0x03
 
| 0x03
| HMAC SHA-1
+
| HMAC-SHA-1
| Wii U NAND HMAC.
+
| IOS-FS
 +
| IOSC_FS_MAC_HANDLE
 +
SLC NAND HMAC key.
 
|-
 
|-
 
| 0x04
 
| 0x04
 
| AES-128
 
| AES-128
| Old Wii common key.
+
| IOS-MCP
 +
| IOSC_COMMON_ENC_HANDLE
 +
Wii common key.
 
|-
 
|-
 
| 0x05
 
| 0x05
 
| AES-128
 
| AES-128
| Wii U RNG key. Used by commands 0x15, 0x16, 0x17 and 0x18.
+
| IOS-MCP
 +
| IOSC_BACKUP_ENC_HANDLE
 +
Wii U backup key.
 +
Used by commands 0x15, 0x16, 0x17 and 0x18.
 
|-
 
|-
 
| 0x06
 
| 0x06
 
| AES-128
 
| AES-128
| Fixed key stored in IOS-CRYPTO's data.
+
| ALL
 +
| IOSC_APP_ENC_HANDLE
 +
Wii SD key.
 
|-
 
|-
 
| 0x07
 
| 0x07
 
| AES-128
 
| AES-128
| Wii U SEEPROM key.
+
| IOS-MCP
 +
| IOSC_BOOTOSVER_ENC_HANDLE
 +
SEEPROM key.
 
|-
 
|-
 
| 0x08
 
| 0x08
 
| NONE
 
| NONE
| Unused.
+
| NONE
 +
| IOSC_CACRLVER_HANDLE
 +
Unused.
 
|-
 
|-
 
| 0x09
 
| 0x09
 
| NONE
 
| NONE
| Unused.
+
| NONE
 +
| IOSC_SIGNERCRLVER_HANDLE
 +
Unused.
 
|-
 
|-
 
| 0x0A
 
| 0x0A
 
| NONE
 
| NONE
| Unused.
+
| NONE
 +
| IOSC_FSVER_HANDLE
 +
Unused.
 
|-
 
|-
 
| 0x0B
 
| 0x0B
| UNK
+
| AES-128
| Unknown (0x10 bytes).
+
| IOS-MCP
 +
| IOSC_COMMON2_ENC_HANDLE
 +
Wii common2 key.
 
|-
 
|-
 
| 0x0C
 
| 0x0C
 
| AES-128
 
| AES-128
| Wii U drive key. Comes from SEEPROM at offset 0x40.
+
| IOS-FS
 +
| Drive key
 
|-
 
|-
 
| 0x0D
 
| 0x0D
 
| AES-128
 
| AES-128
| ARM [[Ancast_Image|Ancast Image]] (this and the below one are for all ARM-ancast images launched via IOS-MCP).
+
| IOS-MCP
 +
| Starbuck [[Ancast_Image|ancast]] key
 
|-
 
|-
 
| 0x0E
 
| 0x0E
| RSA-2048 modulus
+
| RSA-2048
| ARM [[Ancast_Image|Ancast Image]] (stored inside IOS-CRYPTO's data).
+
| IOS-MCP
 +
| Starbuck [[Ancast_Image|ancast]] modulus
 
|-
 
|-
 
| 0x0F
 
| 0x0F
| RSA-2048 modulus
+
| RSA-2048
| Unknown (stored inside IOS-CRYPTO's data).
+
| IOS-MCP
 +
| Boot1 [[Ancast_Image|ancast]] modulus
 
|-
 
|-
 
| 0x10
 
| 0x10
 
| AES-128
 
| AES-128
| Wii U common key.
+
| IOS-MCP
 +
| Wii U common key
 
|-
 
|-
 
| 0x11
 
| 0x11
| UNK
+
| AES-128
| Unknown (0x10 bytes).
+
| IOS-FS
 +
| MLC NAND key
 
|-
 
|-
 
| 0x12
 
| 0x12
 
| AES-128
 
| AES-128
| WagonU and usb-storage key.
+
| IOS-MCP
 +
IOS-FS
 +
| STRM key
 +
Generated by ECB-encrypting the IVS seed from SEEPROM with the IVS key from the OTP.
 +
Used for USB WFS and WagonU file streaming.
 
|-
 
|-
 
| 0x13
 
| 0x13
 
| AES-128
 
| AES-128
| Old Wii NAND key.
+
| IOS-FS
 +
| SLCCMPT NAND key
 
|-
 
|-
 
| 0x14
 
| 0x14
| HMAC SHA-1
+
| HMAC-SHA-1
| Old Wii NAND HMAC.
+
| IOS-FS
 +
| SLCCMPT NAND HMAC key
 
|-
 
|-
 
| 0x15
 
| 0x15
 
| AES-128
 
| AES-128
| vWii common key.
+
| IOS-MCP
 +
| vWii common key
 
|-
 
|-
 
| 0x16
 
| 0x16
 
| AES-128
 
| AES-128
| Key to encrypt DRH WLAN data.
+
| IOS-PAD
 +
| DRH WLAN data key
 
|-
 
|-
 
| 0x17
 
| 0x17
 
| AES-128
 
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (used by IOS-NET).
+
| IOS-NET
 +
| UDS local-WLAN CCMP key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 +
Shared with the 3DS.
 
|-
 
|-
 
| 0x18
 
| 0x18
 
| AES-128
 
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (used by IOS-NET).
+
| IOS-NET
 +
| DLP key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 +
Shared with the 3DS.
 
|-
 
|-
 
| 0x19
 
| 0x19
 
| AES-128
 
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (used by IOS-ACP).
+
| ALL
 +
| APT wrap key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 +
Shared with the 3DS.
 
|-
 
|-
 
| 0x1A
 
| 0x1A
| UNK
+
| AES-128
| Unknown (0x10 bytes).
+
| IOS-FS
 +
| Wii media title key
 
|-
 
|-
 
| 0x1B
 
| 0x1B
 
| AES-128
 
| AES-128
| Key to encrypt/decrypt SSL RSA key.
+
| IOS-NSEC
 +
| SSL RSA key encryption key
 
|-
 
|-
 
| 0x1C
 
| 0x1C
| UNK
+
| ECC-B233
| Unknown (0x1E bytes).
+
| IOS-NSEC
 +
| Wii U device unique certificate private key
 
|-
 
|-
 
| 0x1D
 
| 0x1D
| UNK
+
| ECC-B233
| Unknown (0x1E bytes).
+
| IOS-NSEC
 +
| Wii U device authentication common certificate private key
 
|-
 
|-
 
| 0x1E
 
| 0x1E
 
| AES-128
 
| AES-128
| Unknown (used by IOS-NET).
+
| IOS-NSEC
 +
| APPSTORE objinfo/objdata key
 +
Generated by copying the first 0x10 bytes of the Wii U device unique certificate private key.
 
|-
 
|-
 
| 0x1F
 
| 0x1F
 
| AES-128
 
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (used by IOS-NIM-BOSS).
+
| IOS-NIM-BOSS
 +
| SpotPass data file key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x20
 
| 0x20
| UNK
+
| HMAC-SHA-256
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x40 bytes).
+
| IOS-NIM-BOSS
 +
| SpotPass data file HMAC key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x21
 
| 0x21
| UNK
+
| HMAC-SHA-256
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x40 bytes).
+
| IOS-NIM-BOSS
 +
| VersionList HMAC key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x22
 
| 0x22
| UNK
+
| HMAC-SHA-256
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x40 bytes).
+
| IOS-PAD
 +
| Amiibo HMAC key 1
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x23
 
| 0x23
| UNK
+
| HMAC-SHA-256
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x40 bytes).
+
| IOS-PAD
 +
| Amiibo HMAC key 2
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x24
 
| 0x24
| UNK
+
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x10 bytes).
+
| IOS-PAD
 +
| NFC key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x25
 
| 0x25
| UNK
+
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x10 bytes).
+
| IOS-PAD
 +
| Wii U NFC key block key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 +
Used for decrypting the Wii U specific "unfixed infos" and "locked secret" keys.
 
|-
 
|-
 
| 0x26
 
| 0x26
| UNK
+
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (0x10 bytes).
+
| IOS-FS
 +
| Unknown
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
 
|-
 
|-
 
| 0x27
 
| 0x27
 
| AES-128
 
| AES-128
| Unknown. Generated by XORing the Wii U XOR key and static data inside IOS-CRYPTO (used by IOS-NIM-BOSS).
+
| IOS-NIM-BOSS
 +
| Pushmore link key
 +
Generated by XORing the XOR key with static data inside IOS-CRYPTO
 
|-
 
|-
 
| 0x28
 
| 0x28
| UNK
+
| AES-128
| Unknown (0x10 bytes).
+
| IOS-FS
 +
| SHDD key
 +
This key is only set for board types IH or ID.
 +
If the ShddConfig flag in SEEPROM is 0x0000 and the system is a development unit, it is the same as the MLC NAND key.
 +
If the ShddConfig flag in SEEPROM is 0xFFFF, it is generated by decrypting the SHDD seed from SEEPROM with the SHDD key from eFuses.
 
|-
 
|-
| 0x29 to 0x40
+
| 0x29-0x40
| UNK
+
| NONE
| Unused.
+
| NONE
 +
| Unused
 
|}
 
|}