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