psa_crypto_cipher.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. /*
  2. * PSA cipher driver entry points
  3. */
  4. /*
  5. * Copyright The Mbed TLS Contributors
  6. * SPDX-License-Identifier: Apache-2.0
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  9. * not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  16. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #include "common.h"
  21. #if defined(MBEDTLS_PSA_CRYPTO_C)
  22. #include "psa_crypto_cipher.h"
  23. #include "psa_crypto_core.h"
  24. #include "psa_crypto_random_impl.h"
  25. #include "mbedtls/cipher.h"
  26. #include "mbedtls/error.h"
  27. #include <string.h>
  28. const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
  29. psa_algorithm_t alg,
  30. psa_key_type_t key_type,
  31. size_t key_bits,
  32. mbedtls_cipher_id_t *cipher_id)
  33. {
  34. mbedtls_cipher_mode_t mode;
  35. mbedtls_cipher_id_t cipher_id_tmp;
  36. if (PSA_ALG_IS_AEAD(alg)) {
  37. alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
  38. }
  39. if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
  40. switch (alg) {
  41. #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
  42. case PSA_ALG_STREAM_CIPHER:
  43. mode = MBEDTLS_MODE_STREAM;
  44. break;
  45. #endif
  46. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
  47. case PSA_ALG_CTR:
  48. mode = MBEDTLS_MODE_CTR;
  49. break;
  50. #endif
  51. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
  52. case PSA_ALG_CFB:
  53. mode = MBEDTLS_MODE_CFB;
  54. break;
  55. #endif
  56. #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
  57. case PSA_ALG_OFB:
  58. mode = MBEDTLS_MODE_OFB;
  59. break;
  60. #endif
  61. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  62. case PSA_ALG_ECB_NO_PADDING:
  63. mode = MBEDTLS_MODE_ECB;
  64. break;
  65. #endif
  66. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
  67. case PSA_ALG_CBC_NO_PADDING:
  68. mode = MBEDTLS_MODE_CBC;
  69. break;
  70. #endif
  71. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
  72. case PSA_ALG_CBC_PKCS7:
  73. mode = MBEDTLS_MODE_CBC;
  74. break;
  75. #endif
  76. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
  77. case PSA_ALG_CCM_STAR_NO_TAG:
  78. mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
  79. break;
  80. #endif
  81. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  82. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
  83. mode = MBEDTLS_MODE_CCM;
  84. break;
  85. #endif
  86. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  87. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
  88. mode = MBEDTLS_MODE_GCM;
  89. break;
  90. #endif
  91. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  92. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
  93. mode = MBEDTLS_MODE_CHACHAPOLY;
  94. break;
  95. #endif
  96. default:
  97. return NULL;
  98. }
  99. } else if (alg == PSA_ALG_CMAC) {
  100. mode = MBEDTLS_MODE_ECB;
  101. } else {
  102. return NULL;
  103. }
  104. switch (key_type) {
  105. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
  106. case PSA_KEY_TYPE_AES:
  107. cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
  108. break;
  109. #endif
  110. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
  111. case PSA_KEY_TYPE_ARIA:
  112. cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
  113. break;
  114. #endif
  115. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
  116. case PSA_KEY_TYPE_DES:
  117. /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
  118. * and 192 for three-key Triple-DES. */
  119. if (key_bits == 64) {
  120. cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
  121. } else {
  122. cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
  123. }
  124. /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
  125. * but two-key Triple-DES is functionally three-key Triple-DES
  126. * with K1=K3, so that's how we present it to mbedtls. */
  127. if (key_bits == 128) {
  128. key_bits = 192;
  129. }
  130. break;
  131. #endif
  132. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
  133. case PSA_KEY_TYPE_CAMELLIA:
  134. cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
  135. break;
  136. #endif
  137. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
  138. case PSA_KEY_TYPE_CHACHA20:
  139. cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
  140. break;
  141. #endif
  142. default:
  143. return NULL;
  144. }
  145. if (cipher_id != NULL) {
  146. *cipher_id = cipher_id_tmp;
  147. }
  148. return mbedtls_cipher_info_from_values(cipher_id_tmp,
  149. (int) key_bits, mode);
  150. }
  151. #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
  152. static psa_status_t psa_cipher_setup(
  153. mbedtls_psa_cipher_operation_t *operation,
  154. const psa_key_attributes_t *attributes,
  155. const uint8_t *key_buffer, size_t key_buffer_size,
  156. psa_algorithm_t alg,
  157. mbedtls_operation_t cipher_operation)
  158. {
  159. int ret = 0;
  160. size_t key_bits;
  161. const mbedtls_cipher_info_t *cipher_info = NULL;
  162. psa_key_type_t key_type = attributes->core.type;
  163. (void) key_buffer_size;
  164. mbedtls_cipher_init(&operation->ctx.cipher);
  165. operation->alg = alg;
  166. key_bits = attributes->core.bits;
  167. cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
  168. key_bits, NULL);
  169. if (cipher_info == NULL) {
  170. return PSA_ERROR_NOT_SUPPORTED;
  171. }
  172. ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
  173. if (ret != 0) {
  174. goto exit;
  175. }
  176. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
  177. if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
  178. /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
  179. uint8_t keys[24];
  180. memcpy(keys, key_buffer, 16);
  181. memcpy(keys + 16, key_buffer, 8);
  182. ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
  183. keys,
  184. 192, cipher_operation);
  185. } else
  186. #endif
  187. {
  188. ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
  189. (int) key_bits, cipher_operation);
  190. }
  191. if (ret != 0) {
  192. goto exit;
  193. }
  194. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
  195. defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
  196. switch (alg) {
  197. case PSA_ALG_CBC_NO_PADDING:
  198. ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
  199. MBEDTLS_PADDING_NONE);
  200. break;
  201. case PSA_ALG_CBC_PKCS7:
  202. ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
  203. MBEDTLS_PADDING_PKCS7);
  204. break;
  205. default:
  206. /* The algorithm doesn't involve padding. */
  207. ret = 0;
  208. break;
  209. }
  210. if (ret != 0) {
  211. goto exit;
  212. }
  213. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
  214. MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
  215. operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
  216. PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
  217. operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
  218. exit:
  219. return mbedtls_to_psa_error(ret);
  220. }
  221. psa_status_t mbedtls_psa_cipher_encrypt_setup(
  222. mbedtls_psa_cipher_operation_t *operation,
  223. const psa_key_attributes_t *attributes,
  224. const uint8_t *key_buffer, size_t key_buffer_size,
  225. psa_algorithm_t alg)
  226. {
  227. return psa_cipher_setup(operation, attributes,
  228. key_buffer, key_buffer_size,
  229. alg, MBEDTLS_ENCRYPT);
  230. }
  231. psa_status_t mbedtls_psa_cipher_decrypt_setup(
  232. mbedtls_psa_cipher_operation_t *operation,
  233. const psa_key_attributes_t *attributes,
  234. const uint8_t *key_buffer, size_t key_buffer_size,
  235. psa_algorithm_t alg)
  236. {
  237. return psa_cipher_setup(operation, attributes,
  238. key_buffer, key_buffer_size,
  239. alg, MBEDTLS_DECRYPT);
  240. }
  241. psa_status_t mbedtls_psa_cipher_set_iv(
  242. mbedtls_psa_cipher_operation_t *operation,
  243. const uint8_t *iv, size_t iv_length)
  244. {
  245. if (iv_length != operation->iv_length) {
  246. return PSA_ERROR_INVALID_ARGUMENT;
  247. }
  248. return mbedtls_to_psa_error(
  249. mbedtls_cipher_set_iv(&operation->ctx.cipher,
  250. iv, iv_length));
  251. }
  252. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  253. /** Process input for which the algorithm is set to ECB mode.
  254. *
  255. * This requires manual processing, since the PSA API is defined as being
  256. * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
  257. * but the underlying mbedtls_cipher_update only takes full blocks.
  258. *
  259. * \param ctx The mbedtls cipher context to use. It must have been
  260. * set up for ECB.
  261. * \param[in] input The input plaintext or ciphertext to process.
  262. * \param input_length The number of bytes to process from \p input.
  263. * This does not need to be aligned to a block boundary.
  264. * If there is a partial block at the end of the input,
  265. * it is stored in \p ctx for future processing.
  266. * \param output The buffer where the output is written. It must be
  267. * at least `BS * floor((p + input_length) / BS)` bytes
  268. * long, where `p` is the number of bytes in the
  269. * unprocessed partial block in \p ctx (with
  270. * `0 <= p <= BS - 1`) and `BS` is the block size.
  271. * \param output_length On success, the number of bytes written to \p output.
  272. * \c 0 on error.
  273. *
  274. * \return #PSA_SUCCESS or an error from a hardware accelerator
  275. */
  276. static psa_status_t psa_cipher_update_ecb(
  277. mbedtls_cipher_context_t *ctx,
  278. const uint8_t *input,
  279. size_t input_length,
  280. uint8_t *output,
  281. size_t *output_length)
  282. {
  283. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  284. size_t block_size = ctx->cipher_info->block_size;
  285. size_t internal_output_length = 0;
  286. *output_length = 0;
  287. if (input_length == 0) {
  288. status = PSA_SUCCESS;
  289. goto exit;
  290. }
  291. if (ctx->unprocessed_len > 0) {
  292. /* Fill up to block size, and run the block if there's a full one. */
  293. size_t bytes_to_copy = block_size - ctx->unprocessed_len;
  294. if (input_length < bytes_to_copy) {
  295. bytes_to_copy = input_length;
  296. }
  297. memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
  298. input, bytes_to_copy);
  299. input_length -= bytes_to_copy;
  300. input += bytes_to_copy;
  301. ctx->unprocessed_len += bytes_to_copy;
  302. if (ctx->unprocessed_len == block_size) {
  303. status = mbedtls_to_psa_error(
  304. mbedtls_cipher_update(ctx,
  305. ctx->unprocessed_data,
  306. block_size,
  307. output, &internal_output_length));
  308. if (status != PSA_SUCCESS) {
  309. goto exit;
  310. }
  311. output += internal_output_length;
  312. *output_length += internal_output_length;
  313. ctx->unprocessed_len = 0;
  314. }
  315. }
  316. while (input_length >= block_size) {
  317. /* Run all full blocks we have, one by one */
  318. status = mbedtls_to_psa_error(
  319. mbedtls_cipher_update(ctx, input,
  320. block_size,
  321. output, &internal_output_length));
  322. if (status != PSA_SUCCESS) {
  323. goto exit;
  324. }
  325. input_length -= block_size;
  326. input += block_size;
  327. output += internal_output_length;
  328. *output_length += internal_output_length;
  329. }
  330. if (input_length > 0) {
  331. /* Save unprocessed bytes for later processing */
  332. memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
  333. input, input_length);
  334. ctx->unprocessed_len += input_length;
  335. }
  336. status = PSA_SUCCESS;
  337. exit:
  338. return status;
  339. }
  340. #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
  341. psa_status_t mbedtls_psa_cipher_update(
  342. mbedtls_psa_cipher_operation_t *operation,
  343. const uint8_t *input, size_t input_length,
  344. uint8_t *output, size_t output_size, size_t *output_length)
  345. {
  346. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  347. size_t expected_output_size;
  348. if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
  349. /* Take the unprocessed partial block left over from previous
  350. * update calls, if any, plus the input to this call. Remove
  351. * the last partial block, if any. You get the data that will be
  352. * output in this call. */
  353. expected_output_size =
  354. (operation->ctx.cipher.unprocessed_len + input_length)
  355. / operation->block_length * operation->block_length;
  356. } else {
  357. expected_output_size = input_length;
  358. }
  359. if (output_size < expected_output_size) {
  360. return PSA_ERROR_BUFFER_TOO_SMALL;
  361. }
  362. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  363. if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
  364. /* mbedtls_cipher_update has an API inconsistency: it will only
  365. * process a single block at a time in ECB mode. Abstract away that
  366. * inconsistency here to match the PSA API behaviour. */
  367. status = psa_cipher_update_ecb(&operation->ctx.cipher,
  368. input,
  369. input_length,
  370. output,
  371. output_length);
  372. } else
  373. #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
  374. {
  375. status = mbedtls_to_psa_error(
  376. mbedtls_cipher_update(&operation->ctx.cipher, input,
  377. input_length, output, output_length));
  378. if (*output_length > output_size) {
  379. return PSA_ERROR_CORRUPTION_DETECTED;
  380. }
  381. }
  382. return status;
  383. }
  384. psa_status_t mbedtls_psa_cipher_finish(
  385. mbedtls_psa_cipher_operation_t *operation,
  386. uint8_t *output, size_t output_size, size_t *output_length)
  387. {
  388. psa_status_t status = PSA_ERROR_GENERIC_ERROR;
  389. uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
  390. if (operation->ctx.cipher.unprocessed_len != 0) {
  391. if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
  392. operation->alg == PSA_ALG_CBC_NO_PADDING) {
  393. status = PSA_ERROR_INVALID_ARGUMENT;
  394. goto exit;
  395. }
  396. }
  397. status = mbedtls_to_psa_error(
  398. mbedtls_cipher_finish(&operation->ctx.cipher,
  399. temp_output_buffer,
  400. output_length));
  401. if (status != PSA_SUCCESS) {
  402. goto exit;
  403. }
  404. if (*output_length == 0) {
  405. ; /* Nothing to copy. Note that output may be NULL in this case. */
  406. } else if (output_size >= *output_length) {
  407. memcpy(output, temp_output_buffer, *output_length);
  408. } else {
  409. status = PSA_ERROR_BUFFER_TOO_SMALL;
  410. }
  411. exit:
  412. mbedtls_platform_zeroize(temp_output_buffer,
  413. sizeof(temp_output_buffer));
  414. return status;
  415. }
  416. psa_status_t mbedtls_psa_cipher_abort(
  417. mbedtls_psa_cipher_operation_t *operation)
  418. {
  419. /* Sanity check (shouldn't happen: operation->alg should
  420. * always have been initialized to a valid value). */
  421. if (!PSA_ALG_IS_CIPHER(operation->alg)) {
  422. return PSA_ERROR_BAD_STATE;
  423. }
  424. mbedtls_cipher_free(&operation->ctx.cipher);
  425. return PSA_SUCCESS;
  426. }
  427. psa_status_t mbedtls_psa_cipher_encrypt(
  428. const psa_key_attributes_t *attributes,
  429. const uint8_t *key_buffer,
  430. size_t key_buffer_size,
  431. psa_algorithm_t alg,
  432. const uint8_t *iv,
  433. size_t iv_length,
  434. const uint8_t *input,
  435. size_t input_length,
  436. uint8_t *output,
  437. size_t output_size,
  438. size_t *output_length)
  439. {
  440. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  441. mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
  442. size_t update_output_length, finish_output_length;
  443. status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
  444. key_buffer, key_buffer_size,
  445. alg);
  446. if (status != PSA_SUCCESS) {
  447. goto exit;
  448. }
  449. if (iv_length > 0) {
  450. status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
  451. if (status != PSA_SUCCESS) {
  452. goto exit;
  453. }
  454. }
  455. status = mbedtls_psa_cipher_update(&operation, input, input_length,
  456. output, output_size,
  457. &update_output_length);
  458. if (status != PSA_SUCCESS) {
  459. goto exit;
  460. }
  461. status = mbedtls_psa_cipher_finish(
  462. &operation,
  463. mbedtls_buffer_offset(output, update_output_length),
  464. output_size - update_output_length, &finish_output_length);
  465. if (status != PSA_SUCCESS) {
  466. goto exit;
  467. }
  468. *output_length = update_output_length + finish_output_length;
  469. exit:
  470. if (status == PSA_SUCCESS) {
  471. status = mbedtls_psa_cipher_abort(&operation);
  472. } else {
  473. mbedtls_psa_cipher_abort(&operation);
  474. }
  475. return status;
  476. }
  477. psa_status_t mbedtls_psa_cipher_decrypt(
  478. const psa_key_attributes_t *attributes,
  479. const uint8_t *key_buffer,
  480. size_t key_buffer_size,
  481. psa_algorithm_t alg,
  482. const uint8_t *input,
  483. size_t input_length,
  484. uint8_t *output,
  485. size_t output_size,
  486. size_t *output_length)
  487. {
  488. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  489. mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
  490. size_t olength, accumulated_length;
  491. status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
  492. key_buffer, key_buffer_size,
  493. alg);
  494. if (status != PSA_SUCCESS) {
  495. goto exit;
  496. }
  497. if (operation.iv_length > 0) {
  498. status = mbedtls_psa_cipher_set_iv(&operation,
  499. input, operation.iv_length);
  500. if (status != PSA_SUCCESS) {
  501. goto exit;
  502. }
  503. }
  504. status = mbedtls_psa_cipher_update(
  505. &operation,
  506. mbedtls_buffer_offset_const(input, operation.iv_length),
  507. input_length - operation.iv_length,
  508. output, output_size, &olength);
  509. if (status != PSA_SUCCESS) {
  510. goto exit;
  511. }
  512. accumulated_length = olength;
  513. status = mbedtls_psa_cipher_finish(
  514. &operation,
  515. mbedtls_buffer_offset(output, accumulated_length),
  516. output_size - accumulated_length, &olength);
  517. if (status != PSA_SUCCESS) {
  518. goto exit;
  519. }
  520. *output_length = accumulated_length + olength;
  521. exit:
  522. if (status == PSA_SUCCESS) {
  523. status = mbedtls_psa_cipher_abort(&operation);
  524. } else {
  525. mbedtls_psa_cipher_abort(&operation);
  526. }
  527. return status;
  528. }
  529. #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
  530. #endif /* MBEDTLS_PSA_CRYPTO_C */