psa_crypto_cipher.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. /*
  2. * PSA cipher driver entry points
  3. */
  4. /*
  5. * Copyright The Mbed TLS Contributors
  6. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  7. */
  8. #include "common.h"
  9. #if defined(MBEDTLS_PSA_CRYPTO_C)
  10. #include "psa_crypto_cipher.h"
  11. #include "psa_crypto_core.h"
  12. #include "psa_crypto_random_impl.h"
  13. #include "mbedtls/cipher.h"
  14. #include "mbedtls/error.h"
  15. #include <string.h>
  16. /* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
  17. * are enabled, but it does not provide any compatibility check between them
  18. * (i.e. if the specified key works with the specified algorithm). This helper
  19. * function is meant to provide this support.
  20. * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
  21. * requires CIPHER_C to be enabled.
  22. */
  23. static psa_status_t mbedtls_cipher_validate_values(
  24. psa_algorithm_t alg,
  25. psa_key_type_t key_type)
  26. {
  27. /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
  28. eliminate bits of the logic below. */
  29. #if !defined(PSA_WANT_KEY_TYPE_AES)
  30. MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
  31. #endif
  32. #if !defined(PSA_WANT_KEY_TYPE_ARIA)
  33. MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
  34. #endif
  35. #if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
  36. MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
  37. #endif
  38. #if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
  39. MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
  40. #endif
  41. #if !defined(PSA_WANT_KEY_TYPE_DES)
  42. MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
  43. #endif
  44. #if !defined(PSA_WANT_ALG_CCM)
  45. MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
  46. #endif
  47. #if !defined(PSA_WANT_ALG_GCM)
  48. MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
  49. #endif
  50. #if !defined(PSA_WANT_ALG_STREAM_CIPHER)
  51. MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
  52. #endif
  53. #if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
  54. MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
  55. #endif
  56. #if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
  57. MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
  58. #endif
  59. #if !defined(PSA_WANT_ALG_CTR)
  60. MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
  61. #endif
  62. #if !defined(PSA_WANT_ALG_CFB)
  63. MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
  64. #endif
  65. #if !defined(PSA_WANT_ALG_OFB)
  66. MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
  67. #endif
  68. #if !defined(PSA_WANT_ALG_XTS)
  69. MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
  70. #endif
  71. #if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
  72. MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
  73. #endif
  74. #if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
  75. MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
  76. #endif
  77. #if !defined(PSA_WANT_ALG_CBC_PKCS7)
  78. MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
  79. #endif
  80. #if !defined(PSA_WANT_ALG_CMAC)
  81. MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
  82. #endif
  83. if (alg == PSA_ALG_STREAM_CIPHER ||
  84. alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
  85. if (key_type == PSA_KEY_TYPE_CHACHA20) {
  86. return PSA_SUCCESS;
  87. }
  88. }
  89. if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
  90. alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
  91. alg == PSA_ALG_CCM_STAR_NO_TAG) {
  92. if (key_type == PSA_KEY_TYPE_AES ||
  93. key_type == PSA_KEY_TYPE_ARIA ||
  94. key_type == PSA_KEY_TYPE_CAMELLIA) {
  95. return PSA_SUCCESS;
  96. }
  97. }
  98. if (alg == PSA_ALG_CTR ||
  99. alg == PSA_ALG_CFB ||
  100. alg == PSA_ALG_OFB ||
  101. alg == PSA_ALG_XTS ||
  102. alg == PSA_ALG_ECB_NO_PADDING ||
  103. alg == PSA_ALG_CBC_NO_PADDING ||
  104. alg == PSA_ALG_CBC_PKCS7 ||
  105. alg == PSA_ALG_CMAC) {
  106. if (key_type == PSA_KEY_TYPE_AES ||
  107. key_type == PSA_KEY_TYPE_ARIA ||
  108. key_type == PSA_KEY_TYPE_DES ||
  109. key_type == PSA_KEY_TYPE_CAMELLIA) {
  110. return PSA_SUCCESS;
  111. }
  112. }
  113. return PSA_ERROR_NOT_SUPPORTED;
  114. }
  115. psa_status_t mbedtls_cipher_values_from_psa(
  116. psa_algorithm_t alg,
  117. psa_key_type_t key_type,
  118. size_t *key_bits,
  119. mbedtls_cipher_mode_t *mode,
  120. mbedtls_cipher_id_t *cipher_id)
  121. {
  122. mbedtls_cipher_id_t cipher_id_tmp;
  123. /* Only DES modifies key_bits */
  124. #if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
  125. (void) key_bits;
  126. #endif
  127. if (PSA_ALG_IS_AEAD(alg)) {
  128. alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
  129. }
  130. if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
  131. switch (alg) {
  132. #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
  133. case PSA_ALG_STREAM_CIPHER:
  134. *mode = MBEDTLS_MODE_STREAM;
  135. break;
  136. #endif
  137. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
  138. case PSA_ALG_CTR:
  139. *mode = MBEDTLS_MODE_CTR;
  140. break;
  141. #endif
  142. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
  143. case PSA_ALG_CFB:
  144. *mode = MBEDTLS_MODE_CFB;
  145. break;
  146. #endif
  147. #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
  148. case PSA_ALG_OFB:
  149. *mode = MBEDTLS_MODE_OFB;
  150. break;
  151. #endif
  152. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  153. case PSA_ALG_ECB_NO_PADDING:
  154. *mode = MBEDTLS_MODE_ECB;
  155. break;
  156. #endif
  157. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
  158. case PSA_ALG_CBC_NO_PADDING:
  159. *mode = MBEDTLS_MODE_CBC;
  160. break;
  161. #endif
  162. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
  163. case PSA_ALG_CBC_PKCS7:
  164. *mode = MBEDTLS_MODE_CBC;
  165. break;
  166. #endif
  167. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
  168. case PSA_ALG_CCM_STAR_NO_TAG:
  169. *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
  170. break;
  171. #endif
  172. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  173. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
  174. *mode = MBEDTLS_MODE_CCM;
  175. break;
  176. #endif
  177. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  178. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
  179. *mode = MBEDTLS_MODE_GCM;
  180. break;
  181. #endif
  182. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  183. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
  184. *mode = MBEDTLS_MODE_CHACHAPOLY;
  185. break;
  186. #endif
  187. default:
  188. return PSA_ERROR_NOT_SUPPORTED;
  189. }
  190. } else if (alg == PSA_ALG_CMAC) {
  191. *mode = MBEDTLS_MODE_ECB;
  192. } else {
  193. return PSA_ERROR_NOT_SUPPORTED;
  194. }
  195. switch (key_type) {
  196. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
  197. case PSA_KEY_TYPE_AES:
  198. cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
  199. break;
  200. #endif
  201. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
  202. case PSA_KEY_TYPE_ARIA:
  203. cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
  204. break;
  205. #endif
  206. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
  207. case PSA_KEY_TYPE_DES:
  208. /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
  209. * and 192 for three-key Triple-DES. */
  210. if (*key_bits == 64) {
  211. cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
  212. } else {
  213. cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
  214. }
  215. /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
  216. * but two-key Triple-DES is functionally three-key Triple-DES
  217. * with K1=K3, so that's how we present it to mbedtls. */
  218. if (*key_bits == 128) {
  219. *key_bits = 192;
  220. }
  221. break;
  222. #endif
  223. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
  224. case PSA_KEY_TYPE_CAMELLIA:
  225. cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
  226. break;
  227. #endif
  228. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
  229. case PSA_KEY_TYPE_CHACHA20:
  230. cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
  231. break;
  232. #endif
  233. default:
  234. return PSA_ERROR_NOT_SUPPORTED;
  235. }
  236. if (cipher_id != NULL) {
  237. *cipher_id = cipher_id_tmp;
  238. }
  239. return mbedtls_cipher_validate_values(alg, key_type);
  240. }
  241. #if defined(MBEDTLS_CIPHER_C)
  242. const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
  243. psa_algorithm_t alg,
  244. psa_key_type_t key_type,
  245. size_t key_bits,
  246. mbedtls_cipher_id_t *cipher_id)
  247. {
  248. mbedtls_cipher_mode_t mode;
  249. psa_status_t status;
  250. mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
  251. status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
  252. if (status != PSA_SUCCESS) {
  253. return NULL;
  254. }
  255. if (cipher_id != NULL) {
  256. *cipher_id = cipher_id_tmp;
  257. }
  258. return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
  259. }
  260. #endif /* MBEDTLS_CIPHER_C */
  261. #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
  262. static psa_status_t psa_cipher_setup(
  263. mbedtls_psa_cipher_operation_t *operation,
  264. const psa_key_attributes_t *attributes,
  265. const uint8_t *key_buffer, size_t key_buffer_size,
  266. psa_algorithm_t alg,
  267. mbedtls_operation_t cipher_operation)
  268. {
  269. int ret = 0;
  270. size_t key_bits;
  271. const mbedtls_cipher_info_t *cipher_info = NULL;
  272. psa_key_type_t key_type = attributes->type;
  273. (void) key_buffer_size;
  274. mbedtls_cipher_init(&operation->ctx.cipher);
  275. operation->alg = alg;
  276. key_bits = attributes->bits;
  277. cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
  278. key_bits, NULL);
  279. if (cipher_info == NULL) {
  280. return PSA_ERROR_NOT_SUPPORTED;
  281. }
  282. ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
  283. if (ret != 0) {
  284. goto exit;
  285. }
  286. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
  287. if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
  288. /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
  289. uint8_t keys[24];
  290. memcpy(keys, key_buffer, 16);
  291. memcpy(keys + 16, key_buffer, 8);
  292. ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
  293. keys,
  294. 192, cipher_operation);
  295. } else
  296. #endif
  297. {
  298. ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
  299. (int) key_bits, cipher_operation);
  300. }
  301. if (ret != 0) {
  302. goto exit;
  303. }
  304. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
  305. defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
  306. switch (alg) {
  307. case PSA_ALG_CBC_NO_PADDING:
  308. ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
  309. MBEDTLS_PADDING_NONE);
  310. break;
  311. case PSA_ALG_CBC_PKCS7:
  312. ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
  313. MBEDTLS_PADDING_PKCS7);
  314. break;
  315. default:
  316. /* The algorithm doesn't involve padding. */
  317. ret = 0;
  318. break;
  319. }
  320. if (ret != 0) {
  321. goto exit;
  322. }
  323. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
  324. MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
  325. operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
  326. PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
  327. operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
  328. exit:
  329. return mbedtls_to_psa_error(ret);
  330. }
  331. psa_status_t mbedtls_psa_cipher_encrypt_setup(
  332. mbedtls_psa_cipher_operation_t *operation,
  333. const psa_key_attributes_t *attributes,
  334. const uint8_t *key_buffer, size_t key_buffer_size,
  335. psa_algorithm_t alg)
  336. {
  337. return psa_cipher_setup(operation, attributes,
  338. key_buffer, key_buffer_size,
  339. alg, MBEDTLS_ENCRYPT);
  340. }
  341. psa_status_t mbedtls_psa_cipher_decrypt_setup(
  342. mbedtls_psa_cipher_operation_t *operation,
  343. const psa_key_attributes_t *attributes,
  344. const uint8_t *key_buffer, size_t key_buffer_size,
  345. psa_algorithm_t alg)
  346. {
  347. return psa_cipher_setup(operation, attributes,
  348. key_buffer, key_buffer_size,
  349. alg, MBEDTLS_DECRYPT);
  350. }
  351. psa_status_t mbedtls_psa_cipher_set_iv(
  352. mbedtls_psa_cipher_operation_t *operation,
  353. const uint8_t *iv, size_t iv_length)
  354. {
  355. if (iv_length != operation->iv_length) {
  356. return PSA_ERROR_INVALID_ARGUMENT;
  357. }
  358. return mbedtls_to_psa_error(
  359. mbedtls_cipher_set_iv(&operation->ctx.cipher,
  360. iv, iv_length));
  361. }
  362. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  363. /** Process input for which the algorithm is set to ECB mode.
  364. *
  365. * This requires manual processing, since the PSA API is defined as being
  366. * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
  367. * but the underlying mbedtls_cipher_update only takes full blocks.
  368. *
  369. * \param ctx The mbedtls cipher context to use. It must have been
  370. * set up for ECB.
  371. * \param[in] input The input plaintext or ciphertext to process.
  372. * \param input_length The number of bytes to process from \p input.
  373. * This does not need to be aligned to a block boundary.
  374. * If there is a partial block at the end of the input,
  375. * it is stored in \p ctx for future processing.
  376. * \param output The buffer where the output is written. It must be
  377. * at least `BS * floor((p + input_length) / BS)` bytes
  378. * long, where `p` is the number of bytes in the
  379. * unprocessed partial block in \p ctx (with
  380. * `0 <= p <= BS - 1`) and `BS` is the block size.
  381. * \param output_length On success, the number of bytes written to \p output.
  382. * \c 0 on error.
  383. *
  384. * \return #PSA_SUCCESS or an error from a hardware accelerator
  385. */
  386. static psa_status_t psa_cipher_update_ecb(
  387. mbedtls_cipher_context_t *ctx,
  388. const uint8_t *input,
  389. size_t input_length,
  390. uint8_t *output,
  391. size_t *output_length)
  392. {
  393. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  394. size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
  395. size_t internal_output_length = 0;
  396. *output_length = 0;
  397. if (input_length == 0) {
  398. status = PSA_SUCCESS;
  399. goto exit;
  400. }
  401. if (ctx->unprocessed_len > 0) {
  402. /* Fill up to block size, and run the block if there's a full one. */
  403. size_t bytes_to_copy = block_size - ctx->unprocessed_len;
  404. if (input_length < bytes_to_copy) {
  405. bytes_to_copy = input_length;
  406. }
  407. memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
  408. input, bytes_to_copy);
  409. input_length -= bytes_to_copy;
  410. input += bytes_to_copy;
  411. ctx->unprocessed_len += bytes_to_copy;
  412. if (ctx->unprocessed_len == block_size) {
  413. status = mbedtls_to_psa_error(
  414. mbedtls_cipher_update(ctx,
  415. ctx->unprocessed_data,
  416. block_size,
  417. output, &internal_output_length));
  418. if (status != PSA_SUCCESS) {
  419. goto exit;
  420. }
  421. output += internal_output_length;
  422. *output_length += internal_output_length;
  423. ctx->unprocessed_len = 0;
  424. }
  425. }
  426. while (input_length >= block_size) {
  427. /* Run all full blocks we have, one by one */
  428. status = mbedtls_to_psa_error(
  429. mbedtls_cipher_update(ctx, input,
  430. block_size,
  431. output, &internal_output_length));
  432. if (status != PSA_SUCCESS) {
  433. goto exit;
  434. }
  435. input_length -= block_size;
  436. input += block_size;
  437. output += internal_output_length;
  438. *output_length += internal_output_length;
  439. }
  440. if (input_length > 0) {
  441. /* Save unprocessed bytes for later processing */
  442. memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
  443. input, input_length);
  444. ctx->unprocessed_len += input_length;
  445. }
  446. status = PSA_SUCCESS;
  447. exit:
  448. return status;
  449. }
  450. #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
  451. psa_status_t mbedtls_psa_cipher_update(
  452. mbedtls_psa_cipher_operation_t *operation,
  453. const uint8_t *input, size_t input_length,
  454. uint8_t *output, size_t output_size, size_t *output_length)
  455. {
  456. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  457. size_t expected_output_size;
  458. if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
  459. /* Take the unprocessed partial block left over from previous
  460. * update calls, if any, plus the input to this call. Remove
  461. * the last partial block, if any. You get the data that will be
  462. * output in this call. */
  463. expected_output_size =
  464. (operation->ctx.cipher.unprocessed_len + input_length)
  465. / operation->block_length * operation->block_length;
  466. } else {
  467. expected_output_size = input_length;
  468. }
  469. if (output_size < expected_output_size) {
  470. return PSA_ERROR_BUFFER_TOO_SMALL;
  471. }
  472. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
  473. if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
  474. /* mbedtls_cipher_update has an API inconsistency: it will only
  475. * process a single block at a time in ECB mode. Abstract away that
  476. * inconsistency here to match the PSA API behaviour. */
  477. status = psa_cipher_update_ecb(&operation->ctx.cipher,
  478. input,
  479. input_length,
  480. output,
  481. output_length);
  482. } else
  483. #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
  484. if (input_length == 0) {
  485. /* There is no input, nothing to be done */
  486. *output_length = 0;
  487. status = PSA_SUCCESS;
  488. } else {
  489. status = mbedtls_to_psa_error(
  490. mbedtls_cipher_update(&operation->ctx.cipher, input,
  491. input_length, output, output_length));
  492. if (*output_length > output_size) {
  493. return PSA_ERROR_CORRUPTION_DETECTED;
  494. }
  495. }
  496. return status;
  497. }
  498. psa_status_t mbedtls_psa_cipher_finish(
  499. mbedtls_psa_cipher_operation_t *operation,
  500. uint8_t *output, size_t output_size, size_t *output_length)
  501. {
  502. psa_status_t status = PSA_ERROR_GENERIC_ERROR;
  503. uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
  504. if (operation->ctx.cipher.unprocessed_len != 0) {
  505. if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
  506. operation->alg == PSA_ALG_CBC_NO_PADDING) {
  507. status = PSA_ERROR_INVALID_ARGUMENT;
  508. goto exit;
  509. }
  510. }
  511. status = mbedtls_to_psa_error(
  512. mbedtls_cipher_finish(&operation->ctx.cipher,
  513. temp_output_buffer,
  514. output_length));
  515. if (status != PSA_SUCCESS) {
  516. goto exit;
  517. }
  518. if (*output_length == 0) {
  519. ; /* Nothing to copy. Note that output may be NULL in this case. */
  520. } else if (output_size >= *output_length) {
  521. memcpy(output, temp_output_buffer, *output_length);
  522. } else {
  523. status = PSA_ERROR_BUFFER_TOO_SMALL;
  524. }
  525. exit:
  526. mbedtls_platform_zeroize(temp_output_buffer,
  527. sizeof(temp_output_buffer));
  528. return status;
  529. }
  530. psa_status_t mbedtls_psa_cipher_abort(
  531. mbedtls_psa_cipher_operation_t *operation)
  532. {
  533. /* Sanity check (shouldn't happen: operation->alg should
  534. * always have been initialized to a valid value). */
  535. if (!PSA_ALG_IS_CIPHER(operation->alg)) {
  536. return PSA_ERROR_BAD_STATE;
  537. }
  538. mbedtls_cipher_free(&operation->ctx.cipher);
  539. return PSA_SUCCESS;
  540. }
  541. psa_status_t mbedtls_psa_cipher_encrypt(
  542. const psa_key_attributes_t *attributes,
  543. const uint8_t *key_buffer,
  544. size_t key_buffer_size,
  545. psa_algorithm_t alg,
  546. const uint8_t *iv,
  547. size_t iv_length,
  548. const uint8_t *input,
  549. size_t input_length,
  550. uint8_t *output,
  551. size_t output_size,
  552. size_t *output_length)
  553. {
  554. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  555. mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
  556. size_t update_output_length, finish_output_length;
  557. status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
  558. key_buffer, key_buffer_size,
  559. alg);
  560. if (status != PSA_SUCCESS) {
  561. goto exit;
  562. }
  563. if (iv_length > 0) {
  564. status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
  565. if (status != PSA_SUCCESS) {
  566. goto exit;
  567. }
  568. }
  569. status = mbedtls_psa_cipher_update(&operation, input, input_length,
  570. output, output_size,
  571. &update_output_length);
  572. if (status != PSA_SUCCESS) {
  573. goto exit;
  574. }
  575. status = mbedtls_psa_cipher_finish(
  576. &operation,
  577. mbedtls_buffer_offset(output, update_output_length),
  578. output_size - update_output_length, &finish_output_length);
  579. if (status != PSA_SUCCESS) {
  580. goto exit;
  581. }
  582. *output_length = update_output_length + finish_output_length;
  583. exit:
  584. if (status == PSA_SUCCESS) {
  585. status = mbedtls_psa_cipher_abort(&operation);
  586. } else {
  587. mbedtls_psa_cipher_abort(&operation);
  588. }
  589. return status;
  590. }
  591. psa_status_t mbedtls_psa_cipher_decrypt(
  592. const psa_key_attributes_t *attributes,
  593. const uint8_t *key_buffer,
  594. size_t key_buffer_size,
  595. psa_algorithm_t alg,
  596. const uint8_t *input,
  597. size_t input_length,
  598. uint8_t *output,
  599. size_t output_size,
  600. size_t *output_length)
  601. {
  602. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  603. mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
  604. size_t olength, accumulated_length;
  605. status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
  606. key_buffer, key_buffer_size,
  607. alg);
  608. if (status != PSA_SUCCESS) {
  609. goto exit;
  610. }
  611. if (operation.iv_length > 0) {
  612. status = mbedtls_psa_cipher_set_iv(&operation,
  613. input, operation.iv_length);
  614. if (status != PSA_SUCCESS) {
  615. goto exit;
  616. }
  617. }
  618. status = mbedtls_psa_cipher_update(
  619. &operation,
  620. mbedtls_buffer_offset_const(input, operation.iv_length),
  621. input_length - operation.iv_length,
  622. output, output_size, &olength);
  623. if (status != PSA_SUCCESS) {
  624. goto exit;
  625. }
  626. accumulated_length = olength;
  627. status = mbedtls_psa_cipher_finish(
  628. &operation,
  629. mbedtls_buffer_offset(output, accumulated_length),
  630. output_size - accumulated_length, &olength);
  631. if (status != PSA_SUCCESS) {
  632. goto exit;
  633. }
  634. *output_length = accumulated_length + olength;
  635. exit:
  636. if (status == PSA_SUCCESS) {
  637. status = mbedtls_psa_cipher_abort(&operation);
  638. } else {
  639. mbedtls_psa_cipher_abort(&operation);
  640. }
  641. return status;
  642. }
  643. #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
  644. #endif /* MBEDTLS_PSA_CRYPTO_C */