00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #define __UNUS
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include "Rijndael.h"
00028
00029
00030 #include "Rand.h"
00031
00032 #define SC ((BC - 4) >> 1)
00033
00034 #include "Rijndael-Boxes.h"
00035
00036 static int ROUNDS;
00037
00038 static word8 shifts[3][4][2] = {
00039 {
00040 {0, 0},
00041 {1, 3},
00042 {2, 2},
00043 {3, 1}
00044 },
00045
00046 {
00047 {0, 0},
00048 {1, 5},
00049 {2, 4},
00050 {3, 3}
00051 },
00052
00053 {
00054 {0, 0},
00055 {1, 7},
00056 {3, 5},
00057 {4, 4}
00058 }
00059 };
00060
00061 word8 mul(word8 a, word8 b) {
00062
00063
00064
00065 if (a && b)
00066 return Alogtable[(Logtable[a] + Logtable[b])%255];
00067 else
00068 return 0;
00069 }
00070
00071 void KeyAddition(word8 a[4][4], word8 rk[4][4], word8 BC) {
00072
00073 int i, j;
00074
00075 for(i = 0; i < BC; i++)
00076 for(j = 0; j < 4; j++)
00077 a[i][j] ^= rk[i][j];
00078 }
00079
00080 void ShiftRow(word8 a[4][4], word8 d, word8 BC) {
00081
00082
00083
00084 word8 tmp[4];
00085 int i, j;
00086
00087 for(i = 1; i < 4; i++) {
00088 for(j = 0; j < BC; j++)
00089 tmp[j] = a[(j + shifts[SC][i][d]) % BC][i];
00090 for(j = 0; j < BC; j++)
00091 a[j][i] = tmp[j];
00092 }
00093 }
00094
00095 void Substitution(word8 a[4][4], word8 box[256], word8 BC) {
00096
00097
00098
00099 int i, j;
00100
00101 for(i = 0; i < BC; i++)
00102 for(j = 0; j < 4; j++)
00103 a[i][j] = box[a[i][j]] ;
00104 }
00105
00106 void MixColumn(word8 a[4][4], word8 BC) {
00107
00108
00109 word8 b[4][4];
00110 int i, j;
00111
00112 for(j = 0; j < BC; j++)
00113 for(i = 0; i < 4; i++)
00114 b[j][i] = mul(2,a[j][i])
00115 ^ mul(3,a[j][(i + 1) % 4])
00116 ^ a[j][(i + 2) % 4]
00117 ^ a[j][(i + 3) % 4];
00118 for(i = 0; i < 4; i++)
00119 for(j = 0; j < BC; j++)
00120 a[j][i] = b[j][i];
00121 }
00122
00123 void InvMixColumn(word8 a[4][4], word8 BC) {
00124
00125
00126
00127 int j;
00128
00129 for(j = 0; j < BC; j++)
00130 *((word32*)a[j]) = *((word32*)U1[a[j][0]])
00131 ^ *((word32*)U2[a[j][1]])
00132 ^ *((word32*)U3[a[j][2]])
00133 ^ *((word32*)U4[a[j][3]]);
00134
00135
00136 }
00137
00138 int rijndaelKeySched (word8 k[MAXKC][4], int keyBits __UNUS, word8 W[MAXROUNDS+1][4][4])
00139 {
00140
00141 (void) keyBits;
00142
00143
00144
00145
00146 int j, r, t, rconpointer = 0;
00147 word8 tk[MAXKC][4];
00148 int KC = ROUNDS - 6;
00149
00150 for(j = KC-1; j >= 0; j--)
00151 *((word32*)tk[j]) = *((word32*)k[j]);
00152 r = 0;
00153 t = 0;
00154
00155 for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
00156 for (; (j < KC) && (t < 4); j++, t++)
00157 *((word32*)W[r][t]) = *((word32*)tk[j]);
00158 if (t == 4) {
00159 r++;
00160 t = 0;
00161 }
00162 }
00163
00164 while (r < (ROUNDS+1)) {
00165
00166 tk[0][0] ^= S[tk[KC-1][1]];
00167 tk[0][1] ^= S[tk[KC-1][2]];
00168 tk[0][2] ^= S[tk[KC-1][3]];
00169 tk[0][3] ^= S[tk[KC-1][0]];
00170 tk[0][0] ^= rcon[rconpointer++];
00171
00172 if (KC != 8)
00173 for(j = 1; j < KC; j++)
00174 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
00175 else {
00176 for(j = 1; j < KC/2; j++)
00177 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
00178 tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
00179 tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
00180 tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
00181 tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
00182 for(j = KC/2 + 1; j < KC; j++)
00183 *((word32*)tk[j]) ^= *((word32*)tk[j-1]);
00184 }
00185
00186 for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
00187 for (; (j < KC) && (t < 4); j++, t++)
00188 *((word32*)W[r][t]) = *((word32*)tk[j]);
00189 if (t == 4) {
00190 r++;
00191 t = 0;
00192 }
00193 }
00194 }
00195
00196 return 0;
00197 }
00198
00199 int rijndaelKeyEnctoDec (int keyBits __UNUS, word8 W[MAXROUNDS+1][4][4])
00200 {
00201 (void) keyBits;
00202
00203 int r;
00204
00205 for (r = 1; r < ROUNDS; r++) {
00206 InvMixColumn(W[r], 4);
00207 }
00208 return 0;
00209 }
00210
00211 int rijndaelEncrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
00212 {
00213
00214
00215 int r;
00216 word8 temp[4][4];
00217
00218 *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[0][0]);
00219 *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[0][1]);
00220 *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[0][2]);
00221 *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
00222 *((word32*)b) = *((word32*)T1[temp[0][0]])
00223 ^ *((word32*)T2[temp[1][1]])
00224 ^ *((word32*)T3[temp[2][2]])
00225 ^ *((word32*)T4[temp[3][3]]);
00226 *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
00227 ^ *((word32*)T2[temp[2][1]])
00228 ^ *((word32*)T3[temp[3][2]])
00229 ^ *((word32*)T4[temp[0][3]]);
00230 *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
00231 ^ *((word32*)T2[temp[3][1]])
00232 ^ *((word32*)T3[temp[0][2]])
00233 ^ *((word32*)T4[temp[1][3]]);
00234 *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
00235 ^ *((word32*)T2[temp[0][1]])
00236 ^ *((word32*)T3[temp[1][2]])
00237 ^ *((word32*)T4[temp[2][3]]);
00238 for(r = 1; r < ROUNDS-1; r++) {
00239 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
00240 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
00241 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
00242 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
00243 *((word32*)b) = *((word32*)T1[temp[0][0]])
00244 ^ *((word32*)T2[temp[1][1]])
00245 ^ *((word32*)T3[temp[2][2]])
00246 ^ *((word32*)T4[temp[3][3]]);
00247 *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
00248 ^ *((word32*)T2[temp[2][1]])
00249 ^ *((word32*)T3[temp[3][2]])
00250 ^ *((word32*)T4[temp[0][3]]);
00251 *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
00252 ^ *((word32*)T2[temp[3][1]])
00253 ^ *((word32*)T3[temp[0][2]])
00254 ^ *((word32*)T4[temp[1][3]]);
00255 *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
00256 ^ *((word32*)T2[temp[0][1]])
00257 ^ *((word32*)T3[temp[1][2]])
00258 ^ *((word32*)T4[temp[2][3]]);
00259 }
00260
00261 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[ROUNDS-1][0]);
00262 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[ROUNDS-1][1]);
00263 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[ROUNDS-1][2]);
00264 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]);
00265 b[0] = T1[temp[0][0]][1];
00266 b[1] = T1[temp[1][1]][1];
00267 b[2] = T1[temp[2][2]][1];
00268 b[3] = T1[temp[3][3]][1];
00269 b[4] = T1[temp[1][0]][1];
00270 b[5] = T1[temp[2][1]][1];
00271 b[6] = T1[temp[3][2]][1];
00272 b[7] = T1[temp[0][3]][1];
00273 b[8] = T1[temp[2][0]][1];
00274 b[9] = T1[temp[3][1]][1];
00275 b[10] = T1[temp[0][2]][1];
00276 b[11] = T1[temp[1][3]][1];
00277 b[12] = T1[temp[3][0]][1];
00278 b[13] = T1[temp[0][1]][1];
00279 b[14] = T1[temp[1][2]][1];
00280 b[15] = T1[temp[2][3]][1];
00281 *((word32*)b) ^= *((word32*)rk[ROUNDS][0]);
00282 *((word32*)(b+4)) ^= *((word32*)rk[ROUNDS][1]);
00283 *((word32*)(b+8)) ^= *((word32*)rk[ROUNDS][2]);
00284 *((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
00285
00286 return 0;
00287 }
00288
00289 int rijndaelEncryptRound (word8 a[4][4],
00290 word8 rk[MAXROUNDS+1][4][4], int rounds)
00291
00292
00293
00294 {
00295 int r;
00296 word8 temp[4][4];
00297
00298
00299
00300 if (rounds > ROUNDS) rounds = ROUNDS;
00301
00302 *((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]);
00303 *((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]);
00304 *((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]);
00305 *((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]);
00306
00307 for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
00308 *((word32*)temp[0]) = *((word32*)T1[a[0][0]])
00309 ^ *((word32*)T2[a[1][1]])
00310 ^ *((word32*)T3[a[2][2]])
00311 ^ *((word32*)T4[a[3][3]]);
00312 *((word32*)temp[1]) = *((word32*)T1[a[1][0]])
00313 ^ *((word32*)T2[a[2][1]])
00314 ^ *((word32*)T3[a[3][2]])
00315 ^ *((word32*)T4[a[0][3]]);
00316 *((word32*)temp[2]) = *((word32*)T1[a[2][0]])
00317 ^ *((word32*)T2[a[3][1]])
00318 ^ *((word32*)T3[a[0][2]])
00319 ^ *((word32*)T4[a[1][3]]);
00320 *((word32*)temp[3]) = *((word32*)T1[a[3][0]])
00321 ^ *((word32*)T2[a[0][1]])
00322 ^ *((word32*)T3[a[1][2]])
00323 ^ *((word32*)T4[a[2][3]]);
00324 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]);
00325 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]);
00326 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]);
00327 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]);
00328 }
00329 if (rounds == ROUNDS) {
00330
00331 temp[0][0] = T1[a[0][0]][1];
00332 temp[0][1] = T1[a[1][1]][1];
00333 temp[0][2] = T1[a[2][2]][1];
00334 temp[0][3] = T1[a[3][3]][1];
00335 temp[1][0] = T1[a[1][0]][1];
00336 temp[1][1] = T1[a[2][1]][1];
00337 temp[1][2] = T1[a[3][2]][1];
00338 temp[1][3] = T1[a[0][3]][1];
00339 temp[2][0] = T1[a[2][0]][1];
00340 temp[2][1] = T1[a[3][1]][1];
00341 temp[2][2] = T1[a[0][2]][1];
00342 temp[2][3] = T1[a[1][3]][1];
00343 temp[3][0] = T1[a[3][0]][1];
00344 temp[3][1] = T1[a[0][1]][1];
00345 temp[3][2] = T1[a[1][2]][1];
00346 temp[3][3] = T1[a[2][3]][1];
00347 *((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]);
00348 *((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]);
00349 *((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]);
00350 *((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]);
00351 }
00352
00353 return 0;
00354 }
00355
00356
00357 int rijndaelDecrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
00358 {
00359 int r;
00360 word8 temp[4][4];
00361
00362
00363 *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[ROUNDS][0]);
00364 *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[ROUNDS][1]);
00365 *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[ROUNDS][2]);
00366 *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]);
00367 *((word32*)b) = *((word32*)T5[temp[0][0]])
00368 ^ *((word32*)T6[temp[3][1]])
00369 ^ *((word32*)T7[temp[2][2]])
00370 ^ *((word32*)T8[temp[1][3]]);
00371 *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
00372 ^ *((word32*)T6[temp[0][1]])
00373 ^ *((word32*)T7[temp[3][2]])
00374 ^ *((word32*)T8[temp[2][3]]);
00375 *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
00376 ^ *((word32*)T6[temp[1][1]])
00377 ^ *((word32*)T7[temp[0][2]])
00378 ^ *((word32*)T8[temp[3][3]]);
00379 *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
00380 ^ *((word32*)T6[temp[2][1]])
00381 ^ *((word32*)T7[temp[1][2]])
00382 ^ *((word32*)T8[temp[0][3]]);
00383 for(r = ROUNDS-1; r > 1; r--) {
00384 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
00385 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
00386 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
00387 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
00388 *((word32*)b) = *((word32*)T5[temp[0][0]])
00389 ^ *((word32*)T6[temp[3][1]])
00390 ^ *((word32*)T7[temp[2][2]])
00391 ^ *((word32*)T8[temp[1][3]]);
00392 *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
00393 ^ *((word32*)T6[temp[0][1]])
00394 ^ *((word32*)T7[temp[3][2]])
00395 ^ *((word32*)T8[temp[2][3]]);
00396 *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
00397 ^ *((word32*)T6[temp[1][1]])
00398 ^ *((word32*)T7[temp[0][2]])
00399 ^ *((word32*)T8[temp[3][3]]);
00400 *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
00401 ^ *((word32*)T6[temp[2][1]])
00402 ^ *((word32*)T7[temp[1][2]])
00403 ^ *((word32*)T8[temp[0][3]]);
00404 }
00405
00406 *((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[1][0]);
00407 *((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[1][1]);
00408 *((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[1][2]);
00409 *((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
00410 b[0] = S5[temp[0][0]];
00411 b[1] = S5[temp[3][1]];
00412 b[2] = S5[temp[2][2]];
00413 b[3] = S5[temp[1][3]];
00414 b[4] = S5[temp[1][0]];
00415 b[5] = S5[temp[0][1]];
00416 b[6] = S5[temp[3][2]];
00417 b[7] = S5[temp[2][3]];
00418 b[8] = S5[temp[2][0]];
00419 b[9] = S5[temp[1][1]];
00420 b[10] = S5[temp[0][2]];
00421 b[11] = S5[temp[3][3]];
00422 b[12] = S5[temp[3][0]];
00423 b[13] = S5[temp[2][1]];
00424 b[14] = S5[temp[1][2]];
00425 b[15] = S5[temp[0][3]];
00426 *((word32*)b) ^= *((word32*)rk[0][0]);
00427 *((word32*)(b+4)) ^= *((word32*)rk[0][1]);
00428 *((word32*)(b+8)) ^= *((word32*)rk[0][2]);
00429 *((word32*)(b+12)) ^= *((word32*)rk[0][3]);
00430
00431 return 0;
00432 }
00433
00434
00435 int rijndaelDecryptRound (word8 a[4][4],
00436 word8 rk[MAXROUNDS+1][4][4], int rounds)
00437
00438
00439
00440
00441
00442
00443 {
00444 int r;
00445
00446
00447
00448 if (rounds > ROUNDS) rounds = ROUNDS;
00449
00450
00451
00452
00453
00454 KeyAddition(a,rk[ROUNDS],4);
00455 Substitution(a,Si,4);
00456 ShiftRow(a,1,4);
00457
00458
00459
00460 for(r = ROUNDS-1; r > rounds; r--) {
00461 KeyAddition(a,rk[r],4);
00462 InvMixColumn(a,4);
00463 Substitution(a,Si,4);
00464 ShiftRow(a,1,4);
00465 }
00466
00467 if (rounds == 0) {
00468
00469
00470 KeyAddition(a,rk[0],4);
00471 }
00472
00473 return 0;
00474 }
00475
00476
00477
00478
00479 int makeKey(keyInstance *key, BYTE direction, int keyByteLen, char *keyMaterial)
00480 {
00481 word8 k[MAXKC][4];
00482 int i;
00483 int keyLen = keyByteLen*8;
00484
00485 if (key == NULL) {
00486 return BAD_KEY_INSTANCE;
00487 }
00488
00489 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
00490 key->direction = direction;
00491 } else {
00492 return BAD_KEY_DIR;
00493 }
00494
00495 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
00496 key->keyLen = keyLen;
00497 } else {
00498 return BAD_KEY_MAT;
00499 }
00500
00501 if ( keyMaterial ) {
00502 strncpy(key->keyMaterial, keyMaterial, keyByteLen);
00503 } else {
00504 return BAD_KEY_MAT;
00505 }
00506
00507 ROUNDS = keyLen/32 + 6;
00508
00509
00510 for(i = 0; i < key->keyLen/8; i++) {
00511 k[i / 4][i % 4] = (word8) key->keyMaterial[i];
00512 }
00513 rijndaelKeySched (k, key->keyLen, key->keySched);
00514 if (direction == DIR_DECRYPT)
00515 rijndaelKeyEnctoDec (key->keyLen, key->keySched);
00516
00517 return TRUE;
00518 }
00519
00520 int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
00521 {
00522 int i;
00523
00524 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
00525 cipher->mode = mode;
00526 } else {
00527 return BAD_CIPHER_MODE;
00528 }
00529
00530
00531 if (IV != NULL) {
00532 for(i = 0; i < 16; i++) cipher->IV[i] = IV[i];
00533 }
00534 else
00535 {
00536
00537 for(i = 0; i < 16; i++)
00538 cipher->IV[i]=(BYTE)randomMT();
00539 }
00540
00541 return TRUE;
00542 }
00543
00544
00545 int blockEncrypt(cipherInstance *cipher,
00546 keyInstance *key, BYTE *input, int inputByteLen, BYTE *outBuffer)
00547 {
00548 int i, k, numBlocks;
00549 word8 block[16], iv[4][4];
00550 int inputLen = inputByteLen*8;
00551
00552 if (cipher == NULL ||
00553 key == NULL ||
00554 key->direction == DIR_DECRYPT) {
00555 return BAD_CIPHER_STATE;
00556 }
00557
00558
00559 numBlocks = inputLen/128;
00560
00561 switch (cipher->mode) {
00562 case MODE_ECB:
00563 for (i = numBlocks; i > 0; i--) {
00564
00565 rijndaelEncrypt (input, outBuffer, key->keySched);
00566
00567 input += 16;
00568 outBuffer += 16;
00569 }
00570 break;
00571
00572 case MODE_CBC:
00573 #if STRICT_ALIGN
00574 memcpy(block,cipher->IV,16);
00575 #else
00576 *((word32*)block) = *((word32*)(cipher->IV));
00577 *((word32*)(block+4)) = *((word32*)(cipher->IV+4));
00578 *((word32*)(block+8)) = *((word32*)(cipher->IV+8));
00579 *((word32*)(block+12)) = *((word32*)(cipher->IV+12));
00580 #endif
00581
00582 for (i = numBlocks; i > 0; i--) {
00583 *((word32*)block) ^= *((word32*)(input));
00584 *((word32*)(block+4)) ^= *((word32*)(input+4));
00585 *((word32*)(block+8)) ^= *((word32*)(input+8));
00586 *((word32*)(block+12)) ^= *((word32*)(input+12));
00587
00588 rijndaelEncrypt (block, outBuffer, key->keySched);
00589
00590 input += 16;
00591 outBuffer += 16;
00592 }
00593 break;
00594
00595 case MODE_CFB1:
00596 #if STRICT_ALIGN
00597 memcpy(iv,cipher->IV,16);
00598 #else
00599 *((word32*)iv[0]) = *((word32*)(cipher->IV));
00600 *((word32*)iv[1]) = *((word32*)(cipher->IV+4));
00601 *((word32*)iv[2]) = *((word32*)(cipher->IV+8));
00602 *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
00603 #endif
00604 for (i = numBlocks; i > 0; i--) {
00605 for (k = 0; k < 128; k++) {
00606 *((word32*)block) = *((word32*)iv[0]);
00607 *((word32*)(block+4)) = *((word32*)iv[1]);
00608 *((word32*)(block+8)) = *((word32*)iv[2]);
00609 *((word32*)(block+12)) = *((word32*)iv[3]);
00610
00611 rijndaelEncrypt (block, block, key->keySched);
00612 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
00613 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
00614 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
00615 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
00616 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
00617 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
00618 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
00619 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
00620 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
00621 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
00622 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
00623 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
00624 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
00625 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
00626 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
00627 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
00628 iv[3][3] = (word8)((iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1);
00629 }
00630 }
00631 break;
00632
00633 default:
00634 return BAD_CIPHER_STATE;
00635 }
00636
00637 return numBlocks*128;
00638 }
00639
00640 int blockDecrypt(cipherInstance *cipher,
00641 keyInstance *key, BYTE *input, int inputByteLen, BYTE *outBuffer)
00642 {
00643 int i, k, numBlocks;
00644 word8 block[16], iv[4][4];
00645 int inputLen = inputByteLen*8;
00646
00647 if (cipher == NULL ||
00648 key == NULL ||
00649 cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT) {
00650 return BAD_CIPHER_STATE;
00651 }
00652
00653
00654 numBlocks = inputLen/128;
00655
00656 switch (cipher->mode) {
00657 case MODE_ECB:
00658 for (i = numBlocks; i > 0; i--) {
00659
00660 rijndaelDecrypt (input, outBuffer, key->keySched);
00661
00662 input += 16;
00663 outBuffer += 16;
00664
00665 }
00666 break;
00667
00668 case MODE_CBC:
00669
00670
00671 rijndaelDecrypt (input, block, key->keySched);
00672 #if STRICT_ALIGN
00673 memcpy(outBuffer,cipher->IV,16);
00674 *((word32*)(outBuffer)) ^= *((word32*)block);
00675 *((word32*)(outBuffer+4)) ^= *((word32*)(block+4));
00676 *((word32*)(outBuffer+8)) ^= *((word32*)(block+8));
00677 *((word32*)(outBuffer+12)) ^= *((word32*)(block+12));
00678 #else
00679 *((word32*)(outBuffer)) = *((word32*)block) ^ *((word32*)(cipher->IV));
00680 *((word32*)(outBuffer+4)) = *((word32*)(block+4)) ^ *((word32*)(cipher->IV+4));
00681 *((word32*)(outBuffer+8)) = *((word32*)(block+8)) ^ *((word32*)(cipher->IV+8));
00682 *((word32*)(outBuffer+12)) = *((word32*)(block+12)) ^ *((word32*)(cipher->IV+12));
00683 #endif
00684
00685
00686 for (i = numBlocks-1; i > 0; i--) {
00687
00688 rijndaelDecrypt (input, block, key->keySched);
00689
00690 *((word32*)(outBuffer+16)) = *((word32*)block) ^
00691 *((word32*)(input-16));
00692 *((word32*)(outBuffer+20)) = *((word32*)(block+4)) ^
00693 *((word32*)(input-12));
00694 *((word32*)(outBuffer+24)) = *((word32*)(block+8)) ^
00695 *((word32*)(input-8));
00696 *((word32*)(outBuffer+28)) = *((word32*)(block+12)) ^
00697 *((word32*)(input-4));
00698
00699 input += 16;
00700 outBuffer += 16;
00701 }
00702 break;
00703
00704 case MODE_CFB1:
00705 #if STRICT_ALIGN
00706 memcpy(iv,cipher->IV,16);
00707 #else
00708 *((word32*)iv[0]) = *((word32*)(cipher->IV));
00709 *((word32*)iv[1]) = *((word32*)(cipher->IV+4));
00710 *((word32*)iv[2]) = *((word32*)(cipher->IV+8));
00711 *((word32*)iv[3]) = *((word32*)(cipher->IV+12));
00712 #endif
00713 for (i = numBlocks; i > 0; i--) {
00714 for (k = 0; k < 128; k++) {
00715 *((word32*)block) = *((word32*)iv[0]);
00716 *((word32*)(block+4)) = *((word32*)iv[1]);
00717 *((word32*)(block+8)) = *((word32*)iv[2]);
00718 *((word32*)(block+12)) = *((word32*)iv[3]);
00719
00720 rijndaelEncrypt (block, block, key->keySched);
00721 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
00722 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
00723 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
00724 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
00725 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
00726 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
00727 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
00728 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
00729 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
00730 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
00731 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
00732 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
00733 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
00734 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
00735 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
00736 iv[3][3] = (word8)((iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1);
00737 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
00738 }
00739 }
00740 break;
00741
00742 default:
00743 return BAD_CIPHER_STATE;
00744 }
00745
00746 return numBlocks*128;
00747 }
00748
00749
00761 int cipherUpdateRounds(cipherInstance *cipher,
00762 keyInstance *key, BYTE *input, int inputLen __UNUS, BYTE *outBuffer, int rounds)
00763 {
00764 (void) inputLen;
00765
00766 int j;
00767 word8 block[4][4];
00768
00769 if (cipher == NULL ||
00770 key == NULL) {
00771 return BAD_CIPHER_STATE;
00772 }
00773
00774 for (j = 3; j >= 0; j--) {
00775
00776 *((word32*)block[j]) = *((word32*)(input+4*j));
00777 }
00778
00779 switch (key->direction) {
00780 case DIR_ENCRYPT:
00781 rijndaelEncryptRound (block, key->keySched, rounds);
00782 break;
00783
00784 case DIR_DECRYPT:
00785 rijndaelDecryptRound (block, key->keySched, rounds);
00786 break;
00787
00788 default: return BAD_KEY_DIR;
00789 }
00790
00791 for (j = 3; j >= 0; j--) {
00792
00793 *((word32*)(outBuffer+4*j)) = *((word32*)block[j]);
00794 }
00795
00796 return TRUE;
00797 }