blob: 46bc30384e2df0c31eaff181e23b13c739564e5b [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/*******************************************************************************
2 * Copyright (C) 2016, ZXIC Corporation.
3 *
4 * File Name:
5 * File Mark:
6 * Description:
7 * Others:
8 * Version: 1.0
9 * Author: zxic
10 * Date: 2016.12.15
11 * modify
12 ********************************************************************************/
13
14/****************************************************************************
15* Include files
16****************************************************************************/
17#include <malloc.h>
18#include <errno.h>
19#include <asm/io.h>
20#include <linux/mtd/mtd.h>
21#include <asm-generic/ioctl.h>
22#include <config.h>
23#include <common.h>
24#include <command.h>
25
26#include <../drivers/hash/drv_hash.h>
27#include <../drivers/rsa/drv_rsa.h>
28#include <secure_verify.h>
29#include <asm/arch/efuse.h>
30
31
32
33/****************************************************************************
34* Local Macros
35****************************************************************************/
36#define E_N_LEN 256
37#define HASH_LEN 128
38#define reg32(addr) (*(volatile unsigned long *)(addr))
39
40/****************************************************************************
41* Local Types
42****************************************************************************/
43
44
45/****************************************************************************
46* Global Value
47****************************************************************************/
48/* Disable Secure Verify as Default. */
49unsigned int guiEfuseStatus = 1;
50unsigned char g_ddr_size_flag = 0;
51
52static unsigned char gbEfuseReadFlag = 0;
53
54/****************************************************************************
55* Local Funcs
56****************************************************************************/
57
58static void efuse_read_prepare(void)
59{
60 //start read efuse all 256bit
61 while((reg32(SYS_EFUSE_BASE + 0x4) & 1) == 1);// bit0=1 ctl is busy
62 reg32(SYS_EFUSE_BASE + 0x4) = 1;
63 while((reg32(SYS_EFUSE_BASE + 0x14) & 2) == 0);//bit1=0 read not over
64}
65
66static void efuse_program_32bit(u32 bit_offset, u32 data)
67{
68 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
69 reg32(SYS_EFUSE_BASE+0x8) = bit_offset;
70 reg32(SYS_EFUSE_BASE+0xc) = data;
71 reg32(SYS_EFUSE_BASE+0x4) = (0<<4)|(2<<1)|1;//cs0 program 32bit
72 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
73 reg32(SYS_EFUSE_BASE+0x4) = (1<<4)|(2<<1)|1;//cs1 program 32bit
74}
75
76void efuse_program_secure_en(u32 en)
77{
78 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
79 reg32(SYS_EFUSE_BASE+0x8) = 0; //bit[7:0] secure_boot_en
80 if(en)
81 reg32(SYS_EFUSE_BASE+0xc) = 0xFF;
82 reg32(SYS_EFUSE_BASE+0x4) = (0<<4)|(2<<1)|1;//cs0 program 32bit
83 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
84 reg32(SYS_EFUSE_BASE+0x4) = (1<<4)|(2<<1)|1;//cs1 program 32bit
85}
86
87void efuse_program_chip_flag(u32 flag)
88{
89 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
90 reg32(SYS_EFUSE_BASE+0x8) = 0; //bit[31:8] secure_chip_flag
91
92 if(flag&0xFF != 0)
93 reg32(SYS_EFUSE_BASE+0xc) = 0;
94 else
95 reg32(SYS_EFUSE_BASE+0xc) = flag;
96
97 reg32(SYS_EFUSE_BASE+0x4) = (0<<4)|(2<<1)|1;//cs0 program 32bit
98 while((reg32(SYS_EFUSE_BASE+0x4)&1)==1);// bit0=1 ctl is busy
99 reg32(SYS_EFUSE_BASE+0x4) = (1<<4)|(2<<1)|1;//cs1 program 32bit
100}
101
102void efuse_program_puk_hash(u32 *key)
103{
104 efuse_program_32bit(32, key[0]);
105 efuse_program_32bit(64, key[1]);
106 efuse_program_32bit(96, key[2]);
107 efuse_program_32bit(128, key[3]);
108}
109#if 0
110/**-------------------------------------------------------------------------------------------------------------------@n
111 * º¯ÊýÃû³Æ: chip_is_spe
112 * ¹¦ÄÜÃèÊö: ÓÃÓÚÅжÏоƬÊÇ·ñÎª×¨ÍøÐ¾Æ¬
113 * ·µ »Ø Öµ: 0,¹«ÍøÐ¾Æ¬ 1,×¨ÍøÐ¾Æ¬
114 *--------------------------------------------------------------------------------------------------------------------*/
115u32 chip_is_spe(void)
116{
117 u8 tmp_chip_flag[3] = {0x53, 0x50, 0x45}; /*SPE*/
118 u32 efuse_tmp_buf[5] = {0};
119 efuse_struct *psEfuseInfo = NULL;
120
121 psEfuseInfo = (efuse_struct *)efuse_tmp_buf;
122 memcpy(psEfuseInfo, EFUSE_RAM_BASE, sizeof(efuse_struct));
123
124 if(memcmp(psEfuseInfo->chip_flag,tmp_chip_flag,3))
125 /*chip com*/
126 return 0;
127
128 /*chip spe*/
129 return 1;
130}
131#endif
132static void efuse_get_data(void)
133{
134 efuse_struct *psEfuseInfo = NULL;
135 u32 uiLen = 0;
136
137 /* Secure Verify. 1->Disable, 0->Enable. */
138 if((reg32(EFUSE_BYPASS) & 1) == 1)
139 {
140 guiEfuseStatus = 1; //Disable.
141 BOOT_PRINTF(UBOOT_NOTICE, "EFUSE_BYPASS=1, SecureVerify->Disable.\n");
142 return ;
143 }
144
145 /* step 0*/
146 psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
147
148 /* get chip flag */
149 if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_WINBD_256M_DDR)
150 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_WINBD_256M_DDR)
151 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_UNILC_256M_DDR)
152 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_UNILC_256M_DDR)
153 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_APM_256M_DDR)
154 || ((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_APM_256M_DDR))
155 {
156 g_ddr_size_flag = CHIP_DDR_IS_32M;
157 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
158 }
159 else if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_UNILC_512M_DDR)
160 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_APM_512M_DDR)
161 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_GW_ESMT_512M_DDR)
162 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_UNILC_512M_DDR)
163 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_AZW_UNILC_512M_DDR)
164 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_APM_512M_DDR)
165 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECO_ZW_ESMT_512M_DDR))
166 {
167 g_ddr_size_flag = CHIP_DDR_IS_64M;
168 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
169 }
lh758261d2023-07-13 05:52:04 -0700170 else if(((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_2G_DDR)
171 ||((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOGG_GW_NYC_2G_DDR))
lh9ed821d2023-04-07 01:36:19 -0700172 {
173 g_ddr_size_flag = CHIP_DDR_IS_256M;
174 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
175 }
176 else
177 {
178 g_ddr_size_flag = CHIP_DDR_IS_128M;
179 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
180 }
181
182 if((psEfuseInfo->secure_flag & 0xFF) != 0xFF)
183 {
184 guiEfuseStatus = 1; //Disable.
185 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag!=0xFF, SecureVerify->Disable.\n");
186 return ;
187 }
188
189 /* step 1*/
190 for(uiLen = 0; uiLen < 4; uiLen++)
191 {
192 if(psEfuseInfo->puk_hash[uiLen] != 0)
193 {
194 break;
195 }
196 if(uiLen == 3)
197 {
198 guiEfuseStatus = 1; //Disable.
199 BOOT_PRINTF(UBOOT_NOTICE, "PubKey_HASH=Invalid, SecureVerify->Disable.\n");
200 return ;
201 }
202 }
203 BOOT_PRINTF(UBOOT_NOTICE, "All Flag & Param is Valid, SecureVerify->ENABLE.\n");
204 guiEfuseStatus = 0; //Enable.
205}
206
207static u8 efuse_cmp_word(u32* src, u32* dst, u32 cnt)
208{
209 u32 i;
210 for(i = 0; i < cnt; i++)
211 {
212 if(src[i] != dst[i])
213 {
214 return 1;
215 }
216 }
217 return 0;
218}
219
220u8 secure_verify(u32 addr)
221{
222 u32 uiLen = 0;
223 u32 uiRet = -1;
224 u32 uiLoop = 0;
225 image_header_t *puiLegacyImgAddr = NULL;
226 sImageHeader *psImageHeader = NULL;
227 u32 *puiDataLoadAddr = NULL;
228 u32 *puiArrPubKeyEN = NULL;
229 u32 *puiArrHASH = NULL;
230
231 efuse_struct *psEfuseInfo = NULL;
232
233 u32 uiHashResArr[4] = {0};
234 u32 uiHashResLen = 0;
235 u32 uiHashVerifySize = 0;
236 u32 uiRsaResArr[32] = {0};
237
238 T_Rsa_Paramter sRSAInput;
239 u32 *puiRsaResAddr = NULL;
240
241 if(NULL == addr)
242 {
243 BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");
244 return -1;
245 }
246
247 psImageHeader = (sImageHeader *)addr;
248 puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageHeader));
249 uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);
250
251 psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
252
253 BOOT_PRINTF(UBOOT_NOTICE, "uiHashVerifySize=0x%x, EFUSE_RAM_BASE=0x%x.\n", uiHashVerifySize, EFUSE_RAM_BASE);
254
255 /*
256 * step 0
257 */
258 uiLen = E_N_LEN;
259 puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;
260
261 Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiArrPubKeyEN, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);
262
263 BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
264
265 if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))
266 {
267 BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");
268 return 1;
269 }
270 puiArrHASH = psImageHeader->uiHashY;
271
272 /*
273 * step 1
274 */
275 sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
276 sRSAInput.udNbitLen = 1024;
277 sRSAInput.udEbitLen = 1024;
278 sRSAInput.pudInputM = puiArrHASH;
279 sRSAInput.pudInputE = puiArrPubKeyEN;
280 sRSAInput.pudInputN = (puiArrPubKeyEN + 32);
281 sRSAInput.pudOutputP = uiRsaResArr;
282
283 uiRet = Rsa_Calculate(sRSAInput);
284 if(uiRet != 0)
285 {
286 BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);
287 return 2;
288 }
289 puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);
290
291 /*
292 * step 2
293 */
294 uiLen = uiHashVerifySize;
295 puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t);
296
297 /* Cleanup Output Buffer. */
298 uiHashResLen = 0;
299 memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));
300
301 uiRet = Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiDataLoadAddr, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);
302 if(uiRet != 0)
303 {
304 BOOT_PRINTF(UBOOT_ERR, "Hash_Calculate ERROR(0x%x)!\n", uiRet);
305 return -1;
306 }
307
308 if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))
309 {
310 BOOT_PRINTF(UBOOT_ERR, "LegacyImg Verify -> Failed !\n");
311 return 3;
312 }
313
314 return 0;
315}
316
317void efuse_get_devinfo(efuse_struct *efuse_info)
318{
319 u32 i;
320 efuse_struct *s_efuse = (efuse_struct*)EFUSE_RAM_BASE;
321
322 efuse_read_prepare();
323
324 efuse_info->secure_flag = s_efuse->secure_flag;
325
326 for(i = 0; i < 4; i ++)
327 {
328 efuse_info->puk_hash[i] = s_efuse->puk_hash[i];
329 }
330
331 for(i = 0; i < 3; i ++)
332 {
333 efuse_info->dev_id[i] = s_efuse->dev_id[i];
334
335 }
336
337}
338/*******************************************************************************
339* Function: efuse_init
340* Description:
341* Parameters:
342* Input:
343*
344* Output:
345*
346* Returns:
347*
348* Others:
349********************************************************************************/
350int efuse_init(void)
351{
352 /* Init Once is Enough. */
353 if(gbEfuseReadFlag == 0)
354 {
355 efuse_read_prepare();
356 gbEfuseReadFlag = 1;
357 BOOT_PRINTF(UBOOT_DBG, "gbEfuseReadFlag=1.\n");
358 }
359
360 /* Efuse Status decide ENABLE/DISABLE SecureVerify. */
361 efuse_get_data();
362
363 return 0;
364}
365
366