blob: 6468f0f20328d0936de550a230e9c2660ba933aa [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) {
235 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100236 }
237
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100238 status = psa_hash_abort(operation);
239 if (status != PSA_SUCCESS) {
240 /* Release the operation context, ignore if the operation fails. */
241 (void)tfm_crypto_operation_release(handle_out);
242 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100243 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100244
245 status = tfm_crypto_operation_release(handle_out);
246
Antonio de Angelis4743e672019-04-11 11:38:48 +0100247 return status;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100248}
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100249
250/**
251 * TODO: psa_hash_clone(...)
252 *
253 */
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100254/*!@}*/