xref: /OK3568_Linux_fs/u-boot/tools/rockchip/loaderimage.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun #include "compiler.h"
7*4882a593Smuzhiyun #include <version.h>
8*4882a593Smuzhiyun #include "sha.h"
9*4882a593Smuzhiyun #include <u-boot/sha256.h>
10*4882a593Smuzhiyun #include <u-boot/crc.h>
11*4882a593Smuzhiyun #include <linux/sizes.h>
12*4882a593Smuzhiyun #include <linux/kconfig.h>
13*4882a593Smuzhiyun #include <config.h>
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun extern uint32_t crc32_rk(uint32_t, const unsigned char *, uint32_t);
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define OPT_PACK "--pack"
18*4882a593Smuzhiyun #define OPT_UNPACK "--unpack"
19*4882a593Smuzhiyun #define OPT_UBOOT "--uboot"
20*4882a593Smuzhiyun #define OPT_TRUSTOS "--trustos"
21*4882a593Smuzhiyun #define OPT_KERNEL "--kernel"
22*4882a593Smuzhiyun #define OPT_SIZE "--size"
23*4882a593Smuzhiyun #define OPT_VERSION "--version"
24*4882a593Smuzhiyun #define OPT_INFO "--info"
25*4882a593Smuzhiyun #define OPT_PREPATH "--prepath"
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /* pack or unpack */
28*4882a593Smuzhiyun #define MODE_PACK 0
29*4882a593Smuzhiyun #define MODE_UNPACK 1
30*4882a593Smuzhiyun #define MODE_INFO 2
31*4882a593Smuzhiyun #define CONFIG_SECUREBOOT_SHA256
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /* image type */
34*4882a593Smuzhiyun #define IMAGE_UBOOT 0
35*4882a593Smuzhiyun #define IMAGE_TRUST 1
36*4882a593Smuzhiyun #define IMAGE_KERNEL 2
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /* magic and hash size */
39*4882a593Smuzhiyun #define LOADER_MAGIC_SIZE 8
40*4882a593Smuzhiyun #define LOADER_HASH_SIZE 32
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /* uboot image config */
43*4882a593Smuzhiyun #define UBOOT_NAME "uboot"
44*4882a593Smuzhiyun #ifdef CONFIG_RK_NVME_BOOT_EN
45*4882a593Smuzhiyun #define UBOOT_NUM 2
46*4882a593Smuzhiyun #define UBOOT_MAX_SIZE 512 * 1024
47*4882a593Smuzhiyun #else
48*4882a593Smuzhiyun #define UBOOT_NUM 4
49*4882a593Smuzhiyun #define UBOOT_MAX_SIZE 1024 * 1024
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun #define UBOOT_VERSION_STRING                                                   \
53*4882a593Smuzhiyun   U_BOOT_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME ")" CONFIG_IDENT_STRING
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define RK_UBOOT_MAGIC "LOADER  "
56*4882a593Smuzhiyun #define RK_UBOOT_RUNNING_ADDR CONFIG_SYS_TEXT_BASE
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun /* trust image config */
59*4882a593Smuzhiyun #define TRUST_NAME "trustos"
60*4882a593Smuzhiyun #define TRUST_NUM 4
61*4882a593Smuzhiyun #define TRUST_MAX_SIZE 1024 * 1024
62*4882a593Smuzhiyun #define TRUST_VERSION_STRING "Trust os"
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #define RK_TRUST_MAGIC "TOS     "
65*4882a593Smuzhiyun #define RK_TRUST_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_128M + SZ_4M)
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define KERNEL_NAME		"kernel"
68*4882a593Smuzhiyun #define KERNEL_NUM		1
69*4882a593Smuzhiyun #define KERNEL_MAX_SIZE		30720 * 1024
70*4882a593Smuzhiyun #define KERNEL_VERSION_STRING	"kernel os"
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun #define RK_KERNEL_MAGIC		"KERNEL"
73*4882a593Smuzhiyun #define RK_KERNEL_RUNNING_ADDR	(CONFIG_SYS_TEXT_BASE + SZ_4M)
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun typedef struct tag_second_loader_hdr {
76*4882a593Smuzhiyun 	uint8_t magic[LOADER_MAGIC_SIZE]; /* magic */
77*4882a593Smuzhiyun 	uint32_t version;
78*4882a593Smuzhiyun 	uint32_t reserved0;
79*4882a593Smuzhiyun 	uint32_t loader_load_addr;      /* physical load addr */
80*4882a593Smuzhiyun 	uint32_t loader_load_size;      /* size in bytes */
81*4882a593Smuzhiyun 	uint32_t crc32;                 /* crc32 */
82*4882a593Smuzhiyun 	uint32_t hash_len;              /* 20 or 32 , 0 is no hash */
83*4882a593Smuzhiyun 	uint8_t hash[LOADER_HASH_SIZE]; /* sha */
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	unsigned int js_hash;			/*js hsah*/
86*4882a593Smuzhiyun 	unsigned char reserved[1024-32-32-4];
87*4882a593Smuzhiyun 	uint32_t signTag;     /* 0x4E474953 */
88*4882a593Smuzhiyun 	uint32_t signlen;     /* maybe 128 or 256 */
89*4882a593Smuzhiyun 	uint8_t rsaHash[256]; /* maybe 128 or 256, using max size 256 */
90*4882a593Smuzhiyun 	uint8_t reserved2[2048 - 1024 - 256 - 8];
91*4882a593Smuzhiyun } second_loader_hdr;
92*4882a593Smuzhiyun 
usage(const char * prog)93*4882a593Smuzhiyun void usage(const char *prog)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	fprintf(stderr, "Usage: %s [--pack|--unpack] [--uboot|--trustos|--kernel]\
96*4882a593Smuzhiyun 		file_in "
97*4882a593Smuzhiyun 	        "file_out [load_addr]  [--size] [size number]\
98*4882a593Smuzhiyun 		[--version] "
99*4882a593Smuzhiyun 	        "[version] | [--info] [file]\n",
100*4882a593Smuzhiyun 	        prog);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
str2hex(char * str)103*4882a593Smuzhiyun unsigned int str2hex(char *str)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	int i = 0;
106*4882a593Smuzhiyun 	unsigned int value = 0;
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X'))
109*4882a593Smuzhiyun 		str += 2;
110*4882a593Smuzhiyun 	if (*str == 'x' || *str == 'X')
111*4882a593Smuzhiyun 		str += 1;
112*4882a593Smuzhiyun 
113*4882a593Smuzhiyun 	for (i = 0; *str != '\0'; i++, ++str) {
114*4882a593Smuzhiyun 		if (*str >= '0' && *str <= '9')
115*4882a593Smuzhiyun 			value = value * 16 + *str - '0';
116*4882a593Smuzhiyun 		else if (*str >= 'a' && *str <= 'f')
117*4882a593Smuzhiyun 			value = value * 16 + *str - 'a' + 10;
118*4882a593Smuzhiyun 		else if (*str >= 'A' && *str <= 'F')
119*4882a593Smuzhiyun 			value = value * 16 + *str - 'A' + 10;
120*4882a593Smuzhiyun 		else
121*4882a593Smuzhiyun 			break;
122*4882a593Smuzhiyun 	}
123*4882a593Smuzhiyun 	return value;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
js_hash(uint8_t * buf,uint32_t len)126*4882a593Smuzhiyun static uint32_t js_hash(uint8_t *buf, uint32_t len)
127*4882a593Smuzhiyun {
128*4882a593Smuzhiyun 	uint32_t hash = 0x47C6A7E6;
129*4882a593Smuzhiyun 	uint32_t i;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	for (i = 0; i < len; i++)
132*4882a593Smuzhiyun 		hash ^= ((hash << 5) + buf[i] + (hash >> 2));
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	return hash;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun 
main(int argc,char * argv[])137*4882a593Smuzhiyun int main(int argc, char *argv[])
138*4882a593Smuzhiyun {
139*4882a593Smuzhiyun 	int mode = -1, image = -1;
140*4882a593Smuzhiyun 	int max_size, max_num;
141*4882a593Smuzhiyun 	int size, i;
142*4882a593Smuzhiyun 	uint32_t loader_addr, in_loader_addr = -1;
143*4882a593Smuzhiyun 	char *magic, *version, *name;
144*4882a593Smuzhiyun 	FILE *fi, *fo;
145*4882a593Smuzhiyun 	second_loader_hdr hdr;
146*4882a593Smuzhiyun 	char *buf = 0;
147*4882a593Smuzhiyun 	uint32_t in_size = 0, in_num = 0;
148*4882a593Smuzhiyun 	char *file_in = NULL, *file_out = NULL;
149*4882a593Smuzhiyun 	char			*prepath = NULL;
150*4882a593Smuzhiyun 	char			file_name[1024];
151*4882a593Smuzhiyun 	uint32_t curr_version = 0;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	if (argc < 3) {
154*4882a593Smuzhiyun 		usage(argv[0]);
155*4882a593Smuzhiyun 		exit(EXIT_FAILURE);
156*4882a593Smuzhiyun 	}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	for (i = 1; i < argc; i++) {
159*4882a593Smuzhiyun 		if (!strcmp(argv[i], OPT_PACK)) {
160*4882a593Smuzhiyun 			mode = MODE_PACK;
161*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_UNPACK)) {
162*4882a593Smuzhiyun 			mode = MODE_UNPACK;
163*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_UBOOT)) {
164*4882a593Smuzhiyun 			image = IMAGE_UBOOT;
165*4882a593Smuzhiyun 			file_in = argv[++i];
166*4882a593Smuzhiyun 			file_out = argv[++i];
167*4882a593Smuzhiyun 			/* detect whether loader address is delivered */
168*4882a593Smuzhiyun 			if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
169*4882a593Smuzhiyun 				in_loader_addr = str2hex(argv[++i]);
170*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_TRUSTOS)) {
171*4882a593Smuzhiyun 			image = IMAGE_TRUST;
172*4882a593Smuzhiyun 			file_in = argv[++i];
173*4882a593Smuzhiyun 			file_out = argv[++i];
174*4882a593Smuzhiyun 			/* detect whether loader address is delivered */
175*4882a593Smuzhiyun 			if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
176*4882a593Smuzhiyun 				in_loader_addr = str2hex(argv[++i]);
177*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_KERNEL)) {
178*4882a593Smuzhiyun 			image = IMAGE_KERNEL;
179*4882a593Smuzhiyun 			file_in = argv[++i];
180*4882a593Smuzhiyun 			file_out = argv[++i];
181*4882a593Smuzhiyun 			/* detect whether loader address is delivered */
182*4882a593Smuzhiyun 			if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2)))
183*4882a593Smuzhiyun 				in_loader_addr = str2hex(argv[++i]);
184*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_SIZE)) {
185*4882a593Smuzhiyun 			in_size = strtoul(argv[++i], NULL, 10);
186*4882a593Smuzhiyun 			/*
187*4882a593Smuzhiyun 			 * Usually, it must be at 512kb align due to preloader
188*4882a593Smuzhiyun 			 * detects every 512kb. But some product has critial
189*4882a593Smuzhiyun 			 * flash size requirement, we have to make it small than
190*4882a593Smuzhiyun 			 * 512KB.
191*4882a593Smuzhiyun 			 */
192*4882a593Smuzhiyun 			if (in_size % 64) {
193*4882a593Smuzhiyun 				usage(argv[0]);
194*4882a593Smuzhiyun 				exit(EXIT_FAILURE);
195*4882a593Smuzhiyun 			}
196*4882a593Smuzhiyun 			in_size *= 1024;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 			in_num = strtoul(argv[++i], NULL, 10);
199*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_VERSION)) {
200*4882a593Smuzhiyun 			curr_version = strtoul(argv[++i], NULL, 10);
201*4882a593Smuzhiyun 			printf("curr_version = 0x%x\n", curr_version);
202*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_INFO)) {
203*4882a593Smuzhiyun 			mode = MODE_INFO;
204*4882a593Smuzhiyun 			file_in = argv[++i];
205*4882a593Smuzhiyun 		} else if (!strcmp(argv[i], OPT_PREPATH)) {
206*4882a593Smuzhiyun 			prepath = argv[++i];
207*4882a593Smuzhiyun 		} else {
208*4882a593Smuzhiyun 			usage(argv[0]);
209*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
210*4882a593Smuzhiyun 		}
211*4882a593Smuzhiyun 	}
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	/* config image information */
214*4882a593Smuzhiyun 	if (image == IMAGE_UBOOT) {
215*4882a593Smuzhiyun 		name = UBOOT_NAME;
216*4882a593Smuzhiyun 		magic = RK_UBOOT_MAGIC;
217*4882a593Smuzhiyun 		version = UBOOT_VERSION_STRING;
218*4882a593Smuzhiyun 		max_size = in_size ? in_size : UBOOT_MAX_SIZE;
219*4882a593Smuzhiyun 		max_num = in_num ? in_num : UBOOT_NUM;
220*4882a593Smuzhiyun 		loader_addr =
221*4882a593Smuzhiyun 		        (in_loader_addr == -1) ? RK_UBOOT_RUNNING_ADDR : in_loader_addr;
222*4882a593Smuzhiyun 	} else if (image == IMAGE_TRUST) {
223*4882a593Smuzhiyun 		name = TRUST_NAME;
224*4882a593Smuzhiyun 		magic = RK_TRUST_MAGIC;
225*4882a593Smuzhiyun 		version = TRUST_VERSION_STRING;
226*4882a593Smuzhiyun 		max_size = in_size ? in_size : TRUST_MAX_SIZE;
227*4882a593Smuzhiyun 		max_num = in_num ? in_num : TRUST_NUM;
228*4882a593Smuzhiyun 		loader_addr =
229*4882a593Smuzhiyun 		        (in_loader_addr == -1) ? RK_TRUST_RUNNING_ADDR : in_loader_addr;
230*4882a593Smuzhiyun 	} else if (image == IMAGE_KERNEL) {
231*4882a593Smuzhiyun 		name = KERNEL_NAME;
232*4882a593Smuzhiyun 		magic = RK_KERNEL_MAGIC;
233*4882a593Smuzhiyun 		version = KERNEL_VERSION_STRING;
234*4882a593Smuzhiyun 		max_size = in_size ? in_size : KERNEL_MAX_SIZE;
235*4882a593Smuzhiyun 		max_num = in_num ? in_num : KERNEL_NUM;
236*4882a593Smuzhiyun 		loader_addr =
237*4882a593Smuzhiyun 		        (in_loader_addr == -1) ? RK_KERNEL_RUNNING_ADDR : in_loader_addr;
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 	} else if (mode == MODE_INFO) {
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	} else {
242*4882a593Smuzhiyun 		exit(EXIT_FAILURE);
243*4882a593Smuzhiyun 	}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (mode == MODE_PACK) {
246*4882a593Smuzhiyun 		buf = calloc(max_size, max_num);
247*4882a593Smuzhiyun 		if (!buf) {
248*4882a593Smuzhiyun 			perror(file_out);
249*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
250*4882a593Smuzhiyun 		}
251*4882a593Smuzhiyun 		printf("\n load addr is 0x%x!\n", loader_addr);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 		/* Add prepath for file_in name */
254*4882a593Smuzhiyun 		if (prepath && strncmp(prepath, file_in, strlen(prepath))) {
255*4882a593Smuzhiyun 			strcpy(file_name, prepath);
256*4882a593Smuzhiyun 			strcat(file_name, file_in);
257*4882a593Smuzhiyun 			file_in = file_name;
258*4882a593Smuzhiyun 		}
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 		if (!file_in || !file_out) {
261*4882a593Smuzhiyun 			usage(argv[0]);
262*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
263*4882a593Smuzhiyun 		}
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 		/* file in */
266*4882a593Smuzhiyun 		fi = fopen(file_in, "rb");
267*4882a593Smuzhiyun 		if (!fi) {
268*4882a593Smuzhiyun 			perror(file_in);
269*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
270*4882a593Smuzhiyun 		}
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 		/* file out */
273*4882a593Smuzhiyun 		fo = fopen(file_out, "wb");
274*4882a593Smuzhiyun 		if (!fo) {
275*4882a593Smuzhiyun 			perror(file_out);
276*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
277*4882a593Smuzhiyun 		}
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 		printf("pack input %s \n", file_in);
280*4882a593Smuzhiyun 		fseek(fi, 0, SEEK_END);
281*4882a593Smuzhiyun 		size = ftell(fi);
282*4882a593Smuzhiyun 		fseek(fi, 0, SEEK_SET);
283*4882a593Smuzhiyun 		printf("pack file size: %d(%d KB)\n", size, size / 1024);
284*4882a593Smuzhiyun 		if (size > max_size - sizeof(second_loader_hdr)) {
285*4882a593Smuzhiyun 			perror(file_out);
286*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
287*4882a593Smuzhiyun 		}
288*4882a593Smuzhiyun 		memset(&hdr, 0, sizeof(second_loader_hdr));
289*4882a593Smuzhiyun 		memcpy((char *)hdr.magic, magic, LOADER_MAGIC_SIZE);
290*4882a593Smuzhiyun 		hdr.version = curr_version;
291*4882a593Smuzhiyun 		hdr.loader_load_addr = loader_addr;
292*4882a593Smuzhiyun 		if (!fread(buf + sizeof(second_loader_hdr), size, 1, fi))
293*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 		/* Aligned size to 4-byte, Rockchip HW Crypto need 4-byte align */
296*4882a593Smuzhiyun 		size = (((size + 3) >> 2) << 2);
297*4882a593Smuzhiyun 		hdr.loader_load_size = size;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 		hdr.crc32 = crc32_rk(
300*4882a593Smuzhiyun 		                    0, (const unsigned char *)buf + sizeof(second_loader_hdr), size);
301*4882a593Smuzhiyun 		printf("crc = 0x%08x\n", hdr.crc32);
302*4882a593Smuzhiyun 		hdr.js_hash = js_hash((uint8_t *)buf + sizeof(second_loader_hdr), size);
303*4882a593Smuzhiyun #ifndef CONFIG_SECUREBOOT_SHA256
304*4882a593Smuzhiyun 		SHA_CTX ctx;
305*4882a593Smuzhiyun 		uint8_t *sha;
306*4882a593Smuzhiyun 		hdr.hash_len = (SHA_DIGEST_SIZE > LOADER_HASH_SIZE) ? LOADER_HASH_SIZE
307*4882a593Smuzhiyun 		               : SHA_DIGEST_SIZE;
308*4882a593Smuzhiyun 		SHA_init(&ctx);
309*4882a593Smuzhiyun 		SHA_update(&ctx, buf + sizeof(second_loader_hdr), size);
310*4882a593Smuzhiyun 		if (hdr.version > 0)
311*4882a593Smuzhiyun 			SHA_update(&ctx, (void *)&hdr.version, 8);
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 		SHA_update(&ctx, &hdr.loader_load_addr, sizeof(hdr.loader_load_addr));
314*4882a593Smuzhiyun 		SHA_update(&ctx, &hdr.loader_load_size, sizeof(hdr.loader_load_size));
315*4882a593Smuzhiyun 		SHA_update(&ctx, &hdr.hash_len, sizeof(hdr.hash_len));
316*4882a593Smuzhiyun 		sha = (uint8_t *)SHA_final(&ctx);
317*4882a593Smuzhiyun 		memcpy(hdr.hash, sha, hdr.hash_len);
318*4882a593Smuzhiyun #else
319*4882a593Smuzhiyun 		sha256_context ctx;
320*4882a593Smuzhiyun 		uint8_t hash[LOADER_HASH_SIZE];
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		memset(hash, 0, LOADER_HASH_SIZE);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 		hdr.hash_len = 32; /* sha256 */
325*4882a593Smuzhiyun 		sha256_starts(&ctx);
326*4882a593Smuzhiyun 		sha256_update(&ctx, (void *)buf + sizeof(second_loader_hdr), size);
327*4882a593Smuzhiyun 		if (hdr.version > 0)
328*4882a593Smuzhiyun 			sha256_update(&ctx, (void *)&hdr.version, 8);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		sha256_update(&ctx, (void *)&hdr.loader_load_addr,
331*4882a593Smuzhiyun 		              sizeof(hdr.loader_load_addr));
332*4882a593Smuzhiyun 		sha256_update(&ctx, (void *)&hdr.loader_load_size,
333*4882a593Smuzhiyun 		              sizeof(hdr.loader_load_size));
334*4882a593Smuzhiyun 		sha256_update(&ctx, (void *)&hdr.hash_len, sizeof(hdr.hash_len));
335*4882a593Smuzhiyun 		sha256_finish(&ctx, hash);
336*4882a593Smuzhiyun 		memcpy(hdr.hash, hash, hdr.hash_len);
337*4882a593Smuzhiyun #endif /* CONFIG_SECUREBOOT_SHA256 */
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 		printf("%s version: %s\n", name, version);
340*4882a593Smuzhiyun 		memcpy(buf, &hdr, sizeof(second_loader_hdr));
341*4882a593Smuzhiyun 		if (image == IMAGE_KERNEL)
342*4882a593Smuzhiyun 			fwrite(buf, size + sizeof(second_loader_hdr), 1, fo);
343*4882a593Smuzhiyun 		else
344*4882a593Smuzhiyun 			for (i = 0; i < max_num; i++)
345*4882a593Smuzhiyun 				fwrite(buf, max_size, 1, fo);
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 		printf("pack %s success! \n", file_out);
348*4882a593Smuzhiyun 		fclose(fi);
349*4882a593Smuzhiyun 		fclose(fo);
350*4882a593Smuzhiyun 	} else if (mode == MODE_UNPACK) {
351*4882a593Smuzhiyun 		buf = calloc(max_size, max_num);
352*4882a593Smuzhiyun 		if (!buf) {
353*4882a593Smuzhiyun 			perror(file_out);
354*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
355*4882a593Smuzhiyun 		}
356*4882a593Smuzhiyun 		if (!file_in || !file_out) {
357*4882a593Smuzhiyun 			usage(argv[0]);
358*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
359*4882a593Smuzhiyun 		}
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 		/* file in */
362*4882a593Smuzhiyun 		fi = fopen(file_in, "rb");
363*4882a593Smuzhiyun 		if (!fi) {
364*4882a593Smuzhiyun 			perror(file_in);
365*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
366*4882a593Smuzhiyun 		}
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 		/* file out */
369*4882a593Smuzhiyun 		fo = fopen(file_out, "wb");
370*4882a593Smuzhiyun 		if (!fo) {
371*4882a593Smuzhiyun 			perror(file_out);
372*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
373*4882a593Smuzhiyun 		}
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		printf("unpack input %s \n", file_in);
376*4882a593Smuzhiyun 		memset(&hdr, 0, sizeof(second_loader_hdr));
377*4882a593Smuzhiyun 		if (!fread(&hdr, sizeof(second_loader_hdr), 1, fi))
378*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 		if (!fread(buf, hdr.loader_load_size, 1, fi))
381*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 		fwrite(buf, hdr.loader_load_size, 1, fo);
384*4882a593Smuzhiyun 		printf("unpack %s success! \n", file_out);
385*4882a593Smuzhiyun 		fclose(fi);
386*4882a593Smuzhiyun 		fclose(fo);
387*4882a593Smuzhiyun 	} else if (mode == MODE_INFO) {
388*4882a593Smuzhiyun 		second_loader_hdr *hdr;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 		hdr = malloc(sizeof(struct tag_second_loader_hdr));
391*4882a593Smuzhiyun 		if (hdr == NULL) {
392*4882a593Smuzhiyun 			printf("Memory error!\n");
393*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
394*4882a593Smuzhiyun 		}
395*4882a593Smuzhiyun 		/* file in */
396*4882a593Smuzhiyun 		fi = fopen(file_in, "rb");
397*4882a593Smuzhiyun 		if (!fi) {
398*4882a593Smuzhiyun 			perror(file_in);
399*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
400*4882a593Smuzhiyun 		}
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 		if (!fread(hdr, sizeof(struct tag_second_loader_hdr), 1, fi))
403*4882a593Smuzhiyun 			exit(EXIT_FAILURE);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 		if (!(memcmp(RK_UBOOT_MAGIC, hdr->magic, 5)) ||
406*4882a593Smuzhiyun 		    !(memcmp(RK_TRUST_MAGIC, hdr->magic, 3))) {
407*4882a593Smuzhiyun 			printf("The image info:\n");
408*4882a593Smuzhiyun 			printf("Rollback index is %d\n", hdr->version);
409*4882a593Smuzhiyun 			printf("Load Addr is 0x%x\n", hdr->loader_load_addr);
410*4882a593Smuzhiyun 		} else {
411*4882a593Smuzhiyun 			printf("Please input the correct file.\n");
412*4882a593Smuzhiyun 		}
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 		fclose(fi);
415*4882a593Smuzhiyun 		free(hdr);
416*4882a593Smuzhiyun 	}
417*4882a593Smuzhiyun 	free(buf);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	return 0;
420*4882a593Smuzhiyun }
421