Coverage Report

Created: 2025-03-01 06:26

/src/mbedtls/library/psa_crypto_aead.c
Line
Count
Source (jump to first uncovered line)
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
    if (status == PSA_SUCCESS) {
314
0
        *plaintext_length = ciphertext_length - operation.tag_length;
315
0
    }
316
0
    return status;
317
0
}
318
319
/* Set the key and algorithm for a multipart authenticated encryption
320
 * operation. */
321
psa_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
0
{
328
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
329
330
0
    status = psa_aead_setup(operation, attributes, key_buffer,
331
0
                            key_buffer_size, alg);
332
333
0
    if (status == PSA_SUCCESS) {
334
0
        operation->is_encrypt = 1;
335
0
    }
336
337
0
    return status;
338
0
}
339
340
/* Set the key and algorithm for a multipart authenticated decryption
341
 * operation. */
342
psa_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
0
{
349
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
350
351
0
    status = psa_aead_setup(operation, attributes, key_buffer,
352
0
                            key_buffer_size, alg);
353
354
0
    if (status == PSA_SUCCESS) {
355
0
        operation->is_encrypt = 0;
356
0
    }
357
358
0
    return status;
359
0
}
360
361
/* Set a nonce for the multipart AEAD operation*/
362
psa_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
0
{
367
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
368
369
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
370
0
    if (operation->alg == PSA_ALG_GCM) {
371
0
        status = mbedtls_to_psa_error(
372
0
            mbedtls_gcm_starts(&operation->ctx.gcm,
373
0
                               operation->is_encrypt ?
374
0
                               MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
375
0
                               nonce,
376
0
                               nonce_length));
377
0
    } else
378
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
379
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
380
0
    if (operation->alg == PSA_ALG_CCM) {
381
0
        status = mbedtls_to_psa_error(
382
0
            mbedtls_ccm_starts(&operation->ctx.ccm,
383
0
                               operation->is_encrypt ?
384
0
                               MBEDTLS_CCM_ENCRYPT : MBEDTLS_CCM_DECRYPT,
385
0
                               nonce,
386
0
                               nonce_length));
387
0
    } else
388
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
389
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
390
0
    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
0
        if (nonce_length != 12) {
397
0
            return PSA_ERROR_INVALID_ARGUMENT;
398
0
        }
399
400
0
        status = mbedtls_to_psa_error(
401
0
            mbedtls_chachapoly_starts(&operation->ctx.chachapoly,
402
0
                                      nonce,
403
0
                                      operation->is_encrypt ?
404
0
                                      MBEDTLS_CHACHAPOLY_ENCRYPT :
405
0
                                      MBEDTLS_CHACHAPOLY_DECRYPT));
406
0
    } else
407
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
408
0
    {
409
0
        (void) operation;
410
0
        (void) nonce;
411
0
        (void) nonce_length;
412
413
0
        return PSA_ERROR_NOT_SUPPORTED;
414
0
    }
415
416
0
    return status;
417
0
}
418
419
/* Declare the lengths of the message and additional data for AEAD. */
420
psa_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
0
{
425
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
426
0
    if (operation->alg == PSA_ALG_CCM) {
427
0
        return mbedtls_to_psa_error(
428
0
            mbedtls_ccm_set_lengths(&operation->ctx.ccm,
429
0
                                    ad_length,
430
0
                                    plaintext_length,
431
0
                                    operation->tag_length));
432
433
0
    }
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
0
    return PSA_SUCCESS;
441
0
}
442
443
/* Pass additional data to an active multipart AEAD operation. */
444
psa_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
0
{
449
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
450
451
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
452
0
    if (operation->alg == PSA_ALG_GCM) {
453
0
        status = mbedtls_to_psa_error(
454
0
            mbedtls_gcm_update_ad(&operation->ctx.gcm, input, input_length));
455
0
    } else
456
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
457
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
458
0
    if (operation->alg == PSA_ALG_CCM) {
459
0
        status = mbedtls_to_psa_error(
460
0
            mbedtls_ccm_update_ad(&operation->ctx.ccm, input, input_length));
461
0
    } else
462
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
463
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
464
0
    if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
465
0
        status = mbedtls_to_psa_error(
466
0
            mbedtls_chachapoly_update_aad(&operation->ctx.chachapoly,
467
0
                                          input,
468
0
                                          input_length));
469
0
    } else
470
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
471
0
    {
472
0
        (void) operation;
473
0
        (void) input;
474
0
        (void) input_length;
475
476
0
        return PSA_ERROR_NOT_SUPPORTED;
477
0
    }
478
479
0
    return status;
480
0
}
481
482
/* Encrypt or decrypt a message fragment in an active multipart AEAD
483
 * operation.*/
