modules: hal_silabs: adaptations for BLE support in Zephyr
Origin: Silicon Labs Gecko SDK URL: https://github.com/SiliconLabs/gecko_sdk Version: 4.2.0 Purpose: Adding RAIL support. License: Zlib Maintained-by: External Signed-off-by: Pawel Czarnecki <pczarnecki@antmicro.com>
This commit is contained in:
parent
5ea92d1c74
commit
793db3cb74
|
@ -0,0 +1,2 @@
|
|||
zephyr/blobs/gecko
|
||||
tags
|
|
@ -1 +1,2 @@
|
|||
add_subdirectory_ifdef(CONFIG_HAS_SILABS_GECKO gecko)
|
||||
add_subdirectory_ifdef(CONFIG_HAS_SILABS_GECKO zephyr)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
# Copyright (c) 2017, Christian Taedcke
|
||||
# Copyright (c) 2021, Safran Passenger Innovations Germany GmbH
|
||||
# Copyright (c) 2022, Antmicro <www.antmicro.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
@ -27,24 +28,32 @@ endif()
|
|||
|
||||
zephyr_include_directories(
|
||||
Device/SiliconLabs/${SILABS_GECKO_DEVICE}/Include
|
||||
emlib/inc
|
||||
service/sleeptimer/src
|
||||
service/sleeptimer/inc
|
||||
service/sleeptimer/config
|
||||
service/power_manager/src
|
||||
service/power_manager/inc
|
||||
service/power_manager/config
|
||||
service/hfxo_manager/src
|
||||
service/hfxo_manager/inc
|
||||
service/hfxo_manager/config
|
||||
board/config/${SILABS_GECKO_BOARD}
|
||||
board/inc
|
||||
common/inc
|
||||
service/device_init/inc
|
||||
emlib/inc
|
||||
platform/radio/rail_lib/chip/efr32/efr32xg2x
|
||||
platform/radio/rail_lib/common
|
||||
platform/radio/rail_lib/plugin/pa-conversions
|
||||
platform/radio/rail_lib/plugin/pa-conversions/efr32xg22/config
|
||||
protocol/bluetooth//bgstack/ll/inc
|
||||
service/device_init/config/s2
|
||||
service/device_init/config/s2/${PRODUCT_NO}
|
||||
service/device_init/inc
|
||||
service/hfxo_manager/config
|
||||
service/hfxo_manager/inc
|
||||
service/hfxo_manager/src
|
||||
service/power_manager/config
|
||||
service/power_manager/inc
|
||||
service/power_manager/src
|
||||
service/sleeptimer/config
|
||||
service/sleeptimer/inc
|
||||
service/sleeptimer/src
|
||||
util/third_party/crypto/sl_component/sl_protocol_crypto/src
|
||||
)
|
||||
|
||||
foreach(root ${BOARD_ROOT})
|
||||
message( "ROOT: "${root} )
|
||||
message("ROOT: " ${root})
|
||||
if(IS_DIRECTORY "${root}/boards/arm/${CONFIG_BOARD}")
|
||||
zephyr_include_directories(${root}/boards/arm/${CONFIG_BOARD})
|
||||
endif()
|
||||
|
@ -107,3 +116,31 @@ zephyr_sources_ifdef(CONFIG_SOC_SERIES_EFM32JG12B Device/SiliconLabs/EFM32JG12B
|
|||
zephyr_sources_ifdef(CONFIG_SOC_SERIES_EFR32MG21 Device/SiliconLabs/EFR32MG21/Source/system_efr32mg21.c)
|
||||
zephyr_sources_ifdef(CONFIG_SOC_SERIES_EFM32PG1B Device/SiliconLabs/EFM32PG1B/Source/system_efm32pg1b.c)
|
||||
zephyr_sources_ifdef(CONFIG_SOC_SERIES_EFR32MG24 Device/SiliconLabs/EFR32MG24/Source/system_efr32mg24.c)
|
||||
|
||||
function(add_prebuilt_library lib_name prebuilt_path)
|
||||
add_library(${lib_name} STATIC IMPORTED GLOBAL)
|
||||
set_target_properties(${lib_name} PROPERTIES
|
||||
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../zephyr/blobs/${prebuilt_path}
|
||||
)
|
||||
zephyr_link_libraries(${lib_name})
|
||||
endfunction()
|
||||
|
||||
if(CONFIG_BT_SILABS_HCI)
|
||||
# rail
|
||||
zephyr_sources(platform/radio/rail_lib/plugin/pa-conversions/pa_conversions_efr32.c)
|
||||
|
||||
# sl_protocol_crypto
|
||||
zephyr_sources(util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_crypto.c)
|
||||
zephyr_sources(util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_radioaes_management.c)
|
||||
zephyr_sources(util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_radioaes.c)
|
||||
|
||||
# prebuilt libs
|
||||
add_prebuilt_library(liblinklayer gecko/protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_${CONFIG_SOC_SERIES}_gcc_release.a)
|
||||
add_prebuilt_library(libbgcommon gecko/protocol/bluetooth/bgcommon/lib/libbgcommon_${CONFIG_SOC_SERIES}_gcc_release.a)
|
||||
add_prebuilt_library(librail gecko/platform/radio/rail_lib//autogen/librail_release/librail_${CONFIG_SOC_SERIES}_gcc_release.a)
|
||||
|
||||
# link mbedTLS
|
||||
if(CONFIG_MBEDTLS)
|
||||
zephyr_link_libraries(mbedTLS)
|
||||
endif()
|
||||
endif()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,405 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Definition of error codes that occur in rail for use in
|
||||
* RAILCb_AssertFailed. This file is purely informational and optional -
|
||||
* it need not be included even if rail_assert libraries are included.
|
||||
*******************************************************************************
|
||||
* # 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 __RAIL_ASSERT_ERROR_CODES_H__
|
||||
#define __RAIL_ASSERT_ERROR_CODES_H__
|
||||
|
||||
#include "rail_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup Assertions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumeration of all possible error codes from RAIL_ASSERT
|
||||
*/
|
||||
RAIL_ENUM_GENERIC(RAIL_AssertErrorCodes_t, uint32_t)
|
||||
{
|
||||
/** Appended info missing from Rx packet. */
|
||||
RAIL_ASSERT_FAILED_APPENDED_INFO_MISSING = 0,
|
||||
/** Receive FIFO too small for IR calibration. */
|
||||
RAIL_ASSERT_FAILED_RX_FIFO_BYTES = 1,
|
||||
/** Error reading back packet payload. */
|
||||
RAIL_ASSERT_FAILED_RX_FIFO_ZERO_BYTES_READ = 2,
|
||||
/** Receive fifo entry has invalid status. */
|
||||
RAIL_ASSERT_FAILED_ILLEGAL_RXLEN_ENTRY_STATUS = 3,
|
||||
/** Receive fifo entry bad packet length. */
|
||||
RAIL_ASSERT_FAILED_BAD_PACKET_LENGTH = 4,
|
||||
/** Unable to configure radio for IR calibration. */
|
||||
RAIL_ASSERT_FAILED_SYNTH_DIVCTRL_ENUM_CONVERSION_ERROR = 5,
|
||||
/** Reached unexpected state while handling Rx fifo events. */
|
||||
RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RX_FIFO = 6,
|
||||
/** Reached unexpected state while handling RXLEN fifo events. */
|
||||
RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RXLEN_FIFO = 7,
|
||||
/** Reached unexpected state while handling Tx fifo events. */
|
||||
RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TX_FIFO = 8,
|
||||
/** Reached unexpected state while handling Tx ACK fifo events. */
|
||||
RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TXACK_FIFO = 9,
|
||||
/** No memory to store receive packet. */
|
||||
RAIL_ASSERT_FAILED_PBUFFER_NOT_DEFINED = 10,
|
||||
/** Packet length longer than the receive FIFO size. */
|
||||
RAIL_ASSERT_FAILED_INSUFFICIENT_BYTES_IN_RX_PACKET = 11,
|
||||
/** Invalid radio clock prescaler. */
|
||||
RAIL_ASSERT_FAILED_CLOCK_PRESCALER = 12,
|
||||
/** Error synchronizing the RAIL timebase after sleep. */
|
||||
RAIL_ASSERT_FAILED_RTCC_POST_WAKEUP = 13,
|
||||
/** VCO frequency outside supported range. */
|
||||
RAIL_ASSERT_FAILED_SYNTH_VCO_FREQUENCY = 14,
|
||||
/** Radio active while changing channels. */
|
||||
RAIL_ASSERT_FAILED_RAC_STATE = 15,
|
||||
/** Invalid Synth VCOCTRL field calculation. */
|
||||
RAIL_ASSERT_FAILED_SYNTH_INVALID_VCOCTRL = 16,
|
||||
/** Nested attempt to lock the sequencer. */
|
||||
RAIL_ASSERT_FAILED_NESTED_SEQUENCER_LOCK = 17,
|
||||
/** RSSI averaging enabled without a valid callback. */
|
||||
RAIL_ASSERT_FAILED_RSSI_AVERAGE_DONE = 18,
|
||||
/** Invalid dynamic frame length setting provided (dflBits). */
|
||||
RAIL_ASSERT_FAILED_DFL_BITS_SIZE = 19,
|
||||
/** Unable to seed radio pseudo random number generator. */
|
||||
RAIL_ASSERT_FAILED_PROTIMER_RANDOM_SEED = 20,
|
||||
/** Timeout exceeds EFR32XG1 register size. */
|
||||
RAIL_ASSERT_FAILED_EFR32XG1_REGISTER_SIZE = 21,
|
||||
/** Invalid timer channel specified. */
|
||||
RAIL_ASSERT_FAILED_PROTIMER_CHANNEL = 22,
|
||||
/** Timer value larger than RAIL timebase. */
|
||||
RAIL_ASSERT_FAILED_TIMER_REQUIRES_WRAP = 23,
|
||||
/** LBT config exceeds EFR32XG1 register size. */
|
||||
RAIL_ASSERT_FAILED_BASECNTTOP = 24,
|
||||
/** Deprecated CSMA/LBT retry callback unexpectedly called. */
|
||||
RAIL_ASSERT_FAILED_DEPRECATED_LBTRETRY = 25,
|
||||
/** Could not synchronize RAIL timebase with the RTC. */
|
||||
RAIL_ASSERT_FAILED_RTCC_SYNC_MISSED = 26,
|
||||
/** Clock source not ready. */
|
||||
RAIL_ASSERT_FAILED_CLOCK_SOURCE_NOT_READY = 27,
|
||||
/** Attempted to set RAIL timings to invalid value. */
|
||||
RAIL_ASSERT_FAILED_TIMINGS_INVALID = 28,
|
||||
/** NULL was supplied as a RAIL_Handle_t argument. */
|
||||
RAIL_ASSERT_NULL_HANDLE = 29,
|
||||
/** Scheduled timer not running. */
|
||||
RAIL_ASSERT_FAILED_SCHED_TIMER_NOT_RUNNING = 30,
|
||||
/** API improperly called while protocol inactive. */
|
||||
RAIL_ASSERT_FAILED_NO_ACTIVE_CONFIG = 31,
|
||||
/** No active handle after switch. */
|
||||
RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SWITCH = 32,
|
||||
/** Reserved for future use. */
|
||||
RAIL_ASSERT_FAILED_RESERVED33 = 33,
|
||||
/** No active handle for scheduled rx. */
|
||||
RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SCHEDRX = 34,
|
||||
/** Invalid handle for scheduled tx. */
|
||||
RAIL_ASSERT_FAILED_INVALID_HANDLE_SCHEDTX = 35,
|
||||
/** Inactive handle for scheduled tx. */
|
||||
RAIL_ASSERT_FAILED_INACTIVE_HANDLE_SCHEDTX = 36,
|
||||
/** Invalid config index to switch to. */
|
||||
RAIL_ASSERT_FAILED_CONFIG_INDEX_INVALID = 37,
|
||||
/** No active handle for single protocol. */
|
||||
RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SINGLEPROTOCOL = 38,
|
||||
/** This function is deprecated and must not be called. */
|
||||
RAIL_ASSERT_DEPRECATED_FUNCTION = 39,
|
||||
/** Multiprotocol task started with no event to run. */
|
||||
RAIL_ASSERT_MULTIPROTOCOL_NO_EVENT = 40,
|
||||
/** Invalid interrupt enabled. */
|
||||
RAIL_ASSERT_FAILED_INVALID_INTERRUPT_ENABLED = 41,
|
||||
/** Power conversion functions called before curves were initialized. */
|
||||
RAIL_ASSERT_CONVERSION_CURVES_NOT_INITIALIZED = 42,
|
||||
/** Division by zero. */
|
||||
RAIL_ASSERT_DIVISION_BY_ZERO = 43,
|
||||
/** Function cannot be called without access to the hardware. */
|
||||
RAIL_ASSERT_CANT_USE_HARDWARE = 44,
|
||||
/** Pointer parameter was passed as NULL. */
|
||||
RAIL_ASSERT_NULL_PARAMETER = 45,
|
||||
/** Invalid task type passed to RAIL_SetTaskPriority. */
|
||||
RAIL_ASSERT_INVALID_TASK_TYPE = 46,
|
||||
/** Synth radio config buffer for channel hopping too small. */
|
||||
RAIL_ASSERT_SMALL_SYNTH_RADIO_CONFIG_BUFFER = 47,
|
||||
/** Buffer provided for RX Channel Hopping is too small. */
|
||||
RAIL_ASSERT_CHANNEL_HOPPING_BUFFER_TOO_SHORT = 48,
|
||||
/** Invalid action was attempted on a module. */
|
||||
RAIL_ASSERT_INVALID_MODULE_ACTION = 49,
|
||||
/** The radio config for this channel is not compatible with channel hopping. */
|
||||
RAIL_ASSERT_CHANNEL_HOPPING_INVALID_RADIO_CONFIG = 50,
|
||||
/** Channel change failed. */
|
||||
RAIL_ASSERT_CHANNEL_CHANGE_FAILED = 51,
|
||||
/** Attempted to read invalid register. */
|
||||
RAIL_ASSERT_INVALID_REGISTER = 52,
|
||||
/** Can't read register value from NULL state. */
|
||||
RAIL_ASSERT_FAILED_LO_DIV_NULL_STATE = 53,
|
||||
/** DMP radio config caching failed. */
|
||||
RAIL_ASSERT_CACHE_CONFIG_FAILED = 54,
|
||||
/** NULL was supplied as a RAIL_StateTransitions_t argument. */
|
||||
RAIL_ASSERT_NULL_TRANSITIONS = 55,
|
||||
/** LDMA transfer failed. */
|
||||
RAIL_ASSERT_BAD_LDMA_TRANSFER = 56,
|
||||
/** Attempted to wake up with invalid RTCC sync data. */
|
||||
RAIL_ASSERT_INVALID_RTCC_SYNC_VALUES = 57,
|
||||
/** Radio sequencer hit a fault condition. */
|
||||
RAIL_ASSERT_SEQUENCER_FAULT = 58,
|
||||
/** Bus fault. */
|
||||
RAIL_ASSERT_BUS_ERROR = 59,
|
||||
/** The current radio config cannot be used with packet filtering. */
|
||||
RAIL_ASSERT_INVALID_FILTERING_CONFIG = 60,
|
||||
/** Retiming configuration error. */
|
||||
RAIL_ASSERT_RETIMING_CONFIG = 61,
|
||||
/** TX CRC configuration is corrupt. */
|
||||
RAIL_ASSERT_FAILED_TX_CRC_CONFIG = 62,
|
||||
/** The current PA config does not allow for this operation. */
|
||||
RAIL_ASSERT_INVALID_PA_OPERATION = 63,
|
||||
/** The sequencer selected an invalid PA. */
|
||||
RAIL_ASSERT_SEQ_INVALID_PA_SELECTED = 64,
|
||||
/** Invalid/unsupported channel config. */
|
||||
RAIL_ASSERT_FAILED_INVALID_CHANNEL_CONFIG = 65,
|
||||
/** The dynamic frame length configuration is invalid. */
|
||||
RAIL_ASSERT_INVALID_DYNAMIC_FRAME_LENGTH = 66,
|
||||
/** Failed to enable EM1P energy mode. */
|
||||
RAIL_ASSERT_FAILED_EM1P_ENTRY = 67,
|
||||
/** Failed to disable EM1P energy mode. */
|
||||
RAIL_ASSERT_FAILED_EM1P_EXIT = 68,
|
||||
/** Failed to disable RTCC synchronization. */
|
||||
RAIL_ASSERT_FAILED_RTCC_SYNC_STOP = 69,
|
||||
/** Multitimer linked list corrupted. */
|
||||
RAIL_ASSERT_FAILED_MULTITIMER_CORRUPT = 70,
|
||||
/** Unable to configure radio for temperature calibration. */
|
||||
RAIL_ASSERT_FAILED_TEMPCAL_ERROR = 71,
|
||||
/** Invalid EFF configuration. */
|
||||
RAIL_ASSERT_INVALID_EFF_CONFIGURATION = 72,
|
||||
/** Invalid RFFPLL configuration. */
|
||||
RAIL_ASSERT_INVALID_RFFPLL_CONFIGURATION = 73,
|
||||
/** Secure access fault. */
|
||||
RAIL_ASSERT_SECURE_ACCESS_FAULT = 74,
|
||||
/** SYSRTC0 not running. */
|
||||
RAIL_ASSERT_FAILED_SYSRTC0_NOT_RUNNING = 75,
|
||||
/** Radio Configurator not updated. */
|
||||
RAIL_ASSERT_RADIO_CONFIG_NOT_UP_TO_DATE = 76,
|
||||
/** Failed to set the event for configurable RSSI threshold. */
|
||||
RAIL_ASSERT_FAILED_RSSI_THRESHOLD = 77,
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
// Self-referencing defines minimize compiler complaints when using RAIL_ENUM
|
||||
#define RAIL_ASSERT_FAILED_APPENDED_INFO_MISSING ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_APPENDED_INFO_MISSING)
|
||||
#define RAIL_ASSERT_FAILED_RX_FIFO_BYTES ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RX_FIFO_BYTES)
|
||||
#define RAIL_ASSERT_FAILED_RX_FIFO_ZERO_BYTES_READ ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RX_FIFO_ZERO_BYTES_READ)
|
||||
#define RAIL_ASSERT_FAILED_ILLEGAL_RXLEN_ENTRY_STATUS ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_ILLEGAL_RXLEN_ENTRY_STATUS)
|
||||
#define RAIL_ASSERT_FAILED_BAD_PACKET_LENGTH ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_BAD_PACKET_LENGTH)
|
||||
#define RAIL_ASSERT_FAILED_SYNTH_DIVCTRL_ENUM_CONVERSION_ERROR ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_SYNTH_DIVCTRL_ENUM_CONVERSION_ERROR)
|
||||
#define RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RX_FIFO ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RX_FIFO)
|
||||
#define RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RXLEN_FIFO ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_UNEXPECTED_STATE_RXLEN_FIFO)
|
||||
#define RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TX_FIFO ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TX_FIFO)
|
||||
#define RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TXACK_FIFO ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_UNEXPECTED_STATE_TXACK_FIFO)
|
||||
#define RAIL_ASSERT_FAILED_PBUFFER_NOT_DEFINED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_PBUFFER_NOT_DEFINED)
|
||||
#define RAIL_ASSERT_FAILED_INSUFFICIENT_BYTES_IN_RX_PACKET ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_INSUFFICIENT_BYTES_IN_RX_PACKET)
|
||||
#define RAIL_ASSERT_FAILED_CLOCK_PRESCALER ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_CLOCK_PRESCALER)
|
||||
#define RAIL_ASSERT_FAILED_RTCC_POST_WAKEUP ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RTCC_POST_WAKEUP)
|
||||
#define RAIL_ASSERT_FAILED_SYNTH_VCO_FREQUENCY ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_SYNTH_VCO_FREQUENCY)
|
||||
#define RAIL_ASSERT_FAILED_RAC_STATE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RAC_STATE)
|
||||
#define RAIL_ASSERT_FAILED_SYNTH_INVALID_VCOCTRL ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_SYNTH_INVALID_VCOCTRL)
|
||||
#define RAIL_ASSERT_FAILED_NESTED_SEQUENCER_LOCK ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_NESTED_SEQUENCER_LOCK)
|
||||
#define RAIL_ASSERT_FAILED_RSSI_AVERAGE_DONE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RSSI_AVERAGE_DONE)
|
||||
#define RAIL_ASSERT_FAILED_DFL_BITS_SIZE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_DFL_BITS_SIZE)
|
||||
#define RAIL_ASSERT_FAILED_PROTIMER_RANDOM_SEED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_PROTIMER_RANDOM_SEED)
|
||||
#define RAIL_ASSERT_FAILED_EFR32XG1_REGISTER_SIZE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_EFR32XG1_REGISTER_SIZE)
|
||||
#define RAIL_ASSERT_FAILED_PROTIMER_CHANNEL ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_PROTIMER_CHANNEL)
|
||||
#define RAIL_ASSERT_FAILED_TIMER_REQUIRES_WRAP ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_TIMER_REQUIRES_WRAP)
|
||||
#define RAIL_ASSERT_FAILED_BASECNTTOP ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_BASECNTTOP)
|
||||
#define RAIL_ASSERT_FAILED_DEPRECATED_LBTRETRY ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_DEPRECATED_LBTRETRY)
|
||||
#define RAIL_ASSERT_FAILED_RTCC_SYNC_MISSED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RTCC_SYNC_MISSED)
|
||||
#define RAIL_ASSERT_FAILED_CLOCK_SOURCE_NOT_READY ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_CLOCK_SOURCE_NOT_READY)
|
||||
#define RAIL_ASSERT_FAILED_TIMINGS_INVALID ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_TIMINGS_INVALID)
|
||||
#define RAIL_ASSERT_NULL_HANDLE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_NULL_HANDLE)
|
||||
#define RAIL_ASSERT_FAILED_SCHED_TIMER_NOT_RUNNING ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_SCHED_TIMER_NOT_RUNNING)
|
||||
#define RAIL_ASSERT_FAILED_NO_ACTIVE_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_NO_ACTIVE_CONFIG)
|
||||
#define RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SWITCH ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SWITCH)
|
||||
#define RAIL_ASSERT_FAILED_RESERVED33 ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RESERVED33)
|
||||
#define RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SCHEDRX ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SCHEDRX)
|
||||
#define RAIL_ASSERT_FAILED_INVALID_HANDLE_SCHEDTX ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_INVALID_HANDLE_SCHEDTX)
|
||||
#define RAIL_ASSERT_FAILED_INACTIVE_HANDLE_SCHEDTX ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_INACTIVE_HANDLE_SCHEDTX)
|
||||
#define RAIL_ASSERT_FAILED_CONFIG_INDEX_INVALID ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_CONFIG_INDEX_INVALID)
|
||||
#define RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SINGLEPROTOCOL ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_NO_ACTIVE_HANDLE_SINGLEPROTOCOL)
|
||||
#define RAIL_ASSERT_DEPRECATED_FUNCTION ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_DEPRECATED_FUNCTION)
|
||||
#define RAIL_ASSERT_MULTIPROTOCOL_NO_EVENT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_MULTIPROTOCOL_NO_EVENT)
|
||||
#define RAIL_ASSERT_FAILED_INVALID_INTERRUPT_ENABLED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_INVALID_INTERRUPT_ENABLED)
|
||||
#define RAIL_ASSERT_CONVERSION_CURVES_NOT_INITIALIZED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CONVERSION_CURVES_NOT_INITIALIZED)
|
||||
#define RAIL_ASSERT_DIVISION_BY_ZERO ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_DIVISION_BY_ZERO)
|
||||
#define RAIL_ASSERT_CANT_USE_HARDWARE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CANT_USE_HARDWARE)
|
||||
#define RAIL_ASSERT_NULL_PARAMETER ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_NULL_PARAMETER)
|
||||
#define RAIL_ASSERT_INVALID_TASK_TYPE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_TASK_TYPE)
|
||||
#define RAIL_ASSERT_SMALL_SYNTH_RADIO_CONFIG_BUFFER ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_SMALL_SYNTH_RADIO_CONFIG_BUFFER)
|
||||
#define RAIL_ASSERT_CHANNEL_HOPPING_BUFFER_TOO_SHORT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CHANNEL_HOPPING_BUFFER_TOO_SHORT)
|
||||
#define RAIL_ASSERT_INVALID_MODULE_ACTION ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_MODULE_ACTION)
|
||||
#define RAIL_ASSERT_CHANNEL_HOPPING_INVALID_RADIO_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CHANNEL_HOPPING_INVALID_RADIO_CONFIG)
|
||||
#define RAIL_ASSERT_CHANNEL_CHANGE_FAILED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CHANNEL_CHANGE_FAILED)
|
||||
#define RAIL_ASSERT_INVALID_REGISTER ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_REGISTER)
|
||||
#define RAIL_ASSERT_FAILED_LO_DIV_NULL_STATE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_LO_DIV_NULL_STATE)
|
||||
#define RAIL_ASSERT_CACHE_CONFIG_FAILED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_CACHE_CONFIG_FAILED)
|
||||
#define RAIL_ASSERT_NULL_TRANSITIONS ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_NULL_TRANSITIONS)
|
||||
#define RAIL_ASSERT_BAD_LDMA_TRANSFER ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_BAD_LDMA_TRANSFER)
|
||||
#define RAIL_ASSERT_INVALID_RTCC_SYNC_VALUES ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_RTCC_SYNC_VALUES)
|
||||
#define RAIL_ASSERT_SEQUENCER_FAULT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_SEQUENCER_FAULT)
|
||||
#define RAIL_ASSERT_BUS_ERROR ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_BUS_ERROR)
|
||||
#define RAIL_ASSERT_INVALID_FILTERING_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_FILTERING_CONFIG)
|
||||
#define RAIL_ASSERT_RETIMING_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_RETIMING_CONFIG)
|
||||
#define RAIL_ASSERT_FAILED_TX_CRC_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_TX_CRC_CONFIG)
|
||||
#define RAIL_ASSERT_INVALID_PA_OPERATION ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_PA_OPERATION)
|
||||
#define RAIL_ASSERT_SEQ_INVALID_PA_SELECTED ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_SEQ_INVALID_PA_SELECTED)
|
||||
#define RAIL_ASSERT_FAILED_INVALID_CHANNEL_CONFIG ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_INVALID_CHANNEL_CONFIG)
|
||||
#define RAIL_ASSERT_INVALID_DYNAMIC_FRAME_LENGTH ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_DYNAMIC_FRAME_LENGTH)
|
||||
#define RAIL_ASSERT_FAILED_EM1P_ENTRY ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_EM1P_ENTRY)
|
||||
#define RAIL_ASSERT_FAILED_EM1P_EXIT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_EM1P_EXIT)
|
||||
#define RAIL_ASSERT_FAILED_RTCC_SYNC_STOP ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RTCC_SYNC_STOP)
|
||||
#define RAIL_ASSERT_FAILED_MULTITIMER_CORRUPT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_MULTITIMER_CORRUPT)
|
||||
#define RAIL_ASSERT_FAILED_TEMPCAL_ERROR ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_TEMPCAL_ERROR)
|
||||
#define RAIL_ASSERT_INVALID_EFF_CONFIGURATION ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_EFF_CONFIGURATION)
|
||||
#define RAIL_ASSERT_INVALID_RFFPLL_CONFIGURATION ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_INVALID_RFFPLL_CONFIGURATION)
|
||||
#define RAIL_ASSERT_SECURE_ACCESS_FAULT ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_SECURE_ACCESS_FAULT)
|
||||
#define RAIL_ASSERT_FAILED_SYSRTC0_NOT_RUNNING ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_SYSRTC0_NOT_RUNNING)
|
||||
#define RAIL_ASSERT_RADIO_CONFIG_NOT_UP_TO_DATE ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_RADIO_CONFIG_NOT_UP_TO_DATE)
|
||||
#define RAIL_ASSERT_FAILED_RSSI_THRESHOLD ((RAIL_AssertErrorCodes_t) RAIL_ASSERT_FAILED_RSSI_THRESHOLD)
|
||||
#endif//DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
/// Use this define to create an array of error messages that map to the codes
|
||||
/// in \ref RAIL_AssertErrorCodes_t. You can use these to print slightly more
|
||||
/// detailed error strings related to a particular assert error code if desired.
|
||||
/// For example, you could implement your assert failed callback as follows to
|
||||
/// make use of this.
|
||||
///
|
||||
/// @code{.c}
|
||||
/// void RAILCb_AssertFailed(RAIL_Handle_t railHandle, uint32_t errorCode)
|
||||
/// {
|
||||
/// static const char* railErrorMessages[] = RAIL_ASSERT_ERROR_MESSAGES;
|
||||
/// const char *errorMessage = "Unknown";
|
||||
///
|
||||
/// // If this error code is within the range of known error messages then use
|
||||
/// // the appropriate error message.
|
||||
/// if (errorCode < (sizeof(railErrorMessages) / sizeof(char*))) {
|
||||
/// errorMessage = railErrorMessages[errorCode];
|
||||
/// }
|
||||
/// printf(errorMessage);
|
||||
///
|
||||
/// // Reset the chip since an assert is a fatal error
|
||||
/// NVIC_SystemReset();
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
#define RAIL_ASSERT_ERROR_MESSAGES { \
|
||||
/* 0*/ "Appended info missing from Rx packet", \
|
||||
/* 1*/ "Receive FIFO too small for IR calibration", \
|
||||
/* 2*/ "Error reading back packet payload", \
|
||||
/* 3*/ "Receive fifo entry has invalid status", \
|
||||
/* 4*/ "Receive fifo entry bad packet length", \
|
||||
/* 5*/ "Unable to configure radio for IR calibration", \
|
||||
/* 6*/ "Reached unexpected state while handling Rx fifo events", \
|
||||
/* 7*/ "Reached unexpected state while handling RXLEN fifo events", \
|
||||
/* 8*/ "Reached unexpected state while handling Tx fifo events", \
|
||||
/* 9*/ "Reached unexpected state while handling Tx ACK fifo events", \
|
||||
/*10*/ "No memory to store receive packet", \
|
||||
/*11*/ "Packet length longer than the receive FIFO size", \
|
||||
/*12*/ "Invalid radio clock prescaler", \
|
||||
/*13*/ "Error synchronizing the RAIL timebase after sleep", \
|
||||
/*14*/ "VCO frequency outside supported range", \
|
||||
/*15*/ "Radio active while changing channels", \
|
||||
/*16*/ "Invalid Synth VCOCTRL field calculation", \
|
||||
/*17*/ "Nested attempt to lock the sequencer", \
|
||||
/*18*/ "RSSI averaging enabled without a valid callback", \
|
||||
/*19*/ "Invalid dynamic frame length setting provided (dflBits)", \
|
||||
/*20*/ "Unable to seed radio pseudo random number generator", \
|
||||
/*21*/ "Timeout exceeds EFR32XG1 register size", \
|
||||
/*22*/ "Invalid timer channel specified", \
|
||||
/*23*/ "Timer value larger than RAIL timebase", \
|
||||
/*24*/ "LBT config exceeds EFR32XG1 register size", \
|
||||
/*25*/ "Deprecated CSMA/LBT retry callback unexpectedly called", \
|
||||
/*26*/ "Could not synchronize RAIL timebase with the RTC", \
|
||||
/*27*/ "Clock source not ready", \
|
||||
/*28*/ "Attempted to set RAIL timings to invalid value", \
|
||||
/*29*/ "NULL was supplied as a RAIL_Handle_t argument", \
|
||||
/*30*/ "Scheduled timer not running", \
|
||||
/*31*/ "API improperly called while protocol inactive", \
|
||||
/*32*/ "No active handle after switch", \
|
||||
/*33*/ "Reserved for future use", \
|
||||
/*34*/ "No active handle for scheduled rx", \
|
||||
/*35*/ "Invalid handle for scheduled tx", \
|
||||
/*36*/ "Inactive handle for scheduled tx", \
|
||||
/*37*/ "Invalid config index to switch to", \
|
||||
/*38*/ "No active handle for single protocol", \
|
||||
/*39*/ "This function is deprecated and must not be called", \
|
||||
/*40*/ "Multiprotocol task started with no event to run", \
|
||||
/*41*/ "Invalid interrupt enabled", \
|
||||
/*42*/ "Power conversion functions called before curves were initialized", \
|
||||
/*43*/ "Division by zero", \
|
||||
/*44*/ "Function cannot be called without access to the hardware", \
|
||||
/*45*/ "Pointer parameter was passed as NULL", \
|
||||
/*46*/ "Invalid task type passed to RAIL_SetTaskPriority", \
|
||||
/*47*/ "Synth radio config buffer for channel hopping too small", \
|
||||
/*48*/ "Buffer provided for RX Channel Hopping is too small", \
|
||||
/*49*/ "Invalid action was attempted on a module", \
|
||||
/*50*/ "The radio config for this channel is not compatible with channel hopping", \
|
||||
/*51*/ "Channel change failed", \
|
||||
/*52*/ "Attempted to read invalid register", \
|
||||
/*53*/ "Can't read register value from NULL state", \
|
||||
/*54*/ "DMP radio config caching failed", \
|
||||
/*55*/ "NULL was supplied as a RAIL_StateTransitions_t argument", \
|
||||
/*56*/ "LDMA transfer failed", \
|
||||
/*57*/ "Attempted to wake up with invalid RTCC sync data", \
|
||||
/*58*/ "Radio sequencer hit a fault condition", \
|
||||
/*59*/ "Bus fault", \
|
||||
/*60*/ "The current radio config cannot be used with packet filtering", \
|
||||
/*61*/ "Retiming configuration error", \
|
||||
/*62*/ "TX CRC configuration is corrupt", \
|
||||
/*63*/ "The current PA config does not allow for this operation", \
|
||||
/*64*/ "The sequencer selected an invalid PA", \
|
||||
/*65*/ "Invalid/unsupported channel config", \
|
||||
/*66*/ "The dynamic frame length configuration is invalid", \
|
||||
/*67*/ "Failed to enable EM1P energy mode", \
|
||||
/*68*/ "Failed to disable EM1P energy mode", \
|
||||
/*69*/ "Failed to disable RTCC synchronization", \
|
||||
/*70*/ "Multitimer linked list corrupted", \
|
||||
/*71*/ "Unable to configure radio for temperature calibration", \
|
||||
/*72*/ "Invalid EFF configuration", \
|
||||
/*73*/ "Invalid RFFPLL configuration", \
|
||||
/*74*/ "Secure access fault", \
|
||||
/*75*/ "SYSRTC0 not running", \
|
||||
/*76*/ "Radio Configurator not updated", \
|
||||
/*77*/ "Failed to set the event for configurable RSSI threshold", \
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __RAIL_ASSERT_ERROR_CODES_H__
|
|
@ -0,0 +1,719 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Auxiliary header for the RAIL library. Includes consistent definitions
|
||||
* of features available across different chips.
|
||||
*******************************************************************************
|
||||
* # 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 __RAIL_FEATURES_H__
|
||||
#define __RAIL_FEATURES_H__
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup RAIL_API RAIL API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* RAIL Features
|
||||
*****************************************************************************/
|
||||
/**
|
||||
* @addtogroup Features
|
||||
* @brief Overview of support for various features across hardware platforms.
|
||||
* These defines can be used at compile time to determine which
|
||||
* features are available on your platform. However, keep in mind that
|
||||
* these defines hold true for chip families. Your specific part
|
||||
* may have further restrictions (band limitations, power amplifier
|
||||
* restrictions, and so on) on top of those listed below, for which
|
||||
* runtime RAIL_Supports*() APIs can be used to check availability
|
||||
* on a particular chip (after \ref RAIL_Init() has been called).
|
||||
* In general, an attempt to call an API that is not supported on your
|
||||
* chip family as listed below will result in a
|
||||
* \ref RAIL_STATUS_INVALID_CALL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports both SubGHz and 2.4 GHz bands.
|
||||
/// See also runtime refinement \ref RAIL_SupportsDualBand().
|
||||
#if ((_SILICON_LABS_EFR32_RADIO_TYPE == _SILICON_LABS_EFR32_RADIO_DUALBAND) \
|
||||
|| ((FEAT_RF_2G4 == 1) && (FEAT_RF_SUBG == 1)))
|
||||
#define RAIL_SUPPORTS_DUAL_BAND 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_DUAL_BAND 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_DUAL_BAND.
|
||||
#define RAIL_FEAT_DUAL_BAND_RADIO RAIL_SUPPORTS_DUAL_BAND
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the 2.4 GHz band.
|
||||
/// See also runtime refinement \ref RAIL_Supports2p4GHzBand().
|
||||
#if (((_SILICON_LABS_EFR32_RADIO_TYPE == _SILICON_LABS_EFR32_RADIO_DUALBAND) \
|
||||
|| (_SILICON_LABS_EFR32_RADIO_TYPE == _SILICON_LABS_EFR32_RADIO_2G4HZ)) \
|
||||
|| (FEAT_RF_2G4 == 1))
|
||||
#define RAIL_SUPPORTS_2P4GHZ_BAND 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_2P4GHZ_BAND 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_2P4GHZ_BAND.
|
||||
#define RAIL_FEAT_2G4_RADIO RAIL_SUPPORTS_2P4GHZ_BAND
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports SubGHz bands.
|
||||
/// See also runtime refinement \ref RAIL_SupportsSubGHzBand().
|
||||
#if (((_SILICON_LABS_EFR32_RADIO_TYPE == _SILICON_LABS_EFR32_RADIO_DUALBAND) \
|
||||
|| (_SILICON_LABS_EFR32_RADIO_TYPE == _SILICON_LABS_EFR32_RADIO_SUBGHZ)) \
|
||||
|| (FEAT_RF_SUBG == 1))
|
||||
#define RAIL_SUPPORTS_SUBGHZ_BAND 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_SUBGHZ_BAND 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_SUBGHZ_BAND.
|
||||
#define RAIL_FEAT_SUBGIG_RADIO RAIL_SUPPORTS_SUBGHZ_BAND
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports OFDM PA.
|
||||
/// See also runtime refinement \ref RAIL_SupportsOFDMPA().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_SUPPORTS_OFDM_PA 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_OFDM_PA 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// bit masked address filtering.
|
||||
/// See also runtime refinement \ref RAIL_SupportsAddrFilterAddressBitMask().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG >= 2)
|
||||
#define RAIL_SUPPORTS_ADDR_FILTER_ADDRESS_BIT_MASK 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_ADDR_FILTER_ADDRESS_BIT_MASK 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// address filter mask information for incoming packets in
|
||||
/// \ref RAIL_RxPacketInfo_t::filterMask and
|
||||
/// \ref RAIL_IEEE802154_Address_t::filterMask.
|
||||
/// See also runtime refinement \ref RAIL_SupportsAddrFilterMask().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_SUPPORTS_ADDR_FILTER_MASK 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_ADDR_FILTER_MASK 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// alternate power settings for the Power Amplifier.
|
||||
/// See also runtime refinement \ref RAIL_SupportsAlternateTxPower().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG > 1) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_SUPPORTS_ALTERNATE_TX_POWER 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_ALTERNATE_TX_POWER 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_ALTERNATE_TX_POWER.
|
||||
#define RAIL_FEAT_ALTERNATE_POWER_TX_SUPPORTED RAIL_SUPPORTS_ALTERNATE_TX_POWER
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports antenna diversity.
|
||||
/// See also runtime refinement \ref RAIL_SupportsAntennaDiversity().
|
||||
#if ((_SILICON_LABS_32B_SERIES_1_CONFIG >= 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES == 2))
|
||||
#define RAIL_SUPPORTS_ANTENNA_DIVERSITY 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_ANTENNA_DIVERSITY 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_ANTENNA_DIVERSITY.
|
||||
#define RAIL_FEAT_ANTENNA_DIVERSITY RAIL_SUPPORTS_ANTENNA_DIVERSITY
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports path diversity.
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_SUPPORTS_PATH_DIVERSITY 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_PATH_DIVERSITY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports channel hopping.
|
||||
/// See also runtime refinement \ref RAIL_SupportsChannelHopping().
|
||||
#if ((_SILICON_LABS_32B_SERIES_1_CONFIG >= 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG >= 1))
|
||||
#define RAIL_SUPPORTS_CHANNEL_HOPPING 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_CHANNEL_HOPPING 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_CHANNEL_HOPPING.
|
||||
#define RAIL_FEAT_CHANNEL_HOPPING RAIL_SUPPORTS_CHANNEL_HOPPING
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports dual sync words.
|
||||
/// See also runtime refinement \ref RAIL_SupportsDualSyncWords().
|
||||
#if 1
|
||||
#define RAIL_SUPPORTS_DUAL_SYNC_WORDS 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_DUAL_SYNC_WORDS 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports automatic transitions
|
||||
/// from TX to TX.
|
||||
/// See also runtime refinement \ref RAIL_SupportsTxToTx().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_SUPPORTS_TX_TO_TX 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_TX_TO_TX 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports thermistor measurements.
|
||||
/// See also runtime refinement \ref RAIL_SupportsExternalThermistor().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 3) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 5) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_SUPPORTS_EXTERNAL_THERMISTOR 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_EXTERNAL_THERMISTOR 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_EXTERNAL_THERMISTOR.
|
||||
#define RAIL_FEAT_EXTERNAL_THERMISTOR RAIL_SUPPORTS_EXTERNAL_THERMISTOR
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports AUXADC measurements.
|
||||
/// See also runtime refinement \ref RAIL_SupportsAuxAdc().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 3) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 5) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_SUPPORTS_AUXADC 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_AUXADC 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports a high-precision
|
||||
/// LFRCO.
|
||||
/// Best to use the runtime refinement \ref RAIL_SupportsPrecisionLFRCO()
|
||||
/// because some chip revisions do not support it.
|
||||
#if ((_SILICON_LABS_32B_SERIES_1_CONFIG == 3) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_SUPPORTS_PRECISION_LFRCO 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_PRECISION_LFRCO 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports radio entropy.
|
||||
/// See also runtime refinement \ref RAIL_SupportsRadioEntropy().
|
||||
#if 1
|
||||
#define RAIL_SUPPORTS_RADIO_ENTROPY 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RADIO_ENTROPY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// RFSENSE Energy Detection Mode.
|
||||
/// See also runtime refinement \ref RAIL_SupportsRfSenseEnergyDetection().
|
||||
#if ((_SILICON_LABS_32B_SERIES == 1) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_SUPPORTS_RFSENSE_ENERGY_DETECTION 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RFSENSE_ENERGY_DETECTION 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// RFSENSE Selective(OOK) Mode.
|
||||
/// See also runtime refinement \ref RAIL_SupportsRfSenseSelectiveOok().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_SUPPORTS_RFSENSE_SELECTIVE_OOK 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RFSENSE_SELECTIVE_OOK 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_RFSENSE_SELECTIVE_OOK.
|
||||
#define RAIL_FEAT_RFSENSE_SELECTIVE_OOK_MODE_SUPPORTED \
|
||||
RAIL_SUPPORTS_RFSENSE_SELECTIVE_OOK
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the Energy Friendly
|
||||
/// Front End Module (EFF).
|
||||
/// See also runtime refinement \ref RAIL_SupportsEff().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_SUPPORTS_EFF 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_EFF 0
|
||||
#endif
|
||||
|
||||
// BLE features
|
||||
// Some features may not be available on all platforms
|
||||
// due to radio hardware limitations.
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE.
|
||||
/// See also runtime refinement \ref RAIL_SupportsProtocolBLE().
|
||||
#if 1
|
||||
#define RAIL_SUPPORTS_PROTOCOL_BLE RAIL_SUPPORTS_2P4GHZ_BAND
|
||||
#else
|
||||
#define RAIL_SUPPORTS_PROTOCOL_BLE 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 1Mbps
|
||||
/// Non-Viterbi PHY.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports1MbpsNonViterbi().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG >= 1)
|
||||
#define RAIL_BLE_SUPPORTS_1MBPS_NON_VITERBI RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_1MBPS_NON_VITERBI 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 1Mbps Viterbi
|
||||
/// PHY.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports1MbpsViterbi().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_BLE_SUPPORTS_1MBPS_VITERBI RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_1MBPS_VITERBI 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 1Mbps operation.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports1Mbps().
|
||||
#define RAIL_BLE_SUPPORTS_1MBPS \
|
||||
(RAIL_BLE_SUPPORTS_1MBPS_NON_VITERBI || RAIL_BLE_SUPPORTS_1MBPS_VITERBI)
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 2Mbps
|
||||
/// Non-Viterbi PHY.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports2MbpsNonViterbi().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG >= 2)
|
||||
#define RAIL_BLE_SUPPORTS_2MBPS_NON_VITERBI RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_2MBPS_NON_VITERBI 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 2Mbps Viterbi
|
||||
/// PHY.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports2MbpsViterbi().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_BLE_SUPPORTS_2MBPS_VITERBI RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_2MBPS_VITERBI 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE 2Mbps operation.
|
||||
/// See also runtime refinement \ref RAIL_BLE_Supports2Mbps().
|
||||
#define RAIL_BLE_SUPPORTS_2MBPS \
|
||||
(RAIL_BLE_SUPPORTS_2MBPS_NON_VITERBI || RAIL_BLE_SUPPORTS_2MBPS_VITERBI)
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE
|
||||
/// Antenna Switching needed for Angle-of-Arrival receives or
|
||||
/// Angle-of-Departure transmits.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsAntennaSwitching().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_ANTENNA_SWITCHING RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_ANTENNA_SWITCHING 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the BLE Coded PHY
|
||||
/// used for Long-Range.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsCodedPhy().
|
||||
#if ((_SILICON_LABS_32B_SERIES_1_CONFIG == 3) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 1) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_CODED_PHY RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_CODED_PHY 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_BLE_SUPPORTS_CODED_PHY.
|
||||
#define RAIL_FEAT_BLE_CODED RAIL_BLE_SUPPORTS_CODED_PHY
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the BLE Simulscan PHY
|
||||
/// used for simultaneous BLE 1Mbps and Coded PHY reception.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsSimulscanPhy().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_SIMULSCAN_PHY RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_SIMULSCAN_PHY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE
|
||||
/// CTE (Constant Tone Extension) needed for Angle-of-Arrival/Departure
|
||||
/// transmits.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsCte().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_CTE RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_CTE 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the
|
||||
/// Quuppa PHY.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsQuuppa().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_QUUPPA RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_QUUPPA 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE
|
||||
/// IQ Sampling needed for Angle-of-Arrival/Departure receives.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsIQSampling().
|
||||
#if ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
#define RAIL_BLE_SUPPORTS_IQ_SAMPLING RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_IQ_SAMPLING 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports some BLE AOX
|
||||
/// features.
|
||||
#define RAIL_BLE_SUPPORTS_AOX \
|
||||
(RAIL_BLE_SUPPORTS_ANTENNA_SWITCHING \
|
||||
|| RAIL_BLE_SUPPORTS_IQ_SAMPLING \
|
||||
|| RAIL_BLE_SUPPORTS_CTE)
|
||||
|
||||
/// Backwards-compatible synonym of \ref RAIL_BLE_SUPPORTS_AOX
|
||||
#define RAIL_FEAT_BLE_AOX_SUPPORTED RAIL_BLE_SUPPORTS_AOX
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports BLE PHY switch to RX
|
||||
/// functionality, which is used to switch BLE PHYs at a specific time
|
||||
/// to receive auxiliary packets.
|
||||
/// See also runtime refinement \ref RAIL_BLE_SupportsPhySwitchToRx().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_BLE_SUPPORTS_PHY_SWITCH_TO_RX RAIL_SUPPORTS_PROTOCOL_BLE
|
||||
#else
|
||||
#define RAIL_BLE_SUPPORTS_PHY_SWITCH_TO_RX 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_BLE_SUPPORTS_PHY_SWITCH_TO_RX.
|
||||
#define RAIL_FEAT_BLE_PHY_SWITCH_TO_RX RAIL_BLE_SUPPORTS_PHY_SWITCH_TO_RX
|
||||
|
||||
// IEEE 802.15.4 features
|
||||
// Some features may not be available on all platforms
|
||||
// due to radio hardware limitations.
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports IEEE 802.15.4.
|
||||
/// See also runtime refinement \ref RAIL_SupportsProtocolIEEE802154().
|
||||
#if 1
|
||||
#define RAIL_SUPPORTS_PROTOCOL_IEEE802154 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_PROTOCOL_IEEE802154 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports the
|
||||
/// 802.15.4 Wi-Fi Coexistence PHY.
|
||||
/// See also runtime refinement \ref RAIL_IEEE802154_SupportsCoexPhy().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG > 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_COEX_PHY (RAIL_SUPPORTS_PROTOCOL_IEEE802154 && RAIL_SUPPORTS_2P4GHZ_BAND)
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_COEX_PHY 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_IEEE802154_SUPPORTS_COEX_PHY.
|
||||
#define RAIL_FEAT_802154_COEX_PHY RAIL_IEEE802154_SUPPORTS_COEX_PHY
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports a front end module.
|
||||
/// See also runtime refinement \ref RAIL_IEEE802154_SupportsFemPhy().
|
||||
#define RAIL_IEEE802154_SUPPORTS_FEM_PHY (RAIL_SUPPORTS_PROTOCOL_IEEE802154 && RAIL_SUPPORTS_2P4GHZ_BAND)
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4E-2012 feature subset needed for Zigbee R22 GB868.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsESubsetGB868().
|
||||
#if 1
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868 RAIL_SUPPORTS_PROTOCOL_IEEE802154
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868.
|
||||
#define RAIL_FEAT_IEEE802154_E_GB868_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4E-2012 Enhanced ACKing.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsEEnhancedAck().
|
||||
#if 1
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_ENHANCED_ACK RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_ENHANCED_ACK 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_E_ENHANCED_ACK.
|
||||
#define RAIL_FEAT_IEEE802154_E_ENH_ACK_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_E_ENHANCED_ACK
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// receiving IEEE 802.15.4E-2012 Multipurpose frames.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsEMultipurposeFrames().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_MULTIPURPOSE_FRAMES RAIL_IEEE802154_SUPPORTS_E_SUBSET_GB868
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_E_MULTIPURPOSE_FRAMES 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_E_MULTIPURPOSE_FRAMES.
|
||||
#define RAIL_FEAT_IEEE802154_MULTIPURPOSE_FRAME_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_E_MULTIPURPOSE_FRAMES
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4G-2012 feature subset needed for Zigbee R22 GB868.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsGSubsetGB868().
|
||||
#if 1
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868 \
|
||||
(RAIL_SUPPORTS_PROTOCOL_IEEE802154 && RAIL_SUPPORTS_SUBGHZ_BAND)
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868.
|
||||
#define RAIL_FEAT_IEEE802154_G_GB868_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// dynamic FEC
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_DYNFEC \
|
||||
RAIL_FEAT_IEEE802154_G_GB868_SUPPORTED // limit to SUBGHZ for now
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_DYNFEC 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// Wi-SUN mode switching
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsGModeSwitch().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_MODESWITCH \
|
||||
RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868 // limit to SUBGHZ for now
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_MODESWITCH 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4G-2012 reception and transmission of frames
|
||||
/// with 4-byte CRC.
|
||||
/// See also runtime refinement \ref RAIL_IEEE802154_SupportsG4ByteCrc().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_4BYTE_CRC RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_4BYTE_CRC 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_IEEE802154_SUPPORTS_G_4BYTE_CRC.
|
||||
#define RAIL_FEAT_IEEE802154_G_4BYTE_CRC_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_G_4BYTE_CRC
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4G-2012 reception of unwhitened frames.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsGUnwhitenedRx().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_RX RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_RX 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_RX.
|
||||
#define RAIL_FEAT_IEEE802154_G_UNWHITENED_RX_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_RX
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// IEEE 802.15.4G-2012 transmission of unwhitened frames.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsGUnwhitenedTx().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG != 1)
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_TX RAIL_IEEE802154_SUPPORTS_G_SUBSET_GB868
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_TX 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_TX.
|
||||
#define RAIL_FEAT_IEEE802154_G_UNWHITENED_TX_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_G_UNWHITENED_TX
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// canceling the frame-pending lookup event
|
||||
/// \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND
|
||||
/// when the radio transitions to a state that renders the
|
||||
/// the reporting of this event moot (i.e., too late for
|
||||
/// the stack to influence the outgoing ACK).
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsCancelFramePendingLookup().
|
||||
#if 1
|
||||
#define RAIL_IEEE802154_SUPPORTS_CANCEL_FRAME_PENDING_LOOKUP RAIL_SUPPORTS_PROTOCOL_IEEE802154
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_CANCEL_FRAME_PENDING_LOOKUP 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_CANCEL_FRAME_PENDING_LOOKUP.
|
||||
#define RAIL_FEAT_IEEE802154_CANCEL_FP_LOOKUP_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_CANCEL_FRAME_PENDING_LOOKUP
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// early triggering of the frame-pending lookup event
|
||||
/// \ref RAIL_EVENT_IEEE802154_DATA_REQUEST_COMMAND
|
||||
/// just after MAC address fields have been received.
|
||||
/// See also runtime refinement \ref
|
||||
/// RAIL_IEEE802154_SupportsEarlyFramePendingLookup().
|
||||
#if 1
|
||||
#define RAIL_IEEE802154_SUPPORTS_EARLY_FRAME_PENDING_LOOKUP RAIL_SUPPORTS_PROTOCOL_IEEE802154
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_EARLY_FRAME_PENDING_LOOKUP 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref
|
||||
/// RAIL_IEEE802154_SUPPORTS_EARLY_FRAME_PENDING_LOOKUP.
|
||||
#define RAIL_FEAT_IEEE802154_EARLY_FP_LOOKUP_SUPPORTED \
|
||||
RAIL_IEEE802154_SUPPORTS_EARLY_FRAME_PENDING_LOOKUP
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports dual PA configs for mode switch
|
||||
/// or concurrent mode.
|
||||
/// See also runtime refinement \ref RAIL_IEEE802154_SupportsDualPaConfig().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_IEEE802154_SUPPORTS_DUAL_PA_CONFIG 1
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_DUAL_PA_CONFIG 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports IEEE 802.15.4 PHY
|
||||
/// with custom settings
|
||||
#if ((_SILICON_LABS_32B_SERIES_1_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_1_CONFIG == 3))
|
||||
#define RAIL_IEEE802154_SUPPORTS_CUSTOM1_PHY (RAIL_SUPPORTS_PROTOCOL_IEEE802154 && RAIL_SUPPORTS_2P4GHZ_BAND)
|
||||
#else
|
||||
#define RAIL_IEEE802154_SUPPORTS_CUSTOM1_PHY 0
|
||||
#endif
|
||||
|
||||
// Z-Wave features
|
||||
// Some features may not be available on all platforms
|
||||
// due to radio hardware limitations.
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports Z-Wave.
|
||||
/// See also runtime refinement \ref RAIL_SupportsProtocolZWave().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG >= 3) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_SUPPORTS_PROTOCOL_ZWAVE RAIL_SUPPORTS_SUBGHZ_BAND
|
||||
#else
|
||||
#define RAIL_SUPPORTS_PROTOCOL_ZWAVE 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_SUPPORTS_PROTOCOL_ZWAVE.
|
||||
#define RAIL_FEAT_ZWAVE_SUPPORTED RAIL_SUPPORTS_PROTOCOL_ZWAVE
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports energy detect PHY.
|
||||
/// See also runtime refinement \ref RAIL_ZWAVE_SupportsEnergyDetectPhy().
|
||||
#if (_SILICON_LABS_32B_SERIES_1_CONFIG >= 3)
|
||||
#define RAIL_ZWAVE_SUPPORTS_ED_PHY RAIL_SUPPORTS_PROTOCOL_ZWAVE
|
||||
#else
|
||||
#define RAIL_ZWAVE_SUPPORTS_ED_PHY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports concurrent PHY.
|
||||
/// See also runtime refinement \ref RAIL_ZWAVE_SupportsConcPhy().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_ZWAVE_SUPPORTS_CONC_PHY RAIL_SUPPORTS_PROTOCOL_ZWAVE
|
||||
#else
|
||||
#define RAIL_ZWAVE_SUPPORTS_CONC_PHY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports SQ-based PHY.
|
||||
/// See also runtime refinement \ref RAIL_SupportsSQPhy().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 4) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_SUPPORTS_SQ_PHY 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_SQ_PHY 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the code supports Z-Wave
|
||||
/// region information in PTI and
|
||||
/// newer RAIL_ZWAVE_RegionConfig_t structure
|
||||
/// See also runtime refinement \ref RAIL_ZWAVE_SupportsRegionPti().
|
||||
#if 1
|
||||
#define RAIL_ZWAVE_SUPPORTS_REGION_PTI RAIL_SUPPORTS_PROTOCOL_ZWAVE
|
||||
#else
|
||||
#define RAIL_ZWAVE_SUPPORTS_REGION_PTI 0
|
||||
#endif
|
||||
/// Backwards-compatible synonym of \ref RAIL_ZWAVE_SUPPORTS_REGION_PTI.
|
||||
#define RAIL_FEAT_ZWAVE_REGION_PTI RAIL_ZWAVE_SUPPORTS_REGION_PTI
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports raw RX data
|
||||
/// sources other than \ref RAIL_RxDataSource_t::RX_PACKET_DATA.
|
||||
/// See also runtime refinement \ref RAIL_SupportsRxRawData().
|
||||
#if 1
|
||||
#define RAIL_SUPPORTS_RX_RAW_DATA 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RX_RAW_DATA 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// direct mode.
|
||||
/// See also runtime refinement \ref RAIL_SupportsDirectMode().
|
||||
#if ((_SILICON_LABS_32B_SERIES == 1) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 3))
|
||||
#define RAIL_SUPPORTS_DIRECT_MODE 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_DIRECT_MODE 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// RX direct mode data to FIFO.
|
||||
/// See also runtime refinement \ref RAIL_SupportsRxDirectModeDataToFifo().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_SUPPORTS_RX_DIRECT_MODE_DATA_TO_FIFO 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RX_DIRECT_MODE_DATA_TO_FIFO 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// MFM protocol.
|
||||
/// See also runtime refinement \ref RAIL_SupportsMfm().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3)
|
||||
#define RAIL_SUPPORTS_MFM 1
|
||||
#else
|
||||
#define RAIL_SUPPORTS_MFM 0
|
||||
#endif
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 4)
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// 802.15.4 signal detection
|
||||
#define RAIL_IEEE802154_SUPPORTS_SIGNAL_IDENTIFIER (RAIL_SUPPORTS_PROTOCOL_IEEE802154)
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// BLE signal detection
|
||||
#define RAIL_BLE_SUPPORTS_SIGNAL_IDENTIFIER (RAIL_SUPPORTS_PROTOCOL_BLE)
|
||||
#else
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// 802.15.4 signal detection
|
||||
#define RAIL_IEEE802154_SUPPORTS_SIGNAL_IDENTIFIER 0
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// BLE signal detection
|
||||
#define RAIL_BLE_SUPPORTS_SIGNAL_IDENTIFIER 0
|
||||
#endif
|
||||
|
||||
/// Boolean to indicate whether the selected chip supports
|
||||
/// configurable RSSI threshold set by \ref RAIL_SetRssiDetectThreshold().
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 3) \
|
||||
|| (_SILICON_LABS_32B_SERIES_2_CONFIG == 5)
|
||||
#define RAIL_SUPPORTS_RSSI_DETECT_THRESHOLD (1U)
|
||||
#else
|
||||
#define RAIL_SUPPORTS_RSSI_DETECT_THRESHOLD (0U)
|
||||
#endif
|
||||
|
||||
/** @} */ // end of group Features
|
||||
|
||||
/** @} */ // end of group RAIL_API
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __RAIL_FEATURES_H__
|
|
@ -0,0 +1,193 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief The MFM specific header file for the RAIL library.
|
||||
*******************************************************************************
|
||||
* # 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 __RAIL_MFM_H__
|
||||
#define __RAIL_MFM_H__
|
||||
|
||||
#include "rail_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @addtogroup MFM Multi-Level Frequency Modulation
|
||||
/// @ingroup Protocol_Specific
|
||||
/// @brief MFM configuration routines
|
||||
/// Note that this feature is only supported on EFR32xG23 devices.
|
||||
///
|
||||
/// This feature can be used to directly control the TX interpolation filter
|
||||
/// input to allow for a more flexible frequency modulation scheme than the
|
||||
/// standard MODEM. When doing this, the MFM buffer is treated as an array
|
||||
/// of 8-bit signed data used as normalized frequency deviation to the SYNTH
|
||||
/// frequency to directly control the interpolation filter input.
|
||||
/// No support for frame handling, coding, nor shaping is supported.
|
||||
/// Only compatible with FSK modulations.
|
||||
///
|
||||
/// The functions in this group configure RAIL Multi-Level Frequency Modulation (MFM)
|
||||
/// hardware acceleration features.
|
||||
///
|
||||
/// To configure MFM functionality, the application must first set up
|
||||
/// a RAIL instance with \ref RAIL_Init() and other setup functions.
|
||||
/// Before enabling MFM, a ping-pong buffer (called buffer0 and buffer1
|
||||
/// below) must be configured via \ref RAIL_SetMfmPingPongFifo() and
|
||||
/// populated with the initial buffer content.
|
||||
/// MFM is enabled by setting \ref RAIL_TxDataSource_t::TX_MFM_DATA using
|
||||
/// \ref RAIL_ConfigData() and is activated when transmit is started by
|
||||
/// \ref RAIL_StartTx(). Once transmitting the data in the ping-pong buffers,
|
||||
/// RAIL will manage them so it looks like a continuous transmission to the
|
||||
/// receiver. Every time one of the ping-ping buffers has been transmitted,
|
||||
/// \ref RAIL_EVENT_MFM_TX_BUFFER_DONE is triggered so the application can
|
||||
/// update the data in that buffer without the need to start/stop the
|
||||
/// transmission. \ref RAIL_EVENT_MFM_TX_BUFFER_DONE can be enable with \ref
|
||||
/// RAIL_ConfigEvents().
|
||||
/// Use \ref RAIL_StopTx() to finish transmitting.
|
||||
///
|
||||
/// @code{.c}
|
||||
///
|
||||
/// uint8_t txCount = 0;
|
||||
///
|
||||
/// typedef struct RAIL_MFM_Config_App {
|
||||
/// RAIL_MFM_PingPongBufferConfig_t buffer;
|
||||
/// RAIL_StateTiming_t timings;
|
||||
/// } RAIL_MFM_Config_App_t;
|
||||
///
|
||||
/// // Main RAIL_EVENT callback
|
||||
/// static void RAILCb_Event(RAIL_Handle_t railHandle, RAIL_Events_t events)
|
||||
/// {
|
||||
/// // Increment TX counter
|
||||
/// if (events & RAIL_EVENT_MFM_BUF_DONE) {
|
||||
/// txCount++;
|
||||
/// return;
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// static const RAIL_MFM_Config_App_t mfmConfig = {
|
||||
/// .buffer = {
|
||||
/// .pBuffer0 = (&channelHoppingBufferSpace[0]),
|
||||
/// .pBuffer1 = (&channelHoppingBufferSpace[MFM_RAW_BUF_SZ_BYTES / 4]),
|
||||
/// .bufferSizeWords = (MFM_RAW_BUF_SZ_BYTES / 4)
|
||||
/// },
|
||||
/// .timings = {
|
||||
/// .idleToTx = 100,
|
||||
/// .idleToRx = 0,
|
||||
/// .rxToTx = 0,
|
||||
/// .txToRx = 0,
|
||||
/// .rxSearchTimeout = 0,
|
||||
/// .txToRxSearchTimeout = 0
|
||||
/// };
|
||||
///
|
||||
/// RAIL_Status_t mfmInit(void)
|
||||
/// {
|
||||
/// // initialize MFM
|
||||
/// uint32_t idx;
|
||||
/// uint32_t *pDst0 = mfmConfig.pBuffer0;
|
||||
/// uint32_t *pDst1 = mfmConfig.pBuffer1;
|
||||
/// RAIL_Status_t status;
|
||||
/// for (idx = 0; idx < (MFM_RAW_BUF_SZ_BYTES / 16); idx++) {
|
||||
/// pDst0[4 * idx + 0] = 0x755A3100;
|
||||
/// pDst1[4 * idx + 0] = 0x755A3100;
|
||||
/// pDst0[4 * idx + 1] = 0x315A757F;
|
||||
/// pDst1[4 * idx + 1] = 0x315A757F;
|
||||
/// pDst0[4 * idx + 2] = 0x8BA6CF00;
|
||||
/// pDst1[4 * idx + 2] = 0x8BA6CF00;
|
||||
/// pDst0[4 * idx + 3] = 0xCFA68B81;
|
||||
/// pDst1[4 * idx + 3] = 0xCFA68B81;
|
||||
/// }
|
||||
///
|
||||
/// RAIL_Status_t status;
|
||||
/// railDataConfig.txSource = TX_MFM_DATA;
|
||||
/// status = RAIL_SetMfmPingPongFifo(railHandle,
|
||||
/// &(config->buffer));
|
||||
/// if (status != RAIL_STATUS_NO_ERROR) {
|
||||
/// return (status);
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// status = RAIL_ConfigData(railHandle, &railDataConfig);
|
||||
/// if (status != RAIL_STATUS_NO_ERROR) {
|
||||
/// return (status);
|
||||
/// }
|
||||
///
|
||||
/// status = RAIL_SetStateTiming(railHandle, &(config->timings));
|
||||
/// if (status != RAIL_STATUS_NO_ERROR) {
|
||||
/// return (status);
|
||||
/// }
|
||||
///
|
||||
/// // start transmitting
|
||||
/// return (RAIL_StartTx(railHandle, 0, 0, &schedulerInfo));
|
||||
/// }
|
||||
///
|
||||
/// RAIL_Status_t mfmDeInit(void)
|
||||
/// {
|
||||
/// RAIL_Status_t status;
|
||||
/// status = RAIL_StopTx(railHandle, RAIL_STOP_MODES_ALL);
|
||||
/// if (status != RAIL_STATUS_NO_ERROR) {
|
||||
/// return (status);
|
||||
/// }
|
||||
///
|
||||
/// railDataConfig.txSource = TX_PACKET_DATA;
|
||||
/// return (RAIL_ConfigData(railHandle, &railDataConfig));
|
||||
/// }
|
||||
/// @endcode
|
||||
///
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* @struct RAIL_MFM_PingPongBufferConfig_t
|
||||
* @brief A configuration structure for MFM Ping-pong buffer in RAIL.
|
||||
*/
|
||||
typedef struct RAIL_MFM_PingPongBufferConfig {
|
||||
/** pointer to buffer0. Must be 32-bit aligned. */
|
||||
uint32_t *pBuffer0;
|
||||
/** pointer to buffer1. Must be 32-bit aligned. */
|
||||
uint32_t *pBuffer1;
|
||||
/** size of each buffer A and B in 32-bit words. */
|
||||
uint32_t bufferSizeWords;
|
||||
} RAIL_MFM_PingPongBufferConfig_t;
|
||||
|
||||
/**
|
||||
* Set MFM ping-pong buffer.
|
||||
*
|
||||
* @param[in] railHandle A handle of RAIL instance.
|
||||
* @param[in] config A MFM ping-pong buffer configuration structure.
|
||||
* @return A status code indicating success of the function call.
|
||||
*
|
||||
*/
|
||||
RAIL_Status_t RAIL_SetMfmPingPongFifo(RAIL_Handle_t railHandle,
|
||||
const RAIL_MFM_PingPongBufferConfig_t *config);
|
||||
|
||||
/** @} */ // end of MFM
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __RAIL_MFM_H__
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Power Amplifier configuration file.
|
||||
*******************************************************************************
|
||||
* # 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_RAIL_UTIL_PA_CONFIG_H
|
||||
#define SL_RAIL_UTIL_PA_CONFIG_H
|
||||
|
||||
#include "rail_types.h"
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <h> PA Configuration
|
||||
// <o SL_RAIL_UTIL_PA_POWER_DECI_DBM> Initial PA Power (deci-dBm, 100 = 10.0 dBm)
|
||||
// <i> Default: 100
|
||||
#define SL_RAIL_UTIL_PA_POWER_DECI_DBM 100
|
||||
|
||||
// <o SL_RAIL_UTIL_PA_RAMP_TIME_US> PA Ramp Time (microseconds)
|
||||
// <0-65535:1>
|
||||
// <i> Default: 2
|
||||
#define SL_RAIL_UTIL_PA_RAMP_TIME_US 2
|
||||
// <o SL_RAIL_UTIL_PA_VOLTAGE_MV> Milli-volts on PA supply pin (PA_VDD)
|
||||
// <0-65535:1>
|
||||
// <i> Default: 3300
|
||||
#define SL_RAIL_UTIL_PA_VOLTAGE_MV 3300
|
||||
// <o SL_RAIL_UTIL_PA_SELECTION_2P4GHZ> 2.4 GHz PA Selection
|
||||
// <RAIL_TX_POWER_MODE_2P4GIG_HIGHEST=> Highest Possible
|
||||
// <RAIL_TX_POWER_MODE_2P4GIG_HP=> High Power (chip-specific)
|
||||
// <RAIL_TX_POWER_MODE_2P4GIG_LP=> Low Power
|
||||
// <RAIL_TX_POWER_MODE_NONE=> Disable
|
||||
// <i> Default: RAIL_TX_POWER_MODE_2P4GIG_HIGHEST
|
||||
#define SL_RAIL_UTIL_PA_SELECTION_2P4GHZ RAIL_TX_POWER_MODE_2P4GIG_HIGHEST
|
||||
// <o SL_RAIL_UTIL_PA_SELECTION_SUBGHZ> Sub-1 GHz PA Selection
|
||||
// <RAIL_TX_POWER_MODE_NONE=> Disable
|
||||
// <i> Default: RAIL_TX_POWER_MODE_NONE
|
||||
#define SL_RAIL_UTIL_PA_SELECTION_SUBGHZ RAIL_TX_POWER_MODE_NONE
|
||||
// </h>
|
||||
|
||||
// <h> PA Curve Configuration
|
||||
// <s.50 SL_RAIL_UTIL_PA_CURVE_HEADER> Header file containing custom PA curves
|
||||
// <i> Default: "pa_curves_efr32.h"
|
||||
#define SL_RAIL_UTIL_PA_CURVE_HEADER "pa_curves_efr32.h"
|
||||
// <s.50 SL_RAIL_UTIL_PA_CURVE_TYPES> Header file containing PA curve types
|
||||
// <i> Default: "pa_curve_types_efr32.h"
|
||||
#define SL_RAIL_UTIL_PA_CURVE_TYPES "pa_curve_types_efr32.h"
|
||||
// </h>
|
||||
|
||||
// <h> PA Calibration Configuration
|
||||
// <q SL_RAIL_UTIL_PA_CALIBRATION_ENABLE> Apply PA Calibration Factory Offset
|
||||
// <i> Default: 1
|
||||
#define SL_RAIL_UTIL_PA_CALIBRATION_ENABLE 1
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_RAIL_UTIL_PA_CONFIG_H
|
|
@ -0,0 +1,117 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion curves used by Silicon Labs PA power conversion
|
||||
* functions.
|
||||
* @details This file contains the curves needed convert PA power levels to
|
||||
* dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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 __PA_CURVES_H_
|
||||
#define __PA_CURVES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RAIL_PA_CURVES_PIECEWISE_SEGMENTS (9U)
|
||||
#define RAIL_PA_CURVES_LP_VALUES (16U)
|
||||
|
||||
#define RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER 85
|
||||
#define RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER -275
|
||||
//Curve is generated by Max power (in dBm) = 10, increment(in dBm) = 3, segments = 8
|
||||
#define RAIL_PA_CURVES_2P4_HP_VBAT_CURVES \
|
||||
{ { 255, 100, 30 }, \
|
||||
{ 127, 3355, -171056 }, \
|
||||
{ 54, 951, -9651 }, \
|
||||
{ 28, 345, 14060 }, \
|
||||
{ 17, 189, 15304 }, \
|
||||
{ 11, 113, 13588 }, \
|
||||
{ 7, 73, 11317 }, \
|
||||
{ 5, 55, 9733 }, \
|
||||
{ 3, 20, 5375 } }
|
||||
|
||||
#define RAIL_PA_CURVES_2P4_LP_VBAT_MAX_POWER 0
|
||||
#define RAIL_PA_CURVES_2P4_LP_VBAT_MIN_POWER -163
|
||||
#define RAIL_PA_CURVES_2P4_LP_VBAT_CURVES \
|
||||
{ \
|
||||
-287, /*! Power Level 0 */ \
|
||||
-167, /*! Power Level 1 */ \
|
||||
-113, /*! Power Level 2 */ \
|
||||
-83, /*! Power Level 3 */ \
|
||||
-63, /*! Power Level 4 */ \
|
||||
-48, /*! Power Level 5 */ \
|
||||
-36, /*! Power Level 6 */ \
|
||||
-28, /*! Power Level 7 */ \
|
||||
-21, /*! Power Level 8 */ \
|
||||
-14, /*! Power Level 9 */ \
|
||||
-10, /*! Power Level 10 */ \
|
||||
-6, /*! Power Level 11 */ \
|
||||
-3, /*! Power Level 12 */ \
|
||||
0, /*! Power Level 13 */ \
|
||||
3, /*! Power Level 14 */ \
|
||||
5, /*! Power Level 15 */ \
|
||||
}
|
||||
// *INDENT-OFF*
|
||||
// Macro to declare the variables needed to initialize RAIL_TxPowerCurvesConfig_t for use in
|
||||
// RAIL_InitTxPowerCurves, assuming battery powered operation
|
||||
#define RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT \
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHp = { \
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER, \
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER, \
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_CURVES, \
|
||||
}; \
|
||||
static const int16_t RAIL_curves24Lp[RAIL_PA_CURVES_LP_VALUES] = \
|
||||
RAIL_PA_CURVES_2P4_LP_VBAT_CURVES;
|
||||
// *INDENT-OFF*
|
||||
|
||||
#define RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT \
|
||||
{ \
|
||||
.curves = { \
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR, \
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX, \
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHp }, \
|
||||
}, \
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE, \
|
||||
.segments = 0U, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX, \
|
||||
.conversion = { .mappingTable = &RAIL_curves24Lp[0] }, \
|
||||
}, \
|
||||
} \
|
||||
}
|
||||
// *INDENT-OFF*
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,529 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion functions provided to the customer as source for
|
||||
* highest level of customization.
|
||||
* @details This file contains the curves and logic that convert PA power
|
||||
* levels to dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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"
|
||||
#include "em_cmu.h"
|
||||
#include "pa_conversions_efr32.h"
|
||||
#include "rail.h"
|
||||
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
static RAIL_TxPowerCurvesConfigAlt_t powerCurvesState;
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_1) || defined(_SILICON_LAS_32B_SERIES_2_CONFIG_1)
|
||||
#define PA_CONVERSION_MINIMUM_PWRLVL 1
|
||||
#else
|
||||
#define PA_CONVERSION_MINIMUM_PWRLVL 0
|
||||
#endif
|
||||
/* For details on how to use this plugin, see
|
||||
https://www.silabs.com/documents/public/application-notes/an1127-power-amplifier-power-conversion-functions.pdf
|
||||
|
||||
This macro is defined when Silicon Labs builds this into the library as WEAK
|
||||
to ensure it can be overriden by customer versions of these functions. The macro
|
||||
should *not* be defined in a customer build. */
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurves_t *RAIL_GetTxPowerCurve(RAIL_TxPowerMode_t mode)
|
||||
{
|
||||
static RAIL_TxPowerCurves_t powerCurves;
|
||||
|
||||
// Check for an invalid Tx power mode
|
||||
if (mode >= RAIL_TX_POWER_MODE_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
RAIL_Handle_t railHandle = RAIL_EFR32_HANDLE;
|
||||
RAIL_TxPowerLevel_t maxPowerLevel, minPowerLevel;
|
||||
if (RAIL_SupportsTxPowerModeAlt(railHandle,
|
||||
&mode,
|
||||
&maxPowerLevel,
|
||||
&minPowerLevel) == false) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RAIL_TxPowerCurveAlt_t const *curve =
|
||||
powerCurvesState.curves[mode].conversion.powerCurve;
|
||||
|
||||
// Check for an invalid power curve
|
||||
if (curve == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
powerCurves.maxPower = curve->maxPower;
|
||||
powerCurves.minPower = curve->minPower;
|
||||
powerCurves.powerParams = &curve->powerParams[0];
|
||||
return &powerCurves;
|
||||
}
|
||||
|
||||
// This function will not be supported for any parts after efr32xg1x
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
RAIL_Status_t RAIL_InitTxPowerCurves(const RAIL_TxPowerCurvesConfig_t *config)
|
||||
{
|
||||
#ifdef _SILICON_LABS_32B_SERIES_1
|
||||
// First PA is 2.4 GHz high power, using a piecewise fit
|
||||
RAIL_PaDescriptor_t *current =
|
||||
&powerCurvesState.curves[RAIL_TX_POWER_MODE_2P4_HP];
|
||||
current->algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR;
|
||||
current->segments = config->piecewiseSegments;
|
||||
current->min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN;
|
||||
current->max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX;
|
||||
static RAIL_TxPowerCurveAlt_t txPower2p4 = {
|
||||
.minPower = 0U,
|
||||
.maxPower = 0U,
|
||||
.powerParams = { // The current max number of piecewise segments is 8
|
||||
{ 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U },
|
||||
{ 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U },
|
||||
}
|
||||
};
|
||||
txPower2p4.maxPower = config->txPowerSgCurves->maxPower;
|
||||
txPower2p4.minPower = config->txPowerSgCurves->minPower;
|
||||
memcpy(&txPower2p4.powerParams[0],
|
||||
config->txPowerSgCurves->powerParams,
|
||||
config->piecewiseSegments * sizeof(RAIL_TxPowerCurveSegment_t));
|
||||
current->conversion.powerCurve = &txPower2p4;
|
||||
|
||||
// Second PA is 2.4 GHz low power, using a mapping table
|
||||
current = &powerCurvesState.curves[RAIL_TX_POWER_MODE_2P4_LP];
|
||||
current->algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE;
|
||||
current->segments = 0U;
|
||||
current->min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN;
|
||||
current->max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX;
|
||||
current->conversion.mappingTable = config->txPower24LpCurves;
|
||||
|
||||
// Third and final PA is Sub-GHz, using a piecewise fit
|
||||
current = &powerCurvesState.curves[RAIL_TX_POWER_MODE_SUBGIG];
|
||||
current->algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR;
|
||||
current->segments = config->piecewiseSegments;
|
||||
current->min = RAIL_TX_POWER_LEVEL_SUBGIG_MIN;
|
||||
current->max = RAIL_TX_POWER_LEVEL_SUBGIG_HP_MAX;
|
||||
static RAIL_TxPowerCurveAlt_t txPowerSubGig = {
|
||||
.minPower = 0U,
|
||||
.maxPower = 0U,
|
||||
.powerParams = { // The current max number of piecewise segments is 8
|
||||
{ 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U },
|
||||
{ 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U }, { 0U, 0U, 0U },
|
||||
}
|
||||
};
|
||||
txPowerSubGig.maxPower = config->txPowerSgCurves->maxPower;
|
||||
txPowerSubGig.minPower = config->txPowerSgCurves->minPower;
|
||||
memcpy(&txPowerSubGig.powerParams[0],
|
||||
config->txPowerSgCurves->powerParams,
|
||||
config->piecewiseSegments * sizeof(RAIL_TxPowerCurveSegment_t));
|
||||
current->conversion.powerCurve = &txPowerSubGig;
|
||||
|
||||
return RAIL_STATUS_NO_ERROR;
|
||||
#else
|
||||
(void) config;
|
||||
return RAIL_STATUS_INVALID_CALL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
RAIL_Status_t RAIL_InitTxPowerCurvesAlt(const RAIL_TxPowerCurvesConfigAlt_t *config)
|
||||
{
|
||||
RAIL_VerifyTxPowerCurves(config);
|
||||
|
||||
powerCurvesState = *config;
|
||||
|
||||
return RAIL_STATUS_NO_ERROR;
|
||||
}
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
RAIL_TxPowerLevel_t RAIL_ConvertDbmToRaw(RAIL_Handle_t railHandle,
|
||||
RAIL_TxPowerMode_t mode,
|
||||
RAIL_TxPower_t power)
|
||||
{
|
||||
uint32_t powerLevel;
|
||||
uint32_t powerIndex = 0U;
|
||||
uint32_t minPowerLevel;
|
||||
|
||||
(void)railHandle;
|
||||
// This function is called internally from the RAIL library,
|
||||
// so if the user never calls RAIL_InitTxPowerCurves - even
|
||||
// if they never intend to use dBm values in their code -
|
||||
// they'll always hit the assert below. Give the user a way
|
||||
// to not have to call RAIL_InitTxPowerCurves if they don't
|
||||
// care about dBm values by picking a dBm value that returns the
|
||||
// highest RAIL_TxPowerLevel_t possible. In other words, when
|
||||
// a channel dBm limitation greater than or equal to \ref RAIL_TX_POWER_MAX
|
||||
// is converted to raw units, the max RAIL_TxPowerLevel_t will be
|
||||
// returned. When compared to the current power level of the PA,
|
||||
// it will always be greater, indicating that no power coercion
|
||||
// is necessary to comply with channel limitations.
|
||||
if (power >= RAIL_TX_POWER_MAX) {
|
||||
return 255U;
|
||||
}
|
||||
|
||||
// Check for an invalid Tx power mode
|
||||
if (mode >= RAIL_TX_POWER_MODE_NONE) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
RAIL_PaDescriptor_t const *modeInfo = &powerCurvesState.curves[mode];
|
||||
minPowerLevel = MAX(modeInfo->min, PA_CONVERSION_MINIMUM_PWRLVL);
|
||||
|
||||
// If we're in low power mode, just use the simple lookup table
|
||||
if (modeInfo->algorithm == RAIL_PA_ALGORITHM_MAPPING_TABLE) {
|
||||
// Binary search through the lookup table to find the closest power level
|
||||
// without going over.
|
||||
uint32_t lower = 0U;
|
||||
// Track the high side of the estimate
|
||||
powerIndex = modeInfo->max - minPowerLevel;
|
||||
|
||||
while (lower < powerIndex) {
|
||||
// Calculate the midpoint of the current range
|
||||
uint32_t index = powerIndex - (powerIndex - lower) / 2U;
|
||||
if (power < modeInfo->conversion.mappingTable[index]) {
|
||||
powerIndex = index - 1U;
|
||||
} else {
|
||||
lower = index;
|
||||
}
|
||||
}
|
||||
return powerIndex + minPowerLevel;
|
||||
}
|
||||
|
||||
// Here we know we're using the piecewise linear conversion
|
||||
RAIL_TxPowerCurveAlt_t const *paParams = modeInfo->conversion.powerCurve;
|
||||
|
||||
// Check for valid paParams before using them
|
||||
if (paParams == NULL) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
// Cap the power based on the PA settings.
|
||||
if (power > paParams->maxPower) {
|
||||
// If we go above the maximum dbm the chip supports
|
||||
// Then provide maximum powerLevel
|
||||
power = paParams->maxPower;
|
||||
} else if (power < paParams->minPower) {
|
||||
// If we go below the minimum we want included in the curve fit, force it.
|
||||
power = paParams->minPower;
|
||||
} else {
|
||||
}
|
||||
// Map the power value to a 0 - 7 powerIndex value
|
||||
//There are 8 segments of step size of RAIL_TX_POWER_CURVE_INCREMENT in deci dBm
|
||||
//starting from maximum RAIL_TX_POWER_CURVE_MAX in deci dBm
|
||||
// These are just starting points to give the code
|
||||
// a rough idea of which segment to use, based on
|
||||
// how they were fit. Adjustments are made later on
|
||||
// if this turns out to be incorrect.
|
||||
RAIL_TxPower_t txPowerMax = RAIL_TX_POWER_CURVE_DEFAULT_MAX;
|
||||
RAIL_TxPower_t txPowerIncrement = RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT;
|
||||
// if the first curve segment starts with RAIL_TX_POWER_LEVEL_INVALID
|
||||
//It is an extra curve segment to depict the maxpower and increment
|
||||
// (in deci-dBm) used while generating the curves.
|
||||
// The extra segment is only present when curve segment is generated by
|
||||
//using values different than the default - RAIL_TX_POWER_CURVE_DEFAULT_MAX
|
||||
// and RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT.
|
||||
if ((paParams->powerParams[0].maxPowerLevel) == RAIL_TX_POWER_LEVEL_INVALID) {
|
||||
powerIndex += 1U;
|
||||
txPowerMax = paParams->powerParams[0].slope;
|
||||
txPowerIncrement = paParams->powerParams[0].intercept;
|
||||
}
|
||||
|
||||
powerIndex += ((txPowerMax - power) / txPowerIncrement);
|
||||
if (powerIndex > (modeInfo->segments - 1U)) {
|
||||
powerIndex = (modeInfo->segments - 1U);
|
||||
}
|
||||
|
||||
do {
|
||||
// Select the correct piecewise segment to use for conversion.
|
||||
RAIL_TxPowerCurveSegment_t const *powerParams =
|
||||
&paParams->powerParams[powerIndex];
|
||||
|
||||
// powerLevel can only go down to 0.
|
||||
if (powerParams->intercept + powerParams->slope * power < 0) {
|
||||
powerLevel = 0U;
|
||||
} else {
|
||||
powerLevel = powerParams->intercept + powerParams->slope * power;
|
||||
}
|
||||
|
||||
// Add 500 to do rounding correctly, as opposed to just rounding towards 0
|
||||
powerLevel = ((powerLevel + 500U) / 1000U);
|
||||
|
||||
// In case it turns out the resultant power level was too low and we have
|
||||
// to recalculate with the next curve...
|
||||
powerIndex++;
|
||||
} while ((powerIndex < modeInfo->segments)
|
||||
&& (powerLevel <= paParams->powerParams[powerIndex].maxPowerLevel));
|
||||
|
||||
// We already know that powerIndex is at most modeInfo->segments
|
||||
if (powerLevel > paParams->powerParams[powerIndex - 1U].maxPowerLevel) {
|
||||
powerLevel = paParams->powerParams[powerIndex - 1U].maxPowerLevel;
|
||||
}
|
||||
|
||||
// If we go below the minimum we want included in the curve fit, force it.
|
||||
if (powerLevel < minPowerLevel) {
|
||||
powerLevel = minPowerLevel;
|
||||
}
|
||||
|
||||
return (RAIL_TxPowerLevel_t)powerLevel;
|
||||
}
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
RAIL_TxPower_t RAIL_ConvertRawToDbm(RAIL_Handle_t railHandle,
|
||||
RAIL_TxPowerMode_t mode,
|
||||
RAIL_TxPowerLevel_t powerLevel)
|
||||
{
|
||||
(void)railHandle;
|
||||
|
||||
// Check for an invalid Tx power mode
|
||||
if (mode >= RAIL_TX_POWER_MODE_NONE) {
|
||||
return RAIL_TX_POWER_MIN;
|
||||
}
|
||||
|
||||
RAIL_PaDescriptor_t const *modeInfo = &powerCurvesState.curves[mode];
|
||||
|
||||
if (modeInfo->algorithm == RAIL_PA_ALGORITHM_MAPPING_TABLE) {
|
||||
// Limit the max power level
|
||||
if (powerLevel > modeInfo->max) {
|
||||
powerLevel = modeInfo->max;
|
||||
}
|
||||
|
||||
// We 1-index low power PA power levels, but of course arrays are 0 indexed
|
||||
powerLevel -= MAX(modeInfo->min, PA_CONVERSION_MINIMUM_PWRLVL);
|
||||
|
||||
//If the index calculation above underflowed, then provide the lowest array index.
|
||||
if (powerLevel > (modeInfo->max - modeInfo->min)) {
|
||||
powerLevel = 0U;
|
||||
}
|
||||
return modeInfo->conversion.mappingTable[powerLevel];
|
||||
} else {
|
||||
#if defined(_SILICON_LABS_32B_SERIES_1) || defined(_SILICON_LAS_32B_SERIES_2_CONFIG_1)
|
||||
// Although 0 is a legitimate power on non-2.4 LP PA's and can be set via
|
||||
// "RAIL_SetTxPower(railHandle, 0)" it is MUCH lower than power
|
||||
// level 1 (approximately -50 dBm). Including it in the piecewise
|
||||
// linear fit would skew the curve substantially, so we exclude it
|
||||
// from the conversion.
|
||||
if (powerLevel == 0U) {
|
||||
return -500;
|
||||
}
|
||||
#endif
|
||||
|
||||
RAIL_TxPowerCurveAlt_t const *powerCurve = modeInfo->conversion.powerCurve;
|
||||
// Check for a valid powerCurve pointer before using it
|
||||
if (powerCurve == NULL) {
|
||||
return RAIL_TX_POWER_MIN;
|
||||
}
|
||||
|
||||
RAIL_TxPowerCurveSegment_t const *powerParams = powerCurve->powerParams;
|
||||
// Check for a valid powerParams pointer before using it
|
||||
if (powerParams == NULL) {
|
||||
return RAIL_TX_POWER_MIN;
|
||||
}
|
||||
|
||||
// Hard code the extremes (i.e. don't use the curve fit) in order
|
||||
// to make it clear that we are reaching the extent of the chip's
|
||||
// capabilities
|
||||
if (powerLevel <= modeInfo->min) {
|
||||
return powerCurve->minPower;
|
||||
} else if (powerLevel >= modeInfo->max) {
|
||||
return powerCurve->maxPower;
|
||||
} else {
|
||||
}
|
||||
|
||||
// Figure out which parameter to use based on the power level
|
||||
uint8_t x = 0;
|
||||
uint8_t upperBound = modeInfo->segments - 1U;
|
||||
|
||||
// If the first curve segment starts with RAIL_TX_POWER_LEVEL_INVALID,
|
||||
// then it is an additional curve segment that stores maxpower and increment
|
||||
// (in deci-dBm) used to generate the curves.
|
||||
// The extra info segment is present only if the curves were generated using
|
||||
// values other than default - RAIL_TX_POWER_CURVE_DEFAULT_MAX and
|
||||
// RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT.
|
||||
if ((powerParams[0].maxPowerLevel) == RAIL_TX_POWER_LEVEL_INVALID) {
|
||||
x = 1U; // skip over the first entry
|
||||
}
|
||||
|
||||
for (; x < upperBound; x++) {
|
||||
if (powerParams[x + 1U].maxPowerLevel < powerLevel) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int32_t power;
|
||||
power = ((1000 * (int32_t)(powerLevel)) - powerParams[x].intercept);
|
||||
power = ((power + (powerParams[x].slope / 2)) / powerParams[x].slope);
|
||||
|
||||
if (power > powerCurve->maxPower) {
|
||||
return powerCurve->maxPower;
|
||||
} else if (power < powerCurve->minPower) {
|
||||
return powerCurve->minPower;
|
||||
} else {
|
||||
return (RAIL_TxPower_t)power;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
RAIL_Status_t RAIL_GetTxPowerCurveLimits(RAIL_Handle_t railHandle,
|
||||
RAIL_TxPowerMode_t mode,
|
||||
RAIL_TxPower_t *maxPower,
|
||||
RAIL_TxPower_t *increment)
|
||||
{
|
||||
(void)railHandle;
|
||||
// Check for an invalid Tx power mode
|
||||
if (mode >= RAIL_TX_POWER_MODE_NONE) {
|
||||
return RAIL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
//The power max info only for available Linear fit
|
||||
RAIL_PaDescriptor_t const *modeInfo = &powerCurvesState.curves[mode];
|
||||
if (modeInfo->algorithm == RAIL_PA_ALGORITHM_MAPPING_TABLE) {
|
||||
return RAIL_STATUS_INVALID_CALL;
|
||||
}
|
||||
*maxPower = RAIL_TX_POWER_CURVE_DEFAULT_MAX;
|
||||
*increment = RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT;
|
||||
RAIL_TxPowerCurveAlt_t const *paParams = modeInfo->conversion.powerCurve;
|
||||
if ((paParams->powerParams[0].maxPowerLevel) == RAIL_TX_POWER_LEVEL_INVALID) {
|
||||
*maxPower = paParams->powerParams[0].slope;
|
||||
*increment = (RAIL_TxPower_t)paParams->powerParams[0].intercept;
|
||||
}
|
||||
return RAIL_STATUS_NO_ERROR;
|
||||
}
|
||||
|
||||
// This macro is defined when Silicon Labs builds curves into the library as WEAK
|
||||
// to ensure it can be overriden by customer versions of these functions. It
|
||||
// should *not* be defined in a customer build.
|
||||
#if !defined(RAIL_PA_CONVERSIONS_WEAK) && !defined(HAL_CONFIG)
|
||||
|
||||
#include "sl_rail_util_pa_config.h"
|
||||
|
||||
void sl_rail_util_pa_init(void)
|
||||
{
|
||||
#if SL_RAIL_UTIL_PA_VOLTAGE_MV > 1800
|
||||
(void)RAIL_InitTxPowerCurvesAlt(&RAIL_TxPowerCurvesVbat);
|
||||
#else
|
||||
(void)RAIL_InitTxPowerCurvesAlt(&RAIL_TxPowerCurvesDcdc);
|
||||
#endif
|
||||
#if SL_RAIL_UTIL_PA_CALIBRATION_ENABLE
|
||||
RAIL_EnablePaCal(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if RAIL_SUPPORTS_2P4GHZ_BAND
|
||||
static RAIL_TxPowerConfig_t txPowerConfig2p4Ghz = {
|
||||
.mode = SL_RAIL_UTIL_PA_SELECTION_2P4GHZ,
|
||||
.voltage = SL_RAIL_UTIL_PA_VOLTAGE_MV,
|
||||
.rampTime = SL_RAIL_UTIL_PA_RAMP_TIME_US,
|
||||
};
|
||||
#endif
|
||||
RAIL_TxPowerConfig_t *sl_rail_util_pa_get_tx_power_config_2p4ghz(void)
|
||||
{
|
||||
#if RAIL_SUPPORTS_2P4GHZ_BAND
|
||||
return &txPowerConfig2p4Ghz;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
#if RAIL_SUPPORTS_SUBGHZ_BAND
|
||||
static RAIL_TxPowerConfig_t txPowerConfigSubGhz = {
|
||||
.mode = SL_RAIL_UTIL_PA_SELECTION_SUBGHZ,
|
||||
.voltage = SL_RAIL_UTIL_PA_VOLTAGE_MV,
|
||||
.rampTime = SL_RAIL_UTIL_PA_RAMP_TIME_US,
|
||||
};
|
||||
#endif
|
||||
RAIL_TxPowerConfig_t *sl_rail_util_pa_get_tx_power_config_subghz(void)
|
||||
{
|
||||
#if RAIL_SUPPORTS_SUBGHZ_BAND
|
||||
return &txPowerConfigSubGhz;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void sl_rail_util_pa_on_channel_config_change(RAIL_Handle_t rail_handle,
|
||||
const RAIL_ChannelConfigEntry_t *entry)
|
||||
{
|
||||
if (!RAIL_IsPaAutoModeEnabled(rail_handle)) {
|
||||
RAIL_TxPowerConfig_t currentTxPowerConfig;
|
||||
RAIL_TxPowerConfig_t *newTxPowerConfigPtr;
|
||||
RAIL_TxPower_t txPowerDeciDbm;
|
||||
RAIL_Status_t status;
|
||||
|
||||
// Get current TX Power Config.
|
||||
status = RAIL_GetTxPowerConfig(rail_handle, ¤tTxPowerConfig);
|
||||
if (status != RAIL_STATUS_NO_ERROR) {
|
||||
while (true) {
|
||||
} // Error: Can't get TX Power Config
|
||||
}
|
||||
|
||||
#if RAIL_SUPPORTS_DUAL_BAND
|
||||
// Determine new TX Power Config.
|
||||
if (entry->baseFrequency < 1000000000UL) {
|
||||
newTxPowerConfigPtr = &txPowerConfigSubGhz;
|
||||
} else {
|
||||
newTxPowerConfigPtr = &txPowerConfig2p4Ghz;
|
||||
}
|
||||
#else
|
||||
(void) entry;
|
||||
#if RAIL_SUPPORTS_2P4GHZ_BAND
|
||||
newTxPowerConfigPtr = &txPowerConfig2p4Ghz;
|
||||
#else
|
||||
newTxPowerConfigPtr = &txPowerConfigSubGhz;
|
||||
#endif
|
||||
#endif
|
||||
// Call RAIL_ConfigTxPower only if TX Power Config mode has changed.
|
||||
if (currentTxPowerConfig.mode != newTxPowerConfigPtr->mode) {
|
||||
// Save current TX power before RAIL_ConfigTxPower (because not preserved).
|
||||
if (currentTxPowerConfig.mode == RAIL_TX_POWER_MODE_NONE) {
|
||||
txPowerDeciDbm = SL_RAIL_UTIL_PA_POWER_DECI_DBM;
|
||||
} else {
|
||||
txPowerDeciDbm = RAIL_GetTxPowerDbm(rail_handle);
|
||||
}
|
||||
|
||||
// Apply new TX Power Config.
|
||||
status = RAIL_ConfigTxPower(rail_handle, newTxPowerConfigPtr);
|
||||
if (status != RAIL_STATUS_NO_ERROR) {
|
||||
while (true) {
|
||||
} // Error: Can't set TX Power Config
|
||||
}
|
||||
// Restore TX power after RAIL_ConfigTxPower.
|
||||
status = RAIL_SetTxPowerDbm(rail_handle, txPowerDeciDbm);
|
||||
if (status != RAIL_STATUS_NO_ERROR) {
|
||||
while (true) {
|
||||
} // Error: Can't set TX Power
|
||||
}
|
||||
}
|
||||
} // !RAIL_IsPaAutoModeEnabled
|
||||
}
|
||||
#endif // !RAIL_PA_CONVERSIONS_WEAK
|
|
@ -0,0 +1,182 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion functions provided to the customer as source for
|
||||
* highest level of customization.
|
||||
* @details This file contains the curves and logic that convert PA power
|
||||
* levels to dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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 PA_CONVERSIONS_EFR32_H
|
||||
#define PA_CONVERSIONS_EFR32_H
|
||||
|
||||
#include "rail_types.h"
|
||||
|
||||
// This macro is defined when Silicon Labs builds curves into the library as WEAK
|
||||
// to ensure it can be overriden by customer versions of these functions. It
|
||||
// should *not* be defined in a customer build.
|
||||
#if !defined(RAIL_PA_CONVERSIONS_WEAK)
|
||||
#ifdef SL_RAIL_UTIL_PA_CONFIG_HEADER
|
||||
#include SL_RAIL_UTIL_PA_CONFIG_HEADER
|
||||
#else
|
||||
#include "sl_rail_util_pa_conversions_efr32_config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAL_CONFIG
|
||||
#include "hal-config.h"
|
||||
#ifdef HAL_PA_CURVE_HEADER
|
||||
#ifdef SL_RAIL_UTIL_PA_CURVE_HEADER
|
||||
#undef SL_RAIL_UTIL_PA_CURVE_HEADER
|
||||
#endif
|
||||
#define SL_RAIL_UTIL_PA_CURVE_HEADER HAL_PA_CURVE_HEADER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SL_RAIL_UTIL_PA_CURVE_HEADER
|
||||
#include SL_RAIL_UTIL_PA_CURVE_HEADER
|
||||
#else
|
||||
#include "pa_curves_efr32.h"
|
||||
#endif
|
||||
|
||||
#ifdef SL_RAIL_UTIL_PA_CURVE_TYPES
|
||||
#include SL_RAIL_UTIL_PA_CURVE_TYPES
|
||||
#else
|
||||
#include "pa_curve_types_efr32.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// The curves to be used when battery voltage powers transmission
|
||||
extern const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat;
|
||||
|
||||
/// The curves to be used when the DC-DC converter powers transmission
|
||||
extern const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc;
|
||||
|
||||
/**
|
||||
* Initialize TxPower curves.
|
||||
*
|
||||
* @param[in] txPowerCurvesConfig Struct containing pointers to custom
|
||||
* tx power curves.
|
||||
* @return RAIL_Status_t indicating success or an error.
|
||||
*
|
||||
* @note: This function is deprecated, and will no longer be supported
|
||||
* for any chips released after EFRXG1X parts. Please use
|
||||
* RAIL_InitTxPowerCurvesAlt instead.
|
||||
*/
|
||||
RAIL_Status_t RAIL_InitTxPowerCurves(const RAIL_TxPowerCurvesConfig_t *config);
|
||||
|
||||
/**
|
||||
* Initialize TxPower curves.
|
||||
*
|
||||
* @param[in] txPowerCurvesConfig Struct containing pointers to custom
|
||||
* tx power curves.
|
||||
* @return RAIL_Status_t indicating success or an error.
|
||||
*
|
||||
*/
|
||||
RAIL_Status_t RAIL_InitTxPowerCurvesAlt(const RAIL_TxPowerCurvesConfigAlt_t *config);
|
||||
|
||||
/**
|
||||
* Gets the curve that should be used for conversion functions based on the
|
||||
* current PA configuration.
|
||||
*
|
||||
* @param[in] mode PA mode whose curves are needed.
|
||||
* @return RAIL_TxPowerCurves_t that should be used for conversion functions.
|
||||
*
|
||||
* @note: If the mode is not supported by the the chip,
|
||||
* then NULL will be returned.
|
||||
*/
|
||||
RAIL_TxPowerCurves_t const * RAIL_GetTxPowerCurve(RAIL_TxPowerMode_t mode);
|
||||
|
||||
/**
|
||||
* Gets the maximum power in deci-dBm that should be used for calculating
|
||||
* the segments and to find right curve segment to convert Dbm to raw power
|
||||
* level for a specific PA.
|
||||
* For the PAs with \ref RAIL_PaConversionAlgorithm_t
|
||||
* \ref RAIL_PA_ALGORITHM_PIECEWISE_LINEAR , if the curves are generated with
|
||||
* maxPower and increment other than \ref RAIL_TX_POWER_CURVE_DEFAULT_MAX and
|
||||
* \ref RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT respectively, then the first
|
||||
* \ref RAIL_TxPowerCurveSegment_t has its maxPowerLevel equal to
|
||||
* \ref RAIL_TX_POWER_LEVEL_INVALID and its slope and intercept stores the
|
||||
* maxPower and increment in deci-dBm respectively.
|
||||
*
|
||||
* @param[in] railHandle A RAIL instance handle.
|
||||
* @param[in] mode PA mode whose curves are needed.
|
||||
* @param[in] maxpower A pointer to memory allocated to hold the maxpower in
|
||||
* deci-dBm used in calculation of curve segments .
|
||||
* A NULL configuration will produce undefined behavior.
|
||||
* @param[in] increment A pointer to memory allocated to hold the increment in
|
||||
* deci-dBm used in calculation of curve segments.
|
||||
* A NULL configuration will produce undefined behavior.
|
||||
* @return RAIL_Status_t indicating success or an error.
|
||||
*
|
||||
*/
|
||||
RAIL_Status_t RAIL_GetTxPowerCurveLimits(RAIL_Handle_t railHandle,
|
||||
RAIL_TxPowerMode_t mode,
|
||||
RAIL_TxPower_t *maxpower,
|
||||
RAIL_TxPower_t *increment);
|
||||
|
||||
/**
|
||||
* Initialize PA TX Curves
|
||||
*
|
||||
*/
|
||||
void sl_rail_util_pa_init(void);
|
||||
|
||||
/**
|
||||
* Get a pointer to the TX Power Config 2.4 GHz structure.
|
||||
*
|
||||
* @return a pointer to the TX Power Config stucture.
|
||||
*
|
||||
*/
|
||||
RAIL_TxPowerConfig_t *sl_rail_util_pa_get_tx_power_config_2p4ghz(void);
|
||||
|
||||
/**
|
||||
* Get a pointer to the TX Power Config Sub-GHz structure.
|
||||
*
|
||||
* @return a pointer to the TX Power Config stucture.
|
||||
*
|
||||
*/
|
||||
RAIL_TxPowerConfig_t *sl_rail_util_pa_get_tx_power_config_subghz(void);
|
||||
|
||||
/**
|
||||
* Provide a channel config change callback capable of configuring the PA
|
||||
* correctly.
|
||||
*
|
||||
* @param[in] rail_handle The RAIL handle being passed into this callback.
|
||||
* @param[in] entry The channel config entry being switched to by hardware.
|
||||
*
|
||||
*/
|
||||
void sl_rail_util_pa_on_channel_config_change(RAIL_Handle_t rail_handle,
|
||||
const RAIL_ChannelConfigEntry_t *entry);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PA_CONVERSIONS_EFR32_H
|
|
@ -0,0 +1,221 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion curve types used by Silicon Labs PA power
|
||||
* conversion functions.
|
||||
* @details This file contains the curve types needed convert PA power levels
|
||||
* to dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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 PA_CURVE_TYPES_EFR32_H
|
||||
#define PA_CURVE_TYPES_EFR32_H
|
||||
|
||||
#include "rail_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @struct RAIL_TxPowerCurves
|
||||
*
|
||||
* @brief Structure containing data defining each segment of the
|
||||
* power (deci-dBm) to powerLevel mapping curve fits.
|
||||
*
|
||||
* Note, these used in an equation of the form:
|
||||
*
|
||||
* powerLevel * 1000 = slope * power + intercept
|
||||
*
|
||||
* powerLevel is the 0-252/0-248/1-7 values used in the RAIL_Get/SetTxPower
|
||||
* functions, and power is the actual output power of the PA, specified
|
||||
* in deci-dBm.
|
||||
*
|
||||
* @note If the curves are generated with
|
||||
* maxPower and increment other than \ref RAIL_TX_POWER_CURVE_DEFAULT_MAX and
|
||||
* \ref RAIL_TX_POWER_CURVE_DEFAULT_INCREMENT respectively, then the first
|
||||
* \ref RAIL_TxPowerCurveSegment_t has its maxPowerLevel equal to
|
||||
* \ref RAIL_TX_POWER_LEVEL_INVALID and its slope and intercept stores the
|
||||
* maxPower and increment in deci-dBm respectively.
|
||||
*/
|
||||
typedef struct RAIL_TxPowerCurveSegment {
|
||||
/** The highest power level that this segment will be used to convert */
|
||||
uint16_t maxPowerLevel;
|
||||
/** slope of the line */
|
||||
int16_t slope;
|
||||
/** y-intercept of the line */
|
||||
int32_t intercept;
|
||||
} RAIL_TxPowerCurveSegment_t;
|
||||
|
||||
/**
|
||||
* @struct RAIL_TxPowerCurves
|
||||
*
|
||||
* @brief Structure containing the min and max values for a given
|
||||
* PA and voltage supply combination (in deci-dBm).
|
||||
*/
|
||||
typedef struct RAIL_TxPowerCurves {
|
||||
/** max deci-dBm value */
|
||||
int16_t maxPower;
|
||||
/** min deci-dBm value */
|
||||
int16_t minPower;
|
||||
/**
|
||||
* Pointer to "piecewiseSegments"-length array of
|
||||
* RAIL_TxPowerCurveSegment_t of power (deci-dBm) to
|
||||
* powerLevel conversion fits.
|
||||
*/
|
||||
const RAIL_TxPowerCurveSegment_t *powerParams;
|
||||
} RAIL_TxPowerCurves_t;
|
||||
|
||||
/**
|
||||
* @struct RAIL_TxPowerCurvesConfig
|
||||
*
|
||||
* @brief Structure containing curve fit information and other metadata
|
||||
* required to properly use the WEAK versions of RAIL_ConvertRawToDb
|
||||
* and RAIL_ConvertDbmToRaw
|
||||
*/
|
||||
typedef struct RAIL_TxPowerCurvesConfig {
|
||||
/**
|
||||
* Pointer a RAIL_TxPowerCurves_t representing the piecewise linear segments
|
||||
* of curves that map power level to power in dBm for the 2.4 GHz high power
|
||||
* PA.
|
||||
*
|
||||
* @note By the default conversion implementation, segments must be specified
|
||||
* in decreasing power order. That is, the 0th entry of this array should be
|
||||
* used to convert the highest power (levels). Segment at position n is valid
|
||||
* from maxPowerLevel+1 from the segment at n+1 (or 0 if n is array length -
|
||||
* 1) to maxPowerLevel of segment n, inclusive.
|
||||
*/
|
||||
const RAIL_TxPowerCurves_t *txPower24HpCurves;
|
||||
|
||||
/**
|
||||
* Pointer a RAIL_TxPowerCurves_t representing the piecewise linear segments
|
||||
* of curves that map power level to power in dBm for the subgig PA.
|
||||
*
|
||||
* @note By the default conversion implementation, segments must be specified
|
||||
* in decreasing power order. That is, the 0th entry of this array should be
|
||||
* used to convert the highest power (levels). Segment at position n is valid
|
||||
* from maxPowerLevel+1 from the segment at n+1 (or 0 if n is array length -
|
||||
* 1) to maxPowerLevel of segment n, inclusive.
|
||||
*/
|
||||
const RAIL_TxPowerCurves_t *txPowerSgCurves;
|
||||
|
||||
/**
|
||||
* Look up table for each of the power levels of the 2.4GHz low power
|
||||
* amplifier and their equivalent deci-dB value.
|
||||
*/
|
||||
const int16_t *txPower24LpCurves;
|
||||
/**
|
||||
* The number of piecewise segments provided to the PA in each of the four
|
||||
* conversion curve fits. The default is 8, but regardless of the number, it
|
||||
* must be the same for all curves.
|
||||
*/
|
||||
uint8_t piecewiseSegments;
|
||||
} RAIL_TxPowerCurvesConfig_t;
|
||||
|
||||
/// PA conversion algorithms types for converting between dBm and power levels
|
||||
RAIL_ENUM(RAIL_PaConversionAlgorithm_t) {
|
||||
RAIL_PA_ALGORITHM_PIECEWISE_LINEAR, /** Piecewise linear fit */
|
||||
RAIL_PA_ALGORITHM_MAPPING_TABLE, /** Mapping table between quantities */
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_THIS
|
||||
// Self-referencing defines minimize compiler complaints when using RAIL_ENUM
|
||||
#define RAIL_PA_ALGORITHM_PIECEWISE_LINEAR ((RAIL_PaConversionAlgorithm_t) RAIL_PA_ALGORITHM_PIECEWISE_LINEAR)
|
||||
#define RAIL_PA_ALGORITHM_MAPPING_TABLE ((RAIL_PaConversionAlgorithm_t) RAIL_PA_ALGORITHM_MAPPING_TABLE)
|
||||
#endif//DOXYGEN_SHOULD_SKIP_THIS
|
||||
|
||||
/**
|
||||
* @struct RAIL_TxPowerCurvesAlt
|
||||
*
|
||||
* @brief Structure containing the min and max values for a given
|
||||
* PA and voltage supply combination (in deci-dBm).
|
||||
*/
|
||||
typedef struct RAIL_TxPowerCurveAlt {
|
||||
/** max deci-dBm value */
|
||||
int16_t maxPower;
|
||||
/** min deci-dBm value */
|
||||
int16_t minPower;
|
||||
/**
|
||||
* "piecewiseSegments"-length array of RAIL_TxPowerCurveSegment_t
|
||||
* of power (deci-dBm) to powerLevel conversion fits.
|
||||
*/
|
||||
RAIL_TxPowerCurveSegment_t powerParams[];
|
||||
} RAIL_TxPowerCurveAlt_t;
|
||||
|
||||
typedef union RAIL_PowerConversion {
|
||||
/**
|
||||
* Pointer to a powerCurve containing line segment data for the curves
|
||||
* corresponding to a specific PA.
|
||||
*
|
||||
* @note By the default conversion implementation, segments must be specified
|
||||
* in decreasing power order. That is, the 0th entry of this array should be
|
||||
* used to convert the highest power (levels). Segment at position n is valid
|
||||
* from maxPowerLevel+1 from the segment at n+1 (or 0 if n is array length -
|
||||
* 1) to maxPowerLevel of segment n, inclusive.
|
||||
*/
|
||||
const RAIL_TxPowerCurveAlt_t *powerCurve;
|
||||
/**
|
||||
* Lookup table for PA's which use the mapping table algorithm for converting
|
||||
* between deci-dBm and power levels.
|
||||
*/
|
||||
const int16_t *mappingTable;
|
||||
} RAIL_PowerConversion_t;
|
||||
|
||||
/// PA descriptor as used in the PA conversion functions
|
||||
typedef struct RAIL_PaDescriptor {
|
||||
/** Algorithm used to map dBm to power levels for this PA */
|
||||
RAIL_PaConversionAlgorithm_t algorithm;
|
||||
/**
|
||||
* The number of piecewise segments provided to the PA in a piecewise linear
|
||||
* curve fit. The default is 8. Should be set to 0 when not using the
|
||||
* piecewise linear algorithm.
|
||||
*/
|
||||
uint8_t segments;
|
||||
/** Min power level for this PA */
|
||||
RAIL_TxPowerLevel_t min;
|
||||
/** Max power level for this PA */
|
||||
RAIL_TxPowerLevel_t max;
|
||||
/** Union containing a pointer to algorithm-specific conversion data. */
|
||||
RAIL_PowerConversion_t conversion;
|
||||
} RAIL_PaDescriptor_t;
|
||||
|
||||
/**
|
||||
* @typedef RAIL_TxPowerCurvesConfigAlt_t
|
||||
*
|
||||
* @brief More generic structure containing information about
|
||||
* piecewise linear curves and mapping tables, instead of specific PA's.
|
||||
*/
|
||||
typedef struct RAIL_TxPowerCurvesConfigAlt {
|
||||
RAIL_PaDescriptor_t curves[RAIL_NUM_PA];
|
||||
uint32_t signature;
|
||||
uint16_t paVoltage;
|
||||
} RAIL_TxPowerCurvesConfigAlt_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PA_CURVE_TYPES_EFR32_H
|
|
@ -0,0 +1,347 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Default PA power conversion structures with curves calibrated by the
|
||||
* RAIL team.
|
||||
* @details This file contains the curves that convert PA power levels to dBm
|
||||
* powers.
|
||||
*******************************************************************************
|
||||
* # 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 entire file should never be used on FCC pre-certified modules
|
||||
#ifndef _SILICON_LABS_MODULE
|
||||
|
||||
#include "em_device.h"
|
||||
#include "pa_conversions_efr32.h"
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_1)
|
||||
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHpVbat = {
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_CURVES
|
||||
};
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataSgVbat = {
|
||||
RAIL_PA_CURVES_SG_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_SG_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_SG_VBAT_CURVES
|
||||
};
|
||||
static const int16_t RAIL_curves24LpVbat[RAIL_PA_CURVES_LP_VALUES] =
|
||||
RAIL_PA_CURVES_2P4_LP;
|
||||
|
||||
// This macro is defined when Silicon Labs builds this into the library as WEAK
|
||||
// to ensure it can be overriden by customer versions of these functions. It
|
||||
// should *not* be defined in a customer build.
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_2P4_HP_SG_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE,
|
||||
.segments = 0U,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX,
|
||||
.conversion = { .mappingTable = &RAIL_curves24LpVbat[0] },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_2P4_HP_SG_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_SUBGIG_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_SUBGIG_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataSgVbat },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHpDcdc = {
|
||||
RAIL_PA_CURVES_2P4_HP_DCDC_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_DCDC_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_DCDC_CURVES
|
||||
};
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataSgDcdc = {
|
||||
RAIL_PA_CURVES_SG_DCDC_MAX_POWER,
|
||||
RAIL_PA_CURVES_SG_DCDC_MIN_POWER,
|
||||
RAIL_PA_CURVES_SG_DCDC_CURVES
|
||||
};
|
||||
static const int16_t RAIL_curves24LpDcdc[RAIL_PA_CURVES_LP_VALUES] =
|
||||
RAIL_PA_CURVES_2P4_LP;
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_2P4_HP_SG_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpDcdc },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE,
|
||||
.segments = 0U,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX,
|
||||
.conversion = { .mappingTable = &RAIL_curves24LpDcdc[0] },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_2P4_HP_SG_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_SUBGIG_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_SUBGIG_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataSgDcdc },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
#elif ((_SILICON_LABS_32B_SERIES_2_CONFIG == 2) || (_SILICON_LABS_32B_SERIES_2_CONFIG == 7))
|
||||
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHpVbat = {
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_CURVES,
|
||||
};
|
||||
static const int16_t RAIL_curves24Lp[RAIL_PA_CURVES_LP_VALUES] =
|
||||
RAIL_PA_CURVES_2P4_LP_VBAT_CURVES;
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE, \
|
||||
.segments = 0U, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX, \
|
||||
.conversion = { .mappingTable = &RAIL_curves24Lp[0] }, \
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE, \
|
||||
.segments = 0U, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX, \
|
||||
.conversion = { .mappingTable = &RAIL_curves24Lp[0] }, \
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_3)
|
||||
|
||||
RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT;
|
||||
|
||||
// This chip has the same curve for Vbat and DCDC
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5)
|
||||
|
||||
RAIL_DECLARE_TX_POWER_VBAT_CURVES_ALT;
|
||||
|
||||
// This chip has the same curve for Vbat and DCDC
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = RAIL_DECLARE_TX_POWER_CURVES_CONFIG_ALT;
|
||||
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHpVbat = {
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_CURVES,
|
||||
};
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataMpVbat = {
|
||||
RAIL_PA_CURVES_2P4_MP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_MP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_MP_VBAT_CURVES,
|
||||
};
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataLpVbat = {
|
||||
RAIL_PA_CURVES_2P4_LP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_LP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_LP,
|
||||
};
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
#if _SILICON_LABS_32B_SERIES_2_CONFIG == 1
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_MP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_MP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataMpVbat },
|
||||
},
|
||||
#endif // _SILICON_LABS_32B_SERIES_2_CONFIG == 1
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataLpVbat },
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_MP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_MP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataMpVbat },
|
||||
},
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_LP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_LP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataLpVbat },
|
||||
},
|
||||
}
|
||||
};
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_4)
|
||||
static const RAIL_TxPowerCurveAlt_t RAIL_piecewiseDataHpVbat = {
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MAX_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_MIN_POWER,
|
||||
RAIL_PA_CURVES_2P4_HP_VBAT_CURVES,
|
||||
};
|
||||
static const int16_t RAIL_curves24Lp[RAIL_PA_CURVES_LP_VALUES] =
|
||||
RAIL_PA_CURVES_2P4_LP_VBAT_CURVES;
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesVbat = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE, \
|
||||
.segments = 0U, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX, \
|
||||
.conversion = { .mappingTable = &RAIL_curves24Lp[0] }, \
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef RAIL_PA_CONVERSIONS_WEAK
|
||||
__WEAK
|
||||
#endif
|
||||
const RAIL_TxPowerCurvesConfigAlt_t RAIL_TxPowerCurvesDcdc = {
|
||||
.curves = {
|
||||
{
|
||||
.algorithm = RAIL_PA_ALGORITHM_PIECEWISE_LINEAR,
|
||||
.segments = RAIL_PA_CURVES_PIECEWISE_SEGMENTS,
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_HP_MIN,
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_HP_MAX,
|
||||
.conversion = { .powerCurve = &RAIL_piecewiseDataHpVbat },
|
||||
},
|
||||
{ \
|
||||
.algorithm = RAIL_PA_ALGORITHM_MAPPING_TABLE, \
|
||||
.segments = 0U, \
|
||||
.min = RAIL_TX_POWER_LEVEL_2P4_LP_MIN, \
|
||||
.max = RAIL_TX_POWER_LEVEL_2P4_LP_MAX, \
|
||||
.conversion = { .mappingTable = &RAIL_curves24Lp[0] }, \
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
#error "Unsupported platform!"
|
||||
#endif
|
||||
|
||||
#endif //_SILICON_LABS_MODULE
|
|
@ -0,0 +1,80 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion curves used by Silicon Labs PA power conversion
|
||||
* functions.
|
||||
* @details This file contains the curves needed convert PA power levels to
|
||||
* dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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 PA_CURVES_EFR32_H
|
||||
#define PA_CURVES_EFR32_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#ifdef _SILICON_LABS_32B_SERIES_1
|
||||
#include "efr32xg1x/sl_rail_util_pa_curves.h"
|
||||
#elif defined (_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
#include "efr32xg21/sl_rail_util_pa_curves.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
|
||||
#include "efr32xg22/sl_rail_util_pa_curves.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_3)
|
||||
#if defined(_SILICON_LABS_EFR32_SUBGHZ_HP_PA_PRESENT)
|
||||
#if (_SILICON_LABS_EFR32_SUBGHZ_HP_PA_MAX_OUTPUT_DBM == 20)
|
||||
#include "efr32xg23/sl_rail_util_pa_curves_20dbm.h"
|
||||
#elif (_SILICON_LABS_EFR32_SUBGHZ_HP_PA_MAX_OUTPUT_DBM == 10)
|
||||
#include "efr32xg23/sl_rail_util_pa_curves_10dbm_434M.h"
|
||||
#else
|
||||
#include "efr32xg23/sl_rail_util_pa_curves_14dbm.h"
|
||||
#endif
|
||||
#else
|
||||
#error "No valid PA available for selected chip."
|
||||
#endif
|
||||
#elif defined (_SILICON_LABS_32B_SERIES_2_CONFIG_4)
|
||||
#if defined(_SILICON_LABS_EFR32_2G4HZ_HP_PA_PRESENT) \
|
||||
&& (_SILICON_LABS_EFR32_2G4HZ_HP_PA_MAX_OUTPUT_DBM > 10)
|
||||
#include "efr32xg24/sl_rail_util_pa_curves_20dbm.h"
|
||||
#else
|
||||
#include "efr32xg24/sl_rail_util_pa_curves_10dbm.h"
|
||||
#endif
|
||||
#elif defined (_SILICON_LABS_32B_SERIES_2_CONFIG_5)
|
||||
#include "efr32xg25/sl_rail_util_pa_curves.h"
|
||||
#elif (_SILICON_LABS_32B_SERIES_2_CONFIG == 7)
|
||||
#include "efr32xg27/sl_rail_util_pa_curves.h"
|
||||
#else
|
||||
#error "Unsupported platform!"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // PA_CURVES_EFR32_H
|
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief PA power conversion curves used by Silicon Labs PA power conversion
|
||||
* functions.
|
||||
* @details This file contains the curves needed convert PA power levels to
|
||||
* dBm powers.
|
||||
*******************************************************************************
|
||||
* # 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_RAIL_UTIL_PA_CONVERSIONS_EFR32_CONFIG_H
|
||||
#define SL_RAIL_UTIL_PA_CONVERSIONS_EFR32_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _SILICON_LABS_32B_SERIES_1
|
||||
#include "efr32xg1x/config/sl_rail_util_pa_config.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2)
|
||||
#include "efr32xg22/config/sl_rail_util_pa_config.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_3)
|
||||
#include "efr32xg23/config/sl_rail_util_pa_config.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_4)
|
||||
#include "efr32xg24/config/sl_rail_util_pa_config.h"
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_2_CONFIG_5)
|
||||
#include "efr32xg25/config/sl_rail_util_pa_config.h"
|
||||
#elif (_SILICON_LABS_32B_SERIES_2_CONFIG == 7)
|
||||
#include "efr32xg27/config/sl_rail_util_pa_config.h"
|
||||
#elif defined (_SILICON_LABS_32B_SERIES_2)
|
||||
#include "efr32xg21/config/sl_rail_util_pa_config.h"
|
||||
#else
|
||||
#error "Unsupported platform!"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_RAIL_UTIL_PA_CONVERSIONS_EFR32_CONFIG_H
|
|
@ -0,0 +1,122 @@
|
|||
/***************************************************************************//**
|
||||
* @brief Bluetooth controller HCI API.
|
||||
*
|
||||
* This interface is for external use.
|
||||
*******************************************************************************
|
||||
* # 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_BTCTRL_HCI_H_
|
||||
#define _SL_BTCTRL_HCI_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sl_status.h"
|
||||
|
||||
//Initialize Vendor Specific Extensions
|
||||
void sl_bthci_init_vs(void);
|
||||
|
||||
void sl_bthci_init_upper(void);
|
||||
|
||||
void hci_enableVendorSpecificDebugging(void);
|
||||
|
||||
void hci_debugEnable(void);
|
||||
|
||||
sl_status_t hci_send_sleep_command_complete(void);
|
||||
|
||||
/**
|
||||
* The Bluetooth controller receives a HCI message fragment from the host.
|
||||
* The HCI transport can give the HCI message in fragments.
|
||||
* @param[in] data Pointer to the received data.
|
||||
* @param[in] len Length of the received data.
|
||||
* @param[in] lastFragment Indicate whether this is the last
|
||||
* fragment of an HCI message (true / false).
|
||||
* @return 0 - success
|
||||
* -1 - out of memory
|
||||
* -2 - badly formatted message. */
|
||||
int16_t sl_btctrl_hci_receive(uint8_t *data, int16_t len, bool lastFragment);
|
||||
|
||||
static inline int16_t hci_common_transport_receive(uint8_t *data, int16_t len, bool lastFragment)
|
||||
{
|
||||
return sl_btctrl_hci_receive(data, len, lastFragment);
|
||||
}
|
||||
|
||||
/**
|
||||
* The HCI transport has transmitted a message.
|
||||
* The HCI can transmit the next message after the transport
|
||||
* has given this indication. */
|
||||
void sl_btctrl_hci_transmit_complete(uint32_t status);
|
||||
|
||||
static inline void hci_common_transport_transmit_complete(uint32_t status)
|
||||
{
|
||||
sl_btctrl_hci_transmit_complete(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* The HCI transport has been reconnected with the host.
|
||||
* The HCI can transmit the next message after this function
|
||||
* has been called. */
|
||||
void sl_btctrl_hci_transmit_reconnected(void);
|
||||
|
||||
static inline void hci_common_transport_transmit_reconnected(void)
|
||||
{
|
||||
sl_btctrl_hci_transmit_reconnected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Host has sent HCI reset command callback handler.
|
||||
* This is implemented as weak function and can be overridden by application to perform own activities before doing reset.
|
||||
* It is also possible to call sl_btctrl_hard_reset to start hard reset procedure
|
||||
*
|
||||
* @return - true to progress with normal soft reset
|
||||
* - false if normal reset procedure should be bypassed
|
||||
*/
|
||||
bool sl_btctrl_reset_handler(void);
|
||||
|
||||
/**
|
||||
* Hard reset device
|
||||
* This is called from reset callback handler to implement hard reset
|
||||
* If HCI packet is in middle of transmit to host, reset will be done after transmit is complete
|
||||
*/
|
||||
void sl_btctrl_request_hard_reset(void);
|
||||
|
||||
void sl_btctrl_hci_parser_init_conn(void);
|
||||
|
||||
void sl_btctrl_hci_parser_init_adv(void);
|
||||
|
||||
void sl_btctrl_hci_parser_init_phy(void);
|
||||
|
||||
void sl_btctrl_hci_parser_init_past(void);
|
||||
|
||||
void sl_btctrl_hci_parser_init_default(void);
|
||||
|
||||
/**
|
||||
* Create hardware error event and try to send it to the host.
|
||||
* The created event shall be sent as high priority event.
|
||||
* @param[in] errorCode Code describing the error. */
|
||||
void sl_btctrl_hci_send_hardware_error_event(uint8_t errorCode);
|
||||
|
||||
#endif // _SL_BTCTRL_HCI_H_
|
|
@ -0,0 +1,229 @@
|
|||
/***************************************************************************//**
|
||||
* @brief Bluetooth Link Layer configuration API
|
||||
*******************************************************************************
|
||||
* # 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_BTCTRL_LINKLAYER_H_
|
||||
#define _SL_BTCTRL_LINKLAYER_H_
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void sl_bt_controller_init(void);
|
||||
|
||||
void sl_bt_controller_deinit(void);
|
||||
|
||||
void sl_btctrl_init(void);
|
||||
|
||||
/**
|
||||
* Allocate memory buffers for controller
|
||||
*
|
||||
* @param memsize size of memory to allocate
|
||||
* @returns number of memory buffers allocated
|
||||
*/
|
||||
uint32_t sl_btctrl_init_mem(uint32_t memsize);
|
||||
|
||||
/**
|
||||
* Configures how many maximum sized ACL data packets
|
||||
* can the controller store.
|
||||
*/
|
||||
void sl_btctrl_configure_le_buffer_size(uint8_t count);
|
||||
|
||||
/**
|
||||
* Release all memory allocated by controller
|
||||
*/
|
||||
void sli_btctrl_deinit_mem(void);
|
||||
|
||||
void sli_btctrl_set_interrupt_priorities();
|
||||
|
||||
sl_status_t sl_btctrl_init_ll(void);
|
||||
|
||||
void sli_btctrl_set_address(uint8_t *address);
|
||||
|
||||
//Initialize memory objects used by LinkLayer
|
||||
//In future these should be configured individually
|
||||
sl_status_t sl_btctrl_init_basic(uint8_t connections, uint8_t adv_sets, uint8_t whitelist);
|
||||
|
||||
void sli_btctrl_events_init(void);
|
||||
|
||||
enum sl_btctrl_channelmap_flags{
|
||||
SL_BTCTRL_CHANNELMAP_FLAG_ACTIVE_ADAPTIVITY = 0x01,
|
||||
SL_BTCTRL_CHANNELMAP_FLAG_PASSIVE_ADAPTIVITY= 0x02,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize and enable adaptive frequency hopping
|
||||
*/
|
||||
sl_status_t sl_btctrl_init_afh(uint32_t flags);
|
||||
|
||||
/**
|
||||
* Enable high power use under appropriate conditions
|
||||
*/
|
||||
void sl_btctrl_init_highpower(void);
|
||||
|
||||
/**
|
||||
* @brief Initilize periodic advertiser
|
||||
*/
|
||||
void sl_btctrl_init_periodic_adv();
|
||||
|
||||
/**
|
||||
* @brief Initilize periodic advertiser
|
||||
*/
|
||||
void sl_btctrl_init_periodic_scan();
|
||||
|
||||
/**
|
||||
* @brief Enable and initialize support for the PAWR advertiser.
|
||||
* @param[in] num_adv Number of advertising sets supporting PAWR.
|
||||
* If set to zero, previously allocated PAWR sets are only freed.
|
||||
* @return SL_STATUS_OK, or an appropriate error code.
|
||||
*/
|
||||
sl_status_t sl_btctrl_pawr_advertiser_configure(uint8_t max_pawr_sets);
|
||||
|
||||
/**
|
||||
* @brief Enable and initialize support for PAWR sync/receiver.
|
||||
* @return SL_STATUS_OK, or an appropriate error code. */
|
||||
sl_status_t sl_btctrl_pawr_synchronizer_configure(void);
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for synchronized scanners
|
||||
*
|
||||
* @param num_scan Number of Periodic Scanners Allowed
|
||||
* @return SL_STATUS_OK if allocation was succesfull, failure reason otherwise
|
||||
*/
|
||||
sl_status_t sl_btctrl_alloc_periodic_scan(uint8_t num_scan);
|
||||
|
||||
/**
|
||||
* @brief Allocate memory for periodic advertisers
|
||||
*
|
||||
* @param num_adv Number of advertisers to allocate
|
||||
*/
|
||||
sl_status_t sl_btctrl_alloc_periodic_adv(uint8_t num_adv);
|
||||
|
||||
/**
|
||||
* Call to enable the even connection scheduling algorithm.
|
||||
* This function should be called before link layer initialization.
|
||||
*/
|
||||
void sl_btctrl_enable_even_connsch();
|
||||
|
||||
/**
|
||||
* Call to initialize multiprotocol
|
||||
* in bluetooth controller
|
||||
*/
|
||||
void sl_btctrl_init_multiprotocol();
|
||||
|
||||
/**
|
||||
* Link with symbol to enable radio watchdog
|
||||
*/
|
||||
void sl_btctrl_enable_radio_watchdog();
|
||||
|
||||
/**
|
||||
* Initialize CTE receiver
|
||||
*/
|
||||
sl_status_t sl_btctrl_init_cte_receiver();
|
||||
|
||||
/**
|
||||
* Initialize CTE transmitter
|
||||
*/
|
||||
sl_status_t sl_btctrl_init_cte_transmitter();
|
||||
|
||||
/**
|
||||
* Initialize both CTE receiver and transmitter
|
||||
*
|
||||
* Note: This is for backward compatibility. It is recommend to
|
||||
* use sl_btctrl_init_cte_receiver and sl_btctrl_init_cte_transmitter
|
||||
* functions instead.
|
||||
*/
|
||||
sl_status_t sl_btctrl_init_cte();
|
||||
|
||||
/**
|
||||
* Check if event bitmap indicates pending events
|
||||
* @return bool pending events
|
||||
*/
|
||||
bool sli_pending_btctrl_events(void);
|
||||
|
||||
/**
|
||||
* Disable the support for Coded and Simulscan PHYs.
|
||||
*/
|
||||
void sl_btctrl_disable_coded_phy(void);
|
||||
|
||||
/**
|
||||
* Disable the support for 2M PHY.
|
||||
*/
|
||||
void sl_btctrl_disable_2m_phy(void);
|
||||
|
||||
/**
|
||||
* Initialize adv component
|
||||
*/
|
||||
void sl_btctrl_init_adv(void);
|
||||
|
||||
void sl_btctrl_init_conn(void);
|
||||
|
||||
void sl_btctrl_init_phy(void);
|
||||
|
||||
void sl_btctrl_init_adv_ext(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize extended scanner state
|
||||
*
|
||||
*/
|
||||
void sl_btctrl_init_scan_ext(void);
|
||||
|
||||
void sl_btctrl_init_scan(void);
|
||||
|
||||
/**
|
||||
* @brief return true if controller is initialized
|
||||
*
|
||||
*/
|
||||
bool sl_btctrl_is_initialized();
|
||||
|
||||
/**
|
||||
* @brief Sets PAST initiator feature bit,
|
||||
* and links in PAST sender and ll_adv_sync symbols to the project.
|
||||
*/
|
||||
void sl_btctrl_init_past_local_sync_transfer(void);
|
||||
|
||||
/**
|
||||
* @brief Sets PAST initiator feature bit,
|
||||
* and links in PAST sender, ll_scan_sync and ll_scan_sync_registry symbols to the project.
|
||||
*/
|
||||
void sl_btctrl_init_past_remote_sync_transfer(void);
|
||||
|
||||
/**
|
||||
* @brief Sets PAST receiver feature bit,
|
||||
* and links in PAST receiver, ll_scan_sync and ll_scan_sync_registry symbols to the project.
|
||||
*/
|
||||
void sl_btctrl_init_past_receiver(void);
|
||||
|
||||
/**
|
||||
* @brief Configure how often to send the Number Of Completed Packets HCI event.
|
||||
* @param[in] packets When the controller has transmitted this number of ACL data packets it will send
|
||||
* the Number Of Completed Packets HCI event to the host.
|
||||
* @param[in] events When this number of connection events have passed and the controller did not yet report
|
||||
* all the transmitted packets, then it will send the Number Of Completed Packets HCI event to the host.
|
||||
*/
|
||||
void sl_btctrl_configure_completed_packets_reporting(uint8_t packets, uint8_t events);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
/***************************************************************************//**
|
||||
* @brief The API between HCI and common HCI transport.
|
||||
*
|
||||
* The interface configuration shall be done using UC configuration.
|
||||
*******************************************************************************
|
||||
* # 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 _HCI_COMMON_TRANSPORT_H_
|
||||
#define _HCI_COMMON_TRANSPORT_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "sl_btctrl_hci.h"
|
||||
|
||||
/**
|
||||
* The HCI receives a message from currently selected transport layer.
|
||||
* The HCI transport calls this function implemented in the HCI
|
||||
* once it has received a complete HCI message. If the HCI does not
|
||||
* manage to process the message, the transport may drop the message.
|
||||
* @param[in] data Pointer to the received data.
|
||||
* @param[in] len Length of the received data.
|
||||
* @param[in] lastFragment Indicates if this is the last fragment of
|
||||
* a complete HCI message.
|
||||
* @return 0 - success
|
||||
* -1 - out of memory
|
||||
* -2 - badly formatted message. */
|
||||
int16_t hci_common_transport_receive(uint8_t *data, int16_t len, bool lastFragment);
|
||||
|
||||
/**
|
||||
* Transmit HCI message using the currently used transport layer.
|
||||
* The HCI calls this function to transmit a full HCI message.
|
||||
* @param[in] data Data buffer to be transmitted.
|
||||
* @param[in] len Length of the data.
|
||||
* @return 0 - on success, or non-zero on failure. */
|
||||
uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len);
|
||||
|
||||
/**
|
||||
* The HCI transport indicates a message has been transmitted. */
|
||||
void hci_common_transport_transmit_complete(uint32_t status);
|
||||
|
||||
/**
|
||||
* The HCI transport has been reconnected with the host. */
|
||||
void hci_common_transport_transmit_reconnected(void);
|
||||
|
||||
/**
|
||||
* Initialize the currently selected transport layer. */
|
||||
void hci_common_transport_init(void);
|
||||
|
||||
#endif // _COMMON_TRANSPORT_H_
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -35,7 +35,7 @@
|
|||
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) || defined(DOXYGEN)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup sl_se_manager Secure Element Manager
|
||||
* @addtogroup sl_se_manager Secure Engine Manager
|
||||
*
|
||||
* @note The APIs are thread-safe.
|
||||
*
|
||||
|
@ -46,7 +46,7 @@
|
|||
* @addtogroup sl_se_manager_core Core
|
||||
*
|
||||
* @brief
|
||||
* Secure Element Manager Core API
|
||||
* Secure Engine Manager Core API
|
||||
*
|
||||
* @details
|
||||
* API for initialization of SE Manager and SE command context with yield
|
||||
|
@ -55,9 +55,12 @@
|
|||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#include "sl_se_manager_key_handling.h"
|
||||
#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 "sl_se_manager_cipher.h"
|
||||
|
||||
#include "em_se.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
|
@ -96,6 +99,60 @@ sl_status_t sl_se_init(void);
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit(void);
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT) || defined(DOXYGEN)
|
||||
/***************************************************************************//**
|
||||
* @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 || DOXYGEN
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT) || defined(DOXYGEN)
|
||||
/***************************************************************************//**
|
||||
* @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(CRYPTOACC_PRESENT)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize an SE command context object
|
||||
|
@ -134,59 +191,6 @@ sl_status_t sl_se_init_command_context(sl_se_command_context_t *cmd_ctx);
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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);
|
||||
|
||||
#if defined(CRYPTOACC_PRESENT) || defined(DOXYGEN)
|
||||
/***************************************************************************//**
|
||||
* @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(CRYPTOACC_PRESENT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -199,20 +203,32 @@ sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
|||
#endif // SL_SE_MANAGER_H
|
||||
|
||||
// THE REST OF THE FILE IS DOCUMENTATION ONLY
|
||||
/// @addtogroup sl_se_manager Secure Element Manager API
|
||||
/// @brief Silicon Labs Secure Element Manager
|
||||
/// @addtogroup sl_se_manager Secure Engine Manager API
|
||||
/// @brief Silicon Labs Secure Engine Manager
|
||||
/// @{
|
||||
///
|
||||
/// @details
|
||||
/// # Introduction
|
||||
///
|
||||
/// The Secure Element (SE) Manager provides thread-safe APIs for the Secure Element's mailbox interface.
|
||||
/// The SE Manager will use the SE hardware peripherals to accelerate cryptographic operations.
|
||||
/// The Secure Engine (SE) Manager provides thread-safe APIs for the Secure Engine's mailbox interface. Note that PSA Crypto is the main device independant crypto API and should be used
|
||||
/// whenever possible, see @ref ls_psa_usage. However, 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
|
||||
|
@ -242,9 +258,8 @@ sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
|||
/// - Read SE OTP contents
|
||||
/// - Read SE firmware version
|
||||
/// - Read provisioned certificates
|
||||
/// - Multi-thread safe APIs for MicriumOS, FreeRTOS and Zephyr OS
|
||||
///
|
||||
/// For a full overview of the available APIs, see @ref sl_se_manager.
|
||||
/// - Multi-thread safe APIs for MicriumOS and FreeRTOS
|
||||
/// - Retrieveing attestation tokens (@ref sl_se_manager_attestation)
|
||||
///
|
||||
/// ## Key Storage and Use of SE Wrapped Keys
|
||||
///
|
||||
|
@ -359,7 +374,7 @@ sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
|||
///
|
||||
/// ## Tamper
|
||||
///
|
||||
/// The Secure Element (SE) tamper module connects a number of hardware and software-driven tamper signals to a set of configurable hardware and software responses.
|
||||
/// 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,
|
||||
|
@ -431,22 +446,25 @@ sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx);
|
|||
///
|
||||
/// ## RTOS Mode and Multi-Thread Safety
|
||||
///
|
||||
/// The SE Manager supports multi-thread safe APIs for MicriumOS, FreeRTOS and Zephyr OS.
|
||||
/// @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.
|
||||
///
|
||||
/// For MicriumOS support the user application must define the compile time option SL_CATALOG_MICRIUMOS_KERNEL_PRESENT.
|
||||
/// For FreeRTOS support the user application must define the compile time option SL_CATALOG_FREERTOS_KERNEL_PRESENT.
|
||||
/// For Zephyr OS support the user application must define the compile time option SL_CATALOG_ZEPHYR_KERNEL_PRESENT.
|
||||
/// For bare metal mode (non-RTOS) the user must not define SL_CATALOG_MICRIUMOS_KERNEL_PRESENT, SL_CATALOG_FREERTOS_KERNEL_PRESENT or SL_CATALOG_ZEPHYR_KERNEL_PRESENT.
|
||||
/// For bare metal mode (non-RTOS) the user must not define SL_CATALOG_MICRIUMOS_KERNEL_PRESENT or SL_CATALOG_FREERTOS_KERNEL_PRESENT.
|
||||
///
|
||||
/// Applications created using Simplicity Studio 5 need to include the header file called _sl_component_catalog.h_ which will include a macro define for one of the abovementioned RTOSes if present.
|
||||
///
|
||||
/// In the cases with SL_CATALOG_MICRIUMOS_KERNEL_PRESENT, SL_CATALOG_FREERTOS_KERNEL_PRESENT or SL_CATALOG_ZEPHYR_KERNEL_PRESENT defined (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 Element to complete a mailbox command.
|
||||
/// In the cases with SL_CATALOG_MICRIUMOS_KERNEL_PRESENT or SL_CATALOG_FREERTOS_KERNEL_PRESENT defined (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 (_mutex_ in MicriumOS, _semaphore_ in FreeRTOS and both in Zephyr OS)
|
||||
/// to protect the Secure Element 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.
|
||||
/// 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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -32,7 +32,9 @@
|
|||
|
||||
#include "em_device.h"
|
||||
|
||||
#if defined(SEMAILBOX_PRESENT) || defined(DOXYGEN)
|
||||
#if (defined(SEMAILBOX_PRESENT) \
|
||||
&& (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) \
|
||||
|| defined(DOXYGEN)
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
@ -61,8 +63,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
|
@ -93,7 +93,9 @@ extern "C" {
|
|||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes.
|
||||
* 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.
|
||||
|
@ -123,10 +125,10 @@ sl_status_t sl_se_attestation_get_psa_iat_token(sl_se_command_context_t *cmd_ctx
|
|||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] challenge_size
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
* Size of the challenge object in bytes. Must be either 32, 48 or 64.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Buffer holding the input data.
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
|
@ -152,7 +154,9 @@ sl_status_t sl_se_attestation_get_psa_iat_token_size(sl_se_command_context_t *cm
|
|||
* Buffer where the output token will be stored.
|
||||
*
|
||||
* @param[in] token_buf_size
|
||||
* Size of token_buf in bytes.
|
||||
* 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.
|
||||
|
@ -182,10 +186,10 @@ sl_status_t sl_se_attestation_get_config_token(sl_se_command_context_t *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.
|
||||
* Size of the challenge object in bytes. Must be 32.
|
||||
*
|
||||
* @param[out] token_size
|
||||
* Number of bytes actually used in token_buf.
|
||||
* Pointer to output word. Result is stored here.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
|
@ -194,8 +198,6 @@ sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd
|
|||
size_t challenge_size,
|
||||
size_t *token_size);
|
||||
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -203,6 +205,6 @@ sl_status_t sl_se_attestation_get_config_token_size(sl_se_command_context_t *cmd
|
|||
/// @} (end addtogroup sl_se_manager_attestation)
|
||||
/// @} (end addtogroup sl_se_manager)
|
||||
|
||||
#endif // defined(SEMAILBOX_PRESENT)
|
||||
#endif // SEMAILBOX_PRESENT && VAULT
|
||||
|
||||
#endif // SL_SE_MANAGER_ATTESTATION_H
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#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_CATALOG_ZEPHYR_KERNEL_PRESENT)) \
|
||||
#if (defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)) \
|
||||
&& !defined(SL_SE_MANAGER_THREADING)
|
||||
#error "RTOS requires threading mode."
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -46,7 +46,7 @@
|
|||
* @details
|
||||
* API for performing symmetric encryption, Authenticated Encryption and
|
||||
* Additional Data (AEAD) operations, and computing Message Authentication
|
||||
* Codes (MACs) using the Secure Element.
|
||||
* Codes (MACs) using the Secure Engine.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
@ -339,7 +339,7 @@ sl_status_t sl_se_ccm_encrypt_and_tag(sl_se_command_context_t *cmd_ctx,
|
|||
* The buffer holding the tag.
|
||||
*
|
||||
* @param[in] tag_len
|
||||
* The length of the tag in Bytes.
|
||||
* The length of the tag in Bytes. Must be 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
|
@ -353,6 +353,145 @@ sl_status_t sl_se_ccm_auth_decrypt(sl_se_command_context_t *cmd_ctx,
|
|||
unsigned char *output,
|
||||
const unsigned char *tag, size_t tag_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a CCM streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a CCM streaming command context object to be used in subsequent
|
||||
* CCM streaming function calls.
|
||||
*
|
||||
* @param[in] ccm_ctx
|
||||
* Pointer to a CCM streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to a SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] mode
|
||||
* The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
|
||||
*
|
||||
* @param[in] total_message_length
|
||||
* The total length of the text to encrypt/decrypt
|
||||
*
|
||||
* @param[in] iv
|
||||
* The initialization vector (commonly referred to as nonce for CCM).
|
||||
*
|
||||
* @param[in] iv_len
|
||||
* The length of the IV.
|
||||
*
|
||||
* @param[in] add
|
||||
* The buffer holding the additional data.
|
||||
*
|
||||
* @param[in] add_len
|
||||
* The length of the additional data.
|
||||
*
|
||||
* @param[in] tag_len
|
||||
* Encryption: The length of the tag to generate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
|
||||
* Decryption: The length of the tag to authenticate. Must be 0, 4, 6, 8, 10, 12, 14 or 16.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ccm_multipart_starts(sl_se_ccm_multipart_context_t *ccm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_cipher_operation_t mode,
|
||||
uint32_t total_message_length,
|
||||
const uint8_t *iv,
|
||||
size_t iv_len,
|
||||
const uint8_t *add,
|
||||
size_t add_len,
|
||||
size_t tag_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function feeds an input buffer into an ongoing CCM computation.
|
||||
*
|
||||
* It is called between sl_se_ccm_multipart_starts() and sl_se_ccm_multipart_finish().
|
||||
* Can be called repeatedly.
|
||||
*
|
||||
* @param[in] ccm_ctx
|
||||
* Pointer to a CCM streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to a SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] length
|
||||
* The length of the input data. This must be a multiple of 16 except in
|
||||
* the last call before sl_se_ccm_multipart_finish().
|
||||
*
|
||||
* @param[in] input
|
||||
* Buffer holding the input data, must be at least @p length bytes wide.
|
||||
*
|
||||
* @param[out] output
|
||||
* Buffer for holding the output data, must be at least @p length bytes wide.
|
||||
*
|
||||
* @param[out] output_length
|
||||
* Length of data that has been encrypted/decrypted.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
|
||||
sl_status_t sl_se_ccm_multipart_update(sl_se_ccm_multipart_context_t *ccm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
size_t length,
|
||||
const uint8_t *input,
|
||||
uint8_t *output,
|
||||
size_t *output_length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Finish a CCM streaming operation and return the resulting CCM tag.
|
||||
*
|
||||
* It is called after sl_se_ccm_multipart_update().
|
||||
*
|
||||
* @param[in] ccm_ctx
|
||||
* Pointer to a CCM streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in, out] tag
|
||||
* Encryption: The buffer for holding the tag.
|
||||
* Decryption: The tag to authenticate.
|
||||
*
|
||||
* @param[in] tag_size
|
||||
* The size of the tag buffer. Must be equal or greater to the length of the expected tag.
|
||||
*
|
||||
* @param[out] output
|
||||
* Buffer for holding the output data.
|
||||
*
|
||||
* @param[in] output_size
|
||||
* Output buffer size. Must be equal or greater to the stored data from
|
||||
* sl_se_ccm_multipart_update (maximum 16 bytes).
|
||||
*
|
||||
* @param[out] output_length
|
||||
* Length of data that has been encrypted/decrypted.
|
||||
*
|
||||
* @return
|
||||
* Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_ccm_multipart_finish(sl_se_ccm_multipart_context_t *ccm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
uint8_t *tag,
|
||||
uint8_t tag_size,
|
||||
uint8_t *output,
|
||||
uint8_t output_size,
|
||||
uint8_t *output_length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function performs GCM encryption or decryption of a buffer.
|
||||
|
@ -540,16 +679,76 @@ sl_status_t sl_se_cmac(sl_se_command_context_t *cmd_ctx,
|
|||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_cmac_multipart_starts(sl_se_cmac_multipart_context_t *cmac_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_cmac_multipart_starts().
|
||||
*
|
||||
* Prepare a CMAC streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a CMAC streaming command context object to be used in subsequent
|
||||
* CMAC streaming function calls.
|
||||
*
|
||||
* @param[in] cmac_ctx
|
||||
* Pointer to a CMAC streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_cmac_starts(sl_se_cmac_streaming_context_t *cmac_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key);
|
||||
const sl_se_key_descriptor_t *key) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function feeds an input buffer into an ongoing CMAC computation.
|
||||
*
|
||||
* @details
|
||||
* It is called between sl_se_cmac_starts() and sl_se_cmac_finish().
|
||||
* It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
|
||||
* Can be called repeatedly.
|
||||
*
|
||||
* @param[in,out] cmac_ctx
|
||||
* Pointer to a CMAC streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] input
|
||||
* Buffer holding the input data, must be at least @p input_len 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_cmac_multipart_update(sl_se_cmac_multipart_context_t *cmac_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
const uint8_t *input,
|
||||
size_t input_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_cmac_multipart_update().
|
||||
*
|
||||
* This function feeds an input buffer into an ongoing CMAC computation.
|
||||
*
|
||||
* @details
|
||||
* It is called between sl_se_cmac_multipart_starts() and sl_se_cmac_multipart_finish().
|
||||
* Can be called repeatedly.
|
||||
*
|
||||
* @param[in,out] cmac_ctx
|
||||
|
@ -564,15 +763,45 @@ sl_status_t sl_se_cmac_starts(sl_se_cmac_streaming_context_t *cmac_ctx,
|
|||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
|
||||
sl_status_t sl_se_cmac_update(sl_se_cmac_streaming_context_t *cmac_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len);
|
||||
size_t input_len) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Finish a CMAC streaming operation and return the resulting CMAC tag.
|
||||
*
|
||||
* @details
|
||||
* It is called after sl_se_cmac_multipart_update().
|
||||
*
|
||||
* @param[in,out] cmac_ctx
|
||||
* Pointer to a CMAC streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[out] output
|
||||
* Buffer holding the 16-byte CMAC tag, must be at least 16 bytes wide.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_cmac_multipart_finish(sl_se_cmac_multipart_context_t *cmac_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
uint8_t *output);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_cmac_multipart_finish().
|
||||
*
|
||||
* Finish a CMAC streaming operation and return the resulting CMAC tag.
|
||||
*
|
||||
* @details
|
||||
* It is called after sl_se_cmac_update().
|
||||
*
|
||||
* @param[in,out] cmac_ctx
|
||||
|
@ -585,12 +814,13 @@ sl_status_t sl_se_cmac_update(sl_se_cmac_streaming_context_t *cmac_ctx,
|
|||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_cmac_finish(sl_se_cmac_streaming_context_t *cmac_ctx,
|
||||
uint8_t *output);
|
||||
uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a GCM streaming command context object.
|
||||
* Deprecated, please switch to using \ref sl_se_gcm_multipart_starts().
|
||||
*
|
||||
* Prepare a GCM streaming command context object.
|
||||
* @details
|
||||
* Prepare a GCM streaming command context object to be used in subsequent
|
||||
* GCM streaming function calls.
|
||||
|
@ -629,10 +859,56 @@ sl_status_t sl_se_gcm_starts(sl_se_gcm_streaming_context_t *gcm_ctx,
|
|||
const uint8_t *iv,
|
||||
size_t iv_len,
|
||||
const uint8_t *add,
|
||||
size_t add_len);
|
||||
size_t add_len) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare a GCM streaming command context object.
|
||||
*
|
||||
* @details
|
||||
* Prepare a GCM streaming command context object to be used in subsequent
|
||||
* GCM streaming function calls.
|
||||
*
|
||||
* @param[in, out] gcm_ctx
|
||||
* Pointer to a GCM streaming context object.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @param[in] key
|
||||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] mode
|
||||
* The operation to perform: SL_SE_ENCRYPT or SL_SE_DECRYPT.
|
||||
*
|
||||
* @param[in] iv
|
||||
* The initialization vector.
|
||||
*
|
||||
* @param[in] iv_len
|
||||
* The length of the IV.
|
||||
*
|
||||
* @param[in] add
|
||||
* The buffer holding the additional data, or NULL if @p add_len is 0.
|
||||
*
|
||||
* @param[in] add_len
|
||||
* The length of the additional data. If 0, @p add is NULL.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_gcm_multipart_starts(sl_se_gcm_multipart_context_t *gcm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
sl_se_cipher_operation_t mode,
|
||||
const uint8_t *iv,
|
||||
size_t iv_len,
|
||||
const uint8_t *add,
|
||||
size_t add_len);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_gcm_multipart_update().
|
||||
*
|
||||
* This function feeds an input buffer into an ongoing GCM computation.
|
||||
*
|
||||
* It is called between sl_se_gcm_starts() and sl_se_gcm_finish().
|
||||
|
@ -657,10 +933,45 @@ sl_status_t sl_se_gcm_starts(sl_se_gcm_streaming_context_t *gcm_ctx,
|
|||
sl_status_t sl_se_gcm_update(sl_se_gcm_streaming_context_t *gcm_ctx,
|
||||
size_t length,
|
||||
const uint8_t *input,
|
||||
uint8_t *output);
|
||||
uint8_t *output) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function feeds an input buffer into an ongoing GCM computation.
|
||||
*
|
||||
* It is called between sl_se_gcm_multipart_starts() and sl_se_gcm_multiapart_finish().
|
||||
* Can be called repeatedly.
|
||||
*
|
||||
* @param[in, out] gcm_ctx
|
||||
* Pointer to a GCM streaming context object.
|
||||
*
|
||||
* @param[in] length
|
||||
* The length of the input data.
|
||||
*
|
||||
* @param[in] input
|
||||
* Buffer holding the input data, must be at least @p length bytes wide.
|
||||
*
|
||||
* @param[out] output
|
||||
* Buffer for holding the output data, must be at least @p length bytes wide.
|
||||
*
|
||||
* @param[out] output_length
|
||||
* Length of data that has been encrypted/decrypted.
|
||||
*
|
||||
* @return
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_gcm_multipart_update(sl_se_gcm_multipart_context_t *gcm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
size_t length,
|
||||
const uint8_t *input,
|
||||
uint8_t *output,
|
||||
size_t *output_length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_gcm_multipart_finish().
|
||||
*
|
||||
* Finish a GCM streaming operation and return the resulting GCM tag.
|
||||
*
|
||||
* It is called after sl_se_gcm_update().
|
||||
|
@ -679,7 +990,47 @@ sl_status_t sl_se_gcm_update(sl_se_gcm_streaming_context_t *gcm_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_gcm_finish(sl_se_gcm_streaming_context_t *gcm_ctx,
|
||||
uint8_t *tag,
|
||||
size_t tag_len);
|
||||
size_t tag_len) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Finish a GCM streaming operation and return the resulting GCM tag.
|
||||
*
|
||||
* It is called after sl_se_gcm_multipart_update().
|
||||
*
|
||||
* @param[in, out] gcm_ctx
|
||||
* Pointer to a GCM streaming context object.
|
||||
*
|
||||
* @param[in, out] tag
|
||||
* Encryption: The buffer for holding the tag.
|
||||
* Decryption: The tag to authenticate.
|
||||
*
|
||||
* @param[in] tag_length
|
||||
* Encryption: Length of the output tag.
|
||||
* Decryption: Length of tag to verify
|
||||
*
|
||||
* @param[out] output
|
||||
* Buffer for holding the output data.
|
||||
*
|
||||
* @param[in] output_size
|
||||
* Output buffer size. Must be equal or greater to the stored data from
|
||||
* sl_se_gcm_multipart_update (stored data is maximum 16 bytes).
|
||||
*
|
||||
* @param[out] output_length
|
||||
* Length of data that has been encrypted/decrypted.
|
||||
*
|
||||
* @return
|
||||
* Returns SL_SE_INVALID_SIGNATURE if authentication step fails.
|
||||
* Status code, @ref sl_status.h.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_gcm_multipart_finish(sl_se_gcm_multipart_context_t *gcm_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
const sl_se_key_descriptor_t *key,
|
||||
uint8_t *tag,
|
||||
uint8_t tag_length,
|
||||
uint8_t *output,
|
||||
uint8_t output_size,
|
||||
uint8_t *output_length);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
/// of the configuration options in this file.
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) || defined(SL_CATALOG_ZEPHYR_KERNEL_PRESENT)
|
||||
#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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API definitions
|
||||
* @brief Silicon Labs Secure Engine Manager API definitions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,14 +34,16 @@
|
|||
|
||||
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) || defined(DOXYGEN)
|
||||
|
||||
#if !defined(SL_TRUSTZONE_NONSECURE)
|
||||
#if !defined(SE_MANAGER_CONFIG_FILE)
|
||||
#include "sl_se_manager_config.h"
|
||||
#else
|
||||
#include SE_MANAGER_CONFIG_FILE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
|
@ -139,30 +141,39 @@ extern "C" {
|
|||
|
||||
/// 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) || defined(DOXYGEN)
|
||||
/// Symmetric key type for ChaCha20
|
||||
#define SL_SE_KEY_TYPE_CHACHA20 0x00000020
|
||||
|
||||
/// 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-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 X25519 key for ECDH
|
||||
#define SL_SE_KEY_TYPE_ECC_X25519 (SL_SE_KEY_TYPE_ECC_MONTGOMERY | (0x20))
|
||||
/// 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
|
||||
|
@ -201,6 +212,11 @@ extern "C" {
|
|||
#define SL_SE_KEY_SLOT_VOLATILE_3 0x03 ///< Internal volatile slot 3
|
||||
#endif
|
||||
|
||||
/// Minimum key slot value for internal keys
|
||||
#define SL_SE_KEY_SLOT_INTERNAL_MIN 0xF7
|
||||
|
||||
/// 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)
|
||||
|
@ -216,6 +232,19 @@ extern "C" {
|
|||
#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
|
||||
/// @{
|
||||
|
||||
|
@ -228,14 +257,12 @@ extern "C" {
|
|||
/// Certificate signature size
|
||||
#define SL_SE_CERT_SIGN_SIZE 64
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
/// Batch ID certificate
|
||||
#define SL_SE_CERT_BATCH 0x01
|
||||
#define SL_SE_CERT_BATCH 0x01
|
||||
/// SE ID certificate
|
||||
#define SL_SE_CERT_DEVICE_SE 0x02
|
||||
#define SL_SE_CERT_DEVICE_SE 0x02
|
||||
/// Host ID certificate
|
||||
#define SL_SE_CERT_DEVICE_HOST 0x03
|
||||
#endif
|
||||
#define SL_SE_CERT_DEVICE_HOST 0x03
|
||||
|
||||
/// @addtogroup sl_se_manager_util_tamper Tamper options
|
||||
/// @brief
|
||||
|
@ -250,6 +277,8 @@ extern "C" {
|
|||
#define SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP 7 ///< Erase OTP - THIS WILL MAKE THE DEVICE INOPERATIONAL!
|
||||
|
||||
// SE tamper signals
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
|
||||
#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
|
||||
|
@ -284,6 +313,45 @@ extern "C" {
|
|||
#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
|
||||
|
||||
#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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -42,9 +42,9 @@
|
|||
*
|
||||
* @brief
|
||||
* Random number generators
|
||||
*
|
||||
* @details
|
||||
* API for getting randomness from the Secure Element True Random Number
|
||||
*
|
||||
* API for getting randomness from the Secure Engine True Random Number
|
||||
* Generator (TRNG).
|
||||
*
|
||||
* @{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -109,6 +109,29 @@ sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
|||
*
|
||||
* @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
|
||||
* Deprecated, please switch to using \ref sl_se_hash1_multipart_starts().
|
||||
*
|
||||
* 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_update() and
|
||||
* sl_se_hash_finish().
|
||||
*
|
||||
|
@ -126,7 +149,7 @@ sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha1_streaming_context_t *sha1_ctx);
|
||||
sl_se_sha1_streaming_context_t *sha1_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
|
@ -134,6 +157,29 @@ sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
*
|
||||
* @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
|
||||
* Deprecated, please switch to using \ref sl_se_hash224_multipart_starts().
|
||||
*
|
||||
* 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_update() and
|
||||
* sl_se_hash_finish().
|
||||
*
|
||||
|
@ -151,7 +197,7 @@ sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha224_streaming_context_t *sha224_ctx);
|
||||
sl_se_sha224_streaming_context_t *sha224_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
|
@ -159,6 +205,29 @@ sl_status_t sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
*
|
||||
* @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);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_hash256_multipart_starts().
|
||||
*
|
||||
* 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_update() and
|
||||
* sl_se_hash_finish().
|
||||
*
|
||||
|
@ -176,7 +245,7 @@ sl_status_t sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha256_streaming_context_t *sha256_ctx);
|
||||
sl_se_sha256_streaming_context_t *sha256_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
/***************************************************************************//**
|
||||
|
@ -185,6 +254,29 @@ sl_status_t sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
*
|
||||
* @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
|
||||
* Deprecated, please switch to using \ref sl_se_hash384_multipart_starts().
|
||||
*
|
||||
* 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_update() and
|
||||
* sl_se_hash_finish().
|
||||
*
|
||||
|
@ -202,7 +294,7 @@ sl_status_t sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha384_streaming_context_t *sha384_ctx);
|
||||
sl_se_sha384_streaming_context_t *sha384_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
|
@ -210,6 +302,29 @@ sl_status_t sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
*
|
||||
* @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);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_hash512_multipart_starts().
|
||||
*
|
||||
* 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_update() and
|
||||
* sl_se_hash_finish().
|
||||
*
|
||||
|
@ -227,7 +342,7 @@ sl_status_t sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha512_streaming_context_t *sha512_ctx);
|
||||
sl_se_sha512_streaming_context_t *sha512_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
/***************************************************************************//**
|
||||
|
@ -236,6 +351,35 @@ sl_status_t sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
*
|
||||
* @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
|
||||
* Deprecated, please switch to using \ref sl_se_hash_multipart_starts().
|
||||
*
|
||||
* 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_update()
|
||||
* and sl_se_hash_finish().
|
||||
*
|
||||
|
@ -258,12 +402,43 @@ sl_status_t sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
void *hash_type_ctx);
|
||||
void *hash_type_ctx) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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
|
||||
* Deprecated, please switch to using \ref sl_se_hash_multipart_update().
|
||||
*
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
*
|
||||
* This function is called between @ref sl_se_hash_starts() and
|
||||
* @ref sl_se_hash_finish().
|
||||
* This function can be called repeatedly.
|
||||
|
@ -282,12 +457,43 @@ sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len);
|
||||
size_t input_len) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deprecated, please switch to using \ref sl_se_hash_multipart_finish().
|
||||
*
|
||||
* Finish a hash streaming operation and return the resulting hash digest.
|
||||
*
|
||||
* This function is called after sl_se_hash_update().
|
||||
*
|
||||
* @param[in] hash_ctx
|
||||
|
@ -306,7 +512,7 @@ sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len);
|
||||
size_t digest_len) SL_DEPRECATED_API_SDK_3_3;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager Internal key defines
|
||||
* @brief Silicon Labs Secure Engine Manager Internal key defines
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -35,6 +35,7 @@
|
|||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
/// Key descriptor for internal application attestation key
|
||||
#define SL_SE_APPLICATION_ATTESTATION_KEY \
|
||||
{ \
|
||||
|
@ -50,6 +51,22 @@
|
|||
}, \
|
||||
}, \
|
||||
}
|
||||
#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
|
||||
|
@ -111,4 +128,16 @@
|
|||
}, \
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -366,7 +366,7 @@ sl_status_t sl_se_ecjpake_write_round_two(sl_se_ecjpake_context_t *ctx,
|
|||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given lenght of the generated key.
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
|
@ -391,8 +391,11 @@ sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
|||
* @param[in] in_key
|
||||
* Pointer to the input key material.
|
||||
*
|
||||
* @param[in] hash
|
||||
* Which hashing algorithm to use.
|
||||
* @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).
|
||||
|
@ -405,7 +408,7 @@ sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
|||
*
|
||||
* @param[in,out] out_key
|
||||
* Pointer to the generated key material. The length member of out_key is
|
||||
* used to request a given lenght of the generated key.
|
||||
* used to request a given length of the generated key.
|
||||
*
|
||||
* @return
|
||||
* SL_STATUS_OK if the signature is successfully verified, otherwise an
|
||||
|
@ -413,7 +416,7 @@ sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
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_hash_type_t hash,
|
||||
sl_se_pbkdf2_prf_type_t prf,
|
||||
const unsigned char *salt,
|
||||
size_t salt_len,
|
||||
uint32_t iterations,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager key handling.
|
||||
* @brief Silicon Labs Secure Engine Manager key handling.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -50,7 +50,7 @@ extern "C" {
|
|||
/***************************************************************************//**
|
||||
* \addtogroup sl_se_manager_key_handling Key handling
|
||||
*
|
||||
* \brief Secure Element key handling API.
|
||||
* \brief Secure Engine key handling API.
|
||||
*
|
||||
* \details
|
||||
* API for using cryptographic keys with the SE. Contains functionality to
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -87,10 +87,12 @@ extern "C" {
|
|||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use.
|
||||
* 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.
|
||||
* 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.
|
||||
|
@ -139,10 +141,12 @@ sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
|||
* Pointer to sl_se_key_descriptor_t structure.
|
||||
*
|
||||
* @param[in] hash_alg
|
||||
* Which hashing algorithm to use.
|
||||
* 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.
|
||||
* 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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API types
|
||||
* @brief Silicon Labs Secure Engine Manager API types
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -78,6 +78,7 @@ 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 {
|
||||
|
@ -88,7 +89,6 @@ typedef struct {
|
|||
|
||||
/// SE certificate types
|
||||
typedef uint8_t sl_se_cert_type_t;
|
||||
#endif // _SILICON_LABS_SECURITY_FEATURE_VAULT
|
||||
|
||||
/// OTP initialization data structure
|
||||
typedef struct {
|
||||
|
@ -331,15 +331,42 @@ typedef enum {
|
|||
|
||||
/// CMAC streaming context
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
const sl_se_key_descriptor_t *key; ///< Pointer to key object
|
||||
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;
|
||||
|
||||
/// CMAC streaming context. Deprecated.
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
const sl_se_key_descriptor_t *key; ///< Pointer to key object
|
||||
sl_se_cmac_multipart_context_t cmac_ctx; ///< CMAC streaming context
|
||||
} sl_se_cmac_streaming_context_t;
|
||||
|
||||
/// GCM streaming context
|
||||
/// 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 (_SILICON_LABS_32B_SERIES_2_CONFIG == 1)
|
||||
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;
|
||||
#endif
|
||||
uint8_t final_data_length; ///< Length of data saved
|
||||
} sl_se_ccm_multipart_context_t;
|
||||
|
||||
/// GCM streaming context. Deprecated.
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
const sl_se_key_descriptor_t *key;///< Pointer to key object
|
||||
|
@ -352,6 +379,20 @@ typedef struct {
|
|||
bool last_op; ///< Last operation / update
|
||||
} sl_se_gcm_streaming_context_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t len; ///< Total length of the encrypted data
|
||||
uint64_t add_len; ///< Total length of the additional data
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG < 3)
|
||||
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
|
||||
|
@ -369,7 +410,7 @@ typedef enum {
|
|||
#endif
|
||||
} sl_se_hash_type_t;
|
||||
|
||||
/// Generic hash streaming context
|
||||
/// Generic hash streaming context. Deprecated.
|
||||
typedef struct {
|
||||
sl_se_command_context_t *cmd_ctx; ///< Pointer to command context object
|
||||
sl_se_hash_type_t hash_type; ///< Hash type
|
||||
|
@ -377,21 +418,45 @@ typedef struct {
|
|||
void *hash_type_ctx; ///< Pointer to hash specific context
|
||||
} sl_se_hash_streaming_context_t;
|
||||
|
||||
/// SHA-1 streaming context
|
||||
/// SHA-1 streaming context. Safe to use.
|
||||
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-1 streaming context. Deprecated.
|
||||
typedef struct {
|
||||
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_streaming_context_t;
|
||||
|
||||
/// SHA-224 streaming context
|
||||
/// SHA-224 streaming context. Safe to use.
|
||||
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-224 streaming context. Deprecated.
|
||||
typedef struct {
|
||||
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_streaming_context_t;
|
||||
|
||||
/// SHA-256 streaming context
|
||||
/// SHA-256 streaming context. Safe to use.
|
||||
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;
|
||||
|
||||
/// SHA-256 streaming context. Deprecated.
|
||||
typedef struct {
|
||||
uint32_t total[2]; ///< Number of bytes processed
|
||||
uint8_t state[32]; ///< Intermediate digest state
|
||||
|
@ -399,14 +464,30 @@ typedef struct {
|
|||
} sl_se_sha256_streaming_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
/// SHA-384 streaming context
|
||||
/// SHA-384 streaming context. Safe to use.
|
||||
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-384 streaming context. Deprecated.
|
||||
typedef struct {
|
||||
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_streaming_context_t;
|
||||
|
||||
/// SHA-512 streaming context
|
||||
/// SHA-512 streaming context. Safe to use.
|
||||
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;
|
||||
|
||||
/// SHA-512 streaming context. Deprecated.
|
||||
typedef struct {
|
||||
uint32_t total[4]; ///< Number of bytes processed
|
||||
uint8_t state[64]; ///< Intermediate digest state
|
||||
|
@ -452,6 +533,13 @@ typedef struct {
|
|||
uint8_t Xp[64]; ///< Their point (round 2)
|
||||
} sl_se_ecjpake_context_t;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
/// 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(SEMAILBOX_PRESENT)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -44,13 +44,15 @@
|
|||
* Device initialisation, debug lock, upgrade functionality, user data...
|
||||
*
|
||||
* @details
|
||||
* API for managing the Secure Element or Root code on a device. Upload and
|
||||
* 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 "em_se.h"
|
||||
#include "sl_status.h"
|
||||
|
@ -181,20 +183,6 @@ sl_status_t sl_se_apply_host_image(sl_se_command_context_t *cmd_ctx,
|
|||
void *image_addr,
|
||||
uint32_t size);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear Host firmware upgrade status.
|
||||
*
|
||||
* @param[in] cmd_ctx
|
||||
* Pointer to an SE command context object.
|
||||
*
|
||||
* @return
|
||||
* @retval SL_STATUS_OK when the Host upgrade status has been cleared,
|
||||
* otherwise an error code from @ref sl_status.h if no upgrade has been run
|
||||
* and there is nothing to clear.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_upgrade_status_clear(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get upgrade status of Host firmware image.
|
||||
|
@ -488,6 +476,7 @@ sl_status_t sl_se_get_serialnumber(sl_se_command_context_t *cmd_ctx,
|
|||
sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t *version);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1) || defined(DOXYGEN)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read the EMU->RSTCAUSE after a tamper reset. This function should be called
|
||||
|
@ -506,6 +495,7 @@ sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_get_reset_cause(sl_se_command_context_t *cmd_ctx,
|
||||
uint32_t* reset_cause);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
|
@ -580,7 +570,7 @@ sl_status_t sl_se_set_debug_options(sl_se_command_context_t *cmd_ctx,
|
|||
* @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 element.
|
||||
* commissioning information in the secure engine.
|
||||
*
|
||||
* @return
|
||||
* One of the following sl_status_t codes:
|
||||
|
@ -589,7 +579,7 @@ sl_status_t sl_se_set_debug_options(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_erase_device(sl_se_command_context_t *cmd_ctx);
|
||||
|
||||
/***************************************************************************//**
|
||||
/****************************************************************q***********//**
|
||||
* @brief
|
||||
* Disabled device erase functionality.
|
||||
*
|
||||
|
@ -709,6 +699,8 @@ sl_status_t sl_se_disable_tamper(sl_se_command_context_t *cmd_ctx,
|
|||
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.
|
||||
|
@ -748,7 +740,6 @@ 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);
|
||||
#endif // (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
||||
#endif // defined(SEMAILBOX_PRESENT)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager internal API.
|
||||
* @brief Silicon Labs Secure Engine Manager internal API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -49,7 +49,7 @@ extern "C" {
|
|||
// -------------------------------
|
||||
// SE status codes
|
||||
|
||||
/// Response status codes for the Secure Element
|
||||
/// 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
|
||||
|
@ -95,8 +95,6 @@ extern "C" {
|
|||
#define SLI_SE_COMMAND_APPLY_HOST_IMAGE 0x43060001UL
|
||||
#define SLI_SE_COMMAND_STATUS_HOST_IMAGE 0x43070000UL
|
||||
|
||||
#define SLI_SE_COMMAND_UPGRADE_STATUS_CLEAR 0x430B0000UL
|
||||
|
||||
#define SLI_SE_COMMAND_READ_OTP 0xFE040000UL
|
||||
|
||||
#define SLI_SE_COMMAND_INIT_OTP 0xFF000001UL
|
||||
|
@ -127,6 +125,8 @@ extern "C" {
|
|||
|
||||
#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
|
||||
|
||||
|
@ -149,11 +149,13 @@ extern "C" {
|
|||
#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_2_CONFIG_1)
|
||||
// SLI_SE_COMMAND_STATUS_READ_RSTCAUSE is only available on xG21 devices (series-2-config-1)
|
||||
#define SLI_SE_COMMAND_STATUS_READ_RSTCAUSE 0x43220000UL
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
#endif
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT_SIZE 0x43FA0000UL
|
||||
#define SLI_SE_COMMAND_READ_USER_CERT 0x43FB0000UL
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
#define SLI_SE_COMMAND_ATTEST_PSA_IAT 0x0A030000UL
|
||||
#define SLI_SE_COMMAND_ATTEST_CONFIG 0x0A040000UL
|
||||
#endif
|
||||
|
@ -173,18 +175,16 @@ extern "C" {
|
|||
#define SLI_SE_COMMAND_INIT_AES_128_KEY 0xFF0B0001UL
|
||||
#endif // SEMAILBOX_PRESENT
|
||||
|
||||
// Commands limited to SE Vault devices
|
||||
// Commands limited to SE Vault High devices
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
#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 0x02020002UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC 0x02020002UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_HKDF 0x02020003UL
|
||||
|
||||
#define SLI_SE_COMMAND_EDDSA_SIGN 0x06020000UL
|
||||
#define SLI_SE_COMMAND_EDDSA_VERIFY 0x06030000UL
|
||||
#define SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC 0x02020010UL
|
||||
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_ENCRYPT 0x0C000000UL
|
||||
#define SLI_SE_COMMAND_CHACHAPOLY_DECRYPT 0x0C010000UL
|
||||
|
@ -245,11 +245,9 @@ extern "C" {
|
|||
|
||||
/// Magic paramater for deleting user data
|
||||
#define SLI_SE_COMMAND_OPTION_ERASE_UD 0xDE1E7EADUL
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT) || defined(DOXYGEN)
|
||||
#define SLI_SE_COMMAND_CERT_BATCH 0x00000100UL
|
||||
#define SLI_SE_COMMAND_CERT_SE 0x00000200UL
|
||||
#define SLI_SE_COMMAND_CERT_HOST 0x00000300UL
|
||||
#endif
|
||||
#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) || defined(DOXYGEN)
|
||||
/// Use SHA384 as hash algorithm
|
||||
|
@ -275,6 +273,15 @@ extern "C" {
|
|||
#define SLI_SE_MAX_POINT_MULT_RETRIES 3U
|
||||
#endif
|
||||
|
||||
// EFR32xG23+ doesn't require padding of curve elements or other keys
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG) \
|
||||
&& (_SILICON_LABS_32B_SERIES_2_CONFIG < 3)
|
||||
#define SLI_SE_KEY_PADDING_REQUIRED
|
||||
#define SLI_SE_P521_PADDING_BYTES 2
|
||||
#else
|
||||
#define SLI_SE_P521_PADDING_BYTES 0
|
||||
#endif
|
||||
|
||||
// -------------------------------
|
||||
// Function-like macros
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -32,12 +32,16 @@
|
|||
#if defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
||||
#include "sl_se_manager.h"
|
||||
|
||||
#if !defined(SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT)
|
||||
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "sli_se_manager_osal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_system.h"
|
||||
#include "sl_assert.h"
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
#include "em_bus.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
|
@ -48,21 +52,40 @@
|
|||
|
||||
#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 bool se_manager_initialized = false;
|
||||
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 se_manager_osal_mutex_t se_lock;
|
||||
#endif
|
||||
static se_manager_osal_mutex_t se_lock = { 0 };
|
||||
|
||||
#define SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_START \
|
||||
int32_t kernel_lock_state = 0; \
|
||||
osKernelState_t kernel_state = se_manager_osal_kernel_get_state(); \
|
||||
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) { \
|
||||
kernel_lock_state = se_manager_osal_kernel_lock(); \
|
||||
if (kernel_lock_state < 0) { \
|
||||
return SL_STATUS_FAIL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_END \
|
||||
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) { \
|
||||
if (se_manager_osal_kernel_restore_lock(kernel_lock_state) < 0) { \
|
||||
return SL_STATUS_FAIL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // SL_SE_MANAGER_THREADING
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
// SE command completion.
|
||||
static se_manager_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 SE_Response_t se_manager_command_response;
|
||||
static SE_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)
|
||||
|
@ -80,9 +103,9 @@ sl_status_t sl_se_init(void)
|
|||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_START
|
||||
#endif
|
||||
|
||||
if ( !se_manager_initialized ) {
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
|
@ -107,7 +130,9 @@ sl_status_t sl_se_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
CORE_EXIT_CRITICAL();
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
@ -125,14 +150,16 @@ sl_status_t sl_se_deinit(void)
|
|||
#if defined (SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_SE_MANAGER_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.
|
||||
CORE_EXIT_CRITICAL();
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_END
|
||||
#endif
|
||||
|
||||
// Acquire the SE lock to make sure no thread is executing SE commands
|
||||
// when we de-initialize.
|
||||
|
@ -158,9 +185,12 @@ sl_status_t sl_se_deinit(void)
|
|||
|
||||
// Mark the SE Manager as un-initialized.
|
||||
se_manager_initialized = false;
|
||||
} else {
|
||||
CORE_EXIT_CRITICAL();
|
||||
}
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
else {
|
||||
SLI_SE_MANAGER_KERNEL_CRITICAL_SECTION_END
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined (SL_SE_MANAGER_THREADING)
|
||||
// || defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
@ -196,6 +226,10 @@ sl_status_t sli_se_to_sl_status(SE_Response_t res)
|
|||
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(CRYPTOACC_PRESENT)
|
||||
case SLI_SE_RESPONSE_MAILBOX_INVALID:
|
||||
return SL_STATUS_COMMAND_IS_INVALID;
|
||||
|
@ -207,42 +241,41 @@ sl_status_t sli_se_to_sl_status(SE_Response_t res)
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
|
||||
/***************************************************************************//**
|
||||
* Take the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
* 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)
|
||||
{
|
||||
return se_manager_osal_take_mutex(&se_lock);
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
sl_status_t status = se_manager_osal_take_mutex(&se_lock);
|
||||
#else
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
#endif
|
||||
#if defined(_CMU_CLKEN1_SEMAILBOXHOST_MASK)
|
||||
if (status == SL_STATUS_OK) {
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 1);
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Give the SE lock in order to synchronize multiple threads calling into
|
||||
* the SE Manager API concurrently.
|
||||
* 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)
|
||||
BUS_RegBitWrite(&CMU->CLKEN1, _CMU_CLKEN1_SEMAILBOXHOST_SHIFT, 0);
|
||||
#endif
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
return se_manager_osal_give_mutex(&se_lock);
|
||||
}
|
||||
|
||||
#else // SL_SE_MANAGER_THREADING
|
||||
|
||||
// No MT synchronization when the app does not need threading (e.g. bare metal)
|
||||
|
||||
sl_status_t sli_se_lock_acquire(void)
|
||||
{
|
||||
#else
|
||||
return SL_STATUS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
sl_status_t sli_se_lock_release(void)
|
||||
{
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#endif // SL_SE_MANAGER_THREADING
|
||||
|
||||
#if defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION)
|
||||
|
||||
/***************************************************************************//**
|
||||
|
@ -266,6 +299,29 @@ void SEMBRX_IRQHandler(void)
|
|||
|
||||
#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.
|
||||
|
@ -310,6 +366,8 @@ sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
|||
|
||||
// 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 = SE_readCommandResponse();
|
||||
|
@ -334,7 +392,7 @@ sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
#elif defined(CRYPTOACC_PRESENT)
|
||||
#elif defined(CRYPTOACC_PRESENT) // SEMAILBOX_PRESENT
|
||||
|
||||
sl_status_t sli_se_execute_and_wait(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
|
@ -421,7 +479,9 @@ sl_status_t sl_se_ack_command(sl_se_command_context_t *cmd_ctx)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // CRYPTOACC_PRESENT
|
||||
|
||||
#endif // !SL_CATALOG_TZ_SECURE_KEY_LIBRARY_NS_PRESENT
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize an SE command context object
|
||||
|
@ -450,29 +510,6 @@ sl_status_t sl_se_deinit_command_context(sl_se_command_context_t *cmd_ctx)
|
|||
return sl_se_init_command_context(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* 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
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
||||
#endif // defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -94,6 +94,60 @@ static sl_status_t validate_and_update_command_word(uint32_t *command_word,
|
|||
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
|
||||
SE_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);
|
||||
SE_DataTransfer_t noncedata =
|
||||
SE_DATATRANSFER_DEFAULT(dummy_nonce, challenge_size);
|
||||
SE_addDataInput(se_cmd, &noncedata);
|
||||
SE_DataTransfer_t sizedata =
|
||||
SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
SE_addDataOutput(se_cmd, &sizedata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get an attestation token from the SE
|
||||
|
@ -145,6 +199,18 @@ static sl_status_t get_attestation_token(sl_se_command_context_t *cmd_ctx,
|
|||
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
|
||||
SE_Command_t *se_cmd = &cmd_ctx->command;
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
@ -155,66 +221,12 @@ static sl_status_t get_attestation_token(sl_se_command_context_t *cmd_ctx,
|
|||
SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
SE_addDataOutput(se_cmd, &sizedata);
|
||||
SE_DataTransfer_t tokendata =
|
||||
SE_DATATRANSFER_DEFAULT(token_buf, ((token_buf_size + 0x3) & ~0x3));
|
||||
SE_DATATRANSFER_DEFAULT(token_buf, ((*token_size + 0x3) & ~0x3));
|
||||
SE_addDataOutput(se_cmd, &tokendata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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
|
||||
SE_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);
|
||||
SE_DataTransfer_t noncedata =
|
||||
SE_DATATRANSFER_DEFAULT(dummy_nonce, challenge_size);
|
||||
SE_addDataInput(se_cmd, &noncedata);
|
||||
SE_DataTransfer_t sizedata =
|
||||
SE_DATATRANSFER_DEFAULT(token_size, sizeof(*token_size));
|
||||
SE_addDataOutput(se_cmd, &sizedata);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,8 +34,6 @@
|
|||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_system.h"
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,13 +34,11 @@
|
|||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_system.h"
|
||||
#include "sl_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se Secure Element Manager API
|
||||
* \addtogroup sl_se Secure Engine Manager API
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -50,9 +48,8 @@
|
|||
/***************************************************************************//**
|
||||
* Start a SHA1 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha1_streaming_context_t *sha1_ctx)
|
||||
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,
|
||||
|
@ -65,7 +62,7 @@ sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || sha1_ctx == NULL) {
|
||||
if (cmd_ctx == NULL || sha1_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -73,10 +70,35 @@ sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
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 SHA1 stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha1_streaming_context_t *sha1_ctx)
|
||||
{
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || sha1_ctx == NULL ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
|
||||
sl_se_sha1_multipart_context_t sha1_ctx_multi;
|
||||
|
||||
sl_status_t status = sl_se_hash_sha1_multipart_starts(&sha1_ctx_multi, hash_ctx->cmd_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(sha1_ctx->total, sha1_ctx_multi.total, sizeof(sha1_ctx->total));
|
||||
memcpy(sha1_ctx->state, sha1_ctx_multi.state, sizeof(sha1_ctx->state));
|
||||
|
||||
hash_ctx->hash_type_ctx = sha1_ctx;
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA1;
|
||||
hash_ctx->size = 20;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
@ -85,9 +107,8 @@ sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
* Start a SHA224 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha224_streaming_context_t *sha224_ctx)
|
||||
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,
|
||||
|
@ -100,7 +121,7 @@ sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || sha224_ctx == NULL) {
|
||||
if (cmd_ctx == NULL || sha224_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -108,10 +129,37 @@ sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
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 SHA224 stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha224_streaming_context_t *sha224_ctx)
|
||||
{
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || sha224_ctx == NULL ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
|
||||
sl_se_sha224_multipart_context_t sha224_ctx_multi;
|
||||
|
||||
sl_status_t status = sl_se_hash_sha224_multipart_starts(&sha224_ctx_multi, hash_ctx->cmd_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy(sha224_ctx->total, sha224_ctx_multi.total, sizeof(sha224_ctx->total));
|
||||
memcpy(sha224_ctx->state, sha224_ctx_multi.state, sizeof(sha224_ctx->state));
|
||||
|
||||
hash_ctx->hash_type_ctx = sha224_ctx;
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA224;
|
||||
hash_ctx->size = 28;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
@ -120,9 +168,8 @@ sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
* Start a SHA256 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha256_streaming_context_t *sha256_ctx)
|
||||
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,
|
||||
|
@ -135,7 +182,7 @@ sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
0x5B, 0xE0, 0xCD, 0x19
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || sha256_ctx == NULL) {
|
||||
if (cmd_ctx == NULL || sha256_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -143,10 +190,37 @@ sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
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;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA256 stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha256_streaming_context_t *sha256_ctx)
|
||||
{
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || sha256_ctx == NULL ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
hash_ctx->hash_type_ctx = sha256_ctx;
|
||||
|
||||
sl_se_sha256_multipart_context_t sha256_ctx_multi;
|
||||
|
||||
sl_status_t status = sl_se_hash_sha256_multipart_starts(&sha256_ctx_multi, hash_ctx->cmd_ctx);
|
||||
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(sha256_ctx->total, sha256_ctx_multi.total, sizeof(sha256_ctx->total));
|
||||
memcpy(sha256_ctx->state, sha256_ctx_multi.state, sizeof(sha256_ctx->state));
|
||||
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA256;
|
||||
hash_ctx->size = 32;
|
||||
hash_ctx->hash_type_ctx = sha256_ctx;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
@ -156,9 +230,8 @@ sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
* Start a SHA384 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha384_streaming_context_t *sha384_ctx)
|
||||
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,
|
||||
|
@ -171,7 +244,7 @@ sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || sha384_ctx == NULL) {
|
||||
if (cmd_ctx == NULL || sha384_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -181,10 +254,36 @@ sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
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 SHA384 stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha384_streaming_context_t *sha384_ctx)
|
||||
{
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || sha384_ctx == NULL ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
hash_ctx->hash_type_ctx = sha384_ctx;
|
||||
|
||||
sl_se_sha384_multipart_context_t sha384_ctx_multi;
|
||||
|
||||
sl_status_t status = sl_se_hash_sha384_multipart_starts(&sha384_ctx_multi, hash_ctx->cmd_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
memcpy(sha384_ctx->total, sha384_ctx_multi.total, sizeof(sha384_ctx->total));
|
||||
memcpy(sha384_ctx->state, sha384_ctx_multi.state, sizeof(sha384_ctx->state));
|
||||
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA384;
|
||||
hash_ctx->size = 48;
|
||||
hash_ctx->hash_type_ctx = sha384_ctx;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
@ -193,9 +292,7 @@ sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
* Start a SHA512 stream operation.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha512_streaming_context_t *sha512_ctx)
|
||||
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,
|
||||
|
@ -208,7 +305,7 @@ sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79
|
||||
};
|
||||
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || sha512_ctx == NULL) {
|
||||
if (cmd_ctx == NULL || sha512_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -218,24 +315,91 @@ sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
sha512_ctx->total[3] = 0;
|
||||
memcpy(sha512_ctx->state, init_state_sha512, sizeof(sha512_ctx->state));
|
||||
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
hash_ctx->hash_type_ctx = sha512_ctx;
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA512;
|
||||
hash_ctx->size = 64;
|
||||
sha512_ctx->hash_type = SL_SE_HASH_SHA512;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a SHA512 stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t
|
||||
sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_sha512_streaming_context_t *sha512_ctx)
|
||||
{
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || sha512_ctx == NULL ) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
hash_ctx->cmd_ctx = cmd_ctx;
|
||||
|
||||
sl_se_sha512_multipart_context_t sha512_ctx_multi;
|
||||
|
||||
sl_status_t status = sl_se_hash_sha512_multipart_starts(&sha512_ctx_multi, hash_ctx->cmd_ctx);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
memcpy(sha512_ctx->total, sha512_ctx_multi.total, sizeof(sha512_ctx->total));
|
||||
memcpy(sha512_ctx->state, sha512_ctx_multi.state, sizeof(sha512_ctx->state));
|
||||
|
||||
hash_ctx->hash_type = SL_SE_HASH_SHA512;
|
||||
hash_ctx->hash_type_ctx = sha512_ctx;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Start a hash stream operation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_hash_type_t hash_type,
|
||||
void *hash_type_ctx)
|
||||
{
|
||||
if (cmd_ctx == NULL || hash_ctx == NULL || hash_type_ctx == NULL) {
|
||||
if (hash_ctx == NULL || cmd_ctx == NULL || hash_type_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -257,7 +421,6 @@ sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
cmd_ctx,
|
||||
(sl_se_sha256_streaming_context_t*)
|
||||
hash_type_ctx);
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
return sl_se_hash_sha384_starts(hash_ctx,
|
||||
|
@ -280,24 +443,24 @@ sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
/***************************************************************************//**
|
||||
* Feeds an input block into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
const uint8_t *input,
|
||||
uint32_t num_blocks)
|
||||
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)
|
||||
{
|
||||
sl_se_command_context_t *cmd_ctx = hash_ctx->cmd_ctx;
|
||||
SE_Command_t *se_cmd = &cmd_ctx->command;
|
||||
uint32_t command_word;
|
||||
unsigned int ilen, state_len;
|
||||
uint8_t *state;
|
||||
|
||||
switch (hash_ctx->hash_type) {
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA1;
|
||||
// SHA1 block size is 64 bytes
|
||||
ilen = 64 * num_blocks;
|
||||
// SHA1 state size is 20 bytes
|
||||
state_len = 20;
|
||||
state = ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
|
@ -306,7 +469,7 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
ilen = 64 * num_blocks;
|
||||
// SHA224 state size is 32 bytes
|
||||
state_len = 32;
|
||||
state = ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
|
@ -315,7 +478,7 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
ilen = 64 * num_blocks;
|
||||
// SHA256 state size is 32 bytes
|
||||
state_len = 32;
|
||||
state = ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
@ -325,7 +488,7 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
ilen = 128 * num_blocks;
|
||||
// SHA384 state size is 64 bytes
|
||||
state_len = 64;
|
||||
state = ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
|
@ -334,7 +497,7 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
ilen = 128 * num_blocks;
|
||||
// SHA512 state size is 64 bytes
|
||||
state_len = 64;
|
||||
state = ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -346,7 +509,7 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
|
||||
SE_addParameter(se_cmd, ilen);
|
||||
|
||||
SE_DataTransfer_t data_in = SE_DATATRANSFER_DEFAULT((void *)input, ilen);
|
||||
SE_DataTransfer_t data_in = SE_DATATRANSFER_DEFAULT(input, ilen);
|
||||
SE_DataTransfer_t iv_in = SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
SE_DataTransfer_t iv_out = SE_DATATRANSFER_DEFAULT(state, state_len);
|
||||
|
||||
|
@ -361,9 +524,10 @@ static sl_status_t se_cmd_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
/***************************************************************************//**
|
||||
* Feeds an input buffer into an ongoing hash computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len)
|
||||
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 blocksize, countersize, blocks, fill, left;
|
||||
uint32_t *counter;
|
||||
|
@ -374,45 +538,45 @@ sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
if (hash_ctx == NULL || input == NULL) {
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || input == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_ctx->hash_type) {
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
blocksize = 64;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer;
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
blocksize = 64;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer;
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
blocksize = 64;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer;
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
blocksize = 128;
|
||||
countersize = 128 / 32;
|
||||
counter = ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer;
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
blocksize = 128;
|
||||
countersize = 128 / 32;
|
||||
counter = ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer;
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -428,16 +592,20 @@ sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
// 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
|
||||
}
|
||||
|
||||
if ( (left > 0) && (input_len >= fill) ) {
|
||||
memcpy( (void *) (buffer + left), input, fill);
|
||||
status = se_cmd_hash_update(hash_ctx, buffer, 1);
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, buffer, 1);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
@ -448,7 +616,7 @@ sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
|
||||
if ( input_len >= blocksize ) {
|
||||
blocks = input_len / blocksize;
|
||||
status = se_cmd_hash_update(hash_ctx, input, blocks);
|
||||
status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, input, blocks);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
@ -462,13 +630,121 @@ sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
/***************************************************************************//**
|
||||
* Feeds an input buffer into an ongoing hash computation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_len)
|
||||
|
||||
{
|
||||
if (hash_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_ctx->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
{
|
||||
sl_se_sha1_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA1;
|
||||
sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA224:
|
||||
{
|
||||
sl_se_sha224_multipart_context_t hash_type_ctx_multi;
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA224;
|
||||
sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
|
||||
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA256:
|
||||
{
|
||||
sl_se_sha256_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA256;
|
||||
sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
|
||||
break;
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
{
|
||||
sl_se_sha384_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA384;
|
||||
sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA512:
|
||||
{
|
||||
sl_se_sha512_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA512;
|
||||
sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Finish an ongoing hash streaming computation.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len)
|
||||
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)
|
||||
{
|
||||
size_t last_data_byte, num_pad_bytes, blocksize, countersize, outputsize;
|
||||
uint8_t msglen[16];
|
||||
|
@ -495,33 +771,33 @@ sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
};
|
||||
#endif
|
||||
|
||||
if (hash_ctx == NULL || digest_out == NULL) {
|
||||
if (hash_type_ctx == NULL || cmd_ctx == NULL || digest_out == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_ctx->hash_type) {
|
||||
switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
blocksize = 64;
|
||||
outputsize = 20;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
state = ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
|
||||
state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
blocksize = 64;
|
||||
outputsize = 28;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
state = ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
|
||||
state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
blocksize = 64;
|
||||
outputsize = 32;
|
||||
countersize = 64 / 32;
|
||||
counter = ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
state = ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
|
||||
state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|
@ -529,16 +805,16 @@ sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
blocksize = 128;
|
||||
outputsize = 48;
|
||||
countersize = 128 / 32;
|
||||
counter = ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
state = ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
|
||||
state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
blocksize = 128;
|
||||
outputsize = 64;
|
||||
countersize = 128 / 32;
|
||||
counter = ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total;
|
||||
state = ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state;
|
||||
counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
|
||||
state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -568,12 +844,94 @@ sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
|||
? ( (blocksize - (countersize * 4)) - last_data_byte)
|
||||
: ( ((2 * blocksize) - (countersize * 4)) - last_data_byte);
|
||||
|
||||
sl_se_hash_update(hash_ctx, sha_padding, num_pad_bytes);
|
||||
sl_se_hash_update(hash_ctx, msglen, countersize * 4);
|
||||
sl_status_t status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, sha_padding, num_pad_bytes);
|
||||
|
||||
memcpy(digest_out, state, outputsize);
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, msglen, countersize * 4);
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
if (status == SL_STATUS_OK) {
|
||||
memcpy(digest_out, state, outputsize);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Finish an ongoing hash streaming computation. Deprecated.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
|
||||
uint8_t *digest_out,
|
||||
size_t digest_len)
|
||||
{
|
||||
if (hash_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash_ctx->hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
{
|
||||
sl_se_sha1_multipart_context_t hash_type_ctx_multi;
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
|
||||
hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA1;
|
||||
return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA224:
|
||||
{
|
||||
sl_se_sha224_multipart_context_t hash_type_ctx_multi;
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
|
||||
return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
|
||||
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA256:
|
||||
{
|
||||
sl_se_sha256_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
|
||||
return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
|
||||
|
||||
break;
|
||||
}
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
case SL_SE_HASH_SHA384:
|
||||
{
|
||||
sl_se_sha384_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
|
||||
return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
|
||||
|
||||
break;
|
||||
}
|
||||
case SL_SE_HASH_SHA512:
|
||||
{
|
||||
sl_se_sha512_multipart_context_t hash_type_ctx_multi;
|
||||
|
||||
memcpy(hash_type_ctx_multi.total, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
|
||||
memcpy(hash_type_ctx_multi.state, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
|
||||
memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
|
||||
hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
|
||||
return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
|
@ -586,26 +944,60 @@ sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
|
|||
uint8_t* digest,
|
||||
size_t digest_len)
|
||||
{
|
||||
sl_status_t status;
|
||||
sl_se_hash_streaming_context_t hash_ctx;
|
||||
union hash_type_ctx_u {
|
||||
sl_se_sha1_streaming_context_t sha1_ctx;
|
||||
sl_se_sha224_streaming_context_t sha224_ctx;
|
||||
sl_se_sha256_streaming_context_t sha256_ctx;
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
sl_se_sha384_streaming_context_t sha384_ctx;
|
||||
sl_se_sha512_streaming_context_t sha512_ctx;
|
||||
#endif
|
||||
} hash_type_ctx;
|
||||
|
||||
status = sl_se_hash_starts(&hash_ctx, cmd_ctx, hash_type, &hash_type_ctx);
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = sl_se_hash_update(&hash_ctx, message, message_size);
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = sl_se_hash_finish(&hash_ctx, digest, digest_len);
|
||||
}
|
||||
if (cmd_ctx == NULL
|
||||
|| digest == NULL
|
||||
|| (message == NULL
|
||||
&& message_size != 0)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
return status;
|
||||
|
||||
SE_Command_t *se_cmd = &cmd_ctx->command;
|
||||
uint32_t command_word = SE_COMMAND_HASH;
|
||||
uint32_t digest_size = 0;
|
||||
|
||||
switch (hash_type) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SE_COMMAND_OPTION_HASH_SHA1;
|
||||
digest_size = 20;
|
||||
break;
|
||||
case SL_SE_HASH_SHA224:
|
||||
command_word |= SE_COMMAND_OPTION_HASH_SHA224;
|
||||
digest_size = 28;
|
||||
break;
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= 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 |= SE_COMMAND_OPTION_HASH_SHA384;
|
||||
digest_size = 48;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
digest_size = 64;
|
||||
command_word |= 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);
|
||||
|
||||
SE_addParameter(se_cmd, message_size);
|
||||
|
||||
SE_DataTransfer_t data_in = SE_DATATRANSFER_DEFAULT(message, message_size);
|
||||
SE_DataTransfer_t data_out = SE_DATATRANSFER_DEFAULT(digest, digest_size);
|
||||
|
||||
SE_addDataInput(se_cmd, &data_in);
|
||||
SE_addDataOutput(se_cmd, &data_out);
|
||||
|
||||
// Execute and wait
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup sl_se) */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,13 +34,11 @@
|
|||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_system.h"
|
||||
#include <string.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* \addtogroup sl_se Secure Element Manager API
|
||||
* \addtogroup sl_se Secure Engine Manager API
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -120,8 +118,14 @@ sl_status_t sl_se_ecdh_compute_shared_secret(sl_se_command_context_t *cmd_ctx,
|
|||
}
|
||||
}
|
||||
#else
|
||||
if ((key_pubkey_size * 2) > key_out->storage.location.buffer.size) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
if (key_in_priv->type == SL_SE_KEY_TYPE_ECC_X25519) {
|
||||
if (key_pubkey_size > key_out->storage.location.buffer.size) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
if ((key_pubkey_size * 2) > key_out->storage.location.buffer.size) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -437,7 +441,7 @@ sl_status_t sl_se_ecjpake_check(const sl_se_ecjpake_context_t *ctx)
|
|||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ctx->curve_flags == 0 || (ctx->pwd_len > 0 && ctx->pwd == NULL)) {
|
||||
if (ctx->curve_flags == 0) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -1002,14 +1006,14 @@ sl_status_t sl_se_derive_key_hkdf(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
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_hash_type_t hash,
|
||||
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)
|
||||
{
|
||||
uint32_t hash_mask;
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
uint32_t command_word = 0U;
|
||||
|
||||
if ((cmd_ctx == NULL) || (in_key == NULL) || (out_key == NULL)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
|
@ -1022,27 +1026,40 @@ sl_status_t sl_se_derive_key_pbkdf2(sl_se_command_context_t *cmd_ctx,
|
|||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
switch (hash) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
hash_mask = SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
switch (prf) {
|
||||
case SL_SE_PRF_HMAC_SHA1:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC
|
||||
| SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA224:
|
||||
hash_mask = SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
case SL_SE_PRF_HMAC_SHA224:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC
|
||||
| SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
hash_mask = SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
case SL_SE_PRF_HMAC_SHA256:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC
|
||||
| SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA384:
|
||||
hash_mask = SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
case SL_SE_PRF_HMAC_SHA384:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC
|
||||
| SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
hash_mask = SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
case SL_SE_PRF_HMAC_SHA512:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_HMAC
|
||||
| SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG) \
|
||||
&& (_SILICON_LABS_32B_SERIES_2_CONFIG >= 3)
|
||||
// PBKDF2 with CMAC as the PRF was first supported on EFR32xG23.
|
||||
case SL_SE_PRF_AES_CMAC_128:
|
||||
command_word = SLI_SE_COMMAND_DERIVE_KEY_PBKDF2_CMAC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
|
@ -1050,7 +1067,7 @@ sl_status_t sl_se_derive_key_pbkdf2(sl_se_command_context_t *cmd_ctx,
|
|||
|
||||
// SE command structures.
|
||||
SE_Command_t *se_cmd = &cmd_ctx->command;
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_DERIVE_KEY_PBKDF2 | hash_mask);
|
||||
sli_se_command_init(cmd_ctx, command_word);
|
||||
|
||||
sli_add_key_parameters(cmd_ctx, in_key, status);
|
||||
SE_addParameter(se_cmd, salt_len);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager key handling.
|
||||
* @brief Silicon Labs Secure Engine Manager key handling.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -83,29 +83,25 @@
|
|||
#define KEYSPEC_ATTRIBUTES_ECC_SIGN (1U << 10)
|
||||
#define KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK 0x0000007fU
|
||||
|
||||
#define KEYSPEC_TYPE_ECC_EDWARDS ((uint32_t)(0xaUL << KEYSPEC_TYPE_OFFSET))
|
||||
#define KEYSPEC_TYPE_ECC_MONTGOMERY ((uint32_t)(0xbUL << KEYSPEC_TYPE_OFFSET))
|
||||
#define KEYSPEC_TYPE_ECC_EDDSA ((uint32_t)(0xcUL << KEYSPEC_TYPE_OFFSET))
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
#define KEYSPEC_TYPE_ECC_EDWARDS \
|
||||
(uint32_t)(0xaUL << KEYSPEC_TYPE_OFFSET)
|
||||
#define KEYSPEC_TYPE_ECC_MONTGOMERY \
|
||||
(uint32_t)(0xbUL << KEYSPEC_TYPE_OFFSET)
|
||||
#define KEYSPEC_TYPE_ECC_EDDSA \
|
||||
(uint32_t)(0xcUL << KEYSPEC_TYPE_OFFSET)
|
||||
|
||||
#define KEYSPEC_MODE_WRAPPED \
|
||||
(2UL << KEYSPEC_MODE_OFFSET)
|
||||
|
||||
#define KEYSPEC_RESTRICTION_INTERNAL \
|
||||
(2UL << KEYSPEC_RESTRICTION_OFFSET)
|
||||
#define KEYSPEC_RESTRICTION_RESTRICTED \
|
||||
(3UL << KEYSPEC_RESTRICTION_OFFSET)
|
||||
|
||||
#define KEYSPEC_ECC_WEIERSTRASS_PRIME_A_IS_ZERO \
|
||||
(1U << 9)
|
||||
#define KEYSPEC_ECC_WEIERSTRASS_PRIME_A_IS_MINUS_THREE \
|
||||
(1U << 8)
|
||||
|
||||
#endif
|
||||
|
||||
#define KEYSPEC_RESTRICTION_LOCKED (1UL << KEYSPEC_RESTRICTION_OFFSET)
|
||||
#define KEYSPEC_RESTRICTION_INTERNAL (2UL << KEYSPEC_RESTRICTION_OFFSET)
|
||||
#define KEYSPEC_RESTRICTION_RESTRICTED (3UL << KEYSPEC_RESTRICTION_OFFSET)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Local Functions
|
||||
|
@ -113,22 +109,22 @@
|
|||
sl_status_t sli_key_get_storage_size(const sl_se_key_descriptor_t* key,
|
||||
uint32_t *storage_size)
|
||||
{
|
||||
sl_status_t status;
|
||||
uint32_t key_size;
|
||||
|
||||
if (key == NULL || storage_size == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
status = sli_key_get_size(key, &key_size);
|
||||
uint32_t key_size = 0;
|
||||
sl_status_t status = sli_key_get_size(key, &key_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
uint32_t key_type = (key->type & KEYSPEC_TYPE_MASK);
|
||||
|
||||
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
|
||||
// Round up to word length
|
||||
key_size = (key_size + 3U) & ~0x03U;
|
||||
#endif
|
||||
|
||||
if (key_type == KEYSPEC_TYPE_RAW) {
|
||||
*storage_size = key_size;
|
||||
|
@ -149,22 +145,19 @@ sl_status_t sli_key_get_storage_size(const sl_se_key_descriptor_t* key,
|
|||
|
||||
if ((key_type == KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME)) {
|
||||
*storage_size = key_size * (1 * has_private_key + 2 * has_public_key + 6 * has_custom_curve);
|
||||
}
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
else if (key_type == KEYSPEC_TYPE_ECC_EDWARDS) {
|
||||
} else if (key_type == KEYSPEC_TYPE_ECC_EDWARDS) {
|
||||
*storage_size = key_size * (has_private_key + has_public_key + 5 * has_custom_curve);
|
||||
} else if ((key_type == KEYSPEC_TYPE_ECC_MONTGOMERY)
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_EDDSA)) {
|
||||
*storage_size = key_size * (has_private_key + has_public_key);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Clear the additional bytes of a key that is not word-aligned.
|
||||
|
@ -195,6 +188,7 @@ static sl_status_t clear_padding(const sl_se_key_descriptor_t *key)
|
|||
}
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Global Functions
|
||||
|
@ -210,11 +204,9 @@ sl_status_t sli_key_get_size(const sl_se_key_descriptor_t *key, uint32_t *size)
|
|||
if (key_type == KEYSPEC_TYPE_RAW) {
|
||||
*size = (key->type & KEYSPEC_ATTRIBUTES_MASK);
|
||||
} else if ((key_type == KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME)
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_EDWARDS)
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_MONTGOMERY)
|
||||
#endif
|
||||
) {
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_EDDSA)) {
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
bool has_custom_curve =
|
||||
((key->flags & SL_SE_KEY_FLAG_ASYMMETRIC_USES_CUSTOM_DOMAIN) != 0);
|
||||
|
@ -236,13 +228,7 @@ sl_status_t sli_key_get_size(const sl_se_key_descriptor_t *key, uint32_t *size)
|
|||
{
|
||||
*size = (key->type & KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK);
|
||||
}
|
||||
}
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
else if (key_type == KEYSPEC_TYPE_ECC_EDDSA) {
|
||||
*size = 32;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -272,8 +258,10 @@ sl_status_t sli_key_check_equivalent(const sl_se_key_descriptor_t *key_1,
|
|||
if (key_1->type != key_2->type) {
|
||||
// The type fields are different, but this may be due to one of the keys
|
||||
// not containing the size in the type, but rather in the size field.
|
||||
if ((key_1->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM) {
|
||||
if (((key_1->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_WEIERSTRASS_PRIME_CUSTOM)
|
||||
|| ((key_1->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== SL_SE_KEY_TYPE_ECC_EDDSA)) {
|
||||
if ((key_1->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)
|
||||
== (key_2->type & SL_SE_KEY_TYPE_ALGORITHM_MASK)) {
|
||||
// Assume that the sizes are equal for now (this will be checked later)
|
||||
|
@ -313,12 +301,12 @@ sl_status_t sli_key_check_equivalent(const sl_se_key_descriptor_t *key_1,
|
|||
}
|
||||
|
||||
// Verify key sizes
|
||||
uint32_t key_1_size;
|
||||
uint32_t key_1_size = 0;
|
||||
status = sli_key_get_size(key_1, &key_1_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
uint32_t key_2_size;
|
||||
uint32_t key_2_size = 0;
|
||||
status = sli_key_get_size(key_2, &key_2_size);
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
|
@ -387,14 +375,12 @@ sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t *key,
|
|||
if (key->flags & SL_SE_KEY_FLAG_NON_EXPORTABLE) {
|
||||
keyspec_restriction = KEYSPEC_RESTRICTION_LOCKED;
|
||||
}
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
if (key->flags & SL_SE_KEY_FLAG_IS_DEVICE_GENERATED) {
|
||||
keyspec_restriction = KEYSPEC_RESTRICTION_INTERNAL;
|
||||
}
|
||||
if ((key->flags & SL_SE_KEY_FLAG_IS_RESTRICTED) == SL_SE_KEY_FLAG_IS_RESTRICTED) {
|
||||
keyspec_restriction = KEYSPEC_RESTRICTION_RESTRICTED;
|
||||
}
|
||||
#endif
|
||||
// Key restrictions are only applicable to volatile and wrapped keys
|
||||
if (key->storage.method == SL_SE_KEY_STORAGE_EXTERNAL_PLAINTEXT) {
|
||||
if (keyspec_restriction != 0) {
|
||||
|
@ -421,7 +407,7 @@ sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t *key,
|
|||
|
||||
if (key->storage.method == SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE) {
|
||||
if (key->storage.location.slot
|
||||
< SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY) {
|
||||
< SL_SE_KEY_SLOT_INTERNAL_MIN) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
*keyspec = (*keyspec & ~KEYSPEC_INDEX_MASK)
|
||||
|
@ -474,12 +460,8 @@ sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t *key,
|
|||
}
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
if ((key->type & KEYSPEC_TYPE_MASK) >= KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME
|
||||
&& (key->type & KEYSPEC_TYPE_MASK) < KEYSPEC_TYPE_ECC_EDDSA) {
|
||||
#else
|
||||
if ((key->type & KEYSPEC_TYPE_MASK) == KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME) {
|
||||
#endif
|
||||
if (signing_only) {
|
||||
*keyspec |= KEYSPEC_ATTRIBUTES_ECC_SIGN;
|
||||
}
|
||||
|
@ -506,20 +488,12 @@ sl_status_t sli_se_key_to_keyspec(const sl_se_key_descriptor_t *key,
|
|||
*keyspec = (*keyspec & ~KEYSPEC_ATTRIBUTES_MASK)
|
||||
| (size & KEYSPEC_ATTRIBUTES_MASK);
|
||||
} else if ((key_type == KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME)
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_EDWARDS)
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_MONTGOMERY)
|
||||
#endif
|
||||
) {
|
||||
|| (key_type == KEYSPEC_TYPE_ECC_EDDSA)) {
|
||||
*keyspec = (*keyspec & ~KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK)
|
||||
| ((size - 1) & KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK);
|
||||
}
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
else if (key_type == KEYSPEC_TYPE_ECC_EDDSA) {
|
||||
*keyspec = (*keyspec & ~KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
} else {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
@ -589,7 +563,7 @@ sl_status_t sli_se_keyspec_to_key(const uint32_t keyspec,
|
|||
} else
|
||||
#endif
|
||||
if ((key_index <= SL_SE_KEY_SLOT_APPLICATION_ATTESTATION_KEY)
|
||||
&& (key_index >= SL_SE_KEY_SLOT_APPLICATION_SECURE_DEBUG_KEY)) {
|
||||
&& (key_index >= SL_SE_KEY_SLOT_INTERNAL_MIN)) {
|
||||
key->storage.method = SL_SE_KEY_STORAGE_INTERNAL_IMMUTABLE;
|
||||
} else {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
|
@ -663,21 +637,12 @@ sl_status_t sli_se_keyspec_to_key(const uint32_t keyspec,
|
|||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// For some ECC keys, their length is encoded in the type
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
if ((keyspec & KEYSPEC_TYPE_MASK) != KEYSPEC_TYPE_ECC_EDDSA)
|
||||
#endif
|
||||
{
|
||||
key->type = (key->type & ~SL_SE_KEY_TYPE_ATTRIBUTES_MASK) | ((keyspec & KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK) + 1);
|
||||
}
|
||||
// For ECC keys, their length is encoded in the type
|
||||
key->type = (key->type & ~SL_SE_KEY_TYPE_ATTRIBUTES_MASK) | ((keyspec & KEYSPEC_ATTRIBUTES_ECC_SIZE_MASK) + 1);
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
if ((keyspec & KEYSPEC_TYPE_MASK) >= KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME
|
||||
&& (keyspec & KEYSPEC_TYPE_MASK) < KEYSPEC_TYPE_ECC_EDDSA) {
|
||||
#else
|
||||
if ((keyspec & KEYSPEC_TYPE_MASK) == KEYSPEC_TYPE_ECC_WEIERSTRASS_PRIME) {
|
||||
#endif
|
||||
if (signing_only) {
|
||||
key->flags |= SL_SE_KEY_FLAG_ASYMMETRIC_SIGNING_ONLY;
|
||||
}
|
||||
|
@ -897,10 +862,13 @@ sl_status_t sl_se_generate_key(sl_se_command_context_t *cmd_ctx,
|
|||
// Execute command
|
||||
status = sli_se_execute_and_wait(cmd_ctx);
|
||||
|
||||
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
|
||||
// Clear padding for plaintext keys upon success
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = clear_padding(key_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1103,11 +1071,14 @@ sl_status_t sl_se_export_key(sl_se_command_context_t *cmd_ctx,
|
|||
|
||||
status = sli_se_execute_and_wait(cmd_ctx);
|
||||
|
||||
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
|
||||
// The SE will only output word-aligned data. Clear the extra padding before
|
||||
// returning
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = clear_padding(key_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1180,10 +1151,14 @@ sl_status_t sl_se_transfer_key(sl_se_command_context_t *cmd_ctx,
|
|||
sli_add_key_output(cmd_ctx, key_out, status);
|
||||
|
||||
status = sli_se_execute_and_wait(cmd_ctx);
|
||||
|
||||
#if defined(SLI_SE_KEY_PADDING_REQUIRED)
|
||||
// Clear padding bytes for plaintext keys upon success
|
||||
if (status == SL_STATUS_OK) {
|
||||
status = clear_padding(key_out);
|
||||
}
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,9 +34,6 @@
|
|||
#include "sl_se_manager.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_system.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
|
@ -65,31 +62,36 @@ sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
|||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_SIGN;
|
||||
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
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_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
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_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,16 +109,11 @@ sl_status_t sl_se_ecc_sign(sl_se_command_context_t *cmd_ctx,
|
|||
SE_DataTransfer_t message_buffer = SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
SE_addDataInput(se_cmd, &message_buffer);
|
||||
|
||||
#if defined(SL_SE_KEY_TYPE_ECC_EDDSA)
|
||||
// EdDSA requires the message twice
|
||||
SE_DataTransfer_t repeated_message_buffer;
|
||||
if (key->type == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
repeated_message_buffer.next = (void*)SE_DATATRANSFER_STOP;
|
||||
repeated_message_buffer.data = (void*)message;
|
||||
repeated_message_buffer.length = message_len;
|
||||
SE_addDataInput(se_cmd, (SE_DataTransfer_t*)&repeated_message_buffer);
|
||||
SE_DataTransfer_t repeated_message_buffer = SE_DATATRANSFER_DEFAULT(message, message_len);
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
SE_addDataInput(se_cmd, &repeated_message_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
SE_DataTransfer_t signature_buffer = SE_DATATRANSFER_DEFAULT(signature, signature_len);
|
||||
SE_addDataOutput(se_cmd, &signature_buffer);
|
||||
|
@ -148,32 +145,37 @@ sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
|||
sl_status_t status;
|
||||
uint32_t command_word = SLI_SE_COMMAND_SIGNATURE_VERIFY;
|
||||
|
||||
if (hashed_message == false) {
|
||||
switch (hash_alg) {
|
||||
case SL_SE_HASH_SHA1:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA1;
|
||||
break;
|
||||
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_SHA224:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA224;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA256:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA256;
|
||||
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_SHA384:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA384;
|
||||
break;
|
||||
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
case SL_SE_HASH_SHA512:
|
||||
command_word |= SLI_SE_COMMAND_OPTION_HASH_SHA512;
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,13 +195,10 @@ sl_status_t sl_se_ecc_verify(sl_se_command_context_t *cmd_ctx,
|
|||
SE_DataTransfer_t signature_buffer = SE_DATATRANSFER_DEFAULT(signature,
|
||||
signature_len);
|
||||
|
||||
#if defined(SL_SE_KEY_TYPE_ECC_EDDSA)
|
||||
if (key->type == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
if ((key->type & SL_SE_KEY_TYPE_ALGORITHM_MASK) == SL_SE_KEY_TYPE_ECC_EDDSA) {
|
||||
SE_addDataInput(se_cmd, &signature_buffer);
|
||||
SE_addDataInput(se_cmd, &message_buffer);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
SE_addDataInput(se_cmd, &message_buffer);
|
||||
SE_addDataInput(se_cmd, &signature_buffer);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Silicon Labs Secure Element Manager API.
|
||||
* @brief Silicon Labs Secure Engine Manager API.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
|
@ -34,10 +34,8 @@
|
|||
#include "sl_se_manager_util.h"
|
||||
#include "sli_se_manager_internal.h"
|
||||
#include "em_se.h"
|
||||
#include "em_core.h"
|
||||
#include "em_assert.h"
|
||||
#include "sl_assert.h"
|
||||
#include "em_system.h"
|
||||
#include <string.h>
|
||||
|
||||
/// @addtogroup sl_se_manager
|
||||
/// @{
|
||||
|
@ -210,21 +208,6 @@ sl_status_t sl_se_apply_host_image(sl_se_command_context_t *cmd_ctx,
|
|||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Clear Host firmware upgrade status.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_se_upgrade_status_clear(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// SE command structures
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_UPGRADE_STATUS_CLEAR);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Get upgrade status of Host firmware image.
|
||||
******************************************************************************/
|
||||
|
@ -471,17 +454,15 @@ sl_status_t sl_se_get_debug_lock_status(sl_se_command_context_t *cmd_ctx,
|
|||
#elif defined(CRYPTOACC_PRESENT)
|
||||
uint32_t vse_version = 0;
|
||||
uint32_t debug_lock_flags = 0;
|
||||
SE_Response_t vse_mbx_status = SE_RESPONSE_MAILBOX_INVALID;
|
||||
sl_status_t status;
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
sl_status_t status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Read SE version from VSE mailbox.
|
||||
vse_mbx_status = SE_getVersion(&vse_version);
|
||||
SE_Response_t vse_mbx_status = SE_getVersion(&vse_version);
|
||||
|
||||
// Reading debug lock status is not supported on VSE with versions <= 1.2.2.
|
||||
if ((vse_version <= 0x1010202UL) || (vse_mbx_status != SE_RESPONSE_OK)) {
|
||||
|
@ -575,15 +556,29 @@ sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
|
|||
uint8_t reset_threshold;
|
||||
} otp_tamper_settings;
|
||||
|
||||
// Check for reserved sources
|
||||
if ((otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_1] != SL_SE_TAMPER_LEVEL_IGNORE)
|
||||
|| (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_2] != SL_SE_TAMPER_LEVEL_IGNORE)
|
||||
|| (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_3] != SL_SE_TAMPER_LEVEL_IGNORE)
|
||||
|| (otp_init->tamper_levels[SL_SE_TAMPER_SIGNAL_RESERVED_4] != SL_SE_TAMPER_LEVEL_IGNORE)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Combine tamper levels, two per byte
|
||||
for (size_t i = 0; i < SL_SE_TAMPER_SIGNAL_NUM_SIGNALS; i += 2) {
|
||||
// Check for reserved levels
|
||||
EFM_ASSERT((otp_init->tamper_levels[i] != 3)
|
||||
&& (otp_init->tamper_levels[i] != 5)
|
||||
&& (otp_init->tamper_levels[i] != 6));
|
||||
EFM_ASSERT((otp_init->tamper_levels[i + 1] != 3)
|
||||
&& (otp_init->tamper_levels[i + 1] != 5)
|
||||
&& (otp_init->tamper_levels[i + 1] != 6));
|
||||
for (size_t offset = 0; offset < 2; ++offset) {
|
||||
switch (otp_init->tamper_levels[i + offset]) {
|
||||
case SL_SE_TAMPER_LEVEL_IGNORE:
|
||||
case SL_SE_TAMPER_LEVEL_INTERRUPT:
|
||||
case SL_SE_TAMPER_LEVEL_FILTER:
|
||||
case SL_SE_TAMPER_LEVEL_RESET:
|
||||
case SL_SE_TAMPER_LEVEL_PERMANENTLY_ERASE_OTP:
|
||||
break;
|
||||
default:
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
otp_tamper_settings.levels[i / 2] = (otp_init->tamper_levels[i] & 0x7)
|
||||
| ((otp_init->tamper_levels[i + 1] & 0x7) << 4);
|
||||
|
@ -601,7 +596,7 @@ sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
|
|||
uint8_t reserved3[2];
|
||||
} otp_tamper_settings = {
|
||||
{ 0x00 },
|
||||
{ 0xFF },
|
||||
{ 0xFF, 0xFF },
|
||||
{ 0x00 }
|
||||
};
|
||||
#endif
|
||||
|
@ -766,21 +761,18 @@ sl_status_t sl_se_init_otp(sl_se_command_context_t *cmd_ctx,
|
|||
sl_status_t sl_se_read_otp(sl_se_command_context_t *cmd_ctx,
|
||||
sl_se_otp_init_t *otp_settings)
|
||||
{
|
||||
uint32_t mcu_settings_flags = 0;
|
||||
SE_Response_t vse_mbx_status = SE_RESPONSE_MAILBOX_INVALID;
|
||||
sl_status_t status;
|
||||
|
||||
if (cmd_ctx == NULL || otp_settings == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Try to acquire SE lock
|
||||
status = sli_se_lock_acquire();
|
||||
sl_status_t status = sli_se_lock_acquire();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
vse_mbx_status = SE_getConfigStatusBits(&mcu_settings_flags);
|
||||
uint32_t mcu_settings_flags = 0;
|
||||
SE_Response_t vse_mbx_status = SE_getConfigStatusBits(&mcu_settings_flags);
|
||||
|
||||
// Release SE lock
|
||||
status = sli_se_lock_release();
|
||||
|
@ -945,6 +937,7 @@ sl_status_t sl_se_get_otp_version(sl_se_command_context_t *cmd_ctx,
|
|||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
/***************************************************************************//**
|
||||
* Read the EMU->RSTCAUSE after a tamper reset. This function should be called
|
||||
* if EMU->RSTCAUSE has been cleared upon boot.
|
||||
|
@ -964,6 +957,7 @@ sl_status_t sl_se_get_reset_cause(sl_se_command_context_t *cmd_ctx,
|
|||
SE_addDataOutput(se_cmd, &out_data);
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
#endif // _SILICON_LABS_32B_SERIES_2_CONFIG_1
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enables the secure debug functionality.
|
||||
|
@ -1073,11 +1067,16 @@ sl_status_t sl_se_get_challenge(sl_se_command_context_t *cmd_ctx,
|
|||
******************************************************************************/
|
||||
sl_status_t sl_se_roll_challenge(sl_se_command_context_t *cmd_ctx)
|
||||
{
|
||||
sl_se_challenge_t new_challenge;
|
||||
if (cmd_ctx == NULL) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SE_DataTransfer_t out_data =
|
||||
SE_DATATRANSFER_DEFAULT(new_challenge, sizeof(sl_se_challenge_t));
|
||||
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_ROLL_CHALLENGE);
|
||||
SE_addDataOutput(&cmd_ctx->command, &out_data);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
@ -1140,6 +1139,8 @@ sl_status_t sl_se_disable_tamper(sl_se_command_context_t *cmd_ctx,
|
|||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Read size of stored certificates in SE.
|
||||
******************************************************************************/
|
||||
|
@ -1158,9 +1159,7 @@ sl_status_t sl_se_read_cert_size(sl_se_command_context_t *cmd_ctx,
|
|||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
|
||||
/***************************************************************************//**
|
||||
* Read stored certificates in SE.
|
||||
******************************************************************************/
|
||||
|
@ -1196,12 +1195,16 @@ sl_status_t sl_se_read_cert(sl_se_command_context_t *cmd_ctx,
|
|||
// SE command structures
|
||||
sli_se_command_init(cmd_ctx, SLI_SE_COMMAND_READ_USER_CERT | se_cert_type);
|
||||
|
||||
#if _SILICON_LABS_32B_SERIES_2_CONFIG > 2
|
||||
// One parameter is required, but has no effect
|
||||
SE_addParameter(se_cmd, 0);
|
||||
#endif //
|
||||
|
||||
SE_DataTransfer_t out_data = SE_DATATRANSFER_DEFAULT(cert, num_bytes);
|
||||
SE_addDataOutput(se_cmd, &out_data);
|
||||
|
||||
return sli_se_execute_and_wait(cmd_ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // defined(SEMAILBOX_PRESENT)
|
||||
|
||||
|
|
|
@ -38,20 +38,16 @@
|
|||
#endif
|
||||
|
||||
#if defined (SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#include "sl_status.h"
|
||||
|
||||
#if defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT)
|
||||
// Include MicriumOS kernel abstraction layer:
|
||||
#include "sli_se_manager_osal_micriumos.h"
|
||||
#elif defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
|
||||
// Include FreeRTOS kernel abstraction layer:
|
||||
#include "sli_se_manager_osal_freertos.h"
|
||||
#elif defined(SL_CATALOG_ZEPHYR_KERNEL_PRESENT)
|
||||
// Include Zephyr OS kernel abstraction layer:
|
||||
#include "sli_se_manager_osal_zephyr.h"
|
||||
#if (defined(SL_CATALOG_MICRIUMOS_KERNEL_PRESENT) || defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)) \
|
||||
&& (defined(SL_SE_MANAGER_THREADING) \
|
||||
|| defined(SL_SE_MANAGER_YIELD_WHILE_WAITING_FOR_COMMAND_COMPLETION))
|
||||
// Include CMSIS RTOS2 kernel abstraction layer:
|
||||
#include "sli_se_manager_osal_cmsis_rtos2.h"
|
||||
#else
|
||||
// Include bare metal abstraction layer:
|
||||
#include "sli_se_manager_osal_baremetal.h"
|
||||
|
|
|
@ -79,7 +79,7 @@ __STATIC_INLINE
|
|||
sl_status_t se_manager_osal_init_completion(se_manager_osal_completion_t *p_comp)
|
||||
{
|
||||
*p_comp = 0;
|
||||
return (0);
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/// Free a completion object.
|
||||
|
@ -87,7 +87,7 @@ __STATIC_INLINE
|
|||
sl_status_t se_manager_osal_free_completion(se_manager_osal_completion_t *p_comp)
|
||||
{
|
||||
*p_comp = 0;
|
||||
return (0);
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/// Wait for completion event.
|
||||
|
@ -118,7 +118,7 @@ se_manager_osal_wait_completion(se_manager_osal_completion_t *p_comp, int ticks)
|
|||
}
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Signal completion event.
|
||||
|
@ -126,7 +126,7 @@ __STATIC_INLINE
|
|||
sl_status_t se_manager_osal_complete(se_manager_osal_completion_t* p_comp)
|
||||
{
|
||||
*p_comp = 1;
|
||||
return (0);
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
/**************************************************************************/ /**
|
||||
* @file
|
||||
* @brief OS abstraction layer primitives for SE manager on CMSIS RTOS2
|
||||
*******************************************************************************
|
||||
* # 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 SE_MANAGER_OSAL_CMSIS_RTOS_H
|
||||
#define SE_MANAGER_OSAL_CMSIS_RTOS_H
|
||||
|
||||
#include "cmsis_os2.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
|
||||
#else
|
||||
#include "em_core.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// In order to wait forever in blocking functions the user can pass the
|
||||
/// following value.
|
||||
#define SE_MANAGER_OSAL_WAIT_FOREVER (osWaitForever)
|
||||
/// In order to return immediately in blocking functions the user can pass the
|
||||
/// following value.
|
||||
#define SE_MANAGER_OSAL_NON_BLOCKING (0)
|
||||
|
||||
/// 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
|
||||
|
||||
/// Determine if executing at interrupt level on ARM Cortex-M.
|
||||
#define RUNNING_AT_INTERRUPT_LEVEL (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
|
||||
/// Completion object used to wait for and signal end of an operation.
|
||||
typedef struct se_manager_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;
|
||||
} se_manager_osal_completion_t;
|
||||
|
||||
/// SE manager mutex definition for CMSIS RTOS2.
|
||||
typedef struct se_manager_osal_mutex {
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
osMutexAttr_t mutex_attr;
|
||||
StaticSemaphore_t static_sem_object;
|
||||
#endif
|
||||
osMutexId_t mutex_ID;
|
||||
} se_manager_osal_mutex_t;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Functions
|
||||
|
||||
/// Initialize a mutex object.
|
||||
__STATIC_INLINE
|
||||
sl_status_t se_manager_osal_init_mutex(se_manager_osal_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
#if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
|
||||
// Zeroize all members of the mutex attributes object and setup the static control block.
|
||||
memset(&mutex->mutex_attr, 0, sizeof(mutex->mutex_attr));
|
||||
mutex->mutex_attr.cb_mem = &mutex->static_sem_object;
|
||||
mutex->mutex_attr.cb_size = sizeof(mutex->static_sem_object);
|
||||
mutex->mutex_ID = osMutexNew(&mutex->mutex_attr);
|
||||
#else
|
||||
mutex->mutex_ID = osMutexNew(NULL);
|
||||
#endif
|
||||
|
||||
return (mutex->mutex_ID == NULL ? SL_STATUS_FAIL : SL_STATUS_OK);
|
||||
}
|
||||
|
||||
/// Free a mutex object.
|
||||
__STATIC_INLINE
|
||||
sl_status_t se_manager_osal_free_mutex(se_manager_osal_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
osStatus_t status = osMutexDelete(mutex->mutex_ID);
|
||||
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
|
||||
}
|
||||
|
||||
/// Acquire ownership of a mutex. If busy, wait until available.
|
||||
__STATIC_INLINE
|
||||
sl_status_t se_manager_osal_take_mutex(se_manager_osal_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
osStatus_t status = osOK;
|
||||
if (osKernelGetState() == osKernelRunning) {
|
||||
status = osMutexAcquire(mutex->mutex_ID, SE_MANAGER_OSAL_WAIT_FOREVER);
|
||||
}
|
||||
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
|
||||
}
|
||||
|
||||
/// Try to acquire ownership of a mutex without waiting.
|
||||
__STATIC_INLINE
|
||||
sl_status_t se_manager_osal_take_mutex_non_blocking(se_manager_osal_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
osStatus_t status = osOK;
|
||||
if (osKernelGetState() == osKernelRunning) {
|
||||
status = osMutexAcquire(mutex->mutex_ID, SE_MANAGER_OSAL_NON_BLOCKING);
|
||||
}
|
||||
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
|
||||
}
|
||||
|
||||
/// Release ownership of a mutex.
|
||||
__STATIC_INLINE
|
||||
sl_status_t se_manager_osal_give_mutex(se_manager_osal_mutex_t *mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return SL_STATUS_FAIL;
|
||||
}
|
||||
|
||||
osStatus_t status = osOK;
|
||||
if (osKernelGetState() == osKernelRunning) {
|
||||
status = osMutexRelease(mutex->mutex_ID);
|
||||
}
|
||||
return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
|
||||
}
|
||||
|
||||
/// Initialize a completion object.
|
||||
__STATIC_INLINE sl_status_t
|
||||
se_manager_osal_init_completion(se_manager_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);
|
||||
}
|
||||
|
||||
/// Free a completion object.
|
||||
__STATIC_INLINE sl_status_t
|
||||
se_manager_osal_free_completion(se_manager_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);
|
||||
}
|
||||
|
||||
// Wait for a completion object to be completed.
|
||||
__STATIC_INLINE sl_status_t
|
||||
se_manager_osal_wait_completion(se_manager_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);
|
||||
}
|
||||
|
||||
// Complete a completion object.
|
||||
__STATIC_INLINE sl_status_t
|
||||
se_manager_osal_complete(se_manager_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);
|
||||
}
|
||||
|
||||
// Lock the RTOS Kernel scheduler.
|
||||
__STATIC_INLINE int32_t
|
||||
se_manager_osal_kernel_lock(void)
|
||||
{
|
||||
return osKernelLock();
|
||||
}
|
||||
|
||||
// Restore the RTOS Kernel scheduler lock state.
|
||||
__STATIC_INLINE int32_t
|
||||
se_manager_osal_kernel_restore_lock(int32_t lock)
|
||||
{
|
||||
return osKernelRestoreLock(lock);
|
||||
}
|
||||
|
||||
// Current RTOS kernel state.
|
||||
__STATIC_INLINE osKernelState_t
|
||||
se_manager_osal_kernel_get_state(void)
|
||||
{
|
||||
return osKernelGetState();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SE_MANAGER_OSAL_CMSIS_RTOS_H
|
205
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto.h
vendored
Normal file
205
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto.h
vendored
Normal file
|
@ -0,0 +1,205 @@
|
|||
/***************************************************************************//**
|
||||
* @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 "em_device.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @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_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_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_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.
|
||||
******************************************************************************/
|
||||
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_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_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_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.
|
||||
******************************************************************************/
|
||||
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
|
568
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_crypto.c
vendored
Normal file
568
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_crypto.c
vendored
Normal file
|
@ -0,0 +1,568 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Proprietary crypto primitivies optimized for Silicon Labs devices
|
||||
* with a CRYPTO peripheral.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 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(CRYPTO_PRESENT)
|
||||
|
||||
#include "sli_protocol_crypto.h"
|
||||
#include "crypto_management.h"
|
||||
#include "em_crypto.h"
|
||||
|
||||
// CCM (and CCM-star) implementation optimized for radio protocol usecases
|
||||
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,
|
||||
uint32_t *header,
|
||||
size_t header_length_over_16,
|
||||
unsigned char *tag,
|
||||
size_t tag_length)
|
||||
{
|
||||
// Assumptions:
|
||||
// * There is always header input, and the header buffer is 32 bytes and word-aligned
|
||||
// * The actual data content in the header is at least 16 bytes (full block) and
|
||||
// at maximum 32 bytes (precalculated B0_B1 in BLE). The remainder of the header buffer
|
||||
// is passed in zero-initialized.
|
||||
// * Input parameter header_length_over_16 reflects this: it says how much larger than 16 bytes the
|
||||
// header input buffer is.
|
||||
// * The header is always word-aligned
|
||||
// * 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
|
||||
|
||||
size_t L = (((uint8_t*)header)[0] & 0x7) + 1;
|
||||
|
||||
// Mangling DDATA1 (KEY), DDATA2 (= DATA0/DATA1), DDATA3 (=DATA2/DATA3),
|
||||
// DDATA4 (KEYBUF). Max execution sequence length = 20
|
||||
CRYPTO_TypeDef *device =
|
||||
crypto_management_acquire_preemption(CRYPTO_MANAGEMENT_SAVE_DDATA1
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA2
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA3
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA4
|
||||
| CRYPTO_MANAGEMENT_SAVE_UPTO_SEQ4);
|
||||
|
||||
// Setup CRYPTO for AES-128 mode (256 not implemented here)
|
||||
device->CTRL = CRYPTO_CTRL_AES_AES128;
|
||||
device->WAC = 0UL;
|
||||
|
||||
CRYPTO_KeyBufWriteUnaligned(device, key, cryptoKey128Bits);
|
||||
|
||||
// Store CBC IV in device->DATA0
|
||||
CRYPTO_DataWrite(&device->DATA0, header);
|
||||
|
||||
// Calculate Counter IV for encryption, which is basically
|
||||
// the CBC IV with the flags byte masked with 0x7, and zeroing
|
||||
// out the length field.
|
||||
((uint8_t*)header)[0] &= 0x07;
|
||||
for (size_t i = 16 - L; i < 16; i++) {
|
||||
((uint8_t*)header)[i] = 0;
|
||||
}
|
||||
|
||||
// Store Counter IV in crypto->DATA1
|
||||
CRYPTO_DataWrite(&device->DATA1, header);
|
||||
|
||||
// Start the CBC-MAC by encrypting the IV and storing the result in DATA
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESENC;
|
||||
|
||||
// Update the CBC-MAC with the remainder of the header and
|
||||
// the full AAD, up until block boundary
|
||||
if (header_length_over_16 + add_length > 0) {
|
||||
if (header_length_over_16 < 16) {
|
||||
// Fill up the remainder taking from the ADD (if any) and into the
|
||||
// second header block (guaranteed to have a 32-byte writeable buffer)
|
||||
if (add_length > 0) {
|
||||
size_t injected_add = add_length > (16 - header_length_over_16) ? 16 - header_length_over_16 : add_length;
|
||||
|
||||
for (size_t i = 0; i < injected_add; i++) {
|
||||
(&((uint8_t*)&header[4])[header_length_over_16])[i] = add_data[i];
|
||||
}
|
||||
|
||||
header_length_over_16 += injected_add;
|
||||
add_data += injected_add;
|
||||
add_length -= injected_add;
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate the second header block into the CBC-MAC
|
||||
CRYPTO_DataWrite(&device->DATA3, &header[4]);
|
||||
|
||||
// Accumulate: XOR the input block into the previously accumulated value in DATA0
|
||||
// and encrypt the result to get the updated accumulator in DATA0
|
||||
device->CMD = CRYPTO_CMD_INSTR_DATA3TODATA0XOR;
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESENC;
|
||||
device->CMD = CRYPTO_CMD_INSTR_DATA0TODATA3;
|
||||
|
||||
// Run the remainder of the ADD through the CBC-MAC accumulator
|
||||
if (add_length > 0) {
|
||||
// Set the iteration count
|
||||
device->SEQCTRL = add_length;
|
||||
device->SEQCTRLB = 0;
|
||||
|
||||
CRYPTO_EXECUTE_4(device,
|
||||
CRYPTO_CMD_INSTR_DMA0TODATA, // Load new block of data into DATA0
|
||||
CRYPTO_CMD_INSTR_DATA3TODATA0XOR, // XOR the accumulated tag with the new block
|
||||
CRYPTO_CMD_INSTR_AESENC, // Encrypt the XOR result
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA3 // Store the new accumulated tag to DATA3
|
||||
);
|
||||
while (add_length) {
|
||||
if (add_length < 16) {
|
||||
// Use writeable header buffer for zero padding
|
||||
header[0] = 0;
|
||||
header[1] = 0;
|
||||
header[2] = 0;
|
||||
header[3] = 0;
|
||||
// Since add_data is potentially unaligned, do a byte copy
|
||||
for (size_t i = 0; i < add_length; i++) {
|
||||
((uint8_t*)header)[i] = add_data[i];
|
||||
}
|
||||
CRYPTO_DataWrite(&device->DATA0, header);
|
||||
add_length = 0;
|
||||
} else {
|
||||
CRYPTO_DataWriteUnaligned(&device->DATA0, add_data);
|
||||
add_length -= 16;
|
||||
add_data += 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Move the CBC-MAC accumulator to DATA3
|
||||
device->CMD = CRYPTO_CMD_INSTR_DATA0TODATA3;
|
||||
}
|
||||
|
||||
// Set the iteration count
|
||||
device->SEQCTRL = length;
|
||||
device->SEQCTRLB = 0;
|
||||
|
||||
if (encrypt) {
|
||||
CRYPTO_EXECUTE_16(device,
|
||||
CRYPTO_CMD_INSTR_EXECIFA,
|
||||
|
||||
// Read data input into DATA2
|
||||
CRYPTO_CMD_INSTR_DMA0TODATA,
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA2,
|
||||
|
||||
// Accumulate the plaintext into the CBC-MAC
|
||||
CRYPTO_CMD_INSTR_DATA3TODATA0XOR,
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA3,
|
||||
|
||||
// Calculate key stream block
|
||||
CRYPTO_CMD_INSTR_DATA1INC,
|
||||
CRYPTO_CMD_INSTR_DATA1TODATA0,
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
|
||||
// XOR plaintext with key stream and output the result
|
||||
CRYPTO_CMD_INSTR_DATA2TODATA0XOR,
|
||||
CRYPTO_CMD_INSTR_DATATODMA0,
|
||||
|
||||
// Calculate tag into DATA0 when all data has been processed
|
||||
CRYPTO_CMD_INSTR_EXECIFLAST,
|
||||
CRYPTO_CMD_INSTR_DATA1INCCLR,
|
||||
CRYPTO_CMD_INSTR_DATA1TODATA0,
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
CRYPTO_CMD_INSTR_DATA3TODATA0XOR
|
||||
);
|
||||
} else {
|
||||
CRYPTO_EXECUTE_18(device,
|
||||
CRYPTO_CMD_INSTR_EXECIFA,
|
||||
|
||||
// Calculate key stream block into DATA0
|
||||
CRYPTO_CMD_INSTR_DATA1INC,
|
||||
CRYPTO_CMD_INSTR_DATA1TODATA0,
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
|
||||
// XOR data input with key stream and output the result
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA2,
|
||||
CRYPTO_CMD_INSTR_DMA0TODATA,
|
||||
CRYPTO_CMD_INSTR_DATA2TODATA0XORLEN,
|
||||
CRYPTO_CMD_INSTR_DATATODMA0,
|
||||
|
||||
// Accumulate the plaintext into the CBC-MAC
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA2,
|
||||
CRYPTO_CMD_INSTR_DATA3TODATA0,
|
||||
CRYPTO_CMD_INSTR_DATA2TODATA0XORLEN,
|
||||
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
CRYPTO_CMD_INSTR_DATA0TODATA3,
|
||||
|
||||
// Calculate tag into DATA0 when all data has been processed
|
||||
CRYPTO_CMD_INSTR_EXECIFLAST,
|
||||
CRYPTO_CMD_INSTR_DATA1INCCLR,
|
||||
CRYPTO_CMD_INSTR_DATA1TODATA0,
|
||||
CRYPTO_CMD_INSTR_AESENC,
|
||||
CRYPTO_CMD_INSTR_DATA3TODATA0XOR
|
||||
);
|
||||
}
|
||||
|
||||
while (length) {
|
||||
if (length < 16) {
|
||||
// Use writeable header buffer for zero padding
|
||||
header[0] = 0;
|
||||
header[1] = 0;
|
||||
header[2] = 0;
|
||||
header[3] = 0;
|
||||
// Since input data is potentially unaligned, do a byte copy
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
((uint8_t*)header)[i] = data_in[i];
|
||||
}
|
||||
CRYPTO_DataWrite(&device->DATA0, header);
|
||||
CRYPTO_DataRead(&device->DATA0, header);
|
||||
if (data_out) {
|
||||
// Data output can be unaligned, too
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
data_out[i] = ((uint8_t*)header)[i];
|
||||
}
|
||||
// In this case, we're guaranteed it is the last part of
|
||||
// the data and don't need to adjust the pointer anymore.
|
||||
}
|
||||
length = 0;
|
||||
} else {
|
||||
CRYPTO_DataWriteUnaligned(&device->DATA0, data_in);
|
||||
length -= 16;
|
||||
data_in += 16;
|
||||
if (data_out) {
|
||||
CRYPTO_DataReadUnaligned(&device->DATA0, data_out);
|
||||
data_out += 16;
|
||||
} else {
|
||||
CRYPTO_DataRead(&device->DATA0, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read calculated authentication tag from DATA0 register
|
||||
CRYPTO_DataRead(&device->DATA0, header);
|
||||
crypto_management_release_preemption(device);
|
||||
|
||||
if (encrypt) {
|
||||
// For encryption, return the requested amount of tag
|
||||
for (size_t i = 0; i < tag_length; i++) {
|
||||
tag[i] = ((uint8_t*)header)[i];
|
||||
}
|
||||
} else {
|
||||
// For decryption, verify the requested amount of tag
|
||||
uint32_t accumulator = 0;
|
||||
for (size_t i = 0; i < tag_length; i++) {
|
||||
accumulator |= ((uint8_t*)header)[i] ^ tag[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
|
||||
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)
|
||||
|
||||
{
|
||||
// Use 32-byte word aligned buffer to bypass some time-consuming logic in aes_ccm_radio
|
||||
uint32_t b0b1_words[32 / sizeof(uint32_t)];
|
||||
uint8_t* b0b1_bytes = (uint8_t*)b0b1_words;
|
||||
|
||||
// Fill in B0 block according to BLE spec
|
||||
b0b1_bytes[0] = 0x49U;
|
||||
|
||||
// Copy in the 13 bytes of nonce
|
||||
for (size_t i = 0; i < 13; i++) {
|
||||
b0b1_bytes[i + 1] = iv[i];
|
||||
}
|
||||
|
||||
b0b1_bytes[14] = (uint8_t) length >> 8;
|
||||
b0b1_bytes[15] = (uint8_t) length;
|
||||
b0b1_bytes[16] = 0; // upper octet of AAD length
|
||||
b0b1_bytes[17] = 1; // lower octet of AAD length (BLE CCM always has only one byte of AAD)
|
||||
b0b1_bytes[18] = header; // AAD
|
||||
b0b1_bytes[19] = 0;
|
||||
b0b1_words[5] = 0;
|
||||
b0b1_words[6] = 0;
|
||||
b0b1_words[7] = 0;
|
||||
|
||||
return aes_ccm_radio(encrypt,
|
||||
NULL, 0,
|
||||
data, data, length,
|
||||
key,
|
||||
b0b1_words, 32 - 16,
|
||||
tag, 4);
|
||||
}
|
||||
|
||||
//
|
||||
// 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 (up to
|
||||
// 64 kB of data), meaning the header data size will always
|
||||
// be either 16 (no ciphertext) or 18 bytes long.
|
||||
|
||||
// Use 32-byte word aligned buffer to bypass some time-consuming logic in aes_ccm_radio
|
||||
uint32_t header_words[32 / sizeof(uint32_t)];
|
||||
uint8_t* header_bytes = (uint8_t*)header_words;
|
||||
|
||||
// Start with the 'flags' byte. It encodes whether there is AAD,
|
||||
// and the length of the tag fields
|
||||
header_bytes[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_bytes[i + 1] = iv[i];
|
||||
}
|
||||
|
||||
header_bytes[14] = (uint8_t) length >> 8;
|
||||
header_bytes[15] = (uint8_t) length;
|
||||
header_words[4] = 0;
|
||||
header_words[5] = 0;
|
||||
header_words[6] = 0;
|
||||
header_words[7] = 0;
|
||||
if (aad_len > 0) {
|
||||
header_bytes[16] = (uint8_t) aad_len >> 8; // upper octet of AAD length
|
||||
header_bytes[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_words,
|
||||
(aad_len > 0 ? 2 : 0),
|
||||
tag,
|
||||
tag_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a table of BLE RPA device keys and look for a
|
||||
* match against the supplied hash
|
||||
*/
|
||||
int sli_process_ble_rpa(const unsigned char keytable[],
|
||||
uint32_t keymask,
|
||||
uint32_t prand,
|
||||
uint32_t hash)
|
||||
{
|
||||
size_t index;
|
||||
uint32_t data_register[4] = { 0 };
|
||||
data_register[3] = __REV(prand);
|
||||
|
||||
/* Mangling DDATA1 (KEY) and DDATA2 (= DATA0/DATA1). Max execution length = 2 */
|
||||
CRYPTO_TypeDef *device =
|
||||
crypto_management_acquire_preemption(CRYPTO_MANAGEMENT_SAVE_DDATA1
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA2
|
||||
| CRYPTO_MANAGEMENT_SAVE_UPTO_SEQ0);
|
||||
/* Set up CRYPTO to do AES, and load prand */
|
||||
device->CTRL = CRYPTO_CTRL_AES_AES128 | CRYPTO_CTRL_KEYBUFDIS;
|
||||
device->WAC = 0UL;
|
||||
|
||||
CRYPTO_DataWrite(&device->DATA1, (uint32_t*)data_register);
|
||||
|
||||
/* For each key, execute AES encrypt operation and compare w hash */
|
||||
/* Read result of previous iteration first to minimize stall while waiting
|
||||
for AES to finish */
|
||||
int currentindex = -1;
|
||||
for ( index = 0; index < 32; index++ ) {
|
||||
if ( (keymask & (1U << index)) == 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CRYPTO_DataRead(&device->DATA0, data_register);
|
||||
CRYPTO_DataWrite(&device->KEY, (uint32_t*)(&keytable[index * 16]));
|
||||
CRYPTO_EXECUTE_2(device,
|
||||
CRYPTO_CMD_INSTR_DATA1TODATA0,
|
||||
CRYPTO_CMD_INSTR_AESENC);
|
||||
|
||||
if ( (currentindex >= 0)
|
||||
&& ( (data_register[3] & 0xFFFFFF00UL) == __REV(hash) ) ) {
|
||||
crypto_management_release_preemption(device);
|
||||
return currentindex;
|
||||
}
|
||||
|
||||
currentindex = index;
|
||||
}
|
||||
|
||||
/* Read result of last encryption and check for hash */
|
||||
CRYPTO_DataRead(&device->DATA0, data_register);
|
||||
crypto_management_release_preemption(device);
|
||||
|
||||
if ( (data_register[3] & 0xFFFFFF00UL) == __REV(hash) ) {
|
||||
return currentindex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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])
|
||||
{
|
||||
/* process one ore more blocks of data */
|
||||
CRYPTO_TypeDef *device =
|
||||
crypto_management_acquire_preemption(CRYPTO_MANAGEMENT_SAVE_DDATA1
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA2
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA4);
|
||||
device->WAC = 0;
|
||||
device->CTRL = 0;
|
||||
|
||||
CRYPTO_KeyBufWriteUnaligned(device, key,
|
||||
(keybits == 128UL
|
||||
? cryptoKey128Bits : cryptoKey256Bits));
|
||||
|
||||
if (!encrypt) {
|
||||
// Transform encryption to decryption key
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESENC;
|
||||
device->CMD = CRYPTO_CMD_INSTR_DDATA1TODDATA4;
|
||||
}
|
||||
|
||||
CRYPTO_DataWriteUnaligned(&device->DATA0, (const uint8_t *)input);
|
||||
|
||||
if ( encrypt ) {
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESENC;
|
||||
} else {
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESDEC;
|
||||
}
|
||||
|
||||
CRYPTO_DataReadUnaligned(&device->DATA0, (uint8_t *)output);
|
||||
|
||||
crypto_management_release_preemption(device);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
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])
|
||||
{
|
||||
/* process one ore more blocks of data */
|
||||
CRYPTO_TypeDef *device =
|
||||
crypto_management_acquire_preemption(CRYPTO_MANAGEMENT_SAVE_DDATA1
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA2
|
||||
| CRYPTO_MANAGEMENT_SAVE_DDATA4);
|
||||
device->WAC = 0;
|
||||
device->CTRL = 0;
|
||||
|
||||
CRYPTO_KeyBufWriteUnaligned(device, key,
|
||||
(keybits == 128UL
|
||||
? cryptoKey128Bits : cryptoKey256Bits));
|
||||
|
||||
if ((uint32_t)iv_in != 0) {
|
||||
CRYPTO_DataWriteUnaligned(&device->DATA1, (uint8_t *)iv_in);
|
||||
} else {
|
||||
uint32_t iv[4] = { 0, 0, 0, 0 };
|
||||
CRYPTO_DataWrite(&device->DATA1, iv);
|
||||
}
|
||||
|
||||
device->CMD = CRYPTO_CMD_INSTR_DATA1TODATA0;
|
||||
device->CMD = CRYPTO_CMD_INSTR_AESENC;
|
||||
device->CMD = CRYPTO_CMD_INSTR_DATA1INC;
|
||||
|
||||
CRYPTO_DataWriteUnaligned(&device->DATA0XOR, (uint8_t *)(input));
|
||||
CRYPTO_DataReadUnaligned(&device->DATA0, (uint8_t *)(output));
|
||||
|
||||
if ((uint32_t)iv_out != 0) {
|
||||
CRYPTO_DataReadUnaligned(&device->DATA1, (uint8_t *)iv_out);
|
||||
}
|
||||
|
||||
crypto_management_release_preemption(device);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
#endif /* CRYPTO_PRESENT */
|
864
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_radioaes.c
vendored
Normal file
864
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_protocol_crypto_radioaes.c
vendored
Normal file
|
@ -0,0 +1,864 @@
|
|||
/***************************************************************************//**
|
||||
* @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 "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;
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
203
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_radioaes_management.c
vendored
Normal file
203
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_radioaes_management.c
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/***************************************************************************//**
|
||||
* @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_se_manager_osal.h"
|
||||
#include "em_core.h"
|
||||
|
||||
#if defined(SL_SE_MANAGER_THREADING)
|
||||
static se_manager_osal_mutex_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;
|
||||
|
||||
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
|
||||
|
||||
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(SL_SE_MANAGER_THREADING)
|
||||
sl_status_t ret = SL_STATUS_OK;
|
||||
|
||||
// Non-IRQ, RTOS available: take mutex
|
||||
// Initialize mutex if that hasn't happened yet
|
||||
|
||||
// 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 = se_manager_osal_kernel_get_state();
|
||||
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
|
||||
kernel_lock_state = se_manager_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) {
|
||||
ret = se_manager_osal_init_mutex(&radioaes_lock);
|
||||
if (ret == SL_STATUS_OK) {
|
||||
radioaes_lock_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (kernel_state != osKernelInactive && kernel_state != osKernelReady) {
|
||||
if (se_manager_osal_kernel_restore_lock(kernel_lock_state) < 0) {
|
||||
return SL_STATUS_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == SL_STATUS_OK) {
|
||||
ret = se_manager_osal_take_mutex(&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(SL_SE_MANAGER_THREADING)
|
||||
// Non-IRQ, RTOS available: free mutex
|
||||
return se_manager_osal_give_mutex(&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)
|
101
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_radioaes_management.h
vendored
Normal file
101
gecko/util/third_party/crypto/sl_component/sl_protocol_crypto/src/sli_radioaes_management.h
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
/**************************************************************************/ /**
|
||||
* @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"
|
||||
|
||||
#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_status_t sli_radioaes_acquire(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Release RADIOAES access
|
||||
*
|
||||
* @return SL_STATUS_OK if successful, relevant status code on error
|
||||
******************************************************************************/
|
||||
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_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_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,8 @@
|
|||
# Copyright (c) 2022 Antmicro <www.antmicro.com>
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if(CONFIG_BT_SILABS_HCI)
|
||||
zephyr_include_directories(include)
|
||||
zephyr_sources(src/sl_bt_ll_zephyr.c)
|
||||
endif()
|
|
@ -0,0 +1,3 @@
|
|||
# This file is required by Zephyr build system to properly y-select
|
||||
# CONFIG_TAINT_* symbols when blobs are downloaded with the `west blobs`
|
||||
# command.
|
|
@ -0,0 +1,787 @@
|
|||
MASTER SOFTWARE LICENSE AGREEMENT Version 20210909
|
||||
|
||||
THIS MASTER SOFTWARE LICENSE AGREEMENT (“AGREEMENT”) GOVERNS YOUR USE OF THE
|
||||
LICENSED MATERIALS. INSTALLING, COPYING OR OTHERWISE USING THE SOFTWARE,
|
||||
INDICATES YOUR ACCEPTANCE OF THE TERMS OF THIS AGREEMENT REGARDLESS OF WHETHER
|
||||
YOU CLICK THE “ACCEPT” BUTTON. IF YOU DO NOT AGREE WITH THESE TERMS AND
|
||||
CONDITIONS OR IF YOU ARE NOT AUTHORIZED TO ACCEPT THE TERMS OF THIS LICENSE ON
|
||||
BEHALF OF YOUR EMPLOYER, DECLINE THE LICENSE TERMS AND DO NOT USE THE SOFTWARE
|
||||
OR DOCUMENTATION. THESE TERMS GOVERN YOUR CONTINUED USE OF THE LICENSED
|
||||
MATERIALS THAT YOU DOWNLOAD NOW OR IN THE FUTURE, INCLUDING SUCH ADDITIONAL
|
||||
SOFTWARE MADE AVAILABLE TO YOU THROUGH THE LICENSED MATERIALS YOU HAVE
|
||||
SELECTED, AND ALL UPDATES AND VERSIONS OF SUCH SOFTWARE.
|
||||
|
||||
1. Definitions.
|
||||
|
||||
“Application” means a product developed by Licensee, or for Licensee by a
|
||||
third party, that contains Licensed Programs.
|
||||
|
||||
“Authorized Application” means an Application that contains, integrates, is
|
||||
packaged with, or functions with a Silicon Labs Device in Licensee’s
|
||||
Application. This includes a Licensed Program embedded in a network
|
||||
co-processor or host processor that operates in conjunction with a Silicon
|
||||
Labs Device.
|
||||
|
||||
“Authorized Subcontractor” means a third-party subcontractor that you engage
|
||||
to design or manufacture Authorized Applications and has executed an agreement
|
||||
that is consistent with the terms of this Agreement, including its
|
||||
confidentiality provisions. At all times, you shall remain responsible for the
|
||||
actions or non-actions of you Authorized Subcontractors the same as if the
|
||||
action on non-action was committed by you.
|
||||
|
||||
“Beta Software” means Software, including Software included within an SDK,
|
||||
that is undergoing testing or further development, and has not reached the
|
||||
generally available (GA) stage of development.
|
||||
|
||||
“Commercial License” means an executed, in effect, software license agreement
|
||||
between Licensee and Silicon Labs that governs Licensee’s rights and
|
||||
obligations with respect to Licensee’s use of Micrium Software.
|
||||
|
||||
"Commercial Purpose” means embedding Micrium Software in any Application that
|
||||
you sell or license to End Users or plan to do so.
|
||||
|
||||
“Derivative Works” means a work based upon the Source Code version of the
|
||||
Software, such as a revision, modification, translation, abridgment,
|
||||
condensation, expansion or any other form in which such Software may be
|
||||
recast, transformed or adapted, and that, if prepared without authorization
|
||||
from Silicon Labs, would constitute copyright infringement.
|
||||
|
||||
“Development Tool” means a software provided by Silicon Labs to enable
|
||||
development of Authorized Applications, configuration of Silicon Labs Devices
|
||||
and Software.
|
||||
|
||||
“Documentation” means Silicon Labs technical documentation related to the
|
||||
Software, excluding advertising or marketing materials.
|
||||
|
||||
“Embedded Stacks” means Software (other than Micrium Software) that is stack
|
||||
libraries, application layers, and example code.
|
||||
|
||||
“End User” means a purchaser, sublicensee, recipient and/or user of an
|
||||
Application obtained directly or indirectly from Licensee.
|
||||
|
||||
“External Manufacturers” means a third-party manufacturer, including such
|
||||
manufacturer's subcontractors and agents, which is authorized by Licensee to
|
||||
design and/or manufacture the Applications and to use, install, and test the
|
||||
Applications and the Licensed Programs.
|
||||
|
||||
“Firmware” means executable or binary code that is embedded in the Silicon
|
||||
Labs Device in ROM or flash memory and cannot be modified by Licensee.
|
||||
|
||||
“Licensee” or “you” means the acquirer of the license rights granted by this
|
||||
Agreement. If you are an individual working solely on your own behalf, then
|
||||
you are the Licensee. If you are an employee working on behalf of your
|
||||
employer, then your employer is the Licensee and you confirm that you are
|
||||
authorized to accept the terms of this Agreement on behalf of your Employer.
|
||||
|
||||
“Licensed Programs” means Software in Object Code form that was either
|
||||
originally in Object Code form or was compiled from the Software or Derivative
|
||||
Works and is designed to operate in Applications in Authorized Applications.
|
||||
|
||||
“Licensed Materials” means Software and the related Documentation including
|
||||
all updates and upgrades of the foregoing.
|
||||
|
||||
“Micrium Software” means the Micrium real time kernel within the Micrium real
|
||||
time operating system (Micrium OS).
|
||||
|
||||
“Modified Open Source Software” means Silicon Labs' modifications to Open
|
||||
Source Software that was created by a third party.
|
||||
|
||||
“Object Code” means computer programming code in binary form suitable for
|
||||
machine execution by a processor without the intervening steps of
|
||||
interpretation or compilation.
|
||||
|
||||
“Open Source Software” means the Source Code version of software that may be
|
||||
freely used, modified or distributed without payment of a license fee or
|
||||
royalties subject to the terms of a publicly available software license,
|
||||
excluding Modified Open Source Software, the use of which is subject to the
|
||||
terms of this Agreement.
|
||||
|
||||
“Personal Information” means data concerning an individual user, including but
|
||||
not limited to a user’s activity on a Silicon Labs website, location, IP
|
||||
address, mobile device ID, name, or biometric data collected, stored or
|
||||
transmitted by a Silicon Lab Device or Software.
|
||||
|
||||
“SDK” means software development kit (other than Micrium Software).
|
||||
|
||||
“Silicon Labs” means Silicon Laboratories Inc., a Delaware corporation located
|
||||
at 400 W. Cesar Chavez, Austin, TX 78701 if you are physically located within
|
||||
the United States. If you are physically located outside of the United States,
|
||||
Silicon Labs means Silicon Laboratories International Pte Ltd., a Singapore
|
||||
corporation located at No. 18 Tai Seng Street, #05-01, 18 Tai Seng, Singapore
|
||||
539775.
|
||||
|
||||
"Silicon Labs Devices” means Silicon Labs branded integrated circuit chips
|
||||
purchased from Silicon Labs or one of its authorized distributors.
|
||||
|
||||
“Silicon Labs Open Source Code” means Software created by Silicon Labs and
|
||||
which is (a) delivered to Licensee in Source Code format, (b) is identified as
|
||||
open source code and (c) states that use of the software is subject to the
|
||||
terms of this Agreement.
|
||||
|
||||
“Software” means the computer programing code that was downloaded or otherwise
|
||||
distributed to Licensee and which is the subject of this Agreement. Software
|
||||
may be in Object Code or Source Code form or may be embedded as Firmware in a
|
||||
Silicon Labs Device. Software includes Embedded Stacks, SDKs and Development
|
||||
Tools. Your rights are different depending on whether the Software is
|
||||
delivered to you in Object Code, Source Code or Firmware. Software that is
|
||||
Micrium Software is subject to specific terms and conditions defined in
|
||||
Section 2.
|
||||
|
||||
“Source Code” means the computer programming code in an uncompiled form
|
||||
readable by humans which cannot be executed by a processor unless it is
|
||||
compiled into binary form.
|
||||
|
||||
“Third Party Software” means any software that Silicon Labs has licensed from
|
||||
a third party.
|
||||
|
||||
“Warranty Period” means the period of time ending thirty (30) days after the
|
||||
first delivery of the Software to the Licensee, whether such delivery is in
|
||||
the form of a download or actual physical delivery.
|
||||
|
||||
“Unauthorized Use” means use or inclusion of the Licensed Materials in (a)
|
||||
life support, aeronautical, aerospace, medical, military or nuclear
|
||||
applications; (b) FDA Class III or other devices for which FDA premarket
|
||||
approval is required; (c) implantable devices; (d) life support or life
|
||||
endangering applications where failure or inaccuracy might cause death or
|
||||
personal injury; and (e) automotive or transportation applications or
|
||||
environments unless the specific Silicon Labs Device has been designated by
|
||||
Silicon Labs as compliant with ISO/TS 16949 requirements. 2. Micrium
|
||||
Software.
|
||||
|
||||
The terms and conditions in this Section 2 apply only to Micrium Software and
|
||||
take precedence over any other conflicting terms of this Agreement.
|
||||
|
||||
2.1. Grant of Micrium Software License. Upon accepting this Agreement and
|
||||
downloading the Micrium Software, subject to your compliance with the terms of
|
||||
this Agreement, Silicon Labs hereby grants you a limited, non-exclusive,
|
||||
nontransferable license for the Term (as described in Section 23), as follows:
|
||||
|
||||
2.1.1. You and your Authorized Subcontractors may modify the Source Code
|
||||
version of Micrium Software for the sole purpose of adapting the Micrium
|
||||
Software to your application.
|
||||
|
||||
2.1.2. You may embed the Micrium Software exclusively in products developed by
|
||||
you or by your Authorized Subcontractors on your behalf during the Term that
|
||||
embed the Micrium Software into Silicon Labs Devices (the “End Products”).
|
||||
|
||||
2.1.3. You may distribute copies of the Object Code version of the Micrium
|
||||
Software solely to the extent that such copies are embedded in End Products.
|
||||
|
||||
2.2. Micrium Software License Restrictions. Your use of the Micrium Software
|
||||
is subject to the following restrictions:
|
||||
|
||||
2.2.1. You may allow Authorized Subcontractors to access and use the Micrium
|
||||
Software solely to the extent necessary to adapt the Micrium Software to your
|
||||
application.
|
||||
|
||||
2.2.2. Except as provided in this Agreement, neither you, your Authorized
|
||||
Subcontractors, nor any of your downstream customers may sell, transfer,
|
||||
sublicense, distribute, or disseminate in any way the Object Code or
|
||||
executable code of the Micrium Software in any written or electronic manner.
|
||||
|
||||
2.2.3. Neither you, your Authorized Subcontractors, nor any of your downstream
|
||||
customers may distribute the Source Code version of Micrium Software to any
|
||||
third party under any circumstances. You shall ensure that each of your
|
||||
employees and Authorized Subcontractors that work with Micrium Software are
|
||||
aware of this restriction.
|
||||
|
||||
2.2.4. Except as permitted in this Agreement, neither you, your Authorized
|
||||
Subcontractors, nor any of your downstream customer may embed the Micrium
|
||||
Software in any integrated circuit device that is not a Silicon Labs Device.
|
||||
|
||||
2.3. End User Support. You agree to be fully responsible for all End User
|
||||
support services and warranty costs for all End Products.
|
||||
|
||||
2.4. Commercial Purpose. You are permitted to use the Micrium Software for a
|
||||
Commercial Purpose only if you embed the Micrium Software into a Silicon Labs
|
||||
Device. You may not embed the Micrium Software in a non-Silicon Labs Device
|
||||
unless you and Silicon Labs execute a separate Commercial License Agreement
|
||||
expressly permitting such use.
|
||||
|
||||
2.5. Ownership. Silicon Labs is and shall remain the sole and exclusive owner
|
||||
of the Micrium Software and all Documentation, media, manuals, specifications,
|
||||
instructions and printed materials, and any copies or portions thereof,
|
||||
furnished by Silicon Labs for use with the Micrium Software. You own any
|
||||
improvements or modifications to the Micrium Software made by you or your
|
||||
Authorized Subcontractor on your behalf to adapt Micrium Software for use in
|
||||
your End Products.
|
||||
|
||||
2.6. Maintenence and Support. Standard maintenance and technical support, such
|
||||
as bug fixes, correction of failures, updates and maintenance patches is
|
||||
provided to you at no cost for one year from date that you download the
|
||||
Micrium Software. Silicon Labs may use a variety of methods, including but not
|
||||
limited to telephone, Internet and/or e-mail, to provide such maintenance and
|
||||
support. 3. 8051 SDK.
|
||||
|
||||
The terms and condition in this Section 3 apply only to the 8051 SDK and take
|
||||
precedence over any other conflicting terms of this Agreement.
|
||||
|
||||
3.1. 8051 SDK. The 8051 SDK consists of the following items:
|
||||
|
||||
3.1.1. Drivers;
|
||||
|
||||
3.1.2. Peripheral libraries (excluding CSLIB); and
|
||||
|
||||
3.1.3. Example application code.
|
||||
|
||||
3.2. Installation and Use Rights.
|
||||
|
||||
3.2.1. You may download and install the 8051 SDK on one or more computers and
|
||||
make any number of copies.
|
||||
|
||||
3.2.2. You may internally evaluate the 8051 SDK. If you elect to use the 8051
|
||||
SDK for any other purpose, including modification and distribution, then the
|
||||
following additional terms apply to you.
|
||||
|
||||
3.2.3. You may modify any files for your own use.
|
||||
|
||||
3.2.4. You may redistribute to your customers applications that you develop
|
||||
using the 8051 SDK. Your redistribution may be in any form, including
|
||||
executable binary code, source code, physical media and Internet downloads.
|
||||
|
||||
3.3. Restrictions.
|
||||
|
||||
3.3.1. You may not use the 8051 SDK with any integrated circuit products other
|
||||
than those designed and manufactured by Silicon Labs.
|
||||
|
||||
3.3.2. Except as provided above, you may not redistribute, sublicense, assign,
|
||||
rent or lease any portion of the 8051 SDK to any third party.
|
||||
|
||||
3.3.3. You may not modify or distribute the 8051 SDK so that all or any part
|
||||
of it becomes Open Source Software.
|
||||
|
||||
3.3.4. You may not obscure or remove any product identification, copyright or
|
||||
other notices that appear on or in the 8051 SDK, including any notices from
|
||||
third parties.
|
||||
|
||||
3.3.5. You may not redistribute any modified or unmodified version of the 8051
|
||||
SDK to any third party as a standalone product.
|
||||
|
||||
3.4. Ownership. Silicon Labs is and shall remain the owner of the 8051 SDK at
|
||||
all times. Applications that you develop using the 8051 SDK shall belong to
|
||||
you.
|
||||
|
||||
4. License Grant.
|
||||
|
||||
Silicon Labs hereby grants Licensee a limited, non-transferable,
|
||||
non-exclusive, perpetual license to use the Licensed Materials solely under
|
||||
the following terms and condition:
|
||||
|
||||
4.1. Object Code. With respect to Software (other than Micrium Software) that
|
||||
is delivered to Licensee by Silicon Labs in Object Code format, Licensee may:
|
||||
|
||||
4.1.1. (a) if the Software is an Embedded Stack, you may install one copy of
|
||||
the Software and its components all together on a single computer, and if the
|
||||
Software is copied onto another computer, the original copy must be deleted or
|
||||
otherwise made irreversibly inoperable; (b) if the Software is an SDK or a
|
||||
Development Tool, you may make multiple copies of the Software for your own
|
||||
internal use;
|
||||
|
||||
4.1.2. store one copy of the Software for archival (non-operational) purposes
|
||||
only, so long as access to such copy is restricted;
|
||||
|
||||
4.1.3. use the Licensed Materials to develop applications to be used to
|
||||
program Silicon Labs Devices;
|
||||
|
||||
4.1.4. incorporate the Licensed Materials into Authorized Applications;
|
||||
|
||||
4.1.5. facilitate the integration of the Licensed Materials and Silicon Labs
|
||||
Devices into Authorized Applications; and
|
||||
|
||||
4.1.6. distribute copies of the Licensed Materials to Licensee’s end-user
|
||||
customers, to the extent such copies are in Object Code form only and are
|
||||
incorporated into Authorized Applications.
|
||||
|
||||
4.2. Source Code. With respect to Software (other than Micrium Software and
|
||||
Silicon Labs Open Source Software) that is delivered to Licensee by Silicon
|
||||
Labs in Source Code format, Licensee may:
|
||||
|
||||
4.2.1. use the sample application software in Source Code format to develop
|
||||
and compile applications for use in Authorized Applications;
|
||||
|
||||
4.2.2. copy, prepare Derivative Works of, compile and modify Source Code of
|
||||
the Silicon Labs Software, solely to enable Licensee to design, develop,
|
||||
modify, test, support and/or debug Derivative Works and/or Licensed Programs
|
||||
that are intended to operate in Authorized Applications;
|
||||
|
||||
4.2.3. reproduce and distribute Derivative Works to Authorized Subcontractors
|
||||
under agreements consistent with Licensee’s rights and obligations under this
|
||||
Agreement solely (a) to modify for Licensee’s use in developing and
|
||||
maintaining the Licensed Programs; and (b) to enable Licensee to distribute
|
||||
Licensed Programs externally to End Users in accordance with Section 4.2.5
|
||||
below;
|
||||
|
||||
4.2.4. reproduce and distribute Licensed Programs internally and to Licensee’s
|
||||
External Manufacturers under agreements consistent with Licensee’s rights and
|
||||
obligations under this Agreement, solely (a) for Licensee’s use in developing
|
||||
and maintaining the Licensed Programs; and (b) to enable Licensee to
|
||||
distribute Licensed Programs externally to End Users in accordance with
|
||||
Section 4.2.5 below; and
|
||||
|
||||
4.2.5. distribute Licensed Programs externally to Licensee’s End Users, either
|
||||
directly or through Licensee’s distribution channels and methods, but only for
|
||||
use with Authorized Applications and not on a standalone basis.
|
||||
|
||||
5. License Restrictions.
|
||||
|
||||
The Licensed Materials shall only be used as permitted by this Agreement. Any
|
||||
use of the Licensed Materials not specifically authorized by this Agreement is
|
||||
prohibited.
|
||||
|
||||
5.1. Without limiting the foregoing restriction, and except as authorized by
|
||||
this Agreement, Licensee shall not:
|
||||
|
||||
5.1.1. assign, sublicense, or otherwise transfer the Licensed Materials to any
|
||||
third party;
|
||||
|
||||
5.1.2. reverse compile, disassemble, alter, add to, delete from, or otherwise
|
||||
modify Software delivered to Licensee in Object Code form or in libraries in
|
||||
the Licensed Materials;
|
||||
|
||||
5.1.3. publish the Licensed Materials in any manner that would cause it to
|
||||
become part of the public domain or otherwise become subject to the terms of
|
||||
an Open Source Software license;
|
||||
|
||||
5.1.4. use the Licensed Materials except in conjunction with Silicon Labs
|
||||
Devices;
|
||||
|
||||
5.1.5. distribute the Source Code form of Software to any third party, in
|
||||
whole or in part; or
|
||||
|
||||
5.1.6. remove any copyright, trademark, patent or other proprietary notices
|
||||
from the Licensed Materials or any portion thereof.
|
||||
|
||||
5.2. Licensee shall not use the Licensed Materials in any way to further the
|
||||
development or improvement of any product that does or would compete with any
|
||||
Silicon Labs Device.
|
||||
|
||||
5.3. If the Software is provided to demonstrate the capability of Silicon Labs
|
||||
Devices, it shall be used only for this purpose. Incorporation of the
|
||||
demonstration version of Silicon Labs Software into Applications is solely at
|
||||
Licensee’s risk and liability.
|
||||
|
||||
5.4. Any subsequent distribution or transfer of the Licensed Programs to End
|
||||
Users shall remain subject to the terms and conditions of this Agreement.
|
||||
Whether by execution of an end-user license agreement or other commercially
|
||||
reasonable means, Licensee shall ensure that its End Users’ use of the
|
||||
Licensed Programs shall only be permitted if they are incorporated into
|
||||
Authorized Applications. Licensee shall prohibit any further sublicensing,
|
||||
distribution, sale, marketing, reproduction, modification, reverse engineering
|
||||
or decompiling of the Licensed Programs.
|
||||
|
||||
5.5. Licensor may include features in the Software to restrict use of the
|
||||
Software that does not comply with the terms of this Agreement.
|
||||
|
||||
6. Unauthorized Use.
|
||||
|
||||
The Licensed Materials are not licensed, designed, intended, authorized, or
|
||||
warranted for Unauthorized Use. Licensee shall be solely and exclusively
|
||||
responsible for any Unauthorized Uses by Licensee, Licensee’s Authorized
|
||||
Subcontractors, Licensee’s End Users or other sublicensees, and any
|
||||
Unauthorized Use by such Authorized Subcontractors, End Users or sublicensees,
|
||||
with or without the knowledge of Licensee, shall be attributed to Licensee.
|
||||
Licensee agrees to defend and indemnify Silicon Labs for all third-party
|
||||
claims and for all damages, costs and fees, including Silicon Labs’ attorneys’
|
||||
fees, arising from any such Unauthorized Use of the Licensed Materials.
|
||||
|
||||
7. Open Source Software.
|
||||
|
||||
7.1. If the Software includes any Open Source Software, such Software and the
|
||||
relevant Open Source Software license under which such Software is licensed
|
||||
are disclosed at www.silabs.com. All use of such Open Source Software by
|
||||
Licensee is subject to the terms of the relevant open source software license
|
||||
and Licensee’s use of such Software is expressly conditioned upon Licensee’s
|
||||
compliance with the term of such license.
|
||||
|
||||
7.2. If the Software is Silicon Labs Open Source Code, then the following
|
||||
provisions apply:
|
||||
|
||||
7.2.1. Silicon Labs hereby grants to Licensee a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable copyright license to
|
||||
reproduce, prepare Derivative Works of, publicly display, publicly perform,
|
||||
sublicense, and distribute Silicon Labs Open Source Code and such Derivative
|
||||
Works in Source Code or Object Code form.
|
||||
|
||||
7.2.2. Silicon Labs hereby grants to Licensee a perpetual, worldwide,
|
||||
non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this
|
||||
section) patent license to make, have made, use, offer to sell, sell, import,
|
||||
and otherwise transfer the Silicon Labs Open Source Code, where such license
|
||||
applies only to those patent claims licensable by Silicon Labs that are
|
||||
necessarily infringed by Licensee’s use of the Silicon Labs Open Source Code
|
||||
or by combination with any other device or software.
|
||||
|
||||
7.2.3. Licensee may add Licensee’s own copyright statement to Licensee’s
|
||||
modifications of Silicon Labs Open Source Software and may provide additional
|
||||
or different license terms and conditions for use, reproduction, or
|
||||
distribution of such modifications, or for any such Derivative Works as a
|
||||
whole, provided Licensee’s use, reproduction, and distribution of the Silicon
|
||||
Labs Open Source Software otherwise complies with the conditions stated in
|
||||
this License.
|
||||
|
||||
7.2.4. Licensee may reproduce and distribute copies of the Silicon Labs Open
|
||||
Source Code or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source Code or Object Code form, provided that Licensee
|
||||
meets the following conditions: (a) Licensee must give any other recipients of
|
||||
the Silicon Labs Open Source Code or Derivative Works a copy of this License;
|
||||
and (b) Licensee must cause any modified files to carry prominent notices
|
||||
stating that Licensee changed the files; and (c) Licensee must retain, in the
|
||||
Source Code form of any Derivative Works that Licensee distributes, all
|
||||
copyright, patent, trademark, and attribution notices from the Source Code
|
||||
form of the Silicon Labs Open Source Code, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works; and (d) If the Silicon Labs Open
|
||||
Source Code includes a "NOTICE" text file as part of its distribution, then
|
||||
any Derivative Works that Licensee distributes must include a readable copy of
|
||||
the attribution notices contained within such NOTICE file, excluding those
|
||||
notices that do not pertain to any part of the Derivative Works, in at least
|
||||
one of the following places: within a NOTICE text file distributed as part of
|
||||
the Derivative Works; within the Source Code form or documentation, if
|
||||
provided along with the Derivative Works; or, within a display generated by
|
||||
the Derivative Works, if and wherever such third-party notices normally
|
||||
appear. The contents of the NOTICE file are for informational purposes only
|
||||
and do not modify the License. Licensee may add Licensee’s own attribution
|
||||
notices within Derivative Works that Licensee distributes, alongside or as an
|
||||
addendum to the NOTICE text from the Silicon Labs Open Source Code, provided
|
||||
that such additional attribution notices cannot be construed as modifying the
|
||||
License.
|
||||
|
||||
7.3. With respect to Software that is not Open Source Software, Licensee shall
|
||||
not:
|
||||
|
||||
7.3.1. cause the Software to become subject to any Open Source Software
|
||||
license, including but limited to the general public license (GPL) or the
|
||||
lesser general public license (LGPL);
|
||||
|
||||
7.3.2. cause the Software to be disclosed into the public domain or to any
|
||||
third party except for those third parties to whom License is authorized to
|
||||
distribute Licensed Programs under Sections 4.1.6 or 4.2.5; or
|
||||
|
||||
7.3.3. cause any part of the Software to become a derivative of any Open
|
||||
Source Software.
|
||||
|
||||
7.4. Licensee shall not enable or permit any of its End Users to breach the
|
||||
provisions of this Section 7, and shall include similar restrictive provisions
|
||||
in its end user license agreement with such End Users. If Licensee breaches
|
||||
this Section 7, Licensee shall indemnify and hold Silicon Labs harmless from
|
||||
all costs, claims, settlements and judgments incurred by Silicon Labs,
|
||||
including attorneys’ fees, in the process of defending, challenging and/or
|
||||
settling any demand, claim or order that the Software is subject to an Open
|
||||
Source Software license or must be disclosed into the public domain or to any
|
||||
third party.
|
||||
|
||||
8. Modified Open Source Software.
|
||||
|
||||
Notwithstanding the terms of the Open Source Software license under which the
|
||||
Open Source Software is licensed, the following terms apply to modifications
|
||||
to such Open Source Software that constitute Modified Open Source Software, as
|
||||
defined in this Agreement. The following terms apply regardless of how the
|
||||
Modified Open Source Software was delivered to you.
|
||||
|
||||
8.1.1. You may not use Modified Open Source Software except for use with
|
||||
Licensed Programs that are intended to operate in Authorized Applications.
|
||||
|
||||
8.1.2. You may not obscure, modify or remove copyright notices, files or
|
||||
statements concerning ownership by Silicon Labs or reference to the terms of
|
||||
this Agreement.
|
||||
|
||||
8.1.3. Subject to Sections 8.1.1 and 8.1.2:
|
||||
|
||||
8.1.3.1. You may copy and compile the Source Code of the Modified Open Source
|
||||
Software.
|
||||
|
||||
8.1.3.2. You may reproduce the Object Code and Source Code versions of
|
||||
Modified Open Source Software and distribute the same through multiple levels
|
||||
of distributions, including to your External Manufacturers.
|
||||
|
||||
8.1.3.3. You may modify Modified Open Source Software and create Derivative
|
||||
Works of Modified Open Source Software.
|
||||
|
||||
9. Third Party Software.
|
||||
|
||||
9.1. If the Software contains any Third Party Software, all use of such Third
|
||||
Party Software shall be subject to the terms of the license from such third
|
||||
party to Silicon Labs or a separate end user license agreement, if available,
|
||||
which may be set forth in the header files of the Third Party Software. You
|
||||
agree to comply with all terms and conditions for use of Third Party Software.
|
||||
|
||||
9.2. Silicon Labs has licensed the BLE Homekit from Apple. You may not
|
||||
download or use the BLE Homekit software unless you have executed a MFi
|
||||
License with Apple.
|
||||
|
||||
9.3. Silicon Labs has licensed emWin software, including libraries and
|
||||
executables and related documentation (collectively “emWin Library”) from
|
||||
Segger Microcontroller GmbH. You are entitled to use the emWin Library free
|
||||
of charge, subject to the following conditions, which you accept by virtue of
|
||||
accepting the terms of this Agreement: (a) you may use the emWin library
|
||||
exclusively with EFM 32-bit microcontrollers and EFR radios; (b) you may not
|
||||
use the emWin Library to create or develop software that is similar to or
|
||||
competitive with the emWin Library; and (c) you may not modify the
|
||||
documentation that accompanies the emWin Library.
|
||||
|
||||
9.4. Silicon Labs does not make any endorsements or representations concerning
|
||||
Third Party Software and disclaims all implied warranties concerning Third
|
||||
Party Software. Third Party Software is offered “AS IS.”
|
||||
|
||||
10. Inspection Rights.
|
||||
|
||||
Silicon Labs shall have the right, upon reasonable advance notice, to inspect
|
||||
Licensee's records and facilities with respect to the manufacture of
|
||||
Applications and to receive sample units of Applications in order to verify
|
||||
that such manufacturing is within the scope of this Agreement, that there are
|
||||
appropriate security procedures to protect Silicon Labs’ Confidential
|
||||
Information, and that Licensee is in compliance with its other obligations
|
||||
under this Agreement.
|
||||
|
||||
11. No Other Licenses.
|
||||
|
||||
The licenses granted under this Agreement are specifically set forth herein,
|
||||
and no licenses are granted by Silicon Labs to Licensee by implication or
|
||||
estoppel, and no licenses shall be granted by the parties’ course of doing
|
||||
business.
|
||||
|
||||
12. Beta Software.
|
||||
|
||||
Beta Software, whether Object Code or Source Code (a) can only be used for
|
||||
internal development, demonstration or testing purposes; (b) cannot be
|
||||
included within Licensee’s or End-Users’ products that are intended for
|
||||
general release or high-volume production; and (c) cannot be used to support
|
||||
Z-Wave certification of Silicon Labs Devices. Silicon Labs does not offer any
|
||||
warranties on Beta Software and disclaims all implied warranties including,
|
||||
but not limited to merchantability, fitness for use and noninfringement. Beta
|
||||
Software is offered “AS IS.” Under no circumstances will Silicon Labs incur
|
||||
any liability or obligation to you related to your use of Beta Software. Any
|
||||
use of Beta Software by you in violation of the terms of this Agreement shall
|
||||
automatically terminate your right to use Beta Software for any purpose
|
||||
whatsoever.
|
||||
|
||||
13. Upgrades, Updates, New Versions.
|
||||
|
||||
Although it has no obligation to do so, Silicon Labs may introduce updates,
|
||||
upgrades or new versions of the Software from time to time. Licensee is under
|
||||
no obligation to download or use the updates, upgrade or new version of
|
||||
Software; however, if Licensee elects to do so, the licenses granted to
|
||||
Licensee pursuant to this Agreement shall be deemed to include such updates,
|
||||
upgrades and new versions. In the case of any bug fix, improvement,
|
||||
work-around, or correction made to the Software by Licensee, Licensee agrees
|
||||
to provide to Silicon Labs, at no cost, the source code and any documentation
|
||||
reasonably required for Silicon Labs to be able to incorporate such changes
|
||||
into the Silicon Labs Software.
|
||||
|
||||
14. Regulatory Compliance.
|
||||
|
||||
Silicon Labs does not warrant that Software or any Application will comply
|
||||
with the regulatory requirements of the United States or any other country.
|
||||
Licensee is solely responsible for complying with such requirements and for
|
||||
obtaining necessary government certifications, if any.
|
||||
|
||||
15. License Fee and Royalties.
|
||||
|
||||
Unless Licensee has executed a Commercial License with Silicon Labs, Licensee
|
||||
is not obligated to pay any license fees or royalties to Silicon Labs so long
|
||||
as Licensee complies with the terms of the licenses set forth herein. If
|
||||
Licensee has executed a Commercial License, Licensee agree to pay all license
|
||||
fees, maintenance fees and subscription fees described in such Commercial
|
||||
License.
|
||||
|
||||
16. No Resale Fees.
|
||||
|
||||
Licensee may not directly or indirectly charge any fee or otherwise require or
|
||||
accept any type of monetary compensation solely for redistributing the
|
||||
Licensed Materials which is in excess of any amount paid to Silicon Labs for
|
||||
the same Licensed Materials. This does not apply to the sale of hardware
|
||||
products having the Licensed Materials in object code form embedded within.
|
||||
|
||||
17. Proprietary Rights.
|
||||
|
||||
All rights and title in and to the Licensed Materials, including without
|
||||
limitation, patents, copyrights, moral rights, trademarks and trade secret
|
||||
rights, belong to Silicon Labs or its licensors. Except for the rights
|
||||
expressly granted herein, no other rights are granted to Licensee with respect
|
||||
to the Licensed Materials.
|
||||
|
||||
18. Confidential Information.
|
||||
|
||||
You agree that the Licensed Materials contain confidential information,
|
||||
including trade secrets, know-how and other information, that comprise the
|
||||
exclusive property of Silicon Labs or its licensors. During the period this
|
||||
Agreement is in effect and at all times after its termination, you shall
|
||||
maintain the confidentiality of this information and shall not sell, license,
|
||||
sublicense, publish, display, distribute, disclose or otherwise make available
|
||||
this information to any third party nor use such information except as
|
||||
authorized by this Agreement.
|
||||
|
||||
19. Limited Warranty and Remedies.
|
||||
|
||||
Silicon Labs warrants that, during the Warranty Period, the Software will
|
||||
function substantially in accordance with the Documentation when used with
|
||||
Silicon Labs Devices and that the media on which the Software is furnished
|
||||
will be free from defects in material and workmanship, under normal use and
|
||||
service, when correctly installed and maintained. Silicon Labs does not
|
||||
warrant that the functions in the Licensed Materials will meet Licensee’s
|
||||
specific requirements or that the operation of the Software will be
|
||||
uninterrupted or error free. Silicon Labs does not warrant that the Software
|
||||
does not contain any viruses or bugs. If Licensee notifies Silicon Labs,
|
||||
during the Warranty Period, of a failure of the Software to conform to the
|
||||
limited warranty stated in this section, Silicon Labs’ sole obligation, and
|
||||
Licensee’s sole remedy, will be, at Silicon Labs’ sole discretion: (i)
|
||||
replacement of the Software, or part thereof, with a functionally equivalent
|
||||
software product or part, or (ii) repair of the Software. Without limiting any
|
||||
term or condition stated in this Agreement, this warranty does not apply to
|
||||
any nonconformance caused by (A) improper or inadequate maintenance or
|
||||
calibration, or (B) software or interfacing equipment, parts or supplies not
|
||||
supplied by Silicon Labs or its authorized distributor, (C) modifications to
|
||||
the Software or (D) Unauthorized Use of the Software.
|
||||
|
||||
20. WARRANTY DISCLAIMER.
|
||||
|
||||
EXCEPT AS PROVIDED ABOVE IN SECTION 19, THE LICENSED MATERIALS ARE PROVIDED
|
||||
“AS IS” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT
|
||||
LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT AND THE ENTIRE RISK AS TO THE QUALITY
|
||||
AND PERFORMANCE OF THE LICENSED MATERIALS IS WITH LICENSEE. SILICON LABS DOES
|
||||
NOT WARRANT THAT THE LICENSED MATERIALS ARE FREE FROM DEFECTS THAT COULD CAUSE
|
||||
VULNERABILITY TO CYBER-ATTACK, DATA BREACH OR PRIVACY VIOLATIONS. SILICON LABS
|
||||
DISCLAIMS ALL LIABILITY RELATED TO LICENSEE’S DATA THAT MAY BE RECEIVED,
|
||||
STORED OR USED BY SILICON LABS DEVICES OR SOFTWARE OR INTERCEPTED BY THIRD
|
||||
PARTIES. SILICON LABS DISCLAIMS ALL LIABILITY FOR DAMAGES CAUSED BY THIRD
|
||||
PARTIES, INCLUDING MACILICOUS USE OF, OR INTEFERENCE WITH TRANSMISSION OF,
|
||||
LICENSEE’S DATA.
|
||||
|
||||
21. LIMITATION OF LIABILITY.
|
||||
|
||||
SILICON LABS’ SOLE OBLIGATION OR LIABILITY UNDER THIS AGREEMENT IS THE REPAIR
|
||||
OR REPLACEMENT OF THE LICENSED MATERIALS ACCORDING TO THE LIMITED WARRANTY
|
||||
ABOVE. IN NO EVENT SHALL SILICON LABS OR ANY OF ITS AFFILIATES OR SUPPLIERS BE
|
||||
LIABLE FOR CONSEQUENTIAL, SPECIAL, INCIDENTAL OR SIMILAR DAMAGES, SUCH AS (BUT
|
||||
NOT LIMITED TO) LOSS OF BUSINESS REVENUES, PROFITS OR SAVINGS OR LOSS OF DATA
|
||||
RESULTING FROM THE USE OR INABILITY TO USE THE LICENSED MATERIALS, EVEN IF
|
||||
SILICON LABS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY
|
||||
CLAIM BY ANY THIRD PARTY. THIS INCLUDES, BUT IS NOT LIMITED TO, DAMAGES
|
||||
ARISING FROM THE FAILURE OF THE SILICON LABS DEVICE TO TRANSMIT DATA ARISING
|
||||
FROM A FAILURE OF THE SOFTWARE TO PERFORM IN SUBSTANTIAL ACCORDANCE WITH THE
|
||||
DOCUMENTATION. IN NO EVENT SHALL THE TOTAL CUMULATIVE LIABILITY OF SILICON
|
||||
LABS TO LICENSEE FOR ALL MATTERS RELATED TO THE LICENSED MATERIALS EXCEED THE
|
||||
AMOUNT PAID BY LICENSEE TO SILICON LABS FOR SUCH LICENSED MATERIALS OR ONE
|
||||
UNITED STATES DOLLAR ($1.00 USD). YOU ACKNOWLEDGE THAT THE AMOUNT PAID BY YOU
|
||||
FOR THE LICENSED MATERIALS REFLECTS THIS ALLOCATION OF RISK.
|
||||
|
||||
22. Data Collection.
|
||||
|
||||
To the extent that Silicon Labs Devices collect, store or transfer Personal
|
||||
Information, Silicon Labs may use such Personal Information for its own
|
||||
internal purposes, including marketing Silicon Labs Devices to the user.
|
||||
Silicon Labs will not sell Personal Information to third parties. Silicon Labs
|
||||
Devices will not transfer Personal Information to other devices in a network
|
||||
or to third parties except to the extent necessary to perform the intended
|
||||
function of the Silicon Labs Device. Silicon Labs will not be liable to
|
||||
Licensee or Licensee’s customers for (a) any intended transfer of Personal
|
||||
Information described in the Documentation for the Silicon Labs Device; (b)
|
||||
any unintended transfer of Personal Information or loss of data caused by any
|
||||
third parties or third party devices or software, including hacking, malware,
|
||||
eavesdropping, man-in-the-middle attacks or other intentional acts; or (c)
|
||||
unauthorized access to or misuse of Personal Information by third parties.
|
||||
|
||||
23. Term and Termination.
|
||||
|
||||
This Agreement will take effect on the date the Licensed Materials are
|
||||
acquired by or delivered to Licensee, and will remain in effect unless
|
||||
terminated as provided below. If you breach any of your obligations under this
|
||||
Agreement, this Agreement will immediately and automatically terminate. You
|
||||
may terminate this Agreement at any time by destroying all copies of the
|
||||
Licensed Materials. Upon termination of this Agreement, you shall immediately
|
||||
discontinue the use of the Licensed Materials and shall return or provide
|
||||
certification to Silicon Labs of the destruction of all copies of the Licensed
|
||||
Materials. You many keep one copy of the Licensed Materials for archival
|
||||
(non-operational) purposes only, so long as access to such copies is
|
||||
restricted. If the Agreement is terminated by Silicon Labs, you may continue
|
||||
to distribute copies of the Software already installed in finished inventory,
|
||||
but you may not make any additional copies or install the Software in
|
||||
additional products. All provisions of this Agreement relating to disclaimers
|
||||
of warranties, limitation of liability, remedies or damages, and Silicon Labs’
|
||||
proprietary rights, shall survive any termination of this Agreement for any
|
||||
reason.
|
||||
|
||||
24. Termination of License.
|
||||
|
||||
If you institute patent litigation against Silicon Labs or any of its
|
||||
Affiliates (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that the Licensed Programs directly or indirectly infringe a patent of
|
||||
Licensee, then any patent licenses granted to you under this Agreement for
|
||||
that Licensed Program shall terminate as of the date such litigation is filed.
|
||||
|
||||
25. Export Restrictions.
|
||||
|
||||
You may not export or re-export the Software or any Licensed Programs, or any
|
||||
copy thereof, in violation of any applicable laws or regulations.
|
||||
|
||||
26. Amendments.
|
||||
|
||||
This Agreement may be amended unilaterally by Silicon Labs at any time. The
|
||||
most recent version of this Agreement supersedes and replaces all prior
|
||||
versions. In the event of any conflicting terms, the terms of the most recent
|
||||
version of this Agreement shall control.
|
||||
|
||||
27. Miscellaneous.
|
||||
|
||||
This Agreement sets forth the entire agreement and understanding between the
|
||||
parties and neither party shall be bound by any conditions, definitions,
|
||||
warranties, understandings or representations with respect to the subject
|
||||
matter hereof other than as provided herein or as duly set forth on or after
|
||||
the date hereof in writing and signed by a proper and duly authorized
|
||||
representative of the party to be bound thereby. The failure of any party at
|
||||
any time to require performance of any provision of this Agreement shall in
|
||||
not affect the right of such party to enforce the terms of this Agreement at a
|
||||
later time. No waiver by any party of any condition or of any breach of any
|
||||
term contained in this Agreement, in any one or more instances, shall be
|
||||
construed as a further or continuing waiver of any such condition or of any
|
||||
breach of any such term or any other term set forth in this Agreement. If any
|
||||
provision of this Agreement is unenforceable for any reason, the remaining
|
||||
terms of the Agreement shall not be deemed invalid, inoperative, or
|
||||
unenforceable and, if possible, the unenforceable provision shall be modified
|
||||
or interpreted in a manner to make it enforceable.
|
||||
|
||||
28. Governing Law.
|
||||
|
||||
This Agreement shall be governed by the laws of the State of Texas, United
|
||||
States of America, without regard to that state’s conflicts of laws rules. The
|
||||
1980 United Nations Convention on Contracts for the International Sale of
|
||||
Goods shall not apply. In any dispute arising out of this Agreement, the
|
||||
parties each consent to the exclusive personal jurisdiction and venue in the
|
||||
State and Federal courts located within Travis County, Texas, United States of
|
||||
America. All disputes concerning this Agreement shall be resolved by binding
|
||||
arbitration in Travis County, Texas before a single arbitrator. The
|
||||
arbitration shall be administered by JAMS pursuant to JAMS’ Streamlined
|
||||
Arbitration Rules and Procedures. The arbitration award shall include an award
|
||||
of attorneys’ fees to the prevailing party. Judgment on the award may be
|
||||
entered in any court having jurisdiction. This clause shall not preclude
|
||||
parties from seeking provisional remedies in aid of arbitration from a court
|
||||
of appropriate jurisdiction.
|
||||
|
||||
29. Injunctive Relief.
|
||||
|
||||
The copying, disclosure, or use of the Software in a manner inconsistent with
|
||||
any provision of this Agreement or the improper use of the Silicon Labs
|
||||
trademarks may cause irreparable injury to Silicon Labs for which Silicon Labs
|
||||
may not have an adequate remedy at law. Silicon Labs may be entitled to
|
||||
equitable relief in court, including but not limited to temporary restraining
|
||||
orders, preliminary injunctions and permanent injunctions.
|
||||
|
||||
30. Silicon Labs Trademarks.
|
||||
|
||||
Silicon Labs and the Silicon Labs logo are trademarks of Silicon Laboratories
|
||||
Inc. in the United States and other countries. No use of the Silicon Labs
|
||||
trademarks by Licensee is implied or consented to by Silicon Labs by entering
|
||||
into this Agreement.
|
||||
|
||||
31. Commercial Computer Software.
|
||||
|
||||
If Licensee is an agency of the U.S. Government, the following will apply: The
|
||||
Software has been developed entirely at private expense, is regularly used for
|
||||
nongovernmental purposes and has been licensed to the public. The Software is
|
||||
a “commercial item” as that term is defined in 48 C.F.R. 2.101 (Oct. 1995),
|
||||
consisting of “commercial computer software” and “commercial computer software
|
||||
documentation” as those terms are used in 48 C.F.R. 12.212 (Sept. 1995) or as
|
||||
“commercial computer software” as that term is defined in 48 C.F.R.
|
||||
252.227-7014 (June 1995) or any equivalent agency regulation or contract
|
||||
clause, whichever is applicable. Consistent with 48 C.F.R. 12.212 and 48
|
||||
C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all U.S. Government agencies
|
||||
acquire only those rights to the Software as are expressly set forth herein.
|
|
@ -0,0 +1,21 @@
|
|||
Copyright 2022 Silicon Laboratories Inc. www.silabs.com
|
||||
|
||||
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.
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/bluetooth/hci_driver.h>
|
||||
#include <sl_hci_common_transport.h>
|
||||
|
||||
enum h4_packet {
|
||||
h4_command = 1,
|
||||
h4_acl = 2,
|
||||
h4_sco = 3,
|
||||
h4_event = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief BTLE_LL_Process process linklayer events
|
||||
* @param events
|
||||
*/
|
||||
void BTLE_LL_Process(uint32_t events);
|
||||
|
||||
/**
|
||||
* @brief BTLE_LL_EventRaise raise events to be notified as soon as possible to linklayer
|
||||
* function is implemented by upper layer
|
||||
* @param events bitmap of events to raise
|
||||
*/
|
||||
void BTLE_LL_EventRaise(uint32_t events);
|
||||
|
||||
/**
|
||||
* @brief Check if event bitmap indicates pending events
|
||||
* @return bool pending events
|
||||
*/
|
||||
bool sli_pending_btctrl_events(void);
|
||||
|
||||
/**
|
||||
* @brief Thread entry point that calls Link Layer to process raised events
|
||||
*/
|
||||
void slz_ll_thread_func(void);
|
|
@ -1,2 +1,27 @@
|
|||
build:
|
||||
cmake: .
|
||||
blobs:
|
||||
- path: gecko/protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_efr32bg22_gcc_release.a
|
||||
sha256: 99b3f9abc04c20da4ad8383993275691586aa872ea72a526a544984bb99dc27e
|
||||
type: lib
|
||||
version: '4.0.2'
|
||||
license-path: zephyr/blobs/license/MSLA.txt
|
||||
url: https://github.com/SiliconLabs/gecko_sdk/raw/gsdk_4.0/protocol/bluetooth/bgstack/ll/lib/libbluetooth_controller_efr32xg22_gcc_release.a
|
||||
description: "Binary libraries supporting EFR32 RF subsystems"
|
||||
doc-url: https://github.com/SiliconLabs/gecko_sdk
|
||||
- path: gecko/protocol/bluetooth/bgcommon/lib/libbgcommon_efr32bg22_gcc_release.a
|
||||
sha256: 324b6a724449f83c095db76df11b8ae393b6bd090b1d94c78f2db0af3333426a
|
||||
type: lib
|
||||
version: '4.0.2'
|
||||
license-path: zephyr/blobs/license/MSLA.txt
|
||||
url: https://github.com/SiliconLabs/gecko_sdk/raw/gsdk_4.0/protocol/bluetooth/bgcommon/lib/libbgcommon_efr32xg22_gcc_release.a
|
||||
description: "Binary libraries supporting EFR32 RF subsystems"
|
||||
doc-url: https://github.com/SiliconLabs/gecko_sdk
|
||||
- path: gecko/platform/radio/rail_lib/autogen/librail_release/librail_efr32bg22_gcc_release.a
|
||||
sha256: 8e31545401df4b4dbb2ae0a5814547407a24f431e2e72bb4699a158b83396f23
|
||||
type: lib
|
||||
version: '4.0.2'
|
||||
license-path: zephyr/blobs/license/Zlib.txt
|
||||
url: https://github.com/SiliconLabs/gecko_sdk/raw/gsdk_4.0/platform/radio/rail_lib//autogen/librail_release/librail_efr32xg22_gcc_release.a
|
||||
description: "Binary libraries supporting EFR32 RF subsystems"
|
||||
doc-url: https://github.com/SiliconLabs/gecko_sdk
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Antmicro <www.antmicro.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sl_bt_ll_zephyr.h>
|
||||
|
||||
K_SEM_DEFINE(slz_ll_sem, 0, 1);
|
||||
|
||||
static atomic_t sli_btctrl_events;
|
||||
|
||||
bool sli_pending_btctrl_events(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void BTLE_LL_EventRaise(uint32_t events)
|
||||
{
|
||||
atomic_or(&sli_btctrl_events, events);
|
||||
k_sem_give(&slz_ll_sem);
|
||||
}
|
||||
|
||||
void slz_ll_thread_func(void)
|
||||
{
|
||||
while (true) {
|
||||
k_sem_take(&slz_ll_sem, K_FOREVER);
|
||||
uint32_t events = atomic_clear(&sli_btctrl_events);
|
||||
BTLE_LL_Process(events);
|
||||
}
|
||||
}
|
||||
|
||||
void sl_bt_controller_init()
|
||||
{
|
||||
/* No extra initialization procedure required */
|
||||
}
|
Loading…
Reference in New Issue