blob: 3f2ddbdb5f330b919b72f5b493c1f31e08fff294 [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 Rodgman6d2c1b32023-10-31 17:54:42 +000045 if (alg == PSA_ALG_STREAM_CIPHER ||
46 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0)) {
47 if (key_type == PSA_KEY_TYPE_CHACHA20) {
48 return PSA_SUCCESS;
49 }
Valerio Setti1e21f262023-10-20 16:24:07 +020050 }
51
Dave Rodgman6d2c1b32023-10-31 17:54:42 +000052 if (alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0) ||
53 alg == PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0) ||
54 alg == PSA_ALG_CCM_STAR_NO_TAG) {
55 if (key_type == PSA_KEY_TYPE_AES ||
56 key_type == PSA_KEY_TYPE_ARIA ||
57 key_type == PSA_KEY_TYPE_CAMELLIA) {
58 return PSA_SUCCESS;
59 }
60 }
61
62 if (alg == PSA_ALG_CTR ||
63 alg == PSA_ALG_CFB ||
64 alg == PSA_ALG_OFB ||
65 alg == PSA_ALG_XTS ||
66 alg == PSA_ALG_ECB_NO_PADDING ||
67 alg == PSA_ALG_CBC_NO_PADDING ||
68 alg == PSA_ALG_CBC_PKCS7 ||
69 alg == PSA_ALG_CMAC) {
70 if (key_type == PSA_KEY_TYPE_AES ||
71 key_type == PSA_KEY_TYPE_ARIA ||
72 key_type == PSA_KEY_TYPE_DES ||
73 key_type == PSA_KEY_TYPE_CAMELLIA) {
74 return PSA_SUCCESS;
75 }
76 }
77
78 return PSA_ERROR_NOT_SUPPORTED;
Valerio Setti1e21f262023-10-20 16:24:07 +020079}
80
Valerio Setti4a249822023-10-18 12:34:54 +020081psa_status_t mbedtls_cipher_values_from_psa(
Ronald Cron75e6ae22021-03-17 14:46:05 +010082 psa_algorithm_t alg,
83 psa_key_type_t key_type,
Valerio Setti4a249822023-10-18 12:34:54 +020084 size_t *key_bits,
85 mbedtls_cipher_mode_t *mode,
Gilles Peskine449bd832023-01-11 14:50:10 +010086 mbedtls_cipher_id_t *cipher_id)
Ronald Cron75e6ae22021-03-17 14:46:05 +010087{
Ronald Cron75e6ae22021-03-17 14:46:05 +010088 mbedtls_cipher_id_t cipher_id_tmp;
Valerio Setti36fe8b92023-10-23 14:12:23 +020089 /* Only DES modifies key_bits */
90#if !defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Valerio Setti4a249822023-10-18 12:34:54 +020091 (void) key_bits;
Valerio Setti36fe8b92023-10-23 14:12:23 +020092#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +010093
Gilles Peskine449bd832023-01-11 14:50:10 +010094 if (PSA_ALG_IS_AEAD(alg)) {
95 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
96 }
Ronald Cron75e6ae22021-03-17 14:46:05 +010097
Gilles Peskine449bd832023-01-11 14:50:10 +010098 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
99 switch (alg) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100100#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100101 case PSA_ALG_STREAM_CIPHER:
Valerio Setti4a249822023-10-18 12:34:54 +0200102 *mode = MBEDTLS_MODE_STREAM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100103 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100104#endif
105#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100106 case PSA_ALG_CTR:
Valerio Setti4a249822023-10-18 12:34:54 +0200107 *mode = MBEDTLS_MODE_CTR;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100108 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100109#endif
110#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100111 case PSA_ALG_CFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200112 *mode = MBEDTLS_MODE_CFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100113 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100114#endif
115#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100116 case PSA_ALG_OFB:
Valerio Setti4a249822023-10-18 12:34:54 +0200117 *mode = MBEDTLS_MODE_OFB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100118 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100119#endif
120#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100121 case PSA_ALG_ECB_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200122 *mode = MBEDTLS_MODE_ECB;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100123 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100124#endif
125#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100126 case PSA_ALG_CBC_NO_PADDING:
Valerio Setti4a249822023-10-18 12:34:54 +0200127 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100128 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100129#endif
130#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100131 case PSA_ALG_CBC_PKCS7:
Valerio Setti4a249822023-10-18 12:34:54 +0200132 *mode = MBEDTLS_MODE_CBC;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100133 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100134#endif
135#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200136 case PSA_ALG_CCM_STAR_NO_TAG:
Valerio Setti4a249822023-10-18 12:34:54 +0200137 *mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
Mateusz Starzyk594215b2021-10-14 12:23:06 +0200138 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100139#endif
140#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200142 *mode = MBEDTLS_MODE_CCM;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100143 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100144#endif
145#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200147 *mode = MBEDTLS_MODE_GCM;
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_CHACHA20_POLY1305)
Gilles Peskine449bd832023-01-11 14:50:10 +0100151 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Valerio Setti4a249822023-10-18 12:34:54 +0200152 *mode = MBEDTLS_MODE_CHACHAPOLY;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100153 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100154#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100155 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200156 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100157 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100158 } else if (alg == PSA_ALG_CMAC) {
Valerio Setti4a249822023-10-18 12:34:54 +0200159 *mode = MBEDTLS_MODE_ECB;
Gilles Peskine449bd832023-01-11 14:50:10 +0100160 } else {
Valerio Setti4a249822023-10-18 12:34:54 +0200161 return PSA_ERROR_NOT_SUPPORTED;
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164 switch (key_type) {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100165#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100166 case PSA_KEY_TYPE_AES:
167 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
168 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100169#endif
170#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine6c12a1e2021-09-21 11:59:39 +0200171 case PSA_KEY_TYPE_ARIA:
172 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
173 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100174#endif
175#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100176 case PSA_KEY_TYPE_DES:
177 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
178 * and 192 for three-key Triple-DES. */
Valerio Setti4a249822023-10-18 12:34:54 +0200179 if (*key_bits == 64) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100180 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100181 } else {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100182 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100184 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
185 * but two-key Triple-DES is functionally three-key Triple-DES
186 * with K1=K3, so that's how we present it to mbedtls. */
Valerio Setti4a249822023-10-18 12:34:54 +0200187 if (*key_bits == 128) {
188 *key_bits = 192;
Gilles Peskine449bd832023-01-11 14:50:10 +0100189 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100190 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100191#endif
192#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100193 case PSA_KEY_TYPE_CAMELLIA:
194 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
195 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100196#endif
197#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100198 case PSA_KEY_TYPE_CHACHA20:
199 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
200 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100201#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100202 default:
Valerio Setti4a249822023-10-18 12:34:54 +0200203 return PSA_ERROR_NOT_SUPPORTED;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100204 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 if (cipher_id != NULL) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100206 *cipher_id = cipher_id_tmp;
Gilles Peskine449bd832023-01-11 14:50:10 +0100207 }
Ronald Cron75e6ae22021-03-17 14:46:05 +0100208
Valerio Setti1e21f262023-10-20 16:24:07 +0200209 return mbedtls_cipher_validate_values(alg, key_type);
Valerio Setti4a249822023-10-18 12:34:54 +0200210}
211
212#if defined(MBEDTLS_CIPHER_C)
213const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
214 psa_algorithm_t alg,
215 psa_key_type_t key_type,
216 size_t key_bits,
217 mbedtls_cipher_id_t *cipher_id)
218{
219 mbedtls_cipher_mode_t mode;
220 psa_status_t status;
221 mbedtls_cipher_id_t cipher_id_tmp;
222
223 status = mbedtls_cipher_values_from_psa(alg, key_type, &key_bits, &mode, &cipher_id_tmp);
224 if (status != PSA_SUCCESS) {
225 return NULL;
226 }
227 if (cipher_id != NULL) {
228 *cipher_id = cipher_id_tmp;
229 }
230
231 return mbedtls_cipher_info_from_values(cipher_id_tmp, (int) key_bits, mode);
Ronald Cron75e6ae22021-03-17 14:46:05 +0100232}
Valerio Setti2c2aded2023-08-25 09:22:19 +0200233#endif /* MBEDTLS_CIPHER_C */
Ronald Cron75e6ae22021-03-17 14:46:05 +0100234
Ronald Cron0266cfe2021-03-13 18:50:11 +0100235#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100236
Ronald Cron0266cfe2021-03-13 18:50:11 +0100237static psa_status_t psa_cipher_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100238 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100239 const psa_key_attributes_t *attributes,
240 const uint8_t *key_buffer, size_t key_buffer_size,
241 psa_algorithm_t alg,
Gilles Peskine449bd832023-01-11 14:50:10 +0100242 mbedtls_operation_t cipher_operation)
Ronald Crond6d28882020-12-14 14:56:02 +0100243{
244 int ret = 0;
245 size_t key_bits;
246 const mbedtls_cipher_info_t *cipher_info = NULL;
247 psa_key_type_t key_type = attributes->core.type;
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 (void) key_buffer_size;
Ronald Crond6d28882020-12-14 14:56:02 +0100250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_cipher_init(&operation->ctx.cipher);
Ronald Crond6d28882020-12-14 14:56:02 +0100252
Ronald Cron6e412a72021-03-10 09:58:47 +0100253 operation->alg = alg;
Ronald Crond6d28882020-12-14 14:56:02 +0100254 key_bits = attributes->core.bits;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type,
256 key_bits, NULL);
257 if (cipher_info == NULL) {
258 return PSA_ERROR_NOT_SUPPORTED;
259 }
Ronald Crond6d28882020-12-14 14:56:02 +0100260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
262 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100263 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 }
Ronald Crond6d28882020-12-14 14:56:02 +0100265
Ronald Cron0266cfe2021-03-13 18:50:11 +0100266#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
Ronald Crond6d28882020-12-14 14:56:02 +0100268 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
269 uint8_t keys[24];
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 memcpy(keys, key_buffer, 16);
271 memcpy(keys + 16, key_buffer, 8);
272 ret = mbedtls_cipher_setkey(&operation->ctx.cipher,
273 keys,
274 192, cipher_operation);
275 } else
Ronald Crond6d28882020-12-14 14:56:02 +0100276#endif
277 {
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
279 (int) key_bits, cipher_operation);
Ronald Crond6d28882020-12-14 14:56:02 +0100280 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100282 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 }
Ronald Crond6d28882020-12-14 14:56:02 +0100284
Ronald Cron0266cfe2021-03-13 18:50:11 +0100285#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
286 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 switch (alg) {
Ronald Crond6d28882020-12-14 14:56:02 +0100288 case PSA_ALG_CBC_NO_PADDING:
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
290 MBEDTLS_PADDING_NONE);
Ronald Crond6d28882020-12-14 14:56:02 +0100291 break;
292 case PSA_ALG_CBC_PKCS7:
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
294 MBEDTLS_PADDING_PKCS7);
Ronald Crond6d28882020-12-14 14:56:02 +0100295 break;
296 default:
297 /* The algorithm doesn't involve padding. */
298 ret = 0;
299 break;
300 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 if (ret != 0) {
Ronald Crond6d28882020-12-14 14:56:02 +0100302 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100304#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
305 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100306
Gilles Peskine449bd832023-01-11 14:50:10 +0100307 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ? 1 :
308 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
309 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Ronald Crond6d28882020-12-14 14:56:02 +0100310
311exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 return mbedtls_to_psa_error(ret);
Ronald Crond6d28882020-12-14 14:56:02 +0100313}
314
Ronald Cron0266cfe2021-03-13 18:50:11 +0100315psa_status_t mbedtls_psa_cipher_encrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100316 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100317 const psa_key_attributes_t *attributes,
318 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100320{
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 return psa_cipher_setup(operation, attributes,
322 key_buffer, key_buffer_size,
323 alg, MBEDTLS_ENCRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100324}
325
Ronald Cron0266cfe2021-03-13 18:50:11 +0100326psa_status_t mbedtls_psa_cipher_decrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100327 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100328 const psa_key_attributes_t *attributes,
329 const uint8_t *key_buffer, size_t key_buffer_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100331{
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 return psa_cipher_setup(operation, attributes,
333 key_buffer, key_buffer_size,
334 alg, MBEDTLS_DECRYPT);
Ronald Crond6d28882020-12-14 14:56:02 +0100335}
Ronald Cron6d051732020-10-01 14:10:20 +0200336
Ronald Cron0266cfe2021-03-13 18:50:11 +0100337psa_status_t mbedtls_psa_cipher_set_iv(
338 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 const uint8_t *iv, size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100340{
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 if (iv_length != operation->iv_length) {
342 return PSA_ERROR_INVALID_ARGUMENT;
343 }
Ronald Cron8287e6b2021-03-12 10:35:18 +0100344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 return mbedtls_to_psa_error(
346 mbedtls_cipher_set_iv(&operation->ctx.cipher,
347 iv, iv_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100348}
349
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100350#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine55dffe52021-09-13 09:33:28 +0200351/** Process input for which the algorithm is set to ECB mode.
352 *
353 * This requires manual processing, since the PSA API is defined as being
354 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
355 * but the underlying mbedtls_cipher_update only takes full blocks.
356 *
357 * \param ctx The mbedtls cipher context to use. It must have been
358 * set up for ECB.
359 * \param[in] input The input plaintext or ciphertext to process.
360 * \param input_length The number of bytes to process from \p input.
361 * This does not need to be aligned to a block boundary.
362 * If there is a partial block at the end of the input,
363 * it is stored in \p ctx for future processing.
Gilles Peskined87d8732021-09-13 12:20:51 +0200364 * \param output The buffer where the output is written. It must be
365 * at least `BS * floor((p + input_length) / BS)` bytes
366 * long, where `p` is the number of bytes in the
367 * unprocessed partial block in \p ctx (with
368 * `0 <= p <= BS - 1`) and `BS` is the block size.
Gilles Peskine55dffe52021-09-13 09:33:28 +0200369 * \param output_length On success, the number of bytes written to \p output.
370 * \c 0 on error.
371 *
372 * \return #PSA_SUCCESS or an error from a hardware accelerator
373 */
Ronald Cron6d051732020-10-01 14:10:20 +0200374static psa_status_t psa_cipher_update_ecb(
375 mbedtls_cipher_context_t *ctx,
376 const uint8_t *input,
377 size_t input_length,
378 uint8_t *output,
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200380{
381 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Dave Rodgman85a88132023-06-24 11:41:50 +0100382 size_t block_size = mbedtls_cipher_info_get_block_size(ctx->cipher_info);
Ronald Cron6d051732020-10-01 14:10:20 +0200383 size_t internal_output_length = 0;
384 *output_length = 0;
385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 if (input_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200387 status = PSA_SUCCESS;
388 goto exit;
389 }
390
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 if (ctx->unprocessed_len > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200392 /* Fill up to block size, and run the block if there's a full one. */
393 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
394
Gilles Peskine449bd832023-01-11 14:50:10 +0100395 if (input_length < bytes_to_copy) {
Ronald Cron6d051732020-10-01 14:10:20 +0200396 bytes_to_copy = input_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 }
Ronald Cron6d051732020-10-01 14:10:20 +0200398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
400 input, bytes_to_copy);
Ronald Cron6d051732020-10-01 14:10:20 +0200401 input_length -= bytes_to_copy;
402 input += bytes_to_copy;
403 ctx->unprocessed_len += bytes_to_copy;
404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 if (ctx->unprocessed_len == block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200406 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 mbedtls_cipher_update(ctx,
408 ctx->unprocessed_data,
409 block_size,
410 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200413 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 }
Ronald Cron6d051732020-10-01 14:10:20 +0200415
416 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200417 *output_length += internal_output_length;
418 ctx->unprocessed_len = 0;
419 }
420 }
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 while (input_length >= block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200423 /* Run all full blocks we have, one by one */
424 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 mbedtls_cipher_update(ctx, input,
426 block_size,
427 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200430 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 }
Ronald Cron6d051732020-10-01 14:10:20 +0200432
433 input_length -= block_size;
434 input += block_size;
435
436 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200437 *output_length += internal_output_length;
438 }
439
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 if (input_length > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200441 /* Save unprocessed bytes for later processing */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]),
443 input, input_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200444 ctx->unprocessed_len += input_length;
445 }
446
447 status = PSA_SUCCESS;
448
449exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200451}
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100452#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200453
Ronald Cron0266cfe2021-03-13 18:50:11 +0100454psa_status_t mbedtls_psa_cipher_update(
455 mbedtls_psa_cipher_operation_t *operation,
456 const uint8_t *input, size_t input_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200458{
459 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
460 size_t expected_output_size;
461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
Ronald Cron6d051732020-10-01 14:10:20 +0200463 /* Take the unprocessed partial block left over from previous
464 * update calls, if any, plus the input to this call. Remove
465 * the last partial block, if any. You get the data that will be
466 * output in this call. */
467 expected_output_size =
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 (operation->ctx.cipher.unprocessed_len + input_length)
Ronald Cron6ad554c2021-03-26 09:29:09 +0100469 / operation->block_length * operation->block_length;
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200471 expected_output_size = input_length;
472 }
473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 if (output_size < expected_output_size) {
475 return PSA_ERROR_BUFFER_TOO_SMALL;
476 }
Ronald Cron6d051732020-10-01 14:10:20 +0200477
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100478#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200480 /* mbedtls_cipher_update has an API inconsistency: it will only
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 * process a single block at a time in ECB mode. Abstract away that
482 * inconsistency here to match the PSA API behaviour. */
483 status = psa_cipher_update_ecb(&operation->ctx.cipher,
484 input,
485 input_length,
486 output,
487 output_length);
488 } else
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100489#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200490 {
491 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_cipher_update(&operation->ctx.cipher, input,
493 input_length, output, output_length));
gabor-mezei-arm58c17272021-06-29 16:41:25 +0200494
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 if (*output_length > output_size) {
496 return PSA_ERROR_CORRUPTION_DETECTED;
497 }
Ronald Cron6d051732020-10-01 14:10:20 +0200498 }
499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200501}
502
Ronald Cron0266cfe2021-03-13 18:50:11 +0100503psa_status_t mbedtls_psa_cipher_finish(
504 mbedtls_psa_cipher_operation_t *operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 uint8_t *output, size_t output_size, size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200506{
507 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
508 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 if (operation->ctx.cipher.unprocessed_len != 0) {
511 if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
512 operation->alg == PSA_ALG_CBC_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200513 status = PSA_ERROR_INVALID_ARGUMENT;
514 goto exit;
515 }
516 }
517
518 status = mbedtls_to_psa_error(
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_cipher_finish(&operation->ctx.cipher,
520 temp_output_buffer,
521 output_length));
522 if (status != PSA_SUCCESS) {
Ronald Cron6d051732020-10-01 14:10:20 +0200523 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 }
Ronald Cron6d051732020-10-01 14:10:20 +0200525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (*output_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200527 ; /* Nothing to copy. Note that output may be NULL in this case. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 } else if (output_size >= *output_length) {
529 memcpy(output, temp_output_buffer, *output_length);
530 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200531 status = PSA_ERROR_BUFFER_TOO_SMALL;
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 }
Ronald Cron6d051732020-10-01 14:10:20 +0200533
534exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 mbedtls_platform_zeroize(temp_output_buffer,
536 sizeof(temp_output_buffer));
Ronald Cron6d051732020-10-01 14:10:20 +0200537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200539}
540
Ronald Cron0266cfe2021-03-13 18:50:11 +0100541psa_status_t mbedtls_psa_cipher_abort(
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_psa_cipher_operation_t *operation)
Ronald Cron6d051732020-10-01 14:10:20 +0200543{
Ronald Cron937dfee2021-03-10 09:17:32 +0100544 /* Sanity check (shouldn't happen: operation->alg should
545 * always have been initialized to a valid value). */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 if (!PSA_ALG_IS_CIPHER(operation->alg)) {
547 return PSA_ERROR_BAD_STATE;
548 }
Ronald Cron937dfee2021-03-10 09:17:32 +0100549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_cipher_free(&operation->ctx.cipher);
Ronald Cron6d051732020-10-01 14:10:20 +0200551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return PSA_SUCCESS;
Ronald Cron6d051732020-10-01 14:10:20 +0200553}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100554
Ronald Cron0266cfe2021-03-13 18:50:11 +0100555psa_status_t mbedtls_psa_cipher_encrypt(
556 const psa_key_attributes_t *attributes,
557 const uint8_t *key_buffer,
558 size_t key_buffer_size,
559 psa_algorithm_t alg,
Ronald Cron9b674282021-07-09 09:19:35 +0200560 const uint8_t *iv,
561 size_t iv_length,
Ronald Cron0266cfe2021-03-13 18:50:11 +0100562 const uint8_t *input,
563 size_t input_length,
564 uint8_t *output,
565 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100567{
568 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
569 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Cron8188d192021-12-14 10:58:18 +0100570 size_t update_output_length, finish_output_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100571
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 status = mbedtls_psa_cipher_encrypt_setup(&operation, attributes,
573 key_buffer, key_buffer_size,
574 alg);
575 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100576 goto exit;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100577 }
578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 if (iv_length > 0) {
580 status = mbedtls_psa_cipher_set_iv(&operation, iv, iv_length);
581 if (status != PSA_SUCCESS) {
582 goto exit;
583 }
584 }
585
586 status = mbedtls_psa_cipher_update(&operation, input, input_length,
587 output, output_size,
588 &update_output_length);
589 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100590 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100592
Gilles Peskine42649d92022-11-23 14:15:57 +0100593 status = mbedtls_psa_cipher_finish(
594 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 mbedtls_buffer_offset(output, update_output_length),
596 output_size - update_output_length, &finish_output_length);
597 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100598 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100600
Ronald Cron8188d192021-12-14 10:58:18 +0100601 *output_length = update_output_length + finish_output_length;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200602
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100603exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 if (status == PSA_SUCCESS) {
605 status = mbedtls_psa_cipher_abort(&operation);
606 } else {
607 mbedtls_psa_cipher_abort(&operation);
608 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100609
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100611}
612
Ronald Cron0266cfe2021-03-13 18:50:11 +0100613psa_status_t mbedtls_psa_cipher_decrypt(
614 const psa_key_attributes_t *attributes,
615 const uint8_t *key_buffer,
616 size_t key_buffer_size,
617 psa_algorithm_t alg,
618 const uint8_t *input,
619 size_t input_length,
620 uint8_t *output,
621 size_t output_size,
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100623{
624 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
625 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200626 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 status = mbedtls_psa_cipher_decrypt_setup(&operation, attributes,
629 key_buffer, key_buffer_size,
630 alg);
631 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100632 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 if (operation.iv_length > 0) {
636 status = mbedtls_psa_cipher_set_iv(&operation,
637 input, operation.iv_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 }
642
Gilles Peskine42649d92022-11-23 14:15:57 +0100643 status = mbedtls_psa_cipher_update(
644 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 mbedtls_buffer_offset_const(input, operation.iv_length),
Gilles Peskine42649d92022-11-23 14:15:57 +0100646 input_length - operation.iv_length,
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 output, output_size, &olength);
648 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100649 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100651
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200652 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200653
Gilles Peskine42649d92022-11-23 14:15:57 +0100654 status = mbedtls_psa_cipher_finish(
655 &operation,
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 mbedtls_buffer_offset(output, accumulated_length),
657 output_size - accumulated_length, &olength);
658 if (status != PSA_SUCCESS) {
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100659 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 }
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100661
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200662 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200663
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100664exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 if (status == PSA_SUCCESS) {
666 status = mbedtls_psa_cipher_abort(&operation);
667 } else {
668 mbedtls_psa_cipher_abort(&operation);
669 }
Ronald Cron0266cfe2021-03-13 18:50:11 +0100670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100672}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100673#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100674
Ronald Cron0ff57952021-03-08 16:46:35 +0100675#endif /* MBEDTLS_PSA_CRYPTO_C */