blob: 881d673cc08dfb771fa6b6dc6a5d3aff99593e39 [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
74#if !defined(PSA_WANT_ALG_XTS)
75 MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
76#endif
77#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
78 MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
79#endif
80#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
81 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
82#endif
83#if !defined(PSA_WANT_ALG_CBC_PKCS7)
84 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
85#endif
86#if !defined(PSA_WANT_ALG_CMAC)
87 MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
88#endif
Valerio Setti1e21f262023-10-20 16:24:07 +020089
Dave Rodgman6d2c1b32023-10-31 17:54:42 +000090 if (alg == PSA_ALG_STREAM_CIPHER ||
91 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
92 if (key_type == PSA_KEY_TYPE_CHACHA20) {
93 return PSA_SUCCESS;
94 }
Valerio Setti1e21f262023-10-20 16:24:07 +020095 }
96
Dave Rodgman6d2c1b32023-10-31 17:54:42 +000097 if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
98 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
99 alg == PSA_ALG_CCM_STAR_NO_TAG) {
100 if (key_type == PSA_KEY_TYPE_AES ||
101 key_type == PSA_KEY_TYPE_ARIA ||
102 key_type == PSA_KEY_TYPE_CAMELLIA) {
103 return PSA_SUCCESS;
104 }
105 }
106
107 if (alg == PSA_ALG_CTR ||
108 alg == PSA_ALG_CFB ||
109 alg == PSA_ALG_OFB ||
110 alg == PSA_ALG_XTS ||
111 alg == PSA_ALG_ECB_NO_PADDING ||
112 alg == PSA_ALG_CBC_NO_PADDING ||
113 alg == PSA_ALG_CBC_PKCS7 ||
114 alg == PSA_ALG_CMAC) {
115 if (key_type == PSA_KEY_TYPE_AES ||
116 key_type == PSA_KEY_TYPE_ARIA ||
117 key_type == PSA_KEY_TYPE_DES ||
118 key_type == PSA_KEY_TYPE_CAMELLIA) {
119 return PSA_SUCCESS;
120 }
121 }
122
123 return PSA_ERROR_NOT_SUPPORTED;
Valerio Setti1e21f262023-10-20 16:24:07 +0200124}
125
Valerio Setti4a249822023-10-18 12:34:54 +0200126psa_status_t mbedtls_cipher_values_from_psa(
Ronald Cron75e6ae22021-03-17 14:46:05 +0100127 psa_algorithm_t alg,
128 psa_key_type_t key_type,
Valerio Setti4a249822023-10-18 12:34:54 +0200129 size_t *key_bits,
130 mbedtls_cipher_mode_t *mode,
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 mbedtls_cipher_id_t *cipher_id)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100132{
Ronald Cron75e6ae22021-03-17 14:46:05 +0100133 mbedtls_cipher_id_t cipher_id_tmp;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200134 /* Only DES modifies key_bits */
135#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Valerio Setti4a249822023-10-18 12:34:54 +0200136 (void) key_bits;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200137#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100138
Gilles Peskine449bd832023-01-11 14:50:10 +0100139 if (PSA_ALG_IS_AEAD(alg)) {
140 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
141 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100142
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
144 switch (alg) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100145#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100146 case PSA_ALG_STREAM_CIPHER:
Valerio Setti4a249822023-10-18 12:34:54 +0200147 *mode = MBEDTLS_MODE_STREAM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100148 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100149#endif
150#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100151 case PSA_ALG_CTR:
Valerio Setti4a249822023-10-18 12:34:54 +0200152 *mode = MBEDTLS_MODE_CTR;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100153 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100154#endif
155#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100156 case PSA_ALG_CFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200157 *mode = MBEDTLS_MODE_CFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100158 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100159#endif
160#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100161 case PSA_ALG_OFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200162 *mode = MBEDTLS_MODE_OFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100163 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100164#endif
165#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100166 case PSA_ALG_ECB_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200167 *mode = MBEDTLS_MODE_ECB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100168 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100169#endif
170#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100171 case PSA_ALG_CBC_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200172 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100173 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100174#endif
175#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100176 case PSA_ALG_CBC_PKCS7:
Valerio Setti4a249822023-10-18 12:34:54 +0200177 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100178 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100179#endif
180#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200181 case PSA_ALG_CCM_STAR_NO_TAG:
Valerio Setti4a249822023-10-18 12:34:54 +0200182 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200183 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100184#endif
185#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200187 *mode = MBEDTLS_MODE_CCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100188 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100189#endif
190#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100191 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200192 *mode = MBEDTLS_MODE_GCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100193 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100194#endif
195#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200197 *mode = MBEDTLS_MODE_CHACHAPOLY;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100198 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100199#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100200 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200201 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100202 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 } else if (alg == PSA_ALG_CMAC) {
Valerio Setti4a249822023-10-18 12:34:54 +0200204 *mode = MBEDTLS_MODE_ECB;
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 } else {
Valerio Setti4a249822023-10-18 12:34:54 +0200206 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209 switch (key_type) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100210#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100211 case PSA_KEY_TYPE_AES:
212 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
213 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100214#endif
215#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine6c12a1e2021-09-21 11:59:39 +0200216 case PSA_KEY_TYPE_ARIA:
217 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
218 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100219#endif
220#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100221 case PSA_KEY_TYPE_DES:
222 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
223 * and 192 for three-key Triple-DES. */
Valerio Setti4a249822023-10-18 12:34:54 +0200224 if (*key_bits == 64) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100225 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 } else {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100227 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100229 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
230 * but two-key Triple-DES is functionally three-key Triple-DES
231 * with K1=K3, so that's how we present it to mbedtls. */
Valerio Setti4a249822023-10-18 12:34:54 +0200232 if (*key_bits == 128) {
233 *key_bits = 192;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100235 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100236#endif
237#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100238 case PSA_KEY_TYPE_CAMELLIA:
239 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
240 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100241#endif
242#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100243 case PSA_KEY_TYPE_CHACHA20:
244 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
245 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100246#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100247 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200248 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100249 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 if (cipher_id != NULL) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100251 *cipher_id = cipher_id_tmp;
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100253
Valerio Setti1e21f262023-10-20 16:24:07 +0200254 return mbedtls_cipher_validate_values(alg, key_type);
Valerio Setti4a249822023-10-18 12:34:54 +0200255}
256
257#if defined(MBEDTLS_CIPHER_C)
258const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
259 psa_algorithm_t alg,
260 psa_key_type_t key_type,
261 size_t key_bits,
262 mbedtls_cipher_id_t *cipher_id)
263{
264 mbedtls_cipher_mode_t mode;
265 psa_status_t status;
266 mbedtls_cipher_id_t cipher_id_tmp;
267
268 status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
269 if (status != PSA_SUCCESS) {
270 return NULL;
271 }
272 if (cipher_id != NULL) {
273 *cipher_id = cipher_id_tmp;
274 }
275
276 return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
Ronald Cron75e6ae22021-03-17 14:46:05 +0100277}
Valerio Setti2c2aded2023-08-25 09:22:19 +0200278#endif /* MBEDTLS_CIPHER_C */
Ronald Cron75e6ae22021-03-17 14:46:05 +0100279
Ronald Cron0266cfe2021-03-13 18:50:11 +0100280#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100281
Ronald Cron0266cfe2021-03-13 18:50:11 +0100282static psa_status_t psa_cipher_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100283 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100284 const psa_key_attributes_t *attributes,
285 const uint8_t *key_buffer, size_t key_buffer_size,
286 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 mbedtls_operation_t cipher_operation)
Ronald Crond6d28882020-12-14 14:56:02 +0100288{
289 int ret = 0;
290 size_t key_bits;
291 const mbedtls_cipher_info_t *cipher_info = NULL;
Gilles Peskine2f107ae2024-02-28 01:26:46 +0100292 psa_key_type_t key_type = attributes->type;
Ronald Crond6d28882020-12-14 14:56:02 +0100293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 (void) key_buffer_size;
Ronald Crond6d28882020-12-14 14:56:02 +0100295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 mbedtls_cipher_init(&operation->ctx.cipher);
Ronald Crond6d28882020-12-14 14:56:02 +0100297
Ronald Cron6e412a72021-03-10 09:58:47 +0100298 operation->alg = alg;
Gilles Peskine2f107ae2024-02-28 01:26:46 +0100299 key_bits = attributes->bits;
Gilles Peskine449bd832023-01-11 14:50:10 +0100300 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
301 key_bits, NULL);
302 if (cipher_info == NULL) {
303 return PSA_ERROR_NOT_SUPPORTED;
304 }
Ronald Crond6d28882020-12-14 14:56:02 +0100305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
307 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100308 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 }
Ronald Crond6d28882020-12-14 14:56:02 +0100310
Ronald Cron0266cfe2021-03-13 18:50:11 +0100311#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
Ronald Crond6d28882020-12-14 14:56:02 +0100313 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
314 uint8_t keys[24];
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 memcpy(keys, key_buffer, 16);
316 memcpy(keys + 16, key_buffer, 8);
317 ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
318 keys,
319 192, cipher_operation);
320 } else
Ronald Crond6d28882020-12-14 14:56:02 +0100321#endif
322 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
324 (int) key_bits, cipher_operation);
Ronald Crond6d28882020-12-14 14:56:02 +0100325 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100327 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 }
Ronald Crond6d28882020-12-14 14:56:02 +0100329
Ronald Cron0266cfe2021-03-13 18:50:11 +0100330#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
331 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 switch (alg) {
Ronald Crond6d28882020-12-14 14:56:02 +0100333 case PSA_ALG_CBC_NO_PADDING:
Gilles Peskine449bd832023-01-11 14:50:10 +0100334 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
335 MBEDTLS_PADDING_NONE);
Ronald Crond6d28882020-12-14 14:56:02 +0100336 break;
337 case PSA_ALG_CBC_PKCS7:
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
339 MBEDTLS_PADDING_PKCS7);
Ronald Crond6d28882020-12-14 14:56:02 +0100340 break;
341 default:
342 /* The algorithm doesn't involve padding. */
343 ret = 0;
344 break;
345 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100347 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100349#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
350 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
353 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
354 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Ronald Crond6d28882020-12-14 14:56:02 +0100355
356exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 return mbedtls_to_psa_error(ret);
Ronald Crond6d28882020-12-14 14:56:02 +0100358}
359
Ronald Cron0266cfe2021-03-13 18:50:11 +0100360psa_status_t mbedtls_psa_cipher_encrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100361 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100362 const psa_key_attributes_t *attributes,
363 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100365{
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 return psa_cipher_setup(operation, attributes,
367 key_buffer, key_buffer_size,
368 alg, MBEDTLS_ENCRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100369}
370
Ronald Cron0266cfe2021-03-13 18:50:11 +0100371psa_status_t mbedtls_psa_cipher_decrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100372 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100373 const psa_key_attributes_t *attributes,
374 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100376{
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 return psa_cipher_setup(operation, attributes,
378 key_buffer, key_buffer_size,
379 alg, MBEDTLS_DECRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100380}
Ronald Cron6d051732020-10-01 14:10:20 +0200381
Ronald Cron0266cfe2021-03-13 18:50:11 +0100382psa_status_t mbedtls_psa_cipher_set_iv(
383 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 const uint8_t *iv, size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100385{
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 if (iv_length != operation->iv_length) {
387 return PSA_ERROR_INVALID_ARGUMENT;
388 }
Ronald Cron8287e6b2021-03-12 10:35:18 +0100389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 return mbedtls_to_psa_error(
391 mbedtls_cipher_set_iv(&operation->ctx.cipher,
392 iv, iv_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100393}
394
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100395#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine55dffe52021-09-13 09:33:28 +0200396/** Process input for which the algorithm is set to ECB mode.
397 *
398 * This requires manual processing, since the PSA API is defined as being
399 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
400 * but the underlying mbedtls_cipher_update only takes full blocks.
401 *
402 * \param ctx The mbedtls cipher context to use. It must have been
403 * set up for ECB.
404 * \param[in] input The input plaintext or ciphertext to process.
405 * \param input_length The number of bytes to process from \p input.
406 * This does not need to be aligned to a block boundary.
407 * If there is a partial block at the end of the input,
408 * it is stored in \p ctx for future processing.
Gilles Peskined87d8732021-09-13 12:20:51 +0200409 * \param output The buffer where the output is written. It must be
410 * at least `BS * floor((p + input_length) / BS)` bytes
411 * long, where `p` is the number of bytes in the
412 * unprocessed partial block in \p ctx (with
413 * `0 <= p <= BS - 1`) and `BS` is the block size.
Gilles Peskine55dffe52021-09-13 09:33:28 +0200414 * \param output_length On success, the number of bytes written to \p output.
415 * \c 0 on error.
416 *
417 * \return #PSA_SUCCESS or an error from a hardware accelerator
418 */
Ronald Cron6d051732020-10-01 14:10:20 +0200419static psa_status_t psa_cipher_update_ecb(
420 mbedtls_cipher_context_t *ctx,
421 const uint8_t *input,
422 size_t input_length,
423 uint8_t *output,
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200425{
426 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman85a88132023-06-24 11:41:50 +0100427 size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Ronald Cron6d051732020-10-01 14:10:20 +0200428 size_t internal_output_length = 0;
429 *output_length = 0;
430
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 if (input_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200432 status = PSA_SUCCESS;
433 goto exit;
434 }
435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 if (ctx->unprocessed_len > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200437 /* Fill up to block size, and run the block if there's a full one. */
438 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 if (input_length < bytes_to_copy) {
Ronald Cron6d051732020-10-01 14:10:20 +0200441 bytes_to_copy = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 }
Ronald Cron6d051732020-10-01 14:10:20 +0200443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
445 input, bytes_to_copy);
Ronald Cron6d051732020-10-01 14:10:20 +0200446 input_length -= bytes_to_copy;
447 input += bytes_to_copy;
448 ctx->unprocessed_len += bytes_to_copy;
449
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 if (ctx->unprocessed_len == block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200451 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 mbedtls_cipher_update(ctx,
453 ctx->unprocessed_data,
454 block_size,
455 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200458 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 }
Ronald Cron6d051732020-10-01 14:10:20 +0200460
461 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200462 *output_length += internal_output_length;
463 ctx->unprocessed_len = 0;
464 }
465 }
466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 while (input_length >= block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200468 /* Run all full blocks we have, one by one */
469 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 mbedtls_cipher_update(ctx, input,
471 block_size,
472 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200475 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 }
Ronald Cron6d051732020-10-01 14:10:20 +0200477
478 input_length -= block_size;
479 input += block_size;
480
481 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200482 *output_length += internal_output_length;
483 }
484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 if (input_length > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200486 /* Save unprocessed bytes for later processing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
488 input, input_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200489 ctx->unprocessed_len += input_length;
490 }
491
492 status = PSA_SUCCESS;
493
494exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200496}
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100497#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200498
Ronald Cron0266cfe2021-03-13 18:50:11 +0100499psa_status_t mbedtls_psa_cipher_update(
500 mbedtls_psa_cipher_operation_t *operation,
501 const uint8_t *input, size_t input_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200503{
504 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
505 size_t expected_output_size;
506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
Ronald Cron6d051732020-10-01 14:10:20 +0200508 /* Take the unprocessed partial block left over from previous
509 * update calls, if any, plus the input to this call. Remove
510 * the last partial block, if any. You get the data that will be
511 * output in this call. */
512 expected_output_size =
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 (operation->ctx.cipher.unprocessed_len + input_length)
Ronald Cron6ad554c2021-03-26 09:29:09 +0100514 / operation->block_length * operation->block_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200516 expected_output_size = input_length;
517 }
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 if (output_size < expected_output_size) {
520 return PSA_ERROR_BUFFER_TOO_SMALL;
521 }
Ronald Cron6d051732020-10-01 14:10:20 +0200522
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100523#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200525 /* mbedtls_cipher_update has an API inconsistency: it will only
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 * process a single block at a time in ECB mode. Abstract away that
527 * inconsistency here to match the PSA API behaviour. */
528 status = psa_cipher_update_ecb(&operation->ctx.cipher,
529 input,
530 input_length,
531 output,
532 output_length);
533 } else
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100534#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Gabor Mezeic25fbd22024-01-29 13:33:58 +0100535 if (input_length == 0) {
536 /* There is no input, nothing to be done */
537 *output_length = 0;
538 status = PSA_SUCCESS;
539 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200540 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_cipher_update(&operation->ctx.cipher, input,
542 input_length, output, output_length));
gabor-mezei-arm58c17272021-06-29 16:41:25 +0200543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 if (*output_length > output_size) {
545 return PSA_ERROR_CORRUPTION_DETECTED;
546 }
Ronald Cron6d051732020-10-01 14:10:20 +0200547 }
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200550}
551
Ronald Cron0266cfe2021-03-13 18:50:11 +0100552psa_status_t mbedtls_psa_cipher_finish(
553 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200555{
556 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
557 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 if (operation->ctx.cipher.unprocessed_len != 0) {
560 if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
561 operation->alg == PSA_ALG_CBC_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200562 status = PSA_ERROR_INVALID_ARGUMENT;
563 goto exit;
564 }
565 }
566
567 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_cipher_finish(&operation->ctx.cipher,
569 temp_output_buffer,
570 output_length));
571 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200572 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 }
Ronald Cron6d051732020-10-01 14:10:20 +0200574
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 if (*output_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200576 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 } else if (output_size >= *output_length) {
578 memcpy(output, temp_output_buffer, *output_length);
579 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200580 status = PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 }
Ronald Cron6d051732020-10-01 14:10:20 +0200582
583exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mbedtls_platform_zeroize(temp_output_buffer,
585 sizeof(temp_output_buffer));
Ronald Cron6d051732020-10-01 14:10:20 +0200586
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200588}
589
Ronald Cron0266cfe2021-03-13 18:50:11 +0100590psa_status_t mbedtls_psa_cipher_abort(
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 mbedtls_psa_cipher_operation_t *operation)
Ronald Cron6d051732020-10-01 14:10:20 +0200592{
Ronald Cron937dfee2021-03-10 09:17:32 +0100593 /* Sanity check (shouldn't happen: operation->alg should
594 * always have been initialized to a valid value). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 if (!PSA_ALG_IS_CIPHER(operation->alg)) {
596 return PSA_ERROR_BAD_STATE;
597 }
Ronald Cron937dfee2021-03-10 09:17:32 +0100598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 mbedtls_cipher_free(&operation->ctx.cipher);
Ronald Cron6d051732020-10-01 14:10:20 +0200600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 return PSA_SUCCESS;
Ronald Cron6d051732020-10-01 14:10:20 +0200602}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100603
Ronald Cron0266cfe2021-03-13 18:50:11 +0100604psa_status_t mbedtls_psa_cipher_encrypt(
605 const psa_key_attributes_t *attributes,
606 const uint8_t *key_buffer,
607 size_t key_buffer_size,
608 psa_algorithm_t alg,
Ronald Cron9b674282021-07-09 09:19:35 +0200609 const uint8_t *iv,
610 size_t iv_length,
Ronald Cron0266cfe2021-03-13 18:50:11 +0100611 const uint8_t *input,
612 size_t input_length,
613 uint8_t *output,
614 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100616{
617 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
618 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Cron8188d192021-12-14 10:58:18 +0100619 size_t update_output_length, finish_output_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
622 key_buffer, key_buffer_size,
623 alg);
624 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100625 goto exit;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100626 }
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 if (iv_length > 0) {
629 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
630 if (status != PSA_SUCCESS) {
631 goto exit;
632 }
633 }
634
635 status = mbedtls_psa_cipher_update(&operation, input, input_length,
636 output, output_size,
637 &update_output_length);
638 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100639 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100641
Gilles Peskine42649d92022-11-23 14:15:57 +0100642 status = mbedtls_psa_cipher_finish(
643 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 mbedtls_buffer_offset(output, update_output_length),
645 output_size - update_output_length, &finish_output_length);
646 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100647 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100649
Ronald Cron8188d192021-12-14 10:58:18 +0100650 *output_length = update_output_length + finish_output_length;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200651
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100652exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (status == PSA_SUCCESS) {
654 status = mbedtls_psa_cipher_abort(&operation);
655 } else {
656 mbedtls_psa_cipher_abort(&operation);
657 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100658
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100660}
661
Ronald Cron0266cfe2021-03-13 18:50:11 +0100662psa_status_t mbedtls_psa_cipher_decrypt(
663 const psa_key_attributes_t *attributes,
664 const uint8_t *key_buffer,
665 size_t key_buffer_size,
666 psa_algorithm_t alg,
667 const uint8_t *input,
668 size_t input_length,
669 uint8_t *output,
670 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100672{
673 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
674 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200675 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
678 key_buffer, key_buffer_size,
679 alg);
680 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100681 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100683
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 if (operation.iv_length > 0) {
685 status = mbedtls_psa_cipher_set_iv(&operation,
686 input, operation.iv_length);
687 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100688 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100690 }
691
Gilles Peskine42649d92022-11-23 14:15:57 +0100692 status = mbedtls_psa_cipher_update(
693 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 mbedtls_buffer_offset_const(input, operation.iv_length),
Gilles Peskine42649d92022-11-23 14:15:57 +0100695 input_length - operation.iv_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 output, output_size, &olength);
697 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100698 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100700
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200701 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200702
Gilles Peskine42649d92022-11-23 14:15:57 +0100703 status = mbedtls_psa_cipher_finish(
704 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_buffer_offset(output, accumulated_length),
706 output_size - accumulated_length, &olength);
707 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100708 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100710
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200711 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200712
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100713exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 if (status == PSA_SUCCESS) {
715 status = mbedtls_psa_cipher_abort(&operation);
716 } else {
717 mbedtls_psa_cipher_abort(&operation);
718 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100719
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100721}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100722#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100723
Ronald Cron0ff57952021-03-08 16:46:35 +0100724#endif /* MBEDTLS_PSA_CRYPTO_C */