u4byte k_cycles(const u4byte key_len, AESREF alg, const enum dir_flag f) { u1byte key[32]; u4byte i, cy0, cy1, cy2, c1, c2; // set up a random key of 256 bits block_rndfill(key, 32); // do an set_key to remove any 'first time through' effects alg.set_key(key, key_len, f); c1 = c2 = 0xffffffff; for(i = 0; i < loops; ++i) { block_rndfill(key, 32); // time one and two encryptions cycles(&cy0); alg.set_key(key, key_len, f); cycles(&cy1); alg.set_key(key, key_len, f); alg.set_key(key, key_len, f); cycles(&cy2); cy2 -= cy1; cy1 -= cy0; // time for one and two calls c1 = (c1 > cy1 ? cy1 : c1); // find minimum values over the loops c2 = (c2 > cy2 ? cy2 : c2); } return c2 - c1; // return one call timing }
u4byte e_cycles(const u4byte key_len, AESREF alg) { u1byte pt[16], ct[16], key[32]; u4byte i, cy0, cy1, cy2, c1, c2; // set up a random key of 256 bits block_rndfill(key, 32); // set up a random plain text block_rndfill(pt, 16); // do a set_key in case it is necessary alg.set_key(key, key_len, both); c1 = c2 = 0xffffffff; // do an encrypt to remove any 'first time through' effects alg.encrypt(pt, ct); for(i = 0; i < loops; ++i) { block_rndfill(pt, 16); // time one and two encryptions cycles(&cy0); alg.encrypt(pt, ct); cycles(&cy1); alg.encrypt(pt, ct); alg.encrypt(pt, ct); cycles(&cy2); cy2 -= cy1; cy1 -= cy0; // time for one and two calls c1 = (c1 > cy1 ? cy1 : c1); // find minimum values over the loops c2 = (c2 > cy2 ? cy2 : c2); } return c2 - c1; // return one call timing }
int time_ofb_enc(unsigned int k_len, int blocks, double *av, double *sig) { int i, tol, lcnt, sam_cnt; double cy, av1, sig1; unsigned char key[2 * AES_BLOCK_SIZE]; unsigned char vb[10000 * AES_BLOCK_SIZE]; unsigned char viv[AES_BLOCK_SIZE]; aligned_auto(unsigned char, pt, 10000 * AES_BLOCK_SIZE, 16); aligned_auto(unsigned char, iv, AES_BLOCK_SIZE, 16); aligned_auto(f_ectx, ecx, 1, 16); block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx, key, k_len); block_rndfill(iv, AES_BLOCK_SIZE); memcpy(viv, iv, AES_BLOCK_SIZE); block_rndfill(pt, blocks * AES_BLOCK_SIZE); memcpy(vb, pt, blocks * AES_BLOCK_SIZE); f_ofb_cry(ecx, pt, pt, blocks * AES_BLOCK_SIZE, iv); #ifdef VALIDATE_IN_TIMING OFBenc(vb, blocks * AES_BLOCK_SIZE, viv, ecx); if(memcmp(pt, vb, blocks * AES_BLOCK_SIZE)) goto error1; if(memcmp(viv, iv, AES_BLOCK_SIZE)) goto error2; #endif tol = 10; lcnt = sam_cnt = 0; while(!sam_cnt) { av1 = sig1 = 0.0; for(i = 0; i < SAMPLE1; ++i) { cy = (double)read_tsc(); f_ofb_cry(ecx, pt, pt, blocks * AES_BLOCK_SIZE, iv); cy = (double)read_tsc() - cy; av1 += cy; sig1 += cy * cy; #ifdef VALIDATE_IN_TIMING OFBenc(vb, blocks * AES_BLOCK_SIZE, viv, ecx); if(memcmp(pt, vb, blocks * AES_BLOCK_SIZE)) goto error1; if(memcmp(viv, iv, AES_BLOCK_SIZE)) goto error2; #endif } av1 /= SAMPLE1; sig1 = sqrt((sig1 - av1 * av1 * SAMPLE1) / SAMPLE1); sig1 = (sig1 < 0.05 * av1 ? 0.05 * av1 : sig1); *av = *sig = 0.0; for(i = 0; i < SAMPLE2; ++i) { cy = (double)read_tsc(); f_ofb_cry(ecx, pt, pt, blocks * AES_BLOCK_SIZE, iv); cy = (double)read_tsc() - cy; if(cy > av1 - sig1 && cy < av1 + sig1) { *av += cy; *sig += cy * cy; sam_cnt++; } #ifdef VALIDATE_IN_TIMING OFBenc(vb, blocks * AES_BLOCK_SIZE, viv, ecx); if(memcmp(pt, vb, blocks * AES_BLOCK_SIZE)) goto error1; if(memcmp(viv, iv, AES_BLOCK_SIZE)) goto error2; #endif } if(10 * sam_cnt > 9 * SAMPLE2) { *av /= sam_cnt; *sig = sqrt((*sig - *av * *av * sam_cnt) / sam_cnt); if(*sig > (tol / 100.0) * *av) sam_cnt = 0; } else { if(lcnt++ == 10) { lcnt = 0; tol += 5; if(tol > 30) return 0; } sam_cnt = 0; } } return 1; #ifdef VALIDATE_IN_TIMING error1: printf("\nOFB Encryption data error in timing"); exit(1); error2: printf("\nOFB Encryption iv error in timing"); exit(1); #endif }
int main(void) { int i, k, err, blocks, len, len2; double a0, av, sig, td; unsigned char buf1[BUFLEN]; unsigned char buf2[BUFLEN]; unsigned char iv1[AES_BLOCK_SIZE]; unsigned char iv2[AES_BLOCK_SIZE]; unsigned char key[32]; f_ectx ecx1[1]; f_dctx dcx1[1]; aligned_auto(unsigned char, buf3, BUFLEN, 16); aligned_auto(unsigned char, iv3, AES_BLOCK_SIZE, 16); aligned_auto(f_ectx, ecx2, 1, 16); aligned_auto(f_dctx, dcx2, 1, 16); #if defined( DLL_IMPORT ) && defined( DYNAMIC_LINK ) HINSTANCE h_dll; #endif #if defined( DUAL_CORE ) && defined( _WIN32 ) // we need to constrain the process to one core in order to // obtain meaningful timing data HANDLE ph; DWORD_PTR afp; DWORD_PTR afs; ph = GetCurrentProcess(); if(GetProcessAffinityMask(ph, &afp, &afs)) { afp &= (GetCurrentProcessorNumber() + 1); if(!SetProcessAffinityMask(ph, afp)) { printf("Couldn't set Process Affinity Mask\n\n"); return -1; } } else { printf("Couldn't get Process Affinity Mask\n\n"); return -1; } #endif #if defined( DLL_IMPORT ) && defined( DYNAMIC_LINK ) if(!(h_dll = init_dll(&fn))) return -1; #elif !defined(STATIC_TABLES) aes_init(); #endif if(f_talign(0,16) != EXIT_SUCCESS) return -1; printf("\nRun tests for the AES algorithm"); #if defined( DLL_IMPORT ) printf(" (DLL Version)"); #endif #if defined( __cplusplus ) printf(" (CPP Version)"); #endif for(k = 128; k <= 256; k += 64) { printf("\n\n%03i Bit Keys", k); #ifdef TEST_ECB err = 0; for(i = 0; i < 100; ++i) { block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx1, key, k); f_enc_key(ecx2, key, k); f_dec_key(dcx1, key, k); f_dec_key(dcx2, key, k); block_rndfill(buf1, BUFLEN); memcpy(buf2, buf1, BUFLEN); memcpy(buf3, buf1, BUFLEN); td = rand32() / (65536.0 * 65536.0); len = (unsigned int)(0.5 * BUFLEN * (1.0 + td)); len = AES_BLOCK_SIZE * (len / AES_BLOCK_SIZE); ECBenc(buf2, len, ecx1); f_ecb_enc(ecx2, buf3, buf3, len); if(memcmp(buf2, buf3, len)) err |= 1; if((err & 1) && !(err & 256)) printf("\nECB encryption FAILURE"); ECBdec(buf2, len, dcx1); f_ecb_dec(dcx2, buf3, buf3, len); if(memcmp(buf1, buf2, len)) err |= 2; if(memcmp(buf1, buf3, len)) err |= 4; if((err & 4) && !(err & 512)) printf("\nECB decryption FAILURE"); if(err & 1) err |= 256; if(err & 4) err |= 512; } if(!err) printf("\nECB encrypt and decrypt of data correct"); #endif #ifdef TEST_CBC err = 0; for(i = 0; i < 100; ++i) { block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx1, key, k); f_enc_key(ecx2, key, k); f_dec_key(dcx1, key, k); f_dec_key(dcx2, key, k); block_rndfill(iv1, AES_BLOCK_SIZE); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); block_rndfill(buf1, BUFLEN); memcpy(buf2, buf1, BUFLEN); memcpy(buf3, buf1, BUFLEN); td = rand32() / (65536.0 * 65536.0); len = (unsigned int)(0.5 * BUFLEN * (1.0 + td)); len = AES_BLOCK_SIZE * (len / AES_BLOCK_SIZE); CBCenc(buf2, len, iv2, ecx1); f_cbc_enc(ecx2, buf3, buf3, len, iv3); if(memcmp(buf2, buf3, len)) err |= 1; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 2; if((err & 1) && !(err & 256)) printf("\nCBC encryption FAILURE"); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); CBCdec(buf2, len, iv2, dcx1); f_cbc_dec(dcx2, buf3, buf3, len, iv3); if(memcmp(buf1, buf2, len)) err |= 4; if(memcmp(buf1, buf3, len)) err |= 8; if(memcmp(buf2, buf3, len)) err |= 16; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 32; if((err & 16) && !(err & 512)) printf("\nCBC decryption FAILURE"); if(err & 1) err |= 256; if(err & 16) err |= 512; } if(!(err & ~(2 | 4 | 16 | 32))) printf("\nCBC encrypt and decrypt of data correct"); if(err & (2 | 32)) { printf(" (mismatch of final IV on "); if(err & 2) printf("encrypt"); if((err & (2 | 32)) == 34) printf(" and "); if(err & 32) printf("decrypt"); printf(")"); } #endif #ifdef TEST_CFB err = 0; for(i = 0; i < 100; ++i) { block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx1, key, k); f_enc_key(ecx2, key, k); f_dec_key(dcx1, key, k); f_dec_key(dcx2, key, k); block_rndfill(iv1, AES_BLOCK_SIZE); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); block_rndfill(buf1, BUFLEN); memcpy(buf2, buf1, BUFLEN); memcpy(buf3, buf1, BUFLEN); f_info(ecx1) = 0; f_mode_reset(ecx2); td = rand32() / (65536.0 * 65536.0); len = (unsigned int)(0.5 * BUFLEN * (1.0 + td)); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); #ifdef WHOLE_BLOCKS len = AES_BLOCK_SIZE * (len / AES_BLOCK_SIZE); len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_cfb_enc(ecx2, buf3, buf3, len2, iv3); f_cfb_enc(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3); CFBenc(buf2, len, iv2, ecx1); if(memcmp(buf2, buf3, len)) err |= 1; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 2; if((err & 1) && !(err & 256)) printf("\nCFB encryption FAILURE"); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); f_info(ecx1) = 0; f_mode_reset(ecx2); CFBdec(buf2, len, iv2, ecx1); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); #ifdef WHOLE_BLOCKS len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_cfb_dec(ecx2, buf3, buf3, len2, iv3); f_cfb_dec(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3); if(memcmp(buf1, buf2, len)) err |= 4; if(memcmp(buf1, buf3, len)) err |= 8; if(memcmp(buf2, buf3, len)) err |= 16; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 32; if((err & 16) && !(err & 512)) printf("\nCFB decryption FAILURE"); if(err & 1) err |= 256; if(err & 16) err |= 512; } if(!(err & ~(2 | 4 | 16 | 32))) printf("\nCFB encrypt and decrypt of data correct"); if(err & (2 | 32)) { printf(" (mismatch of final IV on "); if(err & 2) printf("encrypt"); if((err & (2 | 32)) == 34) printf(" and "); if(err & 32) printf("decrypt"); printf(")"); } #endif #ifdef TEST_OFB err = 0; for(i = 0; i < 100; ++i) { block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx1, key, k); f_enc_key(ecx2, key, k); f_dec_key(dcx1, key, k); f_dec_key(dcx2, key, k); block_rndfill(iv1, AES_BLOCK_SIZE); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); block_rndfill(buf1, BUFLEN); memcpy(buf2, buf1, BUFLEN); memcpy(buf3, buf1, BUFLEN); f_info(ecx1) = 0; f_mode_reset(ecx2); td = rand32() / (65536.0 * 65536.0); len = (unsigned int)(0.5 * BUFLEN * (1.0 + td)); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); #ifdef WHOLE_BLOCKS len = AES_BLOCK_SIZE * (len / AES_BLOCK_SIZE); len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_ofb_cry(ecx2, buf3, buf3, len2, iv3); f_ofb_cry(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3); OFBenc(buf2, len, iv2, ecx1); if(memcmp(buf2, buf3, len)) err |= 1; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 2; if((err & 1) && !(err & 256)) printf("\nOFB encryption FAILURE"); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); f_info(ecx1) = 0; f_mode_reset(ecx2); OFBdec(buf2, len, iv2, ecx1); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); #ifdef WHOLE_BLOCKS len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_ofb_cry(ecx2, buf3, buf3, len2, iv3); f_ofb_cry(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3); if(memcmp(buf1, buf2, len)) err |= 4; if(memcmp(buf1, buf3, len)) err |= 8; if(memcmp(buf2, buf3, len)) err |= 16; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 32; if((err & 16) && !(err & 512)) printf("\nOFB decryption FAILURE"); if(err & 1) err |= 256; if(err & 16) err |= 512; } if(!(err & ~(2 | 4 | 16 | 32))) printf("\nOFB encrypt and decrypt of data correct"); if(err & (2 | 32)) { printf(" (mismatch of final IV on "); if(err & 2) printf("encrypt"); if((err & (2 | 32)) == 34) printf(" and "); if(err & 32) printf("decrypt"); printf(")"); } #endif #ifdef TEST_CTR err = 0; for(i = 0; i < 100; ++i) { block_rndfill(key, 2 * AES_BLOCK_SIZE); f_enc_key(ecx1, key, k); f_enc_key(ecx2, key, k); f_dec_key(dcx1, key, k); f_dec_key(dcx2, key, k); block_rndfill(iv1, AES_BLOCK_SIZE); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); block_rndfill(buf1, BUFLEN); memcpy(buf2, buf1, BUFLEN); memcpy(buf3, buf1, BUFLEN); f_info(ecx1) = 0; f_mode_reset(ecx2); td = rand32() / (65536.0 * 65536.0); len = (unsigned int)(0.5 * BUFLEN * (1.0 + td)); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); #ifdef WHOLE_BLOCKS len = AES_BLOCK_SIZE * (len / AES_BLOCK_SIZE); len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_ctr_cry(ecx2, buf3, buf3, len2, iv3, ctr_inc); f_ctr_cry(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3, ctr_inc); CTRcry(buf2, len, iv2, ctr_inc, ecx1); if(memcmp(buf2, buf3, len)) err |= 1; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 2; if((err & 1) && !(err & 256)) printf("\nCTR encryption FAILURE"); memcpy(iv2, iv1, AES_BLOCK_SIZE); memcpy(iv3, iv1, AES_BLOCK_SIZE); f_info(ecx1) = 0; f_mode_reset(ecx2); td = rand32() / (65536.0 * 65536.0); len2 = (unsigned int)(td * len); CTRcry(buf2, len, iv2, ctr_inc, ecx1); #ifdef WHOLE_BLOCKS len2 = AES_BLOCK_SIZE * (len2 / AES_BLOCK_SIZE); #endif f_ctr_cry(ecx2, buf3, buf3, len2, iv3, ctr_inc); f_ctr_cry(ecx2, buf3 + len2, buf3 + len2, len - len2, iv3, ctr_inc); if(memcmp(buf1, buf2, len)) err |= 4; if(memcmp(buf1, buf3, len)) err |= 8; if(memcmp(buf2, buf3, len)) err |= 16; if(memcmp(iv2, iv3, AES_BLOCK_SIZE)) err |= 32; if((err & 16) && !(err & 512)) printf("\nCTR decryption FAILURE"); if(err & 1) err |= 256; if(err & 16) err |= 512; } if(!(err & ~(2 | 4 | 16 | 32))) printf("\nCTR encrypt and decrypt of data correct"); if(err & (2 | 32)) { printf(" (mismatch of final IV on "); if(err & 2) printf("encrypt"); if((err & (2 | 32)) == 34) printf(" and "); if(err & 32) printf("decrypt"); printf(")"); } #endif } #if defined( USE_VIA_ACE_IF_PRESENT ) if(VIA_ACE_AVAILABLE) printf("\n\nAES Timing (Cycles/Byte) with the VIA ACE Engine"); else #endif printf("\n\nAES Timing (Cycles/Byte)"); printf("\nMode Blocks: 1 10 100 1000"); #ifdef TEST_ECB printf("\necb encrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_ecb_enc(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } printf("\necb decrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_ecb_dec(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } #endif #ifdef TEST_CBC printf("\ncbc encrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_cbc_enc(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } printf("\ncbc decrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_cbc_dec(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } #endif #ifdef TEST_CFB printf("\ncfb encrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_cfb_enc(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } printf("\ncfb decrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_cfb_dec(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } #endif #ifdef TEST_OFB printf("\nofb encrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_ofb_enc(16, blocks, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } #endif #ifdef TEST_CTR printf("\nctr encrypt "); for(blocks = 1; blocks < 10000; blocks *= 10) { time_base(&a0, &sig); time_ctr_crypt(16, blocks, ctr_inc, &av, &sig); sig *= 100.0 / av; av = (int)(100.0 * (av - a0) / (16.0 * blocks)) / 100.0; sig = (int)(10 * sig) / 10.0; printf("%9.2f", av); } #endif #if defined( DLL_IMPORT ) && defined( DYNAMIC_LINK ) if(h_dll) FreeLibrary(h_dll); #endif printf("\n\n"); return 0; }
void do_test( unsigned int ntests, enum mode mm ) { unsigned char key[2 * AES_BLOCK_SIZE]; /* the AES key */ unsigned char iv[MAX_BLOCK_SIZE]; /* the nonce */ unsigned char hdr[MAX_BLOCK_SIZE]; /* the header */ unsigned char ptx[MAX_BLOCK_SIZE]; /* the plaintext */ unsigned char ctx[2][MAX_BLOCK_SIZE]; /* BRG and LTC ciphertexts */ unsigned char res[2][MAX_BLOCK_SIZE]; /* BRG and LTC decrypts */ unsigned char tag[2][AES_BLOCK_SIZE]; /* BRG and LTC tags */ unsigned int i, key_len = AES_BLOCK_SIZE, iv_len, hdr_len, msg_len, err = 0, err1, stat; ctx_union context[1]; err1 = RETURN_GOOD; for( i = 0; i < ntests; ++i ) { /* the mode key value */ block_rndfill( key, 16 ); /* the iv/nonce value */ block_rndfill( (unsigned char*)&iv_len, 4 ); iv_len &= 0x1fff; /* adjust for nonce format variations */ switch(mm) { case m_ccm: iv_len = 6 + (iv_len & 7); iv_len = ( iv_len < 7 ? 7 : iv_len ); break; case m_gcm: iv_len &= 0x1fff; iv_len = (iv_len & 0x1000 ? 12 : iv_len); break; case m_eax: iv_len &= 0x1fff; iv_len = (iv_len & 0x1000 ? iv_len & 0x001f : iv_len); } block_rndfill( iv, iv_len ); /* the authenticated header */ block_rndfill( (unsigned char*)&hdr_len, 4 ); hdr_len &= 0x1fff; /* half messages have no headers */ hdr_len = ( hdr_len & 0x1000 ? 0 : hdr_len ); block_rndfill( hdr, hdr_len ); /* the plaintext message */ block_rndfill( (unsigned char*)&msg_len, 4 ); msg_len &= 0x0fff; block_rndfill( ptx, msg_len ); /* initialise BRG version */ ea_funs.brg_ifun[mm](key, key_len, context); memcpy( ctx[0], ptx, msg_len ); /* encrypt and authenticate for BRG version*/ ea_funs.brg_efun[mm](iv, iv_len, hdr, hdr_len, ctx[0], msg_len, tag[0], AES_BLOCK_SIZE, context ); /* initialise BRG version */ ea_funs.brg_ifun[mm]( key, key_len, context ); memcpy( res[0], ctx[0], msg_len ); /* decrypt and verify for BRG version*/ err = ea_funs.brg_dfun[mm]( iv, iv_len, hdr, hdr_len, res[0], msg_len, tag[0], AES_BLOCK_SIZE, context ); /* encrypt and authenticate for LTC version*/ ea_funs.ltc_fun[mm]( key, key_len, iv, iv_len, hdr, hdr_len, ptx, msg_len, ctx[1], tag[1], AES_BLOCK_SIZE, LTC_ENCRYPT, 0); /* decrypt and verify for LTC version*/ ea_funs.ltc_fun[mm]( key, key_len, iv, iv_len, hdr, hdr_len, res[1], msg_len, ctx[1], tag[1], AES_BLOCK_SIZE, LTC_DECRYPT, (int*)&stat); if(memcmp(ptx, res[0], msg_len)) { std::cout << std::endl << mode_name[mm] << ": (BRG) encryption or decryption error"; err1 = RETURN_ERROR; } if(err != RETURN_GOOD) { std::cout << std::endl << mode_name[mm] << ": (BRG) tag error"; err1 = RETURN_ERROR; } if(memcmp(ptx, res[1], msg_len)) { std::cout << std::endl << mode_name[mm] << ": (LTC) encryption or decryption error"; err1 = RETURN_ERROR; } if(stat != RETURN_GOOD) { std::cout << std::endl << mode_name[mm] << ": (LTC)tag error"; err1 = RETURN_ERROR; } if(memcmp(ctx[0], ctx[1], msg_len)) { std::cout << std::endl << mode_name[mm] << ": ciphertext mismatch error"; err1 = RETURN_ERROR; } if(memcmp(tag[0], tag[1], AES_BLOCK_SIZE)) { std::cout << std::endl << mode_name[mm] << ": tag mismatch error"; err1 = RETURN_ERROR; } } if(err1 == RETURN_GOOD) { std::cout << std::endl << mode_name[mm] << ": (BRG) and (LTC) outputs match"; } }