qemu

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

cryptodev-builtin.c (19008B)


      1 /*
      2  * QEMU Cryptodev backend for QEMU cipher APIs
      3  *
      4  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
      5  *
      6  * Authors:
      7  *    Gonglei <arei.gonglei@huawei.com>
      8  *
      9  * This library is free software; you can redistribute it and/or
     10  * modify it under the terms of the GNU Lesser General Public
     11  * License as published by the Free Software Foundation; either
     12  * version 2.1 of the License, or (at your option) any later version.
     13  *
     14  * This library is distributed in the hope that it will be useful,
     15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     17  * Lesser General Public License for more details.
     18  *
     19  * You should have received a copy of the GNU Lesser General Public
     20  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     21  *
     22  */
     23 
     24 #include "qemu/osdep.h"
     25 #include "sysemu/cryptodev.h"
     26 #include "qapi/error.h"
     27 #include "standard-headers/linux/virtio_crypto.h"
     28 #include "crypto/cipher.h"
     29 #include "crypto/akcipher.h"
     30 #include "qom/object.h"
     31 
     32 
     33 /**
     34  * @TYPE_CRYPTODEV_BACKEND_BUILTIN:
     35  * name of backend that uses QEMU cipher API
     36  */
     37 #define TYPE_CRYPTODEV_BACKEND_BUILTIN "cryptodev-backend-builtin"
     38 
     39 OBJECT_DECLARE_SIMPLE_TYPE(CryptoDevBackendBuiltin, CRYPTODEV_BACKEND_BUILTIN)
     40 
     41 
     42 typedef struct CryptoDevBackendBuiltinSession {
     43     QCryptoCipher *cipher;
     44     uint8_t direction; /* encryption or decryption */
     45     uint8_t type; /* cipher? hash? aead? */
     46     QCryptoAkCipher *akcipher;
     47     QTAILQ_ENTRY(CryptoDevBackendBuiltinSession) next;
     48 } CryptoDevBackendBuiltinSession;
     49 
     50 /* Max number of symmetric/asymmetric sessions */
     51 #define MAX_NUM_SESSIONS 256
     52 
     53 #define CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN    512
     54 #define CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN  64
     55 
     56 struct CryptoDevBackendBuiltin {
     57     CryptoDevBackend parent_obj;
     58 
     59     CryptoDevBackendBuiltinSession *sessions[MAX_NUM_SESSIONS];
     60 };
     61 
     62 static void cryptodev_builtin_init(
     63              CryptoDevBackend *backend, Error **errp)
     64 {
     65     /* Only support one queue */
     66     int queues = backend->conf.peers.queues;
     67     CryptoDevBackendClient *cc;
     68 
     69     if (queues != 1) {
     70         error_setg(errp,
     71                   "Only support one queue in cryptdov-builtin backend");
     72         return;
     73     }
     74 
     75     cc = cryptodev_backend_new_client(
     76               "cryptodev-builtin", NULL);
     77     cc->info_str = g_strdup_printf("cryptodev-builtin0");
     78     cc->queue_index = 0;
     79     cc->type = CRYPTODEV_BACKEND_TYPE_BUILTIN;
     80     backend->conf.peers.ccs[0] = cc;
     81 
     82     backend->conf.crypto_services =
     83                          1u << VIRTIO_CRYPTO_SERVICE_CIPHER |
     84                          1u << VIRTIO_CRYPTO_SERVICE_HASH |
     85                          1u << VIRTIO_CRYPTO_SERVICE_MAC |
     86                          1u << VIRTIO_CRYPTO_SERVICE_AKCIPHER;
     87     backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
     88     backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
     89     backend->conf.akcipher_algo = 1u << VIRTIO_CRYPTO_AKCIPHER_RSA;
     90     /*
     91      * Set the Maximum length of crypto request.
     92      * Why this value? Just avoid to overflow when
     93      * memory allocation for each crypto request.
     94      */
     95     backend->conf.max_size = LONG_MAX - sizeof(CryptoDevBackendOpInfo);
     96     backend->conf.max_cipher_key_len = CRYPTODEV_BUITLIN_MAX_CIPHER_KEY_LEN;
     97     backend->conf.max_auth_key_len = CRYPTODEV_BUITLIN_MAX_AUTH_KEY_LEN;
     98 
     99     cryptodev_backend_set_ready(backend, true);
    100 }
    101 
    102 static int
    103 cryptodev_builtin_get_unused_session_index(
    104                  CryptoDevBackendBuiltin *builtin)
    105 {
    106     size_t i;
    107 
    108     for (i = 0; i < MAX_NUM_SESSIONS; i++) {
    109         if (builtin->sessions[i] == NULL) {
    110             return i;
    111         }
    112     }
    113 
    114     return -1;
    115 }
    116 
    117 #define AES_KEYSIZE_128 16
    118 #define AES_KEYSIZE_192 24
    119 #define AES_KEYSIZE_256 32
    120 #define AES_KEYSIZE_128_XTS AES_KEYSIZE_256
    121 #define AES_KEYSIZE_256_XTS 64
    122 
    123 static int
    124 cryptodev_builtin_get_aes_algo(uint32_t key_len, int mode, Error **errp)
    125 {
    126     int algo;
    127 
    128     if (key_len == AES_KEYSIZE_128) {
    129         algo = QCRYPTO_CIPHER_ALG_AES_128;
    130     } else if (key_len == AES_KEYSIZE_192) {
    131         algo = QCRYPTO_CIPHER_ALG_AES_192;
    132     } else if (key_len == AES_KEYSIZE_256) { /* equals AES_KEYSIZE_128_XTS */
    133         if (mode == QCRYPTO_CIPHER_MODE_XTS) {
    134             algo = QCRYPTO_CIPHER_ALG_AES_128;
    135         } else {
    136             algo = QCRYPTO_CIPHER_ALG_AES_256;
    137         }
    138     } else if (key_len == AES_KEYSIZE_256_XTS) {
    139         if (mode == QCRYPTO_CIPHER_MODE_XTS) {
    140             algo = QCRYPTO_CIPHER_ALG_AES_256;
    141         } else {
    142             goto err;
    143         }
    144     } else {
    145         goto err;
    146     }
    147 
    148     return algo;
    149 
    150 err:
    151    error_setg(errp, "Unsupported key length :%u", key_len);
    152    return -1;
    153 }
    154 
    155 static int cryptodev_builtin_get_rsa_hash_algo(
    156     int virtio_rsa_hash, Error **errp)
    157 {
    158     switch (virtio_rsa_hash) {
    159     case VIRTIO_CRYPTO_RSA_MD5:
    160         return QCRYPTO_HASH_ALG_MD5;
    161 
    162     case VIRTIO_CRYPTO_RSA_SHA1:
    163         return QCRYPTO_HASH_ALG_SHA1;
    164 
    165     case VIRTIO_CRYPTO_RSA_SHA256:
    166         return QCRYPTO_HASH_ALG_SHA256;
    167 
    168     case VIRTIO_CRYPTO_RSA_SHA512:
    169         return QCRYPTO_HASH_ALG_SHA512;
    170 
    171     default:
    172         error_setg(errp, "Unsupported rsa hash algo: %d", virtio_rsa_hash);
    173         return -1;
    174     }
    175 }
    176 
    177 static int cryptodev_builtin_set_rsa_options(
    178                     int virtio_padding_algo,
    179                     int virtio_hash_algo,
    180                     QCryptoAkCipherOptionsRSA *opt,
    181                     Error **errp)
    182 {
    183     if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_PKCS1_PADDING) {
    184         int hash_alg;
    185 
    186         hash_alg = cryptodev_builtin_get_rsa_hash_algo(virtio_hash_algo, errp);
    187         if (hash_alg < 0) {
    188             return -1;
    189         }
    190         opt->hash_alg = hash_alg;
    191         opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_PKCS1;
    192         return 0;
    193     }
    194 
    195     if (virtio_padding_algo == VIRTIO_CRYPTO_RSA_RAW_PADDING) {
    196         opt->padding_alg = QCRYPTO_RSA_PADDING_ALG_RAW;
    197         return 0;
    198     }
    199 
    200     error_setg(errp, "Unsupported rsa padding algo: %d", virtio_padding_algo);
    201     return -1;
    202 }
    203 
    204 static int cryptodev_builtin_create_cipher_session(
    205                     CryptoDevBackendBuiltin *builtin,
    206                     CryptoDevBackendSymSessionInfo *sess_info,
    207                     Error **errp)
    208 {
    209     int algo;
    210     int mode;
    211     QCryptoCipher *cipher;
    212     int index;
    213     CryptoDevBackendBuiltinSession *sess;
    214 
    215     if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
    216         error_setg(errp, "Unsupported optype :%u", sess_info->op_type);
    217         return -1;
    218     }
    219 
    220     index = cryptodev_builtin_get_unused_session_index(builtin);
    221     if (index < 0) {
    222         error_setg(errp, "Total number of sessions created exceeds %u",
    223                   MAX_NUM_SESSIONS);
    224         return -1;
    225     }
    226 
    227     switch (sess_info->cipher_alg) {
    228     case VIRTIO_CRYPTO_CIPHER_AES_ECB:
    229         mode = QCRYPTO_CIPHER_MODE_ECB;
    230         algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
    231                                                     mode, errp);
    232         if (algo < 0)  {
    233             return -1;
    234         }
    235         break;
    236     case VIRTIO_CRYPTO_CIPHER_AES_CBC:
    237         mode = QCRYPTO_CIPHER_MODE_CBC;
    238         algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
    239                                                     mode, errp);
    240         if (algo < 0)  {
    241             return -1;
    242         }
    243         break;
    244     case VIRTIO_CRYPTO_CIPHER_AES_CTR:
    245         mode = QCRYPTO_CIPHER_MODE_CTR;
    246         algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
    247                                                     mode, errp);
    248         if (algo < 0)  {
    249             return -1;
    250         }
    251         break;
    252     case VIRTIO_CRYPTO_CIPHER_AES_XTS:
    253         mode = QCRYPTO_CIPHER_MODE_XTS;
    254         algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
    255                                                     mode, errp);
    256         if (algo < 0)  {
    257             return -1;
    258         }
    259         break;
    260     case VIRTIO_CRYPTO_CIPHER_3DES_ECB:
    261         mode = QCRYPTO_CIPHER_MODE_ECB;
    262         algo = QCRYPTO_CIPHER_ALG_3DES;
    263         break;
    264     case VIRTIO_CRYPTO_CIPHER_3DES_CBC:
    265         mode = QCRYPTO_CIPHER_MODE_CBC;
    266         algo = QCRYPTO_CIPHER_ALG_3DES;
    267         break;
    268     case VIRTIO_CRYPTO_CIPHER_3DES_CTR:
    269         mode = QCRYPTO_CIPHER_MODE_CTR;
    270         algo = QCRYPTO_CIPHER_ALG_3DES;
    271         break;
    272     default:
    273         error_setg(errp, "Unsupported cipher alg :%u",
    274                    sess_info->cipher_alg);
    275         return -1;
    276     }
    277 
    278     cipher = qcrypto_cipher_new(algo, mode,
    279                                sess_info->cipher_key,
    280                                sess_info->key_len,
    281                                errp);
    282     if (!cipher) {
    283         return -1;
    284     }
    285 
    286     sess = g_new0(CryptoDevBackendBuiltinSession, 1);
    287     sess->cipher = cipher;
    288     sess->direction = sess_info->direction;
    289     sess->type = sess_info->op_type;
    290 
    291     builtin->sessions[index] = sess;
    292 
    293     return index;
    294 }
    295 
    296 static int cryptodev_builtin_create_akcipher_session(
    297                     CryptoDevBackendBuiltin *builtin,
    298                     CryptoDevBackendAsymSessionInfo *sess_info,
    299                     Error **errp)
    300 {
    301     CryptoDevBackendBuiltinSession *sess;
    302     QCryptoAkCipher *akcipher;
    303     int index;
    304     QCryptoAkCipherKeyType type;
    305     QCryptoAkCipherOptions opts;
    306 
    307     switch (sess_info->algo) {
    308     case VIRTIO_CRYPTO_AKCIPHER_RSA:
    309         opts.alg = QCRYPTO_AKCIPHER_ALG_RSA;
    310         if (cryptodev_builtin_set_rsa_options(sess_info->u.rsa.padding_algo,
    311             sess_info->u.rsa.hash_algo, &opts.u.rsa, errp) != 0) {
    312             return -1;
    313         }
    314         break;
    315 
    316     /* TODO support DSA&ECDSA until qemu crypto framework support these */
    317 
    318     default:
    319         error_setg(errp, "Unsupported akcipher alg %u", sess_info->algo);
    320         return -1;
    321     }
    322 
    323     switch (sess_info->keytype) {
    324     case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC:
    325         type = QCRYPTO_AKCIPHER_KEY_TYPE_PUBLIC;
    326         break;
    327 
    328     case VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE:
    329         type = QCRYPTO_AKCIPHER_KEY_TYPE_PRIVATE;
    330         break;
    331 
    332     default:
    333         error_setg(errp, "Unsupported akcipher keytype %u", sess_info->keytype);
    334         return -1;
    335     }
    336 
    337     index = cryptodev_builtin_get_unused_session_index(builtin);
    338     if (index < 0) {
    339         error_setg(errp, "Total number of sessions created exceeds %u",
    340                    MAX_NUM_SESSIONS);
    341         return -1;
    342     }
    343 
    344     akcipher = qcrypto_akcipher_new(&opts, type, sess_info->key,
    345                                     sess_info->keylen, errp);
    346     if (!akcipher) {
    347         return -1;
    348     }
    349 
    350     sess = g_new0(CryptoDevBackendBuiltinSession, 1);
    351     sess->akcipher = akcipher;
    352 
    353     builtin->sessions[index] = sess;
    354 
    355     return index;
    356 }
    357 
    358 static int cryptodev_builtin_create_session(
    359            CryptoDevBackend *backend,
    360            CryptoDevBackendSessionInfo *sess_info,
    361            uint32_t queue_index,
    362            CryptoDevCompletionFunc cb,
    363            void *opaque)
    364 {
    365     CryptoDevBackendBuiltin *builtin =
    366                       CRYPTODEV_BACKEND_BUILTIN(backend);
    367     CryptoDevBackendSymSessionInfo *sym_sess_info;
    368     CryptoDevBackendAsymSessionInfo *asym_sess_info;
    369     int ret, status;
    370     Error *local_error = NULL;
    371 
    372     switch (sess_info->op_code) {
    373     case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
    374         sym_sess_info = &sess_info->u.sym_sess_info;
    375         ret = cryptodev_builtin_create_cipher_session(
    376                     builtin, sym_sess_info, &local_error);
    377         break;
    378 
    379     case VIRTIO_CRYPTO_AKCIPHER_CREATE_SESSION:
    380         asym_sess_info = &sess_info->u.asym_sess_info;
    381         ret = cryptodev_builtin_create_akcipher_session(
    382                            builtin, asym_sess_info, &local_error);
    383         break;
    384 
    385     case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
    386     case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
    387     default:
    388         error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
    389                    sess_info->op_code);
    390         return -VIRTIO_CRYPTO_NOTSUPP;
    391     }
    392 
    393     if (local_error) {
    394         error_report_err(local_error);
    395     }
    396     if (ret < 0) {
    397         status = -VIRTIO_CRYPTO_ERR;
    398     } else {
    399         sess_info->session_id = ret;
    400         status = VIRTIO_CRYPTO_OK;
    401     }
    402     if (cb) {
    403         cb(opaque, status);
    404     }
    405     return 0;
    406 }
    407 
    408 static int cryptodev_builtin_close_session(
    409            CryptoDevBackend *backend,
    410            uint64_t session_id,
    411            uint32_t queue_index,
    412            CryptoDevCompletionFunc cb,
    413            void *opaque)
    414 {
    415     CryptoDevBackendBuiltin *builtin =
    416                       CRYPTODEV_BACKEND_BUILTIN(backend);
    417     CryptoDevBackendBuiltinSession *session;
    418 
    419     assert(session_id < MAX_NUM_SESSIONS && builtin->sessions[session_id]);
    420 
    421     session = builtin->sessions[session_id];
    422     if (session->cipher) {
    423         qcrypto_cipher_free(session->cipher);
    424     } else if (session->akcipher) {
    425         qcrypto_akcipher_free(session->akcipher);
    426     }
    427 
    428     g_free(session);
    429     builtin->sessions[session_id] = NULL;
    430     if (cb) {
    431         cb(opaque, VIRTIO_CRYPTO_OK);
    432     }
    433     return 0;
    434 }
    435 
    436 static int cryptodev_builtin_sym_operation(
    437                  CryptoDevBackendBuiltinSession *sess,
    438                  CryptoDevBackendSymOpInfo *op_info, Error **errp)
    439 {
    440     int ret;
    441 
    442     if (op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
    443         error_setg(errp,
    444                "Algorithm chain is unsupported for cryptdoev-builtin");
    445         return -VIRTIO_CRYPTO_NOTSUPP;
    446     }
    447 
    448     if (op_info->iv_len > 0) {
    449         ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
    450                                    op_info->iv_len, errp);
    451         if (ret < 0) {
    452             return -VIRTIO_CRYPTO_ERR;
    453         }
    454     }
    455 
    456     if (sess->direction == VIRTIO_CRYPTO_OP_ENCRYPT) {
    457         ret = qcrypto_cipher_encrypt(sess->cipher, op_info->src,
    458                                      op_info->dst, op_info->src_len, errp);
    459         if (ret < 0) {
    460             return -VIRTIO_CRYPTO_ERR;
    461         }
    462     } else {
    463         ret = qcrypto_cipher_decrypt(sess->cipher, op_info->src,
    464                                      op_info->dst, op_info->src_len, errp);
    465         if (ret < 0) {
    466             return -VIRTIO_CRYPTO_ERR;
    467         }
    468     }
    469 
    470     return VIRTIO_CRYPTO_OK;
    471 }
    472 
    473 static int cryptodev_builtin_asym_operation(
    474                  CryptoDevBackendBuiltinSession *sess, uint32_t op_code,
    475                  CryptoDevBackendAsymOpInfo *op_info, Error **errp)
    476 {
    477     int ret;
    478 
    479     switch (op_code) {
    480     case VIRTIO_CRYPTO_AKCIPHER_ENCRYPT:
    481         ret = qcrypto_akcipher_encrypt(sess->akcipher,
    482                                        op_info->src, op_info->src_len,
    483                                        op_info->dst, op_info->dst_len, errp);
    484         break;
    485 
    486     case VIRTIO_CRYPTO_AKCIPHER_DECRYPT:
    487         ret = qcrypto_akcipher_decrypt(sess->akcipher,
    488                                        op_info->src, op_info->src_len,
    489                                        op_info->dst, op_info->dst_len, errp);
    490         break;
    491 
    492     case VIRTIO_CRYPTO_AKCIPHER_SIGN:
    493         ret = qcrypto_akcipher_sign(sess->akcipher,
    494                                     op_info->src, op_info->src_len,
    495                                     op_info->dst, op_info->dst_len, errp);
    496         break;
    497 
    498     case VIRTIO_CRYPTO_AKCIPHER_VERIFY:
    499         ret = qcrypto_akcipher_verify(sess->akcipher,
    500                                       op_info->src, op_info->src_len,
    501                                       op_info->dst, op_info->dst_len, errp);
    502         break;
    503 
    504     default:
    505         return -VIRTIO_CRYPTO_ERR;
    506     }
    507 
    508     if (ret < 0) {
    509         if (op_code == VIRTIO_CRYPTO_AKCIPHER_VERIFY) {
    510             return -VIRTIO_CRYPTO_KEY_REJECTED;
    511         }
    512         return -VIRTIO_CRYPTO_ERR;
    513     }
    514 
    515     /* Buffer is too short, typically the driver should handle this case */
    516     if (unlikely(ret > op_info->dst_len)) {
    517         if (errp && !*errp) {
    518             error_setg(errp, "dst buffer too short");
    519         }
    520 
    521         return -VIRTIO_CRYPTO_ERR;
    522     }
    523 
    524     op_info->dst_len = ret;
    525 
    526     return VIRTIO_CRYPTO_OK;
    527 }
    528 
    529 static int cryptodev_builtin_operation(
    530                  CryptoDevBackend *backend,
    531                  CryptoDevBackendOpInfo *op_info,
    532                  uint32_t queue_index,
    533                  CryptoDevCompletionFunc cb,
    534                  void *opaque)
    535 {
    536     CryptoDevBackendBuiltin *builtin =
    537                       CRYPTODEV_BACKEND_BUILTIN(backend);
    538     CryptoDevBackendBuiltinSession *sess;
    539     CryptoDevBackendSymOpInfo *sym_op_info;
    540     CryptoDevBackendAsymOpInfo *asym_op_info;
    541     enum CryptoDevBackendAlgType algtype = op_info->algtype;
    542     int status = -VIRTIO_CRYPTO_ERR;
    543     Error *local_error = NULL;
    544 
    545     if (op_info->session_id >= MAX_NUM_SESSIONS ||
    546               builtin->sessions[op_info->session_id] == NULL) {
    547         error_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "",
    548                    op_info->session_id);
    549         return -VIRTIO_CRYPTO_INVSESS;
    550     }
    551 
    552     sess = builtin->sessions[op_info->session_id];
    553     if (algtype == CRYPTODEV_BACKEND_ALG_SYM) {
    554         sym_op_info = op_info->u.sym_op_info;
    555         status = cryptodev_builtin_sym_operation(sess, sym_op_info,
    556                                                  &local_error);
    557     } else if (algtype == CRYPTODEV_BACKEND_ALG_ASYM) {
    558         asym_op_info = op_info->u.asym_op_info;
    559         status = cryptodev_builtin_asym_operation(sess, op_info->op_code,
    560                                                   asym_op_info, &local_error);
    561     }
    562 
    563     if (local_error) {
    564         error_report_err(local_error);
    565     }
    566     if (cb) {
    567         cb(opaque, status);
    568     }
    569     return 0;
    570 }
    571 
    572 static void cryptodev_builtin_cleanup(
    573              CryptoDevBackend *backend,
    574              Error **errp)
    575 {
    576     CryptoDevBackendBuiltin *builtin =
    577                       CRYPTODEV_BACKEND_BUILTIN(backend);
    578     size_t i;
    579     int queues = backend->conf.peers.queues;
    580     CryptoDevBackendClient *cc;
    581 
    582     for (i = 0; i < MAX_NUM_SESSIONS; i++) {
    583         if (builtin->sessions[i] != NULL) {
    584             cryptodev_builtin_close_session(backend, i, 0, NULL, NULL);
    585         }
    586     }
    587 
    588     for (i = 0; i < queues; i++) {
    589         cc = backend->conf.peers.ccs[i];
    590         if (cc) {
    591             cryptodev_backend_free_client(cc);
    592             backend->conf.peers.ccs[i] = NULL;
    593         }
    594     }
    595 
    596     cryptodev_backend_set_ready(backend, false);
    597 }
    598 
    599 static void
    600 cryptodev_builtin_class_init(ObjectClass *oc, void *data)
    601 {
    602     CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_CLASS(oc);
    603 
    604     bc->init = cryptodev_builtin_init;
    605     bc->cleanup = cryptodev_builtin_cleanup;
    606     bc->create_session = cryptodev_builtin_create_session;
    607     bc->close_session = cryptodev_builtin_close_session;
    608     bc->do_op = cryptodev_builtin_operation;
    609 }
    610 
    611 static const TypeInfo cryptodev_builtin_info = {
    612     .name = TYPE_CRYPTODEV_BACKEND_BUILTIN,
    613     .parent = TYPE_CRYPTODEV_BACKEND,
    614     .class_init = cryptodev_builtin_class_init,
    615     .instance_size = sizeof(CryptoDevBackendBuiltin),
    616 };
    617 
    618 static void
    619 cryptodev_builtin_register_types(void)
    620 {
    621     type_register_static(&cryptodev_builtin_info);
    622 }
    623 
    624 type_init(cryptodev_builtin_register_types);