00001
00038 #include <assert.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041
00042 #ifdef _MSC_VER
00043 # pragma warning (disable : 4115 )
00044 #endif
00045
00046 #include "rijndael-alg-fst.h"
00047 #include "rijndael-api-fst.h"
00048
00049 int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
00050 int i;
00051 char *keyMat;
00052 u8 cipherKey[MAXKB];
00053
00054 if (key == NULL) {
00055 return BAD_KEY_INSTANCE;
00056 }
00057
00058 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
00059 key->direction = direction;
00060 } else {
00061 return BAD_KEY_DIR;
00062 }
00063
00064 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
00065 key->keyLen = keyLen;
00066 } else {
00067 return BAD_KEY_MAT;
00068 }
00069
00070 if (keyMaterial != NULL) {
00071 strncpy(key->keyMaterial, keyMaterial, keyLen/4);
00072 }
00073
00074
00075 keyMat = key->keyMaterial;
00076 for (i = 0; i < key->keyLen/8; i++) {
00077 int t, v;
00078
00079 t = *keyMat++;
00080 if ((t >= '0') && (t <= '9')) v = (t - '0') << 4;
00081 else if ((t >= 'a') && (t <= 'f')) v = (t - 'a' + 10) << 4;
00082 else if ((t >= 'A') && (t <= 'F')) v = (t - 'A' + 10) << 4;
00083 else return BAD_KEY_MAT;
00084
00085 t = *keyMat++;
00086 if ((t >= '0') && (t <= '9')) v ^= (t - '0');
00087 else if ((t >= 'a') && (t <= 'f')) v ^= (t - 'a' + 10);
00088 else if ((t >= 'A') && (t <= 'F')) v ^= (t - 'A' + 10);
00089 else return BAD_KEY_MAT;
00090
00091 cipherKey[i] = (u8)v;
00092 }
00093 if (direction == DIR_ENCRYPT) {
00094 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
00095 } else {
00096 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
00097 }
00098 rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
00099 return TRUE;
00100 }
00101
00102 int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
00103 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
00104 cipher->mode = mode;
00105 } else {
00106 return BAD_CIPHER_MODE;
00107 }
00108 if (IV != NULL) {
00109 int i;
00110 for (i = 0; i < MAX_IV_SIZE; i++) {
00111 int t, j;
00112
00113 t = IV[2*i];
00114 if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
00115 else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
00116 else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
00117 else return BAD_CIPHER_INSTANCE;
00118
00119 t = IV[2*i+1];
00120 if ((t >= '0') && (t <= '9')) j ^= (t - '0');
00121 else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
00122 else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
00123 else return BAD_CIPHER_INSTANCE;
00124
00125 cipher->IV[i] = (u8)j;
00126 }
00127 } else {
00128 memset(cipher->IV, 0, MAX_IV_SIZE);
00129 }
00130 return TRUE;
00131 }
00132
00133 int blockEncrypt(cipherInstance *cipher, keyInstance *key,
00134 BYTE *input, int inputLen, BYTE *outBuffer) {
00135 int i, k, t, numBlocks;
00136 u8 block[16], *iv;
00137
00138 if (cipher == NULL ||
00139 key == NULL ||
00140 key->direction == DIR_DECRYPT) {
00141 return BAD_CIPHER_STATE;
00142 }
00143 if (input == NULL || inputLen <= 0) {
00144 return 0;
00145 }
00146
00147 numBlocks = inputLen/128;
00148
00149 switch (cipher->mode) {
00150 case MODE_ECB:
00151 for (i = numBlocks; i > 0; i--) {
00152 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
00153 input += 16;
00154 outBuffer += 16;
00155 }
00156 break;
00157
00158 case MODE_CBC:
00159 iv = cipher->IV;
00160 for (i = numBlocks; i > 0; i--) {
00161 ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0];
00162 ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1];
00163 ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2];
00164 ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3];
00165 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00166 iv = outBuffer;
00167 input += 16;
00168 outBuffer += 16;
00169 }
00170 break;
00171
00172 case MODE_CFB1:
00173 iv = cipher->IV;
00174 for (i = numBlocks; i > 0; i--) {
00175 memcpy(outBuffer, input, 16);
00176 for (k = 0; k < 128; k++) {
00177 rijndaelEncrypt(key->ek, key->Nr, iv, block);
00178 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
00179 for (t = 0; t < 15; t++) {
00180
00181 iv[t] = (u8)((iv[t] << 1) | (iv[t + 1] >> 7));
00182 }
00183
00184 iv[15] = (u8)( (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1) );
00185 }
00186 outBuffer += 16;
00187 input += 16;
00188 }
00189 break;
00190
00191 default:
00192 return BAD_CIPHER_STATE;
00193 }
00194
00195 return 128*numBlocks;
00196 }
00197
00207 int padEncrypt(cipherInstance *cipher, keyInstance *key,
00208 BYTE *input, int inputOctets, BYTE *outBuffer) {
00209 int i, numBlocks, padLen;
00210 u8 block[16], *iv;
00211
00212 if (cipher == NULL ||
00213 key == NULL ||
00214 key->direction == DIR_DECRYPT) {
00215 return BAD_CIPHER_STATE;
00216 }
00217 if (input == NULL || inputOctets <= 0) {
00218 return 0;
00219 }
00220
00221 numBlocks = inputOctets/16;
00222
00223 switch (cipher->mode) {
00224 case MODE_ECB:
00225 for (i = numBlocks; i > 0; i--) {
00226 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
00227 input += 16;
00228 outBuffer += 16;
00229 }
00230 padLen = 16 - (inputOctets - 16*numBlocks);
00231 assert(padLen > 0 && padLen <= 16);
00232 memcpy(block, input, 16 - padLen);
00233 memset(block + 16 - padLen, padLen, padLen);
00234 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00235 break;
00236
00237 case MODE_CBC:
00238 iv = cipher->IV;
00239 for (i = numBlocks; i > 0; i--) {
00240 ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0];
00241 ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1];
00242 ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2];
00243 ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3];
00244 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00245 iv = outBuffer;
00246 input += 16;
00247 outBuffer += 16;
00248 }
00249 padLen = 16 - (inputOctets - 16*numBlocks);
00250 assert(padLen > 0 && padLen <= 16);
00251 for (i = 0; i < 16 - padLen; i++) {
00252
00253 block[i] = (u8)(input[i] ^ iv[i]);
00254 }
00255 for (i = 16 - padLen; i < 16; i++) {
00256
00257 block[i] = (u8)( (u8)padLen ^ iv[i] );
00258 }
00259 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00260 break;
00261
00262 default:
00263 return BAD_CIPHER_STATE;
00264 }
00265
00266 return 16*(numBlocks + 1);
00267 }
00268
00269 int blockDecrypt(cipherInstance *cipher, keyInstance *key,
00270 BYTE *input, int inputLen, BYTE *outBuffer) {
00271 int i, k, t, numBlocks;
00272 u8 block[16], *iv;
00273
00274 if (cipher == NULL ||
00275 key == NULL ||
00276 cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT) {
00277 return BAD_CIPHER_STATE;
00278 }
00279 if (input == NULL || inputLen <= 0) {
00280 return 0;
00281 }
00282
00283 numBlocks = inputLen/128;
00284
00285 switch (cipher->mode) {
00286 case MODE_ECB:
00287 for (i = numBlocks; i > 0; i--) {
00288 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
00289 input += 16;
00290 outBuffer += 16;
00291 }
00292 break;
00293
00294 case MODE_CBC:
00295 iv = cipher->IV;
00296 for (i = numBlocks; i > 0; i--) {
00297 rijndaelDecrypt(key->rk, key->Nr, input, block);
00298 ((u32*)block)[0] ^= ((u32*)iv)[0];
00299 ((u32*)block)[1] ^= ((u32*)iv)[1];
00300 ((u32*)block)[2] ^= ((u32*)iv)[2];
00301 ((u32*)block)[3] ^= ((u32*)iv)[3];
00302 memcpy(cipher->IV, input, 16);
00303 memcpy(outBuffer, block, 16);
00304 input += 16;
00305 outBuffer += 16;
00306 }
00307 break;
00308
00309 case MODE_CFB1:
00310 iv = cipher->IV;
00311 for (i = numBlocks; i > 0; i--) {
00312 memcpy(outBuffer, input, 16);
00313 for (k = 0; k < 128; k++) {
00314 rijndaelEncrypt(key->ek, key->Nr, iv, block);
00315 for (t = 0; t < 15; t++) {
00316
00317 iv[t] = (u8)( (iv[t] << 1) | (iv[t + 1] >> 7) );
00318 }
00319
00320 iv[15] = (u8)( (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1) );
00321 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
00322 }
00323 outBuffer += 16;
00324 input += 16;
00325 }
00326 break;
00327
00328 default:
00329 return BAD_CIPHER_STATE;
00330 }
00331
00332 return 128*numBlocks;
00333 }
00334
00335 int padDecrypt(cipherInstance *cipher, keyInstance *key,
00336 BYTE *input, int inputOctets, BYTE *outBuffer) {
00337 int i, numBlocks, padLen;
00338 u8 block[16];
00339
00340 if (cipher == NULL ||
00341 key == NULL ||
00342 key->direction == DIR_ENCRYPT) {
00343 return BAD_CIPHER_STATE;
00344 }
00345 if (input == NULL || inputOctets <= 0) {
00346 return 0;
00347 }
00348 if (inputOctets % 16 != 0) {
00349 return BAD_DATA;
00350 }
00351
00352 numBlocks = inputOctets/16;
00353
00354 switch (cipher->mode) {
00355 case MODE_ECB:
00356
00357 for (i = numBlocks - 1; i > 0; i--) {
00358 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
00359 input += 16;
00360 outBuffer += 16;
00361 }
00362
00363 rijndaelDecrypt(key->rk, key->Nr, input, block);
00364 padLen = block[15];
00365 if (padLen >= 16) {
00366 return BAD_DATA;
00367 }
00368 for (i = 16 - padLen; i < 16; i++) {
00369 if (block[i] != padLen) {
00370 return BAD_DATA;
00371 }
00372 }
00373 memcpy(outBuffer, block, 16 - padLen);
00374 break;
00375
00376 case MODE_CBC:
00377
00378 for (i = numBlocks - 1; i > 0; i--) {
00379 rijndaelDecrypt(key->rk, key->Nr, input, block);
00380 ((u32*)block)[0] ^= ((u32*)cipher->IV)[0];
00381 ((u32*)block)[1] ^= ((u32*)cipher->IV)[1];
00382 ((u32*)block)[2] ^= ((u32*)cipher->IV)[2];
00383 ((u32*)block)[3] ^= ((u32*)cipher->IV)[3];
00384 memcpy(cipher->IV, input, 16);
00385 memcpy(outBuffer, block, 16);
00386 input += 16;
00387 outBuffer += 16;
00388 }
00389
00390 rijndaelDecrypt(key->rk, key->Nr, input, block);
00391 ((u32*)block)[0] ^= ((u32*)cipher->IV)[0];
00392 ((u32*)block)[1] ^= ((u32*)cipher->IV)[1];
00393 ((u32*)block)[2] ^= ((u32*)cipher->IV)[2];
00394 ((u32*)block)[3] ^= ((u32*)cipher->IV)[3];
00395 padLen = block[15];
00396 if (padLen <= 0 || padLen > 16) {
00397 return BAD_DATA;
00398 }
00399 for (i = 16 - padLen; i < 16; i++) {
00400 if (block[i] != padLen) {
00401 return BAD_DATA;
00402 }
00403 }
00404 memcpy(outBuffer, block, 16 - padLen);
00405 break;
00406
00407 default:
00408 return BAD_CIPHER_STATE;
00409 }
00410
00411 return 16*numBlocks - padLen;
00412 }
00413
00414 #ifdef INTERMEDIATE_VALUE_KAT
00415
00425 int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key,
00426 BYTE *input, int inputLen, BYTE *outBuffer, int rounds) {
00427 u8 block[16];
00428
00429 if (cipher == NULL || key == NULL) {
00430 return BAD_CIPHER_STATE;
00431 }
00432
00433 memcpy(block, input, 16);
00434
00435 switch (key->direction) {
00436 case DIR_ENCRYPT:
00437 rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
00438 break;
00439
00440 case DIR_DECRYPT:
00441 rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
00442 break;
00443
00444 default:
00445 return BAD_KEY_DIR;
00446 }
00447
00448 memcpy(outBuffer, block, 16);
00449
00450 return TRUE;
00451 }
00452 #endif