484
psa_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
0
{
492
0
    size_t update_output_length;
493
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
494
495
0
    update_output_length = input_length;
496
497
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
498
0
    if (operation->alg == PSA_ALG_GCM) {
499
0
        status =  mbedtls_to_psa_error(
500
0
            mbedtls_gcm_update(&operation->ctx.gcm,
501
0
                               input, input_length,
502
0
                               output, output_size,
503
0
                               &update_output_length));
504
0
    } else
505
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
506
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
507
0
    if (operation->alg == PSA_ALG_CCM) {
508
0
        if (output_size < input_length) {
509
0
            return PSA_ERROR_BUFFER_TOO_SMALL;
510
0
        }
511
512
0
        status = mbedtls_to_psa_error(
513
0
            mbedtls_ccm_update(&operation->ctx.ccm,
514
0
                               input, input_length,
515
0
                               output, output_size,
516
0
                               &update_output_length));
517
0
    } else
518
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
519
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
520
0
    if (operation->alg == PSA_ALG_CHACHA20_POLY1305) {
521
0
        if (output_size < input_length) {
522
0
            return PSA_ERROR_BUFFER_TOO_SMALL;
523
0
        }
524
525
0
        status = mbedtls_to_psa_error(
526
0
            mbedtls_chachapoly_update(&operation->ctx.chachapoly,
527
0
                                      input_length,
528
0
                                      input,
529
0
                                      output));
530
0
    } else
531
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
532
0
    {
533
0
        (void) operation;
534
0
        (void) input;
535
0
        (void) output;
536
0
        (void) output_size;
537
538
0
        return PSA_ERROR_NOT_SUPPORTED;
539
0
    }
540
541
0
    if (status == PSA_SUCCESS) {
542
0
        *output_length = update_output_length;
543
0
    }
544
545
0
    return status;
546
0
}
547
548
/* Finish encrypting a message in a multipart AEAD operation. */
549
psa_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
0
{
558
0
    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
559
0
    size_t finish_output_size = 0;
560
561
0
    if (tag_size < operation->tag_length) {
562
0
        return PSA_ERROR_BUFFER_TOO_SMALL;
563
0
    }
564
565
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
566
0
    if (operation->alg == PSA_ALG_GCM) {
567
0
        status =  mbedtls_to_psa_error(
568
0
            mbedtls_gcm_finish(&operation->ctx.gcm,
569
0
                               ciphertext, ciphertext_size, ciphertext_length,
570
0
                               tag, operation->tag_length));
571
0
    } else
572
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
573
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
574
0
    if (operation->alg == PSA_ALG_CCM) {
575
        /* tag must be big enough to store a tag of size passed into set
576
         * lengths. */
577
0
        if (tag_size < operation->tag_length) {
578
0
            return PSA_ERROR_BUFFER_TOO_SMALL;
579
0
        }
580
581
0
        status = mbedtls_to_psa_error(
582
0
            mbedtls_ccm_finish(&operation->ctx.ccm,
583
0
                               tag, operation->tag_length));
584
0
    } else
585
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
586
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
587
0
    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
0
        if (tag_size < 16) {
593
0
            return PSA_ERROR_BUFFER_TOO_SMALL;
594
0
        }
595
596
0
        status = mbedtls_to_psa_error(
597
0
            mbedtls_chachapoly_finish(&operation->ctx.chachapoly,
598
0
                                      tag));
599
0
    } else
600
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
601
0
    {
602
0
        (void) ciphertext;
603
0
        (void) ciphertext_size;
604
0
        (void) ciphertext_length;
605
0
        (void) tag;
606
0
        (void) tag_size;
607
0
        (void) tag_length;
608
609
0
        return PSA_ERROR_NOT_SUPPORTED;
610
0
    }
611
612
0
    if (status == PSA_SUCCESS) {
613
        /* This will be zero for all supported algorithms currently, but left
614
         * here for future support. */
615
0
        *ciphertext_length = finish_output_size;
616
0
        *tag_length = operation->tag_length;
617
0
    }
618
619
0
    return status;
620
0
}
621
622
/* Abort an AEAD operation */
623
psa_status_t mbedtls_psa_aead_abort(
624
    mbedtls_psa_aead_operation_t *operation)
625
0
{
626
0
    switch (operation->alg) {
627
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
628
0
        case PSA_ALG_CCM:
629
0
            mbedtls_ccm_free(&operation->ctx.ccm);
630
0
            break;
631
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
632
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
633
0
        case PSA_ALG_GCM:
634
0
            mbedtls_gcm_free(&operation->ctx.gcm);
635
0
            break;
636
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
637
0
#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
638
0
        case PSA_ALG_CHACHA20_POLY1305:
639
0
            mbedtls_chachapoly_free(&operation->ctx.chachapoly);
640
0
            break;
641
0
#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
642
0
    }
643
644
0
    operation->is_encrypt = 0;
645
646
0
    return PSA_SUCCESS;
647
0
}
648
649
#endif /* MBEDTLS_PSA_CRYPTO_C */