📄 aes_rav.cpp
字号:
// Copyright in this code is held by Dr B. R. Gladman but free direct or
// derivative use is permitted subject to acknowledgement of its origin.
// Dr B. R. Gladman <brg@gladman.uk.net> 1st June 2001.
//
// usage: aes_rav /t:[knec] /b:[45678] /k:[45678]
//
// where:
//
// each of the symbols in square brakets can be used in any combination so
// that:
//
// /t:[knec] selects the tests to be used
// /b:[45678] selects the block lengths to be used (in 32-bit words)
// /k:[45678] selects the key lengths to be used (in 32-bit words)
// and:
// k: generate ECB Known Answer Test files
// n: generate ECB Known Answer Test files (new)
// e: generate ECB Monte Carlo Test files
// c: generate CBC Monte Carlo Test files
//
// Note that, when compared with the NIST test vector sequences, this
// code implements one additional (all zero) test vector as the first
// vector in each set (test 0).
#include "aes.h"
#include "aes_aux.h"
#include "aes_tst.h"
#if defined(AES_DLL)
fn_ptrs fn;
#endif
using std::cout;
using std::ifstream;
using std::ofstream;
enum test_type { ecb_vk, ecb_vt, ecb_nvk, ecb_nvt, ecb_me, ecb_md, cbc_me, cbc_md };
void ref_test(const char *in_file, const unsigned int it_cnt, enum test_type t_type,
aes *alg, const word blen, const word klen)
{ word i, test_cnt, cnt, e_cnt, fe_cnt;
byte key[32], pt[32], iv[32], ect[32], act[64];
char str[128];
line_type ty;
ifstream inf;
cout << "Test file " << in_file << ": ";
inf.open(in_file); // reference test vector file
if(!inf)
{
cout << " file not found \n"; return;
}
cnt = 0; e_cnt = test_cnt = 0;
for(;;) // while there are tests
{
ty = find_line(inf, str); // input a line
if(ty == bad_line) // until end of file
break;
if(ty == block_len)
{
if((get_dec(str) >> 3) == blen) continue;
return;
}
else if(ty == key_len)
{
if((get_dec(str) >> 3) == klen) continue;
return;
}
else if(ty == test_no)
{
test_cnt = get_dec(str); continue;
}
else if(ty == iv_val)
{
block_in(iv, str); continue;
}
else if(ty == key_val)
{
block_in(key, str); continue;
}
else if(ty == pt_val)
{
block_in(pt, str);
if(t_type != ecb_md && t_type != cbc_md) continue;
}
else if(ty == ct_val)
{
block_in(ect, str);
if(t_type == ecb_md || t_type == cbc_md) continue;
}
f_set_key(alg, key, klen, both); // set the key
if(t_type == ecb_md || t_type == cbc_md)
{
block_copy(act, ect, blen); // encrypted text to low block
if(t_type == cbc_md) // CBC Monte Carlo decryption
{
block_copy(act + blen, iv, blen); // IV to high block
for(i = 0; i < it_cnt; i += 2) // do decryptions two at a time
{
f_decrypt(alg, act, ect); // decrypt low block
block_xor(act + blen, ect, blen); // xor into high block
f_decrypt(alg, act + blen, ect); // decrypt high block
block_xor(act, ect, blen); // xor into low block
}
}
else // ECB Monte Carlo decryption
{
for(i = 0; i < it_cnt; ++i)
f_decrypt(alg, act, act);
}
if(!block_cmp(pt, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;
if(t_type == ecb_md) // test encryption if ECB mode
{
for(i = 0; i < it_cnt; ++i)
f_encrypt(alg, act, act);
if(!block_cmp(ect, act, blen))
if(!e_cnt++) fe_cnt = test_cnt;
}
}
else // if(t_type == ecb_me || t_type == cbc_me || ecb_vk || ecb_vt)
{
if(t_type == cbc_me) // CBC Monte Carlo encryption
{
block_copy(act, iv, blen);
block_copy(act + blen, pt, blen); // copy IV and plaintext
for(i = 0; i < it_cnt; i += 2)
{
block_xor(act + blen, act, blen); // xor low block into high block
f_encrypt(alg, act + blen, act + blen); // encrypt high block
block_xor(act, act + blen, blen); // xor high block into low block
f_encrypt(alg, act, act); // encrypt low block
}
}
else // ECB Monte Carlo encryption
{
block_copy(act, pt, blen);
for(i = 0; i < it_cnt; ++i)
f_encrypt(alg, act, act);
}
if(!block_cmp(ect, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;
if(t_type != cbc_me) // if ECB mode test decrytpion
{
for(i = 0; i < it_cnt; ++i)
f_decrypt(alg, act, act);
if(!block_cmp(pt, act, blen)) if(!e_cnt++) fe_cnt = test_cnt;
}
}
}
inf.close();
if(e_cnt > 0) // report any errors
{
cout << e_cnt << " ERRORS during test (first on test " << fe_cnt << ")\n";
}
else // else report all is well
cout << "all tests correct\n";
}
void do_tests(const bool vkt, const bool vktn, const bool ecb, const bool cbc, aes *alg,
const word blen, const word klen)
{ char path[128], *sp;
sp = copy_str(path, ref_path);
if(vkt)
{
file_name(sp, 0, blen, klen);
ref_test(path, 1, ecb_vk, alg, blen, klen);
file_name(sp, 1, blen, klen);
ref_test(path, 1, ecb_vt, alg, blen, klen);
}
if(vktn)
{
file_name(sp, 2, blen, klen);
ref_test(path, 1, ecb_nvk, alg, blen, klen);
file_name(sp, 3, blen, klen);
ref_test(path, 1, ecb_nvt, alg, blen, klen);
}
if(ecb)
{
file_name(sp, 4, blen, klen);
ref_test(path, 10000, ecb_me, alg, blen, klen);
file_name(sp, 5, blen, klen);
ref_test(path, 10000, ecb_md, alg, blen, klen);
}
if(cbc)
{
file_name(sp, 6, blen, klen);
ref_test(path, 10000, cbc_me, alg, blen, klen);
file_name(sp, 7, blen, klen);
ref_test(path, 10000, cbc_md, alg, blen, klen);
}
}
#if defined(AES_DLL)
#include "windows.h"
HINSTANCE init_dll(fn_ptrs& fn)
{ HINSTANCE h_dll;
if(!(h_dll = LoadLibrary(dll_path)))
{
std::cout << "\n\nDynamic link Library AES_DLL not found\n\n"; return 0;
}
fn.fn_set_key = (f_ky*)GetProcAddress(h_dll, "_set_key@16");
fn.fn_encrypt = (f_ed*)GetProcAddress(h_dll, "_encrypt@12");
fn.fn_decrypt = (f_ed*)GetProcAddress(h_dll, "_decrypt@12");
fn.fn_set_blk = (f_bl*)GetProcAddress(h_dll, "_set_blk@8");
#if !defined(BLOCK_SIZE)
if(!fn.fn_set_key || !fn.fn_encrypt || !fn.fn_decrypt || !fn.fn_set_blk)
#else
if(!fn.fn_set_key || !fn.fn_encrypt || !fn.fn_decrypt)
#endif
{
std::cout << "\n\nRequired DLL Entry Point(s) not found\n\n";
FreeLibrary(h_dll);
return 0;
}
return h_dll;
}
#endif // AES_DLL
int main(int argc, char *argv[])
{ bool vkt, vktn, ecb, cbc, bf[5], kf[5];
aes alg;
#if defined(AES_DLL)
HINSTANCE h_dll;
if(!(h_dll = init_dll(fn))) return -1;
#endif
#if !defined(AES_IN_CPP)
alg.mode = 0;
#endif
if(argc == 1)
{
cout << "\nusage: aes_rav /t:[knec] /b:[45678] /k:[45678]";
cout << "\n";
cout << "\nwhere the symbols in square brackets can be used in";
cout << "\nany combination (without the brackets) and have the";
cout << "\nfollowing meanings:";
cout << "\n";
cout << "\n /t:[knec] selects which tests are used";
cout << "\n /b:[45678] selects the block lengths used";
cout << "\n /k:[45678] selects the key lengths used";
cout << "\nwhere:";
cout << "\n k: generate ECB Known Answer Test files";
cout << "\n n: generate ECB Known Answer Test files (new)";
cout << "\n e: generate ECB Monte Carlo Test files";
cout << "\n c: generate CBC Monte Carlo Test files";
cout << "\n";
cout << "\nand the characters giving block and key lengths are";
cout << "\ndigits representing the lengths in 32-bit units.\n\n";
exit(0);
}
cout << "\nRun tests for the AES algorithm"
#if defined(AES_DLL)
"(DLL Version)\n\n";
#else
"\n\n";
#endif
vkt = test_args(argc, argv, 't', 'k');
vktn = test_args(argc, argv, 't', 'n');
ecb = test_args(argc, argv, 't', 'e');
cbc = test_args(argc, argv, 't', 'c');
kf[0] = test_args(argc, argv, 'k', '4');
kf[1] = test_args(argc, argv, 'k', '5');
kf[2] = test_args(argc, argv, 'k', '6');
kf[3] = test_args(argc, argv, 'k', '7');
kf[4] = test_args(argc, argv, 'k', '8');
if(!(kf[0] || kf[1] || kf[2] || kf[3] || kf[4]))
{
kf[0] = kf[2] = kf[4] = true; // AES key sizes if not specified
kf[1] = kf[3] = false;
}
#if !defined(BLOCK_SIZE)
bf[0] = test_args(argc, argv, 'b', '4');
bf[1] = test_args(argc, argv, 'b', '5');
bf[2] = test_args(argc, argv, 'b', '6');
bf[3] = test_args(argc, argv, 'b', '7');
bf[4] = test_args(argc, argv, 'b', '8');
if(!(bf[0] || bf[1] || bf[2] || bf[3] || bf[4]))
{
bf[0] = true; // AES block size if not specified
bf[1] = bf[2] = bf[3] = bf[4] = false;
}
#else
bf[0] = bf[1] = bf[2] = bf[3] = bf[4] = false;
bf[(BLOCK_SIZE - 16) / 4] = true;
#endif
for(int bi = 0; bi < 5; ++bi) if(bf[bi])
{
#if !defined(BLOCK_SIZE)
f_set_blk(&alg, 16 + 4 * bi);
#elif defined(AES_DLL)
if(fn.fn_set_blk) f_set_blk(&alg, BLOCK_SIZE);
#endif
for(int ki = 0; ki < 5; ++ki) if(kf[ki])
{
do_tests(vkt, vktn, ecb, cbc, &alg, 16 + 4 * bi, 16 + 4 * ki);
}
}
#if defined(AES_DLL)
if(h_dll) FreeLibrary(h_dll);
#endif
cout << "\n\n";
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -