AES_cbc_decrypt() публичный статический Метод

public static AES_cbc_decrypt ( AES_ctx ctx, byte src, byte dst, int size ) : void
ctx AES_ctx
src byte
dst byte
size int
Результат void
Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="outbuff"></param>
        /// <param name="inbuff"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public void kirk_CMD7(byte *outbuff, byte *inbuff, int size)
        {
            check_initialized();

            var Header = (KIRK_AES128CBC_HEADER *)inbuff;

            if (Header->Mode != KirkMode.DecryptCbc)
            {
                throw (new KirkException(ResultEnum.PSP_KIRK_INVALID_MODE));
            }
            if (Header->Datasize == 0)
            {
                throw (new KirkException(ResultEnum.PSP_KIRK_DATA_SIZE_IS_ZERO));
            }

#if USE_DOTNET_CRYPTO
            var Output = DecryptAes(
                PointerUtils.PointerToByteArray(inbuff + sizeof(KIRK_AES128CBC_HEADER), size),
                _kirk_4_7_get_key(Header->KeySeed)
                );

            PointerUtils.ByteArrayToPointer(Output, outbuff);
#else
            kirk_4_7_get_key(Header->KeySeed, (key) =>
            {
                //Set the key
                Crypto.AES_ctx aesKey;
                Crypto.AES_set_key(&aesKey, key, 128);

                Crypto.AES_cbc_decrypt(&aesKey, inbuff + sizeof(KIRK_AES128CBC_HEADER), outbuff, size);
            });
#endif
        }
Пример #2
0
        public int kirk_CMD7(byte *outbuff, byte *inbuff, int size)
        {
            if (!is_kirk_initialized)
            {
                return(KIRK_NOT_INITIALIZED);
            }

            KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER *)inbuff;

            if (header->Mode != KIRK_MODE_DECRYPT_CBC)
            {
                return(KIRK_INVALID_MODE);
            }
            if (header->Datasize == 0)
            {
                return(KIRK_DATA_SIZE_ZERO);
            }

            byte *key = kirk_4_7_get_key(header->KeySeed);

            if (key == (byte *)KIRK_INVALID_SIZE)
            {
                return(KIRK_INVALID_SIZE);
            }

            //Set the key
            Crypto.AES_ctx aesKey;
            Crypto.AES_set_key(&aesKey, key, 128);

            Crypto.AES_cbc_decrypt(&aesKey, inbuff + sizeof(KIRK_AES128CBC_HEADER), outbuff, size);

            return(KIRK_OPERATION_SUCCESS);
        }
Пример #3
0
        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
        }
Пример #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="keys"></param>
 /// <param name="inbuff"></param>
 /// <returns></returns>
 public int kirk_decrypt_keys(byte *keys, byte *inbuff)
 {
     fixed(Crypto.AES_ctx *aes_kirk1_ptr = &_aes_kirk1)
     {
         Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)keys, 16 * 2);                //decrypt AES & CMAC key to temp buffer
         return(0);
     }
 }
Пример #5
0
        /// <summary>
        /// Cypher-Block Chaining decoding.
        /// Master decryption command, used by firmware modules. Applies CMAC checking.
        /// </summary>
        /// <param name="outbuff"></param>
        /// <param name="inbuff"></param>
        /// <param name="size"></param>
        /// <param name="do_check"></param>
        /// <returns></returns>
        public void kirk_CMD1(byte *outbuff, byte *inbuff, int size, bool do_check = true)
        {
            fixed(Crypto.AES_ctx *aes_kirk1_ptr = &_aes_kirk1)
            {
                check_initialized();
                var header = (AES128CMACHeader *)inbuff;

                if (header->Mode != KirkMode.Cmd1)
                {
                    throw (new KirkException(ResultEnum.PSP_KIRK_INVALID_MODE));
                }

                header_keys keys;                 //0-15 AES key, 16-31 CMAC key

#if USE_DOTNET_CRYPTO
                DecryptAes(kirk1_key, inbuff, (byte *)&keys, 16 * 2);                //decrypt AES & CMAC key to temp buffer
#else
                Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)&keys, 16 * 2);
#endif

                //AES.CreateDecryptor(

                // HOAX WARRING! I have no idea why the hash check on last IPL block fails, so there is an option to disable checking
                if (do_check)
                {
                    kirk_CMD10(inbuff, size);
                }

                //var AES = new RijndaelManaged();

#if USE_DOTNET_CRYPTO
                DecryptAes(
                    PointerUtils.PointerToByteArray(keys.AES, 16),
                    inbuff + sizeof(AES128CMACHeader) + header->DataOffset,
                    outbuff,
                    header->DataSize
                    );
#else
                Crypto.AES_ctx k1;
                Crypto.AES_set_key(&k1, keys.AES, 128);

                Crypto.AES_cbc_decrypt(&k1, inbuff + sizeof(AES128CMACHeader) + header->DataOffset, outbuff, header->DataSize);
#endif
            }
        }
Пример #6
0
        /// <summary>
        /// Cypher-Block Chaining decoding.
        /// Master decryption command, used by firmware modules. Applies CMAC checking.
        /// </summary>
        /// <param name="outbuff"></param>
        /// <param name="inbuff"></param>
        /// <param name="size"></param>
        /// <param name="do_check"></param>
        /// <returns></returns>
        public int kirk_CMD1(byte *outbuff, byte *inbuff, int size, bool do_check = true)
        {
            if (!is_kirk_initialized)
            {
                return(KIRK_NOT_INITIALIZED);
            }

            AES128CMACHeader *header = (AES128CMACHeader *)inbuff;

            //Console.WriteLine(MathUtils.ByteSwap(header->Mode));
            if (header->Mode != KIRK_MODE_CMD1)
            {
                return(KIRK_INVALID_MODE);
            }

            header_keys keys;                                                     //0-15 AES key, 16-31 CMAC key

            Crypto.AES_cbc_decrypt(aes_kirk1_ptr, inbuff, (byte *)&keys, 16 * 2); //decrypt AES & CMAC key to temp buffer

            // HOAX WARRING! I have no idea why the hash check on last IPL block fails, so there is an option to disable checking
            if (do_check)
            {
                int ret = kirk_CMD10(inbuff, size);
                if (ret != KIRK_OPERATION_SUCCESS)
                {
                    return(ret);
                }
            }

            Crypto.AES_ctx k1;
            Crypto.AES_set_key(&k1, keys.AES, 128);

            Crypto.AES_cbc_decrypt(&k1, inbuff + sizeof(AES128CMACHeader) + header->DataOffset, outbuff, header->DataSize);

            return(KIRK_OPERATION_SUCCESS);
        }
Пример #7
0
        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
            }
        }
Пример #8
0
        /// <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");
            }
        }
Пример #9
0
        /// <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));
                }
            }
        }