CSPspEmu.Core.Crypto.Crypto.AES_CMAC_forge C# (CSharp) Method

AES_CMAC_forge() public static method

public static AES_CMAC_forge ( AES_ctx ctx, byte input, int length, byte forge ) : void
ctx AES_ctx
input byte
length int
forge byte
return void
        public static void AES_CMAC_forge(AES_ctx* ctx, byte* input, int length, byte* forge)
        {
            var _X = new byte[16];
            var _Y = new byte[16];
            var _M_last = new byte[16];
            var _padded = new byte[16];
            var _K1 = new byte[16];
            var _K2 = new byte[16];
            int n, i, flag;

            fixed (byte* X = _X)
            fixed (byte* Y = _Y)
            fixed (byte* M_last = _M_last)
            fixed (byte* padded = _padded)
            fixed (byte* K1 = _K1)
            fixed (byte* K2 = _K2)
            {
                generate_subkey(ctx,K1,K2);

                n = (length+15) / 16;       /* n is number of rounds */

                if ( n == 0 )
               {
                    n = 1;
                    flag = 0;
                } else {
                  if ( (length%16) == 0 ) { /* last block is a complete block */
                        flag = 1;
                    } else { /* last block is not complete block */
                        flag = 0;
                    }

                }

                if ( flag != 0 ) { /* last block is complete block */
                    xor_128(&input[16*(n-1)],K1,M_last);
                } else {
                    padding(&input[16*(n-1)],padded,length%16);
                    xor_128(padded,K2,M_last);
                }

                for ( i=0; i<16; i++ ) X[i] = 0;
                for ( i=0; i<n-1; i++ )
                {
                     xor_128(X,&input[16*i],Y); /* Y := Mi (+) X  */
                     AES_encrypt(ctx, Y, X); /* X := AES-128(KEY, Y); */
                }

                xor_128(X,M_last,Y);
                 AES_decrypt(ctx, forge, X);
                //printf("Pre-crypt value: "); for(i=0;i<0x10;i++) printf("%02x", X[i]); printf("\n");
                xor_128(X,Y,forge);
                xor_128(forge,&input[16*(n-1)],Y);
                //AES_encrypt(Y, X, &aes);

                  //Update original input file so it produces the correct CMAC
                for ( i=0; i<16; i++ ) {
                    input[(16*(n-1))+i]= Y[i];
                }
            }
        }

Usage Example

Example #1
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
            }
        }
All Usage Examples Of CSPspEmu.Core.Crypto.Crypto::AES_CMAC_forge