diff options
Diffstat (limited to 'bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c')
-rw-r--r-- | bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c new file mode 100644 index 0000000000..d4ffdacfb9 --- /dev/null +++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c @@ -0,0 +1,303 @@ +/* + * 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; +} |