1 /***************************************************************************//** 2 * @file 3 * @brief Silicon Labs Secure Engine Manager API. 4 ******************************************************************************* 5 * # License 6 * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b> 7 ******************************************************************************* 8 * 9 * SPDX-License-Identifier: Zlib 10 * 11 * The licensor of this software is Silicon Laboratories Inc. 12 * 13 * This software is provided 'as-is', without any express or implied 14 * warranty. In no event will the authors be held liable for any damages 15 * arising from the use of this software. 16 * 17 * Permission is granted to anyone to use this software for any purpose, 18 * including commercial applications, and to alter it and redistribute it 19 * freely, subject to the following restrictions: 20 * 21 * 1. The origin of this software must not be misrepresented; you must not 22 * claim that you wrote the original software. If you use this software 23 * in a product, an acknowledgment in the product documentation would be 24 * appreciated but is not required. 25 * 2. Altered source versions must be plainly marked as such, and must not be 26 * misrepresented as being the original software. 27 * 3. This notice may not be removed or altered from any source distribution. 28 * 29 ******************************************************************************/ 30 #ifndef SL_SE_MANAGER_H 31 #define SL_SE_MANAGER_H 32 33 #include "sli_se_manager_features.h" 34 #if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) 35 36 /***************************************************************************//** 37 * @addtogroup sl_se_manager SE Manager 38 * @{ 39 ******************************************************************************/ 40 41 /***************************************************************************//** 42 * @addtogroup sl_se_manager_core Core 43 * 44 * @brief 45 * Secure Engine Manager Core API 46 * 47 * @details 48 * API for initialization of SE Manager and SE command context with yield 49 * attribute. 50 * 51 * @{ 52 ******************************************************************************/ 53 54 #if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT) 55 #include "sl_se_manager_key_handling.h" 56 #include "sl_se_manager_cipher.h" 57 #endif // SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT 58 #include "sl_se_manager_types.h" 59 60 #include "sli_se_manager_mailbox.h" 61 #include "sl_status.h" 62 #include <stdint.h> 63 #include <stdbool.h> 64 #include <stddef.h> 65 66 #ifdef __cplusplus 67 extern "C" { 68 #endif 69 70 // ----------------------------------------------------------------------------- 71 // Prototypes 72 73 /***************************************************************************//** 74 * @brief 75 * Initialize the SE Manager. 76 * 77 * @details 78 * Initialize the SE Manager by checking hardware availability and setting up 79 * internal module specific resources like mutexes etc. 80 * 81 * @return 82 * Status code, @ref sl_status.h. 83 ******************************************************************************/ 84 sl_status_t sl_se_init(void); 85 86 /***************************************************************************//** 87 * @brief 88 * Denitialize the SE Manager. 89 * 90 * @details 91 * Free resources held by the SE Manager. 92 * 93 * @return 94 * Status code, @ref sl_status.h. 95 ******************************************************************************/ 96 sl_status_t sl_se_deinit(void); 97 98 #if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT) 99 /***************************************************************************//** 100 * @brief 101 * Set the yield attribute of the SE command context object. 102 * 103 * @param[in,out] cmd_ctx 104 * Pointer to an SE command context object. 105 * 106 * @param[in] yield 107 * The user may set this parameter to true in order to tell the SE Manager 108 * to yield the cpu core while waiting for the SE mailbox command to complete. 109 * If false, the SE Manager will busy-wait, by polling the SE mailbox response 110 * register until the SE mailbox command completes. 111 * 112 * @return 113 * Status code, @ref sl_status.h. 114 ******************************************************************************/ 115 sl_status_t sl_se_set_yield(sl_se_command_context_t *cmd_ctx, 116 bool yield); 117 #endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT 118 119 #if defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) 120 /***************************************************************************//** 121 * @brief 122 * From VSE mailbox read which command, if any, was executed. 123 * 124 * @param[in,out] cmd_ctx 125 * Pointer to an SE command context object. If this function returns 126 * SL_STATUS_OK the command word of the SE command context object will be set. 127 * 128 * @return 129 * Status code, @ref sl_status.h. 130 ******************************************************************************/ 131 sl_status_t sl_se_read_executed_command(sl_se_command_context_t *cmd_ctx); 132 133 /***************************************************************************//** 134 * @brief 135 * Acknowledge and get status and output data of a completed command. 136 * 137 * @details 138 * This function acknowledges and gets the status and output data of a 139 * completed mailbox command. The acknowledge operation invalidates the 140 * contents of the output mailbox. The output data is copied into the linked 141 * list of output buffers pointed to in the given command data structure. 142 * 143 * @param[in,out] cmd_ctx 144 * Pointer to an SE command context object. 145 * 146 * @return 147 * Status code, @ref sl_status.h. 148 ******************************************************************************/ 149 sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx); 150 #endif //defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) 151 152 /***************************************************************************//** 153 * @brief 154 * Initialize an SE command context object 155 * 156 * @details 157 * Initialize an SE command context which can be used in subsequent calls to 158 * the SE Manager API in order to execute SE mailbox commands. 159 * 160 * @param[in,out] cmd_ctx 161 * Pointer to an SE command context object to be initialized. This context 162 * object should be used in subsequent calls to the SE Manager API in order 163 * to execute SE mailbox commands. The same command context object cannot be 164 * used concurrently, e.g. by two different threads. However a command context 165 * object may be reused for the next and any subsequent mailbox operatons, 166 * except when streaming commands are in progress in which case only streaming 167 * commands of the same operation type is allowed until the streaming operation 168 * is finished (i.e. the corresponding sl_se_xxx_finish is called). 169 * 170 * @return 171 * Status code, @ref sl_status.h. 172 ******************************************************************************/ 173 sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx); 174 175 /***************************************************************************//** 176 * @brief 177 * De-initialize an SE command context 178 * 179 * @details 180 * De-initialize an SE command context object. 181 * 182 * @param[in,out] cmd_ctx 183 * Pointer to an SE command context object to deinitialize. 184 * 185 * @return 186 * Status code, @ref sl_status.h. 187 ******************************************************************************/ 188 sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx); 189 190 #ifdef __cplusplus 191 } 192 #endif 193 194 /// @} (end addtogroup sl_se_manager_core) 195 /// @} (end addtogroup sl_se_manager) 196 197 #endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) 198 199 #endif // SL_SE_MANAGER_H 200 201 // THE REST OF THE FILE IS DOCUMENTATION ONLY 202 /// @addtogroup sl_se_manager 203 /// @{ 204 /// @details 205 /// 206 /// The Secure Engine (SE) Manager provides thread-safe APIs for the Secure Engine's mailbox interface. Note that PSA Crypto is the recommended device independent crypto API and should be used 207 /// whenever possible. The SE manager APIs can be used directly for performance or space constrained applications. 208 /// 209 /// Available functionality will vary between devices: device management, such as secure firmware upgrade, secure boot and secure debug implementation, is available on all series 2 devices. 210 /// Devices with the SE subsystem includes a low level crypto API where the SE Manager will use the SE hardware peripherals to accelerate cryptographic operations. Finally, Vault High 211 /// devices also include secure key storage functionality, anti-tamper protection, advanced crypto API and attestation. 212 /// 213 /// @note Below are some of the useful application notes linked with Secure Engine Manager:\n 214 /// - <a href="https://www.silabs.com/documents/public/application-notes/an1190-efr32-secure-debug.pdf">AN1190: Series 2 Secure Debug</a>\n 215 /// - <a href="https://www.silabs.com/documents/public/application-notes/an1247-efr32-secure-vault-tamper.pdf">AN1247: Anti-Tamper Protection Configuration and Use</a>\n 216 /// - <a href="https://www.silabs.com/documents/public/application-notes/an1268-efr32-secure-identity.pdf">AN1268: Authenticating Silicon Labs Devices Using Device Certificates</a>\n 217 /// - <a href="https://www.silabs.com/documents/public/application-notes/an1271-efr32-secure-key-storage.pdf">AN1271: Secure Key Storage</a>\n 218 /// - <a href="https://www.silabs.com/documents/public/application-notes/an1218-secure-boot-with-rtsl.pdf">AN1218: Series 2 Secure Boot with RTSL</a>\n 219 /// 220 /// # Functionality 221 /// 222 /// The functionality of the SE Manager includes 223 /// 224 /// - Core API, inititalizing of SE Manager and SE command context (@ref sl_se_manager_core) 225 /// - Secure key storage (@ref sl_se_manager_key_handling) 226 /// - Key wrapping 227 /// - Storing keys in the SE volatile storage 228 /// - Using key by reference 229 /// - Configuration of tamper responses (@ref sl_se_manager_util) 230 /// - The available signals include core hard-fault, glitch detectors, PRS, and failed authenticated commands, 231 /// while the responses vary from triggering an interrupt to the hardware autonomously erasing the one-time-programmable (OTP) memory 232 /// - Block ciphers (@ref sl_se_manager_cipher) 233 /// - Supports AES-ECB, AES-CBC, AES-CFB128, AES-CFB8, AES-CTR, AES-CCM, AES-GCM, CMAC, HMAC and ChaCha20/Poly1305 234 /// - The cipher operations can be performed using plaintext keys, wrapped keys or referencing a key in the SE 235 /// - Streaming operations are supported for AES-GCM and CMAC 236 /// - Block and streaming hash operations (@ref sl_se_manager_hash) 237 /// - Supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 238 /// - True Random Number Generator (@ref sl_se_manager_entropy) 239 /// - Hardware block inside the SE used for generating random numbers. Can be used as a source of entropy, or to securely generate keys inside the SE 240 /// - Elliptic Curve Signature operation (@ref sl_se_manager_signature) 241 /// - ECDSA and EDDSA 242 /// - Key agreement (@ref sl_se_manager_key_derivation) 243 /// - Perform Elliptic Curve Diffie-Hellman and J-PAKE key agreement operations inside the SE 244 /// - Key derivation functions (@ref sl_se_manager_key_derivation) 245 /// - Perform HKDF and PBKDF2 key derivation functions inside the SE 246 /// - Device configuration and utilities (@ref sl_se_manager_util) 247 /// - Write to user data stored inside the SE 248 /// - Configuration of debug locks 249 /// - Configuration of secure boot 250 /// - Configuration of flash lock 251 /// - Read SE OTP contents 252 /// - Read SE firmware version 253 /// - Read provisioned certificates 254 /// - Multi-thread safe APIs for MicriumOS and FreeRTOS 255 /// - Retrieveing attestation tokens (@ref sl_se_manager_attestation) 256 /// 257 /// ## Key Storage and Use of SE Wrapped Keys 258 /// 259 /// The way keys are stored and operated on depends on the options set in the key descriptor used (@ref sl_se_key_descriptor_t). 260 /// Each key descriptor is initialized with a storage location, a key type, and length of the key (some key types have a known length, and it is not required to be set). 261 /// The storage location can either be application memory or inside the SE, for more details, see @ref sl_se_storage_method_t. 262 /// Depending on the use-case, the key descriptors will also store the pointer to a key and an SE key slot, see @ref sl_se_key_slot_t for the list of available internal SE key slots. 263 /// 264 /// For more information on the key handling APIs see @ref sl_se_manager_key_handling. 265 /// 266 /// ### Supported Key Types 267 /// Symmetric keys 268 /// - AES-128 (16 bytes) 269 /// - AES-192 (24 bytes) 270 /// - AES-256 (32 bytes) 271 /// - ChaCha20 (32 bytes) 272 /// 273 /// Asymmetric keys for ECC 274 /// - NIST P-192 275 /// - NIST P-256 276 /// - NIST P-384 277 /// - NIST P-521 278 /// - Curve25519 279 /// - Curve448 280 /// 281 /// Custom Weierstrass Prime curves are also supported (@ref sl_se_custom_weierstrass_prime_domain_t). 282 /// 283 /// ### Example Usage of Keys 284 /// 285 /// @code{.c} 286 /// #define WRAPPED_KEY_OVERHEAD (12UL + 16UL) 287 /// #define AES_256_KEY_SIZE 32UL 288 /// 289 /// uint8_t key_buffer[AES_256_KEY_SIZE]; 290 /// uint8_t wrapped_key_buffer[AES_256_KEY_SIZE + WRAPPED_KEY_OVERHEAD]; 291 /// 292 /// void demo_se_create_key_in_slot(void) { 293 /// sl_se_key_descriptor_t new_key = { 294 /// .type = SL_SE_KEY_TYPE_AES_256, 295 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 296 /// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE, 297 /// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0, 298 /// }; 299 /// sl_se_generate_key(&new_key); 300 /// } 301 /// 302 /// void demo_se_create_plaintext_key(void) { 303 /// sl_se_key_descriptor_t new_key = { 304 /// .type = SL_SE_KEY_TYPE_AES_256, 305 /// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT, 306 /// }; 307 /// new_key.storage.location.buffer.pointer = key_buffer; 308 /// new_key.storage.location.buffer.size = sizeof(key_buffer); 309 /// sl_se_generate_key(&new_key); 310 /// } 311 /// 312 /// void demo_se_create_wrapped_key(void) { 313 /// sl_se_key_descriptor_t new_wrapped_key = { 314 /// .type = SL_SE_KEY_TYPE_AES_256, 315 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 316 /// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED, 317 /// }; 318 /// new_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer; 319 /// new_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer); 320 /// sl_se_generate_key(&new_wrapped_key); 321 /// } 322 /// 323 /// void demo_se_wrapped_key_to_volatile_slot(void) { 324 /// sl_se_key_descriptor_t existing_wrapped_key = { 325 /// .type = SL_SE_KEY_TYPE_AES_256, 326 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 327 /// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED, 328 /// }; 329 /// existing_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer; 330 /// existing_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer); 331 /// sl_se_key_descriptor_t key_in_slot = { 332 /// .type = SL_SE_KEY_TYPE_AES_256, 333 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 334 /// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE, 335 /// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0, 336 /// }; 337 /// sl_se_import_key(&existing_wrapped_key, &key_in_slot); 338 /// } 339 /// 340 /// void demo_se_volatile_slot_to_wrapped_key(void) { 341 /// sl_se_key_descriptor_t existing_volatile_key = { 342 /// .type = SL_SE_KEY_TYPE_AES_256, 343 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 344 /// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE, 345 /// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0, 346 /// }; 347 /// sl_se_key_descriptor_t wrapped_key_out = { 348 /// .type = SL_SE_KEY_TYPE_AES_256, 349 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 350 /// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED, 351 /// }; 352 /// wrapped_key_out.storage.location.buffer.pointer = wrapped_key_buffer; 353 /// wrapped_key_out.storage.location.buffer.size = sizeof(wrapped_key_buffer); 354 /// sl_se_export_key(&existing_volatile_key, &wrapped_key_out); 355 /// } 356 /// 357 /// void demo_se_delete_from_volatile_slot(void) { 358 /// sl_se_key_descriptor_t existing_volatile_key = { 359 /// .type = SL_SE_KEY_TYPE_AES_256, 360 /// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, 361 /// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE, 362 /// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0, 363 /// }; 364 /// sl_se_delete_key(&existing_volatile_key); 365 /// } 366 /// @endcode 367 /// 368 /// ## Tamper 369 /// 370 /// The Secure Engine (SE) tamper module connects a number of hardware and software-driven tamper signals to a set of configurable hardware and software responses. 371 /// This can be used to program the device to automatically respond to external events that could signal that someone is trying to tamper with the device, 372 /// and very rapidly remove secrets stored in the SE. The available tamper signals range from signals based on failed authentication and secure boot to specialized glitch detectors. 373 /// When any of these signals fire, the tamper block can be configured to trigger several different responses, 374 /// ranging from triggering an interrupt to erasing the one-time-programmable (OTP) memory, removing all SE secrets and resulting in a permanently destroyed device. 375 /// 376 /// A tamper signal can lead to a series of different autonomous responses from the tamper module. These responses are listed in the table below. 377 /// | | Response | Description | 378 /// | ----: | :----: | :---- | 379 /// | 0 | Ignore | No action is taken. | 380 /// | 1 | Interrupt | The SETAMPERHOST interrupt on the host is triggered. | 381 /// | 2 | Filter | A counter in the tamper filter is increased. | 382 /// | 4 | Reset | The device is reset. | 383 /// | 7 | Erase OTP | Erases the OTP configuration of the device. | 384 /// 385 /// These responses are cumulative, meaning that if a filter response is triggered, an interrupt will also be triggered. For a full overview of the tamper signals, see @ref sl_se_manager_defines.h. 386 /// 387 /// The tamper configuration is one-time-programmable, and is done using the initialise OTP command to the SE (see @ref sl_se_init_otp). 388 /// This means that tamper settings must be written together with secure boot settings, and are immutable after they are written. 389 /// After tamper has been initialized, it is possible to temporarily disable one or several tamper signals using an authenticated command, 390 /// similar to secure debug unlock. This is only possible if the debug public key has been installed on the device. 391 /// It is only possible to disable the customer enabled response. The default response to a signal cannot be disabled. 392 /// 393 /// Tamper is configured by providing the following: 394 /// <table> 395 /// <caption id="multi_row">Tamper configuration table</caption> 396 /// <tr><th>Setting <th>Description 397 /// <tr><td>Tamper response levels <td>A response level for each tamper signal.\n\n It is not possible to degrade the default response level of a tamper signal, so if a response is set to a lower level than the default response level listed in the table in the Signals section, this won't have any effect. 398 /// <tr><td>Filter settings <td>The tamper filter counter has two settings: 399 /// <ul> 400 /// <li>Reset period 401 /// <li>Trigger threshold 402 /// </ul> 403 /// These options can be set to the values given in the tables in the Response Filter section. Please see the examples section for a suggested use of the tamper filter signal. 404 /// <tr><td>Flags <td>The tamper flags is used to configure two options: 405 /// <ul> 406 /// <li>Digital Glitch Detector Always On – This option will keep the digital glitch detector running even while the SE is not performing any operations. This leads to increased energy consumption. 407 /// <li>Keep Tamper Alive During Sleep (not available on EFR32xG21B devices) – If set, the tamper module keeps running at sleep mode (down to EM3). 408 /// </ul> 409 /// <tr><td>Reset threshold <td>The number of consecutive tamper resets before the the part enters debug mode.\n\n 410 /// If the threshold is set to 0, the part will never enter the debug mode due to tamper reset. 411 /// </table> 412 /// 413 /// ### Example Usage 414 /// 415 /// The glitch detectors can see spurious activations, and should typically not be used to directly drive a serious tamper response. 416 /// Instead they should feed their signals into a tamper interrupt (to handle the response logic on the M33), or into the tamper filter counter, 417 /// which can be used to activate a high level response if a number of incidents occur in a short time window. 418 /// The time period and counter threshold must be tuned to the use case. In the following example the device will erase OTP and become inoperable if 4 glitch signals is seen in a 1 minute time period. 419 /// 420 /// Since you can only configure tamper once for each device, please make sure that this is the configuration you actually want before you execute this example on actual device. 421 /// 422 /// @code{.c} 423 /// sl_se_otp_init_t otp_settings_init = SL_SE_OTP_INIT_DEFAULT; 424 /// 425 /// // Configure tamper levels 426 /// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_FILTER] = SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP; 427 /// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHFALLING] = SL_SE_TAMPER_LEVEL_FILTER; 428 /// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHRISING] = SL_SE_TAMPER_LEVEL_FILTER; 429 /// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_DGLITCH] = SL_SE_TAMPER_LEVEL_FILTER; 430 /// 431 /// 432 /// // Configure tamper filter options 433 /// otp_settings_init.tamper_filter_period = SL_SE_TAMPER_FILTER_PERIOD_1MIN; 434 /// otp_settings_init.tamper_filter_threshold = SL_SE_TAMPER_FILTER_THRESHOLD_4; 435 /// 436 /// 437 /// // Commit OTP settings. This command is only available once! 438 /// sl_se_init_otp(&otp_settings_init); 439 /// @endcode 440 /// 441 /// ## RTOS Mode and Multi-Thread Safety 442 /// 443 /// @note The SE Manager API is multi-thread safe, but does not support preemption. 444 /// This means the API cannot be called from ISR or critical/atomic sections when running in an RTOS thread. 445 /// When using the SE Manager API in a bare-metal application, it is the application developer's responsibility 446 /// to not call the SE Manager APIs when another operation is in progress. 447 /// 448 /// The SE Manager supports multi-thread safe APIs for MicriumOS and FreeRTOS interfacing with CMSIS RTOS2 APIs. 449 /// 450 /// In the cases where Micrium OS or FreeRTOS are included in the project (RTOS-mode), the SE Manager will be configured with threading and yield support. 451 /// Configure ::sl_se_command_context_t with ::sl_se_set_yield to yield the CPU core when the SE Manager is waiting for the Secure Engine to complete a mailbox command. 452 /// 453 /// For threading support the SE Manager applies an SE lock mechanism to protect the Secure Engine Mailbox interface from being accessed by more than one thread, 454 /// ensuring multi-thread safety. For yielding the CPU core while waiting for the SE, the SE Manager APIs that invoke 455 /// SE mailbox commands will wait on a semaphore which is signaled in the ISR that handles the SE mailbox completion interrupt. 456 /// Hence other threads may run on the CPU core while the SE is processing the mailbox command. 457 /// 458 /// @} (end addtogroup sl_se_manager) 459