/** Run unit tests for our AES functionality */ static void test_crypto_aes(void *arg) { char *data1 = NULL, *data2 = NULL, *data3 = NULL; crypto_cipher_t *env1 = NULL, *env2 = NULL; int i, j; char *mem_op_hex_tmp=NULL; int use_evp = !strcmp(arg,"evp"); evaluate_evp_for_aes(use_evp); evaluate_ctr_for_aes(); data1 = tor_malloc(1024); data2 = tor_malloc(1024); data3 = tor_malloc(1024); /* Now, test encryption and decryption with stream cipher. */ data1[0]='\0'; for (i = 1023; i>0; i -= 35) strncat(data1, "Now is the time for all good onions", i); memset(data2, 0, 1024); memset(data3, 0, 1024); env1 = crypto_cipher_new(NULL); test_neq_ptr(env1, 0); env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); test_neq_ptr(env2, 0); /* Try encrypting 512 chars. */ crypto_cipher_encrypt(env1, data2, data1, 512); crypto_cipher_decrypt(env2, data3, data2, 512); test_memeq(data1, data3, 512); test_memneq(data1, data2, 512); /* Now encrypt 1 at a time, and get 1 at a time. */ for (j = 512; j < 560; ++j) { crypto_cipher_encrypt(env1, data2+j, data1+j, 1); } for (j = 512; j < 560; ++j) { crypto_cipher_decrypt(env2, data3+j, data2+j, 1); } test_memeq(data1, data3, 560); /* Now encrypt 3 at a time, and get 5 at a time. */ for (j = 560; j < 1024-5; j += 3) { crypto_cipher_encrypt(env1, data2+j, data1+j, 3); } for (j = 560; j < 1024-5; j += 5) { crypto_cipher_decrypt(env2, data3+j, data2+j, 5); } test_memeq(data1, data3, 1024-5); /* Now make sure that when we encrypt with different chunk sizes, we get the same results. */ crypto_cipher_free(env2); env2 = NULL; memset(data3, 0, 1024); env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); test_neq_ptr(env2, NULL); for (j = 0; j < 1024-16; j += 17) { crypto_cipher_encrypt(env2, data3+j, data1+j, 17); } for (j= 0; j < 1024-16; ++j) { if (data2[j] != data3[j]) { printf("%d: %d\t%d\n", j, (int) data2[j], (int) data3[j]); } } test_memeq(data2, data3, 1024-16); crypto_cipher_free(env1); env1 = NULL; crypto_cipher_free(env2); env2 = NULL; /* NIST test vector for aes. */ /* IV starts at 0 */ env1 = crypto_cipher_new("\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00"); crypto_cipher_encrypt(env1, data1, "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", 16); test_memeq_hex(data1, "0EDD33D3C621E546455BD8BA1418BEC8"); /* Now test rollover. All these values are originally from a python * script. */ crypto_cipher_free(env1); env1 = crypto_cipher_new_with_iv( "\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\x00" "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231" "cdd0b917dbc7186908a6bfb5ffd574d3"); crypto_cipher_free(env1); env1 = crypto_cipher_new_with_iv( "\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73" "3e63c721df790d2c6469cc1953a3ffac"); crypto_cipher_free(env1); env1 = crypto_cipher_new_with_iv( "\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a" "0EDD33D3C621E546455BD8BA1418BEC8"); /* Now check rollover on inplace cipher. */ crypto_cipher_free(env1); env1 = crypto_cipher_new_with_iv( "\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff"); crypto_cipher_crypt_inplace(env1, data2, 64); test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a" "0EDD33D3C621E546455BD8BA1418BEC8" "93e2c5243d6839eac58503919192f7ae" "1908e67cafa08d508816659c2e693191"); crypto_cipher_free(env1); env1 = crypto_cipher_new_with_iv( "\x80\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff"); crypto_cipher_crypt_inplace(env1, data2, 64); test_assert(tor_mem_is_zero(data2, 64)); done: tor_free(mem_op_hex_tmp); if (env1) crypto_cipher_free(env1); if (env2) crypto_cipher_free(env2); tor_free(data1); tor_free(data2); tor_free(data3); }
/** Run AES performance benchmarks. */ static void bench_aes(void) { int len, i; char *b1, *b2, *temp; crypto_cipher_t *c; uint64_t start, end; const int bytes_per_iter = (1<<24); reset_perftime(); c = crypto_cipher_new(NULL); memmgr_destroy(); memmgr_init_check_shared_mem(SHARED_SIZE, UIO_DEVICE, BASE_ADDRESS); FPGA_AES *cipher1 = NULL; char default_iv[] = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; cipher1 = fpga_aes_new_short_16((char*)crypto_cipher_get_key(c), default_iv, 2); if(cipher1 == NULL){ printf("\nCould not allocate cipher"); return; } b1 = memmgr_alloc(8192*2+16);//tor_malloc_zero(len); b2 = memmgr_alloc(8192*2+16);//tor_malloc_zero(len); temp = memmgr_alloc(8192*2+16); printf("\nKey: 0x"); for(i=0; i<16; i++){ printf("%02x", cipher1->key[i]); } printf("\n"); // printf("\nBytes per iter: %i", bytes_per_iter); for (len = 2; len <= 8192; len *= 2) { int iters = bytes_per_iter / len; // printf("\nIterations: %i\n", iters); memset(b1, 0, len); memset(b2, 0, len); memset(temp, 0, len); printf("\nb2: 0x"); for(i=0; i<len; i++){ printf("%02x", b2[i]); } start = perftime(); for (i = 0; i < iters; ++i) { // crypto_cipher_encrypt(c, b1, b2, len); // if(i == iters - 1){ // printf(" i: %i ", i); // } Aes_encrypt_memmgr(cipher1, b1, b2, len); } end = perftime(); memset(b2, 0, len); printf("\nFinal iv/iters: 0x%08x", iters); // for(i=1; i<16; i++){ // printf("%02x", cipher1->iv[i]); // } for(i=0; i<iters; ++i){ crypto_cipher_encrypt(c, temp, b2, len); } int incorrect = 0; printf("\nb1: 0x"); for(i=0; i<len; i++){ printf("%02x", b2[i]); } for(i=0; i<len; i++){ if(temp[i] != b1[i]){ incorrect++; printf("\nIncorrect: 0x%02x - 0x%02x fabric", temp[i], b1[i]); } } // tor_free(b1); // tor_free(b2); printf("%d bytes: %.2f nsec per byte\n", len, NANOCOUNT(start, end, iters*len)); printf("Num incorrect: %i\n", incorrect); //printf("start: %lu, end: %lu\n", start, end); } memmgr_free(b1); memmgr_free(b2); memmgr_free(temp); crypto_cipher_free(c); fpga_aes_free(cipher1); }