xref: /optee_os/lib/libmbedtls/mbedtls/library/psa_crypto_cipher.c (revision cb03400251f98aed22a2664509e3ed9e183800b0)
1b0563631STom Van Eyck /*
2b0563631STom Van Eyck  *  PSA cipher driver entry points
3b0563631STom Van Eyck  */
4b0563631STom Van Eyck /*
5b0563631STom Van Eyck  *  Copyright The Mbed TLS Contributors
6b0563631STom Van Eyck  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
7b0563631STom Van Eyck  */
8b0563631STom Van Eyck 
9b0563631STom Van Eyck #include "common.h"
10b0563631STom Van Eyck 
11b0563631STom Van Eyck #if defined(MBEDTLS_PSA_CRYPTO_C)
12b0563631STom Van Eyck 
13b0563631STom Van Eyck #include "psa_crypto_cipher.h"
14b0563631STom Van Eyck #include "psa_crypto_core.h"
15b0563631STom Van Eyck #include "psa_crypto_random_impl.h"
16b0563631STom Van Eyck 
17b0563631STom Van Eyck #include "mbedtls/cipher.h"
18b0563631STom Van Eyck #include "mbedtls/error.h"
19b0563631STom Van Eyck 
20b0563631STom Van Eyck #include <string.h>
21b0563631STom Van Eyck 
22b0563631STom Van Eyck /* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
23b0563631STom Van Eyck  * are enabled, but it does not provide any compatibility check between them
24b0563631STom Van Eyck  * (i.e. if the specified key works with the specified algorithm). This helper
25b0563631STom Van Eyck  * function is meant to provide this support.
26b0563631STom Van Eyck  * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
27b0563631STom Van Eyck  * requires CIPHER_C to be enabled.
28b0563631STom Van Eyck  */
29b0563631STom Van Eyck static psa_status_t mbedtls_cipher_validate_values(
30b0563631STom Van Eyck     psa_algorithm_t alg,
31b0563631STom Van Eyck     psa_key_type_t key_type)
32b0563631STom Van Eyck {
33b0563631STom Van Eyck     /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
34b0563631STom Van Eyck        eliminate bits of the logic below. */
35b0563631STom Van Eyck #if !defined(PSA_WANT_KEY_TYPE_AES)
36b0563631STom Van Eyck     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
37b0563631STom Van Eyck #endif
38b0563631STom Van Eyck #if !defined(PSA_WANT_KEY_TYPE_ARIA)
39b0563631STom Van Eyck     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
40b0563631STom Van Eyck #endif
41b0563631STom Van Eyck #if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
42b0563631STom Van Eyck     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
43b0563631STom Van Eyck #endif
44b0563631STom Van Eyck #if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
45b0563631STom Van Eyck     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
46b0563631STom Van Eyck #endif
47b0563631STom Van Eyck #if !defined(PSA_WANT_KEY_TYPE_DES)
48b0563631STom Van Eyck     MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
49b0563631STom Van Eyck #endif
50b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CCM)
51b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
52b0563631STom Van Eyck #endif
53b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_GCM)
54b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
55b0563631STom Van Eyck #endif
56b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_STREAM_CIPHER)
57b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
58b0563631STom Van Eyck #endif
59b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
60b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
61b0563631STom Van Eyck #endif
62b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
63b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
64b0563631STom Van Eyck #endif
65b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CTR)
66b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
67b0563631STom Van Eyck #endif
68b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CFB)
69b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
70b0563631STom Van Eyck #endif
71b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_OFB)
72b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
73b0563631STom Van Eyck #endif
74b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_XTS)
75b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
76b0563631STom Van Eyck #endif
77b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
78b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
79b0563631STom Van Eyck #endif
80b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
81b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
82b0563631STom Van Eyck #endif
83b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CBC_PKCS7)
84b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
85b0563631STom Van Eyck #endif
86b0563631STom Van Eyck #if !defined(PSA_WANT_ALG_CMAC)
87b0563631STom Van Eyck     MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
88b0563631STom Van Eyck #endif
89b0563631STom Van Eyck 
90b0563631STom Van Eyck     if (alg == PSA_ALG_STREAM_CIPHER ||
91b0563631STom Van Eyck         alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
92b0563631STom Van Eyck         if (key_type == PSA_KEY_TYPE_CHACHA20) {
93b0563631STom Van Eyck             return PSA_SUCCESS;
94b0563631STom Van Eyck         }
95b0563631STom Van Eyck     }
96b0563631STom Van Eyck 
97b0563631STom Van Eyck     if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
98b0563631STom Van Eyck         alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
99b0563631STom Van Eyck         alg == PSA_ALG_CCM_STAR_NO_TAG) {
100b0563631STom Van Eyck         if (key_type == PSA_KEY_TYPE_AES ||
101b0563631STom Van Eyck             key_type == PSA_KEY_TYPE_ARIA ||
102b0563631STom Van Eyck             key_type == PSA_KEY_TYPE_CAMELLIA) {
103b0563631STom Van Eyck             return PSA_SUCCESS;
104b0563631STom Van Eyck         }
105b0563631STom Van Eyck     }
106b0563631STom Van Eyck 
107b0563631STom Van Eyck     if (alg == PSA_ALG_CTR ||
108b0563631STom Van Eyck         alg == PSA_ALG_CFB ||
109b0563631STom Van Eyck         alg == PSA_ALG_OFB ||
110b0563631STom Van Eyck         alg == PSA_ALG_XTS ||
111b0563631STom Van Eyck         alg == PSA_ALG_ECB_NO_PADDING ||
112b0563631STom Van Eyck         alg == PSA_ALG_CBC_NO_PADDING ||
113b0563631STom Van Eyck         alg == PSA_ALG_CBC_PKCS7 ||
114b0563631STom Van Eyck         alg == PSA_ALG_CMAC) {
115b0563631STom Van Eyck         if (key_type == PSA_KEY_TYPE_AES ||
116b0563631STom Van Eyck             key_type == PSA_KEY_TYPE_ARIA ||
117b0563631STom Van Eyck             key_type == PSA_KEY_TYPE_DES ||
118b0563631STom Van Eyck             key_type == PSA_KEY_TYPE_CAMELLIA) {
119b0563631STom Van Eyck             return PSA_SUCCESS;
120b0563631STom Van Eyck         }
121b0563631STom Van Eyck     }
122b0563631STom Van Eyck 
123b0563631STom Van Eyck     return PSA_ERROR_NOT_SUPPORTED;
124b0563631STom Van Eyck }
125b0563631STom Van Eyck 
126b0563631STom Van Eyck psa_status_t mbedtls_cipher_values_from_psa(
127b0563631STom Van Eyck     psa_algorithm_t alg,
128b0563631STom Van Eyck     psa_key_type_t key_type,
129b0563631STom Van Eyck     size_t *key_bits,
130b0563631STom Van Eyck     mbedtls_cipher_mode_t *mode,
131b0563631STom Van Eyck     mbedtls_cipher_id_t *cipher_id)
132b0563631STom Van Eyck {
133b0563631STom Van Eyck     mbedtls_cipher_id_t cipher_id_tmp;
134b0563631STom Van Eyck     /* Only DES modifies key_bits */
135b0563631STom Van Eyck #if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
136b0563631STom Van Eyck     (void) key_bits;
137b0563631STom Van Eyck #endif
138b0563631STom Van Eyck 
139b0563631STom Van Eyck     if (PSA_ALG_IS_AEAD(alg)) {
140b0563631STom Van Eyck         alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
141b0563631STom Van Eyck     }
142b0563631STom Van Eyck 
143b0563631STom Van Eyck     if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
144b0563631STom Van Eyck         switch (alg) {
145b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
146b0563631STom Van Eyck             case PSA_ALG_STREAM_CIPHER:
147b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_STREAM;
148b0563631STom Van Eyck                 break;
149b0563631STom Van Eyck #endif
150b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
151b0563631STom Van Eyck             case PSA_ALG_CTR:
152b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CTR;
153b0563631STom Van Eyck                 break;
154b0563631STom Van Eyck #endif
155b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
156b0563631STom Van Eyck             case PSA_ALG_CFB:
157b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CFB;
158b0563631STom Van Eyck                 break;
159b0563631STom Van Eyck #endif
160b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
161b0563631STom Van Eyck             case PSA_ALG_OFB:
162b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_OFB;
163b0563631STom Van Eyck                 break;
164b0563631STom Van Eyck #endif
165b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
166b0563631STom Van Eyck             case PSA_ALG_ECB_NO_PADDING:
167b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_ECB;
168b0563631STom Van Eyck                 break;
169b0563631STom Van Eyck #endif
170b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
171b0563631STom Van Eyck             case PSA_ALG_CBC_NO_PADDING:
172b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CBC;
173b0563631STom Van Eyck                 break;
174b0563631STom Van Eyck #endif
175b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
176b0563631STom Van Eyck             case PSA_ALG_CBC_PKCS7:
177b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CBC;
178b0563631STom Van Eyck                 break;
179b0563631STom Van Eyck #endif
180b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
181b0563631STom Van Eyck             case PSA_ALG_CCM_STAR_NO_TAG:
182b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
183b0563631STom Van Eyck                 break;
184b0563631STom Van Eyck #endif
185b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
186b0563631STom Van Eyck             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
187b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CCM;
188b0563631STom Van Eyck                 break;
189b0563631STom Van Eyck #endif
190b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
191b0563631STom Van Eyck             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
192b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_GCM;
193b0563631STom Van Eyck                 break;
194b0563631STom Van Eyck #endif
195b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
196b0563631STom Van Eyck             case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
197b0563631STom Van Eyck                 *mode = MBEDTLS_MODE_CHACHAPOLY;
198b0563631STom Van Eyck                 break;
199b0563631STom Van Eyck #endif
200b0563631STom Van Eyck             default:
201b0563631STom Van Eyck                 return PSA_ERROR_NOT_SUPPORTED;
202b0563631STom Van Eyck         }
203b0563631STom Van Eyck     } else if (alg == PSA_ALG_CMAC) {
204b0563631STom Van Eyck         *mode = MBEDTLS_MODE_ECB;
205b0563631STom Van Eyck     } else {
206b0563631STom Van Eyck         return PSA_ERROR_NOT_SUPPORTED;
207b0563631STom Van Eyck     }
208b0563631STom Van Eyck 
209b0563631STom Van Eyck     switch (key_type) {
210b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
211b0563631STom Van Eyck         case PSA_KEY_TYPE_AES:
212b0563631STom Van Eyck             cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
213b0563631STom Van Eyck             break;
214b0563631STom Van Eyck #endif
215b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
216b0563631STom Van Eyck         case PSA_KEY_TYPE_ARIA:
217b0563631STom Van Eyck             cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
218b0563631STom Van Eyck             break;
219b0563631STom Van Eyck #endif
220b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
221b0563631STom Van Eyck         case PSA_KEY_TYPE_DES:
222b0563631STom Van Eyck             /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
223b0563631STom Van Eyck              * and 192 for three-key Triple-DES. */
224b0563631STom Van Eyck             if (*key_bits == 64) {
225b0563631STom Van Eyck                 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
226b0563631STom Van Eyck             } else {
227b0563631STom Van Eyck                 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
228b0563631STom Van Eyck             }
229b0563631STom Van Eyck             /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
230b0563631STom Van Eyck              * but two-key Triple-DES is functionally three-key Triple-DES
231b0563631STom Van Eyck              * with K1=K3, so that's how we present it to mbedtls. */
232b0563631STom Van Eyck             if (*key_bits == 128) {
233b0563631STom Van Eyck                 *key_bits = 192;
234b0563631STom Van Eyck             }
235b0563631STom Van Eyck             break;
236b0563631STom Van Eyck #endif
237b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
238b0563631STom Van Eyck         case PSA_KEY_TYPE_CAMELLIA:
239b0563631STom Van Eyck             cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
240b0563631STom Van Eyck             break;
241b0563631STom Van Eyck #endif
242b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
243b0563631STom Van Eyck         case PSA_KEY_TYPE_CHACHA20:
244b0563631STom Van Eyck             cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
245b0563631STom Van Eyck             break;
246b0563631STom Van Eyck #endif
247b0563631STom Van Eyck         default:
248b0563631STom Van Eyck             return PSA_ERROR_NOT_SUPPORTED;
249b0563631STom Van Eyck     }
250b0563631STom Van Eyck     if (cipher_id != NULL) {
251b0563631STom Van Eyck         *cipher_id = cipher_id_tmp;
252b0563631STom Van Eyck     }
253b0563631STom Van Eyck 
254b0563631STom Van Eyck     return mbedtls_cipher_validate_values(alg, key_type);
255b0563631STom Van Eyck }
256b0563631STom Van Eyck 
257b0563631STom Van Eyck #if defined(MBEDTLS_CIPHER_C)
258b0563631STom Van Eyck const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
259b0563631STom Van Eyck     psa_algorithm_t alg,
260b0563631STom Van Eyck     psa_key_type_t key_type,
261b0563631STom Van Eyck     size_t key_bits,
262b0563631STom Van Eyck     mbedtls_cipher_id_t *cipher_id)
263b0563631STom Van Eyck {
264b0563631STom Van Eyck     mbedtls_cipher_mode_t mode;
265b0563631STom Van Eyck     psa_status_t status;
266*cb034002SJerome Forissier     mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
267b0563631STom Van Eyck 
268b0563631STom Van Eyck     status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
269b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
270b0563631STom Van Eyck         return NULL;
271b0563631STom Van Eyck     }
272b0563631STom Van Eyck     if (cipher_id != NULL) {
273b0563631STom Van Eyck         *cipher_id = cipher_id_tmp;
274b0563631STom Van Eyck     }
275b0563631STom Van Eyck 
276b0563631STom Van Eyck     return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
277b0563631STom Van Eyck }
278b0563631STom Van Eyck #endif /* MBEDTLS_CIPHER_C */
279b0563631STom Van Eyck 
280b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
281b0563631STom Van Eyck 
282b0563631STom Van Eyck static psa_status_t psa_cipher_setup(
283b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
284b0563631STom Van Eyck     const psa_key_attributes_t *attributes,
285b0563631STom Van Eyck     const uint8_t *key_buffer, size_t key_buffer_size,
286b0563631STom Van Eyck     psa_algorithm_t alg,
287b0563631STom Van Eyck     mbedtls_operation_t cipher_operation)
288b0563631STom Van Eyck {
289b0563631STom Van Eyck     int ret = 0;
290b0563631STom Van Eyck     size_t key_bits;
291b0563631STom Van Eyck     const mbedtls_cipher_info_t *cipher_info = NULL;
292b0563631STom Van Eyck     psa_key_type_t key_type = attributes->type;
293b0563631STom Van Eyck 
294b0563631STom Van Eyck     (void) key_buffer_size;
295b0563631STom Van Eyck 
296b0563631STom Van Eyck     mbedtls_cipher_init(&operation->ctx.cipher);
297b0563631STom Van Eyck 
298b0563631STom Van Eyck     operation->alg = alg;
299b0563631STom Van Eyck     key_bits = attributes->bits;
300b0563631STom Van Eyck     cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
301b0563631STom Van Eyck                                                key_bits, NULL);
302b0563631STom Van Eyck     if (cipher_info == NULL) {
303b0563631STom Van Eyck         return PSA_ERROR_NOT_SUPPORTED;
304b0563631STom Van Eyck     }
305b0563631STom Van Eyck 
306b0563631STom Van Eyck     ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
307b0563631STom Van Eyck     if (ret != 0) {
308b0563631STom Van Eyck         goto exit;
309b0563631STom Van Eyck     }
310b0563631STom Van Eyck 
311b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
312b0563631STom Van Eyck     if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
313b0563631STom Van Eyck         /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
314b0563631STom Van Eyck         uint8_t keys[24];
315b0563631STom Van Eyck         memcpy(keys, key_buffer, 16);
316b0563631STom Van Eyck         memcpy(keys + 16, key_buffer, 8);
317b0563631STom Van Eyck         ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
318b0563631STom Van Eyck                                     keys,
319b0563631STom Van Eyck                                     192, cipher_operation);
320b0563631STom Van Eyck     } else
321b0563631STom Van Eyck #endif
322b0563631STom Van Eyck     {
323b0563631STom Van Eyck         ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
324b0563631STom Van Eyck                                     (int) key_bits, cipher_operation);
325b0563631STom Van Eyck     }
326b0563631STom Van Eyck     if (ret != 0) {
327b0563631STom Van Eyck         goto exit;
328b0563631STom Van Eyck     }
329b0563631STom Van Eyck 
330b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
331b0563631STom Van Eyck     defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
332b0563631STom Van Eyck     switch (alg) {
333b0563631STom Van Eyck         case PSA_ALG_CBC_NO_PADDING:
334b0563631STom Van Eyck             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
335b0563631STom Van Eyck                                                   MBEDTLS_PADDING_NONE);
336b0563631STom Van Eyck             break;
337b0563631STom Van Eyck         case PSA_ALG_CBC_PKCS7:
338b0563631STom Van Eyck             ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
339b0563631STom Van Eyck                                                   MBEDTLS_PADDING_PKCS7);
340b0563631STom Van Eyck             break;
341b0563631STom Van Eyck         default:
342b0563631STom Van Eyck             /* The algorithm doesn't involve padding. */
343b0563631STom Van Eyck             ret = 0;
344b0563631STom Van Eyck             break;
345b0563631STom Van Eyck     }
346b0563631STom Van Eyck     if (ret != 0) {
347b0563631STom Van Eyck         goto exit;
348b0563631STom Van Eyck     }
349b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
350b0563631STom Van Eyck           MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
351b0563631STom Van Eyck 
352b0563631STom Van Eyck     operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
353b0563631STom Van Eyck                                PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
354b0563631STom Van Eyck     operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
355b0563631STom Van Eyck 
356b0563631STom Van Eyck exit:
357b0563631STom Van Eyck     return mbedtls_to_psa_error(ret);
358b0563631STom Van Eyck }
359b0563631STom Van Eyck 
360b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_encrypt_setup(
361b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
362b0563631STom Van Eyck     const psa_key_attributes_t *attributes,
363b0563631STom Van Eyck     const uint8_t *key_buffer, size_t key_buffer_size,
364b0563631STom Van Eyck     psa_algorithm_t alg)
365b0563631STom Van Eyck {
366b0563631STom Van Eyck     return psa_cipher_setup(operation, attributes,
367b0563631STom Van Eyck                             key_buffer, key_buffer_size,
368b0563631STom Van Eyck                             alg, MBEDTLS_ENCRYPT);
369b0563631STom Van Eyck }
370b0563631STom Van Eyck 
371b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_decrypt_setup(
372b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
373b0563631STom Van Eyck     const psa_key_attributes_t *attributes,
374b0563631STom Van Eyck     const uint8_t *key_buffer, size_t key_buffer_size,
375b0563631STom Van Eyck     psa_algorithm_t alg)
376b0563631STom Van Eyck {
377b0563631STom Van Eyck     return psa_cipher_setup(operation, attributes,
378b0563631STom Van Eyck                             key_buffer, key_buffer_size,
379b0563631STom Van Eyck                             alg, MBEDTLS_DECRYPT);
380b0563631STom Van Eyck }
381b0563631STom Van Eyck 
382b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_set_iv(
383b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
384b0563631STom Van Eyck     const uint8_t *iv, size_t iv_length)
385b0563631STom Van Eyck {
386b0563631STom Van Eyck     if (iv_length != operation->iv_length) {
387b0563631STom Van Eyck         return PSA_ERROR_INVALID_ARGUMENT;
388b0563631STom Van Eyck     }
389b0563631STom Van Eyck 
390b0563631STom Van Eyck     return mbedtls_to_psa_error(
391b0563631STom Van Eyck         mbedtls_cipher_set_iv(&operation->ctx.cipher,
392b0563631STom Van Eyck                               iv, iv_length));
393b0563631STom Van Eyck }
394b0563631STom Van Eyck 
395b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
396b0563631STom Van Eyck /** Process input for which the algorithm is set to ECB mode.
397b0563631STom Van Eyck  *
398b0563631STom Van Eyck  * This requires manual processing, since the PSA API is defined as being
399b0563631STom Van Eyck  * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
400b0563631STom Van Eyck  * but the underlying mbedtls_cipher_update only takes full blocks.
401b0563631STom Van Eyck  *
402b0563631STom Van Eyck  * \param ctx           The mbedtls cipher context to use. It must have been
403b0563631STom Van Eyck  *                      set up for ECB.
404b0563631STom Van Eyck  * \param[in] input     The input plaintext or ciphertext to process.
405b0563631STom Van Eyck  * \param input_length  The number of bytes to process from \p input.
406b0563631STom Van Eyck  *                      This does not need to be aligned to a block boundary.
407b0563631STom Van Eyck  *                      If there is a partial block at the end of the input,
408b0563631STom Van Eyck  *                      it is stored in \p ctx for future processing.
409b0563631STom Van Eyck  * \param output        The buffer where the output is written. It must be
410b0563631STom Van Eyck  *                      at least `BS * floor((p + input_length) / BS)` bytes
411b0563631STom Van Eyck  *                      long, where `p` is the number of bytes in the
412b0563631STom Van Eyck  *                      unprocessed partial block in \p ctx (with
413b0563631STom Van Eyck  *                      `0 <= p <= BS - 1`) and `BS` is the block size.
414b0563631STom Van Eyck  * \param output_length On success, the number of bytes written to \p output.
415b0563631STom Van Eyck  *                      \c 0 on error.
416b0563631STom Van Eyck  *
417b0563631STom Van Eyck  * \return #PSA_SUCCESS or an error from a hardware accelerator
418b0563631STom Van Eyck  */
419b0563631STom Van Eyck static psa_status_t psa_cipher_update_ecb(
420b0563631STom Van Eyck     mbedtls_cipher_context_t *ctx,
421b0563631STom Van Eyck     const uint8_t *input,
422b0563631STom Van Eyck     size_t input_length,
423b0563631STom Van Eyck     uint8_t *output,
424b0563631STom Van Eyck     size_t *output_length)
425b0563631STom Van Eyck {
426b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
427b0563631STom Van Eyck     size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
428b0563631STom Van Eyck     size_t internal_output_length = 0;
429b0563631STom Van Eyck     *output_length = 0;
430b0563631STom Van Eyck 
431b0563631STom Van Eyck     if (input_length == 0) {
432b0563631STom Van Eyck         status = PSA_SUCCESS;
433b0563631STom Van Eyck         goto exit;
434b0563631STom Van Eyck     }
435b0563631STom Van Eyck 
436b0563631STom Van Eyck     if (ctx->unprocessed_len > 0) {
437b0563631STom Van Eyck         /* Fill up to block size, and run the block if there's a full one. */
438b0563631STom Van Eyck         size_t bytes_to_copy = block_size - ctx->unprocessed_len;
439b0563631STom Van Eyck 
440b0563631STom Van Eyck         if (input_length < bytes_to_copy) {
441b0563631STom Van Eyck             bytes_to_copy = input_length;
442b0563631STom Van Eyck         }
443b0563631STom Van Eyck 
444b0563631STom Van Eyck         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
445b0563631STom Van Eyck                input, bytes_to_copy);
446b0563631STom Van Eyck         input_length -= bytes_to_copy;
447b0563631STom Van Eyck         input += bytes_to_copy;
448b0563631STom Van Eyck         ctx->unprocessed_len += bytes_to_copy;
449b0563631STom Van Eyck 
450b0563631STom Van Eyck         if (ctx->unprocessed_len == block_size) {
451b0563631STom Van Eyck             status = mbedtls_to_psa_error(
452b0563631STom Van Eyck                 mbedtls_cipher_update(ctx,
453b0563631STom Van Eyck                                       ctx->unprocessed_data,
454b0563631STom Van Eyck                                       block_size,
455b0563631STom Van Eyck                                       output, &internal_output_length));
456b0563631STom Van Eyck 
457b0563631STom Van Eyck             if (status != PSA_SUCCESS) {
458b0563631STom Van Eyck                 goto exit;
459b0563631STom Van Eyck             }
460b0563631STom Van Eyck 
461b0563631STom Van Eyck             output += internal_output_length;
462b0563631STom Van Eyck             *output_length += internal_output_length;
463b0563631STom Van Eyck             ctx->unprocessed_len = 0;
464b0563631STom Van Eyck         }
465b0563631STom Van Eyck     }
466b0563631STom Van Eyck 
467b0563631STom Van Eyck     while (input_length >= block_size) {
468b0563631STom Van Eyck         /* Run all full blocks we have, one by one */
469b0563631STom Van Eyck         status = mbedtls_to_psa_error(
470b0563631STom Van Eyck             mbedtls_cipher_update(ctx, input,
471b0563631STom Van Eyck                                   block_size,
472b0563631STom Van Eyck                                   output, &internal_output_length));
473b0563631STom Van Eyck 
474b0563631STom Van Eyck         if (status != PSA_SUCCESS) {
475b0563631STom Van Eyck             goto exit;
476b0563631STom Van Eyck         }
477b0563631STom Van Eyck 
478b0563631STom Van Eyck         input_length -= block_size;
479b0563631STom Van Eyck         input += block_size;
480b0563631STom Van Eyck 
481b0563631STom Van Eyck         output += internal_output_length;
482b0563631STom Van Eyck         *output_length += internal_output_length;
483b0563631STom Van Eyck     }
484b0563631STom Van Eyck 
485b0563631STom Van Eyck     if (input_length > 0) {
486b0563631STom Van Eyck         /* Save unprocessed bytes for later processing */
487b0563631STom Van Eyck         memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
488b0563631STom Van Eyck                input, input_length);
489b0563631STom Van Eyck         ctx->unprocessed_len += input_length;
490b0563631STom Van Eyck     }
491b0563631STom Van Eyck 
492b0563631STom Van Eyck     status = PSA_SUCCESS;
493b0563631STom Van Eyck 
494b0563631STom Van Eyck exit:
495b0563631STom Van Eyck     return status;
496b0563631STom Van Eyck }
497b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
498b0563631STom Van Eyck 
499b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_update(
500b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
501b0563631STom Van Eyck     const uint8_t *input, size_t input_length,
502b0563631STom Van Eyck     uint8_t *output, size_t output_size, size_t *output_length)
503b0563631STom Van Eyck {
504b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
505b0563631STom Van Eyck     size_t expected_output_size;
506b0563631STom Van Eyck 
507b0563631STom Van Eyck     if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
508b0563631STom Van Eyck         /* Take the unprocessed partial block left over from previous
509b0563631STom Van Eyck          * update calls, if any, plus the input to this call. Remove
510b0563631STom Van Eyck          * the last partial block, if any. You get the data that will be
511b0563631STom Van Eyck          * output in this call. */
512b0563631STom Van Eyck         expected_output_size =
513b0563631STom Van Eyck             (operation->ctx.cipher.unprocessed_len + input_length)
514b0563631STom Van Eyck             / operation->block_length * operation->block_length;
515b0563631STom Van Eyck     } else {
516b0563631STom Van Eyck         expected_output_size = input_length;
517b0563631STom Van Eyck     }
518b0563631STom Van Eyck 
519b0563631STom Van Eyck     if (output_size < expected_output_size) {
520b0563631STom Van Eyck         return PSA_ERROR_BUFFER_TOO_SMALL;
521b0563631STom Van Eyck     }
522b0563631STom Van Eyck 
523b0563631STom Van Eyck #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
524b0563631STom Van Eyck     if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
525b0563631STom Van Eyck         /* mbedtls_cipher_update has an API inconsistency: it will only
526b0563631STom Van Eyck          * process a single block at a time in ECB mode. Abstract away that
527b0563631STom Van Eyck          * inconsistency here to match the PSA API behaviour. */
528b0563631STom Van Eyck         status = psa_cipher_update_ecb(&operation->ctx.cipher,
529b0563631STom Van Eyck                                        input,
530b0563631STom Van Eyck                                        input_length,
531b0563631STom Van Eyck                                        output,
532b0563631STom Van Eyck                                        output_length);
533b0563631STom Van Eyck     } else
534b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
535b0563631STom Van Eyck     if (input_length == 0) {
536b0563631STom Van Eyck         /* There is no input, nothing to be done */
537b0563631STom Van Eyck         *output_length = 0;
538b0563631STom Van Eyck         status = PSA_SUCCESS;
539b0563631STom Van Eyck     } else {
540b0563631STom Van Eyck         status = mbedtls_to_psa_error(
541b0563631STom Van Eyck             mbedtls_cipher_update(&operation->ctx.cipher, input,
542b0563631STom Van Eyck                                   input_length, output, output_length));
543b0563631STom Van Eyck 
544b0563631STom Van Eyck         if (*output_length > output_size) {
545b0563631STom Van Eyck             return PSA_ERROR_CORRUPTION_DETECTED;
546b0563631STom Van Eyck         }
547b0563631STom Van Eyck     }
548b0563631STom Van Eyck 
549b0563631STom Van Eyck     return status;
550b0563631STom Van Eyck }
551b0563631STom Van Eyck 
552b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_finish(
553b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation,
554b0563631STom Van Eyck     uint8_t *output, size_t output_size, size_t *output_length)
555b0563631STom Van Eyck {
556b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
557b0563631STom Van Eyck     uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
558b0563631STom Van Eyck 
559b0563631STom Van Eyck     if (operation->ctx.cipher.unprocessed_len != 0) {
560b0563631STom Van Eyck         if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
561b0563631STom Van Eyck             operation->alg == PSA_ALG_CBC_NO_PADDING) {
562b0563631STom Van Eyck             status = PSA_ERROR_INVALID_ARGUMENT;
563b0563631STom Van Eyck             goto exit;
564b0563631STom Van Eyck         }
565b0563631STom Van Eyck     }
566b0563631STom Van Eyck 
567b0563631STom Van Eyck     status = mbedtls_to_psa_error(
568b0563631STom Van Eyck         mbedtls_cipher_finish(&operation->ctx.cipher,
569b0563631STom Van Eyck                               temp_output_buffer,
570b0563631STom Van Eyck                               output_length));
571b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
572b0563631STom Van Eyck         goto exit;
573b0563631STom Van Eyck     }
574b0563631STom Van Eyck 
575b0563631STom Van Eyck     if (*output_length == 0) {
576b0563631STom Van Eyck         ; /* Nothing to copy. Note that output may be NULL in this case. */
577b0563631STom Van Eyck     } else if (output_size >= *output_length) {
578b0563631STom Van Eyck         memcpy(output, temp_output_buffer, *output_length);
579b0563631STom Van Eyck     } else {
580b0563631STom Van Eyck         status = PSA_ERROR_BUFFER_TOO_SMALL;
581b0563631STom Van Eyck     }
582b0563631STom Van Eyck 
583b0563631STom Van Eyck exit:
584b0563631STom Van Eyck     mbedtls_platform_zeroize(temp_output_buffer,
585b0563631STom Van Eyck                              sizeof(temp_output_buffer));
586b0563631STom Van Eyck 
587b0563631STom Van Eyck     return status;
588b0563631STom Van Eyck }
589b0563631STom Van Eyck 
590b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_abort(
591b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t *operation)
592b0563631STom Van Eyck {
593b0563631STom Van Eyck     /* Sanity check (shouldn't happen: operation->alg should
594b0563631STom Van Eyck      * always have been initialized to a valid value). */
595b0563631STom Van Eyck     if (!PSA_ALG_IS_CIPHER(operation->alg)) {
596b0563631STom Van Eyck         return PSA_ERROR_BAD_STATE;
597b0563631STom Van Eyck     }
598b0563631STom Van Eyck 
599b0563631STom Van Eyck     mbedtls_cipher_free(&operation->ctx.cipher);
600b0563631STom Van Eyck 
601b0563631STom Van Eyck     return PSA_SUCCESS;
602b0563631STom Van Eyck }
603b0563631STom Van Eyck 
604b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_encrypt(
605b0563631STom Van Eyck     const psa_key_attributes_t *attributes,
606b0563631STom Van Eyck     const uint8_t *key_buffer,
607b0563631STom Van Eyck     size_t key_buffer_size,
608b0563631STom Van Eyck     psa_algorithm_t alg,
609b0563631STom Van Eyck     const uint8_t *iv,
610b0563631STom Van Eyck     size_t iv_length,
611b0563631STom Van Eyck     const uint8_t *input,
612b0563631STom Van Eyck     size_t input_length,
613b0563631STom Van Eyck     uint8_t *output,
614b0563631STom Van Eyck     size_t output_size,
615b0563631STom Van Eyck     size_t *output_length)
616b0563631STom Van Eyck {
617b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
618b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
619b0563631STom Van Eyck     size_t update_output_length, finish_output_length;
620b0563631STom Van Eyck 
621b0563631STom Van Eyck     status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
622b0563631STom Van Eyck                                               key_buffer, key_buffer_size,
623b0563631STom Van Eyck                                               alg);
624b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
625b0563631STom Van Eyck         goto exit;
626b0563631STom Van Eyck     }
627b0563631STom Van Eyck 
628b0563631STom Van Eyck     if (iv_length > 0) {
629b0563631STom Van Eyck         status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
630b0563631STom Van Eyck         if (status != PSA_SUCCESS) {
631b0563631STom Van Eyck             goto exit;
632b0563631STom Van Eyck         }
633b0563631STom Van Eyck     }
634b0563631STom Van Eyck 
635b0563631STom Van Eyck     status = mbedtls_psa_cipher_update(&operation, input, input_length,
636b0563631STom Van Eyck                                        output, output_size,
637b0563631STom Van Eyck                                        &update_output_length);
638b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
639b0563631STom Van Eyck         goto exit;
640b0563631STom Van Eyck     }
641b0563631STom Van Eyck 
642b0563631STom Van Eyck     status = mbedtls_psa_cipher_finish(
643b0563631STom Van Eyck         &operation,
644b0563631STom Van Eyck         mbedtls_buffer_offset(output, update_output_length),
645b0563631STom Van Eyck         output_size - update_output_length, &finish_output_length);
646b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
647b0563631STom Van Eyck         goto exit;
648b0563631STom Van Eyck     }
649b0563631STom Van Eyck 
650b0563631STom Van Eyck     *output_length = update_output_length + finish_output_length;
651b0563631STom Van Eyck 
652b0563631STom Van Eyck exit:
653b0563631STom Van Eyck     if (status == PSA_SUCCESS) {
654b0563631STom Van Eyck         status = mbedtls_psa_cipher_abort(&operation);
655b0563631STom Van Eyck     } else {
656b0563631STom Van Eyck         mbedtls_psa_cipher_abort(&operation);
657b0563631STom Van Eyck     }
658b0563631STom Van Eyck 
659b0563631STom Van Eyck     return status;
660b0563631STom Van Eyck }
661b0563631STom Van Eyck 
662b0563631STom Van Eyck psa_status_t mbedtls_psa_cipher_decrypt(
663b0563631STom Van Eyck     const psa_key_attributes_t *attributes,
664b0563631STom Van Eyck     const uint8_t *key_buffer,
665b0563631STom Van Eyck     size_t key_buffer_size,
666b0563631STom Van Eyck     psa_algorithm_t alg,
667b0563631STom Van Eyck     const uint8_t *input,
668b0563631STom Van Eyck     size_t input_length,
669b0563631STom Van Eyck     uint8_t *output,
670b0563631STom Van Eyck     size_t output_size,
671b0563631STom Van Eyck     size_t *output_length)
672b0563631STom Van Eyck {
673b0563631STom Van Eyck     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
674b0563631STom Van Eyck     mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
675b0563631STom Van Eyck     size_t olength, accumulated_length;
676b0563631STom Van Eyck 
677b0563631STom Van Eyck     status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
678b0563631STom Van Eyck                                               key_buffer, key_buffer_size,
679b0563631STom Van Eyck                                               alg);
680b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
681b0563631STom Van Eyck         goto exit;
682b0563631STom Van Eyck     }
683b0563631STom Van Eyck 
684b0563631STom Van Eyck     if (operation.iv_length > 0) {
685b0563631STom Van Eyck         status = mbedtls_psa_cipher_set_iv(&operation,
686b0563631STom Van Eyck                                            input, operation.iv_length);
687b0563631STom Van Eyck         if (status != PSA_SUCCESS) {
688b0563631STom Van Eyck             goto exit;
689b0563631STom Van Eyck         }
690b0563631STom Van Eyck     }
691b0563631STom Van Eyck 
692b0563631STom Van Eyck     status = mbedtls_psa_cipher_update(
693b0563631STom Van Eyck         &operation,
694b0563631STom Van Eyck         mbedtls_buffer_offset_const(input, operation.iv_length),
695b0563631STom Van Eyck         input_length - operation.iv_length,
696b0563631STom Van Eyck         output, output_size, &olength);
697b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
698b0563631STom Van Eyck         goto exit;
699b0563631STom Van Eyck     }
700b0563631STom Van Eyck 
701b0563631STom Van Eyck     accumulated_length = olength;
702b0563631STom Van Eyck 
703b0563631STom Van Eyck     status = mbedtls_psa_cipher_finish(
704b0563631STom Van Eyck         &operation,
705b0563631STom Van Eyck         mbedtls_buffer_offset(output, accumulated_length),
706b0563631STom Van Eyck         output_size - accumulated_length, &olength);
707b0563631STom Van Eyck     if (status != PSA_SUCCESS) {
708b0563631STom Van Eyck         goto exit;
709b0563631STom Van Eyck     }
710b0563631STom Van Eyck 
711b0563631STom Van Eyck     *output_length = accumulated_length + olength;
712b0563631STom Van Eyck 
713b0563631STom Van Eyck exit:
714b0563631STom Van Eyck     if (status == PSA_SUCCESS) {
715b0563631STom Van Eyck         status = mbedtls_psa_cipher_abort(&operation);
716b0563631STom Van Eyck     } else {
717b0563631STom Van Eyck         mbedtls_psa_cipher_abort(&operation);
718b0563631STom Van Eyck     }
719b0563631STom Van Eyck 
720b0563631STom Van Eyck     return status;
721b0563631STom Van Eyck }
722b0563631STom Van Eyck #endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
723b0563631STom Van Eyck 
724b0563631STom Van Eyck #endif /* MBEDTLS_PSA_CRYPTO_C */
725