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