blob: 26ccc1cafcff36c550da71d35b282201638f6828 [file] [log] [blame]
Ronald Cron7ceee8d2021-03-17 16:55:43 +01001/*
2 * PSA AEAD entry points
3 */
4/*
5 * Copyright The Mbed TLS Contributors
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
25#include "psa_crypto_aead.h"
Ronald Cron46f91782021-03-17 08:16:34 +010026#include "psa_crypto_core.h"
Dave Rodgman8e322b12022-11-02 09:25:38 +000027#include "psa_crypto_cipher.h"
Ronald Cron46f91782021-03-17 08:16:34 +010028
29#include "mbedtls/ccm.h"
30#include "mbedtls/chachapoly.h"
31#include "mbedtls/cipher.h"
32#include "mbedtls/gcm.h"
33
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010034typedef struct {
Gilles Peskinef5d7eef2021-11-08 22:12:47 +010035 psa_algorithm_t core_alg;
36 uint8_t tag_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010037 union {
Ronald Cron46f91782021-03-17 08:16:34 +010038 unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
39#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
40 mbedtls_ccm_context ccm;
41#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
42#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
43 mbedtls_gcm_context gcm;
44#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
45#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
46 mbedtls_chachapoly_context chachapoly;
47#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
48 } ctx;
Ronald Cron46f91782021-03-17 08:16:34 +010049} aead_operation_t;
50
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010051#define AEAD_OPERATION_INIT { 0, 0, { 0 } }
Ronald Cron46f91782021-03-17 08:16:34 +010052
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010053static void psa_aead_abort_internal(aead_operation_t *operation)
Ronald Cron46f91782021-03-17 08:16:34 +010054{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010055 switch (operation->core_alg) {
Ronald Cron46f91782021-03-17 08:16:34 +010056#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
57 case PSA_ALG_CCM:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010058 mbedtls_ccm_free(&operation->ctx.ccm);
Ronald Cron46f91782021-03-17 08:16:34 +010059 break;
60#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
61#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
62 case PSA_ALG_GCM:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010063 mbedtls_gcm_free(&operation->ctx.gcm);
Ronald Cron46f91782021-03-17 08:16:34 +010064 break;
65#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
Ronald Cronb9349a62021-03-26 13:32:29 +010066#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
67 case PSA_ALG_CHACHA20_POLY1305:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010068 mbedtls_chachapoly_free(&operation->ctx.chachapoly);
Ronald Cronb9349a62021-03-26 13:32:29 +010069 break;
70#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
Ronald Cron46f91782021-03-17 08:16:34 +010071 }
72}
73
74static psa_status_t psa_aead_setup(
75 aead_operation_t *operation,
76 const psa_key_attributes_t *attributes,
77 const uint8_t *key_buffer,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010078 psa_algorithm_t alg)
Ronald Cron46f91782021-03-17 08:16:34 +010079{
80 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
81 size_t key_bits;
Ronald Cronecbc0682021-03-26 13:25:17 +010082 const mbedtls_cipher_info_t *cipher_info;
Ronald Cron46f91782021-03-17 08:16:34 +010083 mbedtls_cipher_id_t cipher_id;
Ronald Cronecbc0682021-03-26 13:25:17 +010084 size_t full_tag_length = 0;
Ronald Cron46f91782021-03-17 08:16:34 +010085
86 key_bits = attributes->core.bits;
87
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010088 cipher_info = mbedtls_cipher_info_from_psa(alg,
89 attributes->core.type, key_bits,
90 &cipher_id);
91 if (cipher_info == NULL) {
92 return PSA_ERROR_NOT_SUPPORTED;
93 }
Ronald Cron46f91782021-03-17 08:16:34 +010094
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010095 switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
Ronald Cron46f91782021-03-17 08:16:34 +010096#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010097 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Ronald Cron46f91782021-03-17 08:16:34 +010098 operation->core_alg = PSA_ALG_CCM;
Ronald Cronecbc0682021-03-26 13:25:17 +010099 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +0100100 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
101 * The call to mbedtls_ccm_encrypt_and_tag or
102 * mbedtls_ccm_auth_decrypt will validate the tag length. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100103 if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
104 return PSA_ERROR_INVALID_ARGUMENT;
105 }
Ronald Cron46f91782021-03-17 08:16:34 +0100106
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 mbedtls_ccm_init(&operation->ctx.ccm);
Ronald Cron46f91782021-03-17 08:16:34 +0100108 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100109 mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
110 key_buffer, (unsigned int) key_bits));
111 if (status != PSA_SUCCESS) {
112 return status;
113 }
Ronald Cron46f91782021-03-17 08:16:34 +0100114 break;
115#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
116
117#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100118 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Ronald Cron46f91782021-03-17 08:16:34 +0100119 operation->core_alg = PSA_ALG_GCM;
Ronald Cronecbc0682021-03-26 13:25:17 +0100120 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +0100121 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
122 * The call to mbedtls_gcm_crypt_and_tag or
123 * mbedtls_gcm_auth_decrypt will validate the tag length. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100124 if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
125 return PSA_ERROR_INVALID_ARGUMENT;
126 }
Ronald Cron46f91782021-03-17 08:16:34 +0100127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100128 mbedtls_gcm_init(&operation->ctx.gcm);
Ronald Cron46f91782021-03-17 08:16:34 +0100129 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100130 mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
131 key_buffer, (unsigned int) key_bits));
132 if (status != PSA_SUCCESS) {
133 return status;
134 }
Ronald Cron46f91782021-03-17 08:16:34 +0100135 break;
136#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
137
138#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100139 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Ronald Cron46f91782021-03-17 08:16:34 +0100140 operation->core_alg = PSA_ALG_CHACHA20_POLY1305;
Ronald Cronecbc0682021-03-26 13:25:17 +0100141 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +0100142 /* We only support the default tag length. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143 if (alg != PSA_ALG_CHACHA20_POLY1305) {
144 return PSA_ERROR_NOT_SUPPORTED;
145 }
Ronald Cron46f91782021-03-17 08:16:34 +0100146
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100147 mbedtls_chachapoly_init(&operation->ctx.chachapoly);
Ronald Cron46f91782021-03-17 08:16:34 +0100148 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100149 mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
150 key_buffer));
151 if (status != PSA_SUCCESS) {
152 return status;
153 }
Ronald Cron46f91782021-03-17 08:16:34 +0100154 break;
155#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
156
157 default:
Ronald Cron485559e2021-04-28 14:29:00 +0200158 (void) status;
159 (void) key_buffer;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron46f91782021-03-17 08:16:34 +0100161 }
162
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100163 if (PSA_AEAD_TAG_LENGTH(attributes->core.type,
164 key_bits, alg)
165 > full_tag_length) {
166 return PSA_ERROR_INVALID_ARGUMENT;
167 }
Ronald Cron46f91782021-03-17 08:16:34 +0100168
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100169 operation->tag_length = PSA_AEAD_TAG_LENGTH(attributes->core.type,
170 key_bits,
171 alg);
Ronald Cron46f91782021-03-17 08:16:34 +0100172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100173 return PSA_SUCCESS;
Ronald Cron46f91782021-03-17 08:16:34 +0100174}
175
176psa_status_t mbedtls_psa_aead_encrypt(
177 const psa_key_attributes_t *attributes,
178 const uint8_t *key_buffer, size_t key_buffer_size,
179 psa_algorithm_t alg,
180 const uint8_t *nonce, size_t nonce_length,
181 const uint8_t *additional_data, size_t additional_data_length,
182 const uint8_t *plaintext, size_t plaintext_length,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100183 uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
Ronald Cron46f91782021-03-17 08:16:34 +0100184{
185 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
186 aead_operation_t operation = AEAD_OPERATION_INIT;
187 uint8_t *tag;
188 (void) key_buffer_size;
189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100190 status = psa_aead_setup(&operation, attributes, key_buffer, alg);
191 if (status != PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100192 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100193 }
Ronald Cron46f91782021-03-17 08:16:34 +0100194
195 /* For all currently supported modes, the tag is at the end of the
196 * ciphertext. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100197 if (ciphertext_size < (plaintext_length + operation.tag_length)) {
Ronald Cron46f91782021-03-17 08:16:34 +0100198 status = PSA_ERROR_BUFFER_TOO_SMALL;
199 goto exit;
200 }
201 tag = ciphertext + plaintext_length;
202
Ronald Cron46f91782021-03-17 08:16:34 +0100203#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100204 if (operation.core_alg == PSA_ALG_CCM) {
Ronald Cron46f91782021-03-17 08:16:34 +0100205 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100206 mbedtls_ccm_encrypt_and_tag(&operation.ctx.ccm,
207 plaintext_length,
208 nonce, nonce_length,
209 additional_data,
210 additional_data_length,
211 plaintext, ciphertext,
212 tag, operation.tag_length));
213 } else
Ronald Cron46f91782021-03-17 08:16:34 +0100214#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
Ronald Cron810eb162021-04-06 09:01:39 +0200215#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100216 if (operation.core_alg == PSA_ALG_GCM) {
Ronald Cron810eb162021-04-06 09:01:39 +0200217 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100218 mbedtls_gcm_crypt_and_tag(&operation.ctx.gcm,
219 MBEDTLS_GCM_ENCRYPT,
220 plaintext_length,
221 nonce, nonce_length,
222 additional_data, additional_data_length,
223 plaintext, ciphertext,
224 operation.tag_length, tag));
225 } else
Ronald Cron810eb162021-04-06 09:01:39 +0200226#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
Ronald Cron46f91782021-03-17 08:16:34 +0100227#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100228 if (operation.core_alg == PSA_ALG_CHACHA20_POLY1305) {
229 if (nonce_length != 12) {
230 if (nonce_length == 8) {
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100231 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 } else {
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100233 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100234 }
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100235 goto exit;
236 }
237
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100238 if (operation.tag_length != 16) {
Ronald Cron46f91782021-03-17 08:16:34 +0100239 status = PSA_ERROR_NOT_SUPPORTED;
240 goto exit;
241 }
242 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100243 mbedtls_chachapoly_encrypt_and_tag(&operation.ctx.chachapoly,
244 plaintext_length,
245 nonce,
246 additional_data,
247 additional_data_length,
248 plaintext,
249 ciphertext,
250 tag));
251 } else
Ronald Cron46f91782021-03-17 08:16:34 +0100252#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
253 {
254 (void) tag;
Ronald Cron485559e2021-04-28 14:29:00 +0200255 (void) nonce;
256 (void) nonce_length;
257 (void) additional_data;
258 (void) additional_data_length;
259 (void) plaintext;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100260 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron46f91782021-03-17 08:16:34 +0100261 }
262
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100263 if (status == PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100264 *ciphertext_length = plaintext_length + operation.tag_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100265 }
Ronald Cron46f91782021-03-17 08:16:34 +0100266
267exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100268 psa_aead_abort_internal(&operation);
Ronald Cron46f91782021-03-17 08:16:34 +0100269
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100270 return status;
Ronald Cron46f91782021-03-17 08:16:34 +0100271}
272
273/* Locate the tag in a ciphertext buffer containing the encrypted data
274 * followed by the tag. Return the length of the part preceding the tag in
275 * *plaintext_length. This is the size of the plaintext in modes where
276 * the encrypted data has the same size as the plaintext, such as
277 * CCM and GCM. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length,
279 const uint8_t *ciphertext,
280 size_t ciphertext_length,
281 size_t plaintext_size,
282 const uint8_t **p_tag)
Ronald Cron46f91782021-03-17 08:16:34 +0100283{
284 size_t payload_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100285 if (tag_length > ciphertext_length) {
286 return PSA_ERROR_INVALID_ARGUMENT;
287 }
Ronald Cron46f91782021-03-17 08:16:34 +0100288 payload_length = ciphertext_length - tag_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100289 if (payload_length > plaintext_size) {
290 return PSA_ERROR_BUFFER_TOO_SMALL;
291 }
Ronald Cron46f91782021-03-17 08:16:34 +0100292 *p_tag = ciphertext + payload_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100293 return PSA_SUCCESS;
Ronald Cron46f91782021-03-17 08:16:34 +0100294}
295
296psa_status_t mbedtls_psa_aead_decrypt(
297 const psa_key_attributes_t *attributes,
298 const uint8_t *key_buffer, size_t key_buffer_size,
299 psa_algorithm_t alg,
300 const uint8_t *nonce, size_t nonce_length,
301 const uint8_t *additional_data, size_t additional_data_length,
302 const uint8_t *ciphertext, size_t ciphertext_length,
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100303 uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
Ronald Cron46f91782021-03-17 08:16:34 +0100304{
305 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
306 aead_operation_t operation = AEAD_OPERATION_INIT;
307 const uint8_t *tag = NULL;
308 (void) key_buffer_size;
309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 status = psa_aead_setup(&operation, attributes, key_buffer, alg);
311 if (status != PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100312 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100313 }
Ronald Cron46f91782021-03-17 08:16:34 +0100314
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100315 status = psa_aead_unpadded_locate_tag(operation.tag_length,
316 ciphertext, ciphertext_length,
317 plaintext_size, &tag);
318 if (status != PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100319 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100320 }
Ronald Cron46f91782021-03-17 08:16:34 +0100321
Ronald Cron46f91782021-03-17 08:16:34 +0100322#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100323 if (operation.core_alg == PSA_ALG_CCM) {
Ronald Cron46f91782021-03-17 08:16:34 +0100324 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100325 mbedtls_ccm_auth_decrypt(&operation.ctx.ccm,
326 ciphertext_length - operation.tag_length,
327 nonce, nonce_length,
328 additional_data,
329 additional_data_length,
330 ciphertext, plaintext,
331 tag, operation.tag_length));
332 } else
Ronald Cron46f91782021-03-17 08:16:34 +0100333#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
Ronald Cron810eb162021-04-06 09:01:39 +0200334#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100335 if (operation.core_alg == PSA_ALG_GCM) {
Ronald Cron810eb162021-04-06 09:01:39 +0200336 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100337 mbedtls_gcm_auth_decrypt(&operation.ctx.gcm,
338 ciphertext_length - operation.tag_length,
339 nonce, nonce_length,
340 additional_data,
341 additional_data_length,
342 tag, operation.tag_length,
343 ciphertext, plaintext));
344 } else
Ronald Cron810eb162021-04-06 09:01:39 +0200345#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
Ronald Cron46f91782021-03-17 08:16:34 +0100346#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100347 if (operation.core_alg == PSA_ALG_CHACHA20_POLY1305) {
348 if (nonce_length != 12) {
349 if (nonce_length == 8) {
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100350 status = PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100351 } else {
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100352 status = PSA_ERROR_INVALID_ARGUMENT;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100353 }
Bence Szépkúti358e0ea2021-11-17 14:03:08 +0100354 goto exit;
355 }
356
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100357 if (operation.tag_length != 16) {
Ronald Cron46f91782021-03-17 08:16:34 +0100358 status = PSA_ERROR_NOT_SUPPORTED;
359 goto exit;
360 }
361 status = mbedtls_to_psa_error(
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 mbedtls_chachapoly_auth_decrypt(&operation.ctx.chachapoly,
363 ciphertext_length - operation.tag_length,
364 nonce,
365 additional_data,
366 additional_data_length,
367 tag,
368 ciphertext,
369 plaintext));
370 } else
Ronald Cron46f91782021-03-17 08:16:34 +0100371#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
372 {
Ronald Cron485559e2021-04-28 14:29:00 +0200373 (void) nonce;
374 (void) nonce_length;
375 (void) additional_data;
376 (void) additional_data_length;
377 (void) plaintext;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron46f91782021-03-17 08:16:34 +0100379 }
380
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 if (status == PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100382 *plaintext_length = ciphertext_length - operation.tag_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100383 }
Ronald Cron46f91782021-03-17 08:16:34 +0100384
385exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100386 psa_aead_abort_internal(&operation);
Ronald Cron46f91782021-03-17 08:16:34 +0100387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 if (status == PSA_SUCCESS) {
Ronald Cron46f91782021-03-17 08:16:34 +0100389 *plaintext_length = ciphertext_length - operation.tag_length;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100390 }
391 return status;
Ronald Cron46f91782021-03-17 08:16:34 +0100392}
Ronald Cron7ceee8d2021-03-17 16:55:43 +0100393
394#endif /* MBEDTLS_PSA_CRYPTO_C */