In memory of Ben “bushing” Byer, who passed away on Monday, February 8th, 2016.

Difference between revisions of "/dev/crypto"

From WiiUBrew
Jump to navigation Jump to search
Line 49: Line 49:
 
| 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.
|  
+
|
 
|-
 
|-
 
| 0x02
 
| 0x02
Line 114: Line 114:
 
| IOSC_GenerateHash() / IOSC_GenerateHashAsync();
 
| IOSC_GenerateHash() / IOSC_GenerateHashAsync();
 
| IOS_Ioctlv(FD, 0x0C, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0C, 3, 1, vector, queueid, message);
 
| 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.
+
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0D
 
| 0x0D
 
| IOSC_Encrypt() / IOSC_EncryptAsync()
 
| IOSC_Encrypt() / IOSC_EncryptAsync()
 
| IOS_Ioctlv(FD, 0x0D, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0D, 3, 1, vector, queueid, message);
 
| 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.
+
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0E
 
| 0x0E
 
| IOSC_Decrypt() / IOSC_DecryptAsync()
 
| IOSC_Decrypt() / IOSC_DecryptAsync()
 
| IOS_Ioctlv(FD, 0x0E, 3, 1, vector); / IOS_IoctlvAsync(FD, 0x0E, 3, 1, vector, queueid, message);
 
| 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.
+
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x0F
 
| 0x0F
Line 139: Line 139:
 
| IOS_Ioctlv(FD, 0x10, 4, 1, vector); / IOS_IoctlvAsync(FD, 0x10, 4, 1, vector, queueid, message);
 
| 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.
+
| This function has 2 different implementations, one async and the other not.  
 
|-
 
|-
 
| 0x11
 
| 0x11
Line 169: Line 169:
 
| 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.
|  
+
|
 
|-
 
|-
 
| 0x16
 
| 0x16
Line 208: Line 208:
 
|-
 
|-
 
| 0x1C
 
| 0x1C
| get_key_type()
+
| get_security_level()
 
| IOS_Ioctl(FD, 0x1C, 0, 0, out_buf, 4);
 
| IOS_Ioctl(FD, 0x1C, 0, 0, out_buf, 4);
| Gets the key type from the OTP. Should always be 0.
+
| Gets the security level flag from the OTP.  
|  
+
|
 
|-
 
|-
 
| 0x1D
 
| 0x1D
Line 220: Line 220:
 
|-
 
|-
 
| 0x1E
 
| 0x1E
| read_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 226:
 
|-
 
|-
 
| 0x1F
 
| 0x1F
| Unknown
+
| generate_wagonu_key()
 
| IOS_Ioctl(FD, 0x1F, ???, ???, ???, ???);
 
| IOS_Ioctl(FD, 0x1F, ???, ???, ???, ???);
| Seems to read eMMC/etc keys for OSv1 from OTP banks 2 and 4.
+
| Generates the WagonU key used to encrypt/decrypt Wii's eMMC data for migration.  
|  
+
|
 
|-
 
|-
 
| 0x20
 
| 0x20
 
| amiibo_encrypt()
 
| amiibo_encrypt()
 
| IOS_Ioctlv(FD, 0x20, 3, 1, vector);
 
| IOS_Ioctlv(FD, 0x20, 3, 1, vector);
|
+
| Encrypts amiibo data.  
| Encrypts amiibo data.
+
|
 
|-
 
|-
 
| 0x21
 
| 0x21
 
| amiibo_decrypt()
 
| amiibo_decrypt()
 
| IOS_Ioctlv(FD, 0x21, 3, 1, vector);
 
| IOS_Ioctlv(FD, 0x21, 3, 1, vector);
|
+
| Decrypts amiibo data.  
| Decrypts amiibo data.
+
|
 
|-
 
|-
 
| 0x22
 
| 0x22
Line 267: Line 267:
 
! Description
 
! Description
 
|-
 
|-
| 13
+
| 0x00
| AES
+
| ECC-233
| ARM [[Ancast_Image|Ancast Image]](this and the below one are for all ARM-ancast images launched via IOS-MCP).
+
| Unknown private key. Possibly vWii NG ECC key.
 +
|-
 +
| 0x01
 +
| NONE
 +
| Unknown ID (0x04 bytes). Possibly vWii NG ID.
 +
|-
 +
| 0x02
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x03
 +
| UNK
 +
| Unknown (0x14 bytes).
 +
|-
 +
