bool IsKirkInitialized; //"init" emulation
/// <summary>
///
/// </summary>
/// <param name="outbuff"></param>
/// <param name="inbuff"></param>
/// <param name="size"></param>
/// <param name="generate_trash"></param>
/// <returns></returns>
public void kirk_CMD0(byte *outbuff, byte *inbuff, int size, bool generate_trash)
{
var _cmac_header_hash = new byte[16];
var _cmac_data_hash = new byte[16];
fixed(byte *cmac_header_hash = _cmac_header_hash)
fixed(byte *cmac_data_hash = _cmac_data_hash)
//#if !USE_DOTNET_CRYPTO
fixed(Crypto.AES_ctx * aes_kirk1_ptr = &_aes_kirk1)
//#endif
{
check_initialized();
AES128CMACHeader *header = (AES128CMACHeader *)outbuff;
Crypto.memcpy(outbuff, inbuff, size);
if (header->Mode != KirkMode.Cmd1)
{
throw(new KirkException(ResultEnum.PSP_KIRK_INVALID_MODE));
}
header_keys *keys = (header_keys *)outbuff; //0-15 AES key, 16-31 CMAC key
//FILL PREDATA WITH RANDOM DATA
if (generate_trash)
{
kirk_CMD14(outbuff + sizeof(AES128CMACHeader), header->DataOffset);
}
//Make sure data is 16 aligned
int chk_size = header->DataSize;
if ((chk_size % 16) != 0)
{
chk_size += 16 - (chk_size % 16);
}
//ENCRYPT DATA
Crypto.AES_ctx k1;
Crypto.AES_set_key(&k1, keys->AES, 128);
Crypto.AES_cbc_encrypt(&k1, inbuff + sizeof(AES128CMACHeader) + header->DataOffset, outbuff + sizeof(AES128CMACHeader) + header->DataOffset, chk_size);
//CMAC HASHES
Crypto.AES_ctx cmac_key;
Crypto.AES_set_key(&cmac_key, keys->CMAC, 128);
Crypto.AES_CMAC(&cmac_key, outbuff + 0x60, 0x30, cmac_header_hash);
Crypto.AES_CMAC(&cmac_key, outbuff + 0x60, 0x30 + chk_size + header->DataOffset, cmac_data_hash);
Crypto.memcpy(header->CMAC_header_hash, cmac_header_hash, 16);
Crypto.memcpy(header->CMAC_data_hash, cmac_data_hash, 16);
//ENCRYPT KEYS
Crypto.AES_cbc_encrypt(aes_kirk1_ptr, inbuff, outbuff, 16 * 2);
}
}