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