3 #include <asm/arch/sci_types.h>
4 #include "secure_verify.h"
6 #ifdef CONFIG_EMMC_BOOT
11 #define SHA1_SUM_LEN 20
13 LOCAL __inline char *_w2c(wchar_t * wchar)
15 static char buf[73] = { 0 };
17 while ((NULL != wchar[i]) && (i < 72)) {
18 buf[i] = wchar[i] & 0xFF;
27 void hexdump(const char *title, const unsigned char *s, int l)
42 unsigned char sec_header[SEC_HEADER_MAX_SIZE];
44 int secure_header_parser(uint8_t * header_addr)
46 if (strcmp(header_addr, HEADER_NAME) == 0)
52 int get_code_addr(wchar_t * name, uint8_t * header_addr)
56 header_info_t *header_p = (header_info_t *) header_addr;
58 printf("%s, name: %s enter\r\n", __FUNCTION__, _w2c(name));
59 if (name && wcscmp(L"splloader0", name) == 0) {
60 #ifdef CONFIG_ROM_VERIFY_SPL
61 addr = header_addr + CONFIG_BOOTINFO_LENGTH * 2;
63 addr = header_addr + CONFIG_SPL_HASH_LEN;
68 for (i = 0; i < header_p->tags_number; i++) {
69 if (header_p->tag[i].tag_name == CODE_NAME) {
70 addr = header_addr + (header_p->tag[i].tag_offset) * MIN_UNIT;
74 #ifdef CONFIG_ROM_VERIFY_SPL
75 if (wcscmp(L"splloader", name) == 0) {
76 addr -= CONFIG_BOOTINFO_LENGTH;
82 uint32_t get_code_offset(uint8_t * header_addr)
85 header_info_t *header_p = (header_info_t *) header_addr;
87 for (i = 0; i < header_p->tags_number; i++) {
88 if (header_p->tag[i].tag_name == CODE_NAME) {
89 return header_p->tag[i].tag_offset;
95 int get_vlr_addr(wchar_t * name, uint8_t * header_addr)
99 header_info_t *header_p = (header_info_t *) header_addr;
101 printf("%s, name: %s enter\r\n", __FUNCTION__, _w2c(name));
103 if (wcscmp(L"splloader0", name) == 0) {
104 addr = header_addr + CONFIG_SPL_LOAD_LEN - VLR_INFO_SIZ;
109 for (i = 0; i < header_p->tags_number; i++) {
110 if (header_p->tag[i].tag_name == VLR_NAME) {
111 addr = header_addr + (header_p->tag[i].tag_offset) * MIN_UNIT;
118 int get_puk_addr(wchar_t * name, uint8_t * header_addr)
123 header_info_t *header_p = (header_info_t *) header_addr;
125 printf("%s, name: %s enter\r\n", __FUNCTION__, _w2c(name));
127 if (wcscmp(L"splloader0", name) == 0) {
128 #ifdef CONFIG_ROM_VERIFY_SPL
129 addr = header_addr + CONFIG_BOOTINFO_LENGTH;
131 addr = header_addr + CONFIG_SPL_HASH_LEN - KEY_INFO_SIZ;
134 } else if (wcscmp(L"splloader", name) == 0) {
135 size = SEC_HEADER_MAX_SIZE;
136 #ifdef CONFIG_EMMC_BOOT
137 if (TRUE != Emmc_Read(1 /* PARTITION_BOOT1 */ , PUBKEY_BSC_BLOCK_INDEX,
138 PUBKEY_READ_BLOCK_NUMS, (uint8 *) sec_header)) {
139 printf("PARTITION_BOOT1 read error \n");
143 if (nand_read_skip_bad(&nand_info[0], 0, &size, (uint8 *) sec_header) != 0) {
144 printf("PARTITION_BOOT1 read error \n");
148 #ifdef CONFIG_ROM_VERIFY_SPL
151 addr = sec_header + CONFIG_SPL_HASH_LEN - KEY_INFO_SIZ;
154 } else if (wcscmp(L"uboot", name) == 0) {
155 size = SEC_HEADER_MAX_SIZE;
156 #ifdef CONFIG_EMMC_BOOT
157 if (TRUE != Emmc_Read(2 /* PARTITION_BOOT2 */ , PUBKEY_VLR_BLOCK_INDEX,
158 PUBKEY_READ_BLOCK_NUMS, (uint8 *) sec_header)) {
159 printf("PARTITION_BOOT2 read error \n");
163 if (nand_read_skip_bad(&nand_info[0], CONFIG_SYS_NAND_U_BOOT_OFFS, &size, (uint8 *) sec_header) != 0) {
164 printf("PARTITION_BOOT2 read error \n");
168 #ifdef CONFIG_ROM_VERIFY_SPL
172 header_p = (header_info_t *) sec_header;
173 } else if (wcscmp(L"fdl2", name) == 0) {
174 header_p = (header_info_t *) CONFIG_SYS_SDRAM_BASE;
180 for (i = 0; i < header_p->tags_number; i++) {
181 if (header_p->tag[i].tag_name == PUK_NAME) {
182 addr = (uint8_t *) header_p + (header_p->tag[i].tag_offset) * MIN_UNIT;
189 /*copy form libefuse*/
190 #define UID_BLOCK_START 0
191 #define UID_BLOCK_END 1
192 #define UID_BLOCK_LEN (UID_BLOCK_END - UID_BLOCK_START + 1)
193 #define HASH_BLOCK_START 2
194 #define HASH_BLOCK_END 6
195 #define HASH_BLOCK_LEN (HASH_BLOCK_END - HASH_BLOCK_START + 1)
196 #define SECURE_BOOT_BLOCK 1
197 #define SECURE_BOOT_BIT 18
200 int HexChar2Dec(unsigned char c)
202 if ('0' <= c && c <= '9') {
203 return (int)(c - '0');
204 } else if ('a' <= c && c <= 'f') {
205 return ((int)(c - 'a') + 10);
206 } else if ('A' <= c && c <= 'F') {
207 return ((int)(c - 'A') + 10);
213 int str2Num16(const unsigned char *str)
215 return (str[1] == '\0') ? HexChar2Dec(str[0]) : HexChar2Dec(str[0]) * 16 + HexChar2Dec(str[1]);
218 void convertToLittleEndian(unsigned int *data)
220 *data = ((*data & 0xff000000) >> 24)
221 | ((*data & 0x00ff0000) >> 8)
222 | ((*data & 0x0000ff00) << 8)
223 | ((*data & 0x000000ff) << 24);
226 int efuse_hash_read(unsigned char *hash, int count)
228 unsigned char buf[HASH_BLOCK_LEN * 8 + 1] = { 0 };
229 unsigned int values[HASH_BLOCK_LEN] = { 0 };
230 int i = 0, len = 0, ret = -1;
231 unsigned char *ptr = hash;
233 // printf("%s()->Line:%d; count = %d \n", __FUNCTION__, __LINE__, count);
235 if ((0 == hash) || (count < 1))
238 len = MIN(count, sizeof(buf));
239 for (i = HASH_BLOCK_START; i <= HASH_BLOCK_END; i++) {
240 //ret = efuse_read(i, &values[i - HASH_BLOCK_START]);
241 // ret = sci_efuse_read(i);
242 ret = __ddie_efuse_read(i);
243 values[i - HASH_BLOCK_START] = ret;
244 convertToLittleEndian(&values[i - HASH_BLOCK_START]);
246 printf("efuse read err\n");
251 for (i = 0; i < HASH_BLOCK_LEN; i++) {
252 sprintf((char *)&buf[i * 8], "%08x", values[i]);
255 len = (strlen(buf) % 2 == 0) ? strlen(buf) / 2 : (strlen(buf) / 2 + 1);
257 for (i = 0; i < len; ++i) {
259 *ptr++ = str2Num16(buf + idx);
262 //strncpy((char *)hash, (char *)&buf, len);
263 //printf("%s()->Line:%d; hash = %s, len = %d \n", __FUNCTION__, __LINE__, hash, len-1);
267 void secure_hash_str2ul(void *dst, void *src, unsigned int count)
270 unsigned char tmp[9] = { 0 };
271 unsigned char buf[HASH_BLOCK_LEN * 8 + 1] = { 0 };
272 unsigned int *pintdst = dst;
274 sprintf(buf, "%08x%08x%08x%08x%08x", *(uint32_t *) src, *(uint32_t *) (src + 4), *(uint32_t *) (src + 8), *(uint32_t *) (src + 12),
275 *(uint32_t *) (src + 16));
277 for (i = 0; i < count; i += 8) {
278 memset(tmp, 0, sizeof(tmp));
279 strncpy((char *)tmp, (char *)&buf[i], 8);
281 *pintdst++ = (unsigned int)simple_strtoul(tmp, 0, 16);
286 int secure_verify(wchar_t * name, uint8_t * header, uint8_t * code)
291 unsigned char rom_efuse_hash[SHA1_SUM_LEN] = { 0 };
292 unsigned char cal_efuse_hash[SHA1_SUM_LEN] = { 0 };
293 unsigned int rom_efuse[HASH_BLOCK_LEN] = { 0 };
294 unsigned int cal_efuse[HASH_BLOCK_LEN] = { 0 };
296 NBLHeader *nblheader;
299 printf("%s, name: %s enter\r\n", __FUNCTION__, _w2c(name));
301 tmpnbl = malloc(sizeof(NBLHeader));
303 if (name && wcscmp(L"splloader0", name) != 0) {
304 if (!secure_header_parser(header))
308 if (secureboot_enabled()) {
309 if (name && (wcscmp(L"splloader0", name) == 0)) {
310 /*read efuse hash values */
311 efuse_hash_read(rom_efuse_hash, sizeof(rom_efuse_hash));
313 /* memset NBLHeader & save NBLHeader */
314 nblheader = (NBLHeader *) ((unsigned char *)header + BOOTLOADER_HEADER_OFFSET);
315 memcpy(tmpnbl, nblheader, sizeof(NBLHeader));
316 len = nblheader->mHashLen;
318 memset(nblheader, 0, sizeof(NBLHeader));
319 nblheader->mHashLen = len;
320 cal_sha1(header, (nblheader->mHashLen) << 2, cal_efuse_hash);
322 /*restore the NBLHeader */
323 memcpy(nblheader, tmpnbl, sizeof(NBLHeader));
325 /*convert char to int */
326 secure_hash_str2ul(&cal_efuse[0], cal_efuse_hash, 2 * SHA1_SUM_LEN);
327 secure_hash_str2ul(&rom_efuse[0], rom_efuse_hash, 2 * SHA1_SUM_LEN);
329 for (i = 0; i < 5; i++) {
330 rom_efuse[i] &= (~0x80000000); //BIT31
331 cal_efuse[i] &= (~0x80000000); //BIT31
333 //hexdump ("setrom_efuse:", rom_efuse, sizeof (rom_efuse));
334 //hexdump ("setpp:", cal_efuse, sizeof (cal_efuse));
336 if ((rom_efuse[0] == cal_efuse[0]) && (rom_efuse[1] == cal_efuse[1]) && (rom_efuse[2] == cal_efuse[2]) && (rom_efuse[3] == cal_efuse[3])
337 && (rom_efuse[4] == cal_efuse[4])) {
338 printf("efuse hash compare successful\n");
340 printf("efuse hash compare difference\n");
346 puk_addr = get_puk_addr(name, header);
347 // hexdump("puk_addr:", puk_addr, 260);
349 vlr_addr = get_vlr_addr(name, header);
354 code_addr = get_code_addr(name, header);
356 printf("puk_addr=%x,vlr_addr=%x,code_addr=%x\n", puk_addr, vlr_addr, code_addr);
358 secure_check((uint8_t *) code_addr, ((vlr_info_t *) vlr_addr)->length, (uint8_t *) vlr_addr, (uint8_t *) puk_addr);