📄 aesgav.c
字号:
do_enc(alg, ct, ct, 1); // do block encryption
block_xor(ct + blen, ct, blen); // do CBC chaining
do_enc(alg, ct + blen, ct + blen, 1);// do block encryption
}
block_out(ct_val, ct + blen, outf, blen); // output ciphertext
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
}
}
// Monte Carlo Encryption Test of Cipher Block Chaining (CBC) mode
void cbc_md(FILE *outf, f_dctx alg[1], const unsigned long blen, const unsigned long klen)
{ unsigned long j, k;
unsigned char pt[32], ct[64], key[32], dummy;
block_clear(key, klen); // clear key: KEY[0]
block_clear(ct, 2 * blen); // clear ct: IV[0] ct + blen: CT[0]
for(j = 0; j < 400; j++) // 400 Monte Carlo tests
{
block_out(test_no, &dummy, outf, j); // output test number
block_out(key_val, key, outf, klen); // output key
block_out(iv_val, ct, outf, blen); // output initialisation vector
block_out(ct_val, ct + blen, outf, blen); // output ciphertext
f_dec_key(alg, key, klen); // set key
for(k = 0; k < 5000; ++k) // 10000 encryptions, two at a time
{
do_dec(alg, ct + blen, pt, 1); // do block decryption
block_xor(ct, pt, blen); // do CBC chaining
do_dec(alg, ct, pt, 1); // do block decryption
block_xor(ct + blen, pt, blen); // do CBC chaining
}
block_out(pt_val, ct + blen, outf, blen); // output plaintext
// compile next key as defined by NIST
block_xor(key, ct + 2 * blen - klen, klen);
}
}
// Synchronise two comparison files if they get out of step
int sync(int nbr, FILE *inf, char str[], int outp)
{ enum line_type ty;
int nn;
for(;;)
{
ty = find_line(inf, str);
if(ty == bad_line) return -1;
if(ty == test_no)
{
nn = get_dec(str + 2);
if(nn >= nbr) return nn;
}
if(outp)
printf("\n %s", str);
}
}
// Compare two test vector files
void comp_vecs(const char *fn1, const char *fn2)
{ char str1[128], str2[128];
enum line_type ty1, ty2;
int no1, no2, err_cnt, np_cnt, req;
FILE *if1, *if2;
err_cnt = np_cnt = 0; req = TRUE;
if1 = fopen(fn1, "r");
if(!if1) // open first file
{
printf("\n*** 1st file (%s) not found ***", fn1); return;
}
if2 = fopen(fn2, "r");
if(!if2) // open second file
{
printf("\n*** 2nd file (%s) not found ***", fn2); return;
}
for(;;) // while there is still input
{
if(req) // if another line needs to be input
{
ty1 = find_line(if1, str1); ty2 = find_line(if2, str2);
}
if(ty1 == bad_line && ty2 == bad_line) // if end of file on both files
break;
if(ty1 == bad_line || ty2 == bad_line) // if end of file on one file
{
printf("\n%s%s%s%s" , fn1, (ty1 == bad_line ? " short" : " long"), "er than ", fn2);
break;
}
if(ty1 == test_no) // if 'test number' line in file 1
no1 = get_dec(str1);
if(ty2 == test_no) // if 'test number' line in file 2
no2 = get_dec(str2);
if(cmp_nocase(str1, str2) == 0)
{
req = TRUE; continue; // if lines are the same continue
}
if(ty1 == test_no && ty2 == test_no) // if not the same but both are at a
{ // 'test number' line
np_cnt += abs(no2 - no1); req = FALSE;
if(no2 < no1) // extra tests in file 2
{
printf("\nextra test(s) in %s:\n %s", fn2, str2);
no2 = sync(no1, if2, str2, np_cnt < 10); // skip tests in file 2
}
if(no1 < no2) // extra test in file 1
{
printf("\nextra test(s) in %s:\n %s", fn1, str1);
no1 = sync(no2, if1, str1, np_cnt < 10);// skip tests in file 1
}
}
else if(ty1 != ty2) // cannot synchronise test vector files
{
printf("\n*** synchronisation error tests %i and %i ***", no1, no2);
fflush(stdout); return;
}
else if(ty1 != bad_line) // test vector mismatch
{
err_cnt++;
printf("\r*** mismatch error test %i ***", no1);
}
fflush(stdout);
}
if(np_cnt && !err_cnt) // all tests present match
printf("\nother tests match\n");
else
{
if(err_cnt)
printf("\r%s doesn't match %s (%i errors)\n", fn2, fn1, err_cnt);
else
printf("\r%s matches %s\n", fn2, fn1);
}
fclose(if1); fclose(if2);
}
// array of functions to call for each test
typedef void (*f_ep)(FILE *outf, f_ectx alg[1], const unsigned long blen, const unsigned long klen);
typedef void (*f_dp)(FILE *outf, f_dctx alg[1], const unsigned long blen, const unsigned long klen);
f_ep f_ptr[8] = { ecb_vk, ecb_vt, ecb_vkn, ecb_vtn, ecb_me, (f_ep)ecb_md, cbc_me, (f_ep)cbc_md };
// do the tests for each algorithm
void do_tests(int do_cmp, int ttype[3], f_ectx alg[1], const unsigned long blen, const unsigned long klen)
{ char name1[128], name2[128], *sp1, *sp2;
int i;
FILE *outf;
printf("\nGenerate%s tests for aes (AES_BLOCK_SIZE = %i, key size = %i)\n",
(do_cmp ? " and verify" : ""), 8 * blen, 8 * klen);
for(i = 0; i < 8; ++i) // for each type of test /k /x /e /c (2 tests each)
if(ttype[i / 2]) // if this test required
{
// name of file for output of generated test vectors
sp1 = copy_str(name1, out_path);
sp2 = copy_str(name2, ref_path);
file_name(sp1, 128, i, blen, klen);
copy_str(sp2, sp1);
outf = fopen(name1, "w");
if(outf) // if output file is open write it
{
header(outf, i, blen, klen);
f_ptr[i](outf, alg, blen, klen);
fprintf(outf, "\n"); fclose(outf);
if(do_cmp) // compare it with reference if required
comp_vecs(name2, name1);
}
}
}
int main(int argc, char *argv[])
{ int do_cmp, tyf[4], kf[3], ki;
f_ectx alg[1];
#if defined(USE_DLL) && defined(DYNAMIC_LINK)
HINSTANCE h_dll;
if(!(h_dll = init_dll(&fn)))
return -1;
#elif defined(STATIC_TABLES)
aes_init();
#endif
if(argc == 1)
{
printf("\nusage: aes_gav /t:[knec] /k:[468] [/c]");
printf("\n");
printf("\nwhere the symbols in square brackets can be used in");
printf("\nany combination (without the brackets) and have the");
printf("\nfollowing meanings:");
printf("\n");
printf("\n /t:[knec] selects which tests are used");
printf("\n /k:[468] selects the key lengths used");
printf("\n /c compares output with reference");
printf("\nwhere:");
printf("\n k: generate ECB Known Answer Test files");
printf("\n n: generate ECB Known Answer Test files (new)");
printf("\n e: generate ECB Monte Carlo Test files");
printf("\n c: generate CBC Monte Carlo Test files");
printf("\n");
printf("\nand the characters giving block and key lengths are");
printf("\ndigits representing the lengths in 32-bit units.\n\n");
exit(0);
}
printf("\nRun tests for the AES algorithm %s",
#if defined(USE_DLL)
" (DLL Version)\n");
#elif defined(AES_CPP)
" (CPP Version)\n");
#else
"");
#endif
do_cmp = test_args(argc, argv, 'c', '\0');
tyf[0] = test_args(argc, argv, 't', 'k');
tyf[1] = test_args(argc, argv, 't', 'n');
tyf[2] = test_args(argc, argv, 't', 'e');
tyf[3] = test_args(argc, argv, 't', 'c');
kf[0] = test_args(argc, argv, 'k', '4');
kf[1] = test_args(argc, argv, 'k', '6');
kf[2] = test_args(argc, argv, 'k', '8');
if(!(kf[0] || kf[1] || kf[2]))
{
kf[0] = kf[1] = kf[2] = TRUE; // AES key sizes if not specified
}
for(ki = 0; ki < 3; ++ki) if(kf[ki])
{
do_tests(do_cmp, tyf, alg, 16, 16 + 8 * ki);
}
#if defined(USE_DLL) && defined(DYNAMIC_LINK)
if(h_dll) FreeLibrary(h_dll);
#endif
printf("\n\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -