blob: 70dc74d74858671d9b30ad80c2373045f2902c18 [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
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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-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 Peskine695c4cb2022-03-16 12:25:17 +010084#endif
85#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM_STAR_NO_TAG)
Mateusz Starzyk594215b2021-10-14 12:23:06 +020086 case PSA_ALG_CCM_STAR_NO_TAG:
Mateusz Starzyk4cb97392021-10-27 10:42:31 +020087 mode = MBEDTLS_MODE_CCM_STAR_NO_TAG;
Mateusz Starzyk594215b2021-10-14 12:23:06 +020088 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +010089#endif
90#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
Ronald Cron75e6ae22021-03-17 14:46:05 +010091 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ):
92 mode = MBEDTLS_MODE_CCM;
93 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +010094#endif
95#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
Ronald Cron75e6ae22021-03-17 14:46:05 +010096 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ):
97 mode = MBEDTLS_MODE_GCM;
98 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +010099#endif
100#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100101 case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ):
102 mode = MBEDTLS_MODE_CHACHAPOLY;
103 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100104#endif
Ronald Cron75e6ae22021-03-17 14:46:05 +0100105 default:
106 return( NULL );
107 }
108 }
109 else if( alg == PSA_ALG_CMAC )
110 mode = MBEDTLS_MODE_ECB;
111 else
112 return( NULL );
113
114 switch( key_type )
115 {
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100116#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_AES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100117 case PSA_KEY_TYPE_AES:
118 cipher_id_tmp = MBEDTLS_CIPHER_ID_AES;
119 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100120#endif
121#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ARIA)
Gilles Peskine6c12a1e2021-09-21 11:59:39 +0200122 case PSA_KEY_TYPE_ARIA:
123 cipher_id_tmp = MBEDTLS_CIPHER_ID_ARIA;
124 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100125#endif
126#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100127 case PSA_KEY_TYPE_DES:
128 /* key_bits is 64 for Single-DES, 128 for two-key Triple-DES,
129 * and 192 for three-key Triple-DES. */
130 if( key_bits == 64 )
131 cipher_id_tmp = MBEDTLS_CIPHER_ID_DES;
132 else
133 cipher_id_tmp = MBEDTLS_CIPHER_ID_3DES;
134 /* mbedtls doesn't recognize two-key Triple-DES as an algorithm,
135 * but two-key Triple-DES is functionally three-key Triple-DES
136 * with K1=K3, so that's how we present it to mbedtls. */
137 if( key_bits == 128 )
138 key_bits = 192;
139 break;
Gilles Peskine695c4cb2022-03-16 12:25:17 +0100140#endif
141#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_CAMELLIA)
Ronald Cron75e6ae22021-03-17 14:46:05 +0100142 case PSA_KEY_TYPE_CAMELLIA:
143 cipher_id_tmp = MBEDTLS_CIPHER_ID_CAMELLIA;
144 break;
Gilles Peskine695c4cb2022-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 Peskine695c4cb2022-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 Cron0266cfe2021-03-13 18:50:11 +0100161#if defined(MBEDTLS_PSA_BUILTIN_CIPHER)
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100162
Ronald Cron0266cfe2021-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-arm42cdb2a2021-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-arm42cdb2a2021-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 Cron0266cfe2021-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-arm42cdb2a2021-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-arm42cdb2a2021-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 Cron0266cfe2021-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-arm42cdb2a2021-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-arm42cdb2a2021-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 Cron0266cfe2021-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 Cron0266cfe2021-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 Cron0266cfe2021-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 Cron0266cfe2021-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 Cron0266cfe2021-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 Cron0266cfe2021-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-arm42cdb2a2021-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 Peskine695c4cb2022-03-16 12:25:17 +0100274#if defined(MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING)
Gilles Peskine55dffe52021-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 Peskined87d8732021-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 Peskine55dffe52021-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 Peskine695c4cb2022-03-16 12:25:17 +0100378#endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */
Ronald Cron6d051732020-10-01 14:10:20 +0200379
Ronald Cron0266cfe2021-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-arm42cdb2a2021-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 Peskine695c4cb2022-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-arm42cdb2a2021-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 Peskine695c4cb2022-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-arm42cdb2a2021-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-arm58c17272021-06-29 16:41:25 +0200424
425 if( *output_length > output_size )
gabor-mezei-arm00e54f12021-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 Cron0266cfe2021-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-arm42cdb2a2021-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-arm42cdb2a2021-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 Cron0266cfe2021-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-arm42cdb2a2021-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-arma9449a02021-03-25 11:17:10 +0100482
Ronald Cron0266cfe2021-03-13 18:50:11 +0100483psa_status_t mbedtls_psa_cipher_encrypt(
484 const psa_key_attributes_t *attributes,
485 const uint8_t *key_buffer,
486 size_t key_buffer_size,
487 psa_algorithm_t alg,
Ronald Cron9b674282021-07-09 09:19:35 +0200488 const uint8_t *iv,
489 size_t iv_length,
Ronald Cron0266cfe2021-03-13 18:50:11 +0100490 const uint8_t *input,
491 size_t input_length,
492 uint8_t *output,
493 size_t output_size,
494 size_t *output_length )
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100495{
496 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
497 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
Ronald Cron8188d192021-12-14 10:58:18 +0100498 size_t update_output_length, finish_output_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100499
Ronald Cron0266cfe2021-03-13 18:50:11 +0100500 status = mbedtls_psa_cipher_encrypt_setup( &operation, attributes,
501 key_buffer, key_buffer_size,
502 alg );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100503 if( status != PSA_SUCCESS )
504 goto exit;
505
Ronald Cron8188d192021-12-14 10:58:18 +0100506 if( iv_length > 0 )
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100507 {
Ronald Cron8188d192021-12-14 10:58:18 +0100508 status = mbedtls_psa_cipher_set_iv( &operation, iv, iv_length );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100509 if( status != PSA_SUCCESS )
510 goto exit;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100511 }
512
Ronald Cron0266cfe2021-03-13 18:50:11 +0100513 status = mbedtls_psa_cipher_update( &operation, input, input_length,
Ronald Cron8188d192021-12-14 10:58:18 +0100514 output, output_size,
515 &update_output_length );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100516 if( status != PSA_SUCCESS )
517 goto exit;
518
Ronald Cron8188d192021-12-14 10:58:18 +0100519 status = mbedtls_psa_cipher_finish( &operation,
520 output + update_output_length,
521 output_size - update_output_length,
522 &finish_output_length );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100523 if( status != PSA_SUCCESS )
524 goto exit;
525
Ronald Cron8188d192021-12-14 10:58:18 +0100526 *output_length = update_output_length + finish_output_length;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200527
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100528exit:
529 if( status == PSA_SUCCESS )
Ronald Cron0266cfe2021-03-13 18:50:11 +0100530 status = mbedtls_psa_cipher_abort( &operation );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100531 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100532 mbedtls_psa_cipher_abort( &operation );
533
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100534 return( status );
535}
536
Ronald Cron0266cfe2021-03-13 18:50:11 +0100537psa_status_t mbedtls_psa_cipher_decrypt(
538 const psa_key_attributes_t *attributes,
539 const uint8_t *key_buffer,
540 size_t key_buffer_size,
541 psa_algorithm_t alg,
542 const uint8_t *input,
543 size_t input_length,
544 uint8_t *output,
545 size_t output_size,
546 size_t *output_length )
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100547{
548 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
549 mbedtls_psa_cipher_operation_t operation = MBEDTLS_PSA_CIPHER_OPERATION_INIT;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200550 size_t olength, accumulated_length;
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100551
Ronald Cron0266cfe2021-03-13 18:50:11 +0100552 status = mbedtls_psa_cipher_decrypt_setup( &operation, attributes,
553 key_buffer, key_buffer_size,
554 alg );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100555 if( status != PSA_SUCCESS )
556 goto exit;
557
558 if( operation.iv_length > 0 )
559 {
Ronald Cron0266cfe2021-03-13 18:50:11 +0100560 status = mbedtls_psa_cipher_set_iv( &operation,
561 input, operation.iv_length );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100562 if( status != PSA_SUCCESS )
563 goto exit;
564 }
565
Ronald Cron0266cfe2021-03-13 18:50:11 +0100566 status = mbedtls_psa_cipher_update( &operation, input + operation.iv_length,
567 input_length - operation.iv_length,
568 output, output_size, &olength );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100569 if( status != PSA_SUCCESS )
570 goto exit;
571
gabor-mezei-arm6158e282021-06-29 16:42:13 +0200572 accumulated_length = olength;
gabor-mezei-arm258ae072021-06-25 15:25:38 +0200573
Ronald Cron0266cfe2021-03-13 18:50:11 +0100574 status = mbedtls_psa_cipher_finish( &operation, output + accumulated_length,
575 output_size - accumulated_length,
576 &olength );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100577 if( status != PSA_SUCCESS )
578 goto exit;
579
gabor-mezei-arm00e54f12021-06-29 19:06:30 +0200580 *output_length = accumulated_length + olength;
gabor-mezei-arme5ff8f42021-06-25 15:23:05 +0200581
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100582exit:
583 if ( status == PSA_SUCCESS )
Ronald Cron0266cfe2021-03-13 18:50:11 +0100584 status = mbedtls_psa_cipher_abort( &operation );
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100585 else
Ronald Cron0266cfe2021-03-13 18:50:11 +0100586 mbedtls_psa_cipher_abort( &operation );
587
gabor-mezei-arma9449a02021-03-25 11:17:10 +0100588 return( status );
589}
Ronald Cron5d9b00d2021-03-10 14:43:20 +0100590#endif /* MBEDTLS_PSA_BUILTIN_CIPHER */
Ronald Cron8287e6b2021-03-12 10:35:18 +0100591
Ronald Cron0ff57952021-03-08 16:46:35 +0100592#endif /* MBEDTLS_PSA_CRYPTO_C */