2
0

cryptodev-builtin.c 19 KB

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