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