public static AES_CMAC ( AES_ctx ctx, byte input, int length, byte mac ) : void | ||
ctx | AES_ctx | |
input | byte | |
length | int | |
mac | byte | |
Результат | void |
public int kirk_CMD10(byte *inbuff, int insize) { if (!is_kirk_initialized) { return(KIRK_NOT_INITIALIZED); } AES128CMACHeader *header = (AES128CMACHeader *)inbuff; if (!(header->Mode == KIRK_MODE_CMD1 || header->Mode == KIRK_MODE_CMD2 || header->Mode == KIRK_MODE_CMD3)) { return(KIRK_INVALID_MODE); } if (header->DataSize == 0) { return(KIRK_DATA_SIZE_ZERO); } if (header->Mode == KIRK_MODE_CMD1) { header_keys keys; //0-15 AES key, 16-31 CMAC key Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)&keys, 32); //decrypt AES & CMAC key to temp buffer Crypto.AES_ctx cmac_key; Crypto.AES_set_key(&cmac_key, keys.CMAC, 128); 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) { 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) { Console.WriteLine("header hash invalid"); return(KIRK_HEADER_HASH_INVALID); } if (Crypto.memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0) { Console.WriteLine("data hash invalid"); return(KIRK_DATA_HASH_INVALID); } return(KIRK_OPERATION_SUCCESS); } } return(KIRK_SIG_CHECK_INVALID); //Checks for cmd 2 & 3 not included right now }
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); } }
public int kirk_forge(byte *inbuff, int insize) { AES128CMACHeader *header = (AES128CMACHeader *)inbuff; Crypto.AES_ctx cmac_key; var _cmac_header_hash = new byte[16]; var _cmac_data_hash = new byte[16]; int chk_size, i; fixed(byte *cmac_header_hash = _cmac_header_hash) fixed(byte *cmac_data_hash = _cmac_data_hash) { if (!is_kirk_initialized) { return(KIRK_NOT_INITIALIZED); } if (!(header->Mode == KIRK_MODE_CMD1 || header->Mode == KIRK_MODE_CMD2 || header->Mode == KIRK_MODE_CMD3)) { return(KIRK_INVALID_MODE); } if (header->DataSize == 0) { return(KIRK_DATA_SIZE_ZERO); } if (header->Mode == KIRK_MODE_CMD1) { header_keys keys; //0-15 AES key, 16-31 CMAC key Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)&keys, 32); //decrypt AES & CMAC key to temp buffer Crypto.AES_set_key(&cmac_key, keys.CMAC, 128); Crypto.AES_CMAC(&cmac_key, inbuff + 0x60, 0x30, cmac_header_hash); if (Crypto.memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) { return(KIRK_HEADER_HASH_INVALID); } //Make sure data is 16 aligned 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_data_hash, header->CMAC_data_hash, 16) != 0) { //printf("data hash invalid, correcting...\n"); } else { Console.Error.WriteLine("data hash is already valid!"); return(100); } // Forge collision for data hash Crypto.memcpy(cmac_data_hash, header->CMAC_data_hash, 0x10); Crypto.AES_CMAC_forge(&cmac_key, inbuff + 0x60, 0x30 + chk_size + header->DataOffset, cmac_data_hash); //printf("Last row in bad file should be :\n"); for(i=0;i<0x10;i++) printf("%02x", cmac_data_hash[i]); //printf("\n\n"); return(KIRK_OPERATION_SUCCESS); } return(KIRK_SIG_CHECK_INVALID); //Checks for cmd 2 & 3 not included right now } }
bool is_kirk_initialized; //"init" emulation /* ------------------------- INTERNAL STUFF END ------------------------- */ /* ------------------------- IMPLEMENTATION ------------------------- */ public int kirk_CMD0(byte *outbuff, byte *inbuff, int size, bool generate_trash) { if (!is_kirk_initialized) { return(KIRK_NOT_INITIALIZED); } AES128CMACHeader *header = (AES128CMACHeader *)outbuff; Crypto.memcpy(outbuff, inbuff, size); if (header->Mode != KIRK_MODE_CMD1) { return(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); 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) { 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); return(KIRK_OPERATION_SUCCESS); }
/// <summary> /// /// </summary> /// <param name="inbuff"></param> /// <param name="insize"></param> /// <returns></returns> public void kirk_forge(byte *inbuff, int insize) { AES128CMACHeader *header = (AES128CMACHeader *)inbuff; Crypto.AES_ctx cmac_key; var _cmac_header_hash = new byte[16]; var _cmac_data_hash = new byte[16]; int chk_size, i; fixed(byte *cmac_header_hash = _cmac_header_hash) fixed(byte *cmac_data_hash = _cmac_data_hash) fixed(Crypto.AES_ctx * aes_kirk1_ptr = &_aes_kirk1) { check_initialized(); 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_MODE)); throw(new KirkException(ResultEnum.PSP_KIRK_INVALID_SIG_CHECK)); } header_keys keys; //0-15 AES key, 16-31 CMAC key Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)&keys, 32); //decrypt AES & CMAC key to temp buffer Crypto.AES_set_key(&cmac_key, keys.CMAC, 128); Crypto.AES_CMAC(&cmac_key, inbuff + 0x60, 0x30, cmac_header_hash); if (Crypto.memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) { throw (new KirkException(ResultEnum.PSP_KIRK_INVALID_HEADER_HASH)); } //Make sure data is 16 aligned 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_data_hash, header->CMAC_data_hash, 16) != 0) { //printf("data hash invalid, correcting...\n"); } else { Logger.Error("data hash is already valid!"); throw(new NotImplementedException()); //return 100; } // Forge collision for data hash Crypto.memcpy(cmac_data_hash, header->CMAC_data_hash, 0x10); Crypto.AES_CMAC_forge(&cmac_key, inbuff + 0x60, 0x30 + chk_size + header->DataOffset, cmac_data_hash); //printf("Last row in bad file should be :\n"); for(i=0;i<0x10;i++) printf("%02x", cmac_data_hash[i]); //printf("\n\n"); } }
/// <summary> /// /// </summary> /// <param name="inbuff"></param> /// <param name="insize"></param> /// <returns></returns> 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)); } } }