Imported more library files
Not compiling currently
This commit is contained in:
@@ -0,0 +1,458 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_H
|
||||
#define SL_SE_MANAGER_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager SE Manager
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_core Core
|
||||
*
|
||||
* @brief
|
||||
* Secure Engine Manager Core API
|
||||
*
|
||||
* @details
|
||||
* API for initialization of SE Manager and SE command context with yield
|
||||
* attribute.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_cipher.h"
|
||||
#endif // SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
#include "sl_se_manager_types.h"
|
||||
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the SE Manager.
|
||||
*
|
||||
* @details
|
||||
* Initialize the SE Manager by checking hardware availability and setting up
|
||||
* internal module specific resources like mutexes etc.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Denitialize the SE Manager.
|
||||
*
|
||||
* @details
|
||||
* Free resources held by the SE Manager.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit(void);
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set the yield attribute of the SE command context object.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] yield
|
||||
* The user may set this parameter to true in order to tell the SE Manager
|
||||
* to yield the cpu core while waiting for the SE mailbox command to complete.
|
||||
* If false, the SE Manager will busy-wait, by polling the SE mailbox response
|
||||
* register until the SE mailbox command completes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_yield(sl_se_command_context_t *cmd_ctx,
|
||||
bool yield);
|
||||
#endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
|
||||
#if defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* From VSE mailbox read which command, if any, was executed.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object. If this function returns
|
||||
* SL_STATUS_OK the command word of the SE command context object will be set.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_executed_command(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command. The acknowledge operation invalidates the
|
||||
* contents of the output mailbox. The output data is copied into the linked
|
||||
* list of output buffers pointed to in the given command data structure.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
||||
#endif //defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize an SE command context object
|
||||
*
|
||||
* @details
|
||||
* Initialize an SE command context which can be used in subsequent calls to
|
||||
* the SE Manager API in order to execute SE mailbox commands.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object to be initialized. This context
|
||||
* object should be used in subsequent calls to the SE Manager API in order
|
||||
* to execute SE mailbox commands. The same command context object cannot be
|
||||
* used concurrently, e.g. by two different threads. However a command context
|
||||
* object may be reused for the next and any subsequent mailbox operatons,
|
||||
* except when streaming commands are in progress in which case only streaming
|
||||
* commands of the same operation type is allowed until the streaming operation
|
||||
* is finished (i.e. the corresponding sl_se_xxx_finish is called).
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* De-initialize an SE command context
|
||||
*
|
||||
* @details
|
||||
* De-initialize an SE command context object.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object to deinitialize.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_H
|
||||
|
||||
// THE REST OF THE FILE IS DOCUMENTATION ONLY
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
/// @details
|
||||
///
|
||||
/// 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
|
||||
/// whenever possible. The SE manager APIs can be used directly for performance or space constrained applications.
|
||||
///
|
||||
/// 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.
|
||||
/// 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
|
||||
/// devices also include secure key storage functionality, anti-tamper protection, advanced crypto API and attestation.
|
||||
///
|
||||
/// @note Below are some of the useful application notes linked with Secure Engine Manager:\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1190-efr32-secure-debug.pdf">AN1190: Series 2 Secure Debug</a>\n
|
||||
/// - <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
|
||||
/// - <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
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1271-efr32-secure-key-storage.pdf">AN1271: Secure Key Storage</a>\n
|
||||
/// - <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
|
||||
///
|
||||
/// # Functionality
|
||||
///
|
||||
/// The functionality of the SE Manager includes
|
||||
///
|
||||
/// - Core API, inititalizing of SE Manager and SE command context (@ref sl_se_manager_core)
|
||||
/// - Secure key storage (@ref sl_se_manager_key_handling)
|
||||
/// - Key wrapping
|
||||
/// - Storing keys in the SE volatile storage
|
||||
/// - Using key by reference
|
||||
/// - Configuration of tamper responses (@ref sl_se_manager_util)
|
||||
/// - The available signals include core hard-fault, glitch detectors, PRS, and failed authenticated commands,
|
||||
/// while the responses vary from triggering an interrupt to the hardware autonomously erasing the one-time-programmable (OTP) memory
|
||||
/// - Block ciphers (@ref sl_se_manager_cipher)
|
||||
/// - Supports AES-ECB, AES-CBC, AES-CFB128, AES-CFB8, AES-CTR, AES-CCM, AES-GCM, CMAC, HMAC and ChaCha20/Poly1305
|
||||
/// - The cipher operations can be performed using plaintext keys, wrapped keys or referencing a key in the SE
|
||||
/// - Streaming operations are supported for AES-GCM and CMAC
|
||||
/// - Block and streaming hash operations (@ref sl_se_manager_hash)
|
||||
/// - Supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512
|
||||
/// - True Random Number Generator (@ref sl_se_manager_entropy)
|
||||
/// - 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
|
||||
/// - Elliptic Curve Signature operation (@ref sl_se_manager_signature)
|
||||
/// - ECDSA and EDDSA
|
||||
/// - Key agreement (@ref sl_se_manager_key_derivation)
|
||||
/// - Perform Elliptic Curve Diffie-Hellman and J-PAKE key agreement operations inside the SE
|
||||
/// - Key derivation functions (@ref sl_se_manager_key_derivation)
|
||||
/// - Perform HKDF and PBKDF2 key derivation functions inside the SE
|
||||
/// - Device configuration and utilities (@ref sl_se_manager_util)
|
||||
/// - Write to user data stored inside the SE
|
||||
/// - Configuration of debug locks
|
||||
/// - Configuration of secure boot
|
||||
/// - Configuration of flash lock
|
||||
/// - Read SE OTP contents
|
||||
/// - Read SE firmware version
|
||||
/// - Read provisioned certificates
|
||||
/// - Multi-thread safe APIs for MicriumOS and FreeRTOS
|
||||
/// - Retrieveing attestation tokens (@ref sl_se_manager_attestation)
|
||||
///
|
||||
/// ## Key Storage and Use of SE Wrapped Keys
|
||||
///
|
||||
/// The way keys are stored and operated on depends on the options set in the key descriptor used (@ref sl_se_key_descriptor_t).
|
||||
/// 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).
|
||||
/// The storage location can either be application memory or inside the SE, for more details, see @ref sl_se_storage_method_t.
|
||||
/// 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.
|
||||
///
|
||||
/// For more information on the key handling APIs see @ref sl_se_manager_key_handling.
|
||||
///
|
||||
/// ### Supported Key Types
|
||||
/// Symmetric keys
|
||||
/// - AES-128 (16 bytes)
|
||||
/// - AES-192 (24 bytes)
|
||||
/// - AES-256 (32 bytes)
|
||||
/// - ChaCha20 (32 bytes)
|
||||
///
|
||||
/// Asymmetric keys for ECC
|
||||
/// - NIST P-192
|
||||
/// - NIST P-256
|
||||
/// - NIST P-384
|
||||
/// - NIST P-521
|
||||
/// - Curve25519
|
||||
/// - Curve448
|
||||
///
|
||||
/// Custom Weierstrass Prime curves are also supported (@ref sl_se_custom_weierstrass_prime_domain_t).
|
||||
///
|
||||
/// ### Example Usage of Keys
|
||||
///
|
||||
/// @code{.c}
|
||||
/// #define WRAPPED_KEY_OVERHEAD (12UL + 16UL)
|
||||
/// #define AES_256_KEY_SIZE 32UL
|
||||
///
|
||||
/// uint8_t key_buffer[AES_256_KEY_SIZE];
|
||||
/// uint8_t wrapped_key_buffer[AES_256_KEY_SIZE + WRAPPED_KEY_OVERHEAD];
|
||||
///
|
||||
/// void demo_se_create_key_in_slot(void) {
|
||||
/// sl_se_key_descriptor_t new_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_generate_key(&new_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_create_plaintext_key(void) {
|
||||
/// sl_se_key_descriptor_t new_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
|
||||
/// };
|
||||
/// new_key.storage.location.buffer.pointer = key_buffer;
|
||||
/// new_key.storage.location.buffer.size = sizeof(key_buffer);
|
||||
/// sl_se_generate_key(&new_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_create_wrapped_key(void) {
|
||||
/// sl_se_key_descriptor_t new_wrapped_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// new_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// new_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_generate_key(&new_wrapped_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_wrapped_key_to_volatile_slot(void) {
|
||||
/// sl_se_key_descriptor_t existing_wrapped_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// existing_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// existing_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_key_descriptor_t key_in_slot = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_import_key(&existing_wrapped_key, &key_in_slot);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_volatile_slot_to_wrapped_key(void) {
|
||||
/// sl_se_key_descriptor_t existing_volatile_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_key_descriptor_t wrapped_key_out = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// wrapped_key_out.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// wrapped_key_out.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_export_key(&existing_volatile_key, &wrapped_key_out);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_delete_from_volatile_slot(void) {
|
||||
/// sl_se_key_descriptor_t existing_volatile_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_delete_key(&existing_volatile_key);
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// ## Tamper
|
||||
///
|
||||
/// 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.
|
||||
/// 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,
|
||||
/// 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.
|
||||
/// When any of these signals fire, the tamper block can be configured to trigger several different responses,
|
||||
/// ranging from triggering an interrupt to erasing the one-time-programmable (OTP) memory, removing all SE secrets and resulting in a permanently destroyed device.
|
||||
///
|
||||
/// A tamper signal can lead to a series of different autonomous responses from the tamper module. These responses are listed in the table below.
|
||||
/// | | Response | Description |
|
||||
/// | ----: | :----: | :---- |
|
||||
/// | 0 | Ignore | No action is taken. |
|
||||
/// | 1 | Interrupt | The SETAMPERHOST interrupt on the host is triggered. |
|
||||
/// | 2 | Filter | A counter in the tamper filter is increased. |
|
||||
/// | 4 | Reset | The device is reset. |
|
||||
/// | 7 | Erase OTP | Erases the OTP configuration of the device. |
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// The tamper configuration is one-time-programmable, and is done using the initialise OTP command to the SE (see @ref sl_se_init_otp).
|
||||
/// This means that tamper settings must be written together with secure boot settings, and are immutable after they are written.
|
||||
/// After tamper has been initialized, it is possible to temporarily disable one or several tamper signals using an authenticated command,
|
||||
/// similar to secure debug unlock. This is only possible if the debug public key has been installed on the device.
|
||||
/// It is only possible to disable the customer enabled response. The default response to a signal cannot be disabled.
|
||||
///
|
||||
/// Tamper is configured by providing the following:
|
||||
/// <table>
|
||||
/// <caption id="multi_row">Tamper configuration table</caption>
|
||||
/// <tr><th>Setting <th>Description
|
||||
/// <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.
|
||||
/// <tr><td>Filter settings <td>The tamper filter counter has two settings:
|
||||
/// <ul>
|
||||
/// <li>Reset period
|
||||
/// <li>Trigger threshold
|
||||
/// </ul>
|
||||
/// 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.
|
||||
/// <tr><td>Flags <td>The tamper flags is used to configure two options:
|
||||
/// <ul>
|
||||
/// <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.
|
||||
/// <li>Keep Tamper Alive During Sleep (not available on EFR32xG21B devices) – If set, the tamper module keeps running at sleep mode (down to EM3).
|
||||
/// </ul>
|
||||
/// <tr><td>Reset threshold <td>The number of consecutive tamper resets before the the part enters debug mode.\n\n
|
||||
/// If the threshold is set to 0, the part will never enter the debug mode due to tamper reset.
|
||||
/// </table>
|
||||
///
|
||||
/// ### Example Usage
|
||||
///
|
||||
/// The glitch detectors can see spurious activations, and should typically not be used to directly drive a serious tamper response.
|
||||
/// Instead they should feed their signals into a tamper interrupt (to handle the response logic on the M33), or into the tamper filter counter,
|
||||
/// which can be used to activate a high level response if a number of incidents occur in a short time window.
|
||||
/// 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.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// @code{.c}
|
||||
/// sl_se_otp_init_t otp_settings_init = SL_SE_OTP_INIT_DEFAULT;
|
||||
///
|
||||
/// // Configure tamper levels
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_FILTER] = SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHFALLING] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHRISING] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_DGLITCH] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
///
|
||||
///
|
||||
/// // Configure tamper filter options
|
||||
/// otp_settings_init.tamper_filter_period = SL_SE_TAMPER_FILTER_PERIOD_1MIN;
|
||||
/// otp_settings_init.tamper_filter_threshold = SL_SE_TAMPER_FILTER_THRESHOLD_4;
|
||||
///
|
||||
///
|
||||
/// // Commit OTP settings. This command is only available once!
|
||||
/// sl_se_init_otp(&otp_settings_init);
|
||||
/// @endcode
|
||||
///
|
||||
/// ## RTOS Mode and Multi-Thread Safety
|
||||
///
|
||||
/// @note The SE Manager API is multi-thread safe, but does not support preemption.
|
||||
/// This means the API cannot be called from ISR or critical/atomic sections when running in an RTOS thread.
|
||||
/// When using the SE Manager API in a bare-metal application, it is the application developer's responsibility
|
||||
/// to not call the SE Manager APIs when another operation is in progress.
|
||||
///
|
||||
/// The SE Manager supports multi-thread safe APIs for MicriumOS and FreeRTOS interfacing with CMSIS RTOS2 APIs.
|
||||
///
|
||||
/// 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.
|
||||
/// 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.
|
||||
///
|
||||
/// 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,
|
||||
/// ensuring multi-thread safety. For yielding the CPU core while waiting for the SE, the SE Manager APIs that invoke
|
||||
/// SE mailbox commands will wait on a semaphore which is signaled in the ISR that handles the SE mailbox completion interrupt.
|
||||
/// Hence other threads may run on the CPU core while the SE is processing the mailbox command.
|
||||
///
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
@@ -0,0 +1,209 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_ATTESTATION_H
|
||||
#define SL_SE_MANAGER_ATTESTATION_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if (defined(SLI_MAILBOX_COMMAND_SUPPORTED) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT))
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_attestation Attestation
|
||||
*
|
||||
* @brief
|
||||
* System and configuration attestation
|
||||
*
|
||||
* @details
|
||||
* API for retrieveing attestation tokens from the SE.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// 32 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_32 (32U)
|
||||
/// 48 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_48 (48U)
|
||||
/// 64 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_64 (64U)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the PSA initial attest token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes. Must be at least the size found by calling
|
||||
* \ref sl_se_attestation_get_psa_iat_token_size with equivalent arguments,
|
||||
* and padded to word alignment.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @warning
|
||||
* Once a nonce/challenge has been used, the same challenge should not be used
|
||||
* ever again, to prevent replay attacks.
|
||||
*
|
||||
* @warning
|
||||
* The output will be length-extended to the next word-multiple.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the size of a PSA initial attest token with the given nonce
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get an attested (signed) security configuration token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be 32.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes. Must be at least the size found by calling
|
||||
* \ref sl_se_attestation_get_config_token_size with equivalent arguments,
|
||||
* and padded to word alignment.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @warning
|
||||
* Once a nonce/challenge has been used, the same challenge should not be used
|
||||
* ever again, to prevent replay attacks.
|
||||
*
|
||||
* @warning
|
||||
* The output will be length-extended to the next word-multiple.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the size of a security configuration token
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be 32.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_attestation)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED && VAULT
|
||||
|
||||
#endif // SL_SE_MANAGER_ATTESTATION_H
|
||||
@@ -0,0 +1,61 @@
|
||||
/**************************************************************************/ /**
|
||||
* @file
|
||||
* @brief Consistency checks for SE Manager configuration options
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
#define SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING) \
|
||||
&& !defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) \
|
||||
&& !defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
#error "Yield when waiting for SE commands to finish is currently required in RTOS mode."
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) \
|
||||
&& !defined(SL_SE_MANAGER_THREADING)
|
||||
#error "Yield when waiting for SE commands to finish currently requires RTOS mode. I.e. yield support is not available in bare metal mode."
|
||||
#endif
|
||||
|
||||
#if (defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)) \
|
||||
&& !defined(SL_SE_MANAGER_THREADING)
|
||||
#error "RTOS requires threading mode."
|
||||
#endif
|
||||
|
||||
#if (defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) && defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION))
|
||||
#error "Yield support is not available on EFR32xG22 devices"
|
||||
#endif
|
||||
|
||||
#if (SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED != 1)
|
||||
#error "Using multiple blocks for key stream computation is not supported"
|
||||
#endif
|
||||
|
||||
#endif // SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
/**************************************************************************/ /**
|
||||
* @file
|
||||
* @brief SE Manager configuration options
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_SE_MANAGER_CONFIG_H
|
||||
#define SL_SE_MANAGER_CONFIG_H
|
||||
|
||||
/// This file include the configuration options of the SE Manager.
|
||||
/// For the time being the user should not change the default settings
|
||||
/// of the configuration options in this file.
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
// Threading support (as opposed to API calls only from a single thread)
|
||||
// is currently required in RTOS mode.
|
||||
#define SL_SE_MANAGER_THREADING
|
||||
|
||||
#if !defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) && !defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Enable yield support. Configure sl_se_command_context_t to yield CPU while waiting for SE commands.
|
||||
// This is not supported on EFR32xG22.
|
||||
#define SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED
|
||||
#define SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED 1
|
||||
#endif
|
||||
|
||||
// Check consistency of configuration options.
|
||||
// Always include se_manager_check_config.h in order to assert that the
|
||||
// configuration options dependencies and restrictions are ok.
|
||||
#include "sl_se_manager_check_config.h"
|
||||
|
||||
#endif // SL_SE_MANAGER_CONFIG_H
|
||||
@@ -0,0 +1,533 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API definitions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_DEFINES_H
|
||||
#define SL_SE_MANAGER_DEFINES_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#if !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
#if !defined(SE_MANAGER_CONFIG_FILE)
|
||||
#include "sl_se_manager_config.h"
|
||||
#else
|
||||
#include SE_MANAGER_CONFIG_FILE
|
||||
#endif // SE_MANAGER_CONFIG_FILE
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
#endif // SLI_SE_MANAGER_HOST_SYSTEM
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// @addtogroup sl_se_manager_core
|
||||
/// @{
|
||||
|
||||
/// Context initialization values. Some of the context values are not fully
|
||||
/// initialized. The user will need to call the corresponding initialization
|
||||
/// function in order to fully initialize the context objects for further use
|
||||
/// in the SE Manager API. The purpose of these initialization values is to set
|
||||
/// the context objects to a known safe state initially when the context object
|
||||
/// is declared.
|
||||
#define SL_SE_COMMAND_CONTEXT_INIT { SLI_SE_MAILBOX_COMMAND_DEFAULT(0), false }
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// Default configuration for OTP initialisation structure.
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SL_SE_OTP_INIT_DEFAULT \
|
||||
{ \
|
||||
.enable_secure_boot = false, \
|
||||
.verify_secure_boot_certificate = false, \
|
||||
.enable_anti_rollback = false, \
|
||||
.secure_boot_page_lock_narrow = false, \
|
||||
.secure_boot_page_lock_full = false, \
|
||||
.tamper_levels = { 0 }, \
|
||||
.tamper_filter_period = SL_SE_TAMPER_FILTER_PERIOD_2MIN, \
|
||||
.tamper_filter_threshold = SL_SE_TAMPER_FILTER_THRESHOLD_4, \
|
||||
.tamper_flags = 0, \
|
||||
.tamper_reset_threshold = 5 \
|
||||
}
|
||||
#else
|
||||
#define SL_SE_OTP_INIT_DEFAULT \
|
||||
{ \
|
||||
.enable_secure_boot = false, \
|
||||
.verify_secure_boot_certificate = false, \
|
||||
.enable_anti_rollback = false, \
|
||||
.secure_boot_page_lock_narrow = false, \
|
||||
.secure_boot_page_lock_full = false \
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// -------------------------------
|
||||
// Defines for SE functionality
|
||||
|
||||
/// @addtogroup sl_se_manager_key_handling
|
||||
/// @{
|
||||
|
||||
/// Asymmetric key can only be used for signing (not key exchange)
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY (1UL << 10)
|
||||
/// Described key belongs to a custom ECC domain
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_USES_CUSTOM_DOMAIN (1UL << 12)
|
||||
/// Storage buffer contains public part of an asymmetric key
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY (1UL << 13)
|
||||
/// Storage buffer contains private part of an asymmetric key
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY (1UL << 14)
|
||||
/// Allow usage of this key by other bus masters or TrustZone levels than the
|
||||
/// one which created/imported the key
|
||||
#define SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS (1UL << 15)
|
||||
/// Old definition. Retained for backwards compatibility.
|
||||
#define SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY \
|
||||
(SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY)
|
||||
|
||||
/// Do not allow exporting the key to plaintext
|
||||
#define SL_SE_KEY_FLAG_NON_EXPORTABLE (1UL << 24)
|
||||
/// Indicate that the key has been generated by this device. This flag is only
|
||||
/// valid when using the SE to generate a key and makes it non-exportable.
|
||||
#define SL_SE_KEY_FLAG_IS_DEVICE_GENERATED (1UL << 25)
|
||||
/// Indicate that the key can only be used to sign SE generated content. This
|
||||
/// flag is only valid when using the SE to generate a key and makes it
|
||||
/// non-exportable.
|
||||
#define SL_SE_KEY_FLAG_IS_RESTRICTED (1UL << 25 | 1UL << 24)
|
||||
|
||||
/// Mask for algorithm field in key type
|
||||
#define SL_SE_KEY_TYPE_ALGORITHM_MASK 0xf0000000
|
||||
/// Offset of algorithm field in key type
|
||||
#define SL_SE_KEY_TYPE_ALGORITHM_OFFSET 28
|
||||
/// Mask for attributes field in key type
|
||||
#define SL_SE_KEY_TYPE_ATTRIBUTES_MASK 0x00007fff
|
||||
/// Offset of attributes field in key type
|
||||
#define SL_SE_KEY_TYPE_ATTRIBUTES_OFFSET 0
|
||||
|
||||
/// Symmetric key type
|
||||
#define SL_SE_KEY_TYPE_SYMMETRIC 0x00000000
|
||||
/// Symmetric key type for AES-128 (16 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_128 0x00000010
|
||||
/// Symmetric key type for AES-192 (24 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_192 0x00000018
|
||||
/// Symmetric key type for AES-256 (32 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_256 0x00000020
|
||||
|
||||
/// ECC Weierstrass Prime key type
|
||||
#define SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM (0x8U << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
/// ECC Montgomery key type
|
||||
#define SL_SE_KEY_TYPE_ECC_MONTGOMERY (0xbU << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
/// EDDSA key type
|
||||
#define SL_SE_KEY_TYPE_ECC_EDDSA (0xcU << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
|
||||
/// ECC NIST P-192
|
||||
#define SL_SE_KEY_TYPE_ECC_P192 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x18))
|
||||
/// ECC NIST P-224
|
||||
#define SL_SE_KEY_TYPE_ECC_P224 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x1C))
|
||||
/// ECC NIST P-256
|
||||
#define SL_SE_KEY_TYPE_ECC_P256 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x20))
|
||||
|
||||
/// ECC Ed25519 key for EdDSA
|
||||
#define SL_SE_KEY_TYPE_ECC_ED25519 (SL_SE_KEY_TYPE_ECC_EDDSA | (0x20))
|
||||
|
||||
/// ECC X25519 key for ECDH
|
||||
#define SL_SE_KEY_TYPE_ECC_X25519 (SL_SE_KEY_TYPE_ECC_MONTGOMERY | (0x20))
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Symmetric key type for ChaCha20
|
||||
#define SL_SE_KEY_TYPE_CHACHA20 0x00000020
|
||||
|
||||
/// ECC NIST P-384
|
||||
#define SL_SE_KEY_TYPE_ECC_P384 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x30))
|
||||
/// ECC NIST P-521
|
||||
#define SL_SE_KEY_TYPE_ECC_P521 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x42))
|
||||
|
||||
/// ECC X448 key for ECDH
|
||||
#define SL_SE_KEY_TYPE_ECC_X448 (SL_SE_KEY_TYPE_ECC_MONTGOMERY | (0x38))
|
||||
|
||||
/// ECC Ed448 key for EdDSA
|
||||
#define SL_SE_KEY_TYPE_ECC_ED448 (SL_SE_KEY_TYPE_ECC_EDDSA | (0x38))
|
||||
|
||||
#endif
|
||||
|
||||
/// Key storage methods
|
||||
|
||||
/// Key is stored in a plaintext buffer in application memory. Application
|
||||
/// can save its in-memory buffer to non-volatile memory as needed to
|
||||
/// provide key persistence.
|
||||
#define SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT 0x00
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Key is stored encrypted in application memory. This ensures the key in
|
||||
/// wrapped form is only usable on a specific device. If the key
|
||||
/// additionally needs to be prevented from ever being output as plaintext,
|
||||
/// also set the corresponding permission bit. Application can save its
|
||||
/// in-memory buffer to non-volatile memory as needed to provide key
|
||||
/// persistence.
|
||||
/// Keys stored in this way should use the flag
|
||||
/// SL_SE_KEY_FLAG_NON_EXPORTABLE unless there is a specific need to access
|
||||
/// the key value outside the SE.
|
||||
#define SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED 0x01
|
||||
/// Key is stored inside the SE, and will persist until system reset or
|
||||
/// explicitly deleted.
|
||||
/// Keys stored in this way should use the flag
|
||||
/// SL_SE_KEY_FLAG_NON_EXPORTABLE unless there is a specific need to access
|
||||
/// the key value outside the SE.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_VOLATILE 0x02
|
||||
#endif
|
||||
/// Key is one of the pre-defined keys (pre-loaded or write-once) available
|
||||
/// in the SE. See documentation for a list of available keys.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE 0x03
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Key is stored in the KSURAM, an internal Key Slot RAM.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_KSU 0x04
|
||||
#endif
|
||||
|
||||
/// List of available internal SE key slots
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_0 0x00 ///< Internal volatile slot 0
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_1 0x01 ///< Internal volatile slot 1
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_2 0x02 ///< Internal volatile slot 2
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_3 0x03 ///< Internal volatile slot 3
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_SUPPORTS_NVM3_INTERNAL_KEY)
|
||||
/// Minimum key slot value for internal keys
|
||||
#define SL_SE_KEY_SLOT_INTERNAL_MIN 0xF6
|
||||
/// Internal NVM3 key
|
||||
#define SL_SE_KEY_SLOT_NVM3_KEY 0xF6
|
||||
#else
|
||||
/// Minimum key slot value for internal keys
|
||||
#define SL_SE_KEY_SLOT_INTERNAL_MIN 0xF7
|
||||
#endif
|
||||
/// Internal TrustZone root key
|
||||
#define SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY 0xF7
|
||||
/// Internal immutable application secure debug key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY 0xF8
|
||||
/// Internal immutable application AES-128 key (bootloader key)
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY 0xFA
|
||||
/// Internal immutable application secure boot key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY 0xFC
|
||||
/// Internal immutable application attestation key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY 0xFE
|
||||
/// Internal immutable SE attestation key
|
||||
#define SL_SE_KEY_SLOT_SE_ATTESTATION_KEY 0xFF
|
||||
|
||||
/// Size overhead for wrapped keys
|
||||
#define SLI_SE_WRAPPED_KEY_OVERHEAD (12 + 16)
|
||||
/// @} (end addtogroup sl_se_manager_key_handling)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_derivation
|
||||
/// @{
|
||||
|
||||
/// Defines mapping the PBKDF2 PRFs to corresponding sl_se_hash_type_t values.
|
||||
#define SL_SE_PRF_AES_CMAC_128 SL_SE_HASH_NONE ///< CMAC-AES-128
|
||||
#define SL_SE_PRF_HMAC_SHA1 SL_SE_HASH_SHA1 ///< HMAC-SHA-1
|
||||
#define SL_SE_PRF_HMAC_SHA224 SL_SE_HASH_SHA224 ///< HMAC-SHA-224
|
||||
#define SL_SE_PRF_HMAC_SHA256 SL_SE_HASH_SHA256 ///< HMAC-SHA-256
|
||||
#define SL_SE_PRF_HMAC_SHA384 SL_SE_HASH_SHA384 ///< HMAC-SHA-384
|
||||
#define SL_SE_PRF_HMAC_SHA512 SL_SE_HASH_SHA512 ///< HMAC-SHA-512
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE Challenge size
|
||||
#define SL_SE_CHALLENGE_SIZE 16
|
||||
|
||||
/// Certificate key size
|
||||
#define SL_SE_CERT_KEY_SIZE 64
|
||||
|
||||
/// Certificate signature size
|
||||
#define SL_SE_CERT_SIGN_SIZE 64
|
||||
|
||||
/// Batch ID certificate
|
||||
#define SL_SE_CERT_BATCH 0x01
|
||||
/// SE ID certificate
|
||||
#define SL_SE_CERT_DEVICE_SE 0x02
|
||||
/// Host ID certificate
|
||||
#define SL_SE_CERT_DEVICE_HOST 0x03
|
||||
|
||||
/// @addtogroup sl_se_manager_util_tamper Tamper options
|
||||
/// @brief
|
||||
/// Tamper configuration options. Levels, signals and filter options.
|
||||
/// @{
|
||||
|
||||
// SE tamper signal levels
|
||||
#define SL_SE_TAMPER_LEVEL_IGNORE 0 ///< No action taken
|
||||
#define SL_SE_TAMPER_LEVEL_INTERRUPT 1 ///< Generate interrupt
|
||||
#define SL_SE_TAMPER_LEVEL_FILTER 2 ///< Increment filter counter
|
||||
#define SL_SE_TAMPER_LEVEL_RESET 4 ///< System reset
|
||||
#define SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP 7 ///< Erase OTP - THIS WILL MAKE THE DEVICE INOPERATIONAL!
|
||||
|
||||
// SE tamper signals
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_CRC 0x4 ///< SE RAM CRC parity error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x10 ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x11 ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x12 ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x13 ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x14 ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x15 ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS6 0x16 ///< PRS channel 6 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS7 0x17 ///< PRS channel 7 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_DECOUPLE_BOD 0x18 ///< Decouple brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x19 ///< On-device temperature sensor detects operation outside datasheet specification
|
||||
#define SL_SE_TAMPER_SIGNAL_VOLTAGE_GLITCH_FALLING 0x1A ///< Voltage glitch detector detected falling glitch
|
||||
#define SL_SE_TAMPER_SIGNAL_VOLTAGE_GLITCH_RISING 0x1B ///< Voltage glitch detector detected rising glitch
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x1C ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_DEBUG_GRANTED 0x1D ///< SE debug granted
|
||||
#define SL_SE_TAMPER_SIGNAL_DIGITAL_GLITCH 0x1E ///< Digital glitch detector detected an event
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_ICACHE_ERROR 0x1F ///< SE ICACHE checksum error
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5) || defined(_SILICON_LABS_32B_SERIES_2_CONFIG_9)
|
||||
|
||||
// SE tamper signals for xG25 and xG29, with ETAMPDET signal included.
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_2 0x4 ///< SE RAM 2-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x10 ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_ATAMPDET_EMPGD 0x11 ///< Electromagnetic pulse glitch detector
|
||||
#define SL_SE_TAMPER_ATAMPDET_SUPGD 0x12 ///< Supply glitch detector
|
||||
#define SL_SE_TAMPER_SE_ICACHE_ERROR 0x13 ///< SE ICache RAM error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_1 0x14 ///< SE RAM 1-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_BOD 0x15 ///< Brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x16 ///< On-device temperature sensor
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_LOW 0x17 ///< DPLL lock fail low
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_HIGH 0x18 ///< DPLL lock fail high
|
||||
#define SL_SE_TAMPER_SIGNAL_ETAMPDET 0x19 ///< External tamper detect
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x1a ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x1b ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x1c ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x1d ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x1e ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x1f ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#else
|
||||
|
||||
// SE tamper signals
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_2 0x4 ///< SE RAM 2-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x10 ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_ATAMPDET_EMPGD 0x11 ///< Electromagnetic pulse glitch detector
|
||||
#define SL_SE_TAMPER_ATAMPDET_SUPGD 0x12 ///< Supply glitch detector
|
||||
#define SL_SE_TAMPER_SE_ICACHE_ERROR 0x13 ///< SE ICache RAM error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_1 0x14 ///< SE RAM 1-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_BOD 0x15 ///< Brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x16 ///< On-device temperature sensor
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_LOW 0x17 ///< DPLL lock fail low
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_HIGH 0x18 ///< DPLL lock fail high
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x19 ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x1a ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x1b ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x1c ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x1d ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x1e ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS6 0x1f ///< PRS channel 6 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#endif
|
||||
|
||||
// SE tamper filter timeout period.
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_32MS 0x0 ///< Timeout ~32ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_64MS 0x1 ///< Timeout ~64ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_128MS 0x2 ///< Timeout ~128ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_256MS 0x3 ///< Timeout ~256ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_512MS 0x4 ///< Timeout ~512ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1S 0x5 ///< Timeout ~1s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2S 0x6 ///< Timeout ~2s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_4S 0x7 ///< Timeout ~4.1s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_8S 0x8 ///< Timeout ~8.2s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_16S 0x9 ///< Timeout ~16.4s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_33S 0xA ///< Timeout ~32.8s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1MIN 0xB ///< Timeout ~1.1min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2MIN 0xC ///< Timeout ~2.2min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_4MIN 0xD ///< Timeout ~4.4min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_9MIN 0xE ///< Timeout ~8.7min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_18MIN 0xF ///< Timeout ~17.5min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_35MIN 0x10 ///< Timeout ~35min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1H 0x11 ///< Timeout ~1.2h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2H 0x12 ///< Timeout ~2.3h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_5H 0x13 ///< Timeout ~4.7h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_9H 0x14 ///< Timeout ~9.3h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_19H 0x15 ///< Timeout ~18.6h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2DAYS 0x16 ///< Timeout ~1.6days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_3DAYS 0x17 ///< Timeout ~3.1days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_6DAYS 0x18 ///< Timeout ~6.2days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_12DAYS 0x19 ///< Timeout ~12.4days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_25DAYS 0x1A ///< Timeout ~24.9days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_50DAYS 0x1B ///< Timeout ~49.7days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_100DAYS 0x1C ///< Timeout ~99.4days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_199DAYS 0x1D ///< Timeout ~198.8days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_398DAYS 0x1E ///< Timeout ~397.7days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_795DAYS 0x1F ///< Timeout ~795.4days
|
||||
|
||||
// Number of tamper counts to trigger the filter signal.
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_2 0x7 ///< Counter threshold 2
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_4 0x6 ///< Counter threshold 4
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_8 0x5 ///< Counter threshold 8
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_16 0x4 ///< Counter threshold 16
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_32 0x3 ///< Counter threshold 32
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_64 0x2 ///< Counter threshold 64
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_128 0x1 ///< Counter threshold 128
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_256 0x0 ///< Counter threshold 256
|
||||
|
||||
/// Tamper flags.
|
||||
#define SL_SE_TAMPER_FLAG_DGLITCH_ALWAYS_ON (1UL << 1) /// Digital glitch detector always on
|
||||
#define SL_SE_TAMPER_FLAG_KEEP_TAMPER_ALIVE_DURING_SLEEP (1UL << 2) /// Tamper is kept alive during sleep (down to EM3)
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util_tamper)
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#ifdef SL_SUPPRESS_DEPRECATION_WARNINGS_SDK_2025_6
|
||||
/// Initial values for CMAC streaming context struct @ref sl_se_cmac_multipart_context_t
|
||||
#define SL_SE_CMAC_STREAMING_INIT_DEFAULT { NULL, { 0 }, { 0 }, 0 }
|
||||
|
||||
/// Initial values for AES-GCM streaming context struct @ref sl_se_gcm_multipart_context_t
|
||||
#define SL_SE_GCM_STREAMING_INIT_DEFAULT { NULL, 0, 0, { 0 }, { 0 }, \
|
||||
{ 0 }, 0, 0 }
|
||||
#else
|
||||
#define SL_SE_GCM_STREAMING_INIT_DEFAULT _Pragma("GCC warning \"'SL_SE_GCM_STREAMING_INIT_DEFAULT' macro is deprecated as of Simplicity SDK release 2024.12\""){ NULL, 0, 0, { 0 }, { 0 }, \
|
||||
{ 0 }, 0, 0 }
|
||||
|
||||
#define SL_SE_CMAC_STREAMING_INIT_DEFAULT _Pragma("GCC warning \"'SL_SE_CMAC_STREAMING_INIT_DEFAULT' macro is deprecated as of Simplicity SDK release 2024.12\"") { NULL, { 0 }, { 0 }, 0 }
|
||||
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
/// @addtogroup sl_se_manager_cipher
|
||||
/// @{
|
||||
|
||||
/// Block size for the AES
|
||||
#define SL_SE_AES_BLOCK_SIZE (16u)
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_cipher)
|
||||
|
||||
/// @addtogroup sl_se_manager_hash
|
||||
/// @{
|
||||
#define SL_SE_HASH_STREAMING_INIT_DEFAULT { NULL, 0, 0, NULL } ///< Default streaming hash context
|
||||
#define SL_SE_SHA1_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA1 streaming hash context
|
||||
#define SL_SE_SHA224_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA224 streaming hash context
|
||||
#define SL_SE_SHA256_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA256 streaming hash context
|
||||
#define SL_SE_SHA384_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA384 streaming hash context
|
||||
#define SL_SE_SHA512_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA512 streaming hash context
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
|
||||
#elif defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// -------------------------------
|
||||
// Defines for Root code functionality
|
||||
|
||||
#define SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT 16U
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// @addtogroup sl_se_manager_extmem
|
||||
/// @{
|
||||
|
||||
// The maximum number of code regions available on the device.
|
||||
// The number of available code regions may be different on future devices.
|
||||
#define SL_SE_MAX_CODE_REGIONS 8
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_extmem)
|
||||
|
||||
#endif // defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SE_MANAGER_DEFINES_H
|
||||
@@ -0,0 +1,97 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_ENTROPY_H
|
||||
#define SL_SE_MANAGER_ENTROPY_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_entropy Entropy
|
||||
*
|
||||
* @brief
|
||||
* Random number generators
|
||||
* @details
|
||||
*
|
||||
* API for getting randomness from the Secure Engine True Random Number
|
||||
* Generator (TRNG).
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get random data from hardware TRNG.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] data
|
||||
* Random data from TRNG.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of data request.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_random(sl_se_command_context_t *cmd_ctx,
|
||||
void *data,
|
||||
uint32_t num_bytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_entropy)
|
||||
/// @} (end addtogroup sl_se)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_ENTROPY_H
|
||||
@@ -0,0 +1,308 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_HASH_H
|
||||
#define SL_SE_MANAGER_HASH_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_hash Hashing
|
||||
*
|
||||
* @brief
|
||||
* Provides cryptographic hash functions (SHA-1, SHA-224, SHA-256, SHA-384,
|
||||
* SHA-512).
|
||||
*
|
||||
* @details
|
||||
* Provides API for one-way hashing functions.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Produce a message digest (a hash block) using the input data.
|
||||
*
|
||||
* @details
|
||||
* This function generates a message digest adhering to the given inputs.
|
||||
* For instance, if the algorithm is chosen to be SHA-256, it will generate
|
||||
* a 32 bytes message digest computed based on the input message.
|
||||
* This function supports SHA-1, SHA-256 and SHA-512 algorithms.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] hash_type
|
||||
* Which hashing algorithm to use.
|
||||
*
|
||||
* @param[in] message
|
||||
* Pointer to the message buffer to compute the hash/digest from.
|
||||
*
|
||||
* @param[in] message_size
|
||||
* Number of bytes in message.
|
||||
*
|
||||
* @param[out] digest
|
||||
* Pointer to block of memory to store the final digest.
|
||||
*
|
||||
* @param[in] digest_len
|
||||
* The length of the message digest (hash), must be at least the size of the
|
||||
* corresponding hash type.
|
||||
*
|
||||
* @return Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
const uint8_t *message,
|
||||
unsigned int message_size,
|
||||
uint8_t* digest,
|
||||
size_t digest_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA1 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA1 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha1_ctx
|
||||
* Pointer to a SHA1 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t *sha1_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA224 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA224 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha224_ctx
|
||||
* Pointer to a SHA224 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t *sha224_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA256 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA256 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha256_ctx
|
||||
* Pointer to a SHA256 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t *sha256_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA384 streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA384 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha384_ctx
|
||||
* Pointer to a SHA384 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t *sha384_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA512 streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA512 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha512_ctx
|
||||
* Pointer to a SHA512 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t *sha512_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a hash (message digest) streaming command context object to be
|
||||
* used in subsequent calls to hash streaming functions sl_se_hash_multipart_update()
|
||||
* and sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] hash_type
|
||||
* Type of hash algoritm
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_starts(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
*
|
||||
* This function is called between @ref sl_se_hash_multipart_starts() and
|
||||
* @ref sl_se_hash_multipart_finish().
|
||||
* This function can be called repeatedly.
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] input
|
||||
* Buffer holding the input data, must be at least @p ilen bytes wide.
|
||||
*
|
||||
* @param[in] input_len
|
||||
* The length of the input data in bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Finish a hash streaming operation and return the resulting hash digest.
|
||||
*
|
||||
* This function is called after sl_se_hash_multipart_update().
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] digest_out
|
||||
* Buffer for holding the message digest (hash), must be at least the size
|
||||
* of the corresponding message digest type.
|
||||
*
|
||||
* @param[in] digest_len
|
||||
* The length of the message digest (hash), must be at least the size of the
|
||||
* corresponding hash type.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_finish(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_HASH_H
|
||||
@@ -0,0 +1,143 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager Internal key defines
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_INTERNAL_KEYS
|
||||
#define SL_SE_MANAGER_INTERNAL_KEYS
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
#include "sl_se_manager_defines.h"
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
/// Key descriptor for internal application attestation key
|
||||
#define SL_SE_APPLICATION_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE \
|
||||
| SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#else
|
||||
/// Key descriptor for internal application attestation key
|
||||
#define SL_SE_APPLICATION_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Key descriptor for internal SE attestation key
|
||||
/// @note: Can only be used to get the public part
|
||||
#define SL_SE_SYSTEM_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE \
|
||||
| SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_SE_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
/// Key descriptor for secure boot public key
|
||||
#define SL_SE_APPLICATION_SECURE_BOOT_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for secure debug public key
|
||||
#define SL_SE_APPLICATION_SECURE_DEBUG_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for application AES-128 key
|
||||
#define SL_SE_APPLICATION_AES_128_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_AES_128, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for TrustZone root key
|
||||
#define SL_SE_TRUSTZONE_ROOT_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_AES_256, \
|
||||
.flags = SL_SE_KEY_FLAG_IS_DEVICE_GENERATED, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#endif // SL_SE_MANAGER_INTERNAL_KEYS
|
||||
@@ -0,0 +1,436 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
#define SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_key_derivation Key derivation
|
||||
*
|
||||
* @brief
|
||||
* API for key derivation and key agreement (ECDH, EC J-PAKE, HKDF, PBKDF2).
|
||||
*
|
||||
* @details
|
||||
* Contains key derivation functions (HKDF, PBKDF2) and key agreement
|
||||
* functions (ECDH, ECJPAKE).
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
// -------------------------------
|
||||
// Elliptic-curve Diffie–Hellman
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function computes the shared secret with Elliptic Curve Diffie Hellman
|
||||
* (ECDH) algorithm
|
||||
*
|
||||
* @details
|
||||
* Performs Elliptic Curve Diffie Hellman shared secret computation.
|
||||
*
|
||||
* @note
|
||||
* P-521 Elliptic Curve based Elliptic Curve Diffie Hellman (ECDH) expects
|
||||
* a 544 bits (68 bytes) buffer for storing private keys, and
|
||||
* a 1088 bits (136 bytes) buffer for storing public keys and shared secret.
|
||||
* The first 23 bits of d, Qx, Qy and shared secret are padding bits to comply
|
||||
* word-aligned addressing. The padding bits are ignored in the computation.
|
||||
*
|
||||
* This function does not implement the value-checking of the shared secret
|
||||
* as described in RFC7748 when using Montgomery keys.
|
||||
*
|
||||
* In case of using custom domain curves, \p key_in_priv defines the domain
|
||||
* parameters. Moreover, \p key_in_pub should always contain a public key.
|
||||
* If key_in_pub contains a private key, sl_se_export_public_key() can be
|
||||
* used to export the public key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in_priv
|
||||
* Our private key.
|
||||
*
|
||||
* @param[in] key_in_pub
|
||||
* Their public key.
|
||||
*
|
||||
* @param[out] key_out
|
||||
* Shared secret key. Montgomery curve result is one single coordinate.
|
||||
* Other curve types result in one pair of coordinate.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_INVALID_KEY if \p key_in_pub does not contain a public key
|
||||
* when using custom domain curves, otherwise an appropriate error code
|
||||
* (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecdh_compute_shared_secret(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in_priv,
|
||||
const sl_se_key_descriptor_t *key_in_pub,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
// -------------------------------
|
||||
// EC J-PAKE
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check if an EC J-PAKE context is ready for use.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to check. This must be initialized.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_check(const sl_se_ecjpake_context_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive the shared secret (TLS: Pre-Master Secret).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized, set up and have
|
||||
* performed both round one and two.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the derived secret to. This must be a writable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_derive_secret(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This clears an EC J-PAKE context and frees any embedded data structure.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to free. This may be @c NULL, in which case this
|
||||
* function does nothing. If it is not @c NULL, it must point to an
|
||||
* initialized EC J-PAKE context.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_free(sl_se_ecjpake_context_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize an EC J-PAKE context.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to initialize. This must not be @c NULL.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_init(sl_se_ecjpake_context_t *ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read and process the first round message (TLS: contents of the
|
||||
* Client/ServerHello extension, excluding extension type and length bytes).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up.
|
||||
*
|
||||
* @param[in] buf
|
||||
* The buffer holding the first round message. This must be a readable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length in bytes of @p buf.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_read_round_one(sl_se_ecjpake_context_t *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read and process the second round message (TLS: contents of the
|
||||
* Client/ServerKeyExchange).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up and already
|
||||
* have performed round one.
|
||||
*
|
||||
* @param[in] buf
|
||||
* The buffer holding the second round message. This must be a readable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length in bytes of @p buf.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_read_round_two(sl_se_ecjpake_context_t *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set up an EC J-PAKE context for use.
|
||||
*
|
||||
* @note
|
||||
* Currently the only values for hash/curve allowed by the standard are
|
||||
* @ref SL_SE_HASH_SHA256 / @ref SL_SE_KEY_TYPE_ECC_P256.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to set up. This must be initialized.
|
||||
*
|
||||
* @param[in] role
|
||||
* The role of the caller. This must be either @ref SL_SE_ECJPAKE_CLIENT or
|
||||
* @ref SL_SE_ECJPAKE_SERVER.
|
||||
*
|
||||
* @param[in] hash
|
||||
* The identifier of the hash function to use, for example
|
||||
* @ref SL_SE_HASH_SHA256.
|
||||
*
|
||||
* @param[in] curve
|
||||
* The identifier of the elliptic curve to use, for example
|
||||
* @ref SL_SE_KEY_TYPE_ECC_P256.
|
||||
*
|
||||
* @param[in] secret
|
||||
* The pre-shared secret (passphrase). This must be a readable buffer of
|
||||
* length @p len bytes. It need only be valid for the duration of this call.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of the pre-shared secret @p secret.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_setup(sl_se_ecjpake_context_t *ctx,
|
||||
sl_se_ecjpake_role_t role,
|
||||
sl_se_hash_type_t hash,
|
||||
uint32_t curve,
|
||||
const unsigned char *secret,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate and write the first round message (TLS: contents of the
|
||||
* Client/ServerHello extension, excluding extension type and length bytes).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the contents to. This must be a writable buffer of
|
||||
* length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_write_round_one(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate and write the second round message (TLS: contents of the
|
||||
* Client/ServerKeyExchange).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized, set up, and already
|
||||
* have performed round one.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the round two contents to. This must be a writable
|
||||
* buffer of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The size of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_write_round_two(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
// -------------------------------
|
||||
// Key derivation functions
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive a pseudorandom key from the input key material using HKDF.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] in_key
|
||||
* Pointer to the input key material.
|
||||
*
|
||||
* @param[in] hash
|
||||
* Which hashing algorithm to use.
|
||||
*
|
||||
* @param[in] salt
|
||||
* An optional salt value (a non-secret random value).
|
||||
*
|
||||
* @param[in] salt_len
|
||||
* The length of the salt.
|
||||
*
|
||||
* @param[in] info
|
||||
* An optional context and application specific information string.
|
||||
*
|
||||
* @param[in] info_len
|
||||
* The length of info.
|
||||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *in_key,
|
||||
sl_se_hash_type_t hash,
|
||||
const unsigned char *salt,
|
||||
size_t salt_len,
|
||||
const unsigned char *info,
|
||||
size_t info_len,
|
||||
sl_se_key_descriptor_t *out_key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive a pseudorandom key from the input key material using PBKDF2.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] in_key
|
||||
* Pointer to the input key material.
|
||||
*
|
||||
* @param[in] prf
|
||||
* The underlying psuedorandom function (PRF) to use in the algorithm. The
|
||||
* most common choice of HMAC-SHA-{1, 224, 256, 384, 512} is supported on all
|
||||
* Series-2 devices (with Vault High Security). Newer chips, EFR32xG23 and
|
||||
* later, also support usage of AES-CMAC-PRF-128.
|
||||
*
|
||||
* @param[in] salt
|
||||
* An optional salt value (a non-secret random value).
|
||||
*
|
||||
* @param[in] salt_len
|
||||
* The length of the salt.
|
||||
*
|
||||
* @param[in] iterations
|
||||
* The number of iterations to use. Up to 16384 iterations is supported.
|
||||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_derive_key_pbkdf2(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *in_key,
|
||||
sl_se_pbkdf2_prf_type_t prf,
|
||||
const unsigned char *salt,
|
||||
size_t salt_len,
|
||||
uint32_t iterations,
|
||||
sl_se_key_descriptor_t *out_key);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
@@ -0,0 +1,258 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager key handling.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_KEY_HANDLING_H
|
||||
#define SL_SE_MANAGER_KEY_HANDLING_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se_manager_key_handling Key handling
|
||||
*
|
||||
* \brief Secure Engine key handling API.
|
||||
*
|
||||
* \details
|
||||
* API for using cryptographic keys with the SE. Contains functionality to
|
||||
* generate, import and export keys to and from protected types like wrapped
|
||||
* or volatile keys.
|
||||
*
|
||||
* \{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate key descriptor.
|
||||
*
|
||||
* @details
|
||||
* Takes a key descriptor and checks if all required properties have been set
|
||||
* for the specific key type.
|
||||
*
|
||||
* @param[in] key
|
||||
* The key to validate.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_validate_key(const sl_se_key_descriptor_t *key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate a random key adhering to the given key descriptor
|
||||
*
|
||||
* @details
|
||||
* The SE takes a key descriptor and generates a key with the given properties
|
||||
* in the location specified by the descriptor.
|
||||
*
|
||||
* If the key size is not aligned to a multiple of words the key
|
||||
* representation is padded in front of the key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Description of the key to generate. Sets key parameters and describes the
|
||||
* storage location for the key.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_generate_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Import a key using the SE
|
||||
*
|
||||
* @details
|
||||
* Protect a key using the SE. Import a plaintext key and store it either in a
|
||||
* volatile slot or as a wrapped key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* A plaintext key.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Either a volatile or a wrapped key with similar properties as key_in.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_import_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Export a volatile or wrapped key back to plaintext
|
||||
*
|
||||
* @details
|
||||
* Attempt to have the SE export a volatile or wrapped key back to plaintext
|
||||
* if allowed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* Either a volatile or a wrapped key with similar properties as key_out.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* The exported key in plaintext.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
* SL_STATUS_INVALID_PARAMETER if key does not exist.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_export_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transfer a volatile or wrapped key to another protected storage.
|
||||
*
|
||||
* @details
|
||||
* Attempt to have the SE transfer a volatile or wrapped key if allowed.
|
||||
*
|
||||
* @note
|
||||
* The key stored in the source protected storage will not be deleted.
|
||||
*
|
||||
* Transferring a key between the same volatile slot is not allowed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* Either a volatile or a wrapped key with similar properties as key_out.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Either a volatile or a wrapped key with similar properties as key_in.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
* SL_STATUS_INVALID_PARAMETER if key does not exist.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_transfer_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Export the public part of an ECC keypair
|
||||
*
|
||||
* @details
|
||||
* The output key must be specified to only contain a public key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* An asymmetric key with either a private or public part.
|
||||
*
|
||||
* @param[out] key_out
|
||||
* Describes output key parameters. Should only be set to contain the public
|
||||
* part of the key.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_export_public_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Delete a key from a volatile SE storage slot
|
||||
*
|
||||
* @details
|
||||
* The given key will be removed from the SE. The key descriptor is not
|
||||
* modified and can be used to generate a new key without any updates.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Key to delete.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_delete_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the required storage size for the given key
|
||||
*
|
||||
* @details
|
||||
* Finds the total storage size required for a given key. This includes
|
||||
* storage for the public and private part of asymmetric keys, as well as
|
||||
* overhead for wrapping keys.
|
||||
*
|
||||
* @param[in] key
|
||||
* The sl_se_key_descriptor_t to find the required storage size for.
|
||||
*
|
||||
* @param[out] storage_size
|
||||
* The required storage size in bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_storage_size(const sl_se_key_descriptor_t *key,
|
||||
uint32_t *storage_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup sl_se_key) */
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_KEY_HANDLING_H
|
||||
@@ -0,0 +1,185 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_SIGNATURE_H
|
||||
#define SL_SE_MANAGER_SIGNATURE_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_signature Signature
|
||||
*
|
||||
* @brief
|
||||
* Digital Signature Algorithms (ECDSA, EdDSA).
|
||||
*
|
||||
* @details
|
||||
* API for using digital signatures with the SE.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function computes Elliptic-Curve Cryptography (ECC) digital signatures
|
||||
* of a message.
|
||||
*
|
||||
* @note
|
||||
* Edwards-curve Digital Signature Algorithm (EdDSA) generates a message digest
|
||||
* using the input message for computing signatures. The input parameters
|
||||
* \p hash_alg and \p hashed_message do not apply for EdDSA.
|
||||
*
|
||||
* P-521 Elliptic Curve for Elliptic Curve Digital Signature Algorithm (ECDSA)
|
||||
* expects a 544 bits (68 bytes) buffer for storing private keys,
|
||||
* and a 1088 bits (136 bytes) buffer for storing public keys and signatures.
|
||||
* The first 23 bits of d, Qx, Qy, R and S are padding bits to comply
|
||||
* word-aligned addressing.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use. Ignored for EdDSA keys, since EdDSA always
|
||||
* uses SHA-512 for Ed25519 and SHA-3 for Ed448.
|
||||
*
|
||||
* @param[in] hashed_message
|
||||
* The input message is a message digest. Ignored for EdDSA keys, and treated
|
||||
* as false.
|
||||
*
|
||||
* @param[in] message
|
||||
* The message to be used to compute the signature.
|
||||
*
|
||||
* @param[in] message_len
|
||||
* The length of message.
|
||||
*
|
||||
* @param[out] signature
|
||||
* The computed signature.
|
||||
*
|
||||
* @param[in] signature_len
|
||||
* The length of the computed signature.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropiate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
unsigned char *signature,
|
||||
size_t signature_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function verifies Elliptic-Curve Cryptography (ECC) digital signatures
|
||||
* of a message.
|
||||
*
|
||||
* @note
|
||||
* The input parameters \p hash_alg and \p hashed_message do not apply for
|
||||
* Edwards-curve Digital Signature Algorithm (EdDSA).
|
||||
*
|
||||
* P-521 Elliptic Curve for Elliptic Curve Digital Signature Algorithm (ECDSA)
|
||||
* expects a 544 bits (68 bytes) buffer for storing private keys,
|
||||
* and a 1088 bits (136 bytes) buffer for storing public keys and signatures.
|
||||
* The first 23 bits of d, Qx, Qy, R and S are padding bits to comply
|
||||
* word-aligned addressing.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use. Ignored for EdDSA keys, since EdDSA always
|
||||
* uses SHA-512 for Ed25519 and SHA-3 for Ed448.
|
||||
*
|
||||
* @param[in] hashed_message
|
||||
* The input message is a message digest. Ignored for EdDSA keys, and treated
|
||||
* as false.
|
||||
*
|
||||
* @param[in] message
|
||||
* The message to be used to compute signatures.
|
||||
*
|
||||
* @param[in] message_len
|
||||
* The length of message.
|
||||
*
|
||||
* @param[in] signature
|
||||
* The signature to be verified.
|
||||
*
|
||||
* @param[in] signature_len
|
||||
* The length of signature.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropiate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
const unsigned char *signature,
|
||||
size_t signature_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_signature)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_SIGNATURE_H
|
||||
@@ -0,0 +1,514 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API types
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_TYPES_H
|
||||
#define SL_SE_MANAGER_TYPES_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include "sl_se_manager_defines.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// OTP key types
|
||||
typedef enum {
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_BOOT = 0,
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_AUTH,
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_AES_128,
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_ATTESTATION,
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_SE_ATTESTATION,
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
} sl_se_device_key_type_t;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// SE tamper signal levels
|
||||
typedef uint8_t sl_se_tamper_level_t;
|
||||
|
||||
/// SE tamper signals
|
||||
typedef uint32_t sl_se_tamper_signals_t;
|
||||
|
||||
/// SE tamper filter timeout period
|
||||
typedef uint8_t sl_se_tamper_filter_period_t;
|
||||
|
||||
/// Number of tamper counts to trigger the filter signal
|
||||
typedef uint8_t sl_se_tamper_filter_threshold_t;
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
/// Certificate size data structure
|
||||
typedef struct {
|
||||
uint32_t batch_id_size; ///< size in bytes of the Batch certificate
|
||||
uint32_t se_id_size; ///< size in bytes of the SE ID certificate
|
||||
uint32_t host_id_size; ///< size in bytes of the Host ID certificate
|
||||
} sl_se_cert_size_type_t;
|
||||
|
||||
/// SE certificate types
|
||||
typedef uint8_t sl_se_cert_type_t;
|
||||
|
||||
/// OTP initialization data structure
|
||||
typedef struct {
|
||||
/// Enable secure boot for the host.
|
||||
bool enable_secure_boot;
|
||||
/// Require certificate based secure boot signing.
|
||||
bool verify_secure_boot_certificate;
|
||||
/// Enable anti-rollback for host application upgrades.
|
||||
bool enable_anti_rollback;
|
||||
/// Set flag to enable locking down all flash pages that cover the
|
||||
/// secure-booted image, except the last page if end of signature is not
|
||||
/// page-aligned.
|
||||
bool secure_boot_page_lock_narrow;
|
||||
/// Set flag to enable locking down all flash pages that cover the
|
||||
/// secure-booted image, including the last page if end of signature is not
|
||||
/// page-aligned.
|
||||
bool secure_boot_page_lock_full;
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// List of tamper levels to configure for the different tamper sources.
|
||||
sl_se_tamper_level_t tamper_levels[SL_SE_TAMPER_SIGNAL_NUM_SIGNALS];
|
||||
/// Reset period for the tamper filter counter.
|
||||
sl_se_tamper_filter_period_t tamper_filter_period;
|
||||
/// Activation threshold for the tamper filter.
|
||||
sl_se_tamper_filter_threshold_t tamper_filter_threshold;
|
||||
/// Tamper flags.
|
||||
uint8_t tamper_flags;
|
||||
/// Tamper reset halt threshold.
|
||||
uint8_t tamper_reset_threshold;
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
} sl_se_otp_init_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @addtogroup sl_se_manager_core
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE mailbox command context
|
||||
*
|
||||
* @details
|
||||
* This structure defines the common SE mailbox command context used for
|
||||
* all SE Manager API functions that execute SE mailbox commands. The
|
||||
* members of this context structure should be considered internal to the
|
||||
* SE Manager and should not be read or written directly by the user
|
||||
* application. For members that are relevant for the user, the user can
|
||||
* access them via corresponding set and get API functions, e.g.
|
||||
* sl_se_set_yield().
|
||||
******************************************************************************/
|
||||
typedef struct sl_se_command_context_t {
|
||||
sli_se_mailbox_command_t command; ///< SE mailbox command struct
|
||||
bool yield; ///< If true, yield the CPU core while
|
||||
///< waiting for the SE mailbox command
|
||||
///< to complete. If false, busy-wait, by
|
||||
///< polling the SE mailbox response
|
||||
///< register.
|
||||
} sl_se_command_context_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE Debug lock flags
|
||||
typedef uint32_t sl_se_debug_flags_t;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/// Debug lock options
|
||||
typedef struct {
|
||||
/// Non-Secure, Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to debug the non-secure state in a way that is intrusive to
|
||||
/// program execution (DBGLOCK locked).
|
||||
bool non_secure_invasive_debug;
|
||||
/// Non-Secure, Non-Invasive debug access enabled if true. If false, it is
|
||||
/// not possible to debug the non-secure state in a way that is intrusive to
|
||||
/// program execution (NIDLOCK locked).
|
||||
bool non_secure_non_invasive_debug;
|
||||
/// Secure, Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to debug the secure TrustZone state in a way that is intrusive
|
||||
/// to program execution (SPIDLOCK locked).
|
||||
bool secure_invasive_debug;
|
||||
/// Secure, Non-Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to observe the secure TrustZone state using trace.
|
||||
/// (SPNIDLOCK is locked. However if SPIDLOCK is open, SPNIDLOCK will also
|
||||
/// remain open.)
|
||||
bool secure_non_invasive_debug;
|
||||
} sl_se_debug_options_t;
|
||||
#endif
|
||||
|
||||
/// Debug status
|
||||
typedef struct {
|
||||
/// Whether device erase is enabled
|
||||
bool device_erase_enabled;
|
||||
/// Whether secure debug is enabled with @ref sl_se_enable_secure_debug().
|
||||
bool secure_debug_enabled;
|
||||
/// Whether the debug port has been locked with @ref sl_se_apply_debug_lock().
|
||||
/// This parameter does not indicate if the debug port has been unlocked by
|
||||
/// calling @ref sl_se_open_debug().
|
||||
bool debug_port_lock_applied;
|
||||
/// Current state of the debug port.
|
||||
/// True if locked with @ref sl_se_apply_debug_lock().
|
||||
/// False if new clean, erased or unlocked with @ref sl_se_open_debug().
|
||||
bool debug_port_lock_state;
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/// Debug option configuration as set by @ref sl_se_set_debug_options().
|
||||
sl_se_debug_options_t options_config;
|
||||
/// Current state of debug options, locked by @ref sl_se_set_debug_options() and
|
||||
/// unlocked by @ref sl_se_open_debug().
|
||||
sl_se_debug_options_t options_state;
|
||||
#endif
|
||||
} sl_se_debug_status_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_handling
|
||||
/// @{
|
||||
|
||||
/// Supported key types
|
||||
typedef uint32_t sl_se_key_type_t;
|
||||
|
||||
/// Key storage method. Can have one of @ref SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE or
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_KSU.
|
||||
typedef uint32_t sl_se_storage_method_t;
|
||||
|
||||
/// Internal SE key slot
|
||||
typedef uint32_t sl_se_key_slot_t;
|
||||
|
||||
/// Describes where the key is or should be stored
|
||||
typedef struct {
|
||||
uint8_t* pointer; ///< Pointer to a key buffer.
|
||||
uint32_t size; ///< Size of buffer.
|
||||
} sl_se_buffer_t;
|
||||
|
||||
/// KSU Metadata
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
typedef struct {
|
||||
uint8_t keyslot; ///< Keyslot to store key at in KSU
|
||||
uint8_t id; ///< KSU instance to store key
|
||||
uint8_t crypto_engine_id; ///< Which Crypto Engine to use this key
|
||||
uint8_t allowed_key_users; ///< Allowed key users
|
||||
} sl_se_ksu_metadata_t;
|
||||
#endif
|
||||
|
||||
/// Describes the storage location of keys
|
||||
typedef struct {
|
||||
/// Key storage method. Sets meaning of data in location.
|
||||
sl_se_storage_method_t method;
|
||||
/// Describes key storage location. @ref sl_se_buffer_t is used if @ref sl_se_key_storage_t.method is
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT or
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED, while @ref sl_se_key_slot_t is
|
||||
/// used for @ref SL_SE_KEY_STORAGE_INTERNAL_VOLATILE or
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE.
|
||||
/// @ref ksu is used for @ref SL_SE_KEY_STORAGE_INTERNAL_KSU
|
||||
union {
|
||||
sl_se_buffer_t buffer;
|
||||
sl_se_key_slot_t slot;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_se_ksu_metadata_t ksu;
|
||||
#endif
|
||||
} location;
|
||||
} sl_se_key_storage_t;
|
||||
|
||||
/// Contains a full description of a key used by an SE command.
|
||||
typedef struct {
|
||||
/// Key type
|
||||
sl_se_key_type_t type;
|
||||
/// Key size, applicable if key_type == SYMMETRIC
|
||||
size_t size;
|
||||
/// Flags describing restrictions, permissions and attributes of the key.
|
||||
uint32_t flags;
|
||||
/// Storage location for this key
|
||||
sl_se_key_storage_t storage;
|
||||
/// Optional password for key usage (8 bytes). If no password is provided
|
||||
/// (NULL pointer), any key not stored as plaintext will be stored with a
|
||||
/// password of all-zero bytes.
|
||||
uint8_t* password;
|
||||
/// Pointer to domain descriptor if this key contains an asymmetric key on a
|
||||
/// custom domain The reason for pointing instead of containing is to make
|
||||
/// it possible to have the parameters in ROM.
|
||||
const void* domain;
|
||||
} sl_se_key_descriptor_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Custom Weierstrass curve structure.
|
||||
typedef struct {
|
||||
/// Domain size in bytes.
|
||||
const size_t size;
|
||||
/// Modulus p (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* p;
|
||||
/// Order N (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* N;
|
||||
/// Generator X-coordinate (zero-padded from MSB, right-adjusted to extend
|
||||
/// to 32-bit alignment up from domain size)
|
||||
const uint8_t* Gx;
|
||||
/// Generator Y-coordinate (zero-padded from MSB, right-adjusted to extend
|
||||
/// to 32-bit alignment up from domain size)
|
||||
const uint8_t* Gy;
|
||||
/// Parameter a (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* a;
|
||||
/// Parameter b (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* b;
|
||||
/// Set if a equals 0
|
||||
bool a_is_zero;
|
||||
/// Set if a equals -3
|
||||
bool a_is_minus_three;
|
||||
} sl_se_custom_weierstrass_prime_domain_t;
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_handling)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE challenge storage
|
||||
typedef uint8_t sl_se_challenge_t[SL_SE_CHALLENGE_SIZE];
|
||||
|
||||
/// SE status
|
||||
typedef struct {
|
||||
/// Boot status code / error code (Bits [7:0]).
|
||||
uint32_t boot_status;
|
||||
/// SE firmware version.
|
||||
uint32_t se_fw_version;
|
||||
/// Host firmware version (if available).
|
||||
uint32_t host_fw_version;
|
||||
/// Debug lock status.
|
||||
sl_se_debug_status_t debug_status;
|
||||
/// Secure boot enabled.
|
||||
bool secure_boot_enabled;
|
||||
/// Active mode enabled.
|
||||
bool active_mode_enabled;
|
||||
/// Recorded tamper status. Reset on status read.
|
||||
uint32_t tamper_status;
|
||||
/// Currently active tamper sources.
|
||||
uint32_t tamper_status_raw;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
uint8_t rom_revision;
|
||||
/// ROM revision
|
||||
uint8_t otp_patch_sequence;
|
||||
/// OTP patch sequence
|
||||
#endif
|
||||
} sl_se_status_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @addtogroup sl_se_manager_cipher
|
||||
/// @{
|
||||
|
||||
/// Cipher operation types
|
||||
typedef enum {
|
||||
SL_SE_ENCRYPT,
|
||||
SL_SE_DECRYPT
|
||||
} sl_se_cipher_operation_t;
|
||||
|
||||
/// CMAC streaming context
|
||||
typedef struct {
|
||||
uint8_t state[16]; ///< CMAC state
|
||||
uint8_t data_in[16]; ///< Unprocessed data
|
||||
uint8_t data_out[16]; ///< Last 16 bytes of cipher-text
|
||||
size_t length; ///< Length of all processed and unprocessed data
|
||||
} sl_se_cmac_multipart_context_t;
|
||||
|
||||
/// CCM streaming context.
|
||||
typedef struct {
|
||||
uint32_t processed_message_length;///< Current length of the encrypted/decrypted data
|
||||
uint32_t total_message_length; ///< Total length of data to be encrypted/decrypted
|
||||
uint8_t iv[13]; ///< Nonce (MAX size is 13 bytes)
|
||||
uint32_t tag_len; ///< Tag length
|
||||
sl_se_cipher_operation_t mode;///< CCM mode (decrypt or encrypt)
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
uint8_t nonce_counter[16]; ///< Counter to keep CTR state
|
||||
uint8_t iv_len; ///< Nonce length
|
||||
uint8_t cbc_mac_state[16]; ///< State of authenication/MAC
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
#else
|
||||
uint8_t se_ctx[32]; ///< SE encryption state
|
||||
union {
|
||||
uint8_t tagbuf[16]; ///< Tag
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
} mode_specific_buffer; ///< Buffer containing Tag and input data saved for finish operation
|
||||
#endif
|
||||
uint8_t final_data_length; ///< Length of data saved
|
||||
} sl_se_ccm_multipart_context_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t len; ///< Total length of the encrypted data
|
||||
uint64_t add_len; ///< Total length of the additional data
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
uint8_t tagbuf[16]; ///< Tag
|
||||
uint8_t previous_se_ctx[32]; ///< SE state from previous operation
|
||||
#endif
|
||||
uint8_t se_ctx[32]; ///< SE state
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
uint8_t final_data_length; ///< Length of data saved
|
||||
sl_se_cipher_operation_t mode;///< GCM mode
|
||||
bool first_operation; ///< First operation
|
||||
} sl_se_gcm_multipart_context_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_cipher)
|
||||
|
||||
/// @addtogroup sl_se_manager_hash
|
||||
/// @{
|
||||
|
||||
/// Hash algorithms
|
||||
typedef enum {
|
||||
SL_SE_HASH_NONE, ///< No hash
|
||||
SL_SE_HASH_SHA1, ///< SHA-1
|
||||
SL_SE_HASH_SHA224, ///< SHA-224
|
||||
SL_SE_HASH_SHA256, ///< SHA-256
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
SL_SE_HASH_SHA384, ///< SHA-384
|
||||
SL_SE_HASH_SHA512, ///< SHA-512
|
||||
#endif
|
||||
} sl_se_hash_type_t;
|
||||
|
||||
/// SHA-1 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< number of bytes processed
|
||||
uint8_t state[32]; ///< intermediate digest state
|
||||
uint8_t buffer[64]; ///< data block being processed
|
||||
} sl_se_sha1_multipart_context_t;
|
||||
|
||||
/// SHA-224 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< Number of bytes processed
|
||||
uint8_t state[32]; ///< Intermediate digest state
|
||||
uint8_t buffer[64]; ///< Data block being processed
|
||||
} sl_se_sha224_multipart_context_t;
|
||||
|
||||
/// SHA-256 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< Number of bytes processed
|
||||
uint8_t state[32]; ///< Intermediate digest state
|
||||
uint8_t buffer[64]; ///< Data block being processed
|
||||
} sl_se_sha256_multipart_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// SHA-384 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[4]; ///< Number of bytes processed
|
||||
uint8_t state[64]; ///< Intermediate digest state
|
||||
uint8_t buffer[128]; ///< Data block being processed
|
||||
} sl_se_sha384_multipart_context_t;
|
||||
|
||||
/// SHA-512 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[4]; ///< Number of bytes processed
|
||||
uint8_t state[64]; ///< Intermediate digest state
|
||||
uint8_t buffer[128]; ///< Data block being processed
|
||||
} sl_se_sha512_multipart_context_t;
|
||||
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_derivation
|
||||
/// @{
|
||||
|
||||
/// Roles in the EC J-PAKE exchange
|
||||
typedef enum {
|
||||
SL_SE_ECJPAKE_CLIENT = 0, ///< Client
|
||||
SL_SE_ECJPAKE_SERVER, ///< Server
|
||||
} sl_se_ecjpake_role_t;
|
||||
|
||||
/**************************************************************************//**
|
||||
* EC J-PAKE context structure.
|
||||
*
|
||||
* J-PAKE is a symmetric protocol, except for the identifiers used in
|
||||
* Zero-Knowledge Proofs, and the serialization of the second message
|
||||
* (KeyExchange) as defined by the Thread spec.
|
||||
*
|
||||
* In order to benefit from this symmetry, we choose a different naming
|
||||
* convention from the Thread v1.0 spec. Correspondance is indicated in the
|
||||
* description as a pair C: client name, S: server name
|
||||
*****************************************************************************/
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
uint32_t curve_flags; ///< Curve flags to use
|
||||
sl_se_ecjpake_role_t role; ///< Are we client or server?
|
||||
|
||||
char pwd[32]; ///< J-PAKE password
|
||||
size_t pwd_len; ///< J-PAKE password length
|
||||
|
||||
uint8_t r[32]; ///< Random scalar for exchange
|
||||
uint8_t Xm1[64]; ///< Our point 1 (round 1)
|
||||
uint8_t Xm2[64]; ///< Our point 2 (round 1)
|
||||
uint8_t Xp1[64]; ///< Their point 1 (round 1)
|
||||
uint8_t Xp2[64]; ///< Their point 2 (round 1)
|
||||
uint8_t Xp[64]; ///< Their point (round 2)
|
||||
} sl_se_ecjpake_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Typedef sl_se_pbkdf2_prf_type_t to sl_se_hash_type_t in order to maintain
|
||||
/// backward compatibility. Defines for mapping the PRF identifiers to the
|
||||
/// underlying hash enum values exists in sl_se_manager_defines.h.
|
||||
typedef sl_se_hash_type_t sl_se_pbkdf2_prf_type_t;
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_TYPES_H
|
||||
@@ -0,0 +1,960 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_UTIL_H
|
||||
#define SL_SE_MANAGER_UTIL_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_util Utilities
|
||||
*
|
||||
* @brief
|
||||
* Device initialisation, debug lock, upgrade functionality, user data...
|
||||
*
|
||||
* @details
|
||||
* API for managing the Secure Engine or Root code on a device. Upload and
|
||||
* read device configuration.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#endif
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Lifecycle event flags keep track of certain events and state changes by setting a one-time
|
||||
/// irreversible flag in the OTP. This enum contains information on what the separate event flags
|
||||
/// indicate. The lifecycle state flags can be fetched using @ref sl_se_get_lifecycle_event_flags. The utility
|
||||
/// @ref sl_se_lifecycle_event_flag_is_set can be used to check if any specific flag has been set.
|
||||
typedef enum {
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_UNSECURE_UNLOCKED = 0, ///< Host has been unsecure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_UNLOCKED = 1, ///< Host has been secure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_SE_SECURE_UNLOCKED = 2, ///< SE has been secure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_INITIAL_DEBUG_LOCK_SET = 3, ///< Initial debug lock token has been set in MTP
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_DEBUG_ENABLED = 4, ///< Host secure debug has been enabled
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_DEBUG_DISABLED = 5, ///< Host secure debug has been disabled
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_DEBUG_LOCKED = 6, ///< Host has been debug locked
|
||||
SL_SE_LIFECYCLE_EVENT_AXIP_NONCE_ROLL_DISABLED = 7, ///< AXiP nonce rolling has been disabled
|
||||
} sl_se_lifecycle_event_flag_t;
|
||||
#endif // #if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate SE firmware image.
|
||||
*
|
||||
* @details
|
||||
* Validate SE firmware image located at given address. This function is
|
||||
* typically used before calling sl_se_apply_se_image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to SE image to validate.
|
||||
*
|
||||
* @return
|
||||
* One of the following @ref status codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_check_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Apply SE firmware image.
|
||||
*
|
||||
* @details
|
||||
* Apply SE firmware image located at given address.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to SE image to apply.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get upgrade status of SE firmware image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] status
|
||||
* Pointer to 32-bit word where to return upgrade status.
|
||||
*
|
||||
* @param[in] prev_version
|
||||
* Pointer to 32-bit word where to return previous version.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_upgrade_status_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *status,
|
||||
uint32_t *prev_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate Host firmware image.
|
||||
*
|
||||
* @details
|
||||
* Validate Host firmware image located at given address. This function is
|
||||
* typically used before calling @ref sl_se_apply_host_image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to Host image to validate.
|
||||
*
|
||||
* @param[in] size
|
||||
* Size of Host image to validate.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_check_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr,
|
||||
uint32_t size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Apply Host firmware image.
|
||||
*
|
||||
* @details
|
||||
* Apply Host firmware image located at given address.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to Host image to apply.
|
||||
*
|
||||
* @param[in] size
|
||||
* Size of Host image to apply.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr,
|
||||
uint32_t size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get upgrade status of Host firmware image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] status
|
||||
* Pointer to 32-bit word where to return upgrade status.
|
||||
*
|
||||
* @param[in] prev_version
|
||||
* Pointer to 32-bit word where to return previous version.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_get_upgrade_status_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *status,
|
||||
uint32_t *prev_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize key to be stored in the SE OTP flash.
|
||||
*
|
||||
* @details
|
||||
* Initialize key stored in the SE. The command can be used to write (@ref sl_se_device_key_type_t):
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_BOOT
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AUTH
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AES_128
|
||||
*
|
||||
* @note
|
||||
* These keys can not be overwritten, so this command can only be issued once
|
||||
* per key per part.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_type
|
||||
* ID of key type to initialize.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to a buffer that contains the key.
|
||||
* Public keys must be word aligned and have a length of 64 bytes.
|
||||
* AES-128 keys must be word aligned and have length of 16 bytes.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of key buffer in bytes (16 or 64 bytes).
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_otp_key(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_device_key_type_t key_type,
|
||||
void *key,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read a public key stored in the SE.
|
||||
*
|
||||
* @details
|
||||
* Read out a public key stored in the SE. The command can be used to read (@ref sl_se_device_key_type_t):
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_BOOT
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AUTH
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_type
|
||||
* ID of key type to read.
|
||||
*
|
||||
* @param[out] key
|
||||
* Pointer to a buffer to contain the returned public key.
|
||||
* Must be word aligned and have a length of 64 bytes.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of pubkey buffer (64 bytes).
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_pubkey(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_device_key_type_t key_type,
|
||||
void *key,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize and commit SE OTP configuration to OTP.
|
||||
*
|
||||
* @warning
|
||||
* When this function succeeds the configuration is committed to OTP and cannot be changed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] otp_init
|
||||
* Pointer to OTP initialization structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following @ref sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_ABORT when the operation is not attempted.
|
||||
*
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_otp_init_t *otp_init);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the OTP firmware version of the SE module.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] version
|
||||
* Pointer to uint32_t word where version shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read SE OTP configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] otp_settings
|
||||
* Pointer to OTP initialization structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_COMMAND if OTP configuration isn't initialized
|
||||
* - @c SL_STATUS_ABORT when the operation is not attempted.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_otp(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_otp_init_t *otp_settings);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the SE firmware version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] version
|
||||
* Pointer to uint32_t word where version shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_OWNERSHIP when the ownership is already taken
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_se_get_se_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the current debug lock configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] status
|
||||
* Pointer to sl_se_debug_status_t structure to be filled out with the
|
||||
* current status of the debug configuration.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_debug_lock_status(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_debug_status_t *status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the debug lock for the part.
|
||||
*
|
||||
* @details
|
||||
* The debug port will be closed and the only way to open it is through
|
||||
* device erase (if enabled) or through secure debug unlock (if enabled).
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_debug_lock(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Writes data to User Data section in MTP. Write data must be aligned to
|
||||
* word size and contain a number of bytes that is divisable by four.
|
||||
* @note
|
||||
* It is recommended to erase the flash page before performing a write.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[in] offset
|
||||
* Offset to the flash word to write to. Must be aligned to words.
|
||||
* @param[in] data
|
||||
* Data to write to flash.
|
||||
* @param[in] num_bytes
|
||||
* Number of bytes to write to flash. NB: Must be divisable by four.
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_write_user_data(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t offset,
|
||||
void *data,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Erases User Data section in MTP.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_erase_user_data(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the current boot status, versions and system configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] status
|
||||
* SE_Status_t containing current SE status.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK upon command completion. Errors are encoded in the
|
||||
* different parts of the returned status object.
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_status(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_status_t *status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the serial number of the SE module.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] serial
|
||||
* Pointer to array of size 16 bytes.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_serialnumber(sl_se_command_context_t *cmd_ctx,
|
||||
void *serial);
|
||||
|
||||
#if defined(SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the EMU->RSTCAUSE after a tamper reset. This function should be called
|
||||
* if EMU->RSTCAUSE has been cleared upon boot.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] reset_cause
|
||||
* Pointer to uint32_t word where reset cause shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_reset_cause(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *reset_cause);
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the latest cached tamper reset cause. The returned value is the index
|
||||
* of the tamper source that caused a reset.
|
||||
* Requires SE version 2.2.1 or above.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] was_tamper_reset
|
||||
* Pointer to bool that indicates if a tamper event occurred. If the cached
|
||||
* value is 0 this will be false, true otherwise.
|
||||
*
|
||||
* @param[out] reset_cause
|
||||
* Pointer to a uint32_t where the cached reset cause value should
|
||||
* be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when cmd_ctx or reset_cause is NULL
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_tamper_reset_cause(sl_se_command_context_t *cmd_ctx,
|
||||
bool *was_tamper_reset,
|
||||
uint32_t *reset_cause);
|
||||
#endif // SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reads out traceable lifecycle event flags from the OTP. See
|
||||
* \ref sl_se_lifecycle_event_flag_t for details on what the individual flag bits
|
||||
* indicate.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] event_flags
|
||||
* Pointer to an array of at least 8 bytes, to contain the trace flags
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK upon successfull execution, error code elsewise
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_lifecycle_event_flags(sl_se_command_context_t *cmd_ctx, uint64_t *event_flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Utility for checking if a certain lifecycle event flag is set
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pointer to an 8 byte array of lifecycle event flags (event_flags from
|
||||
* \ref sl_se_get_lifecycle_event_flags)
|
||||
*
|
||||
* @param[in] flag_index
|
||||
* Which bit (event flag) to check if is set
|
||||
*
|
||||
* @return
|
||||
* true if event flag bit was set
|
||||
* false if event flag bit was not set
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE bool sl_se_lifecycle_event_flag_is_set(uint64_t *flags, sl_se_lifecycle_event_flag_t flag_index)
|
||||
{
|
||||
return (*flags & (1 << flag_index) ? true : false);
|
||||
}
|
||||
|
||||
#endif // #if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the secure debug functionality.
|
||||
*
|
||||
* @details
|
||||
* Enables the secure debug functionality that can be used to open a locked
|
||||
* debug port through the Get challenge and Open debug commands. This command
|
||||
* can only be executed before the debug port is locked, and after a secure
|
||||
* debug public key has been installed in the SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_enable_secure_debug(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disables the secure debug functionality.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @details
|
||||
* Disables the secure debug functionality that can be used to open a
|
||||
* locked debug port.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_secure_debug(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************/ /**
|
||||
* @brief
|
||||
* Set debug options.
|
||||
*
|
||||
* @details
|
||||
* This function makes it possible to configure the Trust-Zone access
|
||||
* permissions of the debug interface. For details please refer to
|
||||
* @ref sl_se_debug_options_t.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] debug_options
|
||||
* Pointer to debug options structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_debug_options(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_debug_options_t *debug_options);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Performs a device mass erase and debug unlock.
|
||||
*
|
||||
* @details
|
||||
* Performs a device mass erase and resets the debug configuration to its
|
||||
* initial unlocked state. Only available before DEVICE_ERASE_DISABLE has
|
||||
* been executed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @note
|
||||
* This command clears and verifies the complete flash and ram of the
|
||||
* system, excluding the user data pages and one-time programmable
|
||||
* commissioning information in the secure engine.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_COMMAND if device erase is disabled.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_erase_device(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/****************************************************************q***********//**
|
||||
* @brief
|
||||
* Disabled device erase functionality.
|
||||
*
|
||||
* @details
|
||||
* This command disables the device erase command. It does not lock the
|
||||
* debug interface to the part, but it is a permanent action for the part.
|
||||
* If device erase is disabled and the device is debug locked, there is no
|
||||
* way to permanently unlock the part. If secure debug unlock is enabled,
|
||||
* secure debug unlock can still be used to temporarily open the debug port.
|
||||
*
|
||||
* @warning
|
||||
* This command permanently disables the device erase functionality!
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_device_erase(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Request challenge from SE which can be used to open debug access.
|
||||
*
|
||||
* @details
|
||||
* This command requests a challenge (16 bytes) which can be used to generate
|
||||
* a certificate in order to open debug access, @ref sl_se_open_debug.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] challenge
|
||||
* SE challenge storage.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_challenge(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_challenge_t challenge);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Invalidate current challenge and make a new challenge.
|
||||
*
|
||||
* @details
|
||||
* This command requests the SE to invalidate it's current challenge (16bytes)
|
||||
* and generate a new challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_roll_challenge(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlock debug access using certificate and signed challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert
|
||||
* Certificate for debug unlock and signed challenge.
|
||||
*
|
||||
* @param[in] len
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @param[in] debug_options
|
||||
* Debug options to open/unlock.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_open_debug(sl_se_command_context_t *cmd_ctx,
|
||||
void *cert,
|
||||
uint32_t len,
|
||||
const sl_se_debug_options_t *debug_options);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Temporarily disable tamper configuration using certificate and signed
|
||||
* challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert
|
||||
* Certificate for disabling tamper and signed challenge.
|
||||
*
|
||||
* @param[in] len
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @param[in] tamper_signals
|
||||
* Tamper signals to disable. Each signal represented by a bit.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_tamper(sl_se_command_context_t *cmd_ctx,
|
||||
void *cert,
|
||||
uint32_t len,
|
||||
sl_se_tamper_signals_t tamper_signals);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read size of stored certificates in SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in,out] cert_size
|
||||
* Size of the certificates stored in SE.
|
||||
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_cert_size(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_cert_size_type_t *cert_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read stored certificates in SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert_type
|
||||
* Type of the certificate stored in SE.
|
||||
*
|
||||
* @param[in,out] cert
|
||||
* Buffer to read certificate.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_cert(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_cert_type_t cert_type,
|
||||
void *cert,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter SE active mode.
|
||||
*
|
||||
* @details
|
||||
* SE will enter active mode. This will ensure SE is not powered down between
|
||||
* operations, at the expense of increased power consumption.
|
||||
*
|
||||
* @warning
|
||||
* Active mode will prevent entry to EM2/3/4. To allow energy mode entry, exit
|
||||
* active mode through @ref sl_se_exit_active_mode().
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_COMMAND_IS_INVALID when already in active mode
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_enter_active_mode(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Exit SE active mode.
|
||||
*
|
||||
* @details
|
||||
* SE will exit active mode.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_COMMAND_IS_INVALID when already not in active mode
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_exit_active_mode(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the OTP rollback counter.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[out] rollback_counter
|
||||
* Pointer to location where the rollback counter value will be returned.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_rollback_counter(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *rollback_counter);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Increment the OTP rollback counter.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] rollback_counter
|
||||
* Optional: Retrieve the rollback counter count after increment
|
||||
* Set to NULL to ignore
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_increment_rollback_counter(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *rollback_counter);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reads back the stored upgrade file version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[out] version
|
||||
* The stored upgrade file version.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_upgrade_file_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Records a new upgrade file version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[in] version
|
||||
* New upgrade file version
|
||||
*
|
||||
* @return
|
||||
* \ref SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_upgrade_file_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t version);
|
||||
|
||||
#endif // defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_UTIL_H
|
||||
@@ -0,0 +1,138 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs SE Manager macros representing features.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SLI_SE_MANAGER_FEATURES_H
|
||||
#define SLI_SE_MANAGER_FEATURES_H
|
||||
|
||||
#if !defined(__linux__)
|
||||
#include "em_device.h"
|
||||
#endif // !__linux__
|
||||
|
||||
#if defined(DOXYGEN)
|
||||
|
||||
#undef _SILICON_LABS_SECURITY_FEATURE // Allow doxygen to include the SVH only features
|
||||
|
||||
#define _SILICON_LABS_SECURITY_FEATURE _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
#define SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
#define SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#else // DOXYGEN
|
||||
|
||||
#if defined(__linux__)
|
||||
// ---------------------------- HOST ---------------------------- //
|
||||
|
||||
// The header is being used on a host system with Linux running on it,
|
||||
// assume that the endpoint attached to the host system is a SVH type.
|
||||
|
||||
#define SLI_SE_MANAGER_HOST_SYSTEM
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_SE (0)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_VAULT (1)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_ROT (2)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_BASE (3)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
|
||||
// EFR32xG23+ doesn't require padding of curve elements or other keys
|
||||
#define SLI_SE_KEY_PADDING_REQUIRED
|
||||
#define SLI_SE_P521_PADDING_BYTES (2u)
|
||||
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (0u)
|
||||
#elif defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
#define SLI_SE_P521_PADDING_BYTES (0u)
|
||||
// PBKDF2 with CMAC as the PRF was first supported on EFR32xG23.
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (1u)
|
||||
#endif
|
||||
|
||||
// Define the helper macros needed for the host system
|
||||
#define __REV(num) (((num & 0xFF000000) >> 24) \
|
||||
| ((num & 0x00FF0000) >> 8) \
|
||||
| ((num & 0x0000FF00) << 8) \
|
||||
| ((num & 0x000000FF) << 24))
|
||||
|
||||
#elif defined(SEMAILBOX_PRESENT)
|
||||
// --------------------------------- HSE --------------------------------- //
|
||||
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#if (defined(_SILICON_LABS_SECURITY_FEATURE) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) \
|
||||
&& ((defined(_SILICON_LABS_32B_SERIES_2_CONFIG) && _SILICON_LABS_32B_SERIES_2_CONFIG >= 3) \
|
||||
|| defined(_SILICON_LABS_32B_SERIES_3)))
|
||||
// Reading the latest cached tamper reset cause requires SE version 2.2.1 or above.
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
// The option to keep the tamper alive during sleep is only configurable for SE with major version 2
|
||||
#define SLI_SE_TAMPER_FLAG_KEEP_TAMPER_ALIVE_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
#define SLI_SE_MAJOR_VERSION_ONE
|
||||
#else
|
||||
#define SLI_SE_MAJOR_VERSION_TWO
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_SUPPORTS_NVM3_INTERNAL_KEY
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
|
||||
// EFR32xG23+ doesn't require padding of curve elements or other keys
|
||||
#define SLI_SE_KEY_PADDING_REQUIRED
|
||||
#define SLI_SE_P521_PADDING_BYTES (2u)
|
||||
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (0u)
|
||||
#elif defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
#define SLI_SE_P521_PADDING_BYTES (0u)
|
||||
// PBKDF2 with CMAC as the PRF was first supported on EFR32xG23.
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (1u)
|
||||
#endif
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
// --------------------------------- VSE --------------------------------- //
|
||||
|
||||
#define SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#endif // DOXYGEN
|
||||
|
||||
#endif // SLI_SE_MANAGER_FEATURES_H
|
||||
@@ -0,0 +1,212 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager internal API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SE_MANAGER_INTERNAL_H
|
||||
#define SE_MANAGER_INTERNAL_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sl_status.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_se_manager.h"
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Due to a problem with the countermeasures applied to
|
||||
// accelerated point multiplication over elliptic curves,
|
||||
// it is possible that random errors are encountered (this
|
||||
// is extremely unilkely for truly random keys).
|
||||
// As a workaround for this, the affected commands will
|
||||
// retry the operation in order to reduce the probability
|
||||
// that the error code was returned incorrectly. This helps
|
||||
// lower the error probability further when using purposely
|
||||
// small or large scalars, for example during testing.
|
||||
#define SLI_SE_MAX_POINT_MULT_RETRIES 3U
|
||||
#endif
|
||||
|
||||
// -------------------------------
|
||||
// Function-like macros
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Helper macro to init/reset the SE command struct of an SE command context
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to SE context containing the command to initialize/reset
|
||||
*
|
||||
* @param[out] command_word
|
||||
* Command word to set in the SE command.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define sli_se_command_init(cmd_ctx, command_word) \
|
||||
cmd_ctx->command.command = command_word; \
|
||||
cmd_ctx->command.data_in = NULL; \
|
||||
cmd_ctx->command.data_out = NULL; \
|
||||
cmd_ctx->command.num_parameters = 0;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Helper macros to add key parameters and input/output blocks to SE commands
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to SE context
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure
|
||||
* @param[out] status
|
||||
* SL_Status_T
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// Add keyspec to command for given key
|
||||
#define sli_add_key_parameters(cmd_ctx, key, status) { \
|
||||
uint32_t keyspec; \
|
||||
(status) = sli_se_key_to_keyspec((key), &keyspec); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_parameter(&cmd_ctx->command, keyspec); \
|
||||
}
|
||||
|
||||
// Add key metadata buffers to command for given key
|
||||
#define sli_add_key_metadata(cmd_ctx, key, status) \
|
||||
/* Auth data */ \
|
||||
sli_se_datatransfer_t auth_buffer; \
|
||||
(status) = sli_se_get_auth_buffer((key), &auth_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_buffer);
|
||||
|
||||
// Add key metadata buffers with custom auth buffer to command for given key
|
||||
#define sli_add_key_metadata_custom(cmd_ctx, auth_data_buf, key, status) \
|
||||
/* Auth data */ \
|
||||
sli_se_datatransfer_t auth_data_buf; \
|
||||
(status) = sli_se_get_auth_buffer((key), &auth_data_buf); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_data_buf);
|
||||
|
||||
// Add key input buffer to given command
|
||||
#define sli_add_key_input(cmd_ctx, key, status) \
|
||||
sli_se_datatransfer_t key_input_buffer; \
|
||||
(status) = sli_se_get_key_input_output((key), &key_input_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &key_input_buffer);
|
||||
|
||||
// Add Key output buffer to given command
|
||||
#define sli_add_key_output(cmd_ctx, key, status) \
|
||||
sli_se_datatransfer_t key_output_buffer; \
|
||||
(status) = sli_se_get_key_input_output((key), &key_output_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_output(&cmd_ctx->command, &key_output_buffer);
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
sl_status_t sli_se_to_sl_status(sli_se_mailbox_response_t res);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Take the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when successful, or else error code.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_lock_acquire(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Give the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when successful, or else error code.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_lock_release(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute and wait for mailbox command to complete.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Key handling helper functions
|
||||
sl_status_t sli_key_get_storage_size(const sl_se_key_descriptor_t* key,
|
||||
uint32_t *storage_size);
|
||||
sl_status_t sli_key_get_size(const sl_se_key_descriptor_t* key, uint32_t* size);
|
||||
sl_status_t sli_key_check_equivalent(const sl_se_key_descriptor_t* key_1,
|
||||
const sl_se_key_descriptor_t* key_2,
|
||||
bool check_key_flag,
|
||||
bool public_export);
|
||||
|
||||
sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t* key,
|
||||
uint32_t* keyspec);
|
||||
sl_status_t sli_se_keyspec_to_key(const uint32_t keyspec,
|
||||
sl_se_key_descriptor_t* key);
|
||||
sl_status_t sli_se_get_auth_buffer(const sl_se_key_descriptor_t* key,
|
||||
sli_se_datatransfer_t* auth_buffer);
|
||||
sl_status_t sli_se_get_key_input_output(const sl_se_key_descriptor_t* key,
|
||||
sli_se_datatransfer_t* buffer);
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) */
|
||||
|
||||
#endif /* SE_MANAGER_INTERNAL_H */
|
||||
@@ -0,0 +1,731 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SE Mailbox API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SLI_SE_MANAGER_MAILBOX_H
|
||||
#define SLI_SE_MANAGER_MAILBOX_H
|
||||
|
||||
#if defined(__linux__)
|
||||
#define SLI_SE_MAILBOX_HOST_SYSTEM
|
||||
#else
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#include "sl_common.h"
|
||||
|
||||
#if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE status codes
|
||||
|
||||
/// Response status codes for the Secure Engine
|
||||
#define SLI_SE_RESPONSE_MASK 0x000F0000UL
|
||||
/// Command executed successfully or signature was successfully validated.
|
||||
#define SLI_SE_RESPONSE_OK 0x00000000UL
|
||||
|
||||
/// Command was not recognized as a valid command, or is not allowed in the
|
||||
/// current context.
|
||||
#define SLI_SE_RESPONSE_INVALID_COMMAND 0x00010000UL
|
||||
/// User did not provide the required credentials to be allowed to execute the
|
||||
/// command.
|
||||
#define SLI_SE_RESPONSE_AUTHORIZATION_ERROR 0x00020000UL
|
||||
/// Signature validation command (e.g. SE_COMMAND_SIGNATURE_VERIFY) failed to
|
||||
/// verify the given signature as being correct.
|
||||
#define SLI_SE_RESPONSE_INVALID_SIGNATURE 0x00030000UL
|
||||
/// A command started in non-secure mode is trying to access secure memory.
|
||||
#define SLI_SE_RESPONSE_BUS_ERROR 0x00040000UL
|
||||
/// Internal error
|
||||
#define SLI_SE_RESPONSE_INTERNAL_ERROR 0x00050000UL
|
||||
/// An internal error was raised and the command did not execute.
|
||||
#define SLI_SE_RESPONSE_CRYPTO_ERROR 0x00060000UL
|
||||
/// One of the passed parameters is deemed invalid (e.g. out of bounds).
|
||||
#define SLI_SE_RESPONSE_INVALID_PARAMETER 0x00070000UL
|
||||
/// Failure while checking the host for secure boot
|
||||
#define SLI_SE_RESPONSE_SECUREBOOT_ERROR 0x00090000UL
|
||||
/// Failure during selftest
|
||||
#define SLI_SE_RESPONSE_SELFTEST_ERROR 0x000A0000UL
|
||||
/// Feature/item not initialized or not present
|
||||
#define SLI_SE_RESPONSE_NOT_INITIALIZED 0x000B0000UL
|
||||
/// Abort status code is given when no operation is attempted.
|
||||
#define SLI_SE_RESPONSE_ABORT 0x00FF0000UL
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/// Root Code Mailbox is invalid.
|
||||
#define SLI_SE_RESPONSE_MAILBOX_INVALID 0x00FE0000UL
|
||||
/// Root Code Mailbox is valid
|
||||
#define SLI_SE_RESPONSE_MAILBOX_VALID 0xE5ECC0DEUL
|
||||
#endif // CRYPTOACC_PRESENT
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE command words
|
||||
// Commands are grouped based on availability
|
||||
#define SLI_SE_COMMAND_CHECK_SE_IMAGE 0x43020000UL
|
||||
#define SLI_SE_COMMAND_APPLY_SE_IMAGE 0x43030000UL
|
||||
#define SLI_SE_COMMAND_STATUS_SE_IMAGE 0x43040000UL
|
||||
#define SLI_SE_COMMAND_CHECK_HOST_IMAGE 0x43050001UL
|
||||
#define SLI_SE_COMMAND_APPLY_HOST_IMAGE 0x43060001UL
|
||||
#define SLI_SE_COMMAND_STATUS_HOST_IMAGE 0x43070000UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_OTP 0xFE040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_INIT_OTP 0xFF000001UL
|
||||
#define SLI_SE_COMMAND_INIT_PUBKEY 0xFF070001UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY 0xFF080001UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY 0xFF080001UL
|
||||
#define SLI_SE_COMMAND_READ_OTP 0xFE040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_APPLY 0x430C0000UL
|
||||
|
||||
// Commands limited to SE devices
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
#define SLI_SE_COMMAND_CREATE_KEY 0x02000000UL
|
||||
#define SLI_SE_COMMAND_READPUB_KEY 0x02010000UL
|
||||
|
||||
#define SLI_SE_COMMAND_HASH 0x03000000UL
|
||||
#define SLI_SE_COMMAND_HASHUPDATE 0x03010000UL
|
||||
#define SLI_SE_COMMAND_HMAC 0x03020000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_START 0x03040000UL
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_UPDATE 0x03050000UL
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_FINISH 0x03060000UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
#define SLI_SE_COMMAND_HASHFINISH 0x03030000UL
|
||||
|
||||
#define SLI_SE_COMMAND_AES_ENCRYPT 0x04000000UL
|
||||
#define SLI_SE_COMMAND_AES_DECRYPT 0x04010000UL
|
||||
#define SLI_SE_COMMAND_AES_GCM_ENCRYPT 0x04020000UL
|
||||
#define SLI_SE_COMMAND_AES_GCM_DECRYPT 0x04030000UL
|
||||
#define SLI_SE_COMMAND_AES_CMAC 0x04040000UL
|
||||
#define SLI_SE_COMMAND_AES_CCM_ENCRYPT 0x04050000UL
|
||||
#define SLI_SE_COMMAND_AES_CCM_DECRYPT 0x04060000UL
|
||||
|
||||
#define SLI_SE_COMMAND_SIGNATURE_SIGN 0x06000000UL
|
||||
#define SLI_SE_COMMAND_SIGNATURE_VERIFY 0x06010000UL
|
||||
#define SLI_SE_COMMAND_EDDSA_SIGN 0x06020000UL
|
||||
#define SLI_SE_COMMAND_EDDSA_VERIFY 0x06030000UL
|
||||
|
||||
#define SLI_SE_COMMAND_TRNG_GET_RANDOM 0x07000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_JPAKE_R1_GENERATE 0x0B000000UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R1_VERIFY 0x0B000100UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R2_GENERATE 0x0B010000UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R2_VERIFY 0x0B010100UL
|
||||
#define SLI_SE_COMMAND_JPAKE_GEN_SESSIONKEY 0x0B020000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DH 0x0E000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_STATUS_SE_VERSION 0x43080000UL
|
||||
#define SLI_SE_COMMAND_STATUS_OTP_VERSION 0x43080100UL
|
||||
#define SLI_SE_COMMAND_WRITE_USER_DATA 0x43090000UL
|
||||
#define SLI_SE_COMMAND_ERASE_USER_DATA 0x430A0000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_ENABLE_SECURE 0x430D0000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_DISABLE_SECURE 0x430E0000UL
|
||||
#define SLI_SE_COMMAND_DEVICE_ERASE 0x430F0000UL
|
||||
#define SLI_SE_COMMAND_DEVICE_ERASE_DISABLE 0x43100000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_STATUS 0x43110000UL
|
||||
#define SLI_SE_COMMAND_DBG_SET_RESTRICTIONS 0x43120000UL
|
||||
#define SLI_SE_COMMAND_PROTECTED_REGISTER 0x43210000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_READ_DEVICE_DATA 0x43300000UL
|
||||
#define SLI_SE_COMMAND_GET_ROLLBACK_COUNTER 0x43400000UL
|
||||
#endif
|
||||
#if defined(SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE)
|
||||
// SLI_SE_COMMAND_STATUS_READ_RSTCAUSE is only available on xG21 devices (series-2-config-1)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE 0x43220000UL
|
||||
#endif // SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT_SIZE 0x43FA0000UL
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT 0x43FB0000UL
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_GET_HOST_UPGRADE_FILE_VERSION 0x44000000UL
|
||||
#define SLI_SE_COMMAND_SET_HOST_UPGRADE_FILE_VERSION 0x44010000UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
|
||||
#define SLI_SE_COMMAND_ENTER_ACTIVE_MODE 0x45000000UL
|
||||
#define SLI_SE_COMMAND_EXIT_ACTIVE_MODE 0x45010000UL
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SLI_SE_COMMAND_ATTEST_PSA_IAT 0x0A030000UL
|
||||
#define SLI_SE_COMMAND_ATTEST_CONFIG 0x0A040000UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#define SLI_SE_COMMAND_GET_CHALLENGE 0xFD000001UL
|
||||
#define SLI_SE_COMMAND_ROLL_CHALLENGE 0xFD000101UL
|
||||
#define SLI_SE_COMMAND_OPEN_DEBUG 0xFD010001UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_SERIAL 0xFE000000UL
|
||||
#define SLI_SE_COMMAND_GET_STATUS 0xFE010000UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEYBOOT 0xFE020001UL
|
||||
#define SLI_SE_COMMAND_SET_UPGRADEFLAG_SE 0xFE030000UL
|
||||
#define SLI_SE_COMMAND_SET_UPGRADEFLAG_HOST 0xFE030001UL
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE 0xFE050000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_READ_TRACE_FLAGS 0xFE060000UL
|
||||
#endif
|
||||
#define SLI_SE_COMMAND_INIT_PUBKEY_SIGNATURE 0xFF090001UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY_SIGNATURE 0xFF0A0001UL
|
||||
#define SLI_SE_COMMAND_INIT_AES_128_KEY 0xFF0B0001UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_CONFIGURE_QSPI_REF_CLOCK 0xFF150000UL
|
||||
#define SLI_SE_COMMAND_CONFIGURE_QSPI_REGS 0xFF160000UL
|
||||
#define SLI_SE_COMMAND_GET_QSPI_FLPLL_CONFIG 0xFF170000UL
|
||||
#define SLI_SE_COMMAND_APPLY_CODE_REGION_CONFIG 0xFF500000UL
|
||||
#define SLI_SE_COMMAND_CLOSE_CODE_REGION 0xFF510000UL
|
||||
#define SLI_SE_COMMAND_ERASE_CODE_REGION 0xFF520000UL
|
||||
#define SLI_SE_COMMAND_GET_CODE_REGION_CONFIG 0xFF530000UL
|
||||
#define SLI_SE_COMMAND_GET_CODE_REGION_VERSION 0xFF540000UL
|
||||
#define SLI_SE_COMMAND_SET_ACTIVE_BANKED_CODE_REGION 0xFF550000UL
|
||||
#define SLI_SE_COMMAND_WRITE_CODE_REGION 0xFF560000UL
|
||||
#define SLI_SE_COMMAND_ERASE_DATA_REGION 0xFF620000UL
|
||||
#define SLI_SE_COMMAND_WRITE_DATA_REGION 0xFF630000UL
|
||||
#define SLI_SE_COMMAND_GET_DATA_REGION_LOCATION 0xFF640000UL
|
||||
#endif
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
// Commands limited to SE Vault High devices
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SLI_SE_COMMAND_WRAP_KEY 0x01000000UL
|
||||
#define SLI_SE_COMMAND_UNWRAP_KEY 0x01020000UL
|
||||
#define SLI_SE_COMMAND_DELETE_KEY 0x01050000UL
|
||||
#define SLI_SE_COMMAND_TRANSFER_KEY 0x01060000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC 0x02020002UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_HKDF 0x02020003UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC 0x02020010UL
|
||||
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_ENCRYPT 0x0C000000UL
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_DECRYPT 0x0C010000UL
|
||||
#define SLI_SE_COMMAND_CHACHA20_ENCRYPT 0x0C020000UL
|
||||
#define SLI_SE_COMMAND_CHACHA20_DECRYPT 0x0C030000UL
|
||||
#define SLI_SE_COMMAND_POLY1305_KEY_MAC 0x0C040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DISABLE_TAMPER 0xFD020001UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE command options
|
||||
// Commands are grouped based on availability
|
||||
|
||||
/// Secure boot pubkey
|
||||
#define SLI_SE_KEY_TYPE_BOOT 0x00000100UL
|
||||
/// Secure authorization (debug) pubkey
|
||||
#define SLI_SE_KEY_TYPE_AUTH 0x00000200UL
|
||||
|
||||
// Options limited to SE devices
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/// Root pubkey
|
||||
#define SLI_SE_KEY_TYPE_ROOT 0x00000300UL
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Attestation pubkey
|
||||
#define SLI_SE_KEY_TYPE_ATTEST 0x00000400UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
/// BGL encryption key
|
||||
#define SLI_SE_IMMUTABLE_KEY_TYPE_AES_128 0x00000500UL
|
||||
|
||||
/// Use MD5 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_MD5 0x00000100UL
|
||||
/// Use SHA1 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA1 0x00000200UL
|
||||
/// Use SHA224 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA224 0x00000300UL
|
||||
/// Use SHA256 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA256 0x00000400UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Use SHA1 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA1 0x00000700UL
|
||||
/// Use SHA224 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA224 0x00000800UL
|
||||
/// Use SHA256 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA256 0x00000900UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
|
||||
/// Execute algorithm in ECB mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_ECB 0x00000100UL
|
||||
/// Execute algorithm in CBC mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CBC 0x00000200UL
|
||||
/// Execute algorithm in CTR mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CTR 0x00000300UL
|
||||
/// Execute algorithm in CFB mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CFB 0x00000400UL
|
||||
|
||||
/// Run the whole algorithm, all data present
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_WHOLE 0x00000000UL
|
||||
/// Start the algorithm, but get a context to later add more data
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_START 0x00000001UL
|
||||
/// End the algorithm, get the result
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_END 0x00000002UL
|
||||
/// Add more data input to the algorithm. Need to supply previous context,
|
||||
/// and get a context back
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_ADD 0x00000003UL
|
||||
|
||||
/// User data command options
|
||||
/// Magic paramater for deleting user data
|
||||
#define SLI_SE_COMMAND_OPTION_ERASE_UD 0xDE1E7EADUL
|
||||
#define SLI_SE_COMMAND_OPTION_WRITE 0x00000100UL
|
||||
#define SLI_SE_COMMAND_OPTION_READ 0x00000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_CERT_BATCH 0x00000100UL
|
||||
#define SLI_SE_COMMAND_CERT_SE 0x00000200UL
|
||||
#define SLI_SE_COMMAND_CERT_HOST 0x00000300UL
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Use SHA384 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA384 0x00000500UL
|
||||
/// Use SHA512 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA512 0x00000600UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Use SHA384 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA384 0x00000A00UL
|
||||
/// Use SHA512 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA512 0x00000B00UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Other defines
|
||||
|
||||
/** Maximum amount of parameters supported by the hardware FIFO */
|
||||
#define SE_FIFO_MAX_PARAMETERS 13U
|
||||
|
||||
/** Stop datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_STOP 0x00000001UL
|
||||
/** Discard datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_DISCARD 0x40000000UL
|
||||
/** Realign datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_REALIGN 0x20000000UL
|
||||
/** Datatransfer Const Address*/
|
||||
#define SLI_SE_DATATRANSFER_CONSTADDRESS 0x10000000UL
|
||||
/** Stop Length Mask */
|
||||
#define SLI_SE_DATATRANSFER_LENGTH_MASK 0x0FFFFFFFUL
|
||||
|
||||
/** Maximum amount of parameters for largest command in defined command set */
|
||||
#ifndef SLI_SE_COMMAND_MAX_PARAMETERS
|
||||
#define SLI_SE_COMMAND_MAX_PARAMETERS 4U
|
||||
#endif
|
||||
|
||||
/* Sanity-check defines */
|
||||
#if SLI_SE_COMMAND_MAX_PARAMETERS > SE_FIFO_MAX_PARAMETERS
|
||||
#error "Trying to configure more parameters than supported by the hardware"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE DMA transfer descriptor.
|
||||
|
||||
* Can be linked to each other to provide scatter-gather behavior.
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
volatile void* volatile data; /**< Data pointer */
|
||||
void* volatile next; /**< Next descriptor */
|
||||
volatile uint32_t length; /**< Length */
|
||||
} sli_se_datatransfer_t;
|
||||
|
||||
/** Default initialization of data transfer struct */
|
||||
#define SLI_SE_DATATRANSFER_DEFAULT(address, data_size) \
|
||||
{ \
|
||||
.data = (void*)(address), /* Pointer to data block */ \
|
||||
.next = (void*)SLI_SE_DATATRANSFER_STOP, /* This is the last block by default */ \
|
||||
.length = (data_size) | SLI_SE_DATATRANSFER_REALIGN /* Add size, use realign by default */ \
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE mailbox command structure
|
||||
*
|
||||
* @details
|
||||
* This structure defines the command structure used by the SE mailbox
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
uint32_t command; /**< SE Command */
|
||||
sli_se_datatransfer_t* data_in; /**< Input data */
|
||||
sli_se_datatransfer_t* data_out; /**< Output data */
|
||||
uint32_t parameters[SLI_SE_COMMAND_MAX_PARAMETERS]; /**< Parameters */
|
||||
size_t num_parameters; /**< Number of parameters */
|
||||
} sli_se_mailbox_command_t;
|
||||
|
||||
/** Default initialization of command struct */
|
||||
#define SLI_SE_MAILBOX_COMMAND_DEFAULT(command_word) \
|
||||
{ \
|
||||
.command = command_word, /* Given command word */ \
|
||||
.data_in = NULL, /* No data in */ \
|
||||
.data_out = NULL, /* No data out */ \
|
||||
.parameters = { 0, 0, 0, 0 }, /* No parameters */ \
|
||||
.num_parameters = 0 /* No parameters */ \
|
||||
}
|
||||
|
||||
/** Possible responses to a command */
|
||||
typedef uint32_t sli_se_mailbox_response_t;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add input data to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a buffer of input data to the given SE command structure
|
||||
* The buffer gets appended by reference at the end of the list of already
|
||||
* added buffers.
|
||||
*
|
||||
* @note
|
||||
* Note that this function does not copy either the data buffer or the buffer
|
||||
* structure, so make sure to keep the data object in scope until the command
|
||||
* has been executed by the secure element.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE Mailbox command structure.
|
||||
*
|
||||
* @param[in] data
|
||||
* Pointer to a data transfer structure.
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_input(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add output data to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a buffer of output data to the given command structure
|
||||
* The buffer gets appended by reference at the end of the list of already
|
||||
* added buffers.
|
||||
*
|
||||
* @note
|
||||
* Note that this function does not copy either the data buffer or the buffer
|
||||
* structure, so make sure to keep the data object in scope until the command
|
||||
* has been executed by the secure element.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE mailbox command structure.
|
||||
*
|
||||
* @param[in] data
|
||||
* Pointer to a data transfer structure.
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_output(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add a parameter to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a parameter word to the passed command.
|
||||
*
|
||||
* @note
|
||||
* Make sure to not exceed @ref SE_MAX_PARAMETERS.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to a filled-out SE command structure.
|
||||
* @param[in] parameter
|
||||
* Parameter to add.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sli_se_mailbox_command_add_parameter(sli_se_mailbox_command_t *command, uint32_t parameter);
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute the passed command
|
||||
*
|
||||
* @details
|
||||
* This function starts the execution of the passed command by the secure
|
||||
* element. The RXINT interrupt flag will be set upon completion. Call
|
||||
* @ref sli_se_mailbox_read_response to wait for completion and retrieve the
|
||||
* command's execution status.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to a filled-out SE command structure.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sli_se_mailbox_execute_command(sli_se_mailbox_command_t *command);
|
||||
#endif //!defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the status of the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function waits for any running command to complete before reading the
|
||||
* status of the previously executed command.
|
||||
*
|
||||
* @note
|
||||
* The command response needs to be read for every executed command, and can
|
||||
* only be read once per executed command (FIFO behavior).
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SE_RESPONSE_OK when the command was executed successfully or a signature
|
||||
* was successfully verified.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_read_response(void)
|
||||
{
|
||||
while (!(SEMAILBOX_HOST->RX_STATUS & SEMAILBOX_RX_STATUS_RXINT)) {
|
||||
// Wait for command completion by polling SE Mailbox RX interrupt flag
|
||||
}
|
||||
// Return command response
|
||||
return (sli_se_mailbox_response_t)(SEMAILBOX_HOST->RX_HEADER & SLI_SE_RESPONSE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handle the response of the previously executed command.
|
||||
*
|
||||
* \details This function handles the response of the previously
|
||||
* executed HSE command by calling sli_se_mailbox_read_response
|
||||
* to read the response value and returns it. For Series-3 this
|
||||
* function also clears the SEMAILBOX FIFO by reading out the
|
||||
* unused command handle word.
|
||||
* This function is called by the ISR of the SEMAILBOX (called
|
||||
* SEMBRX_IRQHandler ) to clear the SEMBRX_IRQn interrupt signal
|
||||
* on the SEMAILBOX peripheral side. NOTE: The ISR will also
|
||||
* need to clear the SEMBRX_IRQn condition in the internal/local
|
||||
* interrupt controller (NVIC) by calling
|
||||
* NVIC_ClearPendingIRQ(SEMBRX_IRQn).
|
||||
*
|
||||
* \return Value returned by sli_se_mailbox_read_response.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_handle_response(void)
|
||||
{
|
||||
// Read command response
|
||||
sli_se_mailbox_response_t se_mailbox_response = sli_se_mailbox_read_response();
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
// Read the command handle word ( not used ) from the SEMAILBOX FIFO
|
||||
SEMAILBOX_HOST->FIFO;
|
||||
#endif
|
||||
|
||||
// Return command response
|
||||
return se_mailbox_response;
|
||||
}
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
sli_se_mailbox_response_t sli_se_mailbox_read_response(void);
|
||||
|
||||
/**
|
||||
* \brief Handle the response of the previously executed command.
|
||||
*
|
||||
* \details This function handles the response of the previously
|
||||
* executed VSE command by calling sli_se_mailbox_read_response
|
||||
* to read the response value and returns it.
|
||||
*
|
||||
* \return Value returned by sli_se_mailbox_read_response.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_handle_response(void)
|
||||
{
|
||||
// Read and return VSE mailbox command response
|
||||
return sli_se_mailbox_read_response();
|
||||
}
|
||||
#endif // #if defined(SEMAILBOX_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more SE interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* SE interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the Secure Element module
|
||||
* (SE_CONFIGURATION_(TX/RX)INTEN).
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_se_mailbox_disable_interrupt(uint32_t flags)
|
||||
{
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
SEMAILBOX_HOST->CONFIGURATION &= ~flags;
|
||||
#else
|
||||
(void) flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more SE interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* SE interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the Secure Element module
|
||||
* (SEMAILBOX_CONFIGURATION_TXINTEN or SEMAILBOX_CONFIGURATION_RXINTEN).
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_se_mailbox_enable_interrupt(uint32_t flags)
|
||||
{
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
SEMAILBOX_HOST->CONFIGURATION |= flags;
|
||||
#else
|
||||
(void) flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current SE version
|
||||
*
|
||||
* @details
|
||||
* This function returns the current VSE version
|
||||
*
|
||||
* @param[in] version
|
||||
* Pointer to location where to copy the version of VSE to.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_version(uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get VSE configuration and status bits
|
||||
*
|
||||
* @details
|
||||
* This function returns the current VSE configuration and status bits.
|
||||
* The following list explains what the different bits in cfg_status indicate.
|
||||
* A bit value of 1 means enabled, while 0 means disabled:
|
||||
* * [0]: Secure boot
|
||||
* * [1]: Verify secure boot certificate
|
||||
* * [2]: Anti-rollback
|
||||
* * [3]: Narrow page lock
|
||||
* * [4]: Full page lock
|
||||
* The following status bits can be read with VSE versions
|
||||
* higher than 1.2.2.
|
||||
* * [10]: Debug port lock
|
||||
* * [11]: Device erase enabled
|
||||
* * [12]: Secure debug enabled
|
||||
* * [15]: Debug port register state, 1 if the debug port is locked.
|
||||
*
|
||||
* @param[out] cfg_status
|
||||
* Pointer to location to copy Configuration Status bits into.
|
||||
*
|
||||
* @note
|
||||
* This function will check that the mailbox content is valid before
|
||||
* reading the status bits. If the command response has already been read
|
||||
* with a call to @ref sli_vse_mailbox_ack_command(), the validity check will fail, and
|
||||
* the config status bits cannot be read before a reset has occurred.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_cfg_status(uint32_t *cfg_status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the version number of the OTP from the status field of the output
|
||||
* mailbox
|
||||
* @details
|
||||
* This function checks if the OTP version number flag is set in the output
|
||||
* mailbox. If it is, the version number is writen to @ref otp_version pointer
|
||||
* location. If not, it returns error response.
|
||||
*
|
||||
* @param[out] otp_version
|
||||
* Pointer to location to copy OTP version number into.
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_otp_version(uint32_t *otp_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command.
|
||||
* The mailbox command is acknowledged by inverting all bits in the checksum
|
||||
* (XOR with 0xFFFFFFFF).
|
||||
* The output data is copied into the linked list of output buffers pointed
|
||||
* to in the given command data structure.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE command structure.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully or a
|
||||
* signature was successfully verified,
|
||||
* @retval SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* @retval SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* @retval SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* @retval SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command,
|
||||
* e.g. because of conflicting Secure/Non-Secure
|
||||
* memory accesses,
|
||||
* @retval SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* @retval SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* @retval SLI_SE_RESPONSE_MAILBOX_INVALID when mailbox command not done or invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_ack_command(sli_se_mailbox_command_t *command);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function reads the previously executed command.
|
||||
*
|
||||
* @return
|
||||
* One of the SE command words.
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid.
|
||||
******************************************************************************/
|
||||
uint32_t sli_vse_mailbox_read_executed_command(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the VSE Output Mailbox is valid.
|
||||
*
|
||||
* @return True if the VSE Output Mailbox is valid (magic and checksum OK)
|
||||
******************************************************************************/
|
||||
bool sli_vse_mailbox_is_output_valid(void);
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#endif /* SLI_SE_MANAGER_MAILBOX_H */
|
||||
@@ -0,0 +1,560 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_assert.h"
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#include "sl_hal_bus.h"
|
||||
#else
|
||||
#include "em_bus.h"
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
#include "sli_psec_osal.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_managers
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Locals
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
/// Priority to use for SEMBRX IRQ
|
||||
#if defined(SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY)
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY >= (1U << __NVIC_PRIO_BITS) )
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) ) )
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#else
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < CORE_ATOMIC_BASE_PRIORITY_LEVEL)
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#endif
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY
|
||||
#else
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) )
|
||||
#else
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (CORE_ATOMIC_BASE_PRIORITY_LEVEL)
|
||||
#endif
|
||||
#endif
|
||||
#else // defined(SL_SE_MANAGER_THREADING)
|
||||
/// Priority to use for SEMBRX IRQ
|
||||
#if defined(SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY)
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY
|
||||
#else
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (0)
|
||||
#endif
|
||||
#endif // defined(SL_SE_MANAGER_THREADING)
|
||||
#endif // defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Flag to indicate that the SE Manager is initialized or not.
|
||||
static volatile bool se_manager_initialized = false;
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
// Lock mutex for synchronizing multiple threads calling into the
|
||||
// SE Manager API.
|
||||
static sli_psec_osal_lock_t se_lock = { 0 };
|
||||
|
||||
#endif // SL_SE_MANAGER_THREADING
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
// SE command completion.
|
||||
static sli_psec_osal_completion_t se_command_completion;
|
||||
// SE mailbox command response code. This value is read from the SEMAILBOX
|
||||
// in ISR in order to clear the command complete interrupt condition.
|
||||
static sli_se_mailbox_response_t se_manager_command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize the SE Manager.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init(void)
|
||||
{
|
||||
sl_status_t ret = SL_STATUS_OK;
|
||||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
(void)se_manager_command_response;
|
||||
#endif
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_START
|
||||
#endif
|
||||
|
||||
if ( !se_manager_initialized ) {
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
// Initialize SE lock
|
||||
ret = sli_psec_osal_init_lock(&se_lock);
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Initialize command completion object.
|
||||
ret = sli_psec_osal_init_completion(&se_command_completion);
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Enable SE RX mailbox interrupt in NVIC, but not in SEMAILBOX
|
||||
// which will be enabled if the yield parameter in
|
||||
// sli_se_execute_and_wait is true.
|
||||
NVIC_SetPriority(SEMBRX_IRQn, SE_MANAGER_SEMBRX_IRQ_PRIORITY);
|
||||
NVIC_EnableIRQ(SEMBRX_IRQn);
|
||||
}
|
||||
}
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
if (ret == SL_STATUS_OK) {
|
||||
se_manager_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Denitialize the SE Manager.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit(void)
|
||||
{
|
||||
sl_status_t ret = SL_STATUS_OK;
|
||||
|
||||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_START
|
||||
#endif
|
||||
|
||||
if ( se_manager_initialized ) {
|
||||
// We need to exit the critical section in case the SE lock is held by a
|
||||
// thread, and we want to take it before de-initializing.
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
// Acquire the SE lock to make sure no thread is executing SE commands
|
||||
// when we de-initialize.
|
||||
ret = sli_se_lock_acquire();
|
||||
if (ret != SL_STATUS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
// Disable SE RX mailbox interrupt in NVIC.
|
||||
NVIC_ClearPendingIRQ(SEMBRX_IRQn);
|
||||
NVIC_DisableIRQ(SEMBRX_IRQn);
|
||||
// Free command completion object.
|
||||
ret = sli_psec_osal_free_completion(&se_command_completion);
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Free the SE lock mutex
|
||||
ret = sli_psec_osal_free_lock(&se_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark the SE Manager as un-initialized.
|
||||
se_manager_initialized = false;
|
||||
}
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
else {
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Translate SE response codes to sl_status_t codes.
|
||||
*
|
||||
* @return
|
||||
* Converted status code, their meaning is documented here @ref sl_status.h,
|
||||
* Asserts and returns @c SL_STATUS_FAIL on unexpected response.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_to_sl_status(sli_se_mailbox_response_t res)
|
||||
{
|
||||
switch (res) {
|
||||
case SLI_SE_RESPONSE_OK:
|
||||
return SL_STATUS_OK;
|
||||
case SLI_SE_RESPONSE_INVALID_COMMAND:
|
||||
return SL_STATUS_COMMAND_IS_INVALID;
|
||||
case SLI_SE_RESPONSE_AUTHORIZATION_ERROR:
|
||||
return SL_STATUS_INVALID_CREDENTIALS;
|
||||
case SLI_SE_RESPONSE_INVALID_SIGNATURE:
|
||||
return SL_STATUS_INVALID_SIGNATURE;
|
||||
case SLI_SE_RESPONSE_BUS_ERROR:
|
||||
return SL_STATUS_BUS_ERROR;
|
||||
case SLI_SE_RESPONSE_INTERNAL_ERROR:
|
||||
return SL_STATUS_FAIL;
|
||||
case SLI_SE_RESPONSE_CRYPTO_ERROR:
|
||||
return SL_STATUS_FAIL;
|
||||
case SLI_SE_RESPONSE_INVALID_PARAMETER:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
case SLI_SE_RESPONSE_ABORT:
|
||||
return SL_STATUS_ABORT;
|
||||
case SLI_SE_RESPONSE_SELFTEST_ERROR:
|
||||
return SL_STATUS_INITIALIZATION;
|
||||
case SLI_SE_RESPONSE_NOT_INITIALIZED:
|
||||
return SL_STATUS_NOT_INITIALIZED;
|
||||
#if defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
case SLI_SE_RESPONSE_MAILBOX_INVALID:
|
||||
return SL_STATUS_COMMAND_IS_INVALID;
|
||||
#endif
|
||||
default:
|
||||
// Assert we do not get a bad SE response code.
|
||||
EFM_ASSERT(false);
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Acquire the SE lock for exclusive access if necessary (thread mode).
|
||||
* Enable the SEMAILBOX clock if necessary.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_lock_acquire(void)
|
||||
{
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
sl_status_t status = sli_psec_osal_take_lock(&se_lock);
|
||||
#else
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
#endif
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
if (status == SL_STATUS_OK) {
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_hal_bus_reg_write_bit(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 1);
|
||||
#else
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 1);
|
||||
#endif
|
||||
// Make sure the write to CMU->CLKEN1 is finished.
|
||||
__DSB();
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Release the SE lock if necessary (thread mode).
|
||||
* Disable the SEMAILBOX clock if necessary.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_lock_release(void)
|
||||
{
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_hal_bus_reg_write_bit(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 0);
|
||||
#else
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 0);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
return sli_psec_osal_give_lock(&se_lock);
|
||||
#else
|
||||
return SL_STATUS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* SE Mailbox Interrupt Service Routine
|
||||
******************************************************************************/
|
||||
void SEMBRX_IRQHandler(void)
|
||||
{
|
||||
sl_status_t status;
|
||||
// Check if the SE mailbox is the source of the interrupt.
|
||||
if (SEMAILBOX_HOST->RX_STATUS & SEMAILBOX_RX_STATUS_RXINT) {
|
||||
// Signal SE mailbox completion.
|
||||
status = sli_psec_osal_complete(&se_command_completion);
|
||||
EFM_ASSERT(status == SL_STATUS_OK);
|
||||
}
|
||||
// Get command response and clear interrupt condition in SEMAILBOX peripheral
|
||||
se_manager_command_response = sli_se_mailbox_handle_response();
|
||||
// Clear interrupt condition in NVIC
|
||||
NVIC_ClearPendingIRQ(SEMBRX_IRQn);
|
||||
}
|
||||
|
||||
#endif // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set the yield attribute of the SE command context object.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_yield(sl_se_command_context_t *cmd_ctx,
|
||||
bool yield)
|
||||
{
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
cmd_ctx->yield = yield;
|
||||
return SL_STATUS_OK;
|
||||
#else
|
||||
if (yield) {
|
||||
return SL_STATUS_NOT_AVAILABLE;
|
||||
} else {
|
||||
(void) cmd_ctx;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute and wait for SE mailbox command to complete.
|
||||
*
|
||||
* @return
|
||||
* One of the following status code, any other status codes relates to internal
|
||||
* function errors see @ref sl_status.h for their meaning.
|
||||
* - @c SL_STATUS_OK
|
||||
* - @c SL_STATUS_INVALID_PARAMETER
|
||||
******************************************************************************/
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_FAIL;
|
||||
sli_se_mailbox_response_t command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Execute SE mailbox command
|
||||
sli_se_mailbox_execute_command(&cmd_ctx->command);
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
if (cmd_ctx->yield) {
|
||||
// Enable SEMAILBOX RXINT interrupt
|
||||
sli_se_mailbox_enable_interrupt(SEMAILBOX_CONFIGURATION_RXINTEN);
|
||||
|
||||
// Yield and Wait for the command completion signal
|
||||
status = sli_psec_osal_wait_completion(&se_command_completion,
|
||||
SLI_PSEC_OSAL_WAIT_FOREVER);
|
||||
|
||||
// Disable SEMAILBOX RXINT interrupt.
|
||||
sli_se_mailbox_disable_interrupt(SEMAILBOX_CONFIGURATION_RXINTEN);
|
||||
|
||||
if (status != SL_STATUS_OK) {
|
||||
#if (_SILICON_LABS_32B_SERIES == 3)
|
||||
// Read the command handle word ( not used ) from the SEMAILBOX FIFO
|
||||
SEMAILBOX_HOST->FIFO;
|
||||
#endif // #if (_SILICON_LABS_32B_SERIES == 3)
|
||||
sli_se_lock_release();
|
||||
return status;
|
||||
}
|
||||
|
||||
// Get response which is read in the ISR to clear interrupt condition.
|
||||
command_response = se_manager_command_response;
|
||||
// Default to an error.
|
||||
se_manager_command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
} else {
|
||||
// Wait for command completion and get command response
|
||||
command_response = sli_se_mailbox_handle_response();
|
||||
}
|
||||
|
||||
#else // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Wait for command completion and get command response
|
||||
command_response = sli_se_mailbox_handle_response();
|
||||
|
||||
#endif // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (command_response == SLI_SE_RESPONSE_OK) {
|
||||
return status;
|
||||
} else {
|
||||
// Convert from sli_se_mailbox_response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(command_response);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Execute SE mailbox command
|
||||
sli_se_mailbox_execute_command(&cmd_ctx->command);
|
||||
|
||||
return SL_STATUS_FAIL; // Should never get to this point
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* From VSE mailbox read which command, if any, was executed.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_executed_command(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Read command
|
||||
cmd_ctx->command.command = sli_vse_mailbox_read_executed_command();
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (cmd_ctx->command.command == SLI_SE_RESPONSE_MAILBOX_INVALID) {
|
||||
// Convert from sli_se_mailbox_response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(SLI_SE_RESPONSE_MAILBOX_INVALID);
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
sl_status_t command_response;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Acknowledge VSE mailbox command
|
||||
command_response = sli_vse_mailbox_ack_command(&cmd_ctx->command);
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (command_response == SLI_SE_RESPONSE_OK) {
|
||||
return status;
|
||||
} else {
|
||||
// Convert from SE_Response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(command_response);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize an SE command context object
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_se_command_context_t v = SL_SE_COMMAND_CONTEXT_INIT;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*cmd_ctx = v;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* De-initialize an SE command context object
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return sl_se_init_command_context(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
@@ -0,0 +1,296 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sl_se_manager_attestation.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Static Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate the command word, challenge size and update command word with
|
||||
* option flags
|
||||
*
|
||||
* @param[in, out] command_word
|
||||
* The command word to send to the SE. Will be modified to reflect challenge
|
||||
* size.
|
||||
*
|
||||
* @param challenge_size
|
||||
* Size of the challenge to be used.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t validate_and_update_command_word(uint32_t *command_word,
|
||||
size_t challenge_size)
|
||||
{
|
||||
// Check supported challenge sizes
|
||||
uint32_t command_id = *command_word & 0xFFFF0000UL;
|
||||
if (command_id == SLI_SE_COMMAND_ATTEST_PSA_IAT) {
|
||||
switch (challenge_size) {
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_32:
|
||||
*command_word |= 0x01 << 8;
|
||||
break;
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_48:
|
||||
*command_word |= 0x02 << 8;
|
||||
break;
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_64:
|
||||
*command_word |= 0x03 << 8;
|
||||
break;
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (command_id == SLI_SE_COMMAND_ATTEST_CONFIG) {
|
||||
if (challenge_size != SL_SE_ATTESTATION_CHALLENGE_SIZE_32) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// No need to do anything with the command word
|
||||
} else {
|
||||
// Unknown command ID
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// All the checks passed
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the PSA initial attest token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* SE command context struct.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @param[in] command_word
|
||||
* The command word to send to the SE, to differentiat between token types
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t get_attestation_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size,
|
||||
uint32_t command_word)
|
||||
{
|
||||
// Parameter check
|
||||
if (cmd_ctx == NULL || token_size == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Check command word and challenge size
|
||||
sl_status_t status = validate_and_update_command_word(&command_word,
|
||||
challenge_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Use a dummy nonce since the SE requires nonce input even if we just
|
||||
// want to find the token length
|
||||
uint8_t dummy_nonce[SL_SE_ATTESTATION_CHALLENGE_SIZE_64] = { 0 };
|
||||
|
||||
// Build and execute the command
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
// Or comman word with 0x01 to enable length output only
|
||||
sli_se_command_init(cmd_ctx, command_word | 0x01UL);
|
||||
sli_se_datatransfer_t noncedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(dummy_nonce, challenge_size);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &noncedata);
|
||||
sli_se_datatransfer_t sizedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &sizedata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get an attestation token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* SE command context struct.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @param[in] command_word
|
||||
* The command word to send to the SE, to differentiat between token types
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t get_attestation_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size,
|
||||
uint32_t command_word)
|
||||
{
|
||||
// Parameter check
|
||||
if (cmd_ctx == NULL
|
||||
|| auth_challenge == NULL
|
||||
|| token_buf == NULL
|
||||
|| token_size == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Check supported challenge sizes
|
||||
sl_status_t status = validate_and_update_command_word(&command_word,
|
||||
challenge_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Check that buffer is sufficiently large
|
||||
status = get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
command_word);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
if (((*token_size + 0x3) & ~0x3) > token_buf_size) {
|
||||
return SL_STATUS_WOULD_OVERFLOW;
|
||||
}
|
||||
|
||||
// Build and execute the command
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
sli_se_datatransfer_t noncedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(auth_challenge, challenge_size);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &noncedata);
|
||||
sli_se_datatransfer_t sizedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &sizedata);
|
||||
sli_se_datatransfer_t tokendata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_buf, ((*token_size + 0x3) & ~0x3));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &tokendata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the PSA initial attest token from the SE
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token(cmd_ctx,
|
||||
auth_challenge,
|
||||
challenge_size,
|
||||
token_buf,
|
||||
token_buf_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_PSA_IAT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the size of a PSA initial attest token with the given nonce
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_PSA_IAT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get an attested (signed) security configuration token from the SE
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token(cmd_ctx,
|
||||
auth_challenge,
|
||||
challenge_size,
|
||||
token_buf,
|
||||
token_buf_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_CONFIG);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the size of a security configuration token
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_CONFIG);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se_manager) */
|
||||
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED && VAULT
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get random data from hardware TRNG.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_random(sl_se_command_context_t *cmd_ctx,
|
||||
void * data,
|
||||
uint32_t num_bytes)
|
||||
{
|
||||
sli_se_mailbox_command_t *se_cmd;
|
||||
sl_status_t ret;
|
||||
uint32_t surplus_bytes, i;
|
||||
uint32_t surplus_word = 0;
|
||||
|
||||
if (cmd_ctx == NULL || (num_bytes != 0 && data == NULL)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
se_cmd = &cmd_ctx->command;
|
||||
surplus_bytes = num_bytes & 0x3U;
|
||||
num_bytes &= ~0x3U;
|
||||
|
||||
if (num_bytes > 0U) {
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(data, num_bytes);
|
||||
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, num_bytes);
|
||||
|
||||
// Execute and wait
|
||||
if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
|
||||
memset(data, 0, num_bytes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (surplus_bytes > 0) {
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(&surplus_word, 4);
|
||||
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, 4);
|
||||
|
||||
// Execute and wait
|
||||
if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
|
||||
memset(data, 0, num_bytes + surplus_bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *output = (uint8_t*)data + num_bytes;
|
||||
for (i = 0; i < surplus_bytes; i++) {
|
||||
output[i] = (surplus_word >> (i * 8U)) & 0xFFU;
|
||||
}
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
@@ -0,0 +1,673 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se Secure Engine Manager API
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA1 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t *sha1_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha1[32] = {
|
||||
0x67, 0x45, 0x23, 0x01,
|
||||
0xEF, 0xCD, 0xAB, 0x89,
|
||||
0x98, 0xBA, 0xDC, 0xFE,
|
||||
0x10, 0x32, 0x54, 0x76,
|
||||
0xC3, 0xD2, 0xE1, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha1_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha1_ctx->total[0] = 0;
|
||||
sha1_ctx->total[1] = 0;
|
||||
memcpy(sha1_ctx->state, init_state_sha1, sizeof(sha1_ctx->state));
|
||||
|
||||
sha1_ctx->hash_type = SL_SE_HASH_SHA1;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA224 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t *sha224_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha224[32] = {
|
||||
0xC1, 0x05, 0x9E, 0xD8,
|
||||
0x36, 0x7C, 0xD5, 0x07,
|
||||
0x30, 0x70, 0xDD, 0x17,
|
||||
0xF7, 0x0E, 0x59, 0x39,
|
||||
0xFF, 0xC0, 0x0B, 0x31,
|
||||
0x68, 0x58, 0x15, 0x11,
|
||||
0x64, 0xF9, 0x8F, 0xA7,
|
||||
0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha224_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha224_ctx->total[0] = 0;
|
||||
sha224_ctx->total[1] = 0;
|
||||
memcpy(sha224_ctx->state, init_state_sha224, sizeof(sha224_ctx->state));
|
||||
|
||||
sha224_ctx->hash_type = SL_SE_HASH_SHA224;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA256 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t *sha256_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha256[32] = {
|
||||
0x6A, 0x09, 0xE6, 0x67,
|
||||
0xBB, 0x67, 0xAE, 0x85,
|
||||
0x3C, 0x6E, 0xF3, 0x72,
|
||||
0xA5, 0x4F, 0xF5, 0x3A,
|
||||
0x51, 0x0E, 0x52, 0x7F,
|
||||
0x9B, 0x05, 0x68, 0x8C,
|
||||
0x1F, 0x83, 0xD9, 0xAB,
|
||||
0x5B, 0xE0, 0xCD, 0x19
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha256_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha256_ctx->total[0] = 0;
|
||||
sha256_ctx->total[1] = 0;
|
||||
memcpy(sha256_ctx->state, init_state_sha256, sizeof(sha256_ctx->state));
|
||||
|
||||
sha256_ctx->hash_type = SL_SE_HASH_SHA256;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* Start a SHA384 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t *sha384_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha384[64] = {
|
||||
0xCB, 0xBB, 0x9D, 0x5D, 0xC1, 0x05, 0x9E, 0xD8,
|
||||
0x62, 0x9A, 0x29, 0x2A, 0x36, 0x7C, 0xD5, 0x07,
|
||||
0x91, 0x59, 0x01, 0x5A, 0x30, 0x70, 0xDD, 0x17,
|
||||
0x15, 0x2F, 0xEC, 0xD8, 0xF7, 0x0E, 0x59, 0x39,
|
||||
0x67, 0x33, 0x26, 0x67, 0xFF, 0xC0, 0x0B, 0x31,
|
||||
0x8E, 0xB4, 0x4A, 0x87, 0x68, 0x58, 0x15, 0x11,
|
||||
0xDB, 0x0C, 0x2E, 0x0D, 0x64, 0xF9, 0x8F, 0xA7,
|
||||
0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha384_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha384_ctx->total[0] = 0;
|
||||
sha384_ctx->total[1] = 0;
|
||||
sha384_ctx->total[2] = 0;
|
||||
sha384_ctx->total[3] = 0;
|
||||
memcpy(sha384_ctx->state, init_state_sha384, sizeof(sha384_ctx->state));
|
||||
|
||||
sha384_ctx->hash_type = SL_SE_HASH_SHA384;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA512 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t *sha512_ctx, sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha512[64] = {
|
||||
0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08,
|
||||
0xBB, 0x67, 0xAE, 0x85, 0x84, 0xCA, 0xA7, 0x3B,
|
||||
0x3C, 0x6E, 0xF3, 0x72, 0xFE, 0x94, 0xF8, 0x2B,
|
||||
0xA5, 0x4F, 0xF5, 0x3A, 0x5F, 0x1D, 0x36, 0xF1,
|
||||
0x51, 0x0E, 0x52, 0x7F, 0xAD, 0xE6, 0x82, 0xD1,
|
||||
0x9B, 0x05, 0x68, 0x8C, 0x2B, 0x3E, 0x6C, 0x1F,
|
||||
0x1F, 0x83, 0xD9, 0xAB, 0xFB, 0x41, 0xBD, 0x6B,
|
||||
0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha512_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha512_ctx->total[0] = 0;
|
||||
sha512_ctx->total[1] = 0;
|
||||
sha512_ctx->total[2] = 0;
|
||||
sha512_ctx->total[3] = 0;
|
||||
memcpy(sha512_ctx->state, init_state_sha512, sizeof(sha512_ctx->state));
|
||||
|
||||
sha512_ctx->hash_type = SL_SE_HASH_SHA512;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a hash stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_starts(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type)
|
||||
{
|
||||
if (cmd_ctx == NULL || hash_type_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
return sl_se_hash_sha1_multipart_starts((sl_se_sha1_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
return sl_se_hash_sha224_multipart_starts((sl_se_sha224_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
return sl_se_hash_sha256_multipart_starts((sl_se_sha256_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
return sl_se_hash_sha384_multipart_starts((sl_se_sha384_multipart_context_t*)
|
||||
hash_type_ctx,
|
||||
cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
return sl_se_hash_sha512_multipart_starts((sl_se_sha512_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Feeds an input block into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
static sl_status_t se_cmd_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
uint32_t num_blocks)
|
||||
{
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
uint8_t *state;
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASHUPDATE;
|
||||
size_t state_len, blocksize;
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
state_len = 20;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
state_len = 32;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
state_len = 32;
|
||||
blocksize = 64;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
state_len = 64;
|
||||
blocksize = 128;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
state_len = 64;
|
||||
blocksize = 128;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
size_t ilen = blocksize * num_blocks;
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, ilen);
|
||||
|
||||
sli_se_datatransfer_t data_in = SLI_SE_DATATRANSFER_DEFAULT(input, ilen);
|
||||
sli_se_datatransfer_t iv_in = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
sli_se_datatransfer_t iv_out = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &iv_in);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &data_in);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &iv_out);
|
||||
|
||||
// Execute and wait
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len)
|
||||
{
|
||||
size_t blocks, fill, left, blocksize, countersize;
|
||||
sl_status_t status;
|
||||
uint8_t *buffer;
|
||||
uint32_t *counter;
|
||||
|
||||
if ( input_len == 0 ) {
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || input == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 128;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 128;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
countersize = blocksize / 32;
|
||||
left = (counter[0] & (blocksize - 1));
|
||||
fill = blocksize - left;
|
||||
|
||||
counter[0] += input_len;
|
||||
|
||||
// ripple counter
|
||||
if ( counter[0] < input_len ) {
|
||||
counter[1] += 1;
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
for (size_t i = 1; i < (countersize - 1); i++) {
|
||||
if ( counter[i] == 0 ) {
|
||||
counter[i + 1]++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)countersize;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We only support hashing up to 4 GB data
|
||||
// so if anything but counter[0] is set, return NOT_SUPPORTED
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
for (size_t i = 1; i < countersize; i++) {
|
||||
if (counter[i] != 0) {
|
||||
return SL_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( (left > 0) && (input_len >= fill) ) {
|
||||
memcpy( (void *) (buffer + left), input, fill);
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, buffer, 1);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
input += fill;
|
||||
input_len -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
if ( input_len >= blocksize ) {
|
||||
blocks = input_len / blocksize;
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, input, blocks);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
input += blocksize * blocks;
|
||||
input_len -= blocksize * blocks;
|
||||
}
|
||||
|
||||
if ( input_len > 0 ) {
|
||||
memcpy( (void *) (buffer + left), input, input_len);
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Finish an ongoing hash streaming computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_finish(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len)
|
||||
{
|
||||
sl_status_t status;
|
||||
size_t countersize, blocksize, outputsize;
|
||||
uint8_t *state;
|
||||
uint32_t *counter;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASHFINISH;
|
||||
uint8_t *buffer;
|
||||
size_t state_len;
|
||||
#else
|
||||
size_t last_data_byte, num_pad_bytes;
|
||||
uint8_t msglen[16];
|
||||
// Define padding as largest padding we might need
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
static const unsigned char sha_padding[128] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#else
|
||||
static const unsigned char sha_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || digest_out == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 20;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 20;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 28;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 32;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 32;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 32;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 48;
|
||||
blocksize = 128;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 64;
|
||||
blocksize = 128;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( digest_len < outputsize ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
countersize = blocksize / 32;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
|
||||
// We only support hashing up to 4 GB data
|
||||
// so if anything but counter[0] is set, return NOT_SUPPORTED
|
||||
for (size_t i = 1; i < countersize; i++) {
|
||||
if (counter[i] != 0) {
|
||||
return SL_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
// Remaining bytes in buffer
|
||||
size_t rem_bytes = (counter[0] & (blocksize - 1));
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, rem_bytes);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, counter[0]);
|
||||
|
||||
sli_se_datatransfer_t in_0 = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
sli_se_datatransfer_t in_1 = SLI_SE_DATATRANSFER_DEFAULT(buffer, rem_bytes);
|
||||
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(digest_out, outputsize);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &in_0);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &in_1);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &out);
|
||||
|
||||
// Execute and wait
|
||||
status = sli_se_execute_and_wait(cmd_ctx);
|
||||
#else
|
||||
|
||||
/* Convert counter value to bits, and put in big-endian array */
|
||||
uint8_t residual = 0;
|
||||
for (size_t i = 0; i < countersize; i++) {
|
||||
size_t msglen_index = ( (countersize - i) * sizeof(uint32_t) ) - 1;
|
||||
|
||||
msglen[msglen_index - 0] = ((counter[i] << 3) + residual) & 0xFF;
|
||||
msglen[msglen_index - 1] = (counter[i] >> 5) & 0xFF;
|
||||
msglen[msglen_index - 2] = (counter[i] >> 13) & 0xFF;
|
||||
msglen[msglen_index - 3] = (counter[i] >> 21) & 0xFF;
|
||||
|
||||
residual = (counter[i] >> 29) & 0xFF;
|
||||
}
|
||||
|
||||
last_data_byte = (counter[0] & (blocksize - 1) );
|
||||
num_pad_bytes = (last_data_byte < (blocksize - (countersize * 4)) )
|
||||
? ( (blocksize - (countersize * 4)) - last_data_byte)
|
||||
: ( ((2 * blocksize) - (countersize * 4)) - last_data_byte);
|
||||
|
||||
status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, sha_padding, num_pad_bytes);
|
||||
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, msglen, countersize * 4);
|
||||
}
|
||||
|
||||
if (status == SL_STATUS_OK) {
|
||||
memcpy(digest_out, state, outputsize);
|
||||
}
|
||||
#endif // SLI_SE_MAJOR_VERSION_TWO
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Produce a message digest (a hash block) using the input data.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
const uint8_t *message,
|
||||
unsigned int message_size,
|
||||
uint8_t* digest,
|
||||
size_t digest_len)
|
||||
{
|
||||
if (cmd_ctx == NULL
|
||||
|| digest == NULL
|
||||
|| (message == NULL
|
||||
&& message_size != 0)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASH;
|
||||
uint32_t digest_size = 0;
|
||||
|
||||
switch (hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
digest_size = 20;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
digest_size = 28;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
digest_size = 32;
|
||||
break;
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
digest_size = 48;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
digest_size = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( digest_len < digest_size ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_size);
|
||||
|
||||
sli_se_datatransfer_t data_in = SLI_SE_DATATRANSFER_DEFAULT(message, message_size);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(digest, digest_size);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &data_in);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
|
||||
// Execute and wait
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* ECC signature generation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
unsigned char *signature,
|
||||
size_t signature_len)
|
||||
{
|
||||
if (cmd_ctx == NULL || key == NULL || signature == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if ( message == NULL && message_len != 0 ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_SIGN;
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
command_word = SLI_SE_COMMAND_EDDSA_SIGN;
|
||||
} else {
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup SE command and parameters
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
// Add key parameters to command
|
||||
sli_add_key_parameters(cmd_ctx, key, status);
|
||||
// Message size (number of bytes)
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_len);
|
||||
// Add key metadata block to command
|
||||
sli_add_key_metadata(cmd_ctx, key, status);
|
||||
// Add key input block to command
|
||||
sli_add_key_input(cmd_ctx, key, status);
|
||||
|
||||
sli_se_datatransfer_t message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
|
||||
// EdDSA requires the message twice
|
||||
sli_se_datatransfer_t repeated_message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &repeated_message_buffer);
|
||||
}
|
||||
|
||||
sli_se_datatransfer_t signature_buffer = SLI_SE_DATATRANSFER_DEFAULT(signature, signature_len);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &signature_buffer);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* ECC signature verification.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
const unsigned char *signature,
|
||||
size_t signature_len)
|
||||
{
|
||||
if (cmd_ctx == NULL || key == NULL || (message == NULL && message_len != 0) || signature == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// Key needs to contain public key in order to verify signatures
|
||||
if (!(key->flags & SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_VERIFY;
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
command_word = SLI_SE_COMMAND_EDDSA_VERIFY;
|
||||
} else {
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup SE command and parameters
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
// Add key parameters to command
|
||||
sli_add_key_parameters(cmd_ctx, key, status);
|
||||
// Message size (number of bytes)
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_len);
|
||||
// Add key metadata block to command
|
||||
sli_add_key_metadata(cmd_ctx, key, status);
|
||||
// Add key input block to command
|
||||
sli_add_key_input(cmd_ctx, key, status);
|
||||
|
||||
sli_se_datatransfer_t message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message,
|
||||
message_len);
|
||||
sli_se_datatransfer_t signature_buffer = SLI_SE_DATATRANSFER_DEFAULT(signature,
|
||||
signature_len);
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &signature_buffer);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
} else {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &signature_buffer);
|
||||
}
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,617 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SE Mailbox API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
|
||||
#if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
#include "sl_core.h"
|
||||
#endif
|
||||
|
||||
#include "sl_assert.h"
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup se
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/// Signal that OTP version is incorporated into the status field of the output
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_SET (1 << 21)
|
||||
/// Mask defining the region of the status field that contains the OTP version
|
||||
/// number.
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_MASK (0xFF000000UL)
|
||||
/// Shift to insert a number into the otp version part of the status field
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_SHIFT (24)
|
||||
|
||||
/* Size of VSE Mailbox instance.
|
||||
There are two instances, input and output. */
|
||||
#define ROOT_MAILBOX_SIZE (512UL)
|
||||
|
||||
/* Base addresses of the VSE Input and Output Mailbox data structures.
|
||||
(Must be stored in a RAM area which is not used by the VSE)
|
||||
We use the upper 1KB of FRC RAM for the VSE mailboxes. */
|
||||
#define ROOT_MAILBOX_OUTPUT_S_BASE (RDMEM_FRCRAM_S_MEM_END + 1 - ROOT_MAILBOX_SIZE)
|
||||
#define ROOT_MAILBOX_INPUT_S_BASE (ROOT_MAILBOX_OUTPUT_S_BASE - ROOT_MAILBOX_SIZE)
|
||||
|
||||
// SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S is defined in sl_trustzone_secure_config.h
|
||||
#if ((defined(SL_TRUSTZONE_SECURE) && !defined(SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S)) \
|
||||
|| (defined(SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S) && SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S))
|
||||
|
||||
#define RDMEM_FRCRAM_MEM_BASE RDMEM_FRCRAM_S_MEM_BASE
|
||||
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE SYSCFG->ROOTDATA1;
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE_EXPECTED ROOT_MAILBOX_OUTPUT_S_BASE
|
||||
#else
|
||||
#define RDMEM_FRCRAM_MEM_BASE RDMEM_FRCRAM_NS_MEM_BASE
|
||||
|
||||
// VSE will always output the secure address, if NS is desired, caculate the NS address.
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE (SYSCFG->ROOTDATA1 - RDMEM_FRCRAM_S_MEM_BASE + RDMEM_FRCRAM_NS_MEM_BASE);
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE_EXPECTED (RDMEM_FRCRAM_NS_MEM_END + 1 - ROOT_MAILBOX_SIZE)
|
||||
#endif
|
||||
#define ROOT_MAILBOX_INPUT_BASE (ROOT_MAILBOX_OUTPUT_BASE_EXPECTED - ROOT_MAILBOX_SIZE)
|
||||
|
||||
/* Position of parameter number field in VSE Input Mailbox LENGTH field.*/
|
||||
#define ROOT_MB_LENGTH_PARAM_NUM_SHIFT (24)
|
||||
|
||||
/* Done flag indicating that the VSE Mailbox handler has completed
|
||||
processing the mailbox command. */
|
||||
#define ROOT_MB_DONE (1 << 23)
|
||||
|
||||
/* VSE Configuration Status bits mask */
|
||||
#define ROOT_MB_OUTPUT_STATUS_CONFIG_BITS_MASK (0xFFFF)
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
// VSE Input Mailbox structure
|
||||
typedef struct {
|
||||
volatile uint32_t magic;
|
||||
volatile uint32_t command;
|
||||
volatile uint32_t length;
|
||||
volatile uint32_t data[0];
|
||||
} root_mailbox_input_t;
|
||||
|
||||
// VSE Output Mailbox structure
|
||||
typedef struct {
|
||||
volatile uint32_t magic;
|
||||
volatile uint32_t version;
|
||||
volatile uint32_t status;
|
||||
volatile uint32_t command;
|
||||
volatile uint32_t length;
|
||||
volatile uint32_t data[0];
|
||||
} root_mailbox_output_t;
|
||||
/** @endcond */
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/*******************************************************************************
|
||||
************************** STATIC FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Write to FIFO
|
||||
*
|
||||
* @param value
|
||||
* Value to write to FIFO
|
||||
******************************************************************************/
|
||||
#if defined(_SEMAILBOX_FIFO_RESETVALUE)
|
||||
__STATIC_INLINE void write_to_fifo(uint32_t value)
|
||||
{
|
||||
SEMAILBOX_HOST->FIFO = value;
|
||||
}
|
||||
#else
|
||||
__STATIC_INLINE void write_to_fifo(uint32_t value)
|
||||
{
|
||||
SEMAILBOX_HOST->FIFO[0].DATA = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Return a pointer to the root mailbox output
|
||||
*
|
||||
* @return root_mailbox_output_t pointer
|
||||
******************************************************************************/
|
||||
static root_mailbox_output_t* get_root_mailbox_output(void)
|
||||
{
|
||||
// Setup pointer to the VSE Output Mailbox data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
bool sys_cfg_clk_enabled = ((CMU->CLKEN0 & CMU_CLKEN0_SYSCFG) != 0);
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
|
||||
root_mailbox_output_t *mailbox_output = (root_mailbox_output_t *) ROOT_MAILBOX_OUTPUT_BASE;
|
||||
if (!sys_cfg_clk_enabled) {
|
||||
CMU->CLKEN0_CLR = CMU_CLKEN0_SYSCFG;
|
||||
}
|
||||
return mailbox_output;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the running command has completed.
|
||||
*
|
||||
* @details
|
||||
* This function polls the SE-to-host mailbox interrupt flag.
|
||||
*
|
||||
* @return True if a command has completed and the result is available
|
||||
******************************************************************************/
|
||||
static bool vse_is_command_completed(root_mailbox_output_t *root_mailbox_output)
|
||||
{
|
||||
// First verify that the response is ok
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check status MB_DONE flag of the mailbox
|
||||
return ((root_mailbox_output->status & ROOT_MB_DONE) == ROOT_MB_DONE);
|
||||
}
|
||||
#endif // SEMAILBOX_PRESENT
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add input data to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_input(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data)
|
||||
{
|
||||
if (command->data_in == NULL) {
|
||||
command->data_in = data;
|
||||
} else {
|
||||
sli_se_datatransfer_t *next = command->data_in;
|
||||
while (next->next != (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
next = (sli_se_datatransfer_t*)next->next;
|
||||
}
|
||||
next->next = data;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add output data to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_output(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data)
|
||||
{
|
||||
if (command->data_out == NULL) {
|
||||
command->data_out = data;
|
||||
} else {
|
||||
sli_se_datatransfer_t *next = command->data_out;
|
||||
while (next->next != (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
next = (sli_se_datatransfer_t*)next->next;
|
||||
}
|
||||
next->next = data;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add a parameter to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_parameter(sli_se_mailbox_command_t *command, uint32_t parameter)
|
||||
{
|
||||
if (command->num_parameters >= SLI_SE_COMMAND_MAX_PARAMETERS) {
|
||||
EFM_ASSERT(command->num_parameters < SLI_SE_COMMAND_MAX_PARAMETERS);
|
||||
return;
|
||||
}
|
||||
|
||||
command->parameters[command->num_parameters] = parameter;
|
||||
command->num_parameters += 1;
|
||||
}
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute a command on the SE by writing the command to SEMAILBOX->FIFO
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_execute_command(sli_se_mailbox_command_t *command)
|
||||
{
|
||||
// Don't overflow our struct
|
||||
if (command->num_parameters > SLI_SE_COMMAND_MAX_PARAMETERS) {
|
||||
EFM_ASSERT(command->num_parameters <= SLI_SE_COMMAND_MAX_PARAMETERS);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
|
||||
// Wait for room available in the mailbox
|
||||
while (!(SEMAILBOX_HOST->TX_STATUS & SEMAILBOX_TX_STATUS_TXINT)) {
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES == 3)
|
||||
// Write header (including message size) to start transaction
|
||||
SEMAILBOX_HOST->TX_HEADER = sizeof(uint32_t) * (5 + command->num_parameters);
|
||||
// Write a 32-bit word to the FIFO ( potentially used as command handle )
|
||||
write_to_fifo(0);
|
||||
#else
|
||||
// Write header (including message size) to start transaction
|
||||
SEMAILBOX_HOST->TX_HEADER = sizeof(uint32_t) * (4 + command->num_parameters);
|
||||
#endif
|
||||
|
||||
// Write command into FIFO
|
||||
write_to_fifo(command->command);
|
||||
|
||||
// Write DMA descriptors into FIFO
|
||||
write_to_fifo((uint32_t)command->data_in);
|
||||
write_to_fifo((uint32_t)command->data_out);
|
||||
|
||||
// Write applicable parameters into FIFO
|
||||
for (size_t i = 0; i < command->num_parameters; i++) {
|
||||
write_to_fifo(command->parameters[i]);
|
||||
}
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
// Prepare the VSE Mailbox within a critical section to prevent
|
||||
// the process from getting interrupted. At this point, the only option
|
||||
// we have is to go through a reset, so it is safe to enter the critical section.
|
||||
(void)CORE_EnterCritical();
|
||||
|
||||
// Setup pointer to the VSE Mailbox Input data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
root_mailbox_input_t *mailbox_input = (root_mailbox_input_t*)ROOT_MAILBOX_INPUT_BASE;
|
||||
uint32_t *mailbox_data;
|
||||
unsigned int mailbox_dataLen, inDataLen, i;
|
||||
sli_se_datatransfer_t *inDataDesc;
|
||||
uint32_t *inData;
|
||||
uint32_t checksum;
|
||||
bool sysCfgClkWasEnabled = ((CMU->CLKEN0 & CMU_CLKEN0_SYSCFG) != 0);
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
|
||||
|
||||
// Store the secure memory base addresses for VSE to be able to read from the address
|
||||
// Set base of Mailbox Input data structure in SYSCFG register in order
|
||||
// for VSE to find it.
|
||||
SYSCFG->ROOTDATA0 = ROOT_MAILBOX_INPUT_S_BASE;
|
||||
// Set base of Mailbox Output data structure in SYSCFG register in order
|
||||
// for VSE to know where to write output data.
|
||||
// Write command into FIFO
|
||||
SYSCFG->ROOTDATA1 = ROOT_MAILBOX_OUTPUT_S_BASE;
|
||||
|
||||
if (!sysCfgClkWasEnabled) {
|
||||
CMU->CLKEN0_CLR = CMU_CLKEN0_SYSCFG;
|
||||
}
|
||||
|
||||
mailbox_input->magic = SLI_SE_RESPONSE_MAILBOX_VALID;
|
||||
mailbox_input->command = command->command;
|
||||
|
||||
// Write applicable parameters into Mailbox DATA array
|
||||
mailbox_data = (uint32_t*) mailbox_input->data;
|
||||
for (mailbox_dataLen = 0; mailbox_dataLen < command->num_parameters; mailbox_dataLen++) {
|
||||
mailbox_data[mailbox_dataLen] = command->parameters[mailbox_dataLen];
|
||||
}
|
||||
|
||||
// Write input data into Mailbox DATA array
|
||||
inDataLen = 0;
|
||||
for (inDataDesc = command->data_in; inDataDesc; inDataDesc = (sli_se_datatransfer_t*) inDataDesc->next) {
|
||||
inData = (uint32_t*) inDataDesc->data;
|
||||
for (i = 0; i < (inDataDesc->length & SLI_SE_DATATRANSFER_LENGTH_MASK) / sizeof(uint32_t); i++) {
|
||||
// Make sure we do not overflow the input mailbox.
|
||||
EFM_ASSERT(mailbox_dataLen < ROOT_MAILBOX_SIZE);
|
||||
mailbox_data[mailbox_dataLen++] = inData[i];
|
||||
inDataLen++;
|
||||
}
|
||||
if (inDataDesc->next == (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write number of parameters and data words to 'length' field of mailbox.
|
||||
mailbox_input->length =
|
||||
inDataLen | (command->num_parameters << ROOT_MB_LENGTH_PARAM_NUM_SHIFT);
|
||||
|
||||
// Calculate checksum using bitwise XOR over the all words in the mailbox
|
||||
// data structure, minus the CHECKSUM word (32bit = 4bytes ) at the end.
|
||||
checksum = mailbox_input->magic;
|
||||
checksum ^= mailbox_input->command;
|
||||
checksum ^= mailbox_input->length;
|
||||
for (i = 0; i < mailbox_dataLen; i++) {
|
||||
checksum ^= mailbox_data[i];
|
||||
}
|
||||
|
||||
// Finally, write the calculated checksum to mailbox checksum field
|
||||
mailbox_data[mailbox_dataLen] = checksum;
|
||||
|
||||
__NVIC_SystemReset();
|
||||
|
||||
#endif // #if defined(SEMAILBOX_PRESENT)
|
||||
}
|
||||
#endif // #if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current SE version
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_version(uint32_t *version)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
if (version == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Return the 'version' from the Output Mailbox
|
||||
*version = root_mailbox_output->version;
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get VSE configuration and status bits
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_cfg_status(uint32_t *cfg_status)
|
||||
{
|
||||
if (cfg_status == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Return the configuration status bits
|
||||
*cfg_status = root_mailbox_output->status & ROOT_MB_OUTPUT_STATUS_CONFIG_BITS_MASK;
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the version number of the OTP from the status field of the output
|
||||
* mailbox
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_otp_version(uint32_t *otp_version)
|
||||
{
|
||||
if (otp_version == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
bool is_otp_version_set = root_mailbox_output->status & SE_VSE_REPLY_STATUS_OTP_VERSION_SET;
|
||||
if (is_otp_version_set) {
|
||||
// Return the OTP version from the status field.
|
||||
*otp_version = (root_mailbox_output->status & SE_VSE_REPLY_STATUS_OTP_VERSION_MASK) >> SE_VSE_REPLY_STATUS_OTP_VERSION_SHIFT;
|
||||
} else {
|
||||
return SLI_SE_RESPONSE_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the previously executed command.
|
||||
******************************************************************************/
|
||||
uint32_t sli_vse_mailbox_read_executed_command(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
return root_mailbox_output->command;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the status of the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function reads the status of the previously executed command.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully or a signature
|
||||
* was successfully verified,
|
||||
* SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command, e.g.
|
||||
* because of conflicting Secure/Non-Secure memory accesses,
|
||||
* SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_se_mailbox_read_response(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
return (sli_se_mailbox_response_t)(root_mailbox_output->status & SLI_SE_RESPONSE_MASK);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command.
|
||||
* The mailbox command is acknowledged by inverting all bits in the checksum
|
||||
* (XOR with 0xFFFFFFFF).
|
||||
* The output data is copied into the linked list of output buffers pointed
|
||||
* to in the given command data structure.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE command structure.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully or a
|
||||
* signature was successfully verified,
|
||||
* @retval SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* @retval SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* @retval SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* @retval SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command,
|
||||
* e.g. because of conflicting Secure/Non-Secure
|
||||
* memory accesses,
|
||||
* @retval SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* @retval SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* @retval SLI_SE_RESPONSE_MAILBOX_INVALID when mailbox command not done or invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_ack_command(sli_se_mailbox_command_t *command)
|
||||
{
|
||||
// Setup pointer to the VSE Output Mailbox data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
uint32_t *mbData = (uint32_t*) root_mailbox_output->data;
|
||||
sli_se_datatransfer_t *outDataDesc = command->data_out;
|
||||
unsigned int outDataLen, outDataCnt, i, outDescLen;
|
||||
uint32_t *outData;
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Get output data length
|
||||
outDataLen = root_mailbox_output->length;
|
||||
|
||||
// Acknowledge the output mailbox response by invalidating checksum
|
||||
mbData[outDataLen] ^= 0xFFFFFFFFUL;
|
||||
|
||||
// Check command status code
|
||||
if ((root_mailbox_output->status & SLI_SE_RESPONSE_MASK) != SLI_SE_RESPONSE_OK) {
|
||||
return root_mailbox_output->status & SLI_SE_RESPONSE_MASK;
|
||||
}
|
||||
|
||||
// Copy data from the Output Mailbox to the linked list of output
|
||||
// buffers provided by the user
|
||||
outDataCnt = 0;
|
||||
while (outDataDesc && (outDataCnt < outDataLen)) {
|
||||
outData = (uint32_t*) outDataDesc->data;
|
||||
outDescLen =
|
||||
(outDataDesc->length & SLI_SE_DATATRANSFER_LENGTH_MASK) / sizeof(uint32_t);
|
||||
for (i = 0; (i < outDescLen) && (outDataCnt < outDataLen); i++) {
|
||||
outData[i] = mbData[outDataCnt++];
|
||||
}
|
||||
// If we have reached the end of a buffer, go to next buffer descriptor
|
||||
if (i == outDescLen) {
|
||||
outDataDesc = (sli_se_datatransfer_t*)
|
||||
((uint32_t)outDataDesc->next & ~SLI_SE_DATATRANSFER_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the output data list is too small to copy all output data in
|
||||
// mailbox.
|
||||
if ((outDataDesc == 0) && (outDataCnt < outDataLen)) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the VSE Output Mailbox is valid.
|
||||
*
|
||||
* @return True if the VSE Output Mailbox is valid (magic and checksum OK)
|
||||
******************************************************************************/
|
||||
bool sli_vse_mailbox_is_output_valid(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
uint32_t *mb_ptr32 = (uint32_t*) root_mailbox_output;
|
||||
uint32_t checksum;
|
||||
unsigned int mb_len, cnt;
|
||||
|
||||
if ((uint32_t)root_mailbox_output > ROOT_MAILBOX_OUTPUT_BASE_EXPECTED
|
||||
|| (uint32_t)root_mailbox_output < RDMEM_FRCRAM_MEM_BASE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify magic word of mailbox
|
||||
if (root_mailbox_output->magic != SLI_SE_RESPONSE_MAILBOX_VALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get length of mailbox
|
||||
mb_len = sizeof(root_mailbox_output_t) / sizeof(uint32_t) + root_mailbox_output->length;
|
||||
if (mb_len >= ROOT_MAILBOX_SIZE) {
|
||||
return false;
|
||||
}
|
||||
// Calculate checksum using bitwise XOR over all words in the mailbox
|
||||
// data structure, minus the CHECKSUM word at the end.
|
||||
for (checksum = 0, cnt = 0; cnt < mb_len; cnt++) {
|
||||
checksum ^= mb_ptr32[cnt];
|
||||
}
|
||||
|
||||
// Verify that the calculated checksum is equal to the mailbox checksum.
|
||||
return (mb_ptr32[mb_len] == checksum);
|
||||
}
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/** @} (end addtogroup se) */
|
||||
|
||||
#endif /* defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) */
|
||||
Reference in New Issue
Block a user