blob: e49b14593d664f8258b95952a33eb75961ee1e84 [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
Jamie Fox0e54ebc2019-04-09 14:21:04 +01008#include <stddef.h>
9#include <stdint.h>
Antonio de Angelis8908f472018-08-31 15:44:25 +010010
Antonio de Angelis4743e672019-04-11 11:38:48 +010011/* FixMe: Use PSA_CONNECTION_REFUSED when performing parameter
12 * integrity checks but this will have to be revised
13 * when the full set of error codes mandated by PSA FF
14 * is available.
15 */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010016#include "tfm_mbedcrypto_include.h"
Antonio de Angelis4743e672019-04-11 11:38:48 +010017
Jamie Fox0e54ebc2019-04-09 14:21:04 +010018#include "tfm_crypto_api.h"
19#include "tfm_crypto_defs.h"
Antonio de Angelis8908f472018-08-31 15:44:25 +010020
21/*!
22 * \defgroup public_psa Public functions, PSA
23 *
24 */
25
26/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000027psa_status_t tfm_crypto_cipher_set_iv(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +010031{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010032 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010033 psa_cipher_operation_t *operation = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +010034
Antonio de Angelis4743e672019-04-11 11:38:48 +010035 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000036 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +010037 }
38
Antonio de Angelis4743e672019-04-11 11:38:48 +010039 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
Jamie Fox0e54ebc2019-04-09 14:21:04 +010040 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000041 return PSA_CONNECTION_REFUSED;
42 }
Antonio de Angelis4743e672019-04-11 11:38:48 +010043 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010044 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010045 uint32_t *handle_out = out_vec[0].base;
46 const unsigned char *iv = in_vec[1].base;
47 size_t iv_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000048
Antonio de Angelis4743e672019-04-11 11:38:48 +010049 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010050 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000051
Antonio de Angelis8908f472018-08-31 15:44:25 +010052 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000053 status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +010054 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +010055 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000056 if (status != PSA_SUCCESS) {
57 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +010058 }
59
Jamie Fox0e54ebc2019-04-09 14:21:04 +010060 status = psa_cipher_set_iv(operation, iv, iv_length);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010061 if (status != PSA_SUCCESS) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +010062 /* Release the operation context, ignore if the operation fails. */
63 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000064 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +010065 }
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010066
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000067 return status;
68}
Antonio de Angelis4743e672019-04-11 11:38:48 +010069
Jamie Fox0e54ebc2019-04-09 14:21:04 +010070/**
71 * TODO: psa_cipher_generate_iv(...)
72 *
73 */
74
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000075psa_status_t tfm_crypto_cipher_encrypt_setup(psa_invec in_vec[],
76 size_t in_len,
77 psa_outvec out_vec[],
78 size_t out_len)
79{
Antonio de Angelis4743e672019-04-11 11:38:48 +010080 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010081 psa_cipher_operation_t *operation = NULL;
82
Antonio de Angelis4743e672019-04-11 11:38:48 +010083 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000084 return PSA_CONNECTION_REFUSED;
85 }
86
Antonio de Angelis4743e672019-04-11 11:38:48 +010087 if ((out_vec[0].len != sizeof(uint32_t)) ||
88 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000089 return PSA_CONNECTION_REFUSED;
90 }
Antonio de Angelis4743e672019-04-11 11:38:48 +010091 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010092 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010093 uint32_t *handle_out = out_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010094 psa_key_handle_t key_handle = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010095 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000096
Jamie Fox0e54ebc2019-04-09 14:21:04 +010097 /* Allocate the operation context in the secure world */
98 status = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
99 &handle,
100 (void **)&operation);
101 if (status != PSA_SUCCESS) {
102 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100103 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100104
105 *handle_out = handle;
106
107 status = psa_cipher_encrypt_setup(operation, key_handle, alg);
108 if (status != PSA_SUCCESS) {
109 /* Release the operation context, ignore if the operation fails. */
110 (void)tfm_crypto_operation_release(handle_out);
111 return status;
112 }
113
Antonio de Angelis4743e672019-04-11 11:38:48 +0100114 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100115}
116
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000117psa_status_t tfm_crypto_cipher_decrypt_setup(psa_invec in_vec[],
118 size_t in_len,
119 psa_outvec out_vec[],
120 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100121{
Antonio de Angelis4743e672019-04-11 11:38:48 +0100122 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100123 psa_cipher_operation_t *operation = NULL;
124
Antonio de Angelis4743e672019-04-11 11:38:48 +0100125 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000126 return PSA_CONNECTION_REFUSED;
127 }
128
Antonio de Angelis4743e672019-04-11 11:38:48 +0100129 if ((out_vec[0].len != sizeof(uint32_t)) ||
130 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000131 return PSA_CONNECTION_REFUSED;
132 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100133 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100134 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100135 uint32_t *handle_out = out_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100136 psa_key_handle_t key_handle = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100137 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000138
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100139 /* Allocate the operation context in the secure world */
140 status = tfm_crypto_operation_alloc(TFM_CRYPTO_CIPHER_OPERATION,
141 &handle,
142 (void **)&operation);
143 if (status != PSA_SUCCESS) {
144 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100145 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100146
147 *handle_out = handle;
148
149 status = psa_cipher_decrypt_setup(operation, key_handle, alg);
150 if (status != PSA_SUCCESS) {
151 /* Release the operation context, ignore if the operation fails. */
152 (void)tfm_crypto_operation_release(handle_out);
153 return status;
154 }
155
Antonio de Angelis4743e672019-04-11 11:38:48 +0100156 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100157}
158
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000159psa_status_t tfm_crypto_cipher_update(psa_invec in_vec[],
160 size_t in_len,
161 psa_outvec out_vec[],
162 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100163{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100164 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100165 psa_cipher_operation_t *operation = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100166
Antonio de Angelis4743e672019-04-11 11:38:48 +0100167 if ((in_len != 2) || (out_len != 2)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000168 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100169 }
170
Antonio de Angelis4743e672019-04-11 11:38:48 +0100171 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
172 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000173 return PSA_CONNECTION_REFUSED;
174 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100175 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100176 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100177 uint32_t *handle_out = out_vec[0].base;
178 const uint8_t *input = in_vec[1].base;
179 size_t input_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000180 unsigned char *output = out_vec[1].base;
181 size_t output_size = out_vec[1].len;
182
Antonio de Angelis4743e672019-04-11 11:38:48 +0100183 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100184 *handle_out = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100185
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000186 /* Initialise the output_length to zero */
187 out_vec[1].len = 0;
Jamie Fox82b87ca2018-12-11 16:41:11 +0000188
Antonio de Angelis8908f472018-08-31 15:44:25 +0100189 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000190 status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100191 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100192 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000193 if (status != PSA_SUCCESS) {
194 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100195 }
196
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100197 status = psa_cipher_update(operation, input, input_length,
198 output, output_size, &out_vec[1].len);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100199 if (status != PSA_SUCCESS) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100200 /* Release the operation context, ignore if the operation fails. */
201 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000202 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100203 }
204
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100205 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100206}
207
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000208psa_status_t tfm_crypto_cipher_finish(psa_invec in_vec[],
209 size_t in_len,
210 psa_outvec out_vec[],
211 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100212{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100213 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100214 psa_cipher_operation_t *operation = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100215
Antonio de Angelis4743e672019-04-11 11:38:48 +0100216 if ((in_len != 1) || (out_len != 2)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000217 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100218 }
219
Antonio de Angelis4743e672019-04-11 11:38:48 +0100220 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
221 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000222 return PSA_CONNECTION_REFUSED;
223 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100224 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100225 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100226 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000227 unsigned char *output = out_vec[1].base;
228 size_t output_size = out_vec[1].len;
229
Antonio de Angelis4743e672019-04-11 11:38:48 +0100230 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100231 *handle_out = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100232
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000233 /* Initialise the output_length to zero */
234 out_vec[1].len = 0;
235
Antonio de Angelis8908f472018-08-31 15:44:25 +0100236 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000237 status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100238 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100239 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000240 if (status != PSA_SUCCESS) {
241 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100242 }
243
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100244 status = psa_cipher_finish(operation, output, output_size, &out_vec[1].len);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100245 if (status != PSA_SUCCESS) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100246 /* Release the operation context, ignore if the operation fails. */
247 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000248 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100249 }
250
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100251 status = tfm_crypto_operation_release(handle_out);
252
Antonio de Angelis4743e672019-04-11 11:38:48 +0100253 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100254}
255
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000256psa_status_t tfm_crypto_cipher_abort(psa_invec in_vec[],
257 size_t in_len,
258 psa_outvec out_vec[],
259 size_t out_len)
Antonio de Angelis8908f472018-08-31 15:44:25 +0100260{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000261 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100262 psa_cipher_operation_t *operation = NULL;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100263
Antonio de Angelis4743e672019-04-11 11:38:48 +0100264 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000265 return PSA_CONNECTION_REFUSED;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100266 }
267
Antonio de Angelis4743e672019-04-11 11:38:48 +0100268 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
269 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000270 return PSA_CONNECTION_REFUSED;
271 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100272 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100273 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100274 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000275
Antonio de Angelis4743e672019-04-11 11:38:48 +0100276 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100277 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000278
Antonio de Angelis8908f472018-08-31 15:44:25 +0100279 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000280 status = tfm_crypto_operation_lookup(TFM_CRYPTO_CIPHER_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100281 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100282 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000283 if (status != PSA_SUCCESS) {
284 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100285 }
286
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100287 status = psa_cipher_abort(operation);
288
289 if (status != PSA_SUCCESS) {
290 /* Release the operation context, ignore if the operation fails. */
291 (void)tfm_crypto_operation_release(handle_out);
292 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100293 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100294
295 status = tfm_crypto_operation_release(handle_out);
296
Antonio de Angelis4743e672019-04-11 11:38:48 +0100297 return status;
Antonio de Angelis8908f472018-08-31 15:44:25 +0100298}
299/*!@}*/