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 <stdint.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdbool.h>
11 #include <unistd.h>
12 #include <sys/mman.h>
13 #include <fcntl.h>
14 #include <string.h>
15 #include "cc_pal_types.h"
16 #include "dx_env.h"
17 #include "dx_nvm.h"
18 #include "cc_regs.h"
19 #include "dx_host.h"
20 #include "tests_hw_access_iot.h"
21 #include "tests_phys_map.h"
22 #include "test_log.h"
23 #include "dx_crys_kernel.h"
24 #include "cc_otp_defs.h"
25
26
27
28 /******************************/
29 /* function definitions */
30 /*****************************/
31
testCheckLcs(unsigned int nextLcs)32 unsigned int testCheckLcs(unsigned int nextLcs)
33 {
34 unsigned int regVal = 0;
35
36 /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
37 WAIT_NVM_IDLE(regVal);
38
39 /* Read the LCS register */
40 regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
41 regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
42
43 /* Verify lcs */
44 if(regVal != nextLcs) {
45 TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
46 return -1;
47 }
48
49 return 0;
50 }
51
52
testCheckLcsAndError(unsigned int nextLcs)53 unsigned int testCheckLcsAndError(unsigned int nextLcs)
54 {
55 unsigned int regVal = 0;
56
57 /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
58 WAIT_NVM_IDLE(regVal);
59
60 /* Read the LCS register */
61 regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
62 regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
63
64 /* Verify lcs */
65 if(regVal != nextLcs) {
66 TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
67 return -1;
68 }
69
70 if ((CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal) != 0) ||
71 (CC_REG_FLD_GET(0, LCS_REG, ERROR_KPICV_ZERO_CNT, regVal) != 0) ||
72 (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCEICV_ZERO_CNT, regVal) != 0) ||
73 (CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal) != 0) ||
74 (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCE_ZERO_CNT, regVal) != 0)) {
75 TEST_PRINTF_ERROR("regVal 0x%x indicates error for LCS %d", regVal, nextLcs);
76 return -1;
77 }
78
79 return 0;
80 }
81
82
testGetLcs(unsigned int * lcs)83 unsigned int testGetLcs(unsigned int *lcs)
84 {
85 unsigned int regVal = 0;
86
87 /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
88 WAIT_NVM_IDLE(regVal);
89
90 /* Read the LCS register */
91 regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
92 regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
93
94 *lcs = regVal;
95
96 return 0;
97 }
98
99
testGetOtpSize(unsigned int * size)100 unsigned int testGetOtpSize(unsigned int * size)
101 {
102 unsigned int regVal = 0;
103
104 /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
105 WAIT_NVM_IDLE(regVal);
106
107 /* Read the LCS register */
108 regVal = READ_REG(DX_OTP_ADDR_WIDTH_DEF_REG_OFFSET);
109 regVal = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, regVal);
110
111 *size = regVal;
112
113 return 0;
114 }
115
116
117 /* Global Reset of CC and AO and env regs */
performPowerOnReset(void)118 void performPowerOnReset(void)
119 {
120 WRITE_ENV(DX_ENV_CC_POR_N_ADDR_REG_OFFSET , 0x1UL);
121 usleep(1000);
122
123 /* poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid) */
124 WAIT_NVM_IDLE(regVal);
125
126 #ifdef BIG__ENDIAN
127 /* Set DMA endianess to big */
128 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
129 #else /* LITTLE__ENDIAN */
130 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
131 #endif
132
133 /* turn off the DFA since Cerberus doesn't support it */
134 TURN_DFA_OFF();
135 return;
136
137 }
138
139
140 /* Reset both CC and AO regs */
performColdReset(void)141 void performColdReset(void)
142 {
143 WRITE_ENV(DX_ENV_CC_COLD_RST_REG_OFFSET , 0x1UL);
144 usleep(1000);
145
146 #ifdef BIG__ENDIAN
147 /* Set DMA endianess to big */
148 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
149 #else /* LITTLE__ENDIAN */
150 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
151 #endif
152 /* turn off the DFA since Cerberus doesn't support it */
153 TURN_DFA_OFF();
154 return;
155 }
156
157
158 /* Reset only CC regs */
performWarmReset(void)159 void performWarmReset(void)
160 {
161 WRITE_ENV(DX_ENV_CC_RST_N_REG_OFFSET , 0x1UL);
162 usleep(1000);
163
164 #ifdef BIG__ENDIAN
165 /* Set DMA endianess to big */
166 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
167 #else /* LITTLE__ENDIAN */
168 WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
169 #endif
170 return;
171
172 }
173
testBurnOtp(unsigned int * otpBuf,unsigned int nextLcs)174 unsigned int testBurnOtp(unsigned int *otpBuf, unsigned int nextLcs)
175 {
176
177 CCError_t error = 0;
178 unsigned int i = 0;
179
180 /* Clean OTP */
181 for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
182 WRITE_OTP(i, 0);
183 usleep(1000);
184 }
185
186 /* Perform SW reset to reach CM LCS */
187 performPowerOnReset();
188 usleep(1000);
189
190 /* Copy new OTP buffer */
191 for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
192 TEST_PRINTF("writing Otp [0x%X] 0x%X", i, otpBuf[i]);
193 WRITE_OTP(i, otpBuf[i]);
194 usleep(1000);
195 }
196
197 /* Perform SW reset after writing to OTP new values */
198 performPowerOnReset();
199
200 /* verify LCS */
201 error = testCheckLcs(nextLcs);
202 if (error == 0) {
203 TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
204 } else {
205 TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
206 }
207
208 return error;
209 }
210
211
initPlatform(void)212 uint32_t initPlatform(void)
213 {
214 unsigned int rc = 0;
215
216 rc = TestMapCCRegs();
217 if (rc != 0) {
218 TEST_PRINTF_ERROR("Failed to TestMapCCRegs");
219 return rc;
220 }
221
222 TST_SET_ENV_TO_SECURE();
223
224 return 0;
225 }
226
freePlatform(void)227 void freePlatform(void)
228 {
229 TestUnmapCCRegs();
230 }
231
232
233 /*
234 * @brief This function
235 *
236 * @param[in]
237 *
238 * @param[out]
239 *
240 * @return void -
241
242 */
testSetKdrInOtpBuff(unsigned int * otp,unsigned char * kdrBuff)243 unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff)
244 {
245 int i = 0;
246 int zeroCount = 0;
247 int kdrZeroSize = ((0x1 << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SIZE)-1);
248 int kdrZeroMask = (kdrZeroSize << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT);
249
250 if ((NULL == otp) ||
251 (NULL == kdrBuff)) {
252 TEST_PRINTF_ERROR(" ilegal params\n");
253 return TEST_INVALID_PARAM_ERR;
254 }
255 for (i=0; i< CC_OTP_HUK_SIZE_IN_WORDS; i++) {
256 TEST_CONVERT_BYTE_ARR_TO_WORD(&kdrBuff[i*sizeof(uint32_t)], otp[CC_OTP_START_OFFSET+i])
257 }
258
259 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_START_OFFSET], CC_OTP_HUK_SIZE_IN_WORDS, zeroCount);
260 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(kdrZeroMask);
261 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT;
262 return TEST_OK;
263
264 }
265
266
267 /*
268 * @brief This function
269 *
270 * @param[in]
271 *
272 * @param[out]
273 *
274 * @return void -
275
276 */
testSetHbkInOtpBuff(unsigned int * otp,unsigned char * hbkBuff,OtpHbkTypes_t type)277 unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type)
278 {
279 int i = 0;
280 int zeroCount = 0;
281 int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK1_OFFSET:CC_OTP_HBK0_OFFSET;
282 int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK0_SIZE_IN_WORDS:0;
283 int hbkWordSize;
284
285
286 if ((NULL == otp) ||
287 (NULL == hbkBuff)) {
288 TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
289 return TEST_INVALID_PARAM_ERR;
290 }
291 TEST_PRINTF_ERROR("type %d\n", type);
292 if ((type == TEST_OTP_HBK0_TYPE) ||
293 (type == TEST_OTP_HBK1_TYPE)) {
294 hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS;
295 } else if ((type == TEST_OTP_HBK_256_TYPE) ||
296 (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE))) {
297 hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS+CC_OTP_HBK1_SIZE_IN_WORDS;
298 } else {
299 TEST_PRINTF_ERROR("ilegal type %d\n", type);
300 return TEST_INVALID_PARAM_ERR;
301 }
302 //clear OEM HBK and its zero count
303 memset(&otp[CC_OTP_HBK1_OFFSET], 0, CC_OTP_HBK1_SIZE_IN_WORDS);
304 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
305 //clear ICV HBK
306 memset(&otp[CC_OTP_HBK0_OFFSET], 0, CC_OTP_HBK0_SIZE_IN_WORDS);
307 //clear ICV HBK zero count
308 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
309 // clear HBK0 usage
310 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (1<<CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT);
311 TEST_PRINTF_ERROR("writing hbk otpStartOffset %d, hbkWordSize %d\n", otpStartOffset, hbkWordSize);
312 for (i=0; i< hbkWordSize; i++) {
313 TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset+i)*sizeof(uint32_t)], otp[otpStartOffset+i]);
314 }
315
316 if (type & TEST_OTP_HBK0_TYPE) {
317 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK0_OFFSET], CC_OTP_HBK0_SIZE_IN_WORDS, zeroCount);
318 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
319 otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT;
320 TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
321 }
322 if (type & TEST_OTP_HBK1_TYPE) {
323 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK1_OFFSET], CC_OTP_HBK1_SIZE_IN_WORDS, zeroCount);
324 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
325 otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
326 TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
327 }
328 if (type == TEST_OTP_HBK_256_TYPE) {
329 TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK_OFFSET], hbkWordSize, zeroCount);
330 otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
331 otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
332 TEST_PRINTF_ERROR("zeros for HBK0 %d\n", zeroCount);
333 }
334 TEST_PRINTF_ERROR("otp[0x%lx] 0x%x, otp[0x%lx] 0x%x\n", CC_OTP_OEM_FLAG_OFFSET,
335 otp[CC_OTP_OEM_FLAG_OFFSET], CC_OTP_MANUFACTURE_FLAG_OFFSET, otp[CC_OTP_MANUFACTURE_FLAG_OFFSET]);
336
337 return TEST_OK;
338 }
339
340 /*
341 * @brief This function
342 *
343 * @param[in]
344 *
345 * @param[out]
346 *
347 * @return void -
348
349 */
testSetKpicvInOtpBuff(unsigned int * otpBuf,unsigned int * kpicvBuff)350 unsigned int testSetKpicvInOtpBuff(unsigned int *otpBuf, unsigned int *kpicvBuff)
351 {
352 int zeroCount = 0;
353 uint32_t hwWord = 0;
354
355 if ((NULL == otpBuf) ||
356 (NULL == kpicvBuff)) {
357 TEST_PRINTF_ERROR(" ilegal params\n");
358 return TEST_INVALID_PARAM_ERR;
359 }
360 memcpy((uint8_t *)(otpBuf+CC_OTP_KPICV_OFFSET), (uint8_t *)kpicvBuff, CC_OTP_KPICV_SIZE_IN_WORDS*sizeof(uint32_t));
361
362 TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KPICV_OFFSET], CC_OTP_KPICV_SIZE_IN_WORDS, zeroCount);
363 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
364 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, zeroCount);
365 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, 0);
366 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
367 return TEST_OK;
368 }
369 /*
370 * @brief This function
371 *
372 * @param[in]
373 *
374 * @param[out]
375 *
376 * @return void -
377
378 */
testSetKceicvOtpBuff(unsigned int * otpBuf,unsigned int * kceicvBuff)379 unsigned int testSetKceicvOtpBuff(unsigned int *otpBuf, unsigned int *kceicvBuff)
380 {
381 int zeroCount = 0;
382 uint32_t hwWord = 0;
383
384 if ((NULL == otpBuf) ||
385 (NULL == kceicvBuff)) {
386 TEST_PRINTF_ERROR(" ilegal params\n");
387 return TEST_INVALID_PARAM_ERR;
388 }
389 memcpy((uint8_t *)(otpBuf+CC_OTP_KCEICV_OFFSET), (uint8_t *)kceicvBuff, CC_OTP_KCEICV_SIZE_IN_WORDS*sizeof(uint32_t));
390
391 TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCEICV_OFFSET], CC_OTP_KCEICV_SIZE_IN_WORDS, zeroCount);
392 hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
393 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, zeroCount);
394 CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, 0);
395 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
396 return TEST_OK;
397 }
398
399 /*
400 * @brief This function
401 *
402 * @param[in]
403 *
404 * @param[out]
405 *
406 * @return void -
407
408 */
testSetKcpOtpBuff(unsigned int * otpBuf,unsigned int * kcpBuff)409 unsigned int testSetKcpOtpBuff(unsigned int *otpBuf, unsigned int *kcpBuff)
410 {
411 int zeroCount = 0;
412 uint32_t hwWord = 0;
413
414 if ((NULL == otpBuf) ||
415 (NULL == kcpBuff)) {
416 TEST_PRINTF_ERROR(" ilegal params\n");
417 return TEST_INVALID_PARAM_ERR;
418 }
419 memcpy((uint8_t *)(otpBuf+CC_OTP_KCP_OFFSET), (uint8_t *)kcpBuff, CC_OTP_KCP_SIZE_IN_WORDS*sizeof(uint32_t));
420
421 TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCP_OFFSET], CC_OTP_KCP_SIZE_IN_WORDS, zeroCount);
422 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
423 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, zeroCount);
424 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, 0);
425 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
426 return TEST_OK;
427 }
428
429 /*
430 * @brief This function
431 *
432 * @param[in]
433 *
434 * @param[out]
435 *
436 * @return void -
437
438 */
testSetKceOtpBuff(unsigned int * otpBuf,unsigned int * kceBuff)439 unsigned int testSetKceOtpBuff(unsigned int *otpBuf, unsigned int *kceBuff)
440 {
441 int zeroCount = 0;
442 uint32_t hwWord = 0;
443
444 if ((NULL == otpBuf) ||
445 (NULL == kceBuff)) {
446 TEST_PRINTF_ERROR(" ilegal params\n");
447 return TEST_INVALID_PARAM_ERR;
448 }
449 memcpy((uint8_t *)(otpBuf+CC_OTP_KCE_OFFSET), (uint8_t *)kceBuff, CC_OTP_KCE_SIZE_IN_WORDS*sizeof(uint32_t));
450
451 TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCE_OFFSET], CC_OTP_KCE_SIZE_IN_WORDS, zeroCount);
452 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
453 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, zeroCount);
454 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, 0);
455 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
456 return TEST_OK;
457 }
458
459 /*
460 * @brief This function suggegst that all keys are already set, and set manufacture and oem flags appropriately
461 *
462 * @param[in]
463 *
464 * @param[out]
465 *
466 * @return void -
467
468 */
testSetLcsOtpBuff(unsigned int * otpBuf,unsigned int lcsState)469 unsigned int testSetLcsOtpBuff(unsigned int *otpBuf, unsigned int lcsState)
470 {
471 //if RMA => set ICV_RMA and OEM_RMA bits
472 //if CM => man_flag[31:0]=0 && oem_flag[7:0] = 0
473 //if DM => oem_flag[7:0] = 0
474 // otherwise SE
475
476 uint32_t hwWord = 0;
477
478 switch (lcsState) {
479 case TESTS_LCS_RMA:
480 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
481 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, ICV_RMA_MODE, hwWord, 1);
482 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, OEM_RMA_MODE, hwWord, 1);
483 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
484 break;
485 case TESTS_LCS_CM:
486 otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = 0;
487 // continue to clean oem_flag[7:0] bits as for DM
488 case TESTS_LCS_DM:
489 hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
490 CC_REG_FLD_SET2(0, OTP_OEM_FLAG, HBK_ZERO_BITS, hwWord, 0);
491 otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
492 break;
493
494 case TESTS_LCS_SEC_DISABLED:
495 case TESTS_LCS_SEC_ENABLED:
496 break;
497 default:
498 TEST_PRINTF_ERROR(" ilegal lcs params\n");
499 return TEST_INVALID_PARAM_ERR;
500 }
501 return TEST_OK;
502 }
503