/dev/crypto

From WiiUBrew
Jump to navigation Jump to search

/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:

0x00: Mapped by the 3rd message queue
0x01: Mapped by the 3rd message queue
0x02: Mapped by the 4th message queue
0x03: Mapped by the 4th message queue
0x04: Mapped by the 4th message queue
0x05: Mapped by the 4th message queue
0x06: Mapped by the 3rd message queue
0x07: Mapped by the 4th message queue
0x08: Mapped by the 4th message queue
0x09: Mapped by the 3rd message queue
0x0A: Mapped by the 3rd message queue
0x0B: Mapped by the 2nd message queue | Mapped by the 4th message queue (async version)
0x0C: Mapped by the 2nd message queue
0x0D: Mapped by the 2nd message queue
0x0E: Mapped by the 4th message queue
0x0F: Mapped by the 2nd message queue | Mapped by the 4th message queue (async version)
0x10: Mapped by the 4th message queue
0x11: Mapped by the 3rd message queue
0x12: Mapped by the 4th message queue
0x13: Mapped by the 4th message queue
0x14: Mapped by the 1st message queue
0x15: Mapped by the 3rd message queue
0x16: Mapped by the 4th message queue
0x17: Mapped by the 4th message queue
0x18: Not mapped
0x19: Mapped by the 2nd message queue
0x1A: Mapped by the 2nd message queue
0x1B: Mapped by the 1st message queue
0x1C: Mapped by the 2nd message queue
0x1D: Mapped by the 1st message queue
0x1E: Mapped by the 1st message queue
0x1F: Mapped by the 4th message queue
0x20: Mapped by the 4th message queue
0x21: Mapped by the 1st message queue
0x22: Mapped by the 3rd message queue

List of functions (ioctl/ioctlv)

