blob: 8f8b74e7e49921d1ed116e19413e04751818f381 [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"
27
Paul Elliottadb8b162021-04-20 16:06:57 +010028#include <string.h>
29#include "mbedtls/platform.h"
30#if !defined(MBEDTLS_PLATFORM_C)
31#define mbedtls_calloc calloc
32#define mbedtls_free free
33#endif
34
Ronald Cron46f91782021-03-17 08:16:34 +010035#include "mbedtls/ccm.h"
36#include "mbedtls/chachapoly.h"
37#include "mbedtls/cipher.h"
38#include "mbedtls/gcm.h"
Paul Elliottadb8b162021-04-20 16:06:57 +010039#include "mbedtls/error.h"
Ronald Cron46f91782021-03-17 08:16:34 +010040
Paul Elliottadb8b162021-04-20 16:06:57 +010041/* Constant-time buffer comparison. This is duplication of code from
42 * psa_crypto.c, but has nowhere private I can put it for the minute. Really
43 belongs in the constant time module, when that gets implemented */
44static inline int safer_memcmp( const uint8_t *a, const uint8_t *b, size_t n )
Ronald Cron46f91782021-03-17 08:16:34 +010045{
Paul Elliottadb8b162021-04-20 16:06:57 +010046 size_t i;
47 unsigned char diff = 0;
48
49 for( i = 0; i < n; i++ )
50 diff |= a[i] ^ b[i];
51
52 return( diff );
Ronald Cron46f91782021-03-17 08:16:34 +010053}
54
Paul Elliottadb8b162021-04-20 16:06:57 +010055
Ronald Cron46f91782021-03-17 08:16:34 +010056static psa_status_t psa_aead_setup(
Paul Elliottcbbde5f2021-05-10 18:19:46 +010057 mbedtls_psa_aead_operation_t *operation,
Ronald Cron46f91782021-03-17 08:16:34 +010058 const psa_key_attributes_t *attributes,
59 const uint8_t *key_buffer,
60 psa_algorithm_t alg )
61{
62 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
63 size_t key_bits;
Ronald Cronecbc0682021-03-26 13:25:17 +010064 const mbedtls_cipher_info_t *cipher_info;
Ronald Cron46f91782021-03-17 08:16:34 +010065 mbedtls_cipher_id_t cipher_id;
Ronald Cronecbc0682021-03-26 13:25:17 +010066 size_t full_tag_length = 0;
Ronald Cron46f91782021-03-17 08:16:34 +010067
68 key_bits = attributes->core.bits;
69
Ronald Cronecbc0682021-03-26 13:25:17 +010070 cipher_info = mbedtls_cipher_info_from_psa( alg,
71 attributes->core.type, key_bits,
72 &cipher_id );
73 if( cipher_info == NULL )
Ronald Cron46f91782021-03-17 08:16:34 +010074 return( PSA_ERROR_NOT_SUPPORTED );
75
76 switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) )
77 {
78#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
79 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
Paul Elliott07a30c42021-04-20 14:13:23 +010080 operation->alg = PSA_ALG_CCM;
Ronald Cronecbc0682021-03-26 13:25:17 +010081 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +010082 /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
83 * The call to mbedtls_ccm_encrypt_and_tag or
84 * mbedtls_ccm_auth_decrypt will validate the tag length. */
85 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 )
86 return( PSA_ERROR_INVALID_ARGUMENT );
87
88 mbedtls_ccm_init( &operation->ctx.ccm );
89 status = mbedtls_to_psa_error(
90 mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id,
91 key_buffer, (unsigned int) key_bits ) );
92 if( status != PSA_SUCCESS )
93 return( status );
94 break;
95#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
96
97#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
98 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
Paul Elliott07a30c42021-04-20 14:13:23 +010099 operation->alg = PSA_ALG_GCM;
Ronald Cronecbc0682021-03-26 13:25:17 +0100100 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +0100101 /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
102 * The call to mbedtls_gcm_crypt_and_tag or
103 * mbedtls_gcm_auth_decrypt will validate the tag length. */
104 if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 )
105 return( PSA_ERROR_INVALID_ARGUMENT );
106
107 mbedtls_gcm_init( &operation->ctx.gcm );
108 status = mbedtls_to_psa_error(
109 mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id,
110 key_buffer, (unsigned int) key_bits ) );
111 if( status != PSA_SUCCESS )
112 return( status );
113 break;
114#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
115
116#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
117 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
Paul Elliott07a30c42021-04-20 14:13:23 +0100118 operation->alg = PSA_ALG_CHACHA20_POLY1305;
Ronald Cronecbc0682021-03-26 13:25:17 +0100119 full_tag_length = 16;
Ronald Cron46f91782021-03-17 08:16:34 +0100120 /* We only support the default tag length. */
121 if( alg != PSA_ALG_CHACHA20_POLY1305 )
122 return( PSA_ERROR_NOT_SUPPORTED );
123
124 mbedtls_chachapoly_init( &operation->ctx.chachapoly );
125 status = mbedtls_to_psa_error(
126 mbedtls_chachapoly_setkey( &operation->ctx.chachapoly,
127 key_buffer ) );
128 if( status != PSA_SUCCESS )
129 return( status );
130 break;
131#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
132
133 default:
134 return( PSA_ERROR_NOT_SUPPORTED );
135 }
136
Bence Szépkútiec174e22021-03-19 18:46:15 +0100137 if( PSA_AEAD_TAG_LENGTH( attributes->core.type,
138 key_bits, alg )
139 > full_tag_length )
Ronald Cron46f91782021-03-17 08:16:34 +0100140 return( PSA_ERROR_INVALID_ARGUMENT );
141
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100142 operation->key_type = psa_get_key_type( attributes );
143
144 operation->tag_length = PSA_AEAD_TAG_LENGTH( operation->key_type,
Bence Szépkútiec174e22021-03-19 18:46:15 +0100145 key_bits,
146 alg );
Ronald Cron46f91782021-03-17 08:16:34 +0100147
148 return( PSA_SUCCESS );
149}
150
151psa_status_t mbedtls_psa_aead_encrypt(
152 const psa_key_attributes_t *attributes,
153 const uint8_t *key_buffer, size_t key_buffer_size,
154 psa_algorithm_t alg,
155 const uint8_t *nonce, size_t nonce_length,
156 const uint8_t *additional_data, size_t additional_data_length,
157 const uint8_t *plaintext, size_t plaintext_length,
158 uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length )
159{
160 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100161 mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
Ronald Cron46f91782021-03-17 08:16:34 +0100162 uint8_t *tag;
163 (void) key_buffer_size;
164
165 status = psa_aead_setup( &operation, attributes, key_buffer, alg );
166 if( status != PSA_SUCCESS )
167 goto exit;
168
169 /* For all currently supported modes, the tag is at the end of the
170 * ciphertext. */
171 if( ciphertext_size < ( plaintext_length + operation.tag_length ) )
172 {
173 status = PSA_ERROR_BUFFER_TOO_SMALL;
174 goto exit;
175 }
176 tag = ciphertext + plaintext_length;
177
Ronald Cron46f91782021-03-17 08:16:34 +0100178#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Paul Elliott07a30c42021-04-20 14:13:23 +0100179 if( operation.alg == PSA_ALG_CCM )
Ronald Cron46f91782021-03-17 08:16:34 +0100180 {
181 status = mbedtls_to_psa_error(
182 mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm,
183 plaintext_length,
184 nonce, nonce_length,
185 additional_data,
186 additional_data_length,
187 plaintext, ciphertext,
188 tag, operation.tag_length ) );
189 }
190 else
191#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
Ronald Cron810eb162021-04-06 09:01:39 +0200192#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Paul Elliott07a30c42021-04-20 14:13:23 +0100193 if( operation.alg == PSA_ALG_GCM )
Ronald Cron810eb162021-04-06 09:01:39 +0200194 {
195 status = mbedtls_to_psa_error(
196 mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm,
197 MBEDTLS_GCM_ENCRYPT,
198 plaintext_length,
199 nonce, nonce_length,
200 additional_data, additional_data_length,
201 plaintext, ciphertext,
202 operation.tag_length, tag ) );
203 }
204 else
205#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
Ronald Cron46f91782021-03-17 08:16:34 +0100206#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Paul Elliott07a30c42021-04-20 14:13:23 +0100207 if( operation.alg == PSA_ALG_CHACHA20_POLY1305 )
Ronald Cron46f91782021-03-17 08:16:34 +0100208 {
209 if( nonce_length != 12 || operation.tag_length != 16 )
210 {
211 status = PSA_ERROR_NOT_SUPPORTED;
212 goto exit;
213 }
214 status = mbedtls_to_psa_error(
215 mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly,
216 plaintext_length,
217 nonce,
218 additional_data,
219 additional_data_length,
220 plaintext,
221 ciphertext,
222 tag ) );
223 }
224 else
225#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
226 {
227 (void) tag;
228 return( PSA_ERROR_NOT_SUPPORTED );
229 }
230
231 if( status == PSA_SUCCESS )
232 *ciphertext_length = plaintext_length + operation.tag_length;
233
234exit:
Paul Elliottadb8b162021-04-20 16:06:57 +0100235 mbedtls_psa_aead_abort( &operation );
Ronald Cron46f91782021-03-17 08:16:34 +0100236
237 return( status );
238}
239
240/* Locate the tag in a ciphertext buffer containing the encrypted data
241 * followed by the tag. Return the length of the part preceding the tag in
242 * *plaintext_length. This is the size of the plaintext in modes where
243 * the encrypted data has the same size as the plaintext, such as
244 * CCM and GCM. */
245static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length,
246 const uint8_t *ciphertext,
247 size_t ciphertext_length,
248 size_t plaintext_size,
249 const uint8_t **p_tag )
250{
251 size_t payload_length;
252 if( tag_length > ciphertext_length )
253 return( PSA_ERROR_INVALID_ARGUMENT );
254 payload_length = ciphertext_length - tag_length;
255 if( payload_length > plaintext_size )
256 return( PSA_ERROR_BUFFER_TOO_SMALL );
257 *p_tag = ciphertext + payload_length;
258 return( PSA_SUCCESS );
259}
260
261psa_status_t mbedtls_psa_aead_decrypt(
262 const psa_key_attributes_t *attributes,
263 const uint8_t *key_buffer, size_t key_buffer_size,
264 psa_algorithm_t alg,
265 const uint8_t *nonce, size_t nonce_length,
266 const uint8_t *additional_data, size_t additional_data_length,
267 const uint8_t *ciphertext, size_t ciphertext_length,
268 uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length )
269{
270 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100271 mbedtls_psa_aead_operation_t operation = MBEDTLS_PSA_AEAD_OPERATION_INIT;
Ronald Cron46f91782021-03-17 08:16:34 +0100272 const uint8_t *tag = NULL;
273 (void) key_buffer_size;
274
275 status = psa_aead_setup( &operation, attributes, key_buffer, alg );
276 if( status != PSA_SUCCESS )
277 goto exit;
278
279 status = psa_aead_unpadded_locate_tag( operation.tag_length,
280 ciphertext, ciphertext_length,
281 plaintext_size, &tag );
282 if( status != PSA_SUCCESS )
283 goto exit;
284
Ronald Cron46f91782021-03-17 08:16:34 +0100285#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Paul Elliott07a30c42021-04-20 14:13:23 +0100286 if( operation.alg == PSA_ALG_CCM )
Ronald Cron46f91782021-03-17 08:16:34 +0100287 {
288 status = mbedtls_to_psa_error(
289 mbedtls_ccm_auth_decrypt( &operation.ctx.ccm,
290 ciphertext_length - operation.tag_length,
291 nonce, nonce_length,
292 additional_data,
293 additional_data_length,
294 ciphertext, plaintext,
295 tag, operation.tag_length ) );
296 }
297 else
298#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
Ronald Cron810eb162021-04-06 09:01:39 +0200299#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Paul Elliott07a30c42021-04-20 14:13:23 +0100300 if( operation.alg == PSA_ALG_GCM )
Ronald Cron810eb162021-04-06 09:01:39 +0200301 {
302 status = mbedtls_to_psa_error(
303 mbedtls_gcm_auth_decrypt( &operation.ctx.gcm,
304 ciphertext_length - operation.tag_length,
305 nonce, nonce_length,
306 additional_data,
307 additional_data_length,
308 tag, operation.tag_length,
309 ciphertext, plaintext ) );
310 }
311 else
312#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
Ronald Cron46f91782021-03-17 08:16:34 +0100313#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Paul Elliott07a30c42021-04-20 14:13:23 +0100314 if( operation.alg == PSA_ALG_CHACHA20_POLY1305 )
Ronald Cron46f91782021-03-17 08:16:34 +0100315 {
316 if( nonce_length != 12 || operation.tag_length != 16 )
317 {
318 status = PSA_ERROR_NOT_SUPPORTED;
319 goto exit;
320 }
321 status = mbedtls_to_psa_error(
322 mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly,
323 ciphertext_length - operation.tag_length,
324 nonce,
325 additional_data,
326 additional_data_length,
327 tag,
328 ciphertext,
329 plaintext ) );
330 }
331 else
332#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
333 {
334 return( PSA_ERROR_NOT_SUPPORTED );
335 }
336
337 if( status == PSA_SUCCESS )
338 *plaintext_length = ciphertext_length - operation.tag_length;
339
340exit:
Paul Elliottadb8b162021-04-20 16:06:57 +0100341 mbedtls_psa_aead_abort( &operation );
Ronald Cron46f91782021-03-17 08:16:34 +0100342
343 if( status == PSA_SUCCESS )
344 *plaintext_length = ciphertext_length - operation.tag_length;
345 return( status );
346}
Ronald Cron7ceee8d2021-03-17 16:55:43 +0100347
Paul Elliottadb8b162021-04-20 16:06:57 +0100348/* Set the key and algorithm for a multipart authenticated encryption
349 * operation. */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100350psa_status_t mbedtls_psa_aead_encrypt_setup( mbedtls_psa_aead_operation_t
351 *operation,
Paul Elliott2df40052021-05-07 17:52:18 +0100352 const psa_key_attributes_t
353 *attributes,
354 const uint8_t *key_buffer,
355 size_t key_buffer_size,
Paul Elliottadb8b162021-04-20 16:06:57 +0100356 psa_algorithm_t alg )
357{
358 psa_status_t status;
359
360 (void) key_buffer_size;
361
362 status = psa_aead_setup( operation, attributes, key_buffer, alg );
363
364 if( status == PSA_SUCCESS )
365 {
366 operation->is_encrypt = 1;
367 }
368
369 return ( status );
370}
371
372/* Set the key and algorithm for a multipart authenticated decryption
373 * operation. */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100374psa_status_t mbedtls_psa_aead_decrypt_setup( mbedtls_psa_aead_operation_t
375 *operation,
Paul Elliott2df40052021-05-07 17:52:18 +0100376 const psa_key_attributes_t
377 *attributes,
378 const uint8_t *key_buffer,
379 size_t key_buffer_size,
Paul Elliottadb8b162021-04-20 16:06:57 +0100380 psa_algorithm_t alg )
381{
382 psa_status_t status;
383
384 (void) key_buffer_size;
385
386 status = psa_aead_setup( operation, attributes, key_buffer, alg );
387
388 if( status == PSA_SUCCESS )
389 {
390 operation->is_encrypt = 0;
391 }
392
393 return ( status );
394}
395
Paul Elliottadb8b162021-04-20 16:06:57 +0100396/* Set a nonce for the multipart AEAD operation*/
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100397psa_status_t mbedtls_psa_aead_set_nonce( mbedtls_psa_aead_operation_t
398 *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100399 const uint8_t *nonce,
400 size_t nonce_length )
401{
402 psa_status_t status;
403
Paul Elliottadb8b162021-04-20 16:06:57 +0100404 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
405 if( operation->alg == PSA_ALG_GCM )
406 {
407 /* GCM sets nonce once additional data has been supplied */
408 memcpy(operation->nonce, nonce, nonce_length);
409
410 /* We know that nonce size cannot exceed the uint8_t size */
411 operation->nonce_length = ( uint8_t ) nonce_length;
412 status = PSA_SUCCESS;
413 }
414 else
415#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
416#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
417 if( operation->alg == PSA_ALG_CCM )
418 {
419 /* Multipart CCM not supported as yet, so CCM is basically operating
420 in oneshot mode. Store the nonce as we need this later */
421 memcpy(operation->nonce, nonce, nonce_length);
422
423 /* We know that nonce size cannot exceed the uint8_t size */
424 operation->nonce_length = ( uint8_t ) nonce_length;
425 status = PSA_SUCCESS;
426 }
427 else
428#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
429#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
430 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
431 {
432 if( nonce_length != 12 && nonce_length != 8)
433 {
434 return( PSA_ERROR_INVALID_ARGUMENT );
435 }
436
Paul Elliott2df40052021-05-07 17:52:18 +0100437 status = mbedtls_to_psa_error(
438 mbedtls_chachapoly_starts( &operation->ctx.chachapoly,
439 nonce,
440 operation->is_encrypt ?
441 MBEDTLS_CHACHAPOLY_ENCRYPT :
442 MBEDTLS_CHACHAPOLY_DECRYPT ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100443 }
444 else
445#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
446 {
447 ( void ) nonce;
448 ( void ) nonce_length;
449
450 return ( PSA_ERROR_NOT_SUPPORTED );
451 }
452
Paul Elliottadb8b162021-04-20 16:06:57 +0100453 return( status );
454}
455 /* Declare the lengths of the message and additional data for AEAD. */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100456psa_status_t mbedtls_psa_aead_set_lengths( mbedtls_psa_aead_operation_t
457 *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100458 size_t ad_length,
459 size_t plaintext_length )
460{
461
Paul Elliottadb8b162021-04-20 16:06:57 +0100462#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
463 if( operation->alg == PSA_ALG_GCM )
464 {
465#if SIZE_MAX > UINT32_MAX
466 if( ( (uint64_t) ad_length ) >> 61 != 0 ||
467 ( (uint64_t) plaintext_length ) > 0xFFFFFFFE0ull )
468 {
469 return ( PSA_ERROR_INVALID_ARGUMENT );
470 }
471#endif
472 }
473 else
474#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
475#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
476 if( operation->alg == PSA_ALG_CCM )
477 {
478 if( ad_length > 0xFF00 )
479 {
480 return ( PSA_ERROR_INVALID_ARGUMENT );
481 }
482 }
483 else
484#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
485#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
486 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
487 {
488 /* No length restrictions for ChaChaPoly. */
489 }
490 else
491#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
492 {
493 ( void ) ad_length;
494 ( void ) plaintext_length;
495
496 return ( PSA_ERROR_NOT_SUPPORTED );
497 }
498
499 operation->ad_remaining = ad_length;
500 operation->body_remaining = plaintext_length;
501 operation->lengths_set = 1;
502
503 return ( PSA_SUCCESS );
504}
505
506/* Pass additional data to an active multipart AEAD operation. */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100507psa_status_t mbedtls_psa_aead_update_ad( mbedtls_psa_aead_operation_t
508 *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100509 const uint8_t *input,
510 size_t input_length )
511{
512 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
513
Paul Elliottadb8b162021-04-20 16:06:57 +0100514 if( operation->lengths_set )
515 {
516 if ( operation->ad_remaining < input_length )
517 {
518 return( PSA_ERROR_INVALID_ARGUMENT );
519 }
520
521 operation->ad_remaining -= input_length;
522 }
523
524#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
525 if( operation->alg == PSA_ALG_GCM )
526 {
527 if( !operation->lengths_set || operation->ad_started )
528 {
529 return( PSA_ERROR_BAD_STATE );
530 }
531
532 /* GCM currently requires all the additional data to be passed in in
533 * one contigious buffer, so until that is re-done, we have to enforce
534 * this, as we cannot allocate a buffer to collate multiple calls into.
535 */
Paul Elliott72c10082021-04-23 19:02:16 +0100536 if( operation->ad_remaining != 0 )
Paul Elliottadb8b162021-04-20 16:06:57 +0100537 {
538 return ( PSA_ERROR_INVALID_ARGUMENT );
539 }
540
Paul Elliott2df40052021-05-07 17:52:18 +0100541 status = mbedtls_to_psa_error(
542 mbedtls_gcm_starts( &operation->ctx.gcm,
543 operation->is_encrypt ?
544 MBEDTLS_GCM_ENCRYPT : MBEDTLS_GCM_DECRYPT,
545 operation->nonce,
546 operation->nonce_length,
547 input,
548 input_length ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100549
550 }
551 else
552#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
553#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
554 if( operation->alg == PSA_ALG_CCM )
555 {
556 /* CCM requires all additional data to be passed in in one go at the
557 minute, as we are basically operating in oneshot mode. */
Paul Elliott72c10082021-04-23 19:02:16 +0100558 if( operation->ad_started )
Paul Elliottadb8b162021-04-20 16:06:57 +0100559 {
560 return( PSA_ERROR_BAD_STATE );
561 }
562
563 /* Save the additional data for later, this will be passed in
564 when we have the body. */
565 operation->ad_buffer = ( uint8_t * ) mbedtls_calloc(1, input_length );
566
567 if( operation->ad_buffer )
568 {
569 memcpy( operation->ad_buffer, input, input_length );
570 operation->ad_length = input_length;
Paul Elliott72c10082021-04-23 19:02:16 +0100571 status = PSA_SUCCESS;
Paul Elliottadb8b162021-04-20 16:06:57 +0100572 }
573 else
574 {
575 return ( PSA_ERROR_INSUFFICIENT_MEMORY );
576 }
577 }
578 else
579#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
580#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
581 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
582 {
Paul Elliott2df40052021-05-07 17:52:18 +0100583 status = mbedtls_to_psa_error(
584 mbedtls_chachapoly_update_aad( &operation->ctx.chachapoly,
585 input,
586 input_length ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100587 }
588 else
589#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
590 {
591 (void) input;
592 (void) input_length;
593
594 return ( PSA_ERROR_NOT_SUPPORTED );
595 }
596
597 if( status == PSA_SUCCESS )
598 {
599 operation->ad_started = 1;
600 }
601
602 return ( status );
603}
604
605/* Encrypt or decrypt a message fragment in an active multipart AEAD
606 * operation.*/
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100607psa_status_t mbedtls_psa_aead_update( mbedtls_psa_aead_operation_t *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100608 const uint8_t *input,
609 size_t input_length,
610 uint8_t *output,
611 size_t output_size,
612 size_t *output_length )
613{
614 size_t update_output_size;
615 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Paul Elliottfd3ca242021-04-25 18:10:42 +0100616 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Elliottadb8b162021-04-20 16:06:57 +0100617
Paul Elliottfd3ca242021-04-25 18:10:42 +0100618 update_output_size = input_length;
Paul Elliottadb8b162021-04-20 16:06:57 +0100619
Paul Elliott72c10082021-04-23 19:02:16 +0100620 if( PSA_AEAD_UPDATE_OUTPUT_SIZE( operation->key_type, operation->alg,
621 input_length ) > output_size )
Paul Elliottadb8b162021-04-20 16:06:57 +0100622 {
623 return ( PSA_ERROR_BUFFER_TOO_SMALL );
624 }
625
626 if( operation->lengths_set)
627 {
628 /* Additional data length was supplied, but not all the additional
629 data was supplied.*/
630 if( operation->ad_remaining != 0 )
631 {
632 return ( PSA_ERROR_INVALID_ARGUMENT );
633 }
634
635 /* Too much data provided. */
636 if( operation->body_remaining < input_length )
637 {
638 return ( PSA_ERROR_INVALID_ARGUMENT );
639 }
640
641 operation->body_remaining -= input_length;
642 }
643
644#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
645 if( operation->alg == PSA_ALG_GCM )
646 {
647 /* For the time being set the requirement that all of the body data
648 * must be passed in in one update, rather than deal with the complexity
649 * of non block size aligned updates. This will be fixed in 3.0 when
650 we can change the signature of the GCM multipart functions */
651 if( !operation->lengths_set || operation->body_remaining != 0 )
652 {
653 return( PSA_ERROR_BAD_STATE );
654 }
655
Paul Elliott72c10082021-04-23 19:02:16 +0100656 if( !operation->ad_started )
Paul Elliottadb8b162021-04-20 16:06:57 +0100657 {
658 return( PSA_ERROR_BAD_STATE );
659 }
660
661 status = mbedtls_to_psa_error( mbedtls_gcm_update( &operation->ctx.gcm,
662 input_length,
663 input,
664 output ) );
665 }
666 else
667#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
668#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
669 if( operation->alg == PSA_ALG_CCM )
670 {
671 /* CCM dooes not support multipart yet, so all the input has to be
Paul Elliottfd3ca242021-04-25 18:10:42 +0100672 passed in in one go. */
Paul Elliott72c10082021-04-23 19:02:16 +0100673 if( operation->body_started )
Paul Elliottadb8b162021-04-20 16:06:57 +0100674 {
675 return( PSA_ERROR_BAD_STATE );
676 }
677
Paul Elliottfd3ca242021-04-25 18:10:42 +0100678 /* Need to store tag for Finish() / Verify() */
Paul Elliott2df40052021-05-07 17:52:18 +0100679 operation->tag_buffer =
680 ( uint8_t * ) mbedtls_calloc(1, operation->tag_length );
Paul Elliottadb8b162021-04-20 16:06:57 +0100681
Paul Elliottfd3ca242021-04-25 18:10:42 +0100682 if( operation->tag_buffer )
Paul Elliottadb8b162021-04-20 16:06:57 +0100683 {
Paul Elliottfd3ca242021-04-25 18:10:42 +0100684
685 if( operation->is_encrypt )
686 {
687 /* Perform oneshot CCM encryption with additional data already
688 stored, as CCM does not support multipart yet.*/
Paul Elliott2df40052021-05-07 17:52:18 +0100689 status = mbedtls_to_psa_error(
690 mbedtls_ccm_encrypt_and_tag( &operation->ctx.ccm,
691 input_length,
692 operation->nonce,
693 operation->nonce_length,
694 operation->ad_buffer,
695 operation->ad_length,
696 input,
697 output,
698 operation->tag_buffer,
699 operation->tag_length ) );
Paul Elliottfd3ca242021-04-25 18:10:42 +0100700
701 /* Even if the above operation fails, we no longer need the
702 additional data.*/
703 mbedtls_free(operation->ad_buffer);
704 operation->ad_buffer = NULL;
705 operation->ad_length = 0;
706 }
707 else
708 {
709 /* Need to back up the body data so we can do this again
710 later.*/
Paul Elliott2df40052021-05-07 17:52:18 +0100711 operation->body_buffer =
712 ( uint8_t * ) mbedtls_calloc(1, input_length );
Paul Elliottfd3ca242021-04-25 18:10:42 +0100713
714 if( operation->body_buffer )
715 {
716 memcpy( operation->body_buffer, input, input_length );
717 operation->body_length = input_length;
718
Paul Elliott2df40052021-05-07 17:52:18 +0100719 /* this will fail, as the tag is clearly false, but will
720 write the decrypted data to the output buffer.*/
721 ret = mbedtls_ccm_auth_decrypt( &operation->ctx.ccm,
722 input_length,
723 operation->nonce,
724 operation->nonce_length,
725 operation->ad_buffer,
726 operation->ad_length,
Paul Elliottfd3ca242021-04-25 18:10:42 +0100727 input, output,
728 operation->tag_buffer,
729 operation->tag_length );
730
731 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
732 {
733 status = PSA_SUCCESS;
734 }
735 else
736 {
737 status = mbedtls_to_psa_error( ret );
738 }
739 }
740 else
741 {
742 status = PSA_ERROR_INSUFFICIENT_MEMORY;
743 }
744 }
Paul Elliottadb8b162021-04-20 16:06:57 +0100745 }
746 else
747 {
Paul Elliottfd3ca242021-04-25 18:10:42 +0100748 status = PSA_ERROR_INSUFFICIENT_MEMORY;
Paul Elliottadb8b162021-04-20 16:06:57 +0100749 }
Paul Elliottadb8b162021-04-20 16:06:57 +0100750 }
751 else
752#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
753#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
754 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
755 {
Paul Elliott2df40052021-05-07 17:52:18 +0100756 status = mbedtls_to_psa_error(
757 mbedtls_chachapoly_update( &operation->ctx.chachapoly,
758 input_length,
759 input,
760 output ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100761 }
762 else
763#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
764 {
765 (void) input;
766 (void) input_length;
767
768 return ( PSA_ERROR_NOT_SUPPORTED );
769 }
770
771 if( status == PSA_SUCCESS )
772 {
773 *output_length = update_output_size;
774 operation->body_started = 1;
775 }
776
777 return( status );
778}
779
780/* Common checks for both mbedtls_psa_aead_finish() and
781 mbedtls_psa_aead_verify() */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100782static psa_status_t mbedtls_psa_aead_finish_checks( mbedtls_psa_aead_operation_t
Paul Elliott2df40052021-05-07 17:52:18 +0100783 *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100784 size_t output_size,
Paul Elliottfd3ca242021-04-25 18:10:42 +0100785 size_t tag_size )
Paul Elliottadb8b162021-04-20 16:06:57 +0100786{
Paul Elliottfd3ca242021-04-25 18:10:42 +0100787 size_t finish_output_size;
788
Paul Elliottadb8b162021-04-20 16:06:57 +0100789 if( operation->lengths_set )
790 {
791 if( operation->ad_remaining != 0 || operation->body_remaining != 0 )
792 {
793 return( PSA_ERROR_BAD_STATE );
794 }
795 }
796
Paul Elliottfd3ca242021-04-25 18:10:42 +0100797 if( tag_size < operation->tag_length )
Paul Elliottadb8b162021-04-20 16:06:57 +0100798 {
799 return ( PSA_ERROR_BUFFER_TOO_SMALL );
800 }
801
Paul Elliottfd3ca242021-04-25 18:10:42 +0100802 if( operation->is_encrypt )
Paul Elliottadb8b162021-04-20 16:06:57 +0100803 {
Paul Elliott2df40052021-05-07 17:52:18 +0100804 finish_output_size =
805 PSA_AEAD_FINISH_OUTPUT_SIZE( operation->key_type,
806 operation->alg );
Paul Elliottadb8b162021-04-20 16:06:57 +0100807 }
808 else
809 {
Paul Elliott2df40052021-05-07 17:52:18 +0100810 finish_output_size =
811 PSA_AEAD_VERIFY_OUTPUT_SIZE( operation->key_type,
812 operation->alg );
Paul Elliottadb8b162021-04-20 16:06:57 +0100813 }
814
Paul Elliottfd3ca242021-04-25 18:10:42 +0100815 if( output_size < finish_output_size )
Paul Elliottadb8b162021-04-20 16:06:57 +0100816 {
817 return ( PSA_ERROR_BUFFER_TOO_SMALL );
818 }
819
820 return ( PSA_SUCCESS );
Paul Elliottadb8b162021-04-20 16:06:57 +0100821}
822
823/* Finish encrypting a message in a multipart AEAD operation. */
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100824psa_status_t mbedtls_psa_aead_finish( mbedtls_psa_aead_operation_t *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100825 uint8_t *ciphertext,
826 size_t ciphertext_size,
827 size_t *ciphertext_length,
828 uint8_t *tag,
829 size_t tag_size,
830 size_t *tag_length )
831{
832 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Paul Elliottfd3ca242021-04-25 18:10:42 +0100833 size_t finish_output_size = 0;
Paul Elliottadb8b162021-04-20 16:06:57 +0100834
Paul Elliott2df40052021-05-07 17:52:18 +0100835 status = mbedtls_psa_aead_finish_checks( operation, ciphertext_size,
836 tag_size );
Paul Elliottadb8b162021-04-20 16:06:57 +0100837
838 if( status != PSA_SUCCESS )
839 {
840 return status;
841 }
842
843#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
844 if( operation->alg == PSA_ALG_GCM )
845 {
846 /* We will need to do final GCM pass in here when multipart is done. */
847 status = mbedtls_to_psa_error( mbedtls_gcm_finish( &operation->ctx.gcm,
848 tag,
849 tag_size ) );
850 }
851 else
852#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
853#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
854 if( operation->alg == PSA_ALG_CCM )
855 {
Paul Elliottfd3ca242021-04-25 18:10:42 +0100856 /* Copy the previously generated tag into place */
857 memcpy( tag, operation->tag_buffer, operation->tag_length );
Paul Elliottadb8b162021-04-20 16:06:57 +0100858
Paul Elliottfd3ca242021-04-25 18:10:42 +0100859 mbedtls_free(operation->tag_buffer);
860 operation->tag_buffer = NULL;
Paul Elliottadb8b162021-04-20 16:06:57 +0100861
Paul Elliottfd3ca242021-04-25 18:10:42 +0100862 status = PSA_SUCCESS;
Paul Elliottadb8b162021-04-20 16:06:57 +0100863 }
864 else
865#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
866#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
867 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
868 {
Paul Elliott2df40052021-05-07 17:52:18 +0100869 status = mbedtls_to_psa_error(
870 mbedtls_chachapoly_finish( &operation->ctx.chachapoly,
871 tag ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100872 }
873 else
874#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
875 {
876 ( void ) ciphertext;
877 ( void ) ciphertext_size;
878 ( void ) ciphertext_length;
879 ( void ) tag;
880 ( void ) tag_size;
881 ( void ) tag_length;
882
883 return ( PSA_ERROR_NOT_SUPPORTED );
884 }
885
886 if( status == PSA_SUCCESS )
887 {
888 *ciphertext_length = finish_output_size;
Paul Elliottfd3ca242021-04-25 18:10:42 +0100889 *tag_length = operation->tag_length;
Paul Elliottadb8b162021-04-20 16:06:57 +0100890 }
891
892 mbedtls_psa_aead_abort(operation);
893
894 return ( status );
895}
896
897/* Finish authenticating and decrypting a message in a multipart AEAD
898 * operation.*/
Paul Elliottcbbde5f2021-05-10 18:19:46 +0100899psa_status_t mbedtls_psa_aead_verify( mbedtls_psa_aead_operation_t *operation,
Paul Elliottadb8b162021-04-20 16:06:57 +0100900 uint8_t *plaintext,
901 size_t plaintext_size,
902 size_t *plaintext_length,
903 const uint8_t *tag,
904 size_t tag_length )
905{
906 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
907 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
908
Paul Elliottfd3ca242021-04-25 18:10:42 +0100909 uint8_t * temp_buffer;
910 size_t temp_buffer_size;
911
912 size_t finish_output_size = 0;
Paul Elliottadb8b162021-04-20 16:06:57 +0100913
914 int do_tag_check = 1;
915 uint8_t check_tag[16];
916
Paul Elliott2df40052021-05-07 17:52:18 +0100917 status = mbedtls_psa_aead_finish_checks( operation, plaintext_size,
918 tag_length );
Paul Elliottadb8b162021-04-20 16:06:57 +0100919
920 if( status != PSA_SUCCESS )
921 {
922 return status;
923 }
924
925#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
926 if( operation->alg == PSA_ALG_GCM )
927 {
928 /* Call finish to get the tag for comparison */
Paul Elliott2df40052021-05-07 17:52:18 +0100929 status = mbedtls_to_psa_error(
930 mbedtls_gcm_finish( &operation->ctx.gcm,
931 check_tag,
932 operation->tag_length ) );
Paul Elliottadb8b162021-04-20 16:06:57 +0100933 }
934 else
935#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
936#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
937 if( operation->alg == PSA_ALG_CCM )
938 {
Paul Elliottfd3ca242021-04-25 18:10:42 +0100939 if( !operation->ad_buffer || !operation->body_buffer )
Paul Elliottadb8b162021-04-20 16:06:57 +0100940 {
941 return( PSA_ERROR_BAD_STATE );
942 }
943
Paul Elliottfd3ca242021-04-25 18:10:42 +0100944 /* Perform oneshot CCM decryption *again*, as its the
945 * only way to get the tag, but this time throw away the
946 results, as verify cannot write that much data. */
947 temp_buffer_size = PSA_AEAD_UPDATE_OUTPUT_SIZE( operation->key_type,
Paul Elliott2df40052021-05-07 17:52:18 +0100948 operation->alg,
949 operation->body_length
950 );
Paul Elliottadb8b162021-04-20 16:06:57 +0100951
Paul Elliottfd3ca242021-04-25 18:10:42 +0100952 temp_buffer = ( uint8_t * ) mbedtls_calloc(1, temp_buffer_size );
Paul Elliottadb8b162021-04-20 16:06:57 +0100953
Paul Elliottfd3ca242021-04-25 18:10:42 +0100954 if( temp_buffer )
Paul Elliottadb8b162021-04-20 16:06:57 +0100955 {
Paul Elliott2df40052021-05-07 17:52:18 +0100956 ret = mbedtls_ccm_auth_decrypt( &operation->ctx.ccm,
957 operation->body_length,
958 operation->nonce,
959 operation->nonce_length,
960 operation->ad_buffer,
961 operation->ad_length,
962 operation->body_buffer,
963 temp_buffer, tag, tag_length );
Paul Elliottfd3ca242021-04-25 18:10:42 +0100964
965 if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED )
966 {
967 status = PSA_ERROR_INVALID_SIGNATURE;
968 }
969 else
970 {
971 status = mbedtls_to_psa_error( ret );
972 do_tag_check = 0;
973 }
Paul Elliottadb8b162021-04-20 16:06:57 +0100974 }
975 else
976 {
Paul Elliottfd3ca242021-04-25 18:10:42 +0100977 status = PSA_ERROR_INSUFFICIENT_MEMORY;
Paul Elliottadb8b162021-04-20 16:06:57 +0100978 }
979
980 /* Even if the above operation fails, we no longer need the data */
Paul Elliottfd3ca242021-04-25 18:10:42 +0100981 mbedtls_free(temp_buffer);
Paul Elliottadb8b162021-04-20 16:06:57 +0100982
Paul Elliottfd3ca242021-04-25 18:10:42 +0100983 mbedtls_free(operation->body_buffer);
984 operation->body_buffer = NULL;
985 operation->body_length = 0;
986
987 mbedtls_free(operation->tag_buffer);
988 operation->tag_buffer = NULL;
Paul Elliottadb8b162021-04-20 16:06:57 +0100989 }
990 else
991#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
992#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
993 if( operation->alg == PSA_ALG_CHACHA20_POLY1305 )
994 {
995 // call finish to get the tag for comparison.
Paul Elliott2df40052021-05-07 17:52:18 +0100996 status = mbedtls_to_psa_error(
997 mbedtls_chachapoly_finish( &operation->ctx.chachapoly,
998 check_tag ) );
Paul Elliottfd3ca242021-04-25 18:10:42 +0100999
Paul Elliottadb8b162021-04-20 16:06:57 +01001000 }
1001 else
1002#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
1003 {
1004 ( void ) plaintext;
1005 ( void ) plaintext_size;
1006 ( void ) plaintext_length;
1007 ( void ) tag;
1008 ( void ) tag_length;
1009
1010 return ( PSA_ERROR_NOT_SUPPORTED );
1011 }
1012
1013 if( status == PSA_SUCCESS )
1014 {
Paul Elliott72c10082021-04-23 19:02:16 +01001015 *plaintext_length = finish_output_size;
1016
Paul Elliottadb8b162021-04-20 16:06:57 +01001017 if( do_tag_check && safer_memcmp(tag, check_tag, tag_length) != 0 )
1018 {
Paul Elliott811d8d42021-04-22 11:31:14 +01001019 status = PSA_ERROR_INVALID_SIGNATURE;
Paul Elliottadb8b162021-04-20 16:06:57 +01001020 }
1021 }
1022
1023 mbedtls_psa_aead_abort(operation);
1024
1025 return ( status );
1026}
1027
1028/* Abort an AEAD operation */
Paul Elliottcbbde5f2021-05-10 18:19:46 +01001029psa_status_t mbedtls_psa_aead_abort( mbedtls_psa_aead_operation_t *operation )
Paul Elliottadb8b162021-04-20 16:06:57 +01001030{
Paul Elliott811d8d42021-04-22 11:31:14 +01001031 switch( operation->alg )
Paul Elliottadb8b162021-04-20 16:06:57 +01001032 {
Paul Elliott811d8d42021-04-22 11:31:14 +01001033#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
1034 case PSA_ALG_CCM:
Paul Elliottadb8b162021-04-20 16:06:57 +01001035 mbedtls_ccm_free( &operation->ctx.ccm );
1036 break;
1037#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
1038#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
1039 case PSA_ALG_GCM:
1040 mbedtls_gcm_free( &operation->ctx.gcm );
1041 break;
1042#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
1043#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Paul Elliott811d8d42021-04-22 11:31:14 +01001044 case PSA_ALG_CHACHA20_POLY1305:
1045 mbedtls_chachapoly_free( &operation->ctx.chachapoly );
1046 break;
Paul Elliottadb8b162021-04-20 16:06:57 +01001047#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
1048 }
1049
Paul Elliottcbbde5f2021-05-10 18:19:46 +01001050 operation->lengths_set = 0;
1051 operation->is_encrypt = 0;
1052 operation->ad_started = 0;
1053 operation->body_started = 0;
1054
Paul Elliottfd3ca242021-04-25 18:10:42 +01001055 mbedtls_free(operation->ad_buffer);
1056 operation->ad_buffer = NULL;
1057 operation->ad_length = 0;
1058
1059 mbedtls_free(operation->body_buffer);
1060 operation->body_buffer = NULL;
1061 operation->body_length = 0;
1062
1063 mbedtls_free(operation->tag_buffer);
1064 operation->tag_buffer = NULL;
1065
Paul Elliottadb8b162021-04-20 16:06:57 +01001066 return( PSA_SUCCESS );
1067}
1068
Ronald Cron7ceee8d2021-03-17 16:55:43 +01001069#endif /* MBEDTLS_PSA_CRYPTO_C */
1070