xref: /openbmc/qemu/tests/bench/benchmark-crypto-cipher.c (revision b8eada54b2ad8a7d98d93d5ab4d3e888c5880097)
13b472e71SThomas Huth /*
23b472e71SThomas Huth  * QEMU Crypto cipher speed benchmark
33b472e71SThomas Huth  *
43b472e71SThomas Huth  * Copyright (c) 2017 HUAWEI TECHNOLOGIES CO., LTD.
53b472e71SThomas Huth  *
63b472e71SThomas Huth  * Authors:
73b472e71SThomas Huth  *    Longpeng(Mike) <longpeng2@huawei.com>
83b472e71SThomas Huth  *
93b472e71SThomas Huth  * This work is licensed under the terms of the GNU GPL, version 2 or
103b472e71SThomas Huth  * (at your option) any later version.  See the COPYING file in the
113b472e71SThomas Huth  * top-level directory.
123b472e71SThomas Huth  */
133b472e71SThomas Huth #include "qemu/osdep.h"
143b472e71SThomas Huth #include "qemu/units.h"
153b472e71SThomas Huth #include "crypto/init.h"
163b472e71SThomas Huth #include "crypto/cipher.h"
173b472e71SThomas Huth 
test_cipher_speed(size_t chunk_size,QCryptoCipherMode mode,QCryptoCipherAlgo alg)183b472e71SThomas Huth static void test_cipher_speed(size_t chunk_size,
193b472e71SThomas Huth                               QCryptoCipherMode mode,
20*a092c513SMarkus Armbruster                               QCryptoCipherAlgo alg)
213b472e71SThomas Huth {
223b472e71SThomas Huth     QCryptoCipher *cipher;
233b472e71SThomas Huth     Error *err = NULL;
243b472e71SThomas Huth     uint8_t *key = NULL, *iv = NULL;
253b472e71SThomas Huth     uint8_t *plaintext = NULL, *ciphertext = NULL;
263b472e71SThomas Huth     size_t nkey;
273b472e71SThomas Huth     size_t niv;
283b472e71SThomas Huth     const size_t total = 2 * GiB;
293b472e71SThomas Huth     size_t remain;
303b472e71SThomas Huth 
313b472e71SThomas Huth     if (!qcrypto_cipher_supports(alg, mode)) {
323b472e71SThomas Huth         return;
333b472e71SThomas Huth     }
343b472e71SThomas Huth 
353b472e71SThomas Huth     nkey = qcrypto_cipher_get_key_len(alg);
363b472e71SThomas Huth     niv = qcrypto_cipher_get_iv_len(alg, mode);
373b472e71SThomas Huth     if (mode == QCRYPTO_CIPHER_MODE_XTS) {
383b472e71SThomas Huth         nkey *= 2;
393b472e71SThomas Huth     }
403b472e71SThomas Huth 
413b472e71SThomas Huth     key = g_new0(uint8_t, nkey);
423b472e71SThomas Huth     memset(key, g_test_rand_int(), nkey);
433b472e71SThomas Huth 
443b472e71SThomas Huth     iv = g_new0(uint8_t, niv);
453b472e71SThomas Huth     memset(iv, g_test_rand_int(), niv);
463b472e71SThomas Huth 
473b472e71SThomas Huth     ciphertext = g_new0(uint8_t, chunk_size);
483b472e71SThomas Huth 
493b472e71SThomas Huth     plaintext = g_new0(uint8_t, chunk_size);
503b472e71SThomas Huth     memset(plaintext, g_test_rand_int(), chunk_size);
513b472e71SThomas Huth 
523b472e71SThomas Huth     cipher = qcrypto_cipher_new(alg, mode,
533b472e71SThomas Huth                                 key, nkey, &err);
543b472e71SThomas Huth     g_assert(cipher != NULL);
553b472e71SThomas Huth 
563b472e71SThomas Huth     if (mode != QCRYPTO_CIPHER_MODE_ECB)
573b472e71SThomas Huth         g_assert(qcrypto_cipher_setiv(cipher,
583b472e71SThomas Huth                                       iv, niv,
593b472e71SThomas Huth                                       &err) == 0);
603b472e71SThomas Huth 
613b472e71SThomas Huth     g_test_timer_start();
623b472e71SThomas Huth     remain = total;
633b472e71SThomas Huth     while (remain) {
643b472e71SThomas Huth         g_assert(qcrypto_cipher_encrypt(cipher,
653b472e71SThomas Huth                                         plaintext,
663b472e71SThomas Huth                                         ciphertext,
673b472e71SThomas Huth                                         chunk_size,
683b472e71SThomas Huth                                         &err) == 0);
693b472e71SThomas Huth         remain -= chunk_size;
703b472e71SThomas Huth     }
713b472e71SThomas Huth     g_test_timer_elapsed();
723b472e71SThomas Huth 
733b472e71SThomas Huth     g_test_message("enc(%s-%s) chunk %zu bytes %.2f MB/sec ",
74*a092c513SMarkus Armbruster                    QCryptoCipherAlgo_str(alg),
753b472e71SThomas Huth                    QCryptoCipherMode_str(mode),
763b472e71SThomas Huth                    chunk_size, (double)total / MiB / g_test_timer_last());
773b472e71SThomas Huth 
783b472e71SThomas Huth     g_test_timer_start();
793b472e71SThomas Huth     remain = total;
803b472e71SThomas Huth     while (remain) {
813b472e71SThomas Huth         g_assert(qcrypto_cipher_decrypt(cipher,
823b472e71SThomas Huth                                         plaintext,
833b472e71SThomas Huth                                         ciphertext,
843b472e71SThomas Huth                                         chunk_size,
853b472e71SThomas Huth                                         &err) == 0);
863b472e71SThomas Huth         remain -= chunk_size;
873b472e71SThomas Huth     }
883b472e71SThomas Huth     g_test_timer_elapsed();
893b472e71SThomas Huth 
903b472e71SThomas Huth     g_test_message("dec(%s-%s) chunk %zu bytes %.2f MB/sec ",
91*a092c513SMarkus Armbruster                    QCryptoCipherAlgo_str(alg),
923b472e71SThomas Huth                    QCryptoCipherMode_str(mode),
933b472e71SThomas Huth                    chunk_size, (double)total / MiB / g_test_timer_last());
943b472e71SThomas Huth 
953b472e71SThomas Huth     qcrypto_cipher_free(cipher);
963b472e71SThomas Huth     g_free(plaintext);
973b472e71SThomas Huth     g_free(ciphertext);
983b472e71SThomas Huth     g_free(iv);
993b472e71SThomas Huth     g_free(key);
1003b472e71SThomas Huth }
1013b472e71SThomas Huth 
1023b472e71SThomas Huth 
test_cipher_speed_ecb_aes_128(const void * opaque)1033b472e71SThomas Huth static void test_cipher_speed_ecb_aes_128(const void *opaque)
1043b472e71SThomas Huth {
1053b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1063b472e71SThomas Huth     test_cipher_speed(chunk_size,
1073b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_ECB,
108*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_128);
1093b472e71SThomas Huth }
1103b472e71SThomas Huth 
test_cipher_speed_ecb_aes_256(const void * opaque)1113b472e71SThomas Huth static void test_cipher_speed_ecb_aes_256(const void *opaque)
1123b472e71SThomas Huth {
1133b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1143b472e71SThomas Huth     test_cipher_speed(chunk_size,
1153b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_ECB,
116*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_256);
1173b472e71SThomas Huth }
1183b472e71SThomas Huth 
test_cipher_speed_cbc_aes_128(const void * opaque)1193b472e71SThomas Huth static void test_cipher_speed_cbc_aes_128(const void *opaque)
1203b472e71SThomas Huth {
1213b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1223b472e71SThomas Huth     test_cipher_speed(chunk_size,
1233b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_CBC,
124*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_128);
1253b472e71SThomas Huth }
1263b472e71SThomas Huth 
test_cipher_speed_cbc_aes_256(const void * opaque)1273b472e71SThomas Huth static void test_cipher_speed_cbc_aes_256(const void *opaque)
1283b472e71SThomas Huth {
1293b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1303b472e71SThomas Huth     test_cipher_speed(chunk_size,
1313b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_CBC,
132*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_256);
1333b472e71SThomas Huth }
1343b472e71SThomas Huth 
test_cipher_speed_ctr_aes_128(const void * opaque)1353b472e71SThomas Huth static void test_cipher_speed_ctr_aes_128(const void *opaque)
1363b472e71SThomas Huth {
1373b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1383b472e71SThomas Huth     test_cipher_speed(chunk_size,
1393b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_CTR,
140*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_128);
1413b472e71SThomas Huth }
1423b472e71SThomas Huth 
test_cipher_speed_ctr_aes_256(const void * opaque)1433b472e71SThomas Huth static void test_cipher_speed_ctr_aes_256(const void *opaque)
1443b472e71SThomas Huth {
1453b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1463b472e71SThomas Huth     test_cipher_speed(chunk_size,
1473b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_CTR,
148*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_256);
1493b472e71SThomas Huth }
1503b472e71SThomas Huth 
test_cipher_speed_xts_aes_128(const void * opaque)1513b472e71SThomas Huth static void test_cipher_speed_xts_aes_128(const void *opaque)
1523b472e71SThomas Huth {
1533b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1543b472e71SThomas Huth     test_cipher_speed(chunk_size,
1553b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_XTS,
156*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_128);
1573b472e71SThomas Huth }
1583b472e71SThomas Huth 
test_cipher_speed_xts_aes_256(const void * opaque)1593b472e71SThomas Huth static void test_cipher_speed_xts_aes_256(const void *opaque)
1603b472e71SThomas Huth {
1613b472e71SThomas Huth     size_t chunk_size = (size_t)opaque;
1623b472e71SThomas Huth     test_cipher_speed(chunk_size,
1633b472e71SThomas Huth                       QCRYPTO_CIPHER_MODE_XTS,
164*a092c513SMarkus Armbruster                       QCRYPTO_CIPHER_ALGO_AES_256);
1653b472e71SThomas Huth }
1663b472e71SThomas Huth 
1673b472e71SThomas Huth 
main(int argc,char ** argv)1683b472e71SThomas Huth int main(int argc, char **argv)
1693b472e71SThomas Huth {
1703b472e71SThomas Huth     char *alg = NULL;
1713b472e71SThomas Huth     char *size = NULL;
1723b472e71SThomas Huth     g_test_init(&argc, &argv, NULL);
1733b472e71SThomas Huth     g_assert(qcrypto_init(NULL) == 0);
1743b472e71SThomas Huth 
1753b472e71SThomas Huth #define ADD_TEST(mode, cipher, keysize, chunk)                          \
1763b472e71SThomas Huth     if ((!alg || g_str_equal(alg, #mode)) &&                            \
1773b472e71SThomas Huth         (!size || g_str_equal(size, #chunk)))                           \
1783b472e71SThomas Huth         g_test_add_data_func(                                           \
1793b472e71SThomas Huth         "/crypto/cipher/" #mode "-" #cipher "-" #keysize "/chunk-" #chunk, \
1803b472e71SThomas Huth         (void *)chunk,                                                  \
1813b472e71SThomas Huth         test_cipher_speed_ ## mode ## _ ## cipher ## _ ## keysize)
1823b472e71SThomas Huth 
1833b472e71SThomas Huth     if (argc >= 2) {
1843b472e71SThomas Huth         alg = argv[1];
1853b472e71SThomas Huth     }
1863b472e71SThomas Huth     if (argc >= 3) {
1873b472e71SThomas Huth         size = argv[2];
1883b472e71SThomas Huth     }
1893b472e71SThomas Huth 
1903b472e71SThomas Huth #define ADD_TESTS(chunk)                        \
1913b472e71SThomas Huth     do {                                        \
1923b472e71SThomas Huth         ADD_TEST(ecb, aes, 128, chunk);         \
1933b472e71SThomas Huth         ADD_TEST(ecb, aes, 256, chunk);         \
1943b472e71SThomas Huth         ADD_TEST(cbc, aes, 128, chunk);         \
1953b472e71SThomas Huth         ADD_TEST(cbc, aes, 256, chunk);         \
1963b472e71SThomas Huth         ADD_TEST(ctr, aes, 128, chunk);         \
1973b472e71SThomas Huth         ADD_TEST(ctr, aes, 256, chunk);         \
1983b472e71SThomas Huth         ADD_TEST(xts, aes, 128, chunk);         \
1993b472e71SThomas Huth         ADD_TEST(xts, aes, 256, chunk);         \
2003b472e71SThomas Huth     } while (0)
2013b472e71SThomas Huth 
2023b472e71SThomas Huth     ADD_TESTS(512);
2033b472e71SThomas Huth     ADD_TESTS(4096);
2043b472e71SThomas Huth     ADD_TESTS(16384);
2053b472e71SThomas Huth     ADD_TESTS(65536);
2063b472e71SThomas Huth 
2073b472e71SThomas Huth     return g_test_run();
2083b472e71SThomas Huth }
209