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