Imported more library files

Not compiling currently
This commit is contained in:
2025-04-12 23:37:19 +01:00
parent 264a3462e0
commit 9d06f983af
2518 changed files with 1021900 additions and 52 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 DiffieHellman
/***************************************************************************//**
* @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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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) */

View File

@@ -0,0 +1,486 @@
/***************************************************************************//**
* @file
* @brief Mbed TLS device acceleration capabilities.
*******************************************************************************
* # 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_MBEDTLS_ACCELERATION_H
#define SLI_MBEDTLS_ACCELERATION_H
// This condition makes it possible to disable alt-plugins for the classic
// Mbed TLS APIs (overriding the user-exposed config option). This is notably
// used on the NS side of TrustZone-enabled applications.
#if !defined(NO_CRYPTO_ACCELERATION)
// -----------------------------------------------------------------------------
// Acceleration enabling defines
/**
* \def MBEDTLS_AES_ALT
*
* Enable hardware acceleration for the AES block cipher modes through
* the mbed TLS APIs.
*
* Module: sl_mbedtls_support/src/crypto_aes.c for devices with CRYPTO,
* sl_mbedtls_support/src/se_aes.c for devices with HSE,
* sl_mbedtls_support/src/cryptoacc_aes.c for devices with CRYPTOACC,
* sl_mbedtls_support/src/aes_aes.c for devices with AES
*
* See \ref MBEDTLS_AES_C for more information.
*/
#if defined(_SILICON_LABS_32B_SERIES)
#define MBEDTLS_AES_ALT
#endif
#if defined(CRYPTOACC_PRESENT) || defined(SEMAILBOX_PRESENT)
#define AES_192_SUPPORTED
#endif
/**
* \def MBEDTLS_CCM_ALT
*
* Enable hardware acceleration of CCM through mbed TLS APIs.
* Not enabled when PSA Crypto is present in the build together with the PSA driver for CCM,
* as that would preclude software fallback for cases where the hardware capabilites do not
* cover the full potential usage of the PSA Driver API
*
* Module: sl_mbedtls_support/src/mbedtls_ccm.c for all devices, plus:
* - sl_psa_driver/src/sli_se_transparent_driver_aead.c and sl_psa_driver/src/sli_se_driver_aead.c for devices with HSE,
* - sl_psa_driver/src/sli_cryptoacc_transparent_driver_aead.c for devices with CRYPTOACC
*
* Requires: \ref MBEDTLS_AES_C and \ref MBEDTLS_CCM_C (CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See MBEDTLS_CCM_C for more information.
*/
#if defined(CRYPTOACC_PRESENT) || defined(SEMAILBOX_PRESENT)
// Remove this when full multipart support is present in the CCM ALT driver
// Todo: remove guard when [PSEC-1954][PSEC-2109][PSEC-3133] are done
#if !(defined(MBEDTLS_PSA_CRYPTO_DRIVERS))
#define MBEDTLS_CCM_ALT
#endif
#endif
/**
* \def MBEDTLS_CMAC_ALT
*
* Enable hardware acceleration CMAC through mbed TLS APIs.
*
* Module: sl_mbedtls_support/src/mbedtls_cmac.c for all devices, plus:
* - sl_psa_driver/src/sli_se_transparent_driver_mac.c and sl_psa_driver/src/sli_se_driver_mac.c for devices with HSE,
* - sl_psa_driver/src/sli_cryptoacc_transparent_driver_mac.c for devices with CRYPTOACC
*
* Requires: \ref MBEDTLS_AES_C and \ref MBEDTLS_CMAC_C (CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See MBEDTLS_CMAC_C for more information.
*/
#if defined(CRYPTOACC_PRESENT) || defined(SEMAILBOX_PRESENT)
#define MBEDTLS_CMAC_ALT
#endif
/**
* \def MBEDTLS_GCM_ALT
*
* Enable hardware acceleration GCM.
*
* Module: sl_mbedtls_support/src/se_gcm.c for devices with HSE,
* sl_mbedtls_support/src/cryptoacc_gcm.c for devices with CRYPTOACC
*
* Requires: \ref MBEDTLS_GCM_C (CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See MBEDTLS_GCM_C for more information.
*/
#if defined(CRYPTOACC_PRESENT) || (defined(SEMAILBOX_PRESENT))
#define MBEDTLS_GCM_ALT
#endif
/**
* \def MBEDTLS_SHA1_ALT
*
* Enable hardware acceleration for the SHA1 cryptographic hash algorithm
* through the mbed TLS APIs.
*
* Module: sl_mbedtls_support/src/mbedtls_sha.c for all devices, plus:
* - sl_psa_driver/src/sli_se_transparent_driver_hash.c for devices with HSE,
* - sl_psa_driver/src/sli_cryptoacc_transparent_driver_hash.c for devices with CRYPTOACC
*
* Caller: library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
* library/x509write_crt.c
*
* Requires: \ref MBEDTLS_SHA1_C and (CRYPTO_PRESENT or CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See MBEDTLS_SHA1_C for more information.
*/
#if defined(CRYPTOACC_PRESENT) || defined(SEMAILBOX_PRESENT)
#define MBEDTLS_SHA1_ALT
#endif
/**
* \def MBEDTLS_SHA256_ALT
*
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
* hash algorithms through the mbed TLS APIs.
*
* Module: sl_mbedtls_support/src/mbedtls_sha.c for all devices, plus:
* - sl_psa_driver/src/sli_se_transparent_driver_hash.c for devices with HSE,
* - sl_psa_driver/src/sli_cryptoacc_transparent_driver_hash.c for devices with CRYPTOACC
*
* Caller: library/entropy.c
* library/mbedtls_md.c
* library/ssl_cli.c
* library/ssl_srv.c
* library/ssl_tls.c
*
* Requires: \ref MBEDTLS_SHA256_C and (CRYPTO_PRESENT or CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See MBEDTLS_SHA256_C for more information.
*/
#if defined(CRYPTOACC_PRESENT) || defined(SEMAILBOX_PRESENT)
#define MBEDTLS_SHA256_ALT
#endif
/**
* \def MBEDTLS_SHA512_ALT
*
* Enable hardware acceleration for the SHA-384 and SHA-512 cryptographic
* hash algorithms through the mbed TLS APIs.
*
* Module: sl_mbedtls_support/src/mbedtls_sha.c
* sl_psa_driver/src/sli_se_transparent_driver_hash.c
*
* Requires: \ref MBEDTLS_SHA512_C
*
* See MBEDTLS_SHA512_C for more information.
*/
#if defined(SEMAILBOX_PRESENT) \
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
#define MBEDTLS_SHA512_ALT
#endif
/**
* \def MBEDTLS_ECP_INTERNAL_ALT
* \def ECP_SHORTWEIERSTRASS
* \def MBEDTLS_ECP_ADD_MIXED_ALT
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
*
* Enable hardware acceleration for the elliptic curve over GF(p) library
* in mbed TLS. This accelerates the raw arithmetic operations.
*
* Module: sl_mbedtls_support/src/crypto_ecp.c
*
* Caller: library/ecp.c
*
* Requires: \ref MBEDTLS_BIGNUM_C, \ref MBEDTLS_ECP_C and at least one
* MBEDTLS_ECP_DP_XXX_ENABLED and CRYPTO_PRESENT
*/
#if defined(CRYPTO_PRESENT) \
&& (defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED))
#define MBEDTLS_ECP_INTERNAL_ALT
#define ECP_SHORTWEIERSTRASS
#define MBEDTLS_ECP_ADD_MIXED_ALT
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
#endif
/**
* \def MBEDTLS_ECDH_COMPUTE_SHARED_ALT
* \def MBEDTLS_ECDH_GEN_PUBLIC_ALT
* \def MBEDTLS_ECDSA_GENKEY_ALT
* \def MBEDTLS_ECDSA_SIGN_ALT
* \def MBEDTLS_ECDSA_VERIFY_ALT
*
* Enable hardware acceleration for certain ECC operations.
*
* Module: sl_mbedtls_support/src/mbedtls_ecdsa_ecdh.c for all devices, plus:
* - sl_psa_driver/src/sli_se_driver_signature.c and sl_psa_driver/src/sli_se_driver_key_management.c for devices with HSE,
* - sl_psa_driver/src/sli_cryptoacc_transparent_driver_signature.c and sl_psa_driver/src/sli_cryptoacc_transparent_driver_key_management.c for devices with CRYPTOACC
*
* Requires: \ref MBEDTLS_ECP_C (CRYPTOACC_PRESENT or SEMAILBOX_PRESENT)
*
* See \ref MBEDTLS_ECP_C for more information.
*/
#if defined(CRYPTOACC_PRESENT)
#if !(defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) \
|| defined(MBEDTLS_ECP_DP_CURVE448_ENABLED) )
#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
#endif // #if !( defined(MBEDTLS_ECP_DP_XXX_ENABLED) ...
#if !(defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) )
#define MBEDTLS_ECDSA_GENKEY_ALT
#define MBEDTLS_ECDSA_VERIFY_ALT
#if !defined(MBEDTLS_ECDSA_DETERMINISTIC)
#define MBEDTLS_ECDSA_SIGN_ALT
#endif
#endif // #if !( defined(MBEDTLS_ECP_DP_XXX_ENABLED) ...
#endif /* CRYPTOACC */
#if defined(SEMAILBOX_PRESENT)
#if !defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) \
&& !defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
/* Do not enable the ECDH and/or ECDSA ALT implementations when one or more
* non-accelerated curves are included, then the application needs to
* use the standard mbedTLS library. */
#if !( (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_SE) \
&& (defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)))
#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
#endif
#if !( (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_SE) \
&& (defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) ) )
#define MBEDTLS_ECDSA_GENKEY_ALT
#if !defined(MBEDTLS_ECDSA_DETERMINISTIC)
#define MBEDTLS_ECDSA_SIGN_ALT
#endif
#define MBEDTLS_ECDSA_VERIFY_ALT
#endif
#endif // #if !defined(MBEDTLS_ECP_DP_XXXX_ENABLED) && ...
/**
* \def MBEDTLS_ECJPAKE_ALT
*
* Enable hardware acceleration JPAKE.
*
* Module: sl_mbedtls_support/src/se_jpake.c
*
* Requires: \ref MBEDTLS_ECJPAKE_C (SEMAILBOX_PRESENT)
*
* See \ref MBEDTLS_ECJPAKE_C for more information.
*/
#define MBEDTLS_ECJPAKE_ALT
#endif /* SEMAILBOX_PRESENT */
/**
* \def MBEDTLS_ENTROPY_ADC_PRESENT
*
* Decode if device supports retrieving entropy data from the ADC
* incorporated on devices from Silicon Labs.
*
* Requires ADC_PRESENT && _ADC_SINGLECTRLX_VREFSEL_VENTROPY &&
* _SILICON_LABS_32B_SERIES_1
*/
#if defined(ADC_PRESENT) \
&& defined(_ADC_SINGLECTRLX_VREFSEL_VENTROPY) \
&& defined(_SILICON_LABS_32B_SERIES_1)
#define MBEDTLS_ENTROPY_ADC_PRESENT
#endif
/**
* \def MBEDTLS_TRNG_PRESENT
*
* Determine whether mbedTLS supports the TRNG (if present) on the device.
*
* Requires TRNG_PRESENT and not _SILICON_LABS_GECKO_INTERNAL_SDID_95 (xg14)
*/
#if defined(TRNG_PRESENT) \
&& !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95)
#undef MBEDTLS_TRNG_PRESENT
#define MBEDTLS_TRNG_PRESENT
#endif
/**
* \def MBEDTLS_ENTROPY_RAIL_PRESENT
*
* Determine whether mbedTLS supports RAIL entropy on the device.
* This is currently only available on a few series-1 devices
* where there is no functional TRNG.
*
* Requires _EFR_DEVICE and one of
* _SILICON_LABS_GECKO_INTERNAL_SDID_80
* _SILICON_LABS_GECKO_INTERNAL_SDID_89
* _SILICON_LABS_GECKO_INTERNAL_SDID_95
*/
#if defined(_EFR_DEVICE) \
&& (defined(_SILICON_LABS_GECKO_INTERNAL_SDID_80) \
|| defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) \
|| defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95) )
#if defined(SL_CATALOG_RAIL_LIB_PRESENT)
#undef MBEDTLS_ENTROPY_RAIL_PRESENT
#define MBEDTLS_ENTROPY_RAIL_PRESENT
#endif
#endif
/* Default ECC configuration for Silicon Labs devices: */
/* Save RAM by adjusting to our exact needs */
#ifndef MBEDTLS_MPI_MAX_SIZE
#define MBEDTLS_MPI_MAX_SIZE 32 // 384 bits is 48 bytes
#endif
/*
Set MBEDTLS_ECP_WINDOW_SIZE to configure
ECC point multiplication window size, see ecp.h:
2 = Save RAM at the expense of speed
3 = Improve speed at the expense of RAM
4 = Optimize speed at the expense of RAM
*/
#define MBEDTLS_ECP_WINDOW_SIZE 2
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
#if defined(MBEDTLS_ECP_C)
/* First section: devices with ECP hardware acceleration enabled */
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
/* When the internal ECP implementation is overridden, apply optimisation
* only when it benefits us for curves we can't accelerate. */
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#define MBEDTLS_ECP_NIST_OPTIM
#endif /* Non-accelerated SECP R1 curves requested */
/* If only accelerated curves are requested, and no non-accelerated ones,
* we can turn on the NO_FALLBACK flag to dead-strip a whole lot of ECC
* math software implementation. */
#if (defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ) \
&& !(defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) \
|| defined(MBEDTLS_ECP_DP_CURVE448_ENABLED))
#define MBEDTLS_ECP_NO_FALLBACK
#endif /* Only ECP-hardware-accelerated curves requested */
/* Second section: devices with ECDSA / ECDH hardware acceleration (without ECP) */
#elif defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) \
|| defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) \
|| defined(MBEDTLS_ECDSA_GENKEY_ALT) \
|| defined(MBEDTLS_ECDSA_SIGN_ALT) \
|| defined(MBEDTLS_ECDSA_VERIFY_ALT) \
/* When the upper layers calling into ECP_C are overridden, apply optimisation
* only when it benefits us for curves we can't accelerate. */
#if (defined(SEMAILBOX_PRESENT) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_SE) ) \
|| defined(CRYPTOACC_PRESENT)
#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) \
|| (defined(MBEDTLS_ECDSA_DETERMINISTIC) \
&& (defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)))
#define MBEDTLS_ECP_NIST_OPTIM
#endif /* Non-accelerated SECP R1 curves requested */
#endif /* Devices not implementing the full suite of SECP R1 curves */
/* Third section: configurations without any ECP/ECC acceleration at all */
#else
/* When there's no ECC acceleration at all, apply optimisation always when
* applicable curves are present. */
#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) \
|| defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
#define MBEDTLS_ECP_NIST_OPTIM
#endif /* Software-optimisable curve requested */
#endif /* Different acceleration constellations */
#endif /* MBEDTLS_ECP_C */
/*
Set max CTR-DRBG seed input size to reasonable default in order to reduce
stack usage when using CTR-DRBG.
NOTE:
Due to existing dependencies we need to keep the setting of
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT here. However this is subject to be moved
later, to sl_mbedtls_config.h or mbedtls_config_autogen.h in order to be more
practical for configuration.
*/
#if !defined(MBEDTLS_CTR_DRBG_MAX_SEED_INPUT)
#if !(defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) \
&& defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) \
&& defined(MBEDTLS_ECDSA_GENKEY_ALT) \
&& defined(MBEDTLS_ECDSA_SIGN_ALT) \
&& defined(MBEDTLS_ECDSA_VERIFY_ALT))
/*
If any of ECDH and/or ECDSA ALT is/are not enabled, then the ecp_mul_xxx()
functions will seed the internal drbg (for randomization of projective
coordinates) with the private key of size corresponding to the curve
hence we will need to adjust:
*/
#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
// For key size 521 bits (=66 bytes) add 66 - 32 (256bits default) = 34 bytes
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 + 66 - 32)
#elif defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)
// For key size 512 bits (=64 bytes) add 64 - 32 (256bits default) = 32 bytes
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 + 64 - 32)
#elif defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
// For key size 448 bits (=56 bytes) add 56 - 32 (256bits default) = 24 bytes
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 + 56 - 32)
#elif defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
// For key size 384 bits (=48 bytes) add 48 - 32 (256bits default) = 16 bytes
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 + 48 - 32)
#elif defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)
// For key size 384 bits (=48 bytes) add 48 - 32 (256bits default) = 16 bytes
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2 + 48 - 32)
#else
// Default value to support curve sizes up to 256 bits ( 32 bytes )
#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT (MBEDTLS_CTR_DRBG_ENTROPY_LEN + MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2)
#endif
#endif
#endif
#endif // !NO_CRYPTO_ACCELERATION
#endif // SLI_MBEDTLS_ACCELERATION_H

View File

@@ -0,0 +1,155 @@
/***************************************************************************//**
* @file
* @brief Mbed TLS 'omnipresent' config content.
*******************************************************************************
* # 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_MBEDTLS_OMIPRESENT_H
#define SLI_MBEDTLS_OMIPRESENT_H
#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#if !defined(SL_CATALOG_SE_CPC_PRIMARY_PRESENT)
#include "em_device.h"
#endif
// -----------------------------------------------------------------------------
// Non-volatile seed function headers
#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT)
// Provide the NV seed function signatures since we have no specific header
// for them.
#include <stddef.h>
int sli_nv_seed_read(unsigned char *buf, size_t buf_len);
int sli_nv_seed_write(unsigned char *buf, size_t buf_len);
#endif // MBEDTLS_PLATFORM_NV_SEED_ALT
// -----------------------------------------------------------------------------
// Platform macros
#if defined(MBEDTLS_PLATFORM_CALLOC_MACRO) && defined(MBEDTLS_PLATFORM_FREE_MACRO)
// By default MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO are
// defined in mbedtls_platform_dynamic_memory_allocation_config_default.slcc.
// Alternative implementations can configure MBEDTLS_PLATFORM_CALLOC_MACRO and
// MBEDTLS_PLATFORM_FREE_MACRO to use other platform specific implementations.
// Alternatively some use cases may select runtime initialisation in the
// application by explicitly calling mbedtls_platform_set_calloc_free() by
// selecting mbedtls_platform_dynamic_memory_allocation_config_init_runtime.
#include <stddef.h>
extern void *MBEDTLS_PLATFORM_CALLOC_MACRO(size_t n, size_t size);
extern void MBEDTLS_PLATFORM_FREE_MACRO(void *ptr);
#endif // MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO
// -----------------------------------------------------------------------------
// Device differentiation logic
#if defined(CRYPTO_PRESENT)
#define SLI_MBEDTLS_DEVICE_S1
#if !defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95)
#define SLI_MBEDTLS_DEVICE_S1_WITH_TRNG
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
// The TRNG may possibly not work depending on the die revision.
#define SLI_MBEDTLS_DEVICE_S1_WITH_TRNG_ERRATA
#endif
#elif defined(SEMAILBOX_PRESENT) && defined(_SILICON_LABS_32B_SERIES_2)
#define SLI_MBEDTLS_DEVICE_S2
#define SLI_MBEDTLS_DEVICE_HSE
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
#define SLI_MBEDTLS_DEVICE_SE_V1
#define SLI_MBEDTLS_DEVICE_HSE_V1
#else
#define SLI_MBEDTLS_DEVICE_SE_V2
#define SLI_MBEDTLS_DEVICE_HSE_V2
#endif
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
#define SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH
#else
#define SLI_MBEDTLS_DEVICE_HSE_VAULT_MID
#endif
#elif defined(SEMAILBOX_PRESENT) && defined(_SILICON_LABS_32B_SERIES_3)
#define SLI_MBEDTLS_DEVICE_S3
#define SLI_MBEDTLS_DEVICE_HC
#define SLI_MBEDTLS_DEVICE_HSE
#define SLI_MBEDTLS_DEVICE_SE_V2
#define SLI_MBEDTLS_DEVICE_HSE_V2
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
#define SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH
#else
#define SLI_MBEDTLS_DEVICE_HSE_VAULT_MID
#endif
#elif defined(CRYPTOACC_PRESENT)
#define SLI_MBEDTLS_DEVICE_S2
#define SLI_MBEDTLS_DEVICE_VSE
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
#define SLI_MBEDTLS_DEVICE_SE_V1
#define SLI_MBEDTLS_DEVICE_VSE_V1
#else
#define SLI_MBEDTLS_DEVICE_SE_V2
#define SLI_MBEDTLS_DEVICE_VSE_V2
#endif
#elif defined(SL_CATALOG_SE_CPC_PRIMARY_PRESENT)
#define SLI_MBEDTLS_DEVICE_S2
#define SLI_MBEDTLS_DEVICE_HSE
// #define SLI_MBEDTLS_DEVICE_SE_V1
// #define SLI_MBEDTLS_DEVICE_SE_V2
// #define SLI_MBEDTLS_DEVICE_HSE_V1
// #define SLI_MBEDTLS_DEVICE_HSE_V2
// #define SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH
// #define SLI_MBEDTLS_DEVICE_HSE_VAULT_MID
#elif defined(SLI_CRYPTOACC_PRESENT_SI91X)
#define SLI_MBEDTLS_DEVICE_SI91X
#endif
#endif // SLI_MBEDTLS_OMIPRESENT_H

View File

@@ -0,0 +1,125 @@
/***************************************************************************//**
* @file
* @brief PSA Crypto device acceleration capabilities.
*******************************************************************************
* # 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_PSA_ACCELERATION_H
#define SLI_PSA_ACCELERATION_H
// -------------------------------------
// Hash
#define MBEDTLS_PSA_ACCEL_ALG_SHA_1
#define MBEDTLS_PSA_ACCEL_ALG_SHA_224
#define MBEDTLS_PSA_ACCEL_ALG_SHA_256
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) || defined (SLI_MBEDTLS_DEVICE_SI91X)
#define MBEDTLS_PSA_ACCEL_ALG_SHA_384
#define MBEDTLS_PSA_ACCEL_ALG_SHA_512
#endif
// -------------------------------------
// Cipher
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_AES
#define MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING
#define MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING
#define MBEDTLS_PSA_ACCEL_ALG_CTR
#if !defined(SLI_MBEDTLS_DEVICE_SI91X)
#define MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7
#define MBEDTLS_PSA_ACCEL_ALG_CFB
#define MBEDTLS_PSA_ACCEL_ALG_OFB
#endif
#if (defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) && !defined(_SILICON_LABS_32B_SERIES_3)) || defined(SLI_MBEDTLS_DEVICE_SI91X)
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20
#endif
// -------------------------------------
// AEAD
#define MBEDTLS_PSA_ACCEL_ALG_GCM
#define MBEDTLS_PSA_ACCEL_ALG_CCM
#if (defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) && !defined(_SILICON_LABS_32B_SERIES_3)) || defined(SLI_MBEDTLS_DEVICE_SI91X)
#define MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305
#endif
// -------------------------------------
// MAC
#define MBEDTLS_PSA_ACCEL_ALG_CMAC
#define MBEDTLS_PSA_ACCEL_ALG_HMAC
#if defined(SLI_MBEDTLS_DEVICE_HSE_V1)
#define MBEDTLS_PSA_ACCEL_ALG_CBC_MAC
#endif
// -------------------------------------
// Elliptic curves
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR
#define MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_192
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_256
#if (defined(SLI_MBEDTLS_DEVICE_S2) && !defined(SLI_MBEDTLS_DEVICE_HSE_V1)) || defined(SLI_MBEDTLS_DEVICE_SI91X)
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_224
#endif
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) && !defined(_SILICON_LABS_32B_SERIES_3)
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384
#define MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521
#endif
#if defined(SLI_MBEDTLS_DEVICE_VSE)
#define MBEDTLS_PSA_ACCEL_ECC_SECP_K1_256
#endif
#if defined(SLI_MBEDTLS_DEVICE_HSE_V1) && defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) \
|| defined(SLI_MBEDTLS_DEVICE_HSE_V2)
#define MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_255
#endif
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) && !defined(_SILICON_LABS_32B_SERIES_3)
#define MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448
#endif
// -------------------------------------
// Key agreement
#define MBEDTLS_PSA_ACCEL_ALG_ECDH
// -------------------------------------
// Signature
#define MBEDTLS_PSA_ACCEL_ALG_ECDSA
#endif // SLI_PSA_ACCELERATION_H

View File

@@ -0,0 +1,92 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS AES block cipher
*******************************************************************************
* # 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 AES_ALT_H
#define AES_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins Mbed TLS Plugins
* \brief These plugins are used to support acceleration on Silicon Labs
* Hardware for various algorithms.
*
* The APIs are not intended to be used directly, but hook into acceleration points
* in the relevant Mbed TLS APIs
*
* The plugins support sharing of cryptography hardware in multi-threaded applications,
* as well as a reduced overhead configuration for optimal performance in single-threaded
* applications.
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_aes Accelerated AES Block Cipher
* \brief Accelerated AES block cipher for the mbed TLS API using the AES, CRYPTO,
* CRYPTOACC or SE peripheral
*
* \{
******************************************************************************/
#if defined(MBEDTLS_AES_ALT)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief AES context structure
*/
typedef struct {
unsigned int keybits; /*!< size of key */
unsigned char key[32]; /*!< AES key 128, 192 or 256 bits */
}
mbedtls_aes_context;
#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
* \brief The AES XTS context-type definition.
*/
typedef struct mbedtls_aes_xts_context{
mbedtls_aes_context crypt; /*!< The AES context to use for AES block
encryption or decryption. */
mbedtls_aes_context tweak; /*!< The AES context used for tweak
computation. */
} mbedtls_aes_xts_context;
#endif /* MBEDTLS_CIPHER_MODE_XTS */
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_AES_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_aes) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* AES_ALT_H */

View File

@@ -0,0 +1,72 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS AES-CCM AEAD cipher
*******************************************************************************
* # 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 CCM_ALT_H
#define CCM_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_ccm Accelerated AES-CCM AEAD Cipher
* \brief Accelerated AES-CCM AEAD cipher for the mbed TLS API using the CRYPTOACC
* or SE peripheral
*
* \{
******************************************************************************/
#if defined(MBEDTLS_CCM_ALT)
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief The CCM context-type definition. The CCM context is passed
* to the APIs called.
*/
typedef struct {
unsigned char key[32]; /*!< The key in use. */
unsigned int keybits;
}
mbedtls_ccm_context;
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CCM_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_ccm) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* CCM_ALT_H */

View File

@@ -0,0 +1,77 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS AES-CMAC cipher
*******************************************************************************
* # 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 CMAC_ALT_H
#define CMAC_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_cmac Accelerated AES-CMAC Cipher
* \brief Accelerated AES-CMAC cipher for the mbed TLS API using the CRYPTOACC or
* SE peripheral. This implementation builds on the PSA Crypto drivers
* (\ref sl_psa_drivers).
*
* \{
******************************************************************************/
#if defined(MBEDTLS_CMAC_ALT)
#ifdef __cplusplus
extern "C" {
#endif
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_types.h"
#define SL_MAC_OPERATION_CTX_TYPE sli_se_transparent_mac_operation_t
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_types.h"
#define SL_MAC_OPERATION_CTX_TYPE sli_cryptoacc_transparent_mac_operation_t
#endif
struct mbedtls_cmac_context_t {
SL_MAC_OPERATION_CTX_TYPE ctx;
};
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_CMAC_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_cmac) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* CMAC_ALT_H */

View File

@@ -0,0 +1,90 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS Elliptic Curve J-PAKE
*******************************************************************************
* # 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 ECJPAKE_ALT_H
#define ECJPAKE_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_jpake Accelerated Elliptic Curve J-PAKE
* \brief Accelerated Elliptic Curve J-PAKE for the mbed TLS API using the SE
* peripheral
*
* \{
******************************************************************************/
#if defined(MBEDTLS_ECJPAKE_ALT)
#ifdef __cplusplus
extern "C" {
#endif
/**
* 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
* convetion from the Thread v1.0 spec. Correspondance is indicated in the
* description as a pair C: client name, S: server name
*/
typedef struct {
uint32_t curve_flags; /**< Curve flags to use */
mbedtls_ecjpake_role role; /**< Are we client or server? */
int point_format; /**< Format for point export */
char pwd[33]; /**< 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) */
} mbedtls_ecjpake_context;
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_ECJPAKE_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_jpake) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* ECJPAKE_ALT_H */

View File

@@ -0,0 +1,122 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS Galois/Counter Mode (GCM) for AES-128-bit block ciphers
*******************************************************************************
* # 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 GCM_ALT_H
#define GCM_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_gcm Accelerated GCM AES-128 Cipher
* \brief Accelerated AES-GCM-128 cipher for the mbed TLS API using the CRYPTOACC
* or SE peripheral
*
* \{
* This module implements the GCM AES-128 cipher, as defined in
* <em>D. McGrew, J. Viega, The Galois/Counter Mode of Operation
* (GCM), Natl. Inst. Stand. Technol.</em>
* For more information on GCM, see <em>NIST SP 800-38D: Recommendation for
* Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC</em>.
*
******************************************************************************/
#if defined(MBEDTLS_GCM_ALT)
/* SiliconLabs CRYPTO hardware acceleration implementation */
#include "em_device.h"
#include <stdbool.h>
#if defined(CRYPTO_PRESENT)
#include "em_crypto.h"
#elif defined(CRYPTOACC_PRESENT)
#include "sx_aes.h"
#include "sl_enum.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(CRYPTOACC_PRESENT)
SL_ENUM(sli_gcm_mode_t) {
SLI_GCM_ENC = 1,
SLI_GCM_DEC = 2,
};
#endif
/**
* \brief The GCM context structure.
*/
typedef struct {
unsigned int keybits; /*!< Size of key */
uint64_t len; /*!< Total length of encrypted data. */
uint64_t add_len; /*!< Total length of additional data. */
#if defined(CRYPTO_PRESENT)
CRYPTO_DData_TypeDef key; /*!< AES key, 128 or 256 bits */
int mode; /*!< Encryption or decryption */
CRYPTO_TypeDef* device; /*!< CRYPTO device to use */
CRYPTO_Data_TypeDef ghash_state; /*!< GHASH state */
CRYPTO_Data_TypeDef gctr_state; /*!< GCTR counter value */
CRYPTO_Data_TypeDef ghash_key; /*!< GHASH key (is a constant value
which is faster to restore than
to reconstruct each time). */
#elif defined(SEMAILBOX_PRESENT)
unsigned char key[32]; /*!< AES key 128, 192 or 256 bits */
int mode; /*!< Encryption or decryption */
size_t iv_len; /*!< IV length */
bool last_op; /*!< Last streaming block identified */
uint8_t tagbuf[16]; /*!< Buffer for storing tag */
uint8_t se_ctx_enc[32]; /*!< SE GCM encryption state */
uint8_t se_ctx_dec[32]; /*!< SE GCM decryption state */
#elif defined(CRYPTOACC_PRESENT)
unsigned char key[32]; /*!< AES key 128, 192 or 256 bits */
sli_gcm_mode_t dir; /*!< Encryption or decryption */
uint8_t sx_ctx[AES_CTX_xCM_SIZE]; /*!< CRYPTOACC GCM state */
#endif
}
mbedtls_gcm_context;
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_GCM_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_gcm) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* GCM_ALT_H */

View File

@@ -0,0 +1,92 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs SE device management interface.
*******************************************************************************
* # 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_MANAGEMENT_H
#define SE_MANAGEMENT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_se_management Peripheral Instance Management: Secure Engine
* \brief Concurrency management functions for Secure Engine mailbox access
*
* \{
******************************************************************************/
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_manager_mailbox.h"
#include "sli_se_manager_internal.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief Get ownership of the SE mailbox
*
* \return 0 if successful, negative on error
*/
__STATIC_INLINE int se_management_acquire(void)
{
// Acquire SE manager lock
return sli_se_lock_acquire() == SL_STATUS_OK ? 0 : -1;
}
/**
* \brief Release ownership of the SE mailbox
*
* \return 0 if successful, negative on error
*/
__STATIC_INLINE int se_management_release(void)
{
// Release SE manager lock
return sli_se_lock_release() == SL_STATUS_OK ? 0 : -1;
}
#ifdef __cplusplus
}
#endif
#endif /* SEMAILBOX_PRESENT */
/** \} (end addtogroup sl_se_management) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* SE_MANAGEMENT_H */

View File

@@ -0,0 +1,81 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS SHA-1 cryptographic hash function
*******************************************************************************
* # 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 SHA1_ALT_H
#define SHA1_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_sha1 Accelerated SHA-1 Hash Function
* \brief Accelerated mbed TLS SHA-1 cryptographic hash function for the mbed
* TLS API using Silicon Labs peripherals. This implementation builds on
* the PSA Crypto drivers (\ref sl_psa_drivers).
*
* \{
******************************************************************************/
#if defined(MBEDTLS_SHA1_ALT)
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_types.h"
#define SL_HASH_OPERATION_CTX_TYPE sli_se_transparent_hash_operation_t
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_types.h"
#define SL_HASH_OPERATION_CTX_TYPE sli_cryptoacc_transparent_hash_operation_t
#endif
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-1 context structure
*/
typedef SL_HASH_OPERATION_CTX_TYPE mbedtls_sha1_context;
#ifdef __cplusplus
}
#endif
#endif /* #if defined(MBEDTLS_SHA1_ALT) */
/** \} (end addtogroup sl_mbedtls_plugins_sha1) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* SHA1_ALT_H */

View File

@@ -0,0 +1,83 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS SHA-224 and SHA-256 cryptographic hash functions
*******************************************************************************
* # 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 SHA256_ALT_H
#define SHA256_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_sha256 Accelerated SHA-224/SHA-256 Hash Function
* \brief Accelerated mbed TLS SHA-224/SHA-256 cryptographic hash functions for
* the mbed TLS API using Silicon Labs peripherals. This implementation
* builds on the PSA Crypto drivers (\ref sl_psa_drivers).
*
* \{
******************************************************************************/
#if defined(MBEDTLS_SHA256_ALT)
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_types.h"
#define SL_HASH_OPERATION_CTX_TYPE sli_se_transparent_hash_operation_t
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_types.h"
#define SL_HASH_OPERATION_CTX_TYPE sli_cryptoacc_transparent_hash_operation_t
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-256 context structure
*/
typedef SL_HASH_OPERATION_CTX_TYPE mbedtls_sha256_context;
#ifdef __cplusplus
}
#endif
#endif /* #if defined(MBEDTLS_SHA256_ALT) */
/** \} (end addtogroup sl_mbedtls_plugins_sha256) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* SHA256_ALT_H */

View File

@@ -0,0 +1,80 @@
/***************************************************************************//**
* @file
* @brief Accelerated mbed TLS SHA-384 and SHA-512 cryptographic hash functions
*******************************************************************************
* # 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 SHA512_ALT_H
#define SHA512_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_sha512 Accelerated SHA-384/SHA-512 Hash Function
* \brief Accelerated mbed TLS SHA-384/SHA-512 cryptographic hash function for
* the mbed TLS API using Silicon Labs peripherals. This implementation
* builds on the PSA Crypto drivers (\ref sl_psa_drivers).
*
* \{
******************************************************************************/
#if defined(MBEDTLS_SHA512_ALT)
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_types.h"
#define SL_HASH_OPERATION_CTX_TYPE sli_se_transparent_hash_operation_t
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SHA-512 context structure
*/
typedef SL_HASH_OPERATION_CTX_TYPE mbedtls_sha512_context;
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_SHA512_ALT */
/** \} (end addtogroup sl_mbedtls_plugins_sha512) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* SHA512_ALT_H */

View File

@@ -0,0 +1,42 @@
/***************************************************************************//**
* @file
* @brief Silicon Laboratories platform integration for mbedTLS
*******************************************************************************
* # 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_MBEDTLS_H
#define SL_MBEDTLS_H
/**
* Initialize the Silicon Labs platform integration of mbedTLS.
*
* This function must be called by an application before using any mbedTLS
* functions. This function will make sure that the platform hooks in mbedTLS
* are configured to ensure correct runtime behavior.
*/
void sl_mbedtls_init(void);
#endif // SL_MBEDTLS_H

View File

@@ -0,0 +1,179 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto utility functions.
*******************************************************************************
* # 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 SL_PSA_CRYPTO_H
#define SL_PSA_CRYPTO_H
#include "psa/crypto.h"
#include "sl_psa_values.h"
#include <stddef.h>
// -----------------------------------------------------------------------------
// Functions
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* \addtogroup sl_psa_key_management
* \{
******************************************************************************/
/***************************************************************************//**
* @brief
* Set the location attribute of a key in PSA Crypto according to a given
* persistence level, and a preferred location. If the preferred location is
* not available, perhaps because the device does not support this location,
* the primary local storage (PSA_KEY_LOCATION_LOCAL_STORAGE) will be used.
*
* @param[out] attributes
* The attribute structure to write to.
*
* @param[in] persistence
* The persistence level of the key. If this is #PSA_KEY_PERSISTENCE_VOLATILE,
* the key will be volatile, and the key identifier attribute is reset to 0.
*
* @param[in] preferred_location
* The location of the key. Can be \ref SL_PSA_KEY_LOCATION_WRAPPED,
* \ref SL_PSA_KEY_LOCATION_BUILTIN, or PSA_KEY_LOCATION_LOCAL_STORAGE.
******************************************************************************/
void sl_psa_set_key_lifetime_with_location_preference(
psa_key_attributes_t *attributes,
psa_key_persistence_t persistence,
psa_key_location_t preferred_location);
/***************************************************************************//**
* @brief
* Get the 'most secure' location attribute of a key usable in this
* implementation of PSA Crypto.
*
* @return
* The 'most secure' usable location of a key. In order of preference, the
* following values can be returned: \ref SL_PSA_KEY_LOCATION_WRAPPED,
* or PSA_KEY_LOCATION_LOCAL_STORAGE.
******************************************************************************/
psa_key_location_t sl_psa_get_most_secure_key_location(void);
/** \} (end addtogroup sl_psa_key_management) */
#ifdef __cplusplus
}
#endif
#ifdef DOXYGEN
/***************************************************************************//**
* \defgroup sl_psa_crypto PSA Crypto Extensions
* @brief Silicon Labs specific extensions to the PSA Crypto API
* @{
******************************************************************************/
/***************************************************************************//**
* \defgroup sl_psa_key_derivation Key Derivation
* @brief Key Derivation extensions to the PSA Crypto API
* @{
******************************************************************************/
// This function is declared in psa/crypto.h, which currently is not included with
// doxygen. Declared here for visibility on docs.silabs.com.
/** Perform a single-shot key derivation operation and output the resulting key.
*
* This function supports HKDF and PBKDF2.
*
* \note
* - PBKDF2-CMAC is not suported on xG21
* - PBKDF2-CMAC is only KDF supported for xG27
*
* This function obtains its secret input from a key object, and any additional
* inputs such as buffers and integers. The output of this function is a key
* object containing the output of the selected key derivation function.
*
*
* \param alg The key derivation algorithm to compute
* (\c PSA_ALG_XXX value such that
* #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true).
* \param key_in Identifier of the secret key to input to the
* operation. It must allow the usage
* PSA_KEY_USAGE_DERIVE and be of a symmetric
* type.
* \param[in] info A context- and application specific
* information string. Only used for HKDF, but
* can be omitted.
* \param info_length The length of the provided info in bytes.
* \param[in] salt An optional salt value (a non-secret random value).
* Used for both HKDF and PBKDF2. Recommended for
* PBKDF2.
* \param salt_length The length of the provided salt in bytes.
* \param iterations The number of iterations to use. Maximum
* supported value is 16384. Only used for PBKDF2.
* \param[in] key_out_attributes The attributes for the new key output by the
* derivation operation. The key must be of a
* symmetric type.
* \param[out] key_out The identifier of the new key output by the
* derivation operation.
*
* \retval #PSA_SUCCESS
* Success.
* \retval #PSA_ERROR_INVALID_HANDLE
* \retval #PSA_ERROR_NOT_PERMITTED
* The input key does not have the required usage policy set.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input- or output key is not of a symmetric type.
* \retval #PSA_ERROR_INVALID_ARGUMENT
* The input- or output key is larger than what the SE can handle.
* \retval #PSA_ERROR_NOT_SUPPORTED
* The requested algorithm is not supported.
* \retval #PSA_ERROR_HARDWARE_FAILURE
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
* \retval #PSA_ERROR_STORAGE_FAILURE
* \retval #PSA_ERROR_BAD_STATE
* The library has not been previously initialized by psa_crypto_init().
* It is implementation-dependent whether a failure to initialize
* results in this error code.
*/
psa_status_t sl_psa_key_derivation_single_shot(
psa_algorithm_t alg,
mbedtls_svc_key_id_t key_in,
const uint8_t *info,
size_t info_length,
const uint8_t *salt,
size_t salt_length,
size_t iterations,
const psa_key_attributes_t *key_out_attributes,
mbedtls_svc_key_id_t *key_out);
/** @} */ // end defgroup sl_psa_key_derivation
/** @} */ // end defgroup sl_psa_crypto
#endif // DOXYGEN
#endif // SL_PSA_CRYPTO_H

View File

@@ -0,0 +1,192 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Values.
*******************************************************************************
* # License
* <b>Copyright 2022 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_PSA_VALUES_H
#define SL_PSA_VALUES_H
#include "sli_psa_driver_features.h"
#if defined(SL_TRUSTZONE_NONSECURE)
// include path: trusted-firmware-m/interface/include
#include "psa/crypto.h"
#else
// include path: mbedtls/include
#include "psa/crypto_driver_common.h"
#endif
//------------------------------------------------------------------------------
// Device Agnostic Values
/***************************************************************************//**
* \addtogroup sl_psa_crypto
* @{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_key_management Key Management
* \brief PSA Crypto key management on Silicon Labs devices
*
* @section built_in_keys Built-in Keys
* The PSA Crypto API provides a mechanism for accessing keys that are stored
* in the hardware. Available built-in key IDs vary for different family of devices.
* For devices vith a Virtual Secure Engine see
* \ref sl_psa_drivers_cryptoacc_builtin_keys , and for devices with a Hardware
* Secure Engine see \ref sl_psa_drivers_se_builtin_keys .
*
* Refer to AN1311 for more information on the
* usage of builtin keys through PSA Crypto.
* @{
******************************************************************************/
/// Location value for keys to be stored encrypted with the device-unique secret.
/// Wrapped key locations are vailable on Secure Vault High devices.
#define SL_PSA_KEY_LOCATION_WRAPPED ((psa_key_location_t)0x000001UL)
/// Location value for usage of built-in keys.
/// Built-in key locations are available on Secure Vault Mid (and higher) devices
/// with PUF-key support.
// Identical to SL_PSA_KEY_LOCATION_WRAPPED for implementation-related reasons.
#define SL_PSA_KEY_LOCATION_BUILTIN ((psa_key_location_t)0x000001UL)
// #define SLE_PSA_KEY_LOCATION_SE_VOLATILE ((psa_key_location_t)0x800000UL)
// #define SLE_PSA_KEY_LOCATION_KSU ((psa_key_location_t)0x800001UL)
//------------------------------------------------------------------------------
// Hardware Secure Engine
#if defined(SLI_MBEDTLS_DEVICE_HSE)
/// Location value for keys to be stored encrypted with the device-unique secret,
/// or for accessing the built-in keys on Vault-High devices. Users should use
/// SL_PSA_KEY_LOCATION_WRAPPED or SL_PSA_KEY_LOCATION_BUILTIN instead.
#define PSA_KEY_LOCATION_SL_SE_OPAQUE (SL_PSA_KEY_LOCATION_WRAPPED)
#if defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS) || defined(SL_TRUSTZONE_NONSECURE)
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se_builtin_keys Built-in keys on devices with a HSE
* \brief These key ID values allow access to the keys which respectively are and
* can be preprovisioned in Secure Engine (HSE) devices.
*
* The key IDs are within the the builtin range of PSA [MBEDTLS_PSA_KEY_ID_BUILTIN_MIN,
* MBEDLTS_PSA_KEY_ID_BUILTIN_MAX].
*
* @{
******************************************************************************/
#if defined(SLI_PSA_DRIVER_FEATURE_ATTESTATION)
#ifndef SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID
/// Vendor Key ID for the built-in application identity key on Vault High devices.
#define SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 5)
#endif
#ifndef SL_SE_BUILTIN_KEY_SYSTEM_ATTESTATION_ID
/// Vendor Key ID for the built-in SE identity key on Vault High devices.
#define SL_SE_BUILTIN_KEY_SYSTEM_ATTESTATION_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 4)
#endif
#endif // SLI_PSA_DRIVER_FEATURE_ATTESTATION
#ifndef SL_SE_BUILTIN_KEY_SECUREBOOT_ID
/// Vendor Key ID for the Secure Boot verifying key provisioned to the Secure Engine.
#define SL_SE_BUILTIN_KEY_SECUREBOOT_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1)
#endif
#ifndef SL_SE_BUILTIN_KEY_SECUREDEBUG_ID
/// Vendor Key ID for the Secure Debug verifying key provisioned to the Secure Engine.
#define SL_SE_BUILTIN_KEY_SECUREDEBUG_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 2)
#endif
#ifndef SL_SE_BUILTIN_KEY_AES128_ID
/// Vendor Key ID for AES-128 key provisioned to the Secure Engine.
#define SL_SE_BUILTIN_KEY_AES128_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 3)
#endif
#ifndef SL_SE_BUILTIN_KEY_TRUSTZONE_ID
/// Vendor Key ID for the TrustZone root key.
#define SL_SE_BUILTIN_KEY_TRUSTZONE_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 6)
#endif
#ifndef SL_SE_BUILTIN_KEY_AES128_ALG
/// Algorithm with which the #SL_SE_BUILTIN_KEY_AES128_ID key will be used.
// PSA Crypto only allows one specific usage algorithm per built-in key ID.
#define SL_SE_BUILTIN_KEY_AES128_ALG (SL_SE_BUILTIN_KEY_AES128_ALG_CONFIG)
#endif
/** @} (end addtogroup sl_psa_drivers_se_builtin_keys) */
#endif // SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS || SL_TRUSTZONE_NONSECURE
#endif // SLI_MBEDTLS_DEVICE_HSE
//------------------------------------------------------------------------------
// Virtual Secure Engine
#if defined(SLI_PSA_DRIVER_FEATURE_PUF_KEY)
/// Location value for built-in keys on VSE archtectures
/// Users should use \ref SL_PSA_KEY_LOCATION_BUILTIN instead
#define PSA_KEY_LOCATION_SL_CRYPTOACC_OPAQUE (SL_PSA_KEY_LOCATION_BUILTIN)
#if defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS) || defined(SL_TRUSTZONE_NONSECURE)
/***************************************************************************//**
* \addtogroup sl_psa_drivers_cryptoacc_builtin_keys Built-in keys on devices with a VSE
* \brief These key ID values allow access to the keys which respectively are and
* can be preprovisioned in Virtual Secure Engine (VSE) devices.
*
* The key ID's are within the the builtin range of PSA [MBEDTLS_PSA_KEY_ID_BUILTIN_MIN,
* MBEDLTS_PSA_KEY_ID_BUILTIN_MAX].
* @{
******************************************************************************/
#ifndef SL_CRYPTOACC_BUILTIN_KEY_PUF_ID
/// Vendor Key ID for the PUF-derived hardware unique key.
#define SL_CRYPTOACC_BUILTIN_KEY_PUF_ID (MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1)
#endif
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/// Internal ID for PUF-derived key.
#define SLI_CRYPTOACC_BUILTIN_KEY_PUF_SLOT (SL_CRYPTOACC_BUILTIN_KEY_PUF_ID && 0xFF)
/// Version of opaque header struct.
#define SLI_CRYPTOACC_OPAQUE_KEY_CONTEXT_VERSION (0x00)
/// @endcond
/** @} (end addtogroup sl_psa_drivers_cryptoacc) */
#endif // SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS || SL_TRUSTZONE_NONSECURE
/** @} (end addtogroup sl_psa_key_management) */
/** @} (end addtogroup sl_psa_drivers) */
#endif // SLI_PSA_DRIVER_FEATURE_PUF_KEY
#endif // SL_PSA_VALUES_H

View File

@@ -0,0 +1,155 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs internal PSA Crypto utility functions.
*******************************************************************************
* # License
* <b>Copyright 2022 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_PSA_CRYPTO_H
#define SLI_PSA_CRYPTO_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include "psa/crypto.h"
#include <stddef.h>
#include <stdbool.h>
// -----------------------------------------------------------------------------
// Defines and Macros
// Persistent key ID ranges.
#define SLI_PSA_KEY_ID_RANGE_THREAD_START (0x00020000)
#define SLI_PSA_KEY_ID_RANGE_THREAD_END (0x0002FFFF)
#define SLI_PSA_KEY_ID_RANGE_ZIGBEE_START (0x00030000)
#define SLI_PSA_KEY_ID_RANGE_ZIGBEE_END (0x0003FFFF)
// Convert a type name into an enum entry name, since enum entries and type
// names share the same C namespace.
#define SLI_PSA_CONTEXT_ENUM_NAME(NAME) \
NAME ## _e
#define SLI_MBEDTLS_CONTEXT_ENUM_NAME(NAME) \
NAME ## _e
// Convenience macros for getting the size of a context structure type
#define SLI_PSA_CONTEXT_GET_RUNTIME_SIZE(NAME) \
(sli_psa_context_get_size(SLI_PSA_CONTEXT_ENUM_NAME(NAME)))
#define SLI_MBEDTLS_CONTEXT_GET_RUNTIME_SIZE(NAME) \
(sli_mbedtls_context_get_size(SLI_MBEDTLS_CONTEXT_ENUM_NAME(NAME)))
// -----------------------------------------------------------------------------
// Type Definitions
// Type names supported by sli_psa_context_get_size.
typedef enum {
SLI_PSA_CONTEXT_ENUM_NAME(psa_hash_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_cipher_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_pake_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_mac_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_aead_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_key_derivation_operation_t),
SLI_PSA_CONTEXT_ENUM_NAME(psa_key_attributes_t)
} sli_psa_context_name_t;
// Type names supported by sli_mbedtls_context_get_size.
typedef enum {
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_aes_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ccm_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_cipher_context_t),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ctr_drbg_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_entropy_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_md_context_t),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_nist_kw_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_pk_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_sha1_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_sha256_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_config),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_context),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_cookie_ctx),
SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_x509_crt)
} sli_mbedtls_context_name_t;
// -----------------------------------------------------------------------------
// Function Declarations
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @brief
* Get the size of a named PSA context structure. This is valuable for code
* shipping as precompiled libraries and needing to link with a source version
* of PSA Crypto, since the context structures can change in size based on
* configuration options which might not have been present at library
* compilation time.
*
* @param ctx_type
* Which context structure to get the size of. Use
* #SLI_PSA_CONTEXT_ENUM_NAME(psa_xxx_operation_t) as argument.
*
* @return
* Size (in bytes) of the context structure as expected by the current build.
******************************************************************************/
size_t sli_psa_context_get_size(sli_psa_context_name_t ctx_type);
/***************************************************************************//**
* @brief
* Get the size of a named Mbed TLS context structure. This is valuable for
* code shipping as precompiled libraries and needing to link with a source
* version of PSA Crypto, since the context structures can change in size
* based on configuration options which might not have been present at library
* compilation time.
*
* @param ctx_type
* Which context structure to get the size of. Use
* #SLI_MBEDTLS_CONTEXT_ENUM_NAME(<mbed-tls-type>) as argument.
*
* @return
* Size (in bytes) of the context structure as expected by the current build.
******************************************************************************/
size_t sli_mbedtls_context_get_size(sli_mbedtls_context_name_t ctx_type);
/***************************************************************************//**
* @brief
* Check if a key is copyable even though the key attributes do not have the
* PSA_KEY_USAGE_COPY flag set.
*
* @param key_id
* The key ID of the key of interest.
*
* @return
* True if the key should be unconditionally copyable, otherwise false.
******************************************************************************/
bool sli_psa_key_is_unconditionally_copyable(psa_key_id_t key_id);
#ifdef __cplusplus
}
#endif
/// @endcond
#endif // SLI_PSA_CRYPTO_H

View File

@@ -0,0 +1,259 @@
/**************************************************************************/ /**
* @file
* @brief Threading primitive implementation for mbed TLS
*******************************************************************************
* # License
* <b>Copyright 2021 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 THREADING_ALT_H
#define THREADING_ALT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_mbedtls_plugins_threading Threading Primitives
* \brief Threading primitive implementation for mbed TLS
*
* This module provides a threading implementation, based on CMSIS RTOS2, that
* can be used by Mbed TLS when threading is required.
*
* \note These plugins are automatically enabled when creating an SLC project
* with Micrium OS or FreeRTOS with Mbed TLS.
*
* \{
******************************************************************************/
#include <stdbool.h>
#if defined(MBEDTLS_THREADING_ALT) && defined(MBEDTLS_THREADING_C)
#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)
#include "sli_psec_osal.h"
#include "sl_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SL_THREADING_ALT
#define MUTEX_INIT = { 0 }
/// Mbed TLS mutexes maps to SLI PSEC OSAL locks.
typedef sli_psec_osal_lock_t mbedtls_threading_mutex_t;
typedef struct mbedtls_test_thread_t {
osThreadAttr_t thread_attr;
osThreadId_t thread_ID;
} mbedtls_test_thread_t;
#include "mbedtls/threading.h"
#ifndef MBEDTLS_ERR_THREADING_THREAD_ERROR
#define MBEDTLS_ERR_THREADING_THREAD_ERROR -0x001F
#endif
/**
* \brief Set mutex recursive
*
* \param mutex Pointer to the mutex
*/
static inline void THREADING_SetRecursive(mbedtls_threading_mutex_t *mutex)
{
sl_status_t sl_status = sli_psec_osal_set_recursive_lock((sli_psec_osal_lock_t*)mutex);
EFM_ASSERT(sl_status == SL_STATUS_OK);
}
/**
* \brief Initialize a given mutex
*
* \param mutex Pointer to the mutex needing initialization
*/
static inline void THREADING_InitMutex(mbedtls_threading_mutex_t *mutex)
{
sl_status_t sl_status = sli_psec_osal_init_lock(mutex);
EFM_ASSERT(sl_status == SL_STATUS_OK);
}
/**
* \brief Free a given mutex
*
* \param mutex Pointer to the mutex being freed
*/
static inline void THREADING_FreeMutex(mbedtls_threading_mutex_t *mutex)
{
sl_status_t sl_status = sli_psec_osal_free_lock(mutex);
EFM_ASSERT(sl_status == SL_STATUS_OK);
}
/**
* \brief Pend on a mutex
*
* \param mutex Pointer to the mutex being pended on
*
* \return RTOS_ERR_NONE on success, error code otherwise.
*/
static inline int THREADING_TakeMutexBlocking(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}
sl_status_t sl_status = sli_psec_osal_take_lock(mutex);
return (sl_status == SL_STATUS_OK ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR);
}
/**
* \brief Try to own a mutex without waiting
*
* \param mutex Pointer to the mutex being tested
*
* \return RTOS_ERR_NONE on success (= mutex successfully owned), error code otherwise.
*/
static inline int THREADING_TakeMutexNonBlocking(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}
sl_status_t sl_status = sli_psec_osal_take_lock_non_blocking(mutex);
return (sl_status == SL_STATUS_OK ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR);
}
/**
* \brief Release a mutex
*
* \param mutex Pointer to the mutex being released
*
* \return RTOS_ERR_NONE on success, error code otherwise.
*/
static inline int THREADING_GiveMutex(mbedtls_threading_mutex_t *mutex)
{
if (mutex == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}
sl_status_t sl_status = sli_psec_osal_give_lock(mutex);
return (sl_status == SL_STATUS_OK ? 0 : MBEDTLS_ERR_THREADING_MUTEX_ERROR);
}
/**
* \brief The thread create function implementation
*
* \param thread Pointer to the thread being created
* \param thread_func Pointer to the thread function
* \param thread_data Pointer to the thread data
*/
static inline int THREADING_ThreadCreate(mbedtls_test_thread_t *thread,
void (*thread_func)(
void *),
void *thread_data)
{
if (thread == NULL || thread_func == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}
thread->thread_ID = osThreadNew(thread_func, thread_data, &thread->thread_attr);
if (thread->thread_ID == NULL) {
return MBEDTLS_ERR_THREADING_THREAD_ERROR;
}
return 0;
}
/**
* \brief The thread join function implementation
*
* \param thread Pointer to the thread being joined
*/
static inline int THREADING_ThreadJoin(mbedtls_test_thread_t *thread)
{
if (thread == NULL) {
return MBEDTLS_ERR_THREADING_BAD_INPUT_DATA;
}
if (osThreadJoin(thread->thread_ID) != 0) {
return MBEDTLS_ERR_THREADING_THREAD_ERROR;
}
return 0;
}
#ifdef __cplusplus
}
#endif
#endif // SL_CATALOG_MICRIUMOS_KERNEL_PRESENT || SL_CATALOG_FREERTOS_KERNEL_PRESENT
#ifdef __cplusplus
extern "C" {
#endif
/* Forward declaration of threading_set_alt */
void mbedtls_threading_set_alt(void (*mutex_init)(mbedtls_threading_mutex_t *),
void (*mutex_free)(mbedtls_threading_mutex_t *),
int (*mutex_lock)(mbedtls_threading_mutex_t *),
int (*mutex_unlock)(mbedtls_threading_mutex_t *) );
/* Forward declaration of test_thread_set_alt */
void mbedtls_test_thread_set_alt(int (*thread_create)(mbedtls_test_thread_t *thread,
void (*thread_func)(
void *),
void *thread_data),
int (*thread_join)(mbedtls_test_thread_t *thread));
/**
* \brief Helper function for setting up the mbed TLS threading subsystem
*/
static inline void THREADING_setup(void)
{
mbedtls_threading_set_alt(&THREADING_InitMutex,
&THREADING_FreeMutex,
&THREADING_TakeMutexBlocking,
&THREADING_GiveMutex);
}
static inline void THREAD_test_setup(void)
{
mbedtls_test_thread_set_alt(&THREADING_ThreadCreate,
&THREADING_ThreadJoin);
}
#ifdef __cplusplus
}
#endif
#endif /* MBEDTLS_THREADING_ALT && MBEDTLS_THREADING_C */
/** \} (end addtogroup sl_mbedtls_plugins_threading) */
/** \} (end addtogroup sl_mbedtls_plugins) */
/// @endcond
#endif /* THREADING_ALT_H */

View File

@@ -0,0 +1,403 @@
/***************************************************************************//**
* @file
* @brief AES-CMAC abstraction based on PSA accelerators
*******************************************************************************
* # 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.
*
******************************************************************************/
/**
* This file includes an alternative implementation of various functions in
* cmac.c, using the accelerators incorporated in devices from Silicon Labs.
*
* This alternative implementation calls the PSA Crypto drivers provided
* by Silicon Labs. For details on these drivers, see \ref sl_psa_drivers.
*/
#include <mbedtls/build_info.h>
#if defined (MBEDTLS_CMAC_C) && defined(MBEDTLS_CMAC_ALT)
#include "mbedtls/cmac.h"
#include "mbedtls/error.h"
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdlib.h>
#define mbedtls_calloc calloc
#define mbedtls_free free
#if defined(MBEDTLS_SELF_TEST)
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_PLATFORM_C */
#include "psa/crypto.h"
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_functions.h"
#define SLI_DEVICE_HAS_AES_192
#define MAC_IMPLEMENTATION_PRESENT
#define MAC_SETUP_EN_FCT sli_se_transparent_mac_sign_setup
#define MAC_SETUP_DE_FCT sli_se_transparent_mac_verify_setup
#define MAC_UPDATE_FCT sli_se_transparent_mac_update
#define MAC_FINISH_EN_FCT sli_se_transparent_mac_sign_finish
#define MAC_FINISH_DE_FCT sli_se_transparent_mac_verify_finish
#define MAC_ABORT_FCT sli_se_transparent_mac_abort
#define MAC_ONESHOT_EN_FCT sli_se_transparent_mac_compute
#define MAC_ONESHOT_DE_FCT sli_se_transparent_mac_verify
#if defined(RADIOAES_PRESENT)
#include "sli_protocol_crypto.h"
#endif
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_functions.h"
#define SLI_DEVICE_HAS_AES_192
#define MAC_IMPLEMENTATION_PRESENT
#define MAC_SETUP_EN_FCT sli_cryptoacc_transparent_mac_sign_setup
#define MAC_SETUP_DE_FCT sli_cryptoacc_transparent_mac_verify_setup
#define MAC_UPDATE_FCT sli_cryptoacc_transparent_mac_update
#define MAC_FINISH_EN_FCT sli_cryptoacc_transparent_mac_sign_finish
#define MAC_FINISH_DE_FCT sli_cryptoacc_transparent_mac_verify_finish
#define MAC_ABORT_FCT sli_cryptoacc_transparent_mac_abort
#define MAC_ONESHOT_EN_FCT sli_cryptoacc_transparent_mac_compute
#define MAC_ONESHOT_DE_FCT sli_cryptoacc_transparent_mac_verify
#endif
#if defined(MAC_IMPLEMENTATION_PRESENT)
#include <string.h>
static int psa_status_to_mbedtls(psa_status_t status)
{
switch ( status ) {
case PSA_SUCCESS:
return 0;
case PSA_ERROR_HARDWARE_FAILURE:
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
default:
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
}
static inline void sl_psa_set_key_type(psa_key_attributes_t *attributes,
psa_key_type_t type)
{
/* Common case: quick path */
attributes->MBEDTLS_PRIVATE(type) = type;
}
int mbedtls_cipher_cmac_starts(mbedtls_cipher_context_t *ctx,
const unsigned char *key, size_t keybits)
{
mbedtls_cipher_type_t type;
mbedtls_cmac_context_t *cmac_ctx;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
sl_psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
if ( ctx == NULL || ctx->MBEDTLS_PRIVATE(cipher_info) == NULL || key == NULL ) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
type = (mbedtls_cipher_type_t)ctx->MBEDTLS_PRIVATE(cipher_info)->MBEDTLS_PRIVATE(type);
switch ( type ) {
case MBEDTLS_CIPHER_AES_128_ECB:
psa_set_key_bits(&attr, 128);
break;
case MBEDTLS_CIPHER_AES_192_ECB:
#if defined(SLI_DEVICE_HAS_AES_192)
psa_set_key_bits(&attr, 192);
#else
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
#endif
break;
case MBEDTLS_CIPHER_AES_256_ECB:
psa_set_key_bits(&attr, 256);
break;
default:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
}
if ( ctx->MBEDTLS_PRIVATE(cmac_ctx) == NULL ) {
/* Allocate CMAC context memory if it hasn't already been allocated */
cmac_ctx = mbedtls_calloc(1, sizeof(struct mbedtls_cmac_context_t) );
if ( cmac_ctx == NULL ) {
return(MBEDTLS_ERR_CIPHER_ALLOC_FAILED);
}
ctx->MBEDTLS_PRIVATE(cmac_ctx) = cmac_ctx;
} else {
mbedtls_platform_zeroize(ctx->MBEDTLS_PRIVATE(cmac_ctx), sizeof(*ctx->MBEDTLS_PRIVATE(cmac_ctx)) );
}
return psa_status_to_mbedtls(
MAC_SETUP_EN_FCT(&ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx,
&attr,
key,
keybits / 8U,
PSA_ALG_CMAC) );
}
int mbedtls_cipher_cmac_update(mbedtls_cipher_context_t *ctx,
const unsigned char *input, size_t ilen)
{
if ( ctx == NULL || ctx->MBEDTLS_PRIVATE(cipher_info) == NULL || input == NULL
|| ctx->MBEDTLS_PRIVATE(cmac_ctx) == NULL ) {
return(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
}
return psa_status_to_mbedtls(
MAC_UPDATE_FCT(&ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx,
input,
ilen) );
}
int mbedtls_cipher_cmac_finish(mbedtls_cipher_context_t *ctx,
unsigned char *output)
{
if ( ctx == NULL || ctx->MBEDTLS_PRIVATE(cipher_info) == NULL || ctx->MBEDTLS_PRIVATE(cmac_ctx) == NULL
|| output == NULL ) {
return(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
}
size_t olen = 0;
return psa_status_to_mbedtls(
MAC_FINISH_EN_FCT(&ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx,
output,
MBEDTLS_AES_BLOCK_SIZE,
&olen) );
}
int mbedtls_cipher_cmac_reset(mbedtls_cipher_context_t *ctx)
{
if ( ctx == NULL || ctx->MBEDTLS_PRIVATE(cipher_info) == NULL || ctx->MBEDTLS_PRIVATE(cmac_ctx) == NULL ) {
return(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
}
uint8_t key[32];
size_t key_len;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
sl_psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
if ( ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx.cipher_mac.key_len > sizeof(key) ) {
return(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
}
/* Save the key to be able to restart the operation */
memcpy(key,
ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx.cipher_mac.key,
ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx.cipher_mac.key_len);
key_len = ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx.cipher_mac.key_len;
psa_set_key_bits(&attr, key_len * 8);
/* Abort and restart with the same key */
MAC_ABORT_FCT(&ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx);
return psa_status_to_mbedtls(
MAC_SETUP_EN_FCT(&ctx->MBEDTLS_PRIVATE(cmac_ctx)->ctx,
&attr,
key,
key_len,
PSA_ALG_CMAC) );
}
#if defined(RADIOAES_PRESENT) && defined(SEMAILBOX_PRESENT)
/* For speeding up PBKDF2-CMAC, which needs a lot of iterations with small-size
* CMAC operations, we can dispatch these to the RADIOAES instance if there is
* one available.
*
* Function limitations: can only be used with AES-128 or AES-256, and needs to
* have as short as possible execution time to not block other time-sensitive
* operations (such as BLE RPA). Will always output a full CMAC (16 bytes).
*
* \param key Raw key bytes, \p keylen bytes long
* \param keylen Length of \p key in bytes, either 16 (AES-128) or 32 (AES-256)
* \param input Data bytes to calculate the CMAC over, length \p ilen bytes
* \param ilen Length in bytes of \p input
* \param output Output buffer for the calculated CMAC tag (16 bytes)
*
* \return \c 0 on success, MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED on failure
*/
static int sli_short_cmac_operation(const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output)
{
sl_status_t status = sli_aes_cmac_radio(key,
keylen,
input,
ilen,
output);
if (status == SL_STATUS_OK) {
return 0;
} else {
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
}
}
#endif
int mbedtls_cipher_cmac(const mbedtls_cipher_info_t *cipher_info,
const unsigned char *key, size_t keylen,
const unsigned char *input, size_t ilen,
unsigned char *output)
{
if ( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
switch ( cipher_info->MBEDTLS_PRIVATE(type) ) {
case MBEDTLS_CIPHER_AES_128_ECB:
if ( keylen != 128UL ) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
break;
case MBEDTLS_CIPHER_AES_192_ECB:
#if defined(SLI_DEVICE_HAS_AES_192)
if ( keylen != 192UL ) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
break;
#else
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
#endif
case MBEDTLS_CIPHER_AES_256_ECB:
if ( keylen != 256UL ) {
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
break;
default:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
}
#if defined(RADIOAES_PRESENT) && defined(SEMAILBOX_PRESENT)
/* Use the fast shortcut if available */
if ( (keylen == 128UL || keylen == 256UL) && (ilen <= 2 * MBEDTLS_AES_BLOCK_SIZE) ) {
return sli_short_cmac_operation(key, keylen,
input, ilen, output);
}
#endif
size_t olen = 0;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
sl_psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
switch ( cipher_info->MBEDTLS_PRIVATE(type) ) {
case MBEDTLS_CIPHER_AES_128_ECB:
psa_set_key_bits(&attr, 128);
break;
case MBEDTLS_CIPHER_AES_192_ECB:
psa_set_key_bits(&attr, 192);
break;
case MBEDTLS_CIPHER_AES_256_ECB:
psa_set_key_bits(&attr, 256);
break;
default:
return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
}
return psa_status_to_mbedtls(
MAC_ONESHOT_EN_FCT(&attr,
key, keylen / 8U,
PSA_ALG_CMAC,
input, ilen,
output, MBEDTLS_AES_BLOCK_SIZE, &olen) );
}
/*
* Implementation of AES-CMAC-PRF-128 defined in RFC 4615
*/
int mbedtls_aes_cmac_prf_128(const unsigned char *key, size_t key_length,
const unsigned char *input, size_t in_len,
unsigned char output[16])
{
int ret;
unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE];
unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE];
if ( key == NULL || input == NULL || output == NULL ) {
return(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA);
}
size_t olen = 0;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
sl_psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attr, 128);
if ( key_length == MBEDTLS_AES_BLOCK_SIZE ) {
/* Use key as is */
memcpy(int_key, key, MBEDTLS_AES_BLOCK_SIZE);
} else {
memset(zero_key, 0, MBEDTLS_AES_BLOCK_SIZE);
#if defined(RADIOAES_PRESENT) && defined(SEMAILBOX_PRESENT)
/* Use the fast shortcut if available */
if ( key_length <= 2 * MBEDTLS_AES_BLOCK_SIZE ) {
ret = sli_short_cmac_operation(zero_key, MBEDTLS_AES_BLOCK_SIZE * 8,
key, key_length, int_key);
} else
#endif
{
ret = psa_status_to_mbedtls(
MAC_ONESHOT_EN_FCT(&attr,
zero_key, MBEDTLS_AES_BLOCK_SIZE,
PSA_ALG_CMAC,
key, key_length,
int_key, MBEDTLS_AES_BLOCK_SIZE, &olen) );
}
if ( ret != 0 ) {
goto exit;
}
}
#if defined(RADIOAES_PRESENT) && defined(SEMAILBOX_PRESENT)
/* Use the fast shortcut if available */
if ( key_length <= 2 * MBEDTLS_AES_BLOCK_SIZE ) {
ret = sli_short_cmac_operation(int_key, MBEDTLS_AES_BLOCK_SIZE * 8,
input, in_len, (uint8_t*)output);
} else
#endif
{
ret = psa_status_to_mbedtls(
MAC_ONESHOT_EN_FCT(&attr,
int_key, MBEDTLS_AES_BLOCK_SIZE,
PSA_ALG_CMAC,
input, in_len,
(uint8_t*)output, in_len, &olen) );
}
exit:
mbedtls_platform_zeroize(int_key, sizeof(int_key) );
return(ret);
}
#endif /* MAC_IMPLEMENTATION_PRESENT */
#endif /* MBEDTLS_CMAC_C && MBEDTLS_CMAC_ALT */

View File

@@ -0,0 +1,391 @@
/***************************************************************************//**
* @file
* @brief mbed TLS elliptic curve operations accelerated by PSA crypto drivers
*******************************************************************************
* # 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.
*
******************************************************************************/
/**
* This file includes an alternative implementation of high-level ECDSA and ECDH
* functions from the mbed TLS API, using the relevant accelerators incorporated
* in devices from Silicon Labs.
*
* For Series-1 devices with a CRYPTO peripheral, see crypto_ecp.c.
*
* This alternative implementation calls the PSA Crypto drivers provided
* by Silicon Labs. For details on these drivers, see \ref sl_psa_drivers.
*/
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_ECP_C)
#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) \
|| defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) \
|| defined(MBEDTLS_ECDSA_GENKEY_ALT) \
|| defined(MBEDTLS_ECDSA_VERIFY_ALT) \
|| defined(MBEDTLS_ECDSA_SIGN_ALT)
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_functions.h"
#define ECC_IMPLEMENTATION_PRESENT
#define ECC_KEYGEN_FCT sli_se_transparent_generate_key
#define ECC_PUBKEY_FCT sli_se_transparent_export_public_key
#define ECDSA_SIGN_FCT sli_se_transparent_sign_hash
#define ECDSA_VERIFY_FCT sli_se_transparent_verify_hash
#define ECDH_DERIVE_FCT sli_se_transparent_key_agreement
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_functions.h"
#define ECC_IMPLEMENTATION_PRESENT
#define ECC_KEYGEN_FCT sli_cryptoacc_transparent_generate_key
#define ECC_PUBKEY_FCT sli_cryptoacc_transparent_export_public_key
#define ECDSA_SIGN_FCT sli_cryptoacc_transparent_sign_hash
#define ECDSA_VERIFY_FCT sli_cryptoacc_transparent_verify_hash
#define ECDH_DERIVE_FCT sli_cryptoacc_transparent_key_agreement
#endif
#include "mbedtls/ecdh.h"
#include "mbedtls/ecdsa.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/bignum.h"
#include "mbedtls/error.h"
#include "psa/crypto.h"
#if defined(ECC_IMPLEMENTATION_PRESENT)
static int psa_status_to_mbedtls(psa_status_t status)
{
switch ( status ) {
case PSA_SUCCESS:
return 0;
case PSA_ERROR_INVALID_SIGNATURE:
return MBEDTLS_ERR_ECP_VERIFY_FAILED;
case PSA_ERROR_HARDWARE_FAILURE:
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
default:
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
}
}
static int mbedtls_grp_to_psa_attr(mbedtls_ecp_group_id id,
psa_key_attributes_t *attr)
{
switch (id) {
case MBEDTLS_ECP_DP_SECP192R1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_bits(attr, 192);
break;
#if defined(CRYPTOACC_PRESENT)
case MBEDTLS_ECP_DP_SECP224R1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_bits(attr, 224);
break;
case MBEDTLS_ECP_DP_SECP256K1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_K1);
psa_set_key_bits(attr, 256);
break;
#endif
case MBEDTLS_ECP_DP_SECP256R1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_bits(attr, 256);
break;
case MBEDTLS_ECP_DP_SECP384R1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_bits(attr, 384);
break;
case MBEDTLS_ECP_DP_SECP521R1:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
psa_set_key_bits(attr, 521);
break;
case MBEDTLS_ECP_DP_CURVE25519:
attr->MBEDTLS_PRIVATE(type) = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY);
psa_set_key_bits(attr, 255);
break;
default:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
}
return PSA_SUCCESS;
}
#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) \
|| defined(MBEDTLS_ECDSA_GENKEY_ALT)
static int ecc_keygen(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q)
{
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
uint8_t keybuf[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2 + 1u] = { 0 };
psa_status_t status = psa_status_to_mbedtls(
mbedtls_grp_to_psa_attr(grp->id, &attr) );
if ( status != PSA_SUCCESS ) {
return status;
}
size_t keybytes;
status = psa_status_to_mbedtls(
ECC_KEYGEN_FCT(&attr,
keybuf,
sizeof(keybuf),
&keybytes) );
if ( status != PSA_SUCCESS ) {
return status;
}
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY) {
mbedtls_mpi_read_binary_le(d, keybuf, keybytes);
} else {
mbedtls_mpi_read_binary(d, keybuf, keybytes);
}
status = psa_status_to_mbedtls(
ECC_PUBKEY_FCT(&attr,
keybuf,
keybytes,
keybuf,
sizeof(keybuf),
&keybytes) );
if ( status != PSA_SUCCESS ) {
return status;
}
if ( PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY ) {
mbedtls_mpi_read_binary_le(&Q->MBEDTLS_PRIVATE(X), keybuf, keybytes);
} else {
// The first byte is used to store uncompressed representation byte.
mbedtls_mpi_read_binary(&Q->MBEDTLS_PRIVATE(X), keybuf + 1u, keybytes / 2);
mbedtls_mpi_read_binary(&Q->MBEDTLS_PRIVATE(Y), keybuf + keybytes / 2 + 1u, keybytes / 2);
mbedtls_mpi_lset(&Q->MBEDTLS_PRIVATE(Z), 1);
}
return status;
}
#endif /* #if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
|| defined(MBEDTLS_ECDSA_GENKEY_ALT) */
#if defined(MBEDTLS_ECDSA_GENKEY_ALT)
/*
* Generate key pair
*/
int mbedtls_ecdsa_genkey(mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
/* PSA uses internal entropy */
(void)f_rng;
(void)p_rng;
mbedtls_ecp_group_load(&ctx->MBEDTLS_PRIVATE(grp), gid);
return ecc_keygen(&ctx->MBEDTLS_PRIVATE(grp), &ctx->MBEDTLS_PRIVATE(d), &ctx->MBEDTLS_PRIVATE(Q));
}
#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
#if defined(MBEDTLS_ECDSA_SIGN_ALT)
int mbedtls_ecdsa_sign(mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
{
/* PSA uses internal entropy */
(void)f_rng;
(void)p_rng;
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
uint8_t key_signature_buf[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2] = { 0 };
psa_status_t status = psa_status_to_mbedtls(
mbedtls_grp_to_psa_attr(grp->id, &attr));
if ( status != PSA_SUCCESS ) {
return status;
}
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_SIGN_HASH);
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY) {
return PSA_ERROR_NOT_SUPPORTED;
}
size_t keybytes = PSA_BITS_TO_BYTES(psa_get_key_bits(&attr));
// Make sure d is in range 1..n-1
if ((mbedtls_mpi_cmp_int(d, 1) < 0) || (mbedtls_mpi_cmp_mpi(d, &grp->N) >= 0)) {
return MBEDTLS_ERR_ECP_INVALID_KEY;
}
mbedtls_mpi_write_binary(d, key_signature_buf, keybytes);
status = psa_status_to_mbedtls(
ECDSA_SIGN_FCT(&attr,
key_signature_buf,
keybytes,
PSA_ALG_ECDSA_ANY,
buf,
blen,
key_signature_buf,
sizeof(key_signature_buf),
&keybytes) );
if ( status != PSA_SUCCESS ) {
return status;
}
mbedtls_mpi_read_binary(r, key_signature_buf, keybytes / 2);
mbedtls_mpi_read_binary(s, key_signature_buf + (keybytes / 2), keybytes / 2);
return status;
}
#endif /* MBEDTLS_ECDSA_SIGN_ALT */
#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
int mbedtls_ecdsa_verify(mbedtls_ecp_group *grp,
const unsigned char *buf, size_t blen,
const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
{
uint8_t pub[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2 + 1] = { 0 };
uint8_t signature[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2] = { 0 };
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = psa_status_to_mbedtls(
mbedtls_grp_to_psa_attr(grp->id, &attr) );
if ( status != PSA_SUCCESS ) {
return status;
}
/* Check signature components r, s or both are not negative. */
if ( (r->MBEDTLS_PRIVATE(s) < 0) || (s->MBEDTLS_PRIVATE(s) < 0) ) {
return MBEDTLS_ERR_ECP_VERIFY_FAILED;
}
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_VERIFY_HASH);
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY) {
return PSA_ERROR_NOT_SUPPORTED;
}
attr.MBEDTLS_PRIVATE(type) =
PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)));
size_t keybytes = PSA_BITS_TO_BYTES(psa_get_key_bits(&attr));
/* pull out signature info from mbedtls structures */
mbedtls_mpi_write_binary(r, signature, keybytes);
mbedtls_mpi_write_binary(s, &signature[keybytes], keybytes);
pub[0] = 0x04; // Uncompressed public key
mbedtls_mpi_write_binary(&Q->MBEDTLS_PRIVATE(X), &pub[1u], keybytes);
mbedtls_mpi_write_binary(&Q->MBEDTLS_PRIVATE(Y), &pub[keybytes + 1u], keybytes);
return psa_status_to_mbedtls(
ECDSA_VERIFY_FCT(&attr,
pub,
keybytes * 2 + 1u,
PSA_ALG_ECDSA_ANY,
buf,
blen,
signature,
keybytes * 2) );
}
#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
int mbedtls_ecdh_gen_public(mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
/* PSA uses internal entropy */
(void)f_rng;
(void)p_rng;
return ecc_keygen(grp, d, Q);
}
#endif /* #if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) */
#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
int mbedtls_ecdh_compute_shared(mbedtls_ecp_group *grp, mbedtls_mpi *z,
const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng)
{
/* PSA uses internal entropy */
(void)f_rng;
(void)p_rng;
uint8_t pub[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2 + 1u] = { 0 };
uint8_t priv[((((MBEDTLS_ECP_MAX_BYTES) +3) / 4) * 4) * 2] = { 0 };
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status = psa_status_to_mbedtls(
mbedtls_grp_to_psa_attr(grp->id, &attr) );
if ( status != PSA_SUCCESS ) {
return status;
}
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_DERIVE);
size_t keylen = PSA_BITS_TO_BYTES(psa_get_key_bits(&attr));
size_t publen;
/* pull out key info from mbedtls structures */
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY) {
publen = keylen;
mbedtls_mpi_write_binary_le(d, priv, keylen);
mbedtls_mpi_write_binary_le(&Q->MBEDTLS_PRIVATE(X), pub, keylen);
} else {
publen = 2 * keylen + 1u;
mbedtls_mpi_write_binary(d, priv, keylen);
pub[0] = 0x04; // uncompressed public key
mbedtls_mpi_write_binary(&Q->MBEDTLS_PRIVATE(X), pub + 1u, keylen);
mbedtls_mpi_write_binary(&Q->MBEDTLS_PRIVATE(Y), pub + keylen + 1u, keylen);
}
status = psa_status_to_mbedtls(
ECDH_DERIVE_FCT(PSA_ALG_ECDH,
&attr,
priv,
keylen,
pub,
publen,
pub,
sizeof(pub),
&publen) );
if ( status != PSA_SUCCESS ) {
return status;
}
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(&attr)) == PSA_ECC_FAMILY_MONTGOMERY) {
mbedtls_mpi_read_binary_le(z, pub, publen);
} else {
mbedtls_mpi_read_binary(z, pub, publen);
}
return status;
}
#endif /* #if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) */
#endif /* ECC_IMPLEMENTATION_PRESENT */
#endif /* #if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT) */
#endif /* #if defined(MBEDTLS_ECP_C) */

View File

@@ -0,0 +1,242 @@
/***************************************************************************//**
* @file
* @brief SHA-1, SHA-256 and SHA-512 mbedTLS plugin on top of PSA accelerators.
*******************************************************************************
* # 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.
*
******************************************************************************/
/**
* This file includes an alternative implementation of the SHA functionality in
* mbed TLS' APIs, using the accelerators incorporated in devices from Silicon Labs.
*
* This alternative implementation calls the PSA Crypto drivers provided
* by Silicon Labs. For details on these drivers, see \ref sl_psa_drivers.
*/
#include <mbedtls/build_info.h>
#if (defined(MBEDTLS_SHA256_ALT) && defined(MBEDTLS_SHA256_C)) \
|| (defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C)) \
|| (defined(MBEDTLS_SHA512_ALT) && defined(MBEDTLS_SHA512_C))
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_transparent_functions.h"
#define HASH_IMPLEMENTATION_PRESENT
#define HASH_SETUP_FCT sli_se_transparent_hash_setup
#define HASH_UPDATE_FCT sli_se_transparent_hash_update
#define HASH_FINISH_FCT sli_se_transparent_hash_finish
#define HASH_ABORT_FCT sli_se_transparent_hash_abort
#define HASH_ONESHOT_FCT sli_se_transparent_hash_compute
#elif defined(CRYPTOACC_PRESENT)
#include "sli_cryptoacc_transparent_functions.h"
#define HASH_IMPLEMENTATION_PRESENT
#define HASH_SETUP_FCT sli_cryptoacc_transparent_hash_setup
#define HASH_UPDATE_FCT sli_cryptoacc_transparent_hash_update
#define HASH_FINISH_FCT sli_cryptoacc_transparent_hash_finish
#define HASH_ABORT_FCT sli_cryptoacc_transparent_hash_abort
#define HASH_ONESHOT_FCT sli_cryptoacc_transparent_hash_compute
#endif
#include "mbedtls/error.h"
#include "mbedtls/platform.h"
#if defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C)
#include "mbedtls/sha1.h"
#endif /* SHA1 acceleration active */
#if defined(MBEDTLS_SHA256_ALT) && defined(MBEDTLS_SHA256_C)
#include "mbedtls/sha256.h"
#endif /* SHA256 acceleration active */
#if defined(MBEDTLS_SHA512_ALT) && defined(MBEDTLS_SHA512_C)
#include "mbedtls/sha512.h"
#endif /* SHA512 acceleration active */
#if defined(HASH_IMPLEMENTATION_PRESENT)
static int psa_status_to_mbedtls(psa_status_t status, psa_algorithm_t alg)
{
switch ( status ) {
case PSA_SUCCESS:
return 0;
case PSA_ERROR_HARDWARE_FAILURE:
return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
case PSA_ERROR_NOT_SUPPORTED:
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
case PSA_ERROR_INVALID_ARGUMENT:
switch ( alg ) {
#if defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C)
case PSA_ALG_SHA_1:
return MBEDTLS_ERR_SHA1_BAD_INPUT_DATA;
#endif
#if defined(MBEDTLS_SHA256_ALT) && defined(MBEDTLS_SHA256_C)
case PSA_ALG_SHA_256:
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
#endif
#if defined(MBEDTLS_SHA512_ALT) && defined(MBEDTLS_SHA512_C)
case PSA_ALG_SHA_512:
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
#endif
default:
return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
}
default:
return MBEDTLS_ERR_ERROR_GENERIC_ERROR;
}
}
#if defined(MBEDTLS_SHA512_ALT) && (defined(MBEDTLS_SHA384_C) || defined(MBEDTLS_SHA512_C))
void mbedtls_sha512_init(mbedtls_sha512_context *ctx)
{
HASH_ABORT_FCT(ctx);
}
void mbedtls_sha512_free(mbedtls_sha512_context *ctx)
{
HASH_ABORT_FCT(ctx);
}
void mbedtls_sha512_clone(mbedtls_sha512_context *dst,
const mbedtls_sha512_context *src)
{
*dst = *src;
}
int mbedtls_sha512_starts(mbedtls_sha512_context *ctx, int is384)
{
if (is384 > 1) {
return MBEDTLS_ERR_SHA512_BAD_INPUT_DATA;
}
return psa_status_to_mbedtls(HASH_SETUP_FCT(ctx, is384 ? PSA_ALG_SHA_384 : PSA_ALG_SHA_512), PSA_ALG_SHA_512);
}
int mbedtls_sha512_update(mbedtls_sha512_context *ctx, const unsigned char *input,
size_t ilen)
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT(ctx, input, ilen), PSA_ALG_SHA_512);
}
int mbedtls_internal_sha512_process(mbedtls_sha512_context *ctx, const unsigned char data[128])
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT(ctx, data, 128), PSA_ALG_SHA_512);
}
int mbedtls_sha512_finish(mbedtls_sha512_context *ctx, unsigned char *output)
{
size_t out_length = 0;
return psa_status_to_mbedtls(HASH_FINISH_FCT(ctx, output, 64, &out_length), PSA_ALG_SHA_512);
}
#endif /* SHA512 acceleration active */
#if defined(MBEDTLS_SHA256_ALT) && (defined(MBEDTLS_SHA256_C) || defined(MBEDTLS_SHA224_C))
void mbedtls_sha256_init(mbedtls_sha256_context *ctx)
{
HASH_ABORT_FCT((void *)ctx);
}
void mbedtls_sha256_free(mbedtls_sha256_context *ctx)
{
HASH_ABORT_FCT((void *)ctx);
}
void mbedtls_sha256_clone(mbedtls_sha256_context *dst,
const mbedtls_sha256_context *src)
{
*dst = *src;
}
int mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224)
{
if (is224 > 1) {
return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA;
}
return psa_status_to_mbedtls(HASH_SETUP_FCT((void *)ctx, is224 ? PSA_ALG_SHA_224 : PSA_ALG_SHA_256), PSA_ALG_SHA_256);
}
int mbedtls_sha256_update(mbedtls_sha256_context *ctx, const unsigned char *input,
size_t ilen)
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT((void *)ctx, input, ilen), PSA_ALG_SHA_256);
}
int mbedtls_internal_sha256_process(mbedtls_sha256_context *ctx, const unsigned char data[64])
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT((void *)ctx, data, 64), PSA_ALG_SHA_256);
}
int mbedtls_sha256_finish(mbedtls_sha256_context *ctx, unsigned char *output)
{
size_t out_length = 0;
return psa_status_to_mbedtls(HASH_FINISH_FCT((void *)ctx, output, 32, &out_length), PSA_ALG_SHA_256);
}
#endif /* SHA256 acceleration active */
#if defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C)
void mbedtls_sha1_init(mbedtls_sha1_context *ctx)
{
HASH_ABORT_FCT((void *)ctx);
}
void mbedtls_sha1_free(mbedtls_sha1_context *ctx)
{
HASH_ABORT_FCT((void *)ctx);
}
void mbedtls_sha1_clone(mbedtls_sha1_context *dst,
const mbedtls_sha1_context *src)
{
*dst = *src;
}
int mbedtls_sha1_starts(mbedtls_sha1_context *ctx)
{
return psa_status_to_mbedtls(HASH_SETUP_FCT((void *)ctx, PSA_ALG_SHA_1), PSA_ALG_SHA_1);
}
int mbedtls_sha1_update(mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen)
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT((void *)ctx, input, ilen), PSA_ALG_SHA_1);
}
int mbedtls_internal_sha1_process(mbedtls_sha1_context *ctx, const unsigned char data[64])
{
return psa_status_to_mbedtls(HASH_UPDATE_FCT((void *)ctx, data, 64), PSA_ALG_SHA_1);
}
int mbedtls_sha1_finish(mbedtls_sha1_context *ctx, unsigned char output[20])
{
size_t out_length = 0;
return psa_status_to_mbedtls(HASH_FINISH_FCT((void *)ctx, output, 20, &out_length), PSA_ALG_SHA_1);
}
#endif /* SHA1 acceleration active */
#endif /* HASH_IMPLEMENTATION_PRESENT */
#endif /* (SHA1 or SHA256 or SHA512) acceleration active */

View File

@@ -0,0 +1,780 @@
/***************************************************************************//**
* @file
* @brief AES abstraction based on Secure Engine
*******************************************************************************
* # 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.
*
******************************************************************************/
/*
* This file includes alternative plugin implementations of various
* functions in aes.c using the Secure Engine accelerator incorporated
* in Series-2 devices with Secure Engine from Silicon Laboratories.
*/
/**
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
*
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_AES_ALT)
#include "em_device.h"
#if defined(SEMAILBOX_PRESENT)
#include "sli_se_manager_mailbox.h"
#include "sli_se_manager_internal.h"
#include "se_management.h"
#include "mbedtls/aes.h"
#include "mbedtls/platform.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"
#include <string.h>
/*
* Initialize AES context
*/
void mbedtls_aes_init(mbedtls_aes_context *ctx)
{
memset(ctx, 0, sizeof(mbedtls_aes_context) );
}
/*
* Clear AES context
*/
void mbedtls_aes_free(mbedtls_aes_context *ctx)
{
if ( ctx == NULL ) {
return;
}
memset(ctx, 0, sizeof(mbedtls_aes_context) );
}
#if defined(MBEDTLS_CIPHER_MODE_XTS)
void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
{
mbedtls_aes_init(&ctx->crypt);
mbedtls_aes_init(&ctx->tweak);
}
void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
{
if ( ctx == NULL ) {
return;
}
mbedtls_aes_free(&ctx->crypt);
mbedtls_aes_free(&ctx->tweak);
}
static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
unsigned int keybits,
const unsigned char **key1,
unsigned int *key1bits,
const unsigned char **key2,
unsigned int *key2bits)
{
const unsigned int half_keybits = keybits / 2;
const unsigned int half_keybytes = half_keybits / 8;
switch ( keybits ) {
case 256: break;
case 512: break;
default: return(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH);
}
*key1bits = half_keybits;
*key2bits = half_keybits;
*key1 = &key[0];
*key2 = &key[half_keybytes];
return 0;
}
int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
int ret;
const unsigned char *key1 = NULL;
const unsigned char *key2 = NULL;
unsigned int key1bits = 0;
unsigned int key2bits = 0;
ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
&key2, &key2bits);
if ( ret != 0 ) {
return(ret);
}
/* Set the tweak key. Always set tweak key for the encryption mode. */
ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
if ( ret != 0 ) {
return(ret);
}
/* Set crypt key for encryption. */
return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
}
int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
int ret;
const unsigned char *key1 = NULL;
const unsigned char *key2 = NULL;
unsigned int key1bits = 0;
unsigned int key2bits = 0;
if (ctx == NULL || key == NULL) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
&key2, &key2bits);
if ( ret != 0 ) {
return(ret);
}
/* Set the tweak key. Always set tweak key for encryption. */
ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
if ( ret != 0 ) {
return(ret);
}
/* Set crypt key for decryption. */
return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
}
/* Endianess with 64 bits values */
#ifndef GET_UINT64_LE
#define GET_UINT64_LE(n, b, i) \
{ \
(n) = ( (uint64_t) (b)[(i) + 7] << 56) \
| ( (uint64_t) (b)[(i) + 6] << 48) \
| ( (uint64_t) (b)[(i) + 5] << 40) \
| ( (uint64_t) (b)[(i) + 4] << 32) \
| ( (uint64_t) (b)[(i) + 3] << 24) \
| ( (uint64_t) (b)[(i) + 2] << 16) \
| ( (uint64_t) (b)[(i) + 1] << 8) \
| ( (uint64_t) (b)[(i)]); \
}
#endif
#ifndef PUT_UINT64_LE
#define PUT_UINT64_LE(n, b, i) \
{ \
(b)[(i) + 7] = (unsigned char) ( (n) >> 56); \
(b)[(i) + 6] = (unsigned char) ( (n) >> 48); \
(b)[(i) + 5] = (unsigned char) ( (n) >> 40); \
(b)[(i) + 4] = (unsigned char) ( (n) >> 32); \
(b)[(i) + 3] = (unsigned char) ( (n) >> 24); \
(b)[(i) + 2] = (unsigned char) ( (n) >> 16); \
(b)[(i) + 1] = (unsigned char) ( (n) >> 8); \
(b)[(i)] = (unsigned char) ( (n) ); \
}
#endif
/*
* GF(2^128) multiplication function
*
* This function multiplies a field element by x in the polynomial field
* representation. It uses 64-bit word operations to gain speed but compensates
* for machine endianess and hence works correctly on both big and little
* endian machines.
*/
static void mbedtls_gf128mul_x_ble(unsigned char r[16],
const unsigned char x[16])
{
uint64_t a, b, ra, rb;
GET_UINT64_LE(a, x, 0);
GET_UINT64_LE(b, x, 8);
ra = (a << 1) ^ 0x0087 >> (8 - ( (b >> 63) << 3) );
rb = (a >> 63) | (b << 1);
PUT_UINT64_LE(ra, r, 0);
PUT_UINT64_LE(rb, r, 8);
}
/*
* AES-XTS buffer encryption/decryption
*/
int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
int mode,
size_t length,
const unsigned char data_unit[16],
const unsigned char *input,
unsigned char *output)
{
int ret;
size_t blocks = length / 16;
size_t leftover = length % 16;
unsigned char tweak[16];
unsigned char prev_tweak[16];
unsigned char tmp[16];
if ((mode != MBEDTLS_AES_ENCRYPT) && (mode != MBEDTLS_AES_DECRYPT)) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
/* Data units must be at least 16 bytes long. */
if ( length < 16 ) {
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
}
/* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
if ( length > (1 << 20) * 16 ) {
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
}
/* Compute the tweak. */
ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
data_unit, tweak);
if ( ret != 0 ) {
return(ret);
}
while ( blocks-- ) {
size_t i;
if ( leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0 ) {
/* We are on the last block in a decrypt operation that has
* leftover bytes, so we need to use the next tweak for this block,
* and this tweak for the lefover bytes. Save the current tweak for
* the leftovers and then update the current tweak for use on this,
* the last full block. */
memcpy(prev_tweak, tweak, sizeof(tweak) );
mbedtls_gf128mul_x_ble(tweak, tweak);
}
for ( i = 0; i < 16; i++ ) {
tmp[i] = input[i] ^ tweak[i];
}
ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
if ( ret != 0 ) {
return(ret);
}
for ( i = 0; i < 16; i++ ) {
output[i] = tmp[i] ^ tweak[i];
}
/* Update the tweak for the next block. */
mbedtls_gf128mul_x_ble(tweak, tweak);
output += 16;
input += 16;
}
if ( leftover ) {
/* If we are on the leftover bytes in a decrypt operation, we need to
* use the previous tweak for these bytes (as saved in prev_tweak). */
unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
/* We are now on the final part of the data unit, which doesn't divide
* evenly by 16. It's time for ciphertext stealing. */
size_t i;
unsigned char *prev_output = output - 16;
/* Copy ciphertext bytes from the previous block to our output for each
* byte of cyphertext we won't steal. At the same time, copy the
* remainder of the input for this final round (since the loop bounds
* are the same). */
for ( i = 0; i < leftover; i++ ) {
output[i] = prev_output[i];
tmp[i] = input[i] ^ t[i];
}
/* Copy ciphertext bytes from the previous block for input in this
* round. */
for (; i < 16; i++ ) {
tmp[i] = prev_output[i] ^ t[i];
}
ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
if ( ret != 0 ) {
return ret;
}
/* Write the result back to the previous block, overriding the previous
* output we copied. */
for ( i = 0; i < 16; i++ ) {
prev_output[i] = tmp[i] ^ t[i];
}
}
return(0);
}
#endif /* MBEDTLS_CIPHER_MODE_XTS */
/*
* AES key schedule (encryption)
*/
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
memset(ctx, 0, sizeof(mbedtls_aes_context) );
if ( (128UL != keybits) && (192UL != keybits) && (256UL != keybits) ) {
// Unsupported key size
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
ctx->keybits = keybits;
memcpy(ctx->key, key, keybits / 8);
return 0;
}
/*
* AES key schedule (decryption)
*/
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx,
const unsigned char *key,
unsigned int keybits)
{
return mbedtls_aes_setkey_enc(ctx, key, keybits);
}
/*
* AES-ECB block encryption/decryption
*/
int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
int mode,
const unsigned char input[16],
unsigned char output[16])
{
sli_se_mailbox_response_t command_status;
if ((mode != MBEDTLS_AES_ENCRYPT) && (mode != MBEDTLS_AES_DECRYPT)) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
if ( ctx->keybits != 128UL && ctx->keybits != 192UL && ctx->keybits != 256UL) {
return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
}
sli_se_mailbox_command_t command = SLI_SE_MAILBOX_COMMAND_DEFAULT((mode == MBEDTLS_AES_ENCRYPT ? SLI_SE_COMMAND_AES_ENCRYPT : SLI_SE_COMMAND_AES_DECRYPT) | SLI_SE_COMMAND_OPTION_MODE_ECB | SLI_SE_COMMAND_OPTION_CONTEXT_WHOLE);
sli_se_datatransfer_t key = SLI_SE_DATATRANSFER_DEFAULT(ctx->key, (ctx->keybits / 8));
sli_se_datatransfer_t in = SLI_SE_DATATRANSFER_DEFAULT((void*)input, 16);
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(output, 16);
sli_se_mailbox_command_add_input(&command, &key);
sli_se_mailbox_command_add_input(&command, &in);
sli_se_mailbox_command_add_output(&command, &out);
sli_se_mailbox_command_add_parameter(&command, (ctx->keybits / 8));
sli_se_mailbox_command_add_parameter(&command, 16);
int status = se_management_acquire();
if (status != 0) {
return status;
}
sli_se_mailbox_execute_command(&command);
command_status = sli_se_mailbox_handle_response();
se_management_release();
if ( command_status == SLI_SE_RESPONSE_OK ) {
return 0;
} else {
return (int)command_status;
}
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* AES-CBC buffer encryption/decryption
*/
int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output)
{
sli_se_mailbox_response_t command_status;
if ((mode != MBEDTLS_AES_ENCRYPT) && (mode != MBEDTLS_AES_DECRYPT)) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
// Input length must be a multiple of 16 bytes which is the AES block
// length.
if ( length & 0xf ) {
return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
}
if ( ctx->keybits != 128UL && ctx->keybits != 192UL && ctx->keybits != 256UL) {
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
sli_se_mailbox_command_t command = SLI_SE_MAILBOX_COMMAND_DEFAULT((mode == MBEDTLS_AES_ENCRYPT ? SLI_SE_COMMAND_AES_ENCRYPT : SLI_SE_COMMAND_AES_DECRYPT) | SLI_SE_COMMAND_OPTION_MODE_CBC | SLI_SE_COMMAND_OPTION_CONTEXT_ADD);
sli_se_datatransfer_t key = SLI_SE_DATATRANSFER_DEFAULT(ctx->key, (ctx->keybits / 8));
sli_se_datatransfer_t iv_in = SLI_SE_DATATRANSFER_DEFAULT(iv, 16);
sli_se_datatransfer_t iv_out = SLI_SE_DATATRANSFER_DEFAULT(iv, 16);
sli_se_datatransfer_t in = SLI_SE_DATATRANSFER_DEFAULT((void*)input, length);
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(output, length);
sli_se_mailbox_command_add_input(&command, &key);
sli_se_mailbox_command_add_input(&command, &iv_in);
sli_se_mailbox_command_add_input(&command, &in);
sli_se_mailbox_command_add_output(&command, &out);
sli_se_mailbox_command_add_output(&command, &iv_out);
sli_se_mailbox_command_add_parameter(&command, (ctx->keybits / 8));
sli_se_mailbox_command_add_parameter(&command, length);
int status = se_management_acquire();
if (status != 0) {
return status;
}
sli_se_mailbox_execute_command(&command);
command_status = sli_se_mailbox_handle_response();
se_management_release();
if ( command_status == SLI_SE_RESPONSE_OK ) {
return 0;
} else {
return (int)command_status;
}
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CIPHER_MODE_CFB)
/*
* AES-CFB128 buffer encryption/decryption
*/
int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
int mode,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output)
{
size_t n = iv_off ? *iv_off : 0;
size_t processed = 0;
sli_se_mailbox_response_t command_status = SLI_SE_RESPONSE_OK;
if ((mode != MBEDTLS_AES_ENCRYPT) && (mode != MBEDTLS_AES_DECRYPT)) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
if ( n > 15 ) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
if ( ctx->keybits != 128UL && ctx->keybits != 192UL && ctx->keybits != 256UL) {
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
while ( processed < length ) {
if ( n > 0 ) {
/* start by filling up the IV */
if ( mode == MBEDTLS_AES_ENCRYPT ) {
iv[n] = output[processed] = (unsigned char)(iv[n] ^ input[processed]);
} else {
int c = input[processed];
output[processed] = (unsigned char)(c ^ iv[n]);
iv[n] = (unsigned char) c;
}
n = (n + 1) & 0x0F;
processed++;
} else {
/* process one ore more blocks of data */
size_t iterations = (length - processed) / 16;
if ( iterations > 0 ) {
sli_se_mailbox_command_t command = SLI_SE_MAILBOX_COMMAND_DEFAULT((mode == MBEDTLS_AES_ENCRYPT ? SLI_SE_COMMAND_AES_ENCRYPT : SLI_SE_COMMAND_AES_DECRYPT) | SLI_SE_COMMAND_OPTION_MODE_CFB | SLI_SE_COMMAND_OPTION_CONTEXT_ADD);
sli_se_datatransfer_t key = SLI_SE_DATATRANSFER_DEFAULT(ctx->key, (ctx->keybits / 8));
sli_se_datatransfer_t iv_in = SLI_SE_DATATRANSFER_DEFAULT(iv, 16);
sli_se_datatransfer_t iv_out = SLI_SE_DATATRANSFER_DEFAULT(iv, 16);
sli_se_datatransfer_t in = SLI_SE_DATATRANSFER_DEFAULT((void*)&input[processed], iterations * 16);
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(&output[processed], iterations * 16);
sli_se_mailbox_command_add_input(&command, &key);
sli_se_mailbox_command_add_input(&command, &iv_in);
sli_se_mailbox_command_add_input(&command, &in);
sli_se_mailbox_command_add_output(&command, &out);
sli_se_mailbox_command_add_output(&command, &iv_out);
sli_se_mailbox_command_add_parameter(&command, (ctx->keybits / 8));
sli_se_mailbox_command_add_parameter(&command, iterations * 16);
int status = se_management_acquire();
if (status != 0) {
return status;
}
sli_se_mailbox_execute_command(&command);
command_status = sli_se_mailbox_handle_response();
se_management_release();
processed += iterations * 16;
}
if ( command_status != SLI_SE_RESPONSE_OK ) {
goto exit;
}
while ( length - processed > 0 ) {
if ( n == 0 ) {
// Need to update the IV but don't have a full block of input to pass to the SE
int status = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
if (status != 0) {
return status;
}
}
/* Save remainder to iv */
if ( mode == MBEDTLS_AES_ENCRYPT ) {
iv[n] = output[processed] = (unsigned char)(iv[n] ^ input[processed]);
} else {
int c = input[processed];
output[processed] = (unsigned char)(c ^ iv[n]);
iv[n] = (unsigned char) c;
}
n = (n + 1) & 0x0F;
processed++;
}
}
}
if ( iv_off ) {
*iv_off = n;
}
exit:
if ( command_status == SLI_SE_RESPONSE_OK ) {
return 0;
} else {
return (int)command_status;
}
}
/*
* AES-CFB8 buffer encryption/decryption
*/
int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
int mode,
size_t length,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output)
{
unsigned char c;
unsigned char ov[17];
int ret = 0;
if ((mode != MBEDTLS_AES_ENCRYPT) && (mode != MBEDTLS_AES_DECRYPT)) {
return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
}
if ( ctx->keybits != 128UL && ctx->keybits != 192UL && ctx->keybits != 256UL) {
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
while ( length-- ) {
memcpy(ov, iv, 16);
if ( (ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv) ) != 0 ) {
return ret;
}
if ( mode == MBEDTLS_AES_DECRYPT ) {
ov[16] = *input;
}
c = *output++ = (unsigned char)(iv[0] ^ *input++);
if ( mode == MBEDTLS_AES_ENCRYPT ) {
ov[16] = c;
}
memcpy(iv, ov + 1, 16);
}
return ret;
}
#endif /*MBEDTLS_CIPHER_MODE_CFB */
#if defined(MBEDTLS_CIPHER_MODE_CTR)
/*
* AES-CTR buffer encryption/decryption
*/
int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
size_t length,
size_t *nc_off,
unsigned char nonce_counter[16],
unsigned char stream_block[16],
const unsigned char *input,
unsigned char *output)
{
size_t n = nc_off ? *nc_off : 0;
size_t processed = 0;
sli_se_mailbox_response_t command_status = SLI_SE_RESPONSE_OK;
if ( ctx->keybits != 128UL && ctx->keybits != 192UL && ctx->keybits != 256UL) {
return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
}
while ( processed < length ) {
if ( n > 0 ) {
/* start by filling up the IV */
output[processed] = (unsigned char)(input[processed] ^ stream_block[n]);
n = (n + 1) & 0x0F;
processed++;
} else {
/* process one or more blocks of data */
size_t iterations = (length - processed) / 16;
if ( iterations > 0 ) {
sli_se_mailbox_command_t command = SLI_SE_MAILBOX_COMMAND_DEFAULT(SLI_SE_COMMAND_AES_ENCRYPT | SLI_SE_COMMAND_OPTION_MODE_CTR | SLI_SE_COMMAND_OPTION_CONTEXT_ADD);
sli_se_datatransfer_t key = SLI_SE_DATATRANSFER_DEFAULT(ctx->key, (ctx->keybits / 8));
sli_se_datatransfer_t iv_in = SLI_SE_DATATRANSFER_DEFAULT(nonce_counter, 16);
sli_se_datatransfer_t iv_out = SLI_SE_DATATRANSFER_DEFAULT(nonce_counter, 16);
sli_se_datatransfer_t in = SLI_SE_DATATRANSFER_DEFAULT((void*)&input[processed], iterations * 16);
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(&output[processed], iterations * 16);
sli_se_mailbox_command_add_input(&command, &key);
sli_se_mailbox_command_add_input(&command, &iv_in);
sli_se_mailbox_command_add_input(&command, &in);
sli_se_mailbox_command_add_output(&command, &out);
sli_se_mailbox_command_add_output(&command, &iv_out);
sli_se_mailbox_command_add_parameter(&command, (ctx->keybits / 8));
sli_se_mailbox_command_add_parameter(&command, iterations * 16);
int status = se_management_acquire();
if (status != 0) {
return status;
}
sli_se_mailbox_execute_command(&command);
command_status = sli_se_mailbox_handle_response();
se_management_release();
processed += iterations * 16;
}
if ( command_status != SLI_SE_RESPONSE_OK ) {
goto exit;
}
while ( length - processed > 0 ) {
if ( n == 0 ) {
// Get a new stream block
int status = mbedtls_aes_crypt_ecb(ctx,
MBEDTLS_AES_ENCRYPT,
nonce_counter,
stream_block);
if (status != 0) {
return status;
}
// increment nonce counter...
for (size_t i = 0; i < 16; i++) {
nonce_counter[15 - i] = nonce_counter[15 - i] + 1;
if ( nonce_counter[15 - i] != 0 ) {
break;
}
}
}
/* Save remainder to iv */
output[processed] = (unsigned char)(input[processed] ^ stream_block[n]);
n = (n + 1) & 0x0F;
processed++;
}
}
}
if ( nc_off ) {
*nc_off = n;
}
exit:
if ( command_status == SLI_SE_RESPONSE_OK ) {
return 0;
} else {
return (int)command_status;
}
}
#endif /* MBEDTLS_CIPHER_MODE_CTR */
#if defined(MBEDTLS_CIPHER_MODE_OFB)
/*
* AES-OFB (Output Feedback Mode) buffer encryption/decryption
*/
int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
size_t length,
size_t *iv_off,
unsigned char iv[16],
const unsigned char *input,
unsigned char *output)
{
int ret = 0;
size_t n;
n = *iv_off;
if ( n > 15 ) {
return(MBEDTLS_ERR_AES_BAD_INPUT_DATA);
}
while ( length-- ) {
if ( n == 0 ) {
ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
if ( ret != 0 ) {
goto exit;
}
}
*output++ = *input++ ^ iv[n];
n = (n + 1) & 0x0F;
}
*iv_off = n;
exit:
return(ret);
}
#endif /* MBEDTLS_CIPHER_MODE_OFB */
#endif /* SEMAILBOX_PRESENT */
#endif /* MBEDTLS_AES_ALT */
#endif /* MBEDTLS_AES_C */

View File

@@ -0,0 +1,197 @@
/***************************************************************************//**
* @file
* @brief Entropy driver for Silicon Labs devices.
*******************************************************************************
* # 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.
*
******************************************************************************/
// -------------------------------------
// Includes
#include <mbedtls/build_info.h>
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
#include "entropy_poll.h"
#include "psa/crypto.h"
#include "em_device.h"
#if defined(MBEDTLS_TRNG_PRESENT) \
|| defined(SEMAILBOX_PRESENT) \
|| defined(CRYPTOACC_PRESENT)
#define SLI_ENTROPY_HAVE_TRNG
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
/* If PSA is not configured with external RNG, do a forward declaration of the
* external RNG function here to allow us to call it for entropy as well. */
psa_status_t mbedtls_psa_external_get_random(
void *context,
uint8_t *output, size_t output_size, size_t *output_length);
#endif
#endif
#if !defined(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED)
/* Repeat declaration of MBEDTLS_ERR_ENTROPY_SOURCE_FAILED since the full entropy.h
* header is not always a clean include. I.e. when mbedtls_hardware_poll is used
* without having the full entropy module (with collector) present, the header will
* potentially complain about missing a SHA256/SHA512 context structure definition. */
#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C
#endif
/* For devices with an active TRNG errata, we need to rely on a different
* source of entropy. */
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) \
|| defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95)
#define SLI_ENTROPY_REQUIRE_FALLBACK
#endif
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
#include "em_system.h" // SYSTEM_ChipRevisionGet()
#endif
// -------------------------------------
// Local function definitions
// Include radio entropy fallback if present & required
#if defined(MBEDTLS_ENTROPY_RAIL_PRESENT) \
&& (!defined(SLI_ENTROPY_HAVE_TRNG) || defined(SLI_ENTROPY_REQUIRE_FALLBACK))
#include "rail.h"
static int rail_get_random(unsigned char *output,
size_t len,
size_t *out_len)
{
uint16_t rail_entropy_request_len;
if (len > UINT16_MAX) {
rail_entropy_request_len = UINT16_MAX;
} else {
rail_entropy_request_len = (uint16_t)len;
}
*out_len = (size_t)RAIL_GetRadioEntropy(RAIL_EFR32_HANDLE,
(uint8_t *)output,
rail_entropy_request_len);
return 0;
}
#endif // radio fallback
#if defined(MBEDTLS_ENTROPY_ADC_C) \
&& (!defined(SLI_ENTROPY_HAVE_TRNG) || defined(SLI_ENTROPY_REQUIRE_FALLBACK))
#if !defined(MBEDTLS_ENTROPY_ADC_INSTANCE)
#define MBEDTLS_ENTROPY_ADC_INSTANCE 0
#endif
#include "sl_entropy_adc.h"
static int adc_get_random(unsigned char *output,
size_t len,
size_t *out_len)
{
mbedtls_entropy_adc_context adc_ctx;
int ret = -1;
mbedtls_entropy_adc_init(&adc_ctx);
ret = mbedtls_entropy_adc_set_instance(&adc_ctx, MBEDTLS_ENTROPY_ADC_INSTANCE);
if (ret < 0) {
goto exit;
}
ret = mbedtls_entropy_adc_poll(&adc_ctx, output, len, out_len);
exit:
mbedtls_entropy_adc_free(&adc_ctx);
return ret;
}
#endif // ADC fallback
#if (defined(MBEDTLS_ENTROPY_RAIL_PRESENT) || defined(MBEDTLS_ENTROPY_ADC_C)) \
&& (!defined(SLI_ENTROPY_HAVE_TRNG) || defined(SLI_ENTROPY_REQUIRE_FALLBACK))
static int rail_adc_entropy(unsigned char *output,
size_t len,
size_t *olen)
{
(void) output;
(void) len;
(void) olen;
*olen = 0;
int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
#if defined(MBEDTLS_ENTROPY_RAIL_PRESENT)
ret = rail_get_random(output, len, olen);
if (*olen > 0 && ret == 0) {
// Return if we actually gathered something
// Otherwise, fallback to the ADC source if it is available.
return ret;
}
#endif // MBEDTLS_ENTROPY_RAIL_PRESENT
#if defined(MBEDTLS_ENTROPY_ADC_C)
ret = adc_get_random(output, len, olen);
#endif // MBEDTLS_ENTROPY_ADC_C
return ret;
}
#endif // RAIL and ADC entropy
// -------------------------------------
// Global function definitions
int mbedtls_hardware_poll(void *data,
unsigned char *output,
size_t len,
size_t *olen)
{
(void)data;
#if defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
// TRNG entropy on EFR32xG13 is under errata on revisions < A3
SYSTEM_ChipRevision_TypeDef rev;
SYSTEM_ChipRevisionGet(&rev);
if ((rev.major == 1) && (rev.minor < 3)) {
// On affected revisions, fall back to radio (prefered) or ADC entropy
return rail_adc_entropy(output, len, olen);
}
#elif defined(SLI_ENTROPY_REQUIRE_FALLBACK)
// Other devices for which this symbol is defined have TRNG erratas requiring
// fallback to other sources for all revisions.
return rail_adc_entropy(output, len, olen);
#endif
#if !defined(SLI_ENTROPY_REQUIRE_FALLBACK) \
|| defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89)
// Devices not requiring fallback (or fell through here because the active
// errata does not apply to the ICs revision) use a TRNG when available, but
// can also use the radio or ADC when no TRNG is present.
#if defined(SLI_ENTROPY_HAVE_TRNG)
psa_status_t status = mbedtls_psa_external_get_random(data, output, len, olen);
if (status == PSA_SUCCESS) {
return 0;
} else {
return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
}
#else // SLI_ENTROPY_HAVE_TRNG
return rail_adc_entropy(output, len, olen);
#endif // SLI_ENTROPY_HAVE_TRNG
#endif
}
#endif // MBEDTLS_ENTROPY_HARDWARE_ALT

View File

@@ -0,0 +1,121 @@
/***************************************************************************//**
* @file
* @brief Initialize the Silicon Labs platform integration of mbedTLS.
*******************************************************************************
* # 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_mbedtls.h"
#include "sl_assert.h"
#include "mbedtls/build_info.h"
#if !defined(SL_TRUSTZONE_NONSECURE)
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
#include "sl_se_manager.h"
#endif
#if defined(CRYPTOACC_PRESENT) && (_SILICON_LABS_32B_SERIES_2_CONFIG > 2)
#include "cryptoacc_management.h"
#endif
#endif // #if !defined(SL_TRUSTZONE_NONSECURE)
#if defined(MBEDTLS_THREADING_ALT) && defined(MBEDTLS_THREADING_C)
#include "mbedtls/threading.h"
#if defined(MBEDTLS_PSA_CRYPTO_C)
#include "cmsis_os2.h"
#include <stdbool.h>
static volatile bool mbedtls_psa_slots_mutex_inited = false;
/**
* \brief Lock all task switches
*
* \return Previous lock state
*
*/
static inline int32_t lock_task_switches(void)
{
int32_t kernel_lock_state = 0;
osKernelState_t kernel_state = osKernelGetState();
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
kernel_lock_state = osKernelLock();
}
return kernel_lock_state;
}
/**
* \brief Restores the previous lock state
*/
static inline void restore_lock_state(int32_t kernel_lock_state)
{
osKernelState_t kernel_state = osKernelGetState();
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
if (osKernelRestoreLock(kernel_lock_state) < 0) {
EFM_ASSERT(false);
}
}
}
#endif // defined(MBEDTLS_PSA_CRYPTO_C)
#endif // defined(MBEDTLS_THREADING_ALT) && defined(MBEDTLS_THREADING_C)
void sl_mbedtls_init(void)
{
#if !defined(SL_TRUSTZONE_NONSECURE)
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
/* Initialize the SE Manager including the SE lock.
No need for critical region here since sl_se_init implements one. */
sl_status_t ret;
ret = sl_se_init();
EFM_ASSERT(ret == SL_STATUS_OK);
#endif
#if defined(CRYPTOACC_PRESENT) && (_SILICON_LABS_32B_SERIES_2_CONFIG > 2)
// Set up SCA countermeasures in hardware
cryptoacc_initialize_countermeasures();
#endif // SILICON_LABS_32B_SERIES_2_CONFIG > 2
#endif // #if !defined(SL_TRUSTZONE_NONSECURE)
#if defined(MBEDTLS_THREADING_ALT) && defined(MBEDTLS_THREADING_C)
mbedtls_threading_set_alt(&THREADING_InitMutex,
&THREADING_FreeMutex,
&THREADING_TakeMutexBlocking,
&THREADING_GiveMutex);
#if defined(MBEDTLS_PSA_CRYPTO_C)
// Initialize mutex for PSA slot access in psa_crypto_slot_management.c
if (!mbedtls_psa_slots_mutex_inited) {
int32_t kernel_lock_state = lock_task_switches();
if (!mbedtls_psa_slots_mutex_inited) {
mbedtls_mutex_init(&mbedtls_threading_key_slot_mutex);
mbedtls_psa_slots_mutex_inited = true;
}
restore_lock_state(kernel_lock_state);
}
#endif // #if defined(MBEDTLS_PSA_CRYPTO_C)
#if defined(MBEDTLS_THREADING_TEST)
mbedtls_test_thread_set_alt(&THREADING_ThreadCreate,
&THREADING_ThreadJoin);
#endif //MBEDTLS_THREADING_TEST
#endif // #if defined(MBEDTLS_THREADING_ALT) && defined(MBEDTLS_THREADING_C)
}

View File

@@ -0,0 +1,77 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto utility functions.
*******************************************************************************
* # 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.
*
******************************************************************************/
#include "sl_psa_crypto.h"
#include "sli_psa_driver_features.h"
// -----------------------------------------------------------------------------
// Global functions
void sl_psa_set_key_lifetime_with_location_preference(
psa_key_attributes_t *attributes,
psa_key_persistence_t persistence,
psa_key_location_t preferred_location)
{
psa_key_location_t selected_location = PSA_KEY_LOCATION_LOCAL_STORAGE;
switch (preferred_location) {
// The underlying values for wrapped and built-in keys are the same. In
// order to avoid compiler errors, we therefore use #elif in order to make
// sure that we do not get identical switch labels.
#if defined(SLI_PSA_DRIVER_FEATURE_WRAPPED_KEYS)
case SL_PSA_KEY_LOCATION_WRAPPED:
selected_location = SL_PSA_KEY_LOCATION_WRAPPED;
break;
#elif defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS)
case SL_PSA_KEY_LOCATION_BUILTIN:
selected_location = SL_PSA_KEY_LOCATION_BUILTIN;
break;
#endif
default:
// Use the already set PSA_KEY_LOCATION_LOCAL_STORAGE.
break;
}
psa_key_lifetime_t lifetime =
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence,
selected_location);
psa_set_key_lifetime(attributes, lifetime);
}
psa_key_location_t sl_psa_get_most_secure_key_location(void)
{
#if defined(SLI_PSA_DRIVER_FEATURE_WRAPPED_KEYS)
return SL_PSA_KEY_LOCATION_WRAPPED;
#else
return PSA_KEY_LOCATION_LOCAL_STORAGE;
#endif
}

View File

@@ -0,0 +1,117 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs internal PSA Crypto utility functions.
*******************************************************************************
* # License
* <b>Copyright 2022 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_psa_crypto.h"
#include "psa/crypto.h"
#include "mbedtls/aes.h"
#include "mbedtls/ccm.h"
#include "mbedtls/cipher.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/entropy.h"
#include "mbedtls/md.h"
#include "mbedtls/nist_kw.h"
#include "mbedtls/pk.h"
#include "mbedtls/sha1.h"
#include "mbedtls/sha256.h"
#include "mbedtls/ssl.h"
#include "mbedtls/ssl_cookie.h"
#include "mbedtls/x509_crt.h"
// -----------------------------------------------------------------------------
// Public function definitions
size_t sli_psa_context_get_size(sli_psa_context_name_t ctx_type)
{
switch (ctx_type) {
case SLI_PSA_CONTEXT_ENUM_NAME(psa_hash_operation_t):
return sizeof(psa_hash_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_cipher_operation_t):
return sizeof(psa_cipher_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_mac_operation_t):
return sizeof(psa_mac_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_aead_operation_t):
return sizeof(psa_aead_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_key_derivation_operation_t):
return sizeof(psa_key_derivation_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_pake_operation_t):
return sizeof(psa_pake_operation_t);
case SLI_PSA_CONTEXT_ENUM_NAME(psa_key_attributes_t):
return sizeof(psa_key_attributes_t);
default:
return 0;
}
}
size_t sli_mbedtls_context_get_size(sli_mbedtls_context_name_t ctx_type)
{
switch (ctx_type) {
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_aes_context):
return sizeof(mbedtls_aes_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ccm_context):
return sizeof(mbedtls_ccm_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_cipher_context_t):
return sizeof(mbedtls_cipher_context_t);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ctr_drbg_context):
return sizeof(mbedtls_ctr_drbg_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_entropy_context):
return sizeof(mbedtls_entropy_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_md_context_t):
return sizeof(mbedtls_md_context_t);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_nist_kw_context):
return sizeof(mbedtls_nist_kw_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_pk_context):
return sizeof(mbedtls_pk_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_sha1_context):
return sizeof(mbedtls_sha1_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_sha256_context):
return sizeof(mbedtls_sha256_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_config):
return sizeof(mbedtls_ssl_config);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_context):
return sizeof(mbedtls_ssl_context);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_ssl_cookie_ctx):
return sizeof(mbedtls_ssl_cookie_ctx);
case SLI_MBEDTLS_CONTEXT_ENUM_NAME(mbedtls_x509_crt):
return sizeof(mbedtls_x509_crt);
default:
return 0;
}
}
bool sli_psa_key_is_unconditionally_copyable(psa_key_id_t key_id)
{
bool is_persistent_zigbee_key = key_id >= SLI_PSA_KEY_ID_RANGE_ZIGBEE_START
&& key_id <= SLI_PSA_KEY_ID_RANGE_ZIGBEE_END;
bool is_persistent_thread_key = key_id >= SLI_PSA_KEY_ID_RANGE_THREAD_START
&& key_id <= SLI_PSA_KEY_ID_RANGE_THREAD_END;
return (is_persistent_zigbee_key || is_persistent_thread_key);
}

View File

@@ -0,0 +1,221 @@
/***************************************************************************//**
* @file
* @brief Accelerated cryptographic primitives using the CRYPTO and RADIOAES
* peripherals, for series-1 and series-2 respectively.
*******************************************************************************
* # 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 SLI_PROTOCOL_CRYPTO_H
#define SLI_PROTOCOL_CRYPTO_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* @addtogroup sli_protocol_crypto
* @brief Accelerated cryptographic primitives using the CRYPTO and RADIOAES
* peripherals, for series-1 and series-2 respectively.
* @{
******************************************************************************/
#include "sl_status.h"
#include "sl_code_classification.h"
#include "em_device.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @brief Initialise Silabs internal protocol crypto library
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
sl_status_t sli_protocol_crypto_init(void);
/***************************************************************************//**
* @brief AES-CTR block encryption/decryption optimized for radio
*
* @param key AES key
* @param keybits must be 128 or 256
* @param input 16-byte input block
* @param iv_in 16-byte counter/IV starting value
* @param iv_out 16-byte counter/IV output after block round
* @param output 16-byte output block
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_aes_crypt_ctr_radio(const unsigned char *key,
unsigned int keybits,
const unsigned char input[16],
const unsigned char iv_in[16],
volatile unsigned char iv_out[16],
volatile unsigned char output[16]);
/***************************************************************************//**
* @brief AES-ECB block encryption/decryption optimized for radio
*
* @param encrypt true for encryption, false for decryption
* @param key AES key
* @param keybits must be 128 or 256
* @param input 16-byte input block
* @param output 16-byte output block
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_aes_crypt_ecb_radio(bool encrypt,
const unsigned char *key,
unsigned int keybits,
const unsigned char input[16],
volatile unsigned char output[16]);
#if defined(RADIOAES_PRESENT)
/***************************************************************************//**
* @brief AES-CMAC calculation optimized for radio
*
* @param key AES key
* @param keybits Must be 128 or 256
* @param input Input buffer containing the message to be signed
* @param length Amount of bytes in the input buffer
* @param output 16-byte output block for calculated CMAC
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_aes_cmac_radio(const unsigned char *key,
unsigned int keybits,
const unsigned char *input,
unsigned int length,
volatile unsigned char output[16]);
/***************************************************************************//**
* @brief Seeds the AES mask. It is recommended to call this function
during initialization in order to avoid taking the potential
hit of requesting RNG output in an IRQ context.
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
void sli_aes_seed_mask(void);
#endif
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for BLE
*
* @param data Input/output buffer of payload data of BLE packet
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param header header of BLE packet (1 byte)
* @param tag authentication tag of BLE packet (4 bytes)
*
* @return SL_STATUS_OK if successful and authenticated,
* SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
* relevant status code on other error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_ccm_auth_decrypt_ble(unsigned char *data,
size_t length,
const unsigned char *key,
const unsigned char *iv,
unsigned char header,
unsigned char *tag);
/***************************************************************************//**
* @brief CCM buffer encryption optimized for BLE
*
* @param data Input/output buffer of payload data of BLE packet
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param header header of BLE packet (1 byte)
* @param tag buffer where the BLE packet tag (4 bytes) will be written
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_ccm_encrypt_and_tag_ble(unsigned char *data,
size_t length,
const unsigned char *key,
const unsigned char *iv,
unsigned char header,
unsigned char *tag);
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for Zigbee
*
* @param data Input/output buffer of payload data (decrypt-in-place)
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param aad Input buffer of Additional Authenticated Data
* @param aad_len Length of buffer @p aad
* @param tag authentication tag
* @param tag_len Length of authentication tag
*
* @return SL_STATUS_OK if successful and authenticated,
* SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
* relevant status code on other error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_ccm_zigbee(bool encrypt,
const unsigned char *data_in,
unsigned char *data_out,
size_t length,
const unsigned char *key,
const unsigned char *iv,
const unsigned char *aad,
size_t aad_len,
unsigned char *tag,
size_t tag_len);
/***************************************************************************//**
* @brief Process a table of BLE RPA device keys and look for a
* match against the supplied hash
*
* @param keytable Pointer to an array of AES-128 keys, corresponding to the
* per-device key in the BLE RPA process
* @param keymask Bitmask indicating with key indices in keytable are valid
* @param prand 24-bit BLE nonce to encrypt with each key and match against hash
* @param hash BLE RPA hash to match against (last 24 bits of AES result)
*
* @return 0-based index of matching key if a match is found, -1 for no match.
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
int sli_process_ble_rpa(const unsigned char keytable[],
uint32_t keymask,
uint32_t prand,
uint32_t hash);
#ifdef __cplusplus
}
#endif
/// @} (end addtogroup sli_protocol_crypto)
/// @endcond
#endif // SLI_PROTOCOL_CRYPTO_H

View File

@@ -0,0 +1,868 @@
/***************************************************************************//**
* @file
* @brief Accelerated cryptographic primitives using the RADIOAES peripheral.
*******************************************************************************
* # 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 "em_device.h"
#if defined(RADIOAES_PRESENT)
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include "sli_radioaes_management.h"
#include "sli_protocol_crypto.h"
#include "sl_code_classification.h"
#include "em_core.h"
#define AES_BLOCK_BYTES 16U
#define AES_128_KEY_BYTES 16U
#define AES_256_KEY_BYTES 32U
#define RADIOAES_CONFIG_BYTES 4U
#ifndef RADIOAES_BLE_RPA_MAX_KEYS
#define RADIOAES_BLE_RPA_MAX_KEYS 32
#endif
/// value for sli_radioaes_dma_sg_descr.tag to direct data to parameters
#define DMA_SG_TAG_ISCONFIG 0x00000010
/// value for sli_radioaes_dma_sg_descr.tag to direct data to processing
#define DMA_SG_TAG_ISDATA 0x00000000
/// value for sli_radioaes_dma_sg_descr.tag specifying data as last
#define DMA_SG_TAG_ISLAST 0x00000020
/// macro to set the offset in the configuration for sli_radioaes_dma_sg_descr.tag
#define DMA_SG_TAG_SETCFGOFFSET(a) ((((a) & 0xFF) << 8))
/// value for sli_radioaes_dma_sg_descr.tag specifying data type payload (will be encrypted/decrypted and authenticated)
#define DMA_SG_TAG_DATATYPE_AESPAYLOAD 0x00000000
/// value for sli_radioaes_dma_sg_descr.tag specifying data type header (will only be authenticated, not encrypted/decrypted)
#define DMA_SG_TAG_DATATYPE_AESHEADER 0x00000040
/// macro to set the amount of invalid bytes in for sli_radioaes_dma_sg_descr.tag
#define DMA_SG_TAG_SETINVALIDBYTES(a) ((((a) & 0x1F) << 8))
#define DMA_AXI_DESCR_CONST_ADDR 0x10000000
#define DMA_AXI_DESCR_REALIGN 0x20000000
#define DMA_AXI_DESCR_DISCARD 0x40000000
#define DMA_AXI_DESCR_INT_ENABLE 0x80000000
#define DMA_AXI_DESCR_INT_DISABLE 0x00000000
#define DMA_AXI_DESCR_NEXT_STOP 0x00000001
#define DMA_AXI_DESCR_NEXT_CONTINUE 0x00000000
#define DMA_AXI_DESCR_MASK_NEXT_ADD 0xFFFFFFFC
/// value of flags to discard the data
#define BLOCK_S_DISCARD_DATA 0x40000000
/// value of flags to realign the data
#define BLOCK_S_REALIGN_DATA 0x20000000
/// value of flags to set addressing in constant mode (pointing to a FIFO)
#define BLOCK_S_CONST_ADDR 0x10000000
/// value of flags to set addressing in increment mode (pointing to a buffer)
#define BLOCK_S_INCR_ADDR 0x00000000
/// mask for flags to only get DMA-related options
#define BLOCK_S_FLAG_MASK_DMA_PROPS 0x70000000
/// value of flags mask for fetcher location destination
#define BLOCK_S_MASK_LOC_DEST 0x00FFFFFF
/// Config ///
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_CFG 0
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_KEY 8
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_IV 40
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_IV2 56
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_KEY2 72
/// BA411E offset for Configuration word in DMA Scatter-Gather Tag
#define AES_OFFSET_MASK 104
/// BA411E Mode Register value for ECB mode of operation
#define AES_MODEID_ECB 0x00000100
/// BA411E Mode Register value for CBC mode of operation
#define AES_MODEID_CBC 0x00000200
/// BA411E Mode Register value for CTR mode of operation
#define AES_MODEID_CTR 0x00000400
/// BA411E Mode Register value for CCM mode of operation
#define AES_MODEID_CCM 0x00002000
/// BA411E Mode Register value for CMAC mode of operation
#define AES_MODEID_CMA 0x00010000
/// BA411E Mode Register value for AES context saving
#define AES_MODEID_CX_SAVE 0x00000020
/// BA411E Mode Register value for AES context loading
#define AES_MODEID_CX_LOAD 0x00000010
/// BA411E Mode Register value for AES no context
#define AES_MODEID_NO_CX 0x00000000
/// BA411E Mode Register value for AES keysize of 128 bits
#define AES_MODEID_AES128 0x00000000
/// BA411E Mode Register value for AES keysize of 256 bits
#define AES_MODEID_AES256 0x00000004
/// BA411E Mode Register value for AES keysize of 192 bits
#define AES_MODEID_AES192 0x00000008
/// BA411E Mode Register value for encryption mode
#define AES_MODEID_ENCRYPT 0x00000000
/// BA411E Mode Register value for decryption mode
#define AES_MODEID_DECRYPT 0x00000001
/// BA411E Size for IV in GCM mode
#define AES_IV_GCM_SIZE 12
/// BA411E Size for IV in all modes except GCM
#define AES_IV_SIZE 16
/// BA411E Size for Context in GCM and CCM modes
#define AES_CTX_xCM_SIZE 32
/// BA411E Size for Context in all modes except GCM and CCM
#define AES_CTX_SIZE 16
///
/// @brief Select which IP core the DMA will use. To set in descriptor sli_radioaes_dma_sg_descr.tag.
///
typedef enum {
DMA_SG_ENGINESELECT_BYPASS = 0x00, ///< direct bypass from input to output
DMA_SG_ENGINESELECT_BA411E = 0x01, ///< data flow through BA411E AES
DMA_SG_ENGINESELECT_BA412 = 0x02, ///< data flow through BA412 DES
DMA_SG_ENGINESELECT_BA413 = 0x03, ///< data flow through BA413 Hash
DMA_SG_ENGINESELECT_BA417 = 0x04 ///< data flow through BA417 ChaChaPoly
} dma_engine_select_t;
///
/// @brief Structure that represent a descriptor for the DMA module
/// (in scatter-gather mode).
///
typedef struct {
volatile uint32_t address;
volatile uint32_t nextDescr;
volatile uint32_t lengthAndIrq;
volatile uint32_t tag;
} sli_radioaes_dma_descr_t;
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
#define SLI_RADIOAES_MASK_DESCRIPTOR(next_descr_addr) \
{ \
.address = (uint32_t) &sli_radioaes_mask, \
.nextDescr = next_descr_addr, \
.lengthAndIrq = 0x20000004UL, \
.tag = 0x00006811UL \
};
#endif
#define DMA_AXI_DESCR_END_POINTER ((sli_radioaes_dma_descr_t*) DMA_AXI_DESCR_NEXT_STOP)
// Local CCM variables
static const uint32_t aes_ccm_config_encrypt = AES_MODEID_CCM
| AES_MODEID_NO_CX
| AES_MODEID_AES128
| AES_MODEID_ENCRYPT;
static const uint32_t aes_ccm_config_decrypt = AES_MODEID_CCM
| AES_MODEID_NO_CX
| AES_MODEID_AES128
| AES_MODEID_DECRYPT;
static const uint32_t zeros = 0;
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
static sl_status_t sli_radioaes_run_operation(sli_radioaes_dma_descr_t *first_fetch_descriptor,
sli_radioaes_dma_descr_t *first_push_descriptor)
{
sli_radioaes_state_t aes_ctx;
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
sli_radioaes_dma_descr_t mask_descr = SLI_RADIOAES_MASK_DESCRIPTOR((uint32_t)first_fetch_descriptor);
#endif
sl_status_t status = sli_radioaes_acquire();
if (status == SL_STATUS_ISR) {
sli_radioaes_save_state(&aes_ctx);
} else if (status != SL_STATUS_OK) {
return status;
}
RADIOAES->CTRL = AES_CTRL_FETCHERSCATTERGATHER | AES_CTRL_PUSHERSCATTERGATHER;
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
RADIOAES->FETCHADDR = (uint32_t) &mask_descr;
#else
RADIOAES->FETCHADDR = (uint32_t) first_fetch_descriptor;
#endif
RADIOAES->PUSHADDR = (uint32_t) first_push_descriptor;
RADIOAES->CMD = AES_CMD_STARTPUSHER | AES_CMD_STARTFETCHER;
while (RADIOAES->STATUS & (AES_STATUS_FETCHERBSY | AES_STATUS_PUSHERBSY)) {
// Wait for completion
}
if (status == SL_STATUS_ISR) {
sli_radioaes_restore_state(&aes_ctx);
}
return sli_radioaes_release();
}
// CCM (and CCM-star) implementation
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
static sl_status_t aes_ccm_radio(bool encrypt,
const unsigned char *add_data,
size_t add_length,
const unsigned char *data_in,
unsigned char *data_out,
size_t length,
const unsigned char *key,
const unsigned char *header,
size_t header_length,
unsigned char *tag,
size_t tag_length)
{
// Assumptions:
// * There is always header input, but the header input may be block-aligned (BLE-CCM)
// * There may not always be ADD input (e.g. BLE-CCM)
// * There may not always be data input (e.g. CCM in authenticated-only mode)
// * The header input is pre-calculated by the caller of this function
// * Data output may be NULL (in which case it is discarded)
// * Tag length may be 0 (CCM-star), in which case the tag pointer is also allowed to be NULL
// Setup ver_failed output buffer and initialize it in case of decryption to an invalid value
volatile uint8_t ver_failed[AES_BLOCK_BYTES] = {[0 ... AES_BLOCK_BYTES - 1] = 0xFF };
// Calculate padding bytes. Since the accelerator expects to see the AESPAYLOAD data type
// at least once during the operation, ensure that we're emitting a padding block in case
// no input data is present.
size_t header_pad_bytes = (AES_BLOCK_BYTES - ((header_length + add_length) % AES_BLOCK_BYTES)) % AES_BLOCK_BYTES;
size_t data_pad_bytes = (length > 0 ? (AES_BLOCK_BYTES - (length % AES_BLOCK_BYTES)) % AES_BLOCK_BYTES : 16);
// Fetchers
// Tag output. If used, always the last descriptor. Not used for CCM-* without tag, the
// accelerator actually looks at the header and figures out whether or not to take in
// tag input.
sli_radioaes_dma_descr_t ccm_desc_fetcher_tag = {
.address = (uint32_t) tag,
.nextDescr = (uint32_t) DMA_AXI_DESCR_END_POINTER,
.lengthAndIrq = (uint32_t) tag_length
| BLOCK_S_INCR_ADDR
| BLOCK_S_REALIGN_DATA,
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISDATA
| DMA_SG_TAG_ISLAST
| DMA_SG_TAG_DATATYPE_AESPAYLOAD
| DMA_SG_TAG_SETINVALIDBYTES(AES_BLOCK_BYTES - tag_length)
};
// Data input. Can be zero-length, in which case we'll issue a bogus descriptor instead.
sli_radioaes_dma_descr_t ccm_desc_fetcher_data = {
.address = (uint32_t) (length > 0 ? data_in : ver_failed),
.nextDescr = (uint32_t) ((encrypt || tag_length == 0) ? DMA_AXI_DESCR_END_POINTER : &ccm_desc_fetcher_tag),
.lengthAndIrq = (uint32_t) (length > 0 ? length : data_pad_bytes)
| BLOCK_S_INCR_ADDR
| BLOCK_S_REALIGN_DATA,
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISDATA
| DMA_SG_TAG_DATATYPE_AESPAYLOAD
| ((encrypt || tag_length == 0) ? DMA_SG_TAG_ISLAST : 0)
| DMA_SG_TAG_SETINVALIDBYTES(data_pad_bytes),
};
// Possible CCM AAD block (concatenated with the header). Can be zero-length, in which case
// this descriptor should not be referenced but rather bypassed to data.
sli_radioaes_dma_descr_t ccm_desc_fetcher_add = {
.address = (uint32_t) add_data,
.nextDescr = (uint32_t) &ccm_desc_fetcher_data,
.lengthAndIrq = (uint32_t) add_length
| BLOCK_S_INCR_ADDR
| BLOCK_S_REALIGN_DATA,
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISDATA
| DMA_SG_TAG_DATATYPE_AESHEADER
| DMA_SG_TAG_SETINVALIDBYTES(header_pad_bytes)
};
// Header input block. Always present.
sli_radioaes_dma_descr_t ccm_desc_fetcher_header = {
.address = (uint32_t) header,
.nextDescr = (uint32_t) (add_length > 0 ? &ccm_desc_fetcher_add : &ccm_desc_fetcher_data),
.lengthAndIrq = (uint32_t) header_length
| BLOCK_S_INCR_ADDR
| (add_length > 0 ? 0 : BLOCK_S_REALIGN_DATA),
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISDATA
| DMA_SG_TAG_DATATYPE_AESHEADER
| (add_length > 0 ? 0 : DMA_SG_TAG_SETINVALIDBYTES(header_pad_bytes))
};
// Key input block. Always present.
sli_radioaes_dma_descr_t ccm_desc_fetcher_key = {
.address = (uint32_t) key,
.nextDescr = (uint32_t) &ccm_desc_fetcher_header,
.lengthAndIrq = (uint32_t) AES_128_KEY_BYTES
| BLOCK_S_INCR_ADDR
| BLOCK_S_REALIGN_DATA,
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISCONFIG
| DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_KEY)
};
// Operation configuration word block. Always present.
sli_radioaes_dma_descr_t ccm_desc_fetcher_config = {
.address = (uint32_t) (encrypt ? &aes_ccm_config_encrypt : &aes_ccm_config_decrypt),
.nextDescr = (uint32_t) &ccm_desc_fetcher_key,
.lengthAndIrq = (uint32_t) RADIOAES_CONFIG_BYTES
| BLOCK_S_INCR_ADDR
| BLOCK_S_REALIGN_DATA,
.tag = DMA_SG_ENGINESELECT_BA411E
| DMA_SG_TAG_ISCONFIG
| DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_CFG)
};
// Pushers
// Tag / verification output padding, only if 0 < tag length < 16 bytes.
sli_radioaes_dma_descr_t ccm_desc_pusher_final_padding = {
.address = (uint32_t) NULL,
.nextDescr = (uint32_t) DMA_AXI_DESCR_END_POINTER,
.lengthAndIrq = (uint32_t) (AES_BLOCK_BYTES - tag_length)
| DMA_AXI_DESCR_DISCARD
};
// Tag output. Direct into tag buffer for encrypt, into local buffer for
// decrypt-and-verify. This descriptor is not referenced with tag_length == 0 (CCM-*)
sli_radioaes_dma_descr_t ccm_desc_pusher_tag = {
.address = (uint32_t) (encrypt ? tag : (unsigned char *)ver_failed),
.nextDescr = (uint32_t) ((AES_BLOCK_BYTES - tag_length) > 0 ? &ccm_desc_pusher_final_padding : DMA_AXI_DESCR_END_POINTER),
.lengthAndIrq = (uint32_t) tag_length
};
// Data padding output. There's guaranteed always at least one of data or data padding.
sli_radioaes_dma_descr_t ccm_desc_pusher_data_padding = {
.address = (uint32_t) NULL,
.nextDescr = (uint32_t) (tag_length > 0 ? &ccm_desc_pusher_tag : DMA_AXI_DESCR_END_POINTER),
.lengthAndIrq = (uint32_t) data_pad_bytes
| DMA_AXI_DESCR_DISCARD,
};
// Data (ciphertext/plaintext) output. Pointer can be NULL, in which case we tell the
// DMA to discard the data.
sli_radioaes_dma_descr_t ccm_desc_pusher_data = {
.address = (uint32_t) data_out,
.nextDescr = (uint32_t) (data_pad_bytes > 0 ? &ccm_desc_pusher_data_padding : (tag_length > 0 ? &ccm_desc_pusher_tag : DMA_AXI_DESCR_END_POINTER)),
.lengthAndIrq = (uint32_t) length
| (data_out == NULL ? DMA_AXI_DESCR_DISCARD : 0),
};
// Discard all AAD input (which is reflected back to the output). There's guaranteed always a header.
sli_radioaes_dma_descr_t ccm_desc_pusher_header_add = {
.address = (uint32_t) NULL,
.nextDescr = (uint32_t) (length > 0 ? &ccm_desc_pusher_data : &ccm_desc_pusher_data_padding),
.lengthAndIrq = (uint32_t) (header_length + add_length + header_pad_bytes)
| DMA_AXI_DESCR_DISCARD
};
sl_status_t status = sli_radioaes_run_operation(&ccm_desc_fetcher_config, &ccm_desc_pusher_header_add);
if (status != SL_STATUS_OK) {
return status;
}
// Check MIC
if (!encrypt) {
uint32_t accumulator = 0;
for (size_t i = 0; i < tag_length; i++) {
accumulator |= ver_failed[i];
}
if (accumulator != 0) {
return SL_STATUS_INVALID_SIGNATURE;
}
}
return SL_STATUS_OK;
}
// Perform a CCM encrypt/decrypt operation with BLE parameters and input.
// This means:
// * 13 bytes IV
// * 1 byte AAD (parameter 'header')
// * AES-128 key (16 byte key)
// * in-place encrypt/decrypt with variable length plain/ciphertext
// (up to 64 kB, uint16 overflow)
// * 4 byte tag
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
static sl_status_t aes_ccm_ble(bool encrypt,
unsigned char *data,
size_t length,
const unsigned char *key,
const unsigned char *iv,
unsigned char header,
unsigned char *tag)
{
uint8_t b0b1[19];
// Fill in B0 block according to BLE spec
b0b1[0] = 0x49U;
// Copy in the 13 bytes of nonce
for (size_t i = 0; i < 13; i++) {
b0b1[i + 1] = iv[i];
}
b0b1[14] = (uint8_t) length >> 8;
b0b1[15] = (uint8_t) length;
b0b1[16] = 0; // upper octet of AAD length
b0b1[17] = 1; // lower octet of AAD length (BLE CCM always has only one byte of AAD)
b0b1[18] = header; // AAD
return aes_ccm_radio(encrypt,
NULL, 0,
data, data, length,
key,
b0b1, sizeof(b0b1),
tag, 4);
}
sl_status_t sli_aes_crypt_ctr_radio(const unsigned char *key,
unsigned int keybits,
const unsigned char input[AES_BLOCK_BYTES],
const unsigned char iv_in[AES_BLOCK_BYTES],
volatile unsigned char iv_out[AES_BLOCK_BYTES],
volatile unsigned char output[AES_BLOCK_BYTES])
{
uint32_t aes_config;
static const uint32_t zero = 0;
switch (keybits) {
case 256:
aes_config = AES_MODEID_CTR | AES_MODEID_CX_LOAD | (((uint32_t)iv_out != 0) ? AES_MODEID_CX_SAVE : 0) | AES_MODEID_AES256;
break;
case 192:
return SL_STATUS_NOT_SUPPORTED;
case 128:
aes_config = AES_MODEID_CTR | AES_MODEID_CX_LOAD | (((uint32_t)iv_out != 0) ? AES_MODEID_CX_SAVE : 0) | AES_MODEID_AES128;
break;
default:
return SL_STATUS_INVALID_KEY;
}
sli_radioaes_dma_descr_t aes_desc_pusher_ctx = {
.address = (uint32_t) iv_out,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST
};
sli_radioaes_dma_descr_t aes_desc_pusher_data = {
.address = (uint32_t) output,
.nextDescr = (((uint32_t)iv_out != 0) ? (uint32_t) &aes_desc_pusher_ctx : DMA_AXI_DESCR_NEXT_STOP),
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISDATA
};
sli_radioaes_dma_descr_t aes_desc_fetcher_data = {
.address = (uint32_t) input,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST | DMA_SG_TAG_ISDATA | DMA_SG_TAG_DATATYPE_AESPAYLOAD
};
sli_radioaes_dma_descr_t aes_desc_fetcher_no_ctx = {
.address = (uint32_t) &zero,
.nextDescr = (uint32_t) &aes_desc_fetcher_data,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_CONST_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_IV)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_ctx = {
.address = (uint32_t) iv_in,
.nextDescr = (uint32_t) &aes_desc_fetcher_data,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_IV)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_config = {
.address = (uint32_t) &aes_config,
.nextDescr = (((uint32_t)iv_in != 0) ? (uint32_t) &aes_desc_fetcher_ctx : (uint32_t) &aes_desc_fetcher_no_ctx),
.lengthAndIrq = sizeof(aes_config),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_CFG)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_key = {
.address = (uint32_t) key,
.nextDescr = (uint32_t) &aes_desc_fetcher_config,
.lengthAndIrq = (uint32_t) (keybits / 8) | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_KEY)
};
// Start operation
return sli_radioaes_run_operation(&aes_desc_fetcher_key, &aes_desc_pusher_data);
}
sl_status_t sli_aes_crypt_ecb_radio(bool encrypt,
const unsigned char *key,
unsigned int keybits,
const unsigned char input[AES_BLOCK_BYTES],
volatile unsigned char output[AES_BLOCK_BYTES])
{
uint32_t aes_config;
switch (keybits) {
case 256:
aes_config = AES_MODEID_ECB | AES_MODEID_NO_CX | AES_MODEID_AES256;
break;
case 192:
return SL_STATUS_NOT_SUPPORTED;
case 128:
aes_config = AES_MODEID_ECB | AES_MODEID_NO_CX | AES_MODEID_AES128;
break;
default:
return SL_STATUS_INVALID_KEY;
}
aes_config |= encrypt ? AES_MODEID_ENCRYPT : AES_MODEID_DECRYPT;
sli_radioaes_dma_descr_t aes_desc_pusher_data = {
.address = (uint32_t) output,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST
};
sli_radioaes_dma_descr_t aes_desc_fetcher_data = {
.address = (uint32_t) input,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST | DMA_SG_TAG_ISDATA | DMA_SG_TAG_DATATYPE_AESPAYLOAD
};
sli_radioaes_dma_descr_t aes_desc_fetcher_config = {
.address = (uint32_t) &aes_config,
.nextDescr = (uint32_t) &aes_desc_fetcher_data,
.lengthAndIrq = sizeof(aes_config),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_CFG)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_key = {
.address = (uint32_t) key,
.nextDescr = (uint32_t) &aes_desc_fetcher_config,
.lengthAndIrq = (uint32_t) (keybits / 8) | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_KEY)
};
// Start operation
return sli_radioaes_run_operation(&aes_desc_fetcher_key, &aes_desc_pusher_data);
}
sl_status_t sli_aes_cmac_radio(const unsigned char *key,
unsigned int keybits,
const unsigned char *input,
unsigned int length,
volatile unsigned char output[16])
{
uint32_t aes_config;
switch (keybits) {
case 256:
aes_config = AES_MODEID_CMA | AES_MODEID_NO_CX | AES_MODEID_AES256 | AES_MODEID_ENCRYPT;
break;
case 192:
return SL_STATUS_NOT_SUPPORTED;
case 128:
aes_config = AES_MODEID_CMA | AES_MODEID_NO_CX | AES_MODEID_AES128 | AES_MODEID_ENCRYPT;
break;
default:
return SL_STATUS_INVALID_KEY;
}
size_t pad_len = 16 - (length % 16);
if (pad_len == 16 && length > 0) {
pad_len = 0;
}
if (length == 0) {
length = 16UL;
input = (const unsigned char *)&zeros;
} else {
length = (length + 15) & ~0xFUL;
}
sli_radioaes_dma_descr_t aes_desc_pusher_data = {
.address = (uint32_t) output,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST
};
sli_radioaes_dma_descr_t aes_desc_fetcher_data = {
.address = (uint32_t) input,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = length | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST | DMA_SG_TAG_ISDATA | DMA_SG_TAG_DATATYPE_AESPAYLOAD | DMA_SG_TAG_SETINVALIDBYTES(pad_len)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_config = {
.address = (uint32_t) &aes_config,
.nextDescr = (uint32_t) &aes_desc_fetcher_data,
.lengthAndIrq = sizeof(aes_config),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_CFG)
};
sli_radioaes_dma_descr_t aes_desc_fetcher_key = {
.address = (uint32_t) key,
.nextDescr = (uint32_t) &aes_desc_fetcher_config,
.lengthAndIrq = (uint32_t) (keybits / 8) | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_KEY)
};
// Start operation
return sli_radioaes_run_operation(&aes_desc_fetcher_key, &aes_desc_pusher_data);
}
//
// CCM buffer authenticated decryption optimized for BLE
//
sl_status_t sli_ccm_auth_decrypt_ble(unsigned char *data,
size_t length,
const unsigned char *key,
const unsigned char *iv,
unsigned char header,
unsigned char *tag)
{
return aes_ccm_ble(false,
data,
length,
key,
iv,
header,
(uint8_t *) tag);
}
//
// CCM buffer encryption optimized for BLE
//
sl_status_t sli_ccm_encrypt_and_tag_ble(unsigned char *data,
size_t length,
const unsigned char *key,
const unsigned char *iv,
unsigned char header,
unsigned char *tag)
{
return aes_ccm_ble(true,
data,
length,
key,
iv,
header,
tag);
}
sl_status_t sli_ccm_zigbee(bool encrypt,
const unsigned char *data_in,
unsigned char *data_out,
size_t length,
const unsigned char *key,
const unsigned char *iv,
const unsigned char *aad,
size_t aad_len,
unsigned char *tag,
size_t tag_len)
{
// Validated assumption: for ZigBee, the authenticated data
// length will always fit into a 16-bit length field, meaning
// the header will always be either 16 or 18 bytes long.
uint8_t header[18];
// Start with the 'flags' byte. It encodes whether there is AAD,
// and the length of the tag fields
header[0] = 0x01 // always 2 bytes of message length
| ((aad_len > 0) ? 0x40 : 0x00) // Set 'aflag' bit if there is AAD
| ((tag_len >= 4) ? (((tag_len - 2) / 2) << 3) : 0); // Encode tag length
for (size_t i = 0; i < 13; i++) {
header[i + 1] = iv[i];
}
header[14] = (uint8_t) length >> 8;
header[15] = (uint8_t) length;
if (aad_len > 0) {
header[16] = (uint8_t) aad_len >> 8; // upper octet of AAD length
header[17] = (uint8_t) aad_len; // lower octet of AAD length
}
return aes_ccm_radio(encrypt,
aad,
aad_len,
data_in,
data_out,
length,
key,
header,
(aad_len > 0 ? 18 : 16),
tag,
tag_len);
}
//
// Process a table of BLE RPA device keys and look for a
// match against the supplied hash. Algorithm is AES-128.
//
int sli_process_ble_rpa(const unsigned char keytable[],
uint32_t keymask,
uint32_t prand,
uint32_t hash)
{
int block;
int previous_block = -1, result = -1;
static const uint32_t aes_rpa_config = AES_MODEID_ECB
| AES_MODEID_NO_CX
| AES_MODEID_AES128
| AES_MODEID_ENCRYPT;
uint32_t rpa_data_in[AES_BLOCK_BYTES / sizeof(uint32_t)] = { 0 };
volatile uint32_t rpa_data_out[AES_BLOCK_BYTES / sizeof(uint32_t)];
sli_radioaes_state_t aes_ctx;
CORE_DECLARE_IRQ_STATE;
rpa_data_in[3] = __REV(prand);
sli_radioaes_dma_descr_t aes_desc_pusher_data = {
.address = (uint32_t) rpa_data_out,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST
};
sli_radioaes_dma_descr_t aes_desc_fetcher_data = {
.address = (uint32_t) rpa_data_in,
.nextDescr = DMA_AXI_DESCR_NEXT_STOP,
.lengthAndIrq = AES_BLOCK_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISLAST | DMA_SG_TAG_ISDATA | DMA_SG_TAG_DATATYPE_AESPAYLOAD
};
sli_radioaes_dma_descr_t aes_desc_fetcher_config = {
.address = (uint32_t) &aes_rpa_config,
.nextDescr = (uint32_t) &aes_desc_fetcher_data,
.lengthAndIrq = sizeof(aes_rpa_config),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_CFG)
};
volatile sli_radioaes_dma_descr_t aes_desc_fetcher_key = {
.address = (uint32_t) NULL, // Filled out in each round of RPA check
.nextDescr = (uint32_t) &aes_desc_fetcher_config,
.lengthAndIrq = (uint32_t) AES_128_KEY_BYTES | (BLOCK_S_INCR_ADDR & BLOCK_S_FLAG_MASK_DMA_PROPS),
.tag = DMA_SG_ENGINESELECT_BA411E | DMA_SG_TAG_ISCONFIG | DMA_SG_TAG_SETCFGOFFSET(AES_OFFSET_KEY)
};
// Start operation
sl_status_t status = sli_radioaes_acquire();
if (status == SL_STATUS_ISR) {
sli_radioaes_save_state(&aes_ctx);
} else if (status != SL_STATUS_OK) {
return -1;
}
RADIOAES->CTRL = AES_CTRL_FETCHERSCATTERGATHER | AES_CTRL_PUSHERSCATTERGATHER;
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
// Start with feeding the mask input
sli_radioaes_dma_descr_t mask_descr = SLI_RADIOAES_MASK_DESCRIPTOR(DMA_AXI_DESCR_NEXT_STOP);
RADIOAES->FETCHADDR = (uint32_t) &mask_descr;
RADIOAES->CMD = AES_CMD_STARTFETCHER;
#endif
// Start a critical section to avoid preemption in-between loading of the RPA key
// and starting the corresponding data pusher.
CORE_ENTER_CRITICAL();
// Data output contains hash in the most significant word (WORD3).
// Descriptors for blocks that are not included in key mask will be skipped.
for (block = 0; block < RADIOAES_BLE_RPA_MAX_KEYS; block++) {
if ( keymask & (1U << block) ) { // Skip masked keys
// Handle pending interrupts while the peripheral is in 'preemptable' state
CORE_YIELD_CRITICAL();
// Write key address and start operation
while (RADIOAES->STATUS & AES_STATUS_FETCHERBSY) {
// Wait for completion
}
aes_desc_fetcher_key.address = (uint32_t) &keytable[block * AES_128_KEY_BYTES];
RADIOAES->FETCHADDR = (uint32_t) &aes_desc_fetcher_key;
RADIOAES->CMD = AES_CMD_STARTFETCHER;
// Wait for pusher from previous round to finish
while (RADIOAES->STATUS & AES_STATUS_PUSHERBSY) {
// Wait for completion
}
RADIOAES->PUSHADDR = (uint32_t) &aes_desc_pusher_data;
// Check previous results while AES is processing
if ((previous_block >= 0) && ((rpa_data_out[3] & 0xFFFFFF00) == __REV(hash)) ) {
// Make sure AES is finished before returning
RADIOAES->CMD = AES_CMD_STARTPUSHER;
result = previous_block;
break;
}
// Start pusher so it is ready to push results when encryption is done
RADIOAES->CMD = AES_CMD_STARTPUSHER;
previous_block = block;
}
}
CORE_EXIT_CRITICAL();
// Wait for last data and check it
while (RADIOAES->STATUS & AES_STATUS_PUSHERBSY) {
// Wait for completion
}
if (status == SL_STATUS_ISR) {
sli_radioaes_restore_state(&aes_ctx);
}
sli_radioaes_release();
if (result >= 0) {
return result;
}
if ((rpa_data_out[3] & 0xFFFFFF00) == __REV(hash) ) {
return previous_block;
}
// No match
return -1;
}
void sli_aes_seed_mask(void)
{
// Acquiring and releasing the peripheral should ensure the mask is properly
// set.
(void) sli_radioaes_acquire();
(void) sli_radioaes_release();
}
/// @endcond
#endif // defined(RADIOAES_PRESENT)

View File

@@ -0,0 +1,211 @@
/***************************************************************************//**
* @file
* @brief Threadsafe utilities for RADIOAES peripheral.
*******************************************************************************
* # 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 "em_device.h"
#if defined(RADIOAES_PRESENT)
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include "sli_radioaes_management.h"
#include "sli_psec_osal.h"
#include "em_core.h"
#include "sl_code_classification.h"
#if defined(SLI_PSEC_THREADING)
static sli_psec_osal_lock_t radioaes_lock = { 0 };
static volatile bool radioaes_lock_initialized = false;
#endif
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#if defined(SL_CATALOG_PSA_CRYPTO_PRESENT)
// If the PSA Crypto core is present, use its randomness abstraction to get
// the initial mask seed.
#include "psa/crypto.h"
#else
// If the PSA Crypto core is not present, we need to target the TRNG driver
// directly to get the initial mask seed. We'll always have an external randomness
// provider function on devices containing a RADIOAES instance.
#include "sli_psa_driver_common.h"
#endif
#include "sl_assert.h"
uint32_t sli_radioaes_mask = 0;
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
static void sli_radioaes_update_mask(void)
{
if (sli_radioaes_mask == 0) {
// Mask has not been initialized yet, get a random value to start
#if defined(SL_CATALOG_PSA_CRYPTO_PRESENT)
psa_status_t status = psa_generate_random((uint8_t*)&sli_radioaes_mask, sizeof(sli_radioaes_mask));
EFM_ASSERT(status == PSA_SUCCESS);
#else
size_t out_len = 0;
psa_status_t status = mbedtls_psa_external_get_random(NULL, (uint8_t*)&sli_radioaes_mask, sizeof(sli_radioaes_mask), &out_len);
EFM_ASSERT(status == PSA_SUCCESS);
EFM_ASSERT(out_len == sizeof(sli_radioaes_mask));
#endif
}
// Use a different mask for each new operation
// The masking logic requires the upper mask bit to be set
sli_radioaes_mask = (sli_radioaes_mask + 1) | (1UL << 31);
}
#endif // SLI_RADIOAES_REQUIRES_MASKING
// Initialize the RADIOAES lock (mutex) for mutual exclusive access
sl_status_t sli_protocol_crypto_init(void)
{
sl_status_t sl_status = SL_STATUS_OK;
#if defined(SLI_PSEC_THREADING)
// Check flag first before going into a critical section, to avoid going into
// a critical section on every single acquire() call. Since the _initialized
// flag only transitions false -> true, we can in 99% of the calls avoid the
// critical section.
if (!radioaes_lock_initialized) {
int32_t kernel_lock_state = 0;
osKernelState_t kernel_state = sli_psec_osal_kernel_get_state();
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
kernel_lock_state = sli_psec_osal_kernel_lock();
if (kernel_lock_state < 0) {
return SL_STATUS_SUSPENDED;
}
}
// Check the flag again after entering the critical section. Now that we're
// in the critical section, we can be sure that we are the only ones looking
// at the flag and no-one is interrupting us during its manipulation.
if (!radioaes_lock_initialized) {
sl_status = sli_psec_osal_init_lock(&radioaes_lock);
if (sl_status == SL_STATUS_OK) {
radioaes_lock_initialized = true;
}
}
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
if (sli_psec_osal_kernel_restore_lock(kernel_lock_state) < 0) {
return SL_STATUS_INVALID_STATE;
}
}
}
#endif
return sl_status;
}
sl_status_t sli_radioaes_acquire(void)
{
#if defined(_CMU_CLKEN0_MASK)
CMU->CLKEN0 |= CMU_CLKEN0_RADIOAES;
#endif
CMU->RADIOCLKCTRL |= CMU_RADIOCLKCTRL_EN;
if ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0U) {
// IRQ: need to store & restore RADIOAES registers
while (RADIOAES->STATUS & (AES_STATUS_FETCHERBSY | AES_STATUS_PUSHERBSY | AES_STATUS_SOFTRSTBSY)) {
// Wait for completion of the previous operation, since the RADIOAES
// peripheral does not support preemption of an operation in progress.
}
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
// The mask should have been initialized from non-ISR context by calling
// sl_mbedtls_init, before using the radioaes.
EFM_ASSERT(sli_radioaes_mask != 0);
#endif
return SL_STATUS_ISR;
} else {
#if defined(SLI_PSEC_THREADING)
sl_status_t ret = SL_STATUS_OK;
if (!radioaes_lock_initialized) {
ret = sli_protocol_crypto_init();
}
if (ret == SL_STATUS_OK) {
ret = sli_psec_osal_take_lock(&radioaes_lock);
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
if (ret == SL_STATUS_OK) {
sli_radioaes_update_mask();
}
#endif
}
return ret;
#else
// Non-IRQ, no RTOS: busywait
while (RADIOAES->STATUS & (AES_STATUS_FETCHERBSY | AES_STATUS_PUSHERBSY | AES_STATUS_SOFTRSTBSY)) {
// Wait for completion
}
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
sli_radioaes_update_mask();
#endif
return SL_STATUS_OK;
#endif
}
}
sl_status_t sli_radioaes_release(void)
{
// IRQ: nothing to do
if ((SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0U) {
return SL_STATUS_OK;
}
#if defined(SLI_PSEC_THREADING)
// Non-IRQ, RTOS available: free lock
return sli_psec_osal_give_lock(&radioaes_lock);
#else
// Non-IRQ, no RTOS: nothing to do.
return SL_STATUS_OK;
#endif
}
sl_status_t sli_radioaes_save_state(sli_radioaes_state_t *ctx)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
ctx->FETCHADDR = RADIOAES->FETCHADDR;
ctx->PUSHADDR = RADIOAES->PUSHADDR;
CORE_EXIT_CRITICAL();
return SL_STATUS_OK;
}
sl_status_t sli_radioaes_restore_state(sli_radioaes_state_t *ctx)
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_CRITICAL();
RADIOAES->FETCHADDR = ctx->FETCHADDR;
RADIOAES->PUSHADDR = ctx->PUSHADDR;
CORE_EXIT_CRITICAL();
return SL_STATUS_OK;
}
/// @endcond
#endif //defined(RADIOAES_PRESENT)

View File

@@ -0,0 +1,106 @@
/**************************************************************************/ /**
* @file
* @brief Threadsafe utilities for RADIOAES peripheral.
*******************************************************************************
* # 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 SLI_RADIOAES_MANAGEMENT_H
#define SLI_RADIOAES_MANAGEMENT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include <stdint.h>
#include "sl_status.h"
#include "sl_code_classification.h"
#if defined(RADIOAES_PRESENT)
/***************************************************************************//**
* @addtogroup sli_protocol_crypto
* @{
******************************************************************************/
///
/// @brief Structure that represents the state of the RADIOAES peripheral
/// (in scatter-gather mode).
///
typedef struct {
uint32_t FETCHADDR; ///< Fetcher Address
uint32_t PUSHADDR; ///< Pusher Address
} sli_radioaes_state_t;
#if defined(SLI_RADIOAES_REQUIRES_MASKING)
/// Static variable containing the masking value for the RADIOAES
extern uint32_t sli_radioaes_mask;
#endif // SLI_RADIOAES_REQUIRES_MASKING
/***************************************************************************//**
* @brief Acquire RADIOAES access
*
* @return SL_STATUS_OK if successful and resource is idle,
* SL_STATUS_ISR if successful but resource was preempted, in
* which case the caller is responsible for saving state,
* relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_radioaes_acquire(void);
/***************************************************************************//**
* @brief Release RADIOAES access
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_radioaes_release(void);
/***************************************************************************//**
* @brief Save RADIOAES register state to RAM
*
* @param ctx Context struct to save register state into
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_radioaes_save_state(sli_radioaes_state_t *ctx);
/***************************************************************************//**
* @brief Restore RADIOAES register state from RAM
*
* @param ctx Context struct to restore register state from
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_PROTOCOL_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_radioaes_restore_state(sli_radioaes_state_t *ctx);
#ifdef __cplusplus
}
#endif
/// @} (end addtogroup sli_protocol_crypto)
#endif // RADIOAES_PRESENT
/// @endcond
#endif // SLI_RADIOAES_MANAGEMENT_H

View File

@@ -0,0 +1,26 @@
/***************************************************************************//**
* # License
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is Third Party Software licensed by Silicon Labs from a third party
* and is governed by the sections of the MSLA applicable to Third Party
* Software and the additional terms set forth below.
*
******************************************************************************/
#ifndef __SL_PSA_ERROR_H__
#define __SL_PSA_ERROR_H__
// Supplementary error codes for the SPM and RoT Services as defined in PSA
// Firmware Framework v1.0, which are not present in crypto_values.h. For non-
// TrustZone SKL builds, this file does not include anything at all. This is
// because our driver implementations only uses error codes that already exist
// in crypto_values.h.
#if defined(TFM_CONFIG_SL_SECURE_LIBRARY)
#include "trusted-firmware-m/interface/include/psa/error.h"
#endif
#endif // __SL_PSA_ERROR_H__

View File

@@ -0,0 +1,29 @@
/***************************************************************************//**
* # License
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is Third Party Software licensed by Silicon Labs from a third party
* and is governed by the sections of the MSLA applicable to Third Party
* Software and the additional terms set forth below.
*
******************************************************************************/
/** \file internal_trusted_storage.h
* \brief Interface and declarations of trusted storage.
*/
#ifndef INTERNAL_TRUSTED_STORAGE_H
#define INTERNAL_TRUSTED_STORAGE_H
// We need to add condition for TFM internal_trusted_storage.h, in case that
// -cp option is not selected.
#if defined(SL_TRUSTZONE_SECURE)
#include "trusted-firmware-m/interface/include/psa/internal_trusted_storage.h"
#else
#include "psa_crypto_its.h"
#include "sli_internal_trusted_storage.h"
#endif
#endif /* INTERNAL_TRUSTED_STORAGE_H */

View File

@@ -0,0 +1,131 @@
/***************************************************************************//**
* # License
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is Third Party Software licensed by Silicon Labs from a third party
* and is governed by the sections of the MSLA applicable to Third Party
* Software and the additional terms set forth below.
*
******************************************************************************/
/** \file sli_internal_trusted_storage.h
* \brief Internal interface and declarations of trusted storage.
*/
#ifndef SLI_INTERNAL_TRUSTED_STORAGE_H
#define SLI_INTERNAL_TRUSTED_STORAGE_H
#include <stddef.h>
#include <stdint.h>
#include <psa/crypto_types.h>
#include <psa/crypto_values.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(TFM_CONFIG_SL_SECURE_LIBRARY)
#define PSA_STORAGE_FLAG_WRITE_ONCE_SECURE_ACCESSIBLE (1 << 3)
#endif // TFM_CONFIG_SL_SECURE_LIBRARY
psa_status_t sli_psa_its_change_key_id(mbedtls_svc_key_id_t old_id,
mbedtls_svc_key_id_t new_id);
/**
* \brief Check if the ITS encryption is enabled
*
* \details The function is added in order to support runtime checking
* needed by trustzone-agnostic libraries
*
* \retval PSA_SUCCESS ITS encryption is enabled
* \retval PSA_ERROR_NOT_SUPPORTED ITS encryption is not supported
*/
psa_status_t sli_psa_its_encrypted(void);
#if defined(SLI_PSA_ITS_ENCRYPTED) && !defined(SEMAILBOX_PRESENT)
/**
* \brief Set the root key to be used when deriving session keys for ITS encryption.
*
* \param[in] root_key Buffer containing the root key.
* \param[in] root_key_size Size of the root key in bytes. Must be 32 (256 bits).
*
* \return A status indicating the success/failure of the operation
*
* \retval PSA_SUCCESS The key was successfully set.
* \retval PSA_ERROR_INVALID_ARGUMENT The root key was NULL or had an invalid size.
* \retval PSA_ERROR_ALREADY_EXISTS The root key has already been initialized.
*/
psa_status_t sli_psa_its_set_root_key(uint8_t *root_key, size_t root_key_size);
#endif // defined(SLI_PSA_ITS_ENCRYPTED) && !defined(SEMAILBOX_PRESENT)
/* Magic values for ITS metadata versions */
#define SLI_PSA_ITS_META_MAGIC_V1 (0x05E175D1UL)
#define SLI_PSA_ITS_META_MAGIC_V2 (0x5E175D10UL)
/* Allocated range of NVM3 IDs for PSA ITS usage */
#define SLI_PSA_ITS_NVM3_RANGE_SIZE (0x00400UL)
#if (SL_PSA_ITS_SUPPORT_V3_DRIVER)
#define SLI_PSA_ITS_NVM3_RANGE_END (0x87100UL)
#define SLI_PSA_ITS_NVM3_RANGE_START (SLI_PSA_ITS_NVM3_RANGE_END - SLI_PSA_ITS_NVM3_RANGE_SIZE)
#else
#define SLI_PSA_ITS_NVM3_RANGE_BASE (0x83100UL)
#endif
#ifndef SL_PSA_ITS_MAX_FILES
#define SL_PSA_ITS_MAX_FILES SLI_PSA_ITS_NVM3_RANGE_SIZE
#endif
#if (SL_PSA_ITS_SUPPORT_V3_DRIVER)
#if !defined(SL_PSA_ITS_REMOVE_V1_HEADER_SUPPORT) && SL_PSA_ITS_SUPPORT_V1_DRIVER
#define SLI_PSA_ITS_SUPPORT_V1_FORMAT_INTERNAL
#endif
#if SL_PSA_ITS_SUPPORT_V2_DRIVER
#define SLI_PSA_ITS_NVM3_RANGE_START_V2_DRIVER (0x83100UL)
#define SLI_PSA_ITS_NVM3_RANGE_END_V2_DRIVER \
SLI_PSA_ITS_NVM3_RANGE_START_V2_DRIVER + SLI_PSA_ITS_NVM3_RANGE_SIZE
#endif
#if defined(SLI_PSA_ITS_ENCRYPTED)
// Define some cryptographic constants if not already set. This depends on the underlying
// crypto accelerator in use (CRYPTOACC has these defines, but not SEMAILBOX).
#define AES_GCM_MAC_SIZE 16
#define AES_GCM_IV_SIZE (12)
#define SLI_ITS_ENCRYPTED_BLOB_SIZE_OVERHEAD (AES_GCM_IV_SIZE + AES_GCM_MAC_SIZE)
#endif // defined(SLI_PSA_ITS_ENCRYPTED)
// Due to alignment constraints on the 64-bit UID, the v2 header struct is
// serialized to 16 bytes instead of the 24 bytes the v1 header compiles to.
typedef struct {
uint32_t magic;
psa_storage_create_flags_t flags;
psa_storage_uid_t uid;
} sli_its_file_meta_v2_t;
#if defined(SLI_PSA_ITS_ENCRYPTED)
typedef struct {
uint8_t iv[AES_GCM_IV_SIZE];
// When encrypted & authenticated, MAC is stored at the end of the data array
uint8_t data[];
} sli_its_encrypted_blob_t;
#endif
#if defined(SLI_PSA_ITS_ENCRYPTED)
psa_status_t sli_encrypt_its_file(sli_its_file_meta_v2_t *metadata,
uint8_t *plaintext,
size_t plaintext_size,
sli_its_encrypted_blob_t *blob,
size_t blob_size,
size_t *blob_length);
#endif
#endif // SL_PSA_ITS_SUPPORT_V3_DRIVER
#ifdef __cplusplus
}
#endif
#endif /* SLI_INTERNAL_TRUSTED_STORAGE_H */

View File

@@ -0,0 +1,230 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto common driver functions.
*******************************************************************************
* # 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 SLI_PSA_DRIVER_COMMON_H
#define SLI_PSA_DRIVER_COMMON_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include "psa/crypto.h"
#include <stddef.h>
// -----------------------------------------------------------------------------
// Static inline functions
/*******************************************************************************
* @brief
* Validate that a elliptic curve (in Weierstrass form) private key is valid.
* This fuction attempts to operate in constant time.
*
* @param[in] privkey
* A buffer containing the private key.
*
* @param padding_bytes
* A buffer containing the modulus (n) to compare the private key against.
*
* @return
* PSA_SUCCESS if the key is in [1, n-1], PSA_ERROR_INVALID_ARGUMENT otherwise.
******************************************************************************/
static inline psa_status_t sli_psa_validate_ecc_weierstrass_privkey(
const void *privkey,
const void *modulus,
size_t privkey_size)
{
// Compare private key to maximum allowed value, n - 1,
// and also check that it is non-zero.
// Initial values.
uint8_t non_zero_accumulator = 0;
int32_t memcmp_res = 0;
int32_t diff = 0;
// Loop over every byte in the private key. We start from the end so that
// the final result we store reflects the first byte which differs between the
// two numbers (privkey and modulus).
for (size_t i = 0; i < privkey_size; ++i) {
// Partial non-zero check operation.
non_zero_accumulator |= ((uint8_t *)privkey)[privkey_size - 1 - i];
// Compute the difference between the current bytes being compared.
diff = ((uint8_t *)privkey)[privkey_size - 1 - i]
- ((uint8_t *)modulus)[privkey_size - 1 - i];
// This will only update memcmp_res if the difference is non-zero.
memcmp_res = (memcmp_res & - !diff) | diff;
}
if ((non_zero_accumulator == 0) || (memcmp_res >= 0)) {
// We have either failed because the private key turned out to be empty,
// or because the result of the memcmp indicated that the privkey was not
// smaller than the modulus.
return PSA_ERROR_INVALID_ARGUMENT;
} else {
return PSA_SUCCESS;
}
}
/***************************************************************************//**
* @brief
* Clear a memory location in a way that is guaranteed not be optimized away
* by the compiler.
*
* @param[in] v
* Pointer to memory location.
*
* @param[in] n
* Number of bytes to clear.
******************************************************************************/
static inline psa_status_t sli_psa_zeroize(void *v, size_t n)
{
if (n == 0) {
return PSA_SUCCESS;
}
volatile unsigned char *p = v;
while (n--) {
*p++ = 0;
}
return PSA_SUCCESS;
}
/***************************************************************************//**
* @brief
* Perform a memcmp() in 'constant time'.
*
* @param[in] a
* Pointer to the first memory location.
*
* @param[in] a
* Pointer to the second memory location.
*
* @param[in] n
* Number of bytes to compare between the two memory locations.
*
* @return
* Zero if the buffer contents are equal, non-zero otherwise.
******************************************************************************/
static inline uint8_t sli_psa_safer_memcmp(const uint8_t *a,
const uint8_t *b,
size_t n)
{
uint8_t diff = 0u;
for (size_t i = 0; i < n; i++) {
diff |= a[i] ^ b[i];
}
return diff;
}
// -----------------------------------------------------------------------------
// Function declarations
/*******************************************************************************
* @brief
* Validate the PKCS#7 padding contained in the final block of plaintext
* in certain block cipher modes of operation. Based on the get_pkcs_padding()
* implementation in Mbed TLS.
*
* @param[in] padded_data
* A buffer of (at least) size 16 containing the padded final block.
*
* @param padded_data_length
* The length of the paddad data (should be 16). Parameter is mainly kept used
* in order to make it harder for the compiler to optimize out some of the
* "time-constantness".
*
* @param[out] padding_bytes
* The amount of padding bytes that the data contains.
*
* @return
* PSA_SUCCESS if the padding is valid, PSA_ERROR_INVALID_PADDING otherwise.
******************************************************************************/
psa_status_t sli_psa_validate_pkcs7_padding(uint8_t *padded_data,
size_t padded_data_length,
size_t *padding_bytes);
/**
* \brief Initialize Galois field (2^128) multiplication table
*
* This function is used as part of a software-based GHASH (as defined in
* AES-GCM) algorithm, and originates from the mbed TLS implementation in gcm.c
*
* It takes the in the 'H' value for the GHASH operation (which is a block of
* zeroes encrypted using AES-ECB with the key to be used for GHASH/GCM), and
* converts it into a multiplication table for later use by the multiplication
* function.
*
* \param[in] Ek 'H' value for which to create the multiplication tables
* \param[out] HL Lower multiplication table for 'H'
* \param[out] HH Upper multiplication table for 'H'
*/
void sli_psa_software_ghash_setup(const uint8_t Ek[16],
uint64_t HL[16],
uint64_t HH[16]);
/**
* \brief Galois field (2^128) multiplication operation
*
* This function is used as part of a software-based GHASH (as defined in
* AES-GCM) algorithm, and originates from the mbed TLS implementation in gcm.c
*
* This function takes in a 128-bit scalar and multiplies it with H (Galois
* field multiplication as defined in AES-GCM). H is not provided to this
* function directly. Instead, multiplication tables for the specific H need to
* be calculated first by \ref sli_psa_software_ghash_setup, and passed to this
* function.
*
* \param[in] HL Lower multiplication table for 'H'
* \param[in] HH Upper multiplication table for 'H'
* \param[out] output Output buffer for the multiplication result
* \param[in] input Input buffer for the scalar to multiply
*/
void sli_psa_software_ghash_multiply(const uint64_t HL[16],
const uint64_t HH[16],
uint8_t output[16],
const uint8_t input[16]);
#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) \
&& !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
// Declare the TRNG function prototype if it's not already declared by PSA
psa_status_t mbedtls_psa_external_get_random(void *context,
uint8_t *output,
size_t output_size,
size_t *output_length);
#endif // MBEDTLS_ENTROPY_HARDWARE_ALT && MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG
/// @endcond
#endif // SLI_PSA_DRIVER_COMMON_H

View File

@@ -0,0 +1,393 @@
/***************************************************************************//**
* @file
* @brief PSA Crypto driver feature enablement.
*******************************************************************************
* # 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_PSA_DRIVER_FEATURES_H
#define SLI_PSA_DRIVER_FEATURES_H
#include "mbedtls/build_info.h"
// -----------------------------------------------------------------------------
// Feature inclusion (available AND requested)
// -------------------------------------
// Keys
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
#define SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS
#define SLI_PSA_DRIVER_FEATURE_WRAPPED_KEYS
#endif
#if defined(SLI_MBEDTLS_DEVICE_VSE) && defined(SEPUF_PRESENT)
#define SLI_PSA_DRIVER_FEATURE_PUF_KEY
#endif
#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) \
&& (defined(SLI_MBEDTLS_DEVICE_HSE) || defined(SLI_PSA_DRIVER_FEATURE_PUF_KEY))
#define SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS
#define SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS
#endif
// -------------------------------------
// TRNG
#if defined(SLI_MBEDTLS_DEVICE_HSE) \
|| defined(SLI_MBEDTLS_DEVICE_VSE) \
|| defined(SLI_MBEDTLS_DEVICE_S1_WITH_TRNG) \
|| defined(SLI_MBEDTLS_DEVICE_SI91X)
#define SLI_PSA_DRIVER_FEATURE_TRNG
#endif
#if defined(SLI_MBEDTLS_DEVICE_S1_WITH_TRNG_ERRATA)
#define SLI_PSA_DRIVER_FEATURE_TRNG_ERRATA_HANDLING
#endif
// -------------------------------------
// Attestation
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) && !defined(_SILICON_LABS_32B_SERIES_3_CONFIG_301)
#define SLI_PSA_DRIVER_FEATURE_ATTESTATION
#endif
// -------------------------------------
// AEAD
#if defined(PSA_WANT_ALG_CCM) && defined(MBEDTLS_PSA_ACCEL_ALG_CCM)
#define SLI_PSA_DRIVER_FEATURE_AEAD
#define SLI_PSA_DRIVER_FEATURE_AEAD_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_CCM
#endif
#if defined(PSA_WANT_ALG_GCM) && defined(MBEDTLS_PSA_ACCEL_ALG_GCM)
#define SLI_PSA_DRIVER_FEATURE_AEAD
#define SLI_PSA_DRIVER_FEATURE_AEAD_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_GCM
// TODO: add public config option.
#if defined(SLI_PSA_SUPPORT_GCM_IV_CALCULATION)
// Can use software implementation in order to compute IVs.
#define SLI_PSA_DRIVER_FEATURE_GCM_IV_CALCULATION
#endif
#endif
#if defined(PSA_WANT_ALG_CHACHA20_POLY1305) && defined(MBEDTLS_PSA_ACCEL_ALG_CHACHA20_POLY1305)
#define SLI_PSA_DRIVER_FEATURE_AEAD
#define SLI_PSA_DRIVER_FEATURE_CHACHAPOLY
#endif
// -------------------------------------
// Cipher
#if defined(PSA_WANT_KEY_TYPE_AES) && defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_AES)
#define SLI_PSA_DRIVER_FEATURE_AES
#if defined(PSA_WANT_ALG_ECB_NO_PADDING) && defined(MBEDTLS_PSA_ACCEL_ALG_ECB_NO_PADDING)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_ECB
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_CTR) && defined(MBEDTLS_PSA_ACCEL_ALG_CTR)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_CTR
#define SLI_PSA_DRIVER_FEATURE_AES_CTR_VARIANT
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_CFB) && defined(MBEDTLS_PSA_ACCEL_ALG_CFB)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_CFB
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_OFB) && defined(MBEDTLS_PSA_ACCEL_ALG_OFB)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_OFB
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_CCM) && defined(MBEDTLS_PSA_ACCEL_ALG_CCM)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_CCM_STAR_NO_TAG
#define SLI_PSA_DRIVER_FEATURE_AES_CTR_VARIANT
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_CBC_NO_PADDING) && defined(MBEDTLS_PSA_ACCEL_ALG_CBC_NO_PADDING)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_CBC_NO_PADDING
#define SLI_PSA_DRIVER_FEATURE_AES_CBC_VARIANT
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#if defined(PSA_WANT_ALG_CBC_PKCS7) && defined(MBEDTLS_PSA_ACCEL_ALG_CBC_PKCS7)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_BLOCK_CIPHER
#define SLI_PSA_DRIVER_FEATURE_AES_CBC_PKCS7
#define SLI_PSA_DRIVER_FEATURE_AES_CBC_VARIANT
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
#endif
#if defined(PSA_WANT_KEY_TYPE_CHACHA20) && defined(PSA_WANT_ALG_STREAM_CIPHER) \
&& defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_CHACHA20)
#define SLI_PSA_DRIVER_FEATURE_CIPHER
#define SLI_PSA_DRIVER_FEATURE_STREAM_CIPHER
#define SLI_PSA_DRIVER_FEATURE_CHACHA20
#define SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
#endif
// -------------------------------------
// Key derivation
#if defined(PSA_WANT_ALG_HKDF) && defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
#define SLI_PSA_DRIVER_FEATURE_KDF
#define SLI_PSA_DRIVER_FEATURE_HKDF
#endif
#if defined(PSA_WANT_ALG_PBKDF2_HMAC) && defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
#define SLI_PSA_DRIVER_FEATURE_KDF
#define SLI_PSA_DRIVER_FEATURE_PBKDF2
#define SLI_PSA_DRIVER_FEATURE_PBKDF2_HMAC
#endif
#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) && defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH) \
&& defined(SLI_MBEDTLS_DEVICE_HSE_V2)
#define SLI_PSA_DRIVER_FEATURE_KDF
#define SLI_PSA_DRIVER_FEATURE_PBKDF2
#define SLI_PSA_DRIVER_FEATURE_PBKDF2_CMAC
#endif
#if defined(PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128) && defined(SLI_PSA_DRIVER_FEATURE_PUF_KEY)
#define SLI_PSA_DRIVER_FEATURE_KDF
#define SLI_PSA_DRIVER_FEATURE_PBKDF2
#define SLI_PSA_DRIVER_FEATURE_PBKDF2_CMAC
#endif
// -------------------------------------
// Hash
#if defined(PSA_WANT_ALG_SHA_1) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_1)
#define SLI_PSA_DRIVER_FEATURE_HASH
#define SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_SHA1
#define SLI_PSA_DRIVER_FEATURE_HASH_STATE_32
#endif
#if defined(PSA_WANT_ALG_SHA_224) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_224)
#define SLI_PSA_DRIVER_FEATURE_HASH
#define SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_SHA224
#define SLI_PSA_DRIVER_FEATURE_HASH_STATE_32
#endif
#if defined(PSA_WANT_ALG_SHA_256) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_256)
#define SLI_PSA_DRIVER_FEATURE_HASH
#define SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_SHA256
#define SLI_PSA_DRIVER_FEATURE_HASH_STATE_32
#endif
#if defined(PSA_WANT_ALG_SHA_384) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_384)
#define SLI_PSA_DRIVER_FEATURE_HASH
#define SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_SHA384
#define SLI_PSA_DRIVER_FEATURE_HASH_STATE_64
#endif
#if defined(PSA_WANT_ALG_SHA_512) && defined(MBEDTLS_PSA_ACCEL_ALG_SHA_512)
#define SLI_PSA_DRIVER_FEATURE_HASH
#define SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_SHA512
#define SLI_PSA_DRIVER_FEATURE_HASH_STATE_64
#endif
// -------------------------------------
// MAC
#if defined(PSA_WANT_ALG_HMAC) && defined(MBEDTLS_PSA_ACCEL_ALG_HMAC)
#define SLI_PSA_DRIVER_FEATURE_MAC
#define SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_HMAC
#endif
#if defined(PSA_WANT_ALG_CMAC) && defined(MBEDTLS_PSA_ACCEL_ALG_CMAC)
#define SLI_PSA_DRIVER_FEATURE_MAC
#define SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_CMAC
#endif
#if defined(PSA_WANT_ALG_CBC_MAC) && defined(MBEDTLS_PSA_ACCEL_ALG_CBC_MAC)
#define SLI_PSA_DRIVER_FEATURE_MAC
#define SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
#define SLI_PSA_DRIVER_FEATURE_CBC_MAC
#endif
// -------------------------------------
// Elliptic curve cryptography
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_R1_192)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPR1
#define SLI_PSA_DRIVER_FEATURE_P192R1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_R1_224) \
&& !defined(SLI_MBEDTLS_DEVICE_HSE_V1)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPR1
#define SLI_PSA_DRIVER_FEATURE_P224R1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_R1_256)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPR1
#define SLI_PSA_DRIVER_FEATURE_P256R1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_R1_384) \
&& defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_384)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPR1
#define SLI_PSA_DRIVER_FEATURE_P384R1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_R1_521) \
&& defined(MBEDTLS_PSA_ACCEL_ECC_SECP_R1_521)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPR1
#define SLI_PSA_DRIVER_FEATURE_P521R1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_SECP_K1_256) \
&& defined(SLI_MBEDTLS_DEVICE_VSE)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_SECPK1
#define SLI_PSA_DRIVER_FEATURE_P256K1
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_MONTGOMERY_255) \
&& defined(SLI_MBEDTLS_DEVICE_HSE)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_MONTGOMERY
#define SLI_PSA_DRIVER_FEATURE_CURVE25519
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_MONTGOMERY_448) \
&& defined(MBEDTLS_PSA_ACCEL_ECC_MONTGOMERY_448)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_MONTGOMERY
#define SLI_PSA_DRIVER_FEATURE_CURVE448
#endif
#if (defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT) \
|| defined (PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE) \
|| defined(PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY)) \
&& defined(PSA_WANT_ECC_TWISTED_EDWARDS_255) \
&& defined(SLI_MBEDTLS_DEVICE_HSE)
#define SLI_PSA_DRIVER_FEATURE_ECC
#define SLI_PSA_DRIVER_FEATURE_EDWARDS
#define SLI_PSA_DRIVER_FEATURE_EDWARDS25519
#endif
// -------------------------------------
// Key agreement
#if defined(PSA_WANT_ALG_ECDH) && defined(MBEDTLS_PSA_ACCEL_ALG_ECDH) \
&& defined(SLI_PSA_DRIVER_FEATURE_ECC)
#define SLI_PSA_DRIVER_FEATURE_KEY_AGREEMENT
#define SLI_PSA_DRIVER_FEATURE_ECDH
#endif
// -------------------------------------
// Signature
#if defined(PSA_WANT_ALG_ECDSA) && defined(MBEDTLS_PSA_ACCEL_ALG_ECDSA) \
&& (defined(SLI_PSA_DRIVER_FEATURE_SECPR1) \
|| defined(SLI_PSA_DRIVER_FEATURE_SECPK1))
#define SLI_PSA_DRIVER_FEATURE_SIGNATURE
#define SLI_PSA_DRIVER_FEATURE_ECDSA
#endif
#if defined(PSA_WANT_ALG_EDDSA) && defined(SLI_PSA_DRIVER_FEATURE_EDWARDS)
#define SLI_PSA_DRIVER_FEATURE_SIGNATURE
#define SLI_PSA_DRIVER_FEATURE_EDDSA
#endif
#endif // SLI_PSA_DRIVER_FEATURES_H

View File

@@ -0,0 +1,204 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Secure Engine Driver AEAD functions.
*******************************************************************************
* # 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 SLI_SE_DRIVER_AEAD_H
#define SLI_SE_DRIVER_AEAD_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
// -----------------------------------------------------------------------------
// Types
typedef struct {
sl_se_cipher_operation_t direction;
size_t ad_length;
size_t pt_length;
uint8_t nonce[16];
size_t nonce_length;
} sli_se_driver_aead_preinit_t;
typedef struct {
psa_algorithm_t alg;
sl_se_key_descriptor_t key_desc;
size_t ad_len;
size_t pt_len;
union {
sl_se_gcm_multipart_context_t gcm;
sl_se_ccm_multipart_context_t ccm;
sli_se_driver_aead_preinit_t preinit;
} ctx;
} sli_se_driver_aead_operation_t;
// -----------------------------------------------------------------------------
// Functions
#ifdef __cplusplus
extern "C" {
#endif
psa_status_t sli_se_driver_aead_encrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
psa_status_t sli_se_driver_aead_decrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
psa_status_t sli_se_driver_aead_encrypt_tag(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length);
psa_status_t sli_se_driver_aead_decrypt_tag(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
const uint8_t* tag,
size_t tag_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
psa_status_t sli_se_driver_aead_encrypt_decrypt_setup(sli_se_driver_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
sl_se_cipher_operation_t operation_direction,
uint8_t *key_storage_buffer,
size_t key_storage_buffer_size,
size_t key_storage_overhead);
psa_status_t sli_se_driver_aead_set_nonce(sli_se_driver_aead_operation_t *operation,
const uint8_t *nonce,
size_t nonce_size);
psa_status_t sli_se_driver_aead_set_lengths(sli_se_driver_aead_operation_t *operation,
size_t ad_length,
size_t plaintext_length);
psa_status_t sli_se_driver_aead_update_ad(sli_se_driver_aead_operation_t *operation,
uint8_t *key_buffer,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_driver_aead_update(sli_se_driver_aead_operation_t *operation,
uint8_t *key_buffer,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_driver_aead_finish(sli_se_driver_aead_operation_t *operation,
uint8_t *key_buffer,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length);
psa_status_t sli_se_driver_aead_verify(sli_se_driver_aead_operation_t *operation,
uint8_t *key_buffer,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length,
const uint8_t *tag,
size_t tag_length);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_DRIVER_AEAD_H

View File

@@ -0,0 +1,135 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Secure Engine Driver cipher functions.
*******************************************************************************
* # 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 SLI_SE_DRIVER_CIPHER_H
#define SLI_SE_DRIVER_CIPHER_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sl_se_manager_types.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
// -----------------------------------------------------------------------------
// Types
typedef struct {
sl_se_key_descriptor_t key_desc;
sl_se_cipher_operation_t direction;
psa_algorithm_t alg;
uint8_t iv[16];
size_t iv_len;
uint8_t streaming_block[16];
size_t processed_length;
} sli_se_driver_cipher_operation_t;
// -----------------------------------------------------------------------------
// Functions
#ifdef __cplusplus
extern "C" {
#endif
psa_status_t sli_se_driver_cipher_encrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *iv,
size_t iv_length,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_driver_cipher_decrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_driver_cipher_encrypt_setup(sli_se_driver_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
psa_algorithm_t alg);
psa_status_t sli_se_driver_cipher_decrypt_setup(sli_se_driver_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
psa_algorithm_t alg);
psa_status_t sli_se_driver_cipher_set_iv(sli_se_driver_cipher_operation_t *operation,
const uint8_t *iv,
size_t iv_length);
psa_status_t sli_se_driver_cipher_update(sli_se_driver_cipher_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_driver_cipher_finish(sli_se_driver_cipher_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_driver_cipher_abort(sli_se_driver_cipher_operation_t *operation);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_DRIVER_CIPHER_H

View File

@@ -0,0 +1,105 @@
/***************************************************************************//**
* @file
* @brief SE Driver for Silicon Labs devices with an embedded SE, for use with
* PSA Crypto and Mbed TLS
*******************************************************************************
* # 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 SLI_SE_DRIVER_KEY_DERIVATION
#define SLI_SE_DRIVER_KEY_DERIVATION
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sl_se_manager.h"
#include "sl_se_manager_defines.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
#include "psa/crypto_platform.h"
// -----------------------------------------------------------------------------
// Structs and typedefs
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
#define SLI_SE_MAX_ECP_PRIVATE_KEY_SIZE (PSA_BITS_TO_BYTES(521))
#else
#define SLI_SE_MAX_ECP_PRIVATE_KEY_SIZE (PSA_BITS_TO_BYTES(256))
#endif
#define SLI_SE_MAX_ECP_PUBLIC_KEY_SIZE (SLI_SE_MAX_ECP_PRIVATE_KEY_SIZE * 2)
#define SLI_SE_MAX_PADDED_ECP_PRIVATE_KEY_SIZE \
(SLI_SE_MAX_ECP_PRIVATE_KEY_SIZE \
+ sli_se_get_padding(SLI_SE_MAX_ECP_PRIVATE_KEY_SIZE))
#define SLI_SE_MAX_PADDED_ECP_PUBLIC_KEY_SIZE \
(SLI_SE_MAX_PADDED_ECP_PRIVATE_KEY_SIZE * 2)
// -----------------------------------------------------------------------------
// Function declarations
#ifdef __cplusplus
extern "C" {
#endif
psa_status_t sli_se_driver_key_agreement(
psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_DRIVER_KEY_DERIVATION

View File

@@ -0,0 +1,351 @@
/***************************************************************************//**
* @file
* @brief SE Driver for Silicon Labs devices with an embedded SE, for use with
* PSA Crypto and Mbed TLS
*******************************************************************************
* # 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 SLI_SE_DRIVER_KEY_MANAGEMENT_H
#define SLI_SE_DRIVER_KEY_MANAGEMENT_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sli_se_opaque_types.h"
#include "sli_se_version_dependencies.h"
#include "sl_se_manager.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Defines and macros
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
/// Max available curve size
#define SLI_SE_MAX_CURVE_SIZE (521)
#else
/// Max available curve size
#define SLI_SE_MAX_CURVE_SIZE (256)
#endif
/// Byte size of maximum available ECC private key padded to word-alignment
#define SLI_SE_MAX_PADDED_KEY_PAIR_SIZE \
(PSA_BITS_TO_BYTES(SLI_SE_MAX_CURVE_SIZE) \
+ sli_se_get_padding(PSA_BITS_TO_BYTES(SLI_SE_MAX_CURVE_SIZE)))
/// Byte size of maximum available ECDSA signature padded to word-alignment
#define SLI_SE_MAX_PADDED_SIGNATURE_SIZE \
(PSA_ECDSA_SIGNATURE_SIZE(SLI_SE_MAX_CURVE_SIZE) \
+ 2 * sli_se_get_padding(PSA_BITS_TO_BYTES(SLI_SE_MAX_CURVE_SIZE)))
/// Byte size of maximum available ECC public key padded to word-alignment
#define SLI_SE_MAX_PADDED_PUBLIC_KEY_SIZE (SLI_SE_MAX_PADDED_SIGNATURE_SIZE)
/** Determine the number of bytes necessary to pad size to a word-alignment
* @param size
* Unsigend integer type.
* @returns the number of padding bytes required
*/
#define sli_se_get_padding(size) ((4 - (size & 3)) & 3)
/** Pad size to word alignment
* @param size
* Unsigend integer type.
* @returns the number of padding bytes required
*/
#define sli_se_word_align(size) ((size + 3) & ~3)
// -----------------------------------------------------------------------------
// Static inline functions
/**
* @brief
* Pad the big endian number in buffer with zeros
* @param tmp_buffer
* A buffer to store the padded number
* @param buffer
* The buffer containing the number
* @param buffer_size
* Byte size of the number to pad
* @note
* Buffer sizes must be pre-validated.
*/
static inline void sli_se_pad_big_endian(uint8_t *tmp_buffer,
const uint8_t *buffer,
size_t buffer_size)
{
size_t padding = sli_se_get_padding(buffer_size);
memset(tmp_buffer, 0, padding); // Set the preceeding 0s
memcpy(tmp_buffer + padding, buffer, buffer_size); // Copy actual content
}
/**
* @brief
* Remove the padding from a zero-padded big endian number
* @param tmp_buffer
* Buffer containing the padded number
* @param buffer
* The buffer to write unpadded number to
* @param buffer_size
* Byte size of unpadded number
* @note
* Buffer sizes must be pre-validated.
*/
static inline void sli_se_unpad_big_endian(const uint8_t *tmp_buffer,
uint8_t *buffer,
size_t buffer_size)
{
size_t padding = sli_se_get_padding(buffer_size);
memcpy(buffer, tmp_buffer + padding, buffer_size);
}
/**
* @brief
* Pad each coordinate of a big endian curve point
* @param tmp_buffer
* A buffer to store the padded point
* @param buffer
* The buffer containing the point
* @param coord_size
* Byte size of each coordinate
* @note
* Buffer sizes must be pre-validated.
*/
static inline void sli_se_pad_curve_point(uint8_t *tmp_buffer,
const uint8_t *buffer,
size_t coord_size)
{
size_t padding = sli_se_get_padding(coord_size);
sli_se_pad_big_endian(tmp_buffer, buffer, coord_size);
sli_se_pad_big_endian(tmp_buffer + coord_size + padding,
buffer + coord_size,
coord_size);
}
/**
* @brief
* Strip away the padding from each coordinate of a big endian curve point
* @param tmp_buffer
* The buffer where the padded point is stored
* @param buffer
* A buffer to store the unpadded point
* @param coord_size
* Byte size of each coordinate
* @note
* Buffer sizes must be pre-validated.
*/
static inline void sli_se_unpad_curve_point(const uint8_t *tmp_buffer,
uint8_t *buffer,
size_t coord_size)
{
size_t padding = sli_se_get_padding(coord_size);
sli_se_unpad_big_endian(tmp_buffer, buffer, coord_size);
sli_se_unpad_big_endian(tmp_buffer + coord_size + padding,
buffer + coord_size,
coord_size);
}
/**
* @brief
* Set the key desc to a plaintext key type pointing to data.
* @param[out] key_desc
* The SE manager key struct representing a key
* @param[in] data
* Buffer containing the key
* @param[in] data_length
* Length of the buffer
*/
static inline
void sli_se_key_descriptor_set_plaintext(sl_se_key_descriptor_t *key_desc,
const uint8_t *data,
size_t data_length)
{
key_desc->storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key_desc->storage.location.buffer.pointer = (uint8_t *)data;
// TODO: Improve SE manager alignment requirements
key_desc->storage.location.buffer.size = sli_se_word_align(data_length);
}
/**
* @brief
* Determine if a format byte is necessary for the key type
* @param key_type
* PSA key type for the key in question
* @returns
* 1 if the key type requires a format byte,
* 0 otherwise
*/
static inline uint32_t sli_se_has_format_byte(psa_key_type_t key_type)
{
if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(key_type)) {
if ((PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) != PSA_ECC_FAMILY_MONTGOMERY)
&& (PSA_KEY_TYPE_ECC_GET_FAMILY(key_type) != PSA_ECC_FAMILY_TWISTED_EDWARDS)) {
return 1U;
}
}
return 0U;
}
// -----------------------------------------------------------------------------
// Function declarations
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief
* Store the required parts of the key descriptor in the context placed the
* start of the given key buffer.
*
* @param key_desc[in]
* Key descriptor to export.
* @param key_buffer[out]
* Pointer to the key buffer containing key context.
* @param key_buffer_size[in]
* Size of key buffer.
* @returns
* PSA_SUCCESS stored key desc in context
* PSA_ERROR_BUFFER_TOO_SMALL output buffer is too small to hold an opaque key context
*/
psa_status_t store_key_desc_in_context(sl_se_key_descriptor_t *key_desc,
uint8_t *key_buffer,
size_t key_buffer_size);
/**
* @brief
* Get the key descriptor from the key buffer and attributes
*
* @param[in] attributes
* The PSA attributes struct representing a key
* @param[in] key_buffer
* Buffer containing key context from PSA core
* @param[in] key_buffer_size
* Size of key_buffer
* @param[out] key_desc
* The SE manager key descriptor struct to populate
* @returns
* PSA_SUCCESS if everything is OK
* PSA_ERROR_INVALID_ARGUMENT if key buffer does not mach a valid key context
* @note
* The resulting key descriptor is only valid as long as the key_buffer
* array remains in scope. In practice, this is only guaranteed throughout a
* single driver function.
*/
psa_status_t sli_se_key_desc_from_input(const psa_key_attributes_t* attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
sl_se_key_descriptor_t *key_desc);
/**
* @brief
* Build a key descriptor from a PSA attributest struct
*
* @param attributes
* The PSA attributes struct representing a key
* @param key_size
* Size of the key
* @param key_desc
* The SE manager key struct representing the same key
* @returns
* PSA_SUCCESS on success
* PSA_ERROR_INVALID_ARGUMENT on invalid attributes
*/
psa_status_t sli_se_key_desc_from_psa_attributes(const psa_key_attributes_t *attributes,
size_t key_size,
sl_se_key_descriptor_t *key_desc);
/**
* @brief
* Set the relevant location field of the key descriptor
*
* @param[in] attributes
* The PSA attributes struct representing a key
* @param[in] key_buffer
* Buffer containing key context from PSA core
* @param[in] key_buffer_size
* Size of key_buffer
* @param[in] key_size
* Size of the key
* @param[out] key_desc
* The SE manager key descriptor struct to populate
* @returns
* PSA_SUCCESS if everything is OK
* PSA_ERROR_INVALID_ARGUMENT if key buffer does not mach a valid key context
*/
psa_status_t sli_se_set_key_desc_output(const psa_key_attributes_t* attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t key_size,
sl_se_key_descriptor_t *key_desc);
// psa_generate_key entry point for both opaque and transparent drivers
psa_status_t sli_se_driver_generate_key(const psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *output_length);
#if defined(SLI_SE_VERSION_ECDH_PUBKEY_VALIDATION_UNCERTAIN) \
&& defined(MBEDTLS_ECP_C) \
&& defined(MBEDTLS_PSA_CRYPTO_C) \
&& SL_SE_SUPPORT_FW_PRIOR_TO_1_2_2
psa_status_t sli_se_driver_validate_pubkey_with_fallback(psa_key_type_t key_type,
size_t key_bits,
const uint8_t *data,
size_t data_length);
#endif // Software fallback for SE < 1.2.2
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_DRIVER_KEY_MANAGEMENT_H

View File

@@ -0,0 +1,127 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Secure Engine Driver MAC functions.
*******************************************************************************
* # 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 SLI_SE_DRIVER_MAC_H
#define SLI_SE_DRIVER_MAC_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
#include "sl_se_manager.h"
#include "sl_se_manager_cipher.h"
// -----------------------------------------------------------------------------
// Types
typedef struct {
psa_algorithm_t alg;
union {
sl_se_cmac_multipart_context_t cmac;
struct {
uint8_t iv[16];
size_t iv_len;
uint8_t streaming_block[16];
size_t processed_length;
} cbcmac;
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
struct {
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_STATE_64)
uint8_t hmac_result[64];
#else
uint8_t hmac_result[32];
#endif // SLI_PSA_DRIVER_FEATURE_HASH_STATE_64
size_t hmac_len;
} hmac;
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
} ctx;
} sli_se_driver_mac_operation_t;
// -----------------------------------------------------------------------------
// Functions
#ifdef __cplusplus
extern "C" {
#endif
sl_se_hash_type_t sli_se_hash_type_from_psa_hmac_alg(psa_algorithm_t alg,
size_t *length);
psa_status_t sli_se_driver_mac_compute(sl_se_key_descriptor_t *key_desc,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t sli_se_driver_mac_sign_setup(sli_se_driver_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
psa_algorithm_t alg);
psa_status_t sli_se_driver_mac_update(sli_se_driver_mac_operation_t *operation,
sl_se_key_descriptor_t *key_desc,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_driver_mac_sign_finish(sli_se_driver_mac_operation_t *operation,
sl_se_key_descriptor_t *key_desc,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_DRIVER_MAC_H

View File

@@ -0,0 +1,380 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver functions for SE.
*******************************************************************************
* # 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 SLI_SE_OPAQUE_FUNCTIONS_H
#define SLI_SE_OPAQUE_FUNCTIONS_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
#include "sli_se_opaque_types.h"
#include "sli_se_driver_key_management.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
#include "psa/crypto_platform.h"
#include "psa/crypto_sizes.h"
#include "psa/crypto_struct.h"
// NOTE: This header file will be autogenerated by PSA Crypto build system based
// on the definitions in sli_se_opaque_driver.json. However, until such a system
// is in place, we rely on manually writing the file.
#ifdef __cplusplus
extern "C" {
#endif
//------------------------------------------------------------------------------
// General
psa_status_t sli_se_opaque_driver_init(void);
psa_status_t sli_se_opaque_driver_deinit(void);
//------------------------------------------------------------------------------
// Key handling
psa_status_t sli_se_opaque_export_key(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
uint8_t *data,
size_t data_size,
size_t *data_length);
psa_status_t sli_se_opaque_import_key(const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
psa_status_t sli_se_opaque_generate_key(const psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length);
psa_status_t sli_se_opaque_export_public_key(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
uint8_t *data,
size_t data_size,
size_t *data_length);
psa_status_t sli_se_opaque_get_builtin_key(psa_drv_slot_number_t slot_number,
psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length);
psa_status_t sli_se_opaque_copy_key(const psa_key_attributes_t *attributes,
const uint8_t *source_key,
size_t source_key_length,
uint8_t *target_key_buffer,
size_t target_key_buffer_size,
size_t *target_key_buffer_length);
//------------------------------------------------------------------------------
// MAC
psa_status_t sli_se_opaque_mac_compute(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t sli_se_opaque_mac_sign_setup(
sli_se_opaque_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_mac_verify_setup(
sli_se_opaque_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_mac_update(sli_se_opaque_mac_operation_t *operation,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_opaque_mac_sign_finish(
sli_se_opaque_mac_operation_t *operation,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t sli_se_opaque_mac_verify_finish(
sli_se_opaque_mac_operation_t *operation,
const uint8_t *mac,
size_t mac_length);
psa_status_t sli_se_opaque_mac_abort(sli_se_opaque_mac_operation_t *operation);
//------------------------------------------------------------------------------
// Signature
psa_status_t sli_se_opaque_sign_message(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
psa_status_t sli_se_opaque_verify_message(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
const uint8_t *signature,
size_t signature_length);
psa_status_t sli_se_opaque_sign_hash(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
psa_status_t sli_se_opaque_verify_hash(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length);
//------------------------------------------------------------------------------
// AEAD
psa_status_t sli_se_opaque_aead_encrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
psa_status_t sli_se_opaque_aead_decrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
psa_status_t sli_se_opaque_aead_encrypt_setup(
sli_se_opaque_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_aead_decrypt_setup(
sli_se_opaque_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_aead_set_nonce(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *nonce,
size_t nonce_size);
psa_status_t sli_se_opaque_aead_set_lengths(
sli_se_opaque_aead_operation_t *operation,
size_t ad_length,
size_t plaintext_length);
psa_status_t sli_se_opaque_aead_update_ad(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_opaque_aead_update(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_opaque_aead_finish(
sli_se_opaque_aead_operation_t *operation,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length);
psa_status_t sli_se_opaque_aead_verify(
sli_se_opaque_aead_operation_t *operation,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length,
const uint8_t *tag,
size_t tag_length);
psa_status_t sli_se_opaque_aead_abort(
sli_se_opaque_aead_operation_t *operation);
//------------------------------------------------------------------------------
// Cipher
psa_status_t sli_se_opaque_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *iv,
size_t iv_length,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_opaque_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_opaque_cipher_encrypt_setup(
sli_se_opaque_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_cipher_decrypt_setup(
sli_se_opaque_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_opaque_cipher_set_iv(
sli_se_opaque_cipher_operation_t *operation,
const uint8_t *iv,
size_t iv_length);
psa_status_t sli_se_opaque_cipher_update(
sli_se_opaque_cipher_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_opaque_cipher_finish(
sli_se_opaque_cipher_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_opaque_cipher_abort(
sli_se_opaque_cipher_operation_t *operation);
//------------------------------------------------------------------------------
// Key agreement
psa_status_t sli_se_opaque_key_agreement(psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_OPAQUE_FUNCTIONS_H

View File

@@ -0,0 +1,160 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver API Internal Types for SE.
*******************************************************************************
* # 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 SLI_SE_OPAQUE_TYPES_H
#define SLI_SE_OPAQUE_TYPES_H
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sl_se_manager_defines.h"
#include "sl_se_manager_types.h"
#include "sl_psa_values.h"
#include "sli_se_driver_aead.h"
#include "sli_se_driver_mac.h"
#include "sli_se_driver_key_derivation.h"
#include "sli_se_driver_cipher.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
#include "psa/crypto_platform.h"
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se PSA drivers for devices with Secure Engine
* \{
******************************************************************************/
// -----------------------------------------------------------------------------
// Defines
/// Location value for keys to be stored encrypted with the device-unique secret,
/// or for accessing the built-in keys on Vault devices. Kept for backward
/// compatibility reasons. Users should use SL_PSA_KEY_LOCATION_WRAPPED or
/// SL_PSA_KEY_LOCATION_BUILTIN instead.
#define PSA_KEY_LOCATION_SLI_SE_OPAQUE ((psa_key_location_t)0x000001UL)
/// Version of opaque header struct
#define SLI_SE_OPAQUE_KEY_CONTEXT_VERSION (0x01)
// -----------------------------------------------------------------------------
// Types
#if defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
/// Key header for context struct of opaque registered keys
typedef struct {
/// Version field for the struct
uint8_t struct_version;
/// Builtin key ID. Set to zero for a key header which is part of a \ref
/// sli_se_opaque_wrapped_key_context_t, otherwise set to an SE Manager builtin
/// key ID.
uint8_t builtin_key_id;
/// Reserved space (initialise to all-zero)
uint8_t reserved[2];
} sli_se_opaque_key_context_header_t;
/// Key context for wrapped keys
typedef struct {
/// Key context header
sli_se_opaque_key_context_header_t header;
/// Key information required to construct an SE manager key descriptor
// sl_se_key_descriptor_t key_desc;
uint32_t key_type;
uint32_t key_size;
uint32_t key_flags;
/// wrapped_buffer is set to a distinctive size to make sizeof() result
/// in the overhead for storing a wrapped key.
/// A wrapped key will in reality consume more space than
/// SLI_SE_WRAPPED_KEY_OVERHEAD
uint8_t wrapped_buffer[SLI_SE_WRAPPED_KEY_OVERHEAD];
/// Variable member, accounting for the extra space
uint8_t fill[];
} sli_se_opaque_wrapped_key_context_t;
// Notes for JSON entry for wrapped driver:
// "base_size": "sizeof(sli_se_opaque_wrapped_key_context_t)",
// "symmetric_factor": 1,
// "key_pair_size": 66,
// "public_key_size" 133
// Is 66/133 the largest keys we accept? What about custom curves?
// ----------------------------------
// Potential format for internal volatile keys
// typedef struct {
// sl_se_key_descriptor_t key_desc;
// } sli_se_opaque_volatile_key_context;
// Notes for JSON entry for internal volatile driver:
// "base_size": "sizeof(sli_se_opaque_volatile_key_context)",
// For the remaining entries, the defaults are fine.
typedef struct {
sl_se_key_descriptor_t key_desc;
#if defined(PSA_WANT_ALG_HMAC)
uint8_t key[SLI_SE_WRAPPED_KEY_OVERHEAD + 64];
#else
uint8_t key[SLI_SE_WRAPPED_KEY_OVERHEAD + 32];
#endif
size_t key_len;
sli_se_driver_mac_operation_t operation;
} sli_se_opaque_mac_operation_t;
typedef struct {
uint8_t key[SLI_SE_WRAPPED_KEY_OVERHEAD + 32];
size_t key_len;
sli_se_driver_aead_operation_t operation;
} sli_se_opaque_aead_operation_t;
typedef struct {
uint8_t key[SLI_SE_WRAPPED_KEY_OVERHEAD + 32];
size_t key_len;
sli_se_driver_cipher_operation_t operation;
} sli_se_opaque_cipher_operation_t;
#endif // SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_OPAQUE_TYPES_H

View File

@@ -0,0 +1,400 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver functions for SE.
*******************************************************************************
* # 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 SLI_SE_TRANSPARENT_FUNCTIONS_H
#define SLI_SE_TRANSPARENT_FUNCTIONS_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se CRYPTOACC transparent PSA driver
* \brief Driver plugin for Silicon Labs SE peripheral adhering to the PSA
* transparent accelerator specification.
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sli_se_transparent_types.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
/* NOTE: This header file will be autogenerated by PSA Crypto build system based
* on the definitions in sli_se_transparent_driver.json. However, until such a
* system is in place, we rely on manually writing the file */
#ifdef __cplusplus
extern "C" {
#endif
//------------------------------------------------------------------------------
// General
psa_status_t sli_se_transparent_driver_init(void);
psa_status_t sli_se_transparent_driver_deinit(void);
//------------------------------------------------------------------------------
// Hashing
psa_status_t sli_se_transparent_hash_setup(
sli_se_transparent_hash_operation_t *operation,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_hash_update(
sli_se_transparent_hash_operation_t *operation,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_transparent_hash_finish(
sli_se_transparent_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
psa_status_t sli_se_transparent_hash_abort(
sli_se_transparent_hash_operation_t *operation);
psa_status_t sli_se_transparent_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *hash,
size_t hash_size,
size_t *hash_length);
psa_status_t sli_se_transparent_hash_clone(
const sli_se_transparent_hash_operation_t *source_operation,
sli_se_transparent_hash_operation_t *target_operation);
//------------------------------------------------------------------------------
// Cipher
psa_status_t sli_se_transparent_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *iv,
size_t iv_length,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_transparent_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_transparent_cipher_encrypt_setup(
sli_se_transparent_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_cipher_decrypt_setup(
sli_se_transparent_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_cipher_set_iv(
sli_se_transparent_cipher_operation_t *operation,
const uint8_t *iv,
size_t iv_length);
psa_status_t sli_se_transparent_cipher_update(
sli_se_transparent_cipher_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_transparent_cipher_abort(
sli_se_transparent_cipher_operation_t *operation);
psa_status_t sli_se_transparent_cipher_finish(
sli_se_transparent_cipher_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length);
//------------------------------------------------------------------------------
// Signature
psa_status_t sli_se_transparent_sign_message(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
psa_status_t sli_se_transparent_verify_message(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
const uint8_t *signature,
size_t signature_length);
psa_status_t sli_se_transparent_sign_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
uint8_t *signature,
size_t signature_size,
size_t *signature_length);
psa_status_t sli_se_transparent_verify_hash(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *hash,
size_t hash_length,
const uint8_t *signature,
size_t signature_length);
//------------------------------------------------------------------------------
// MAC
psa_status_t sli_se_transparent_mac_compute(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t sli_se_transparent_mac_sign_setup(
sli_se_transparent_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_mac_verify_setup(
sli_se_transparent_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_mac_update(
sli_se_transparent_mac_operation_t *operation,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_transparent_mac_sign_finish(
sli_se_transparent_mac_operation_t *operation,
uint8_t *mac,
size_t mac_size,
size_t *mac_length);
psa_status_t sli_se_transparent_mac_verify_finish(
sli_se_transparent_mac_operation_t *operation,
const uint8_t *mac,
size_t mac_length);
psa_status_t sli_se_transparent_mac_abort(
sli_se_transparent_mac_operation_t *operation);
//------------------------------------------------------------------------------
// AEAD
psa_status_t sli_se_transparent_aead_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length);
psa_status_t sli_se_transparent_aead_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length);
psa_status_t sli_se_transparent_aead_encrypt_setup(
sli_se_transparent_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_aead_decrypt_setup(
sli_se_transparent_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg);
psa_status_t sli_se_transparent_aead_set_nonce(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *nonce,
size_t nonce_length);
psa_status_t sli_se_transparent_aead_set_lengths(
sli_se_transparent_aead_operation_t *operation,
size_t ad_length,
size_t plaintext_length);
psa_status_t sli_se_transparent_aead_update_ad(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *input,
size_t input_length);
psa_status_t sli_se_transparent_aead_update(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
psa_status_t sli_se_transparent_aead_finish(
sli_se_transparent_aead_operation_t *operation,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length);
psa_status_t sli_se_transparent_aead_verify(
sli_se_transparent_aead_operation_t *operation,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length,
const uint8_t *tag,
size_t tag_length);
psa_status_t sli_se_transparent_aead_abort(
sli_se_transparent_aead_operation_t *operation);
//------------------------------------------------------------------------------
// Key handling
psa_status_t sli_se_transparent_generate_key(
const psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *output_length);
psa_status_t sli_se_transparent_export_public_key(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
uint8_t *data,
size_t data_size,
size_t *data_length);
psa_status_t sli_se_transparent_import_key(
const psa_key_attributes_t *attributes,
const uint8_t *data,
size_t data_length,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length,
size_t *bits);
//------------------------------------------------------------------------------
// Key agreement
psa_status_t sli_se_transparent_key_agreement(
psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length);
#ifdef __cplusplus
}
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_TRANSPARENT_FUNCTIONS_H

View File

@@ -0,0 +1,117 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver API Types for SE.
*******************************************************************************
* # 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 SLI_SE_TRANSPARENT_TYPES_H
#define SLI_SE_TRANSPARENT_TYPES_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* \addtogroup sl_psa_drivers
* \{
******************************************************************************/
/***************************************************************************//**
* \addtogroup sl_psa_drivers_se
* \{
******************************************************************************/
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sl_se_manager_types.h"
#include "sli_se_driver_aead.h"
#include "sli_se_driver_mac.h"
#include "sli_se_driver_cipher.h"
// Replace inclusion of crypto_driver_common.h with the new psa driver interface
// header file when it becomes available.
#include "psa/crypto_driver_common.h"
// -----------------------------------------------------------------------------
// Types
#define PSA_KEY_LOCATION_SLI_SE_TRANSPARENT ((psa_key_location_t)0x000002UL)
/// PSA transparent accelerator driver compatible context structure
typedef struct {
sl_se_hash_type_t hash_type; ///< Hash type
union {
sl_se_sha1_multipart_context_t sha1_context;
sl_se_sha224_multipart_context_t sha224_context;
sl_se_sha256_multipart_context_t sha256_context;
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
sl_se_sha384_multipart_context_t sha384_context;
sl_se_sha512_multipart_context_t sha512_context;
#endif
} streaming_contexts;
} sli_se_transparent_hash_operation_t;
typedef struct {
uint8_t key[32];
size_t key_len;
sli_se_driver_cipher_operation_t operation;
} sli_se_transparent_cipher_operation_t;
typedef union {
struct {
sli_se_driver_mac_operation_t operation;
uint8_t key[32];
size_t key_len;
} cipher_mac;
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
struct {
psa_algorithm_t alg;
sli_se_transparent_hash_operation_t hash_ctx;
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
uint8_t opad[128];
#else
uint8_t opad[64];
#endif
} hmac;
#endif /* SLI_PSA_DRIVER_FEATURE_HMAC */
} sli_se_transparent_mac_operation_t;
typedef struct {
uint8_t key[32];
size_t key_len;
sli_se_driver_aead_operation_t operation;
} sli_se_transparent_aead_operation_t;
#endif // SLI_MBEDTLS_DEVICE_HSE
/** \} (end addtogroup sl_psa_drivers_se) */
/** \} (end addtogroup sl_psa_drivers) */
/// @endcond
#endif // SLI_SE_TRANSPARENT_TYPES_H

View File

@@ -0,0 +1,141 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Driver SE Version Dependencies.
*******************************************************************************
* # 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 SLI_SE_VERSION_DEPENDENCIES_H
#define SLI_SE_VERSION_DEPENDENCIES_H
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
#include "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sl_se_manager_types.h"
#endif
// -----------------------------------------------------------------------------
// Version Constants
// HSE specific constants
#if defined(SLI_MBEDTLS_DEVICE_HSE)
// The oldest firmware revision with support for checking the validity
// of public ECC keys. Also see SL_SE_SUPPORT_FW_PRIOR_TO_1_2_2 and
// SL_SE_ASSUME_FW_AT_LEAST_1_2_2.
#if !defined(SLI_SE_OLDEST_VERSION_WITH_PUBLIC_KEY_VALIDATION)
#define SLI_SE_OLDEST_VERSION_WITH_PUBLIC_KEY_VALIDATION (0x00010202U)
#endif
// The SE version that first introduced a regression related to Ed25519. See
// SL_SE_ASSUME_FW_UNAFFECTED_BY_ED25519_ERRATA.
#if !defined(SLI_SE_FIRST_VERSION_WITH_BROKEN_ED25519)
#define SLI_SE_FIRST_VERSION_WITH_BROKEN_ED25519 (0x00010202U)
#endif
// The final SE version containing a bug causing Ed25519 to be broken. See
// SL_SE_ASSUME_FW_UNAFFECTED_BY_ED25519_ERRATA.
#if !defined(SLI_SE_LAST_VERSION_WITH_BROKEN_ED25519)
#define SLI_SE_LAST_VERSION_WITH_BROKEN_ED25519 (0x00010208U)
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
// Common HSE/VSE constants
// The first SE version that supports TrustZone Storage Root Key (SRK)
#if !defined(SLI_SE_FIRST_VERSION_WITH_SRK_SUPPORT)
#if defined(SLI_MBEDTLS_DEVICE_SE_V2)
#define SLI_SE_FIRST_VERSION_WITH_SRK_SUPPORT (0x00020200)
#else
#define SLI_SE_FIRST_VERSION_WITH_SRK_SUPPORT (0x0001020c)
#endif
#endif
// -----------------------------------------------------------------------------
// Preprocessor Guard Helper Defines
// -------------------------------
// ECDH
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#if !SL_SE_ASSUME_FW_AT_LEAST_1_2_2 && defined(SLI_MBEDTLS_DEVICE_HSE_V1)
#define SLI_SE_VERSION_ECDH_PUBKEY_VALIDATION_UNCERTAIN
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
// -------------------------------
// EdDSA
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#if !SL_SE_ASSUME_FW_UNAFFECTED_BY_ED25519_ERRATA \
&& defined(SLI_MBEDTLS_DEVICE_HSE_V1)
#define SLI_SE_VERSION_ED25519_ERRATA_UNCERTAIN
#endif
#if defined(SLI_SE_VERSION_ED25519_ERRATA_UNCERTAIN) \
&& defined(SLI_PSA_DRIVER_FEATURE_EDWARDS25519)
#define SLI_SE_VERSION_ED25519_ERRATA_CHECK_REQUIRED
#endif
#endif // SLI_MBEDTLS_DEVICE_HSE
// -----------------------------------------------------------------------------
// Version macros
// HSE specific macros
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#define SLI_SE_VERSION_PUBKEY_VALIDATION_REQUIRED(se_version) \
(se_version < SLI_SE_OLDEST_VERSION_WITH_PUBLIC_KEY_VALIDATION)
#define SLI_SE_VERSION_ED25519_BROKEN(se_version) \
(!((se_version < SLI_SE_FIRST_VERSION_WITH_BROKEN_ED25519) \
|| (se_version > SLI_SE_LAST_VERSION_WITH_BROKEN_ED25519)))
#endif // SLI_MBEDTLS_DEVICE_HSE
// Common HSE/VSE macros
#define SLI_VERSION_REMOVE_DIE_ID(version) ((version) & 0x00FFFFFFU)
#define SLI_SE_VERSION_SUPPORTS_SRK(se_version) \
(SLI_VERSION_REMOVE_DIE_ID(se_version) >= SLI_SE_FIRST_VERSION_WITH_SRK_SUPPORT)
// -----------------------------------------------------------------------------
// Function declarations
#ifdef __cplusplus
extern "C" {
#endif
psa_status_t sli_se_check_eddsa_errata(const psa_key_attributes_t* attributes,
sl_se_command_context_t* cmd_ctx);
#ifdef __cplusplus
}
#endif
/// @endcond
#endif // SLI_SE_VERSION_DEPENDENCIES_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/***************************************************************************/ /**
* @file
* @brief PSA Driver common utility functions
*******************************************************************************
* # License
* <b>Copyright 2021 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_psa_driver_common.h"
#include "constant_time_internal.h"
#include "constant_time_impl.h"
//------------------------------------------------------------------------------
// Function definitions
psa_status_t sli_psa_validate_pkcs7_padding(uint8_t *padded_data,
size_t padded_data_length,
size_t *padding_bytes)
{
size_t i, pad_idx;
unsigned char padding_len;
padding_len = padded_data[padded_data_length - 1];
*padding_bytes = padding_len;
mbedtls_ct_condition_t bad =
mbedtls_ct_uint_gt(padding_len, padded_data_length);
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_uint_eq(padding_len, 0));
// The number of bytes checked must be independent of padding_len, so pick
// input_len, which is 16 bytes (one block) for our use cases.
pad_idx = padded_data_length - padding_len;
for (i = 0; i < padded_data_length; i++) {
mbedtls_ct_condition_t in_padding = mbedtls_ct_uint_ge(i, pad_idx);
mbedtls_ct_condition_t different =
mbedtls_ct_uint_ne(padded_data[i], padding_len);
bad = mbedtls_ct_bool_or(bad, mbedtls_ct_bool_and(in_padding, different));
}
return (psa_status_t)mbedtls_ct_error_if_else_0(bad,
PSA_ERROR_INVALID_PADDING);
}

View File

@@ -0,0 +1,114 @@
/***************************************************************************//**
* @file
* @brief PSA Driver initialization interface.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#include "psa/crypto.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sli_se_transparent_functions.h"
#include "sl_se_manager.h"
#include "sli_se_opaque_functions.h"
#endif // SLI_MBEDTLS_DEVICE_HSE
#if defined(SLI_MBEDTLS_DEVICE_VSE)
#include "sli_cryptoacc_transparent_functions.h"
#include "cryptoacc_management.h"
#endif // SLI_MBEDTLS_DEVICE_VSE
// -----------------------------------------------------------------------------
// Driver entry points
#if defined(SLI_MBEDTLS_DEVICE_HSE)
psa_status_t sli_se_transparent_driver_init(void)
{
sl_status_t sl_status = sl_se_init();
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return PSA_SUCCESS;
}
psa_status_t sli_se_transparent_driver_deinit(void)
{
sl_status_t sl_status = sl_se_deinit();
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return PSA_SUCCESS;
}
#if defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
psa_status_t sli_se_opaque_driver_init(void)
{
sl_status_t sl_status = sl_se_init();
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return PSA_SUCCESS;
}
psa_status_t sli_se_opaque_driver_deinit(void)
{
sl_status_t sl_status = sl_se_deinit();
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS
#elif defined(SLI_MBEDTLS_DEVICE_VSE)
psa_status_t sli_cryptoacc_transparent_driver_init(void)
{
// Consider moving the clock init and etc. here, which is performed by the
// management functions.
#if defined(SLI_MBEDTLS_DEVICE_VSE_V2)
return cryptoacc_initialize_countermeasures();
#else
return PSA_SUCCESS;
#endif
}
psa_status_t sli_cryptoacc_transparent_driver_deinit(void)
{
return PSA_SUCCESS;
}
#endif

View File

@@ -0,0 +1,160 @@
/***************************************************************************//**
* @file
* @brief Default PSA TRNG hook for Silicon Labs devices.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
#include "psa/crypto.h"
#include "psa/crypto_extra.h"
#include "psa/crypto_platform.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sl_se_manager.h"
#include "sl_se_manager_entropy.h"
#elif defined(SLI_MBEDTLS_DEVICE_VSE)
#include "sli_cryptoacc_driver_trng.h"
#elif defined(SLI_TRNG_DEVICE_SI91X)
#include "sl_si91x_psa_trng.h"
#endif
// -----------------------------------------------------------------------------
// Typedefs
#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
typedef void mbedtls_psa_external_random_context_t;
#endif
// -----------------------------------------------------------------------------
// Static functions
#if defined(SLI_MBEDTLS_DEVICE_HSE)
static psa_status_t se_get_random(unsigned char *output,
size_t len,
size_t *out_len)
{
sl_status_t ret;
sl_se_command_context_t cmd_ctx;
// Initialize the SE manager.
ret = sl_se_init();
if (ret != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
// Initialize command context
ret = sl_se_init_command_context(&cmd_ctx);
if (ret != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
// Get entropy
ret = sl_se_get_random(&cmd_ctx, output, len);
if (ret == SL_STATUS_OK) {
*out_len = len;
return PSA_SUCCESS;
}
*out_len = 0;
return PSA_ERROR_HARDWARE_FAILURE;
}
#endif // SLI_MBEDTLS_DEVICE_HSE
// -----------------------------------------------------------------------------
// Global entry points
psa_status_t mbedtls_psa_external_get_random(
mbedtls_psa_external_random_context_t *context,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
(void)context;
#if defined(SLI_PSA_DRIVER_FEATURE_TRNG)
psa_status_t entropy_status = PSA_ERROR_CORRUPTION_DETECTED;
*output_length = 0;
#if defined(SLI_MBEDTLS_DEVICE_HSE)
entropy_status = se_get_random(output,
output_size,
output_length);
#elif defined(SLI_MBEDTLS_DEVICE_VSE)
entropy_status = sli_cryptoacc_trng_get_random(output, output_size);
if (entropy_status == PSA_SUCCESS) {
*output_length = output_size;
}
#else
size_t entropy_max_retries = 5;
while (entropy_max_retries > 0 && entropy_status != PSA_SUCCESS) {
size_t offset = *output_length;
// Read random bytes
#if defined(SLI_TRNG_DEVICE_SI91X)
entropy_status = sl_si91x_psa_get_random(&output[offset],
output_size - offset,
output_length);
#endif
*output_length += offset;
if (*output_length >= output_size) {
entropy_status = PSA_SUCCESS;
}
// Consume a retry before going through another loop
entropy_max_retries--;
}
#endif
return entropy_status;
#else // SLI_PSA_DRIVER_FEATURE_TRNG
(void) output;
(void) output_size;
(void) output_length;
return PSA_ERROR_HARDWARE_FAILURE;
#endif // SLI_PSA_DRIVER_FEATURE_TRNG
}
#endif // MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG || MBEDTLS_ENTROPY_HARDWARE_ALT

View File

@@ -0,0 +1,170 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Driver Builtin key functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include <psa/crypto.h>
#include "sli_se_opaque_types.h"
#include "sl_psa_values.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Driver entry points
#if defined(SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS)
psa_status_t sli_se_opaque_get_builtin_key(psa_drv_slot_number_t slot_number,
psa_key_attributes_t *attributes,
uint8_t *key_buffer,
size_t key_buffer_size,
size_t *key_buffer_length)
{
sli_se_opaque_key_context_header_t header;
memset(&header, 0, sizeof(header));
// Set key type and permissions according to key ID
switch ( slot_number ) {
#if defined(SLI_PSA_DRIVER_FEATURE_ATTESTATION)
case SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY:
psa_set_key_bits(attributes, 256);
psa_set_key_type(attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) );
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
break;
case SL_SE_KEY_SLOT_SE_ATTESTATION_KEY:
psa_set_key_bits(attributes, 256);
psa_set_key_type(attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1) );
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
break;
#endif // SLI_PSA_DRIVER_FEATURE_ATTESTATION
case SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY:
psa_set_key_bits(attributes, 256);
psa_set_key_type(attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1) );
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
break;
case SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY:
psa_set_key_bits(attributes, 256);
psa_set_key_type(attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1) );
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(attributes, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));
break;
case SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY:
psa_set_key_bits(attributes, 128);
psa_set_key_type(attributes, PSA_KEY_TYPE_AES);
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(attributes, SL_SE_BUILTIN_KEY_AES128_ALG);
break;
case SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY:
psa_set_key_bits(attributes, 256);
psa_set_key_type(attributes, PSA_KEY_TYPE_AES);
psa_set_key_usage_flags(attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
psa_set_key_algorithm(attributes, PSA_ALG_CMAC);
break;
default:
return(PSA_ERROR_DOES_NOT_EXIST);
}
psa_set_key_lifetime(attributes,
PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_PERSISTENCE_READ_ONLY,
PSA_KEY_LOCATION_SLI_SE_OPAQUE) );
// Check the key buffer size after populating the key attributes:
// From mbedTLS, psa-driver-interface.md (snippet):
//
// This entry point may return the following status values:
// (...)
// * PSA_ERROR_BUFFER_TOO_SMALL: key_buffer_size is insufficient.
// In this case, the driver must pass the key's attributes in
// *attributes. In particular, get_builtin_key(slot_number,
// &attributes, NULL, 0) is a way for the core to obtain the
// key's attributes.
if (key_buffer_size < sizeof(sli_se_opaque_key_context_header_t)) {
return(PSA_ERROR_BUFFER_TOO_SMALL);
}
header.struct_version = SLI_SE_OPAQUE_KEY_CONTEXT_VERSION;
header.builtin_key_id = (uint8_t) slot_number;
memcpy(key_buffer, &header, sizeof(sli_se_opaque_key_context_header_t));
*key_buffer_length = sizeof(sli_se_opaque_key_context_header_t);
return(PSA_SUCCESS);
}
#if !defined(PSA_CRYPTO_DRIVER_TEST)
psa_status_t mbedtls_psa_platform_get_builtin_key(
mbedtls_svc_key_id_t key_id,
psa_key_lifetime_t *lifetime,
psa_drv_slot_number_t *slot_number)
{
switch (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(key_id)) {
#if defined(SLI_PSA_DRIVER_FEATURE_ATTESTATION)
case SL_SE_BUILTIN_KEY_APPLICATION_ATTESTATION_ID:
*slot_number = SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY;
break;
case SL_SE_BUILTIN_KEY_SYSTEM_ATTESTATION_ID:
*slot_number = SL_SE_KEY_SLOT_SE_ATTESTATION_KEY;
break;
#endif // SLI_PSA_DRIVER_FEATURE_ATTESTATION
case SL_SE_BUILTIN_KEY_SECUREBOOT_ID:
*slot_number = SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY;
break;
case SL_SE_BUILTIN_KEY_SECUREDEBUG_ID:
*slot_number = SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY;
break;
case SL_SE_BUILTIN_KEY_AES128_ID:
*slot_number = SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY;
break;
case SL_SE_BUILTIN_KEY_TRUSTZONE_ID:
*slot_number = SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY;
break;
default:
return(PSA_ERROR_DOES_NOT_EXIST);
}
*lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
PSA_KEY_PERSISTENCE_READ_ONLY,
PSA_KEY_LOCATION_SLI_SE_OPAQUE);
return(PSA_SUCCESS);
}
#endif // !PSA_CRYPTO_DRIVER_TEST
#endif // SLI_PSA_DRIVER_FEATURE_BUILTIN_KEYS
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,589 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Driver Key Derivation functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sli_psa_driver_common.h" // sli_psa_zeroize()
#include "sli_se_opaque_functions.h"
#include "sli_se_driver_key_management.h"
#include "sli_se_driver_key_derivation.h"
#include "sli_se_version_dependencies.h"
#include "psa/crypto.h"
#include "sl_se_manager.h"
#include "sl_se_manager_key_derivation.h"
#include "sl_se_manager_util.h"
#include "sli_se_manager_internal.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Custom SL PSA driver entry points
#if defined(SLI_PSA_DRIVER_FEATURE_HKDF)
psa_status_t sli_se_driver_single_shot_hkdf(
psa_algorithm_t alg,
const psa_key_attributes_t *key_in_attributes,
const uint8_t *key_in_buffer,
size_t key_in_buffer_size,
const uint8_t* info,
size_t info_length,
const uint8_t* salt,
size_t salt_length,
const psa_key_attributes_t *key_out_attributes,
uint8_t *key_out_buffer,
size_t key_out_buffer_size)
{
// This driver function will not be called unless alg is of HKDF type.
sl_se_hash_type_t sl_hash_alg = SL_SE_HASH_NONE;
psa_algorithm_t psa_hash_alg = PSA_ALG_HKDF_GET_HASH(alg);
switch (psa_hash_alg) {
case PSA_ALG_SHA_1:
sl_hash_alg = SL_SE_HASH_SHA1;
break;
case PSA_ALG_SHA_224:
sl_hash_alg = SL_SE_HASH_SHA224;
break;
case PSA_ALG_SHA_256:
sl_hash_alg = SL_SE_HASH_SHA256;
break;
case PSA_ALG_SHA_384:
sl_hash_alg = SL_SE_HASH_SHA384;
break;
case PSA_ALG_SHA_512:
sl_hash_alg = SL_SE_HASH_SHA512;
break;
default:
return PSA_ERROR_NOT_SUPPORTED;
}
// Create input key descriptor.
sl_se_key_descriptor_t key_in_desc = { 0 };
psa_status_t psa_status = sli_se_key_desc_from_input(key_in_attributes,
key_in_buffer,
key_in_buffer_size,
&key_in_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
size_t key_out_size = PSA_BITS_TO_BYTES(psa_get_key_bits(key_out_attributes));
// Check that we don't request more than 255 times the hash digest size.
// This limitation comes from RFC-5869.
if (key_out_size > 255 * PSA_HASH_LENGTH(psa_hash_alg)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Create output key descriptor.
sl_se_key_descriptor_t key_out_desc = { 0 };
psa_status = sli_se_key_desc_from_psa_attributes(
key_out_attributes,
key_out_size,
&key_out_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
psa_status = sli_se_set_key_desc_output(key_out_attributes,
key_out_buffer,
key_out_buffer_size,
key_out_size,
&key_out_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Prepare SE command context.
sl_se_command_context_t cmd_ctx = { 0 };
sl_status_t sl_status = sl_se_init_command_context(&cmd_ctx);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Execute the SE command.
sl_status = sl_se_derive_key_hkdf(&cmd_ctx,
&key_in_desc,
sl_hash_alg,
salt,
salt_length,
info,
info_length,
&key_out_desc);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
} else {
psa_status = PSA_SUCCESS;
}
if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(key_out_attributes))
== PSA_KEY_LOCATION_SLI_SE_OPAQUE) {
// Add the key desc to the output array for opaque keys.
psa_status = store_key_desc_in_context(&key_out_desc,
key_out_buffer,
key_out_buffer_size);
}
return psa_status;
}
#endif // SLI_PSA_DRIVER_FEATURE_HKDF
#if defined(SLI_PSA_DRIVER_FEATURE_PBKDF2)
psa_status_t sli_se_driver_single_shot_pbkdf2(
psa_algorithm_t alg,
const psa_key_attributes_t *key_in_attributes,
const uint8_t *key_in_buffer,
size_t key_in_buffer_size,
const uint8_t* salt,
size_t salt_length,
const psa_key_attributes_t *key_out_attributes,
uint32_t iterations,
uint8_t *key_out_buffer,
size_t key_out_buffer_size)
{
sl_se_hash_type_t sl_prf = SL_SE_HASH_NONE;
psa_algorithm_t psa_hash_alg = PSA_ALG_GET_HASH(alg);
switch (psa_hash_alg) {
case PSA_ALG_SHA_1:
sl_prf = SL_SE_PRF_HMAC_SHA1;
break;
case PSA_ALG_SHA_224:
sl_prf = SL_SE_PRF_HMAC_SHA224;
break;
case PSA_ALG_SHA_256:
sl_prf = SL_SE_PRF_HMAC_SHA256;
break;
case PSA_ALG_SHA_384:
sl_prf = SL_SE_PRF_HMAC_SHA384;
break;
case PSA_ALG_SHA_512:
sl_prf = SL_SE_PRF_HMAC_SHA512;
break;
default:
if (alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) {
sl_prf = SL_SE_PRF_AES_CMAC_128;
break;
}
return PSA_ERROR_NOT_SUPPORTED;
}
// Create input key descriptor.
sl_se_key_descriptor_t key_in_desc = { 0 };
psa_status_t psa_status = sli_se_key_desc_from_input(key_in_attributes,
key_in_buffer,
key_in_buffer_size,
&key_in_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
size_t key_out_size = PSA_BITS_TO_BYTES(psa_get_key_bits(key_out_attributes));
if ( alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128 ) {
#define AES_CMAC_PRF_128_BLOCK_SIZE 128
// The out key length can atmost be 128 bits long.
if ( !key_out_size || (key_out_size > PSA_BITS_TO_BYTES(AES_CMAC_PRF_128_BLOCK_SIZE)) ) {
return PSA_ERROR_INVALID_ARGUMENT;
}
} else { // HMAC based
// In conformance with rfc 8018 (sec 5.2), max output length should not exceed
// 2 ^ 32 -1 * hlen.
// Our max key size is limited by type of key bits in attributes, so no further
// validation is necessary.Our key out size is narrower than the rfc specification.
if ( !key_out_size ) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
if ( !iterations ) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Create output key descriptor.
sl_se_key_descriptor_t key_out_desc = { 0 };
psa_status = sli_se_key_desc_from_psa_attributes(
key_out_attributes,
key_out_size,
&key_out_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
psa_status = sli_se_set_key_desc_output(key_out_attributes,
key_out_buffer,
key_out_buffer_size,
key_out_size,
&key_out_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Prepare SE command context.
sl_se_command_context_t cmd_ctx = { 0 };
sl_status_t sl_status = sl_se_init_command_context(&cmd_ctx);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Execute the SE command.
sl_status = sl_se_derive_key_pbkdf2(&cmd_ctx,
&key_in_desc,
sl_prf,
salt,
salt_length,
iterations,
&key_out_desc);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
} else {
psa_status = PSA_SUCCESS;
}
if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(key_out_attributes))
== PSA_KEY_LOCATION_SLI_SE_OPAQUE) {
// Add the key desc to the output array for opaque keys.
psa_status = store_key_desc_in_context(&key_out_desc,
key_out_buffer,
key_out_buffer_size);
}
return psa_status;
}
#endif // SLI_PSA_DRIVER_FEATURE_PBKDF2
// -----------------------------------------------------------------------------
// Driver entry points
psa_status_t sli_se_driver_key_agreement(psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_ECDH)
sl_se_key_descriptor_t priv_desc = { 0 };
sl_se_key_descriptor_t pub_desc = { 0 };
sl_se_key_descriptor_t shared_desc = { 0 };
sl_se_command_context_t cmd_ctx = SL_SE_COMMAND_CONTEXT_INIT;
sl_status_t sl_status = SL_STATUS_FAIL;
psa_status_t psa_status = PSA_ERROR_CORRUPTION_DETECTED;
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
size_t padding_bytes = 0;
uint8_t tmp_output_buf[SLI_SE_MAX_PADDED_ECP_PUBLIC_KEY_SIZE] = { 0 };
#else
uint8_t tmp_output_buf[SLI_SE_MAX_ECP_PUBLIC_KEY_SIZE] = { 0 };
#endif // SLI_SE_KEY_PADDING_REQUIRED
// Argument check.
if (attributes == NULL
|| key_buffer == NULL
|| peer_key == NULL
|| output == NULL
|| output_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_key_type_t key_type = psa_get_key_type(attributes);
size_t key_bits = psa_get_key_bits(attributes);
// Check that key_buffer contains private key.
if (PSA_KEY_TYPE_IS_PUBLIC_KEY(key_type)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Only accelerate ECDH.
if (!PSA_ALG_IS_ECDH(alg)) {
return PSA_ERROR_NOT_SUPPORTED;
}
// Check private key buffer.
if (key_buffer_size < PSA_BITS_TO_BYTES(key_bits)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Check sufficient output buffer size.
if (output_size < PSA_BITS_TO_BYTES(key_bits)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
#if defined(SLI_SE_VERSION_ECDH_PUBKEY_VALIDATION_UNCERTAIN)
sl_status = sl_se_init_command_context(&cmd_ctx);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
uint32_t se_version = 0;
sl_status = sl_se_get_se_version(&cmd_ctx, &se_version);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
se_version = SLI_VERSION_REMOVE_DIE_ID(se_version);
// External public key validation is required for older versions of SE FW.
if (SLI_SE_VERSION_PUBKEY_VALIDATION_REQUIRED(se_version)) {
#if defined(MBEDTLS_ECP_C) \
&& defined(MBEDTLS_PSA_CRYPTO_C) \
&& SL_SE_SUPPORT_FW_PRIOR_TO_1_2_2
psa_status = sli_se_driver_validate_pubkey_with_fallback(key_type,
key_bits,
peer_key,
peer_key_length);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
#else
// No fallback code is compiled in, cannot do public key validation.
return PSA_ERROR_NOT_SUPPORTED;
#endif
}
#endif // SLI_SE_VERSION_ECDH_PUBKEY_VALIDATION_UNCERTAIN
switch (key_type) {
#if defined(SLI_PSA_DRIVER_FEATURE_SECPR1)
case PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):
switch (key_bits) {
#if defined(SLI_PSA_DRIVER_FEATURE_P192R1)
case 192:
pub_desc.type = SL_SE_KEY_TYPE_ECC_P192;
break;
#endif // SLI_PSA_DRIVER_FEATURE_P192R1
#if defined(SLI_PSA_DRIVER_FEATURE_P224R1)
case 224:
pub_desc.type = SL_SE_KEY_TYPE_ECC_P224;
break;
#endif // SLI_PSA_DRIVER_FEATURE_P224R1
#if defined(SLI_PSA_DRIVER_FEATURE_P256R1)
case 256:
pub_desc.type = SL_SE_KEY_TYPE_ECC_P256;
break;
#endif // SLI_PSA_DRIVER_FEATURE_P256R1
#if defined(SLI_PSA_DRIVER_FEATURE_P384R1)
case 384:
pub_desc.type = SL_SE_KEY_TYPE_ECC_P384;
break;
#endif // SLI_PSA_DRIVER_FEATURE_P384R1
#if defined(SLI_PSA_DRIVER_FEATURE_P521R1)
case 521:
pub_desc.type = SL_SE_KEY_TYPE_ECC_P521;
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
padding_bytes = SLI_SE_P521_PADDING_BYTES;
#endif
break;
#endif // SLI_PSA_DRIVER_FEATURE_P521R1
default:
return PSA_ERROR_NOT_SUPPORTED;
}
// Set key descriptor attributes.
// If padding is required, the descriptor will be set later as part of
// the padding. If padding is not required, set the descriptor here.
if (pub_desc.type != 0
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
&& padding_bytes == 0
#endif
) {
sli_se_key_descriptor_set_plaintext(&pub_desc,
peer_key + 1,
peer_key_length - 1);
sli_se_key_descriptor_set_plaintext(&shared_desc,
tmp_output_buf,
sizeof(tmp_output_buf));
shared_desc.size = PSA_BITS_TO_BYTES(key_bits) * 2;
}
break;
#endif // SLI_PSA_DRIVER_FEATURE_SECPR1
#if defined(SLI_PSA_DRIVER_FEATURE_MONTGOMERY)
case PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):
// Check peer_key is of sufficient size.
if (peer_key_length < PSA_BITS_TO_BYTES(key_bits)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
switch (key_bits) {
#if defined(SLI_PSA_DRIVER_FEATURE_CURVE25519)
case 255:
pub_desc.type = SL_SE_KEY_TYPE_ECC_X25519;
break;
#endif // SLI_PSA_DRIVER_FEATURE_CURVE25519
#if defined(SLI_PSA_DRIVER_FEATURE_CURVE448)
case 448:
pub_desc.type = SL_SE_KEY_TYPE_ECC_X448;
break;
#endif // SLI_PSA_DRIVER_FEATURE_CURVE448
default:
return PSA_ERROR_NOT_SUPPORTED;
}
// Set key descriptor attributes.
sli_se_key_descriptor_set_plaintext(&pub_desc,
peer_key,
peer_key_length);
sli_se_key_descriptor_set_plaintext(&shared_desc,
output,
output_size);
shared_desc.size = PSA_BITS_TO_BYTES(key_bits);
break;
#endif // SLI_PSA_DRIVER_FEATURE_MONTGOMERY
default:
return PSA_ERROR_NOT_SUPPORTED;
}
// Generate a key descriptor for private key.
psa_status = sli_se_key_desc_from_input(attributes,
key_buffer,
key_buffer_size,
&priv_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Panther crypto engine requires alignment on word boundries instead of byte
// boundaries which is used in the PSA crypto API.
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
uint8_t tmp_priv_padded_buf[SLI_SE_MAX_PADDED_ECP_PRIVATE_KEY_SIZE] = { 0 };
uint8_t tmp_pub_padded_buf[SLI_SE_MAX_PADDED_ECP_PUBLIC_KEY_SIZE] = { 0 };
// Should currently only happen for curve P521.
if (padding_bytes > 0) {
// Can only do padding on non-wrapped keys.
if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes))
== PSA_KEY_LOCATION_LOCAL_STORAGE) {
// Pad private key.
sli_se_pad_big_endian(tmp_priv_padded_buf, key_buffer,
PSA_BITS_TO_BYTES(key_bits));
// Re-set key descriptor attributes.
sli_se_key_descriptor_set_plaintext(&priv_desc,
tmp_priv_padded_buf,
sizeof(tmp_priv_padded_buf));
}
// Pad public key.
sli_se_pad_curve_point(tmp_pub_padded_buf, peer_key + 1,
PSA_BITS_TO_BYTES(key_bits));
// Set key descriptor attributes.
sli_se_key_descriptor_set_plaintext(&pub_desc,
tmp_pub_padded_buf,
sizeof(tmp_pub_padded_buf));
sli_se_key_descriptor_set_plaintext(&shared_desc,
tmp_output_buf,
sizeof(tmp_output_buf));
shared_desc.size = (PSA_BITS_TO_BYTES(key_bits) + padding_bytes) * 2;
}
#endif // SLI_SE_KEY_PADDING_REQUIRED
// Set key descriptor attributes that are common to all supported curves.
pub_desc.flags |= SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY;
shared_desc.type = SL_SE_KEY_TYPE_SYMMETRIC;
// Re-init SE command context.
sl_status = sl_se_init_command_context(&cmd_ctx);
if (sl_status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
// Perform key agreement algorithm (ECDH).
sl_status = sl_se_ecdh_compute_shared_secret(&cmd_ctx,
&priv_desc,
&pub_desc,
&shared_desc);
if (sl_status != SL_STATUS_OK) {
if (sl_status == SL_STATUS_COMMAND_IS_INVALID) {
// This error will be returned if the key type isn't supported.
return PSA_ERROR_NOT_SUPPORTED;
} else {
// If the ECDH operation failed, this is most likely due to the peer key
// being an invalid elliptic curve point. Other sources for failure should
// hopefully have been caught during parameter validation.
return PSA_ERROR_INVALID_ARGUMENT;
}
}
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
// Remove padding bytes and clean up temporary key storage.
if (padding_bytes > 0) {
sli_se_unpad_curve_point(tmp_output_buf,
tmp_output_buf,
PSA_BITS_TO_BYTES(key_bits));
sli_psa_zeroize(tmp_priv_padded_buf, sizeof(tmp_priv_padded_buf));
}
#endif // SLI_SE_KEY_PADDING_REQUIRED
// Montgomery curve computations do not require the temporary buffer to store the y-coord.
if (key_type == PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)) {
memcpy(output, tmp_output_buf, PSA_BITS_TO_BYTES(key_bits));
sli_psa_zeroize(tmp_output_buf, sizeof(tmp_output_buf));
}
*output_length = PSA_BITS_TO_BYTES(key_bits);
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_ECDH
(void) attributes;
(void) key_buffer;
(void) peer_key;
(void) output;
(void) output_length;
(void) alg;
(void) key_buffer_size;
(void) peer_key_length;
(void) output_size;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_ECDH
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,582 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Driver Mac functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "sli_psa_driver_common.h" // sli_psa_zeroize()
#include "psa/crypto.h"
#include "mbedtls/platform.h"
#include "sli_se_driver_mac.h"
#include "sli_se_manager_internal.h"
#include "sli_se_driver_key_management.h"
#include "sli_psa_driver_common.h"
#include <string.h>
//------------------------------------------------------------------------------
// Static functions
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
sl_se_hash_type_t sli_se_hash_type_from_psa_hmac_alg(psa_algorithm_t alg,
size_t *length)
{
if (!PSA_ALG_IS_HMAC(alg)) {
return SL_SE_HASH_NONE;
}
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(alg);
switch (hash_alg) {
case PSA_ALG_SHA_1:
*length = 20;
return SL_SE_HASH_SHA1;
case PSA_ALG_SHA_224:
*length = 28;
return SL_SE_HASH_SHA224;
case PSA_ALG_SHA_256:
*length = 32;
return SL_SE_HASH_SHA256;
#if defined(SLI_MBEDTLS_DEVICE_HSE_VAULT_HIGH)
case PSA_ALG_SHA_384:
*length = 48;
return SL_SE_HASH_SHA384;
case PSA_ALG_SHA_512:
*length = 64;
return SL_SE_HASH_SHA512;
#endif
default:
return SL_SE_HASH_NONE;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
//------------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_driver_mac_compute(sl_se_key_descriptor_t *key_desc,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC)
if (mac == NULL
|| mac_length == NULL
|| key_desc == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
sl_status_t status;
psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
sl_se_command_context_t cmd_ctx = { 0 };
status = sl_se_init_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(alg)) {
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_STATE_64)
uint8_t tmp_hmac[64];
#else
uint8_t tmp_hmac[32];
#endif
size_t requested_length = 0;
sl_se_hash_type_t hash_type =
sli_se_hash_type_from_psa_hmac_alg(alg, &requested_length);
if (hash_type == SL_SE_HASH_NONE) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (PSA_MAC_TRUNCATED_LENGTH(alg) > requested_length) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (PSA_MAC_TRUNCATED_LENGTH(alg) > 0) {
requested_length = PSA_MAC_TRUNCATED_LENGTH(alg);
}
if (mac_size < requested_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
uint8_t *temp_key_buf = NULL;
uint32_t key_buffer_size = key_desc->storage.location.buffer.size;
size_t padding = sli_se_get_padding(key_buffer_size);
size_t word_aligned_buffer_size = 0;
if (padding > 0u) {
// We can only manipulate the transparent keys.
if (key_desc->storage.method == SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT) {
word_aligned_buffer_size
= sli_se_word_align(key_desc->storage.location.buffer.size);
temp_key_buf = mbedtls_calloc(1, word_aligned_buffer_size);
if (temp_key_buf == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
// Since we know that this must be a plaintext key, we can freely
// modify the key descriptor
memcpy(temp_key_buf,
key_desc->storage.location.buffer.pointer,
key_desc->storage.location.buffer.size);
key_desc->storage.location.buffer.pointer = temp_key_buf;
key_desc->storage.location.buffer.size = word_aligned_buffer_size;
}
}
#endif // SLI_SE_KEY_PADDING_REQUIRED
status = sl_se_hmac(&cmd_ctx,
key_desc,
hash_type,
input,
input_length,
tmp_hmac,
sizeof(tmp_hmac));
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
if (padding > 0u) {
sli_psa_zeroize(temp_key_buf, word_aligned_buffer_size);
mbedtls_free(temp_key_buf);
}
#endif // SLI_SE_KEY_PADDING_REQUIRED
if (status == PSA_SUCCESS) {
memcpy(mac, tmp_hmac, requested_length);
*mac_length = requested_length;
} else {
*mac_length = 0;
}
sli_psa_zeroize(tmp_hmac, sizeof(tmp_hmac));
goto exit;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC) \
&& (defined(SLI_PSA_DRIVER_FEATURE_CMAC) \
|| defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC))
else
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
{
size_t output_length = PSA_MAC_TRUNCATED_LENGTH(alg);
if (output_length == 0) {
output_length = 16;
} else if (output_length > 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (mac_size < output_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
switch (PSA_ALG_FULL_LENGTH_MAC(alg)) {
#if defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
case PSA_ALG_CBC_MAC: {
uint8_t tmp_buf[16] = { 0 };
uint8_t tmp_mac[16] = { 0 };
if (input_length % 16 != 0 || input_length < 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Do an AES-CBC encrypt with zero IV, keeping only the last block.
while (input_length > 0) {
status = sl_se_aes_crypt_cbc(&cmd_ctx,
key_desc,
SL_SE_ENCRYPT,
16,
tmp_mac,
input,
tmp_buf);
input_length -= 16;
input += 16;
}
// Copy the requested number of bytes (max 16) to the user buffer.
if (status == SL_STATUS_OK) {
memcpy(mac, tmp_mac, output_length);
sli_psa_zeroize(tmp_mac, sizeof(tmp_mac));
*mac_length = output_length;
}
goto exit;
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC)
case PSA_ALG_CMAC: {
uint8_t tmp_mac[16] = { 0 };
status = sl_se_cmac(&cmd_ctx,
key_desc,
input,
input_length,
tmp_mac);
// Copy the requested number of bytes (max 16) to the user buffer.
if (status == SL_STATUS_OK) {
memcpy(mac, tmp_mac, output_length);
sli_psa_zeroize(tmp_mac, sizeof(tmp_mac));
*mac_length = output_length;
}
goto exit;
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC
default:
return PSA_ERROR_NOT_SUPPORTED;
break;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
exit:
if (status == SL_STATUS_INVALID_PARAMETER) {
psa_status = PSA_ERROR_INVALID_ARGUMENT;
} else if (status == SL_STATUS_FAIL) {
psa_status = PSA_ERROR_DOES_NOT_EXIST;
} else if (status != SL_STATUS_OK) {
psa_status = PSA_ERROR_HARDWARE_FAILURE;
} else {
psa_status = PSA_SUCCESS;
}
// Cleanup
status = sl_se_deinit_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return psa_status;
#else // SLI_PSA_DRIVER_FEATURE_MAC
(void)key_desc;
(void)alg;
(void)input;
(void)input_length;
(void)mac;
(void)mac_size;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC
}
//------------------------------------------------------------------------------
// Multi-part driver entry points
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
psa_status_t sli_se_driver_mac_sign_setup(
sli_se_driver_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
psa_algorithm_t alg)
{
if (operation == NULL
|| attributes == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Start by resetting context
memset(operation, 0, sizeof(*operation));
switch (PSA_ALG_FULL_LENGTH_MAC(alg)) {
#if defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
case PSA_ALG_CBC_MAC:
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (PSA_MAC_TRUNCATED_LENGTH(alg) > 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
break;
#endif // SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC)
case PSA_ALG_CMAC:
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_AES) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (PSA_MAC_TRUNCATED_LENGTH(alg) > 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
break;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC
default:
return PSA_ERROR_NOT_SUPPORTED;
}
operation->alg = alg;
return PSA_SUCCESS;
}
psa_status_t sli_se_driver_mac_update(sli_se_driver_mac_operation_t *operation,
sl_se_key_descriptor_t *key_desc,
const uint8_t *input,
size_t input_length)
{
if (operation == NULL
|| (input == NULL && input_length > 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Ephemeral contexts
sl_se_command_context_t cmd_ctx = { 0 };
sl_status_t status = sl_se_init_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
psa_status_t psa_status = PSA_ERROR_NOT_SUPPORTED;
switch (PSA_ALG_FULL_LENGTH_MAC(operation->alg)) {
#if defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
case PSA_ALG_CBC_MAC:
if (input_length == 0) {
psa_status = PSA_SUCCESS;
goto exit;
}
// Add bytes to the streaming buffer up to the next block boundary
if (operation->ctx.cbcmac.processed_length % 16 != 0) {
size_t bytes_to_boundary
= 16 - operation->ctx.cbcmac.processed_length % 16;
if (input_length < bytes_to_boundary) {
memcpy(&operation->ctx.cbcmac.streaming_block[16 - bytes_to_boundary],
input,
input_length);
operation->ctx.cbcmac.processed_length += input_length;
psa_status = PSA_SUCCESS;
goto exit;
}
memcpy(&operation->ctx.cbcmac.streaming_block[16 - bytes_to_boundary],
input,
bytes_to_boundary);
input_length -= bytes_to_boundary;
input += bytes_to_boundary;
operation->ctx.cbcmac.processed_length += bytes_to_boundary;
status = sl_se_aes_crypt_cbc(&cmd_ctx,
key_desc,
SL_SE_ENCRYPT,
16,
operation->ctx.cbcmac.iv,
operation->ctx.cbcmac.streaming_block,
operation->ctx.cbcmac.iv);
if (status == SL_STATUS_FAIL) {
psa_status = PSA_ERROR_DOES_NOT_EXIST;
goto exit;
} else if (status != SL_STATUS_OK) {
psa_status = PSA_ERROR_HARDWARE_FAILURE;
goto exit;
}
}
// Draw all full blocks
while (input_length >= 16) {
status = sl_se_aes_crypt_cbc(&cmd_ctx,
key_desc,
SL_SE_ENCRYPT,
16,
operation->ctx.cbcmac.iv,
input,
operation->ctx.cbcmac.iv);
if (status != SL_STATUS_OK) {
psa_status = PSA_ERROR_HARDWARE_FAILURE;
goto exit;
}
operation->ctx.cbcmac.processed_length += 16;
input += 16;
input_length -= 16;
}
if (input_length > 0) {
memcpy(operation->ctx.cbcmac.streaming_block,
input,
input_length);
operation->ctx.cbcmac.processed_length += input_length;
}
psa_status = PSA_SUCCESS;
goto exit;
#endif // SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC)
case PSA_ALG_CMAC:
if (input_length == 0) {
psa_status = PSA_SUCCESS;
goto exit;
}
status = sl_se_cmac_multipart_update(&operation->ctx.cmac,
&cmd_ctx,
key_desc,
input,
input_length);
if (status == SL_STATUS_FAIL) {
psa_status = PSA_ERROR_DOES_NOT_EXIST;
goto exit;
} else if (status != SL_STATUS_OK) {
psa_status = PSA_ERROR_HARDWARE_FAILURE;
goto exit;
}
psa_status = PSA_SUCCESS;
goto exit;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC
default:
psa_status = PSA_ERROR_BAD_STATE;
goto exit;
}
exit:
// Cleanup
status = sl_se_deinit_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
return psa_status;
}
psa_status_t sli_se_driver_mac_sign_finish(
sli_se_driver_mac_operation_t *operation,
sl_se_key_descriptor_t *key_desc,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
if (operation == NULL
|| mac == NULL
|| mac_size == 0
|| mac_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Set maximum output size to 16 or truncated length
if (mac_size > 16) {
mac_size = 16;
}
size_t truncated_length = PSA_MAC_TRUNCATED_LENGTH(operation->alg);
if (truncated_length != 0
&& mac_size > truncated_length) {
mac_size = truncated_length;
}
switch (PSA_ALG_FULL_LENGTH_MAC(operation->alg)) {
#if defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
case PSA_ALG_CBC_MAC: {
(void)key_desc;
if (operation->ctx.cbcmac.processed_length % 16 != 0) {
return PSA_ERROR_BAD_STATE;
}
// Copy the requested number of bytes (max 16) to the user buffer.
memcpy(mac, operation->ctx.cbcmac.iv, mac_size);
*mac_length = mac_size;
return PSA_SUCCESS;
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC)
case PSA_ALG_CMAC: {
// Ephemeral contexts
sl_se_command_context_t cmd_ctx = { 0 };
uint8_t tmp_mac[16] = { 0 };
sl_status_t status = sl_se_init_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
status = sl_se_cmac_multipart_finish(&operation->ctx.cmac,
&cmd_ctx,
key_desc,
tmp_mac);
if (status != SL_STATUS_OK) {
*mac_length = 0;
return PSA_ERROR_HARDWARE_FAILURE;
}
// Cleanup
status = sl_se_deinit_command_context(&cmd_ctx);
if (status != SL_STATUS_OK) {
*mac_length = 0;
return PSA_ERROR_HARDWARE_FAILURE;
}
// Copy the requested number of bytes (max 16) to the user buffer.
memcpy(mac, tmp_mac, mac_size);
*mac_length = mac_size;
return PSA_SUCCESS;
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC
default:
return PSA_ERROR_BAD_STATE;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,278 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver AEAD functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
#include "psa/crypto.h"
#include "sli_se_opaque_types.h"
#include "sli_se_opaque_functions.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_opaque_aead_encrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length)
{
return sli_se_driver_aead_encrypt(attributes,
key_buffer,
key_buffer_size,
alg,
nonce,
nonce_length,
additional_data,
additional_data_length,
plaintext,
plaintext_length,
ciphertext,
ciphertext_size,
ciphertext_length);
}
psa_status_t sli_se_opaque_aead_decrypt(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length)
{
return sli_se_driver_aead_decrypt(attributes,
key_buffer,
key_buffer_size,
alg,
nonce,
nonce_length,
additional_data,
additional_data_length,
ciphertext,
ciphertext_length,
plaintext,
plaintext_size,
plaintext_length);
}
// -----------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_opaque_aead_encrypt_setup(
sli_se_opaque_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Start by resetting context
memset(operation, 0, sizeof(*operation));
// Setup generic context struct
return sli_se_driver_aead_encrypt_decrypt_setup(&(operation->operation),
attributes,
key_buffer,
key_buffer_size,
alg,
SL_SE_ENCRYPT,
operation->key,
sizeof(operation->key),
SLI_SE_WRAPPED_KEY_OVERHEAD);
}
psa_status_t sli_se_opaque_aead_decrypt_setup(
sli_se_opaque_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Start by resetting context
memset(operation, 0, sizeof(*operation));
// Setup generic context struct
return sli_se_driver_aead_encrypt_decrypt_setup(&(operation->operation),
attributes,
key_buffer,
key_buffer_size,
alg,
SL_SE_DECRYPT,
operation->key,
sizeof(operation->key),
SLI_SE_WRAPPED_KEY_OVERHEAD);
}
psa_status_t sli_se_opaque_aead_set_nonce(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *nonce,
size_t nonce_size)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_set_nonce(&(operation->operation),
nonce,
nonce_size);
}
psa_status_t sli_se_opaque_aead_set_lengths(
sli_se_opaque_aead_operation_t *operation,
size_t ad_length,
size_t plaintext_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_set_lengths(&(operation->operation),
ad_length,
plaintext_length);
}
psa_status_t sli_se_opaque_aead_update_ad(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_update_ad(&(operation->operation),
operation->key,
input,
input_length);
}
psa_status_t sli_se_opaque_aead_update(
sli_se_opaque_aead_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_update(&(operation->operation),
operation->key,
input,
input_length,
output,
output_size,
output_length);
}
psa_status_t sli_se_opaque_aead_finish(
sli_se_opaque_aead_operation_t *operation,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_finish(&(operation->operation),
operation->key,
ciphertext,
ciphertext_size,
ciphertext_length,
tag,
tag_size,
tag_length);
}
psa_status_t sli_se_opaque_aead_verify(
sli_se_opaque_aead_operation_t *operation,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length,
const uint8_t *tag,
size_t tag_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_verify(&(operation->operation),
operation->key,
plaintext,
plaintext_size,
plaintext_length,
tag,
tag_length);
}
psa_status_t sli_se_opaque_aead_abort(
sli_se_opaque_aead_operation_t *operation)
{
// No state is ever left in HW, so zeroing context should do the trick
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
}
#endif // SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS

View File

@@ -0,0 +1,417 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver Cipher functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
#include "psa/crypto.h"
#include "sli_se_opaque_types.h"
#include "sli_se_opaque_functions.h"
#include "sli_se_driver_cipher.h"
#include "sli_se_driver_key_management.h"
#include "sl_se_manager.h"
#include "sl_se_manager_cipher.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Static functions
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
static void update_key_from_context(sli_se_opaque_cipher_operation_t* ctx)
{
// Point the key to the buffer
ctx->operation.key_desc.storage.location.buffer.pointer = ctx->key;
}
static psa_status_t initialize_key_in_context(
const psa_key_attributes_t *attributes,
sli_se_opaque_cipher_operation_t *operation,
const uint8_t *key_buffer,
size_t key_buffer_size)
{
// Double check that the location of the key actually is
// as expected for this driver.
if (PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes))
!= PSA_KEY_LOCATION_SLI_SE_OPAQUE) {
return PSA_ERROR_NOT_SUPPORTED;
}
// Initialize the key descriptor.
psa_status_t psa_status = sli_se_key_desc_from_input(attributes,
key_buffer,
key_buffer_size,
&operation->operation.key_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Copy the key material -- could be either a built-in or a wrapped key.
sli_se_opaque_key_context_header_t *key_context_header =
(sli_se_opaque_key_context_header_t *)key_buffer;
if (key_context_header->builtin_key_id != 0) { // Built-in key.
memcpy(operation->key,
key_buffer,
sizeof(sli_se_opaque_key_context_header_t));
operation->key_len = sizeof(sli_se_opaque_key_context_header_t);
} else { // Wrapped key.
size_t key_size = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
size_t offset = offsetof(sli_se_opaque_wrapped_key_context_t, wrapped_buffer);
if (key_buffer_size < key_size + sizeof(sli_se_opaque_wrapped_key_context_t)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (sizeof(operation->key) < key_size + SLI_SE_WRAPPED_KEY_OVERHEAD) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->key,
key_buffer + offset,
key_size + SLI_SE_WRAPPED_KEY_OVERHEAD);
operation->key_len = key_size + SLI_SE_WRAPPED_KEY_OVERHEAD;
}
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
// -----------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_opaque_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *iv,
size_t iv_length,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined (SLI_PSA_DRIVER_FEATURE_CIPHER)
return sli_se_driver_cipher_encrypt(attributes,
key_buffer,
key_buffer_size,
alg,
iv,
iv_length,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)iv;
(void)iv_length;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER
}
psa_status_t sli_se_opaque_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined (SLI_PSA_DRIVER_FEATURE_CIPHER)
return sli_se_driver_cipher_decrypt(attributes,
key_buffer,
key_buffer_size,
alg,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER
}
// -----------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_opaque_cipher_encrypt_setup(
sli_se_opaque_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL || attributes == NULL || key_buffer == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Reset context
memset(operation, 0, sizeof(*operation));
psa_status_t psa_status = sli_se_driver_cipher_encrypt_setup(&operation->operation,
attributes,
alg);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Copy key into context
psa_status = initialize_key_in_context(attributes,
operation,
key_buffer,
key_buffer_size);
return psa_status;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_opaque_cipher_decrypt_setup(
sli_se_opaque_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL || attributes == NULL || key_buffer == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Reset context
memset(operation, 0, sizeof(*operation));
psa_status_t psa_status = sli_se_driver_cipher_decrypt_setup(&operation->operation,
attributes,
alg);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Copy key into context
psa_status = initialize_key_in_context(attributes,
operation,
key_buffer,
key_buffer_size);
return psa_status;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_opaque_cipher_set_iv(
sli_se_opaque_cipher_operation_t *operation,
const uint8_t *iv,
size_t iv_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (operation->key_len == 0) {
// context hasn't been properly initialised
return PSA_ERROR_BAD_STATE;
}
return sli_se_driver_cipher_set_iv(&operation->operation, iv, iv_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)iv;
(void)iv_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_opaque_cipher_update(
sli_se_opaque_cipher_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
// Argument check
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// For wrapped keys, set the key correctly
sli_se_opaque_key_context_header_t *key_context_header =
(sli_se_opaque_key_context_header_t *)operation->key;
if (key_context_header->builtin_key_id == 0) {
update_key_from_context(operation);
}
// Compute
return sli_se_driver_cipher_update(&operation->operation,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_opaque_cipher_finish(
sli_se_opaque_cipher_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// For wrapped keys, set the key correctly
sli_se_opaque_key_context_header_t *key_context_header =
(sli_se_opaque_key_context_header_t *)operation->key;
if (key_context_header->builtin_key_id == 0) {
update_key_from_context(operation);
}
// Compute
return sli_se_driver_cipher_finish(&operation->operation,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_opaque_cipher_abort(
sli_se_opaque_cipher_operation_t *operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation != NULL) {
// Wipe context
memset(operation, 0, sizeof(sli_se_opaque_cipher_operation_t));
}
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
#endif // SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS

View File

@@ -0,0 +1,426 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver Mac functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
#include "psa/crypto.h"
#include "sli_se_driver_key_management.h"
#include "sli_se_opaque_types.h"
#include "sli_se_opaque_functions.h"
#include "sli_se_manager_internal.h"
#include "sli_psa_driver_common.h"
#include <string.h>
//------------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_opaque_mac_compute(const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC)
if (key_buffer == NULL
|| attributes == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Ephemeral contexts
sl_se_key_descriptor_t key_desc = { 0 };
psa_status_t psa_status = sli_se_key_desc_from_input(attributes,
key_buffer,
key_buffer_size,
&key_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
return sli_se_driver_mac_compute(&key_desc,
alg,
input,
input_length,
mac,
mac_size,
mac_length);
#else // SLI_PSA_DRIVER_FEATURE_MAC
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)input;
(void)input_length;
(void)mac;
(void)mac_size;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC
}
//------------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_opaque_mac_sign_setup(
sli_se_opaque_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| attributes == NULL
|| key_buffer == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_status_t psa_status;
// start by resetting context
memset(operation, 0, sizeof(*operation));
// Add support for one-shot HMAC through the multipart interface
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(alg)) {
// SE does not support multipart HMAC. Construct it from hashing instead.
// Check key type and output size
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_HMAC) {
// For HMAC, key type is strictly enforced
return PSA_ERROR_INVALID_ARGUMENT;
}
size_t output_size = 0;
sl_se_hash_type_t hash = sli_se_hash_type_from_psa_hmac_alg(alg,
&output_size);
if (hash == SL_SE_HASH_NONE) {
return PSA_ERROR_NOT_SUPPORTED;
}
if (output_size > sizeof(operation->operation.ctx.hmac.hmac_result)) {
return PSA_ERROR_NOT_SUPPORTED;
}
operation->operation.alg = alg;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC) \
&& (defined(SLI_PSA_DRIVER_FEATURE_CMAC) \
|| defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC))
else
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
{
psa_status = sli_se_driver_mac_sign_setup(&(operation->operation),
attributes,
alg);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
psa_status = sli_se_key_desc_from_input(attributes,
key_buffer,
key_buffer_size,
&(operation->key_desc));
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
size_t padding = 0;
operation->key_len = psa_get_key_bits(attributes) / 8;
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
padding = sli_se_get_padding(operation->key_len);
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(alg)) {
if ((operation->key_len < sizeof(uint32_t))
|| ((operation->key_len + padding)
> (sizeof(operation->key) - SLI_SE_WRAPPED_KEY_OVERHEAD))) {
return PSA_ERROR_INVALID_ARGUMENT;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC) \
&& (defined(SLI_PSA_DRIVER_FEATURE_CMAC) \
|| defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC))
else
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
{
switch (operation->key_len) {
case 16: // Fallthrough
case 24: // Fallthrough
case 32:
break;
default:
return PSA_ERROR_INVALID_ARGUMENT;
}
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
if (operation->key_desc.storage.location.buffer.size
< (SLI_SE_WRAPPED_KEY_OVERHEAD + operation->key_len + padding)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->key,
operation->key_desc.storage.location.buffer.pointer,
SLI_SE_WRAPPED_KEY_OVERHEAD + operation->key_len + padding);
// Point key_descriptor at internal copy of key
operation->key_desc.storage.location.buffer.pointer = operation->key;
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif
}
psa_status_t sli_se_opaque_mac_verify_setup(
sli_se_opaque_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
// Since the PSA Crypto core exposes the verify functionality of the drivers
// without actually implementing the fallback to 'sign' when the driver
// doesn't support verify, we need to do this ourselves for the time being.
return sli_se_opaque_mac_sign_setup(operation,
attributes,
key_buffer,
key_buffer_size,
alg);
}
psa_status_t sli_se_opaque_mac_update(sli_se_opaque_mac_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| (input == NULL && input_length > 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(operation->operation.alg)) {
if ( operation->operation.ctx.hmac.hmac_len > 0 ) {
return PSA_ERROR_BAD_STATE;
}
return sli_se_driver_mac_compute(
&(operation->key_desc),
operation->operation.alg,
input,
input_length,
operation->operation.ctx.hmac.hmac_result,
sizeof(operation->operation.ctx.hmac.hmac_result),
&operation->operation.ctx.hmac.hmac_len);
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
return sli_se_driver_mac_update(&(operation->operation),
&(operation->key_desc),
input,
input_length);
#else
return PSA_ERROR_NOT_SUPPORTED;
#endif
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)input;
(void)input_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_opaque_mac_sign_finish(
sli_se_opaque_mac_operation_t *operation,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| mac == NULL
|| mac_size == 0
|| mac_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(operation->operation.alg)) {
if ( operation->operation.ctx.hmac.hmac_len == 0 ) {
return PSA_ERROR_BAD_STATE;
}
if ( mac_size < operation->operation.ctx.hmac.hmac_len ) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(mac,
operation->operation.ctx.hmac.hmac_result,
operation->operation.ctx.hmac.hmac_len);
*mac_length = operation->operation.ctx.hmac.hmac_len;
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
return sli_se_driver_mac_sign_finish(&(operation->operation),
&(operation->key_desc),
mac,
mac_size,
mac_length);
#else
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)mac;
(void)mac_size;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_opaque_mac_verify_finish(
sli_se_opaque_mac_operation_t *operation,
const uint8_t *mac,
size_t mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
// Since the PSA Crypto core exposes the verify functionality of the drivers
// without actually implementing the fallback to 'sign' when the driver
// doesn't support verify, we need to do this ourselves for the time being.
uint8_t calculated_mac[PSA_MAC_MAX_SIZE] = { 0 };
size_t calculated_length = PSA_MAC_MAX_SIZE;
psa_status_t status = sli_se_opaque_mac_sign_finish(operation,
calculated_mac,
sizeof(calculated_mac),
&calculated_length);
if (status != PSA_SUCCESS) {
return status;
}
if (mac_length > sizeof(calculated_mac)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (sli_psa_safer_memcmp(mac, calculated_mac, mac_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
} else {
status = PSA_SUCCESS;
}
sli_psa_zeroize(calculated_mac, sizeof(calculated_mac));
return status;
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)mac;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_opaque_mac_abort(sli_se_opaque_mac_operation_t *operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
// There's no state in hardware that we need to preserve, so zeroing out the
// context suffices.
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
#endif // SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS

View File

@@ -0,0 +1,63 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Opaque Driver Key Derivation functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE) && defined(SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS)
#include "psa/crypto.h"
#include "sli_se_driver_key_derivation.h"
//------------------------------------------------------------------------------
// Driver entry points
psa_status_t sli_se_opaque_key_agreement(psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
return sli_se_driver_key_agreement(alg,
attributes,
key_buffer,
key_buffer_size,
peer_key,
peer_key_length,
output,
output_size,
output_length);
}
#endif // SLI_MBEDTLS_DEVICE_HSE && SLI_PSA_DRIVER_FEATURE_OPAQUE_KEYS

View File

@@ -0,0 +1,279 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver AEAD functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_transparent_types.h"
#include "sli_se_transparent_functions.h"
#include <string.h>
//------------------------------------------------------------------------------
// One-shot driver entry points
psa_status_t sli_se_transparent_aead_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *plaintext,
size_t plaintext_length,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length)
{
return sli_se_driver_aead_encrypt(attributes,
key_buffer,
key_buffer_size,
alg,
nonce,
nonce_length,
additional_data,
additional_data_length,
plaintext,
plaintext_length,
ciphertext,
ciphertext_size,
ciphertext_length);
}
psa_status_t sli_se_transparent_aead_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *nonce,
size_t nonce_length,
const uint8_t *additional_data,
size_t additional_data_length,
const uint8_t *ciphertext,
size_t ciphertext_length,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length)
{
return sli_se_driver_aead_decrypt(attributes,
key_buffer,
key_buffer_size,
alg,
nonce,
nonce_length,
additional_data,
additional_data_length,
ciphertext,
ciphertext_length,
plaintext,
plaintext_size,
plaintext_length);
}
//------------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_transparent_aead_encrypt_setup(
sli_se_transparent_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Start by resetting context
memset(operation, 0, sizeof(*operation));
// Setup generic context struct
return sli_se_driver_aead_encrypt_decrypt_setup(&(operation->operation),
attributes,
key_buffer,
key_buffer_size,
alg,
SL_SE_ENCRYPT,
operation->key,
sizeof(operation->key),
0);
}
psa_status_t sli_se_transparent_aead_decrypt_setup(
sli_se_transparent_aead_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Start by resetting context
memset(operation, 0, sizeof(*operation));
// Setup generic context struct
return sli_se_driver_aead_encrypt_decrypt_setup(&(operation->operation),
attributes,
key_buffer,
key_buffer_size,
alg,
SL_SE_DECRYPT,
operation->key,
sizeof(operation->key),
0);
}
psa_status_t sli_se_transparent_aead_set_nonce(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *nonce,
size_t nonce_size)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_set_nonce(&(operation->operation),
nonce,
nonce_size);
}
psa_status_t sli_se_transparent_aead_set_lengths(
sli_se_transparent_aead_operation_t *operation,
size_t ad_length,
size_t plaintext_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_set_lengths(&(operation->operation),
ad_length,
plaintext_length);
}
psa_status_t sli_se_transparent_aead_update_ad(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_update_ad(&(operation->operation),
operation->key,
input,
input_length);
}
psa_status_t sli_se_transparent_aead_update(
sli_se_transparent_aead_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_update(&(operation->operation),
operation->key,
input,
input_length,
output,
output_size,
output_length);
}
psa_status_t sli_se_transparent_aead_finish(
sli_se_transparent_aead_operation_t *operation,
uint8_t *ciphertext,
size_t ciphertext_size,
size_t *ciphertext_length,
uint8_t *tag,
size_t tag_size,
size_t *tag_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_finish(&(operation->operation),
operation->key,
ciphertext,
ciphertext_size,
ciphertext_length,
tag,
tag_size,
tag_length);
}
psa_status_t sli_se_transparent_aead_verify(
sli_se_transparent_aead_operation_t *operation,
uint8_t *plaintext,
size_t plaintext_size,
size_t *plaintext_length,
const uint8_t *tag,
size_t tag_length)
{
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return sli_se_driver_aead_verify(&(operation->operation),
operation->key,
plaintext,
plaintext_size,
plaintext_length,
tag,
tag_length);
}
psa_status_t sli_se_transparent_aead_abort(
sli_se_transparent_aead_operation_t *operation)
{
// No state is ever left in HW, so zeroing context should do the trick
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,388 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver Cipher functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_transparent_types.h"
#include "sli_se_transparent_functions.h"
#include "sl_se_manager.h"
#include "sl_se_manager_cipher.h"
#include "sli_se_driver_cipher.h"
#include "sli_se_driver_key_management.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Static functions
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER)
static void update_key_from_context(
sli_se_transparent_cipher_operation_t* operation)
{
// Point to transparent key buffer as storage location
sli_se_key_descriptor_set_plaintext(&operation->operation.key_desc,
operation->key,
sizeof(operation->key));
}
static psa_status_t initialize_key_in_context(
const psa_key_attributes_t *attributes,
sli_se_transparent_cipher_operation_t *operation,
const uint8_t *key_buffer,
size_t key_buffer_size)
{
const size_t key_size = PSA_BITS_TO_BYTES(psa_get_key_bits(attributes));
psa_status_t psa_status =
sli_se_key_desc_from_psa_attributes(attributes,
key_size,
&operation->operation.key_desc);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
if (key_buffer_size < key_size) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (sizeof(operation->key) < key_size) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->key, key_buffer, key_size);
operation->key_len = key_size;
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER
// -----------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_transparent_cipher_encrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *iv,
size_t iv_length,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER)
return sli_se_driver_cipher_encrypt(attributes,
key_buffer,
key_buffer_size,
alg,
iv,
iv_length,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)iv;
(void)iv_length;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER
}
psa_status_t sli_se_transparent_cipher_decrypt(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER)
return sli_se_driver_cipher_decrypt(attributes,
key_buffer,
key_buffer_size,
alg,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER
}
// -----------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_transparent_cipher_encrypt_setup(
sli_se_transparent_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL || attributes == NULL || key_buffer == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Reset context
memset(operation, 0, sizeof(*operation));
psa_status_t psa_status =
sli_se_driver_cipher_encrypt_setup(&operation->operation,
attributes,
alg);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Copy key into context
psa_status = initialize_key_in_context(attributes,
operation,
key_buffer,
key_buffer_size);
return psa_status;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_transparent_cipher_decrypt_setup(
sli_se_transparent_cipher_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL || attributes == NULL || key_buffer == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Reset context
memset(operation, 0, sizeof(*operation));
psa_status_t psa_status =
sli_se_driver_cipher_decrypt_setup(&operation->operation,
attributes,
alg);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
// Copy key into context
psa_status = initialize_key_in_context(attributes,
operation,
key_buffer,
key_buffer_size);
return psa_status;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_transparent_cipher_set_iv(
sli_se_transparent_cipher_operation_t *operation,
const uint8_t *iv,
size_t iv_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (operation->key_len == 0) {
// context hasn't been properly initialised
return PSA_ERROR_BAD_STATE;
}
return sli_se_driver_cipher_set_iv(&operation->operation, iv, iv_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)iv;
(void)iv_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_transparent_cipher_update(
sli_se_transparent_cipher_operation_t *operation,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
// Argument check
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Set the key correctly
update_key_from_context(operation);
// Compute
return sli_se_driver_cipher_update(&operation->operation,
input,
input_length,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)input;
(void)input_length;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_transparent_cipher_finish(
sli_se_transparent_cipher_operation_t *operation,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
update_key_from_context(operation);
return sli_se_driver_cipher_finish(&operation->operation,
output,
output_size,
output_length);
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
(void)output;
(void)output_size;
(void)output_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
psa_status_t sli_se_transparent_cipher_abort(
sli_se_transparent_cipher_operation_t *operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART)
if (operation != NULL) {
// Wipe context
memset(operation, 0, sizeof(sli_se_transparent_cipher_operation_t));
}
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
(void)operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CIPHER_MULTIPART
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,409 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver Hash functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_transparent_types.h"
#include "sli_se_transparent_functions.h"
#include "sl_se_manager.h"
#include "sl_se_manager_hash.h"
#include <string.h>
// -----------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_transparent_hash_compute(psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH)
if ((input == NULL && input_length > 0)
|| (hash == NULL && hash_size > 0)
|| hash_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
sl_se_hash_type_t hash_type;
sl_se_command_context_t ephemeral_se_ctx;
switch (alg) {
#if defined(SLI_PSA_DRIVER_FEATURE_SHA1)
case PSA_ALG_SHA_1:
hash_type = SL_SE_HASH_SHA1;
*hash_length = 20;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA224)
case PSA_ALG_SHA_224:
hash_type = SL_SE_HASH_SHA224;
*hash_length = 28;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA256)
case PSA_ALG_SHA_256:
hash_type = SL_SE_HASH_SHA256;
*hash_length = 32;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA384)
case PSA_ALG_SHA_384:
hash_type = SL_SE_HASH_SHA384;
*hash_length = 48;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA512)
case PSA_ALG_SHA_512:
hash_type = SL_SE_HASH_SHA512;
*hash_length = 64;
break;
#endif
default:
return PSA_ERROR_NOT_SUPPORTED;
}
if (hash_size < *hash_length) {
*hash_length = 0;
return PSA_ERROR_BUFFER_TOO_SMALL;
}
sl_status_t status = sl_se_init_command_context(&ephemeral_se_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
status = sl_se_hash(&ephemeral_se_ctx,
hash_type,
input,
input_length,
hash,
hash_size);
if (status == SL_STATUS_OK) {
return PSA_SUCCESS;
} else {
*hash_length = 0;
return PSA_ERROR_HARDWARE_FAILURE;
}
#else // SLI_PSA_DRIVER_FEATURE_HASH
(void)alg;
(void)input;
(void)input_length;
(void)hash;
(void)hash_size;
(void)hash_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH
}
// -----------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_transparent_hash_setup(
sli_se_transparent_hash_operation_t *operation,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART)
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// reset context
memset(&operation->streaming_contexts, 0, sizeof(operation->streaming_contexts));
// create ephemeral contexts
sl_se_command_context_t ephemeral_se_ctx;
sl_status_t status = SL_STATUS_INVALID_PARAMETER;
switch (alg) {
#if defined(SLI_PSA_DRIVER_FEATURE_SHA1)
case PSA_ALG_SHA_1:
operation->hash_type = SL_SE_HASH_SHA1;
status = sl_se_hash_sha1_multipart_starts(&(operation->streaming_contexts.sha1_context),
&ephemeral_se_ctx);
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA224)
case PSA_ALG_SHA_224:
operation->hash_type = SL_SE_HASH_SHA224;
status = sl_se_hash_sha224_multipart_starts(&(operation->streaming_contexts.sha224_context),
&ephemeral_se_ctx);
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA256)
case PSA_ALG_SHA_256:
operation->hash_type = SL_SE_HASH_SHA256;
status = sl_se_hash_sha256_multipart_starts(&(operation->streaming_contexts.sha256_context),
&ephemeral_se_ctx);
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA384)
case PSA_ALG_SHA_384:
operation->hash_type = SL_SE_HASH_SHA384;
status = sl_se_hash_sha384_multipart_starts(&(operation->streaming_contexts.sha384_context),
&ephemeral_se_ctx);
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA512)
case PSA_ALG_SHA_512:
operation->hash_type = SL_SE_HASH_SHA512;
status = sl_se_hash_sha512_multipart_starts(&(operation->streaming_contexts.sha512_context),
&ephemeral_se_ctx);
break;
#endif
default:
return PSA_ERROR_NOT_SUPPORTED;
}
if (status == SL_STATUS_OK) {
return PSA_SUCCESS;
} else {
return PSA_ERROR_HARDWARE_FAILURE;
}
#else // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
(void) operation;
(void) alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
}
psa_status_t sli_se_transparent_hash_update(
sli_se_transparent_hash_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART)
if (operation == NULL
|| (input == NULL && input_length > 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// create ephemeral contexts
sl_se_command_context_t ephemeral_se_ctx;
sl_status_t status = sl_se_init_command_context(&ephemeral_se_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
status = sl_se_hash_multipart_update((void*)&(operation->streaming_contexts),
&ephemeral_se_ctx,
input,
input_length);
if (status == SL_STATUS_OK) {
return PSA_SUCCESS;
} else {
return PSA_ERROR_HARDWARE_FAILURE;
}
#else // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
(void) operation;
(void) input;
(void) input_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
}
psa_status_t sli_se_transparent_hash_finish(
sli_se_transparent_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART)
if (operation == NULL
|| (hash == NULL && hash_size > 0)
|| hash_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// create ephemeral contexts
sl_se_command_context_t ephemeral_se_ctx;
sl_status_t status = sl_se_init_command_context(&ephemeral_se_ctx);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
status = sl_se_hash_multipart_finish((void*)&(operation->streaming_contexts),
&ephemeral_se_ctx,
hash,
hash_size);
// reset context
memset(&operation->streaming_contexts,
0,
sizeof(operation->streaming_contexts));
if (status == SL_STATUS_OK) {
switch (operation->hash_type) {
#if defined(SLI_PSA_DRIVER_FEATURE_SHA1)
case SL_SE_HASH_SHA1:
*hash_length = 20;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA224)
case SL_SE_HASH_SHA224:
*hash_length = 28;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA256)
case SL_SE_HASH_SHA256:
*hash_length = 32;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA384)
case SL_SE_HASH_SHA384:
*hash_length = 48;
break;
#endif
#if defined(SLI_PSA_DRIVER_FEATURE_SHA512)
case SL_SE_HASH_SHA512:
*hash_length = 64;
break;
#endif
default:
return PSA_ERROR_BAD_STATE;
}
return PSA_SUCCESS;
} else if ( status == SL_STATUS_INVALID_PARAMETER) {
return PSA_ERROR_BUFFER_TOO_SMALL;
} else {
return PSA_ERROR_HARDWARE_FAILURE;
}
#else // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
(void) operation;
(void) hash;
(void) hash_size;
(void) hash_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
}
psa_status_t sli_se_transparent_hash_abort(
sli_se_transparent_hash_operation_t *operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART)
if (operation != NULL) {
// Accelerator does not keep state, so just zero out the context and we're good
memset(operation, 0, sizeof(sli_se_transparent_hash_operation_t));
}
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
(void) operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
}
psa_status_t sli_se_transparent_hash_clone(
const sli_se_transparent_hash_operation_t *source_operation,
sli_se_transparent_hash_operation_t *target_operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART)
if (source_operation == NULL
|| target_operation == NULL) {
return PSA_ERROR_BAD_STATE;
}
// Source operation must be active (setup has been called)
if (source_operation->hash_type == 0) {
return PSA_ERROR_BAD_STATE;
}
// Target operation must be inactive (setup has not been called)
if (target_operation->hash_type != 0) {
return PSA_ERROR_BAD_STATE;
}
// The operation context does not contain any pointers, and the target
// operation have already have been initialized, so we can do a direct copy.
*target_operation = *source_operation;
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
(void) source_operation;
(void) target_operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_HASH_MULTIPART
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,598 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver Mac functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_transparent_types.h"
#include "sli_se_transparent_functions.h"
#include "sli_psa_driver_common.h"
#include <string.h>
//------------------------------------------------------------------------------
// Static asserts
// Make sure that the two locations of 'alg' are in the same place, since we
// access them interchangeably.
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
_Static_assert(offsetof(sli_se_transparent_mac_operation_t, hmac.alg)
== offsetof(sli_se_transparent_mac_operation_t,
cipher_mac.operation.alg),
"hmac.alg and cipher_mac.oepration.alg are not aliases");
#endif // SLI_PSA_DRIVER_FEATURE_MAC
//------------------------------------------------------------------------------
// Static functions
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
static psa_status_t sli_se_transparent_driver_symmetric_key_from_context(
sl_se_key_descriptor_t* key_desc,
sli_se_transparent_mac_operation_t* operation)
{
// Point to transparent key buffer as storage location
key_desc->storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key_desc->storage.location.buffer.pointer = operation->cipher_mac.key;
key_desc->storage.location.buffer.size = sizeof(operation->cipher_mac.key);
key_desc->size = operation->cipher_mac.key_len;
switch (PSA_ALG_FULL_LENGTH_MAC(operation->cipher_mac.operation.alg)) {
case PSA_ALG_CBC_MAC:
case PSA_ALG_CMAC:
if (key_desc->size == 16) {
key_desc->type = SL_SE_KEY_TYPE_AES_128;
} else if (key_desc->size == 24) {
key_desc->type = SL_SE_KEY_TYPE_AES_192;
} else if (key_desc->size == 32) {
key_desc->type = SL_SE_KEY_TYPE_AES_256;
} else {
return PSA_ERROR_BAD_STATE;
}
break;
default:
return PSA_ERROR_BAD_STATE;
}
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_MAC)
static psa_status_t sli_se_transparent_driver_symmetric_key_from_psa(
sl_se_key_descriptor_t* key_desc,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size)
{
// Point to transparent key buffer as storage location
key_desc->storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT;
key_desc->storage.location.buffer.pointer = (uint8_t *)key_buffer;
key_desc->storage.location.buffer.size = key_buffer_size;
// Verify and set key attributes
psa_key_type_t keytype = psa_get_key_type(attributes);
switch (keytype) {
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
case PSA_KEY_TYPE_AES: {
switch (psa_get_key_bits(attributes)) {
case 128:
key_desc->size = 16;
key_desc->type = SL_SE_KEY_TYPE_AES_128;
break;
case 192:
key_desc->size = 24;
key_desc->type = SL_SE_KEY_TYPE_AES_192;
break;
case 256:
key_desc->size = 32;
key_desc->type = SL_SE_KEY_TYPE_AES_256;
break;
default:
return PSA_ERROR_NOT_SUPPORTED;
}
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
case PSA_KEY_TYPE_HMAC: {
key_desc->size = psa_get_key_bits(attributes) / 8;
key_desc->type = SL_SE_KEY_TYPE_SYMMETRIC;
break;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
default:
return PSA_ERROR_INVALID_ARGUMENT;
break;
}
if (key_buffer_size < key_desc->size) {
return PSA_ERROR_INVALID_ARGUMENT;
}
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_MAC
//------------------------------------------------------------------------------
// Single-shot driver entry points
psa_status_t sli_se_transparent_mac_compute(
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg,
const uint8_t *input,
size_t input_length,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC)
if (key_buffer == NULL
|| attributes == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Ephemeral contexts
sl_se_key_descriptor_t key_desc = { 0 };
psa_status_t psa_status
= sli_se_transparent_driver_symmetric_key_from_psa(&key_desc,
attributes,
key_buffer,
key_buffer_size);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
return sli_se_driver_mac_compute(&key_desc,
alg,
input,
input_length,
mac,
mac_size,
mac_length);
#else // SLI_PSA_DRIVER_FEATURE_MAC
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
(void)input;
(void)input_length;
(void)mac;
(void)mac_size;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC
}
//------------------------------------------------------------------------------
// Multi-part driver entry points
psa_status_t sli_se_transparent_mac_sign_setup(
sli_se_transparent_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| attributes == NULL
|| (key_buffer == NULL && key_buffer_size > 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_status_t status;
// start by resetting context
memset(operation, 0, sizeof(*operation));
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(alg)) {
// SE does not support multipart HMAC. Construct it from hashing instead.
// Check key type and output size
if (psa_get_key_type(attributes) != PSA_KEY_TYPE_HMAC) {
// For HMAC, key type is strictly enforced
return PSA_ERROR_INVALID_ARGUMENT;
}
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(alg);
size_t digest_len = PSA_HASH_LENGTH(hash_alg);
if (PSA_MAC_TRUNCATED_LENGTH(alg) > digest_len) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Setup the hash accumulator first, such that we can return early for non-
// supported hash functions and avoid potentially overflowing buffer lengths.
status = sli_se_transparent_hash_setup(&operation->hmac.hash_ctx,
hash_alg);
if (status != PSA_SUCCESS) {
return status;
}
size_t keylen = psa_get_key_bits(attributes) / 8;
size_t blocklen
= (hash_alg == PSA_ALG_SHA_384 || hash_alg == PSA_ALG_SHA_512) ? 128 : 64;
if (key_buffer_size < keylen) {
return PSA_ERROR_INVALID_ARGUMENT;
}
// Reduce the key if larger than a block
if (keylen > blocklen) {
status = sli_se_transparent_hash_compute(
hash_alg,
key_buffer,
keylen,
operation->hmac.opad,
sizeof(operation->hmac.opad),
&keylen);
if (status != PSA_SUCCESS) {
return status;
}
} else if (keylen > 0) {
memcpy(operation->hmac.opad, key_buffer, keylen);
}
// Calculate inner padding in opad buffer and start a multipart hash with it
for (size_t i = 0; i < keylen; i++) {
operation->hmac.opad[i] ^= 0x36;
}
memset(&operation->hmac.opad[keylen], 0x36, blocklen - keylen);
status = sli_se_transparent_hash_update(
&operation->hmac.hash_ctx,
operation->hmac.opad, blocklen);
if (status != PSA_SUCCESS) {
return status;
}
// Calculate outer padding and store it for finalisation
for (size_t i = 0; i < blocklen; i++) {
operation->hmac.opad[i] ^= 0x36 ^ 0x5C;
}
operation->hmac.alg = alg;
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
status = sli_se_driver_mac_sign_setup(&(operation->cipher_mac.operation),
attributes,
alg);
if (status != PSA_SUCCESS) {
return status;
}
operation->cipher_mac.key_len = psa_get_key_bits(attributes) / 8;
switch (operation->cipher_mac.key_len) {
case 16:
if (key_buffer_size < 16) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->cipher_mac.key, key_buffer, 16);
break;
case 24:
if (key_buffer_size < 24) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->cipher_mac.key, key_buffer, 24);
break;
case 32:
if (key_buffer_size < 32) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memcpy(operation->cipher_mac.key, key_buffer, 32);
break;
default:
return PSA_ERROR_INVALID_ARGUMENT;
}
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)attributes;
(void)key_buffer;
(void)key_buffer_size;
(void)alg;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_transparent_mac_verify_setup(
sli_se_transparent_mac_operation_t *operation,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
psa_algorithm_t alg)
{
// Since the PSA Crypto core exposes the verify functionality of the drivers
// without actually implementing the fallback to 'sign' when the driver
// doesn't support verify, we need to do this ourselves for the time being.
return sli_se_transparent_mac_sign_setup(operation,
attributes,
key_buffer,
key_buffer_size,
alg);
}
psa_status_t sli_se_transparent_mac_update(
sli_se_transparent_mac_operation_t *operation,
const uint8_t *input,
size_t input_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| (input == NULL && input_length > 0)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(operation->hmac.alg)) {
return sli_se_transparent_hash_update(
&operation->hmac.hash_ctx,
input,
input_length);
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
// Ephemeral contexts
sl_se_key_descriptor_t key_desc = { 0 };
psa_status_t psa_status
= sli_se_transparent_driver_symmetric_key_from_context(&key_desc,
operation);
if (psa_status != PSA_SUCCESS) {
return psa_status;
}
return sli_se_driver_mac_update(&(operation->cipher_mac.operation),
&key_desc,
input,
input_length);
#else // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)input;
(void)input_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_transparent_mac_sign_finish(
sli_se_transparent_mac_operation_t *operation,
uint8_t *mac,
size_t mac_size,
size_t *mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
if (operation == NULL
|| mac == NULL
|| mac_size == 0
|| mac_length == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
#if defined(SLI_PSA_DRIVER_FEATURE_HMAC)
if (PSA_ALG_IS_HMAC(operation->hmac.alg)) {
uint8_t buffer[sizeof(operation->hmac.opad)
+ (sizeof(operation->hmac.opad) / 2)];
size_t olen = 0;
psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(operation->hmac.alg);
#if !defined(SLI_PSA_DRIVER_FEATURE_HASH_STATE_64)
if (hash_alg == PSA_ALG_SHA_384 || hash_alg == PSA_ALG_SHA_512) {
// Could only reach here if the programmer has made some errors. Take the
// safe approach of checking just in case, in order to avoid certain
// buffer overflows.
return PSA_ERROR_BAD_STATE;
}
size_t blocklen = 64;
#else
size_t blocklen
= (hash_alg == PSA_ALG_SHA_384 || hash_alg == PSA_ALG_SHA_512) ? 128 : 64;
#endif
// Construct outer hash input from opad and hash result
memcpy(buffer, operation->hmac.opad, blocklen);
memset(operation->hmac.opad, 0, sizeof(operation->hmac.opad));
psa_status_t status = sli_se_transparent_hash_finish(
&operation->hmac.hash_ctx,
&buffer[blocklen],
sizeof(buffer) - blocklen,
&olen);
if (status != PSA_SUCCESS) {
return status;
}
// Calculate HMAC
status = sli_se_transparent_hash_compute(
hash_alg,
buffer,
blocklen + olen,
buffer,
sizeof(buffer),
&olen);
if (status != PSA_SUCCESS) {
return status;
}
// Copy out a potentially truncated HMAC
size_t requested_length = PSA_MAC_TRUNCATED_LENGTH(operation->hmac.alg);
if (requested_length == 0) {
requested_length = olen;
}
if (requested_length > mac_size) {
memset(buffer, 0, sizeof(buffer));
return PSA_ERROR_BUFFER_TOO_SMALL;
}
memcpy(mac, buffer, requested_length);
*mac_length = requested_length;
memset(buffer, 0, sizeof(buffer));
return PSA_SUCCESS;
}
#endif // SLI_PSA_DRIVER_FEATURE_HMAC
#if defined(SLI_PSA_DRIVER_FEATURE_CMAC) || defined(SLI_PSA_DRIVER_FEATURE_CBC_MAC)
// Ephemeral contexts
sl_se_key_descriptor_t key_desc = { 0 };
psa_status_t status = sli_se_transparent_driver_symmetric_key_from_context(
&key_desc,
operation);
if (status != PSA_SUCCESS) {
return status;
}
return sli_se_driver_mac_sign_finish(&(operation->cipher_mac.operation),
&key_desc,
mac,
mac_size,
mac_length);
#else // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_CMAC || SLI_PSA_DRIVER_FEATURE_CBC_MAC
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)mac;
(void)mac_size;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_transparent_mac_verify_finish(
sli_se_transparent_mac_operation_t *operation,
const uint8_t *mac,
size_t mac_length)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
// Since the PSA Crypto core exposes the verify functionality of the drivers
// without actually implementing the fallback to 'sign' when the driver
// doesn't support verify, we need to do this ourselves for the time being.
uint8_t calculated_mac[PSA_MAC_MAX_SIZE] = { 0 };
size_t calculated_length = PSA_MAC_MAX_SIZE;
psa_status_t status = sli_se_transparent_mac_sign_finish(
operation,
calculated_mac, sizeof(calculated_mac), &calculated_length);
if (status != PSA_SUCCESS) {
return status;
}
if (mac_length > sizeof(calculated_mac)) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (sli_psa_safer_memcmp(mac, calculated_mac, mac_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
} else {
status = PSA_SUCCESS;
}
memset(calculated_mac, 0, sizeof(calculated_mac));
return status;
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
(void)mac;
(void)mac_length;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
psa_status_t sli_se_transparent_mac_abort(
sli_se_transparent_mac_operation_t *operation)
{
#if defined(SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART)
// There's no state in hardware that we need to preserve, so zeroing out the
// context suffices.
if (operation == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
memset(operation, 0, sizeof(*operation));
return PSA_SUCCESS;
#else // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
(void)operation;
return PSA_ERROR_NOT_SUPPORTED;
#endif // SLI_PSA_DRIVER_FEATURE_MAC_MULTIPART
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,64 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Transparent Driver Key derivation functions.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_driver_key_derivation.h"
//------------------------------------------------------------------------------
// Driver entry points
psa_status_t sli_se_transparent_key_agreement(
psa_algorithm_t alg,
const psa_key_attributes_t *attributes,
const uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *peer_key,
size_t peer_key_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
return sli_se_driver_key_agreement(alg,
attributes,
key_buffer,
key_buffer_size,
peer_key,
peer_key_length,
output,
output_size,
output_length);
}
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,72 @@
/***************************************************************************//**
* @file
* @brief Silicon Labs PSA Crypto Driver SE Version Dependencies.
*******************************************************************************
* # 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 "sli_psa_driver_features.h"
#if defined(SLI_MBEDTLS_DEVICE_HSE)
#include "psa/crypto.h"
#include "sli_se_version_dependencies.h"
#include "sli_se_driver_key_management.h"
#include "sl_se_manager_util.h"
// -----------------------------------------------------------------------------
// Global functions
#if defined(SLI_SE_VERSION_ED25519_ERRATA_CHECK_REQUIRED)
// Check for an errata causing the SE to emit a faulty EdDSA public key for
// operations where only a private key is provided. Assumes that an already
// initalized SE command context is passed as input.
psa_status_t sli_se_check_eddsa_errata(const psa_key_attributes_t* attributes,
sl_se_command_context_t* cmd_ctx)
{
if (PSA_KEY_TYPE_ECC_GET_FAMILY(psa_get_key_type(attributes))
== PSA_ECC_FAMILY_TWISTED_EDWARDS) {
uint32_t se_version = 0;
sl_status_t status = sl_se_get_se_version(cmd_ctx, &se_version);
if (status != SL_STATUS_OK) {
return PSA_ERROR_HARDWARE_FAILURE;
}
se_version = SLI_VERSION_REMOVE_DIE_ID(se_version);
if (SLI_SE_VERSION_ED25519_BROKEN(se_version)) {
return PSA_ERROR_NOT_SUPPORTED;
}
}
return PSA_SUCCESS;
}
#endif // SLI_SE_VERSION_ED25519_ERRATA_CHECK_REQUIRED
#endif // SLI_MBEDTLS_DEVICE_HSE

View File

@@ -0,0 +1,214 @@
/***************************************************************************//**
* @file
* @brief Provides hardware accelerated cryptographic primitives.
*******************************************************************************
* # 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_CRYPTO_H
#define SLI_CRYPTO_H
#include "em_device.h"
#if defined(_SILICON_LABS_32B_SERIES_2)
#include "sli_crypto_s2.h"
#elif defined(_SILICON_LABS_32B_SERIES_3)
#include "sli_crypto_s3.h"
#elif
#error Unsupported device.
#endif
#include "sl_status.h"
#include "sl_code_classification.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for BLE
*
* @param key_descriptor AES key descriptor
* @param data Input/output buffer of payload data of BLE packet
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param header header of BLE packet (1 byte)
* @param tag authentication tag of BLE packet (4 bytes)
*
* @return SL_STATUS_OK if successful and authenticated,
* SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
* relevant status code on other error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_ccm_auth_decrypt_ble(sli_crypto_descriptor_t *key_descriptor,
unsigned char *data,
size_t length,
const unsigned char *iv,
unsigned char header,
unsigned char *tag);
/***************************************************************************//**
* @brief CCM buffer encryption optimized for BLE
*
* @param key_descriptor AES key descriptor
* @param data Input/output buffer of payload data of BLE packet
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param header header of BLE packet (1 byte)
* @param tag buffer where the BLE packet tag (4 bytes) will be written
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_ccm_encrypt_and_tag_ble(sli_crypto_descriptor_t *key_descriptor,
unsigned char *data,
size_t length,
const unsigned char *iv,
unsigned char header,
unsigned char *tag);
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for Zigbee
*
* @param key_descriptor AES key descriptor
* @param encrypt Encrypt operation
* @param data_in Input buffer of payload data (decrypt-in-place)
* @param data_out output buffer of payload data (decrypt-in-place)
* @param length length of input data
* @param iv nonce (initialization vector)
* must be 13 bytes
* @param aad Input buffer of Additional Authenticated Data
* @param aad_len Length of buffer aad
* @param tag authentication tag
* @param tag_len Length of authentication tag
*
* @return SL_STATUS_OK if successful and authenticated,
* SL_STATUS_INVALID_SIGNATURE if tag does not match payload,
* relevant status code on other error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_ccm_zigbee(sli_crypto_descriptor_t *key_descriptor,
bool encrypt,
const unsigned char *data_in,
unsigned char *data_out,
size_t length,
const unsigned char *iv,
const unsigned char *aad,
size_t aad_len,
unsigned char *tag,
size_t tag_len);
/***************************************************************************//**
* @brief Process a table of BLE RPA device keys and look for a
* match against the supplied hash
*
* @param key_descriptor SLI crypto descriptor. If plaintext keys are used the
* descriptor provides a pointer to an array of AES-128 keys.
* If KSU stored keys are used, the descriptor provides the
* starting key slot ID of the KSU RAM where the IRK list is
* located
* @param irk_len Number of IRK to be resolved for the RPA operation
* @param keymask Bitmask indicating with key indices in key table are valid
* @param prand 24-bit BLE nonce to encrypt with each key and match against
* hash
* @param hash BLE RPA hash to match against (last 24 bits of AES result)
* @param irk_index 0-based index of matching key if a match is found,
* -1 for no match or error
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_process_rpa(sli_crypto_descriptor_t *key_descriptor,
size_t irk_len,
uint64_t keymask,
uint32_t prand,
uint32_t hash,
int *irk_index);
/***************************************************************************//**
* @brief AES-CTR block encryption/decryption optimized for radio
*
* @param key_descriptor AES key descriptor
* @param keybits must be 128 or 256
* @param input 16-byte input block
* @param iv_in 16-byte counter/IV starting value
* @param iv_out 16-byte counter/IV output after block round
* @param output 16-byte output block
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_aes_ctr_radio(sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char input[SLI_CRYPTO_AES_BLOCK_SIZE],
const unsigned char iv_in[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char iv_out[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE]);
/***************************************************************************//**
* @brief AES-ECB block encryption/decryption optimized for radio
*
* @param encrypt true for encryption, false for decryption
* @param key_descriptor AES key descriptor
* @param keybits must be 128 or 256
* @param input 16-byte input block
* @param output 16-byte output block
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_aes_ecb_radio(bool encrypt,
sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char input[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE]);
/***************************************************************************//**
* @brief AES-CMAC calculation optimized for radio
*
* @param key_descriptor AES key descriptor
* @param keybits Must be 128 or 256
* @param input Input buffer containing the message to be signed
* @param length Amount of bytes in the input buffer
* @param output 16-byte output block for calculated CMAC
*
* @return SL_STATUS_OK if successful, relevant status code on error
******************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SLI_CRYPTO, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_crypto_aes_cmac_radio(sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char *input,
unsigned int length,
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE]);
// #endif
#ifdef __cplusplus
}
#endif
#endif // SLI_CRYPTO_H

View File

@@ -0,0 +1,83 @@
/***************************************************************************//**
* @file
* @brief Hardware accelerated cryptographic defintions specific to series-2
*******************************************************************************
* # 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_CRYPTO_S2_H
#define SLI_CRYPTO_S2_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/// Standard buffer size in bytes
#define SLI_CRYPTO_AES_BLOCK_SIZE 16
/// Location value for keys stored in plaintext
#define SLI_CRYPTO_KEY_LOCATION_PLAINTEXT ((sli_crypto_key_location_t)0x00000000UL)
/// The SLI Crypto API supports only the RADIOAES crypto engine on Series-2
#define SLI_CRYPTO_ENGINE_RADIOAES ((sli_crypto_engine_t)0x00000001UL)
#define SLI_CRYPTO_ENGINE_DEFAULT (SLI_CRYPTO_ENGINE_RADIOAES)
/// Used to choose a crypto engine.
/// @ref SLI_CRYPTO_LPWAES.
typedef uint32_t sli_crypto_engine_t;
/// Key storage location. Can either
/// @ref SLI_CRYPTO_KEY_LOCATION_PLAINTEXT
typedef uint32_t sli_crypto_key_location_t;
/// Describes where the plaintext key is stored
typedef struct {
uint8_t* pointer; ///< Pointer to a key buffer.
uint32_t size; ///< Size of buffer.
} sli_crypto_key_buffer_t;
/// Describes the plaintext key
typedef struct {
sli_crypto_key_buffer_t buffer; ///< Key buffer.
uint32_t key_size; ///< Key size.
} sli_crypto_plaintext_key_t;
typedef struct {
/// Key storage location.
sli_crypto_key_location_t location;
/// Crypto engine.
sli_crypto_engine_t engine;
/// Describes key storage location.
union {
sli_crypto_plaintext_key_t plaintext_key;
} key;
} sli_crypto_descriptor_t;
#ifdef __cplusplus
}
#endif
#endif // SLI_CRYPTO_S2_H

View File

@@ -0,0 +1,220 @@
/***************************************************************************//**
* @file
* @brief Provides hardware accelerated cryptographic primitives for series-2.
*******************************************************************************
* # 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 "em_device.h"
#include "sli_crypto.h"
#include "sl_assert.h"
#include "sli_protocol_crypto.h"
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for BLE
******************************************************************************/
sl_status_t sli_crypto_ccm_auth_decrypt_ble(sli_crypto_descriptor_t *key_descriptor,
unsigned char *data,
size_t length,
const unsigned char *iv,
unsigned char header,
unsigned char *tag)
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(data != NULL);
EFM_ASSERT(iv != NULL);
EFM_ASSERT(tag != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_ccm_auth_decrypt_ble(data,
length,
(const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
iv,
header,
tag);
}
/***************************************************************************//**
* @brief CCM buffer encryption optimized for BLE
******************************************************************************/
sl_status_t sli_crypto_ccm_encrypt_and_tag_ble(sli_crypto_descriptor_t *key_descriptor,
unsigned char *data,
size_t length,
const unsigned char *iv,
unsigned char header,
unsigned char *tag)
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(data != NULL);
EFM_ASSERT(iv != NULL);
EFM_ASSERT(tag != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_ccm_encrypt_and_tag_ble(data,
length,
(const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
iv,
header,
tag);
}
/***************************************************************************//**
* @brief CCM buffer authenticated decryption optimized for Zigbee
******************************************************************************/
sl_status_t sli_crypto_ccm_zigbee(sli_crypto_descriptor_t *key_descriptor,
bool encrypt,
const unsigned char *data_in,
unsigned char *data_out,
size_t length,
const unsigned char *iv,
const unsigned char *aad,
size_t aad_len,
unsigned char *tag,
size_t tag_len)
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(data_in != NULL);
EFM_ASSERT(iv != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_ccm_zigbee(encrypt,
data_in,
data_out,
length,
(const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
iv,
aad,
aad_len,
tag,
tag_len);
}
/***************************************************************************//**
* @brief Process a table of BLE RPA device keys and look for a
* match against the supplied hash
******************************************************************************/
sl_status_t sli_crypto_process_rpa(sli_crypto_descriptor_t *key_descriptor,
size_t irk_len,
uint64_t keymask,
uint32_t prand,
uint32_t hash,
int *irk_index)
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(irk_index != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
(void)irk_len;
const unsigned char *keytable
= (const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer;
*irk_index = sli_process_ble_rpa(keytable,
(uint32_t)keymask,
prand,
hash);
if (*irk_index == -1) {
return SL_STATUS_FAIL;
}
return SL_STATUS_OK;
}
// /***************************************************************************//**
// * @brief AES-CTR block encryption/decryption optimized for radio
// *******************************************************************************/
sl_status_t sli_crypto_aes_ctr_radio(sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char input[SLI_CRYPTO_AES_BLOCK_SIZE],
const unsigned char iv_in[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char iv_out[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE])
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(keybits == 128 || keybits == 192 || keybits == 256);
EFM_ASSERT(input != NULL);
EFM_ASSERT(iv_in != NULL);
EFM_ASSERT(output != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.key_size == keybits / 8);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_aes_crypt_ctr_radio( (const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
keybits,
input,
iv_in,
iv_out,
output);
}
/***************************************************************************//**
* @brief AES-ECB block encryption/decryption optimized for radio
********************************************************************************/
sl_status_t sli_crypto_aes_ecb_radio(bool encrypt,
sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char input[SLI_CRYPTO_AES_BLOCK_SIZE],
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE])
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(keybits == 128 || keybits == 192 || keybits == 256);
EFM_ASSERT(input != NULL);
EFM_ASSERT(output != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.key_size == keybits / 8);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_aes_crypt_ecb_radio(encrypt,
(const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
keybits,
input,
output);
}
/***************************************************************************//**
* @brief AES-CMAC calculation optimized for radio
********************************************************************************/
sl_status_t sli_crypto_aes_cmac_radio(sli_crypto_descriptor_t *key_descriptor,
unsigned int keybits,
const unsigned char *input,
unsigned int length,
volatile unsigned char output[SLI_CRYPTO_AES_BLOCK_SIZE])
{
EFM_ASSERT(key_descriptor != NULL);
EFM_ASSERT(keybits == 128 || keybits == 192 || keybits == 256);
EFM_ASSERT(input != NULL);
EFM_ASSERT(length == SLI_CRYPTO_AES_BLOCK_SIZE);
EFM_ASSERT(output != NULL);
EFM_ASSERT(key_descriptor->location == SLI_CRYPTO_KEY_LOCATION_PLAINTEXT);
EFM_ASSERT(key_descriptor->key.plaintext_key.key_size == keybits / 8);
EFM_ASSERT(key_descriptor->key.plaintext_key.buffer.pointer != NULL);
return sli_aes_cmac_radio((const unsigned char *)key_descriptor->key.plaintext_key.buffer.pointer,
keybits,
input,
length,
output);
}

View File

@@ -0,0 +1,54 @@
/**************************************************************************/ /**
* @file
* @brief OS abstraction layer primitives for the platform/security components.
*******************************************************************************
* # 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_PSEC_OSAL_H
#define SLI_PSEC_OSAL_H
// -----------------------------------------------------------------------------
// Includes
#if defined(SLI_PSEC_CONFIG_FILE)
#include SLI_PSEC_CONFIG_FILE
#endif
#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)
// Include CMSIS RTOS2 kernel abstraction layer:
#include "sli_psec_osal_cmsis_rtos2.h"
#define SLI_PSEC_THREADING
#else
// Include bare metal abstraction layer:
#include "sli_psec_osal_baremetal.h"
#endif
#endif // SLI_PSEC_OSAL_H

View File

@@ -0,0 +1,368 @@
/**************************************************************************/ /**
* @file
* @brief OS abstraction layer primitives for platform/security on CMSIS RTOS2
*******************************************************************************
* # 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_PSEC_OSAL_CMSIS_RTOS_H
#define SLI_PSEC_OSAL_CMSIS_RTOS_H
// -----------------------------------------------------------------------------
// Includes
#include "sl_common.h"
#include "sl_status.h"
#include "cmsis_os2.h"
#include "sl_core.h"
#include "sl_code_classification.h"
#if defined (SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
#include "FreeRTOSConfig.h"
#if (configSUPPORT_STATIC_ALLOCATION == 1)
#include "FreeRTOS.h" // StaticSemaphore_t
#include <string.h>
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
// -----------------------------------------------------------------------------
// Defines
/// In order to wait forever in blocking functions the user can pass the
/// following value.
#define SLI_PSEC_OSAL_WAIT_FOREVER (osWaitForever)
/// In order to return immediately in blocking functions the user can pass the
/// following value.
#define SLI_PSEC_OSAL_NON_BLOCKING (0)
// Checks if kernel is running
#define SLI_PSEC_OSAL_KERNEL_RUNNING (osKernelGetState() == osKernelRunning)
// Lock kernel (task scheduler) to enter critical section
#define SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_START \
int32_t kernel_lock_state = 0; \
osKernelState_t kernel_state = osKernelGetState(); \
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) { \
kernel_lock_state = osKernelLock(); \
if (kernel_lock_state < 0) { \
return SL_STATUS_FAIL; \
} \
}
// Resume kernel to exit critical section
#define SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END \
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) { \
if (osKernelRestoreLock(kernel_lock_state) < 0) { \
return SL_STATUS_FAIL; \
} \
}
// -----------------------------------------------------------------------------
// Typedefs
/// Completion object used to wait for and signal end of an operation.
typedef struct sli_psec_osal_completion {
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
osSemaphoreAttr_t semaphore_attr;
StaticSemaphore_t static_sem_object;
#endif
osSemaphoreId_t semaphore_ID;
} sli_psec_osal_completion_t;
/// SLI PSEC lock definition for CMSIS RTOS2.
typedef struct sli_psec_osal_lock {
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
StaticSemaphore_t static_sem_object;
#endif
osMutexAttr_t mutex_attr;
osMutexId_t mutex_ID;
} sli_psec_osal_lock_t;
// -----------------------------------------------------------------------------
// Functions
/***************************************************************************//**
* @brief Set recursive attribute of lock
*
* @details If recursive lock is needed, this function must be called
* before calling sli_psec_osal_init_lock.
*
* @param lock Pointer to the lock
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
__STATIC_INLINE
sl_status_t sli_psec_osal_set_recursive_lock(sli_psec_osal_lock_t *lock)
{
if (lock == NULL) {
return SL_STATUS_INVALID_PARAMETER;
}
lock->mutex_attr.attr_bits |= osMutexRecursive;
return SL_STATUS_OK;
}
/***************************************************************************//**
* @brief Initialize a given lock
*
* @param lock Pointer to the lock needing initialization
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
__STATIC_INLINE sl_status_t sli_psec_osal_init_lock(sli_psec_osal_lock_t *lock)
{
if (lock == NULL) {
return SL_STATUS_FAIL;
}
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
// Zeroize all members of the lock attributes object and setup the static control block.
lock->mutex_attr.cb_mem = &lock->static_sem_object;
lock->mutex_attr.cb_size = sizeof(lock->static_sem_object);
#endif
lock->mutex_ID = osMutexNew(&lock->mutex_attr);
return (lock->mutex_ID == NULL ? SL_STATUS_FAIL : SL_STATUS_OK);
}
/***************************************************************************//**
* @brief Free a given lock
*
* @param lock Pointer to the lock being freed
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
__STATIC_INLINE sl_status_t sli_psec_osal_free_lock(sli_psec_osal_lock_t *lock)
{
if (lock == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osMutexDelete(lock->mutex_ID);
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}
/***************************************************************************//**
* @brief Check if lock is open for calling thread
*
* @param lock Pointer to the lock to be checked
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_PSEC_OSAL, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_psec_osal_lock_is_accessible(sli_psec_osal_lock_t *lock);
/***************************************************************************//**
* @brief Pend on a lock with timeout
*
* @param lock Pointer to the lock being pended on
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_PSEC_OSAL, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_psec_osal_take_lock_timeout(sli_psec_osal_lock_t *lock,
uint32_t timeout);
/***************************************************************************//**
* @brief Pend on a lock forever
*
* @param lock Pointer to the lock being pended on
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
__STATIC_INLINE sl_status_t sli_psec_osal_take_lock(sli_psec_osal_lock_t *lock)
{
return sli_psec_osal_take_lock_timeout(lock, SLI_PSEC_OSAL_WAIT_FOREVER);
}
/***************************************************************************//**
* @brief Try to acquire ownership of a lock without waiting.
*
* @param lock Pointer to the lock being tested
*
* @return SL_STATUS_OK on success (= lock successfully owned),
* error code otherwise.
*****************************************************************************/
__STATIC_INLINE
sl_status_t sli_psec_osal_take_lock_non_blocking(sli_psec_osal_lock_t *lock)
{
return sli_psec_osal_take_lock_timeout(lock, SLI_PSEC_OSAL_NON_BLOCKING);
}
/***************************************************************************//**
* @brief Release a lock
*
* @param lock Pointer to the lock being released
*
* @return SL_STATUS_OK on success, error code otherwise.
*****************************************************************************/
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_PSEC_OSAL, SL_CODE_CLASS_TIME_CRITICAL)
sl_status_t sli_psec_osal_give_lock(sli_psec_osal_lock_t *lock);
/***************************************************************************//**
* @brief Initialize a completion object.
*
* @param p_comp Pointer to an sli_psec_osal_completion_t object allocated
* by the user.
*
* @return Status code, @ref sl_status.h.
*****************************************************************************/
__STATIC_INLINE sl_status_t
sli_psec_osal_init_completion(sli_psec_osal_completion_t *p_comp)
{
if (p_comp == NULL) {
return SL_STATUS_FAIL;
}
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
// Zeroize all members of the semaphore attributes object and setup the static control block.
memset(&p_comp->semaphore_attr, 0, sizeof(p_comp->semaphore_attr));
p_comp->semaphore_attr.cb_mem = &p_comp->static_sem_object;
p_comp->semaphore_attr.cb_size = sizeof(p_comp->static_sem_object);
p_comp->semaphore_ID = osSemaphoreNew(1u, 0u, &p_comp->semaphore_attr);
#else
p_comp->semaphore_ID = osSemaphoreNew(1u, 0u, NULL);
#endif
return (p_comp->semaphore_ID == NULL ? SL_STATUS_FAIL : SL_STATUS_OK);
}
/***************************************************************************//**
* @brief Free a completion object.
*
* @param p_comp Pointer to an sli_psec_osal_completion_t object.
*
* @return Status code, @ref sl_status.h.
*****************************************************************************/
__STATIC_INLINE sl_status_t
sli_psec_osal_free_completion(sli_psec_osal_completion_t *p_comp)
{
if (p_comp == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osSemaphoreDelete(p_comp->semaphore_ID);
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}
/***************************************************************************//**
* @brief Wait for completion event.
*
* @param p_comp Pointer to completion object which must be initialized by
* calling sli_psec_osal_completion_init before calling this
* function.
*
* @param ticks Ticks to wait for the completion.
* Pass a value of SLI_PSEC_OSAL_WAIT_FOREVER in order to
* wait forever.
* Pass a value of SLI_PSEC_OSAL_NON_BLOCKING in order to
* return immediately.
*
* @return Status code, @ref sl_status.h. Typcally SL_STATUS_OK if success,
* or SL_STATUS_TIMEOUT if no completion within the given ticks.
*****************************************************************************/
__STATIC_INLINE sl_status_t
sli_psec_osal_wait_completion(sli_psec_osal_completion_t *p_comp, int ticks)
{
if (p_comp == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osOK;
if (osKernelGetState() == osKernelRunning) {
status = osSemaphoreAcquire(p_comp->semaphore_ID,
(uint32_t)ticks);
}
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}
/***************************************************************************//**
* @brief Signal completion.
*
* @param p_comp Pointer to completion object which must be initialized by
* calling sli_psec_osal_completion_init before calling this
* function.
*
* @return Status code, @ref sl_status.h.
*****************************************************************************/
__STATIC_INLINE
sl_status_t sli_psec_osal_complete(sli_psec_osal_completion_t* p_comp)
{
if (p_comp == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osOK;
osKernelState_t state = osKernelGetState();
if ((state == osKernelRunning) || (state == osKernelLocked)) {
status = osSemaphoreRelease(p_comp->semaphore_ID);
}
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}
/***************************************************************************//**
* @brief Lock the RTOS Kernel scheduler.
*
* @return Status code, @ref cmsis_os2.h
*****************************************************************************/
__STATIC_INLINE int32_t sli_psec_osal_kernel_lock(void)
{
return osKernelLock();
}
/***************************************************************************//**
* @brief Restore the RTOS Kernel scheduler lock state.
*
* @return Status code, @ref cmsis_os2.h
*****************************************************************************/
__STATIC_INLINE int32_t sli_psec_osal_kernel_restore_lock(int32_t lock)
{
return osKernelRestoreLock(lock);
}
/***************************************************************************//**
* @brief Get current RTOS kernel state.
*
* @return Status code, @ref cmsis_os2.h
*****************************************************************************/
__STATIC_INLINE osKernelState_t
sli_psec_osal_kernel_get_state(void)
{
return osKernelGetState();
}
#ifdef __cplusplus
}
#endif
#endif // SLI_PSEC_OSAL_CMSIS_RTOS_H

View File

@@ -0,0 +1,101 @@
/**************************************************************************/ /**
* @file
* @brief OS abstraction layer primitives for platform/security on CMSIS RTOS2
*******************************************************************************
* # 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.
*
******************************************************************************/
// -----------------------------------------------------------------------------
// Includes
#include "sl_common.h"
#include "sli_psec_osal_cmsis_rtos2.h"
// -----------------------------------------------------------------------------
// Functions
/// Check if lock is open for calling thread
sl_status_t sli_psec_osal_lock_is_accessible(sli_psec_osal_lock_t *lock)
{
sl_status_t sl_status;
CORE_DECLARE_IRQ_STATE;
if (lock == NULL) {
return SL_STATUS_FAIL;
}
CORE_ENTER_CRITICAL();
osThreadId_t mutex_owner = osMutexGetOwner(lock->mutex_ID);
if (mutex_owner == NULL) {
sl_status = SL_STATUS_OK;
} else {
if (mutex_owner != osThreadGetId()) {
sl_status = SL_STATUS_FAIL;
} else {
if (lock->mutex_attr.attr_bits & osMutexRecursive) {
sl_status = SL_STATUS_OK;
} else {
sl_status = SL_STATUS_FAIL;
}
}
}
CORE_EXIT_CRITICAL();
return sl_status;
}
/// Attempt to take ownership or lock. Wait until available if already locked, or timeout.
sl_status_t sli_psec_osal_take_lock_timeout(sli_psec_osal_lock_t *lock, uint32_t timeout)
{
if (lock == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osOK;
if (osKernelGetState() == osKernelRunning) {
if (CORE_IRQ_DISABLED()) {
return sli_psec_osal_lock_is_accessible(lock);
} else {
status = osMutexAcquire(lock->mutex_ID, timeout);
}
}
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}
/// Release ownership of a lock.
sl_status_t sli_psec_osal_give_lock(sli_psec_osal_lock_t *lock)
{
if (lock == NULL) {
return SL_STATUS_FAIL;
}
osStatus_t status = osOK;
if (osKernelGetState() == osKernelRunning) {
if (CORE_IRQ_DISABLED()) {
return sli_psec_osal_lock_is_accessible(lock);
} else {
status = osMutexRelease(lock->mutex_ID);
}
}
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
}