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 | 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 intefaced 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. | ||
= Commands = | = Commands = | ||
On PSP there are | On PSP there are 18 KIRK commands. On PSVita, there are these 18 commands plus some new commands to support bigger keys (192 bits for example). See [https://wiki.henkaku.xyz/vita/F00D_Commands#gcauthmgr_sm.self F00D commands]. | ||
KIRK functions are called with the same 5 arguments (outbuf, outbuf_size, inbuf, inbuf_size, service_number (which is the command ID)). Depending on the service number used, the expectations of the inbuf or outbuf vary and are detailed below. | |||
== Table == | == Table == | ||
Line 505: | Line 16: | ||
! scope="col"| Input size | ! scope="col"| Input size | ||
! scope="col"| Output size | ! scope="col"| Output size | ||
! scope="col"| Result | |||
! scope="col"| Used in | ! scope="col"| Used in | ||
|- | |- | ||
| 1 | | 1 | ||
| KIRK_CMD_DECRYPT_PRIVATE | | KIRK_CMD_DECRYPT_PRIVATE | ||
| Super-Duper decryption (no inverse) | | Super-Duper decryption (no inverse) | ||
| buf_size+ | | buf_size+0x40 | ||
| buf_size | | buf_size | ||
| memlmd, mesg_led | | | ||
| memlmd, mesg_led | |||
|- | |- | ||
| 2 | | 2 | ||
| | | KIRK_CMD_2 | ||
| Encrypt Operation | | Encrypt Operation (inverse of cmd 3) | ||
| | | | ||
| | | | ||
| | | | ||
| | | | ||
|- | |- | ||
| 3 | | 3 | ||
| | | KIRK_CMD_3 | ||
| Decrypt Operation | | Decrypt Operation (inverse of cmd 2) | ||
| | | | ||
| | | | ||
| | | | ||
| | | | ||
|- | |- | ||
| 4 | | 4 | ||
| | | KIRK_CMD_ENCRYPT_IV_0 | ||
| Encrypt Operation (inverse of | | Encrypt Operation (inverse of cmd 7) (IV=0) | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| chnnlsv, memab | | | ||
| chnnlsv, memab | |||
|- | |- | ||
| 5 | | 5 | ||
| | | KIRK_CMD_ENCRYPT_IV_FUSE | ||
| Encrypt Operation (inverse of | | Encrypt Operation (inverse of cmd 8) (IV=FuseID) | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| | | | ||
| chnnlsv, psheet since PSP FW 2.81 for PGD, ?openpsid for IDS Certificates? | |||
|- | |- | ||
| 6 | | 6 | ||
| | | KIRK_CMD_ENCRYPT_IV_USER | ||
| Encrypt Operation (inverse of | | Encrypt Operation (inverse of cmd 9) (IV=UserDefined) | ||
| | | | ||
| | | | ||
| | | | ||
| | |||
| | |||
|- | |- | ||
| 7 | | 7 | ||
| | | KIRK_CMD_DECRYPT_IV_0 | ||
| Decrypt Operation (inverse of | | Decrypt Operation (inverse of cmd 4) (IV=0) | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| memlmd, mesg_led,chnnlsv, memab | | | ||
| memlmd, mesg_led,chnnlsv, memab | |||
|- | |- | ||
| 8 | | 8 | ||
| | | KIRK_CMD_DECRYPT_IV_FUSE | ||
| Decrypt Operation (inverse of | | Decrypt Operation (inverse of cmd 5) (IV=FuseID) | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| buf_size+0x14 | | buf_size+0x14 | ||
| | | | ||
| chnnlsv, psheet since PSP FW 2.81 for PGD | |||
|- | |- | ||
| 9 | | 9 | ||
| | | KIRK_CMD_DECRYPT_IV_USER | ||
| Decrypt Operation (inverse of | | Decrypt Operation (inverse of cmd 6) (IV=UserDefined) | ||
| | | | ||
| | |||
| | | | ||
| | | | ||
| | |||
|- | |- | ||
| 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) | ||
| | | | ||
| | | | ||
| | |||
| | | | ||
|- | |- | ||
| 11 (0xB) | | 11 (0xB) | ||
Line 612: | Line 103: | ||
| SHA1 Hash | | SHA1 Hash | ||
| buf_size >= 0x14 | | buf_size >= 0x14 | ||
| 0x14 | | ?0x14? | ||
| memlmd, mesg_led, memab | | | ||
| memlmd, mesg_led, memab | |||
|- | |- | ||
| 12 (0xC) | | 12 (0xC) | ||
| | | KIRK_CMD_MUL1 | ||
| ECDSA Generate | | ECDSA Generate Keys | ||
| 0 | | 0 | ||
| 0x3C | | 0x3C | ||
| | | | ||
| | | memab | ||
|- | |- | ||
| 13 (0xD) | | 13 (0xD) | ||
| | | KIRK_CMD_MUL2 | ||
| ECDSA Multiply Point | | ECDSA Multiply Point | ||
| 0x3C | | 0x3C | ||
| 0x3C | | 0x3C | ||
| | | | ||
| | | | ||
|- | |- | ||
| 14 (0xE) | | 14 (0xE) | ||
Line 640: | Line 128: | ||
| 0 | | 0 | ||
| 0x14 | | 0x14 | ||
| mesg_led, chnnlsv, memab, semawm | | | ||
| mesg_led, chnnlsv, memab, semawm | |||
|- | |- | ||
| 15 (0xF) | | 15 (0xF) | ||
| | | KIRK_CMD_15 | ||
| | | (absolutely no idea – could be KIRK initialization) | ||
| | | | ||
| | | | ||
| | |||
| IPL | | IPL | ||
|- | |- | ||
| 16 (0x10) | | 16 (0x10) | ||
Line 658: | Line 144: | ||
| 0x34 | | 0x34 | ||
| 0x28 | | 0x28 | ||
| | | | ||
| | | memab | ||
|- | |- | ||
| 17 (0x11) | | 17 (0x11) | ||
| KIRK_CMD_SIGVRY | | KIRK_CMD_SIGVRY | ||
| | | Signature Verification (checks for generated signatures) | ||
| 0x64 | | 0x64 | ||
| 0 | | 0 | ||
| | | | ||
| | | memab | ||
|- | |- | ||
| 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 | |||
|} | |} | ||
== Command | == Command 1: decryption and authentication == | ||
=== Overview === | === Overview === | ||
There are two versions of this service: AES CMAC Verification, and ECDSA Verification. They use the header section of the input buffer slightly differently as follows. | |||
There are two versions of this service: AES CMAC | |||
=== AES CMAC Version === | === AES CMAC Version === | ||
''' | '''Key Header Structure (Length 0x60)''': | ||
*0x00-0x0F is decryption key (but stored encrypted with AES128, is not PLAINTEXT key) | |||
*0x10-0x1F is CMAC key (but again, derived ver not plain) | |||
*0x20-0x2F is header hash (CMAC) | |||
*0x30-0x3F is data hash (CMAC) | |||
*0x40-0x5F is 0 | |||
'''Metadata Header Structure (Length 0x30)''': | |||
*0x60-0x63 is set to 1 to indicate KIRK1 Verification | |||
*0x64-0x67 is 0 to indicate AES CMAC Version | |||
*0x68-0x6B is 0 | |||
*0x6C-0x6F is 0 for retail versions and 0xFFFFFFFF for dev versions | |||
*0x70-0x73 is length of decrypted data | |||
*0x74-0x77 is length of padding after Metadata header before real data starts | |||
*0x78-0x8F is 0 | |||
==== Decryption process ==== | |||
The first 0x20 bytes of the Key Header is decrypted with the KIRK 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 two blocks (0x20 bytes at offset 0) are decrypted with the KIRK 1 AES Key. 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 header section and the AES CMAC of the data section. | |||
=== ECDSA Version === | === ECDSA Version === | ||
'''Key Header Structure (Length 0x60)''': | '''Key Header Structure (Length 0x60)''': | ||
*0x00-0x0F is decryption key (but stored encrypted with AES128, is not PLAINTEXT key) | |||
*0x10-0x23 is header ECDSA sig r | |||
*0x24-0x37 is header ECDSA sig s | |||
*0x38-0x4b is data ECDSA sig r | |||
*0x4c-0x5f is data ECDSA sig s | |||
'''Metadata Header Structure (Length 0x30)''': | |||
*0x60-0x63 is set to 1 to indicate KIRK1 Verification | |||
*0x64-0x67 is set to 1 to indicate ECDSA version | |||
*0x68-0x6B is 0 | |||
*0x6C-0x6F is 0 for retail versions and 0xFFFFFFFF for dev versions | |||
*0x70-0x73 is length of decrypted data | |||
*0x74-0x77 is length of padding after Metadata header before real data starts | |||
*0x78-0x8F is 0 | |||
=== | ==== Decryption process ==== | ||
The ECDSA version is slightly different. Only the first block (0x10 bytes) is decrypted with the Kirk 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 Data section is also checked via SHA1 of the entire data through a ECDSA Verify call. | |||
The ECDSA curve parameters used for this ECDSA Verification are as follows. | |||
p=FFFFFFFFFFFFFFFF00000001FFFFFFFFFFFFFFFF | |||
= | NP=FFFFFFFFFFFFFFFF0001B5C617F290EAE1DBAD8F | ||
a=-3 | |||
b=65D1488C0359E234ADC95BD3908014BD91A525F9 | |||
'''Base Point''': | |||
Gx=2259ACEE15489CB096A882F0AE1CF9FD8EE5F8FA | |||
Gy=604358456D0A1CB2908DE90F27D75C82BEC108C0 | |||
'''Public Point''': | |||
Px=ED9CE58234E61A53C685D64D51D0236BC3B5D4B9 | |||
Py=049DF1A075C0E04FB344858B61B79B69A63D2C39 | |||
== Command 2 (DRM encrypt) == | |||
This command is mostly unknown. | |||
The | 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 == | |||
== | == Command 4 == | ||
=== | == Command 5 == | ||
Command 6 | == Command 6 == | ||
== Command 7 == | |||
Command | == Command 8 == | ||
== Command 9 == | |||
== Command | == Command 10 == | ||
== Command 11 == | |||
== Command | == Command 12: ECDSA key pair generation == | ||
Elliptic Curve Math formula : <math>y^2 = x^3 +ax +b mod p</math> with NP points on the curve | |||
p = FFFFFFFFFFFFFFFF00000001FFFFFFFFFFFFFFFF | |||
= | N= FFFFFFFFFFFFFFFEFFFFB5AE3C523E63944F2127 | ||
a= -3 | |||
b= A68BEDC33418029C1D3CE33B9A321FCCBB9E0F0B | |||
'''Base Point''': | |||
Gx= 128EC4256487FD8FDF64E2437BC0A1F6D5AFDE2C | |||
= | Gy= 5958557EB1DB001260425524DBC379D5AC5F4ADF | ||
'''Invocation''': | |||
<pre> | |||
u8 keypair[0x3c] | |||
sceUtilsBufferCopyWithRange(keypair,0x3c,0,0,0xC); | |||
</pre> | |||
This returns the following into the keypair buffer (each value is 0x14 bytes long): | |||
*0x00 - randomly generated private key | |||
*0x14 - Public Key point x value | |||
*0x28 - Public Key point y value | |||
Basically function 0xC generates a random number < N and multiplies it to the base point G to get the new public key. | |||
== Command 13: point multiplication == | |||
Elliptic Curve Math formula : <math>y^2 = x^3 +ax +b mod p</math> with NP points on the curve | |||
p = FFFFFFFFFFFFFFFF00000001FFFFFFFFFFFFFFFF | |||
NP= FFFFFFFFFFFFFFFEFFFFB5AE3C523E63944F2127 | |||
= | a= -3 | ||
b= A68BEDC33418029C1D3CE33B9A321FCCBB9E0F0B | |||
'''Base Point''': | |||
Gx= 128EC4256487FD8FDF64E2437BC0A1F6D5AFDE2C | |||
Gy= 5958557EB1DB001260425524DBC379D5AC5F4ADF | |||
'''Invocation''': | |||
<pre> | |||
u8 buffer[0x3C] | |||
u8 newpoint[0x28] | |||
memcpy(buffer, multiplier, 0x14); | |||
memcpy(buffer+0x14, pointx, 0x14); | |||
memcpy(buffer+0x28, pointy, 0x14); | |||
sceUtilsBufferCopyWithRange(newpoint,0x28,buffer,0x3c,0xD); | |||
</pre> | |||
The result is a new point(x and y are each 0x14 bytes long). | |||
To test this, you can call 0xC service and copy the first 0x14 bytes to a new buffer, then copy the Gx and Gy values after that. Calling 0xD with the new buffer will return the values of x and y that were generated by the 0xC call. | |||
== Command | == Command 14 == | ||
== Command 15 == | |||
== Command 16 == | |||
== Command 17 == | |||
== Command 18 == | |||
= Library = | |||
= | == Calling commands using KIRK registers == | ||
= | |||
* [https://github.com/DaveeFTW/iplsdk/tree/master/src/kirk] | * [https://github.com/DaveeFTW/iplsdk/tree/master/src/kirk] | ||
Line 1,022: | Line 347: | ||
* [http://uofw.github.io/upspd/docs/SilverSpring_Blog/my.malloc.us/silverspring/kirk-crypto-engine/index.html] | * [http://uofw.github.io/upspd/docs/SilverSpring_Blog/my.malloc.us/silverspring/kirk-crypto-engine/index.html] | ||
= | = Notes = | ||
In 2008 SilverSpring wrote: | |||
<pre> | |||
Currently what is known about the cipher is that it is: | |||
a block cipher operating in CBC mode | |||
an all zero 128-bit initialization vector | |||
128-bit block and key sizes | |||
cmd4/7 uses a static key that is identical in all PSP’s | |||
cmd5/8 uses a key based off the fuseID making all operations unique per PSP | |||
cmd6/9 uses a user-defined 128-bit key | |||
cmd1/2/3 uses the block cipher but also signature algorithms | |||
the remaining KIRK cmd’s do not use the block cipher (sig, hash, & prng algo’s) | |||
</pre> |