| 0x04
 +
| AES-128
 +
| Old Wii common key.
 +
|-
 +
| 0x05
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x06
 +
| AES-128
 +
| Fixed key stored in IOS-CRYPTO's data.
 +
|-
 +
| 0x07
 +
| AES-128
 +
| Wii U SEEPROM key.
 +
|-
 +
| 0x08
 +
| NONE
 +
| Unused.
 
|-
 
|-
| 14
+
| 0x09
 +
| NONE
 +
| Unused.
 +
|-
 +
| 0x0A
 +
| NONE
 +
| Unused.
 +
|-
 +
| 0x0B
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x0C
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x0D
 +
| AES-128
 +
| ARM [[Ancast_Image|Ancast Image]] (this and the below one are for all ARM-ancast images launched via IOS-MCP).
 +
|-
 +
| 0x0E
 +
| RSA-2048 modulus
 +
| ARM [[Ancast_Image|Ancast Image]] (stored inside IOS-CRYPTO's data).
 +
|-
 +
| 0x0F
 
| RSA-2048 modulus
 
| RSA-2048 modulus
| ARM [[Ancast_Image|Ancast Image]]
+
| Unknown (stored inside IOS-CRYPTO's data).
 +
|-
 +
| 0x10
 +
| AES-128
 +
| Wii U common key.
 +
|-
 +
| 0x11
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x12
 +
| AES-128
 +
| WagonU key.
 +
|-
 +
| 0x13
 +
| AES-128
 +
| Old Wii NAND key.
 +
|-
 +
| 0x14
 +
| HMAC SHA-1
 +
| Old Wii NAND HMAC.
 +
|-
 +
| 0x15
 +
| AES-128
 +
| vWii common key.
 +
|-
 +
| 0x16
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x17
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x18
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x19
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x1A
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x1B
 +
| AES-128
 +
| Key to encrypt/decrypt SSL RSA key.
 +
|-
 +
| 0x1C
 +
| UNK
 +
| Unknown (0x1E bytes).
 +
|-
 +
| 0x1D
 +
| UNK
 +
| Unknown (0x1E bytes).
 +
|-
 +
| 0x1E
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x1F
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x20
 +
| UNK
 +
| Unknown (0x40 bytes).
 +
|-
 +
| 0x21
 +
| UNK
 +
| Unknown (0x40 bytes).
 +
|-
 +
| 0x22
 +
| UNK
 +
| Unknown (0x40 bytes).
 +
|-
 +
| 0x23
 +
| UNK
 +
| Unknown (0x40 bytes).
 +
|-
 +
| 0x24
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x25
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x26
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x27
 +
| UNK
 +
| Unknown (0x10 bytes).
 +
|-
 +
| 0x28
 +
| UNK
 +
| Unknown (0x10 bytes).
 
|-
 
|-
| 27
+
| 0x29 to 0x40
| RSA
+
| UNK
| SSL RSA Key
+
| Unused.
 
|}
 
|}

Revision as of 22:23, 25 January 2016

