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