| /* |
| * Copyright 2017 NXP |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * |
| * o Redistributions of source code must retain the above copyright notice, this list |
| * of conditions and the following disclaimer. |
| * |
| * o Redistributions in binary form must reproduce the above copyright notice, this |
| * list of conditions and the following disclaimer in the documentation and/or |
| * other materials provided with the distribution. |
| * |
| * o Neither the name of the copyright holder nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "fsl_bee.h" |
| |
| /******************************************************************************* |
| * Definitions |
| ******************************************************************************/ |
| |
| /******************************************************************************* |
| * Variables |
| ******************************************************************************/ |
| |
| /******************************************************************************* |
| * Code |
| ******************************************************************************/ |
| |
| static void aligned_memcpy(void *dst, const void *src, size_t size) |
| { |
| register uint32_t *to32 = (uint32_t *)(uintptr_t)dst; |
| register const uint32_t *from32 = (const uint32_t *)(uintptr_t)src; |
| |
| while (size >= sizeof(uint32_t)) |
| { |
| *to32 = *from32; |
| size -= sizeof(uint32_t); |
| to32++; |
| from32++; |
| } |
| } |
| |
| 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; |
| } |
| |
| 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 |
| } |
| |
| void BEE_GetDefaultConfig(bee_region_config_t *config) |
| { |
| assert(config); |
| |
| config->mode = kBEE_AesEcbMode; |
| config->regionBot = 0U; |
| config->regionTop = 0U; |
| config->addrOffset = 0xF0000000U; |
| config->regionEn = kBEE_RegionDisabled; |
| } |
| |
| status_t BEE_SetRegionConfig(BEE_Type *base, bee_region_t region, const bee_region_config_t *config) |
| { |
| IOMUXC_GPR_Type *iomuxc = IOMUXC_GPR; |
| bool reenable = false; |
| |
| /* Wait until BEE is in idle state */ |
| while (!(BEE_GetStatusFlags(base) & kBEE_IdleFlag)) |
| { |
| } |
| |
| /* Disable BEE before region configuration in case it is enabled. */ |
| if ((base->CTRL >> BEE_CTRL_BEE_ENABLE_SHIFT) & 1) |
| { |
| BEE_Disable(base); |
| reenable = true; |
| } |
| |
| if (region == kBEE_Region0) |
| { |
| /* Region 0 config */ |
| iomuxc->GPR18 = config->regionBot; |
| iomuxc->GPR19 = config->regionTop; |
| |
| base->CTRL |= BEE_CTRL_CTRL_AES_MODE_R0(config->mode); |
| base->ADDR_OFFSET0 = BEE_ADDR_OFFSET0_ADDR_OFFSET0(config->addrOffset); |
| } |
| |
| else if (region == kBEE_Region1) |
| { |
| /* Region 1 config */ |
| iomuxc->GPR20 = config->regionBot; |
| iomuxc->GPR21 = config->regionTop; |
| |
| base->CTRL |= BEE_CTRL_CTRL_AES_MODE_R1(config->mode); |
| base->ADDR_OFFSET1 = BEE_ADDR_OFFSET1_ADDR_OFFSET0(config->addrOffset); |
| base->REGION1_BOT = BEE_REGION1_BOT_REGION1_BOT(config->regionBot); |
| base->REGION1_TOP = BEE_REGION1_TOP_REGION1_TOP(config->regionTop); |
| } |
| |
| else |
| { |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Enable/disable region if desired */ |
| if (config->regionEn == kBEE_RegionEnabled) |
| { |
| iomuxc->GPR11 |= IOMUXC_GPR_GPR11_BEE_DE_RX_EN(1 << region); |
| } |
| else |
| { |
| iomuxc->GPR11 &= ~IOMUXC_GPR_GPR11_BEE_DE_RX_EN(1 << region); |
| } |
| |
| /* Reenable BEE if it was enabled before. */ |
| if (reenable) |
| { |
| BEE_Enable(base); |
| } |
| |
| return kStatus_Success; |
| } |
| |
| status_t BEE_SetRegionKey( |
| BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize, const uint8_t *nonce, size_t nonceSize) |
| { |
| bool reenable = false; |
| |
| /* Key must be 32-bit aligned */ |
| if (((uintptr_t)key & 0x3u) || (keySize != 16)) |
| { |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Wait until BEE is in idle state */ |
| while (!(BEE_GetStatusFlags(base) & kBEE_IdleFlag)) |
| { |
| } |
| |
| /* Disable BEE before region configuration in case it is enabled. */ |
| if ((base->CTRL >> BEE_CTRL_BEE_ENABLE_SHIFT) & 1) |
| { |
| BEE_Disable(base); |
| reenable = true; |
| } |
| |
| if (region == kBEE_Region0) |
| { |
| base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK; |
| |
| if (nonce) |
| { |
| if (nonceSize != 16) |
| { |
| return kStatus_InvalidArgument; |
| } |
| memcpy((uint32_t *)&base->CTR_NONCE0_W0, nonce, nonceSize); |
| } |
| } |
| |
| else if (region == kBEE_Region1) |
| { |
| base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK; |
| |
| if (nonce) |
| { |
| if (nonceSize != 16) |
| { |
| return kStatus_InvalidArgument; |
| } |
| memcpy((uint32_t *)&base->CTR_NONCE1_W0, nonce, nonceSize); |
| } |
| } |
| |
| else |
| { |
| return kStatus_InvalidArgument; |
| } |
| |
| /* Try to load key. If BEE key selection fuse is programmed to use OTMP key on this device, this operation should |
| * fail. */ |
| aligned_memcpy((uint32_t *)&base->AES_KEY0_W0, key, keySize); |
| if (memcmp((uint32_t *)&base->AES_KEY0_W0, key, keySize) != 0) |
| { |
| return kStatus_Fail; |
| } |
| |
| /* Reenable BEE if it was enabled before. */ |
| if (reenable) |
| { |
| BEE_Enable(base); |
| } |
| |
| return kStatus_Success; |
| } |
| |
| uint32_t BEE_GetStatusFlags(BEE_Type *base) |
| { |
| return base->STATUS; |
| } |
| |
| void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask) |
| { |
| /* w1c */ |
| base->STATUS |= mask; |
| } |