qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at master 204 lines 6.1 kB view raw
1/* 2 * QEMU Crypto cipher speed benchmark 3 * 4 * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD. 5 * 6 * Authors: 7 * Longpeng(Mike) <longpeng2@huawei.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2 or 10 * (at your option) any later version. See the COPYING file in the 11 * top-level directory. 12 */ 13#include "qemu/osdep.h" 14#include "qemu/units.h" 15#include "crypto/init.h" 16#include "crypto/cipher.h" 17 18static void test_cipher_speed(size_t chunk_size, 19 QCryptoCipherMode mode, 20 QCryptoCipherAlgorithm alg) 21{ 22 QCryptoCipher *cipher; 23 Error *err = NULL; 24 uint8_t *key = NULL, *iv = NULL; 25 uint8_t *plaintext = NULL, *ciphertext = NULL; 26 size_t nkey; 27 size_t niv; 28 const size_t total = 2 * GiB; 29 size_t remain; 30 31 if (!qcrypto_cipher_supports(alg, mode)) { 32 return; 33 } 34 35 nkey = qcrypto_cipher_get_key_len(alg); 36 niv = qcrypto_cipher_get_iv_len(alg, mode); 37 if (mode == QCRYPTO_CIPHER_MODE_XTS) { 38 nkey *= 2; 39 } 40 41 key = g_new0(uint8_t, nkey); 42 memset(key, g_test_rand_int(), nkey); 43 44 iv = g_new0(uint8_t, niv); 45 memset(iv, g_test_rand_int(), niv); 46 47 ciphertext = g_new0(uint8_t, chunk_size); 48 49 plaintext = g_new0(uint8_t, chunk_size); 50 memset(plaintext, g_test_rand_int(), chunk_size); 51 52 cipher = qcrypto_cipher_new(alg, mode, 53 key, nkey, &err); 54 g_assert(cipher != NULL); 55 56 if (mode != QCRYPTO_CIPHER_MODE_ECB) 57 g_assert(qcrypto_cipher_setiv(cipher, 58 iv, niv, 59 &err) == 0); 60 61 g_test_timer_start(); 62 remain = total; 63 while (remain) { 64 g_assert(qcrypto_cipher_encrypt(cipher, 65 plaintext, 66 ciphertext, 67 chunk_size, 68 &err) == 0); 69 remain -= chunk_size; 70 } 71 g_test_timer_elapsed(); 72 73 g_print("Enc chunk %zu bytes ", chunk_size); 74 g_print("%.2f MB/sec ", (double)total / MiB / g_test_timer_last()); 75 76 g_test_timer_start(); 77 remain = total; 78 while (remain) { 79 g_assert(qcrypto_cipher_decrypt(cipher, 80 plaintext, 81 ciphertext, 82 chunk_size, 83 &err) == 0); 84 remain -= chunk_size; 85 } 86 g_test_timer_elapsed(); 87 88 g_print("Dec chunk %zu bytes ", chunk_size); 89 g_print("%.2f MB/sec ", (double)total / MiB / g_test_timer_last()); 90 91 qcrypto_cipher_free(cipher); 92 g_free(plaintext); 93 g_free(ciphertext); 94 g_free(iv); 95 g_free(key); 96} 97 98 99static void test_cipher_speed_ecb_aes_128(const void *opaque) 100{ 101 size_t chunk_size = (size_t)opaque; 102 test_cipher_speed(chunk_size, 103 QCRYPTO_CIPHER_MODE_ECB, 104 QCRYPTO_CIPHER_ALG_AES_128); 105} 106 107static void test_cipher_speed_ecb_aes_256(const void *opaque) 108{ 109 size_t chunk_size = (size_t)opaque; 110 test_cipher_speed(chunk_size, 111 QCRYPTO_CIPHER_MODE_ECB, 112 QCRYPTO_CIPHER_ALG_AES_256); 113} 114 115static void test_cipher_speed_cbc_aes_128(const void *opaque) 116{ 117 size_t chunk_size = (size_t)opaque; 118 test_cipher_speed(chunk_size, 119 QCRYPTO_CIPHER_MODE_CBC, 120 QCRYPTO_CIPHER_ALG_AES_128); 121} 122 123static void test_cipher_speed_cbc_aes_256(const void *opaque) 124{ 125 size_t chunk_size = (size_t)opaque; 126 test_cipher_speed(chunk_size, 127 QCRYPTO_CIPHER_MODE_CBC, 128 QCRYPTO_CIPHER_ALG_AES_256); 129} 130 131static void test_cipher_speed_ctr_aes_128(const void *opaque) 132{ 133 size_t chunk_size = (size_t)opaque; 134 test_cipher_speed(chunk_size, 135 QCRYPTO_CIPHER_MODE_CTR, 136 QCRYPTO_CIPHER_ALG_AES_128); 137} 138 139static void test_cipher_speed_ctr_aes_256(const void *opaque) 140{ 141 size_t chunk_size = (size_t)opaque; 142 test_cipher_speed(chunk_size, 143 QCRYPTO_CIPHER_MODE_CTR, 144 QCRYPTO_CIPHER_ALG_AES_256); 145} 146 147static void test_cipher_speed_xts_aes_128(const void *opaque) 148{ 149 size_t chunk_size = (size_t)opaque; 150 test_cipher_speed(chunk_size, 151 QCRYPTO_CIPHER_MODE_XTS, 152 QCRYPTO_CIPHER_ALG_AES_128); 153} 154 155static void test_cipher_speed_xts_aes_256(const void *opaque) 156{ 157 size_t chunk_size = (size_t)opaque; 158 test_cipher_speed(chunk_size, 159 QCRYPTO_CIPHER_MODE_XTS, 160 QCRYPTO_CIPHER_ALG_AES_256); 161} 162 163 164int main(int argc, char **argv) 165{ 166 char *alg = NULL; 167 char *size = NULL; 168 g_test_init(&argc, &argv, NULL); 169 g_assert(qcrypto_init(NULL) == 0); 170 171#define ADD_TEST(mode, cipher, keysize, chunk) \ 172 if ((!alg || g_str_equal(alg, #mode)) && \ 173 (!size || g_str_equal(size, #chunk))) \ 174 g_test_add_data_func( \ 175 "/crypto/cipher/" #mode "-" #cipher "-" #keysize "/chunk-" #chunk, \ 176 (void *)chunk, \ 177 test_cipher_speed_ ## mode ## _ ## cipher ## _ ## keysize) 178 179 if (argc >= 2) { 180 alg = argv[1]; 181 } 182 if (argc >= 3) { 183 size = argv[2]; 184 } 185 186#define ADD_TESTS(chunk) \ 187 do { \ 188 ADD_TEST(ecb, aes, 128, chunk); \ 189 ADD_TEST(ecb, aes, 256, chunk); \ 190 ADD_TEST(cbc, aes, 128, chunk); \ 191 ADD_TEST(cbc, aes, 256, chunk); \ 192 ADD_TEST(ctr, aes, 128, chunk); \ 193 ADD_TEST(ctr, aes, 256, chunk); \ 194 ADD_TEST(xts, aes, 128, chunk); \ 195 ADD_TEST(xts, aes, 256, chunk); \ 196 } while (0) 197 198 ADD_TESTS(512); 199 ADD_TESTS(4096); 200 ADD_TESTS(16384); 201 ADD_TESTS(65536); 202 203 return g_test_run(); 204}