blob: efc5813ff08858f61559191560259f7f15e5796a [file] [log] [blame]
Ronald Cron0ff57952021-03-08 16:46:35 +01001/*
2 * PSA cipher driver entry points
3 */
4/*
5 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00006 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Ronald Cron0ff57952021-03-08 16:46:35 +01007 */
8
9#include "common.h"
10
11#if defined(MBEDTLS_PSA_CRYPTO_C)
12
Martin Man4741e0b2022-08-02 12:44:35 +020013#include "psa_crypto_cipher.h"
Ronald Crond6d28882020-12-14 14:56:02 +010014#include "psa_crypto_core.h"
Ronald Cron6d051732020-10-01 14:10:20 +020015#include "psa_crypto_random_impl.h"
16
Ronald Crond6d28882020-12-14 14:56:02 +010017#include "mbedtls/cipher.h"
Ronald Cron6d051732020-10-01 14:10:20 +020018#include "mbedtls/error.h"
Ronald Cron0ff57952021-03-08 16:46:35 +010019
Ronald Crond6d28882020-12-14 14:56:02 +010020#include <string.h>
21
Valerio Setti1e21f262023-10-20 16:24:07 +020022/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
23 * are enabled, but it does not provide any compatibility check between them
24 * (i.e. if the specified key works with the specified algorithm). This helper
25 * function is meant to provide this support.
26 * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
27 * requires CIPHER_C to be enabled.
28 */
29static psa_status_t mbedtls_cipher_validate_values(
30 psa_algorithm_t alg,
31 psa_key_type_t key_type)
32{
Dave Rodgman3e5cc172023-10-31 17:54:58 +000033 /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
34 eliminate bits of the logic below. */
35#if !defined(PSA_WANT_KEY_TYPE_AES)
36 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
37#endif
38#if !defined(PSA_WANT_KEY_TYPE_ARIA)
39 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
40#endif
41#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
42 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
43#endif
44#if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
45 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
46#endif
47#if !defined(PSA_WANT_KEY_TYPE_DES)
48 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
49#endif
50#if !defined(PSA_WANT_ALG_CCM)
51 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
52#endif
53#if !defined(PSA_WANT_ALG_GCM)
54 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
55#endif
56#if !defined(PSA_WANT_ALG_STREAM_CIPHER)
57 MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
58#endif
59#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
60 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
61#endif
62#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
63 MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
64#endif
65#if !defined(PSA_WANT_ALG_CTR)
66 MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
67#endif
68#if !defined(PSA_WANT_ALG_CFB)
69 MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
70#endif
71#if !defined(PSA_WANT_ALG_OFB)
72 MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
73#endif
Dave Rodgman3e5cc172023-10-31 17:54:58 +000074#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
75 MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
76#endif
77#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
78 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
79#endif
80#if !defined(PSA_WANT_ALG_CBC_PKCS7)
81 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
82#endif
83#if !defined(PSA_WANT_ALG_CMAC)
84 MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
85#endif
Valerio Setti1e21f262023-10-20 16:24:07 +020086
Dave Rodgman6d2c1b32023-10-31 17:54:42 +000087 if (alg == PSA_ALG_STREAM_CIPHER ||
88 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
89 if (key_type == PSA_KEY_TYPE_CHACHA20) {
90 return PSA_SUCCESS;
91 }
Valerio Setti1e21f262023-10-20 16:24:07 +020092 }
93
Dave Rodgman6d2c1b32023-10-31 17:54:42 +000094 if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
95 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
96 alg == PSA_ALG_CCM_STAR_NO_TAG) {
97 if (key_type == PSA_KEY_TYPE_AES ||
98 key_type == PSA_KEY_TYPE_ARIA ||
99 key_type == PSA_KEY_TYPE_CAMELLIA) {
100 return PSA_SUCCESS;
101 }
102 }
103
104 if (alg == PSA_ALG_CTR ||
105 alg == PSA_ALG_CFB ||
106 alg == PSA_ALG_OFB ||
107 alg == PSA_ALG_XTS ||
108 alg == PSA_ALG_ECB_NO_PADDING ||
109 alg == PSA_ALG_CBC_NO_PADDING ||
110 alg == PSA_ALG_CBC_PKCS7 ||
111 alg == PSA_ALG_CMAC) {
112 if (key_type == PSA_KEY_TYPE_AES ||
113 key_type == PSA_KEY_TYPE_ARIA ||
114 key_type == PSA_KEY_TYPE_DES ||
115 key_type == PSA_KEY_TYPE_CAMELLIA) {
116 return PSA_SUCCESS;
117 }
118 }
119
120 return PSA_ERROR_NOT_SUPPORTED;
Valerio Setti1e21f262023-10-20 16:24:07 +0200121}
122
Valerio Setti4a249822023-10-18 12:34:54 +0200123psa_status_t mbedtls_cipher_values_from_psa(
Ronald Cron75e6ae22021-03-17 14:46:05 +0100124 psa_algorithm_t alg,
125 psa_key_type_t key_type,
Valerio Setti4a249822023-10-18 12:34:54 +0200126 size_t *key_bits,
127 mbedtls_cipher_mode_t *mode,
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 mbedtls_cipher_id_t *cipher_id)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100129{
Ronald Cron75e6ae22021-03-17 14:46:05 +0100130 mbedtls_cipher_id_t cipher_id_tmp;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200131 /* Only DES modifies key_bits */
132#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Valerio Setti4a249822023-10-18 12:34:54 +0200133 (void) key_bits;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200134#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100135
Gilles Peskine449bd832023-01-11 14:50:10 +0100136 if (PSA_ALG_IS_AEAD(alg)) {
137 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
138 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100139
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
141 switch (alg) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100142#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100143 case PSA_ALG_STREAM_CIPHER:
Valerio Setti4a249822023-10-18 12:34:54 +0200144 *mode = MBEDTLS_MODE_STREAM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100145 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100146#endif
147#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100148 case PSA_ALG_CTR:
Valerio Setti4a249822023-10-18 12:34:54 +0200149 *mode = MBEDTLS_MODE_CTR;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100150 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100151#endif
152#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100153 case PSA_ALG_CFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200154 *mode = MBEDTLS_MODE_CFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100155 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100156#endif
157#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100158 case PSA_ALG_OFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200159 *mode = MBEDTLS_MODE_OFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100160 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100161#endif
162#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100163 case PSA_ALG_ECB_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200164 *mode = MBEDTLS_MODE_ECB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100165 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100166#endif
167#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100168 case PSA_ALG_CBC_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200169 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100170 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100171#endif
172#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100173 case PSA_ALG_CBC_PKCS7:
Valerio Setti4a249822023-10-18 12:34:54 +0200174 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100175 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100176#endif
177#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200178 case PSA_ALG_CCM_STAR_NO_TAG:
Valerio Setti4a249822023-10-18 12:34:54 +0200179 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200180 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100181#endif
182#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200184 *mode = MBEDTLS_MODE_CCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100185 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100186#endif
187#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100188 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200189 *mode = MBEDTLS_MODE_GCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100190 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100191#endif
192#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200194 *mode = MBEDTLS_MODE_CHACHAPOLY;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100195 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100196#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100197 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200198 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100199 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 } else if (alg == PSA_ALG_CMAC) {
Valerio Setti4a249822023-10-18 12:34:54 +0200201 *mode = MBEDTLS_MODE_ECB;
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 } else {
Valerio Setti4a249822023-10-18 12:34:54 +0200203 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine449bd832023-01-11 14:50:10 +0100204 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 switch (key_type) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100207#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100208 case PSA_KEY_TYPE_AES:
209 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
210 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100211#endif
212#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine6c12a1e2021-09-21 11:59:39 +0200213 case PSA_KEY_TYPE_ARIA:
214 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
215 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100216#endif
217#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100218 case PSA_KEY_TYPE_DES:
219 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
220 * and 192 for three-key Triple-DES. */
Valerio Setti4a249822023-10-18 12:34:54 +0200221 if (*key_bits == 64) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100222 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 } else {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100224 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100226 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
227 * but two-key Triple-DES is functionally three-key Triple-DES
228 * with K1=K3, so that's how we present it to mbedtls. */
Valerio Setti4a249822023-10-18 12:34:54 +0200229 if (*key_bits == 128) {
230 *key_bits = 192;
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100232 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100233#endif
234#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100235 case PSA_KEY_TYPE_CAMELLIA:
236 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
237 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100238#endif
239#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100240 case PSA_KEY_TYPE_CHACHA20:
241 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
242 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100243#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100244 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200245 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100246 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 if (cipher_id != NULL) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100248 *cipher_id = cipher_id_tmp;
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100250
Valerio Setti1e21f262023-10-20 16:24:07 +0200251 return mbedtls_cipher_validate_values(alg, key_type);
Valerio Setti4a249822023-10-18 12:34:54 +0200252}
253
254#if defined(MBEDTLS_CIPHER_C)
255const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
256 psa_algorithm_t alg,
257 psa_key_type_t key_type,
258 size_t key_bits,
259 mbedtls_cipher_id_t *cipher_id)
260{
261 mbedtls_cipher_mode_t mode;
262 psa_status_t status;
Patrick Wildt38bc9602024-05-15 18:22:17 +0000263 mbedtls_cipher_id_t cipher_id_tmp = MBEDTLS_CIPHER_ID_NONE;
Valerio Setti4a249822023-10-18 12:34:54 +0200264
265 status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
266 if (status != PSA_SUCCESS) {
267 return NULL;
268 }
269 if (cipher_id != NULL) {
270 *cipher_id = cipher_id_tmp;
271 }
272
273 return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
Ronald Cron75e6ae22021-03-17 14:46:05 +0100274}
Valerio Setti2c2aded2023-08-25 09:22:19 +0200275#endif /* MBEDTLS_CIPHER_C */
Ronald Cron75e6ae22021-03-17 14:46:05 +0100276
Ronald Cron0266cfe2021-03-13 18:50:11 +0100277#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100278
Ronald Cron0266cfe2021-03-13 18:50:11 +0100279static psa_status_t psa_cipher_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100280 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100281 const psa_key_attributes_t *attributes,
282 const uint8_t *key_buffer, size_t key_buffer_size,
283 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 mbedtls_operation_t cipher_operation)
Ronald Crond6d28882020-12-14 14:56:02 +0100285{
286 int ret = 0;
287 size_t key_bits;
288 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2f107ae2024-02-28 01:26:46 +0100289 psa_key_type_t key_type = attributes->type;
Ronald Crond6d28882020-12-14 14:56:02 +0100290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 (void) key_buffer_size;
Ronald Crond6d28882020-12-14 14:56:02 +0100292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 mbedtls_cipher_init(&operation->ctx.cipher);
Ronald Crond6d28882020-12-14 14:56:02 +0100294
Ronald Cron6e412a72021-03-10 09:58:47 +0100295 operation->alg = alg;
Gilles Peskine2f107ae2024-02-28 01:26:46 +0100296 key_bits = attributes->bits;
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
298 key_bits, NULL);
299 if (cipher_info == NULL) {
300 return PSA_ERROR_NOT_SUPPORTED;
301 }
Ronald Crond6d28882020-12-14 14:56:02 +0100302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
304 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100305 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 }
Ronald Crond6d28882020-12-14 14:56:02 +0100307
Ronald Cron0266cfe2021-03-13 18:50:11 +0100308#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
Ronald Crond6d28882020-12-14 14:56:02 +0100310 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
311 uint8_t keys[24];
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 memcpy(keys, key_buffer, 16);
313 memcpy(keys + 16, key_buffer, 8);
314 ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
315 keys,
316 192, cipher_operation);
317 } else
Ronald Crond6d28882020-12-14 14:56:02 +0100318#endif
319 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
321 (int) key_bits, cipher_operation);
Ronald Crond6d28882020-12-14 14:56:02 +0100322 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100324 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 }
Ronald Crond6d28882020-12-14 14:56:02 +0100326
Ronald Cron0266cfe2021-03-13 18:50:11 +0100327#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
328 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 switch (alg) {
Ronald Crond6d28882020-12-14 14:56:02 +0100330 case PSA_ALG_CBC_NO_PADDING:
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
332 MBEDTLS_PADDING_NONE);
Ronald Crond6d28882020-12-14 14:56:02 +0100333 break;
334 case PSA_ALG_CBC_PKCS7:
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
336 MBEDTLS_PADDING_PKCS7);
Ronald Crond6d28882020-12-14 14:56:02 +0100337 break;
338 default:
339 /* The algorithm doesn't involve padding. */
340 ret = 0;
341 break;
342 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100343 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100344 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100346#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
347 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
350 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
351 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Ronald Crond6d28882020-12-14 14:56:02 +0100352
353exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 return mbedtls_to_psa_error(ret);
Ronald Crond6d28882020-12-14 14:56:02 +0100355}
356
Ronald Cron0266cfe2021-03-13 18:50:11 +0100357psa_status_t mbedtls_psa_cipher_encrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100358 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100359 const psa_key_attributes_t *attributes,
360 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100361 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100362{
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 return psa_cipher_setup(operation, attributes,
364 key_buffer, key_buffer_size,
365 alg, MBEDTLS_ENCRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100366}
367
Ronald Cron0266cfe2021-03-13 18:50:11 +0100368psa_status_t mbedtls_psa_cipher_decrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100369 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100370 const psa_key_attributes_t *attributes,
371 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100373{
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 return psa_cipher_setup(operation, attributes,
375 key_buffer, key_buffer_size,
376 alg, MBEDTLS_DECRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100377}
Ronald Cron6d051732020-10-01 14:10:20 +0200378
Ronald Cron0266cfe2021-03-13 18:50:11 +0100379psa_status_t mbedtls_psa_cipher_set_iv(
380 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 const uint8_t *iv, size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100382{
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 if (iv_length != operation->iv_length) {
384 return PSA_ERROR_INVALID_ARGUMENT;
385 }
Ronald Cron8287e6b2021-03-12 10:35:18 +0100386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 return mbedtls_to_psa_error(
388 mbedtls_cipher_set_iv(&operation->ctx.cipher,
389 iv, iv_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100390}
391
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100392#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine55dffe52021-09-13 09:33:28 +0200393/** Process input for which the algorithm is set to ECB mode.
394 *
395 * This requires manual processing, since the PSA API is defined as being
396 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
397 * but the underlying mbedtls_cipher_update only takes full blocks.
398 *
399 * \param ctx The mbedtls cipher context to use. It must have been
400 * set up for ECB.
401 * \param[in] input The input plaintext or ciphertext to process.
402 * \param input_length The number of bytes to process from \p input.
403 * This does not need to be aligned to a block boundary.
404 * If there is a partial block at the end of the input,
405 * it is stored in \p ctx for future processing.
Gilles Peskined87d8732021-09-13 12:20:51 +0200406 * \param output The buffer where the output is written. It must be
407 * at least `BS * floor((p + input_length) / BS)` bytes
408 * long, where `p` is the number of bytes in the
409 * unprocessed partial block in \p ctx (with
410 * `0 <= p <= BS - 1`) and `BS` is the block size.
Gilles Peskine55dffe52021-09-13 09:33:28 +0200411 * \param output_length On success, the number of bytes written to \p output.
412 * \c 0 on error.
413 *
414 * \return #PSA_SUCCESS or an error from a hardware accelerator
415 */
Ronald Cron6d051732020-10-01 14:10:20 +0200416static psa_status_t psa_cipher_update_ecb(
417 mbedtls_cipher_context_t *ctx,
418 const uint8_t *input,
419 size_t input_length,
420 uint8_t *output,
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200422{
423 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman85a88132023-06-24 11:41:50 +0100424 size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Ronald Cron6d051732020-10-01 14:10:20 +0200425 size_t internal_output_length = 0;
426 *output_length = 0;
427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 if (input_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200429 status = PSA_SUCCESS;
430 goto exit;
431 }
432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 if (ctx->unprocessed_len > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200434 /* Fill up to block size, and run the block if there's a full one. */
435 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 if (input_length < bytes_to_copy) {
Ronald Cron6d051732020-10-01 14:10:20 +0200438 bytes_to_copy = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 }
Ronald Cron6d051732020-10-01 14:10:20 +0200440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
442 input, bytes_to_copy);
Ronald Cron6d051732020-10-01 14:10:20 +0200443 input_length -= bytes_to_copy;
444 input += bytes_to_copy;
445 ctx->unprocessed_len += bytes_to_copy;
446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 if (ctx->unprocessed_len == block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200448 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 mbedtls_cipher_update(ctx,
450 ctx->unprocessed_data,
451 block_size,
452 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200455 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 }
Ronald Cron6d051732020-10-01 14:10:20 +0200457
458 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200459 *output_length += internal_output_length;
460 ctx->unprocessed_len = 0;
461 }
462 }
463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 while (input_length >= block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200465 /* Run all full blocks we have, one by one */
466 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 mbedtls_cipher_update(ctx, input,
468 block_size,
469 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200472 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 }
Ronald Cron6d051732020-10-01 14:10:20 +0200474
475 input_length -= block_size;
476 input += block_size;
477
478 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200479 *output_length += internal_output_length;
480 }
481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 if (input_length > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200483 /* Save unprocessed bytes for later processing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
485 input, input_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200486 ctx->unprocessed_len += input_length;
487 }
488
489 status = PSA_SUCCESS;
490
491exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200493}
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100494#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200495
Ronald Cron0266cfe2021-03-13 18:50:11 +0100496psa_status_t mbedtls_psa_cipher_update(
497 mbedtls_psa_cipher_operation_t *operation,
498 const uint8_t *input, size_t input_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200500{
501 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
502 size_t expected_output_size;
503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
Ronald Cron6d051732020-10-01 14:10:20 +0200505 /* Take the unprocessed partial block left over from previous
506 * update calls, if any, plus the input to this call. Remove
507 * the last partial block, if any. You get the data that will be
508 * output in this call. */
509 expected_output_size =
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 (operation->ctx.cipher.unprocessed_len + input_length)
Ronald Cron6ad554c2021-03-26 09:29:09 +0100511 / operation->block_length * operation->block_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200513 expected_output_size = input_length;
514 }
515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 if (output_size < expected_output_size) {
517 return PSA_ERROR_BUFFER_TOO_SMALL;
518 }
Ronald Cron6d051732020-10-01 14:10:20 +0200519
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100520#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200522 /* mbedtls_cipher_update has an API inconsistency: it will only
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 * process a single block at a time in ECB mode. Abstract away that
524 * inconsistency here to match the PSA API behaviour. */
525 status = psa_cipher_update_ecb(&operation->ctx.cipher,
526 input,
527 input_length,
528 output,
529 output_length);
530 } else
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100531#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Gabor Mezeic25fbd22024-01-29 13:33:58 +0100532 if (input_length == 0) {
533 /* There is no input, nothing to be done */
534 *output_length = 0;
535 status = PSA_SUCCESS;
536 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200537 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_cipher_update(&operation->ctx.cipher, input,
539 input_length, output, output_length));
gabor-mezei-arm58c17272021-06-29 16:41:25 +0200540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 if (*output_length > output_size) {
542 return PSA_ERROR_CORRUPTION_DETECTED;
543 }
Ronald Cron6d051732020-10-01 14:10:20 +0200544 }
545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200547}
548
Ronald Cron0266cfe2021-03-13 18:50:11 +0100549psa_status_t mbedtls_psa_cipher_finish(
550 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200552{
553 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
554 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
555
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 if (operation->ctx.cipher.unprocessed_len != 0) {
557 if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
558 operation->alg == PSA_ALG_CBC_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200559 status = PSA_ERROR_INVALID_ARGUMENT;
560 goto exit;
561 }
562 }
563
564 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 mbedtls_cipher_finish(&operation->ctx.cipher,
566 temp_output_buffer,
567 output_length));
568 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200569 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100570 }
Ronald Cron6d051732020-10-01 14:10:20 +0200571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (*output_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200573 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 } else if (output_size >= *output_length) {
575 memcpy(output, temp_output_buffer, *output_length);
576 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200577 status = PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 }
Ronald Cron6d051732020-10-01 14:10:20 +0200579
580exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 mbedtls_platform_zeroize(temp_output_buffer,
582 sizeof(temp_output_buffer));
Ronald Cron6d051732020-10-01 14:10:20 +0200583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200585}
586
Ronald Cron0266cfe2021-03-13 18:50:11 +0100587psa_status_t mbedtls_psa_cipher_abort(
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 mbedtls_psa_cipher_operation_t *operation)
Ronald Cron6d051732020-10-01 14:10:20 +0200589{
Ronald Cron937dfee2021-03-10 09:17:32 +0100590 /* Sanity check (shouldn't happen: operation->alg should
591 * always have been initialized to a valid value). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 if (!PSA_ALG_IS_CIPHER(operation->alg)) {
593 return PSA_ERROR_BAD_STATE;
594 }
Ronald Cron937dfee2021-03-10 09:17:32 +0100595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 mbedtls_cipher_free(&operation->ctx.cipher);
Ronald Cron6d051732020-10-01 14:10:20 +0200597
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 return PSA_SUCCESS;
Ronald Cron6d051732020-10-01 14:10:20 +0200599}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100600
Ronald Cron0266cfe2021-03-13 18:50:11 +0100601psa_status_t mbedtls_psa_cipher_encrypt(
602 const psa_key_attributes_t *attributes,
603 const uint8_t *key_buffer,
604 size_t key_buffer_size,
605 psa_algorithm_t alg,
Ronald Cron9b674282021-07-09 09:19:35 +0200606 const uint8_t *iv,
607 size_t iv_length,
Ronald Cron0266cfe2021-03-13 18:50:11 +0100608 const uint8_t *input,
609 size_t input_length,
610 uint8_t *output,
611 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100613{
614 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
615 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Cron8188d192021-12-14 10:58:18 +0100616 size_t update_output_length, finish_output_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
619 key_buffer, key_buffer_size,
620 alg);
621 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100622 goto exit;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100623 }
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 if (iv_length > 0) {
626 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
627 if (status != PSA_SUCCESS) {
628 goto exit;
629 }
630 }
631
632 status = mbedtls_psa_cipher_update(&operation, input, input_length,
633 output, output_size,
634 &update_output_length);
635 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100636 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100638
Gilles Peskine42649d92022-11-23 14:15:57 +0100639 status = mbedtls_psa_cipher_finish(
640 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 mbedtls_buffer_offset(output, update_output_length),
642 output_size - update_output_length, &finish_output_length);
643 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100644 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100646
Ronald Cron8188d192021-12-14 10:58:18 +0100647 *output_length = update_output_length + finish_output_length;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200648
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100649exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (status == PSA_SUCCESS) {
651 status = mbedtls_psa_cipher_abort(&operation);
652 } else {
653 mbedtls_psa_cipher_abort(&operation);
654 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100657}
658
Ronald Cron0266cfe2021-03-13 18:50:11 +0100659psa_status_t mbedtls_psa_cipher_decrypt(
660 const psa_key_attributes_t *attributes,
661 const uint8_t *key_buffer,
662 size_t key_buffer_size,
663 psa_algorithm_t alg,
664 const uint8_t *input,
665 size_t input_length,
666 uint8_t *output,
667 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100669{
670 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
671 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200672 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
675 key_buffer, key_buffer_size,
676 alg);
677 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100678 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 if (operation.iv_length > 0) {
682 status = mbedtls_psa_cipher_set_iv(&operation,
683 input, operation.iv_length);
684 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100685 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100687 }
688
Gilles Peskine42649d92022-11-23 14:15:57 +0100689 status = mbedtls_psa_cipher_update(
690 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 mbedtls_buffer_offset_const(input, operation.iv_length),
Gilles Peskine42649d92022-11-23 14:15:57 +0100692 input_length - operation.iv_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 output, output_size, &olength);
694 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100695 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100697
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200698 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200699
Gilles Peskine42649d92022-11-23 14:15:57 +0100700 status = mbedtls_psa_cipher_finish(
701 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 mbedtls_buffer_offset(output, accumulated_length),
703 output_size - accumulated_length, &olength);
704 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100705 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100707
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200708 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200709
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100710exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if (status == PSA_SUCCESS) {
712 status = mbedtls_psa_cipher_abort(&operation);
713 } else {
714 mbedtls_psa_cipher_abort(&operation);
715 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100718}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100719#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100720
Ronald Cron0ff57952021-03-08 16:46:35 +0100721#endif /* MBEDTLS_PSA_CRYPTO_C */