Imported more library files
Not compiling currently
This commit is contained in:
@@ -0,0 +1,458 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_H
|
||||
#define SL_SE_MANAGER_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager SE Manager
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_core Core
|
||||
*
|
||||
* @brief
|
||||
* Secure Engine Manager Core API
|
||||
*
|
||||
* @details
|
||||
* API for initialization of SE Manager and SE command context with yield
|
||||
* attribute.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_cipher.h"
|
||||
#endif // SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
#include "sl_se_manager_types.h"
|
||||
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the SE Manager.
|
||||
*
|
||||
* @details
|
||||
* Initialize the SE Manager by checking hardware availability and setting up
|
||||
* internal module specific resources like mutexes etc.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Denitialize the SE Manager.
|
||||
*
|
||||
* @details
|
||||
* Free resources held by the SE Manager.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit(void);
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set the yield attribute of the SE command context object.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] yield
|
||||
* The user may set this parameter to true in order to tell the SE Manager
|
||||
* to yield the cpu core while waiting for the SE mailbox command to complete.
|
||||
* If false, the SE Manager will busy-wait, by polling the SE mailbox response
|
||||
* register until the SE mailbox command completes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_yield(sl_se_command_context_t *cmd_ctx,
|
||||
bool yield);
|
||||
#endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
|
||||
#if defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* From VSE mailbox read which command, if any, was executed.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object. If this function returns
|
||||
* SL_STATUS_OK the command word of the SE command context object will be set.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_executed_command(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command. The acknowledge operation invalidates the
|
||||
* contents of the output mailbox. The output data is copied into the linked
|
||||
* list of output buffers pointed to in the given command data structure.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
||||
#endif //defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize an SE command context object
|
||||
*
|
||||
* @details
|
||||
* Initialize an SE command context which can be used in subsequent calls to
|
||||
* the SE Manager API in order to execute SE mailbox commands.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object to be initialized. This context
|
||||
* object should be used in subsequent calls to the SE Manager API in order
|
||||
* to execute SE mailbox commands. The same command context object cannot be
|
||||
* used concurrently, e.g. by two different threads. However a command context
|
||||
* object may be reused for the next and any subsequent mailbox operatons,
|
||||
* except when streaming commands are in progress in which case only streaming
|
||||
* commands of the same operation type is allowed until the streaming operation
|
||||
* is finished (i.e. the corresponding sl_se_xxx_finish is called).
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* De-initialize an SE command context
|
||||
*
|
||||
* @details
|
||||
* De-initialize an SE command context object.
|
||||
*
|
||||
* @param[in,out] cmd_ctx
|
||||
* Pointer to an SE command context object to deinitialize.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_H
|
||||
|
||||
// THE REST OF THE FILE IS DOCUMENTATION ONLY
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
/// @details
|
||||
///
|
||||
/// The Secure Engine (SE) Manager provides thread-safe APIs for the Secure Engine's mailbox interface. Note that PSA Crypto is the recommended device independent crypto API and should be used
|
||||
/// whenever possible. The SE manager APIs can be used directly for performance or space constrained applications.
|
||||
///
|
||||
/// Available functionality will vary between devices: device management, such as secure firmware upgrade, secure boot and secure debug implementation, is available on all series 2 devices.
|
||||
/// Devices with the SE subsystem includes a low level crypto API where the SE Manager will use the SE hardware peripherals to accelerate cryptographic operations. Finally, Vault High
|
||||
/// devices also include secure key storage functionality, anti-tamper protection, advanced crypto API and attestation.
|
||||
///
|
||||
/// @note Below are some of the useful application notes linked with Secure Engine Manager:\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1190-efr32-secure-debug.pdf">AN1190: Series 2 Secure Debug</a>\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1247-efr32-secure-vault-tamper.pdf">AN1247: Anti-Tamper Protection Configuration and Use</a>\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1268-efr32-secure-identity.pdf">AN1268: Authenticating Silicon Labs Devices Using Device Certificates</a>\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1271-efr32-secure-key-storage.pdf">AN1271: Secure Key Storage</a>\n
|
||||
/// - <a href="https://www.silabs.com/documents/public/application-notes/an1218-secure-boot-with-rtsl.pdf">AN1218: Series 2 Secure Boot with RTSL</a>\n
|
||||
///
|
||||
/// # Functionality
|
||||
///
|
||||
/// The functionality of the SE Manager includes
|
||||
///
|
||||
/// - Core API, inititalizing of SE Manager and SE command context (@ref sl_se_manager_core)
|
||||
/// - Secure key storage (@ref sl_se_manager_key_handling)
|
||||
/// - Key wrapping
|
||||
/// - Storing keys in the SE volatile storage
|
||||
/// - Using key by reference
|
||||
/// - Configuration of tamper responses (@ref sl_se_manager_util)
|
||||
/// - The available signals include core hard-fault, glitch detectors, PRS, and failed authenticated commands,
|
||||
/// while the responses vary from triggering an interrupt to the hardware autonomously erasing the one-time-programmable (OTP) memory
|
||||
/// - Block ciphers (@ref sl_se_manager_cipher)
|
||||
/// - Supports AES-ECB, AES-CBC, AES-CFB128, AES-CFB8, AES-CTR, AES-CCM, AES-GCM, CMAC, HMAC and ChaCha20/Poly1305
|
||||
/// - The cipher operations can be performed using plaintext keys, wrapped keys or referencing a key in the SE
|
||||
/// - Streaming operations are supported for AES-GCM and CMAC
|
||||
/// - Block and streaming hash operations (@ref sl_se_manager_hash)
|
||||
/// - Supports SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512
|
||||
/// - True Random Number Generator (@ref sl_se_manager_entropy)
|
||||
/// - Hardware block inside the SE used for generating random numbers. Can be used as a source of entropy, or to securely generate keys inside the SE
|
||||
/// - Elliptic Curve Signature operation (@ref sl_se_manager_signature)
|
||||
/// - ECDSA and EDDSA
|
||||
/// - Key agreement (@ref sl_se_manager_key_derivation)
|
||||
/// - Perform Elliptic Curve Diffie-Hellman and J-PAKE key agreement operations inside the SE
|
||||
/// - Key derivation functions (@ref sl_se_manager_key_derivation)
|
||||
/// - Perform HKDF and PBKDF2 key derivation functions inside the SE
|
||||
/// - Device configuration and utilities (@ref sl_se_manager_util)
|
||||
/// - Write to user data stored inside the SE
|
||||
/// - Configuration of debug locks
|
||||
/// - Configuration of secure boot
|
||||
/// - Configuration of flash lock
|
||||
/// - Read SE OTP contents
|
||||
/// - Read SE firmware version
|
||||
/// - Read provisioned certificates
|
||||
/// - Multi-thread safe APIs for MicriumOS and FreeRTOS
|
||||
/// - Retrieveing attestation tokens (@ref sl_se_manager_attestation)
|
||||
///
|
||||
/// ## Key Storage and Use of SE Wrapped Keys
|
||||
///
|
||||
/// The way keys are stored and operated on depends on the options set in the key descriptor used (@ref sl_se_key_descriptor_t).
|
||||
/// Each key descriptor is initialized with a storage location, a key type, and length of the key (some key types have a known length, and it is not required to be set).
|
||||
/// The storage location can either be application memory or inside the SE, for more details, see @ref sl_se_storage_method_t.
|
||||
/// Depending on the use-case, the key descriptors will also store the pointer to a key and an SE key slot, see @ref sl_se_key_slot_t for the list of available internal SE key slots.
|
||||
///
|
||||
/// For more information on the key handling APIs see @ref sl_se_manager_key_handling.
|
||||
///
|
||||
/// ### Supported Key Types
|
||||
/// Symmetric keys
|
||||
/// - AES-128 (16 bytes)
|
||||
/// - AES-192 (24 bytes)
|
||||
/// - AES-256 (32 bytes)
|
||||
/// - ChaCha20 (32 bytes)
|
||||
///
|
||||
/// Asymmetric keys for ECC
|
||||
/// - NIST P-192
|
||||
/// - NIST P-256
|
||||
/// - NIST P-384
|
||||
/// - NIST P-521
|
||||
/// - Curve25519
|
||||
/// - Curve448
|
||||
///
|
||||
/// Custom Weierstrass Prime curves are also supported (@ref sl_se_custom_weierstrass_prime_domain_t).
|
||||
///
|
||||
/// ### Example Usage of Keys
|
||||
///
|
||||
/// @code{.c}
|
||||
/// #define WRAPPED_KEY_OVERHEAD (12UL + 16UL)
|
||||
/// #define AES_256_KEY_SIZE 32UL
|
||||
///
|
||||
/// uint8_t key_buffer[AES_256_KEY_SIZE];
|
||||
/// uint8_t wrapped_key_buffer[AES_256_KEY_SIZE + WRAPPED_KEY_OVERHEAD];
|
||||
///
|
||||
/// void demo_se_create_key_in_slot(void) {
|
||||
/// sl_se_key_descriptor_t new_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_generate_key(&new_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_create_plaintext_key(void) {
|
||||
/// sl_se_key_descriptor_t new_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
|
||||
/// };
|
||||
/// new_key.storage.location.buffer.pointer = key_buffer;
|
||||
/// new_key.storage.location.buffer.size = sizeof(key_buffer);
|
||||
/// sl_se_generate_key(&new_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_create_wrapped_key(void) {
|
||||
/// sl_se_key_descriptor_t new_wrapped_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// new_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// new_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_generate_key(&new_wrapped_key);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_wrapped_key_to_volatile_slot(void) {
|
||||
/// sl_se_key_descriptor_t existing_wrapped_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// existing_wrapped_key.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// existing_wrapped_key.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_key_descriptor_t key_in_slot = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_import_key(&existing_wrapped_key, &key_in_slot);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_volatile_slot_to_wrapped_key(void) {
|
||||
/// sl_se_key_descriptor_t existing_volatile_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_key_descriptor_t wrapped_key_out = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// };
|
||||
/// wrapped_key_out.storage.location.buffer.pointer = wrapped_key_buffer;
|
||||
/// wrapped_key_out.storage.location.buffer.size = sizeof(wrapped_key_buffer);
|
||||
/// sl_se_export_key(&existing_volatile_key, &wrapped_key_out);
|
||||
/// }
|
||||
///
|
||||
/// void demo_se_delete_from_volatile_slot(void) {
|
||||
/// sl_se_key_descriptor_t existing_volatile_key = {
|
||||
/// .type = SL_SE_KEY_TYPE_AES_256,
|
||||
/// .flags = SL_SE_KEY_FLAG_NON_EXPORTABLE,
|
||||
/// .storage.method = SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// .storage.location.slot = SL_SE_KEY_SLOT_VOLATILE_0,
|
||||
/// };
|
||||
/// sl_se_delete_key(&existing_volatile_key);
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// ## Tamper
|
||||
///
|
||||
/// The Secure Engine (SE) tamper module connects a number of hardware and software-driven tamper signals to a set of configurable hardware and software responses.
|
||||
/// This can be used to program the device to automatically respond to external events that could signal that someone is trying to tamper with the device,
|
||||
/// and very rapidly remove secrets stored in the SE. The available tamper signals range from signals based on failed authentication and secure boot to specialized glitch detectors.
|
||||
/// When any of these signals fire, the tamper block can be configured to trigger several different responses,
|
||||
/// ranging from triggering an interrupt to erasing the one-time-programmable (OTP) memory, removing all SE secrets and resulting in a permanently destroyed device.
|
||||
///
|
||||
/// A tamper signal can lead to a series of different autonomous responses from the tamper module. These responses are listed in the table below.
|
||||
/// | | Response | Description |
|
||||
/// | ----: | :----: | :---- |
|
||||
/// | 0 | Ignore | No action is taken. |
|
||||
/// | 1 | Interrupt | The SETAMPERHOST interrupt on the host is triggered. |
|
||||
/// | 2 | Filter | A counter in the tamper filter is increased. |
|
||||
/// | 4 | Reset | The device is reset. |
|
||||
/// | 7 | Erase OTP | Erases the OTP configuration of the device. |
|
||||
///
|
||||
/// These responses are cumulative, meaning that if a filter response is triggered, an interrupt will also be triggered. For a full overview of the tamper signals, see @ref sl_se_manager_defines.h.
|
||||
///
|
||||
/// The tamper configuration is one-time-programmable, and is done using the initialise OTP command to the SE (see @ref sl_se_init_otp).
|
||||
/// This means that tamper settings must be written together with secure boot settings, and are immutable after they are written.
|
||||
/// After tamper has been initialized, it is possible to temporarily disable one or several tamper signals using an authenticated command,
|
||||
/// similar to secure debug unlock. This is only possible if the debug public key has been installed on the device.
|
||||
/// It is only possible to disable the customer enabled response. The default response to a signal cannot be disabled.
|
||||
///
|
||||
/// Tamper is configured by providing the following:
|
||||
/// <table>
|
||||
/// <caption id="multi_row">Tamper configuration table</caption>
|
||||
/// <tr><th>Setting <th>Description
|
||||
/// <tr><td>Tamper response levels <td>A response level for each tamper signal.\n\n It is not possible to degrade the default response level of a tamper signal, so if a response is set to a lower level than the default response level listed in the table in the Signals section, this won't have any effect.
|
||||
/// <tr><td>Filter settings <td>The tamper filter counter has two settings:
|
||||
/// <ul>
|
||||
/// <li>Reset period
|
||||
/// <li>Trigger threshold
|
||||
/// </ul>
|
||||
/// These options can be set to the values given in the tables in the Response Filter section. Please see the examples section for a suggested use of the tamper filter signal.
|
||||
/// <tr><td>Flags <td>The tamper flags is used to configure two options:
|
||||
/// <ul>
|
||||
/// <li>Digital Glitch Detector Always On – This option will keep the digital glitch detector running even while the SE is not performing any operations. This leads to increased energy consumption.
|
||||
/// <li>Keep Tamper Alive During Sleep (not available on EFR32xG21B devices) – If set, the tamper module keeps running at sleep mode (down to EM3).
|
||||
/// </ul>
|
||||
/// <tr><td>Reset threshold <td>The number of consecutive tamper resets before the the part enters debug mode.\n\n
|
||||
/// If the threshold is set to 0, the part will never enter the debug mode due to tamper reset.
|
||||
/// </table>
|
||||
///
|
||||
/// ### Example Usage
|
||||
///
|
||||
/// The glitch detectors can see spurious activations, and should typically not be used to directly drive a serious tamper response.
|
||||
/// Instead they should feed their signals into a tamper interrupt (to handle the response logic on the M33), or into the tamper filter counter,
|
||||
/// which can be used to activate a high level response if a number of incidents occur in a short time window.
|
||||
/// The time period and counter threshold must be tuned to the use case. In the following example the device will erase OTP and become inoperable if 4 glitch signals is seen in a 1 minute time period.
|
||||
///
|
||||
/// Since you can only configure tamper once for each device, please make sure that this is the configuration you actually want before you execute this example on actual device.
|
||||
///
|
||||
/// @code{.c}
|
||||
/// sl_se_otp_init_t otp_settings_init = SL_SE_OTP_INIT_DEFAULT;
|
||||
///
|
||||
/// // Configure tamper levels
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_FILTER] = SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHFALLING] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_VGLITCHRISING] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
/// otp_settings_init.tamper_levels[SL_SE_TAMPER_SIGNAL_DGLITCH] = SL_SE_TAMPER_LEVEL_FILTER;
|
||||
///
|
||||
///
|
||||
/// // Configure tamper filter options
|
||||
/// otp_settings_init.tamper_filter_period = SL_SE_TAMPER_FILTER_PERIOD_1MIN;
|
||||
/// otp_settings_init.tamper_filter_threshold = SL_SE_TAMPER_FILTER_THRESHOLD_4;
|
||||
///
|
||||
///
|
||||
/// // Commit OTP settings. This command is only available once!
|
||||
/// sl_se_init_otp(&otp_settings_init);
|
||||
/// @endcode
|
||||
///
|
||||
/// ## RTOS Mode and Multi-Thread Safety
|
||||
///
|
||||
/// @note The SE Manager API is multi-thread safe, but does not support preemption.
|
||||
/// This means the API cannot be called from ISR or critical/atomic sections when running in an RTOS thread.
|
||||
/// When using the SE Manager API in a bare-metal application, it is the application developer's responsibility
|
||||
/// to not call the SE Manager APIs when another operation is in progress.
|
||||
///
|
||||
/// The SE Manager supports multi-thread safe APIs for MicriumOS and FreeRTOS interfacing with CMSIS RTOS2 APIs.
|
||||
///
|
||||
/// In the cases where Micrium OS or FreeRTOS are included in the project (RTOS-mode), the SE Manager will be configured with threading and yield support.
|
||||
/// Configure ::sl_se_command_context_t with ::sl_se_set_yield to yield the CPU core when the SE Manager is waiting for the Secure Engine to complete a mailbox command.
|
||||
///
|
||||
/// For threading support the SE Manager applies an SE lock mechanism to protect the Secure Engine Mailbox interface from being accessed by more than one thread,
|
||||
/// ensuring multi-thread safety. For yielding the CPU core while waiting for the SE, the SE Manager APIs that invoke
|
||||
/// SE mailbox commands will wait on a semaphore which is signaled in the ISR that handles the SE mailbox completion interrupt.
|
||||
/// Hence other threads may run on the CPU core while the SE is processing the mailbox command.
|
||||
///
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
@@ -0,0 +1,209 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_ATTESTATION_H
|
||||
#define SL_SE_MANAGER_ATTESTATION_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if (defined(SLI_MAILBOX_COMMAND_SUPPORTED) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT))
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_attestation Attestation
|
||||
*
|
||||
* @brief
|
||||
* System and configuration attestation
|
||||
*
|
||||
* @details
|
||||
* API for retrieveing attestation tokens from the SE.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// 32 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_32 (32U)
|
||||
/// 48 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_48 (48U)
|
||||
/// 64 byte challenge size
|
||||
#define SL_SE_ATTESTATION_CHALLENGE_SIZE_64 (64U)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the PSA initial attest token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes. Must be at least the size found by calling
|
||||
* \ref sl_se_attestation_get_psa_iat_token_size with equivalent arguments,
|
||||
* and padded to word alignment.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @warning
|
||||
* Once a nonce/challenge has been used, the same challenge should not be used
|
||||
* ever again, to prevent replay attacks.
|
||||
*
|
||||
* @warning
|
||||
* The output will be length-extended to the next word-multiple.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the size of a PSA initial attest token with the given nonce
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get an attested (signed) security configuration token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be 32.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes. Must be at least the size found by calling
|
||||
* \ref sl_se_attestation_get_config_token_size with equivalent arguments,
|
||||
* and padded to word alignment.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @warning
|
||||
* Once a nonce/challenge has been used, the same challenge should not be used
|
||||
* ever again, to prevent replay attacks.
|
||||
*
|
||||
* @warning
|
||||
* The output will be length-extended to the next word-multiple.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the size of a security configuration token
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be 32.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_attestation)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED && VAULT
|
||||
|
||||
#endif // SL_SE_MANAGER_ATTESTATION_H
|
||||
@@ -0,0 +1,61 @@
|
||||
/**************************************************************************/ /**
|
||||
* @file
|
||||
* @brief Consistency checks for SE Manager configuration options
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
#define SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING) \
|
||||
&& !defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) \
|
||||
&& !defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
#error "Yield when waiting for SE commands to finish is currently required in RTOS mode."
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) \
|
||||
&& !defined(SL_SE_MANAGER_THREADING)
|
||||
#error "Yield when waiting for SE commands to finish currently requires RTOS mode. I.e. yield support is not available in bare metal mode."
|
||||
#endif
|
||||
|
||||
#if (defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)) \
|
||||
&& !defined(SL_SE_MANAGER_THREADING)
|
||||
#error "RTOS requires threading mode."
|
||||
#endif
|
||||
|
||||
#if (defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) && defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION))
|
||||
#error "Yield support is not available on EFR32xG22 devices"
|
||||
#endif
|
||||
|
||||
#if (SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED != 1)
|
||||
#error "Using multiple blocks for key stream computation is not supported"
|
||||
#endif
|
||||
|
||||
#endif // SL_SE_MANAGER_CHECK_CONFIG_H
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,63 @@
|
||||
/**************************************************************************/ /**
|
||||
* @file
|
||||
* @brief SE Manager configuration options
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_SE_MANAGER_CONFIG_H
|
||||
#define SL_SE_MANAGER_CONFIG_H
|
||||
|
||||
/// This file include the configuration options of the SE Manager.
|
||||
/// For the time being the user should not change the default settings
|
||||
/// of the configuration options in this file.
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
// Threading support (as opposed to API calls only from a single thread)
|
||||
// is currently required in RTOS mode.
|
||||
#define SL_SE_MANAGER_THREADING
|
||||
|
||||
#if !defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION) && !defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Enable yield support. Configure sl_se_command_context_t to yield CPU while waiting for SE commands.
|
||||
// This is not supported on EFR32xG22.
|
||||
#define SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED
|
||||
#define SLI_SE_AES_CTR_NUM_BLOCKS_BUFFERED 1
|
||||
#endif
|
||||
|
||||
// Check consistency of configuration options.
|
||||
// Always include se_manager_check_config.h in order to assert that the
|
||||
// configuration options dependencies and restrictions are ok.
|
||||
#include "sl_se_manager_check_config.h"
|
||||
|
||||
#endif // SL_SE_MANAGER_CONFIG_H
|
||||
@@ -0,0 +1,533 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API definitions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_DEFINES_H
|
||||
#define SL_SE_MANAGER_DEFINES_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#if !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
#if !defined(SE_MANAGER_CONFIG_FILE)
|
||||
#include "sl_se_manager_config.h"
|
||||
#else
|
||||
#include SE_MANAGER_CONFIG_FILE
|
||||
#endif // SE_MANAGER_CONFIG_FILE
|
||||
#endif // SL_TRUSTZONE_NONSECURE
|
||||
#endif // SLI_SE_MANAGER_HOST_SYSTEM
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// @addtogroup sl_se_manager_core
|
||||
/// @{
|
||||
|
||||
/// Context initialization values. Some of the context values are not fully
|
||||
/// initialized. The user will need to call the corresponding initialization
|
||||
/// function in order to fully initialize the context objects for further use
|
||||
/// in the SE Manager API. The purpose of these initialization values is to set
|
||||
/// the context objects to a known safe state initially when the context object
|
||||
/// is declared.
|
||||
#define SL_SE_COMMAND_CONTEXT_INIT { SLI_SE_MAILBOX_COMMAND_DEFAULT(0), false }
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// Default configuration for OTP initialisation structure.
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SL_SE_OTP_INIT_DEFAULT \
|
||||
{ \
|
||||
.enable_secure_boot = false, \
|
||||
.verify_secure_boot_certificate = false, \
|
||||
.enable_anti_rollback = false, \
|
||||
.secure_boot_page_lock_narrow = false, \
|
||||
.secure_boot_page_lock_full = false, \
|
||||
.tamper_levels = { 0 }, \
|
||||
.tamper_filter_period = SL_SE_TAMPER_FILTER_PERIOD_2MIN, \
|
||||
.tamper_filter_threshold = SL_SE_TAMPER_FILTER_THRESHOLD_4, \
|
||||
.tamper_flags = 0, \
|
||||
.tamper_reset_threshold = 5 \
|
||||
}
|
||||
#else
|
||||
#define SL_SE_OTP_INIT_DEFAULT \
|
||||
{ \
|
||||
.enable_secure_boot = false, \
|
||||
.verify_secure_boot_certificate = false, \
|
||||
.enable_anti_rollback = false, \
|
||||
.secure_boot_page_lock_narrow = false, \
|
||||
.secure_boot_page_lock_full = false \
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// -------------------------------
|
||||
// Defines for SE functionality
|
||||
|
||||
/// @addtogroup sl_se_manager_key_handling
|
||||
/// @{
|
||||
|
||||
/// Asymmetric key can only be used for signing (not key exchange)
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY (1UL << 10)
|
||||
/// Described key belongs to a custom ECC domain
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_USES_CUSTOM_DOMAIN (1UL << 12)
|
||||
/// Storage buffer contains public part of an asymmetric key
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY (1UL << 13)
|
||||
/// Storage buffer contains private part of an asymmetric key
|
||||
#define SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY (1UL << 14)
|
||||
/// Allow usage of this key by other bus masters or TrustZone levels than the
|
||||
/// one which created/imported the key
|
||||
#define SL_SE_KEY_FLAG_ALLOW_ANY_ACCESS (1UL << 15)
|
||||
/// Old definition. Retained for backwards compatibility.
|
||||
#define SL_SE_KEY_FLAG_ASYMMMETRIC_SIGNING_ONLY \
|
||||
(SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY)
|
||||
|
||||
/// Do not allow exporting the key to plaintext
|
||||
#define SL_SE_KEY_FLAG_NON_EXPORTABLE (1UL << 24)
|
||||
/// Indicate that the key has been generated by this device. This flag is only
|
||||
/// valid when using the SE to generate a key and makes it non-exportable.
|
||||
#define SL_SE_KEY_FLAG_IS_DEVICE_GENERATED (1UL << 25)
|
||||
/// Indicate that the key can only be used to sign SE generated content. This
|
||||
/// flag is only valid when using the SE to generate a key and makes it
|
||||
/// non-exportable.
|
||||
#define SL_SE_KEY_FLAG_IS_RESTRICTED (1UL << 25 | 1UL << 24)
|
||||
|
||||
/// Mask for algorithm field in key type
|
||||
#define SL_SE_KEY_TYPE_ALGORITHM_MASK 0xf0000000
|
||||
/// Offset of algorithm field in key type
|
||||
#define SL_SE_KEY_TYPE_ALGORITHM_OFFSET 28
|
||||
/// Mask for attributes field in key type
|
||||
#define SL_SE_KEY_TYPE_ATTRIBUTES_MASK 0x00007fff
|
||||
/// Offset of attributes field in key type
|
||||
#define SL_SE_KEY_TYPE_ATTRIBUTES_OFFSET 0
|
||||
|
||||
/// Symmetric key type
|
||||
#define SL_SE_KEY_TYPE_SYMMETRIC 0x00000000
|
||||
/// Symmetric key type for AES-128 (16 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_128 0x00000010
|
||||
/// Symmetric key type for AES-192 (24 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_192 0x00000018
|
||||
/// Symmetric key type for AES-256 (32 byte key)
|
||||
#define SL_SE_KEY_TYPE_AES_256 0x00000020
|
||||
|
||||
/// ECC Weierstrass Prime key type
|
||||
#define SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM (0x8U << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
/// ECC Montgomery key type
|
||||
#define SL_SE_KEY_TYPE_ECC_MONTGOMERY (0xbU << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
/// EDDSA key type
|
||||
#define SL_SE_KEY_TYPE_ECC_EDDSA (0xcU << SL_SE_KEY_TYPE_ALGORITHM_OFFSET)
|
||||
|
||||
/// ECC NIST P-192
|
||||
#define SL_SE_KEY_TYPE_ECC_P192 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x18))
|
||||
/// ECC NIST P-224
|
||||
#define SL_SE_KEY_TYPE_ECC_P224 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x1C))
|
||||
/// ECC NIST P-256
|
||||
#define SL_SE_KEY_TYPE_ECC_P256 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x20))
|
||||
|
||||
/// ECC Ed25519 key for EdDSA
|
||||
#define SL_SE_KEY_TYPE_ECC_ED25519 (SL_SE_KEY_TYPE_ECC_EDDSA | (0x20))
|
||||
|
||||
/// ECC X25519 key for ECDH
|
||||
#define SL_SE_KEY_TYPE_ECC_X25519 (SL_SE_KEY_TYPE_ECC_MONTGOMERY | (0x20))
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Symmetric key type for ChaCha20
|
||||
#define SL_SE_KEY_TYPE_CHACHA20 0x00000020
|
||||
|
||||
/// ECC NIST P-384
|
||||
#define SL_SE_KEY_TYPE_ECC_P384 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x30))
|
||||
/// ECC NIST P-521
|
||||
#define SL_SE_KEY_TYPE_ECC_P521 (SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM | (0x42))
|
||||
|
||||
/// ECC X448 key for ECDH
|
||||
#define SL_SE_KEY_TYPE_ECC_X448 (SL_SE_KEY_TYPE_ECC_MONTGOMERY | (0x38))
|
||||
|
||||
/// ECC Ed448 key for EdDSA
|
||||
#define SL_SE_KEY_TYPE_ECC_ED448 (SL_SE_KEY_TYPE_ECC_EDDSA | (0x38))
|
||||
|
||||
#endif
|
||||
|
||||
/// Key storage methods
|
||||
|
||||
/// Key is stored in a plaintext buffer in application memory. Application
|
||||
/// can save its in-memory buffer to non-volatile memory as needed to
|
||||
/// provide key persistence.
|
||||
#define SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT 0x00
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Key is stored encrypted in application memory. This ensures the key in
|
||||
/// wrapped form is only usable on a specific device. If the key
|
||||
/// additionally needs to be prevented from ever being output as plaintext,
|
||||
/// also set the corresponding permission bit. Application can save its
|
||||
/// in-memory buffer to non-volatile memory as needed to provide key
|
||||
/// persistence.
|
||||
/// Keys stored in this way should use the flag
|
||||
/// SL_SE_KEY_FLAG_NON_EXPORTABLE unless there is a specific need to access
|
||||
/// the key value outside the SE.
|
||||
#define SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED 0x01
|
||||
/// Key is stored inside the SE, and will persist until system reset or
|
||||
/// explicitly deleted.
|
||||
/// Keys stored in this way should use the flag
|
||||
/// SL_SE_KEY_FLAG_NON_EXPORTABLE unless there is a specific need to access
|
||||
/// the key value outside the SE.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_VOLATILE 0x02
|
||||
#endif
|
||||
/// Key is one of the pre-defined keys (pre-loaded or write-once) available
|
||||
/// in the SE. See documentation for a list of available keys.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE 0x03
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Key is stored in the KSURAM, an internal Key Slot RAM.
|
||||
#define SL_SE_KEY_STORAGE_INTERNAL_KSU 0x04
|
||||
#endif
|
||||
|
||||
/// List of available internal SE key slots
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_0 0x00 ///< Internal volatile slot 0
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_1 0x01 ///< Internal volatile slot 1
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_2 0x02 ///< Internal volatile slot 2
|
||||
#define SL_SE_KEY_SLOT_VOLATILE_3 0x03 ///< Internal volatile slot 3
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_SUPPORTS_NVM3_INTERNAL_KEY)
|
||||
/// Minimum key slot value for internal keys
|
||||
#define SL_SE_KEY_SLOT_INTERNAL_MIN 0xF6
|
||||
/// Internal NVM3 key
|
||||
#define SL_SE_KEY_SLOT_NVM3_KEY 0xF6
|
||||
#else
|
||||
/// Minimum key slot value for internal keys
|
||||
#define SL_SE_KEY_SLOT_INTERNAL_MIN 0xF7
|
||||
#endif
|
||||
/// Internal TrustZone root key
|
||||
#define SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY 0xF7
|
||||
/// Internal immutable application secure debug key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY 0xF8
|
||||
/// Internal immutable application AES-128 key (bootloader key)
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY 0xFA
|
||||
/// Internal immutable application secure boot key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY 0xFC
|
||||
/// Internal immutable application attestation key
|
||||
#define SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY 0xFE
|
||||
/// Internal immutable SE attestation key
|
||||
#define SL_SE_KEY_SLOT_SE_ATTESTATION_KEY 0xFF
|
||||
|
||||
/// Size overhead for wrapped keys
|
||||
#define SLI_SE_WRAPPED_KEY_OVERHEAD (12 + 16)
|
||||
/// @} (end addtogroup sl_se_manager_key_handling)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_derivation
|
||||
/// @{
|
||||
|
||||
/// Defines mapping the PBKDF2 PRFs to corresponding sl_se_hash_type_t values.
|
||||
#define SL_SE_PRF_AES_CMAC_128 SL_SE_HASH_NONE ///< CMAC-AES-128
|
||||
#define SL_SE_PRF_HMAC_SHA1 SL_SE_HASH_SHA1 ///< HMAC-SHA-1
|
||||
#define SL_SE_PRF_HMAC_SHA224 SL_SE_HASH_SHA224 ///< HMAC-SHA-224
|
||||
#define SL_SE_PRF_HMAC_SHA256 SL_SE_HASH_SHA256 ///< HMAC-SHA-256
|
||||
#define SL_SE_PRF_HMAC_SHA384 SL_SE_HASH_SHA384 ///< HMAC-SHA-384
|
||||
#define SL_SE_PRF_HMAC_SHA512 SL_SE_HASH_SHA512 ///< HMAC-SHA-512
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE Challenge size
|
||||
#define SL_SE_CHALLENGE_SIZE 16
|
||||
|
||||
/// Certificate key size
|
||||
#define SL_SE_CERT_KEY_SIZE 64
|
||||
|
||||
/// Certificate signature size
|
||||
#define SL_SE_CERT_SIGN_SIZE 64
|
||||
|
||||
/// Batch ID certificate
|
||||
#define SL_SE_CERT_BATCH 0x01
|
||||
/// SE ID certificate
|
||||
#define SL_SE_CERT_DEVICE_SE 0x02
|
||||
/// Host ID certificate
|
||||
#define SL_SE_CERT_DEVICE_HOST 0x03
|
||||
|
||||
/// @addtogroup sl_se_manager_util_tamper Tamper options
|
||||
/// @brief
|
||||
/// Tamper configuration options. Levels, signals and filter options.
|
||||
/// @{
|
||||
|
||||
// SE tamper signal levels
|
||||
#define SL_SE_TAMPER_LEVEL_IGNORE 0 ///< No action taken
|
||||
#define SL_SE_TAMPER_LEVEL_INTERRUPT 1 ///< Generate interrupt
|
||||
#define SL_SE_TAMPER_LEVEL_FILTER 2 ///< Increment filter counter
|
||||
#define SL_SE_TAMPER_LEVEL_RESET 4 ///< System reset
|
||||
#define SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP 7 ///< Erase OTP - THIS WILL MAKE THE DEVICE INOPERATIONAL!
|
||||
|
||||
// SE tamper signals
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_CRC 0x4 ///< SE RAM CRC parity error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x10 ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x11 ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x12 ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x13 ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x14 ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x15 ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS6 0x16 ///< PRS channel 6 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS7 0x17 ///< PRS channel 7 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_DECOUPLE_BOD 0x18 ///< Decouple brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x19 ///< On-device temperature sensor detects operation outside datasheet specification
|
||||
#define SL_SE_TAMPER_SIGNAL_VOLTAGE_GLITCH_FALLING 0x1A ///< Voltage glitch detector detected falling glitch
|
||||
#define SL_SE_TAMPER_SIGNAL_VOLTAGE_GLITCH_RISING 0x1B ///< Voltage glitch detector detected rising glitch
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x1C ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_DEBUG_GRANTED 0x1D ///< SE debug granted
|
||||
#define SL_SE_TAMPER_SIGNAL_DIGITAL_GLITCH 0x1E ///< Digital glitch detector detected an event
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_ICACHE_ERROR 0x1F ///< SE ICACHE checksum error
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5) || defined(_SILICON_LABS_32B_SERIES_2_CONFIG_9)
|
||||
|
||||
// SE tamper signals for xG25 and xG29, with ETAMPDET signal included.
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_2 0x4 ///< SE RAM 2-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x10 ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_ATAMPDET_EMPGD 0x11 ///< Electromagnetic pulse glitch detector
|
||||
#define SL_SE_TAMPER_ATAMPDET_SUPGD 0x12 ///< Supply glitch detector
|
||||
#define SL_SE_TAMPER_SE_ICACHE_ERROR 0x13 ///< SE ICache RAM error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_1 0x14 ///< SE RAM 1-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_BOD 0x15 ///< Brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x16 ///< On-device temperature sensor
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_LOW 0x17 ///< DPLL lock fail low
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_HIGH 0x18 ///< DPLL lock fail high
|
||||
#define SL_SE_TAMPER_SIGNAL_ETAMPDET 0x19 ///< External tamper detect
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x1a ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x1b ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x1c ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x1d ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x1e ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x1f ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#else
|
||||
|
||||
// SE tamper signals
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_1 0x0 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_FILTER_COUNTER 0x1 ///< Filter counter exceeds threshold
|
||||
#define SL_SE_TAMPER_SIGNAL_WATCHDOG 0x2 ///< SE watchdog timeout
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_2 0x3 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_2 0x4 ///< SE RAM 2-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_HARDFAULT 0x5 ///< SE CPU hardfault
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_3 0x6 ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SOFTWARE_ASSERTION 0x7 ///< SE software triggers an assert
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_SECURE_BOOT_FAILED 0x8 ///< Secure boot of SE firmware failed
|
||||
#define SL_SE_TAMPER_SIGNAL_USER_SECURE_BOOT_FAILED 0x9 ///< Secure boot of user code failed
|
||||
#define SL_SE_TAMPER_SIGNAL_MAILBOX_AUTHORIZATION_ERROR 0xA ///< Unauthorised command received over the Mailbox interface
|
||||
#define SL_SE_TAMPER_SIGNAL_DCI_AUTHORIZATION_ERROR 0xB ///< Unauthorised command received over the DCI interface
|
||||
#define SL_SE_TAMPER_SIGNAL_FLASH_INTEGRITY_ERROR 0xC ///< Flash content couldn't be properly authenticated
|
||||
#define SL_SE_TAMPER_SIGNAL_RESERVED_4 0xD ///< Reserved tamper signal
|
||||
#define SL_SE_TAMPER_SIGNAL_SELFTEST_FAILED 0xE ///< Integrity error of internal storage is detected
|
||||
#define SL_SE_TAMPER_SIGNAL_TRNG_MONITOR 0xF ///< TRNG monitor detected lack of entropy
|
||||
#define SL_SE_TAMPER_SIGNAL_SECURE_LOCK_ERROR 0x10 ///< Debug lock internal logic check failed
|
||||
#define SL_SE_TAMPER_ATAMPDET_EMPGD 0x11 ///< Electromagnetic pulse glitch detector
|
||||
#define SL_SE_TAMPER_ATAMPDET_SUPGD 0x12 ///< Supply glitch detector
|
||||
#define SL_SE_TAMPER_SE_ICACHE_ERROR 0x13 ///< SE ICache RAM error
|
||||
#define SL_SE_TAMPER_SIGNAL_SE_RAM_ECC_1 0x14 ///< SE RAM 1-bit ECC error
|
||||
#define SL_SE_TAMPER_SIGNAL_BOD 0x15 ///< Brown-out-detector threshold alert
|
||||
#define SL_SE_TAMPER_SIGNAL_TEMPERATURE_SENSOR 0x16 ///< On-device temperature sensor
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_LOW 0x17 ///< DPLL lock fail low
|
||||
#define SL_SE_TAMPER_SIGNAL_DPLL_LOCK_FAIL_HIGH 0x18 ///< DPLL lock fail high
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS0 0x19 ///< PRS channel 0 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS1 0x1a ///< PRS channel 1 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS2 0x1b ///< PRS channel 2 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS3 0x1c ///< PRS channel 3 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS4 0x1d ///< PRS channel 4 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS5 0x1e ///< PRS channel 5 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_PRS6 0x1f ///< PRS channel 6 asserted
|
||||
#define SL_SE_TAMPER_SIGNAL_NUM_SIGNALS 0x20 ///< Number of tamper signals
|
||||
|
||||
#endif
|
||||
|
||||
// SE tamper filter timeout period.
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_32MS 0x0 ///< Timeout ~32ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_64MS 0x1 ///< Timeout ~64ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_128MS 0x2 ///< Timeout ~128ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_256MS 0x3 ///< Timeout ~256ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_512MS 0x4 ///< Timeout ~512ms
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1S 0x5 ///< Timeout ~1s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2S 0x6 ///< Timeout ~2s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_4S 0x7 ///< Timeout ~4.1s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_8S 0x8 ///< Timeout ~8.2s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_16S 0x9 ///< Timeout ~16.4s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_33S 0xA ///< Timeout ~32.8s
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1MIN 0xB ///< Timeout ~1.1min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2MIN 0xC ///< Timeout ~2.2min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_4MIN 0xD ///< Timeout ~4.4min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_9MIN 0xE ///< Timeout ~8.7min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_18MIN 0xF ///< Timeout ~17.5min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_35MIN 0x10 ///< Timeout ~35min
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_1H 0x11 ///< Timeout ~1.2h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2H 0x12 ///< Timeout ~2.3h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_5H 0x13 ///< Timeout ~4.7h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_9H 0x14 ///< Timeout ~9.3h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_19H 0x15 ///< Timeout ~18.6h
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_2DAYS 0x16 ///< Timeout ~1.6days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_3DAYS 0x17 ///< Timeout ~3.1days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_6DAYS 0x18 ///< Timeout ~6.2days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_12DAYS 0x19 ///< Timeout ~12.4days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_25DAYS 0x1A ///< Timeout ~24.9days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_50DAYS 0x1B ///< Timeout ~49.7days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_100DAYS 0x1C ///< Timeout ~99.4days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_199DAYS 0x1D ///< Timeout ~198.8days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_398DAYS 0x1E ///< Timeout ~397.7days
|
||||
#define SL_SE_TAMPER_FILTER_PERIOD_795DAYS 0x1F ///< Timeout ~795.4days
|
||||
|
||||
// Number of tamper counts to trigger the filter signal.
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_2 0x7 ///< Counter threshold 2
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_4 0x6 ///< Counter threshold 4
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_8 0x5 ///< Counter threshold 8
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_16 0x4 ///< Counter threshold 16
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_32 0x3 ///< Counter threshold 32
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_64 0x2 ///< Counter threshold 64
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_128 0x1 ///< Counter threshold 128
|
||||
#define SL_SE_TAMPER_FILTER_THRESHOLD_256 0x0 ///< Counter threshold 256
|
||||
|
||||
/// Tamper flags.
|
||||
#define SL_SE_TAMPER_FLAG_DGLITCH_ALWAYS_ON (1UL << 1) /// Digital glitch detector always on
|
||||
#define SL_SE_TAMPER_FLAG_KEEP_TAMPER_ALIVE_DURING_SLEEP (1UL << 2) /// Tamper is kept alive during sleep (down to EM3)
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util_tamper)
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#ifdef SL_SUPPRESS_DEPRECATION_WARNINGS_SDK_2025_6
|
||||
/// Initial values for CMAC streaming context struct @ref sl_se_cmac_multipart_context_t
|
||||
#define SL_SE_CMAC_STREAMING_INIT_DEFAULT { NULL, { 0 }, { 0 }, 0 }
|
||||
|
||||
/// Initial values for AES-GCM streaming context struct @ref sl_se_gcm_multipart_context_t
|
||||
#define SL_SE_GCM_STREAMING_INIT_DEFAULT { NULL, 0, 0, { 0 }, { 0 }, \
|
||||
{ 0 }, 0, 0 }
|
||||
#else
|
||||
#define SL_SE_GCM_STREAMING_INIT_DEFAULT _Pragma("GCC warning \"'SL_SE_GCM_STREAMING_INIT_DEFAULT' macro is deprecated as of Simplicity SDK release 2024.12\""){ NULL, 0, 0, { 0 }, { 0 }, \
|
||||
{ 0 }, 0, 0 }
|
||||
|
||||
#define SL_SE_CMAC_STREAMING_INIT_DEFAULT _Pragma("GCC warning \"'SL_SE_CMAC_STREAMING_INIT_DEFAULT' macro is deprecated as of Simplicity SDK release 2024.12\"") { NULL, { 0 }, { 0 }, 0 }
|
||||
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
/// @addtogroup sl_se_manager_cipher
|
||||
/// @{
|
||||
|
||||
/// Block size for the AES
|
||||
#define SL_SE_AES_BLOCK_SIZE (16u)
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_cipher)
|
||||
|
||||
/// @addtogroup sl_se_manager_hash
|
||||
/// @{
|
||||
#define SL_SE_HASH_STREAMING_INIT_DEFAULT { NULL, 0, 0, NULL } ///< Default streaming hash context
|
||||
#define SL_SE_SHA1_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA1 streaming hash context
|
||||
#define SL_SE_SHA224_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA224 streaming hash context
|
||||
#define SL_SE_SHA256_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA256 streaming hash context
|
||||
#define SL_SE_SHA384_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA384 streaming hash context
|
||||
#define SL_SE_SHA512_STREAMING_INIT_DEFAULT { { 0 }, { 0 }, { 0 } } ///< SHA512 streaming hash context
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
|
||||
#elif defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// -------------------------------
|
||||
// Defines for Root code functionality
|
||||
|
||||
#define SL_SE_ROOT_CONFIG_MCU_SETTINGS_SHIFT 16U
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// @addtogroup sl_se_manager_extmem
|
||||
/// @{
|
||||
|
||||
// The maximum number of code regions available on the device.
|
||||
// The number of available code regions may be different on future devices.
|
||||
#define SL_SE_MAX_CODE_REGIONS 8
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_extmem)
|
||||
|
||||
#endif // defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SE_MANAGER_DEFINES_H
|
||||
@@ -0,0 +1,97 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_ENTROPY_H
|
||||
#define SL_SE_MANAGER_ENTROPY_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_entropy Entropy
|
||||
*
|
||||
* @brief
|
||||
* Random number generators
|
||||
* @details
|
||||
*
|
||||
* API for getting randomness from the Secure Engine True Random Number
|
||||
* Generator (TRNG).
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get random data from hardware TRNG.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] data
|
||||
* Random data from TRNG.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of data request.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_random(sl_se_command_context_t *cmd_ctx,
|
||||
void *data,
|
||||
uint32_t num_bytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_entropy)
|
||||
/// @} (end addtogroup sl_se)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_ENTROPY_H
|
||||
@@ -0,0 +1,308 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_HASH_H
|
||||
#define SL_SE_MANAGER_HASH_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_hash Hashing
|
||||
*
|
||||
* @brief
|
||||
* Provides cryptographic hash functions (SHA-1, SHA-224, SHA-256, SHA-384,
|
||||
* SHA-512).
|
||||
*
|
||||
* @details
|
||||
* Provides API for one-way hashing functions.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Produce a message digest (a hash block) using the input data.
|
||||
*
|
||||
* @details
|
||||
* This function generates a message digest adhering to the given inputs.
|
||||
* For instance, if the algorithm is chosen to be SHA-256, it will generate
|
||||
* a 32 bytes message digest computed based on the input message.
|
||||
* This function supports SHA-1, SHA-256 and SHA-512 algorithms.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] hash_type
|
||||
* Which hashing algorithm to use.
|
||||
*
|
||||
* @param[in] message
|
||||
* Pointer to the message buffer to compute the hash/digest from.
|
||||
*
|
||||
* @param[in] message_size
|
||||
* Number of bytes in message.
|
||||
*
|
||||
* @param[out] digest
|
||||
* Pointer to block of memory to store the final digest.
|
||||
*
|
||||
* @param[in] digest_len
|
||||
* The length of the message digest (hash), must be at least the size of the
|
||||
* corresponding hash type.
|
||||
*
|
||||
* @return Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
const uint8_t *message,
|
||||
unsigned int message_size,
|
||||
uint8_t* digest,
|
||||
size_t digest_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA1 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA1 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha1_ctx
|
||||
* Pointer to a SHA1 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t *sha1_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA224 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA224 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha224_ctx
|
||||
* Pointer to a SHA224 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t *sha224_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA256 hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA256 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha256_ctx
|
||||
* Pointer to a SHA256 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t *sha256_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA384 streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA384 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha384_ctx
|
||||
* Pointer to a SHA384 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t *sha384_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a SHA512 streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a SHA512 hash streaming command context object to be used in
|
||||
* subsequent calls to hash streaming functions sl_se_hash_multipart_update() and
|
||||
* sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] sha512_ctx
|
||||
* Pointer to a SHA512 streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t *sha512_ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a hash streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a hash (message digest) streaming command context object to be
|
||||
* used in subsequent calls to hash streaming functions sl_se_hash_multipart_update()
|
||||
* and sl_se_hash_multipart_finish().
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] hash_type
|
||||
* Type of hash algoritm
|
||||
*
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_starts(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
*
|
||||
* This function is called between @ref sl_se_hash_multipart_starts() and
|
||||
* @ref sl_se_hash_multipart_finish().
|
||||
* This function can be called repeatedly.
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] input
|
||||
* Buffer holding the input data, must be at least @p ilen bytes wide.
|
||||
*
|
||||
* @param[in] input_len
|
||||
* The length of the input data in bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Finish a hash streaming operation and return the resulting hash digest.
|
||||
*
|
||||
* This function is called after sl_se_hash_multipart_update().
|
||||
*
|
||||
* @param[in] hash_type_ctx
|
||||
* Pointer to a hash streaming context object specific to the hash type
|
||||
* specified by @p hash_type.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] digest_out
|
||||
* Buffer for holding the message digest (hash), must be at least the size
|
||||
* of the corresponding message digest type.
|
||||
*
|
||||
* @param[in] digest_len
|
||||
* The length of the message digest (hash), must be at least the size of the
|
||||
* corresponding hash type.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_finish(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_HASH_H
|
||||
@@ -0,0 +1,143 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager Internal key defines
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_INTERNAL_KEYS
|
||||
#define SL_SE_MANAGER_INTERNAL_KEYS
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
#include "sl_se_manager_defines.h"
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
/// Key descriptor for internal application attestation key
|
||||
#define SL_SE_APPLICATION_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE \
|
||||
| SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#else
|
||||
/// Key descriptor for internal application attestation key
|
||||
#define SL_SE_APPLICATION_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Key descriptor for internal SE attestation key
|
||||
/// @note: Can only be used to get the public part
|
||||
#define SL_SE_SYSTEM_ATTESTATION_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE \
|
||||
| SL_SE_KEY_FLAG_IS_DEVICE_GENERATED \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PRIVATE_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_SE_ATTESTATION_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
/// Key descriptor for secure boot public key
|
||||
#define SL_SE_APPLICATION_SECURE_BOOT_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_SECURE_BOOT_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for secure debug public key
|
||||
#define SL_SE_APPLICATION_SECURE_DEBUG_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_ECC_P256, \
|
||||
.flags = SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY \
|
||||
| SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for application AES-128 key
|
||||
#define SL_SE_APPLICATION_AES_128_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_AES_128, \
|
||||
.flags = SL_SE_KEY_FLAG_NON_EXPORTABLE, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_APPLICATION_AES_128_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/// Key descriptor for TrustZone root key
|
||||
#define SL_SE_TRUSTZONE_ROOT_KEY \
|
||||
{ \
|
||||
.type = SL_SE_KEY_TYPE_AES_256, \
|
||||
.flags = SL_SE_KEY_FLAG_IS_DEVICE_GENERATED, \
|
||||
.storage = { \
|
||||
.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE, \
|
||||
.location = { \
|
||||
.slot = SL_SE_KEY_SLOT_TRUSTZONE_ROOT_KEY, \
|
||||
}, \
|
||||
}, \
|
||||
}
|
||||
#endif // SL_SE_MANAGER_INTERNAL_KEYS
|
||||
@@ -0,0 +1,436 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
#define SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_key_derivation Key derivation
|
||||
*
|
||||
* @brief
|
||||
* API for key derivation and key agreement (ECDH, EC J-PAKE, HKDF, PBKDF2).
|
||||
*
|
||||
* @details
|
||||
* Contains key derivation functions (HKDF, PBKDF2) and key agreement
|
||||
* functions (ECDH, ECJPAKE).
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
// -------------------------------
|
||||
// Elliptic-curve Diffie–Hellman
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function computes the shared secret with Elliptic Curve Diffie Hellman
|
||||
* (ECDH) algorithm
|
||||
*
|
||||
* @details
|
||||
* Performs Elliptic Curve Diffie Hellman shared secret computation.
|
||||
*
|
||||
* @note
|
||||
* P-521 Elliptic Curve based Elliptic Curve Diffie Hellman (ECDH) expects
|
||||
* a 544 bits (68 bytes) buffer for storing private keys, and
|
||||
* a 1088 bits (136 bytes) buffer for storing public keys and shared secret.
|
||||
* The first 23 bits of d, Qx, Qy and shared secret are padding bits to comply
|
||||
* word-aligned addressing. The padding bits are ignored in the computation.
|
||||
*
|
||||
* This function does not implement the value-checking of the shared secret
|
||||
* as described in RFC7748 when using Montgomery keys.
|
||||
*
|
||||
* In case of using custom domain curves, \p key_in_priv defines the domain
|
||||
* parameters. Moreover, \p key_in_pub should always contain a public key.
|
||||
* If key_in_pub contains a private key, sl_se_export_public_key() can be
|
||||
* used to export the public key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in_priv
|
||||
* Our private key.
|
||||
*
|
||||
* @param[in] key_in_pub
|
||||
* Their public key.
|
||||
*
|
||||
* @param[out] key_out
|
||||
* Shared secret key. Montgomery curve result is one single coordinate.
|
||||
* Other curve types result in one pair of coordinate.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_INVALID_KEY if \p key_in_pub does not contain a public key
|
||||
* when using custom domain curves, otherwise an appropriate error code
|
||||
* (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecdh_compute_shared_secret(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in_priv,
|
||||
const sl_se_key_descriptor_t *key_in_pub,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
// -------------------------------
|
||||
// EC J-PAKE
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check if an EC J-PAKE context is ready for use.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to check. This must be initialized.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_check(const sl_se_ecjpake_context_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive the shared secret (TLS: Pre-Master Secret).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized, set up and have
|
||||
* performed both round one and two.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the derived secret to. This must be a writable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_derive_secret(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This clears an EC J-PAKE context and frees any embedded data structure.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to free. This may be @c NULL, in which case this
|
||||
* function does nothing. If it is not @c NULL, it must point to an
|
||||
* initialized EC J-PAKE context.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_free(sl_se_ecjpake_context_t *ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize an EC J-PAKE context.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to initialize. This must not be @c NULL.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_init(sl_se_ecjpake_context_t *ctx,
|
||||
sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read and process the first round message (TLS: contents of the
|
||||
* Client/ServerHello extension, excluding extension type and length bytes).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up.
|
||||
*
|
||||
* @param[in] buf
|
||||
* The buffer holding the first round message. This must be a readable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length in bytes of @p buf.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_read_round_one(sl_se_ecjpake_context_t *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read and process the second round message (TLS: contents of the
|
||||
* Client/ServerKeyExchange).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up and already
|
||||
* have performed round one.
|
||||
*
|
||||
* @param[in] buf
|
||||
* The buffer holding the second round message. This must be a readable buffer
|
||||
* of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length in bytes of @p buf.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_read_round_two(sl_se_ecjpake_context_t *ctx,
|
||||
const unsigned char *buf,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set up an EC J-PAKE context for use.
|
||||
*
|
||||
* @note
|
||||
* Currently the only values for hash/curve allowed by the standard are
|
||||
* @ref SL_SE_HASH_SHA256 / @ref SL_SE_KEY_TYPE_ECC_P256.
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to set up. This must be initialized.
|
||||
*
|
||||
* @param[in] role
|
||||
* The role of the caller. This must be either @ref SL_SE_ECJPAKE_CLIENT or
|
||||
* @ref SL_SE_ECJPAKE_SERVER.
|
||||
*
|
||||
* @param[in] hash
|
||||
* The identifier of the hash function to use, for example
|
||||
* @ref SL_SE_HASH_SHA256.
|
||||
*
|
||||
* @param[in] curve
|
||||
* The identifier of the elliptic curve to use, for example
|
||||
* @ref SL_SE_KEY_TYPE_ECC_P256.
|
||||
*
|
||||
* @param[in] secret
|
||||
* The pre-shared secret (passphrase). This must be a readable buffer of
|
||||
* length @p len bytes. It need only be valid for the duration of this call.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of the pre-shared secret @p secret.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_setup(sl_se_ecjpake_context_t *ctx,
|
||||
sl_se_ecjpake_role_t role,
|
||||
sl_se_hash_type_t hash,
|
||||
uint32_t curve,
|
||||
const unsigned char *secret,
|
||||
size_t len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate and write the first round message (TLS: contents of the
|
||||
* Client/ServerHello extension, excluding extension type and length bytes).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized and set up.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the contents to. This must be a writable buffer of
|
||||
* length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The length of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_write_round_one(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate and write the second round message (TLS: contents of the
|
||||
* Client/ServerKeyExchange).
|
||||
*
|
||||
* @param[in] ctx
|
||||
* The EC J-PAKE context to use. This must be initialized, set up, and already
|
||||
* have performed round one.
|
||||
*
|
||||
* @param[out] buf
|
||||
* The buffer to write the round two contents to. This must be a writable
|
||||
* buffer of length @p len bytes.
|
||||
*
|
||||
* @param[in] len
|
||||
* The size of @p buf in bytes.
|
||||
*
|
||||
* @param[out] olen
|
||||
* The address at which to store the total number of bytes written to @p buf.
|
||||
* This must not be @c NULL.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecjpake_write_round_two(sl_se_ecjpake_context_t *ctx,
|
||||
unsigned char *buf,
|
||||
size_t len,
|
||||
size_t *olen);
|
||||
|
||||
// -------------------------------
|
||||
// Key derivation functions
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive a pseudorandom key from the input key material using HKDF.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] in_key
|
||||
* Pointer to the input key material.
|
||||
*
|
||||
* @param[in] hash
|
||||
* Which hashing algorithm to use.
|
||||
*
|
||||
* @param[in] salt
|
||||
* An optional salt value (a non-secret random value).
|
||||
*
|
||||
* @param[in] salt_len
|
||||
* The length of the salt.
|
||||
*
|
||||
* @param[in] info
|
||||
* An optional context and application specific information string.
|
||||
*
|
||||
* @param[in] info_len
|
||||
* The length of info.
|
||||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *in_key,
|
||||
sl_se_hash_type_t hash,
|
||||
const unsigned char *salt,
|
||||
size_t salt_len,
|
||||
const unsigned char *info,
|
||||
size_t info_len,
|
||||
sl_se_key_descriptor_t *out_key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Derive a pseudorandom key from the input key material using PBKDF2.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] in_key
|
||||
* Pointer to the input key material.
|
||||
*
|
||||
* @param[in] prf
|
||||
* The underlying psuedorandom function (PRF) to use in the algorithm. The
|
||||
* most common choice of HMAC-SHA-{1, 224, 256, 384, 512} is supported on all
|
||||
* Series-2 devices (with Vault High Security). Newer chips, EFR32xG23 and
|
||||
* later, also support usage of AES-CMAC-PRF-128.
|
||||
*
|
||||
* @param[in] salt
|
||||
* An optional salt value (a non-secret random value).
|
||||
*
|
||||
* @param[in] salt_len
|
||||
* The length of the salt.
|
||||
*
|
||||
* @param[in] iterations
|
||||
* The number of iterations to use. Up to 16384 iterations is supported.
|
||||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropriate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_derive_key_pbkdf2(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *in_key,
|
||||
sl_se_pbkdf2_prf_type_t prf,
|
||||
const unsigned char *salt,
|
||||
size_t salt_len,
|
||||
uint32_t iterations,
|
||||
sl_se_key_descriptor_t *out_key);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_KEY_DERIVATION_H
|
||||
@@ -0,0 +1,258 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager key handling.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_KEY_HANDLING_H
|
||||
#define SL_SE_MANAGER_KEY_HANDLING_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se_manager_key_handling Key handling
|
||||
*
|
||||
* \brief Secure Engine key handling API.
|
||||
*
|
||||
* \details
|
||||
* API for using cryptographic keys with the SE. Contains functionality to
|
||||
* generate, import and export keys to and from protected types like wrapped
|
||||
* or volatile keys.
|
||||
*
|
||||
* \{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate key descriptor.
|
||||
*
|
||||
* @details
|
||||
* Takes a key descriptor and checks if all required properties have been set
|
||||
* for the specific key type.
|
||||
*
|
||||
* @param[in] key
|
||||
* The key to validate.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_validate_key(const sl_se_key_descriptor_t *key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Generate a random key adhering to the given key descriptor
|
||||
*
|
||||
* @details
|
||||
* The SE takes a key descriptor and generates a key with the given properties
|
||||
* in the location specified by the descriptor.
|
||||
*
|
||||
* If the key size is not aligned to a multiple of words the key
|
||||
* representation is padded in front of the key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Description of the key to generate. Sets key parameters and describes the
|
||||
* storage location for the key.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_generate_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Import a key using the SE
|
||||
*
|
||||
* @details
|
||||
* Protect a key using the SE. Import a plaintext key and store it either in a
|
||||
* volatile slot or as a wrapped key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* A plaintext key.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Either a volatile or a wrapped key with similar properties as key_in.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_import_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Export a volatile or wrapped key back to plaintext
|
||||
*
|
||||
* @details
|
||||
* Attempt to have the SE export a volatile or wrapped key back to plaintext
|
||||
* if allowed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* Either a volatile or a wrapped key with similar properties as key_out.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* The exported key in plaintext.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
* SL_STATUS_INVALID_PARAMETER if key does not exist.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_export_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Transfer a volatile or wrapped key to another protected storage.
|
||||
*
|
||||
* @details
|
||||
* Attempt to have the SE transfer a volatile or wrapped key if allowed.
|
||||
*
|
||||
* @note
|
||||
* The key stored in the source protected storage will not be deleted.
|
||||
*
|
||||
* Transferring a key between the same volatile slot is not allowed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* Either a volatile or a wrapped key with similar properties as key_out.
|
||||
*
|
||||
* @param[in] key_out
|
||||
* Either a volatile or a wrapped key with similar properties as key_in.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
* SL_STATUS_INVALID_PARAMETER if key does not exist.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_transfer_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Export the public part of an ECC keypair
|
||||
*
|
||||
* @details
|
||||
* The output key must be specified to only contain a public key.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_in
|
||||
* An asymmetric key with either a private or public part.
|
||||
*
|
||||
* @param[out] key_out
|
||||
* Describes output key parameters. Should only be set to contain the public
|
||||
* part of the key.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_export_public_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key_in,
|
||||
const sl_se_key_descriptor_t *key_out);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Delete a key from a volatile SE storage slot
|
||||
*
|
||||
* @details
|
||||
* The given key will be removed from the SE. The key descriptor is not
|
||||
* modified and can be used to generate a new key without any updates.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Key to delete.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_delete_key(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the required storage size for the given key
|
||||
*
|
||||
* @details
|
||||
* Finds the total storage size required for a given key. This includes
|
||||
* storage for the public and private part of asymmetric keys, as well as
|
||||
* overhead for wrapping keys.
|
||||
*
|
||||
* @param[in] key
|
||||
* The sl_se_key_descriptor_t to find the required storage size for.
|
||||
*
|
||||
* @param[out] storage_size
|
||||
* The required storage size in bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_storage_size(const sl_se_key_descriptor_t *key,
|
||||
uint32_t *storage_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup sl_se_key) */
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_KEY_HANDLING_H
|
||||
@@ -0,0 +1,185 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_SIGNATURE_H
|
||||
#define SL_SE_MANAGER_SIGNATURE_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_signature Signature
|
||||
*
|
||||
* @brief
|
||||
* Digital Signature Algorithms (ECDSA, EdDSA).
|
||||
*
|
||||
* @details
|
||||
* API for using digital signatures with the SE.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function computes Elliptic-Curve Cryptography (ECC) digital signatures
|
||||
* of a message.
|
||||
*
|
||||
* @note
|
||||
* Edwards-curve Digital Signature Algorithm (EdDSA) generates a message digest
|
||||
* using the input message for computing signatures. The input parameters
|
||||
* \p hash_alg and \p hashed_message do not apply for EdDSA.
|
||||
*
|
||||
* P-521 Elliptic Curve for Elliptic Curve Digital Signature Algorithm (ECDSA)
|
||||
* expects a 544 bits (68 bytes) buffer for storing private keys,
|
||||
* and a 1088 bits (136 bytes) buffer for storing public keys and signatures.
|
||||
* The first 23 bits of d, Qx, Qy, R and S are padding bits to comply
|
||||
* word-aligned addressing.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use. Ignored for EdDSA keys, since EdDSA always
|
||||
* uses SHA-512 for Ed25519 and SHA-3 for Ed448.
|
||||
*
|
||||
* @param[in] hashed_message
|
||||
* The input message is a message digest. Ignored for EdDSA keys, and treated
|
||||
* as false.
|
||||
*
|
||||
* @param[in] message
|
||||
* The message to be used to compute the signature.
|
||||
*
|
||||
* @param[in] message_len
|
||||
* The length of message.
|
||||
*
|
||||
* @param[out] signature
|
||||
* The computed signature.
|
||||
*
|
||||
* @param[in] signature_len
|
||||
* The length of the computed signature.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the command was executed successfully, otherwise an
|
||||
* appropiate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
unsigned char *signature,
|
||||
size_t signature_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function verifies Elliptic-Curve Cryptography (ECC) digital signatures
|
||||
* of a message.
|
||||
*
|
||||
* @note
|
||||
* The input parameters \p hash_alg and \p hashed_message do not apply for
|
||||
* Edwards-curve Digital Signature Algorithm (EdDSA).
|
||||
*
|
||||
* P-521 Elliptic Curve for Elliptic Curve Digital Signature Algorithm (ECDSA)
|
||||
* expects a 544 bits (68 bytes) buffer for storing private keys,
|
||||
* and a 1088 bits (136 bytes) buffer for storing public keys and signatures.
|
||||
* The first 23 bits of d, Qx, Qy, R and S are padding bits to comply
|
||||
* word-aligned addressing.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use. Ignored for EdDSA keys, since EdDSA always
|
||||
* uses SHA-512 for Ed25519 and SHA-3 for Ed448.
|
||||
*
|
||||
* @param[in] hashed_message
|
||||
* The input message is a message digest. Ignored for EdDSA keys, and treated
|
||||
* as false.
|
||||
*
|
||||
* @param[in] message
|
||||
* The message to be used to compute signatures.
|
||||
*
|
||||
* @param[in] message_len
|
||||
* The length of message.
|
||||
*
|
||||
* @param[in] signature
|
||||
* The signature to be verified.
|
||||
*
|
||||
* @param[in] signature_len
|
||||
* The length of signature.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
* appropiate error code (@ref sl_status.h).
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
const unsigned char *signature,
|
||||
size_t signature_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_signature)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_SIGNATURE_H
|
||||
@@ -0,0 +1,514 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API types
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_TYPES_H
|
||||
#define SL_SE_MANAGER_TYPES_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
#include "sl_se_manager_defines.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// OTP key types
|
||||
typedef enum {
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_BOOT = 0,
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_AUTH,
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_AES_128,
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_ATTESTATION,
|
||||
SL_SE_KEY_TYPE_IMMUTABLE_SE_ATTESTATION,
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
} sl_se_device_key_type_t;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// SE tamper signal levels
|
||||
typedef uint8_t sl_se_tamper_level_t;
|
||||
|
||||
/// SE tamper signals
|
||||
typedef uint32_t sl_se_tamper_signals_t;
|
||||
|
||||
/// SE tamper filter timeout period
|
||||
typedef uint8_t sl_se_tamper_filter_period_t;
|
||||
|
||||
/// Number of tamper counts to trigger the filter signal
|
||||
typedef uint8_t sl_se_tamper_filter_threshold_t;
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
/// Certificate size data structure
|
||||
typedef struct {
|
||||
uint32_t batch_id_size; ///< size in bytes of the Batch certificate
|
||||
uint32_t se_id_size; ///< size in bytes of the SE ID certificate
|
||||
uint32_t host_id_size; ///< size in bytes of the Host ID certificate
|
||||
} sl_se_cert_size_type_t;
|
||||
|
||||
/// SE certificate types
|
||||
typedef uint8_t sl_se_cert_type_t;
|
||||
|
||||
/// OTP initialization data structure
|
||||
typedef struct {
|
||||
/// Enable secure boot for the host.
|
||||
bool enable_secure_boot;
|
||||
/// Require certificate based secure boot signing.
|
||||
bool verify_secure_boot_certificate;
|
||||
/// Enable anti-rollback for host application upgrades.
|
||||
bool enable_anti_rollback;
|
||||
/// Set flag to enable locking down all flash pages that cover the
|
||||
/// secure-booted image, except the last page if end of signature is not
|
||||
/// page-aligned.
|
||||
bool secure_boot_page_lock_narrow;
|
||||
/// Set flag to enable locking down all flash pages that cover the
|
||||
/// secure-booted image, including the last page if end of signature is not
|
||||
/// page-aligned.
|
||||
bool secure_boot_page_lock_full;
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// List of tamper levels to configure for the different tamper sources.
|
||||
sl_se_tamper_level_t tamper_levels[SL_SE_TAMPER_SIGNAL_NUM_SIGNALS];
|
||||
/// Reset period for the tamper filter counter.
|
||||
sl_se_tamper_filter_period_t tamper_filter_period;
|
||||
/// Activation threshold for the tamper filter.
|
||||
sl_se_tamper_filter_threshold_t tamper_filter_threshold;
|
||||
/// Tamper flags.
|
||||
uint8_t tamper_flags;
|
||||
/// Tamper reset halt threshold.
|
||||
uint8_t tamper_reset_threshold;
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
} sl_se_otp_init_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @addtogroup sl_se_manager_core
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE mailbox command context
|
||||
*
|
||||
* @details
|
||||
* This structure defines the common SE mailbox command context used for
|
||||
* all SE Manager API functions that execute SE mailbox commands. The
|
||||
* members of this context structure should be considered internal to the
|
||||
* SE Manager and should not be read or written directly by the user
|
||||
* application. For members that are relevant for the user, the user can
|
||||
* access them via corresponding set and get API functions, e.g.
|
||||
* sl_se_set_yield().
|
||||
******************************************************************************/
|
||||
typedef struct sl_se_command_context_t {
|
||||
sli_se_mailbox_command_t command; ///< SE mailbox command struct
|
||||
bool yield; ///< If true, yield the CPU core while
|
||||
///< waiting for the SE mailbox command
|
||||
///< to complete. If false, busy-wait, by
|
||||
///< polling the SE mailbox response
|
||||
///< register.
|
||||
} sl_se_command_context_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_core)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE Debug lock flags
|
||||
typedef uint32_t sl_se_debug_flags_t;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/// Debug lock options
|
||||
typedef struct {
|
||||
/// Non-Secure, Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to debug the non-secure state in a way that is intrusive to
|
||||
/// program execution (DBGLOCK locked).
|
||||
bool non_secure_invasive_debug;
|
||||
/// Non-Secure, Non-Invasive debug access enabled if true. If false, it is
|
||||
/// not possible to debug the non-secure state in a way that is intrusive to
|
||||
/// program execution (NIDLOCK locked).
|
||||
bool non_secure_non_invasive_debug;
|
||||
/// Secure, Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to debug the secure TrustZone state in a way that is intrusive
|
||||
/// to program execution (SPIDLOCK locked).
|
||||
bool secure_invasive_debug;
|
||||
/// Secure, Non-Invasive debug access enabled if true. If false, it is not
|
||||
/// possible to observe the secure TrustZone state using trace.
|
||||
/// (SPNIDLOCK is locked. However if SPIDLOCK is open, SPNIDLOCK will also
|
||||
/// remain open.)
|
||||
bool secure_non_invasive_debug;
|
||||
} sl_se_debug_options_t;
|
||||
#endif
|
||||
|
||||
/// Debug status
|
||||
typedef struct {
|
||||
/// Whether device erase is enabled
|
||||
bool device_erase_enabled;
|
||||
/// Whether secure debug is enabled with @ref sl_se_enable_secure_debug().
|
||||
bool secure_debug_enabled;
|
||||
/// Whether the debug port has been locked with @ref sl_se_apply_debug_lock().
|
||||
/// This parameter does not indicate if the debug port has been unlocked by
|
||||
/// calling @ref sl_se_open_debug().
|
||||
bool debug_port_lock_applied;
|
||||
/// Current state of the debug port.
|
||||
/// True if locked with @ref sl_se_apply_debug_lock().
|
||||
/// False if new clean, erased or unlocked with @ref sl_se_open_debug().
|
||||
bool debug_port_lock_state;
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/// Debug option configuration as set by @ref sl_se_set_debug_options().
|
||||
sl_se_debug_options_t options_config;
|
||||
/// Current state of debug options, locked by @ref sl_se_set_debug_options() and
|
||||
/// unlocked by @ref sl_se_open_debug().
|
||||
sl_se_debug_options_t options_state;
|
||||
#endif
|
||||
} sl_se_debug_status_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_handling
|
||||
/// @{
|
||||
|
||||
/// Supported key types
|
||||
typedef uint32_t sl_se_key_type_t;
|
||||
|
||||
/// Key storage method. Can have one of @ref SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT,
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED,
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_VOLATILE,
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE or
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_KSU.
|
||||
typedef uint32_t sl_se_storage_method_t;
|
||||
|
||||
/// Internal SE key slot
|
||||
typedef uint32_t sl_se_key_slot_t;
|
||||
|
||||
/// Describes where the key is or should be stored
|
||||
typedef struct {
|
||||
uint8_t* pointer; ///< Pointer to a key buffer.
|
||||
uint32_t size; ///< Size of buffer.
|
||||
} sl_se_buffer_t;
|
||||
|
||||
/// KSU Metadata
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
typedef struct {
|
||||
uint8_t keyslot; ///< Keyslot to store key at in KSU
|
||||
uint8_t id; ///< KSU instance to store key
|
||||
uint8_t crypto_engine_id; ///< Which Crypto Engine to use this key
|
||||
uint8_t allowed_key_users; ///< Allowed key users
|
||||
} sl_se_ksu_metadata_t;
|
||||
#endif
|
||||
|
||||
/// Describes the storage location of keys
|
||||
typedef struct {
|
||||
/// Key storage method. Sets meaning of data in location.
|
||||
sl_se_storage_method_t method;
|
||||
/// Describes key storage location. @ref sl_se_buffer_t is used if @ref sl_se_key_storage_t.method is
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT or
|
||||
/// @ref SL_SE_KEY_STORAGE_EXTERNAL_WRAPPED, while @ref sl_se_key_slot_t is
|
||||
/// used for @ref SL_SE_KEY_STORAGE_INTERNAL_VOLATILE or
|
||||
/// @ref SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE.
|
||||
/// @ref ksu is used for @ref SL_SE_KEY_STORAGE_INTERNAL_KSU
|
||||
union {
|
||||
sl_se_buffer_t buffer;
|
||||
sl_se_key_slot_t slot;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_se_ksu_metadata_t ksu;
|
||||
#endif
|
||||
} location;
|
||||
} sl_se_key_storage_t;
|
||||
|
||||
/// Contains a full description of a key used by an SE command.
|
||||
typedef struct {
|
||||
/// Key type
|
||||
sl_se_key_type_t type;
|
||||
/// Key size, applicable if key_type == SYMMETRIC
|
||||
size_t size;
|
||||
/// Flags describing restrictions, permissions and attributes of the key.
|
||||
uint32_t flags;
|
||||
/// Storage location for this key
|
||||
sl_se_key_storage_t storage;
|
||||
/// Optional password for key usage (8 bytes). If no password is provided
|
||||
/// (NULL pointer), any key not stored as plaintext will be stored with a
|
||||
/// password of all-zero bytes.
|
||||
uint8_t* password;
|
||||
/// Pointer to domain descriptor if this key contains an asymmetric key on a
|
||||
/// custom domain The reason for pointing instead of containing is to make
|
||||
/// it possible to have the parameters in ROM.
|
||||
const void* domain;
|
||||
} sl_se_key_descriptor_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Custom Weierstrass curve structure.
|
||||
typedef struct {
|
||||
/// Domain size in bytes.
|
||||
const size_t size;
|
||||
/// Modulus p (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* p;
|
||||
/// Order N (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* N;
|
||||
/// Generator X-coordinate (zero-padded from MSB, right-adjusted to extend
|
||||
/// to 32-bit alignment up from domain size)
|
||||
const uint8_t* Gx;
|
||||
/// Generator Y-coordinate (zero-padded from MSB, right-adjusted to extend
|
||||
/// to 32-bit alignment up from domain size)
|
||||
const uint8_t* Gy;
|
||||
/// Parameter a (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* a;
|
||||
/// Parameter b (zero-padded from MSB, right-adjusted to extend to 32-bit
|
||||
/// alignment up from domain size)
|
||||
const uint8_t* b;
|
||||
/// Set if a equals 0
|
||||
bool a_is_zero;
|
||||
/// Set if a equals -3
|
||||
bool a_is_minus_three;
|
||||
} sl_se_custom_weierstrass_prime_domain_t;
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_handling)
|
||||
|
||||
/// @addtogroup sl_se_manager_util
|
||||
/// @{
|
||||
|
||||
/// SE challenge storage
|
||||
typedef uint8_t sl_se_challenge_t[SL_SE_CHALLENGE_SIZE];
|
||||
|
||||
/// SE status
|
||||
typedef struct {
|
||||
/// Boot status code / error code (Bits [7:0]).
|
||||
uint32_t boot_status;
|
||||
/// SE firmware version.
|
||||
uint32_t se_fw_version;
|
||||
/// Host firmware version (if available).
|
||||
uint32_t host_fw_version;
|
||||
/// Debug lock status.
|
||||
sl_se_debug_status_t debug_status;
|
||||
/// Secure boot enabled.
|
||||
bool secure_boot_enabled;
|
||||
/// Active mode enabled.
|
||||
bool active_mode_enabled;
|
||||
/// Recorded tamper status. Reset on status read.
|
||||
uint32_t tamper_status;
|
||||
/// Currently active tamper sources.
|
||||
uint32_t tamper_status_raw;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
uint8_t rom_revision;
|
||||
/// ROM revision
|
||||
uint8_t otp_patch_sequence;
|
||||
/// OTP patch sequence
|
||||
#endif
|
||||
} sl_se_status_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
|
||||
/// @addtogroup sl_se_manager_cipher
|
||||
/// @{
|
||||
|
||||
/// Cipher operation types
|
||||
typedef enum {
|
||||
SL_SE_ENCRYPT,
|
||||
SL_SE_DECRYPT
|
||||
} sl_se_cipher_operation_t;
|
||||
|
||||
/// CMAC streaming context
|
||||
typedef struct {
|
||||
uint8_t state[16]; ///< CMAC state
|
||||
uint8_t data_in[16]; ///< Unprocessed data
|
||||
uint8_t data_out[16]; ///< Last 16 bytes of cipher-text
|
||||
size_t length; ///< Length of all processed and unprocessed data
|
||||
} sl_se_cmac_multipart_context_t;
|
||||
|
||||
/// CCM streaming context.
|
||||
typedef struct {
|
||||
uint32_t processed_message_length;///< Current length of the encrypted/decrypted data
|
||||
uint32_t total_message_length; ///< Total length of data to be encrypted/decrypted
|
||||
uint8_t iv[13]; ///< Nonce (MAX size is 13 bytes)
|
||||
uint32_t tag_len; ///< Tag length
|
||||
sl_se_cipher_operation_t mode;///< CCM mode (decrypt or encrypt)
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
uint8_t nonce_counter[16]; ///< Counter to keep CTR state
|
||||
uint8_t iv_len; ///< Nonce length
|
||||
uint8_t cbc_mac_state[16]; ///< State of authenication/MAC
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
#else
|
||||
uint8_t se_ctx[32]; ///< SE encryption state
|
||||
union {
|
||||
uint8_t tagbuf[16]; ///< Tag
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
} mode_specific_buffer; ///< Buffer containing Tag and input data saved for finish operation
|
||||
#endif
|
||||
uint8_t final_data_length; ///< Length of data saved
|
||||
} sl_se_ccm_multipart_context_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t len; ///< Total length of the encrypted data
|
||||
uint64_t add_len; ///< Total length of the additional data
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
uint8_t tagbuf[16]; ///< Tag
|
||||
uint8_t previous_se_ctx[32]; ///< SE state from previous operation
|
||||
#endif
|
||||
uint8_t se_ctx[32]; ///< SE state
|
||||
uint8_t final_data[16]; ///< Input data saved for finish operation
|
||||
uint8_t final_data_length; ///< Length of data saved
|
||||
sl_se_cipher_operation_t mode;///< GCM mode
|
||||
bool first_operation; ///< First operation
|
||||
} sl_se_gcm_multipart_context_t;
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_cipher)
|
||||
|
||||
/// @addtogroup sl_se_manager_hash
|
||||
/// @{
|
||||
|
||||
/// Hash algorithms
|
||||
typedef enum {
|
||||
SL_SE_HASH_NONE, ///< No hash
|
||||
SL_SE_HASH_SHA1, ///< SHA-1
|
||||
SL_SE_HASH_SHA224, ///< SHA-224
|
||||
SL_SE_HASH_SHA256, ///< SHA-256
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
SL_SE_HASH_SHA384, ///< SHA-384
|
||||
SL_SE_HASH_SHA512, ///< SHA-512
|
||||
#endif
|
||||
} sl_se_hash_type_t;
|
||||
|
||||
/// SHA-1 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< number of bytes processed
|
||||
uint8_t state[32]; ///< intermediate digest state
|
||||
uint8_t buffer[64]; ///< data block being processed
|
||||
} sl_se_sha1_multipart_context_t;
|
||||
|
||||
/// SHA-224 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< Number of bytes processed
|
||||
uint8_t state[32]; ///< Intermediate digest state
|
||||
uint8_t buffer[64]; ///< Data block being processed
|
||||
} sl_se_sha224_multipart_context_t;
|
||||
|
||||
/// SHA-256 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[2]; ///< Number of bytes processed
|
||||
uint8_t state[32]; ///< Intermediate digest state
|
||||
uint8_t buffer[64]; ///< Data block being processed
|
||||
} sl_se_sha256_multipart_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// SHA-384 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[4]; ///< Number of bytes processed
|
||||
uint8_t state[64]; ///< Intermediate digest state
|
||||
uint8_t buffer[128]; ///< Data block being processed
|
||||
} sl_se_sha384_multipart_context_t;
|
||||
|
||||
/// SHA-512 streaming context.
|
||||
typedef struct {
|
||||
sl_se_hash_type_t hash_type; ///< Hash streaming context
|
||||
uint32_t total[4]; ///< Number of bytes processed
|
||||
uint8_t state[64]; ///< Intermediate digest state
|
||||
uint8_t buffer[128]; ///< Data block being processed
|
||||
} sl_se_sha512_multipart_context_t;
|
||||
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_hash)
|
||||
|
||||
/// @addtogroup sl_se_manager_key_derivation
|
||||
/// @{
|
||||
|
||||
/// Roles in the EC J-PAKE exchange
|
||||
typedef enum {
|
||||
SL_SE_ECJPAKE_CLIENT = 0, ///< Client
|
||||
SL_SE_ECJPAKE_SERVER, ///< Server
|
||||
} sl_se_ecjpake_role_t;
|
||||
|
||||
/**************************************************************************//**
|
||||
* EC J-PAKE context structure.
|
||||
*
|
||||
* J-PAKE is a symmetric protocol, except for the identifiers used in
|
||||
* Zero-Knowledge Proofs, and the serialization of the second message
|
||||
* (KeyExchange) as defined by the Thread spec.
|
||||
*
|
||||
* In order to benefit from this symmetry, we choose a different naming
|
||||
* convention from the Thread v1.0 spec. Correspondance is indicated in the
|
||||
* description as a pair C: client name, S: server name
|
||||
*****************************************************************************/
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
uint32_t curve_flags; ///< Curve flags to use
|
||||
sl_se_ecjpake_role_t role; ///< Are we client or server?
|
||||
|
||||
char pwd[32]; ///< J-PAKE password
|
||||
size_t pwd_len; ///< J-PAKE password length
|
||||
|
||||
uint8_t r[32]; ///< Random scalar for exchange
|
||||
uint8_t Xm1[64]; ///< Our point 1 (round 1)
|
||||
uint8_t Xm2[64]; ///< Our point 2 (round 1)
|
||||
uint8_t Xp1[64]; ///< Their point 1 (round 1)
|
||||
uint8_t Xp2[64]; ///< Their point 2 (round 1)
|
||||
uint8_t Xp[64]; ///< Their point (round 2)
|
||||
} sl_se_ecjpake_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Typedef sl_se_pbkdf2_prf_type_t to sl_se_hash_type_t in order to maintain
|
||||
/// backward compatibility. Defines for mapping the PRF identifiers to the
|
||||
/// underlying hash enum values exists in sl_se_manager_defines.h.
|
||||
typedef sl_se_hash_type_t sl_se_pbkdf2_prf_type_t;
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_key_derivation)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_TYPES_H
|
||||
@@ -0,0 +1,960 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SL_SE_MANAGER_UTIL_H
|
||||
#define SL_SE_MANAGER_UTIL_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager_util Utilities
|
||||
*
|
||||
* @brief
|
||||
* Device initialisation, debug lock, upgrade functionality, user data...
|
||||
*
|
||||
* @details
|
||||
* API for managing the Secure Engine or Root code on a device. Upload and
|
||||
* read device configuration.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#endif
|
||||
#include "sl_se_manager_types.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Lifecycle event flags keep track of certain events and state changes by setting a one-time
|
||||
/// irreversible flag in the OTP. This enum contains information on what the separate event flags
|
||||
/// indicate. The lifecycle state flags can be fetched using @ref sl_se_get_lifecycle_event_flags. The utility
|
||||
/// @ref sl_se_lifecycle_event_flag_is_set can be used to check if any specific flag has been set.
|
||||
typedef enum {
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_UNSECURE_UNLOCKED = 0, ///< Host has been unsecure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_UNLOCKED = 1, ///< Host has been secure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_SE_SECURE_UNLOCKED = 2, ///< SE has been secure-unlocked
|
||||
SL_SE_LIFECYCLE_EVENT_INITIAL_DEBUG_LOCK_SET = 3, ///< Initial debug lock token has been set in MTP
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_DEBUG_ENABLED = 4, ///< Host secure debug has been enabled
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_SECURE_DEBUG_DISABLED = 5, ///< Host secure debug has been disabled
|
||||
SL_SE_LIFECYCLE_EVENT_HOST_DEBUG_LOCKED = 6, ///< Host has been debug locked
|
||||
SL_SE_LIFECYCLE_EVENT_AXIP_NONCE_ROLL_DISABLED = 7, ///< AXiP nonce rolling has been disabled
|
||||
} sl_se_lifecycle_event_flag_t;
|
||||
#endif // #if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Prototypes
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate SE firmware image.
|
||||
*
|
||||
* @details
|
||||
* Validate SE firmware image located at given address. This function is
|
||||
* typically used before calling sl_se_apply_se_image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to SE image to validate.
|
||||
*
|
||||
* @return
|
||||
* One of the following @ref status codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_check_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Apply SE firmware image.
|
||||
*
|
||||
* @details
|
||||
* Apply SE firmware image located at given address.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to SE image to apply.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get upgrade status of SE firmware image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] status
|
||||
* Pointer to 32-bit word where to return upgrade status.
|
||||
*
|
||||
* @param[in] prev_version
|
||||
* Pointer to 32-bit word where to return previous version.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_upgrade_status_se_image(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *status,
|
||||
uint32_t *prev_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate Host firmware image.
|
||||
*
|
||||
* @details
|
||||
* Validate Host firmware image located at given address. This function is
|
||||
* typically used before calling @ref sl_se_apply_host_image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to Host image to validate.
|
||||
*
|
||||
* @param[in] size
|
||||
* Size of Host image to validate.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_check_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr,
|
||||
uint32_t size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Apply Host firmware image.
|
||||
*
|
||||
* @details
|
||||
* Apply Host firmware image located at given address.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] image_addr
|
||||
* Pointer to Host image to apply.
|
||||
*
|
||||
* @param[in] size
|
||||
* Size of Host image to apply.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
void *image_addr,
|
||||
uint32_t size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get upgrade status of Host firmware image.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] status
|
||||
* Pointer to 32-bit word where to return upgrade status.
|
||||
*
|
||||
* @param[in] prev_version
|
||||
* Pointer to 32-bit word where to return previous version.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_get_upgrade_status_host_image(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *status,
|
||||
uint32_t *prev_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize key to be stored in the SE OTP flash.
|
||||
*
|
||||
* @details
|
||||
* Initialize key stored in the SE. The command can be used to write (@ref sl_se_device_key_type_t):
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_BOOT
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AUTH
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AES_128
|
||||
*
|
||||
* @note
|
||||
* These keys can not be overwritten, so this command can only be issued once
|
||||
* per key per part.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_type
|
||||
* ID of key type to initialize.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to a buffer that contains the key.
|
||||
* Public keys must be word aligned and have a length of 64 bytes.
|
||||
* AES-128 keys must be word aligned and have length of 16 bytes.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of key buffer in bytes (16 or 64 bytes).
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_otp_key(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_device_key_type_t key_type,
|
||||
void *key,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read a public key stored in the SE.
|
||||
*
|
||||
* @details
|
||||
* Read out a public key stored in the SE. The command can be used to read (@ref sl_se_device_key_type_t):
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_BOOT
|
||||
* * SL_SE_KEY_TYPE_IMMUTABLE_AUTH
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key_type
|
||||
* ID of key type to read.
|
||||
*
|
||||
* @param[out] key
|
||||
* Pointer to a buffer to contain the returned public key.
|
||||
* Must be word aligned and have a length of 64 bytes.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of pubkey buffer (64 bytes).
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_pubkey(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_device_key_type_t key_type,
|
||||
void *key,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize and commit SE OTP configuration to OTP.
|
||||
*
|
||||
* @warning
|
||||
* When this function succeeds the configuration is committed to OTP and cannot be changed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] otp_init
|
||||
* Pointer to OTP initialization structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following @ref sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_ABORT when the operation is not attempted.
|
||||
*
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_otp_init_t *otp_init);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the OTP firmware version of the SE module.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] version
|
||||
* Pointer to uint32_t word where version shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read SE OTP configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] otp_settings
|
||||
* Pointer to OTP initialization structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_COMMAND if OTP configuration isn't initialized
|
||||
* - @c SL_STATUS_ABORT when the operation is not attempted.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_otp(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_otp_init_t *otp_settings);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the SE firmware version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] version
|
||||
* Pointer to uint32_t word where version shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_OWNERSHIP when the ownership is already taken
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sl_se_get_se_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the current debug lock configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] status
|
||||
* Pointer to sl_se_debug_status_t structure to be filled out with the
|
||||
* current status of the debug configuration.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_debug_lock_status(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_debug_status_t *status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the debug lock for the part.
|
||||
*
|
||||
* @details
|
||||
* The debug port will be closed and the only way to open it is through
|
||||
* device erase (if enabled) or through secure debug unlock (if enabled).
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_apply_debug_lock(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Writes data to User Data section in MTP. Write data must be aligned to
|
||||
* word size and contain a number of bytes that is divisable by four.
|
||||
* @note
|
||||
* It is recommended to erase the flash page before performing a write.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[in] offset
|
||||
* Offset to the flash word to write to. Must be aligned to words.
|
||||
* @param[in] data
|
||||
* Data to write to flash.
|
||||
* @param[in] num_bytes
|
||||
* Number of bytes to write to flash. NB: Must be divisable by four.
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_write_user_data(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t offset,
|
||||
void *data,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Erases User Data section in MTP.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_erase_user_data(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Returns the current boot status, versions and system configuration.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] status
|
||||
* SE_Status_t containing current SE status.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK upon command completion. Errors are encoded in the
|
||||
* different parts of the returned status object.
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_status(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_status_t *status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the serial number of the SE module.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] serial
|
||||
* Pointer to array of size 16 bytes.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_serialnumber(sl_se_command_context_t *cmd_ctx,
|
||||
void *serial);
|
||||
|
||||
#if defined(SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the EMU->RSTCAUSE after a tamper reset. This function should be called
|
||||
* if EMU->RSTCAUSE has been cleared upon boot.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] reset_cause
|
||||
* Pointer to uint32_t word where reset cause shall be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_reset_cause(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *reset_cause);
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the latest cached tamper reset cause. The returned value is the index
|
||||
* of the tamper source that caused a reset.
|
||||
* Requires SE version 2.2.1 or above.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] was_tamper_reset
|
||||
* Pointer to bool that indicates if a tamper event occurred. If the cached
|
||||
* value is 0 this will be false, true otherwise.
|
||||
*
|
||||
* @param[out] reset_cause
|
||||
* Pointer to a uint32_t where the cached reset cause value should
|
||||
* be returned.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when cmd_ctx or reset_cause is NULL
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_tamper_reset_cause(sl_se_command_context_t *cmd_ctx,
|
||||
bool *was_tamper_reset,
|
||||
uint32_t *reset_cause);
|
||||
#endif // SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reads out traceable lifecycle event flags from the OTP. See
|
||||
* \ref sl_se_lifecycle_event_flag_t for details on what the individual flag bits
|
||||
* indicate.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] event_flags
|
||||
* Pointer to an array of at least 8 bytes, to contain the trace flags
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK upon successfull execution, error code elsewise
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_lifecycle_event_flags(sl_se_command_context_t *cmd_ctx, uint64_t *event_flags);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Utility for checking if a certain lifecycle event flag is set
|
||||
*
|
||||
* @param[in] flags
|
||||
* Pointer to an 8 byte array of lifecycle event flags (event_flags from
|
||||
* \ref sl_se_get_lifecycle_event_flags)
|
||||
*
|
||||
* @param[in] flag_index
|
||||
* Which bit (event flag) to check if is set
|
||||
*
|
||||
* @return
|
||||
* true if event flag bit was set
|
||||
* false if event flag bit was not set
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE bool sl_se_lifecycle_event_flag_is_set(uint64_t *flags, sl_se_lifecycle_event_flag_t flag_index)
|
||||
{
|
||||
return (*flags & (1 << flag_index) ? true : false);
|
||||
}
|
||||
|
||||
#endif // #if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enables the secure debug functionality.
|
||||
*
|
||||
* @details
|
||||
* Enables the secure debug functionality that can be used to open a locked
|
||||
* debug port through the Get challenge and Open debug commands. This command
|
||||
* can only be executed before the debug port is locked, and after a secure
|
||||
* debug public key has been installed in the SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_enable_secure_debug(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disables the secure debug functionality.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @details
|
||||
* Disables the secure debug functionality that can be used to open a
|
||||
* locked debug port.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_secure_debug(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************/ /**
|
||||
* @brief
|
||||
* Set debug options.
|
||||
*
|
||||
* @details
|
||||
* This function makes it possible to configure the Trust-Zone access
|
||||
* permissions of the debug interface. For details please refer to
|
||||
* @ref sl_se_debug_options_t.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] debug_options
|
||||
* Pointer to debug options structure.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_debug_options(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_debug_options_t *debug_options);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Performs a device mass erase and debug unlock.
|
||||
*
|
||||
* @details
|
||||
* Performs a device mass erase and resets the debug configuration to its
|
||||
* initial unlocked state. Only available before DEVICE_ERASE_DISABLE has
|
||||
* been executed.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @note
|
||||
* This command clears and verifies the complete flash and ram of the
|
||||
* system, excluding the user data pages and one-time programmable
|
||||
* commissioning information in the secure engine.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_COMMAND if device erase is disabled.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_erase_device(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/****************************************************************q***********//**
|
||||
* @brief
|
||||
* Disabled device erase functionality.
|
||||
*
|
||||
* @details
|
||||
* This command disables the device erase command. It does not lock the
|
||||
* debug interface to the part, but it is a permanent action for the part.
|
||||
* If device erase is disabled and the device is debug locked, there is no
|
||||
* way to permanently unlock the part. If secure debug unlock is enabled,
|
||||
* secure debug unlock can still be used to temporarily open the debug port.
|
||||
*
|
||||
* @warning
|
||||
* This command permanently disables the device erase functionality!
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_device_erase(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Request challenge from SE which can be used to open debug access.
|
||||
*
|
||||
* @details
|
||||
* This command requests a challenge (16 bytes) which can be used to generate
|
||||
* a certificate in order to open debug access, @ref sl_se_open_debug.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] challenge
|
||||
* SE challenge storage.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_challenge(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_challenge_t challenge);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Invalidate current challenge and make a new challenge.
|
||||
*
|
||||
* @details
|
||||
* This command requests the SE to invalidate it's current challenge (16bytes)
|
||||
* and generate a new challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_roll_challenge(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unlock debug access using certificate and signed challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert
|
||||
* Certificate for debug unlock and signed challenge.
|
||||
*
|
||||
* @param[in] len
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @param[in] debug_options
|
||||
* Debug options to open/unlock.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_open_debug(sl_se_command_context_t *cmd_ctx,
|
||||
void *cert,
|
||||
uint32_t len,
|
||||
const sl_se_debug_options_t *debug_options);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Temporarily disable tamper configuration using certificate and signed
|
||||
* challenge.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert
|
||||
* Certificate for disabling tamper and signed challenge.
|
||||
*
|
||||
* @param[in] len
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @param[in] tamper_signals
|
||||
* Tamper signals to disable. Each signal represented by a bit.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_OPERATION when the SE command ID is not recognized
|
||||
* - @c SL_STATUS_INVALID_CREDENTIALS when the command is not authorized
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_disable_tamper(sl_se_command_context_t *cmd_ctx,
|
||||
void *cert,
|
||||
uint32_t len,
|
||||
sl_se_tamper_signals_t tamper_signals);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read size of stored certificates in SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in,out] cert_size
|
||||
* Size of the certificates stored in SE.
|
||||
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_cert_size(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_cert_size_type_t *cert_size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read stored certificates in SE.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] cert_type
|
||||
* Type of the certificate stored in SE.
|
||||
*
|
||||
* @param[in,out] cert
|
||||
* Buffer to read certificate.
|
||||
*
|
||||
* @param[in] num_bytes
|
||||
* Length of certificate in number of bytes.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_cert(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_cert_type_t cert_type,
|
||||
void *cert,
|
||||
uint32_t num_bytes);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enter SE active mode.
|
||||
*
|
||||
* @details
|
||||
* SE will enter active mode. This will ensure SE is not powered down between
|
||||
* operations, at the expense of increased power consumption.
|
||||
*
|
||||
* @warning
|
||||
* Active mode will prevent entry to EM2/3/4. To allow energy mode entry, exit
|
||||
* active mode through @ref sl_se_exit_active_mode().
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_COMMAND_IS_INVALID when already in active mode
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_enter_active_mode(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Exit SE active mode.
|
||||
*
|
||||
* @details
|
||||
* SE will exit active mode.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
* - @c SL_STATUS_OK when the command was executed successfully
|
||||
* - @c SL_STATUS_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* - @c SL_STATUS_COMMAND_IS_INVALID when already not in active mode
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_exit_active_mode(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the OTP rollback counter.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[out] rollback_counter
|
||||
* Pointer to location where the rollback counter value will be returned.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_rollback_counter(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *rollback_counter);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Increment the OTP rollback counter.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[out] rollback_counter
|
||||
* Optional: Retrieve the rollback counter count after increment
|
||||
* Set to NULL to ignore
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_increment_rollback_counter(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *rollback_counter);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reads back the stored upgrade file version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[out] version
|
||||
* The stored upgrade file version.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_upgrade_file_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Records a new upgrade file version.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
* @param[in] version
|
||||
* New upgrade file version
|
||||
*
|
||||
* @return
|
||||
* \ref SL_STATUS_OK when the function executed successfully, else, a status code
|
||||
* of type sl_status_t that indicates why the function was not successful,
|
||||
* @ref status
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_upgrade_file_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t version);
|
||||
|
||||
#endif // defined(_SILICON_LABS_32B_SERIES_3)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} (end addtogroup sl_se_manager_util)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#endif // SL_SE_MANAGER_UTIL_H
|
||||
@@ -0,0 +1,138 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs SE Manager macros representing features.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SLI_SE_MANAGER_FEATURES_H
|
||||
#define SLI_SE_MANAGER_FEATURES_H
|
||||
|
||||
#if !defined(__linux__)
|
||||
#include "em_device.h"
|
||||
#endif // !__linux__
|
||||
|
||||
#if defined(DOXYGEN)
|
||||
|
||||
#undef _SILICON_LABS_SECURITY_FEATURE // Allow doxygen to include the SVH only features
|
||||
|
||||
#define _SILICON_LABS_SECURITY_FEATURE _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
#define SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
#define SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#else // DOXYGEN
|
||||
|
||||
#if defined(__linux__)
|
||||
// ---------------------------- HOST ---------------------------- //
|
||||
|
||||
// The header is being used on a host system with Linux running on it,
|
||||
// assume that the endpoint attached to the host system is a SVH type.
|
||||
|
||||
#define SLI_SE_MANAGER_HOST_SYSTEM
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_SE (0)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_VAULT (1)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_ROT (2)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE_BASE (3)
|
||||
#define _SILICON_LABS_SECURITY_FEATURE _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
|
||||
// EFR32xG23+ doesn't require padding of curve elements or other keys
|
||||
#define SLI_SE_KEY_PADDING_REQUIRED
|
||||
#define SLI_SE_P521_PADDING_BYTES (2u)
|
||||
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (0u)
|
||||
#elif defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
#define SLI_SE_P521_PADDING_BYTES (0u)
|
||||
// PBKDF2 with CMAC as the PRF was first supported on EFR32xG23.
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (1u)
|
||||
#endif
|
||||
|
||||
// Define the helper macros needed for the host system
|
||||
#define __REV(num) (((num & 0xFF000000) >> 24) \
|
||||
| ((num & 0x00FF0000) >> 8) \
|
||||
| ((num & 0x0000FF00) << 8) \
|
||||
| ((num & 0x000000FF) << 24))
|
||||
|
||||
#elif defined(SEMAILBOX_PRESENT)
|
||||
// --------------------------------- HSE --------------------------------- //
|
||||
|
||||
#define SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#if (defined(_SILICON_LABS_SECURITY_FEATURE) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) \
|
||||
&& ((defined(_SILICON_LABS_32B_SERIES_2_CONFIG) && _SILICON_LABS_32B_SERIES_2_CONFIG >= 3) \
|
||||
|| defined(_SILICON_LABS_32B_SERIES_3)))
|
||||
// Reading the latest cached tamper reset cause requires SE version 2.2.1 or above.
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE_AVAILABLE
|
||||
// The option to keep the tamper alive during sleep is only configurable for SE with major version 2
|
||||
#define SLI_SE_TAMPER_FLAG_KEEP_TAMPER_ALIVE_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
#define SLI_SE_MAJOR_VERSION_ONE
|
||||
#else
|
||||
#define SLI_SE_MAJOR_VERSION_TWO
|
||||
#endif
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_SUPPORTS_NVM3_INTERNAL_KEY
|
||||
#endif
|
||||
|
||||
#if defined(SLI_SE_MAJOR_VERSION_ONE)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
|
||||
// EFR32xG23+ doesn't require padding of curve elements or other keys
|
||||
#define SLI_SE_KEY_PADDING_REQUIRED
|
||||
#define SLI_SE_P521_PADDING_BYTES (2u)
|
||||
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (0u)
|
||||
#elif defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
#define SLI_SE_P521_PADDING_BYTES (0u)
|
||||
// PBKDF2 with CMAC as the PRF was first supported on EFR32xG23.
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC_AVAILABLE
|
||||
#define SLI_MINIMUM_REQUIRED_NUMBER_PARAMS (1u)
|
||||
#endif
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
// --------------------------------- VSE --------------------------------- //
|
||||
|
||||
#define SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#endif // DOXYGEN
|
||||
|
||||
#endif // SLI_SE_MANAGER_FEATURES_H
|
||||
@@ -0,0 +1,212 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager internal API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SE_MANAGER_INTERNAL_H
|
||||
#define SE_MANAGER_INTERNAL_H
|
||||
|
||||
#include "sli_se_manager_features.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sl_status.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_se_manager.h"
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Due to a problem with the countermeasures applied to
|
||||
// accelerated point multiplication over elliptic curves,
|
||||
// it is possible that random errors are encountered (this
|
||||
// is extremely unilkely for truly random keys).
|
||||
// As a workaround for this, the affected commands will
|
||||
// retry the operation in order to reduce the probability
|
||||
// that the error code was returned incorrectly. This helps
|
||||
// lower the error probability further when using purposely
|
||||
// small or large scalars, for example during testing.
|
||||
#define SLI_SE_MAX_POINT_MULT_RETRIES 3U
|
||||
#endif
|
||||
|
||||
// -------------------------------
|
||||
// Function-like macros
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Helper macro to init/reset the SE command struct of an SE command context
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to SE context containing the command to initialize/reset
|
||||
*
|
||||
* @param[out] command_word
|
||||
* Command word to set in the SE command.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define sli_se_command_init(cmd_ctx, command_word) \
|
||||
cmd_ctx->command.command = command_word; \
|
||||
cmd_ctx->command.data_in = NULL; \
|
||||
cmd_ctx->command.data_out = NULL; \
|
||||
cmd_ctx->command.num_parameters = 0;
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Helper macros to add key parameters and input/output blocks to SE commands
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to SE context
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure
|
||||
* @param[out] status
|
||||
* SL_Status_T
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// Add keyspec to command for given key
|
||||
#define sli_add_key_parameters(cmd_ctx, key, status) { \
|
||||
uint32_t keyspec; \
|
||||
(status) = sli_se_key_to_keyspec((key), &keyspec); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_parameter(&cmd_ctx->command, keyspec); \
|
||||
}
|
||||
|
||||
// Add key metadata buffers to command for given key
|
||||
#define sli_add_key_metadata(cmd_ctx, key, status) \
|
||||
/* Auth data */ \
|
||||
sli_se_datatransfer_t auth_buffer; \
|
||||
(status) = sli_se_get_auth_buffer((key), &auth_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_buffer);
|
||||
|
||||
// Add key metadata buffers with custom auth buffer to command for given key
|
||||
#define sli_add_key_metadata_custom(cmd_ctx, auth_data_buf, key, status) \
|
||||
/* Auth data */ \
|
||||
sli_se_datatransfer_t auth_data_buf; \
|
||||
(status) = sli_se_get_auth_buffer((key), &auth_data_buf); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &auth_data_buf);
|
||||
|
||||
// Add key input buffer to given command
|
||||
#define sli_add_key_input(cmd_ctx, key, status) \
|
||||
sli_se_datatransfer_t key_input_buffer; \
|
||||
(status) = sli_se_get_key_input_output((key), &key_input_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_input(&cmd_ctx->command, &key_input_buffer);
|
||||
|
||||
// Add Key output buffer to given command
|
||||
#define sli_add_key_output(cmd_ctx, key, status) \
|
||||
sli_se_datatransfer_t key_output_buffer; \
|
||||
(status) = sli_se_get_key_input_output((key), &key_output_buffer); \
|
||||
if ((status) != SL_STATUS_OK) { \
|
||||
return (status); \
|
||||
} \
|
||||
sli_se_mailbox_command_add_output(&cmd_ctx->command, &key_output_buffer);
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
sl_status_t sli_se_to_sl_status(sli_se_mailbox_response_t res);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Take the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when successful, or else error code.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_lock_acquire(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Give the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK when successful, or else error code.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_lock_release(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute and wait for mailbox command to complete.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
// Key handling helper functions
|
||||
sl_status_t sli_key_get_storage_size(const sl_se_key_descriptor_t* key,
|
||||
uint32_t *storage_size);
|
||||
sl_status_t sli_key_get_size(const sl_se_key_descriptor_t* key, uint32_t* size);
|
||||
sl_status_t sli_key_check_equivalent(const sl_se_key_descriptor_t* key_1,
|
||||
const sl_se_key_descriptor_t* key_2,
|
||||
bool check_key_flag,
|
||||
bool public_export);
|
||||
|
||||
sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t* key,
|
||||
uint32_t* keyspec);
|
||||
sl_status_t sli_se_keyspec_to_key(const uint32_t keyspec,
|
||||
sl_se_key_descriptor_t* key);
|
||||
sl_status_t sli_se_get_auth_buffer(const sl_se_key_descriptor_t* key,
|
||||
sli_se_datatransfer_t* auth_buffer);
|
||||
sl_status_t sli_se_get_key_input_output(const sl_se_key_descriptor_t* key,
|
||||
sli_se_datatransfer_t* buffer);
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) */
|
||||
|
||||
#endif /* SE_MANAGER_INTERNAL_H */
|
||||
@@ -0,0 +1,731 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SE Mailbox API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef SLI_SE_MANAGER_MAILBOX_H
|
||||
#define SLI_SE_MANAGER_MAILBOX_H
|
||||
|
||||
#if defined(__linux__)
|
||||
#define SLI_SE_MAILBOX_HOST_SYSTEM
|
||||
#else
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#endif // __linux__
|
||||
|
||||
#include "sl_common.h"
|
||||
|
||||
#if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE status codes
|
||||
|
||||
/// Response status codes for the Secure Engine
|
||||
#define SLI_SE_RESPONSE_MASK 0x000F0000UL
|
||||
/// Command executed successfully or signature was successfully validated.
|
||||
#define SLI_SE_RESPONSE_OK 0x00000000UL
|
||||
|
||||
/// Command was not recognized as a valid command, or is not allowed in the
|
||||
/// current context.
|
||||
#define SLI_SE_RESPONSE_INVALID_COMMAND 0x00010000UL
|
||||
/// User did not provide the required credentials to be allowed to execute the
|
||||
/// command.
|
||||
#define SLI_SE_RESPONSE_AUTHORIZATION_ERROR 0x00020000UL
|
||||
/// Signature validation command (e.g. SE_COMMAND_SIGNATURE_VERIFY) failed to
|
||||
/// verify the given signature as being correct.
|
||||
#define SLI_SE_RESPONSE_INVALID_SIGNATURE 0x00030000UL
|
||||
/// A command started in non-secure mode is trying to access secure memory.
|
||||
#define SLI_SE_RESPONSE_BUS_ERROR 0x00040000UL
|
||||
/// Internal error
|
||||
#define SLI_SE_RESPONSE_INTERNAL_ERROR 0x00050000UL
|
||||
/// An internal error was raised and the command did not execute.
|
||||
#define SLI_SE_RESPONSE_CRYPTO_ERROR 0x00060000UL
|
||||
/// One of the passed parameters is deemed invalid (e.g. out of bounds).
|
||||
#define SLI_SE_RESPONSE_INVALID_PARAMETER 0x00070000UL
|
||||
/// Failure while checking the host for secure boot
|
||||
#define SLI_SE_RESPONSE_SECUREBOOT_ERROR 0x00090000UL
|
||||
/// Failure during selftest
|
||||
#define SLI_SE_RESPONSE_SELFTEST_ERROR 0x000A0000UL
|
||||
/// Feature/item not initialized or not present
|
||||
#define SLI_SE_RESPONSE_NOT_INITIALIZED 0x000B0000UL
|
||||
/// Abort status code is given when no operation is attempted.
|
||||
#define SLI_SE_RESPONSE_ABORT 0x00FF0000UL
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/// Root Code Mailbox is invalid.
|
||||
#define SLI_SE_RESPONSE_MAILBOX_INVALID 0x00FE0000UL
|
||||
/// Root Code Mailbox is valid
|
||||
#define SLI_SE_RESPONSE_MAILBOX_VALID 0xE5ECC0DEUL
|
||||
#endif // CRYPTOACC_PRESENT
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE command words
|
||||
// Commands are grouped based on availability
|
||||
#define SLI_SE_COMMAND_CHECK_SE_IMAGE 0x43020000UL
|
||||
#define SLI_SE_COMMAND_APPLY_SE_IMAGE 0x43030000UL
|
||||
#define SLI_SE_COMMAND_STATUS_SE_IMAGE 0x43040000UL
|
||||
#define SLI_SE_COMMAND_CHECK_HOST_IMAGE 0x43050001UL
|
||||
#define SLI_SE_COMMAND_APPLY_HOST_IMAGE 0x43060001UL
|
||||
#define SLI_SE_COMMAND_STATUS_HOST_IMAGE 0x43070000UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_OTP 0xFE040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_INIT_OTP 0xFF000001UL
|
||||
#define SLI_SE_COMMAND_INIT_PUBKEY 0xFF070001UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY 0xFF080001UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY 0xFF080001UL
|
||||
#define SLI_SE_COMMAND_READ_OTP 0xFE040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_APPLY 0x430C0000UL
|
||||
|
||||
// Commands limited to SE devices
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
#define SLI_SE_COMMAND_CREATE_KEY 0x02000000UL
|
||||
#define SLI_SE_COMMAND_READPUB_KEY 0x02010000UL
|
||||
|
||||
#define SLI_SE_COMMAND_HASH 0x03000000UL
|
||||
#define SLI_SE_COMMAND_HASHUPDATE 0x03010000UL
|
||||
#define SLI_SE_COMMAND_HMAC 0x03020000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_START 0x03040000UL
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_UPDATE 0x03050000UL
|
||||
#define SLI_SE_COMMAND_HMAC_STREAMING_FINISH 0x03060000UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
#define SLI_SE_COMMAND_HASHFINISH 0x03030000UL
|
||||
|
||||
#define SLI_SE_COMMAND_AES_ENCRYPT 0x04000000UL
|
||||
#define SLI_SE_COMMAND_AES_DECRYPT 0x04010000UL
|
||||
#define SLI_SE_COMMAND_AES_GCM_ENCRYPT 0x04020000UL
|
||||
#define SLI_SE_COMMAND_AES_GCM_DECRYPT 0x04030000UL
|
||||
#define SLI_SE_COMMAND_AES_CMAC 0x04040000UL
|
||||
#define SLI_SE_COMMAND_AES_CCM_ENCRYPT 0x04050000UL
|
||||
#define SLI_SE_COMMAND_AES_CCM_DECRYPT 0x04060000UL
|
||||
|
||||
#define SLI_SE_COMMAND_SIGNATURE_SIGN 0x06000000UL
|
||||
#define SLI_SE_COMMAND_SIGNATURE_VERIFY 0x06010000UL
|
||||
#define SLI_SE_COMMAND_EDDSA_SIGN 0x06020000UL
|
||||
#define SLI_SE_COMMAND_EDDSA_VERIFY 0x06030000UL
|
||||
|
||||
#define SLI_SE_COMMAND_TRNG_GET_RANDOM 0x07000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_JPAKE_R1_GENERATE 0x0B000000UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R1_VERIFY 0x0B000100UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R2_GENERATE 0x0B010000UL
|
||||
#define SLI_SE_COMMAND_JPAKE_R2_VERIFY 0x0B010100UL
|
||||
#define SLI_SE_COMMAND_JPAKE_GEN_SESSIONKEY 0x0B020000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DH 0x0E000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_STATUS_SE_VERSION 0x43080000UL
|
||||
#define SLI_SE_COMMAND_STATUS_OTP_VERSION 0x43080100UL
|
||||
#define SLI_SE_COMMAND_WRITE_USER_DATA 0x43090000UL
|
||||
#define SLI_SE_COMMAND_ERASE_USER_DATA 0x430A0000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_ENABLE_SECURE 0x430D0000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_DISABLE_SECURE 0x430E0000UL
|
||||
#define SLI_SE_COMMAND_DEVICE_ERASE 0x430F0000UL
|
||||
#define SLI_SE_COMMAND_DEVICE_ERASE_DISABLE 0x43100000UL
|
||||
#define SLI_SE_COMMAND_DBG_LOCK_STATUS 0x43110000UL
|
||||
#define SLI_SE_COMMAND_DBG_SET_RESTRICTIONS 0x43120000UL
|
||||
#define SLI_SE_COMMAND_PROTECTED_REGISTER 0x43210000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_READ_DEVICE_DATA 0x43300000UL
|
||||
#define SLI_SE_COMMAND_GET_ROLLBACK_COUNTER 0x43400000UL
|
||||
#endif
|
||||
#if defined(SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE)
|
||||
// SLI_SE_COMMAND_STATUS_READ_RSTCAUSE is only available on xG21 devices (series-2-config-1)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE 0x43220000UL
|
||||
#endif // SLI_SE_COMMAND_STATUS_READ_RSTCAUSE_AVAILABLE
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT_SIZE 0x43FA0000UL
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT 0x43FB0000UL
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_GET_HOST_UPGRADE_FILE_VERSION 0x44000000UL
|
||||
#define SLI_SE_COMMAND_SET_HOST_UPGRADE_FILE_VERSION 0x44010000UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
|
||||
#define SLI_SE_COMMAND_ENTER_ACTIVE_MODE 0x45000000UL
|
||||
#define SLI_SE_COMMAND_EXIT_ACTIVE_MODE 0x45010000UL
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SLI_SE_COMMAND_ATTEST_PSA_IAT 0x0A030000UL
|
||||
#define SLI_SE_COMMAND_ATTEST_CONFIG 0x0A040000UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#define SLI_SE_COMMAND_GET_CHALLENGE 0xFD000001UL
|
||||
#define SLI_SE_COMMAND_ROLL_CHALLENGE 0xFD000101UL
|
||||
#define SLI_SE_COMMAND_OPEN_DEBUG 0xFD010001UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_SERIAL 0xFE000000UL
|
||||
#define SLI_SE_COMMAND_GET_STATUS 0xFE010000UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEYBOOT 0xFE020001UL
|
||||
#define SLI_SE_COMMAND_SET_UPGRADEFLAG_SE 0xFE030000UL
|
||||
#define SLI_SE_COMMAND_SET_UPGRADEFLAG_HOST 0xFE030001UL
|
||||
#define SLI_SE_COMMAND_READ_TAMPER_RESET_CAUSE 0xFE050000UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_READ_TRACE_FLAGS 0xFE060000UL
|
||||
#endif
|
||||
#define SLI_SE_COMMAND_INIT_PUBKEY_SIGNATURE 0xFF090001UL
|
||||
#define SLI_SE_COMMAND_READ_PUBKEY_SIGNATURE 0xFF0A0001UL
|
||||
#define SLI_SE_COMMAND_INIT_AES_128_KEY 0xFF0B0001UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#define SLI_SE_COMMAND_CONFIGURE_QSPI_REF_CLOCK 0xFF150000UL
|
||||
#define SLI_SE_COMMAND_CONFIGURE_QSPI_REGS 0xFF160000UL
|
||||
#define SLI_SE_COMMAND_GET_QSPI_FLPLL_CONFIG 0xFF170000UL
|
||||
#define SLI_SE_COMMAND_APPLY_CODE_REGION_CONFIG 0xFF500000UL
|
||||
#define SLI_SE_COMMAND_CLOSE_CODE_REGION 0xFF510000UL
|
||||
#define SLI_SE_COMMAND_ERASE_CODE_REGION 0xFF520000UL
|
||||
#define SLI_SE_COMMAND_GET_CODE_REGION_CONFIG 0xFF530000UL
|
||||
#define SLI_SE_COMMAND_GET_CODE_REGION_VERSION 0xFF540000UL
|
||||
#define SLI_SE_COMMAND_SET_ACTIVE_BANKED_CODE_REGION 0xFF550000UL
|
||||
#define SLI_SE_COMMAND_WRITE_CODE_REGION 0xFF560000UL
|
||||
#define SLI_SE_COMMAND_ERASE_DATA_REGION 0xFF620000UL
|
||||
#define SLI_SE_COMMAND_WRITE_DATA_REGION 0xFF630000UL
|
||||
#define SLI_SE_COMMAND_GET_DATA_REGION_LOCATION 0xFF640000UL
|
||||
#endif
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
// Commands limited to SE Vault High devices
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define SLI_SE_COMMAND_WRAP_KEY 0x01000000UL
|
||||
#define SLI_SE_COMMAND_UNWRAP_KEY 0x01020000UL
|
||||
#define SLI_SE_COMMAND_DELETE_KEY 0x01050000UL
|
||||
#define SLI_SE_COMMAND_TRANSFER_KEY 0x01060000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC 0x02020002UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_HKDF 0x02020003UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC 0x02020010UL
|
||||
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_ENCRYPT 0x0C000000UL
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_DECRYPT 0x0C010000UL
|
||||
#define SLI_SE_COMMAND_CHACHA20_ENCRYPT 0x0C020000UL
|
||||
#define SLI_SE_COMMAND_CHACHA20_DECRYPT 0x0C030000UL
|
||||
#define SLI_SE_COMMAND_POLY1305_KEY_MAC 0x0C040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_DISABLE_TAMPER 0xFD020001UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// SE command options
|
||||
// Commands are grouped based on availability
|
||||
|
||||
/// Secure boot pubkey
|
||||
#define SLI_SE_KEY_TYPE_BOOT 0x00000100UL
|
||||
/// Secure authorization (debug) pubkey
|
||||
#define SLI_SE_KEY_TYPE_AUTH 0x00000200UL
|
||||
|
||||
// Options limited to SE devices
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/// Root pubkey
|
||||
#define SLI_SE_KEY_TYPE_ROOT 0x00000300UL
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Attestation pubkey
|
||||
#define SLI_SE_KEY_TYPE_ATTEST 0x00000400UL
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
/// BGL encryption key
|
||||
#define SLI_SE_IMMUTABLE_KEY_TYPE_AES_128 0x00000500UL
|
||||
|
||||
/// Use MD5 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_MD5 0x00000100UL
|
||||
/// Use SHA1 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA1 0x00000200UL
|
||||
/// Use SHA224 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA224 0x00000300UL
|
||||
/// Use SHA256 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA256 0x00000400UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Use SHA1 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA1 0x00000700UL
|
||||
/// Use SHA224 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA224 0x00000800UL
|
||||
/// Use SHA256 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA256 0x00000900UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
|
||||
/// Execute algorithm in ECB mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_ECB 0x00000100UL
|
||||
/// Execute algorithm in CBC mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CBC 0x00000200UL
|
||||
/// Execute algorithm in CTR mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CTR 0x00000300UL
|
||||
/// Execute algorithm in CFB mode
|
||||
#define SLI_SE_COMMAND_OPTION_MODE_CFB 0x00000400UL
|
||||
|
||||
/// Run the whole algorithm, all data present
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_WHOLE 0x00000000UL
|
||||
/// Start the algorithm, but get a context to later add more data
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_START 0x00000001UL
|
||||
/// End the algorithm, get the result
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_END 0x00000002UL
|
||||
/// Add more data input to the algorithm. Need to supply previous context,
|
||||
/// and get a context back
|
||||
#define SLI_SE_COMMAND_OPTION_CONTEXT_ADD 0x00000003UL
|
||||
|
||||
/// User data command options
|
||||
/// Magic paramater for deleting user data
|
||||
#define SLI_SE_COMMAND_OPTION_ERASE_UD 0xDE1E7EADUL
|
||||
#define SLI_SE_COMMAND_OPTION_WRITE 0x00000100UL
|
||||
#define SLI_SE_COMMAND_OPTION_READ 0x00000000UL
|
||||
|
||||
#define SLI_SE_COMMAND_CERT_BATCH 0x00000100UL
|
||||
#define SLI_SE_COMMAND_CERT_SE 0x00000200UL
|
||||
#define SLI_SE_COMMAND_CERT_HOST 0x00000300UL
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/// Use SHA384 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA384 0x00000500UL
|
||||
/// Use SHA512 as hash algorithm
|
||||
#define SLI_SE_COMMAND_OPTION_HASH_SHA512 0x00000600UL
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
/// Use SHA384 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA384 0x00000A00UL
|
||||
/// Use SHA512 as hash algorithm for HMAC streaming operation
|
||||
#define SLI_SE_COMMAND_OPTION_HMAC_HASH_SHA512 0x00000B00UL
|
||||
#endif // _SILICON_LABS_32B_SERIES_3
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Other defines
|
||||
|
||||
/** Maximum amount of parameters supported by the hardware FIFO */
|
||||
#define SE_FIFO_MAX_PARAMETERS 13U
|
||||
|
||||
/** Stop datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_STOP 0x00000001UL
|
||||
/** Discard datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_DISCARD 0x40000000UL
|
||||
/** Realign datatransfer */
|
||||
#define SLI_SE_DATATRANSFER_REALIGN 0x20000000UL
|
||||
/** Datatransfer Const Address*/
|
||||
#define SLI_SE_DATATRANSFER_CONSTADDRESS 0x10000000UL
|
||||
/** Stop Length Mask */
|
||||
#define SLI_SE_DATATRANSFER_LENGTH_MASK 0x0FFFFFFFUL
|
||||
|
||||
/** Maximum amount of parameters for largest command in defined command set */
|
||||
#ifndef SLI_SE_COMMAND_MAX_PARAMETERS
|
||||
#define SLI_SE_COMMAND_MAX_PARAMETERS 4U
|
||||
#endif
|
||||
|
||||
/* Sanity-check defines */
|
||||
#if SLI_SE_COMMAND_MAX_PARAMETERS > SE_FIFO_MAX_PARAMETERS
|
||||
#error "Trying to configure more parameters than supported by the hardware"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE DMA transfer descriptor.
|
||||
|
||||
* Can be linked to each other to provide scatter-gather behavior.
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
volatile void* volatile data; /**< Data pointer */
|
||||
void* volatile next; /**< Next descriptor */
|
||||
volatile uint32_t length; /**< Length */
|
||||
} sli_se_datatransfer_t;
|
||||
|
||||
/** Default initialization of data transfer struct */
|
||||
#define SLI_SE_DATATRANSFER_DEFAULT(address, data_size) \
|
||||
{ \
|
||||
.data = (void*)(address), /* Pointer to data block */ \
|
||||
.next = (void*)SLI_SE_DATATRANSFER_STOP, /* This is the last block by default */ \
|
||||
.length = (data_size) | SLI_SE_DATATRANSFER_REALIGN /* Add size, use realign by default */ \
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief SE mailbox command structure
|
||||
*
|
||||
* @details
|
||||
* This structure defines the command structure used by the SE mailbox
|
||||
******************************************************************************/
|
||||
typedef struct {
|
||||
uint32_t command; /**< SE Command */
|
||||
sli_se_datatransfer_t* data_in; /**< Input data */
|
||||
sli_se_datatransfer_t* data_out; /**< Output data */
|
||||
uint32_t parameters[SLI_SE_COMMAND_MAX_PARAMETERS]; /**< Parameters */
|
||||
size_t num_parameters; /**< Number of parameters */
|
||||
} sli_se_mailbox_command_t;
|
||||
|
||||
/** Default initialization of command struct */
|
||||
#define SLI_SE_MAILBOX_COMMAND_DEFAULT(command_word) \
|
||||
{ \
|
||||
.command = command_word, /* Given command word */ \
|
||||
.data_in = NULL, /* No data in */ \
|
||||
.data_out = NULL, /* No data out */ \
|
||||
.parameters = { 0, 0, 0, 0 }, /* No parameters */ \
|
||||
.num_parameters = 0 /* No parameters */ \
|
||||
}
|
||||
|
||||
/** Possible responses to a command */
|
||||
typedef uint32_t sli_se_mailbox_response_t;
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add input data to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a buffer of input data to the given SE command structure
|
||||
* The buffer gets appended by reference at the end of the list of already
|
||||
* added buffers.
|
||||
*
|
||||
* @note
|
||||
* Note that this function does not copy either the data buffer or the buffer
|
||||
* structure, so make sure to keep the data object in scope until the command
|
||||
* has been executed by the secure element.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE Mailbox command structure.
|
||||
*
|
||||
* @param[in] data
|
||||
* Pointer to a data transfer structure.
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_input(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add output data to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a buffer of output data to the given command structure
|
||||
* The buffer gets appended by reference at the end of the list of already
|
||||
* added buffers.
|
||||
*
|
||||
* @note
|
||||
* Note that this function does not copy either the data buffer or the buffer
|
||||
* structure, so make sure to keep the data object in scope until the command
|
||||
* has been executed by the secure element.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE mailbox command structure.
|
||||
*
|
||||
* @param[in] data
|
||||
* Pointer to a data transfer structure.
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_output(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add a parameter to a mailbox command
|
||||
*
|
||||
* @details
|
||||
* This function adds a parameter word to the passed command.
|
||||
*
|
||||
* @note
|
||||
* Make sure to not exceed @ref SE_MAX_PARAMETERS.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to a filled-out SE command structure.
|
||||
* @param[in] parameter
|
||||
* Parameter to add.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sli_se_mailbox_command_add_parameter(sli_se_mailbox_command_t *command, uint32_t parameter);
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute the passed command
|
||||
*
|
||||
* @details
|
||||
* This function starts the execution of the passed command by the secure
|
||||
* element. The RXINT interrupt flag will be set upon completion. Call
|
||||
* @ref sli_se_mailbox_read_response to wait for completion and retrieve the
|
||||
* command's execution status.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to a filled-out SE command structure.
|
||||
******************************************************************************/
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_SE_MANAGER, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
void sli_se_mailbox_execute_command(sli_se_mailbox_command_t *command);
|
||||
#endif //!defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the status of the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function waits for any running command to complete before reading the
|
||||
* status of the previously executed command.
|
||||
*
|
||||
* @note
|
||||
* The command response needs to be read for every executed command, and can
|
||||
* only be read once per executed command (FIFO behavior).
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SE_RESPONSE_OK when the command was executed successfully or a signature
|
||||
* was successfully verified.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_read_response(void)
|
||||
{
|
||||
while (!(SEMAILBOX_HOST->RX_STATUS & SEMAILBOX_RX_STATUS_RXINT)) {
|
||||
// Wait for command completion by polling SE Mailbox RX interrupt flag
|
||||
}
|
||||
// Return command response
|
||||
return (sli_se_mailbox_response_t)(SEMAILBOX_HOST->RX_HEADER & SLI_SE_RESPONSE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Handle the response of the previously executed command.
|
||||
*
|
||||
* \details This function handles the response of the previously
|
||||
* executed HSE command by calling sli_se_mailbox_read_response
|
||||
* to read the response value and returns it. For Series-3 this
|
||||
* function also clears the SEMAILBOX FIFO by reading out the
|
||||
* unused command handle word.
|
||||
* This function is called by the ISR of the SEMAILBOX (called
|
||||
* SEMBRX_IRQHandler ) to clear the SEMBRX_IRQn interrupt signal
|
||||
* on the SEMAILBOX peripheral side. NOTE: The ISR will also
|
||||
* need to clear the SEMBRX_IRQn condition in the internal/local
|
||||
* interrupt controller (NVIC) by calling
|
||||
* NVIC_ClearPendingIRQ(SEMBRX_IRQn).
|
||||
*
|
||||
* \return Value returned by sli_se_mailbox_read_response.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_handle_response(void)
|
||||
{
|
||||
// Read command response
|
||||
sli_se_mailbox_response_t se_mailbox_response = sli_se_mailbox_read_response();
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
// Read the command handle word ( not used ) from the SEMAILBOX FIFO
|
||||
SEMAILBOX_HOST->FIFO;
|
||||
#endif
|
||||
|
||||
// Return command response
|
||||
return se_mailbox_response;
|
||||
}
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
sli_se_mailbox_response_t sli_se_mailbox_read_response(void);
|
||||
|
||||
/**
|
||||
* \brief Handle the response of the previously executed command.
|
||||
*
|
||||
* \details This function handles the response of the previously
|
||||
* executed VSE command by calling sli_se_mailbox_read_response
|
||||
* to read the response value and returns it.
|
||||
*
|
||||
* \return Value returned by sli_se_mailbox_read_response.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE sli_se_mailbox_response_t sli_se_mailbox_handle_response(void)
|
||||
{
|
||||
// Read and return VSE mailbox command response
|
||||
return sli_se_mailbox_read_response();
|
||||
}
|
||||
#endif // #if defined(SEMAILBOX_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable one or more SE interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* SE interrupt sources to disable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the Secure Element module
|
||||
* (SE_CONFIGURATION_(TX/RX)INTEN).
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_se_mailbox_disable_interrupt(uint32_t flags)
|
||||
{
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
SEMAILBOX_HOST->CONFIGURATION &= ~flags;
|
||||
#else
|
||||
(void) flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable one or more SE interrupts.
|
||||
*
|
||||
* @param[in] flags
|
||||
* SE interrupt sources to enable. Use a bitwise logic OR combination of
|
||||
* valid interrupt flags for the Secure Element module
|
||||
* (SEMAILBOX_CONFIGURATION_TXINTEN or SEMAILBOX_CONFIGURATION_RXINTEN).
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_se_mailbox_enable_interrupt(uint32_t flags)
|
||||
{
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
SEMAILBOX_HOST->CONFIGURATION |= flags;
|
||||
#else
|
||||
(void) flags;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current SE version
|
||||
*
|
||||
* @details
|
||||
* This function returns the current VSE version
|
||||
*
|
||||
* @param[in] version
|
||||
* Pointer to location where to copy the version of VSE to.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_version(uint32_t *version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get VSE configuration and status bits
|
||||
*
|
||||
* @details
|
||||
* This function returns the current VSE configuration and status bits.
|
||||
* The following list explains what the different bits in cfg_status indicate.
|
||||
* A bit value of 1 means enabled, while 0 means disabled:
|
||||
* * [0]: Secure boot
|
||||
* * [1]: Verify secure boot certificate
|
||||
* * [2]: Anti-rollback
|
||||
* * [3]: Narrow page lock
|
||||
* * [4]: Full page lock
|
||||
* The following status bits can be read with VSE versions
|
||||
* higher than 1.2.2.
|
||||
* * [10]: Debug port lock
|
||||
* * [11]: Device erase enabled
|
||||
* * [12]: Secure debug enabled
|
||||
* * [15]: Debug port register state, 1 if the debug port is locked.
|
||||
*
|
||||
* @param[out] cfg_status
|
||||
* Pointer to location to copy Configuration Status bits into.
|
||||
*
|
||||
* @note
|
||||
* This function will check that the mailbox content is valid before
|
||||
* reading the status bits. If the command response has already been read
|
||||
* with a call to @ref sli_vse_mailbox_ack_command(), the validity check will fail, and
|
||||
* the config status bits cannot be read before a reset has occurred.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_cfg_status(uint32_t *cfg_status);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the version number of the OTP from the status field of the output
|
||||
* mailbox
|
||||
* @details
|
||||
* This function checks if the OTP version number flag is set in the output
|
||||
* mailbox. If it is, the version number is writen to @ref otp_version pointer
|
||||
* location. If not, it returns error response.
|
||||
*
|
||||
* @param[out] otp_version
|
||||
* Pointer to location to copy OTP version number into.
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_otp_version(uint32_t *otp_version);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command.
|
||||
* The mailbox command is acknowledged by inverting all bits in the checksum
|
||||
* (XOR with 0xFFFFFFFF).
|
||||
* The output data is copied into the linked list of output buffers pointed
|
||||
* to in the given command data structure.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE command structure.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully or a
|
||||
* signature was successfully verified,
|
||||
* @retval SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* @retval SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* @retval SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* @retval SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command,
|
||||
* e.g. because of conflicting Secure/Non-Secure
|
||||
* memory accesses,
|
||||
* @retval SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* @retval SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* @retval SLI_SE_RESPONSE_MAILBOX_INVALID when mailbox command not done or invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_ack_command(sli_se_mailbox_command_t *command);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function reads the previously executed command.
|
||||
*
|
||||
* @return
|
||||
* One of the SE command words.
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid.
|
||||
******************************************************************************/
|
||||
uint32_t sli_vse_mailbox_read_executed_command(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the VSE Output Mailbox is valid.
|
||||
*
|
||||
* @return True if the VSE Output Mailbox is valid (magic and checksum OK)
|
||||
******************************************************************************/
|
||||
bool sli_vse_mailbox_is_output_valid(void);
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#endif /* SLI_SE_MANAGER_MAILBOX_H */
|
||||
@@ -0,0 +1,560 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_assert.h"
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#include "sl_hal_bus.h"
|
||||
#else
|
||||
#include "em_bus.h"
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
#include "sli_psec_osal.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_managers
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Locals
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
/// Priority to use for SEMBRX IRQ
|
||||
#if defined(SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY)
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY >= (1U << __NVIC_PRIO_BITS) )
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) ) )
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#else
|
||||
#if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < CORE_ATOMIC_BASE_PRIORITY_LEVEL)
|
||||
#error Illegal SEMBRX priority level.
|
||||
#endif
|
||||
#endif
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY
|
||||
#else
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) )
|
||||
#else
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (CORE_ATOMIC_BASE_PRIORITY_LEVEL)
|
||||
#endif
|
||||
#endif
|
||||
#else // defined(SL_SE_MANAGER_THREADING)
|
||||
/// Priority to use for SEMBRX IRQ
|
||||
#if defined(SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY)
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY
|
||||
#else
|
||||
#define SE_MANAGER_SEMBRX_IRQ_PRIORITY (0)
|
||||
#endif
|
||||
#endif // defined(SL_SE_MANAGER_THREADING)
|
||||
#endif // defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Flag to indicate that the SE Manager is initialized or not.
|
||||
static volatile bool se_manager_initialized = false;
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
// Lock mutex for synchronizing multiple threads calling into the
|
||||
// SE Manager API.
|
||||
static sli_psec_osal_lock_t se_lock = { 0 };
|
||||
|
||||
#endif // SL_SE_MANAGER_THREADING
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
// SE command completion.
|
||||
static sli_psec_osal_completion_t se_command_completion;
|
||||
// SE mailbox command response code. This value is read from the SEMAILBOX
|
||||
// in ISR in order to clear the command complete interrupt condition.
|
||||
static sli_se_mailbox_response_t se_manager_command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize the SE Manager.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init(void)
|
||||
{
|
||||
sl_status_t ret = SL_STATUS_OK;
|
||||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
(void)se_manager_command_response;
|
||||
#endif
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_START
|
||||
#endif
|
||||
|
||||
if ( !se_manager_initialized ) {
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
// Initialize SE lock
|
||||
ret = sli_psec_osal_init_lock(&se_lock);
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Initialize command completion object.
|
||||
ret = sli_psec_osal_init_completion(&se_command_completion);
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Enable SE RX mailbox interrupt in NVIC, but not in SEMAILBOX
|
||||
// which will be enabled if the yield parameter in
|
||||
// sli_se_execute_and_wait is true.
|
||||
NVIC_SetPriority(SEMBRX_IRQn, SE_MANAGER_SEMBRX_IRQ_PRIORITY);
|
||||
NVIC_EnableIRQ(SEMBRX_IRQn);
|
||||
}
|
||||
}
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
if (ret == SL_STATUS_OK) {
|
||||
se_manager_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Denitialize the SE Manager.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit(void)
|
||||
{
|
||||
sl_status_t ret = SL_STATUS_OK;
|
||||
|
||||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_START
|
||||
#endif
|
||||
|
||||
if ( se_manager_initialized ) {
|
||||
// We need to exit the critical section in case the SE lock is held by a
|
||||
// thread, and we want to take it before de-initializing.
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
// Acquire the SE lock to make sure no thread is executing SE commands
|
||||
// when we de-initialize.
|
||||
ret = sli_se_lock_acquire();
|
||||
if (ret != SL_STATUS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
// Disable SE RX mailbox interrupt in NVIC.
|
||||
NVIC_ClearPendingIRQ(SEMBRX_IRQn);
|
||||
NVIC_DisableIRQ(SEMBRX_IRQn);
|
||||
// Free command completion object.
|
||||
ret = sli_psec_osal_free_completion(&se_command_completion);
|
||||
#endif // SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
if (ret == SL_STATUS_OK) {
|
||||
// Free the SE lock mutex
|
||||
ret = sli_psec_osal_free_lock(&se_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mark the SE Manager as un-initialized.
|
||||
se_manager_initialized = false;
|
||||
}
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
else {
|
||||
SLI_PSEC_OSAL_KERNEL_CRITICAL_SECTION_END
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Translate SE response codes to sl_status_t codes.
|
||||
*
|
||||
* @return
|
||||
* Converted status code, their meaning is documented here @ref sl_status.h,
|
||||
* Asserts and returns @c SL_STATUS_FAIL on unexpected response.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_to_sl_status(sli_se_mailbox_response_t res)
|
||||
{
|
||||
switch (res) {
|
||||
case SLI_SE_RESPONSE_OK:
|
||||
return SL_STATUS_OK;
|
||||
case SLI_SE_RESPONSE_INVALID_COMMAND:
|
||||
return SL_STATUS_COMMAND_IS_INVALID;
|
||||
case SLI_SE_RESPONSE_AUTHORIZATION_ERROR:
|
||||
return SL_STATUS_INVALID_CREDENTIALS;
|
||||
case SLI_SE_RESPONSE_INVALID_SIGNATURE:
|
||||
return SL_STATUS_INVALID_SIGNATURE;
|
||||
case SLI_SE_RESPONSE_BUS_ERROR:
|
||||
return SL_STATUS_BUS_ERROR;
|
||||
case SLI_SE_RESPONSE_INTERNAL_ERROR:
|
||||
return SL_STATUS_FAIL;
|
||||
case SLI_SE_RESPONSE_CRYPTO_ERROR:
|
||||
return SL_STATUS_FAIL;
|
||||
case SLI_SE_RESPONSE_INVALID_PARAMETER:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
case SLI_SE_RESPONSE_ABORT:
|
||||
return SL_STATUS_ABORT;
|
||||
case SLI_SE_RESPONSE_SELFTEST_ERROR:
|
||||
return SL_STATUS_INITIALIZATION;
|
||||
case SLI_SE_RESPONSE_NOT_INITIALIZED:
|
||||
return SL_STATUS_NOT_INITIALIZED;
|
||||
#if defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
case SLI_SE_RESPONSE_MAILBOX_INVALID:
|
||||
return SL_STATUS_COMMAND_IS_INVALID;
|
||||
#endif
|
||||
default:
|
||||
// Assert we do not get a bad SE response code.
|
||||
EFM_ASSERT(false);
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Acquire the SE lock for exclusive access if necessary (thread mode).
|
||||
* Enable the SEMAILBOX clock if necessary.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_lock_acquire(void)
|
||||
{
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
sl_status_t status = sli_psec_osal_take_lock(&se_lock);
|
||||
#else
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
#endif
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
if (status == SL_STATUS_OK) {
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_hal_bus_reg_write_bit(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 1);
|
||||
#else
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 1);
|
||||
#endif
|
||||
// Make sure the write to CMU->CLKEN1 is finished.
|
||||
__DSB();
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Release the SE lock if necessary (thread mode).
|
||||
* Disable the SEMAILBOX clock if necessary.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_se_lock_release(void)
|
||||
{
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_3)
|
||||
sl_hal_bus_reg_write_bit(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 0);
|
||||
#else
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 0);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
return sli_psec_osal_give_lock(&se_lock);
|
||||
#else
|
||||
return SL_STATUS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* SE Mailbox Interrupt Service Routine
|
||||
******************************************************************************/
|
||||
void SEMBRX_IRQHandler(void)
|
||||
{
|
||||
sl_status_t status;
|
||||
// Check if the SE mailbox is the source of the interrupt.
|
||||
if (SEMAILBOX_HOST->RX_STATUS & SEMAILBOX_RX_STATUS_RXINT) {
|
||||
// Signal SE mailbox completion.
|
||||
status = sli_psec_osal_complete(&se_command_completion);
|
||||
EFM_ASSERT(status == SL_STATUS_OK);
|
||||
}
|
||||
// Get command response and clear interrupt condition in SEMAILBOX peripheral
|
||||
se_manager_command_response = sli_se_mailbox_handle_response();
|
||||
// Clear interrupt condition in NVIC
|
||||
NVIC_ClearPendingIRQ(SEMBRX_IRQn);
|
||||
}
|
||||
|
||||
#endif // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set the yield attribute of the SE command context object.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_set_yield(sl_se_command_context_t *cmd_ctx,
|
||||
bool yield)
|
||||
{
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
cmd_ctx->yield = yield;
|
||||
return SL_STATUS_OK;
|
||||
#else
|
||||
if (yield) {
|
||||
return SL_STATUS_NOT_AVAILABLE;
|
||||
} else {
|
||||
(void) cmd_ctx;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute and wait for SE mailbox command to complete.
|
||||
*
|
||||
* @return
|
||||
* One of the following status code, any other status codes relates to internal
|
||||
* function errors see @ref sl_status.h for their meaning.
|
||||
* - @c SL_STATUS_OK
|
||||
* - @c SL_STATUS_INVALID_PARAMETER
|
||||
******************************************************************************/
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) && !defined(SLI_SE_MANAGER_HOST_SYSTEM)
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_FAIL;
|
||||
sli_se_mailbox_response_t command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Execute SE mailbox command
|
||||
sli_se_mailbox_execute_command(&cmd_ctx->command);
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
if (cmd_ctx->yield) {
|
||||
// Enable SEMAILBOX RXINT interrupt
|
||||
sli_se_mailbox_enable_interrupt(SEMAILBOX_CONFIGURATION_RXINTEN);
|
||||
|
||||
// Yield and Wait for the command completion signal
|
||||
status = sli_psec_osal_wait_completion(&se_command_completion,
|
||||
SLI_PSEC_OSAL_WAIT_FOREVER);
|
||||
|
||||
// Disable SEMAILBOX RXINT interrupt.
|
||||
sli_se_mailbox_disable_interrupt(SEMAILBOX_CONFIGURATION_RXINTEN);
|
||||
|
||||
if (status != SL_STATUS_OK) {
|
||||
#if (_SILICON_LABS_32B_SERIES == 3)
|
||||
// Read the command handle word ( not used ) from the SEMAILBOX FIFO
|
||||
SEMAILBOX_HOST->FIFO;
|
||||
#endif // #if (_SILICON_LABS_32B_SERIES == 3)
|
||||
sli_se_lock_release();
|
||||
return status;
|
||||
}
|
||||
|
||||
// Get response which is read in the ISR to clear interrupt condition.
|
||||
command_response = se_manager_command_response;
|
||||
// Default to an error.
|
||||
se_manager_command_response = SLI_SE_RESPONSE_INTERNAL_ERROR;
|
||||
} else {
|
||||
// Wait for command completion and get command response
|
||||
command_response = sli_se_mailbox_handle_response();
|
||||
}
|
||||
|
||||
#else // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Wait for command completion and get command response
|
||||
command_response = sli_se_mailbox_handle_response();
|
||||
|
||||
#endif // #if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (command_response == SLI_SE_RESPONSE_OK) {
|
||||
return status;
|
||||
} else {
|
||||
// Convert from sli_se_mailbox_response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(command_response);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED) // SLI_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Execute SE mailbox command
|
||||
sli_se_mailbox_execute_command(&cmd_ctx->command);
|
||||
|
||||
return SL_STATUS_FAIL; // Should never get to this point
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* From VSE mailbox read which command, if any, was executed.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_read_executed_command(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Read command
|
||||
cmd_ctx->command.command = sli_vse_mailbox_read_executed_command();
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (cmd_ctx->command.command == SLI_SE_RESPONSE_MAILBOX_INVALID) {
|
||||
// Convert from sli_se_mailbox_response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(SLI_SE_RESPONSE_MAILBOX_INVALID);
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_status_t status;
|
||||
sl_status_t command_response;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Acknowledge VSE mailbox command
|
||||
command_response = sli_vse_mailbox_ack_command(&cmd_ctx->command);
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
||||
// Return sl_status_t code.
|
||||
if (command_response == SLI_SE_RESPONSE_OK) {
|
||||
return status;
|
||||
} else {
|
||||
// Convert from SE_Response_t to sl_status_t code and return.
|
||||
return sli_se_to_sl_status(command_response);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // SLI_VSE_MAILBOX_COMMAND_SUPPORTED
|
||||
|
||||
#endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize an SE command context object
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_se_command_context_t v = SL_SE_COMMAND_CONTEXT_INIT;
|
||||
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*cmd_ctx = v;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* De-initialize an SE command context object
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return sl_se_init_command_context(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED) || defined(SLI_VSE_MAILBOX_COMMAND_SUPPORTED)
|
||||
@@ -0,0 +1,296 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sl_se_manager_attestation.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Static Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Validate the command word, challenge size and update command word with
|
||||
* option flags
|
||||
*
|
||||
* @param[in, out] command_word
|
||||
* The command word to send to the SE. Will be modified to reflect challenge
|
||||
* size.
|
||||
*
|
||||
* @param challenge_size
|
||||
* Size of the challenge to be used.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t validate_and_update_command_word(uint32_t *command_word,
|
||||
size_t challenge_size)
|
||||
{
|
||||
// Check supported challenge sizes
|
||||
uint32_t command_id = *command_word & 0xFFFF0000UL;
|
||||
if (command_id == SLI_SE_COMMAND_ATTEST_PSA_IAT) {
|
||||
switch (challenge_size) {
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_32:
|
||||
*command_word |= 0x01 << 8;
|
||||
break;
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_48:
|
||||
*command_word |= 0x02 << 8;
|
||||
break;
|
||||
case SL_SE_ATTESTATION_CHALLENGE_SIZE_64:
|
||||
*command_word |= 0x03 << 8;
|
||||
break;
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (command_id == SLI_SE_COMMAND_ATTEST_CONFIG) {
|
||||
if (challenge_size != SL_SE_ATTESTATION_CHALLENGE_SIZE_32) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// No need to do anything with the command word
|
||||
} else {
|
||||
// Unknown command ID
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// All the checks passed
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the PSA initial attest token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* SE command context struct.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @param[in] command_word
|
||||
* The command word to send to the SE, to differentiat between token types
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t get_attestation_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size,
|
||||
uint32_t command_word)
|
||||
{
|
||||
// Parameter check
|
||||
if (cmd_ctx == NULL || token_size == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Check command word and challenge size
|
||||
sl_status_t status = validate_and_update_command_word(&command_word,
|
||||
challenge_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Use a dummy nonce since the SE requires nonce input even if we just
|
||||
// want to find the token length
|
||||
uint8_t dummy_nonce[SL_SE_ATTESTATION_CHALLENGE_SIZE_64] = { 0 };
|
||||
|
||||
// Build and execute the command
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
// Or comman word with 0x01 to enable length output only
|
||||
sli_se_command_init(cmd_ctx, command_word | 0x01UL);
|
||||
sli_se_datatransfer_t noncedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(dummy_nonce, challenge_size);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &noncedata);
|
||||
sli_se_datatransfer_t sizedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &sizedata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get an attestation token from the SE
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* SE command context struct.
|
||||
*
|
||||
* @param[in] auth_challenge
|
||||
* Buffer with a challenge object selected by the caller.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_buf
|
||||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
*
|
||||
* @param[in] command_word
|
||||
* The command word to send to the SE, to differentiat between token types
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
static sl_status_t get_attestation_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size,
|
||||
uint32_t command_word)
|
||||
{
|
||||
// Parameter check
|
||||
if (cmd_ctx == NULL
|
||||
|| auth_challenge == NULL
|
||||
|| token_buf == NULL
|
||||
|| token_size == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Check supported challenge sizes
|
||||
sl_status_t status = validate_and_update_command_word(&command_word,
|
||||
challenge_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Check that buffer is sufficiently large
|
||||
status = get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
command_word);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
if (((*token_size + 0x3) & ~0x3) > token_buf_size) {
|
||||
return SL_STATUS_WOULD_OVERFLOW;
|
||||
}
|
||||
|
||||
// Build and execute the command
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
sli_se_datatransfer_t noncedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(auth_challenge, challenge_size);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &noncedata);
|
||||
sli_se_datatransfer_t sizedata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &sizedata);
|
||||
sli_se_datatransfer_t tokendata =
|
||||
SLI_SE_DATATRANSFER_DEFAULT(token_buf, ((*token_size + 0x3) & ~0x3));
|
||||
sli_se_mailbox_command_add_output(se_cmd, &tokendata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the PSA initial attest token from the SE
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token(cmd_ctx,
|
||||
auth_challenge,
|
||||
challenge_size,
|
||||
token_buf,
|
||||
token_buf_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_PSA_IAT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the size of a PSA initial attest token with the given nonce
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_psa_iat_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_PSA_IAT);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get an attested (signed) security configuration token from the SE
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token(sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *auth_challenge,
|
||||
size_t challenge_size,
|
||||
uint8_t *token_buf,
|
||||
size_t token_buf_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token(cmd_ctx,
|
||||
auth_challenge,
|
||||
challenge_size,
|
||||
token_buf,
|
||||
token_buf_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_CONFIG);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get the size of a security configuration token
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd_ctx,
|
||||
size_t challenge_size,
|
||||
size_t *token_size)
|
||||
{
|
||||
return get_attestation_token_size(cmd_ctx,
|
||||
challenge_size,
|
||||
token_size,
|
||||
SLI_SE_COMMAND_ATTEST_CONFIG);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se_manager) */
|
||||
|
||||
#endif // SLI_MAILBOX_COMMAND_SUPPORTED && VAULT
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,103 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get random data from hardware TRNG.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_get_random(sl_se_command_context_t *cmd_ctx,
|
||||
void * data,
|
||||
uint32_t num_bytes)
|
||||
{
|
||||
sli_se_mailbox_command_t *se_cmd;
|
||||
sl_status_t ret;
|
||||
uint32_t surplus_bytes, i;
|
||||
uint32_t surplus_word = 0;
|
||||
|
||||
if (cmd_ctx == NULL || (num_bytes != 0 && data == NULL)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
se_cmd = &cmd_ctx->command;
|
||||
surplus_bytes = num_bytes & 0x3U;
|
||||
num_bytes &= ~0x3U;
|
||||
|
||||
if (num_bytes > 0U) {
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(data, num_bytes);
|
||||
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, num_bytes);
|
||||
|
||||
// Execute and wait
|
||||
if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
|
||||
memset(data, 0, num_bytes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (surplus_bytes > 0) {
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_TRNG_GET_RANDOM);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(&surplus_word, 4);
|
||||
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, 4);
|
||||
|
||||
// Execute and wait
|
||||
if ((ret = sli_se_execute_and_wait(cmd_ctx)) != SL_STATUS_OK) {
|
||||
memset(data, 0, num_bytes + surplus_bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t *output = (uint8_t*)data + num_bytes;
|
||||
for (i = 0; i < surplus_bytes; i++) {
|
||||
output[i] = (surplus_word >> (i * 8U)) & 0xFFU;
|
||||
}
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
@@ -0,0 +1,673 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include "sl_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se Secure Engine Manager API
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA1 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t *sha1_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha1[32] = {
|
||||
0x67, 0x45, 0x23, 0x01,
|
||||
0xEF, 0xCD, 0xAB, 0x89,
|
||||
0x98, 0xBA, 0xDC, 0xFE,
|
||||
0x10, 0x32, 0x54, 0x76,
|
||||
0xC3, 0xD2, 0xE1, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha1_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha1_ctx->total[0] = 0;
|
||||
sha1_ctx->total[1] = 0;
|
||||
memcpy(sha1_ctx->state, init_state_sha1, sizeof(sha1_ctx->state));
|
||||
|
||||
sha1_ctx->hash_type = SL_SE_HASH_SHA1;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA224 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t *sha224_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha224[32] = {
|
||||
0xC1, 0x05, 0x9E, 0xD8,
|
||||
0x36, 0x7C, 0xD5, 0x07,
|
||||
0x30, 0x70, 0xDD, 0x17,
|
||||
0xF7, 0x0E, 0x59, 0x39,
|
||||
0xFF, 0xC0, 0x0B, 0x31,
|
||||
0x68, 0x58, 0x15, 0x11,
|
||||
0x64, 0xF9, 0x8F, 0xA7,
|
||||
0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha224_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha224_ctx->total[0] = 0;
|
||||
sha224_ctx->total[1] = 0;
|
||||
memcpy(sha224_ctx->state, init_state_sha224, sizeof(sha224_ctx->state));
|
||||
|
||||
sha224_ctx->hash_type = SL_SE_HASH_SHA224;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA256 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t *sha256_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha256[32] = {
|
||||
0x6A, 0x09, 0xE6, 0x67,
|
||||
0xBB, 0x67, 0xAE, 0x85,
|
||||
0x3C, 0x6E, 0xF3, 0x72,
|
||||
0xA5, 0x4F, 0xF5, 0x3A,
|
||||
0x51, 0x0E, 0x52, 0x7F,
|
||||
0x9B, 0x05, 0x68, 0x8C,
|
||||
0x1F, 0x83, 0xD9, 0xAB,
|
||||
0x5B, 0xE0, 0xCD, 0x19
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha256_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha256_ctx->total[0] = 0;
|
||||
sha256_ctx->total[1] = 0;
|
||||
memcpy(sha256_ctx->state, init_state_sha256, sizeof(sha256_ctx->state));
|
||||
|
||||
sha256_ctx->hash_type = SL_SE_HASH_SHA256;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* Start a SHA384 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t *sha384_ctx,
|
||||
sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha384[64] = {
|
||||
0xCB, 0xBB, 0x9D, 0x5D, 0xC1, 0x05, 0x9E, 0xD8,
|
||||
0x62, 0x9A, 0x29, 0x2A, 0x36, 0x7C, 0xD5, 0x07,
|
||||
0x91, 0x59, 0x01, 0x5A, 0x30, 0x70, 0xDD, 0x17,
|
||||
0x15, 0x2F, 0xEC, 0xD8, 0xF7, 0x0E, 0x59, 0x39,
|
||||
0x67, 0x33, 0x26, 0x67, 0xFF, 0xC0, 0x0B, 0x31,
|
||||
0x8E, 0xB4, 0x4A, 0x87, 0x68, 0x58, 0x15, 0x11,
|
||||
0xDB, 0x0C, 0x2E, 0x0D, 0x64, 0xF9, 0x8F, 0xA7,
|
||||
0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha384_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha384_ctx->total[0] = 0;
|
||||
sha384_ctx->total[1] = 0;
|
||||
sha384_ctx->total[2] = 0;
|
||||
sha384_ctx->total[3] = 0;
|
||||
memcpy(sha384_ctx->state, init_state_sha384, sizeof(sha384_ctx->state));
|
||||
|
||||
sha384_ctx->hash_type = SL_SE_HASH_SHA384;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA512 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t *sha512_ctx, sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
static const uint8_t init_state_sha512[64] = {
|
||||
0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08,
|
||||
0xBB, 0x67, 0xAE, 0x85, 0x84, 0xCA, 0xA7, 0x3B,
|
||||
0x3C, 0x6E, 0xF3, 0x72, 0xFE, 0x94, 0xF8, 0x2B,
|
||||
0xA5, 0x4F, 0xF5, 0x3A, 0x5F, 0x1D, 0x36, 0xF1,
|
||||
0x51, 0x0E, 0x52, 0x7F, 0xAD, 0xE6, 0x82, 0xD1,
|
||||
0x9B, 0x05, 0x68, 0x8C, 0x2B, 0x3E, 0x6C, 0x1F,
|
||||
0x1F, 0x83, 0xD9, 0xAB, 0xFB, 0x41, 0xBD, 0x6B,
|
||||
0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || sha512_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sha512_ctx->total[0] = 0;
|
||||
sha512_ctx->total[1] = 0;
|
||||
sha512_ctx->total[2] = 0;
|
||||
sha512_ctx->total[3] = 0;
|
||||
memcpy(sha512_ctx->state, init_state_sha512, sizeof(sha512_ctx->state));
|
||||
|
||||
sha512_ctx->hash_type = SL_SE_HASH_SHA512;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a hash stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_starts(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type)
|
||||
{
|
||||
if (cmd_ctx == NULL || hash_type_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
return sl_se_hash_sha1_multipart_starts((sl_se_sha1_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
return sl_se_hash_sha224_multipart_starts((sl_se_sha224_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
return sl_se_hash_sha256_multipart_starts((sl_se_sha256_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
return sl_se_hash_sha384_multipart_starts((sl_se_sha384_multipart_context_t*)
|
||||
hash_type_ctx,
|
||||
cmd_ctx);
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
return sl_se_hash_sha512_multipart_starts((sl_se_sha512_multipart_context_t*)
|
||||
hash_type_ctx, cmd_ctx);
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Feeds an input block into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
static sl_status_t se_cmd_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
uint32_t num_blocks)
|
||||
{
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
uint8_t *state;
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASHUPDATE;
|
||||
size_t state_len, blocksize;
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
state_len = 20;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
state_len = 32;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
state_len = 32;
|
||||
blocksize = 64;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
state_len = 64;
|
||||
blocksize = 128;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
state_len = 64;
|
||||
blocksize = 128;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
size_t ilen = blocksize * num_blocks;
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, ilen);
|
||||
|
||||
sli_se_datatransfer_t data_in = SLI_SE_DATATRANSFER_DEFAULT(input, ilen);
|
||||
sli_se_datatransfer_t iv_in = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
sli_se_datatransfer_t iv_out = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &iv_in);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &data_in);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &iv_out);
|
||||
|
||||
// Execute and wait
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_update(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len)
|
||||
{
|
||||
size_t blocks, fill, left, blocksize, countersize;
|
||||
sl_status_t status;
|
||||
uint8_t *buffer;
|
||||
uint32_t *counter;
|
||||
|
||||
if ( input_len == 0 ) {
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || input == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 64;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 128;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
blocksize = 128;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
countersize = blocksize / 32;
|
||||
left = (counter[0] & (blocksize - 1));
|
||||
fill = blocksize - left;
|
||||
|
||||
counter[0] += input_len;
|
||||
|
||||
// ripple counter
|
||||
if ( counter[0] < input_len ) {
|
||||
counter[1] += 1;
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
for (size_t i = 1; i < (countersize - 1); i++) {
|
||||
if ( counter[i] == 0 ) {
|
||||
counter[i + 1]++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)countersize;
|
||||
#endif
|
||||
}
|
||||
|
||||
// We only support hashing up to 4 GB data
|
||||
// so if anything but counter[0] is set, return NOT_SUPPORTED
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
for (size_t i = 1; i < countersize; i++) {
|
||||
if (counter[i] != 0) {
|
||||
return SL_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( (left > 0) && (input_len >= fill) ) {
|
||||
memcpy( (void *) (buffer + left), input, fill);
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, buffer, 1);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
input += fill;
|
||||
input_len -= fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
if ( input_len >= blocksize ) {
|
||||
blocks = input_len / blocksize;
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, input, blocks);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
input += blocksize * blocks;
|
||||
input_len -= blocksize * blocks;
|
||||
}
|
||||
|
||||
if ( input_len > 0 ) {
|
||||
memcpy( (void *) (buffer + left), input, input_len);
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Finish an ongoing hash streaming computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_multipart_finish(void *hash_type_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len)
|
||||
{
|
||||
sl_status_t status;
|
||||
size_t countersize, blocksize, outputsize;
|
||||
uint8_t *state;
|
||||
uint32_t *counter;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASHFINISH;
|
||||
uint8_t *buffer;
|
||||
size_t state_len;
|
||||
#else
|
||||
size_t last_data_byte, num_pad_bytes;
|
||||
uint8_t msglen[16];
|
||||
// Define padding as largest padding we might need
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
static const unsigned char sha_padding[128] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#else
|
||||
static const unsigned char sha_padding[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || digest_out == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 20;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 20;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 28;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 32;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 32;
|
||||
blocksize = 64;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 32;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 48;
|
||||
blocksize = 128;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
outputsize = 64;
|
||||
blocksize = 128;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
state_len = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( digest_len < outputsize ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
countersize = blocksize / 32;
|
||||
#if defined(SLI_SE_MAJOR_VERSION_TWO)
|
||||
|
||||
// We only support hashing up to 4 GB data
|
||||
// so if anything but counter[0] is set, return NOT_SUPPORTED
|
||||
for (size_t i = 1; i < countersize; i++) {
|
||||
if (counter[i] != 0) {
|
||||
return SL_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
// Remaining bytes in buffer
|
||||
size_t rem_bytes = (counter[0] & (blocksize - 1));
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, rem_bytes);
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, counter[0]);
|
||||
|
||||
sli_se_datatransfer_t in_0 = SLI_SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
sli_se_datatransfer_t in_1 = SLI_SE_DATATRANSFER_DEFAULT(buffer, rem_bytes);
|
||||
sli_se_datatransfer_t out = SLI_SE_DATATRANSFER_DEFAULT(digest_out, outputsize);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &in_0);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &in_1);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &out);
|
||||
|
||||
// Execute and wait
|
||||
status = sli_se_execute_and_wait(cmd_ctx);
|
||||
#else
|
||||
|
||||
/* Convert counter value to bits, and put in big-endian array */
|
||||
uint8_t residual = 0;
|
||||
for (size_t i = 0; i < countersize; i++) {
|
||||
size_t msglen_index = ( (countersize - i) * sizeof(uint32_t) ) - 1;
|
||||
|
||||
msglen[msglen_index - 0] = ((counter[i] << 3) + residual) & 0xFF;
|
||||
msglen[msglen_index - 1] = (counter[i] >> 5) & 0xFF;
|
||||
msglen[msglen_index - 2] = (counter[i] >> 13) & 0xFF;
|
||||
msglen[msglen_index - 3] = (counter[i] >> 21) & 0xFF;
|
||||
|
||||
residual = (counter[i] >> 29) & 0xFF;
|
||||
}
|
||||
|
||||
last_data_byte = (counter[0] & (blocksize - 1) );
|
||||
num_pad_bytes = (last_data_byte < (blocksize - (countersize * 4)) )
|
||||
? ( (blocksize - (countersize * 4)) - last_data_byte)
|
||||
: ( ((2 * blocksize) - (countersize * 4)) - last_data_byte);
|
||||
|
||||
status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, sha_padding, num_pad_bytes);
|
||||
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, msglen, countersize * 4);
|
||||
}
|
||||
|
||||
if (status == SL_STATUS_OK) {
|
||||
memcpy(digest_out, state, outputsize);
|
||||
}
|
||||
#endif // SLI_SE_MAJOR_VERSION_TWO
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Produce a message digest (a hash block) using the input data.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
const uint8_t *message,
|
||||
unsigned int message_size,
|
||||
uint8_t* digest,
|
||||
size_t digest_len)
|
||||
{
|
||||
if (cmd_ctx == NULL
|
||||
|| digest == NULL
|
||||
|| (message == NULL
|
||||
&& message_size != 0)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
uint32_t command_word = SLI_SE_COMMAND_HASH;
|
||||
uint32_t digest_size = 0;
|
||||
|
||||
switch (hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
digest_size = 20;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
digest_size = 28;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
digest_size = 32;
|
||||
break;
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
digest_size = 48;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
digest_size = 64;
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ( digest_len < digest_size ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_size);
|
||||
|
||||
sli_se_datatransfer_t data_in = SLI_SE_DATATRANSFER_DEFAULT(message, message_size);
|
||||
sli_se_datatransfer_t data_out = SLI_SE_DATATRANSFER_DEFAULT(digest, digest_size);
|
||||
|
||||
sli_se_mailbox_command_add_input(se_cmd, &data_in);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &data_out);
|
||||
|
||||
// Execute and wait
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
/***************************************************************************//**
|
||||
* ECC signature generation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
unsigned char *signature,
|
||||
size_t signature_len)
|
||||
{
|
||||
if (cmd_ctx == NULL || key == NULL || signature == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if ( message == NULL && message_len != 0 ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_SIGN;
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
command_word = SLI_SE_COMMAND_EDDSA_SIGN;
|
||||
} else {
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup SE command and parameters
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
// Add key parameters to command
|
||||
sli_add_key_parameters(cmd_ctx, key, status);
|
||||
// Message size (number of bytes)
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_len);
|
||||
// Add key metadata block to command
|
||||
sli_add_key_metadata(cmd_ctx, key, status);
|
||||
// Add key input block to command
|
||||
sli_add_key_input(cmd_ctx, key, status);
|
||||
|
||||
sli_se_datatransfer_t message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
|
||||
// EdDSA requires the message twice
|
||||
sli_se_datatransfer_t repeated_message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &repeated_message_buffer);
|
||||
}
|
||||
|
||||
sli_se_datatransfer_t signature_buffer = SLI_SE_DATATRANSFER_DEFAULT(signature, signature_len);
|
||||
sli_se_mailbox_command_add_output(se_cmd, &signature_buffer);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* ECC signature verification.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_hash_type_t hash_alg,
|
||||
bool hashed_message,
|
||||
const unsigned char *message,
|
||||
size_t message_len,
|
||||
const unsigned char *signature,
|
||||
size_t signature_len)
|
||||
{
|
||||
if (cmd_ctx == NULL || key == NULL || (message == NULL && message_len != 0) || signature == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
// Key needs to contain public key in order to verify signatures
|
||||
if (!(key->flags & SL_SE_KEY_FLAG_ASYMMETRIC_BUFFER_HAS_PUBLIC_KEY)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
sli_se_mailbox_command_t *se_cmd = &cmd_ctx->command;
|
||||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_VERIFY;
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
command_word = SLI_SE_COMMAND_EDDSA_VERIFY;
|
||||
} else {
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup SE command and parameters
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
// Add key parameters to command
|
||||
sli_add_key_parameters(cmd_ctx, key, status);
|
||||
// Message size (number of bytes)
|
||||
sli_se_mailbox_command_add_parameter(se_cmd, message_len);
|
||||
// Add key metadata block to command
|
||||
sli_add_key_metadata(cmd_ctx, key, status);
|
||||
// Add key input block to command
|
||||
sli_add_key_input(cmd_ctx, key, status);
|
||||
|
||||
sli_se_datatransfer_t message_buffer = SLI_SE_DATATRANSFER_DEFAULT(message,
|
||||
message_len);
|
||||
sli_se_datatransfer_t signature_buffer = SLI_SE_DATATRANSFER_DEFAULT(signature,
|
||||
signature_len);
|
||||
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &signature_buffer);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
} else {
|
||||
sli_se_mailbox_command_add_input(se_cmd, &message_buffer);
|
||||
sli_se_mailbox_command_add_input(se_cmd, &signature_buffer);
|
||||
}
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SLI_MAILBOX_COMMAND_SUPPORTED)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,617 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief SE Mailbox API
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2024 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "sli_se_manager_mailbox.h"
|
||||
|
||||
#if defined(SLI_SE_MAILBOX_HOST_SYSTEM) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
#include "sl_core.h"
|
||||
#endif
|
||||
|
||||
#include "sl_assert.h"
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup se
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/// Signal that OTP version is incorporated into the status field of the output
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_SET (1 << 21)
|
||||
/// Mask defining the region of the status field that contains the OTP version
|
||||
/// number.
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_MASK (0xFF000000UL)
|
||||
/// Shift to insert a number into the otp version part of the status field
|
||||
#define SE_VSE_REPLY_STATUS_OTP_VERSION_SHIFT (24)
|
||||
|
||||
/* Size of VSE Mailbox instance.
|
||||
There are two instances, input and output. */
|
||||
#define ROOT_MAILBOX_SIZE (512UL)
|
||||
|
||||
/* Base addresses of the VSE Input and Output Mailbox data structures.
|
||||
(Must be stored in a RAM area which is not used by the VSE)
|
||||
We use the upper 1KB of FRC RAM for the VSE mailboxes. */
|
||||
#define ROOT_MAILBOX_OUTPUT_S_BASE (RDMEM_FRCRAM_S_MEM_END + 1 - ROOT_MAILBOX_SIZE)
|
||||
#define ROOT_MAILBOX_INPUT_S_BASE (ROOT_MAILBOX_OUTPUT_S_BASE - ROOT_MAILBOX_SIZE)
|
||||
|
||||
// SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S is defined in sl_trustzone_secure_config.h
|
||||
#if ((defined(SL_TRUSTZONE_SECURE) && !defined(SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S)) \
|
||||
|| (defined(SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S) && SL_TRUSTZONE_PERIPHERAL_AHBRADIO_S))
|
||||
|
||||
#define RDMEM_FRCRAM_MEM_BASE RDMEM_FRCRAM_S_MEM_BASE
|
||||
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE SYSCFG->ROOTDATA1;
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE_EXPECTED ROOT_MAILBOX_OUTPUT_S_BASE
|
||||
#else
|
||||
#define RDMEM_FRCRAM_MEM_BASE RDMEM_FRCRAM_NS_MEM_BASE
|
||||
|
||||
// VSE will always output the secure address, if NS is desired, caculate the NS address.
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE (SYSCFG->ROOTDATA1 - RDMEM_FRCRAM_S_MEM_BASE + RDMEM_FRCRAM_NS_MEM_BASE);
|
||||
#define ROOT_MAILBOX_OUTPUT_BASE_EXPECTED (RDMEM_FRCRAM_NS_MEM_END + 1 - ROOT_MAILBOX_SIZE)
|
||||
#endif
|
||||
#define ROOT_MAILBOX_INPUT_BASE (ROOT_MAILBOX_OUTPUT_BASE_EXPECTED - ROOT_MAILBOX_SIZE)
|
||||
|
||||
/* Position of parameter number field in VSE Input Mailbox LENGTH field.*/
|
||||
#define ROOT_MB_LENGTH_PARAM_NUM_SHIFT (24)
|
||||
|
||||
/* Done flag indicating that the VSE Mailbox handler has completed
|
||||
processing the mailbox command. */
|
||||
#define ROOT_MB_DONE (1 << 23)
|
||||
|
||||
/* VSE Configuration Status bits mask */
|
||||
#define ROOT_MB_OUTPUT_STATUS_CONFIG_BITS_MASK (0xFFFF)
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** TYPEDEFS ***********************************
|
||||
******************************************************************************/
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
// VSE Input Mailbox structure
|
||||
typedef struct {
|
||||
volatile uint32_t magic;
|
||||
volatile uint32_t command;
|
||||
volatile uint32_t length;
|
||||
volatile uint32_t data[0];
|
||||
} root_mailbox_input_t;
|
||||
|
||||
// VSE Output Mailbox structure
|
||||
typedef struct {
|
||||
volatile uint32_t magic;
|
||||
volatile uint32_t version;
|
||||
volatile uint32_t status;
|
||||
volatile uint32_t command;
|
||||
volatile uint32_t length;
|
||||
volatile uint32_t data[0];
|
||||
} root_mailbox_output_t;
|
||||
/** @endcond */
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/*******************************************************************************
|
||||
************************** STATIC FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Write to FIFO
|
||||
*
|
||||
* @param value
|
||||
* Value to write to FIFO
|
||||
******************************************************************************/
|
||||
#if defined(_SEMAILBOX_FIFO_RESETVALUE)
|
||||
__STATIC_INLINE void write_to_fifo(uint32_t value)
|
||||
{
|
||||
SEMAILBOX_HOST->FIFO = value;
|
||||
}
|
||||
#else
|
||||
__STATIC_INLINE void write_to_fifo(uint32_t value)
|
||||
{
|
||||
SEMAILBOX_HOST->FIFO[0].DATA = value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Return a pointer to the root mailbox output
|
||||
*
|
||||
* @return root_mailbox_output_t pointer
|
||||
******************************************************************************/
|
||||
static root_mailbox_output_t* get_root_mailbox_output(void)
|
||||
{
|
||||
// Setup pointer to the VSE Output Mailbox data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
bool sys_cfg_clk_enabled = ((CMU->CLKEN0 & CMU_CLKEN0_SYSCFG) != 0);
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
|
||||
root_mailbox_output_t *mailbox_output = (root_mailbox_output_t *) ROOT_MAILBOX_OUTPUT_BASE;
|
||||
if (!sys_cfg_clk_enabled) {
|
||||
CMU->CLKEN0_CLR = CMU_CLKEN0_SYSCFG;
|
||||
}
|
||||
return mailbox_output;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the running command has completed.
|
||||
*
|
||||
* @details
|
||||
* This function polls the SE-to-host mailbox interrupt flag.
|
||||
*
|
||||
* @return True if a command has completed and the result is available
|
||||
******************************************************************************/
|
||||
static bool vse_is_command_completed(root_mailbox_output_t *root_mailbox_output)
|
||||
{
|
||||
// First verify that the response is ok
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check status MB_DONE flag of the mailbox
|
||||
return ((root_mailbox_output->status & ROOT_MB_DONE) == ROOT_MB_DONE);
|
||||
}
|
||||
#endif // SEMAILBOX_PRESENT
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add input data to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_input(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data)
|
||||
{
|
||||
if (command->data_in == NULL) {
|
||||
command->data_in = data;
|
||||
} else {
|
||||
sli_se_datatransfer_t *next = command->data_in;
|
||||
while (next->next != (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
next = (sli_se_datatransfer_t*)next->next;
|
||||
}
|
||||
next->next = data;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add output data to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_output(sli_se_mailbox_command_t *command, sli_se_datatransfer_t *data)
|
||||
{
|
||||
if (command->data_out == NULL) {
|
||||
command->data_out = data;
|
||||
} else {
|
||||
sli_se_datatransfer_t *next = command->data_out;
|
||||
while (next->next != (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
next = (sli_se_datatransfer_t*)next->next;
|
||||
}
|
||||
next->next = data;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Add a parameter to a mailbox command
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_command_add_parameter(sli_se_mailbox_command_t *command, uint32_t parameter)
|
||||
{
|
||||
if (command->num_parameters >= SLI_SE_COMMAND_MAX_PARAMETERS) {
|
||||
EFM_ASSERT(command->num_parameters < SLI_SE_COMMAND_MAX_PARAMETERS);
|
||||
return;
|
||||
}
|
||||
|
||||
command->parameters[command->num_parameters] = parameter;
|
||||
command->num_parameters += 1;
|
||||
}
|
||||
|
||||
#if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Execute a command on the SE by writing the command to SEMAILBOX->FIFO
|
||||
******************************************************************************/
|
||||
void sli_se_mailbox_execute_command(sli_se_mailbox_command_t *command)
|
||||
{
|
||||
// Don't overflow our struct
|
||||
if (command->num_parameters > SLI_SE_COMMAND_MAX_PARAMETERS) {
|
||||
EFM_ASSERT(command->num_parameters <= SLI_SE_COMMAND_MAX_PARAMETERS);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT)
|
||||
|
||||
// Wait for room available in the mailbox
|
||||
while (!(SEMAILBOX_HOST->TX_STATUS & SEMAILBOX_TX_STATUS_TXINT)) {
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES == 3)
|
||||
// Write header (including message size) to start transaction
|
||||
SEMAILBOX_HOST->TX_HEADER = sizeof(uint32_t) * (5 + command->num_parameters);
|
||||
// Write a 32-bit word to the FIFO ( potentially used as command handle )
|
||||
write_to_fifo(0);
|
||||
#else
|
||||
// Write header (including message size) to start transaction
|
||||
SEMAILBOX_HOST->TX_HEADER = sizeof(uint32_t) * (4 + command->num_parameters);
|
||||
#endif
|
||||
|
||||
// Write command into FIFO
|
||||
write_to_fifo(command->command);
|
||||
|
||||
// Write DMA descriptors into FIFO
|
||||
write_to_fifo((uint32_t)command->data_in);
|
||||
write_to_fifo((uint32_t)command->data_out);
|
||||
|
||||
// Write applicable parameters into FIFO
|
||||
for (size_t i = 0; i < command->num_parameters; i++) {
|
||||
write_to_fifo(command->parameters[i]);
|
||||
}
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
// Prepare the VSE Mailbox within a critical section to prevent
|
||||
// the process from getting interrupted. At this point, the only option
|
||||
// we have is to go through a reset, so it is safe to enter the critical section.
|
||||
(void)CORE_EnterCritical();
|
||||
|
||||
// Setup pointer to the VSE Mailbox Input data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
root_mailbox_input_t *mailbox_input = (root_mailbox_input_t*)ROOT_MAILBOX_INPUT_BASE;
|
||||
uint32_t *mailbox_data;
|
||||
unsigned int mailbox_dataLen, inDataLen, i;
|
||||
sli_se_datatransfer_t *inDataDesc;
|
||||
uint32_t *inData;
|
||||
uint32_t checksum;
|
||||
bool sysCfgClkWasEnabled = ((CMU->CLKEN0 & CMU_CLKEN0_SYSCFG) != 0);
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_SYSCFG;
|
||||
|
||||
// Store the secure memory base addresses for VSE to be able to read from the address
|
||||
// Set base of Mailbox Input data structure in SYSCFG register in order
|
||||
// for VSE to find it.
|
||||
SYSCFG->ROOTDATA0 = ROOT_MAILBOX_INPUT_S_BASE;
|
||||
// Set base of Mailbox Output data structure in SYSCFG register in order
|
||||
// for VSE to know where to write output data.
|
||||
// Write command into FIFO
|
||||
SYSCFG->ROOTDATA1 = ROOT_MAILBOX_OUTPUT_S_BASE;
|
||||
|
||||
if (!sysCfgClkWasEnabled) {
|
||||
CMU->CLKEN0_CLR = CMU_CLKEN0_SYSCFG;
|
||||
}
|
||||
|
||||
mailbox_input->magic = SLI_SE_RESPONSE_MAILBOX_VALID;
|
||||
mailbox_input->command = command->command;
|
||||
|
||||
// Write applicable parameters into Mailbox DATA array
|
||||
mailbox_data = (uint32_t*) mailbox_input->data;
|
||||
for (mailbox_dataLen = 0; mailbox_dataLen < command->num_parameters; mailbox_dataLen++) {
|
||||
mailbox_data[mailbox_dataLen] = command->parameters[mailbox_dataLen];
|
||||
}
|
||||
|
||||
// Write input data into Mailbox DATA array
|
||||
inDataLen = 0;
|
||||
for (inDataDesc = command->data_in; inDataDesc; inDataDesc = (sli_se_datatransfer_t*) inDataDesc->next) {
|
||||
inData = (uint32_t*) inDataDesc->data;
|
||||
for (i = 0; i < (inDataDesc->length & SLI_SE_DATATRANSFER_LENGTH_MASK) / sizeof(uint32_t); i++) {
|
||||
// Make sure we do not overflow the input mailbox.
|
||||
EFM_ASSERT(mailbox_dataLen < ROOT_MAILBOX_SIZE);
|
||||
mailbox_data[mailbox_dataLen++] = inData[i];
|
||||
inDataLen++;
|
||||
}
|
||||
if (inDataDesc->next == (void*)SLI_SE_DATATRANSFER_STOP) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Write number of parameters and data words to 'length' field of mailbox.
|
||||
mailbox_input->length =
|
||||
inDataLen | (command->num_parameters << ROOT_MB_LENGTH_PARAM_NUM_SHIFT);
|
||||
|
||||
// Calculate checksum using bitwise XOR over the all words in the mailbox
|
||||
// data structure, minus the CHECKSUM word (32bit = 4bytes ) at the end.
|
||||
checksum = mailbox_input->magic;
|
||||
checksum ^= mailbox_input->command;
|
||||
checksum ^= mailbox_input->length;
|
||||
for (i = 0; i < mailbox_dataLen; i++) {
|
||||
checksum ^= mailbox_data[i];
|
||||
}
|
||||
|
||||
// Finally, write the calculated checksum to mailbox checksum field
|
||||
mailbox_data[mailbox_dataLen] = checksum;
|
||||
|
||||
__NVIC_SystemReset();
|
||||
|
||||
#endif // #if defined(SEMAILBOX_PRESENT)
|
||||
}
|
||||
#endif // #if !defined(SLI_SE_MAILBOX_HOST_SYSTEM)
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current SE version
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_version(uint32_t *version)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
if (version == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Return the 'version' from the Output Mailbox
|
||||
*version = root_mailbox_output->version;
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get VSE configuration and status bits
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_cfg_status(uint32_t *cfg_status)
|
||||
{
|
||||
if (cfg_status == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Return the configuration status bits
|
||||
*cfg_status = root_mailbox_output->status & ROOT_MB_OUTPUT_STATUS_CONFIG_BITS_MASK;
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the version number of the OTP from the status field of the output
|
||||
* mailbox
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_get_otp_version(uint32_t *otp_version)
|
||||
{
|
||||
if (otp_version == NULL) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the response is ok.
|
||||
if (!sli_vse_mailbox_is_output_valid()) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
bool is_otp_version_set = root_mailbox_output->status & SE_VSE_REPLY_STATUS_OTP_VERSION_SET;
|
||||
if (is_otp_version_set) {
|
||||
// Return the OTP version from the status field.
|
||||
*otp_version = (root_mailbox_output->status & SE_VSE_REPLY_STATUS_OTP_VERSION_MASK) >> SE_VSE_REPLY_STATUS_OTP_VERSION_SHIFT;
|
||||
} else {
|
||||
return SLI_SE_RESPONSE_INVALID_COMMAND;
|
||||
}
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the previously executed command.
|
||||
******************************************************************************/
|
||||
uint32_t sli_vse_mailbox_read_executed_command(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
return root_mailbox_output->command;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the status of the previously executed command.
|
||||
*
|
||||
* @details
|
||||
* This function reads the status of the previously executed command.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes:
|
||||
* SLI_SE_RESPONSE_OK when the command was executed successfully or a signature
|
||||
* was successfully verified,
|
||||
* SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command, e.g.
|
||||
* because of conflicting Secure/Non-Secure memory accesses,
|
||||
* SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* SLI_SE_RESPONSE_MAILBOX_INVALID when the mailbox content is invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_se_mailbox_read_response(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
return (sli_se_mailbox_response_t)(root_mailbox_output->status & SLI_SE_RESPONSE_MASK);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Acknowledge and get status and output data of a completed command.
|
||||
*
|
||||
* @details
|
||||
* This function acknowledges and gets the status and output data of a
|
||||
* completed mailbox command.
|
||||
* The mailbox command is acknowledged by inverting all bits in the checksum
|
||||
* (XOR with 0xFFFFFFFF).
|
||||
* The output data is copied into the linked list of output buffers pointed
|
||||
* to in the given command data structure.
|
||||
*
|
||||
* @param[in] command
|
||||
* Pointer to an SE command structure.
|
||||
*
|
||||
* @return
|
||||
* One of the SE_RESPONSE return codes.
|
||||
* @retval SLI_SE_RESPONSE_OK when the command was executed successfully or a
|
||||
* signature was successfully verified,
|
||||
* @retval SLI_SE_RESPONSE_INVALID_COMMAND when the command ID was not recognized,
|
||||
* @retval SE_RESPONSE_AUTHORIZATION_ERROR when the command is not authorized,
|
||||
* @retval SE_RESPONSE_INVALID_SIGNATURE when signature verification failed,
|
||||
* @retval SE_RESPONSE_BUS_ERROR when a bus error was thrown during the command,
|
||||
* e.g. because of conflicting Secure/Non-Secure
|
||||
* memory accesses,
|
||||
* @retval SE_RESPONSE_CRYPTO_ERROR on an internal SE failure, or
|
||||
* @retval SLI_SE_RESPONSE_INVALID_PARAMETER when an invalid parameter was passed
|
||||
* @retval SLI_SE_RESPONSE_MAILBOX_INVALID when mailbox command not done or invalid
|
||||
******************************************************************************/
|
||||
sli_se_mailbox_response_t sli_vse_mailbox_ack_command(sli_se_mailbox_command_t *command)
|
||||
{
|
||||
// Setup pointer to the VSE Output Mailbox data structure
|
||||
// (must be stored in a RAM area which is not used by the VSE)
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
|
||||
uint32_t *mbData = (uint32_t*) root_mailbox_output->data;
|
||||
sli_se_datatransfer_t *outDataDesc = command->data_out;
|
||||
unsigned int outDataLen, outDataCnt, i, outDescLen;
|
||||
uint32_t *outData;
|
||||
|
||||
// First verify that the Output Mailbox includes a valid response.
|
||||
if (!vse_is_command_completed(root_mailbox_output)) {
|
||||
return SLI_SE_RESPONSE_MAILBOX_INVALID;
|
||||
}
|
||||
|
||||
// Get output data length
|
||||
outDataLen = root_mailbox_output->length;
|
||||
|
||||
// Acknowledge the output mailbox response by invalidating checksum
|
||||
mbData[outDataLen] ^= 0xFFFFFFFFUL;
|
||||
|
||||
// Check command status code
|
||||
if ((root_mailbox_output->status & SLI_SE_RESPONSE_MASK) != SLI_SE_RESPONSE_OK) {
|
||||
return root_mailbox_output->status & SLI_SE_RESPONSE_MASK;
|
||||
}
|
||||
|
||||
// Copy data from the Output Mailbox to the linked list of output
|
||||
// buffers provided by the user
|
||||
outDataCnt = 0;
|
||||
while (outDataDesc && (outDataCnt < outDataLen)) {
|
||||
outData = (uint32_t*) outDataDesc->data;
|
||||
outDescLen =
|
||||
(outDataDesc->length & SLI_SE_DATATRANSFER_LENGTH_MASK) / sizeof(uint32_t);
|
||||
for (i = 0; (i < outDescLen) && (outDataCnt < outDataLen); i++) {
|
||||
outData[i] = mbData[outDataCnt++];
|
||||
}
|
||||
// If we have reached the end of a buffer, go to next buffer descriptor
|
||||
if (i == outDescLen) {
|
||||
outDataDesc = (sli_se_datatransfer_t*)
|
||||
((uint32_t)outDataDesc->next & ~SLI_SE_DATATRANSFER_STOP);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the output data list is too small to copy all output data in
|
||||
// mailbox.
|
||||
if ((outDataDesc == 0) && (outDataCnt < outDataLen)) {
|
||||
return SLI_SE_RESPONSE_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return SLI_SE_RESPONSE_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check whether the VSE Output Mailbox is valid.
|
||||
*
|
||||
* @return True if the VSE Output Mailbox is valid (magic and checksum OK)
|
||||
******************************************************************************/
|
||||
bool sli_vse_mailbox_is_output_valid(void)
|
||||
{
|
||||
root_mailbox_output_t *root_mailbox_output = get_root_mailbox_output();
|
||||
uint32_t *mb_ptr32 = (uint32_t*) root_mailbox_output;
|
||||
uint32_t checksum;
|
||||
unsigned int mb_len, cnt;
|
||||
|
||||
if ((uint32_t)root_mailbox_output > ROOT_MAILBOX_OUTPUT_BASE_EXPECTED
|
||||
|| (uint32_t)root_mailbox_output < RDMEM_FRCRAM_MEM_BASE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify magic word of mailbox
|
||||
if (root_mailbox_output->magic != SLI_SE_RESPONSE_MAILBOX_VALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get length of mailbox
|
||||
mb_len = sizeof(root_mailbox_output_t) / sizeof(uint32_t) + root_mailbox_output->length;
|
||||
if (mb_len >= ROOT_MAILBOX_SIZE) {
|
||||
return false;
|
||||
}
|
||||
// Calculate checksum using bitwise XOR over all words in the mailbox
|
||||
// data structure, minus the CHECKSUM word at the end.
|
||||
for (checksum = 0, cnt = 0; cnt < mb_len; cnt++) {
|
||||
checksum ^= mb_ptr32[cnt];
|
||||
}
|
||||
|
||||
// Verify that the calculated checksum is equal to the mailbox checksum.
|
||||
return (mb_ptr32[mb_len] == checksum);
|
||||
}
|
||||
|
||||
#endif // #if defined(CRYPTOACC_PRESENT)
|
||||
|
||||
/** @} (end addtogroup se) */
|
||||
|
||||
#endif /* defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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) */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user