1 /*
2 * Copyright 2019-2021 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_otfad.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14
15 /* Component ID definition, used by tools. */
16 #ifndef FSL_COMPONENT_ID
17 #define FSL_COMPONENT_ID "platform.drivers.otfad"
18 #endif
19
20 /*******************************************************************************
21 * Prototypes
22 ******************************************************************************/
23
24 /*******************************************************************************
25 * Variables
26 ******************************************************************************/
27
28 /*******************************************************************************
29 * Code
30 ******************************************************************************/
31 /*!
32 * brief OTFAD module get default configuration.
33 *
34 * param config configuration.
35 */
OTFAD_GetDefaultConfig(otfad_config_t * config)36 void OTFAD_GetDefaultConfig(otfad_config_t *config)
37 {
38 assert(config != NULL);
39
40 /* Including OTFAD operate mode, IRQ eable, key blob and restricted register access */
41 #if defined(FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE) && (FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE > 0)
42 config->enableIntRequest = false;
43 #endif /* FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE */
44 #if defined(FSL_FEATURE_OTFAD_HAS_FORCE_ERR) && (FSL_FEATURE_OTFAD_HAS_FORCE_ERR > 0)
45 config->forceError = false;
46 #endif /* FSL_FEATURE_OTFAD_HAS_FORCE_ERR */
47 config->forceSVM = false;
48 config->forceLDM = false;
49
50 config->restrictedRegAccess = false;
51
52 #if defined(FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING) && (FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING > 0)
53 /* Start key blob processing */
54 config->startKeyBlobProcessing = false;
55 config->keyBlobProcess = false;
56 config->keyBlobScramble = false;
57 #endif /* FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING */
58
59 /* Global OTFAD enable */
60 config->enableOTFAD = false;
61 }
62
63 /*!
64 * brief OTFAD module initialization function, this function need to put into ram for keyblob process.
65 *
66 * param base OTFAD base address.
67 */
AT_QUICKACCESS_SECTION_CODE(void OTFAD_Init (OTFAD_Type * base,const otfad_config_t * config))68 AT_QUICKACCESS_SECTION_CODE(void OTFAD_Init(OTFAD_Type *base, const otfad_config_t *config))
69 {
70 assert(config != NULL);
71
72 /* No independent clock and it is bind with flexspi clock,
73 so it need to enable clock for flexspi firstly with initialization. */
74
75 uint32_t temp = 0U;
76 uint32_t status = 0U;
77
78 /* Set OTFAD operate mode, IRQ eable, key blob and restricted register access */
79 temp = OTFAD_CR_FLDM(config->forceLDM) |
80 #if defined(FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE) && (FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE > 0)
81 OTFAD_CR_IRQE(config->enableIntRequest) |
82 #endif /* FSL_FEATURE_OTFAD_HAS_HAS_IRQ_ENABLE */
83 #if defined(FSL_FEATURE_OTFAD_HAS_FORCE_ERR) && (FSL_FEATURE_OTFAD_HAS_FORCE_ERR > 0)
84 OTFAD_CR_FERR(config->forceError) |
85 #endif /* FSL_FEATURE_OTFAD_HAS_FORCE_ERR */
86 #if defined(FSL_FEATURE_OTFAD_HAS_SVM_MODE) && FSL_FEATURE_OTFAD_HAS_SVM_MODE
87 OTFAD_CR_FSVM(config->forceSVM) |
88 #endif /* FSL_FEATURE_OTFAD_HAS_SVM_MODE */
89 #if defined(FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING) && (FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING > 0)
90 OTFAD_CR_KBSE(config->keyBlobScramble) | OTFAD_CR_KBPE(config->keyBlobProcess) |
91 #endif /* FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING */
92 OTFAD_CR_RRAE(config->restrictedRegAccess);
93
94 /* Enable global OTFAD operation */
95 temp |= OTFAD_CR_GE(config->enableOTFAD);
96
97 /* Wait for AHB bus idle, otherwise the keyblob process will fail */
98 status = ((FLEXSPI_Type *)config->flexspiBaseAddr)->STS0;
99 while (!((status & FLEXSPI_STS0_ARBIDLE_MASK) && (status & FLEXSPI_STS0_SEQIDLE_MASK)))
100 {
101 status = ((FLEXSPI_Type *)config->flexspiBaseAddr)->STS0;
102 }
103
104 #if defined(FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING) && (FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING > 0)
105 /* Start key blob processing, and software set SKBP only once after a hard reset */
106 if (config->startKeyBlobProcessing == true)
107 {
108 temp |= OTFAD_CR_SKBP(config->startKeyBlobProcessing);
109 }
110 #endif /* FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING */
111
112 base->CR |= temp;
113
114 #if defined(FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING) && (FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING > 0)
115 /* Check key blob precessing done if enabled */
116 if (config->keyBlobProcess == true)
117 {
118 while (0U == ((base->SR & OTFAD_SR_KBD_MASK) >> OTFAD_SR_KBD_SHIFT))
119 {
120 ; /* Intentional empty */
121 }
122 }
123 #endif /* FSL_FEATURE_OTFAD_HAS_KEYBLOB_PROCESSING */
124 }
125
126 /*!
127 * brief Deinitializes the OTFAD.
128 *
129 */
AT_QUICKACCESS_SECTION_CODE(void OTFAD_Deinit (OTFAD_Type * base))130 AT_QUICKACCESS_SECTION_CODE(void OTFAD_Deinit(OTFAD_Type *base))
131 {
132 /* Disable global OTFAD operation */
133 base->CR &= ~OTFAD_CR_GE(1U);
134 }
135
OTFAD_SetEncryptionConfig(OTFAD_Type * base,const otfad_encryption_config_t * config)136 status_t OTFAD_SetEncryptionConfig(OTFAD_Type *base, const otfad_encryption_config_t *config)
137 {
138 assert(config != NULL);
139
140 status_t status = kStatus_Success;
141 uint32_t temp = 0U;
142 uint32_t startAddr = config->startAddr;
143 uint32_t endAddr = config->endAddr;
144 const uint32_t *tempKey = config->key;
145 const uint32_t *tempCounter = config->counter;
146 uint8_t contextIndex = config->contextIndex;
147 uint8_t regAccessMode = 0U;
148
149 /* Get restricted register access mode */
150 regAccessMode = (uint8_t)((base->SR & OTFAD_SR_RRAM_MASK) >> OTFAD_SR_RRAM_SHIFT);
151
152 if (regAccessMode == 0U)
153 {
154 /* Set context region */
155 if (startAddr <= endAddr)
156 {
157 /* Address is aligned with 1KBytes */
158 startAddr = (startAddr & OTFAD_RGD_W0_SRTADDR_MASK) >> OTFAD_RGD_W0_SRTADDR_SHIFT;
159 endAddr = (endAddr & OTFAD_RGD_W1_ENDADDR_MASK) >> OTFAD_RGD_W1_ENDADDR_SHIFT;
160
161 temp |= OTFAD_RGD_W1_ENDADDR(endAddr) | OTFAD_RGD_W1_RO(config->readOnly) |
162 OTFAD_RGD_W1_ADE(config->AESdecryption) | OTFAD_RGD_W1_VLD(config->valid);
163
164 /* Set context n start address */
165 base->CTX[contextIndex].RGD_W0 = OTFAD_RGD_W0_SRTADDR(startAddr);
166 /* Set context n end address and enable context n AES decryption */
167 base->CTX[contextIndex].RGD_W1 = temp;
168 }
169 else
170 {
171 status = kStatus_OTFAD_AddressError;
172 }
173
174 /* Set encryption key */
175 base->CTX[contextIndex].KEY[0] = tempKey[0];
176 base->CTX[contextIndex].KEY[1] = tempKey[1];
177 base->CTX[contextIndex].KEY[2] = tempKey[2];
178 base->CTX[contextIndex].KEY[3] = tempKey[3];
179
180 /* Set encryption counter */
181 base->CTX[contextIndex].CTR[0] = tempCounter[0];
182 base->CTX[contextIndex].CTR[1] = tempCounter[1];
183 }
184 else
185 {
186 /* Restricted register mode, access to these registers is treated as read-as-zero, write-ignored */
187 status = kStatus_OTFAD_ResRegAccessMode;
188 }
189
190 return status;
191 }
192
OTFAD_GetEncryptionConfig(OTFAD_Type * base,otfad_encryption_config_t * config)193 status_t OTFAD_GetEncryptionConfig(OTFAD_Type *base, otfad_encryption_config_t *config)
194 {
195 assert(config != NULL);
196
197 status_t status = kStatus_Success;
198 uint8_t regAccessMode = 0U;
199
200 /* Get restricted register access mode */
201 regAccessMode = (uint8_t)((base->SR & OTFAD_SR_RRAM_MASK) >> OTFAD_SR_RRAM_SHIFT);
202
203 if (regAccessMode == 0U)
204 {
205 config->key[0] = base->CTX[config->contextIndex].KEY[0];
206 config->key[1] = base->CTX[config->contextIndex].KEY[1];
207 config->key[2] = base->CTX[config->contextIndex].KEY[2];
208 config->key[3] = base->CTX[config->contextIndex].KEY[3];
209
210 config->counter[0] = base->CTX[config->contextIndex].CTR[0];
211 config->counter[1] = base->CTX[config->contextIndex].CTR[1];
212
213 config->startAddr =
214 (base->CTX[config->contextIndex].RGD_W0 & OTFAD_RGD_W0_SRTADDR_MASK) >> OTFAD_RGD_W0_SRTADDR_SHIFT;
215 config->endAddr =
216 (base->CTX[config->contextIndex].RGD_W1 & OTFAD_RGD_W1_ENDADDR_MASK) >> OTFAD_RGD_W1_ENDADDR_SHIFT;
217 }
218 else
219 {
220 /* Restricted register mode, access to these registers is treated as read-as-zero, write-ignored */
221 status = kStatus_OTFAD_ResRegAccessMode;
222 }
223
224 return status;
225 }
226
OTFAD_HitDetermination(OTFAD_Type * base,uint32_t address,uint8_t * contextIndex)227 status_t OTFAD_HitDetermination(OTFAD_Type *base, uint32_t address, uint8_t *contextIndex)
228 {
229 status_t status = kStatus_Success;
230 bool contextValid = false;
231 uint8_t hitNumber = 0U;
232 uint8_t totalHits = 0U;
233 uint8_t index = 0U;
234 uint8_t i;
235 uint32_t startAddr;
236 uint32_t endAddr;
237 uint32_t tempAddr;
238
239 /* Address is aligned with 1KBytes */
240 tempAddr = (address & 0xFFFFFC00U) >> 10U;
241
242 for (i = 0U; i < OTFAD_RGD_W1_COUNT; i++)
243 {
244 startAddr = (base->CTX[index].RGD_W0 & OTFAD_RGD_W0_SRTADDR_MASK) >> OTFAD_RGD_W0_SRTADDR_SHIFT;
245 endAddr = (base->CTX[index].RGD_W1 & OTFAD_RGD_W1_ENDADDR_MASK) >> OTFAD_RGD_W1_ENDADDR_SHIFT;
246 contextValid =
247 ((base->CTX[index].RGD_W1 & OTFAD_RGD_W1_VLD_MASK) >> OTFAD_RGD_W1_VLD_SHIFT) == 1U ? true : false;
248
249 /* Check address hits context n or not */
250 if ((tempAddr >= startAddr) && (tempAddr <= endAddr) && contextValid)
251 {
252 totalHits++;
253 hitNumber = i;
254 }
255
256 index++;
257 }
258
259 /* Hit in multiple contexts or no contexts */
260 if (totalHits != 1U)
261 {
262 status = kStatus_OTFAD_RegionOverlap;
263 }
264 /* Hit in single context */
265 else
266 {
267 *contextIndex = hitNumber;
268 }
269
270 return status;
271 }
272