1 /*! *********************************************************************************
2  * Copyright 2022 NXP
3  * All rights reserved.
4  *
5  * \file
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  ********************************************************************************** */
9 
10 #include "sss_crypto.h"
11 
12 sss_sscp_key_store_t g_keyStore;
13 sss_sscp_session_t g_sssSession;
14 sscp_context_t g_sscpContext;
15 
16 static uint32_t g_isCryptoHWInitialized = SSS_CRYPTOHW_NONINITIALIZED;
17 
18 /******************************************************************************/
19 /*************************** Mutex ********************************************/
20 /******************************************************************************/
21 #if defined(MBEDTLS_THREADING_C)
22 
23 /**
24  * \def MBEDTLS_MCUX_FREERTOS_THREADING_ALT
25  * You can comment this macro if you provide your own alternate implementation.
26  *
27  */
28 #if defined(SDK_OS_FREE_RTOS)
29 #define MBEDTLS_MCUX_FREERTOS_THREADING_ALT
30 #endif
31 
32 #if defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT)
33 /**
34  * @brief Initializes the mbedTLS mutex functions.
35  *
36  * Provides mbedTLS access to mutex create, destroy, take and free.
37  *
38  * @see MBEDTLS_THREADING_ALT
39  */
40 static void CRYPTO_ConfigureThreadingMcux(void);
41 #endif /* defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT) */
42 
43 #endif /* defined(MBEDTLS_THREADING_C) */
44 
45 /******************************************************************************/
46 /******************** CRYPTO_InitHardware **************************************/
47 /******************************************************************************/
48 /*!
49  * @brief Application init for various Crypto blocks.
50  *
51  * This function is provided to be called by MCUXpresso SDK applications.
52  * It calls basic init for Crypto Hw acceleration and Hw entropy modules.
53  */
CRYPTO_InitHardware(void)54 status_t CRYPTO_InitHardware(void)
55 {
56 #if defined(MBEDTLS_NXP_SSSAPI)
57 #if defined(MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT)
58     CRYPTO_ConfigureThreadingMcux();
59 #endif /* (MBEDTLS_THREADING_C) && defined(MBEDTLS_THREADING_ALT) */
60 #endif
61     status_t ret;
62     do
63     {
64         if (g_isCryptoHWInitialized == SSS_CRYPTOHW_INITIALIZED)
65         {
66             ret = kStatus_Success;
67             break;
68         }
69         ret = kStatus_Fail;
70 
71         sss_sscp_rng_t rctx;
72         if (ELEMU_mu_wait_for_ready(ELEMUA, SSS_MAX_SUBSYTEM_WAIT) != kStatus_Success)
73         {
74             break;
75         }
76 #if (defined(ELEMU_HAS_LOADABLE_FW) && ELEMU_HAS_LOADABLE_FW)
77         if (ELEMU_loadFwLocal(ELEMUA) != kStatus_ELEMU_Success)
78         {
79             break;
80         }
81 #endif /* ELEMU_HAS_LOADABLE_FW */
82         if (sscp_mu_init(&g_sscpContext, (ELEMU_Type *)(uintptr_t)ELEMUA) != kStatus_SSCP_Success)
83         {
84             break;
85         }
86         if (sss_sscp_open_session(&g_sssSession, 0u, SSS_SUBSYSTEM, &g_sscpContext) != kStatus_SSS_Success)
87         {
88             break;
89         }
90         if (sss_sscp_key_store_init(&g_keyStore, &g_sssSession) != kStatus_SSS_Success)
91         {
92             break;
93         }
94 
95         /* RNG call used to init ELE TRNG required e.g. by sss_sscp_key_store_generate_key service
96         if TRNG initialization is no needed for used operations, the following code can be removed
97         to increase the perfomance.*/
98         if (sss_sscp_rng_context_init(&g_sssSession, &rctx, SSS_HIGH_QUALITY_RNG) != kStatus_SSS_Success)
99         {
100             break;
101         }
102         /*Providing NULL output buffer, as we just need to initialize TRNG, not get random data*/
103         if (sss_sscp_rng_get_random(&rctx, NULL, 0x0u) != kStatus_SSS_Success)
104         {
105             break;
106         }
107         if (sss_sscp_rng_free(&rctx) != kStatus_SSS_Success)
108         {
109             break;
110         }
111         g_isCryptoHWInitialized = SSS_CRYPTOHW_INITIALIZED;
112         ret                     = kStatus_Success;
113 
114     } while (false);
115     return ret;
116 }
117 
118 /*!
119  * @brief Application reinit for various Crypto blocks.
120  *
121  * This function is provided to be called after wake up from low power Power Down
122  * or Deep Power Down modes to reinit Crypto HW blocks.
123  */
CRYPTO_ReinitHardware(void)124 status_t CRYPTO_ReinitHardware(void)
125 {
126     /* Reset the init state so the hardware will be reinitialized at the next cryptographic HW acceleration operation */
127     g_isCryptoHWInitialized = SSS_CRYPTOHW_NONINITIALIZED;
128 
129     return kStatus_Success;
130 }
131 
132 /*!
133  * @brief This function will allow reinitizialize the cryptographic HW acceleration
134  * next time we need it, typically after lowpower mode.
135  */
CRYPTO_DeinitHardware(void)136 void CRYPTO_DeinitHardware(void)
137 {
138     g_isCryptoHWInitialized = SSS_CRYPTOHW_NONINITIALIZED;
139 }
140 
CRYPTO_ELEMU_reset(void)141 void CRYPTO_ELEMU_reset(void)
142 {
143     CRYPTO_DeinitHardware();
144     (void)ELEMU_LP_WakeupPathInit(ELEMUA);
145 }
146 
147 /******************************************************************************/
148 /*************************** Mutex ********************************************/
149 /******************************************************************************/
150 #if defined(MBEDTLS_THREADING_C)
151 
152 /**
153  * \def MBEDTLS_MCUX_FREERTOS_THREADING_ALT
154  * You can comment this macro if you provide your own alternate implementation.
155  *
156  */
157 #if defined(SDK_OS_FREE_RTOS)
158 #define MBEDTLS_MCUX_FREERTOS_THREADING_ALT
159 #endif
160 
161 /*
162  * Define global mutexes for HW accelerator
163  */
164 
165 #if defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT)
166 /**
167  * @brief Initializes the mbedTLS mutex functions.
168  *
169  * Provides mbedTLS access to mutex create, destroy, take and free.
170  *
171  * @see MBEDTLS_THREADING_ALT
172  */
173 static void CRYPTO_ConfigureThreadingMcux(void);
174 #endif /* defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT) */
175 
176 #endif /* defined(MBEDTLS_THREADING_C) */
177 
178 /*-----------------------------------------------------------*/
179 /*--------- mbedTLS threading functions for FreeRTOS --------*/
180 /*--------------- See MBEDTLS_THREADING_ALT -----------------*/
181 /*-----------------------------------------------------------*/
182 #if defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT)
183 /* Threading mutex implementations for mbedTLS. */
184 #include "mbedtls/threading.h"
185 #include "threading_alt.h"
186 
187 /**
188  * @brief Implementation of mbedtls_mutex_init for thread-safety.
189  *
190  */
mcux_mbedtls_mutex_init(mbedtls_threading_mutex_t * mutex)191 void mcux_mbedtls_mutex_init(mbedtls_threading_mutex_t *mutex)
192 {
193     mutex->mutex = xSemaphoreCreateMutex();
194 
195     if (mutex->mutex != NULL)
196     {
197         mutex->is_valid = 1;
198     }
199     else
200     {
201         mutex->is_valid = 0;
202     }
203 }
204 
205 /**
206  * @brief Implementation of mbedtls_mutex_free for thread-safety.
207  *
208  */
mcux_mbedtls_mutex_free(mbedtls_threading_mutex_t * mutex)209 void mcux_mbedtls_mutex_free(mbedtls_threading_mutex_t *mutex)
210 {
211     if (mutex->is_valid == 1)
212     {
213         vSemaphoreDelete(mutex->mutex);
214         mutex->is_valid = 0;
215     }
216 }
217 
218 /**
219  * @brief Implementation of mbedtls_mutex_lock for thread-safety.
220  *
221  * @return 0 if successful, MBEDTLS_ERR_THREADING_MUTEX_ERROR if timeout,
222  * MBEDTLS_ERR_THREADING_BAD_INPUT_DATA if the mutex is not valid.
223  */
mcux_mbedtls_mutex_lock(mbedtls_threading_mutex_t * mutex)224 int mcux_mbedtls_mutex_lock(mbedtls_threading_mutex_t *mutex)
225 {
226     int ret = MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
227 
228     if (mutex->is_valid == 1)
229     {
230         if (xSemaphoreTake(mutex->mutex, portMAX_DELAY))
231         {
232             ret = 0;
233         }
234         else
235         {
236             ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
237         }
238     }
239 
240     return ret;
241 }
242 
243 /**
244  * @brief Implementation of mbedtls_mutex_unlock for thread-safety.
245  *
246  * @return 0 if successful, MBEDTLS_ERR_THREADING_MUTEX_ERROR if timeout,
247  * MBEDTLS_ERR_THREADING_BAD_INPUT_DATA if the mutex is not valid.
248  */
mcux_mbedtls_mutex_unlock(mbedtls_threading_mutex_t * mutex)249 int mcux_mbedtls_mutex_unlock(mbedtls_threading_mutex_t *mutex)
250 {
251     int ret = MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
252 
253     if (mutex->is_valid == 1)
254     {
255         if (xSemaphoreGive(mutex->mutex))
256         {
257             ret = 0;
258         }
259         else
260         {
261             ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
262         }
263     }
264 
265     return ret;
266 }
267 
CRYPTO_ConfigureThreadingMcux(void)268 static void CRYPTO_ConfigureThreadingMcux(void)
269 {
270     /* Configure mbedtls to use FreeRTOS mutexes. */
271     mbedtls_threading_set_alt(mcux_mbedtls_mutex_init, mcux_mbedtls_mutex_free, mcux_mbedtls_mutex_lock,
272                               mcux_mbedtls_mutex_unlock);
273 }
274 #endif /* defined(MBEDTLS_MCUX_FREERTOS_THREADING_ALT) */
275