blob: f4fc499ba4894d7efba85b560f8ff40fca1b5ca1 [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
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may
9 * not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include "common.h"
22
23#if defined(MBEDTLS_PSA_CRYPTO_C)
24
Martin Man4741e0b2022-08-02 12:44:35 +020025#include "psa_crypto_cipher.h"
Ronald Crond6d28882020-12-14 14:56:02 +010026#include "psa_crypto_core.h"
Ronald Cron6d051732020-10-01 14:10:20 +020027#include "psa_crypto_random_impl.h"
28
Ronald Crond6d28882020-12-14 14:56:02 +010029#include "mbedtls/cipher.h"
Ronald Cron6d051732020-10-01 14:10:20 +020030#include "mbedtls/error.h"
Ronald Cron0ff57952021-03-08 16:46:35 +010031
Ronald Crond6d28882020-12-14 14:56:02 +010032#include <string.h>
33
Valerio Setti1e21f262023-10-20 16:24:07 +020034/* mbedtls_cipher_values_from_psa() below only checks if the proper build symbols
35 * are enabled, but it does not provide any compatibility check between them
36 * (i.e. if the specified key works with the specified algorithm). This helper
37 * function is meant to provide this support.
38 * mbedtls_cipher_info_from_psa() might be used for the same purpose, but it
39 * requires CIPHER_C to be enabled.
40 */
41static psa_status_t mbedtls_cipher_validate_values(
42 psa_algorithm_t alg,
43 psa_key_type_t key_type)
44{
Dave Rodgman3e5cc172023-10-31 17:54:58 +000045 /* Reduce code size - hinting to the compiler about what it can assume allows the compiler to
46 eliminate bits of the logic below. */
47#if !defined(PSA_WANT_KEY_TYPE_AES)
48 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_AES);
49#endif
50#if !defined(PSA_WANT_KEY_TYPE_ARIA)
51 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_ARIA);
52#endif
53#if !defined(PSA_WANT_KEY_TYPE_CAMELLIA)
54 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CAMELLIA);
55#endif
56#if !defined(PSA_WANT_KEY_TYPE_CHACHA20)
57 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_CHACHA20);
58#endif
59#if !defined(PSA_WANT_KEY_TYPE_DES)
60 MBEDTLS_ASSUME(key_type != PSA_KEY_TYPE_DES);
61#endif
62#if !defined(PSA_WANT_ALG_CCM)
63 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0));
64#endif
65#if !defined(PSA_WANT_ALG_GCM)
66 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0));
67#endif
68#if !defined(PSA_WANT_ALG_STREAM_CIPHER)
69 MBEDTLS_ASSUME(alg != PSA_ALG_STREAM_CIPHER);
70#endif
71#if !defined(PSA_WANT_ALG_CHACHA20_POLY1305)
72 MBEDTLS_ASSUME(alg != PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0));
73#endif
74#if !defined(PSA_WANT_ALG_CCM_STAR_NO_TAG)
75 MBEDTLS_ASSUME(alg != PSA_ALG_CCM_STAR_NO_TAG);
76#endif
77#if !defined(PSA_WANT_ALG_CTR)
78 MBEDTLS_ASSUME(alg != PSA_ALG_CTR);
79#endif
80#if !defined(PSA_WANT_ALG_CFB)
81 MBEDTLS_ASSUME(alg != PSA_ALG_CFB);
82#endif
83#if !defined(PSA_WANT_ALG_OFB)
84 MBEDTLS_ASSUME(alg != PSA_ALG_OFB);
85#endif
86#if !defined(PSA_WANT_ALG_XTS)
87 MBEDTLS_ASSUME(alg != PSA_ALG_XTS);
88#endif
89#if !defined(PSA_WANT_ALG_ECB_NO_PADDING)
90 MBEDTLS_ASSUME(alg != PSA_ALG_ECB_NO_PADDING);
91#endif
92#if !defined(PSA_WANT_ALG_CBC_NO_PADDING)
93 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_NO_PADDING);
94#endif
95#if !defined(PSA_WANT_ALG_CBC_PKCS7)
96 MBEDTLS_ASSUME(alg != PSA_ALG_CBC_PKCS7);
97#endif
98#if !defined(PSA_WANT_ALG_CMAC)
99 MBEDTLS_ASSUME(alg != PSA_ALG_CMAC);
100#endif
101
Dave Rodgman6d2c1b32023-10-31 17:54:42 +0000102 if (alg == PSA_ALG_STREAM_CIPHER ||
103 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
104 if (key_type == PSA_KEY_TYPE_CHACHA20) {
105 return PSA_SUCCESS;
106 }
Valerio Setti1e21f262023-10-20 16:24:07 +0200107 }
108
Dave Rodgman6d2c1b32023-10-31 17:54:42 +0000109 if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
110 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
111 alg == PSA_ALG_CCM_STAR_NO_TAG) {
112 if (key_type == PSA_KEY_TYPE_AES ||
113 key_type == PSA_KEY_TYPE_ARIA ||
114 key_type == PSA_KEY_TYPE_CAMELLIA) {
115 return PSA_SUCCESS;
116 }
117 }
118
119 if (alg == PSA_ALG_CTR ||
120 alg == PSA_ALG_CFB ||
121 alg == PSA_ALG_OFB ||
122 alg == PSA_ALG_XTS ||
123 alg == PSA_ALG_ECB_NO_PADDING ||
124 alg == PSA_ALG_CBC_NO_PADDING ||
125 alg == PSA_ALG_CBC_PKCS7 ||
126 alg == PSA_ALG_CMAC) {
127 if (key_type == PSA_KEY_TYPE_AES ||
128 key_type == PSA_KEY_TYPE_ARIA ||
129 key_type == PSA_KEY_TYPE_DES ||
130 key_type == PSA_KEY_TYPE_CAMELLIA) {
131 return PSA_SUCCESS;
132 }
133 }
134
135 return PSA_ERROR_NOT_SUPPORTED;
Valerio Setti1e21f262023-10-20 16:24:07 +0200136}
137
Valerio Setti4a249822023-10-18 12:34:54 +0200138psa_status_t mbedtls_cipher_values_from_psa(
Ronald Cron75e6ae22021-03-17 14:46:05 +0100139 psa_algorithm_t alg,
140 psa_key_type_t key_type,
Valerio Setti4a249822023-10-18 12:34:54 +0200141 size_t *key_bits,
142 mbedtls_cipher_mode_t *mode,
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 mbedtls_cipher_id_t *cipher_id)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100144{
Ronald Cron75e6ae22021-03-17 14:46:05 +0100145 mbedtls_cipher_id_t cipher_id_tmp;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200146 /* Only DES modifies key_bits */
147#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Valerio Setti4a249822023-10-18 12:34:54 +0200148 (void) key_bits;
Valerio Setti36fe8b92023-10-23 14:12:23 +0200149#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100150
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 if (PSA_ALG_IS_AEAD(alg)) {
152 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
153 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100154
Gilles Peskine449bd832023-01-11 14:50:10 +0100155 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
156 switch (alg) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100157#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100158 case PSA_ALG_STREAM_CIPHER:
Valerio Setti4a249822023-10-18 12:34:54 +0200159 *mode = MBEDTLS_MODE_STREAM;
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_CTR)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100163 case PSA_ALG_CTR:
Valerio Setti4a249822023-10-18 12:34:54 +0200164 *mode = MBEDTLS_MODE_CTR;
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_CFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100168 case PSA_ALG_CFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200169 *mode = MBEDTLS_MODE_CFB;
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_OFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100173 case PSA_ALG_OFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200174 *mode = MBEDTLS_MODE_OFB;
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_ECB_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100178 case PSA_ALG_ECB_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200179 *mode = MBEDTLS_MODE_ECB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100180 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100181#endif
182#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100183 case PSA_ALG_CBC_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200184 *mode = MBEDTLS_MODE_CBC;
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_CBC_PKCS7)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100188 case PSA_ALG_CBC_PKCS7:
Valerio Setti4a249822023-10-18 12:34:54 +0200189 *mode = MBEDTLS_MODE_CBC;
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_CCM_STAR_NO_TAG)
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200193 case PSA_ALG_CCM_STAR_NO_TAG:
Valerio Setti4a249822023-10-18 12:34:54 +0200194 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200195 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100196#endif
197#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200199 *mode = MBEDTLS_MODE_CCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100200 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100201#endif
202#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200204 *mode = MBEDTLS_MODE_GCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100205 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100206#endif
207#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200209 *mode = MBEDTLS_MODE_CHACHAPOLY;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100210 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100211#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100212 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200213 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100214 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 } else if (alg == PSA_ALG_CMAC) {
Valerio Setti4a249822023-10-18 12:34:54 +0200216 *mode = MBEDTLS_MODE_ECB;
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 } else {
Valerio Setti4a249822023-10-18 12:34:54 +0200218 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 switch (key_type) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100222#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100223 case PSA_KEY_TYPE_AES:
224 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
225 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100226#endif
227#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine6c12a1e2021-09-21 11:59:39 +0200228 case PSA_KEY_TYPE_ARIA:
229 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
230 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100231#endif
232#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100233 case PSA_KEY_TYPE_DES:
234 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
235 * and 192 for three-key Triple-DES. */
Valerio Setti4a249822023-10-18 12:34:54 +0200236 if (*key_bits == 64) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100237 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100238 } else {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100239 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100241 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
242 * but two-key Triple-DES is functionally three-key Triple-DES
243 * with K1=K3, so that's how we present it to mbedtls. */
Valerio Setti4a249822023-10-18 12:34:54 +0200244 if (*key_bits == 128) {
245 *key_bits = 192;
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100247 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100248#endif
249#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100250 case PSA_KEY_TYPE_CAMELLIA:
251 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
252 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100253#endif
254#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100255 case PSA_KEY_TYPE_CHACHA20:
256 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
257 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100258#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100259 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200260 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100261 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 if (cipher_id != NULL) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100263 *cipher_id = cipher_id_tmp;
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100265
Valerio Setti1e21f262023-10-20 16:24:07 +0200266 return mbedtls_cipher_validate_values(alg, key_type);
Valerio Setti4a249822023-10-18 12:34:54 +0200267}
268
269#if defined(MBEDTLS_CIPHER_C)
270const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
271 psa_algorithm_t alg,
272 psa_key_type_t key_type,
273 size_t key_bits,
274 mbedtls_cipher_id_t *cipher_id)
275{
276 mbedtls_cipher_mode_t mode;
277 psa_status_t status;
278 mbedtls_cipher_id_t cipher_id_tmp;
279
280 status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
281 if (status != PSA_SUCCESS) {
282 return NULL;
283 }
284 if (cipher_id != NULL) {
285 *cipher_id = cipher_id_tmp;
286 }
287
288 return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
Ronald Cron75e6ae22021-03-17 14:46:05 +0100289}
Valerio Setti2c2aded2023-08-25 09:22:19 +0200290#endif /* MBEDTLS_CIPHER_C */
Ronald Cron75e6ae22021-03-17 14:46:05 +0100291
Ronald Cron0266cfe2021-03-13 18:50:11 +0100292#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100293
Ronald Cron0266cfe2021-03-13 18:50:11 +0100294static psa_status_t psa_cipher_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100295 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100296 const psa_key_attributes_t *attributes,
297 const uint8_t *key_buffer, size_t key_buffer_size,
298 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 mbedtls_operation_t cipher_operation)
Ronald Crond6d28882020-12-14 14:56:02 +0100300{
301 int ret = 0;
302 size_t key_bits;
303 const mbedtls_cipher_info_t *cipher_info = NULL;
304 psa_key_type_t key_type = attributes->core.type;
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306 (void) key_buffer_size;
Ronald Crond6d28882020-12-14 14:56:02 +0100307
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_cipher_init(&operation->ctx.cipher);
Ronald Crond6d28882020-12-14 14:56:02 +0100309
Ronald Cron6e412a72021-03-10 09:58:47 +0100310 operation->alg = alg;
Ronald Crond6d28882020-12-14 14:56:02 +0100311 key_bits = attributes->core.bits;
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
313 key_bits, NULL);
314 if (cipher_info == NULL) {
315 return PSA_ERROR_NOT_SUPPORTED;
316 }
Ronald Crond6d28882020-12-14 14:56:02 +0100317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
319 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100320 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 }
Ronald Crond6d28882020-12-14 14:56:02 +0100322
Ronald Cron0266cfe2021-03-13 18:50:11 +0100323#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
Ronald Crond6d28882020-12-14 14:56:02 +0100325 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
326 uint8_t keys[24];
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 memcpy(keys, key_buffer, 16);
328 memcpy(keys + 16, key_buffer, 8);
329 ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
330 keys,
331 192, cipher_operation);
332 } else
Ronald Crond6d28882020-12-14 14:56:02 +0100333#endif
334 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100335 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
336 (int) key_bits, cipher_operation);
Ronald Crond6d28882020-12-14 14:56:02 +0100337 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100338 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100339 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 }
Ronald Crond6d28882020-12-14 14:56:02 +0100341
Ronald Cron0266cfe2021-03-13 18:50:11 +0100342#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
343 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 switch (alg) {
Ronald Crond6d28882020-12-14 14:56:02 +0100345 case PSA_ALG_CBC_NO_PADDING:
Gilles Peskine449bd832023-01-11 14:50:10 +0100346 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
347 MBEDTLS_PADDING_NONE);
Ronald Crond6d28882020-12-14 14:56:02 +0100348 break;
349 case PSA_ALG_CBC_PKCS7:
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
351 MBEDTLS_PADDING_PKCS7);
Ronald Crond6d28882020-12-14 14:56:02 +0100352 break;
353 default:
354 /* The algorithm doesn't involve padding. */
355 ret = 0;
356 break;
357 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100358 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100359 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100361#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
362 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
365 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
366 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Ronald Crond6d28882020-12-14 14:56:02 +0100367
368exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100369 return mbedtls_to_psa_error(ret);
Ronald Crond6d28882020-12-14 14:56:02 +0100370}
371
Ronald Cron0266cfe2021-03-13 18:50:11 +0100372psa_status_t mbedtls_psa_cipher_encrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100373 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100374 const psa_key_attributes_t *attributes,
375 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100377{
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 return psa_cipher_setup(operation, attributes,
379 key_buffer, key_buffer_size,
380 alg, MBEDTLS_ENCRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100381}
382
Ronald Cron0266cfe2021-03-13 18:50:11 +0100383psa_status_t mbedtls_psa_cipher_decrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100384 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100385 const psa_key_attributes_t *attributes,
386 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100388{
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 return psa_cipher_setup(operation, attributes,
390 key_buffer, key_buffer_size,
391 alg, MBEDTLS_DECRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100392}
Ronald Cron6d051732020-10-01 14:10:20 +0200393
Ronald Cron0266cfe2021-03-13 18:50:11 +0100394psa_status_t mbedtls_psa_cipher_set_iv(
395 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 const uint8_t *iv, size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100397{
Gilles Peskine449bd832023-01-11 14:50:10 +0100398 if (iv_length != operation->iv_length) {
399 return PSA_ERROR_INVALID_ARGUMENT;
400 }
Ronald Cron8287e6b2021-03-12 10:35:18 +0100401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 return mbedtls_to_psa_error(
403 mbedtls_cipher_set_iv(&operation->ctx.cipher,
404 iv, iv_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100405}
406
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100407#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine55dffe52021-09-13 09:33:28 +0200408/** Process input for which the algorithm is set to ECB mode.
409 *
410 * This requires manual processing, since the PSA API is defined as being
411 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
412 * but the underlying mbedtls_cipher_update only takes full blocks.
413 *
414 * \param ctx The mbedtls cipher context to use. It must have been
415 * set up for ECB.
416 * \param[in] input The input plaintext or ciphertext to process.
417 * \param input_length The number of bytes to process from \p input.
418 * This does not need to be aligned to a block boundary.
419 * If there is a partial block at the end of the input,
420 * it is stored in \p ctx for future processing.
Gilles Peskined87d8732021-09-13 12:20:51 +0200421 * \param output The buffer where the output is written. It must be
422 * at least `BS * floor((p + input_length) / BS)` bytes
423 * long, where `p` is the number of bytes in the
424 * unprocessed partial block in \p ctx (with
425 * `0 <= p <= BS - 1`) and `BS` is the block size.
Gilles Peskine55dffe52021-09-13 09:33:28 +0200426 * \param output_length On success, the number of bytes written to \p output.
427 * \c 0 on error.
428 *
429 * \return #PSA_SUCCESS or an error from a hardware accelerator
430 */
Ronald Cron6d051732020-10-01 14:10:20 +0200431static psa_status_t psa_cipher_update_ecb(
432 mbedtls_cipher_context_t *ctx,
433 const uint8_t *input,
434 size_t input_length,
435 uint8_t *output,
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200437{
438 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman85a88132023-06-24 11:41:50 +0100439 size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Ronald Cron6d051732020-10-01 14:10:20 +0200440 size_t internal_output_length = 0;
441 *output_length = 0;
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 if (input_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200444 status = PSA_SUCCESS;
445 goto exit;
446 }
447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 if (ctx->unprocessed_len > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200449 /* Fill up to block size, and run the block if there's a full one. */
450 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 if (input_length < bytes_to_copy) {
Ronald Cron6d051732020-10-01 14:10:20 +0200453 bytes_to_copy = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 }
Ronald Cron6d051732020-10-01 14:10:20 +0200455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
457 input, bytes_to_copy);
Ronald Cron6d051732020-10-01 14:10:20 +0200458 input_length -= bytes_to_copy;
459 input += bytes_to_copy;
460 ctx->unprocessed_len += bytes_to_copy;
461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 if (ctx->unprocessed_len == block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200463 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 mbedtls_cipher_update(ctx,
465 ctx->unprocessed_data,
466 block_size,
467 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200470 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 }
Ronald Cron6d051732020-10-01 14:10:20 +0200472
473 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200474 *output_length += internal_output_length;
475 ctx->unprocessed_len = 0;
476 }
477 }
478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 while (input_length >= block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200480 /* Run all full blocks we have, one by one */
481 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 mbedtls_cipher_update(ctx, input,
483 block_size,
484 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200487 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 }
Ronald Cron6d051732020-10-01 14:10:20 +0200489
490 input_length -= block_size;
491 input += block_size;
492
493 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200494 *output_length += internal_output_length;
495 }
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 if (input_length > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200498 /* Save unprocessed bytes for later processing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
500 input, input_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200501 ctx->unprocessed_len += input_length;
502 }
503
504 status = PSA_SUCCESS;
505
506exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200508}
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100509#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200510
Ronald Cron0266cfe2021-03-13 18:50:11 +0100511psa_status_t mbedtls_psa_cipher_update(
512 mbedtls_psa_cipher_operation_t *operation,
513 const uint8_t *input, size_t input_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200515{
516 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
517 size_t expected_output_size;
518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
Ronald Cron6d051732020-10-01 14:10:20 +0200520 /* Take the unprocessed partial block left over from previous
521 * update calls, if any, plus the input to this call. Remove
522 * the last partial block, if any. You get the data that will be
523 * output in this call. */
524 expected_output_size =
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 (operation->ctx.cipher.unprocessed_len + input_length)
Ronald Cron6ad554c2021-03-26 09:29:09 +0100526 / operation->block_length * operation->block_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200528 expected_output_size = input_length;
529 }
530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 if (output_size < expected_output_size) {
532 return PSA_ERROR_BUFFER_TOO_SMALL;
533 }
Ronald Cron6d051732020-10-01 14:10:20 +0200534
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100535#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200537 /* mbedtls_cipher_update has an API inconsistency: it will only
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 * process a single block at a time in ECB mode. Abstract away that
539 * inconsistency here to match the PSA API behaviour. */
540 status = psa_cipher_update_ecb(&operation->ctx.cipher,
541 input,
542 input_length,
543 output,
544 output_length);
545 } else
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100546#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200547 {
548 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_cipher_update(&operation->ctx.cipher, input,
550 input_length, output, output_length));
gabor-mezei-arm58c17272021-06-29 16:41:25 +0200551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 if (*output_length > output_size) {
553 return PSA_ERROR_CORRUPTION_DETECTED;
554 }
Ronald Cron6d051732020-10-01 14:10:20 +0200555 }
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200558}
559
Ronald Cron0266cfe2021-03-13 18:50:11 +0100560psa_status_t mbedtls_psa_cipher_finish(
561 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200563{
564 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
565 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 if (operation->ctx.cipher.unprocessed_len != 0) {
568 if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
569 operation->alg == PSA_ALG_CBC_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200570 status = PSA_ERROR_INVALID_ARGUMENT;
571 goto exit;
572 }
573 }
574
575 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 mbedtls_cipher_finish(&operation->ctx.cipher,
577 temp_output_buffer,
578 output_length));
579 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200580 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 }
Ronald Cron6d051732020-10-01 14:10:20 +0200582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 if (*output_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200584 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 } else if (output_size >= *output_length) {
586 memcpy(output, temp_output_buffer, *output_length);
587 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200588 status = PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 }
Ronald Cron6d051732020-10-01 14:10:20 +0200590
591exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 mbedtls_platform_zeroize(temp_output_buffer,
593 sizeof(temp_output_buffer));
Ronald Cron6d051732020-10-01 14:10:20 +0200594
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200596}
597
Ronald Cron0266cfe2021-03-13 18:50:11 +0100598psa_status_t mbedtls_psa_cipher_abort(
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 mbedtls_psa_cipher_operation_t *operation)
Ronald Cron6d051732020-10-01 14:10:20 +0200600{
Ronald Cron937dfee2021-03-10 09:17:32 +0100601 /* Sanity check (shouldn't happen: operation->alg should
602 * always have been initialized to a valid value). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 if (!PSA_ALG_IS_CIPHER(operation->alg)) {
604 return PSA_ERROR_BAD_STATE;
605 }
Ronald Cron937dfee2021-03-10 09:17:32 +0100606
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 mbedtls_cipher_free(&operation->ctx.cipher);
Ronald Cron6d051732020-10-01 14:10:20 +0200608
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 return PSA_SUCCESS;
Ronald Cron6d051732020-10-01 14:10:20 +0200610}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100611
Ronald Cron0266cfe2021-03-13 18:50:11 +0100612psa_status_t mbedtls_psa_cipher_encrypt(
613 const psa_key_attributes_t *attributes,
614 const uint8_t *key_buffer,
615 size_t key_buffer_size,
616 psa_algorithm_t alg,
Ronald Cron9b674282021-07-09 09:19:35 +0200617 const uint8_t *iv,
618 size_t iv_length,
Ronald Cron0266cfe2021-03-13 18:50:11 +0100619 const uint8_t *input,
620 size_t input_length,
621 uint8_t *output,
622 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100624{
625 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
626 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Cron8188d192021-12-14 10:58:18 +0100627 size_t update_output_length, finish_output_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
630 key_buffer, key_buffer_size,
631 alg);
632 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100633 goto exit;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (iv_length > 0) {
637 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
638 if (status != PSA_SUCCESS) {
639 goto exit;
640 }
641 }
642
643 status = mbedtls_psa_cipher_update(&operation, input, input_length,
644 output, output_size,
645 &update_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
Gilles Peskine42649d92022-11-23 14:15:57 +0100650 status = mbedtls_psa_cipher_finish(
651 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 mbedtls_buffer_offset(output, update_output_length),
653 output_size - update_output_length, &finish_output_length);
654 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100655 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100657
Ronald Cron8188d192021-12-14 10:58:18 +0100658 *output_length = update_output_length + finish_output_length;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200659
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100660exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 if (status == PSA_SUCCESS) {
662 status = mbedtls_psa_cipher_abort(&operation);
663 } else {
664 mbedtls_psa_cipher_abort(&operation);
665 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100668}
669
Ronald Cron0266cfe2021-03-13 18:50:11 +0100670psa_status_t mbedtls_psa_cipher_decrypt(
671 const psa_key_attributes_t *attributes,
672 const uint8_t *key_buffer,
673 size_t key_buffer_size,
674 psa_algorithm_t alg,
675 const uint8_t *input,
676 size_t input_length,
677 uint8_t *output,
678 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100680{
681 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
682 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200683 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
686 key_buffer, key_buffer_size,
687 alg);
688 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100689 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100691
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 if (operation.iv_length > 0) {
693 status = mbedtls_psa_cipher_set_iv(&operation,
694 input, operation.iv_length);
695 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100696 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100698 }
699
Gilles Peskine42649d92022-11-23 14:15:57 +0100700 status = mbedtls_psa_cipher_update(
701 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 mbedtls_buffer_offset_const(input, operation.iv_length),
Gilles Peskine42649d92022-11-23 14:15:57 +0100703 input_length - operation.iv_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 output, output_size, &olength);
705 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100706 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100708
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200709 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200710
Gilles Peskine42649d92022-11-23 14:15:57 +0100711 status = mbedtls_psa_cipher_finish(
712 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_buffer_offset(output, accumulated_length),
714 output_size - accumulated_length, &olength);
715 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100716 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100718
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200719 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200720
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100721exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (status == PSA_SUCCESS) {
723 status = mbedtls_psa_cipher_abort(&operation);
724 } else {
725 mbedtls_psa_cipher_abort(&operation);
726 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100727
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100729}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100730#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100731
Ronald Cron0ff57952021-03-08 16:46:35 +0100732#endif /* MBEDTLS_PSA_CRYPTO_C */