blob: 5b35abdd7784d24efafb3cf4f6488bdb7e09bcf1 [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020025# include <psa_crypto_cipher.h>
26# include "psa_crypto_core.h"
27# include "psa_crypto_random_impl.h"
Ronald Cron6d051732020-10-01 14:10:20 +020028
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "mbedtls/cipher.h"
30# include "mbedtls/error.h"
Ronald Cron0ff57952021-03-08 16:46:35 +010031
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020032# include <string.h>
Ronald Crond6d28882020-12-14 14:56:02 +010033
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020034# if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES) || \
35 (defined(PSA_CRYPTO_DRIVER_TEST) && \
36 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_DES)))
37# define BUILTIN_KEY_TYPE_DES 1
38# endif
Ronald Cron5d9b00d2021-03-10 14:43:20 +010039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040# if (defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
41 (defined(PSA_CRYPTO_DRIVER_TEST) && \
42 defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)))
43# define BUILTIN_ALG_CBC_NO_PADDING 1
44# endif
Ronald Cron5d9b00d2021-03-10 14:43:20 +010045
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020046# if (defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7) || \
47 (defined(PSA_CRYPTO_DRIVER_TEST) && \
48 defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)))
49# define BUILTIN_ALG_CBC_PKCS7 1
50# endif
Ronald Cron5d9b00d2021-03-10 14:43:20 +010051
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020052# if (defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20) || \
53 (defined(PSA_CRYPTO_DRIVER_TEST) && \
54 defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20)))
55# define BUILTIN_KEY_TYPE_CHACHA20 1
56# endif
Ronald Cron5d9b00d2021-03-10 14:43:20 +010057
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020058const mbedtls_cipher_info_t *
59mbedtls_cipher_info_from_psa(psa_algorithm_t alg,
60 psa_key_type_t key_type,
61 size_t key_bits,
62 mbedtls_cipher_id_t *cipher_id)
Ronald Cron75e6ae22021-03-17 14:46:05 +010063{
64 mbedtls_cipher_mode_t mode;
65 mbedtls_cipher_id_t cipher_id_tmp;
66
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020067 if (PSA_ALG_IS_AEAD(alg))
68 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0);
Ronald Cron75e6ae22021-03-17 14:46:05 +010069
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020070 if (PSA_ALG_IS_CIPHER(alg) || PSA_ALG_IS_AEAD(alg)) {
71 switch (alg) {
Ronald Cron75e6ae22021-03-17 14:46:05 +010072 case PSA_ALG_STREAM_CIPHER:
73 mode = MBEDTLS_MODE_STREAM;
74 break;
75 case PSA_ALG_CTR:
76 mode = MBEDTLS_MODE_CTR;
77 break;
78 case PSA_ALG_CFB:
79 mode = MBEDTLS_MODE_CFB;
80 break;
81 case PSA_ALG_OFB:
82 mode = MBEDTLS_MODE_OFB;
83 break;
84 case PSA_ALG_ECB_NO_PADDING:
85 mode = MBEDTLS_MODE_ECB;
86 break;
87 case PSA_ALG_CBC_NO_PADDING:
88 mode = MBEDTLS_MODE_CBC;
89 break;
90 case PSA_ALG_CBC_PKCS7:
91 mode = MBEDTLS_MODE_CBC;
92 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020093 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, 0):
Ronald Cron75e6ae22021-03-17 14:46:05 +010094 mode = MBEDTLS_MODE_CCM;
95 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020096 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_GCM, 0):
Ronald Cron75e6ae22021-03-17 14:46:05 +010097 mode = MBEDTLS_MODE_GCM;
98 break;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020099 case PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CHACHA20_POLY1305, 0):
Ronald Cron75e6ae22021-03-17 14:46:05 +0100100 mode = MBEDTLS_MODE_CHACHAPOLY;
101 break;
102 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200103 return NULL;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100104 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105 } else if (alg == PSA_ALG_CMAC)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100106 mode = MBEDTLS_MODE_ECB;
107 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108 return NULL;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100109
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200110 switch (key_type) {
Ronald Cron75e6ae22021-03-17 14:46:05 +0100111 case PSA_KEY_TYPE_AES:
112 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
113 break;
114 case PSA_KEY_TYPE_DES:
115 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
116 * and 192 for three-key Triple-DES. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117 if (key_bits == 64)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100118 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
119 else
120 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
121 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
122 * but two-key Triple-DES is functionally three-key Triple-DES
123 * with K1=K3, so that's how we present it to mbedtls. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200124 if (key_bits == 128)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100125 key_bits = 192;
126 break;
127 case PSA_KEY_TYPE_CAMELLIA:
128 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
129 break;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100130 case PSA_KEY_TYPE_CHACHA20:
131 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
132 break;
133 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200134 return NULL;
Ronald Cron75e6ae22021-03-17 14:46:05 +0100135 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200136 if (cipher_id != NULL)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100137 *cipher_id = cipher_id_tmp;
138
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200139 return (
140 mbedtls_cipher_info_from_values(cipher_id_tmp, (int)key_bits, mode));
Ronald Cron75e6ae22021-03-17 14:46:05 +0100141}
142
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200143# if defined(MBEDTLS_PSA_BUILTIN_CIPHER) || defined(PSA_CRYPTO_DRIVER_TEST)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100144
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145static psa_status_t cipher_setup(mbedtls_psa_cipher_operation_t *operation,
146 const psa_key_attributes_t *attributes,
147 const uint8_t *key_buffer,
148 size_t key_buffer_size,
149 psa_algorithm_t alg,
150 mbedtls_operation_t cipher_operation)
Ronald Crond6d28882020-12-14 14:56:02 +0100151{
152 int ret = 0;
153 size_t key_bits;
154 const mbedtls_cipher_info_t *cipher_info = NULL;
155 psa_key_type_t key_type = attributes->core.type;
156
157 (void)key_buffer_size;
158
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200159 mbedtls_cipher_init(&operation->ctx.cipher);
Ronald Crond6d28882020-12-14 14:56:02 +0100160
Ronald Cron6e412a72021-03-10 09:58:47 +0100161 operation->alg = alg;
Ronald Crond6d28882020-12-14 14:56:02 +0100162 key_bits = attributes->core.bits;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200163 cipher_info = mbedtls_cipher_info_from_psa(alg, key_type, key_bits, NULL);
164 if (cipher_info == NULL)
165 return PSA_ERROR_NOT_SUPPORTED;
Ronald Crond6d28882020-12-14 14:56:02 +0100166
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200167 ret = mbedtls_cipher_setup(&operation->ctx.cipher, cipher_info);
168 if (ret != 0)
Ronald Crond6d28882020-12-14 14:56:02 +0100169 goto exit;
170
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200171# if defined(BUILTIN_KEY_TYPE_DES)
172 if (key_type == PSA_KEY_TYPE_DES && key_bits == 128) {
Ronald Crond6d28882020-12-14 14:56:02 +0100173 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
174 uint8_t keys[24];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200175 memcpy(keys, key_buffer, 16);
176 memcpy(keys + 16, key_buffer, 8);
177 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, keys, 192,
178 cipher_operation);
179 } else
180# endif
Ronald Crond6d28882020-12-14 14:56:02 +0100181 {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200182 ret = mbedtls_cipher_setkey(&operation->ctx.cipher, key_buffer,
183 (int)key_bits, cipher_operation);
Ronald Crond6d28882020-12-14 14:56:02 +0100184 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200185 if (ret != 0)
Ronald Crond6d28882020-12-14 14:56:02 +0100186 goto exit;
187
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200188# if defined(BUILTIN_ALG_CBC_NO_PADDING) || \
189 defined(BUILTIN_ALG_CBC_PKCS7)
190 switch (alg) {
Ronald Crond6d28882020-12-14 14:56:02 +0100191 case PSA_ALG_CBC_NO_PADDING:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200192 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
193 MBEDTLS_PADDING_NONE);
Ronald Crond6d28882020-12-14 14:56:02 +0100194 break;
195 case PSA_ALG_CBC_PKCS7:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200196 ret = mbedtls_cipher_set_padding_mode(&operation->ctx.cipher,
197 MBEDTLS_PADDING_PKCS7);
Ronald Crond6d28882020-12-14 14:56:02 +0100198 break;
199 default:
200 /* The algorithm doesn't involve padding. */
201 ret = 0;
202 break;
203 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200204 if (ret != 0)
Ronald Crond6d28882020-12-14 14:56:02 +0100205 goto exit;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200206# endif /* BUILTIN_ALG_CBC_NO_PADDING || BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100207
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200208 operation->block_length = (PSA_ALG_IS_STREAM_CIPHER(alg) ?
209 1 :
210 PSA_BLOCK_CIPHER_BLOCK_LENGTH(key_type));
211 operation->iv_length = PSA_CIPHER_IV_LENGTH(key_type, alg);
Ronald Crond6d28882020-12-14 14:56:02 +0100212
213exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200214 return mbedtls_to_psa_error(ret);
Ronald Crond6d28882020-12-14 14:56:02 +0100215}
216
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200217static psa_status_t
218cipher_encrypt_setup(mbedtls_psa_cipher_operation_t *operation,
219 const psa_key_attributes_t *attributes,
220 const uint8_t *key_buffer,
221 size_t key_buffer_size,
222 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100223{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200224 return (cipher_setup(operation, attributes, key_buffer, key_buffer_size,
225 alg, MBEDTLS_ENCRYPT));
Ronald Crond6d28882020-12-14 14:56:02 +0100226}
227
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200228static psa_status_t
229cipher_decrypt_setup(mbedtls_psa_cipher_operation_t *operation,
230 const psa_key_attributes_t *attributes,
231 const uint8_t *key_buffer,
232 size_t key_buffer_size,
233 psa_algorithm_t alg)
Ronald Crond6d28882020-12-14 14:56:02 +0100234{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 return (cipher_setup(operation, attributes, key_buffer, key_buffer_size,
236 alg, MBEDTLS_DECRYPT));
Ronald Crond6d28882020-12-14 14:56:02 +0100237}
Ronald Cron6d051732020-10-01 14:10:20 +0200238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239static psa_status_t cipher_set_iv(mbedtls_psa_cipher_operation_t *operation,
240 const uint8_t *iv,
241 size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100242{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200243 if (iv_length != operation->iv_length)
244 return PSA_ERROR_INVALID_ARGUMENT;
Ronald Cron8287e6b2021-03-12 10:35:18 +0100245
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246 return (mbedtls_to_psa_error(
247 mbedtls_cipher_set_iv(&operation->ctx.cipher, iv, iv_length)));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100248}
249
Ronald Cron6d051732020-10-01 14:10:20 +0200250/* Process input for which the algorithm is set to ECB mode. This requires
251 * manual processing, since the PSA API is defined as being able to process
252 * arbitrary-length calls to psa_cipher_update() with ECB mode, but the
253 * underlying mbedtls_cipher_update only takes full blocks. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200254static psa_status_t psa_cipher_update_ecb(mbedtls_cipher_context_t *ctx,
255 const uint8_t *input,
256 size_t input_length,
257 uint8_t *output,
258 size_t output_size,
259 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200260{
261 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
262 size_t block_size = ctx->cipher_info->block_size;
263 size_t internal_output_length = 0;
264 *output_length = 0;
265
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200266 if (input_length == 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200267 status = PSA_SUCCESS;
268 goto exit;
269 }
270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 if (ctx->unprocessed_len > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200272 /* Fill up to block size, and run the block if there's a full one. */
273 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275 if (input_length < bytes_to_copy)
Ronald Cron6d051732020-10-01 14:10:20 +0200276 bytes_to_copy = input_length;
277
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
279 bytes_to_copy);
Ronald Cron6d051732020-10-01 14:10:20 +0200280 input_length -= bytes_to_copy;
281 input += bytes_to_copy;
282 ctx->unprocessed_len += bytes_to_copy;
283
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200284 if (ctx->unprocessed_len == block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200285 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200286 mbedtls_cipher_update(ctx, ctx->unprocessed_data, block_size,
287 output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200288
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289 if (status != PSA_SUCCESS)
Ronald Cron6d051732020-10-01 14:10:20 +0200290 goto exit;
291
292 output += internal_output_length;
293 output_size -= internal_output_length;
294 *output_length += internal_output_length;
295 ctx->unprocessed_len = 0;
296 }
297 }
298
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299 while (input_length >= block_size) {
Ronald Cron6d051732020-10-01 14:10:20 +0200300 /* Run all full blocks we have, one by one */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200301 status = mbedtls_to_psa_error(mbedtls_cipher_update(
302 ctx, input, block_size, output, &internal_output_length));
Ronald Cron6d051732020-10-01 14:10:20 +0200303
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 if (status != PSA_SUCCESS)
Ronald Cron6d051732020-10-01 14:10:20 +0200305 goto exit;
306
307 input_length -= block_size;
308 input += block_size;
309
310 output += internal_output_length;
311 output_size -= internal_output_length;
312 *output_length += internal_output_length;
313 }
314
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200315 if (input_length > 0) {
Ronald Cron6d051732020-10-01 14:10:20 +0200316 /* Save unprocessed bytes for later processing */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200317 memcpy(&(ctx->unprocessed_data[ctx->unprocessed_len]), input,
318 input_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200319 ctx->unprocessed_len += input_length;
320 }
321
322 status = PSA_SUCCESS;
323
324exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200325 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200326}
327
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200328static psa_status_t cipher_update(mbedtls_psa_cipher_operation_t *operation,
329 const uint8_t *input,
330 size_t input_length,
331 uint8_t *output,
332 size_t output_size,
333 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200334{
335 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
336 size_t expected_output_size;
337
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200338 if (!PSA_ALG_IS_STREAM_CIPHER(operation->alg)) {
Ronald Cron6d051732020-10-01 14:10:20 +0200339 /* Take the unprocessed partial block left over from previous
340 * update calls, if any, plus the input to this call. Remove
341 * the last partial block, if any. You get the data that will be
342 * output in this call. */
343 expected_output_size =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200344 (operation->ctx.cipher.unprocessed_len + input_length) /
345 operation->block_length * operation->block_length;
346 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200347 expected_output_size = input_length;
348 }
349
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200350 if (output_size < expected_output_size)
351 return PSA_ERROR_BUFFER_TOO_SMALL;
Ronald Cron6d051732020-10-01 14:10:20 +0200352
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200353 if (operation->alg == PSA_ALG_ECB_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200354 /* mbedtls_cipher_update has an API inconsistency: it will only
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200355 * process a single block at a time in ECB mode. Abstract away that
356 * inconsistency here to match the PSA API behaviour. */
357 status = psa_cipher_update_ecb(&operation->ctx.cipher, input,
358 input_length, output, output_size,
359 output_length);
360 } else {
Ronald Cron6d051732020-10-01 14:10:20 +0200361 status = mbedtls_to_psa_error(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 mbedtls_cipher_update(&operation->ctx.cipher, input, input_length,
363 output, output_length));
gabor-mezei-arm58c17272021-06-29 16:41:25 +0200364
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200365 if (*output_length > output_size)
366 return PSA_ERROR_CORRUPTION_DETECTED;
Ronald Cron6d051732020-10-01 14:10:20 +0200367 }
368
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200369 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200370}
371
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200372static psa_status_t cipher_finish(mbedtls_psa_cipher_operation_t *operation,
373 uint8_t *output,
374 size_t output_size,
375 size_t *output_length)
Ronald Cron6d051732020-10-01 14:10:20 +0200376{
377 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
378 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
379
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200380 if (operation->ctx.cipher.unprocessed_len != 0) {
381 if (operation->alg == PSA_ALG_ECB_NO_PADDING ||
382 operation->alg == PSA_ALG_CBC_NO_PADDING) {
Ronald Cron6d051732020-10-01 14:10:20 +0200383 status = PSA_ERROR_INVALID_ARGUMENT;
384 goto exit;
385 }
386 }
387
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200388 status = mbedtls_to_psa_error(mbedtls_cipher_finish(
389 &operation->ctx.cipher, temp_output_buffer, output_length));
390 if (status != PSA_SUCCESS)
Ronald Cron6d051732020-10-01 14:10:20 +0200391 goto exit;
392
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200393 if (*output_length == 0)
Ronald Cron6d051732020-10-01 14:10:20 +0200394 ; /* Nothing to copy. Note that output may be NULL in this case. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200395 else if (output_size >= *output_length)
396 memcpy(output, temp_output_buffer, *output_length);
Ronald Cron6d051732020-10-01 14:10:20 +0200397 else
398 status = PSA_ERROR_BUFFER_TOO_SMALL;
399
400exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200401 mbedtls_platform_zeroize(temp_output_buffer, sizeof(temp_output_buffer));
Ronald Cron6d051732020-10-01 14:10:20 +0200402
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200403 return status;
Ronald Cron6d051732020-10-01 14:10:20 +0200404}
405
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200406static psa_status_t cipher_abort(mbedtls_psa_cipher_operation_t *operation)
Ronald Cron6d051732020-10-01 14:10:20 +0200407{
Ronald Cron937dfee2021-03-10 09:17:32 +0100408 /* Sanity check (shouldn't happen: operation->alg should
409 * always have been initialized to a valid value). */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410 if (!PSA_ALG_IS_CIPHER(operation->alg))
411 return PSA_ERROR_BAD_STATE;
Ronald Cron937dfee2021-03-10 09:17:32 +0100412
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200413 mbedtls_cipher_free(&operation->ctx.cipher);
Ronald Cron6d051732020-10-01 14:10:20 +0200414
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200415 return PSA_SUCCESS;
Ronald Cron6d051732020-10-01 14:10:20 +0200416}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100417
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200418static psa_status_t cipher_encrypt(const psa_key_attributes_t *attributes,
419 const uint8_t *key_buffer,
420 size_t key_buffer_size,
421 psa_algorithm_t alg,
422 const uint8_t *input,
423 size_t input_length,
424 uint8_t *output,
425 size_t output_size,
426 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100427{
428 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 mbedtls_psa_cipher_operation_t operation =
430 MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200431 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100432
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200433 status = cipher_encrypt_setup(&operation, attributes, key_buffer,
434 key_buffer_size, alg);
435 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100436 goto exit;
437
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200438 accumulated_length = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200439 if (operation.iv_length > 0) {
440 status = cipher_set_iv(&operation, output, operation.iv_length);
441 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100442 goto exit;
443
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200444 accumulated_length = operation.iv_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100445 }
446
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200447 status = cipher_update(&operation, input, input_length,
448 output + operation.iv_length,
449 output_size - operation.iv_length, &olength);
450 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100451 goto exit;
452
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200453 accumulated_length += olength;
454
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455 status = cipher_finish(&operation, output + accumulated_length,
456 output_size - accumulated_length, &olength);
457 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100458 goto exit;
459
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200460 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200461
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100462exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200463 if (status == PSA_SUCCESS)
464 status = cipher_abort(&operation);
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100465 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200466 cipher_abort(&operation);
467 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100468}
469
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200470static psa_status_t cipher_decrypt(const psa_key_attributes_t *attributes,
471 const uint8_t *key_buffer,
472 size_t key_buffer_size,
473 psa_algorithm_t alg,
474 const uint8_t *input,
475 size_t input_length,
476 uint8_t *output,
477 size_t output_size,
478 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100479{
480 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481 mbedtls_psa_cipher_operation_t operation =
482 MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200483 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100484
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200485 status = cipher_decrypt_setup(&operation, attributes, key_buffer,
486 key_buffer_size, alg);
487 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100488 goto exit;
489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200490 if (operation.iv_length > 0) {
491 status = cipher_set_iv(&operation, input, operation.iv_length);
492 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100493 goto exit;
494 }
495
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200496 status = cipher_update(&operation, input + operation.iv_length,
497 input_length - operation.iv_length, output,
498 output_size, &olength);
499 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100500 goto exit;
501
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200502 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200503
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200504 status = cipher_finish(&operation, output + accumulated_length,
505 output_size - accumulated_length, &olength);
506 if (status != PSA_SUCCESS)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100507 goto exit;
508
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200509 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200510
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100511exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200512 if (status == PSA_SUCCESS)
513 status = cipher_abort(&operation);
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100514 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200515 cipher_abort(&operation);
516 return status;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100517}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200518# endif /* MBEDTLS_PSA_BUILTIN_CIPHER || PSA_CRYPTO_DRIVER_TEST */
Ronald Cron6d051732020-10-01 14:10:20 +0200519
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200520# if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
521psa_status_t
522mbedtls_psa_cipher_encrypt_setup(mbedtls_psa_cipher_operation_t *operation,
523 const psa_key_attributes_t *attributes,
524 const uint8_t *key_buffer,
525 size_t key_buffer_size,
526 psa_algorithm_t alg)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100527{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200528 return (cipher_encrypt_setup(operation, attributes, key_buffer,
529 key_buffer_size, alg));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100530}
531
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200532psa_status_t
533mbedtls_psa_cipher_decrypt_setup(mbedtls_psa_cipher_operation_t *operation,
534 const psa_key_attributes_t *attributes,
535 const uint8_t *key_buffer,
536 size_t key_buffer_size,
537 psa_algorithm_t alg)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100538{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200539 return (cipher_decrypt_setup(operation, attributes, key_buffer,
540 key_buffer_size, alg));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100541}
542
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200543psa_status_t
544mbedtls_psa_cipher_set_iv(mbedtls_psa_cipher_operation_t *operation,
545 const uint8_t *iv,
546 size_t iv_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100547{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200548 return cipher_set_iv(operation, iv, iv_length);
Ronald Cron8287e6b2021-03-12 10:35:18 +0100549}
550
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200551psa_status_t
552mbedtls_psa_cipher_update(mbedtls_psa_cipher_operation_t *operation,
553 const uint8_t *input,
554 size_t input_length,
555 uint8_t *output,
556 size_t output_size,
557 size_t *output_length)
558{
559 return (cipher_update(operation, input, input_length, output, output_size,
560 output_length));
561}
562
563psa_status_t
564mbedtls_psa_cipher_finish(mbedtls_psa_cipher_operation_t *operation,
565 uint8_t *output,
566 size_t output_size,
567 size_t *output_length)
568{
569 return cipher_finish(operation, output, output_size, output_length);
570}
571
572psa_status_t mbedtls_psa_cipher_abort(mbedtls_psa_cipher_operation_t *operation)
573{
574 return cipher_abort(operation);
575}
576
577psa_status_t mbedtls_psa_cipher_encrypt(const psa_key_attributes_t *attributes,
578 const uint8_t *key_buffer,
579 size_t key_buffer_size,
580 psa_algorithm_t alg,
Ronald Cron8287e6b2021-03-12 10:35:18 +0100581 const uint8_t *input,
582 size_t input_length,
583 uint8_t *output,
584 size_t output_size,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200585 size_t *output_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100586{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200587 return (cipher_encrypt(attributes, key_buffer, key_buffer_size, alg, input,
588 input_length, output, output_size, output_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100589}
590
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200591psa_status_t mbedtls_psa_cipher_decrypt(const psa_key_attributes_t *attributes,
592 const uint8_t *key_buffer,
593 size_t key_buffer_size,
594 psa_algorithm_t alg,
595 const uint8_t *input,
596 size_t input_length,
Ronald Cron8287e6b2021-03-12 10:35:18 +0100597 uint8_t *output,
598 size_t output_size,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599 size_t *output_length)
Ronald Cron8287e6b2021-03-12 10:35:18 +0100600{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200601 return (cipher_decrypt(attributes, key_buffer, key_buffer_size, alg, input,
602 input_length, output, output_size, output_length));
Ronald Cron8287e6b2021-03-12 10:35:18 +0100603}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200604# endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100605
Ronald Cron3522e322021-03-12 11:08:49 +0100606/*
607 * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY.
608 */
609
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200610# if defined(PSA_CRYPTO_DRIVER_TEST)
Ronald Cron3522e322021-03-12 11:08:49 +0100611psa_status_t mbedtls_transparent_test_driver_cipher_encrypt_setup(
612 mbedtls_psa_cipher_operation_t *operation,
613 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200614 const uint8_t *key_buffer,
615 size_t key_buffer_size,
616 psa_algorithm_t alg)
Ronald Cron3522e322021-03-12 11:08:49 +0100617{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200618 return (cipher_encrypt_setup(operation, attributes, key_buffer,
619 key_buffer_size, alg));
Ronald Cron3522e322021-03-12 11:08:49 +0100620}
621
622psa_status_t mbedtls_transparent_test_driver_cipher_decrypt_setup(
623 mbedtls_psa_cipher_operation_t *operation,
624 const psa_key_attributes_t *attributes,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200625 const uint8_t *key_buffer,
626 size_t key_buffer_size,
627 psa_algorithm_t alg)
Ronald Cron3522e322021-03-12 11:08:49 +0100628{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200629 return (cipher_decrypt_setup(operation, attributes, key_buffer,
630 key_buffer_size, alg));
Ronald Cron3522e322021-03-12 11:08:49 +0100631}
632
Ronald Cron3522e322021-03-12 11:08:49 +0100633psa_status_t mbedtls_transparent_test_driver_cipher_set_iv(
634 mbedtls_psa_cipher_operation_t *operation,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200635 const uint8_t *iv,
636 size_t iv_length)
Ronald Cron3522e322021-03-12 11:08:49 +0100637{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200638 return cipher_set_iv(operation, iv, iv_length);
Ronald Cron3522e322021-03-12 11:08:49 +0100639}
640
641psa_status_t mbedtls_transparent_test_driver_cipher_update(
642 mbedtls_psa_cipher_operation_t *operation,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200643 const uint8_t *input,
644 size_t input_length,
645 uint8_t *output,
646 size_t output_size,
647 size_t *output_length)
Ronald Cron3522e322021-03-12 11:08:49 +0100648{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200649 return (cipher_update(operation, input, input_length, output, output_size,
650 output_length));
Ronald Cron3522e322021-03-12 11:08:49 +0100651}
652
653psa_status_t mbedtls_transparent_test_driver_cipher_finish(
654 mbedtls_psa_cipher_operation_t *operation,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200655 uint8_t *output,
656 size_t output_size,
657 size_t *output_length)
Ronald Cron3522e322021-03-12 11:08:49 +0100658{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200659 return cipher_finish(operation, output, output_size, output_length);
Ronald Cron3522e322021-03-12 11:08:49 +0100660}
661
662psa_status_t mbedtls_transparent_test_driver_cipher_abort(
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200663 mbedtls_psa_cipher_operation_t *operation)
Ronald Cron3522e322021-03-12 11:08:49 +0100664{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200665 return cipher_abort(operation);
Ronald Cron3522e322021-03-12 11:08:49 +0100666}
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100667
668psa_status_t mbedtls_transparent_test_driver_cipher_encrypt(
669 const psa_key_attributes_t *attributes,
670 const uint8_t *key_buffer,
671 size_t key_buffer_size,
672 psa_algorithm_t alg,
673 const uint8_t *input,
674 size_t input_length,
675 uint8_t *output,
676 size_t output_size,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200677 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100678{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200679 return (cipher_encrypt(attributes, key_buffer, key_buffer_size, alg, input,
680 input_length, output, output_size, output_length));
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100681}
682
683psa_status_t mbedtls_transparent_test_driver_cipher_decrypt(
684 const psa_key_attributes_t *attributes,
685 const uint8_t *key_buffer,
686 size_t key_buffer_size,
687 psa_algorithm_t alg,
688 const uint8_t *input,
689 size_t input_length,
690 uint8_t *output,
691 size_t output_size,
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200692 size_t *output_length)
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100693{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200694 return (cipher_decrypt(attributes, key_buffer, key_buffer_size, alg, input,
695 input_length, output, output_size, output_length));
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100696}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200697# endif /* PSA_CRYPTO_DRIVER_TEST */
Ronald Cron3522e322021-03-12 11:08:49 +0100698
Ronald Cron0ff57952021-03-08 16:46:35 +0100699#endif /* MBEDTLS_PSA_CRYPTO_C */