blob: b53ace00efdfca5526fa45fbbb0080d731570863 [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 */
53 err = tfm_crypto_operation_release(&(operation->handle));
54 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,
116 &(operation->handle));
Antonio de Angelis8908f472018-08-31 15:44:25 +0100117 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
118 return err;
119 }
120
Antonio de Angelis8908f472018-08-31 15:44:25 +0100121 /* Look up the corresponding operation context */
122 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000123 operation->handle,
124 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100125 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100126 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000127 (void)tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelis8908f472018-08-31 15:44:25 +0100128 return err;
129 }
130
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100131 /* Set the proper cipher mode (encrypt/decrypt) in the operation context */
132 ctx->cipher_mode = (uint8_t) c_mode;
133
Antonio de Angelis8908f472018-08-31 15:44:25 +0100134 /* Bind the algorithm to the cipher operation */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000135 ctx->alg = alg;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100136
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100137 /* Start the crypto engine */
138 status = tfm_crypto_engine_cipher_start(&(ctx->engine_ctx), &engine_info);
139 if (status != PSA_SUCCESS) {
Antonio de Angelis8908f472018-08-31 15:44:25 +0100140 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000141 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100142 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100143 }
144
Jamie Foxefd82732018-11-26 10:34:32 +0000145 /* Set the key usage based on the cipher mode */
146 usage = (c_mode == ENGINE_CIPHER_MODE_DECRYPT) ? PSA_KEY_USAGE_DECRYPT
147 : PSA_KEY_USAGE_ENCRYPT;
148
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100149 /* Access the crypto service key module to retrieve key data */
Jamie Foxefd82732018-11-26 10:34:32 +0000150 err = tfm_crypto_get_key(key,
151 usage,
152 alg,
153 key_data,
Jamie Fox82b87ca2018-12-11 16:41:11 +0000154 CRYPTO_CIPHER_MAX_KEY_LENGTH,
Jamie Foxefd82732018-11-26 10:34:32 +0000155 &key_size);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100156 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
157 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000158 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100159 return err;
160 }
161
162 /* Set the key on the engine */
163 status = tfm_crypto_engine_cipher_set_key(&(ctx->engine_ctx),
164 key_data,
165 key_size,
166 &engine_info);
167 if (status != PSA_SUCCESS) {
168 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000169 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100170 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
171 }
Antonio de Angelis8908f472018-08-31 15:44:25 +0100172
173 /* Bind the key to the cipher operation */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000174 ctx->key = key;
175 ctx->key_set = 1;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100176
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100177 /* Set padding mode on engine in case of CBC */
Antonio de Angelis8908f472018-08-31 15:44:25 +0100178 if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
179
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100180 status = tfm_crypto_engine_cipher_set_padding_mode(&(ctx->engine_ctx),
181 &engine_info);
182 if (status != PSA_SUCCESS) {
Antonio de Angelis8908f472018-08-31 15:44:25 +0100183 /* Release the operation context */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000184 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100185 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100186 }
187 }
188
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100189 /* FIXME: Check based on the algorithm, if we need to have an IV */
190 ctx->iv_required = 1;
191 ctx->block_size = PSA_BLOCK_CIPHER_BLOCK_SIZE(key_type);
192
Antonio de Angelis8908f472018-08-31 15:44:25 +0100193 return TFM_CRYPTO_ERR_PSA_SUCCESS;
194}
195
196/*!
197 * \defgroup public_psa Public functions, PSA
198 *
199 */
200
201/*!@{*/
Antonio de Angelis377a1552018-11-22 17:02:40 +0000202enum tfm_crypto_err_t tfm_crypto_cipher_set_iv(
203 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100204 const unsigned char *iv,
205 size_t iv_length)
206{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100207 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100208 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000209 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100210
211 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000212 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100213 sizeof(psa_cipher_operation_t),
214 TFM_MEMORY_ACCESS_RW);
215 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
216 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
217 }
218 err = tfm_crypto_memory_check((void *)iv, iv_length, TFM_MEMORY_ACCESS_RO);
219 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
220 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
221 }
222
223 /* Look up the corresponding operation context */
224 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000225 operation->handle,
226 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100227 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
228 return err;
229 }
230
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100231 if ((iv_length != ctx->block_size) || (iv_length > TFM_CIPHER_IV_MAX_SIZE)){
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000232 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100233 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100234 }
235
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100236 if ((ctx->iv_set == 1) || (ctx->iv_required == 0)) {
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 TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100239 }
240
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100241 /* Set the IV on the crypto engine */
242 status = tfm_crypto_engine_cipher_set_iv(&(ctx->engine_ctx),
243 iv,
244 iv_length);
245 if (status != PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000246 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100247 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100248 }
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100249
Antonio de Angelis377a1552018-11-22 17:02:40 +0000250 ctx->iv_set = 1;
251 ctx->iv_size = iv_length;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100252
Antonio de Angelis8908f472018-08-31 15:44:25 +0100253 return TFM_CRYPTO_ERR_PSA_SUCCESS;
254}
255
Antonio de Angelis377a1552018-11-22 17:02:40 +0000256enum tfm_crypto_err_t tfm_crypto_cipher_encrypt_setup(
257 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100258 psa_key_slot_t key,
259 psa_algorithm_t alg)
260{
Antonio de Angelis377a1552018-11-22 17:02:40 +0000261 return tfm_crypto_cipher_setup(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100262 key,
263 alg,
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100264 ENGINE_CIPHER_MODE_ENCRYPT);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100265}
266
Antonio de Angelis377a1552018-11-22 17:02:40 +0000267enum tfm_crypto_err_t tfm_crypto_cipher_decrypt_setup(
268 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100269 psa_key_slot_t key,
270 psa_algorithm_t alg)
271{
Antonio de Angelis377a1552018-11-22 17:02:40 +0000272 return tfm_crypto_cipher_setup(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100273 key,
274 alg,
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100275 ENGINE_CIPHER_MODE_DECRYPT);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100276}
277
278enum tfm_crypto_err_t tfm_crypto_cipher_update(
Antonio de Angelis377a1552018-11-22 17:02:40 +0000279 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100280 const uint8_t *input,
281 size_t input_length,
282 unsigned char *output,
283 size_t output_size,
284 size_t *output_length)
285{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100286 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100287 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000288 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100289
290 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000291 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100292 sizeof(psa_cipher_operation_t),
293 TFM_MEMORY_ACCESS_RW);
294 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
295 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
296 }
297 err = tfm_crypto_memory_check((void *)input,
298 input_length,
299 TFM_MEMORY_ACCESS_RO);
300 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
301 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
302 }
303 err = tfm_crypto_memory_check(output,
304 output_size,
305 TFM_MEMORY_ACCESS_RW);
306 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
307 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
308 }
309 err = tfm_crypto_memory_check(output_length,
310 sizeof(size_t),
311 TFM_MEMORY_ACCESS_RW);
312 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
313 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
314 }
315
Jamie Fox82b87ca2018-12-11 16:41:11 +0000316 /* Initialise the output length to zero */
317 *output_length = 0;
318
Antonio de Angelis8908f472018-08-31 15:44:25 +0100319 /* Look up the corresponding operation context */
320 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000321 operation->handle,
322 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100323 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
324 return err;
325 }
326
327 /* If the IV is required and it's not been set yet */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000328 if ((ctx->iv_required == 1) && (ctx->iv_set == 0)) {
Antonio de Angelis8908f472018-08-31 15:44:25 +0100329
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100330 if (ctx->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000331 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100332 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
333 }
334
335 /* This call is used to set the IV on the object */
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000336 return tfm_crypto_cipher_set_iv(operation, input, input_length);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100337 }
338
339 /* If the key is not set, setup phase has not been completed */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000340 if (ctx->key_set == 0) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000341 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100342 return TFM_CRYPTO_ERR_PSA_ERROR_BAD_STATE;
343 }
344
Jamie Fox82b87ca2018-12-11 16:41:11 +0000345 /* FIXME: The implementation currently expects to work only on blocks
346 * of input data whose length is equal to the block size
347 */
348 if (input_length > output_size) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000349 (void)tfm_crypto_cipher_release(operation, ctx);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000350 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
351 }
352
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100353 /* Update the cipher output with the input chunk on the engine */
354 status = tfm_crypto_engine_cipher_update(&(ctx->engine_ctx),
355 input,
356 input_length,
357 output,
358 (uint32_t *)output_length);
359 if (status != PSA_SUCCESS) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000360 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100361 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100362 }
363
Antonio de Angelis8908f472018-08-31 15:44:25 +0100364 return TFM_CRYPTO_ERR_PSA_SUCCESS;
365}
366
367enum tfm_crypto_err_t tfm_crypto_cipher_finish(
Antonio de Angelis377a1552018-11-22 17:02:40 +0000368 psa_cipher_operation_t *operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100369 uint8_t *output,
370 size_t output_size,
371 size_t *output_length)
372{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100373 psa_status_t status = PSA_SUCCESS;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100374 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000375 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100376
377 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000378 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100379 sizeof(psa_cipher_operation_t),
380 TFM_MEMORY_ACCESS_RW);
381 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
382 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
383 }
384 err = tfm_crypto_memory_check(output,
385 output_size,
386 TFM_MEMORY_ACCESS_RW);
387 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
388 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
389 }
390 err = tfm_crypto_memory_check(output_length,
391 sizeof(size_t),
392 TFM_MEMORY_ACCESS_RW);
393 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
394 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
395 }
396
Antonio de Angelis8908f472018-08-31 15:44:25 +0100397 /* Look up the corresponding operation context */
398 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000399 operation->handle,
400 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100401 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
402 return err;
403 }
404
Jamie Fox82b87ca2018-12-11 16:41:11 +0000405 /* Check that the output buffer is large enough for up to one block size of
406 * output data.
407 */
408 if (output_size < ctx->block_size) {
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000409 (void)tfm_crypto_cipher_release(operation, ctx);
Jamie Fox82b87ca2018-12-11 16:41:11 +0000410 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
411 }
412
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100413 /* Finalise the operation on the crypto engine */
414 status = tfm_crypto_engine_cipher_finish(&(ctx->engine_ctx),
415 output,
416 (uint32_t *)output_length);
417 if (status != PSA_SUCCESS) {
418 *output_length = 0;
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000419 (void)tfm_crypto_cipher_release(operation, ctx);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100420 return PSA_STATUS_TO_TFM_CRYPTO_ERR(status);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100421 }
422
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000423 return tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100424}
425
Antonio de Angelis377a1552018-11-22 17:02:40 +0000426enum tfm_crypto_err_t tfm_crypto_cipher_abort(psa_cipher_operation_t *operation)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100427{
428 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000429 struct tfm_cipher_operation_s *ctx = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100430
431 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000432 err = tfm_crypto_memory_check(operation,
Antonio de Angelis8908f472018-08-31 15:44:25 +0100433 sizeof(psa_cipher_operation_t),
434 TFM_MEMORY_ACCESS_RW);
435 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
436 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
437 }
438
439 /* Look up the corresponding operation context */
440 err = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000441 operation->handle,
442 (void **)&ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100443 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
444 return err;
445 }
446
Jamie Fox0ff04ba2019-02-05 14:19:07 +0000447 return tfm_crypto_cipher_release(operation, ctx);
Antonio de Angelis8908f472018-08-31 15:44:25 +0100448}
449/*!@}*/