Command Function Call Description Notes
0x01 IOSCError IOSC_CreateObject(u32* key_handle, IOSCObjectType type, IOSCObjectSubType subtype); IOS_Ioctl(FD, 0x01, in_buf, 0x10, out_buf, 4); Creates a new crypto object and returns a handle for it.
0x02 IOSCError IOSC_DeleteObject(u32 key_handle); IOS_Ioctl(FD, 0x02, in_buf, 4, 0, 0); Deletes a crypto object.
0x03 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);
0x04 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);
0x05 IOSCError IOSC_ImportPublicKey(u8 * publicKeyData, u32 dataSize, u8 * exponent, u32 exponentSize, IOSCPublicKeyHandle publicKeyHandle); IOS_Ioctlv(FD, 0x05, 3, 0, vector);
0x06 IOSCError IOSC_ExportPublicKey(u8 * publicKeyData, u32 dataSize, u8 * exponent, u32 exponentSize, IOSCPublicKeyHandle publicKeyHandle); IOS_Ioctlv(FD, 0x06, 1, 3, vector);
0x07 IOSCError IOSC_ComputeSharedKey(IOSCSecretKeyHandle privateHandle, IOSCPublicKeyHandle publicHandle, IOSCSecretKeyHandle sharedHandle); IOS_Ioctl(FD, 0x07, in_buf, 0x10, 0, 0);
0x08 IOSCError IOSC_SetData(IOSCDataHandle dataHandle, u32 value); IOS_Ioctlv(FD, 0x08, 2, 0, vector);
0x09 IOSCError IOSC_GetData(IOSCDataHandle dataHandle, u32 * value); IOS_Ioctlv(FD, 0x09, 1, 1, vector);
0x0A IOSCError IOSC_GetKeySize(u32 * keySize, IOSCKeyHandle handle); IOS_Ioctl(FD, 0x0A, in_buf, 4, out_buf, 4);
0x0B IOSCError IOSC_GetSignatureSize(u32 * signSize, int handle); IOS_Ioctl(FD, 0x0B, in_buf, 4, out_buf, 4);
0x0C IOSCError IOSC_GenerateHash(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u32 chainingFlag, u8 * hashData, u32 outputSize);
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);
This function has 2 different implementations, one async and the other not.
0x0D IOSCError IOSC_Encrypt(IOSCSecretKeyHandle encryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize);
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);
This function has 2 different implementations, one async and the other not.
0x0E IOSCError IOSC_Decrypt(IOSCSecretKeyHandle decryptHandle, u8 * ivData, u32 ivSize, u8 * inputData, u32 inputSize, u8 * outputData, u32 outputSize);
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);
This function has 2 different implementations, one async and the other not.
0x0F IOSCError IOSC_VerifyPublicKeySign(u8 * inputData, u32 inputSize, IOSCPublicKeyHandle publicHandle, u8 * signData, u32 signSize); IOS_Ioctlv(FD, 0x0F, 3, 0, vector);
0x10 IOSCError IOSC_GenerateBlockMAC(u8 * context, u32 contextSize, u8 * inputData, u32 inputSize, u8 * customData, u32 customDataSize, IOSCSecretKeyHandle signerHandle, u32 chainingFlag, u8 * signData, u32 signDataSize);
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);
This function has 2 different implementations, one async and the other not.
0x11 IOSCError IOSC_ImportCertificate(u8 * certData, u32 certSize, IOSCPublicKeyHandle signerHandle, IOSCPublicKeyHandle publicKeyHandle); IOS_Ioctlv(FD, 0x11, 2, 0, vector);
0x12 IOSCError IOSC_GetDeviceCertificate(IOSCEccSignedCert * certificate, u32 certificateSize); IOS_Ioctl(FD, 0x12, 0, 0, out_buf, 0x180);
0x13 IOSCError IOSC_SetOwnership(u32 handle, u32 users); IOS_Ioctlv(FD, 0x13, 2, 0, vector);
0x14 IOSCError IOSC_GetOwnership(u32 handle, u32 * users); IOS_Ioctlv(FD, 0x14, 1, 1, vector);
0x15 IOSCError IOSC_GenerateRand(u8 * randBytes, u32 numBytes); IOS_Ioctl(FD, 0x15, 0, 0, out_buf, out_size); Generate random data of an arbitrary size.
0x16 IOSCError IOSC_GenerateKey(IOSCKeyHandle handle); IOS_Ioctl(FD, 0x16, in_buf, 4, 0, 0);
0x17 IOSCError IOSC_GeneratePublicKeySign(u8 * hash, u32 hashLength, IOSCSecretKeyHandle signerHandle, u8 * eccSignature, u32 signatureSize); IOS_Ioctlv(FD, 0x17, 2, 1, vector);
0x18 IOSCError IOSC_GenerateCertificate(IOSCSecretKeyHandle privateHandle, IOSCCertName certname, IOSCEccSignedCert * certificate, u32 certSize); IOS_Ioctlv(FD, 0x18, 2, 1, vector);
0x19 IOSCError IOSC_CheckDiHashes(u8 * destAddr, u8 * diskRdBuf, u32 h1Index, u32 h2Index, u8 * h3Ptr); IOS_Ioctl(FD, 0x19, ???, ???, ???, ???); This command is not mapped by the IOS-CRYPTO process and has been superseded by IOSC_ReadHashedBlock.
0x1A odm_encrypt(); IOS_Ioctlv(FD, 0x1A, 3, 2, vector);
0x1B odm_generate_session_key(); IOS_Ioctlv(FD, 0x1B, 3, 1, vector);
0x1C get_security_level(); IOS_Ioctl(FD, 0x1C, 0, 0, out_buf, 4); Gets the security level flag from the OTP.
0x1D IOSCError IOSC_ReadHashedBlock(u8 * destAddr, u8 * diskRdBuf, u32 h1Index, u32 h2Index, u8 * h3Ptr); IOS_Ioctlv(FD, 0x1D, 5, 1, vector);
0x1E read_wii_seeprom_data(); IOS_Ioctl(FD, 0x1E, 0, 0, out_buf, 0x60); Reads the old Wii SEEPROM certificate data from OTP's bank 6.
0x1F generate_wagonu_key(); 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. 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 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); Software AES encryption, this supports multiple AES-modes (AES-CTR, ...). Used by IOS-PAD to encrypt amiibo data.
Mode Description
0x0 AES-ECB
0x1 AES-CBC
0x2 AES-CTR
0x21 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); Software AES decryption version of the above ioctlv. Used by IOS-PAD to decrypt amiibo data.
0x22 set_crypto_thread_priority(); IOS_Ioctl(FD, 0x22, in_buf, 4, 0, 0); Modifies the IOS-CRYPTO main thread's priority.
0x23 get_wagon_certificate_data(); 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

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).

