blob: 4f9290f5c77cf520af124e53eb1a4391f5a5f660 [file] [log] [blame]
Antonio de Angeliscf85ba22018-10-09 13:29:40 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8/**
9 * \brief Include the Crypto engine header. This source module implements the
10 * interface which is being used by the other components of the service
11 * to interact with the cryptography primitives available, in SW or HW.
12 * The current implementation provides only a SW implementation based on
13 * Mbed TLS functions.
14 */
15#include "crypto_engine.h"
16
17#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
18/**
19 * \brief Buffer size used by Mbed TLS for its allocations
20 */
21#define TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN (1024)
22
23/**
24 * \brief Static buffer to be used by Mbed TLS for memory allocations
25 *
26 */
27static uint8_t mbedtls_mem_buf[TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN] = {0};
28
29/**
30 * \brief This function maps Mbed TLS return codes to PSA return codes.
31 *
32 * \param[in] ret Mbed TLS return value
33 *
34 * \return Return values as specified by \ref psa_status_t
35 */
36static psa_status_t mbedtls_to_psa_return(int ret)
37{
38 /* zero return value means success */
39 if (ret == 0) {
40 return PSA_SUCCESS;
41 }
42
43 /* FIXME: For the time being map all errors to PSA_ERROR_UNKNOW_ERROR */
44 switch (ret) {
45 default:
46 return PSA_ERROR_UNKNOWN_ERROR;
47 }
48}
49#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
50
51psa_status_t tfm_crypto_engine_init(void)
52{
53 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
54
55#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
56 /* Initialise the Mbed TLS static memory allocator so that Mbed TLS
57 * allocates memory from the provided static buffer instead of from
58 * the heap.
59 */
60 mbedtls_memory_buffer_alloc_init(mbedtls_mem_buf,
61 TFM_CRYPTO_MBEDTLS_MEM_BUF_LEN);
62 /* The previous function doesn't return any error code */
63 return_value = PSA_SUCCESS;
64#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
65
66 return return_value;
67}
68
69psa_status_t tfm_crypto_engine_hash_setup(const psa_algorithm_t alg,
70 struct hash_engine_info *engine_info)
71{
72 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
73
74#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
75 mbedtls_md_type_t type = MBEDTLS_MD_NONE;
76
77 /* Mbed TLS message digest setup */
78 switch(alg) {
79 case PSA_ALG_MD2:
80#if defined(MBEDTLS_MD2_C)
81 type = MBEDTLS_MD_MD2;
82#endif
83 break;
84 case PSA_ALG_MD4:
85#if defined(MBEDTLS_MD4_C)
86 type = MBEDTLS_MD_MD4;
87#endif
88 break;
89 case PSA_ALG_MD5:
90#if defined(MBEDTLS_MD5_C)
91 type = MBEDTLS_MD_MD5;
92#endif
93 break;
94 case PSA_ALG_RIPEMD160:
95#if defined(MBEDTLS_RIPEMD160_C)
96 type = MBEDTLS_MD_RIPEMD160;
97#endif
98 break;
99 case PSA_ALG_SHA_1:
100#if defined(MBEDTLS_SHA1_C)
101 type = MBEDTLS_MD_SHA1;
102#endif
103 break;
104 case PSA_ALG_SHA_224:
105#if defined(MBEDTLS_SHA256_C)
106 type = MBEDTLS_MD_SHA224;
107#endif
108 break;
109 case PSA_ALG_SHA_256:
110#if defined(MBEDTLS_SHA256_C)
111 type = MBEDTLS_MD_SHA256;
112#endif
113 break;
114 case PSA_ALG_SHA_384:
115#if defined(MBEDTLS_SHA512_C)
116 type = MBEDTLS_MD_SHA384;
117#endif
118 break;
119 case PSA_ALG_SHA_512:
120#if defined(MBEDTLS_SHA512_C)
121 type = MBEDTLS_MD_SHA512;
122#endif
123 break;
124 default:
125 break;
126 }
127
128 engine_info->type = (uint32_t) type;
129
130 /* Mbed TLS currently does not support SHA3: PSA_ALG_SHA3_224,
131 * PSA_ALG_SHA3_256, PSA_ALG_SHA3_384, PSA_ALG_SHA3_512;
132 * Mbed TLS currently does not support SHA-512 Truncated modes:
133 * PSA_ALG_SHA_512_224, PSA_ALG_SHA_512_256
134 */
135 if (type == MBEDTLS_MD_NONE) {
136 return_value = PSA_ERROR_NOT_SUPPORTED;
137 } else {
138 return_value = PSA_SUCCESS;
139 }
140#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
141
142 return return_value;
143}
144
145psa_status_t tfm_crypto_engine_hash_start(
146 union engine_hash_context *hp,
147 const struct hash_engine_info *engine_info)
148{
149 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
150
151#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
152 const mbedtls_md_info_t *info = NULL;
153 int ret;
154
155 /* Mbed TLS message digest init */
156 mbedtls_md_init(&(hp->ctx));
157 info = mbedtls_md_info_from_type((mbedtls_md_type_t)engine_info->type);
158 ret = mbedtls_md_setup(&(hp->ctx), info, 0); /* 0: not HMAC */
159 if (ret != 0) {
160 return_value = mbedtls_to_psa_return(ret);
161 } else {
162 /* Start the message digest context */
163 ret = mbedtls_md_starts(&(hp->ctx));
164 return_value = mbedtls_to_psa_return(ret);
165 }
166#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
167
168 return return_value;
169}
170
171psa_status_t tfm_crypto_engine_hash_update(union engine_hash_context *hp,
172 const uint8_t *input,
173 const uint32_t input_length)
174{
175 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
176
177#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
178 int ret;
179 /* Update the message digest with a new chunk of information */
180 ret = mbedtls_md_update(&(hp->ctx), input, input_length);
181 return_value = mbedtls_to_psa_return(ret);
182#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
183
184 return return_value;
185}
186
187psa_status_t tfm_crypto_engine_hash_finish(union engine_hash_context *hp,
188 uint8_t *hash)
189{
190 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
191
192#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
193 int ret;
194 /* Finalise the hash value, producing the output */
195 ret = mbedtls_md_finish(&(hp->ctx), hash);
196 return_value = mbedtls_to_psa_return(ret);
197#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
198
199 return return_value;
200}
201
202psa_status_t tfm_crypto_engine_hash_release(union engine_hash_context *hp)
203{
204 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
205
206#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
207 /* Clear the Mbed TLS message digest context */
208 mbedtls_md_free(&(hp->ctx));
209 /* The previous function doesn't return any error code */
210 return_value = PSA_SUCCESS;
211#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
212
213 return return_value;
214}
215
216psa_status_t tfm_crypto_engine_cipher_setup(const psa_algorithm_t alg,
217 const psa_key_type_t key_type,
218 const uint32_t key_size,
219 const enum engine_cipher_mode_t engine_cipher_mode,
220 struct cipher_engine_info *engine_info)
221{
222 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
223
224#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
225 mbedtls_cipher_type_t type = MBEDTLS_CIPHER_NONE;
226 mbedtls_cipher_padding_t padding_mode = MBEDTLS_PADDING_NONE;
227 psa_algorithm_t padding_mode_field = PSA_ALG_BLOCK_CIPHER_PAD_NONE;
228
229 /* FIXME: Check that key is compatible with alg. It's assumed that key
230 * key_type will be AES, this needs to be extended as well. A
231 * proper function to determine cipher type based on inputs
232 * will need to be designed here.
233 */
234 if ((engine_cipher_mode != ENGINE_CIPHER_MODE_ENCRYPT) &&
235 (engine_cipher_mode != ENGINE_CIPHER_MODE_DECRYPT)) {
236 return_value = PSA_ERROR_NOT_SUPPORTED;
237 } else {
238 /* Mbed TLS cipher setup */
239 if (key_size == 128) {
240 if (alg == PSA_ALG_CBC_BASE) {
241 type = MBEDTLS_CIPHER_AES_128_CBC;
242 } else if (alg == PSA_ALG_CFB_BASE) {
243 if (engine_cipher_mode == ENGINE_CIPHER_MODE_ENCRYPT) {
244 type = MBEDTLS_CIPHER_AES_128_CFB128;
245 }
246 }
247 }
248
249 if (type == MBEDTLS_CIPHER_NONE) {
250 return_value = PSA_ERROR_NOT_SUPPORTED;
251 } else {
252 /* If CBC, need to set check the padding mode */
253 if ((alg & ~PSA_ALG_BLOCK_CIPHER_PADDING_MASK) == PSA_ALG_CBC_BASE) {
254
255 /* Check the value of padding field */
256 padding_mode_field = alg & PSA_ALG_BLOCK_CIPHER_PADDING_MASK;
257
258 switch (padding_mode_field) {
259 case PSA_ALG_BLOCK_CIPHER_PAD_PKCS7:
260 padding_mode = MBEDTLS_PADDING_PKCS7;
261 return_value = PSA_SUCCESS;
262 break;
263 case PSA_ALG_BLOCK_CIPHER_PAD_NONE:
264 padding_mode = MBEDTLS_PADDING_NONE;
265 return_value = PSA_SUCCESS;
266 break;
267 default:
268 return_value = PSA_ERROR_NOT_SUPPORTED;
269 }
270 } else {
271 /* The engine is correctly configured */
272 return_value = PSA_SUCCESS;
273 }
274 }
275 }
276
277 if (return_value == PSA_SUCCESS) {
278 engine_info->type = (uint32_t) type;
279 engine_info->cipher_mode = engine_cipher_mode;
280 engine_info->padding_mode = (uint32_t) padding_mode;
281 }
282#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
283
284 return return_value;
285}
286
287psa_status_t tfm_crypto_engine_cipher_set_padding_mode(
288 union engine_cipher_context *cp,
289 const struct cipher_engine_info *engine_info)
290{
291 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
292
293#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
294 int ret;
295 ret = mbedtls_cipher_set_padding_mode(&(cp->ctx),
296 (mbedtls_cipher_padding_t)engine_info->padding_mode);
297 return_value = mbedtls_to_psa_return(ret);
298#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
299
300 return return_value;
301}
302
303psa_status_t tfm_crypto_engine_cipher_start(
304 union engine_cipher_context *cp,
305 const struct cipher_engine_info *engine_info)
306{
307 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
308
309#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
310 int ret;
311 const mbedtls_cipher_info_t *info = NULL;
312
313 /* Mbed TLS cipher init */
314 mbedtls_cipher_init(&(cp->ctx));
315 info = mbedtls_cipher_info_from_type(engine_info->type);
316
317 ret = mbedtls_cipher_setup(&(cp->ctx), info);
318 return_value = mbedtls_to_psa_return(ret);
319#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
320
321 return return_value;
322}
323
324psa_status_t tfm_crypto_engine_cipher_set_key(
325 union engine_cipher_context *cp,
326 const uint8_t *key_data,
327 const uint32_t key_size,
328 const struct cipher_engine_info *engine_info)
329{
330 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
331
332#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
333 int ret;
334 /* Mbed TLS cipher set key */
335 if ((engine_info->cipher_mode != ENGINE_CIPHER_MODE_ENCRYPT) &&
336 (engine_info->cipher_mode != ENGINE_CIPHER_MODE_DECRYPT)) {
337 return_value = PSA_ERROR_NOT_SUPPORTED;
338 } else {
339 /* Set the key on the context */
340 ret = mbedtls_cipher_setkey(
341 &(cp->ctx),
342 key_data,
343 PSA_BYTES_TO_BITS(key_size),
344 (engine_info->cipher_mode == ENGINE_CIPHER_MODE_ENCRYPT) ?
345 MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT);
346 return_value = mbedtls_to_psa_return(ret);
347 }
348#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
349
350 return return_value;
351}
352
353psa_status_t tfm_crypto_engine_cipher_set_iv(union engine_cipher_context *cp,
354 const uint8_t *iv,
355 const uint32_t iv_length)
356{
357 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
358
359#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
360 int ret;
361
362 /* Bind the IV to the cipher operation */
363 ret = mbedtls_cipher_set_iv(&(cp->ctx), iv, iv_length);
364 if (ret != 0) {
365 return_value = mbedtls_to_psa_return(ret);
366 } else {
367 /* Reset the context after IV is set */
368 ret = mbedtls_cipher_reset(&(cp->ctx));
369 return_value = mbedtls_to_psa_return(ret);
370 }
371#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
372
373 return return_value;
374}
375
376psa_status_t tfm_crypto_engine_cipher_update(union engine_cipher_context *cp,
377 const uint8_t *input,
378 const uint32_t input_length,
379 uint8_t *output,
380 uint32_t *output_length)
381{
382 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
383
384#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
385 int ret;
386 /* Update with the chunk of input data, eventually producing output */
387 ret = mbedtls_cipher_update(&(cp->ctx), input, input_length,
388 output, (size_t *)output_length);
389 return_value = mbedtls_to_psa_return(ret);
390#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
391
392 return return_value;
393}
394
395psa_status_t tfm_crypto_engine_cipher_finish(union engine_cipher_context *cp,
396 uint8_t *output,
397 uint32_t *output_length)
398{
399 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
400
401#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
402 int ret;
403 /* Finalise the cipher operation */
404 ret = mbedtls_cipher_finish(&(cp->ctx), output, (size_t *)output_length);
405 return_value = mbedtls_to_psa_return(ret);
406#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
407
408 return return_value;
409}
410
411psa_status_t tfm_crypto_engine_cipher_release(union engine_cipher_context *cp)
412{
413 psa_status_t return_value = PSA_ERROR_NOT_SUPPORTED;
414
415#if defined(TFM_CRYPTO_ENGINE_MBEDTLS)
416 /* Clear the Mbed TLS context */
417 mbedtls_cipher_free(&(cp->ctx));
418 /* The previous function doesn't return any error code */
419 return_value = PSA_SUCCESS;
420#endif /* TFM_CRYPTO_ENGINE_MBEDTLS */
421
422 return return_value;
423}