Coverage Report

Created: 2026-07-25 06:10

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