public static void AES_cbc_decrypt(AesCtx *ctx, byte *src, byte *dst, int size) { var blockBuffBytes = new byte[16]; var blockBuffPreviousBytes = new byte[16]; fixed(byte *blockBuff = blockBuffBytes) fixed(byte *blockBuffPrevious = blockBuffPreviousBytes) { Memcpy(blockBuff, src, 16); Memcpy(blockBuffPrevious, src, 16); AES_decrypt(ctx, src, dst); dst += 16; src += 16; int i; for (i = 16; i < size; i += 16) { //step1: backup current block for next block decrypt Memcpy(blockBuff, src, 16); //step2: copy current block to destination Memcpy(dst, src, 16); //step3: decrypt current buffer in place AES_decrypt(ctx, dst, dst); //step4: XOR current buffer with previous buffer xor_128(dst, blockBuffPrevious, dst); //step5: swap buffers Memcpy(blockBuffPrevious, blockBuff, 16); dst += 16; src += 16; } } }
//No IV support! public static void AES_cbc_encrypt(AesCtx *ctx, byte *src, byte *dst, int size) { var blockBuffBytes = new byte[16]; fixed(byte *blockBuff = blockBuffBytes) { int i; for (i = 0; i < size; i += 16) { //step 1: copy block to dst Memcpy(dst, src, 16); //step 2: XOR with previous block if (i != 0) { xor_128(dst, blockBuff, dst); } //step 3: encrypt the block -> it land in block buffer AES_encrypt(ctx, dst, blockBuff); //step 4: copy back the encrypted block to destination Memcpy(dst, blockBuff, 16); dst += 16; src += 16; } } }
public static void generate_subkey(AesCtx *ctx, byte *k1, byte *k2) { var lBytes = new byte[16]; var zBytes = new byte[16]; var tmpBytes = new byte[16]; fixed(byte *tmp = tmpBytes) fixed(byte *l = lBytes) fixed(byte *z = zBytes) fixed(byte *constRb = ConstRb) { int i; for (i = 0; i < 16; i++) { z[i] = 0; } AES_encrypt(ctx, z, l); if ((l[0] & 0x80) == 0) /* If MSB(L) = 0, then K1 = L << 1 */ { leftshift_onebit(l, k1); } else { /* Else K1 = ( L << 1 ) (+) Rb */ leftshift_onebit(l, tmp); xor_128(tmp, constRb, k1); } if ((k1[0] & 0x80) == 0) { leftshift_onebit(k1, k2); } else { leftshift_onebit(k1, tmp); xor_128(tmp, constRb, k2); } } }
public static void AES_CMAC_forge(AesCtx *ctx, byte *input, int length, byte *forge) { var xBytes = new byte[16]; var yBytes = new byte[16]; var mLastBytes = new byte[16]; var paddedBytes = new byte[16]; var k1Bytes = new byte[16]; var k2Bytes = new byte[16]; fixed(byte *x = xBytes) fixed(byte *y = yBytes) fixed(byte *mLast = mLastBytes) fixed(byte *padded = paddedBytes) fixed(byte *k1 = k1Bytes) fixed(byte *k2 = k2Bytes) { generate_subkey(ctx, k1, k2); var n = (length + 15) / 16; int flag; if (n == 0) { n = 1; flag = 0; } else { flag = (length % 16) == 0 ? 1 : 0; } if (flag != 0) { /* last block is complete block */ xor_128(&input[16 * (n - 1)], k1, mLast); } else { Padding(&input[16 * (n - 1)], padded, length % 16); xor_128(padded, k2, mLast); } int i; 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, mLast, 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]; } } }
public static void AES_CMAC(AesCtx *ctx, byte *input, int length, byte *mac) { var xBytes = new byte[16]; var yBytes = new byte[16]; var mLastBytes = new byte[16]; var paddedBytes = new byte[16]; var k1Bytes = new byte[16]; var k2Bytes = new byte[16]; fixed(byte *x = xBytes) fixed(byte *y = yBytes) fixed(byte *mLast = mLastBytes) fixed(byte *padded = paddedBytes) fixed(byte *k1 = k1Bytes) fixed(byte *k2 = k2Bytes) { generate_subkey(ctx, k1, k2); var n = (length + 15) / 16; int flag; if (n == 0) { n = 1; flag = 0; } else { flag = (length % 16) == 0 ? 1 : 0; } if (flag != 0) { /* last block is complete block */ xor_128(&input[16 * (n - 1)], k1, mLast); } else { Padding(&input[16 * (n - 1)], padded, length % 16); xor_128(padded, k2, mLast); } int i; 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, mLast, y); AES_encrypt(ctx, y, x); for (i = 0; i < 16; i++) { mac[i] = x[i]; } } }
public static void AES_encrypt(AesCtx *ctx, byte *src, byte *dst) { RijndaelEncrypt(ctx->Ek, ctx->Nr, src, dst); }
public static void AES_decrypt(AesCtx *ctx, byte *src, byte *dst) { RijndaelDecrypt(ctx->Dk, ctx->Nr, src, dst); }
public static int AES_set_key(AesCtx *ctx, byte *key, int bits) { return(rijndael_set_key((RijndaelCtx *)ctx, key, bits)); }