int main(int argc, char *argv[]) { bool vkt, ecb, cbc; #ifdef __cplusplus mars _mars; rc6 _rc6; rijndael _rijndael; serpent _serpent; twofish _twofish; #else alg_struct _mars; alg_struct _rc6; alg_struct _rijndael; alg_struct _serpent; alg_struct _twofish; _mars.name = MARS(name); _mars.set_key = MARS(set_key); _mars.encrypt = MARS(encrypt); _mars.decrypt = MARS(decrypt); _rc6.name = RC6(name); _rc6.set_key = RC6(set_key); _rc6.encrypt = RC6(encrypt); _rc6.decrypt = RC6(decrypt); _rijndael.name = RIJNDAEL(name); _rijndael.set_key = RIJNDAEL(set_key); _rijndael.encrypt = RIJNDAEL(encrypt); _rijndael.decrypt = RIJNDAEL(decrypt); _serpent.name = SERPENT(name); _serpent.set_key = SERPENT(set_key); _serpent.encrypt = SERPENT(encrypt); _serpent.decrypt = SERPENT(decrypt); _twofish.name = TWOFISH(name); _twofish.set_key = TWOFISH(set_key); _twofish.encrypt = TWOFISH(encrypt); _twofish.decrypt = TWOFISH(decrypt); #endif if(argc == 1) { con_string("\nusage: aes_rav /a:[12345] /t:[kec] [/h]"); con_string("\nwhere:"); con_string("\n /a:[12345] algorithms to be tested"); con_string("\n /t:[kec] type of test"); con_string("\n /h use author's byte order (serpent)"); con_string("\nand:"); con_string("\n 1:mars, 2:rc6, 3:rijndael, 4:serpent, 5:twofish"); con_string("\n k: run ECB Known Answer tests"); con_string("\n e: run ECB Monte Carlo tests"); con_string("\n c: run CBC Monte Carlo tests"); con_string("\n\n"); exit(0); } vkt = test_args(argc, argv, 't', 'k'); ecb = test_args(argc, argv, 't', 'e'); cbc = test_args(argc, argv, 't', 'c'); serpent_hack = false; if(test_args(argc, argv, 'a', '1')) do_tests(vkt, ecb, cbc, _mars); if(test_args(argc, argv, 'a', '2')) do_tests(vkt, ecb, cbc, _rc6); if(test_args(argc, argv, 'a', '3')) do_tests(vkt, ecb, cbc, _rijndael); if(test_args(argc, argv, 'a', '4')) { serpent_hack = test_args(argc, argv, 'h', '\0'); do_tests(vkt, ecb, cbc, _serpent); serpent_hack = false; } if(test_args(argc, argv, 'a', '5')) do_tests(vkt, ecb, cbc, _twofish); return 0; }
m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4); return m & 0xfffffffc; } #endif #ifdef __cplusplus } // end of anonymous namespace #endif char* MARS(name(void)) { return "mars"; } void MARS(set_key)(MARS(CONTEXT) *context, const u1byte in_key[], const u4byte key_bits, const enum dir_flag f) { u4byte i, j, m, t1, t2, *kp; m = key_bits / 32; if(m < 4 || m > 14) return; for(i = 0; i < m; ++i) t_key[i] = u4byte_in(in_key + 4 * i); t_key[i++] = m; for(; i < 15; ++i)
// ========================================================================= // Decryption function // Note: PlaintextLength must be set to the size of the PlaintextData buffer on // entry; on exit, this will be set to the size of the buffer used. NTSTATUS ImpCypherDecryptSectorData( IN GUID* CypherGUID, IN LARGE_INTEGER SectorID, // Indexed from zero IN int SectorSize, // In bytes IN int KeyLength, // In bits IN FREEOTFEBYTE* Key, IN char* KeyASCII, // ASCII representation of "Key" IN int IVLength, // In bits IN FREEOTFEBYTE* IV, IN int CyphertextLength, // In bytes IN FREEOTFEBYTE* CyphertextData, OUT FREEOTFEBYTE* PlaintextData ) { NTSTATUS status = STATUS_SUCCESS; // Null IV in case we're not given an IV char zeroIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE]; int i; INTEGER_128 blockID128; int errnum; MARS(CONTEXT) context; DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDecryptData\n"))); if ( (IsEqualGUID(&CIPHER_GUID_MARS_256_XTS, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_MARS_192_XTS, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_MARS_128_XTS, CypherGUID)) ) { // Generate index in correct format // XTS uses: // *) The sector index (i.e. the number of N-bit sectors) // *) The first sector is sector 0 // *) Littleendian format LARGE_INTEGER__To__INTEGER_128_LittleEndian( SectorID, blockID128 ); if ((errnum = xts_decrypt( &context, &(MARS(set_key)), &(MARS(encrypt)), &(MARS(decrypt)), ((KeyLength/2)), Key, ((KeyLength/2)), &(Key[(KeyLength/2)/8]), CyphertextData, CyphertextLength, PlaintextData, blockID128 )) != CRYPT_OK) { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum)); status = STATUS_UNSUCCESSFUL; } } else if ( (IsEqualGUID(&CIPHER_GUID_MARS_256_CBC, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_MARS_192_CBC, CypherGUID)) || (IsEqualGUID(&CIPHER_GUID_MARS_128_CBC, CypherGUID)) ) { // Handle situation where a NULL/zero length IV is passed in if ( (IVLength == 0) || (IV == NULL) ) { FREEOTFE_MEMZERO(&zeroIV, sizeof(zeroIV)); IV = (char*)&zeroIV; } // Process data using CBC mode // // CBC Mode DECRYPT: // *) Setup key // *) For each block... // *) Decrypt cyphertext with key // *) XOR output plaintext with IV // *) IV = Cyphertext data // Note: "dec" specified; we're DECRYPTING MARS(set_key)(&context, Key, KeyLength, dec); for (i=0; i < CyphertextLength; i += (MARS_BLOCK_SIZE / 8)) { MARS(decrypt)(&context, CyphertextData+i, PlaintextData+i); XORBlock(PlaintextData+i, IV, PlaintextData+i, (MARS_BLOCK_SIZE / 8)); IV = CyphertextData+i; } } else { DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n"))); status = STATUS_INVALID_PARAMETER; } SecZeroMemory(&context, sizeof(context)); DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDecryptData\n"))); return status; }
int main(int argc, char *argv[]) { OFILE outf; #ifdef __cplusplus mars _mars; rc6 _rc6; rijndael _rijndael; serpent _serpent; twofish _twofish; #else alg_struct _mars; alg_struct _rc6; alg_struct _rijndael; alg_struct _serpent; alg_struct _twofish; _mars.name = MARS(name); _mars.set_key = MARS(set_key); _mars.encrypt = MARS(encrypt); _mars.decrypt = MARS(decrypt); _rc6.name = RC6(name); _rc6.set_key = RC6(set_key); _rc6.encrypt = RC6(encrypt); _rc6.decrypt = RC6(decrypt); _rijndael.name = RIJNDAEL(name); _rijndael.set_key = RIJNDAEL(set_key); _rijndael.encrypt = RIJNDAEL(encrypt); _rijndael.decrypt = RIJNDAEL(decrypt); _serpent.name = SERPENT(name); _serpent.set_key = SERPENT(set_key); _serpent.encrypt = SERPENT(encrypt); _serpent.decrypt = SERPENT(decrypt); _twofish.name = TWOFISH(name); _twofish.set_key = TWOFISH(set_key); _twofish.encrypt = TWOFISH(encrypt); _twofish.decrypt = TWOFISH(decrypt); #endif if(argc != 2 && argc != 3) { con_string("\nusage: aes_tmr /a:[12345]"); con_string("\nwhere:"); con_string("\n /a:[12345] algorithms to be tested"); con_string("\nand:"); con_string("\n 1:mars, 2:rc6, 3:rijndael, 4:serpent, 5:twofish"); con_string("\n\n"); exit(0); } outf = open_ofile(outf, argc == 3 ? argv[2] : "CON"); header(outf); if(test_args(argc, argv, 'a', '1')) { time(_mars); do_out(outf, _mars); } if(test_args(argc, argv, 'a', '2')) { time(_rc6); do_out(outf, _rc6); } if(test_args(argc, argv, 'a', '3')) { time(_rijndael); do_out(outf, _rijndael); } if(test_args(argc, argv, 'a', '4')) { time(_serpent); do_out(outf, _serpent); } if(test_args(argc, argv, 'a', '5')) { time(_twofish); do_out(outf, _twofish); } close_ofile(outf); return 0; }