00001
00038 #include "db_config.h"
00039
00040 #ifndef NO_SYSTEM_INCLUDES
00041 #include <string.h>
00042 #endif
00043
00044 #include "db_int.h"
00045 #include "dbinc/crypto.h"
00046
00047 #include "crypto/rijndael/rijndael-alg-fst.h"
00048 #include "crypto/rijndael/rijndael-api-fst.h"
00049
00050
00051
00052
00053
00054
00055 int
00056 __db_makeKey(key, direction, keyLen, keyMaterial)
00057 keyInstance *key;
00058 int direction;
00059 int keyLen;
00060 char *keyMaterial;
00061 {
00062 u8 cipherKey[MAXKB];
00063
00064 if (key == NULL) {
00065 return BAD_KEY_INSTANCE;
00066 }
00067
00068 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
00069 key->direction = direction;
00070 } else {
00071 return BAD_KEY_DIR;
00072 }
00073
00074 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
00075 key->keyLen = keyLen;
00076 } else {
00077 return BAD_KEY_MAT;
00078 }
00079
00080 if (keyMaterial != NULL) {
00081 memcpy(cipherKey, keyMaterial, key->keyLen/8);
00082 }
00083
00084 if (direction == DIR_ENCRYPT) {
00085 key->Nr = __db_rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
00086 } else {
00087 key->Nr = __db_rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
00088 }
00089 __db_rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
00090 return TRUE;
00091 }
00092
00093
00094
00095
00096
00097
00098 int
00099 __db_cipherInit(cipher, mode, IV)
00100 cipherInstance *cipher;
00101 int mode;
00102 char *IV;
00103 {
00104 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
00105 cipher->mode = mode;
00106 } else {
00107 return BAD_CIPHER_MODE;
00108 }
00109 if (IV != NULL) {
00110 memcpy(cipher->IV, IV, MAX_IV_SIZE);
00111 }
00112 return TRUE;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 int
00122 __db_blockEncrypt(cipher, key, input, inputLen, outBuffer)
00123 cipherInstance *cipher;
00124 keyInstance *key;
00125 u_int8_t *input;
00126 size_t inputLen;
00127 u_int8_t *outBuffer;
00128 {
00129 int i, k, t, numBlocks;
00130 u8 block[16], *iv;
00131 u32 tmpiv[4];
00132
00133 if (cipher == NULL ||
00134 key == NULL ||
00135 key->direction == DIR_DECRYPT) {
00136 return BAD_CIPHER_STATE;
00137 }
00138 if (input == NULL || inputLen <= 0) {
00139 return 0;
00140 }
00141
00142 numBlocks = (int)(inputLen/128);
00143
00144 switch (cipher->mode) {
00145 case MODE_ECB:
00146 for (i = numBlocks; i > 0; i--) {
00147 __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
00148 input += 16;
00149 outBuffer += 16;
00150 }
00151 break;
00152
00153 case MODE_CBC:
00154 iv = cipher->IV;
00155 for (i = numBlocks; i > 0; i--) {
00156 memcpy(tmpiv, iv, MAX_IV_SIZE);
00157 ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
00158 ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
00159 ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
00160 ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
00161 __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00162 iv = outBuffer;
00163 input += 16;
00164 outBuffer += 16;
00165 }
00166 break;
00167
00168 case MODE_CFB1:
00169 iv = cipher->IV;
00170 for (i = numBlocks; i > 0; i--) {
00171 memcpy(outBuffer, input, 16);
00172 for (k = 0; k < 128; k++) {
00173 __db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
00174 outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
00175 for (t = 0; t < 15; t++) {
00176 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
00177 }
00178 iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
00179 }
00180 outBuffer += 16;
00181 input += 16;
00182 }
00183 break;
00184
00185 default:
00186 return BAD_CIPHER_STATE;
00187 }
00188
00189 return 128*numBlocks;
00190 }
00191
00201
00202
00203
00204
00205
00206
00207 int
00208 __db_padEncrypt(cipher, key, input, inputOctets, outBuffer)
00209 cipherInstance *cipher;
00210 keyInstance *key;
00211 u_int8_t *input;
00212 int inputOctets;
00213 u_int8_t *outBuffer;
00214 {
00215 int i, numBlocks, padLen;
00216 u8 block[16], *iv;
00217 u32 tmpiv[4];
00218
00219 if (cipher == NULL ||
00220 key == NULL ||
00221 key->direction == DIR_DECRYPT) {
00222 return BAD_CIPHER_STATE;
00223 }
00224 if (input == NULL || inputOctets <= 0) {
00225 return 0;
00226 }
00227
00228 numBlocks = inputOctets/16;
00229
00230 switch (cipher->mode) {
00231 case MODE_ECB:
00232 for (i = numBlocks; i > 0; i--) {
00233 __db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
00234 input += 16;
00235 outBuffer += 16;
00236 }
00237 padLen = 16 - (inputOctets - 16*numBlocks);
00238 DB_ASSERT(padLen > 0 && padLen <= 16);
00239 memcpy(block, input, 16 - padLen);
00240 memset(block + 16 - padLen, padLen, padLen);
00241 __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00242 break;
00243
00244 case MODE_CBC:
00245 iv = cipher->IV;
00246 for (i = numBlocks; i > 0; i--) {
00247 memcpy(tmpiv, iv, MAX_IV_SIZE);
00248 ((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
00249 ((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
00250 ((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
00251 ((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
00252 __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00253 iv = outBuffer;
00254 input += 16;
00255 outBuffer += 16;
00256 }
00257 padLen = 16 - (inputOctets - 16*numBlocks);
00258 DB_ASSERT(padLen > 0 && padLen <= 16);
00259 for (i = 0; i < 16 - padLen; i++) {
00260 block[i] = input[i] ^ iv[i];
00261 }
00262 for (i = 16 - padLen; i < 16; i++) {
00263 block[i] = (u_int8_t)padLen ^ iv[i];
00264 }
00265 __db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
00266 break;
00267
00268 default:
00269 return BAD_CIPHER_STATE;
00270 }
00271
00272 return 16*(numBlocks + 1);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 int
00282 __db_blockDecrypt(cipher, key, input, inputLen, outBuffer)
00283 cipherInstance *cipher;
00284 keyInstance *key;
00285 u_int8_t *input;
00286 size_t inputLen;
00287 u_int8_t *outBuffer;
00288 {
00289 int i, k, t, numBlocks;
00290 u8 block[16], *iv;
00291 u32 tmpiv[4];
00292
00293 if (cipher == NULL ||
00294 key == NULL ||
00295 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
00296 return BAD_CIPHER_STATE;
00297 }
00298 if (input == NULL || inputLen <= 0) {
00299 return 0;
00300 }
00301
00302 numBlocks = (int)(inputLen/128);
00303
00304 switch (cipher->mode) {
00305 case MODE_ECB:
00306 for (i = numBlocks; i > 0; i--) {
00307 __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
00308 input += 16;
00309 outBuffer += 16;
00310 }
00311 break;
00312
00313 case MODE_CBC:
00314 memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
00315 for (i = numBlocks; i > 0; i--) {
00316 __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
00317 ((u32*)block)[0] ^= tmpiv[0];
00318 ((u32*)block)[1] ^= tmpiv[1];
00319 ((u32*)block)[2] ^= tmpiv[2];
00320 ((u32*)block)[3] ^= tmpiv[3];
00321 memcpy(tmpiv, input, 16);
00322 memcpy(outBuffer, block, 16);
00323 input += 16;
00324 outBuffer += 16;
00325 }
00326 break;
00327
00328 case MODE_CFB1:
00329 iv = cipher->IV;
00330 for (i = numBlocks; i > 0; i--) {
00331 memcpy(outBuffer, input, 16);
00332 for (k = 0; k < 128; k++) {
00333 __db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
00334 for (t = 0; t < 15; t++) {
00335 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
00336 }
00337 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
00338 outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
00339 }
00340 outBuffer += 16;
00341 input += 16;
00342 }
00343 break;
00344
00345 default:
00346 return BAD_CIPHER_STATE;
00347 }
00348
00349 return 128*numBlocks;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358 int
00359 __db_padDecrypt(cipher, key, input, inputOctets, outBuffer)
00360 cipherInstance *cipher;
00361 keyInstance *key;
00362 u_int8_t *input;
00363 int inputOctets;
00364 u_int8_t *outBuffer;
00365 {
00366 int i, numBlocks, padLen;
00367 u8 block[16];
00368 u32 tmpiv[4];
00369
00370 if (cipher == NULL ||
00371 key == NULL ||
00372 key->direction == DIR_ENCRYPT) {
00373 return BAD_CIPHER_STATE;
00374 }
00375 if (input == NULL || inputOctets <= 0) {
00376 return 0;
00377 }
00378 if (inputOctets % 16 != 0) {
00379 return BAD_DATA;
00380 }
00381
00382 numBlocks = inputOctets/16;
00383
00384 switch (cipher->mode) {
00385 case MODE_ECB:
00386
00387 for (i = numBlocks - 1; i > 0; i--) {
00388 __db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
00389 input += 16;
00390 outBuffer += 16;
00391 }
00392
00393 __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
00394 padLen = block[15];
00395 if (padLen >= 16) {
00396 return BAD_DATA;
00397 }
00398 for (i = 16 - padLen; i < 16; i++) {
00399 if (block[i] != padLen) {
00400 return BAD_DATA;
00401 }
00402 }
00403 memcpy(outBuffer, block, 16 - padLen);
00404 break;
00405
00406 case MODE_CBC:
00407
00408 memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
00409 for (i = numBlocks - 1; i > 0; i--) {
00410 __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
00411 ((u32*)block)[0] ^= tmpiv[0];
00412 ((u32*)block)[1] ^= tmpiv[1];
00413 ((u32*)block)[2] ^= tmpiv[2];
00414 ((u32*)block)[3] ^= tmpiv[3];
00415 memcpy(tmpiv, input, 16);
00416 memcpy(outBuffer, block, 16);
00417 input += 16;
00418 outBuffer += 16;
00419 }
00420
00421 __db_rijndaelDecrypt(key->rk, key->Nr, input, block);
00422 ((u32*)block)[0] ^= tmpiv[0];
00423 ((u32*)block)[1] ^= tmpiv[1];
00424 ((u32*)block)[2] ^= tmpiv[2];
00425 ((u32*)block)[3] ^= tmpiv[3];
00426 padLen = block[15];
00427 if (padLen <= 0 || padLen > 16) {
00428 return BAD_DATA;
00429 }
00430 for (i = 16 - padLen; i < 16; i++) {
00431 if (block[i] != padLen) {
00432 return BAD_DATA;
00433 }
00434 }
00435 memcpy(outBuffer, block, 16 - padLen);
00436 break;
00437
00438 default:
00439 return BAD_CIPHER_STATE;
00440 }
00441
00442 return 16*numBlocks - padLen;
00443 }
00444
00445 #ifdef INTERMEDIATE_VALUE_KAT
00446
00456
00457
00458
00459
00460
00461
00462 int
00463 __db_cipherUpdateRounds(cipher, key, input, inputLen, outBuffer, rounds)
00464 cipherInstance *cipher;
00465 keyInstance *key;
00466 u_int8_t *input;
00467 size_t inputLen;
00468 u_int8_t *outBuffer;
00469 int rounds;
00470 {
00471 u8 block[16];
00472
00473 if (cipher == NULL || key == NULL) {
00474 return BAD_CIPHER_STATE;
00475 }
00476
00477 memcpy(block, input, 16);
00478
00479 switch (key->direction) {
00480 case DIR_ENCRYPT:
00481 __db_rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
00482 break;
00483
00484 case DIR_DECRYPT:
00485 __db_rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
00486 break;
00487
00488 default:
00489 return BAD_KEY_DIR;
00490 }
00491
00492 memcpy(outBuffer, block, 16);
00493
00494 return TRUE;
00495 }
00496 #endif