Handle Type Owner Description
0x00 ECC-B233 IOS-MCP IOSC_DEV_SIGNING_KEY_HANDLE
Wii U device private key.
0x01 NONE ALL IOSC_DEV_ID_HANDLE
Wii U device ID.
0x02 AES-128 IOS-FS IOSC_FS_ENC_HANDLE
SLC NAND key.
0x03 HMAC-SHA-1 IOS-FS IOSC_FS_MAC_HANDLE
SLC NAND HMAC key.
0x04 AES-128 IOS-MCP IOSC_COMMON_ENC_HANDLE
Wii common key.
0x05 AES-128 IOS-MCP IOSC_BACKUP_ENC_HANDLE
Wii U backup key.
Used by commands 0x15, 0x16, 0x17 and 0x18.
0x06 AES-128 ALL IOSC_APP_ENC_HANDLE
Wii SD key.
0x07 AES-128 IOS-MCP IOSC_BOOTOSVER_ENC_HANDLE
SEEPROM key.
0x08 NONE NONE IOSC_CACRLVER_HANDLE
Unused.
0x09 NONE NONE IOSC_SIGNERCRLVER_HANDLE
Unused.
0x0A NONE NONE IOSC_FSVER_HANDLE
Unused.
0x0B AES-128 IOS-MCP IOSC_COMMON2_ENC_HANDLE
Wii common2 key.
0x0C AES-128 IOS-FS Drive key
0x0D AES-128 IOS-MCP Starbuck ancast key
0x0E RSA-2048 IOS-MCP Starbuck ancast modulus
0x0F RSA-2048 IOS-MCP Boot1 ancast modulus
0x10 AES-128 IOS-MCP Wii U common key
0x11 AES-128 IOS-FS MLC NAND key
0x12 AES-128 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 AES-128 IOS-FS SLCCMPT NAND key
0x14 HMAC-SHA-1 IOS-FS SLCCMPT NAND HMAC key
0x15 AES-128 IOS-MCP vWii common key
0x16 AES-128 IOS-PAD DRH WLAN data key
0x17 AES-128 IOS-NET UDS local-WLAN CCMP key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
Shared with the 3DS.
0x18 AES-128 IOS-NET DLP key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
Shared with the 3DS.
0x19 AES-128 ALL APT wrap key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
Shared with the 3DS.
0x1A AES-128 IOS-FS Wii media title key
0x1B AES-128 IOS-NSEC SSL RSA key encryption key
0x1C ECC-B233 IOS-NSEC Wii U device unique certificate private key
0x1D ECC-B233 IOS-NSEC Wii U device authentication common certificate private key
0x1E AES-128 IOS-NSEC APPSTORE objinfo/objdata key
Generated by copying the first 0x10 bytes of the Wii U device unique certificate private key.
0x1F AES-128 IOS-NIM-BOSS SpotPass data file key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x20 HMAC-SHA-256 IOS-NIM-BOSS SpotPass data file HMAC key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x21 HMAC-SHA-256 IOS-NIM-BOSS VersionList HMAC key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x22 HMAC-SHA-256 IOS-PAD Amiibo HMAC key 1
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x23 HMAC-SHA-256 IOS-PAD Amiibo HMAC key 2
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x24 AES-128 IOS-PAD NFC key
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x25 AES-128 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 AES-128 IOS-FS Unknown
Generated by XORing the XOR key with static data inside IOS-CRYPTO.
0x27 AES-128 IOS-NIM-BOSS Pushmore link key
Generated by XORing the XOR key with static data inside IOS-CRYPTO
0x28 AES-128 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-0x40 NONE NONE Unused