Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:58

0001 /*
0002  * Copyright 2017, 2019 NXP
0003  * All rights reserved.
0004  *
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_bee.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.bee"
0018 #endif
0019 
0020 /*******************************************************************************
0021  * Variables
0022  ******************************************************************************/
0023 
0024 /*******************************************************************************
0025  * Code
0026  ******************************************************************************/
0027 
0028 static void aligned_memcpy(void *dst, const void *src, size_t size)
0029 {
0030     register uint32_t *to32         = (uint32_t *)(uint32_t *)dst;
0031     register const uint32_t *from32 = (const uint32_t *)(const uint32_t *)src;
0032 
0033     while (size >= sizeof(uint32_t))
0034     {
0035         *to32 = *from32;
0036         size -= sizeof(uint32_t);
0037         to32++;
0038         from32++;
0039     }
0040 }
0041 
0042 /*!
0043  * brief Resets BEE module to factory default values.
0044  *
0045  * This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared.
0046  *
0047  * param base BEE peripheral address.
0048  */
0049 void BEE_Init(BEE_Type *base)
0050 {
0051 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0052     CLOCK_EnableClock(kCLOCK_Bee);
0053 #endif
0054 
0055     base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK;
0056 }
0057 
0058 /*!
0059  * brief Resets BEE module, clears keys for both regions and disables clock to the BEE.
0060  *
0061  * This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both
0062  * regions are cleared.
0063  *
0064  * param base BEE peripheral address.
0065  */
0066 void BEE_Deinit(BEE_Type *base)
0067 {
0068     base->CTRL &=
0069         ~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK);
0070 
0071 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0072     CLOCK_DisableClock(kCLOCK_Bee);
0073 #endif
0074 }
0075 
0076 /*!
0077  * brief Loads default values to the BEE region configuration structure.
0078  *
0079  * Loads default values to the BEE region configuration structure. The default values are as follows:
0080  * code
0081  *   config->region0Mode = kBEE_AesCtrMode;
0082  *   config->region1Mode = kBEE_AesCtrMode;
0083  *   config->region0AddrOffset = 0U;
0084  *   config->region1AddrOffset = 0U;
0085  *   config->region0SecLevel = kBEE_SecurityLevel3;
0086  *   config->region1SecLevel = kBEE_SecurityLevel3;
0087  *   config->region1Bot = 0U;
0088  *   config->region1Top = 0U;
0089  *   config->accessPermission = kBEE_AccessProtDisabled;
0090  *   config->endianSwapEn = kBEE_EndianSwapEnabled;
0091  * endcode
0092  *
0093  * param config Configuration structure for BEE peripheral.
0094  */
0095 void BEE_GetDefaultConfig(bee_region_config_t *config)
0096 {
0097     assert(config);
0098 
0099     /* Initializes the configure structure to zero. */
0100     (void)memset(config, 0, sizeof(*config));
0101 
0102     config->region0Mode       = kBEE_AesCtrMode;
0103     config->region1Mode       = kBEE_AesCtrMode;
0104     config->region0AddrOffset = 0U;
0105     config->region1AddrOffset = 0U;
0106     config->region0SecLevel   = kBEE_SecurityLevel3;
0107     config->region1SecLevel   = kBEE_SecurityLevel3;
0108     config->region1Bot        = 0U;
0109     config->region1Top        = 0U;
0110     config->accessPermission  = kBEE_AccessProtDisabled;
0111     config->endianSwapEn      = kBEE_EndianSwapEnabled;
0112 }
0113 
0114 /*!
0115  * brief Sets BEE configuration.
0116  *
0117  * This function sets BEE peripheral and BEE region settings accorging to given configuration structure.
0118  *
0119  * param base BEE peripheral address.
0120  * param config Configuration structure for BEE.
0121  */
0122 void BEE_SetConfig(BEE_Type *base, const bee_region_config_t *config)
0123 {
0124     uint32_t beeCtrlVal;
0125     bool reenable = false;
0126 
0127     /* Wait until BEE is in idle state */
0128     while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
0129     {
0130     }
0131 
0132     /* Disable BEE before region configuration in case it is enabled. */
0133     if ((base->CTRL & BEE_CTRL_BEE_ENABLE_MASK) != 0U)
0134     {
0135         BEE_Disable(base);
0136         reenable = true;
0137     }
0138 
0139     /* Preserve CTRL bit values that are not set by this function */
0140     beeCtrlVal = base->CTRL & 0xFFFF0037U;
0141 
0142     /* Set variable according to configuration */
0143     beeCtrlVal |= BEE_CTRL_AC_PROT_EN(config->accessPermission) | BEE_CTRL_LITTLE_ENDIAN(config->endianSwapEn) |
0144                   BEE_CTRL_SECURITY_LEVEL_R0(config->region0SecLevel) | BEE_CTRL_CTRL_AES_MODE_R0(config->region0Mode) |
0145                   BEE_CTRL_SECURITY_LEVEL_R1(config->region1SecLevel) | BEE_CTRL_CTRL_AES_MODE_R1(config->region1Mode);
0146 
0147     /* Load values to registers */
0148     base->CTRL         = beeCtrlVal;
0149     base->ADDR_OFFSET0 = config->region0AddrOffset;
0150     base->ADDR_OFFSET1 = config->region1AddrOffset;
0151     base->REGION1_BOT  = config->region1Bot;
0152     base->REGION1_TOP  = config->region1Top;
0153 
0154     /* Reenable BEE if it was enabled before. */
0155     if (reenable)
0156     {
0157         BEE_Enable(base);
0158     }
0159 }
0160 
0161 /*!
0162  * brief Loads the AES key for selected region into BEE key registers.
0163  *
0164  * This function loads given AES key to BEE register for the given region.
0165  * The key must be 32-bit aligned and stored in little-endian format.
0166  *
0167  * Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers.
0168  * Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2.
0169  *
0170  * param base BEE peripheral address.
0171  * param region Selection of the BEE region to be configured.
0172  * param key AES key (in little-endian format).
0173  * param keySize Size of AES key.
0174  */
0175 status_t BEE_SetRegionKey(BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize)
0176 {
0177     bool redisable = false;
0178 
0179     /* Key must be 32-bit aligned */
0180     if ((0U != ((uintptr_t)key & 0x3u)) || (keySize != 16U))
0181     {
0182         return kStatus_InvalidArgument;
0183     }
0184 
0185     /* Wait until BEE is in idle state */
0186     while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
0187     {
0188     }
0189 
0190     /* Clear KEY_VALID bit before new key is loaded */
0191     base->CTRL &= ~BEE_CTRL_KEY_VALID_MASK;
0192 
0193     /* Write key registers, key is stored in little-endian format in memory */
0194     aligned_memcpy((uint32_t *)(uint32_t)&base->AES_KEY0_W0, key, keySize);
0195 
0196     /* Enable BEE before key configuration. */
0197     if (0U == (base->CTRL & BEE_CTRL_BEE_ENABLE_MASK))
0198     {
0199         BEE_Enable(base);
0200         redisable = true;
0201     }
0202 
0203     if (region == kBEE_Region0)
0204     {
0205         base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK;
0206     }
0207 
0208     else if (region == kBEE_Region1)
0209     {
0210         base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK;
0211     }
0212 
0213     else
0214     {
0215         return kStatus_InvalidArgument;
0216     }
0217 
0218     /* Set KEY_VALID bit to trigger key loading */
0219     base->CTRL |= BEE_CTRL_KEY_VALID_MASK;
0220     /* Wait until key is ready */
0221     while (0U == (base->CTRL & BEE_CTRL_KEY_VALID_MASK))
0222     {
0223     }
0224 
0225     /* Redisable BEE if it was disabled before this function call. */
0226     if (redisable)
0227     {
0228         BEE_Disable(base);
0229     }
0230 
0231     return kStatus_Success;
0232 }
0233 
0234 /*!
0235  * brief Loads the nonce for selected region into BEE nonce registers.
0236  *
0237  * This function loads given nonce(only AES CTR mode) to BEE register for the given region.
0238  * The nonce must be 32-bit aligned and stored in little-endian format.
0239  *
0240  * param base BEE peripheral address.
0241  * param region Selection of the BEE region to be configured.
0242  * param nonce AES nonce (in little-endian format).
0243  * param nonceSize Size of AES nonce.
0244  */
0245 status_t BEE_SetRegionNonce(BEE_Type *base, bee_region_t region, const uint8_t *nonce, size_t nonceSize)
0246 {
0247     /* Nonce must be 32-bit aligned */
0248     if ((0U != ((uintptr_t)nonce & 0x3u)) || (nonceSize != 16U))
0249     {
0250         return kStatus_InvalidArgument;
0251     }
0252 
0253     /* Wait until BEE is in idle state */
0254     while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
0255     {
0256     }
0257 
0258     /* Write nonce registers, nonce is stored in little-endian format in memory */
0259     if (region == kBEE_Region0)
0260     {
0261         aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE0_W0, nonce, nonceSize);
0262     }
0263 
0264     else if (region == kBEE_Region1)
0265     {
0266         aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE1_W0, nonce, nonceSize);
0267     }
0268 
0269     else
0270     {
0271         return kStatus_InvalidArgument;
0272     }
0273 
0274     return kStatus_Success;
0275 }
0276 
0277 /*!
0278  * brief Gets the BEE status flags.
0279  *
0280  * This function returns status of BEE peripheral.
0281  *
0282  * param base BEE peripheral address.
0283  *
0284  * return The status flags. This is the logical OR of members of the
0285  *         enumeration ::bee_status_flags_t
0286  */
0287 uint32_t BEE_GetStatusFlags(BEE_Type *base)
0288 {
0289     return base->STATUS;
0290 }
0291 
0292 /*!
0293  * brief Clears the BEE status flags.
0294  *
0295  * param base BEE peripheral base address.
0296  * param mask The status flags to clear. This is a logical OR of members of the
0297  *             enumeration ::bee_status_flags_t
0298  */
0299 void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask)
0300 {
0301     /* w1c */
0302     base->STATUS |= mask;
0303 }