forked from Ivasoft/openwrt
rename target/linux/generic-2.6 to generic
SVN-Revision: 21952
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user