Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

rijndael-api-fst.c

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  * __db_makeKey --
00052  *
00053  * PUBLIC: int __db_makeKey __P((keyInstance *, int, int, char *));
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  * __db_cipherInit --
00095  *
00096  * PUBLIC: int __db_cipherInit __P((cipherInstance *, int, char *));
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  * __db_blockEncrypt --
00117  *
00118  * PUBLIC: int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
00119  * PUBLIC:    size_t, u_int8_t *));
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; /* nothing to do */
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  * __db_padEncrypt --
00203  *
00204  * PUBLIC: int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
00205  * PUBLIC:    int, u_int8_t *));
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; /* nothing to do */
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  * __db_blockDecrypt --
00277  *
00278  * PUBLIC: int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
00279  * PUBLIC:    size_t, u_int8_t *));
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; /* nothing to do */
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  * __db_padDecrypt --
00354  *
00355  * PUBLIC: int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
00356  * PUBLIC:    int, u_int8_t *));
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; /* nothing to do */
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                 /* all blocks but last */
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                 /* last block */
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                 /* all blocks but last */
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                 /* last block */
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  * __db_cipherUpdateRounds --
00458  *
00459  * PUBLIC: int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *,
00460  * PUBLIC:    u_int8_t *, int, u_int8_t *, int));
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 /* INTERMEDIATE_VALUE_KAT */

Generated on Sun Dec 25 12:14:17 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2