CSPspEmu.Core.Crypto.Kirk.kirk_forge C# (CSharp) Method

kirk_forge() public method

public kirk_forge ( byte inbuff, int insize ) : void
inbuff byte
insize int
return void
        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;

               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");
               }
        }