1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "tests_otp.h"
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "cc_pal_types.h"
12 #include "cc_regs.h"
13 #include "cc_otp_defs.h"
14
15 #include "board_configs.h"
16 #include "test_pal_log.h"
17 #include "test_pal_time.h"
18
19 #include "hw_access.h"
20
Test_SetLcsOtpBuff(uint32_t * otpBuf,uint32_t lcsState)21 uint32_t Test_SetLcsOtpBuff(uint32_t *otpBuf, uint32_t lcsState)
22 {
23 //if RMA => set ICV_RMA and OEM_RMA bits
24 //if CM => man_flag[31:0]=0 && oem_flag[7:0] = 0
25 //if DM => oem_flag[7:0] = 0
26 // otherwise SE
27
28 uint32_t hwWord = 0;
29
30 switch (lcsState) {
31 case TESTS_LCS_RMA:
32 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
33 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, ICV_RMA_MODE, hwWord, 1);
34 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, OEM_RMA_MODE, hwWord, 1);
35 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
36 break;
37 case TESTS_LCS_CM:
38 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = 0;
39 /* fall-through */
40 // to clean oem_flag[7:0] bits as for DM
41 case TESTS_LCS_DM:
42 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
43 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, HBK_ZERO_BITS, hwWord, 0);
44 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
45 break;
46
47 case TESTS_LCS_SEC_DISABLED:
48 case TESTS_LCS_SEC_ENABLED:
49 break;
50 default:
51 TEST_PRINTF_ERROR("ERROR: ilegal lcs params\n");
52 return TEST_INVALID_PARAM_ERR;
53 }
54 return TEST_OK;
55 }
56
57
Test_SetNotInUseOtpBuff(uint32_t * otpBuf,uint32_t keyType,uint32_t value)58 uint32_t Test_SetNotInUseOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
59 {
60 uint32_t hwWord;
61
62 switch (keyType){
63 // TBD HBK
64 case TEST_KCP_KEY:
65 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
66 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, value);
67 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
68 break;
69 case TEST_KCE_KEY:
70 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
71 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, value);
72 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
73 break;
74 case TEST_KPICV_KEY:
75 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
76 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, value);
77 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
78 break;
79 case TEST_KCEICV_KEY:
80 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
81 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, value);
82 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
83 break;
84 case TEST_HUK_KEY:
85 default:
86 TEST_PRINTF_ERROR("ERROR: can't set notInUse bit for this type of key\n");
87 return TEST_INVALID_PARAM_ERR;
88
89 }
90 return TEST_OK;
91 }
92
Test_SetZeroBitsOtpBuff(uint32_t * otpBuf,uint32_t keyType,uint32_t value)93 uint32_t Test_SetZeroBitsOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
94 {
95 uint32_t hwWord;
96
97 // TBD HBK??
98 switch (keyType){
99 case TEST_KCP_KEY:
100 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
101 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, value);
102 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
103 break;
104 case TEST_KCE_KEY:
105 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
106 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, value);
107 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
108 break;
109 case TEST_KPICV_KEY:
110 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
111 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, value);
112 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
113 break;
114 case TEST_KCEICV_KEY:
115 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
116 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, value);
117 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
118 break;
119 case TEST_HUK_KEY:
120 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
121 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, HUK_ZERO_BITS, hwWord, value);
122 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
123 break;
124 default:
125 TEST_PRINTF_ERROR("ERROR: can't set notInUse bit for this type of key\n");
126 return TEST_INVALID_PARAM_ERR;
127
128 }
129 return TEST_OK;
130 }
131
Test_SetKeyOtpBuff(uint32_t * otpBuf,uint32_t * keyBuff,uint32_t keyType)132 uint32_t Test_SetKeyOtpBuff(uint32_t *otpBuf, uint32_t *keyBuff, uint32_t keyType)
133 {
134 uint32_t zeroCount = 0;
135 uint32_t keySizeInWords = 0;
136 uint32_t keyOffsetInOtp = 0;
137 uint32_t rc = TEST_OK;
138
139 if ((NULL == otpBuf) || (NULL == keyBuff))
140 {
141 TEST_PRINTF_ERROR("ilegal params\n");
142 return TEST_INVALID_PARAM_ERR;
143 }
144
145 // TBD HBK??
146 switch (keyType)
147 {
148 case TEST_HUK_KEY:
149 keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
150 keyOffsetInOtp = CC_OTP_HUK_OFFSET;
151 break;
152 case TEST_KCP_KEY:
153 keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
154 keyOffsetInOtp = CC_OTP_KCP_OFFSET;
155 break;
156 case TEST_KCE_KEY:
157 keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
158 keyOffsetInOtp = CC_OTP_KCE_OFFSET;
159 break;
160 case TEST_KPICV_KEY:
161 keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
162 keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
163 break;
164 case TEST_KCEICV_KEY:
165 keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
166 keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
167 break;
168 default:
169 TEST_PRINTF_ERROR("ERROR: key type is not supported\n")
170 ;
171 return TEST_INVALID_PARAM_ERR;
172
173 }
174
175 memcpy((uint8_t *) (otpBuf + keyOffsetInOtp), (uint8_t *) keyBuff, keySizeInWords * sizeof(uint32_t));
176
177 TEST_CALC_BUFF_ZEROS(keyBuff, keySizeInWords, zeroCount);
178
179 if (keyType != TEST_HUK_KEY)
180 {
181 rc = Test_SetNotInUseOtpBuff(otpBuf, keyType, 0);
182 }
183
184 rc = rc & Test_SetZeroBitsOtpBuff(otpBuf, keyType, zeroCount);
185
186 return rc;
187 }
188
189 /**
190 * This function gets hw key and its size from otp buffer to user buffer
191 *
192 */
Test_GetKeyOtpBuff(uint32_t * otpBuf,uint32_t keyType,uint32_t * keySizeInWords,uint32_t * keyBuff)193 uint32_t Test_GetKeyOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t *keySizeInWords, uint32_t *keyBuff )
194 {
195 uint32_t keyOffsetInOtp = 0;
196 uint32_t rc = TEST_OK;
197
198 if ((NULL == otpBuf) || (NULL == keyBuff) || (NULL == keySizeInWords)) {
199 TEST_PRINTF_ERROR(" ilegal params\n");
200 return TEST_INVALID_PARAM_ERR;
201 }
202
203 // TBD HBK??
204 switch (keyType){
205 case TEST_HUK_KEY:
206 *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
207 keyOffsetInOtp = CC_OTP_HUK_OFFSET;
208 break;
209 case TEST_KCP_KEY:
210 *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
211 keyOffsetInOtp = CC_OTP_KCP_OFFSET;
212 break;
213 case TEST_KCE_KEY:
214 *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
215 keyOffsetInOtp = CC_OTP_KCE_OFFSET;
216 break;
217 case TEST_KPICV_KEY:
218 *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
219 keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
220 break;
221 case TEST_KCEICV_KEY:
222 *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
223 keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
224 break;
225 default:
226 *keySizeInWords = 0;
227 TEST_PRINTF_ERROR("ERROR: key type is not supported\n");
228 return TEST_INVALID_PARAM_ERR;
229
230 }
231 memcpy((uint8_t *)keyBuff, (uint8_t *)(otpBuf + keyOffsetInOtp), (*keySizeInWords)*sizeof(uint32_t));
232
233 return rc;
234 }
235
236
Test_SetHbkInOtpBuff(uint32_t * otp,uint8_t * hbkBuff,OtpHbkTypes_t type)237 uint32_t Test_SetHbkInOtpBuff(uint32_t *otp, uint8_t *hbkBuff, OtpHbkTypes_t type)
238 {
239 uint32_t i = 0;
240 uint32_t zeroCount = 0;
241 int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK1_OFFSET:CC_OTP_HBK0_OFFSET;
242 int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK0_SIZE_IN_WORDS:0;
243 uint32_t hbkWordSize;
244
245
246 if ((NULL == otp) || (NULL == hbkBuff))
247 {
248 TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
249 return TEST_INVALID_PARAM_ERR;
250 }
251
252 if ((type == TEST_OTP_HBK0_TYPE) || (type == TEST_OTP_HBK1_TYPE))
253 {
254 hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS;
255 }
256 else if ((type == TEST_OTP_HBK_256_TYPE) || (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE)))
257 {
258 hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS + CC_OTP_HBK1_SIZE_IN_WORDS;
259 }
260 else
261 {
262 TEST_PRINTF_ERROR("Illegal type %d\n", type);
263 return TEST_INVALID_PARAM_ERR;
264 }
265
266 //clear OEM HBK and its zero count
267 memset(&otp[CC_OTP_HBK1_OFFSET], 0, CC_OTP_HBK1_SIZE_IN_WORDS);
268 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
269
270 if (type != TEST_OTP_HBK1_TYPE)
271 {
272 //clear ICV HBK zero count and clear HBK0 usage
273 memset(&otp[CC_OTP_HBK0_OFFSET], 0, CC_OTP_HBK0_SIZE_IN_WORDS);
274 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
275
276 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (1U << CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT);
277 }
278
279 for (i = 0; i < hbkWordSize; i++)
280 {
281 TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset + i) * sizeof(uint32_t)], otp[otpStartOffset + i]);
282 }
283
284 if (type & TEST_OTP_HBK0_TYPE)
285 {
286 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK0_OFFSET], CC_OTP_HBK0_SIZE_IN_WORDS, zeroCount);
287 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
288 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount) << CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT;
289 }
290
291 if (type & TEST_OTP_HBK1_TYPE)
292 {
293 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK1_OFFSET], CC_OTP_HBK1_SIZE_IN_WORDS, zeroCount);
294 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
295 otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount) << CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
296 }
297
298 if (type == TEST_OTP_HBK_256_TYPE)
299 {
300 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK_OFFSET], hbkWordSize, zeroCount);
301 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
302 otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount) << CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
303 }
304
305 return TEST_OK;
306 }
307
Test_SetSwVerInOtpBuff(uint32_t * otp,uint32_t offset,uint32_t max_size)308 uint32_t Test_SetSwVerInOtpBuff(uint32_t *otp, uint32_t offset, uint32_t max_size)
309 {
310 uint32_t i;
311
312 for (i=0; i<max_size ; i++)
313 {
314 if (otp[offset + i] < 0xFFFFFFFF)
315 {
316 memset(&otp[offset+i+1], 0x0, (max_size-i-1)* sizeof(uint32_t));
317 break;
318 }
319 }
320
321 return TEST_OK;
322 }
323
324
Test_SetDefaultOtp(uint32_t * otpValues,uint32_t otpSize,uint32_t lcsState)325 void Test_SetDefaultOtp(uint32_t* otpValues, uint32_t otpSize, uint32_t lcsState)
326 {
327
328 uint32_t huk[] = {0xCAFE1111, 0xCAFE1222, 0xCAFE1333, 0xCAFE1444, 0xCAFE1555, 0xCAFE1666, 0xCAFE1777, 0xCAFE1888};
329 uint32_t kpicv[] = {0xCAFE2111, 0xCAFE2222, 0xCAFE2333, 0xCAFE2444};
330 uint32_t kceicv[] = {0xCAFE3111, 0xCAFE3222, 0xCAFE3333, 0xCAFE3444};
331 uint32_t kcp[] = {0xCAFE4111, 0xCAFE4222, 0xCAFE4333, 0xCAFE4444};
332 uint32_t kce[] = {0xCAFE5111, 0xCAFE5222, 0xCAFE5333, 0xCAFE5444};
333 uint32_t hbk[] = {0xCAFE6111, 0xCAFE6222, 0xCAFE6333, 0xCAFE6444, 0xCAFE6555, 0xCAFE6666, 0xCAFE6777, 0xCAFE6888};
334
335 memset(otpValues, 0, otpSize);
336
337 Test_SetHbkInOtpBuff (otpValues, (unsigned char*)hbk, TEST_OTP_HBK_256_TYPE);
338
339 Test_SetKeyOtpBuff (otpValues, huk, TEST_HUK_KEY);
340
341 Test_SetKeyOtpBuff (otpValues, kcp, TEST_KCP_KEY);
342
343 Test_SetKeyOtpBuff (otpValues, kce, TEST_KCE_KEY);
344
345 Test_SetKeyOtpBuff (otpValues, kceicv, TEST_KCEICV_KEY);
346
347 Test_SetKeyOtpBuff (otpValues, kpicv, TEST_KPICV_KEY);
348
349 Test_SetLcsOtpBuff (otpValues, lcsState);
350 }
351
352
Test_BurnOtp(uint32_t * otpBuf,uint32_t nextLcs)353 uint32_t Test_BurnOtp(uint32_t *otpBuf, uint32_t nextLcs)
354 {
355
356 CCError_t error = 0;
357 uint32_t i = 0;
358
359 /* Clean OTP */
360 for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
361 WRITE_OTP(i, 0);
362 Test_PalDelay(1000);
363 }
364
365 /* Perform SW reset to reach CM LCS */
366 Test_HalPerformPowerOnReset();
367 Test_PalDelay(1000);
368
369 /* Copy new OTP buffer */
370 for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
371 // TEST_PRINTF("writing Otp [0x%X] 0x%X\n", i, otpBuf[i]);
372 WRITE_OTP(i, otpBuf[i]);
373 Test_PalDelay(1000);
374 }
375
376 /* Perform SW reset after writing to OTP new values */
377 Test_HalPerformPowerOnReset();
378
379 /* verify LCS */
380 error = Test_HalCheckLcs(nextLcs);
381 if (error == 0) {
382 TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
383 } else {
384 TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
385 }
386
387 return error;
388 }
389
390 /**
391 * This function burns otp image through "back door", performs reset, and check if system booted to required lcs
392 *
393 */
Test_GetKeySizeInWordsOtp(uint32_t keyType,uint32_t * keySizeInWords)394 uint32_t Test_GetKeySizeInWordsOtp(uint32_t keyType, uint32_t* keySizeInWords)
395 {
396 // TBD HBK??
397 switch (keyType){
398 case TEST_HUK_KEY:
399 *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
400 break;
401 case TEST_KCP_KEY:
402 *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
403 break;
404 case TEST_KCE_KEY:
405 *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
406 break;
407 case TEST_KPICV_KEY:
408 *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
409 break;
410 case TEST_KCEICV_KEY:
411 *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
412 break;
413 default:
414 *keySizeInWords = 0;
415 TEST_PRINTF_ERROR("ERROR: key type %d is not supported\n", keyType);
416 return TEST_INVALID_PARAM_ERR;
417
418 }
419 return 0;
420 }
421