public void kirk_CMD10(byte* inbuff, int insize)
{
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*)inbuff;
if (!(header.Mode == KirkMode.Cmd1 || header.Mode == KirkMode.Cmd2 || header.Mode == KirkMode.Cmd3))
{
throw(new KirkException(ResultEnum.PSP_KIRK_INVALID_MODE));
}
if (header.DataSize == 0)
{
throw (new KirkException(ResultEnum.PSP_KIRK_DATA_SIZE_IS_ZERO));
}
if (header.Mode != KirkMode.Cmd1)
{
// Checks for cmd 2 & 3 not included right now
throw (new KirkException(ResultEnum.PSP_KIRK_INVALID_SIG_CHECK));
}
header_keys keys; //0-15 AES key, 16-31 CMAC key
#if USE_DOTNET_CRYPTO
DecryptAes(kirk1_key, inbuff, (byte *)&keys, 16 * 2);
#else
Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte*)&keys, 32); //decrypt AES & CMAC key to temp buffer
#endif
Crypto.AES_ctx cmac_key;
Crypto.AES_set_key(&cmac_key, keys.CMAC, 128);
Crypto.AES_CMAC(&cmac_key, inbuff + 0x60, 0x30, cmac_header_hash);
//Make sure data is 16 aligned
int chk_size = header.DataSize;
if ((chk_size % 16) != 0) chk_size += 16 - (chk_size % 16);
Crypto.AES_CMAC(&cmac_key, inbuff + 0x60, 0x30 + chk_size + header.DataOffset, cmac_data_hash);
if (Crypto.memcmp(cmac_header_hash, header.CMAC_header_hash, 16) != 0)
{
Logger.Error("header hash invalid");
throw (new KirkException(ResultEnum.PSP_SUBCWR_HEADER_HASH_INVALID));
}
if (Crypto.memcmp(cmac_data_hash, header.CMAC_data_hash, 16) != 0)
{
Logger.Error("data hash invalid");
throw (new KirkException(ResultEnum.PSP_SUBCWR_HEADER_HASH_INVALID));
}
}
}