blob: 6983b8fb8a6ac670996c83d2ea3582f1ed7c3b74 [file] [log] [blame]
Antonio de Angelisa6f72162018-09-05 11:00:37 +01001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
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
26/* The file "psa_crypto_struct.h" contains definitions for
27 * implementation-specific structs that are declared in "psa_crypto.h". */
28#include "psa_crypto_struct.h"
29
30#include "tfm_crypto_api.h"
31#include "crypto_utils.h"
32
33/*!
34 * \defgroup public_psa Public functions, PSA
35 *
36 */
37
38/*!@{*/
39enum tfm_crypto_err_t tfm_crypto_hash_start(psa_hash_operation_t *handle,
40 psa_algorithm_t alg)
41{
42 int ret;
43 enum tfm_crypto_err_t err;
44 const mbedtls_md_info_t *info = NULL;
45 mbedtls_md_type_t type = MBEDTLS_MD_NONE;
46
47 struct psa_hash_operation_s *operation = NULL;
48
49 /* Validate pointers */
50 err = tfm_crypto_memory_check(handle,
51 sizeof(psa_hash_operation_t),
52 TFM_MEMORY_ACCESS_RW);
53 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
54 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
55 }
56
57 if (PSA_ALG_IS_HASH(alg) == 0) {
58 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
59 }
60
61 /* Mbed TLS message digest setup */
62 switch(alg) {
63 case PSA_ALG_MD2:
64#if defined(MBEDTLS_MD2_C)
65 type = MBEDTLS_MD_MD2;
66#endif
67 break;
68 case PSA_ALG_MD4:
69#if defined(MBEDTLS_MD4_C)
70 type = MBEDTLS_MD_MD4;
71#endif
72 break;
73 case PSA_ALG_MD5:
74#if defined(MBEDTLS_MD5_C)
75 type = MBEDTLS_MD_MD5;
76#endif
77 break;
78 case PSA_ALG_RIPEMD160:
79#if defined(MBEDTLS_RIPEMD160_C)
80 type = MBEDTLS_MD_RIPEMD160;
81#endif
82 break;
83 case PSA_ALG_SHA_1:
84#if defined(MBEDTLS_SHA1_C)
85 type = MBEDTLS_MD_SHA1;
86#endif
87 break;
88 case PSA_ALG_SHA_224:
89#if defined(MBEDTLS_SHA256_C)
90 type = MBEDTLS_MD_SHA224;
91#endif
92 break;
93 case PSA_ALG_SHA_256:
94#if defined(MBEDTLS_SHA256_C)
95 type = MBEDTLS_MD_SHA256;
96#endif
97 break;
98 case PSA_ALG_SHA_384:
99#if defined(MBEDTLS_SHA512_C)
100 type = MBEDTLS_MD_SHA384;
101#endif
102 break;
103 case PSA_ALG_SHA_512:
104#if defined(MBEDTLS_SHA512_C)
105 type = MBEDTLS_MD_SHA512;
106#endif
107 break;
108 default:
109 break;
110 }
111
112 /* Mbed TLS currently does not support SHA3: PSA_ALG_SHA3_224,
113 * PSA_ALG_SHA3_256, PSA_ALG_SHA3_384, PSA_ALG_SHA3_512;
114 * Mbed TLS currently does not support SHA-512 Truncated modes:
115 * PSA_ALG_SHA_512_224, PSA_ALG_SHA_512_256
116 */
117 if (type == MBEDTLS_MD_NONE) {
118 return TFM_CRYPTO_ERR_PSA_ERROR_NOT_SUPPORTED;
119 }
120
121 /* Allocate the operation context in the TFM space */
122 err = tfm_crypto_operation_alloc(TFM_CRYPTO_HASH_OPERATION, handle);
123 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
124 return err;
125 }
126
127 /* Look up the corresponding operation context */
128 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
129 handle,
130 (void **)&operation);
131
132 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
133 /* Release the operation context */
134 tfm_crypto_operation_release(handle);
135 return err;
136 }
137
138 /* Bind the algorithm to the hash operation */
139 operation->alg = alg;
140
141 /* Mbed TLS message digest init */
142 mbedtls_md_init(&operation->ctx.md);
143 info = mbedtls_md_info_from_type(type);
144 ret = mbedtls_md_setup(&(operation->ctx.md), info, 0); /* 0: not HMAC */
145 if (ret != 0) {
146 /* Release the operation context */
147 tfm_crypto_operation_release(handle);
148 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
149 }
150
151 /* Start the message digest context */
152 ret = mbedtls_md_starts(&(operation->ctx.md));
153 if (ret != 0) {
154 /* Release the operation context */
155 tfm_crypto_operation_release(handle);
156 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
157 }
158
159 return TFM_CRYPTO_ERR_PSA_SUCCESS;
160}
161
162enum tfm_crypto_err_t tfm_crypto_hash_update(psa_hash_operation_t *handle,
163 const uint8_t *input,
164 size_t input_length)
165{
166 int ret;
167 enum tfm_crypto_err_t err;
168 struct psa_hash_operation_s *operation = NULL;
169
170 /* Validate pointers */
171 err = tfm_crypto_memory_check(handle,
172 sizeof(psa_hash_operation_t),
173 TFM_MEMORY_ACCESS_RW);
174 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
175 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
176 }
177 err = tfm_crypto_memory_check((void *)input,
178 input_length,
179 TFM_MEMORY_ACCESS_RO);
180 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
181 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
182 }
183
184 /* Look up the corresponding operation context */
185 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
186 handle,
187 (void **)&operation);
188
189 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
190 return err;
191 }
192
193 /* Process the input chunk */
194 ret = mbedtls_md_update(&(operation->ctx.md), input, input_length);
195 if (ret != 0) {
196 /* Release the operation context */
197 tfm_crypto_operation_release(handle);
198 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
199 }
200
201 return TFM_CRYPTO_ERR_PSA_SUCCESS;
202}
203
204enum tfm_crypto_err_t tfm_crypto_hash_finish(psa_hash_operation_t *handle,
205 uint8_t *hash,
206 size_t hash_size,
207 size_t *hash_length)
208{
209 int ret;
210 enum tfm_crypto_err_t err;
211 struct psa_hash_operation_s *operation = NULL;
212
213 /* Validate pointers */
214 err = tfm_crypto_memory_check(handle,
215 sizeof(psa_hash_operation_t),
216 TFM_MEMORY_ACCESS_RW);
217 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
218 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
219 }
220 err = tfm_crypto_memory_check((void *)hash,
221 hash_size,
222 TFM_MEMORY_ACCESS_RO);
223 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
224 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
225 }
226 err = tfm_crypto_memory_check(hash_length,
227 sizeof(size_t),
228 TFM_MEMORY_ACCESS_RW);
229 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
230 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
231 }
232
233 /* Look up the corresponding operation context */
234 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
235 handle,
236 (void **)&operation);
237
238 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
239 return err;
240 }
241
242 if (hash_size < PSA_HASH_SIZE(operation->alg)) {
243 /* Release the operation context */
244 tfm_crypto_operation_release(handle);
245 return TFM_CRYPTO_ERR_PSA_ERROR_BUFFER_TOO_SMALL;
246 }
247
248 /* Finalise the hash value */
249 ret = mbedtls_md_finish(&(operation->ctx.md), hash);
250 if (ret != 0) {
251 /* Release the operation context */
252 tfm_crypto_operation_release(handle);
253 return TFM_CRYPTO_ERR_PSA_ERROR_COMMUNICATION_FAILURE;
254 }
255
256 /* Set the length of the hash that has been produced */
257 *hash_length = PSA_HASH_SIZE(operation->alg);
258
259 /* Clear the Mbed TLS message digest context */
260 mbedtls_md_free(&(operation->ctx.md));
261
262 /* Release the operation context */
263 err = tfm_crypto_operation_release(handle);
264 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
265 return err;
266 }
267
268 return TFM_CRYPTO_ERR_PSA_SUCCESS;
269}
270
271enum tfm_crypto_err_t tfm_crypto_hash_verify(psa_hash_operation_t *handle,
272 const uint8_t *hash,
273 size_t hash_length)
274{
275 enum tfm_crypto_err_t err;
276 uint8_t digest[PSA_HASH_MAX_SIZE] = {0};
277 size_t digest_length;
278 uint32_t idx, comp_mismatch = 0;
279
280 /* Validate pointers */
281 err = tfm_crypto_memory_check(handle,
282 sizeof(psa_hash_operation_t),
283 TFM_MEMORY_ACCESS_RW);
284 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
285 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_ARGUMENT;
286 }
287
288 /* Finalise the hash operation */
289 err = tfm_crypto_hash_finish(handle,
290 digest,
291 PSA_HASH_MAX_SIZE,
292 &digest_length);
293
294 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
295 return err;
296 }
297
298 /* Verify that the computed hash matches the provided one */
299 for (idx=0; idx<(uint32_t)digest_length; idx++) {
300 if (digest[idx] != hash[idx]) {
301 comp_mismatch = 1;
302 }
303 }
304
305 if (comp_mismatch == 1) {
306 return TFM_CRYPTO_ERR_PSA_ERROR_INVALID_SIGNATURE;
307 }
308
309 return TFM_CRYPTO_ERR_PSA_SUCCESS;
310}
311
312enum tfm_crypto_err_t tfm_crypto_hash_abort(psa_hash_operation_t *handle)
313{
314 enum tfm_crypto_err_t err;
315 struct psa_hash_operation_s *operation = NULL;
316
317 /* Look up the corresponding operation context */
318 err = tfm_crypto_operation_lookup(TFM_CRYPTO_HASH_OPERATION,
319 handle,
320 (void **)&operation);
321
322 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
323 return err;
324 }
325
326 /* Clear the Mbed TLS message digest context */
327 mbedtls_md_free(&(operation->ctx.md));
328
329 /* Release the operation context */
330 err = tfm_crypto_operation_release(handle);
331 if (err != TFM_CRYPTO_ERR_PSA_SUCCESS) {
332 return err;
333 }
334
335 return TFM_CRYPTO_ERR_PSA_SUCCESS;
336}
337/*!@}*/