blob: 8356d55fcab75128c507d5aa0e1870d0345e849b [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
8#include <limits.h>
9
10#include "tfm_crypto_defs.h"
11
12/* Pre include Mbed TLS headers */
13#define LIB_PREFIX_NAME __tfm_crypto__
14#include "mbedtls_global_symbols.h"
15
16/* Include the Mbed TLS configuration file, the way Mbed TLS does it
17 * in each of its header files. */
18#if !defined(MBEDTLS_CONFIG_FILE)
19#include "platform/ext/common/tfm_mbedtls_config.h"
20#else
21#include MBEDTLS_CONFIG_FILE
22#endif
23
24#include "psa_crypto.h"
25
Antonio de Angelis377a1552018-11-22 17:02:40 +000026#include "tfm_crypto_struct.h"
Antonio de Angelisa6f72162018-09-05 11:00:37 +010027
28#include "tfm_crypto_api.h"
29#include "crypto_utils.h"
30
31/*!
32 * \defgroup public_psa Public functions, PSA
33 *
34 */
35
36/*!@{*/
Antonio de Angelis377a1552018-11-22 17:02:40 +000037enum tfm_crypto_err_t tfm_crypto_hash_setup(psa_hash_operation_t *operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +010038 psa_algorithm_t alg)
39{
40 int ret;
41 enum tfm_crypto_err_t err;
42 const mbedtls_md_info_t *info = NULL;
43 mbedtls_md_type_t type = MBEDTLS_MD_NONE;
44
Antonio de Angelis377a1552018-11-22 17:02:40 +000045 struct tfm_hash_operation_s *ctx = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +010046
47 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +000048 err = tfm_crypto_memory_check(operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +010049 sizeof(psa_hash_operation_t),
50 TFM_MEMORY_ACCESS_RW);
51 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
52 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
53 }
54
55 if (PSA_ALG_IS_HASH(alg) == 0) {
56 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
57 }
58
59 /* Mbed TLS message digest setup */
60 switch(alg) {
61 case PSA_ALG_MD2:
62#if defined(MBEDTLS_MD2_C)
63 type = MBEDTLS_MD_MD2;
64#endif
65 break;
66 case PSA_ALG_MD4:
67#if defined(MBEDTLS_MD4_C)
68 type = MBEDTLS_MD_MD4;
69#endif
70 break;
71 case PSA_ALG_MD5:
72#if defined(MBEDTLS_MD5_C)
73 type = MBEDTLS_MD_MD5;
74#endif
75 break;
76 case PSA_ALG_RIPEMD160:
77#if defined(MBEDTLS_RIPEMD160_C)
78 type = MBEDTLS_MD_RIPEMD160;
79#endif
80 break;
81 case PSA_ALG_SHA_1:
82#if defined(MBEDTLS_SHA1_C)
83 type = MBEDTLS_MD_SHA1;
84#endif
85 break;
86 case PSA_ALG_SHA_224:
87#if defined(MBEDTLS_SHA256_C)
88 type = MBEDTLS_MD_SHA224;
89#endif
90 break;
91 case PSA_ALG_SHA_256:
92#if defined(MBEDTLS_SHA256_C)
93 type = MBEDTLS_MD_SHA256;
94#endif
95 break;
96 case PSA_ALG_SHA_384:
97#if defined(MBEDTLS_SHA512_C)
98 type = MBEDTLS_MD_SHA384;
99#endif
100 break;
101 case PSA_ALG_SHA_512:
102#if defined(MBEDTLS_SHA512_C)
103 type = MBEDTLS_MD_SHA512;
104#endif
105 break;
106 default:
107 break;
108 }
109
110 /* Mbed TLS currently does not support SHA3: PSA_ALG_SHA3_224,
111 * PSA_ALG_SHA3_256, PSA_ALG_SHA3_384, PSA_ALG_SHA3_512;
112 * Mbed TLS currently does not support SHA-512 Truncated modes:
113 * PSA_ALG_SHA_512_224, PSA_ALG_SHA_512_256
114 */
115 if (type == MBEDTLS_MD_NONE) {
116 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
117 }
118
Antonio de Angelis377a1552018-11-22 17:02:40 +0000119 /* Allocate the operation context in the Secure world */
120 err = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION,
121 &(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100122 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
123 return err;
124 }
125
126 /* Look up the corresponding operation context */
127 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000128 operation->handle,
129 (void **)&ctx);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100130 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
131 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000132 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100133 return err;
134 }
135
Antonio de Angelis377a1552018-11-22 17:02:40 +0000136 /* Bind the algorithm to the hash context */
137 ctx->alg = alg;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100138
139 /* Mbed TLS message digest init */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000140 mbedtls_md_init(&ctx->md);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100141 info = mbedtls_md_info_from_type(type);
Antonio de Angelis377a1552018-11-22 17:02:40 +0000142 ret = mbedtls_md_setup(&(ctx->md), info, 0); /* 0: not HMAC */
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100143 if (ret != 0) {
144 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000145 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100146 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
147 }
148
149 /* Start the message digest context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000150 ret = mbedtls_md_starts(&(ctx->md));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100151 if (ret != 0) {
152 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000153 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100154 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
155 }
156
157 return TFM_CRYPTO_ERR_PSA_SUCCESS;
158}
159
Antonio de Angelis377a1552018-11-22 17:02:40 +0000160enum tfm_crypto_err_t tfm_crypto_hash_update(psa_hash_operation_t *operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100161 const uint8_t *input,
162 size_t input_length)
163{
164 int ret;
165 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000166 struct tfm_hash_operation_s *ctx = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100167
168 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000169 err = tfm_crypto_memory_check(operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100170 sizeof(psa_hash_operation_t),
171 TFM_MEMORY_ACCESS_RW);
172 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
173 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
174 }
175 err = tfm_crypto_memory_check((void *)input,
176 input_length,
177 TFM_MEMORY_ACCESS_RO);
178 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
179 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
180 }
181
182 /* Look up the corresponding operation context */
183 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000184 operation->handle,
185 (void **)&ctx);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100186 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
187 return err;
188 }
189
190 /* Process the input chunk */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000191 ret = mbedtls_md_update(&(ctx->md), input, input_length);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100192 if (ret != 0) {
193 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000194 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100195 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
196 }
197
198 return TFM_CRYPTO_ERR_PSA_SUCCESS;
199}
200
Antonio de Angelis377a1552018-11-22 17:02:40 +0000201enum tfm_crypto_err_t tfm_crypto_hash_finish(psa_hash_operation_t *operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100202 uint8_t *hash,
203 size_t hash_size,
204 size_t *hash_length)
205{
206 int ret;
207 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000208 struct tfm_hash_operation_s *ctx = NULL;
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100209
210 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000211 err = tfm_crypto_memory_check(operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100212 sizeof(psa_hash_operation_t),
213 TFM_MEMORY_ACCESS_RW);
214 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
215 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
216 }
Antonio de Angelis377a1552018-11-22 17:02:40 +0000217 err = tfm_crypto_memory_check(hash,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100218 hash_size,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000219 TFM_MEMORY_ACCESS_RW);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100220 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
221 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
222 }
223 err = tfm_crypto_memory_check(hash_length,
224 sizeof(size_t),
225 TFM_MEMORY_ACCESS_RW);
226 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
227 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
228 }
229
230 /* Look up the corresponding operation context */
231 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000232 operation->handle,
233 (void **)&ctx);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100234 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
235 return err;
236 }
237
Antonio de Angelis377a1552018-11-22 17:02:40 +0000238 if (hash_size < PSA_HASH_SIZE(ctx->alg)) {
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100239 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000240 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100241 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
242 }
243
244 /* Finalise the hash value */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000245 ret = mbedtls_md_finish(&(ctx->md), hash);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100246 if (ret != 0) {
247 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000248 tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100249 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
250 }
251
252 /* Set the length of the hash that has been produced */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000253 *hash_length = PSA_HASH_SIZE(ctx->alg);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100254
255 /* Clear the Mbed TLS message digest context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000256 mbedtls_md_free(&(ctx->md));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100257
258 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000259 err = tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100260 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
261 return err;
262 }
263
264 return TFM_CRYPTO_ERR_PSA_SUCCESS;
265}
266
Antonio de Angelis377a1552018-11-22 17:02:40 +0000267enum tfm_crypto_err_t tfm_crypto_hash_verify(psa_hash_operation_t *operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100268 const uint8_t *hash,
269 size_t hash_length)
270{
271 enum tfm_crypto_err_t err;
272 uint8_t digest[PSA_HASH_MAX_SIZE] = {0};
273 size_t digest_length;
274 uint32_t idx, comp_mismatch = 0;
275
276 /* Validate pointers */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000277 err = tfm_crypto_memory_check(operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100278 sizeof(psa_hash_operation_t),
279 TFM_MEMORY_ACCESS_RW);
280 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
281 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
282 }
283
284 /* Finalise the hash operation */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000285 err = tfm_crypto_hash_finish(operation,
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100286 digest,
287 PSA_HASH_MAX_SIZE,
288 &digest_length);
289
290 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
291 return err;
292 }
293
294 /* Verify that the computed hash matches the provided one */
295 for (idx=0; idx<(uint32_t)digest_length; idx++) {
296 if (digest[idx] != hash[idx]) {
297 comp_mismatch = 1;
298 }
299 }
300
301 if (comp_mismatch == 1) {
302 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
303 }
304
305 return TFM_CRYPTO_ERR_PSA_SUCCESS;
306}
307
Antonio de Angelis377a1552018-11-22 17:02:40 +0000308enum tfm_crypto_err_t tfm_crypto_hash_abort(psa_hash_operation_t *operation)
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100309{
310 enum tfm_crypto_err_t err;
Antonio de Angelis377a1552018-11-22 17:02:40 +0000311 struct tfm_hash_operation_s *ctx = NULL;
312
313 /* Validate pointers */
314 err = tfm_crypto_memory_check(operation,
315 sizeof(psa_hash_operation_t),
316 TFM_MEMORY_ACCESS_RW);
317 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
318 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
319 }
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100320
321 /* Look up the corresponding operation context */
322 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
Antonio de Angelis377a1552018-11-22 17:02:40 +0000323 operation->handle,
324 (void **)&ctx);
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100325 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
326 return err;
327 }
328
329 /* Clear the Mbed TLS message digest context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000330 mbedtls_md_free(&(ctx->md));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100331
332 /* Release the operation context */
Antonio de Angelis377a1552018-11-22 17:02:40 +0000333 err = tfm_crypto_operation_release(&(operation->handle));
Antonio de Angelisa6f72162018-09-05 11:00:37 +0100334 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
335 return err;
336 }
337
338 return TFM_CRYPTO_ERR_PSA_SUCCESS;
339}
340/*!@}*/