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