/***************************************************************************//** * @file * @brief Secure Element API ******************************************************************************* * # License * Copyright 2018 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. * ******************************************************************************/ #ifndef EM_SE_H #define EM_SE_H #ifndef SL_SUPPRESS_DEPRECATION_WARNINGS_SDK_2024_6 #warning "This file is deprecated as of SiSDK 2024.6. The content was moved to sli_se_manager_mailbox.h." #endif #if defined(__linux__) #define SLI_EM_SE_HOST #else #include "em_device.h" #endif // __linux__ #include "sl_common.h" #if defined(SLI_EM_SE_HOST) || defined(SEMAILBOX_PRESENT) || defined(CRYPTOACC_PRESENT) #include #include #include #include "sli_se_manager_mailbox.h" #ifdef __cplusplus extern "C" { #endif /***************************************************************************//** * @addtogroup se SE - Secure Element * * @brief Secure Element peripheral API * * @details * Abstraction of the Secure Element's mailbox interface. * * For series 2 devices with a part number that is xG23 or higher, the * following step is necessary for basic operation: * * Clock enable: * @code CMU_ClockEnable(cmuClock_SEMAILBOX, true);@endcode * * @note The high-level SE API has been moved to the SE manager, and the * implementation in em_se should not be used. * * @note Using the SE's mailbox is not thread-safe in EMLIB, and accessing the * SE's mailbox both in regular and IRQ context is not safe. SE operations * should be performed using the SE manager if possible. * * @{ ******************************************************************************/ /******************************************************************************* ****************************** DEFINES *********************************** ******************************************************************************/ #if defined(CRYPTOACC_PRESENT) /** Root Code Mailbox is invalid. */ #define SE_RESPONSE_MAILBOX_INVALID 0x00FE0000UL /** Root Code Mailbox magic word */ #define SE_RESPONSE_MAILBOX_VALID 0xE5ECC0DEUL #endif /** Response status codes for the Secure Element */ #define SE_RESPONSE_MASK 0x000F0000UL /** Command executed successfully or signature was successfully validated. */ #define SE_RESPONSE_OK 0x00000000UL /** Maximum amount of parameters supported by the hardware FIFO */ #define SE_FIFO_MAX_PARAMETERS 13U /** Stop datatransfer */ #define SE_DATATRANSFER_STOP 0x00000001UL /** Discard datatransfer */ #define SE_DATATRANSFER_DISCARD 0x40000000UL /** Realign datatransfer */ #define SE_DATATRANSFER_REALIGN 0x20000000UL /** Datatransfer Const Address*/ #define SE_DATATRANSFER_CONSTADDRESS 0x10000000UL /** Stop Length Mask */ #define SE_DATATRANSFER_LENGTH_MASK 0x0FFFFFFFUL /** Maximum amount of parameters for largest command in defined command set */ #ifndef SE_MAX_PARAMETERS #define SE_MAX_PARAMETERS 4U #endif /* Sanity-check defines */ #if SE_MAX_PARAMETERS > SE_FIFO_MAX_PARAMETERS #error "Trying to configure more parameters than supported by the hardware" #endif /******************************************************************************* ****************************** TYPEDEFS *********************************** ******************************************************************************/ /** * SE DMA transfer descriptor. Can be linked to each other to provide * scatter-gather behavior. */ typedef sli_se_datatransfer_t SE_DataTransfer_t; /** Default initialization of data transfer struct */ #define SE_DATATRANSFER_DEFAULT(address, length) \ { \ (void*)(address), /* Pointer to data block */ \ (void*)SE_DATATRANSFER_STOP, /* This is the last block by default */ \ (length) | SE_DATATRANSFER_REALIGN /* Add size, use realign by default */ \ } /** * SE Command structure. See */ typedef sli_se_mailbox_command_t SE_Command_t; /** Default initialization of command struct */ #define SE_COMMAND_DEFAULT(command) \ { \ (command), /* Given command */ \ NULL, /* No data in */ \ NULL, /* No data out */ \ { 0, 0, 0, 0 }, /* No parameters */ \ 0 /* No parameters */ \ } /** Possible responses to a command */ typedef sli_se_mailbox_response_t SE_Response_t; /******************************************************************************* ***************************** PROTOTYPES ********************************** ******************************************************************************/ void SE_addDataInput(SE_Command_t *command, SE_DataTransfer_t *data); void SE_addDataOutput(SE_Command_t *command, SE_DataTransfer_t *data); void SE_addParameter(SE_Command_t *command, uint32_t parameter); #if !defined(SLI_EM_SE_HOST) void SE_executeCommand(SE_Command_t *command); #endif // #if !defined(SLI_EM_SE_HOST) #if defined(CRYPTOACC_PRESENT) SE_Response_t SE_getVersion(uint32_t *version); SE_Response_t SE_getConfigStatusBits(uint32_t *cfgStatus); SE_Response_t SE_getOTPVersion(uint32_t *otpVersion); SE_Response_t SE_ackCommand(SE_Command_t *command); #endif // #if defined(CRYPTOACC_PRESENT) // Utilities #if defined(SEMAILBOX_PRESENT) __STATIC_INLINE bool SE_isCommandCompleted(void); __STATIC_INLINE SE_Response_t SE_readCommandResponse(void); #elif defined(CRYPTOACC_PRESENT) bool SE_isCommandCompleted(void); uint32_t SE_readExecutedCommand(void); SE_Response_t SE_readCommandResponse(void); #endif // #if defined(SEMAILBOX_PRESENT) #if !defined(SLI_EM_SE_HOST) __STATIC_INLINE void SE_waitCommandCompletion(void); __STATIC_INLINE void SE_disableInterrupt(uint32_t flags); __STATIC_INLINE void SE_enableInterrupt(uint32_t flags); #endif // #if !defined(SLI_EM_SE_HOST) #if defined(SEMAILBOX_PRESENT) /***************************************************************************//** * @brief * Check whether the running command has completed. * * @details * This function polls the SE-to-host mailbox interrupt flag. * * @return True if a command has completed and the result is available ******************************************************************************/ __STATIC_INLINE bool SE_isCommandCompleted(void) { return (bool)(SEMAILBOX_HOST->RX_STATUS & SEMAILBOX_RX_STATUS_RXINT); } #endif // #if defined(SEMAILBOX_PRESENT) #if defined(SEMAILBOX_PRESENT) /***************************************************************************//** * @brief * Read the status of the previously executed command. * * @details * This function reads the status of the previously executed command. * * @note * The command response needs to be read for every executed command, and can * only be read once per executed command (FIFO behavior). * * @return * One of the SE_RESPONSE return codes: * SE_RESPONSE_OK when the command was executed successfully or a signature * was successfully verified. ******************************************************************************/ __STATIC_INLINE SE_Response_t SE_readCommandResponse(void) { SE_waitCommandCompletion(); return (SE_Response_t)(SEMAILBOX_HOST->RX_HEADER & SE_RESPONSE_MASK); } #endif // #if defined(SEMAILBOX_PRESENT) #if !defined(SLI_EM_SE_HOST) /***************************************************************************//** * @brief * Wait for completion of the current command. * * @details * This function "busy"-waits until the execution of the ongoing instruction * has completed. ******************************************************************************/ __STATIC_INLINE void SE_waitCommandCompletion(void) { /* Wait for completion */ while (!SE_isCommandCompleted()) { } } /***************************************************************************//** * @brief * Disable one or more SE interrupts. * * @param[in] flags * SE interrupt sources to disable. Use a bitwise logic OR combination of * valid interrupt flags for the Secure Element module * (SE_CONFIGURATION_(TX/RX)INTEN). ******************************************************************************/ __STATIC_INLINE void SE_disableInterrupt(uint32_t flags) { #if defined(SEMAILBOX_PRESENT) SEMAILBOX_HOST->CONFIGURATION &= ~flags; #else (void) flags; #endif } /***************************************************************************//** * @brief * Enable one or more SE interrupts. * * @param[in] flags * SE interrupt sources to enable. Use a bitwise logic OR combination of * valid interrupt flags for the Secure Element module * (SEMAILBOX_CONFIGURATION_TXINTEN or SEMAILBOX_CONFIGURATION_RXINTEN). ******************************************************************************/ __STATIC_INLINE void SE_enableInterrupt(uint32_t flags) { #if defined(SEMAILBOX_PRESENT) SEMAILBOX_HOST->CONFIGURATION |= flags; #else (void) flags; #endif } #endif // #if !defined(SLI_EM_SE_HOST) /******************************************************************************* ***************************** DEPRECATED ********************************* ******************************************************************************/ /***************************************************************************//** * @addtogroup se_deprecated Deprecated Functions * @brief Deprecated Functions * * @deprecated * The following functions have been deprecated and will be removed in a * future version of EMLIB. All high-level functionality have been moved to * the SE manager. * * @{ ******************************************************************************/ /******************************************************************************* ****************************** DEFINES *********************************** ******************************************************************************/ #if !defined(SLI_EM_SE_HOST) /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ #if defined(SEMAILBOX_PRESENT) /* Command words for the Security Engine. */ #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) #define SE_COMMAND_WRAP_KEY 0x01000000UL #define SE_COMMAND_UNWRAP_KEY 0x01020000UL #define SE_COMMAND_TRANSFER_KEY 0x01060000UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ #define SE_COMMAND_CREATE_KEY 0x02000000UL #define SE_COMMAND_READPUB_KEY 0x02010000UL #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) #define SE_COMMAND_DERIVE_KEY_PBKDF2 0x02020002UL #define SE_COMMAND_DERIVE_KEY_HKDF 0x02020003UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ #define SE_COMMAND_HASH 0x03000000UL #define SE_COMMAND_HASHUPDATE 0x03010000UL #define SE_COMMAND_HMAC 0x03020000UL #define SE_COMMAND_AES_ENCRYPT 0x04000000UL #define SE_COMMAND_AES_DECRYPT 0x04010000UL #define SE_COMMAND_AES_GCM_ENCRYPT 0x04020000UL #define SE_COMMAND_AES_GCM_DECRYPT 0x04030000UL #define SE_COMMAND_AES_CMAC 0x04040000UL #define SE_COMMAND_AES_CCM_ENCRYPT 0x04050000UL #define SE_COMMAND_AES_CCM_DECRYPT 0x04060000UL #define SE_COMMAND_SIGNATURE_SIGN 0x06000000UL #define SE_COMMAND_SIGNATURE_VERIFY 0x06010000UL #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) #define SE_COMMAND_EDDSA_SIGN 0x06020000UL #define SE_COMMAND_EDDSA_VERIFY 0x06030000UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ #define SE_COMMAND_TRNG_GET_RANDOM 0x07000000UL #define SE_COMMAND_READ_CLOCK 0x07020000UL #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) #define SE_COMMAND_ATTEST_CERTIFY 0x0A000000UL #define SE_COMMAND_ATTEST_TIME 0x0A010000UL #define SE_COMMAND_ATTEST_PUBKEY 0x0A020000UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ #define SE_COMMAND_JPAKE_R1_GENERATE 0x0B000000UL #define SE_COMMAND_JPAKE_R1_VERIFY 0x0B000100UL #define SE_COMMAND_JPAKE_R2_GENERATE 0x0B010000UL #define SE_COMMAND_JPAKE_R2_VERIFY 0x0B010100UL #define SE_COMMAND_JPAKE_GEN_SESSIONKEY 0x0B020000UL #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) #define SE_COMMAND_AEAD_ENCRYPT 0x0C000000UL #define SE_COMMAND_AEAD_DECRYPT 0x0C010000UL #define SE_COMMAND_CHACHA20_ENCRYPT 0x0C020000UL #define SE_COMMAND_CHACHA20_DECRYPT 0x0C030000UL #define SE_COMMAND_POLY1305_KEY_MAC 0x0C040000UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ #define SE_COMMAND_DH 0x0E000000UL #endif // #if defined(SEMAILBOX_PRESENT) #define SE_COMMAND_CHECK_SE_IMAGE 0x43020000UL #define SE_COMMAND_APPLY_SE_IMAGE 0x43030000UL #define SE_COMMAND_STATUS_SE_IMAGE 0x43040000UL #define SE_COMMAND_CHECK_HOST_IMAGE 0x43050001UL #define SE_COMMAND_APPLY_HOST_IMAGE 0x43060001UL #define SE_COMMAND_STATUS_HOST_IMAGE 0x43070000UL #if defined(SEMAILBOX_PRESENT) #define SE_COMMAND_STATUS_SE_VERSION 0x43080000UL #define SE_COMMAND_STATUS_OTP_VERSION 0x43080100UL #define SE_COMMAND_WRITE_USER_DATA 0x43090000UL #define SE_COMMAND_ERASE_USER_DATA 0x430A0000UL #define SE_COMMAND_DBG_LOCK_APPLY 0x430C0000 #define SE_COMMAND_DBG_LOCK_ENABLE_SECURE 0x430D0000 #define SE_COMMAND_DBG_LOCK_DISABLE_SECURE 0x430E0000 #define SE_COMMAND_DEVICE_ERASE 0x430F0000 #define SE_COMMAND_DEVICE_ERASE_DISABLE 0x43100000 #define SE_COMMAND_DBG_LOCK_STATUS 0x43110000 #define SE_COMMAND_PROTECTED_REGISTER 0x43210000 #define SE_COMMAND_GET_CHALLENGE 0xFD000000UL #define SE_COMMAND_ROLL_CHALLENGE 0xFD000100UL #define SE_COMMAND_OPEN_DEBUG 0xFD010001UL #define SE_COMMAND_DISABLE_TAMPER 0xFD020001UL #define SE_COMMAND_READ_SERIAL 0xFE000000UL #define SE_COMMAND_GET_STATUS 0xFE010000UL #define SE_COMMAND_READ_PUBKEYBOOT 0xFE020001UL #define SE_COMMAND_SET_UPGRADEFLAG_SE 0xFE030000UL #define SE_COMMAND_SET_UPGRADEFLAG_HOST 0xFE030001UL #define SE_COMMAND_INIT_PUBKEY_SIGNATURE 0xFF090001UL #define SE_COMMAND_READ_PUBKEY_SIGNATURE 0xFF0A0001UL #endif /* SEMAILBOX_PRESENT */ #if defined(SEMAILBOX_PRESENT) /* Command options for the Secure Element commands. */ /** Use MD5 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_MD5 0x00000100UL /** Use SHA1 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_SHA1 0x00000200UL /** Use SHA224 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_SHA224 0x00000300UL /** Use SHA256 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_SHA256 0x00000400UL #if (defined(_SILICON_LABS_SECURITY_FEATURE) \ && (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)) /** Use SHA384 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_SHA384 0x00000500UL /** Use SHA512 as hash algorithm */ #define SE_COMMAND_OPTION_HASH_SHA512 0x00000600UL #endif /* _SILICON_LABS_SECURITY_FEATURE_VAULT */ /** Execute algorithm in ECB mode */ #define SE_COMMAND_OPTION_MODE_ECB 0x00000100UL /** Execute algorithm in CBC mode */ #define SE_COMMAND_OPTION_MODE_CBC 0x00000200UL /** Execute algorithm in CTR mode */ #define SE_COMMAND_OPTION_MODE_CTR 0x00000300UL /** Execute algorithm in CFB mode */ #define SE_COMMAND_OPTION_MODE_CFB 0x00000400UL /** Execute algorithm in OFB mode */ #define SE_COMMAND_OPTION_MODE_OFB 0x00000500UL /** Execute algorithm in XTS mode */ #define SE_COMMAND_OPTION_MODE_XTS 0x00000800UL #define SE_COMMAND_OPTION_CERT_DEVICE 0x00000100UL #define SE_COMMAND_OPTION_CERT_BATCH 0x00000200UL #define SE_COMMAND_OPTION_CERT_FACTORY 0x00000300UL /** Pubkey type */ #define SE_KEY_TYPE_ROOT 0x00000300UL /** Run the whole algorithm, all data present */ #define SE_COMMAND_OPTION_CONTEXT_WHOLE 0x00000000UL /** Start the algorithm, but get a context to later add more data */ #define SE_COMMAND_OPTION_CONTEXT_START 0x00000001UL /** End the algorithm, get the result */ #define SE_COMMAND_OPTION_CONTEXT_END 0x00000002UL /** Add more data input to the algorithm. Need to supply previous context, * and get a context back */ #define SE_COMMAND_OPTION_CONTEXT_ADD 0x00000003UL /** Padding options for signature functionality. */ #define SE_COMMAND_OPTION_PADDING_NONE 0x00000000UL #define SE_COMMAND_OPTION_PADDING_EMSA_PKCS 0x00000003UL #define SE_COMMAND_OPTION_PADDING_PSS 0x00000004UL /* Special parameters for the Secure Element commands. */ #define SE_COMMAND_OPTION_READ 0x00000000UL #define SE_COMMAND_OPTION_WRITE 0x00000100UL /** Magic parameter for deleting user data */ #define SE_COMMAND_OPTION_ERASE_UD 0xDE1E7EADUL #endif /* SEMAILBOX_PRESENT */ /** Pubkey types */ #define SE_KEY_TYPE_BOOT 0x00000100UL #define SE_KEY_TYPE_AUTH 0x00000200UL #define SE_COMMAND_INIT_OTP 0xFF000001UL #define SE_COMMAND_INIT_PUBKEY 0xFF070001UL #define SE_COMMAND_READ_PUBKEY 0xFF080001UL /** * Command was not recognized as a valid command, or is not allowed in the * current context. */ #define SE_RESPONSE_INVALID_COMMAND 0x00010000UL /** * User did not provide the required credentials to be allowed to execute the * command. */ #define SE_RESPONSE_AUTHORIZATION_ERROR 0x00020000UL /** * Signature validation command (e.g. SE_COMMAND_SIGNATURE_VERIFY) failed to * verify the given signature as being correct. */ #define SE_RESPONSE_INVALID_SIGNATURE 0x00030000UL /** A command started in non-secure mode is trying to access secure memory. */ #define SE_RESPONSE_BUS_ERROR 0x00040000UL /** Internal error */ #define SE_RESPONSE_INTERNAL_ERROR 0x00050000UL /** An internal error was raised and the command did not execute. */ #define SE_RESPONSE_CRYPTO_ERROR 0x00060000UL /** One of the passed parameters is deemed invalid (e.g. out of bounds). */ #define SE_RESPONSE_INVALID_PARAMETER 0x00070000UL /** Failure while checking the host for secure boot */ #define SE_RESPONSE_SECUREBOOT_ERROR 0x00090000UL /** Failure during selftest */ #define SE_RESPONSE_SELFTEST_ERROR 0x000A0000UL /** Feature/item not initialized or not present */ #define SE_RESPONSE_NOT_INITIALIZED 0x000B0000UL /* Abort status code is given when no operation is attempted. */ #define SE_RESPONSE_ABORT 0x00FF0000UL /** @endcond */ /******************************************************************************* ***************************** PROTOTYPES ********************************** ******************************************************************************/ #if defined(SEMAILBOX_PRESENT) // Initialization commands SE_Response_t SE_readPubkey(uint32_t key_type, void* pubkey, uint32_t numBytes, bool signature) SL_DEPRECATED_API_SDK_4_4; #endif // #if defined(SEMAILBOX_PRESENT) #endif // #if !defined(SLI_EM_SE_HOST) /** @} (end addtogroup se_deprecated) */ #ifdef __cplusplus } #endif /** @} (end addtogroup se) */ #endif /* defined(SEMAILBOX_PRESENT) || defined(_SILICON_LABS_32B_SERIES_2_CONFIG_2) */ #endif /* EM_SE_H */