diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-06-26 20:42:58 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2010-06-26 20:42:58 +0000 |
commit | c5552ad03973839d83d32d7108f20c00f192633b (patch) | |
tree | de32e4def600e56134cd085a7447cb6620542078 /target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES | |
parent | 7ec88f88f4c65a22b3b7e32ef87cb42dcb32a6fb (diff) |
rename target/linux/generic-2.6 to generic
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21952 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES')
4 files changed, 710 insertions, 0 deletions
diff --git a/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAes.h b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAes.h new file mode 100644 index 000000000..07a8601f8 --- /dev/null +++ b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAes.h @@ -0,0 +1,62 @@ +/* mvAes.h v2.0 August '99 + * Reference ANSI C code + */ + +/* AES Cipher header file for ANSI C Submissions + Lawrence E. Bassham III + Computer Security Division + National Institute of Standards and Technology + + April 15, 1998 + + This sample is to assist implementers developing to the Cryptographic +API Profile for AES Candidate Algorithm Submissions. Please consult this +document as a cross-reference. + + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE +IMPLEMENTATION SPECIFIC INFORMATION. +*/ + +/* Includes: + Standard include files +*/ + +#include "mvOs.h" + + +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */ + +/* Key direction is invalid, e.g., unknown value */ +#define AES_BAD_KEY_DIR -1 + +/* Key material not of correct length */ +#define AES_BAD_KEY_MAT -2 + +/* Key passed is not valid */ +#define AES_BAD_KEY_INSTANCE -3 + +/* Params struct passed to cipherInit invalid */ +#define AES_BAD_CIPHER_MODE -4 + +/* Cipher in wrong state (e.g., not initialized) */ +#define AES_BAD_CIPHER_STATE -5 + +#define AES_BAD_CIPHER_INSTANCE -7 + + +/* Function protoypes */ +/* CHANGED: makeKey(): parameter blockLen added + this parameter is absolutely necessary if you want to + setup the round keys in a variable block length setting + cipherInit(): parameter blockLen added (for obvious reasons) + */ +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen); +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen, + MV_U32 *plain, int numBlocks, MV_U32 *cipher); +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen, + MV_U32 *plain, int numBlocks, MV_U32 *cipher); + + diff --git a/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c new file mode 100644 index 000000000..a65dc2893 --- /dev/null +++ b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c @@ -0,0 +1,317 @@ +/* rijndael-alg-ref.c v2.0 August '99 + * Reference ANSI C code + * authors: Paulo Barreto + * Vincent Rijmen, K.U.Leuven + * + * This code is placed in the public domain. + */ + +#include "mvOs.h" + +#include "mvAesAlg.h" + +#include "mvAesBoxes.dat" + + +MV_U8 mul1(MV_U8 aa, MV_U8 bb); +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC); +void ShiftRow128Enc(MV_U8 a[4][MAXBC]); +void ShiftRow128Dec(MV_U8 a[4][MAXBC]); +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]); +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]); +void InvMixColumn(MV_U8 a[4][MAXBC]); + + +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]]) + +MV_U8 mul1(MV_U8 aa, MV_U8 bb) +{ + return mask[bb] & Alogtable[aa + Logtable[bb]]; +} + + +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC) +{ + /* Exor corresponding text input and round key input bytes + */ + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0]; + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0]; + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0]; + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0]; + +} + +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) { + /* Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + MV_U8 tmp[MAXBC]; + + tmp[0] = a[1][1]; + tmp[1] = a[1][2]; + tmp[2] = a[1][3]; + tmp[3] = a[1][0]; + + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[1][0] = tmp[0]; + a[1][1] = tmp[1]; + a[1][2] = tmp[2]; + a[1][3] = tmp[3]; + */ + tmp[0] = a[2][2]; + tmp[1] = a[2][3]; + tmp[2] = a[2][0]; + tmp[3] = a[2][1]; + + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[2][0] = tmp[0]; + a[2][1] = tmp[1]; + a[2][2] = tmp[2]; + a[2][3] = tmp[3]; + */ + tmp[0] = a[3][3]; + tmp[1] = a[3][0]; + tmp[2] = a[3][1]; + tmp[3] = a[3][2]; + + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[3][0] = tmp[0]; + a[3][1] = tmp[1]; + a[3][2] = tmp[2]; + a[3][3] = tmp[3]; + */ +} + +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) { + /* Row 0 remains unchanged + * The other three rows are shifted a variable amount + */ + MV_U8 tmp[MAXBC]; + + tmp[0] = a[1][3]; + tmp[1] = a[1][0]; + tmp[2] = a[1][1]; + tmp[3] = a[1][2]; + + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[1][0] = tmp[0]; + a[1][1] = tmp[1]; + a[1][2] = tmp[2]; + a[1][3] = tmp[3]; + */ + + tmp[0] = a[2][2]; + tmp[1] = a[2][3]; + tmp[2] = a[2][0]; + tmp[3] = a[2][1]; + + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[2][0] = tmp[0]; + a[2][1] = tmp[1]; + a[2][2] = tmp[2]; + a[2][3] = tmp[3]; + */ + + tmp[0] = a[3][1]; + tmp[1] = a[3][2]; + tmp[2] = a[3][3]; + tmp[3] = a[3][0]; + + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0]; + /* + a[3][0] = tmp[0]; + a[3][1] = tmp[1]; + a[3][2] = tmp[2]; + a[3][3] = tmp[3]; + */ +} + +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) { + /* Replace every byte of the input by the byte at that place + * in the nonlinear S-box + */ + int i, j; + + for(i = 0; i < 4; i++) + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ; +} + +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) { + /* Mix the four bytes of every column in a linear way + */ + MV_U8 b[4][MAXBC]; + int i, j; + + for(j = 0; j < 4; j++){ + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j]; + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j]; + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j]; + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j]; + } + for(i = 0; i < 4; i++) + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/ + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];; +} + +void InvMixColumn(MV_U8 a[4][MAXBC]) { + /* Mix the four bytes of every column in a linear way + * This is the opposite operation of Mixcolumn + */ + MV_U8 b[4][MAXBC]; + int i, j; + + for(j = 0; j < 4; j++){ + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]); + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]); + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]); + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]); + } + for(i = 0; i < 4; i++) + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/ + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0]; +} + +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC]) +{ + /* Calculate the necessary round keys + * The number of calculations depends on keyBits and blockBits + */ + int KC, BC, ROUNDS; + int i, j, t, rconpointer = 0; + MV_U8 tk[4][MAXKC]; + + switch (keyBits) { + case 128: KC = 4; break; + case 192: KC = 6; break; + case 256: KC = 8; break; + default : return (-1); + } + + switch (blockBits) { + case 128: BC = 4; break; + case 192: BC = 6; break; + case 256: BC = 8; break; + default : return (-2); + } + + switch (keyBits >= blockBits ? keyBits : blockBits) { + case 128: ROUNDS = 10; break; + case 192: ROUNDS = 12; break; + case 256: ROUNDS = 14; break; + default : return (-3); /* this cannot happen */ + } + + + for(j = 0; j < KC; j++) + for(i = 0; i < 4; i++) + tk[i][j] = k[i][j]; + t = 0; + /* copy values into round key array */ + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++) + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j]; + + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */ + /* calculate new values */ + for(i = 0; i < 4; i++) + tk[i][0] ^= S[tk[(i+1)%4][KC-1]]; + tk[0][0] ^= rcon[rconpointer++]; + + if (KC != 8) + for(j = 1; j < KC; j++) + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1]; + else { + for(j = 1; j < KC/2; j++) + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1]; + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]]; + for(j = KC/2 + 1; j < KC; j++) + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1]; + } + /* copy values into round key array */ + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++) + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j]; + } + + return 0; +} + + + +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds) +{ + /* Encryption of one block. + */ + int r, BC, ROUNDS; + + BC = 4; + ROUNDS = rounds; + + /* begin with a key addition + */ + + KeyAddition(a,rk[0],BC); + + /* ROUNDS-1 ordinary rounds + */ + for(r = 1; r < ROUNDS; r++) { + Substitution(a,S); + ShiftRow128Enc(a); + MixColumn(a, rk[r]); + /*KeyAddition(a,rk[r],BC);*/ + } + + /* Last round is special: there is no MixColumn + */ + Substitution(a,S); + ShiftRow128Enc(a); + KeyAddition(a,rk[ROUNDS],BC); + + return 0; +} + + +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds) +{ + int r, BC, ROUNDS; + + BC = 4; + ROUNDS = rounds; + + /* To decrypt: apply the inverse operations of the encrypt routine, + * in opposite order + * + * (KeyAddition is an involution: it 's equal to its inverse) + * (the inverse of Substitution with table S is Substitution with the inverse table of S) + * (the inverse of Shiftrow is Shiftrow over a suitable distance) + */ + + /* First the special round: + * without InvMixColumn + * with extra KeyAddition + */ + KeyAddition(a,rk[ROUNDS],BC); + ShiftRow128Dec(a); + Substitution(a,Si); + + /* ROUNDS-1 ordinary rounds + */ + for(r = ROUNDS-1; r > 0; r--) { + KeyAddition(a,rk[r],BC); + InvMixColumn(a); + ShiftRow128Dec(a); + Substitution(a,Si); + + } + + /* End with the extra key addition + */ + + KeyAddition(a,rk[0],BC); + + return 0; +} + diff --git a/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h new file mode 100644 index 000000000..ec81e403f --- /dev/null +++ b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h @@ -0,0 +1,19 @@ +/* rijndael-alg-ref.h v2.0 August '99 + * Reference ANSI C code + * authors: Paulo Barreto + * Vincent Rijmen, K.U.Leuven + */ +#ifndef __RIJNDAEL_ALG_H +#define __RIJNDAEL_ALG_H + +#define MAXBC (128/32) +#define MAXKC (256/32) +#define MAXROUNDS 14 + + +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]); + +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds); +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds); + +#endif /* __RIJNDAEL_ALG_H */ diff --git a/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c new file mode 100644 index 000000000..b432dc6e6 --- /dev/null +++ b/target/linux/generic/files/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c @@ -0,0 +1,312 @@ +/* rijndael-api-ref.c v2.1 April 2000 + * Reference ANSI C code + * authors: v2.0 Paulo Barreto + * Vincent Rijmen, K.U.Leuven + * v2.1 Vincent Rijmen, K.U.Leuven + * + * This code is placed in the public domain. + */ +#include "mvOs.h" + +#include "mvAes.h" +#include "mvAesAlg.h" + + +/* Defines: + Add any additional defines you need +*/ + +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */ +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */ +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */ + + +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen) +{ + MV_U8 W[MAXROUNDS+1][4][MAXBC]; + MV_U8 k[4][MAXKC]; + MV_U8 j; + int i, rounds, KC; + + if (expandedKey == NULL) + { + return AES_BAD_KEY_INSTANCE; + } + + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256))) + { + return AES_BAD_KEY_MAT; + } + + if (keyMaterial == NULL) + { + return AES_BAD_KEY_MAT; + } + + /* initialize key schedule: */ + for(i=0; i<keyLen/8; i++) + { + j = keyMaterial[i]; + k[i % 4][i / 4] = j; + } + + rijndaelKeySched (k, keyLen, blockLen, W); +#ifdef MV_AES_DEBUG + { + MV_U8* pW = &W[0][0][0]; + int x; + + mvOsPrintf("Expended Key: size = %d\n", sizeof(W)); + for(i=0; i<sizeof(W); i++) + { + mvOsPrintf("%02x ", pW[i]); + } + for(i=0; i<MAXROUNDS+1; i++) + { + mvOsPrintf("\n Round #%02d: ", i); + for(x=0; x<MAXBC; x++) + { + mvOsPrintf("%02x%02x%02x%02x ", + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]); + } + mvOsPrintf("\n"); + } + } +#endif /* MV_AES_DEBUG */ + switch (keyLen) + { + case 128: + rounds = 10; + KC = 4; + break; + case 192: + rounds = 12; + KC = 6; + break; + case 256: + rounds = 14; + KC = 8; + break; + default : + return (-1); + } + + for(i=0; i<MAXBC; i++) + { + for(j=0; j<4; j++) + { + expandedKey[i*4+j] = W[rounds][j][i]; + } + } + for(; i<KC; i++) + { + for(j=0; j<4; j++) + { + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC]; + } + } + + + return 0; +} + +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen, + MV_U32 *plain, int numBlocks, MV_U32 *cipher) +{ + int i, j, t; + MV_U8 block[4][MAXBC]; + int rounds; + char *input, *outBuffer; + + input = (char*)plain; + outBuffer = (char*)cipher; + + /* check parameter consistency: */ + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256))) + { + return AES_BAD_KEY_MAT; + } + if ((mode != MODE_ECB && mode != MODE_CBC)) + { + return AES_BAD_CIPHER_STATE; + } + + switch (keyLen) + { + case 128: rounds = 10; break; + case 192: rounds = 12; break; + case 256: rounds = 14; break; + default : return (-3); /* this cannot happen */ + } + + + switch (mode) + { + case MODE_ECB: + for (i = 0; i < numBlocks; i++) + { + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + /* parse input stream into rectangular array */ + block[t][j] = input[16*i+4*j+t] & 0xFF; + } + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds); + for (j = 0; j < 4; j++) + { + /* parse rectangular array into output ciphertext bytes */ + for(t = 0; t < 4; t++) + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j]; + + } + } + break; + + case MODE_CBC: + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + /* parse initial value into rectangular array */ + block[t][j] = IV[t+4*j] & 0xFF; + } + for (i = 0; i < numBlocks; i++) + { + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + /* parse input stream into rectangular array and exor with + IV or the previous ciphertext */ + block[t][j] ^= input[16*i+4*j+t] & 0xFF; + } + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds); + for (j = 0; j < 4; j++) + { + /* parse rectangular array into output ciphertext bytes */ + for(t = 0; t < 4; t++) + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j]; + } + } + break; + + default: return AES_BAD_CIPHER_STATE; + } + + return 0; +} + +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen, + MV_U32 *srcData, int numBlocks, MV_U32 *dstData) +{ + int i, j, t; + MV_U8 block[4][MAXBC]; + MV_U8 iv[4][MAXBC]; + int rounds; + char *input, *outBuffer; + + input = (char*)srcData; + outBuffer = (char*)dstData; + + if (expandedKey == NULL) + { + return AES_BAD_KEY_MAT; + } + + /* check parameter consistency: */ + if (keyLen != 128 && keyLen != 192 && keyLen != 256) + { + return AES_BAD_KEY_MAT; + } + if ((mode != MODE_ECB && mode != MODE_CBC)) + { + return AES_BAD_CIPHER_STATE; + } + + switch (keyLen) + { + case 128: rounds = 10; break; + case 192: rounds = 12; break; + case 256: rounds = 14; break; + default : return (-3); /* this cannot happen */ + } + + + switch (mode) + { + case MODE_ECB: + for (i = 0; i < numBlocks; i++) + { + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + { + /* parse input stream into rectangular array */ + block[t][j] = input[16*i+4*j+t] & 0xFF; + } + } + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds); + for (j = 0; j < 4; j++) + { + /* parse rectangular array into output ciphertext bytes */ + for(t = 0; t < 4; t++) + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j]; + } + } + break; + + case MODE_CBC: + /* first block */ + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + { + /* parse input stream into rectangular array */ + block[t][j] = input[4*j+t] & 0xFF; + iv[t][j] = block[t][j]; + } + } + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds); + + for (j = 0; j < 4; j++) + { + /* exor the IV and parse rectangular array into output ciphertext bytes */ + for(t = 0; t < 4; t++) + { + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]); + IV[t+4*j] = iv[t][j]; + } + } + + /* next blocks */ + for (i = 1; i < numBlocks; i++) + { + for (j = 0; j < 4; j++) + { + for(t = 0; t < 4; t++) + { + /* parse input stream into rectangular array */ + iv[t][j] = input[16*i+4*j+t] & 0xFF; + block[t][j] = iv[t][j]; + } + } + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds); + + for (j = 0; j < 4; j++) + { + /* exor previous ciphertext block and parse rectangular array + into output ciphertext bytes */ + for(t = 0; t < 4; t++) + { + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]); + IV[t+4*j] = iv[t][j]; + } + } + } + break; + + default: return AES_BAD_CIPHER_STATE; + } + + return 0; +} + + |