qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

benchmark-crypto-cipher.c (6334B)


      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 
     18 static 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_test_message("enc(%s-%s) chunk %zu bytes %.2f MB/sec ",
     74                    QCryptoCipherAlgorithm_str(alg),
     75                    QCryptoCipherMode_str(mode),
     76                    chunk_size, (double)total / MiB / g_test_timer_last());
     77 
     78     g_test_timer_start();
     79     remain = total;
     80     while (remain) {
     81         g_assert(qcrypto_cipher_decrypt(cipher,
     82                                         plaintext,
     83                                         ciphertext,
     84                                         chunk_size,
     85                                         &err) == 0);
     86         remain -= chunk_size;
     87     }
     88     g_test_timer_elapsed();
     89 
     90     g_test_message("dec(%s-%s) chunk %zu bytes %.2f MB/sec ",
     91                    QCryptoCipherAlgorithm_str(alg),
     92                    QCryptoCipherMode_str(mode),
     93                    chunk_size, (double)total / MiB / g_test_timer_last());
     94 
     95     qcrypto_cipher_free(cipher);
     96     g_free(plaintext);
     97     g_free(ciphertext);
     98     g_free(iv);
     99     g_free(key);
    100 }
    101 
    102 
    103 static void test_cipher_speed_ecb_aes_128(const void *opaque)
    104 {
    105     size_t chunk_size = (size_t)opaque;
    106     test_cipher_speed(chunk_size,
    107                       QCRYPTO_CIPHER_MODE_ECB,
    108                       QCRYPTO_CIPHER_ALG_AES_128);
    109 }
    110 
    111 static void test_cipher_speed_ecb_aes_256(const void *opaque)
    112 {
    113     size_t chunk_size = (size_t)opaque;
    114     test_cipher_speed(chunk_size,
    115                       QCRYPTO_CIPHER_MODE_ECB,
    116                       QCRYPTO_CIPHER_ALG_AES_256);
    117 }
    118 
    119 static void test_cipher_speed_cbc_aes_128(const void *opaque)
    120 {
    121     size_t chunk_size = (size_t)opaque;
    122     test_cipher_speed(chunk_size,
    123                       QCRYPTO_CIPHER_MODE_CBC,
    124                       QCRYPTO_CIPHER_ALG_AES_128);
    125 }
    126 
    127 static void test_cipher_speed_cbc_aes_256(const void *opaque)
    128 {
    129     size_t chunk_size = (size_t)opaque;
    130     test_cipher_speed(chunk_size,
    131                       QCRYPTO_CIPHER_MODE_CBC,
    132                       QCRYPTO_CIPHER_ALG_AES_256);
    133 }
    134 
    135 static void test_cipher_speed_ctr_aes_128(const void *opaque)
    136 {
    137     size_t chunk_size = (size_t)opaque;
    138     test_cipher_speed(chunk_size,
    139                       QCRYPTO_CIPHER_MODE_CTR,
    140                       QCRYPTO_CIPHER_ALG_AES_128);
    141 }
    142 
    143 static void test_cipher_speed_ctr_aes_256(const void *opaque)
    144 {
    145     size_t chunk_size = (size_t)opaque;
    146     test_cipher_speed(chunk_size,
    147                       QCRYPTO_CIPHER_MODE_CTR,
    148                       QCRYPTO_CIPHER_ALG_AES_256);
    149 }
    150 
    151 static void test_cipher_speed_xts_aes_128(const void *opaque)
    152 {
    153     size_t chunk_size = (size_t)opaque;
    154     test_cipher_speed(chunk_size,
    155                       QCRYPTO_CIPHER_MODE_XTS,
    156                       QCRYPTO_CIPHER_ALG_AES_128);
    157 }
    158 
    159 static void test_cipher_speed_xts_aes_256(const void *opaque)
    160 {
    161     size_t chunk_size = (size_t)opaque;
    162     test_cipher_speed(chunk_size,
    163                       QCRYPTO_CIPHER_MODE_XTS,
    164                       QCRYPTO_CIPHER_ALG_AES_256);
    165 }
    166 
    167 
    168 int main(int argc, char **argv)
    169 {
    170     char *alg = NULL;
    171     char *size = NULL;
    172     g_test_init(&argc, &argv, NULL);
    173     g_assert(qcrypto_init(NULL) == 0);
    174 
    175 #define ADD_TEST(mode, cipher, keysize, chunk)                          \
    176     if ((!alg || g_str_equal(alg, #mode)) &&                            \
    177         (!size || g_str_equal(size, #chunk)))                           \
    178         g_test_add_data_func(                                           \
    179         "/crypto/cipher/" #mode "-" #cipher "-" #keysize "/chunk-" #chunk, \
    180         (void *)chunk,                                                  \
    181         test_cipher_speed_ ## mode ## _ ## cipher ## _ ## keysize)
    182 
    183     if (argc >= 2) {
    184         alg = argv[1];
    185     }
    186     if (argc >= 3) {
    187         size = argv[2];
    188     }
    189 
    190 #define ADD_TESTS(chunk)                        \
    191     do {                                        \
    192         ADD_TEST(ecb, aes, 128, chunk);         \
    193         ADD_TEST(ecb, aes, 256, chunk);         \
    194         ADD_TEST(cbc, aes, 128, chunk);         \
    195         ADD_TEST(cbc, aes, 256, chunk);         \
    196         ADD_TEST(ctr, aes, 128, chunk);         \
    197         ADD_TEST(ctr, aes, 256, chunk);         \
    198         ADD_TEST(xts, aes, 128, chunk);         \
    199         ADD_TEST(xts, aes, 256, chunk);         \
    200     } while (0)
    201 
    202     ADD_TESTS(512);
    203     ADD_TESTS(4096);
    204     ADD_TESTS(16384);
    205     ADD_TESTS(65536);
    206 
    207     return g_test_run();
    208 }