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