1 /*
2  *  PSA cipher driver 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_cipher.h"
26 #include "psa_crypto_core.h"
27 #include "psa_crypto_random_impl.h"
28 
29 #include "mbedtls/cipher.h"
30 #include "mbedtls/error.h"
31 
32 #include <string.h>
33 
mbedtls_cipher_info_from_psa(psa_algorithm_t alg,psa_key_type_t key_type,size_t key_bits,mbedtls_cipher_id_t * cipher_id)34 const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
35     psa_algorithm_t alg,
36     psa_key_type_t key_type,
37     size_t key_bits,
38     mbedtls_cipher_id_t* cipher_id )
39 {
40     mbedtls_cipher_mode_t mode;
41     mbedtls_cipher_id_t cipher_id_tmp;
42 
43     if( PSA_ALG_IS_AEAD( alg ) )
44         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 );
45 
46     if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
47     {
48         switch( alg )
49         {
50 #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
51             case PSA_ALG_STREAM_CIPHER:
52                 mode = MBEDTLS_MODE_STREAM;
53                 break;
54 #endif
55 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
56             case PSA_ALG_CTR:
57                 mode = MBEDTLS_MODE_CTR;
58                 break;
59 #endif
60 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
61             case PSA_ALG_CFB:
62                 mode = MBEDTLS_MODE_CFB;
63                 break;
64 #endif
65 #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
66             case PSA_ALG_OFB:
67                 mode = MBEDTLS_MODE_OFB;
68                 break;
69 #endif
70 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
71             case PSA_ALG_ECB_NO_PADDING:
72                 mode = MBEDTLS_MODE_ECB;
73                 break;
74 #endif
75 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
76             case PSA_ALG_CBC_NO_PADDING:
77                 mode = MBEDTLS_MODE_CBC;
78                 break;
79 #endif
80 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
81             case PSA_ALG_CBC_PKCS7:
82                 mode = MBEDTLS_MODE_CBC;
83                 break;
84 #endif
85 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
86             case PSA_ALG_CCM_STAR_NO_TAG:
87                 mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
88                 break;
89 #endif
90 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
91             case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
92                 mode = MBEDTLS_MODE_CCM;
93                 break;
94 #endif
95 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
96             case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
97                 mode = MBEDTLS_MODE_GCM;
98                 break;
99 #endif
100 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
101             case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
102                 mode = MBEDTLS_MODE_CHACHAPOLY;
103                 break;
104 #endif
105             default:
106                 return( NULL );
107         }
108     }
109     else if( alg == PSA_ALG_CMAC )
110         mode = MBEDTLS_MODE_ECB;
111     else
112         return( NULL );
113 
114     switch( key_type )
115     {
116 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
117         case PSA_KEY_TYPE_AES:
118             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
119             break;
120 #endif
121 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
122         case PSA_KEY_TYPE_ARIA:
123             cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
124             break;
125 #endif
126 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
127         case PSA_KEY_TYPE_DES:
128             /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
129              * and 192 for three-key Triple-DES. */
130             if( key_bits == 64 )
131                 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
132             else
133                 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
134             /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
135              * but two-key Triple-DES is functionally three-key Triple-DES
136              * with K1=K3, so that's how we present it to mbedtls. */
137             if( key_bits == 128 )
138                 key_bits = 192;
139             break;
140 #endif
141 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
142         case PSA_KEY_TYPE_CAMELLIA:
143             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
144             break;
145 #endif
146 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
147         case PSA_KEY_TYPE_CHACHA20:
148             cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
149             break;
150 #endif
151         default:
152             return( NULL );
153     }
154     if( cipher_id != NULL )
155         *cipher_id = cipher_id_tmp;
156 
157     return( mbedtls_cipher_info_from_values( cipher_id_tmp,
158                                              (int) key_bits, mode ) );
159 }
160 
161 #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
162 
psa_cipher_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,mbedtls_operation_t cipher_operation)163 static psa_status_t psa_cipher_setup(
164     mbedtls_psa_cipher_operation_t *operation,
165     const psa_key_attributes_t *attributes,
166     const uint8_t *key_buffer, size_t key_buffer_size,
167     psa_algorithm_t alg,
168     mbedtls_operation_t cipher_operation )
169 {
170     int ret = 0;
171     size_t key_bits;
172     const mbedtls_cipher_info_t *cipher_info = NULL;
173     psa_key_type_t key_type = attributes->core.type;
174 
175     (void)key_buffer_size;
176 
177     mbedtls_cipher_init( &operation->ctx.cipher );
178 
179     operation->alg = alg;
180     key_bits = attributes->core.bits;
181     cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
182                                                 key_bits, NULL );
183     if( cipher_info == NULL )
184         return( PSA_ERROR_NOT_SUPPORTED );
185 
186     ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
187     if( ret != 0 )
188         goto exit;
189 
190 #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
191     if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
192     {
193         /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
194         uint8_t keys[24];
195         memcpy( keys, key_buffer, 16 );
196         memcpy( keys + 16, key_buffer, 8 );
197         ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
198                                      keys,
199                                      192, cipher_operation );
200     }
201     else
202 #endif
203     {
204         ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
205                                      (int) key_bits, cipher_operation );
206     }
207     if( ret != 0 )
208         goto exit;
209 
210 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
211     defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
212     switch( alg )
213     {
214         case PSA_ALG_CBC_NO_PADDING:
215             ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
216                                                    MBEDTLS_PADDING_NONE );
217             break;
218         case PSA_ALG_CBC_PKCS7:
219             ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
220                                                    MBEDTLS_PADDING_PKCS7 );
221             break;
222         default:
223             /* The algorithm doesn't involve padding. */
224             ret = 0;
225             break;
226     }
227     if( ret != 0 )
228         goto exit;
229 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
230           MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
231 
232     operation->block_length = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
233                                 PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
234     operation->iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
235 
236 exit:
237     return( mbedtls_to_psa_error( ret ) );
238 }
239 
mbedtls_psa_cipher_encrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)240 psa_status_t mbedtls_psa_cipher_encrypt_setup(
241     mbedtls_psa_cipher_operation_t *operation,
242     const psa_key_attributes_t *attributes,
243     const uint8_t *key_buffer, size_t key_buffer_size,
244     psa_algorithm_t alg )
245 {
246     return( psa_cipher_setup( operation, attributes,
247                               key_buffer, key_buffer_size,
248                               alg, MBEDTLS_ENCRYPT ) );
249 }
250 
mbedtls_psa_cipher_decrypt_setup(mbedtls_psa_cipher_operation_t * operation,const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg)251 psa_status_t mbedtls_psa_cipher_decrypt_setup(
252     mbedtls_psa_cipher_operation_t *operation,
253     const psa_key_attributes_t *attributes,
254     const uint8_t *key_buffer, size_t key_buffer_size,
255     psa_algorithm_t alg )
256 {
257     return( psa_cipher_setup( operation, attributes,
258                               key_buffer, key_buffer_size,
259                               alg, MBEDTLS_DECRYPT ) );
260 }
261 
mbedtls_psa_cipher_set_iv(mbedtls_psa_cipher_operation_t * operation,const uint8_t * iv,size_t iv_length)262 psa_status_t mbedtls_psa_cipher_set_iv(
263     mbedtls_psa_cipher_operation_t *operation,
264     const uint8_t *iv, size_t iv_length )
265 {
266     if( iv_length != operation->iv_length )
267         return( PSA_ERROR_INVALID_ARGUMENT );
268 
269     return( mbedtls_to_psa_error(
270                 mbedtls_cipher_set_iv( &operation->ctx.cipher,
271                                        iv, iv_length ) ) );
272 }
273 
274 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
275 /** Process input for which the algorithm is set to ECB mode.
276  *
277  * This requires manual processing, since the PSA API is defined as being
278  * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
279  * but the underlying mbedtls_cipher_update only takes full blocks.
280  *
281  * \param ctx           The mbedtls cipher context to use. It must have been
282  *                      set up for ECB.
283  * \param[in] input     The input plaintext or ciphertext to process.
284  * \param input_length  The number of bytes to process from \p input.
285  *                      This does not need to be aligned to a block boundary.
286  *                      If there is a partial block at the end of the input,
287  *                      it is stored in \p ctx for future processing.
288  * \param output        The buffer where the output is written. It must be
289  *                      at least `BS * floor((p + input_length) / BS)` bytes
290  *                      long, where `p` is the number of bytes in the
291  *                      unprocessed partial block in \p ctx (with
292  *                      `0 <= p <= BS - 1`) and `BS` is the block size.
293  * \param output_length On success, the number of bytes written to \p output.
294  *                      \c 0 on error.
295  *
296  * \return #PSA_SUCCESS or an error from a hardware accelerator
297  */
psa_cipher_update_ecb(mbedtls_cipher_context_t * ctx,const uint8_t * input,size_t input_length,uint8_t * output,size_t * output_length)298 static psa_status_t psa_cipher_update_ecb(
299     mbedtls_cipher_context_t *ctx,
300     const uint8_t *input,
301     size_t input_length,
302     uint8_t *output,
303     size_t *output_length )
304 {
305     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
306     size_t block_size = ctx->cipher_info->block_size;
307     size_t internal_output_length = 0;
308     *output_length = 0;
309 
310     if( input_length == 0 )
311     {
312         status = PSA_SUCCESS;
313         goto exit;
314     }
315 
316     if( ctx->unprocessed_len > 0 )
317     {
318         /* Fill up to block size, and run the block if there's a full one. */
319         size_t bytes_to_copy = block_size - ctx->unprocessed_len;
320 
321         if( input_length < bytes_to_copy )
322             bytes_to_copy = input_length;
323 
324         memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
325                 input, bytes_to_copy );
326         input_length -= bytes_to_copy;
327         input += bytes_to_copy;
328         ctx->unprocessed_len += bytes_to_copy;
329 
330         if( ctx->unprocessed_len == block_size )
331         {
332             status = mbedtls_to_psa_error(
333                 mbedtls_cipher_update( ctx,
334                                        ctx->unprocessed_data,
335                                        block_size,
336                                        output, &internal_output_length ) );
337 
338             if( status != PSA_SUCCESS )
339                 goto exit;
340 
341             output += internal_output_length;
342             *output_length += internal_output_length;
343             ctx->unprocessed_len = 0;
344         }
345     }
346 
347     while( input_length >= block_size )
348     {
349         /* Run all full blocks we have, one by one */
350         status = mbedtls_to_psa_error(
351             mbedtls_cipher_update( ctx, input,
352                                    block_size,
353                                    output, &internal_output_length ) );
354 
355         if( status != PSA_SUCCESS )
356             goto exit;
357 
358         input_length -= block_size;
359         input += block_size;
360 
361         output += internal_output_length;
362         *output_length += internal_output_length;
363     }
364 
365     if( input_length > 0 )
366     {
367         /* Save unprocessed bytes for later processing */
368         memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
369                 input, input_length );
370         ctx->unprocessed_len += input_length;
371     }
372 
373     status = PSA_SUCCESS;
374 
375 exit:
376     return( status );
377 }
378 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
379 
mbedtls_psa_cipher_update(mbedtls_psa_cipher_operation_t * operation,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)380 psa_status_t mbedtls_psa_cipher_update(
381     mbedtls_psa_cipher_operation_t *operation,
382     const uint8_t *input, size_t input_length,
383     uint8_t *output, size_t output_size, size_t *output_length )
384 {
385     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
386     size_t expected_output_size;
387 
388     if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
389     {
390         /* Take the unprocessed partial block left over from previous
391          * update calls, if any, plus the input to this call. Remove
392          * the last partial block, if any. You get the data that will be
393          * output in this call. */
394         expected_output_size =
395             ( operation->ctx.cipher.unprocessed_len + input_length )
396             / operation->block_length * operation->block_length;
397     }
398     else
399     {
400         expected_output_size = input_length;
401     }
402 
403     if( output_size < expected_output_size )
404         return( PSA_ERROR_BUFFER_TOO_SMALL );
405 
406 #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
407     if( operation->alg == PSA_ALG_ECB_NO_PADDING )
408     {
409         /* mbedtls_cipher_update has an API inconsistency: it will only
410         * process a single block at a time in ECB mode. Abstract away that
411         * inconsistency here to match the PSA API behaviour. */
412         status = psa_cipher_update_ecb( &operation->ctx.cipher,
413                                         input,
414                                         input_length,
415                                         output,
416                                         output_length );
417     }
418     else
419 #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
420     {
421         status = mbedtls_to_psa_error(
422             mbedtls_cipher_update( &operation->ctx.cipher, input,
423                                    input_length, output, output_length ) );
424 
425         if( *output_length > output_size )
426             return( PSA_ERROR_CORRUPTION_DETECTED );
427     }
428 
429     return( status );
430 }
431 
mbedtls_psa_cipher_finish(mbedtls_psa_cipher_operation_t * operation,uint8_t * output,size_t output_size,size_t * output_length)432 psa_status_t mbedtls_psa_cipher_finish(
433     mbedtls_psa_cipher_operation_t *operation,
434     uint8_t *output, size_t output_size, size_t *output_length )
435 {
436     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
437     uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
438 
439     if( operation->ctx.cipher.unprocessed_len != 0 )
440     {
441         if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
442             operation->alg == PSA_ALG_CBC_NO_PADDING )
443         {
444             status = PSA_ERROR_INVALID_ARGUMENT;
445             goto exit;
446         }
447     }
448 
449     status = mbedtls_to_psa_error(
450         mbedtls_cipher_finish( &operation->ctx.cipher,
451                                temp_output_buffer,
452                                output_length ) );
453     if( status != PSA_SUCCESS )
454         goto exit;
455 
456     if( *output_length == 0 )
457         ; /* Nothing to copy. Note that output may be NULL in this case. */
458     else if( output_size >= *output_length )
459         memcpy( output, temp_output_buffer, *output_length );
460     else
461         status = PSA_ERROR_BUFFER_TOO_SMALL;
462 
463 exit:
464     mbedtls_platform_zeroize( temp_output_buffer,
465                               sizeof( temp_output_buffer ) );
466 
467     return( status );
468 }
469 
mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t * operation)470 psa_status_t mbedtls_psa_cipher_abort(
471     mbedtls_psa_cipher_operation_t *operation )
472 {
473     /* Sanity check (shouldn't happen: operation->alg should
474      * always have been initialized to a valid value). */
475     if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
476         return( PSA_ERROR_BAD_STATE );
477 
478     mbedtls_cipher_free( &operation->ctx.cipher );
479 
480     return( PSA_SUCCESS );
481 }
482 
mbedtls_psa_cipher_encrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * iv,size_t iv_length,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)483 psa_status_t mbedtls_psa_cipher_encrypt(
484     const psa_key_attributes_t *attributes,
485     const uint8_t *key_buffer,
486     size_t key_buffer_size,
487     psa_algorithm_t alg,
488     const uint8_t *iv,
489     size_t iv_length,
490     const uint8_t *input,
491     size_t input_length,
492     uint8_t *output,
493     size_t output_size,
494     size_t *output_length )
495 {
496     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
497     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
498     size_t update_output_length, finish_output_length;
499 
500     status = mbedtls_psa_cipher_encrypt_setup( &operation, attributes,
501                                                key_buffer, key_buffer_size,
502                                                alg );
503     if( status != PSA_SUCCESS )
504         goto exit;
505 
506     if( iv_length > 0 )
507     {
508         status = mbedtls_psa_cipher_set_iv( &operation, iv, iv_length );
509         if( status != PSA_SUCCESS )
510             goto exit;
511     }
512 
513     status = mbedtls_psa_cipher_update( &operation, input, input_length,
514                                         output, output_size,
515                                         &update_output_length );
516     if( status != PSA_SUCCESS )
517         goto exit;
518 
519     status = mbedtls_psa_cipher_finish(
520         &operation,
521         mbedtls_buffer_offset( output, update_output_length ),
522         output_size - update_output_length, &finish_output_length );
523     if( status != PSA_SUCCESS )
524         goto exit;
525 
526     *output_length = update_output_length + finish_output_length;
527 
528 exit:
529     if( status == PSA_SUCCESS )
530         status = mbedtls_psa_cipher_abort( &operation );
531     else
532         mbedtls_psa_cipher_abort( &operation );
533 
534     return( status );
535 }
536 
mbedtls_psa_cipher_decrypt(const psa_key_attributes_t * attributes,const uint8_t * key_buffer,size_t key_buffer_size,psa_algorithm_t alg,const uint8_t * input,size_t input_length,uint8_t * output,size_t output_size,size_t * output_length)537 psa_status_t mbedtls_psa_cipher_decrypt(
538     const psa_key_attributes_t *attributes,
539     const uint8_t *key_buffer,
540     size_t key_buffer_size,
541     psa_algorithm_t alg,
542     const uint8_t *input,
543     size_t input_length,
544     uint8_t *output,
545     size_t output_size,
546     size_t *output_length )
547 {
548     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
549     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
550     size_t olength, accumulated_length;
551 
552     status = mbedtls_psa_cipher_decrypt_setup( &operation, attributes,
553                                                key_buffer, key_buffer_size,
554                                                alg );
555     if( status != PSA_SUCCESS )
556         goto exit;
557 
558     if( operation.iv_length > 0 )
559     {
560         status = mbedtls_psa_cipher_set_iv( &operation,
561                                             input, operation.iv_length );
562         if( status != PSA_SUCCESS )
563             goto exit;
564     }
565 
566     status = mbedtls_psa_cipher_update(
567         &operation,
568         mbedtls_buffer_offset_const( input, operation.iv_length ),
569         input_length - operation.iv_length,
570         output, output_size, &olength );
571     if( status != PSA_SUCCESS )
572         goto exit;
573 
574     accumulated_length = olength;
575 
576     status = mbedtls_psa_cipher_finish(
577         &operation,
578         mbedtls_buffer_offset( output, accumulated_length ),
579         output_size - accumulated_length, &olength );
580     if( status != PSA_SUCCESS )
581         goto exit;
582 
583     *output_length = accumulated_length + olength;
584 
585 exit:
586     if ( status == PSA_SUCCESS )
587         status = mbedtls_psa_cipher_abort( &operation );
588     else
589         mbedtls_psa_cipher_abort( &operation );
590 
591     return( status );
592 }
593 #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
594 
595 #endif /* MBEDTLS_PSA_CRYPTO_C */
596