psa_crypto_aead.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /*
  2. * PSA AEAD 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_aead.h"
  11. #include "psa_crypto_core.h"
  12. #include "psa_crypto_cipher.h"
  13. #include <string.h>
  14. #include "mbedtls/platform.h"
  15. #include "mbedtls/ccm.h"
  16. #include "mbedtls/chachapoly.h"
  17. #include "mbedtls/cipher.h"
  18. #include "mbedtls/gcm.h"
  19. #include "mbedtls/error.h"
  20. static psa_status_t psa_aead_setup(
  21. mbedtls_psa_aead_operation_t *operation,
  22. const psa_key_attributes_t *attributes,
  23. const uint8_t *key_buffer,
  24. size_t key_buffer_size,
  25. psa_algorithm_t alg)
  26. {
  27. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  28. mbedtls_cipher_id_t cipher_id;
  29. mbedtls_cipher_mode_t mode;
  30. size_t key_bits = attributes->bits;
  31. (void) key_buffer_size;
  32. status = mbedtls_cipher_values_from_psa(alg, attributes->type,
  33. &key_bits, &mode, &cipher_id);
  34. if (status != PSA_SUCCESS) {
  35. return status;
  36. }
  37. switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
  38. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  39. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
  40. operation->alg = PSA_ALG_CCM;
  41. /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
  42. * The call to mbedtls_ccm_encrypt_and_tag or
  43. * mbedtls_ccm_auth_decrypt will validate the tag length. */
  44. if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
  45. return PSA_ERROR_INVALID_ARGUMENT;
  46. }
  47. mbedtls_ccm_init(&operation->ctx.ccm);
  48. status = mbedtls_to_psa_error(
  49. mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
  50. key_buffer, (unsigned int) key_bits));
  51. if (status != PSA_SUCCESS) {
  52. return status;
  53. }
  54. break;
  55. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  56. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  57. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
  58. operation->alg = PSA_ALG_GCM;
  59. /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
  60. * The call to mbedtls_gcm_crypt_and_tag or
  61. * mbedtls_gcm_auth_decrypt will validate the tag length. */
  62. if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->type) != 16) {
  63. return PSA_ERROR_INVALID_ARGUMENT;
  64. }
  65. mbedtls_gcm_init(&operation->ctx.gcm);
  66. status = mbedtls_to_psa_error(
  67. mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
  68. key_buffer, (unsigned int) key_bits));
  69. if (status != PSA_SUCCESS) {
  70. return status;
  71. }
  72. break;
  73. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  74. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  75. case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
  76. operation->alg = PSA_ALG_CHACHA20_POLY1305;
  77. /* We only support the default tag length. */
  78. if (alg != PSA_ALG_CHACHA20_POLY1305) {
  79. return PSA_ERROR_NOT_SUPPORTED;
  80. }
  81. mbedtls_chachapoly_init(&operation->ctx.chachapoly);
  82. status = mbedtls_to_psa_error(
  83. mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
  84. key_buffer));
  85. if (status != PSA_SUCCESS) {
  86. return status;
  87. }
  88. break;
  89. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  90. default:
  91. (void) status;
  92. (void) key_buffer;
  93. return PSA_ERROR_NOT_SUPPORTED;
  94. }
  95. operation->key_type = psa_get_key_type(attributes);
  96. operation->tag_length = PSA_ALG_AEAD_GET_TAG_LENGTH(alg);
  97. return PSA_SUCCESS;
  98. }
  99. psa_status_t mbedtls_psa_aead_encrypt(
  100. const psa_key_attributes_t *attributes,
  101. const uint8_t *key_buffer, size_t key_buffer_size,
  102. psa_algorithm_t alg,
  103. const uint8_t *nonce, size_t nonce_length,
  104. const uint8_t *additional_data, size_t additional_data_length,
  105. const uint8_t *plaintext, size_t plaintext_length,
  106. uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
  107. {
  108. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  109. mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
  110. uint8_t *tag;
  111. status = psa_aead_setup(&operation, attributes, key_buffer,
  112. key_buffer_size, alg);
  113. if (status != PSA_SUCCESS) {
  114. goto exit;
  115. }
  116. /* For all currently supported modes, the tag is at the end of the
  117. * ciphertext. */
  118. if (ciphertext_size < (plaintext_length + operation.tag_length)) {
  119. status = PSA_ERROR_BUFFER_TOO_SMALL;
  120. goto exit;
  121. }
  122. tag = ciphertext + plaintext_length;
  123. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  124. if (operation.alg == PSA_ALG_CCM) {
  125. status = mbedtls_to_psa_error(
  126. mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm,
  127. plaintext_length,
  128. nonce, nonce_length,
  129. additional_data,
  130. additional_data_length,
  131. plaintext, ciphertext,
  132. tag, operation.tag_length));
  133. } else
  134. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  135. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  136. if (operation.alg == PSA_ALG_GCM) {
  137. status = mbedtls_to_psa_error(
  138. mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm,
  139. MBEDTLS_GCM_ENCRYPT,
  140. plaintext_length,
  141. nonce, nonce_length,
  142. additional_data, additional_data_length,
  143. plaintext, ciphertext,
  144. operation.tag_length, tag));
  145. } else
  146. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  147. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  148. if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
  149. if (operation.tag_length != 16) {
  150. status = PSA_ERROR_NOT_SUPPORTED;
  151. goto exit;
  152. }
  153. status = mbedtls_to_psa_error(
  154. mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly,
  155. plaintext_length,
  156. nonce,
  157. additional_data,
  158. additional_data_length,
  159. plaintext,
  160. ciphertext,
  161. tag));
  162. } else
  163. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  164. {
  165. (void) tag;
  166. (void) nonce;
  167. (void) nonce_length;
  168. (void) additional_data;
  169. (void) additional_data_length;
  170. (void) plaintext;
  171. return PSA_ERROR_NOT_SUPPORTED;
  172. }
  173. if (status == PSA_SUCCESS) {
  174. *ciphertext_length = plaintext_length + operation.tag_length;
  175. }
  176. exit:
  177. mbedtls_psa_aead_abort(&operation);
  178. return status;
  179. }
  180. /* Locate the tag in a ciphertext buffer containing the encrypted data
  181. * followed by the tag. Return the length of the part preceding the tag in
  182. * *plaintext_length. This is the size of the plaintext in modes where
  183. * the encrypted data has the same size as the plaintext, such as
  184. * CCM and GCM. */
  185. static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length,
  186. const uint8_t *ciphertext,
  187. size_t ciphertext_length,
  188. size_t plaintext_size,
  189. const uint8_t **p_tag)
  190. {
  191. size_t payload_length;
  192. if (tag_length > ciphertext_length) {
  193. return PSA_ERROR_INVALID_ARGUMENT;
  194. }
  195. payload_length = ciphertext_length - tag_length;
  196. if (payload_length > plaintext_size) {
  197. return PSA_ERROR_BUFFER_TOO_SMALL;
  198. }
  199. *p_tag = ciphertext + payload_length;
  200. return PSA_SUCCESS;
  201. }
  202. psa_status_t mbedtls_psa_aead_decrypt(
  203. const psa_key_attributes_t *attributes,
  204. const uint8_t *key_buffer, size_t key_buffer_size,
  205. psa_algorithm_t alg,
  206. const uint8_t *nonce, size_t nonce_length,
  207. const uint8_t *additional_data, size_t additional_data_length,
  208. const uint8_t *ciphertext, size_t ciphertext_length,
  209. uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
  210. {
  211. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  212. mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
  213. const uint8_t *tag = NULL;
  214. status = psa_aead_setup(&operation, attributes, key_buffer,
  215. key_buffer_size, alg);
  216. if (status != PSA_SUCCESS) {
  217. goto exit;
  218. }
  219. status = psa_aead_unpadded_locate_tag(operation.tag_length,
  220. ciphertext, ciphertext_length,
  221. plaintext_size, &tag);
  222. if (status != PSA_SUCCESS) {
  223. goto exit;
  224. }
  225. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  226. if (operation.alg == PSA_ALG_CCM) {
  227. status = mbedtls_to_psa_error(
  228. mbedtls_ccm_auth_decrypt(&operation.ctx.ccm,
  229. ciphertext_length - operation.tag_length,
  230. nonce, nonce_length,
  231. additional_data,
  232. additional_data_length,
  233. ciphertext, plaintext,
  234. tag, operation.tag_length));
  235. } else
  236. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  237. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  238. if (operation.alg == PSA_ALG_GCM) {
  239. status = mbedtls_to_psa_error(
  240. mbedtls_gcm_auth_decrypt(&operation.ctx.gcm,
  241. ciphertext_length - operation.tag_length,
  242. nonce, nonce_length,
  243. additional_data,
  244. additional_data_length,
  245. tag, operation.tag_length,
  246. ciphertext, plaintext));
  247. } else
  248. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  249. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  250. if (operation.alg == PSA_ALG_CHACHA20_POLY1305) {
  251. if (operation.tag_length != 16) {
  252. status = PSA_ERROR_NOT_SUPPORTED;
  253. goto exit;
  254. }
  255. status = mbedtls_to_psa_error(
  256. mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly,
  257. ciphertext_length - operation.tag_length,
  258. nonce,
  259. additional_data,
  260. additional_data_length,
  261. tag,
  262. ciphertext,
  263. plaintext));
  264. } else
  265. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  266. {
  267. (void) nonce;
  268. (void) nonce_length;
  269. (void) additional_data;
  270. (void) additional_data_length;
  271. (void) plaintext;
  272. return PSA_ERROR_NOT_SUPPORTED;
  273. }
  274. if (status == PSA_SUCCESS) {
  275. *plaintext_length = ciphertext_length - operation.tag_length;
  276. }
  277. exit:
  278. mbedtls_psa_aead_abort(&operation);
  279. if (status == PSA_SUCCESS) {
  280. *plaintext_length = ciphertext_length - operation.tag_length;
  281. }
  282. return status;
  283. }
  284. /* Set the key and algorithm for a multipart authenticated encryption
  285. * operation. */
  286. psa_status_t mbedtls_psa_aead_encrypt_setup(
  287. mbedtls_psa_aead_operation_t *operation,
  288. const psa_key_attributes_t *attributes,
  289. const uint8_t *key_buffer,
  290. size_t key_buffer_size,
  291. psa_algorithm_t alg)
  292. {
  293. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  294. status = psa_aead_setup(operation, attributes, key_buffer,
  295. key_buffer_size, alg);
  296. if (status == PSA_SUCCESS) {
  297. operation->is_encrypt = 1;
  298. }
  299. return status;
  300. }
  301. /* Set the key and algorithm for a multipart authenticated decryption
  302. * operation. */
  303. psa_status_t mbedtls_psa_aead_decrypt_setup(
  304. mbedtls_psa_aead_operation_t *operation,
  305. const psa_key_attributes_t *attributes,
  306. const uint8_t *key_buffer,
  307. size_t key_buffer_size,
  308. psa_algorithm_t alg)
  309. {
  310. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  311. status = psa_aead_setup(operation, attributes, key_buffer,
  312. key_buffer_size, alg);
  313. if (status == PSA_SUCCESS) {
  314. operation->is_encrypt = 0;
  315. }
  316. return status;
  317. }
  318. /* Set a nonce for the multipart AEAD operation*/
  319. psa_status_t mbedtls_psa_aead_set_nonce(
  320. mbedtls_psa_aead_operation_t *operation,
  321. const uint8_t *nonce,
  322. size_t nonce_length)
  323. {
  324. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  325. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  326. if (operation->alg == PSA_ALG_GCM) {
  327. status = mbedtls_to_psa_error(
  328. mbedtls_gcm_starts(&operation->ctx.gcm,
  329. operation->is_encrypt ?
  330. MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
  331. nonce,
  332. nonce_length));
  333. } else
  334. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  335. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  336. if (operation->alg == PSA_ALG_CCM) {
  337. status = mbedtls_to_psa_error(
  338. mbedtls_ccm_starts(&operation->ctx.ccm,
  339. operation->is_encrypt ?
  340. MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT,
  341. nonce,
  342. nonce_length));
  343. } else
  344. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  345. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  346. if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
  347. /* Note - ChaChaPoly allows an 8 byte nonce, but we would have to
  348. * allocate a buffer in the operation, copy the nonce to it and pad
  349. * it, so for now check the nonce is 12 bytes, as
  350. * mbedtls_chachapoly_starts() assumes it can read 12 bytes from the
  351. * passed in buffer. */
  352. if (nonce_length != 12) {
  353. return PSA_ERROR_INVALID_ARGUMENT;
  354. }
  355. status = mbedtls_to_psa_error(
  356. mbedtls_chachapoly_starts(&operation->ctx.chachapoly,
  357. nonce,
  358. operation->is_encrypt ?
  359. MBEDTLS_CHACHAPOLY_ENCRYPT :
  360. MBEDTLS_CHACHAPOLY_DECRYPT));
  361. } else
  362. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  363. {
  364. (void) operation;
  365. (void) nonce;
  366. (void) nonce_length;
  367. return PSA_ERROR_NOT_SUPPORTED;
  368. }
  369. return status;
  370. }
  371. /* Declare the lengths of the message and additional data for AEAD. */
  372. psa_status_t mbedtls_psa_aead_set_lengths(
  373. mbedtls_psa_aead_operation_t *operation,
  374. size_t ad_length,
  375. size_t plaintext_length)
  376. {
  377. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  378. if (operation->alg == PSA_ALG_CCM) {
  379. return mbedtls_to_psa_error(
  380. mbedtls_ccm_set_lengths(&operation->ctx.ccm,
  381. ad_length,
  382. plaintext_length,
  383. operation->tag_length));
  384. }
  385. #else /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  386. (void) operation;
  387. (void) ad_length;
  388. (void) plaintext_length;
  389. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  390. return PSA_SUCCESS;
  391. }
  392. /* Pass additional data to an active multipart AEAD operation. */
  393. psa_status_t mbedtls_psa_aead_update_ad(
  394. mbedtls_psa_aead_operation_t *operation,
  395. const uint8_t *input,
  396. size_t input_length)
  397. {
  398. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  399. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  400. if (operation->alg == PSA_ALG_GCM) {
  401. status = mbedtls_to_psa_error(
  402. mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length));
  403. } else
  404. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  405. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  406. if (operation->alg == PSA_ALG_CCM) {
  407. status = mbedtls_to_psa_error(
  408. mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length));
  409. } else
  410. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  411. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  412. if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
  413. status = mbedtls_to_psa_error(
  414. mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly,
  415. input,
  416. input_length));
  417. } else
  418. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  419. {
  420. (void) operation;
  421. (void) input;
  422. (void) input_length;
  423. return PSA_ERROR_NOT_SUPPORTED;
  424. }
  425. return status;
  426. }
  427. /* Encrypt or decrypt a message fragment in an active multipart AEAD
  428. * operation.*/
  429. psa_status_t mbedtls_psa_aead_update(
  430. mbedtls_psa_aead_operation_t *operation,
  431. const uint8_t *input,
  432. size_t input_length,
  433. uint8_t *output,
  434. size_t output_size,
  435. size_t *output_length)
  436. {
  437. size_t update_output_length;
  438. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  439. update_output_length = input_length;
  440. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  441. if (operation->alg == PSA_ALG_GCM) {
  442. status = mbedtls_to_psa_error(
  443. mbedtls_gcm_update(&operation->ctx.gcm,
  444. input, input_length,
  445. output, output_size,
  446. &update_output_length));
  447. } else
  448. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  449. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  450. if (operation->alg == PSA_ALG_CCM) {
  451. if (output_size < input_length) {
  452. return PSA_ERROR_BUFFER_TOO_SMALL;
  453. }
  454. status = mbedtls_to_psa_error(
  455. mbedtls_ccm_update(&operation->ctx.ccm,
  456. input, input_length,
  457. output, output_size,
  458. &update_output_length));
  459. } else
  460. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  461. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  462. if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
  463. if (output_size < input_length) {
  464. return PSA_ERROR_BUFFER_TOO_SMALL;
  465. }
  466. status = mbedtls_to_psa_error(
  467. mbedtls_chachapoly_update(&operation->ctx.chachapoly,
  468. input_length,
  469. input,
  470. output));
  471. } else
  472. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  473. {
  474. (void) operation;
  475. (void) input;
  476. (void) output;
  477. (void) output_size;
  478. return PSA_ERROR_NOT_SUPPORTED;
  479. }
  480. if (status == PSA_SUCCESS) {
  481. *output_length = update_output_length;
  482. }
  483. return status;
  484. }
  485. /* Finish encrypting a message in a multipart AEAD operation. */
  486. psa_status_t mbedtls_psa_aead_finish(
  487. mbedtls_psa_aead_operation_t *operation,
  488. uint8_t *ciphertext,
  489. size_t ciphertext_size,
  490. size_t *ciphertext_length,
  491. uint8_t *tag,
  492. size_t tag_size,
  493. size_t *tag_length)
  494. {
  495. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  496. size_t finish_output_size = 0;
  497. if (tag_size < operation->tag_length) {
  498. return PSA_ERROR_BUFFER_TOO_SMALL;
  499. }
  500. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  501. if (operation->alg == PSA_ALG_GCM) {
  502. status = mbedtls_to_psa_error(
  503. mbedtls_gcm_finish(&operation->ctx.gcm,
  504. ciphertext, ciphertext_size, ciphertext_length,
  505. tag, operation->tag_length));
  506. } else
  507. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  508. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  509. if (operation->alg == PSA_ALG_CCM) {
  510. /* tag must be big enough to store a tag of size passed into set
  511. * lengths. */
  512. if (tag_size < operation->tag_length) {
  513. return PSA_ERROR_BUFFER_TOO_SMALL;
  514. }
  515. status = mbedtls_to_psa_error(
  516. mbedtls_ccm_finish(&operation->ctx.ccm,
  517. tag, operation->tag_length));
  518. } else
  519. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  520. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  521. if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
  522. /* Belt and braces. Although the above tag_size check should have
  523. * already done this, if we later start supporting smaller tag sizes
  524. * for chachapoly, then passing a tag buffer smaller than 16 into here
  525. * could cause a buffer overflow, so better safe than sorry. */
  526. if (tag_size < 16) {
  527. return PSA_ERROR_BUFFER_TOO_SMALL;
  528. }
  529. status = mbedtls_to_psa_error(
  530. mbedtls_chachapoly_finish(&operation->ctx.chachapoly,
  531. tag));
  532. } else
  533. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  534. {
  535. (void) ciphertext;
  536. (void) ciphertext_size;
  537. (void) ciphertext_length;
  538. (void) tag;
  539. (void) tag_size;
  540. (void) tag_length;
  541. return PSA_ERROR_NOT_SUPPORTED;
  542. }
  543. if (status == PSA_SUCCESS) {
  544. /* This will be zero for all supported algorithms currently, but left
  545. * here for future support. */
  546. *ciphertext_length = finish_output_size;
  547. *tag_length = operation->tag_length;
  548. }
  549. return status;
  550. }
  551. /* Abort an AEAD operation */
  552. psa_status_t mbedtls_psa_aead_abort(
  553. mbedtls_psa_aead_operation_t *operation)
  554. {
  555. switch (operation->alg) {
  556. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
  557. case PSA_ALG_CCM:
  558. mbedtls_ccm_free(&operation->ctx.ccm);
  559. break;
  560. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
  561. #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
  562. case PSA_ALG_GCM:
  563. mbedtls_gcm_free(&operation->ctx.gcm);
  564. break;
  565. #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
  566. #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
  567. case PSA_ALG_CHACHA20_POLY1305:
  568. mbedtls_chachapoly_free(&operation->ctx.chachapoly);
  569. break;
  570. #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
  571. }
  572. operation->is_encrypt = 0;
  573. return PSA_SUCCESS;
  574. }
  575. #endif /* MBEDTLS_PSA_CRYPTO_C */