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

# rijndael-api-fst.c

説明を見る。

    00001
    00038 /*
    00039 #include <assert.h>
    00040 #include <stdlib.h>
    00041 #include <string.h>
    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     /* initialize key schedule: */
    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; /* nothing to do */
    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                                     //d金魚改：大丈夫かな？by d金魚
    00183                     iv[t] = (u8)((iv[t] << 1) | (iv[t + 1] >> 7));
    00184                 }
    00185                                 //d金魚改：(u8)でくくった
    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; /* nothing to do */
    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             //d金魚改：(u8)でくくった
    00255             block[i] = (u8)(input[i] ^ iv[i]);
    00256         }
    00257         for (i = 16 - padLen; i < 16; i++) {
    00258             //d金魚改：(u8)でくくった
    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; /* nothing to do */
    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                                     //d金魚改：(u8)でくくった
    00319                     iv[t] = (u8)( (iv[t] << 1) | (iv[t + 1] >> 7) );
    00320                 }
    00321                                 //d金魚改：(u8)でくくった
    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; /* nothing to do */
    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         /* all blocks but last */
    00359         for (i = numBlocks - 1; i > 0; i--) {
    00360             rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
    00361             input += 16;
    00362             outBuffer += 16;
    00363         }
    00364         /* last block */
    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         /* all blocks but last */
    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         /* last block */
    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 /* INTERMEDIATE_VALUE_KAT */