TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
crypto_cipher.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include "tfm_mbedcrypto_include.h"
12 
13 #include "tfm_crypto_api.h"
14 #include "tfm_crypto_defs.h"
15 #include "tfm_crypto_private.h"
16 
24  size_t in_len,
25  psa_outvec out_vec[],
26  size_t out_len)
27 {
28 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
30 #else
31  psa_status_t status = PSA_SUCCESS;
32  psa_cipher_operation_t *operation = NULL;
33 
34  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 2);
35 
36  if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
37  (out_vec[0].len != sizeof(uint32_t))) {
39  }
40 
41  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
42  uint32_t handle = iov->op_handle;
43  uint32_t *handle_out = out_vec[0].base;
44  unsigned char *iv = out_vec[1].base;
45  size_t iv_size = out_vec[1].len;
46 
47  /* Init the handle in the operation with the one passed from the iov */
48  *handle_out = iov->op_handle;
49 
50  /* Look up the corresponding operation context */
52  handle,
53  (void **)&operation);
54  if (status != PSA_SUCCESS) {
55  return status;
56  }
57 
58  *handle_out = handle;
59 
60  status = psa_cipher_generate_iv(operation, iv, iv_size, &out_vec[1].len);
61  if (status != PSA_SUCCESS) {
62  /* Release the operation context, ignore if the operation fails. */
63  (void)tfm_crypto_operation_release(handle_out);
64  return status;
65  }
66 
67  return status;
68 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
69 }
70 
72  size_t in_len,
73  psa_outvec out_vec[],
74  size_t out_len)
75 {
76 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
78 #else
79  psa_status_t status = PSA_SUCCESS;
80  psa_cipher_operation_t *operation = NULL;
81 
82  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 1, 1);
83 
84  if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
85  (out_vec[0].len != sizeof(uint32_t))) {
87  }
88  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
89  uint32_t handle = iov->op_handle;
90  uint32_t *handle_out = out_vec[0].base;
91  const unsigned char *iv = in_vec[1].base;
92  size_t iv_length = in_vec[1].len;
93 
94  /* Init the handle in the operation with the one passed from the iov */
95  *handle_out = iov->op_handle;
96 
97  /* Look up the corresponding operation context */
99  handle,
100  (void **)&operation);
101  if (status != PSA_SUCCESS) {
102  return status;
103  }
104 
105  status = psa_cipher_set_iv(operation, iv, iv_length);
106  if (status != PSA_SUCCESS) {
107  /* Release the operation context, ignore if the operation fails. */
108  (void)tfm_crypto_operation_release(handle_out);
109  return status;
110  }
111 
112  return status;
113 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
114 }
115 
117  size_t in_len,
118  psa_outvec out_vec[],
119  size_t out_len)
120 {
121 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
123 #else
124  psa_status_t status = PSA_SUCCESS;
125  psa_cipher_operation_t *operation = NULL;
126 
127  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
128 
129  if ((out_vec[0].len != sizeof(uint32_t)) ||
130  (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
132  }
133  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
134  uint32_t handle = iov->op_handle;
135  uint32_t *handle_out = out_vec[0].base;
137  psa_algorithm_t alg = iov->alg;
138 
139  status = tfm_crypto_check_handle_owner(key_handle, NULL);
140  if (status != PSA_SUCCESS) {
141  return status;
142  }
143 
144  /* Allocate the operation context in the secure world */
146  &handle,
147  (void **)&operation);
148  if (status != PSA_SUCCESS) {
149  return status;
150  }
151 
152  *handle_out = handle;
153 
154  status = psa_cipher_encrypt_setup(operation, key_handle, alg);
155  if (status != PSA_SUCCESS) {
156  /* Release the operation context, ignore if the operation fails. */
157  (void)tfm_crypto_operation_release(handle_out);
158  return status;
159  }
160 
161  return status;
162 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
163 }
164 
166  size_t in_len,
167  psa_outvec out_vec[],
168  size_t out_len)
169 {
170 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
172 #else
173  psa_status_t status = PSA_SUCCESS;
174  psa_cipher_operation_t *operation = NULL;
175 
176  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
177 
178  if ((out_vec[0].len != sizeof(uint32_t)) ||
179  (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
181  }
182  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
183  uint32_t handle = iov->op_handle;
184  uint32_t *handle_out = out_vec[0].base;
186  psa_algorithm_t alg = iov->alg;
187 
188  status = tfm_crypto_check_handle_owner(key_handle, NULL);
189  if (status != PSA_SUCCESS) {
190  return status;
191  }
192 
193  /* Allocate the operation context in the secure world */
195  &handle,
196  (void **)&operation);
197  if (status != PSA_SUCCESS) {
198  return status;
199  }
200 
201  *handle_out = handle;
202 
203  status = psa_cipher_decrypt_setup(operation, key_handle, alg);
204  if (status != PSA_SUCCESS) {
205  /* Release the operation context, ignore if the operation fails. */
206  (void)tfm_crypto_operation_release(handle_out);
207  return status;
208  }
209 
210  return status;
211 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
212 }
213 
215  size_t in_len,
216  psa_outvec out_vec[],
217  size_t out_len)
218 {
219 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
221 #else
222  psa_status_t status = PSA_SUCCESS;
223  psa_cipher_operation_t *operation = NULL;
224 
225  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 2, out_len, 1, 2);
226 
227  if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
228  (out_vec[0].len != sizeof(uint32_t))) {
230  }
231 
232  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
233  uint32_t handle = iov->op_handle;
234  uint32_t *handle_out = out_vec[0].base;
235  const uint8_t *input = in_vec[1].base;
236  size_t input_length = in_vec[1].len;
237  unsigned char *output = out_vec[1].base;
238  size_t output_size = out_vec[1].len;
239 
240  /* Init the handle in the operation with the one passed from the iov */
241  *handle_out = iov->op_handle;
242 
243  /* Initialise the output_length to zero */
244  out_vec[1].len = 0;
245 
246  /* Look up the corresponding operation context */
248  handle,
249  (void **)&operation);
250  if (status != PSA_SUCCESS) {
251  return status;
252  }
253 
254  status = psa_cipher_update(operation, input, input_length,
255  output, output_size, &out_vec[1].len);
256  if (status != PSA_SUCCESS) {
257  /* Release the operation context, ignore if the operation fails. */
258  (void)tfm_crypto_operation_release(handle_out);
259  return status;
260  }
261 
262  return status;
263 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
264 }
265 
267  size_t in_len,
268  psa_outvec out_vec[],
269  size_t out_len)
270 {
271 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
273 #else
274  psa_status_t status = PSA_SUCCESS;
275  psa_cipher_operation_t *operation = NULL;
276 
277  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 2);
278 
279  if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
280  (out_vec[0].len != sizeof(uint32_t))) {
282  }
283  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
284  uint32_t handle = iov->op_handle;
285  uint32_t *handle_out = out_vec[0].base;
286  unsigned char *output = out_vec[1].base;
287  size_t output_size = out_vec[1].len;
288 
289  /* Init the handle in the operation with the one passed from the iov */
290  *handle_out = iov->op_handle;
291 
292  /* Initialise the output_length to zero */
293  out_vec[1].len = 0;
294 
295  /* Look up the corresponding operation context */
297  handle,
298  (void **)&operation);
299  if (status != PSA_SUCCESS) {
300  return status;
301  }
302 
303  status = psa_cipher_finish(operation, output, output_size, &out_vec[1].len);
304  if (status != PSA_SUCCESS) {
305  /* Release the operation context, ignore if the operation fails. */
306  (void)tfm_crypto_operation_release(handle_out);
307  return status;
308  }
309 
310  status = tfm_crypto_operation_release(handle_out);
311 
312  return status;
313 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
314 }
315 
317  size_t in_len,
318  psa_outvec out_vec[],
319  size_t out_len)
320 {
321 #ifdef TFM_CRYPTO_CIPHER_MODULE_DISABLED
323 #else
324  psa_status_t status = PSA_SUCCESS;
325  psa_cipher_operation_t *operation = NULL;
326 
327  CRYPTO_IN_OUT_LEN_VALIDATE(in_len, 1, 1, out_len, 1, 1);
328 
329  if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
330  (out_vec[0].len != sizeof(uint32_t))) {
332  }
333  const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
334  uint32_t handle = iov->op_handle;
335  uint32_t *handle_out = out_vec[0].base;
336 
337  /* Init the handle in the operation with the one passed from the iov */
338  *handle_out = iov->op_handle;
339 
340  /* Look up the corresponding operation context */
342  handle,
343  (void **)&operation);
344  if (status != PSA_SUCCESS) {
345  /* Operation does not exist, so abort has no effect */
346  return PSA_SUCCESS;
347  }
348 
349  status = psa_cipher_abort(operation);
350 
351  if (status != PSA_SUCCESS) {
352  /* Release the operation context, ignore if the operation fails. */
353  (void)tfm_crypto_operation_release(handle_out);
354  return status;
355  }
356 
357  status = tfm_crypto_operation_release(handle_out);
358 
359  return status;
360 #endif /* TFM_CRYPTO_CIPHER_MODULE_DISABLED */
361 }
362 
364  size_t in_len,
365  psa_outvec out_vec[],
366  size_t out_len)
367 {
368  /* FixMe: To be implemented */
370 }
371 
373  size_t in_len,
374  psa_outvec out_vec[],
375  size_t out_len)
376 {
377  /* FixMe: To be implemented */
379 }
psa_key_handle_t key_handle
psa_status_t tfm_crypto_check_handle_owner(psa_key_handle_t handle, uint32_t *index)
Checks that the requested handle belongs to the requesting partition.
Definition: crypto_key.c:86
Structure used to pack non-pointer types in a call.
psa_status_t tfm_crypto_cipher_decrypt_setup(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
void * base
Definition: client.h:75
psa_status_t tfm_crypto_cipher_update(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
#define psa_cipher_finish
Definition: crypto_spe.h:83
#define PSA_SUCCESS
Definition: crypto_values.h:35
psa_status_t tfm_crypto_operation_alloc(enum tfm_crypto_operation_type type, uint32_t *handle, void **ctx)
Allocate an operation context in the backend.
Definition: crypto_alloc.c:94
psa_status_t tfm_crypto_cipher_abort(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
size_t len
Definition: client.h:68
#define psa_cipher_set_iv
Definition: crypto_spe.h:75
psa_status_t tfm_crypto_cipher_finish(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
psa_algorithm_t alg
psa_status_t tfm_crypto_cipher_decrypt(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
psa_status_t tfm_crypto_operation_release(uint32_t *handle)
Release an operation context in the backend.
Definition: crypto_alloc.c:132
#define psa_cipher_encrypt_setup
Definition: crypto_spe.h:77
psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
uint32_t psa_algorithm_t
Encoding of a cryptographic algorithm.
Definition: crypto_types.h:90
#define psa_cipher_update
Definition: crypto_spe.h:81
#define CRYPTO_IN_OUT_LEN_VALIDATE(in_len, in_min, in_max, out_len, out_min, out_max)
psa_status_t tfm_crypto_cipher_encrypt(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
#define PSA_ERROR_PROGRAMMER_ERROR
Definition: error.h:32
_unsigned_integral_type_ psa_key_handle_t
Key handle.
Definition: crypto.h:35
#define PSA_ERROR_NOT_SUPPORTED
Definition: crypto_values.h:52
size_t len
Definition: client.h:76
#define psa_cipher_decrypt_setup
Definition: crypto_spe.h:79
psa_status_t tfm_crypto_cipher_generate_iv(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
Definition: crypto_cipher.c:23
#define psa_cipher_generate_iv
Definition: crypto_spe.h:73
psa_status_t tfm_crypto_cipher_set_iv(psa_invec in_vec[], size_t in_len, psa_outvec out_vec[], size_t out_len)
Definition: crypto_cipher.c:71
#define psa_cipher_abort
Definition: crypto_spe.h:85
const void * base
Definition: client.h:67
psa_status_t tfm_crypto_operation_lookup(enum tfm_crypto_operation_type type, uint32_t handle, void **ctx)
Look up an operation context in the backend for the corresponding frontend operation.
Definition: crypto_alloc.c:159
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43