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];
}
}
}