123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 |
- /*
- * Copyright 2017, 2019 NXP
- * All rights reserved.
- *
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "fsl_bee.h"
- /*******************************************************************************
- * Definitions
- ******************************************************************************/
- /* Component ID definition, used by tools. */
- #ifndef FSL_COMPONENT_ID
- #define FSL_COMPONENT_ID "platform.drivers.bee"
- #endif
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- /*******************************************************************************
- * Code
- ******************************************************************************/
- static void aligned_memcpy(void *dst, const void *src, size_t size)
- {
- register uint32_t *to32 = (uint32_t *)(uint32_t *)dst;
- register const uint32_t *from32 = (const uint32_t *)(const uint32_t *)src;
- while (size >= sizeof(uint32_t))
- {
- *to32 = *from32;
- size -= sizeof(uint32_t);
- to32++;
- from32++;
- }
- }
- /*!
- * brief Resets BEE module to factory default values.
- *
- * This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared.
- *
- * param base BEE peripheral address.
- */
- void BEE_Init(BEE_Type *base)
- {
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- CLOCK_EnableClock(kCLOCK_Bee);
- #endif
- base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK;
- }
- /*!
- * brief Resets BEE module, clears keys for both regions and disables clock to the BEE.
- *
- * This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both
- * regions are cleared.
- *
- * param base BEE peripheral address.
- */
- void BEE_Deinit(BEE_Type *base)
- {
- base->CTRL &=
- ~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK);
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- CLOCK_DisableClock(kCLOCK_Bee);
- #endif
- }
- /*!
- * brief Loads default values to the BEE region configuration structure.
- *
- * Loads default values to the BEE region configuration structure. The default values are as follows:
- * code
- * config->region0Mode = kBEE_AesCtrMode;
- * config->region1Mode = kBEE_AesCtrMode;
- * config->region0AddrOffset = 0U;
- * config->region1AddrOffset = 0U;
- * config->region0SecLevel = kBEE_SecurityLevel3;
- * config->region1SecLevel = kBEE_SecurityLevel3;
- * config->region1Bot = 0U;
- * config->region1Top = 0U;
- * config->accessPermission = kBEE_AccessProtDisabled;
- * config->endianSwapEn = kBEE_EndianSwapEnabled;
- * endcode
- *
- * param config Configuration structure for BEE peripheral.
- */
- void BEE_GetDefaultConfig(bee_region_config_t *config)
- {
- assert(config);
- /* Initializes the configure structure to zero. */
- (void)memset(config, 0, sizeof(*config));
- config->region0Mode = kBEE_AesCtrMode;
- config->region1Mode = kBEE_AesCtrMode;
- config->region0AddrOffset = 0U;
- config->region1AddrOffset = 0U;
- config->region0SecLevel = kBEE_SecurityLevel3;
- config->region1SecLevel = kBEE_SecurityLevel3;
- config->region1Bot = 0U;
- config->region1Top = 0U;
- config->accessPermission = kBEE_AccessProtDisabled;
- config->endianSwapEn = kBEE_EndianSwapEnabled;
- }
- /*!
- * brief Sets BEE configuration.
- *
- * This function sets BEE peripheral and BEE region settings accorging to given configuration structure.
- *
- * param base BEE peripheral address.
- * param config Configuration structure for BEE.
- */
- void BEE_SetConfig(BEE_Type *base, const bee_region_config_t *config)
- {
- uint32_t beeCtrlVal;
- bool reenable = false;
- /* Wait until BEE is in idle state */
- while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
- {
- }
- /* Disable BEE before region configuration in case it is enabled. */
- if ((base->CTRL & BEE_CTRL_BEE_ENABLE_MASK) != 0U)
- {
- BEE_Disable(base);
- reenable = true;
- }
- /* Preserve CTRL bit values that are not set by this function */
- beeCtrlVal = base->CTRL & 0xFFFF0037U;
- /* Set variable according to configuration */
- beeCtrlVal |= BEE_CTRL_AC_PROT_EN(config->accessPermission) | BEE_CTRL_LITTLE_ENDIAN(config->endianSwapEn) |
- BEE_CTRL_SECURITY_LEVEL_R0(config->region0SecLevel) | BEE_CTRL_CTRL_AES_MODE_R0(config->region0Mode) |
- BEE_CTRL_SECURITY_LEVEL_R1(config->region1SecLevel) | BEE_CTRL_CTRL_AES_MODE_R1(config->region1Mode);
- /* Load values to registers */
- base->CTRL = beeCtrlVal;
- base->ADDR_OFFSET0 = config->region0AddrOffset;
- base->ADDR_OFFSET1 = config->region1AddrOffset;
- base->REGION1_BOT = config->region1Bot;
- base->REGION1_TOP = config->region1Top;
- /* Reenable BEE if it was enabled before. */
- if (reenable)
- {
- BEE_Enable(base);
- }
- }
- /*!
- * brief Loads the AES key for selected region into BEE key registers.
- *
- * This function loads given AES key to BEE register for the given region.
- * The key must be 32-bit aligned and stored in little-endian format.
- *
- * Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers.
- * Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2.
- *
- * param base BEE peripheral address.
- * param region Selection of the BEE region to be configured.
- * param key AES key (in little-endian format).
- * param keySize Size of AES key.
- */
- status_t BEE_SetRegionKey(BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize)
- {
- bool redisable = false;
- /* Key must be 32-bit aligned */
- if ((0U != ((uintptr_t)key & 0x3u)) || (keySize != 16U))
- {
- return kStatus_InvalidArgument;
- }
- /* Wait until BEE is in idle state */
- while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
- {
- }
- /* Clear KEY_VALID bit before new key is loaded */
- base->CTRL &= ~BEE_CTRL_KEY_VALID_MASK;
- /* Write key registers, key is stored in little-endian format in memory */
- aligned_memcpy((uint32_t *)(uint32_t)&base->AES_KEY0_W0, key, keySize);
- /* Enable BEE before key configuration. */
- if (0U == (base->CTRL & BEE_CTRL_BEE_ENABLE_MASK))
- {
- BEE_Enable(base);
- redisable = true;
- }
- if (region == kBEE_Region0)
- {
- base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK;
- }
- else if (region == kBEE_Region1)
- {
- base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK;
- }
- else
- {
- return kStatus_InvalidArgument;
- }
- /* Set KEY_VALID bit to trigger key loading */
- base->CTRL |= BEE_CTRL_KEY_VALID_MASK;
- /* Wait until key is ready */
- while (0U == (base->CTRL & BEE_CTRL_KEY_VALID_MASK))
- {
- }
- /* Redisable BEE if it was disabled before this function call. */
- if (redisable)
- {
- BEE_Disable(base);
- }
- return kStatus_Success;
- }
- /*!
- * brief Loads the nonce for selected region into BEE nonce registers.
- *
- * This function loads given nonce(only AES CTR mode) to BEE register for the given region.
- * The nonce must be 32-bit aligned and stored in little-endian format.
- *
- * param base BEE peripheral address.
- * param region Selection of the BEE region to be configured.
- * param nonce AES nonce (in little-endian format).
- * param nonceSize Size of AES nonce.
- */
- status_t BEE_SetRegionNonce(BEE_Type *base, bee_region_t region, const uint8_t *nonce, size_t nonceSize)
- {
- /* Nonce must be 32-bit aligned */
- if ((0U != ((uintptr_t)nonce & 0x3u)) || (nonceSize != 16U))
- {
- return kStatus_InvalidArgument;
- }
- /* Wait until BEE is in idle state */
- while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
- {
- }
- /* Write nonce registers, nonce is stored in little-endian format in memory */
- if (region == kBEE_Region0)
- {
- aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE0_W0, nonce, nonceSize);
- }
- else if (region == kBEE_Region1)
- {
- aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE1_W0, nonce, nonceSize);
- }
- else
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- /*!
- * brief Gets the BEE status flags.
- *
- * This function returns status of BEE peripheral.
- *
- * param base BEE peripheral address.
- *
- * return The status flags. This is the logical OR of members of the
- * enumeration ::bee_status_flags_t
- */
- uint32_t BEE_GetStatusFlags(BEE_Type *base)
- {
- return base->STATUS;
- }
- /*!
- * brief Clears the BEE status flags.
- *
- * param base BEE peripheral base address.
- * param mask The status flags to clear. This is a logical OR of members of the
- * enumeration ::bee_status_flags_t
- */
- void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask)
- {
- /* w1c */
- base->STATUS |= mask;
- }
|