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