blob: 574c1843051a99d2a4cbd68129c096908623097e [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
25#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
Ronald Cron75e6ae22021-03-17 14:46:05 +010034const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa(
35 psa_algorithm_t alg,
36 psa_key_type_t key_type,
37 size_t key_bits,
38 mbedtls_cipher_id_t* cipher_id )
39{
40 mbedtls_cipher_mode_t mode;
41 mbedtls_cipher_id_t cipher_id_tmp;
42
43 if( PSA_ALG_IS_AEAD( alg ) )
44 alg = PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 );
45
46 if( PSA_ALG_IS_CIPHER( alg ) || PSA_ALG_IS_AEAD( alg ) )
47 {
48 switch( alg )
49 {
Gilles Peskine449e02e2022-03-16 12:25:17 +010050#if defined(MBEDTLS_PSA_BUILTIN_ALG_STREAM_CIPHER)
Ronald Cron75e6ae22021-03-17 14:46:05 +010051 case PSA_ALG_STREAM_CIPHER:
52 mode = MBEDTLS_MODE_STREAM;
53 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010054#endif
55#if defined(MBEDTLS_PSA_BUILTIN_ALG_CTR)
Ronald Cron75e6ae22021-03-17 14:46:05 +010056 case PSA_ALG_CTR:
57 mode = MBEDTLS_MODE_CTR;
58 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010059#endif
60#if defined(MBEDTLS_PSA_BUILTIN_ALG_CFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +010061 case PSA_ALG_CFB:
62 mode = MBEDTLS_MODE_CFB;
63 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010064#endif
65#if defined(MBEDTLS_PSA_BUILTIN_ALG_OFB)
Ronald Cron75e6ae22021-03-17 14:46:05 +010066 case PSA_ALG_OFB:
67 mode = MBEDTLS_MODE_OFB;
68 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010069#endif
70#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +010071 case PSA_ALG_ECB_NO_PADDING:
72 mode = MBEDTLS_MODE_ECB;
73 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010074#endif
75#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING)
Ronald Cron75e6ae22021-03-17 14:46:05 +010076 case PSA_ALG_CBC_NO_PADDING:
77 mode = MBEDTLS_MODE_CBC;
78 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010079#endif
80#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Ronald Cron75e6ae22021-03-17 14:46:05 +010081 case PSA_ALG_CBC_PKCS7:
82 mode = MBEDTLS_MODE_CBC;
83 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010084#endif
85#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Ronald Cron75e6ae22021-03-17 14:46:05 +010086 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
87 mode = MBEDTLS_MODE_CCM;
88 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010089#endif
90#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Ronald Cron75e6ae22021-03-17 14:46:05 +010091 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
92 mode = MBEDTLS_MODE_GCM;
93 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010094#endif
95#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Ronald Cron75e6ae22021-03-17 14:46:05 +010096 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
97 mode = MBEDTLS_MODE_CHACHAPOLY;
98 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +010099#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100100 default:
101 return( NULL );
102 }
103 }
104 else if( alg == PSA_ALG_CMAC )
105 mode = MBEDTLS_MODE_ECB;
106 else
107 return( NULL );
108
109 switch( key_type )
110 {
Gilles Peskine449e02e2022-03-16 12:25:17 +0100111#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100112 case PSA_KEY_TYPE_AES:
113 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
114 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100115#endif
116#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine8890f642021-09-21 11:59:39 +0200117 case PSA_KEY_TYPE_ARIA:
118 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
119 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100120#endif
121#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100122 case PSA_KEY_TYPE_DES:
123 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
124 * and 192 for three-key Triple-DES. */
125 if( key_bits == 64 )
126 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
127 else
128 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
129 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
130 * but two-key Triple-DES is functionally three-key Triple-DES
131 * with K1=K3, so that's how we present it to mbedtls. */
132 if( key_bits == 128 )
133 key_bits = 192;
134 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100135#endif
136#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100137 case PSA_KEY_TYPE_CAMELLIA:
138 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
139 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100140#endif
141#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARC4)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100142 case PSA_KEY_TYPE_ARC4:
143 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARC4;
144 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100145#endif
146#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CHACHA20)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100147 case PSA_KEY_TYPE_CHACHA20:
148 cipher_id_tmp = MBEDTLS_CIPHER_ID_CHACHA20;
149 break;
Gilles Peskine449e02e2022-03-16 12:25:17 +0100150#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100151 default:
152 return( NULL );
153 }
154 if( cipher_id != NULL )
155 *cipher_id = cipher_id_tmp;
156
157 return( mbedtls_cipher_info_from_values( cipher_id_tmp,
158 (int) key_bits, mode ) );
159}
160
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100161#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100162
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100163static psa_status_t psa_cipher_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100164 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100165 const psa_key_attributes_t *attributes,
166 const uint8_t *key_buffer, size_t key_buffer_size,
167 psa_algorithm_t alg,
168 mbedtls_operation_t cipher_operation )
169{
170 int ret = 0;
171 size_t key_bits;
172 const mbedtls_cipher_info_t *cipher_info = NULL;
173 psa_key_type_t key_type = attributes->core.type;
174
175 (void)key_buffer_size;
176
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200177 mbedtls_cipher_init( &operation->ctx.cipher );
Ronald Crond6d28882020-12-14 14:56:02 +0100178
Ronald Cron6e412a72021-03-10 09:58:47 +0100179 operation->alg = alg;
Ronald Crond6d28882020-12-14 14:56:02 +0100180 key_bits = attributes->core.bits;
181 cipher_info = mbedtls_cipher_info_from_psa( alg, key_type,
182 key_bits, NULL );
183 if( cipher_info == NULL )
184 return( PSA_ERROR_NOT_SUPPORTED );
185
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200186 ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info );
Ronald Crond6d28882020-12-14 14:56:02 +0100187 if( ret != 0 )
188 goto exit;
189
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100190#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Crond6d28882020-12-14 14:56:02 +0100191 if( key_type == PSA_KEY_TYPE_DES && key_bits == 128 )
192 {
193 /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */
194 uint8_t keys[24];
195 memcpy( keys, key_buffer, 16 );
196 memcpy( keys + 16, key_buffer, 8 );
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200197 ret = mbedtls_cipher_setkey( &operation->ctx.cipher,
Ronald Crond6d28882020-12-14 14:56:02 +0100198 keys,
199 192, cipher_operation );
200 }
201 else
202#endif
203 {
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200204 ret = mbedtls_cipher_setkey( &operation->ctx.cipher, key_buffer,
Ronald Crond6d28882020-12-14 14:56:02 +0100205 (int) key_bits, cipher_operation );
206 }
207 if( ret != 0 )
208 goto exit;
209
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100210#if defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING) || \
211 defined(MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7)
Ronald Crond6d28882020-12-14 14:56:02 +0100212 switch( alg )
213 {
214 case PSA_ALG_CBC_NO_PADDING:
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200215 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
Ronald Crond6d28882020-12-14 14:56:02 +0100216 MBEDTLS_PADDING_NONE );
217 break;
218 case PSA_ALG_CBC_PKCS7:
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200219 ret = mbedtls_cipher_set_padding_mode( &operation->ctx.cipher,
Ronald Crond6d28882020-12-14 14:56:02 +0100220 MBEDTLS_PADDING_PKCS7 );
221 break;
222 default:
223 /* The algorithm doesn't involve padding. */
224 ret = 0;
225 break;
226 }
227 if( ret != 0 )
228 goto exit;
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100229#endif /* MBEDTLS_PSA_BUILTIN_ALG_CBC_NO_PADDING ||
230 MBEDTLS_PSA_BUILTIN_ALG_CBC_PKCS7 */
Ronald Crond6d28882020-12-14 14:56:02 +0100231
Ronald Cron6ad554c2021-03-26 09:29:09 +0100232 operation->block_length = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 :
233 PSA_BLOCK_CIPHER_BLOCK_LENGTH( key_type ) );
Ronald Cronc17e8a92021-03-19 14:12:26 +0100234 operation->iv_length = PSA_CIPHER_IV_LENGTH( key_type, alg );
Ronald Crond6d28882020-12-14 14:56:02 +0100235
236exit:
237 return( mbedtls_to_psa_error( ret ) );
238}
239
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100240psa_status_t mbedtls_psa_cipher_encrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100241 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100242 const psa_key_attributes_t *attributes,
243 const uint8_t *key_buffer, size_t key_buffer_size,
244 psa_algorithm_t alg )
245{
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100246 return( psa_cipher_setup( operation, attributes,
247 key_buffer, key_buffer_size,
248 alg, MBEDTLS_ENCRYPT ) );
Ronald Crond6d28882020-12-14 14:56:02 +0100249}
250
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100251psa_status_t mbedtls_psa_cipher_decrypt_setup(
Ronald Cron6e412a72021-03-10 09:58:47 +0100252 mbedtls_psa_cipher_operation_t *operation,
Ronald Crond6d28882020-12-14 14:56:02 +0100253 const psa_key_attributes_t *attributes,
254 const uint8_t *key_buffer, size_t key_buffer_size,
255 psa_algorithm_t alg )
256{
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100257 return( psa_cipher_setup( operation, attributes,
258 key_buffer, key_buffer_size,
259 alg, MBEDTLS_DECRYPT ) );
Ronald Crond6d28882020-12-14 14:56:02 +0100260}
Ronald Cron6d051732020-10-01 14:10:20 +0200261
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100262psa_status_t mbedtls_psa_cipher_set_iv(
263 mbedtls_psa_cipher_operation_t *operation,
264 const uint8_t *iv, size_t iv_length )
Ronald Cron8287e6b2021-03-12 10:35:18 +0100265{
Ronald Cron6ad554c2021-03-26 09:29:09 +0100266 if( iv_length != operation->iv_length )
Ronald Cron8287e6b2021-03-12 10:35:18 +0100267 return( PSA_ERROR_INVALID_ARGUMENT );
268
269 return( mbedtls_to_psa_error(
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200270 mbedtls_cipher_set_iv( &operation->ctx.cipher,
Ronald Cron8287e6b2021-03-12 10:35:18 +0100271 iv, iv_length ) ) );
272}
273
Gilles Peskine449e02e2022-03-16 12:25:17 +0100274#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine7b1c9162021-09-13 09:33:28 +0200275/** Process input for which the algorithm is set to ECB mode.
276 *
277 * This requires manual processing, since the PSA API is defined as being
278 * able to process arbitrary-length calls to psa_cipher_update() with ECB mode,
279 * but the underlying mbedtls_cipher_update only takes full blocks.
280 *
281 * \param ctx The mbedtls cipher context to use. It must have been
282 * set up for ECB.
283 * \param[in] input The input plaintext or ciphertext to process.
284 * \param input_length The number of bytes to process from \p input.
285 * This does not need to be aligned to a block boundary.
286 * If there is a partial block at the end of the input,
287 * it is stored in \p ctx for future processing.
Gilles Peskine03900162021-09-13 12:20:51 +0200288 * \param output The buffer where the output is written. It must be
289 * at least `BS * floor((p + input_length) / BS)` bytes
290 * long, where `p` is the number of bytes in the
291 * unprocessed partial block in \p ctx (with
292 * `0 <= p <= BS - 1`) and `BS` is the block size.
Gilles Peskine7b1c9162021-09-13 09:33:28 +0200293 * \param output_length On success, the number of bytes written to \p output.
294 * \c 0 on error.
295 *
296 * \return #PSA_SUCCESS or an error from a hardware accelerator
297 */
Ronald Cron6d051732020-10-01 14:10:20 +0200298static psa_status_t psa_cipher_update_ecb(
299 mbedtls_cipher_context_t *ctx,
300 const uint8_t *input,
301 size_t input_length,
302 uint8_t *output,
Ronald Cron6d051732020-10-01 14:10:20 +0200303 size_t *output_length )
304{
305 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
306 size_t block_size = ctx->cipher_info->block_size;
307 size_t internal_output_length = 0;
308 *output_length = 0;
309
310 if( input_length == 0 )
311 {
312 status = PSA_SUCCESS;
313 goto exit;
314 }
315
316 if( ctx->unprocessed_len > 0 )
317 {
318 /* Fill up to block size, and run the block if there's a full one. */
319 size_t bytes_to_copy = block_size - ctx->unprocessed_len;
320
321 if( input_length < bytes_to_copy )
322 bytes_to_copy = input_length;
323
324 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
325 input, bytes_to_copy );
326 input_length -= bytes_to_copy;
327 input += bytes_to_copy;
328 ctx->unprocessed_len += bytes_to_copy;
329
330 if( ctx->unprocessed_len == block_size )
331 {
332 status = mbedtls_to_psa_error(
333 mbedtls_cipher_update( ctx,
334 ctx->unprocessed_data,
335 block_size,
336 output, &internal_output_length ) );
337
338 if( status != PSA_SUCCESS )
339 goto exit;
340
341 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200342 *output_length += internal_output_length;
343 ctx->unprocessed_len = 0;
344 }
345 }
346
347 while( input_length >= block_size )
348 {
349 /* Run all full blocks we have, one by one */
350 status = mbedtls_to_psa_error(
351 mbedtls_cipher_update( ctx, input,
352 block_size,
353 output, &internal_output_length ) );
354
355 if( status != PSA_SUCCESS )
356 goto exit;
357
358 input_length -= block_size;
359 input += block_size;
360
361 output += internal_output_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200362 *output_length += internal_output_length;
363 }
364
365 if( input_length > 0 )
366 {
367 /* Save unprocessed bytes for later processing */
368 memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ),
369 input, input_length );
370 ctx->unprocessed_len += input_length;
371 }
372
373 status = PSA_SUCCESS;
374
375exit:
376 return( status );
377}
Gilles Peskine449e02e2022-03-16 12:25:17 +0100378#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200379
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100380psa_status_t mbedtls_psa_cipher_update(
381 mbedtls_psa_cipher_operation_t *operation,
382 const uint8_t *input, size_t input_length,
383 uint8_t *output, size_t output_size, size_t *output_length )
Ronald Cron6d051732020-10-01 14:10:20 +0200384{
385 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
386 size_t expected_output_size;
387
Ronald Cron6e412a72021-03-10 09:58:47 +0100388 if( ! PSA_ALG_IS_STREAM_CIPHER( operation->alg ) )
Ronald Cron6d051732020-10-01 14:10:20 +0200389 {
390 /* Take the unprocessed partial block left over from previous
391 * update calls, if any, plus the input to this call. Remove
392 * the last partial block, if any. You get the data that will be
393 * output in this call. */
394 expected_output_size =
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200395 ( operation->ctx.cipher.unprocessed_len + input_length )
Ronald Cron6ad554c2021-03-26 09:29:09 +0100396 / operation->block_length * operation->block_length;
Ronald Cron6d051732020-10-01 14:10:20 +0200397 }
398 else
399 {
400 expected_output_size = input_length;
401 }
402
403 if( output_size < expected_output_size )
404 return( PSA_ERROR_BUFFER_TOO_SMALL );
405
Gilles Peskine449e02e2022-03-16 12:25:17 +0100406#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Ronald Cron6e412a72021-03-10 09:58:47 +0100407 if( operation->alg == PSA_ALG_ECB_NO_PADDING )
Ronald Cron6d051732020-10-01 14:10:20 +0200408 {
409 /* mbedtls_cipher_update has an API inconsistency: it will only
410 * process a single block at a time in ECB mode. Abstract away that
411 * inconsistency here to match the PSA API behaviour. */
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200412 status = psa_cipher_update_ecb( &operation->ctx.cipher,
Ronald Cron6d051732020-10-01 14:10:20 +0200413 input,
414 input_length,
415 output,
Ronald Cron6d051732020-10-01 14:10:20 +0200416 output_length );
417 }
418 else
Gilles Peskine449e02e2022-03-16 12:25:17 +0100419#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200420 {
421 status = mbedtls_to_psa_error(
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200422 mbedtls_cipher_update( &operation->ctx.cipher, input,
Ronald Cron6d051732020-10-01 14:10:20 +0200423 input_length, output, output_length ) );
gabor-mezei-arm42373bd2021-06-29 16:41:25 +0200424
425 if( *output_length > output_size )
gabor-mezei-arm25230452021-06-29 19:06:30 +0200426 return( PSA_ERROR_CORRUPTION_DETECTED );
Ronald Cron6d051732020-10-01 14:10:20 +0200427 }
428
429 return( status );
430}
431
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100432psa_status_t mbedtls_psa_cipher_finish(
433 mbedtls_psa_cipher_operation_t *operation,
434 uint8_t *output, size_t output_size, size_t *output_length )
Ronald Cron6d051732020-10-01 14:10:20 +0200435{
436 psa_status_t status = PSA_ERROR_GENERIC_ERROR;
437 uint8_t temp_output_buffer[MBEDTLS_MAX_BLOCK_LENGTH];
438
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200439 if( operation->ctx.cipher.unprocessed_len != 0 )
Ronald Cron6d051732020-10-01 14:10:20 +0200440 {
Ronald Cron6e412a72021-03-10 09:58:47 +0100441 if( operation->alg == PSA_ALG_ECB_NO_PADDING ||
442 operation->alg == PSA_ALG_CBC_NO_PADDING )
Ronald Cron6d051732020-10-01 14:10:20 +0200443 {
444 status = PSA_ERROR_INVALID_ARGUMENT;
445 goto exit;
446 }
447 }
448
449 status = mbedtls_to_psa_error(
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200450 mbedtls_cipher_finish( &operation->ctx.cipher,
Ronald Cron6d051732020-10-01 14:10:20 +0200451 temp_output_buffer,
452 output_length ) );
453 if( status != PSA_SUCCESS )
454 goto exit;
455
456 if( *output_length == 0 )
457 ; /* Nothing to copy. Note that output may be NULL in this case. */
458 else if( output_size >= *output_length )
459 memcpy( output, temp_output_buffer, *output_length );
460 else
461 status = PSA_ERROR_BUFFER_TOO_SMALL;
462
463exit:
464 mbedtls_platform_zeroize( temp_output_buffer,
465 sizeof( temp_output_buffer ) );
466
467 return( status );
468}
469
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100470psa_status_t mbedtls_psa_cipher_abort(
471 mbedtls_psa_cipher_operation_t *operation )
Ronald Cron6d051732020-10-01 14:10:20 +0200472{
Ronald Cron937dfee2021-03-10 09:17:32 +0100473 /* Sanity check (shouldn't happen: operation->alg should
474 * always have been initialized to a valid value). */
Ronald Cron6e412a72021-03-10 09:58:47 +0100475 if( ! PSA_ALG_IS_CIPHER( operation->alg ) )
Ronald Cron937dfee2021-03-10 09:17:32 +0100476 return( PSA_ERROR_BAD_STATE );
477
gabor-mezei-armf67d8af2021-04-12 15:47:35 +0200478 mbedtls_cipher_free( &operation->ctx.cipher );
Ronald Cron6d051732020-10-01 14:10:20 +0200479
480 return( PSA_SUCCESS );
481}
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100482
Dave Rodgman08412e22021-12-14 12:52:51 +0000483psa_status_t mbedtls_psa_cipher_encrypt( const psa_key_attributes_t *attributes,
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100484 const uint8_t *key_buffer,
485 size_t key_buffer_size,
486 psa_algorithm_t alg,
Ronald Crona8331692021-07-09 09:19:35 +0200487 const uint8_t *iv,
488 size_t iv_length,
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100489 const uint8_t *input,
490 size_t input_length,
491 uint8_t *output,
492 size_t output_size,
493 size_t *output_length )
494{
495 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
496 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Crona8331692021-07-09 09:19:35 +0200497 size_t update_output_length, finish_output_length;
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100498
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100499 status = mbedtls_psa_cipher_encrypt_setup( &operation, attributes,
500 key_buffer, key_buffer_size,
501 alg );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100502 if( status != PSA_SUCCESS )
503 goto exit;
504
Ronald Crona8331692021-07-09 09:19:35 +0200505 if( iv_length > 0 )
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100506 {
Dave Rodgman08412e22021-12-14 12:52:51 +0000507 status = mbedtls_psa_cipher_set_iv( &operation, iv, iv_length );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100508 if( status != PSA_SUCCESS )
509 goto exit;
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100510 }
511
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100512 status = mbedtls_psa_cipher_update( &operation, input, input_length,
Ronald Crona8331692021-07-09 09:19:35 +0200513 output, output_size, &update_output_length );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100514 if( status != PSA_SUCCESS )
515 goto exit;
516
Dave Rodgman08412e22021-12-14 12:52:51 +0000517 status = mbedtls_psa_cipher_finish( &operation, output + update_output_length,
Ronald Crona8331692021-07-09 09:19:35 +0200518 output_size - update_output_length,
519 &finish_output_length );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100520 if( status != PSA_SUCCESS )
521 goto exit;
522
Ronald Crona8331692021-07-09 09:19:35 +0200523 *output_length = update_output_length + finish_output_length;
gabor-mezei-arm7fbea092021-06-25 15:23:05 +0200524
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100525exit:
526 if( status == PSA_SUCCESS )
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100527 status = mbedtls_psa_cipher_abort( &operation );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100528 else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100529 mbedtls_psa_cipher_abort( &operation );
530
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100531 return( status );
532}
533
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100534psa_status_t mbedtls_psa_cipher_decrypt(
535 const psa_key_attributes_t *attributes,
536 const uint8_t *key_buffer,
537 size_t key_buffer_size,
538 psa_algorithm_t alg,
539 const uint8_t *input,
540 size_t input_length,
541 uint8_t *output,
542 size_t output_size,
543 size_t *output_length )
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100544{
545 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
546 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arm7fbea092021-06-25 15:23:05 +0200547 size_t olength, accumulated_length;
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100548
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100549 status = mbedtls_psa_cipher_decrypt_setup( &operation, attributes,
550 key_buffer, key_buffer_size,
551 alg );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100552 if( status != PSA_SUCCESS )
553 goto exit;
554
555 if( operation.iv_length > 0 )
556 {
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100557 status = mbedtls_psa_cipher_set_iv( &operation,
558 input, operation.iv_length );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100559 if( status != PSA_SUCCESS )
560 goto exit;
561 }
562
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100563 status = mbedtls_psa_cipher_update( &operation, input + operation.iv_length,
564 input_length - operation.iv_length,
565 output, output_size, &olength );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100566 if( status != PSA_SUCCESS )
567 goto exit;
568
gabor-mezei-arm809634d2021-06-29 16:42:13 +0200569 accumulated_length = olength;
gabor-mezei-arm3fd792d2021-06-25 15:25:38 +0200570
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100571 status = mbedtls_psa_cipher_finish( &operation, output + accumulated_length,
572 output_size - accumulated_length,
573 &olength );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100574 if( status != PSA_SUCCESS )
575 goto exit;
576
gabor-mezei-arm25230452021-06-29 19:06:30 +0200577 *output_length = accumulated_length + olength;
gabor-mezei-arm7fbea092021-06-25 15:23:05 +0200578
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100579exit:
580 if ( status == PSA_SUCCESS )
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100581 status = mbedtls_psa_cipher_abort( &operation );
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100582 else
Ronald Croncfc3c7b2021-03-13 18:50:11 +0100583 mbedtls_psa_cipher_abort( &operation );
584
gabor-mezei-armfa990b52021-03-25 11:17:10 +0100585 return( status );
586}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100587#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100588
Ronald Cron0ff57952021-03-08 16:46:35 +0100589#endif /* MBEDTLS_PSA_CRYPTO_C */