/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 IOSC_CreateObject() IOS_Ioctl(FD, 0x01, in_buf, 0x10, out_buf, 4); Creates a new crypto object and returns a handle for it.
0x02 IOSC_DeleteObject() IOS_Ioctl(FD, 0x02, in_buf, 4, 0, 0); Deletes a crypto object.
0x03 import_secret_key() IOS_Ioctlv(FD, 0x03, 4, 0, vector);
0x04 keyring_deallocate_entry() IOS_Ioctlv(FD, 0x04, 1, 3, vector);
0x05 import_pub_key() IOS_Ioctlv(FD, 0x05, 3, 0, vector);
0x06 export_root() IOS_Ioctlv(FD, 0x06, 1, 3, vector);
0x07 compute_shared_key() IOS_Ioctl(FD, 0x07, in_buf, 0x10, 0, 0);
0x08 set_device_id() IOS_Ioctlv(FD, 0x08, 2, 0, vector);
0x09 get_device_id() IOS_Ioctlv(FD, 0x09, 1, 1, vector);
0x0A get_key_size() IOS_Ioctl(FD, 0x0A, in_buf, 4, out_buf, 4);
0x0B get_key_userdata_size() IOS_Ioctl(FD, 0x0B, in_buf, 4, out_buf, 4);
0x0C IOSC_GenerateHash() / IOSC_GenerateHashAsync(); 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 IOSC_Encrypt() / IOSC_EncryptAsync() 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 IOSC_Decrypt() / IOSC_DecryptAsync() 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 verify_public_key_sign() IOS_Ioctlv(FD, 0x0F, 3, 0, vector);
0x10 hmac() / hmac_async() 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 verify_cert() IOS_Ioctlv(FD, 0x11, 2, 0, vector);
0x12 get_device_cert() IOS_Ioctl(FD, 0x12, 0, 0, out_buf, 0x180);
0x13 set_title_key_ownership() IOS_Ioctlv(FD, 0x13, 2, 0, vector);
0x14 get_title_key_ownership() IOS_Ioctlv(FD, 0x14, 1, 1, vector);
0x15 IOSC_GenerateRand() IOS_Ioctl(FD, 0x15, 0, 0, out_buf, out_size); Generate random data of an arbitrary size.
0x16 generate_secret_key() IOS_Ioctl(FD, 0x16, in_buf, 4, 0, 0);
0x17 sign() IOS_Ioctlv(FD, 0x17, 2, 1, vector);
0x18 IOSC_GenerateCertificate() IOS_Ioctlv(FD, 0x18, 2, 1, vector);
0x19 Unknown IOS_Ioctl(FD, 0x19, ???, ???, ???, ???); This command is not mapped by the IOS-CRYPTO process.
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 cryptoReadHashedBlock() 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, ???, ???, ???, ???); Generates the WagonU key used to encrypt/decrypt Wii's eMMC data for migration.
0x20 amiibo_encrypt() IOS_Ioctlv(FD, 0x20, 3, 1, vector); Encrypts amiibo data.
0x21 amiibo_decrypt() IOS_Ioctlv(FD, 0x21, 3, 1, vector); Decrypts amiibo data.
0x22 mcp_auth_unk() IOS_Ioctl(FD, 0x22, in_buf, 4, 0, 0);
0x23 mcp_wagon_archive_unk() IOS_Ioctl(FD, 0x23, in_buf, 0x10, out_buf, 0x200);

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

ID Type Description
0x00 ECC-233 Unknown private key. Possibly vWii NG ECC key.
0x01 NONE Unknown ID (0x04 bytes). Possibly vWii NG ID.
0x02 UNK Unknown (0x10 bytes).
0x03 UNK Unknown (0x14 bytes).
0x04 AES-128 Old Wii common key.
0x05 UNK Unknown (0x10 bytes).
0x06 AES-128 Fixed key stored in IOS-CRYPTO's data.
0x07 AES-128 Wii U SEEPROM key.
0x08 NONE Unused.
0x09 NONE Unused.
0x0A NONE Unused.
0x0B UNK Unknown (0x10 bytes).
0x0C UNK Unknown (0x10 bytes).
0x0D AES-128 ARM Ancast Image (this and the below one are for all ARM-ancast images launched via IOS-MCP).
0x0E RSA-2048 modulus ARM Ancast Image (stored inside IOS-CRYPTO's data).
0x0F RSA-2048 modulus Unknown (stored inside IOS-CRYPTO's data).
0x10 AES-128 Wii U common key.
0x11 UNK Unknown (0x10 bytes).
0x12 AES-128 WagonU key.
0x13 AES-128 Old Wii NAND key.
0x14 HMAC SHA-1 Old Wii NAND HMAC.
0x15 AES-128 vWii common key.
0x16 UNK Unknown (0x10 bytes).
0x17 UNK Unknown (0x10 bytes).
0x18 UNK Unknown (0x10 bytes).
0x19 UNK Unknown (0x10 bytes).
0x1A UNK Unknown (0x10 bytes).
0x1B AES-128 Key to encrypt/decrypt SSL RSA key.
0x1C UNK Unknown (0x1E bytes).
0x1D UNK Unknown (0x1E bytes).
0x1E UNK Unknown (0x10 bytes).
0x1F UNK Unknown (0x10 bytes).
0x20 UNK Unknown (0x40 bytes).
0x21 UNK Unknown (0x40 bytes).
0x22 UNK Unknown (0x40 bytes).
0x23 UNK Unknown (0x40 bytes).
0x24 UNK Unknown (0x10 bytes).
0x25 UNK Unknown (0x10 bytes).
0x26 UNK Unknown (0x10 bytes).
0x27 UNK Unknown (0x10 bytes).
0x28 UNK Unknown (0x10 bytes).
0x29 to 0x40 UNK Unused.