Branch data Line data Source code
1 : : /** 2 : : * Copyright (c) 2019 Nordic Semiconductor ASA 3 : : * 4 : : * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause 5 : : */ 6 : : #include <stdint.h> 7 : : #include <stddef.h> 8 : : #include <string.h> 9 : : 10 : : #include <zephyr.h> 11 : : #include <kernel.h> 12 : : 13 : : BUILD_ASSERT(IS_ENABLED(CONFIG_MULTITHREADING), 14 : : "This file is intended for multi-threading, but single-threading is enabled. " 15 : : "Please check your config build configuration!"); 16 : : 17 : : #if defined(NRF5340_XXAA_APPLICATION) 18 : : #include <hal/nrf_mutex.h> 19 : : #endif /* defined(NRF5340_XXAA_APPLICATION) */ 20 : : 21 : : #include "nrf_cc3xx_platform_defines.h" 22 : : #include "nrf_cc3xx_platform_mutex.h" 23 : : #include "nrf_cc3xx_platform_abort.h" 24 : : 25 : : /** @brief External reference to the platforms abort APIs 26 : : * This is used in case the mutex functions don't 27 : : * provide return values in their APIs. 28 : : */ 29 : : extern nrf_cc3xx_platform_abort_apis_t platform_abort_apis; 30 : : 31 : : #if CONFIG_CC3XX_MUTEX_LOCK 32 : : 33 : : /** @brief Definition of mutex for symmetric cryptography 34 : : */ 35 : : K_MUTEX_DEFINE(sym_mutex_int); 36 : : 37 : : /** @brief Definition of mutex for asymmetric cryptography 38 : : */ 39 : : K_MUTEX_DEFINE(asym_mutex_int); 40 : : 41 : : /** @brief Definition of mutex for power mode changes 42 : : */ 43 : : K_MUTEX_DEFINE(power_mutex_int); 44 : : 45 : : /** @brief Definition of mutex for heap allocations 46 : : */ 47 : : K_MUTEX_DEFINE(heap_mutex_int); 48 : : 49 : : #elif CONFIG_CC3XX_ATOMIC_LOCK 50 : : 51 : : /** @brief Definition of mutex for symmetric cryptography 52 : : */ 53 : : static atomic_t sym_mutex_int; 54 : : 55 : : /** @brief Definition of mutex for asymmetric cryptography 56 : : */ 57 : : static atomic_t asym_mutex_int; 58 : : 59 : : /** @brief Definition of mutex for power mode changes 60 : : */ 61 : : static atomic_t power_mutex_int; 62 : : 63 : : /** @brief Definition of mutex for heap allocations 64 : : */ 65 : : static atomic_t heap_mutex_int; 66 : : 67 : : #elif defined(NRF5340_XXAA_APPLICATION) && NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX 68 : : 69 : : typedef enum { 70 : : HW_MUTEX_SYM_CRYPTO = 15, 71 : : HW_MUTEX_ASYM_CRYPTO = 14, 72 : : HW_MUTEX_POWER_MODE = 13, 73 : : HW_MUTEX_HEAP_ALLOC = 12, 74 : : } hw_mutex_t; 75 : : 76 : : /** @brief Definition of mutex for symmetric cryptography 77 : : */ 78 : : static hw_mutex_t sym_mutex_int = HW_MUTEX_SYM_CRYPTO; 79 : : 80 : : /** @brief Definition of mutex for asymmetric cryptography 81 : : */ 82 : : static hw_mutex_t asym_mutex_int = HW_MUTEX_ASYM_CRYPTO; 83 : : 84 : : /** @brief Definition of mutex for power mode changes 85 : : */ 86 : : static hw_mutex_t power_mutex_int = HW_MUTEX_POWER_MODE; 87 : : 88 : : /** @brief Definition of mutex for heap allocations 89 : : */ 90 : : static hw_mutex_t heap_mutex_int = HW_MUTEX_HEAP_ALLOC; 91 : : 92 : : #else 93 : : #error "Improper configuration of the lock variant!" 94 : : #endif 95 : : 96 : : /** @brief Definition of mutex for random number generation 97 : : */ 98 : : K_MUTEX_DEFINE(rng_mutex_int); 99 : : 100 : : /** @brief Arbritary number of mutexes the system suppors 101 : : */ 102 : : #define NUM_MUTEXES 64 103 : : 104 : : /** @brief Structure definition of the mutex slab 105 : : */ 106 : : struct k_mem_slab mutex_slab; 107 : : 108 : : /** @brief Definition of buffer used for the mutex slabs 109 : : */ 110 : : char __aligned(4) mutex_slab_buffer[NUM_MUTEXES * sizeof(struct k_mutex)]; 111 : : 112 : : /**@brief Definition of RTOS-independent symmetric cryptography mutex 113 : : * with NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that 114 : : * allocation is unneccesary 115 : : */ 116 : : static nrf_cc3xx_platform_mutex_t sym_mutex = { 117 : : .mutex = &sym_mutex_int, 118 : : .flags = IS_ENABLED(CONFIG_CC3XX_ATOMIC_LOCK) ? 119 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC : 120 : : IS_ENABLED(CONFIG_CC3XX_HW_MUTEX_LOCK) ? 121 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX : 122 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID 123 : : }; 124 : : 125 : : /**@brief Definition of RTOS-independent asymmetric cryptography mutex 126 : : * with NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that 127 : : * allocation is unneccesary 128 : : */ 129 : : static nrf_cc3xx_platform_mutex_t asym_mutex = { 130 : : .mutex = &asym_mutex_int, 131 : : .flags = IS_ENABLED(CONFIG_CC3XX_ATOMIC_LOCK) ? 132 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC : 133 : : IS_ENABLED(CONFIG_CC3XX_HW_MUTEX_LOCK) ? 134 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX : 135 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID 136 : : }; 137 : : 138 : : /**@brief Definition of RTOS-independent random number generation mutex 139 : : * with NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that 140 : : * allocation is unneccesary 141 : : */ 142 : : static nrf_cc3xx_platform_mutex_t rng_mutex = { 143 : : .mutex = &rng_mutex_int, 144 : : .flags = NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID 145 : : }; 146 : : 147 : : /**@brief Definition of RTOS-independent power management mutex 148 : : * with NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that 149 : : * allocation is unneccesary 150 : : */ 151 : : static nrf_cc3xx_platform_mutex_t power_mutex = { 152 : : .mutex = &power_mutex_int, 153 : : .flags = IS_ENABLED(CONFIG_CC3XX_ATOMIC_LOCK) ? 154 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC : 155 : : IS_ENABLED(CONFIG_CC3XX_HW_MUTEX_LOCK) ? 156 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX : 157 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID 158 : : }; 159 : : 160 : : /** @brief Definition of RTOS-independent heap allocation mutex 161 : : * with NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID set to indicate that 162 : : * allocation is unneccesary 163 : : * 164 : : * @note This symbol can't be static as it is referenced in the replacement 165 : : * file mbemory_buffer_alloc.c inside the heap structure. 166 : : */ 167 : : nrf_cc3xx_platform_mutex_t heap_mutex = { 168 : : .mutex = &heap_mutex_int, 169 : : .flags = IS_ENABLED(CONFIG_CC3XX_ATOMIC_LOCK) ? 170 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC : 171 : : IS_ENABLED(CONFIG_CC3XX_HW_MUTEX_LOCK) ? 172 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX : 173 : : NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID 174 : : }; 175 : : 176 : : /**@brief static function to initialize a mutex 177 : : */ 178 : 0 : static void mutex_init_platform(nrf_cc3xx_platform_mutex_t *mutex) { 179 : : int ret; 180 : : struct k_mutex * p_mutex; 181 : : 182 : : /* Ensure that the mutex is valid (not NULL) */ 183 [ # # ]: 0 : if (mutex == NULL) { 184 : 0 : platform_abort_apis.abort_fn( 185 : : "mutex_init called with NULL parameter"); 186 : : } 187 : : /* Atomic mutex has been initialized statically */ 188 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC || 189 [ # # ]: 0 : mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX) { 190 : 0 : return; 191 : : } 192 : : 193 : : /* Allocate if this has not been initialized statically */ 194 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_INVALID && 195 [ # # ]: 0 : mutex->mutex == NULL) { 196 : : /* Allocate some memory for the mutex */ 197 : 0 : ret = k_mem_slab_alloc(&mutex_slab, &mutex->mutex, K_FOREVER); 198 [ # # # # ]: 0 : if(ret != 0 || mutex->mutex == NULL) 199 : : { 200 : : /* Allocation failed. Abort all operations */ 201 : 0 : platform_abort_apis.abort_fn( 202 : : "Could not allocate mutex before initializing"); 203 : : } 204 : : 205 : 0 : memset(mutex->mutex, 0, sizeof(struct k_mutex)); 206 : : 207 : : /** Set a flag to ensure that mutex is deallocated by the freeing 208 : : * operation 209 : : */ 210 : 0 : mutex->flags |= NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ALLOCATED; 211 : : } 212 : : 213 : 0 : p_mutex = (struct k_mutex *)mutex->mutex; 214 : 0 : k_mutex_init(p_mutex); 215 : : 216 : : /* Set the mask to indicate that the mutex is valid */ 217 : 0 : mutex->flags |= NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_VALID; 218 : : } 219 : : 220 : : 221 : : /** @brief Static function to free a mutex 222 : : */ 223 : 0 : static void mutex_free_platform(nrf_cc3xx_platform_mutex_t *mutex) { 224 : : /* Ensure that the mutex is valid (not NULL) */ 225 [ # # ]: 0 : if (mutex == NULL) { 226 : 0 : platform_abort_apis.abort_fn( 227 : : "mutex_init called with NULL parameter"); 228 : : } 229 : : 230 : : /* Check if we are freeing a mutex that is atomic */ 231 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC || 232 [ # # ]: 0 : mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX) { 233 : : /*Nothing to free*/ 234 : 0 : return; 235 : : } 236 : : 237 : : /* Check if we are freeing a mutex that isn't initialized */ 238 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_INVALID) { 239 : : /*Nothing to free*/ 240 : 0 : return; 241 : : } 242 : : 243 : : /* Check if the mutex was allocated or being statically defined */ 244 [ # # ]: 0 : if ((mutex->flags & NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ALLOCATED) != 0) { 245 : 0 : k_mem_slab_free(&mutex_slab, &mutex->mutex); 246 : 0 : mutex->mutex = NULL; 247 : : } 248 : : else { 249 : 0 : memset(mutex->mutex, 0, sizeof(struct k_mutex)); 250 : : } 251 : : 252 : : /* Reset the mutex to invalid state */ 253 : 0 : mutex->flags = NRF_CC3XX_PLATFORM_MUTEX_MASK_INVALID; 254 : : } 255 : : 256 : : 257 : : /** @brief Static function to lock a mutex 258 : : */ 259 : 0 : static int32_t mutex_lock_platform(nrf_cc3xx_platform_mutex_t *mutex) { 260 : : int ret; 261 : : struct k_mutex * p_mutex; 262 : : 263 : : /* Ensure that the mutex param is valid (not NULL) */ 264 [ # # ]: 0 : if(mutex == NULL) { 265 : 0 : return NRF_CC3XX_PLATFORM_ERROR_PARAM_NULL; 266 : : } 267 : : 268 [ # # # ]: 0 : switch (mutex->flags) { 269 : 0 : case NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC: 270 : 0 : return atomic_cas((atomic_t *)mutex->mutex, 0, 1) ? 271 [ # # ]: 0 : NRF_CC3XX_PLATFORM_SUCCESS : 272 : : NRF_CC3XX_PLATFORM_ERROR_MUTEX_FAILED; 273 : : 274 : : #if defined(NRF5340_XXAA_APPLICATION) 275 : : 276 : 0 : case NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX: 277 : 0 : return nrf_mutex_lock(NRF_MUTEX, *((uint8_t *)mutex->mutex)) ? 278 [ # # ]: 0 : NRF_CC3XX_PLATFORM_SUCCESS : 279 : : NRF_CC3XX_PLATFORM_ERROR_MUTEX_FAILED; 280 : : 281 : : #endif /* defined(NRF5340_XXAA_APPLICATION) */ 282 : : 283 : 0 : default: 284 : : /* Ensure that the mutex has been initialized */ 285 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_INVALID) { 286 : 0 : return NRF_CC3XX_PLATFORM_ERROR_MUTEX_NOT_INITIALIZED; 287 : : } 288 : : 289 : 0 : p_mutex = (struct k_mutex *)mutex->mutex; 290 : : 291 : 0 : ret = k_mutex_lock(p_mutex, K_FOREVER); 292 [ # # ]: 0 : if (ret == 0) { 293 : 0 : return NRF_CC3XX_PLATFORM_SUCCESS; 294 : : } else { 295 : 0 : return NRF_CC3XX_PLATFORM_ERROR_MUTEX_FAILED; 296 : : } 297 : : } 298 : : } 299 : : 300 : : /** @brief Static function to unlock a mutex 301 : : */ 302 : 0 : static int32_t mutex_unlock_platform(nrf_cc3xx_platform_mutex_t *mutex) { 303 : : struct k_mutex * p_mutex; 304 : : 305 : : /* Ensure that the mutex param is valid (not NULL) */ 306 [ # # ]: 0 : if(mutex == NULL) { 307 : 0 : return NRF_CC3XX_PLATFORM_ERROR_PARAM_NULL; 308 : : } 309 : : 310 [ # # # ]: 0 : switch (mutex->flags) 311 : : { 312 : 0 : case NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_ATOMIC: 313 : 0 : return atomic_cas((atomic_t *)mutex->mutex, 1, 0) ? 314 [ # # ]: 0 : NRF_CC3XX_PLATFORM_SUCCESS : 315 : : NRF_CC3XX_PLATFORM_ERROR_MUTEX_FAILED; 316 : : 317 : : 318 : : #if defined(NRF5340_XXAA_APPLICATION) 319 : : 320 : 0 : case NRF_CC3XX_PLATFORM_MUTEX_MASK_IS_HW_MUTEX: 321 : 0 : nrf_mutex_unlock(NRF_MUTEX, *((uint8_t *)mutex->mutex)); 322 : 0 : return NRF_CC3XX_PLATFORM_SUCCESS; 323 : : 324 : : #endif /* defined(NRF5340_XXAA_APPLICATION) */ 325 : : 326 : 0 : default: 327 : : /* Ensure that the mutex has been initialized */ 328 [ # # ]: 0 : if (mutex->flags == NRF_CC3XX_PLATFORM_MUTEX_MASK_INVALID) { 329 : 0 : return NRF_CC3XX_PLATFORM_ERROR_MUTEX_NOT_INITIALIZED; 330 : : } 331 : : 332 : 0 : p_mutex = (struct k_mutex *)mutex->mutex; 333 : : 334 : 0 : k_mutex_unlock(p_mutex); 335 : 0 : return NRF_CC3XX_PLATFORM_SUCCESS; 336 : : } 337 : : } 338 : : 339 : : /**@brief Constant definition of mutex APIs to set in nrf_cc3xx_platform 340 : : */ 341 : : static const nrf_cc3xx_platform_mutex_apis_t mutex_apis = 342 : : { 343 : : .mutex_init_fn = mutex_init_platform, 344 : : .mutex_free_fn = mutex_free_platform, 345 : : .mutex_lock_fn = mutex_lock_platform, 346 : : .mutex_unlock_fn = mutex_unlock_platform 347 : : }; 348 : : 349 : : 350 : : /** @brief Constant definition of mutexes to set in nrf_cc3xx_platform 351 : : */ 352 : : static const nrf_cc3xx_platform_mutexes_t mutexes = { 353 : : .sym_mutex = &sym_mutex, 354 : : .asym_mutex = &asym_mutex, 355 : : .rng_mutex = &rng_mutex, 356 : : .reserved = NULL, 357 : : .power_mutex = &power_mutex, 358 : : }; 359 : : 360 : : /** @brief Function to initialize the nrf_cc3xx_platform mutex APIs 361 : : */ 362 : : void nrf_cc3xx_platform_mutex_init(void) 363 : : { 364 : 1 : k_mem_slab_init(&mutex_slab, 365 : : mutex_slab_buffer, 366 : : sizeof(struct k_mutex), 367 : : NUM_MUTEXES); 368 : : 369 : 1 : nrf_cc3xx_platform_set_mutexes(&mutex_apis, &mutexes); 370 : 1 : }