blob: 9f6ae9d6ac5340fc0688c6c6f07a70b6c3c63ce3 [file] [log] [blame]
Antonio de Angelis8908f472018-08-31 15:44:25 +01001/*
Antonio de Angelis377a1552018-11-22 17:02:40 +00002 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
Antonio de Angelis8908f472018-08-31 15:44:25 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include <limits.h>
9
10#include "tfm_crypto_defs.h"
11
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010012#include "crypto_engine.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010013
14#include "psa_crypto.h"
15
Antonio de Angelis377a1552018-11-22 17:02:40 +000016#include "tfm_crypto_struct.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010017
18#include "tfm_crypto_api.h"
19#include "crypto_utils.h"
20
Jamie Fox82b87ca2018-12-11 16:41:11 +000021/**
22 * \def CRYPTO_CIPHER_MAX_KEY_LENGTH
23 *
24 * \brief Specifies the maximum key length supported by the
25 * Cipher operations in this implementation
26 */
27#ifndef CRYPTO_CIPHER_MAX_KEY_LENGTH
28#define CRYPTO_CIPHER_MAX_KEY_LENGTH (32)
29#endif
30
Jamie Fox0ff04ba2019-02-05 14:19:07 +000031/**
32 * \brief Release all resources associated with a cipher operation.
33 *
34 * \param[in] operation Frontend cipher operation context
35 * \param[in] ctx Backend cipher operation context
36 *
37 * \return Return values as described in \ref tfm_crypto_err_t
38 */
39static enum tfm_crypto_err_t tfm_crypto_cipher_release(
40 psa_cipher_operation_t *operation,
41 struct tfm_cipher_operation_s *ctx)
42{
43 psa_status_t status;
44 enum tfm_crypto_err_t err;
45
46 /* Release resources in the engine */
47 status = tfm_crypto_engine_cipher_release(&(ctx->engine_ctx));
48 if (status != PSA_SUCCESS) {
49 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
50 }
51
52 /* Release the operation context */
Antonio de Angelis819c2f32019-02-06 14:32:02 +000053 err = tfm_crypto_operation_release(TFM_CRYPTO_CIPHER_OPERATION, operation);
Jamie Fox0ff04ba2019-02-05 14:19:07 +000054 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
55 return err;
56 }
57
58 return TFM_CRYPTO_ERR_PSA_SUCCESS;
59}
60
Antonio de Angelis8908f472018-08-31 15:44:25 +010061static enum tfm_crypto_err_t tfm_crypto_cipher_setup(
Antonio de Angelis377a1552018-11-22 17:02:40 +000062 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +010063 psa_key_slot_t key,
64 psa_algorithm_t alg,
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010065 enum engine_cipher_mode_t c_mode)
Antonio de Angelis8908f472018-08-31 15:44:25 +010066{
Jamie Fox82b87ca2018-12-11 16:41:11 +000067 uint8_t key_data[CRYPTO_CIPHER_MAX_KEY_LENGTH];
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010068 size_t key_size;
69 psa_key_type_t key_type = PSA_KEY_TYPE_NONE;
70 psa_status_t status = PSA_SUCCESS;
71 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +000072 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010073 struct cipher_engine_info engine_info;
Jamie Foxefd82732018-11-26 10:34:32 +000074 psa_key_usage_t usage;
Antonio de Angelis8908f472018-08-31 15:44:25 +010075
76 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +000077 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +010078 sizeof(psa_cipher_operation_t),
79 TFM_MEMORY_ACCESS_RW);
80 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
81 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
82 }
83
84 if (!PSA_ALG_IS_CIPHER(alg)) {
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010085 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +010086 }
87
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010088 /* Access the key module to retrieve key related information */
Antonio de Angelis8908f472018-08-31 15:44:25 +010089 err = tfm_crypto_get_key_information(key, &key_type, &key_size);
90 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Jamie Fox82b87ca2018-12-11 16:41:11 +000091 return err;
92 }
93
94 /* Check if it's a raw data key type */
95 if (key_type == PSA_KEY_TYPE_RAW_DATA) {
96 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_PERMITTED;
97 }
98
99 /* Check compatibility between key and algorithm */
100 if ((key_type == PSA_KEY_TYPE_ARC4) && (alg != PSA_ALG_ARC4)) {
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100101 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100102 }
103
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100104 /* Setup the algorithm on the crypto engine */
105 status = tfm_crypto_engine_cipher_setup(alg,
106 (const psa_key_type_t)key_type,
107 (const uint32_t)key_size,
108 c_mode,
109 &engine_info);
110 if (status != PSA_SUCCESS) {
111 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100112 }
113
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100114 /* Allocate the operation context in the secure world */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000115 err = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000116 operation,
117 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100118 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
119 return err;
120 }
121
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100122 /* Set the proper cipher mode (encrypt/decrypt) in the operation context */
123 ctx->cipher_mode = (uint8_t) c_mode;
124
Antonio de Angelis8908f472018-08-31 15:44:25 +0100125 /* Bind the algorithm to the cipher operation */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000126 ctx->alg = alg;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100127
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100128 /* Start the crypto engine */
129 status = tfm_crypto_engine_cipher_start(&(ctx->engine_ctx), &engine_info);
130 if (status != PSA_SUCCESS) {
Hugues de Valon8b442442019-02-19 14:30:52 +0000131 /* Release the operation context, ignore if this operation fails. */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000132 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100133 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100134 }
135
Jamie Foxefd82732018-11-26 10:34:32 +0000136 /* Set the key usage based on the cipher mode */
137 usage = (c_mode == ENGINE_CIPHER_MODE_DECRYPT) ? PSA_KEY_USAGE_DECRYPT
138 : PSA_KEY_USAGE_ENCRYPT;
139
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100140 /* Access the crypto service key module to retrieve key data */
Jamie Foxefd82732018-11-26 10:34:32 +0000141 err = tfm_crypto_get_key(key,
142 usage,
143 alg,
144 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000145 CRYPTO_CIPHER_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000146 &key_size);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100147 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Hugues de Valon8b442442019-02-19 14:30:52 +0000148 /* Release the operation context, ignore if this operation fails. */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000149 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100150 return err;
151 }
152
153 /* Set the key on the engine */
154 status = tfm_crypto_engine_cipher_set_key(&(ctx->engine_ctx),
155 key_data,
156 key_size,
157 &engine_info);
158 if (status != PSA_SUCCESS) {
Hugues de Valon8b442442019-02-19 14:30:52 +0000159 /* Release the operation context, ignore if this operation fails. */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000160 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100161 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
162 }
Antonio de Angelis8908f472018-08-31 15:44:25 +0100163
164 /* Bind the key to the cipher operation */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000165 ctx->key = key;
166 ctx->key_set = 1;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100167
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100168 /* Set padding mode on engine in case of CBC */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100169 if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
170
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100171 status = tfm_crypto_engine_cipher_set_padding_mode(&(ctx->engine_ctx),
172 &engine_info);
173 if (status != PSA_SUCCESS) {
Hugues de Valon8b442442019-02-19 14:30:52 +0000174 /* Release the operation context, ignore if this operation fails. */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000175 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100176 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100177 }
178 }
179
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100180 /* FIXME: Check based on the algorithm, if we need to have an IV */
181 ctx->iv_required = 1;
182 ctx->block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type);
183
Antonio de Angelis8908f472018-08-31 15:44:25 +0100184 return TFM_CRYPTO_ERR_PSA_SUCCESS;
185}
186
187/*!
188 * \defgroup public_psa Public functions, PSA
189 *
190 */
191
192/*!@{*/
Antonio de Angelis377a1552018-11-22 17:02:40 +0000193enum tfm_crypto_err_t tfm_crypto_cipher_set_iv(
194 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100195 const unsigned char *iv,
196 size_t iv_length)
197{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100198 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100199 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000200 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100201
202 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000203 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100204 sizeof(psa_cipher_operation_t),
205 TFM_MEMORY_ACCESS_RW);
206 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
207 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
208 }
209 err = tfm_crypto_memory_check((void *)iv, iv_length, TFM_MEMORY_ACCESS_RO);
210 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
211 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
212 }
213
214 /* Look up the corresponding operation context */
215 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000216 operation,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000217 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100218 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
219 return err;
220 }
221
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100222 if ((iv_length != ctx->block_size) || (iv_length > TFM_CIPHER_IV_MAX_SIZE)){
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000223 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100224 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100225 }
226
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100227 if ((ctx->iv_set == 1) || (ctx->iv_required == 0)) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000228 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100229 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100230 }
231
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100232 /* Set the IV on the crypto engine */
233 status = tfm_crypto_engine_cipher_set_iv(&(ctx->engine_ctx),
234 iv,
235 iv_length);
236 if (status != PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000237 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100238 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100239 }
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100240
Antonio de Angelis377a1552018-11-22 17:02:40 +0000241 ctx->iv_set = 1;
242 ctx->iv_size = iv_length;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100243
Antonio de Angelis8908f472018-08-31 15:44:25 +0100244 return TFM_CRYPTO_ERR_PSA_SUCCESS;
245}
246
Antonio de Angelis377a1552018-11-22 17:02:40 +0000247enum tfm_crypto_err_t tfm_crypto_cipher_encrypt_setup(
248 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100249 psa_key_slot_t key,
250 psa_algorithm_t alg)
251{
Antonio de Angelis377a1552018-11-22 17:02:40 +0000252 return tfm_crypto_cipher_setup(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100253 key,
254 alg,
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100255 ENGINE_CIPHER_MODE_ENCRYPT);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100256}
257
Antonio de Angelis377a1552018-11-22 17:02:40 +0000258enum tfm_crypto_err_t tfm_crypto_cipher_decrypt_setup(
259 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100260 psa_key_slot_t key,
261 psa_algorithm_t alg)
262{
Antonio de Angelis377a1552018-11-22 17:02:40 +0000263 return tfm_crypto_cipher_setup(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100264 key,
265 alg,
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100266 ENGINE_CIPHER_MODE_DECRYPT);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100267}
268
269enum tfm_crypto_err_t tfm_crypto_cipher_update(
Antonio de Angelis377a1552018-11-22 17:02:40 +0000270 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100271 const uint8_t *input,
272 size_t input_length,
273 unsigned char *output,
274 size_t output_size,
275 size_t *output_length)
276{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100277 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100278 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000279 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100280
281 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000282 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100283 sizeof(psa_cipher_operation_t),
284 TFM_MEMORY_ACCESS_RW);
285 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
286 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
287 }
288 err = tfm_crypto_memory_check((void *)input,
289 input_length,
290 TFM_MEMORY_ACCESS_RO);
291 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
292 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
293 }
294 err = tfm_crypto_memory_check(output,
295 output_size,
296 TFM_MEMORY_ACCESS_RW);
297 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
298 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
299 }
300 err = tfm_crypto_memory_check(output_length,
301 sizeof(size_t),
302 TFM_MEMORY_ACCESS_RW);
303 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
304 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
305 }
306
Jamie Fox82b87ca2018-12-11 16:41:11 +0000307 /* Initialise the output length to zero */
308 *output_length = 0;
309
Antonio de Angelis8908f472018-08-31 15:44:25 +0100310 /* Look up the corresponding operation context */
311 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000312 operation,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000313 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100314 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
315 return err;
316 }
317
318 /* If the IV is required and it's not been set yet */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000319 if ((ctx->iv_required == 1) && (ctx->iv_set == 0)) {
Antonio de Angelis8908f472018-08-31 15:44:25 +0100320
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100321 if (ctx->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000322 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100323 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
324 }
325
326 /* This call is used to set the IV on the object */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000327 return tfm_crypto_cipher_set_iv(operation, input, input_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100328 }
329
330 /* If the key is not set, setup phase has not been completed */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000331 if (ctx->key_set == 0) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000332 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100333 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
334 }
335
Jamie Fox82b87ca2018-12-11 16:41:11 +0000336 /* FIXME: The implementation currently expects to work only on blocks
337 * of input data whose length is equal to the block size
338 */
339 if (input_length > output_size) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000340 (void)tfm_crypto_cipher_release(operation, ctx);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000341 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
342 }
343
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100344 /* Update the cipher output with the input chunk on the engine */
345 status = tfm_crypto_engine_cipher_update(&(ctx->engine_ctx),
346 input,
347 input_length,
348 output,
349 (uint32_t *)output_length);
350 if (status != PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000351 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100352 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100353 }
354
Antonio de Angelis8908f472018-08-31 15:44:25 +0100355 return TFM_CRYPTO_ERR_PSA_SUCCESS;
356}
357
358enum tfm_crypto_err_t tfm_crypto_cipher_finish(
Antonio de Angelis377a1552018-11-22 17:02:40 +0000359 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100360 uint8_t *output,
361 size_t output_size,
362 size_t *output_length)
363{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100364 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100365 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000366 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100367
368 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000369 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100370 sizeof(psa_cipher_operation_t),
371 TFM_MEMORY_ACCESS_RW);
372 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
373 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
374 }
375 err = tfm_crypto_memory_check(output,
376 output_size,
377 TFM_MEMORY_ACCESS_RW);
378 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
379 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
380 }
381 err = tfm_crypto_memory_check(output_length,
382 sizeof(size_t),
383 TFM_MEMORY_ACCESS_RW);
384 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
385 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
386 }
387
Antonio de Angelis8908f472018-08-31 15:44:25 +0100388 /* Look up the corresponding operation context */
389 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000390 operation,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000391 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100392 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
393 return err;
394 }
395
Jamie Fox82b87ca2018-12-11 16:41:11 +0000396 /* Check that the output buffer is large enough for up to one block size of
397 * output data.
398 */
399 if (output_size < ctx->block_size) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000400 (void)tfm_crypto_cipher_release(operation, ctx);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000401 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
402 }
403
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100404 /* Finalise the operation on the crypto engine */
405 status = tfm_crypto_engine_cipher_finish(&(ctx->engine_ctx),
406 output,
407 (uint32_t *)output_length);
408 if (status != PSA_SUCCESS) {
409 *output_length = 0;
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000410 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100411 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100412 }
413
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000414 return tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100415}
416
Antonio de Angelis377a1552018-11-22 17:02:40 +0000417enum tfm_crypto_err_t tfm_crypto_cipher_abort(psa_cipher_operation_t *operation)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100418{
419 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000420 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100421
422 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000423 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100424 sizeof(psa_cipher_operation_t),
425 TFM_MEMORY_ACCESS_RW);
426 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
427 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
428 }
429
430 /* Look up the corresponding operation context */
431 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis819c2f32019-02-06 14:32:02 +0000432 operation,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000433 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100434 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
435 return err;
436 }
437
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000438 return tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100439}
440/*!@}*/