cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
     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_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
    103static 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
    111static 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
    119static 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
    127static 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
    135static 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
    143static 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
    151static 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
    159static 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
    168int 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}