blob: 16e996f7614954c055f82d28990d6264b5d01e0e [file] [log] [blame]
Louis Mayencourt7a36f782018-09-24 14:00:57 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
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>
Louis Mayencourt7a36f782018-09-24 14:00:57 +010010
Summer Qin4b1d03b2019-07-02 14:56:08 +080011/* FixMe: Use PSA_ERROR_CONNECTION_REFUSED when performing parameter
Antonio de Angelis4743e672019-04-11 11:38:48 +010012 * 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"
Louis Mayencourt7a36f782018-09-24 14:00:57 +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_mac_sign_setup(psa_invec in_vec[],
28 size_t in_len,
29 psa_outvec out_vec[],
30 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +010031{
Antonio de Angelis4743e672019-04-11 11:38:48 +010032 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010033 psa_mac_operation_t *operation = NULL;
34
Antonio de Angelis4743e672019-04-11 11:38:48 +010035 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080036 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000037 }
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))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080041 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000042 }
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;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010046 psa_key_handle_t key_handle = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010047 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000048
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010049 status = tfm_crypto_check_handle_owner(key_handle, NULL);
50 if (status != PSA_SUCCESS) {
51 return status;
52 }
53
Jamie Fox0e54ebc2019-04-09 14:21:04 +010054 /* Init the handle in the operation with the one passed from the iov */
55 *handle_out = iov->op_handle;
56
57 /* Allocate the operation context in the secure world */
58 status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
59 &handle,
60 (void **)&operation);
61 if (status != PSA_SUCCESS) {
62 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +010063 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +010064
65 *handle_out = handle;
66
67 status = psa_mac_sign_setup(operation, key_handle, alg);
68 if (status != PSA_SUCCESS) {
69 /* Release the operation context, ignore if the operation fails. */
70 (void)tfm_crypto_operation_release(handle_out);
71 return status;
72 }
73
74 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +010075}
76
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000077psa_status_t tfm_crypto_mac_verify_setup(psa_invec in_vec[],
78 size_t in_len,
79 psa_outvec out_vec[],
80 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +010081{
Antonio de Angelis4743e672019-04-11 11:38:48 +010082 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010083 psa_mac_operation_t *operation = NULL;
84
Antonio de Angelis4743e672019-04-11 11:38:48 +010085 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080086 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000087 }
88
Antonio de Angelis4743e672019-04-11 11:38:48 +010089 if ((out_vec[0].len != sizeof(uint32_t)) ||
90 (in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +080091 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000092 }
Antonio de Angelis4743e672019-04-11 11:38:48 +010093 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010094 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010095 uint32_t *handle_out = out_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +010096 psa_key_handle_t key_handle = iov->key_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +010097 psa_algorithm_t alg = iov->alg;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +000098
Antonio de Angelis60a6fe62019-06-18 15:27:34 +010099 status = tfm_crypto_check_handle_owner(key_handle, NULL);
100 if (status != PSA_SUCCESS) {
101 return status;
102 }
103
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100104 /* Init the handle in the operation with the one passed from the iov */
105 *handle_out = iov->op_handle;
106
107 /* Allocate the operation context in the secure world */
108 status = tfm_crypto_operation_alloc(TFM_CRYPTO_MAC_OPERATION,
109 &handle,
110 (void **)&operation);
111 if (status != PSA_SUCCESS) {
112 return status;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100113 }
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100114
115 *handle_out = handle;
116
117 status = psa_mac_verify_setup(operation, key_handle, alg);
118 if (status != PSA_SUCCESS) {
119 /* Release the operation context, ignore if the operation fails. */
120 (void)tfm_crypto_operation_release(handle_out);
121 return status;
122 }
123
124 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100125}
126
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000127psa_status_t tfm_crypto_mac_update(psa_invec in_vec[],
128 size_t in_len,
129 psa_outvec out_vec[],
130 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100131{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000132 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100133 psa_mac_operation_t *operation = NULL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100134
Antonio de Angelis4743e672019-04-11 11:38:48 +0100135 if ((in_len != 2) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800136 return PSA_ERROR_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100137 }
138
Antonio de Angelis4743e672019-04-11 11:38:48 +0100139 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
140 (out_vec[0].len != sizeof(uint32_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800141 return PSA_ERROR_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100142 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100143 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100144 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100145 uint32_t *handle_out = out_vec[0].base;
146 const uint8_t *input = in_vec[1].base;
147 size_t input_length = in_vec[1].len;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100148
Antonio de Angelis4743e672019-04-11 11:38:48 +0100149 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100150 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000151
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100152 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000153 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100154 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100155 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000156 if (status != PSA_SUCCESS) {
157 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100158 }
159
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100160 status = psa_mac_update(operation, input, input_length);
161 if (status != PSA_SUCCESS) {
162 /* Release the operation context, ignore if the operation fails. */
163 (void)tfm_crypto_operation_release(handle_out);
164 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100165 }
166
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000167 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100168}
169
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000170psa_status_t tfm_crypto_mac_sign_finish(psa_invec in_vec[],
171 size_t in_len,
172 psa_outvec out_vec[],
173 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100174{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000175 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100176 psa_mac_operation_t *operation = NULL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100177
Antonio de Angelis4743e672019-04-11 11:38:48 +0100178 if ((in_len != 1) || (out_len != 2)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800179 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000180 }
181
Antonio de Angelis4743e672019-04-11 11:38:48 +0100182 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
183 (out_vec[0].len != sizeof(uint32_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800184 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000185 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100186 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100187 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100188 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000189 uint8_t *mac = out_vec[1].base;
190 size_t mac_size = out_vec[1].len;
191
Antonio de Angelis4743e672019-04-11 11:38:48 +0100192 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100193 *handle_out = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100194
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000195 /* Initialise mac_length to zero */
196 out_vec[1].len = 0;
197
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100198 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000199 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100200 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100201 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000202 if (status != PSA_SUCCESS) {
203 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100204 }
205
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100206 status = psa_mac_sign_finish(operation, mac, mac_size, &out_vec[1].len);
207 if (status != PSA_SUCCESS) {
208 /* Release the operation context, ignore if the operation fails. */
209 (void)tfm_crypto_operation_release(handle_out);
210 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100211 }
212
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100213 status = tfm_crypto_operation_release(handle_out);
214
Antonio de Angelis4743e672019-04-11 11:38:48 +0100215 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100216}
217
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000218psa_status_t tfm_crypto_mac_verify_finish(psa_invec in_vec[],
219 size_t in_len,
220 psa_outvec out_vec[],
221 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100222{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000223 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100224 psa_mac_operation_t *operation = NULL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100225
Antonio de Angelis4743e672019-04-11 11:38:48 +0100226 if ((in_len != 2) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800227 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000228 }
229
Antonio de Angelis4743e672019-04-11 11:38:48 +0100230 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
231 (out_vec[0].len != sizeof(uint32_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800232 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000233 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100234 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100235 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100236 uint32_t *handle_out = out_vec[0].base;
237 const uint8_t *mac = in_vec[1].base;
238 size_t mac_length = in_vec[1].len;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000239
Antonio de Angelis4743e672019-04-11 11:38:48 +0100240 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100241 *handle_out = iov->op_handle;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100242
243 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000244 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100245 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100246 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000247 if (status != PSA_SUCCESS) {
248 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100249 }
250
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100251 status = psa_mac_verify_finish(operation, mac, mac_length);
252 if (status != PSA_SUCCESS) {
253 /* Release the operation context, ignore if the operation fails. */
254 (void)tfm_crypto_operation_release(handle_out);
255 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100256 }
257
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100258 status = tfm_crypto_operation_release(handle_out);
259
260 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100261}
262
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000263psa_status_t tfm_crypto_mac_abort(psa_invec in_vec[],
264 size_t in_len,
265 psa_outvec out_vec[],
266 size_t out_len)
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100267{
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000268 psa_status_t status = PSA_SUCCESS;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100269 psa_mac_operation_t *operation = NULL;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100270
Antonio de Angelis4743e672019-04-11 11:38:48 +0100271 if ((in_len != 1) || (out_len != 1)) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800272 return PSA_ERROR_CONNECTION_REFUSED;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100273 }
274
Antonio de Angelis4743e672019-04-11 11:38:48 +0100275 if ((in_vec[0].len != sizeof(struct tfm_crypto_pack_iovec)) ||
276 (out_vec[0].len != sizeof(uint32_t))) {
Summer Qin4b1d03b2019-07-02 14:56:08 +0800277 return PSA_ERROR_CONNECTION_REFUSED;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000278 }
Antonio de Angelis4743e672019-04-11 11:38:48 +0100279 const struct tfm_crypto_pack_iovec *iov = in_vec[0].base;
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100280 uint32_t handle = iov->op_handle;
Antonio de Angelis4743e672019-04-11 11:38:48 +0100281 uint32_t *handle_out = out_vec[0].base;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000282
Antonio de Angelis4743e672019-04-11 11:38:48 +0100283 /* Init the handle in the operation with the one passed from the iov */
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100284 *handle_out = iov->op_handle;
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000285
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100286 /* Look up the corresponding operation context */
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000287 status = tfm_crypto_operation_lookup(TFM_CRYPTO_MAC_OPERATION,
Antonio de Angelis4743e672019-04-11 11:38:48 +0100288 handle,
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100289 (void **)&operation);
Antonio de Angelisab85ccd2019-03-25 15:14:29 +0000290 if (status != PSA_SUCCESS) {
Antonio de Angelis25e2b2d2019-04-25 14:49:50 +0100291 /* Operation does not exist, so abort has no effect */
292 return PSA_SUCCESS;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100293 }
294
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100295 status = psa_mac_abort(operation);
296
297 if (status != PSA_SUCCESS) {
298 /* Release the operation context, ignore if the operation fails. */
299 (void)tfm_crypto_operation_release(handle_out);
300 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100301 }
302
Jamie Fox0e54ebc2019-04-09 14:21:04 +0100303 status = tfm_crypto_operation_release(handle_out);
304
Antonio de Angelis4743e672019-04-11 11:38:48 +0100305 return status;
Louis Mayencourt7a36f782018-09-24 14:00:57 +0100306}
307/*!@}*/