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