blob: becc890c36dc3c70f298bb18d5904eed38aa2f37 [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 }
170 else if((psEfuseInfo->secure_flag >> 8) == ZX297520V3ECOSC_GW_NYC_2G_DDR)
171 {
172 g_ddr_size_flag = CHIP_DDR_IS_256M;
173 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
174 }
175 else
176 {
177 g_ddr_size_flag = CHIP_DDR_IS_128M;
178 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
179 }
180
181 if((psEfuseInfo->secure_flag & 0xFF) != 0xFF)
182 {
183 guiEfuseStatus = 1; //Disable.
184 BOOT_PRINTF(UBOOT_NOTICE, "secure_flag!=0xFF, SecureVerify->Disable.\n");
185 return ;
186 }
187
188 /* step 1*/
189 for(uiLen = 0; uiLen < 4; uiLen++)
190 {
191 if(psEfuseInfo->puk_hash[uiLen] != 0)
192 {
193 break;
194 }
195 if(uiLen == 3)
196 {
197 guiEfuseStatus = 1; //Disable.
198 BOOT_PRINTF(UBOOT_NOTICE, "PubKey_HASH=Invalid, SecureVerify->Disable.\n");
199 return ;
200 }
201 }
202 BOOT_PRINTF(UBOOT_NOTICE, "All Flag & Param is Valid, SecureVerify->ENABLE.\n");
203 guiEfuseStatus = 0; //Enable.
204}
205
206static u8 efuse_cmp_word(u32* src, u32* dst, u32 cnt)
207{
208 u32 i;
209 for(i = 0; i < cnt; i++)
210 {
211 if(src[i] != dst[i])
212 {
213 return 1;
214 }
215 }
216 return 0;
217}
218
219u8 secure_verify(u32 addr)
220{
221 u32 uiLen = 0;
222 u32 uiRet = -1;
223 u32 uiLoop = 0;
224 image_header_t *puiLegacyImgAddr = NULL;
225 sImageHeader *psImageHeader = NULL;
226 u32 *puiDataLoadAddr = NULL;
227 u32 *puiArrPubKeyEN = NULL;
228 u32 *puiArrHASH = NULL;
229
230 efuse_struct *psEfuseInfo = NULL;
231
232 u32 uiHashResArr[4] = {0};
233 u32 uiHashResLen = 0;
234 u32 uiHashVerifySize = 0;
235 u32 uiRsaResArr[32] = {0};
236
237 T_Rsa_Paramter sRSAInput;
238 u32 *puiRsaResAddr = NULL;
239
240 if(NULL == addr)
241 {
242 BOOT_PRINTF(UBOOT_ERR, "Bad Parameter(Empty Pointer)!\n");
243 return -1;
244 }
245
246 psImageHeader = (sImageHeader *)addr;
247 puiLegacyImgAddr = (image_header_t *)(addr + sizeof(sImageHeader));
248 uiHashVerifySize = ___htonl(puiLegacyImgAddr->ih_size) + sizeof(image_header_t);
249
250 psEfuseInfo = (efuse_struct*)EFUSE_RAM_BASE;
251
252 BOOT_PRINTF(UBOOT_NOTICE, "uiHashVerifySize=0x%x, EFUSE_RAM_BASE=0x%x.\n", uiHashVerifySize, EFUSE_RAM_BASE);
253
254 /*
255 * step 0
256 */
257 uiLen = E_N_LEN;
258 puiArrPubKeyEN = psImageHeader->uiPubKeyRsaE;
259
260 Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiArrPubKeyEN, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);
261
262 BOOT_PRINTF(UBOOT_DBG, "secure_flag=0x%x.\n", psEfuseInfo->secure_flag);
263
264 if(efuse_cmp_word(psEfuseInfo->puk_hash, uiHashResArr, uiHashResLen))
265 {
266 BOOT_PRINTF(UBOOT_ERR, "PubKey Hash Verify -> Failed !\n");
267 return 1;
268 }
269 puiArrHASH = psImageHeader->uiHashY;
270
271 /*
272 * step 1
273 */
274 sRSAInput.udCalMode = RSA_MOD_EXPO_WITH_INIT;
275 sRSAInput.udNbitLen = 1024;
276 sRSAInput.udEbitLen = 1024;
277 sRSAInput.pudInputM = puiArrHASH;
278 sRSAInput.pudInputE = puiArrPubKeyEN;
279 sRSAInput.pudInputN = (puiArrPubKeyEN + 32);
280 sRSAInput.pudOutputP = uiRsaResArr;
281
282 uiRet = Rsa_Calculate(sRSAInput);
283 if(uiRet != 0)
284 {
285 BOOT_PRINTF(UBOOT_ERR, "Rsa_Calculate ERROR(0x%x)!\n", uiRet);
286 return 2;
287 }
288 puiRsaResAddr = sRSAInput.pudOutputP + (32 - uiHashResLen);
289
290 /*
291 * step 2
292 */
293 uiLen = uiHashVerifySize;
294 puiDataLoadAddr = ___htonl(puiLegacyImgAddr->ih_load) - sizeof(image_header_t);
295
296 /* Cleanup Output Buffer. */
297 uiHashResLen = 0;
298 memset(uiHashResArr, 0, 4*sizeof(uiHashResArr[0]));
299
300 uiRet = Hash_Calculate(HASH_MODE_MD5, HASH_SMALL_ENDIAN, puiDataLoadAddr, uiLen, NULL, 0, uiHashResArr, &uiHashResLen);
301 if(uiRet != 0)
302 {
303 BOOT_PRINTF(UBOOT_ERR, "Hash_Calculate ERROR(0x%x)!\n", uiRet);
304 return -1;
305 }
306
307 if(efuse_cmp_word(puiRsaResAddr, uiHashResArr, uiHashResLen))
308 {
309 BOOT_PRINTF(UBOOT_ERR, "LegacyImg Verify -> Failed !\n");
310 return 3;
311 }
312
313 return 0;
314}
315
316void efuse_get_devinfo(efuse_struct *efuse_info)
317{
318 u32 i;
319 efuse_struct *s_efuse = (efuse_struct*)EFUSE_RAM_BASE;
320
321 efuse_read_prepare();
322
323 efuse_info->secure_flag = s_efuse->secure_flag;
324
325 for(i = 0; i < 4; i ++)
326 {
327 efuse_info->puk_hash[i] = s_efuse->puk_hash[i];
328 }
329
330 for(i = 0; i < 3; i ++)
331 {
332 efuse_info->dev_id[i] = s_efuse->dev_id[i];
333
334 }
335
336}
337/*******************************************************************************
338* Function: efuse_init
339* Description:
340* Parameters:
341* Input:
342*
343* Output:
344*
345* Returns:
346*
347* Others:
348********************************************************************************/
349int efuse_init(void)
350{
351 /* Init Once is Enough. */
352 if(gbEfuseReadFlag == 0)
353 {
354 efuse_read_prepare();
355 gbEfuseReadFlag = 1;
356 BOOT_PRINTF(UBOOT_DBG, "gbEfuseReadFlag=1.\n");
357 }
358
359 /* Efuse Status decide ENABLE/DISABLE SecureVerify. */
360 efuse_get_data();
361
362 return 0;
363}
364
365