KIRK Crypto Engine

This page will be used to document the KIRK Crypto Engine and will be updated as new info is learned (data may change).

The 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 on the other hand is mapped to 0xBDF00000).

It is capable of performing AES encryption, SHA1 Hash, and random number generation.

KIRK Operations (set in 0xBDE00010 register):

C:
  1. // Private Sig + Cipher
  2. 0×01: Super-Duper decryption (no inverse)
  3. 0×02: Encrypt Operation (inverse of 0×03)
  4. 0×03: Decrypt Operation (inverse of 0×02)
  5.  
  6. // Cipher
  7. 0×04: Encrypt Operation (inverse of 0×07) (IV=0)
  8. 0×05: Encrypt Operation (inverse of 0×08) (IV=FuseID)
  9. 0×06: Encrypt Operation (inverse of 0×09) (IV=UserDefined)
  10. 0×07: Decrypt Operation (inverse of 0×04)
  11. 0×08: Decrypt Operation (inverse of 0×05)
  12. 0×09: Decrypt Operation (inverse of 0×06)
  13.  
  14. // Sig Gens
  15. 0x0A: Private Signature Check (checks for private SCE sig)
  16. 0x0B: SHA1 Hash
  17. 0x0C: Mul1
  18. 0x0D: Mul2
  19. 0x0E: Random Number Gen
  20. 0x0F: (absolutely no idea – could be KIRK initialization)
  21. 0×10: Signature Gen
  22.  
  23. // Sig Checks
  24. 0×11: Signature Check (checks for generated sigs)
  25. 0×12: Certificate Check (idstorage signatures)

KIRK Errors (returned in 0xBDE00014 register):

C:
  1. 0×00: Operation Success, no error
  2. 0×01: KIRK not enabled
  3. 0×02: Invalid mode
  4. 0×03: Header check invalid
  5. 0×04: Data check invalid
  6. 0×05: Sig Check failed
  7. 0×06:
  8. 0×07:
  9. 0×08:
  10. 0×09:
  11. 0x0A:
  12. 0x0B:
  13. 0x0C: KIRK not initialized
  14. 0x0D: Invalid Operation (1-18 cmds)
  15. 0x0E: Invalid seed/code (cipher operations)
  16. 0x0F: Invalid size? (cipher operations)
  17. 0×10: Data Size is 0 (sig/cipher operations)

Interface to KIRK device (memory mapped to 0xBDE00000):

C:
  1. typedef volatile struct
  2. {
  3.     u32 signature;
  4.     u32 version;
  5.     u32 error;
  6.     u32 proc_phase;
  7.     u32 command;
  8.     u32 result;
  9.     u32 unk_18;
  10.     u32 status;
  11.     u32 status_async;
  12.     u32 status_async_end;
  13.     u32 status_end;
  14.     u32 src_addr;
  15.     u32 dst_addr;
  16.  
  17. } PspKirkRegs;
  18.  
  19. #define MAKE_PHYS_ADDR(_addr)    (((u32)_addr) & 0x1FFFFFFF)
  20. #define SYNC()                   asm("sync")
  21.  
  22. #define KIRK_HW_REGISTER_ADDR    ((PspKirkRegs *)0xBDE00000)
  23.  
  24. u32 DecryptKirkBlock(void *dst, const void *src)
  25. {
  26.     sceKernelDcacheWritebackInvalidateAll();
  27.  
  28.     PspKirkRegs *const kirk = KIRK_HW_REGISTER_ADDR;
  29.  
  30.     kirk->command = 1; // decrypt operation
  31.     kirk->src_addr = MAKE_PHYS_ADDR(src);
  32.     kirk->dst_addr = MAKE_PHYS_ADDR(dst);
  33.  
  34.     kirk->proc_phase = 1; // start processing
  35.  
  36.     while((kirk->status & 0×11) == 0); // wait until processing complete
  37.  
  38.     if (kirk->status & 0×10) // error occured
  39.     {
  40.         kirk->proc_phase = 2;
  41.  
  42.         while((kirk->status & 2) == 0);
  43.  
  44.         kirk->status_end = kirk->status;
  45.         SYNC();
  46.         return -1;
  47.     }
  48.  
  49.     kirk->status_end = kirk->status;
  50.     SYNC();
  51.     return(kirk->result);
  52. }