Editing Kirk
Jump to navigation
Jump to search
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
The PSP KIRK Crypto Engine is a security hardware device that is embedded into the TACHYON main IC chip. It is a bus master and can DMA to/from main DDR RAM memory, operating independantly of the CPU. It is interfaced via memory mapped registers at base of 0xBDE00000 ([[SPOCK Crypto Engine]] on the other hand is mapped to 0xBDF00000). It is capable of performing AES encryption, decryption, SHA1 Hash, pseudo random number generation, and signature generation and verifications (ECDSA) and CMAC. | The PSP KIRK Crypto Engine is a security hardware device that is embedded into the TACHYON main IC chip. It is a bus master and can DMA to/from main DDR RAM memory, operating independantly of the CPU. It is interfaced via memory mapped registers at base of 0xBDE00000 ([[SPOCK Crypto Engine]] on the other hand is mapped to 0xBDF00000). It is capable of performing AES encryption, decryption, SHA1 Hash, pseudo random number generation, and signature generation and verifications (ECDSA) and CMAC. | ||
All (or almost all) the static keys used by the engine (plus the private key for Kirk command 1) have been found through the PS3 hacks or glitching and can be found on the [[Keys]] page. | |||
= Invocation = | = Invocation = | ||
Line 20: | Line 20: | ||
Both use the usual Weierstrass form. | Both use the usual Weierstrass form. | ||
== Elliptic curve for Kirk | == Elliptic curve for Kirk command 1 == | ||
This curve is used for the ECDSA verification of Kirk | This curve is used for the ECDSA verification of Kirk command 1. | ||
<pre> | <pre> | ||
Line 36: | Line 36: | ||
== Elliptic curve for the other commands == | == Elliptic curve for the other commands == | ||
This curved is used for Kirk commands 0xC, 0xD, | This curved is used for Kirk commands 0xC, 0xD, 0x10, 0x11, and likely 0x12. | ||
<pre> | <pre> | ||
Line 46: | Line 46: | ||
</pre> | </pre> | ||
The public key is variable. For the latest Pre-IPL version which add an additional ECDSA verification of the XOR of the block hashes, the public key is (0xBC660611A70BD7F2D140A48215C096D11D2D4112, 0xF0E9379AC4E0D387C542D091349DD15169DD5A87). | |||
== Code sample == | == Code sample == | ||
Line 88: | Line 88: | ||
crv1_g = ecpy.curves.Point(0x2259ACEE15489CB096A882F0AE1CF9FD8EE5F8FA, 0x604358456D0A1CB2908DE90F27D75C82BEC108C0, crv1) | crv1_g = ecpy.curves.Point(0x2259ACEE15489CB096A882F0AE1CF9FD8EE5F8FA, 0x604358456D0A1CB2908DE90F27D75C82BEC108C0, crv1) | ||
assert(crv1.mul_point(crv1.generator, 0xF392E26490B80FD889F2D9722C1F34D7274F983D) == pt1) | assert(crv1.mul_point(crv1.generator, 0xF392E26490B80FD889F2D9722C1F34D7274F983D) == pt1) | ||
</pre> | </pre> | ||
Line 512: | Line 112: | ||
| KIRK_CMD_DECRYPT_BOOTROM | | KIRK_CMD_DECRYPT_BOOTROM | ||
| Decryption of the psp devkit kbooti bootrom (no inverse) | | Decryption of the psp devkit kbooti bootrom (no inverse) | ||
| encrypted kbooti size | | encrypted kbooti bootrom size | ||
| decrypted kbooti bootrom size | | decrypted kbooti bootrom size | ||
| tachsm.o | | tachsm.o | ||
| {{no}} | | {{no}} | ||
| | | slot 0 (AES) and 1 (CMAC) | ||
|- | |- | ||
| 1 | | 1 | ||
Line 523: | Line 123: | ||
| buf_size+0x90 | | buf_size+0x90 | ||
| buf_size | | buf_size | ||
| memlmd, mesg_led | | memlmd, mesg_led | ||
| {{no}} | | {{no}} | ||
| | | slot 2 (AES and CMAC) | ||
|- | |- | ||
| 2 | | 2 | ||
Line 532: | Line 132: | ||
| buf_size+0x90 | | buf_size+0x90 | ||
| buf_size | | buf_size | ||
| | | | ||
| {{yes}} | | {{yes}} | ||
| | | slot 3 (AES) | ||
|- | |- | ||
| 3 | | 3 | ||
Line 541: | Line 141: | ||
| buf_size+0x90 | | buf_size+0x90 | ||
| buf_size | | buf_size | ||
| | | | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 550: | Line 150: | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| chnnlsv, memab | | chnnlsv, memab | ||
| {{no}} | | {{no}} | ||
| | | slot 4 (AES) | ||
|- | |- | ||
| 5 | | 5 | ||
Line 559: | Line 159: | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| | | chnnlsv, psheet since PSP FW 2.81 for PGD, ?openpsid for IDPS Certificates? | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 567: | Line 167: | ||
| Encrypt Operation (inverse of command 9) (key=user-defined) | | Encrypt Operation (inverse of command 9) (key=user-defined) | ||
| buf_size+0x24 | | buf_size+0x24 | ||
| buf_size+ | | buf_size+0x10 | ||
| | | part of the hibernate mode that only the go has | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 577: | Line 177: | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| memlmd, mesg_led,chnnlsv, memab | | memlmd, mesg_led,chnnlsv, memab | ||
| {{no}} | | {{no}} | ||
| | | slot 4 (AES) | ||
|- | |- | ||
| 8 | | 8 | ||
Line 586: | Line 186: | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| | | chnnlsv, psheet since PSP FW 2.81 for PGD | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 593: | Line 193: | ||
| KIRK_CMD_DECRYPT_USER | | KIRK_CMD_DECRYPT_USER | ||
| Decrypt Operation (inverse of command 6) (key=user-defined) | | Decrypt Operation (inverse of command 6) (key=user-defined) | ||
| | | ? | ||
| buf_size | | buf_size | ||
| | | part of the hibernate mode that only the go has | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 601: | Line 201: | ||
| 10 (0xA) | | 10 (0xA) | ||
| KIRK_CMD_PRIV_SIGVRY | | KIRK_CMD_PRIV_SIGVRY | ||
| Private Signature Verify (checks for private SCE | | Private Signature Verify (checks for private SCE sig) | ||
| buf_size+0x90 | | buf_size+0x90 | ||
| 0 | | 0 | ||
Line 613: | Line 213: | ||
| buf_size >= 0x14 | | buf_size >= 0x14 | ||
| 0x14 | | 0x14 | ||
| memlmd, mesg_led, memab | | memlmd, mesg_led, memab | ||
| {{no}} | | {{no}} | ||
| {{no}} | | {{no}} | ||
Line 622: | Line 222: | ||
| 0 | | 0 | ||
| 0x3C | | 0x3C | ||
| memab | | memab | ||
| {{no}} | | {{no}} | ||
| {{no}} | | {{no}} | ||
Line 631: | Line 231: | ||
| 0x3C | | 0x3C | ||
| 0x3C | | 0x3C | ||
| | | | ||
| {{no}} | | {{no}} | ||
| {{no}} | | {{no}} | ||
Line 640: | Line 240: | ||
| 0 | | 0 | ||
| 0x14 | | 0x14 | ||
| mesg_led, chnnlsv, memab, semawm | | mesg_led, chnnlsv, memab, semawm | ||
| {{no}} | | {{no}} | ||
| {{no}} | | {{no}} | ||
|- | |- | ||
| 15 (0xF) | | 15 (0xF) | ||
| | | KIRK_CMD_INIT | ||
| | | Initializes Kirk. As long as Kirk is uninitialized only commands 0 and 15 can be used. | ||
| | | 0 | ||
| | | 0 | ||
| IPL | | IPL | ||
| {{yes}} | | {{yes}} | ||
Line 658: | Line 258: | ||
| 0x34 | | 0x34 | ||
| 0x28 | | 0x28 | ||
| memab | | memab | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
Line 664: | Line 264: | ||
| 17 (0x11) | | 17 (0x11) | ||
| KIRK_CMD_SIGVRY | | KIRK_CMD_SIGVRY | ||
| | | Signature Verification (checks for generated signatures) | ||
| 0x64 | | 0x64 | ||
| 0 | | 0 | ||
| memab | | memab | ||
| {{no}} | | {{no}} | ||
| {{no}} | | {{no}} | ||
Line 673: | Line 273: | ||
| 18 (0x12) | | 18 (0x12) | ||
| KIRK_CMD_CERTVRY | | KIRK_CMD_CERTVRY | ||
| Certificate Verification | | Certificate Verification (IDStorage Certificates CMAC) | ||
| 0xB8 | | 0xB8 | ||
| 0 | | 0 | ||
| openpsid, memab | | openpsid, memab | ||
| {{yes}} | | {{yes}} | ||
| {{no}} | | {{no}} | ||
|} | |} | ||
== Command | == Command 1: decryption and authentication == | ||
=== Overview === | === Overview === | ||
This function is used to both decrypt and verify the signature of the IPL blocks. | |||
There are two versions of this service: AES CMAC Verification, and ECDSA Verification. They use the header section of the input buffer slightly differently. | |||
In both cases, the total header length is 0x90. The first 0x60 bytes depend on the version. The last 0x30 bytes are the same in both cases: | |||
'''Metadata Header Structure (Length 0x30)''': | |||
'''Metadata Header Structure (Length | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Address !! Size !! Description | ! Address !! Size !! Description | ||
|- | |- | ||
| | | 0x60 || 4 || Set to 1 | ||
| | |||
| | |||
|- | |- | ||
| | | 0x64 || 4 || 0 indicates AES CMAC version, 1 indicates ECDSA version | ||
| | |||
| | |||
|- | |- | ||
| 0x68 || 4 || 0 | |||
| 0x68 || 4 || | |||
|- | |- | ||
| 0x6C || 4 || 0 for retail version and 0xFFFFFFFF for dev versions | | 0x6C || 4 || 0 for retail version and 0xFFFFFFFF for dev versions | ||
Line 750: | Line 308: | ||
| 0x74 || 4 || Length of the padding after the header and before the real data | | 0x74 || 4 || Length of the padding after the header and before the real data | ||
|- | |- | ||
| 0x78 || | | 0x78 || 8 || 0 | ||
|} | |} | ||
=== AES CMAC Version === | === AES CMAC Version === | ||
''' | '''Key Header Structure (Length 0x60)''': | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Address !! Size !! Description | ! Address !! Size !! Description | ||
|- | |- | ||
| 0x10 || 16 || CMAC key, encrypted with the | | 0x00 || 16 || Decryption key, encrypted with the Kirk command 1 AES master key | ||
|- | |||
| 0x10 || 16 || CMAC key, encrypted with the Kirk command 1 AES master key | |||
|- | |- | ||
| 0x20 || 16 || Header hash (CMAC) | | 0x20 || 16 || Header hash (CMAC) | ||
Line 769: | Line 329: | ||
|} | |} | ||
==== | ==== Decryption process ==== | ||
The first 0x20 bytes of the Key Header are decrypted with the Kirk command 1 Stored AES Key. This was allegedly discovered by Datel by decapping the chip and reversing engineering the algorithms and keys. This was also recovered through the failure in PS3 cryptography by decrypting the isolated module in the PSP emulator on the PS3. | |||
The first block is the AES Key used for decrypting the main data. The second block is used to decrypt the next two blocks (0x20 bytes at offset 0x20). These represent the Metadata Header CMAC and the Data CMAC. They are checked against the AES CMAC of the metadata header section and the AES CMAC of the whole data, from the metadata header section to the end of the data (including padding in-between). | |||
=== ECDSA Version === | === ECDSA Version === | ||
Line 785: | Line 341: | ||
|- | |- | ||
! Address !! Size !! Description | ! Address !! Size !! Description | ||
|- | |||
| 0x00 || 0x10 || Decryption key, encrypted with the Kirk command 1 AES master key | |||
|- | |- | ||
| 0x10 || 0x14 || Header ECDSA signature r | | 0x10 || 0x14 || Header ECDSA signature r | ||
Line 795: | Line 353: | ||
|} | |} | ||
==== | ==== Decryption process ==== | ||
The ECDSA version is slightly different. | The ECDSA version is slightly different. Only the first block (0x10 bytes) is decrypted with the Kirk command 1 AES Key. It is used to decrypt the main data section just as in the AES CMAC version. Rather than a CMAC, the Metadata header is checked by SHA1 hashing its 0x30 bytes and checking the signature components through a ECDSA Verify call. The encrypted Data section is also checked via SHA1 of the entire data through a ECDSA Verify call. | ||
The ECDSA curve parameters are indicated above. | |||
== Commands 2 & 3: DRM encrypt & decrypt == | |||
These commands are mostly unknown. The header is the same as Kirk command 1, with the mode set to 2 or 3. | |||
In command 2, the input data passed to Kirk is first checked (presumably CMAC), then decrypted, and re-encrypted with the console unique private key. | |||
Having that common key would allow legit creation of DRM BB install packages. | |||
Command 3 is the decryption counterpart of command 2. | |||
== Commands 4~9: AES encrypt & decrypt == | == Commands 4~9: AES encrypt & decrypt == | ||
All these commands do AES128-CBC encryption/decryption with an IV equal to 0. | All these commands do AES128-CBC encryption/decryption with an IV equal to 0. | ||
- Commands 4 (encryption) and 7 (decryption) use a one of the 128 keys stored in the Kirk chip and available on the [[Keys]] page, index being given by the keyseed field (which must be between 0x00 and 0x7F) | |||
- Commands 5 (encryption) and 8 (decryption) use an unknown per-console key (it is unknown if it is derived from other data, or just stored as-is on the chip) | |||
- Commands 6 (encryption) and 9 (decryption) use a key derived from the keyseed using an unknown key derivation function | |||
In all cases, data is prefixed with a 0x14-byte long header: | |||
In all cases, data is prefixed with a 0x14-byte long header | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! Address !! Size !! Description | ! Address !! Size !! Description | ||
|- | |- | ||
| 0x00 || 4 || Mode: must be 4 for encryption | | 0x00 || 4 || Mode: must be 4 for encryption, 5 for decryption | ||
|- | |- | ||
| 0x04 || 8 || | | 0x04 || 8 || Unknown (0?) | ||
|- | |- | ||
| 0x0C || | | 0x0C || 4 || Keyseed | ||
| | |||
| | |||
|- | |- | ||
| 0x10 || 4 || Size of the following data | | 0x10 || 4 || Size of the following data | ||
|} | |} | ||
== | == Command 10: AES CMAC verification == | ||
Used to verify IdStorage IDPS certificates. | |||
This seems to be the AES CMAC verification of Kirk command 1, and takes the same header as Command 1, the only difference is that no decryption is performed. | |||
See command 1 information for details. | |||
It could also possibly verify CMACs for commands 2 and 3, but that is unknown. | |||
== Command 11: SHA1 == | |||
== Command | |||
This command computes the SHA1 of the input. The input must be prefixed with a 4-byte header giving the length of the buffer. Output is 0x14-byte long. | This command computes the SHA1 of the input. The input must be prefixed with a 4-byte header giving the length of the buffer. Output is 0x14-byte long. | ||
== Command | == Command 12: ECDSA key pair generation == | ||
This command generates a random private key and computes the associated public key. See above for the parameters of the elliptic curve. | This command generates a random private key and computes the associated public key. See above for the parameters of the elliptic curve. | ||
Line 914: | Line 412: | ||
*0x28 - Public Key point y value | *0x28 - Public Key point y value | ||
== Command | == Command 13: ECDSA point multiplication == | ||
This command multiplies an elliptic curve point by a scalar. See above for the parameters of the elliptic curve. | This command multiplies an elliptic curve point by a scalar. See above for the parameters of the elliptic curve. | ||
Line 927: | Line 425: | ||
*0x14 - point y value (kP).y | *0x14 - point y value (kP).y | ||
The result is a new point (x and y are each 0x14 bytes long). | The result is a new point(x and y are each 0x14 bytes long). | ||
== Command | == Command 14: PRNG == | ||
This function takes no input and generates | This function takes no input and generates random data of the given size (depending on the specified size of the output buffer). | ||
== Command | == Command 15: Init == | ||
This function takes no input and no output. | |||
Kirk initialization. | |||
== Command 16: ECDSA signature generation == | |||
This command generates an ECDSA signature of a SHA1 hash (0x14 buffer) using an encrypted private key. | |||
Input is: | |||
*0x00: 0x20-byte long encrypted buffer containing the private key | |||
*0x20: the message hash. | |||
The output is a 0x28-byte long signature (r and s, both 0x14-byte long). | |||
The | |||
The private key buffer is encrypted with a device-specific encryption using the FuseID. | |||
Here is the code of the decryption, thanks to Davee & Proxima. g_fuse90 and g_fuse94 are the two words composing the FuseID (present at the 0xBC100090 and 0xBC100094 hardware registers). | |||
Output is 0x20-byte long, but the last 0xC bytes are ignored (and possibly always equal to zero) for the private key. | |||
*0x20 | <pre> | ||
void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc) | |||
{ | |||
int i, k; | |||
kirk16_data keydata; | |||
u8 subkey_1[0x10], subkey_2[0x10]; | |||
rijndael_ctx aes_ctx; | |||
keydata.fuseid[7] = g_fuse90 &0xFF; | |||
keydata.fuseid[6] = (g_fuse90>>8) &0xFF; | |||
keydata.fuseid[5] = (g_fuse90>>16) &0xFF; | |||
keydata.fuseid[4] = (g_fuse90>>24) &0xFF; | |||
keydata.fuseid[3] = g_fuse94 &0xFF; | |||
keydata.fuseid[2] = (g_fuse94>>8) &0xFF; | |||
keydata.fuseid[1] = (g_fuse94>>16) &0xFF; | |||
keydata.fuseid[0] = (g_fuse94>>24) &0xFF; | |||
/* set encryption key */ | |||
rijndael_set_key(&aes_ctx, kirk16_key, 128); | |||
/* set the subkeys */ | |||
for (i = 0; i < 0x10; i++) | |||
{ | |||
/* set to the fuseid */ | |||
subkey_2[i] = subkey_1[i] = keydata.fuseid[i % 8]; | |||
} | |||
/* do aes crypto */ | |||
for (i = 0; i < 3; i++) | |||
{ | |||
/* encrypt + decrypt */ | |||
rijndael_encrypt(&aes_ctx, subkey_1, subkey_1); | |||
rijndael_decrypt(&aes_ctx, subkey_2, subkey_2); | |||
} | |||
/* set new key */ | |||
rijndael_set_key(&aes_ctx, subkey_1, 128); | |||
/* now lets make the key mesh */ | |||
for (i = 0; i < 3; i++) | |||
{ | |||
/* do encryption in group of 3 */ | |||
for (k = 0; k < 3; k++) | |||
{ | |||
/* crypto */ | |||
rijndael_encrypt(&aes_ctx, subkey_2, subkey_2); | |||
} | |||
/* copy to out block */ | |||
memcpy(&keydata.mesh[i * 0x10], subkey_2, 0x10); | |||
} | |||
/* set the key to the mesh */ | |||
rijndael_set_key(&aes_ctx, &keydata.mesh[0x20], 128); | |||
/* do the encryption routines for the aes key */ | |||
for (i = 0; i < 2; i++) | |||
{ | |||
/* encrypt the data */ | |||
rijndael_encrypt(&aes_ctx, &keydata.mesh[0x10], &keydata.mesh[0x10]); | |||
} | |||
/* set the key to that mesh shit */ | |||
rijndael_set_key(&aes_ctx, &keydata.mesh[0x10], 128); | |||
/* cbc decrypt the dA */ | |||
AES_cbc_decrypt((AES_ctx *)&aes_ctx, dA_enc, dA_out, 0x20); | |||
} | |||
</pre> | |||
== Command | == Command 17: ECDSA signature verification == | ||
This command verifies an ECDSA signature | This command verifies an ECDSA signature using the ECDSA curve described above. | ||
It takes no output, and takes as an input: | It takes no output, and takes as an input: | ||
Line 978: | Line 533: | ||
* 0x50: signature s | * 0x50: signature s | ||
The result of the operation is given by the return value (0 on success, | The result of the operation is given by the return value (0 on success, 5 on failure to verify the signature). | ||
== Command 18: verify certificate == | |||
This command has most likely no output header. | |||
It takes as an input a 0xB8-long buffer: | |||
*0x00: certificate data (either ConsoleID or OpenPSID) | |||
*0x10: certificate public key (x and y) | |||
*0x38: ECDSA signature (r and s) | |||
*0x60: ECDSA public key used for the signature | |||
*0x88: certificate encrypted private key (padded) | |||
*0xA8: AES-CMAC hash of the rest of the header. | |||
Details are on PS Vita wiki. See also DespertarDelCementerio and CEX2DEX programs source codes. | |||
= Error codes = | = Error codes = | ||
Line 1,002: | Line 555: | ||
0×01: Kirk not enabled | 0×01: Kirk not enabled | ||
0×02: Invalid mode | 0×02: Invalid mode | ||
0×03: Invalid header | 0×03: Invalid header digest | ||
0×04: Invalid data | 0×04: Invalid data digest | ||
0×05: Invalid | 0×05: Invalid signature | ||
0x0C: | 0x0C: isInCriticalSection violation | ||
0x0D: Invalid operation (out of 1-18 range) | 0x0D: Invalid operation (out of 1-18 range) | ||
0x0E: Invalid | 0x0E: Invalid seed/code (cipher operations) | ||
0x0F: Invalid | 0x0F: Invalid ?header size? (cipher operations) | ||
0×10: Invalid data size (equals 0) (sign/cipher operations) | 0×10: Invalid data size (equals 0) (sign/cipher operations) | ||
</pre> | </pre> | ||
Line 1,024: | Line 577: | ||
= Open problems = | = Open problems = | ||
* The private key corresponding to the latest version | * The private key corresponding to the latest version PRE-IPL public key is unknown. | ||
* | * Commands 2, 3, 5, 6, 8, and 9 are mostly unknown and need testing/documentation. | ||