メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

rijndael-api-fst.c

説明を見る。
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     /* initialize key schedule: */
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; /* nothing to do */
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                                     //d金魚改:大丈夫かな?by d金魚
00181                     iv[t] = (u8)((iv[t] << 1) | (iv[t + 1] >> 7));
00182                 }
00183                                 //d金魚改:(u8)でくくった
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; /* nothing to do */
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             //d金魚改:(u8)でくくった
00253             block[i] = (u8)(input[i] ^ iv[i]);
00254         }
00255         for (i = 16 - padLen; i < 16; i++) {
00256             //d金魚改:(u8)でくくった
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; /* nothing to do */
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                                     //d金魚改:(u8)でくくった
00317                     iv[t] = (u8)( (iv[t] << 1) | (iv[t + 1] >> 7) );
00318                 }
00319                                 //d金魚改:(u8)でくくった
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; /* nothing to do */
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         /* all blocks but last */
00357         for (i = numBlocks - 1; i > 0; i--) {
00358             rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
00359             input += 16;
00360             outBuffer += 16;
00361         }
00362         /* last block */
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         /* all blocks but last */
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         /* last block */
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 /* INTERMEDIATE_VALUE_KAT */

dkutil_cに対してTue Dec 7 01:09:57 2004に生成されました。 doxygen 1.3.6