blob: 911227d763e77da891c5c177e77be90acc78f274 [file] [log] [blame]
Antonio de Angelisa6f72162018-09-05 11:00:37 +01001/*
Antonio de Angelis377a1552018-11-22 17:02:40 +00002 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
Antonio de Angelisa6f72162018-09-05 11:00:37 +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 Angelisa6f72162018-09-05 11:00:37 +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"
Jamie Fox0ff04ba2019-02-05 14:19:07 +000020
Antonio de Angelisa6f72162018-09-05 11:00:37 +010021/*!
22 * \defgroup public_psa Public functions, PSA
23 *
24 */
25
26/*!@{*/
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000027psa_status_t tfm_crypto_hash_setup(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
Antonio de Angelisa6f72162018-09-05 11:00:37 +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_hash_operation_t *operation = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010034
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000035 if ((in_len != 1) || (out_len != 1)) {
36 return PSA_CONNECTION_REFUSED;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010037 }
38
Antonio de Angelis4743e672019-04-11 11:38:48 +010039 if ((out_vec[0].len != sizeof(uint32_t)) ||
40 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
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 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000047
Antonio de Angelis4743e672019-04-11 11:38:48 +010048 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010049 *handle_out = iov->op_handle;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010050
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010051 /* Allocate the operation context in the secure world */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000052 status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +010053 &handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +010054 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000055 if (status != PSA_SUCCESS) {
56 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010057 }
58
Antonio de Angelis4743e672019-04-11 11:38:48 +010059 *handle_out = handle;
60
Jamie Fox0e54ebc2019-04-09 14:21:04 +010061 status = psa_hash_setup(operation, alg);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010062 if (status != PSA_SUCCESS) {
Hugues de Valon8b442442019-02-19 14:30:52 +000063 /* Release the operation context, ignore if the operation fails. */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010064 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000065 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010066 }
67
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000068 return PSA_SUCCESS;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010069}
70
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000071psa_status_t tfm_crypto_hash_update(psa_invec in_vec[],
72 size_t in_len,
73 psa_outvec out_vec[],
74 size_t out_len)
Antonio de Angelisa6f72162018-09-05 11:00:37 +010075{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +010076 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010077 psa_hash_operation_t *operation = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010078
Antonio de Angelis4743e672019-04-11 11:38:48 +010079 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000080 return PSA_CONNECTION_REFUSED;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010081 }
82
Antonio de Angelis4743e672019-04-11 11:38:48 +010083 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
84 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000085 return PSA_CONNECTION_REFUSED;
86 }
Antonio de Angelis4743e672019-04-11 11:38:48 +010087 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010088 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010089 uint32_t *handle_out = out_vec[0].base;
90 const uint8_t *input = in_vec[1].base;
91 size_t input_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000092
Antonio de Angelis4743e672019-04-11 11:38:48 +010093 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +010094 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000095
Antonio de Angelisa6f72162018-09-05 11:00:37 +010096 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000097 status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +010098 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +010099 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000100 if (status != PSA_SUCCESS) {
101 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100102 }
103
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100104 status = psa_hash_update(operation, input, input_length);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100105 if (status != PSA_SUCCESS) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100106 /* Release the operation context, ignore if the operation fails. */
107 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000108 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100109 }
110
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000111 return PSA_SUCCESS;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100112}
113
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000114psa_status_t tfm_crypto_hash_finish(psa_invec in_vec[],
115 size_t in_len,
116 psa_outvec out_vec[],
117 size_t out_len)
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100118{
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100119 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100120 psa_hash_operation_t *operation = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100121
Antonio de Angelis4743e672019-04-11 11:38:48 +0100122 if ((in_len != 1) || (out_len != 2)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000123 return PSA_CONNECTION_REFUSED;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100124 }
125
Antonio de Angelis4743e672019-04-11 11:38:48 +0100126 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
127 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000128 return PSA_CONNECTION_REFUSED;
129 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100130 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100131 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100132 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000133 uint8_t *hash = out_vec[1].base;
134 size_t hash_size = out_vec[1].len;
135
Antonio de Angelis4743e672019-04-11 11:38:48 +0100136 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100137 *handle_out = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100138
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000139 /* Initialise hash_length to zero */
140 out_vec[1].len = 0;
141
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100142 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000143 status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100144 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100145 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000146 if (status != PSA_SUCCESS) {
147 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100148 }
149
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100150 status = psa_hash_finish(operation, hash, hash_size, &out_vec[1].len);
Antonio de Angeliscf85ba22018-10-09 13:29:40 +0100151 if (status != PSA_SUCCESS) {
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100152 /* Release the operation context, ignore if the operation fails. */
153 (void)tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000154 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100155 }
156
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100157 status = tfm_crypto_operation_release(handle_out);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000158
159 return status;
160}
161
162psa_status_t tfm_crypto_hash_verify(psa_invec in_vec[],
163 size_t in_len,
164 psa_outvec out_vec[],
165 size_t out_len)
166{
167 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100168 psa_hash_operation_t *operation = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100169
Antonio de Angelis4743e672019-04-11 11:38:48 +0100170 if ((in_len != 2) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000171 return PSA_CONNECTION_REFUSED;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100172 }
173
Antonio de Angelis4743e672019-04-11 11:38:48 +0100174 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
175 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000176 return PSA_CONNECTION_REFUSED;
177 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100178 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
179 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100180 uint32_t *handle_out = out_vec[0].base;
181 const uint8_t *hash = in_vec[1].base;
182 size_t hash_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000183
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100184 /* Init the handle in the operation with the one passed from the iov */
185 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000186
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100187 /* Look up the corresponding operation context */
188 status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
189 handle,
190 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000191 if (status != PSA_SUCCESS) {
192 return status;
193 }
194
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100195 status = psa_hash_verify(operation, hash, hash_length);
196 if (status != PSA_SUCCESS) {
197 /* Release the operation context, ignore if the operation fails. */
198 (void)tfm_crypto_operation_release(handle_out);
199 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100200 }
201
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100202 status = tfm_crypto_operation_release(handle_out);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100203
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100204 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100205}
206
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000207psa_status_t tfm_crypto_hash_abort(psa_invec in_vec[],
208 size_t in_len,
209 psa_outvec out_vec[],
210 size_t out_len)
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100211{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000212 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100213 psa_hash_operation_t *operation = NULL;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000214
Antonio de Angelis4743e672019-04-11 11:38:48 +0100215 if ((in_len != 1) || (out_len != 1)) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000216 return PSA_CONNECTION_REFUSED;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000217 }
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100218
Antonio de Angelis4743e672019-04-11 11:38:48 +0100219 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
220 (out_vec[0].len != sizeof(uint32_t))) {
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000221 return PSA_CONNECTION_REFUSED;
222 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100223 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100224 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100225 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000226
Antonio de Angelis4743e672019-04-11 11:38:48 +0100227 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100228 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000229
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100230 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000231 status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100232 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100233 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000234 if (status != PSA_SUCCESS) {
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100235 /* Operation does not exist, so abort has no effect */
236 return PSA_SUCCESS;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100237 }
238
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100239 status = psa_hash_abort(operation);
240 if (status != PSA_SUCCESS) {
241 /* Release the operation context, ignore if the operation fails. */
242 (void)tfm_crypto_operation_release(handle_out);
243 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100244 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100245
246 status = tfm_crypto_operation_release(handle_out);
247
Antonio de Angelis4743e672019-04-11 11:38:48 +0100248 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100249}
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100250
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100251psa_status_t tfm_crypto_hash_clone(psa_invec in_vec[],
252 size_t in_len,
253 psa_outvec out_vec[],
254 size_t out_len)
255{
256 psa_status_t status = PSA_SUCCESS;
257 psa_hash_operation_t *source_operation = NULL;
258 psa_hash_operation_t *target_operation = NULL;
259
260 if ((in_len != 1) || (out_len != 1)) {
261 return PSA_CONNECTION_REFUSED;
262 }
263
264 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
265 (out_vec[0].len != sizeof(uint32_t))) {
266 return PSA_CONNECTION_REFUSED;
267 }
268 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
269 uint32_t source_handle = iov->op_handle;
270 uint32_t *target_handle = out_vec[0].base;
271
272 /* Look up the corresponding source operation context */
273 status = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
274 source_handle,
275 (void **)&source_operation);
276 if (status != PSA_SUCCESS) {
277 return status;
278 }
279
280 /* Allocate the target operation context in the secure world */
281 status = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
282 target_handle,
283 (void **)&target_operation);
284 if (status != PSA_SUCCESS) {
285 return status;
286 }
287
288 status = psa_hash_clone(source_operation, target_operation);
289 if (status != PSA_SUCCESS) {
290 /* Release the target operation context, ignore if it fails. */
291 (void)tfm_crypto_operation_release(target_handle);
292 return status;
293 }
294
295 return status;
296}
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100297/*!@}*/