00001
00031 #include "thig_aes.h"
00032 #include "thig_table.h"
00033
00034
00035
00036
00037
00038
00039 #define VALIDATE_PARMS 1
00040 #define FEISTEL 0
00042 int tabEnable=0;
00043 BYTE tabUsed[256];
00045 #if FEISTEL
00046 CONST char *moduleDescription="Pedagogical C code (Feistel)";
00047 #else
00048 CONST char *moduleDescription="Pedagogical C code";
00049 #endif
00050 CONST char *modeString = "";
00051
00052 #define P0_USED 0x01
00053 #define P1_USED 0x02
00054 #define B0_USED 0x04
00055 #define B1_USED 0x08
00056 #define B2_USED 0x10
00057 #define B3_USED 0x20
00058 #define ALL_USED 0x3F
00059
00061 int numRounds[4]= {0,ROUNDS_128,ROUNDS_192,ROUNDS_256};
00062
00063 #ifndef DEBUG
00064 #ifdef GetCodeSize
00065 #define DEBUG 1
00066 #endif
00067 #endif
00068 #include "thig_debug.h"
00070 #ifdef GetCodeSize
00071 extern DWORD Here(DWORD x);
00072 DWORD TwofishCodeStart(void) { return Here(0); };
00073 #endif
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 int TableOp(int op)
00084 {
00085 static int queryCnt=0;
00086 int i;
00087 switch (op)
00088 {
00089 case TAB_DISABLE:
00090 tabEnable=0;
00091 break;
00092 case TAB_ENABLE:
00093 tabEnable=1;
00094 break;
00095 case TAB_RESET:
00096 queryCnt=0;
00097 for (i=0;i<256;i++)
00098 tabUsed[i]=0;
00099 break;
00100 case TAB_QUERY:
00101 queryCnt++;
00102 for (i=0;i<256;i++)
00103 if (tabUsed[i] != ALL_USED)
00104 return FALSE;
00105 if (queryCnt < TAB_MIN_QUERY)
00106 return FALSE;
00107 break;
00108 }
00109 return TRUE;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 int ParseHexDword(int bits,CONST char *srcTxt,DWORD *d,char *dstTxt)
00133 {
00134 int i;
00135 DWORD b;
00136 char c;
00137
00138
00139
00140
00141 union
00142 {
00143 BYTE b[4];
00144 DWORD d[1];
00145 } v;
00146 v.d[0]=1;
00147 if (v.b[0 ^ ADDR_XOR] != 1)
00148 return BAD_ENDIAN;
00149
00150 #if VALIDATE_PARMS
00151 #if ALIGN32
00152 if (((int)d) & 3)
00153 return BAD_ALIGN32;
00154 #endif
00155 #endif
00156
00157 for (i=0;i*32<bits;i++)
00158 d[i]=0;
00159
00160 for (i=0;i*4<bits;i++)
00161 {
00162 c=srcTxt[i];
00163 if (dstTxt) dstTxt[i]=c;
00164 if ((c >= '0') && (c <= '9'))
00165 b=c-'0';
00166 else if ((c >= 'a') && (c <= 'f'))
00167 b=c-'a'+10;
00168 else if ((c >= 'A') && (c <= 'F'))
00169 b=c-'A'+10;
00170 else
00171 return BAD_KEY_MAT;
00172
00173 d[i/8] |= b << (4*((i^1)&7));
00174 }
00175
00176 return 0;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 DWORD f32(DWORD x,CONST DWORD *k32,int keyLen)
00209 {
00210 BYTE b[4];
00211
00212
00213
00214
00215 *((DWORD *)b) = Bswap(x);
00216 switch (((keyLen + 63)/64) & 3)
00217 {
00218 case 0:
00219 b[0] = p8(04)[b[0]] ^ b0(k32[3]);
00220 b[1] = p8(14)[b[1]] ^ b1(k32[3]);
00221 b[2] = p8(24)[b[2]] ^ b2(k32[3]);
00222 b[3] = p8(34)[b[3]] ^ b3(k32[3]);
00223
00224 case 3:
00225 b[0] = p8(03)[b[0]] ^ b0(k32[2]);
00226 b[1] = p8(13)[b[1]] ^ b1(k32[2]);
00227 b[2] = p8(23)[b[2]] ^ b2(k32[2]);
00228 b[3] = p8(33)[b[3]] ^ b3(k32[2]);
00229
00230 case 2:
00231 b[0] = p8(00)[p8(01)[p8(02)[b[0]] ^ b0(k32[1])] ^ b0(k32[0])];
00232 b[1] = p8(10)[p8(11)[p8(12)[b[1]] ^ b1(k32[1])] ^ b1(k32[0])];
00233 b[2] = p8(20)[p8(21)[p8(22)[b[2]] ^ b2(k32[1])] ^ b2(k32[0])];
00234 b[3] = p8(30)[p8(31)[p8(32)[b[3]] ^ b3(k32[1])] ^ b3(k32[0])];
00235 }
00236
00237 if (tabEnable)
00238 {
00239 tabUsed[b0(x)] |= (P_00 == 0) ? P0_USED : P1_USED;
00240 tabUsed[b1(x)] |= (P_10 == 0) ? P0_USED : P1_USED;
00241 tabUsed[b2(x)] |= (P_20 == 0) ? P0_USED : P1_USED;
00242 tabUsed[b3(x)] |= (P_30 == 0) ? P0_USED : P1_USED;
00243
00244 tabUsed[b[0] ] |= B0_USED;
00245 tabUsed[b[1] ] |= B1_USED;
00246 tabUsed[b[2] ] |= B2_USED;
00247 tabUsed[b[3] ] |= B3_USED;
00248 }
00249
00250
00251 return ((M00(b[0]) ^ M01(b[1]) ^ M02(b[2]) ^ M03(b[3])) ) ^
00252 ((M10(b[0]) ^ M11(b[1]) ^ M12(b[2]) ^ M13(b[3])) << 8) ^
00253 ((M20(b[0]) ^ M21(b[1]) ^ M22(b[2]) ^ M23(b[3])) << 16) ^
00254 ((M30(b[0]) ^ M31(b[1]) ^ M32(b[2]) ^ M33(b[3])) << 24) ;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 DWORD RS_MDS_Encode(DWORD k0,DWORD k1)
00277 {
00278 int i,j;
00279 DWORD r;
00280
00281 for (i=r=0;i<2;i++)
00282 {
00283 r ^= (i) ? k0 : k1;
00284 for (j=0;j<4;j++)
00285 RS_rem(r);
00286 }
00287 return r;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 int reKey(keyInstance *key)
00304 {
00305 int i,k64Cnt;
00306 int keyLen = key->keyLen;
00307 int subkeyCnt = ROUND_SUBKEYS + 2*key->numRounds;
00308 DWORD A,B;
00309 DWORD k32e[MAX_KEY_BITS/64],k32o[MAX_KEY_BITS/64];
00310
00311 #if VALIDATE_PARMS
00312 #if ALIGN32
00313 if ((((int)key) & 3) || (((int)key->key32) & 3))
00314 return BAD_ALIGN32;
00315 #endif
00316 if ((key->keyLen % 64) || (key->keyLen < MIN_KEY_BITS))
00317 return BAD_KEY_INSTANCE;
00318 if (subkeyCnt > TOTAL_SUBKEYS)
00319 return BAD_KEY_INSTANCE;
00320 #endif
00321
00322 k64Cnt=(keyLen+63)/64;
00323 for (i=0;i<k64Cnt;i++)
00324 {
00325 k32e[i]=key->key32[2*i ];
00326 k32o[i]=key->key32[2*i+1];
00327
00328 key->sboxKeys[k64Cnt-1-i]=RS_MDS_Encode(k32e[i],k32o[i]);
00329 }
00330
00331 for (i=0;i<subkeyCnt/2;i++)
00332 {
00333 A = f32(i*SK_STEP ,k32e,keyLen);
00334 B = f32(i*SK_STEP+SK_BUMP,k32o,keyLen);
00335 B = ROL(B,8);
00336 key->subKeys[2*i ] = A+ B;
00337 key->subKeys[2*i+1] = ROL(A+2*B,SK_ROTL);
00338 }
00339
00340 DebugDumpKey(key);
00341
00342 return TRUE;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 int makeKey(keyInstance *key, BYTE direction, int keyLen,CONST char *keyMaterial)
00362 {
00363 int i;
00364
00365 #if VALIDATE_PARMS
00366 if (key == NULL)
00367 return BAD_KEY_INSTANCE;
00368 if ((direction != DIR_ENCRYPT) && (direction != DIR_DECRYPT))
00369 return BAD_KEY_DIR;
00370 if ((keyLen > MAX_KEY_BITS) || (keyLen < 8))
00371 return BAD_KEY_MAT;
00372 key->keySig = VALID_SIG;
00373 #if ALIGN32
00374 if ((((int)key) & 3) || (((int)key->key32) & 3))
00375 return BAD_ALIGN32;
00376 #endif
00377 #endif
00378
00379 key->direction = direction;
00380 key->keyLen = (keyLen+63) & ~63;
00381 key->numRounds = numRounds[(keyLen-1)/64];
00382 for (i=0;i<MAX_KEY_BITS/32;i++)
00383 key->key32[i]=0;
00384 key->keyMaterial[MAX_KEY_SIZE]=0;
00385
00386 if ((keyMaterial == NULL) || (keyMaterial[0]==0))
00387 return TRUE;
00388
00389 if (ParseHexDword(keyLen,keyMaterial,key->key32,key->keyMaterial))
00390 return BAD_KEY_MAT;
00391
00392 return reKey(key);
00393 }
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 int cipherInit(cipherInstance *cipher, BYTE mode,CONST char *IV)
00408 {
00409 int i;
00410 #if VALIDATE_PARMS
00411 if (cipher == NULL)
00412 return BAD_PARAMS;
00413 if ((mode != MODE_ECB) && (mode != MODE_CBC) && (mode != MODE_CFB1))
00414 return BAD_CIPHER_MODE;
00415 cipher->cipherSig = VALID_SIG;
00416 #if ALIGN32
00417 if ((((int)cipher) & 3) || (((int)cipher->IV) & 3) || (((int)cipher->iv32) & 3))
00418 return BAD_ALIGN32;
00419 #endif
00420 #endif
00421
00422 if ((mode != MODE_ECB) && (IV))
00423 {
00424 if (ParseHexDword(BLOCK_SIZE,IV,cipher->iv32,NULL))
00425 return BAD_IV_MAT;
00426 for (i=0;i<BLOCK_SIZE/32;i++)
00427 ((DWORD *)cipher->IV)[i] = Bswap(cipher->iv32[i]);
00428 }
00429
00430 cipher->mode = mode;
00431
00432 return TRUE;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 int blockEncrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input,
00454 int inputLen, BYTE *outBuffer)
00455 {
00456 int i,n,r;
00457 DWORD x[BLOCK_SIZE/32];
00458 DWORD t0,t1,tmp;
00459 int rounds=key->numRounds;
00460 BYTE bit,ctBit,carry;
00461
00462
00463
00464
00465 #if VALIDATE_PARMS
00466 if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
00467 return BAD_CIPHER_STATE;
00468 if ((key == NULL) || (key->keySig != VALID_SIG))
00469 return BAD_KEY_INSTANCE;
00470 if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
00471 return BAD_KEY_INSTANCE;
00472 if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
00473 return BAD_INPUT_LEN;
00474 #if ALIGN32
00475 if ( (((int)cipher) & 3) || (((int)key ) & 3) ||
00476 (((int)input ) & 3) || (((int)outBuffer) & 3))
00477 return BAD_ALIGN32;
00478 #endif
00479 #endif
00480
00481 if (cipher->mode == MODE_CFB1)
00482 {
00483 cipher->mode = MODE_ECB;
00484 for (n=0;n<inputLen;n++)
00485 {
00486 blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
00487 bit = 0x80 >> (n & 7);
00488 ctBit = (input[n/8] & bit) ^ ((((BYTE *) x)[0] & 0x80) >> (n&7));
00489 outBuffer[n/8] = (outBuffer[n/8] & ~ bit) | ctBit;
00490 carry = ctBit >> (7 - (n&7));
00491 for (i=BLOCK_SIZE/8-1;i>=0;i--)
00492 {
00493 bit = cipher->IV[i] >> 7;
00494 cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
00495 carry = bit;
00496 }
00497 }
00498 cipher->mode = MODE_CFB1;
00499 return inputLen;
00500 }
00501
00502
00503 for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
00504 {
00505 #ifdef DEBUG
00506 DebugDump(input,"\n",-1,0,0,0,1);
00507 if (cipher->mode == MODE_CBC)
00508 DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
00509 #endif
00510 for (i=0;i<BLOCK_SIZE/32;i++)
00511 {
00512 x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[INPUT_WHITEN+i];
00513 if (cipher->mode == MODE_CBC)
00514 x[i] ^= cipher->iv32[i];
00515 }
00516
00517 DebugDump(x,"",0,0,0,0,0);
00518 for (r=0;r<rounds;r++)
00519 {
00520 #if FEISTEL
00521 t0 = f32(ROR(x[0], (r+1)/2),key->sboxKeys,key->keyLen);
00522 t1 = f32(ROL(x[1],8+(r+1)/2),key->sboxKeys,key->keyLen);
00523
00524 x[2]^= ROL(t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ], r /2);
00525 x[3]^= ROR(t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1],(r+2) /2);
00526
00527 DebugDump(x,"",r+1,2*(r&1),1,1,0);
00528 #else
00529 t0 = f32( x[0] ,key->sboxKeys,key->keyLen);
00530 t1 = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
00531
00532 x[3] = ROL(x[3],1);
00533 x[2]^= t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ];
00534 x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
00535 x[2] = ROR(x[2],1);
00536
00537 DebugDump(x,"",r+1,2*(r&1),0,1,0);
00538 #endif
00539 if (r < rounds-1)
00540 {
00541 tmp = x[0]; x[0]= x[2]; x[2] = tmp;
00542 tmp = x[1]; x[1]= x[3]; x[3] = tmp;
00543 }
00544 }
00545 #if FEISTEL
00546 x[0] = ROR(x[0],8);
00547 x[1] = ROL(x[1],8);
00548 x[2] = ROR(x[2],8);
00549 x[3] = ROL(x[3],8);
00550 #endif
00551 for (i=0;i<BLOCK_SIZE/32;i++)
00552 {
00553 ((DWORD *)outBuffer)[i] = Bswap(x[i] ^ key->subKeys[OUTPUT_WHITEN+i]);
00554 if (cipher->mode == MODE_CBC)
00555 cipher->iv32[i] = Bswap(((DWORD *)outBuffer)[i]);
00556 }
00557 #ifdef DEBUG
00558 DebugDump(outBuffer,"",rounds+1,0,0,0,1);
00559 if (cipher->mode == MODE_CBC)
00560 DebugDump(cipher->iv32,"",IV_ROUND,0,0,0,0);
00561 #endif
00562 }
00563
00564 return inputLen;
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585 int blockDecrypt(cipherInstance *cipher, keyInstance *key,CONST BYTE *input,
00586 int inputLen, BYTE *outBuffer)
00587 {
00588 int i,n,r;
00589 DWORD x[BLOCK_SIZE/32];
00590 DWORD t0,t1;
00591 int rounds=key->numRounds;
00592 BYTE bit,ctBit,carry;
00593
00594
00595
00596
00597 #if VALIDATE_PARMS
00598 if ((cipher == NULL) || (cipher->cipherSig != VALID_SIG))
00599 return BAD_CIPHER_STATE;
00600 if ((key == NULL) || (key->keySig != VALID_SIG))
00601 return BAD_KEY_INSTANCE;
00602 if ((rounds < 2) || (rounds > MAX_ROUNDS) || (rounds&1))
00603 return BAD_KEY_INSTANCE;
00604 if ((cipher->mode != MODE_CFB1) && (inputLen % BLOCK_SIZE))
00605 return BAD_INPUT_LEN;
00606 #if ALIGN32
00607 if ( (((int)cipher) & 3) || (((int)key ) & 3) ||
00608 (((int)input) & 3) || (((int)outBuffer) & 3))
00609 return BAD_ALIGN32;
00610 #endif
00611 #endif
00612
00613 if (cipher->mode == MODE_CFB1)
00614 {
00615 cipher->mode = MODE_ECB;
00616 for (n=0;n<inputLen;n++)
00617 {
00618 blockEncrypt(cipher,key,cipher->IV,BLOCK_SIZE,(BYTE *)x);
00619 bit = 0x80 >> (n & 7);
00620 ctBit = input[n/8] & bit;
00621 outBuffer[n/8] = (outBuffer[n/8] & ~ bit) |
00622 (ctBit ^ ((((BYTE *) x)[0] & 0x80) >> (n&7)));
00623 carry = ctBit >> (7 - (n&7));
00624 for (i=BLOCK_SIZE/8-1;i>=0;i--)
00625 {
00626 bit = cipher->IV[i] >> 7;
00627 cipher->IV[i] = (cipher->IV[i] << 1) ^ carry;
00628 carry = bit;
00629 }
00630 }
00631 cipher->mode = MODE_CFB1;
00632 return inputLen;
00633 }
00634
00635
00636 for (n=0;n<inputLen;n+=BLOCK_SIZE,input+=BLOCK_SIZE/8,outBuffer+=BLOCK_SIZE/8)
00637 {
00638 DebugDump(input,"\n",rounds+1,0,0,0,1);
00639
00640 for (i=0;i<BLOCK_SIZE/32;i++)
00641 x[i]=Bswap(((DWORD *)input)[i]) ^ key->subKeys[OUTPUT_WHITEN+i];
00642
00643 for (r=rounds-1;r>=0;r--)
00644 {
00645 t0 = f32( x[0] ,key->sboxKeys,key->keyLen);
00646 t1 = f32(ROL(x[1],8),key->sboxKeys,key->keyLen);
00647
00648 DebugDump(x,"",r+1,2*(r&1),0,1,0);
00649 x[2] = ROL(x[2],1);
00650 x[2]^= t0 + t1 + key->subKeys[ROUND_SUBKEYS+2*r ];
00651 x[3]^= t0 + 2*t1 + key->subKeys[ROUND_SUBKEYS+2*r+1];
00652 x[3] = ROR(x[3],1);
00653
00654 if (r)
00655 {
00656 t0 = x[0]; x[0]= x[2]; x[2] = t0;
00657 t1 = x[1]; x[1]= x[3]; x[3] = t1;
00658 }
00659 }
00660 DebugDump(x,"",0,0,0,0,0);
00661
00662 for (i=0;i<BLOCK_SIZE/32;i++)
00663 {
00664 x[i] ^= key->subKeys[INPUT_WHITEN+i];
00665 if (cipher->mode == MODE_CBC)
00666 {
00667 x[i] ^= cipher->iv32[i];
00668 cipher->iv32[i] = Bswap(((DWORD *)input)[i]);
00669 }
00670 ((DWORD *)outBuffer)[i] = Bswap(x[i]);
00671 }
00672 DebugDump(outBuffer,"",-1,0,0,0,1);
00673 }
00674
00675 return inputLen;
00676 }
00677
00678
00679 #ifdef GetCodeSize
00680 DWORD TwofishCodeSize(void) { return Here(0)-TwofishCodeStart(); };
00681 #endif