123ba6841SJoseph Chen /* 223ba6841SJoseph Chen * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd 323ba6841SJoseph Chen * 423ba6841SJoseph Chen * SPDX-License-Identifier: GPL-2.0+ 523ba6841SJoseph Chen */ 623ba6841SJoseph Chen #include "compiler.h" 723ba6841SJoseph Chen #include <version.h> 823ba6841SJoseph Chen #include "sha.h" 923ba6841SJoseph Chen #include <u-boot/sha256.h> 1023ba6841SJoseph Chen #include <u-boot/crc.h> 1123ba6841SJoseph Chen #include <linux/sizes.h> 1223ba6841SJoseph Chen #include <linux/kconfig.h> 1323ba6841SJoseph Chen #include <config.h> 1423ba6841SJoseph Chen 1523ba6841SJoseph Chen extern uint32_t crc32_rk(uint32_t, const unsigned char *, uint32_t); 1623ba6841SJoseph Chen 1723ba6841SJoseph Chen #define OPT_PACK "--pack" 1823ba6841SJoseph Chen #define OPT_UNPACK "--unpack" 1923ba6841SJoseph Chen #define OPT_UBOOT "--uboot" 2023ba6841SJoseph Chen #define OPT_TRUSTOS "--trustos" 21*c64e2562SYifeng Zhao #define OPT_KERNEL "--kernel" 2223ba6841SJoseph Chen #define OPT_SIZE "--size" 2323ba6841SJoseph Chen #define OPT_VERSION "--version" 2423ba6841SJoseph Chen #define OPT_INFO "--info" 2552243bceSJoseph Chen #define OPT_PREPATH "--prepath" 2623ba6841SJoseph Chen 2723ba6841SJoseph Chen /* pack or unpack */ 2823ba6841SJoseph Chen #define MODE_PACK 0 2923ba6841SJoseph Chen #define MODE_UNPACK 1 3023ba6841SJoseph Chen #define MODE_INFO 2 3123ba6841SJoseph Chen #define CONFIG_SECUREBOOT_SHA256 3223ba6841SJoseph Chen 3323ba6841SJoseph Chen /* image type */ 3423ba6841SJoseph Chen #define IMAGE_UBOOT 0 3523ba6841SJoseph Chen #define IMAGE_TRUST 1 36*c64e2562SYifeng Zhao #define IMAGE_KERNEL 2 3723ba6841SJoseph Chen 3823ba6841SJoseph Chen /* magic and hash size */ 3923ba6841SJoseph Chen #define LOADER_MAGIC_SIZE 8 4023ba6841SJoseph Chen #define LOADER_HASH_SIZE 32 4123ba6841SJoseph Chen 4223ba6841SJoseph Chen /* uboot image config */ 4323ba6841SJoseph Chen #define UBOOT_NAME "uboot" 4423ba6841SJoseph Chen #ifdef CONFIG_RK_NVME_BOOT_EN 4523ba6841SJoseph Chen #define UBOOT_NUM 2 4623ba6841SJoseph Chen #define UBOOT_MAX_SIZE 512 * 1024 4723ba6841SJoseph Chen #else 4823ba6841SJoseph Chen #define UBOOT_NUM 4 4923ba6841SJoseph Chen #define UBOOT_MAX_SIZE 1024 * 1024 5023ba6841SJoseph Chen #endif 5123ba6841SJoseph Chen 5223ba6841SJoseph Chen #define UBOOT_VERSION_STRING \ 5323ba6841SJoseph Chen U_BOOT_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME ")" CONFIG_IDENT_STRING 5423ba6841SJoseph Chen 5523ba6841SJoseph Chen #define RK_UBOOT_MAGIC "LOADER " 5623ba6841SJoseph Chen #define RK_UBOOT_RUNNING_ADDR CONFIG_SYS_TEXT_BASE 5723ba6841SJoseph Chen 5823ba6841SJoseph Chen /* trust image config */ 5923ba6841SJoseph Chen #define TRUST_NAME "trustos" 6023ba6841SJoseph Chen #define TRUST_NUM 4 6123ba6841SJoseph Chen #define TRUST_MAX_SIZE 1024 * 1024 6223ba6841SJoseph Chen #define TRUST_VERSION_STRING "Trust os" 6323ba6841SJoseph Chen 6423ba6841SJoseph Chen #define RK_TRUST_MAGIC "TOS " 6523ba6841SJoseph Chen #define RK_TRUST_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_128M + SZ_4M) 6623ba6841SJoseph Chen 67*c64e2562SYifeng Zhao #define KERNEL_NAME "kernel" 68*c64e2562SYifeng Zhao #define KERNEL_NUM 1 69*c64e2562SYifeng Zhao #define KERNEL_MAX_SIZE 30720 * 1024 70*c64e2562SYifeng Zhao #define KERNEL_VERSION_STRING "kernel os" 71*c64e2562SYifeng Zhao 72*c64e2562SYifeng Zhao #define RK_KERNEL_MAGIC "KERNEL" 73*c64e2562SYifeng Zhao #define RK_KERNEL_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_4M) 74*c64e2562SYifeng Zhao 7523ba6841SJoseph Chen typedef struct tag_second_loader_hdr { 7623ba6841SJoseph Chen uint8_t magic[LOADER_MAGIC_SIZE]; /* magic */ 7723ba6841SJoseph Chen uint32_t version; 7823ba6841SJoseph Chen uint32_t reserved0; 7923ba6841SJoseph Chen uint32_t loader_load_addr; /* physical load addr */ 8023ba6841SJoseph Chen uint32_t loader_load_size; /* size in bytes */ 8123ba6841SJoseph Chen uint32_t crc32; /* crc32 */ 8223ba6841SJoseph Chen uint32_t hash_len; /* 20 or 32 , 0 is no hash */ 8323ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE]; /* sha */ 8423ba6841SJoseph Chen 85*c64e2562SYifeng Zhao unsigned int js_hash; /*js hsah*/ 86*c64e2562SYifeng Zhao unsigned char reserved[1024-32-32-4]; 8723ba6841SJoseph Chen uint32_t signTag; /* 0x4E474953 */ 8823ba6841SJoseph Chen uint32_t signlen; /* maybe 128 or 256 */ 8923ba6841SJoseph Chen uint8_t rsaHash[256]; /* maybe 128 or 256, using max size 256 */ 9023ba6841SJoseph Chen uint8_t reserved2[2048 - 1024 - 256 - 8]; 9123ba6841SJoseph Chen } second_loader_hdr; 9223ba6841SJoseph Chen 9323ba6841SJoseph Chen void usage(const char *prog) 9423ba6841SJoseph Chen { 95*c64e2562SYifeng Zhao fprintf(stderr, "Usage: %s [--pack|--unpack] [--uboot|--trustos|--kernel]\ 9623ba6841SJoseph Chen file_in " 9723ba6841SJoseph Chen "file_out [load_addr] [--size] [size number]\ 9823ba6841SJoseph Chen [--version] " 9923ba6841SJoseph Chen "[version] | [--info] [file]\n", 10023ba6841SJoseph Chen prog); 10123ba6841SJoseph Chen } 10223ba6841SJoseph Chen 10323ba6841SJoseph Chen unsigned int str2hex(char *str) 10423ba6841SJoseph Chen { 10523ba6841SJoseph Chen int i = 0; 10623ba6841SJoseph Chen unsigned int value = 0; 10723ba6841SJoseph Chen 10823ba6841SJoseph Chen if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) 10923ba6841SJoseph Chen str += 2; 11023ba6841SJoseph Chen if (*str == 'x' || *str == 'X') 11123ba6841SJoseph Chen str += 1; 11223ba6841SJoseph Chen 11323ba6841SJoseph Chen for (i = 0; *str != '\0'; i++, ++str) { 11423ba6841SJoseph Chen if (*str >= '0' && *str <= '9') 11523ba6841SJoseph Chen value = value * 16 + *str - '0'; 11623ba6841SJoseph Chen else if (*str >= 'a' && *str <= 'f') 11723ba6841SJoseph Chen value = value * 16 + *str - 'a' + 10; 11823ba6841SJoseph Chen else if (*str >= 'A' && *str <= 'F') 11923ba6841SJoseph Chen value = value * 16 + *str - 'A' + 10; 12023ba6841SJoseph Chen else 12123ba6841SJoseph Chen break; 12223ba6841SJoseph Chen } 12323ba6841SJoseph Chen return value; 12423ba6841SJoseph Chen } 12523ba6841SJoseph Chen 126*c64e2562SYifeng Zhao static uint32_t js_hash(uint8_t *buf, uint32_t len) 127*c64e2562SYifeng Zhao { 128*c64e2562SYifeng Zhao uint32_t hash = 0x47C6A7E6; 129*c64e2562SYifeng Zhao uint32_t i; 130*c64e2562SYifeng Zhao 131*c64e2562SYifeng Zhao for (i = 0; i < len; i++) 132*c64e2562SYifeng Zhao hash ^= ((hash << 5) + buf[i] + (hash >> 2)); 133*c64e2562SYifeng Zhao 134*c64e2562SYifeng Zhao return hash; 135*c64e2562SYifeng Zhao } 136*c64e2562SYifeng Zhao 13723ba6841SJoseph Chen int main(int argc, char *argv[]) 13823ba6841SJoseph Chen { 13923ba6841SJoseph Chen int mode = -1, image = -1; 14023ba6841SJoseph Chen int max_size, max_num; 14123ba6841SJoseph Chen int size, i; 14223ba6841SJoseph Chen uint32_t loader_addr, in_loader_addr = -1; 14323ba6841SJoseph Chen char *magic, *version, *name; 14423ba6841SJoseph Chen FILE *fi, *fo; 14523ba6841SJoseph Chen second_loader_hdr hdr; 14623ba6841SJoseph Chen char *buf = 0; 14723ba6841SJoseph Chen uint32_t in_size = 0, in_num = 0; 14823ba6841SJoseph Chen char *file_in = NULL, *file_out = NULL; 14952243bceSJoseph Chen char *prepath = NULL; 15052243bceSJoseph Chen char file_name[1024]; 15123ba6841SJoseph Chen uint32_t curr_version = 0; 15223ba6841SJoseph Chen 15323ba6841SJoseph Chen if (argc < 3) { 15423ba6841SJoseph Chen usage(argv[0]); 15523ba6841SJoseph Chen exit(EXIT_FAILURE); 15623ba6841SJoseph Chen } 15723ba6841SJoseph Chen 15823ba6841SJoseph Chen for (i = 1; i < argc; i++) { 15923ba6841SJoseph Chen if (!strcmp(argv[i], OPT_PACK)) { 16023ba6841SJoseph Chen mode = MODE_PACK; 16123ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UNPACK)) { 16223ba6841SJoseph Chen mode = MODE_UNPACK; 16323ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UBOOT)) { 16423ba6841SJoseph Chen image = IMAGE_UBOOT; 16523ba6841SJoseph Chen file_in = argv[++i]; 16623ba6841SJoseph Chen file_out = argv[++i]; 16723ba6841SJoseph Chen /* detect whether loader address is delivered */ 16823ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2))) 16923ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]); 17023ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_TRUSTOS)) { 17123ba6841SJoseph Chen image = IMAGE_TRUST; 17223ba6841SJoseph Chen file_in = argv[++i]; 17323ba6841SJoseph Chen file_out = argv[++i]; 17423ba6841SJoseph Chen /* detect whether loader address is delivered */ 17523ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2))) 17623ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]); 177*c64e2562SYifeng Zhao } else if (!strcmp(argv[i], OPT_KERNEL)) { 178*c64e2562SYifeng Zhao image = IMAGE_KERNEL; 179*c64e2562SYifeng Zhao file_in = argv[++i]; 180*c64e2562SYifeng Zhao file_out = argv[++i]; 181*c64e2562SYifeng Zhao /* detect whether loader address is delivered */ 182*c64e2562SYifeng Zhao if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2))) 183*c64e2562SYifeng Zhao in_loader_addr = str2hex(argv[++i]); 18423ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_SIZE)) { 18523ba6841SJoseph Chen in_size = strtoul(argv[++i], NULL, 10); 18623ba6841SJoseph Chen /* 18723ba6841SJoseph Chen * Usually, it must be at 512kb align due to preloader 18823ba6841SJoseph Chen * detects every 512kb. But some product has critial 18923ba6841SJoseph Chen * flash size requirement, we have to make it small than 19023ba6841SJoseph Chen * 512KB. 19123ba6841SJoseph Chen */ 19223ba6841SJoseph Chen if (in_size % 64) { 19323ba6841SJoseph Chen usage(argv[0]); 19423ba6841SJoseph Chen exit(EXIT_FAILURE); 19523ba6841SJoseph Chen } 19623ba6841SJoseph Chen in_size *= 1024; 19723ba6841SJoseph Chen 19823ba6841SJoseph Chen in_num = strtoul(argv[++i], NULL, 10); 19923ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_VERSION)) { 20023ba6841SJoseph Chen curr_version = strtoul(argv[++i], NULL, 10); 20123ba6841SJoseph Chen printf("curr_version = 0x%x\n", curr_version); 20223ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_INFO)) { 20323ba6841SJoseph Chen mode = MODE_INFO; 20423ba6841SJoseph Chen file_in = argv[++i]; 20552243bceSJoseph Chen } else if (!strcmp(argv[i], OPT_PREPATH)) { 20652243bceSJoseph Chen prepath = argv[++i]; 20723ba6841SJoseph Chen } else { 20823ba6841SJoseph Chen usage(argv[0]); 20923ba6841SJoseph Chen exit(EXIT_FAILURE); 21023ba6841SJoseph Chen } 21123ba6841SJoseph Chen } 21223ba6841SJoseph Chen 21323ba6841SJoseph Chen /* config image information */ 21423ba6841SJoseph Chen if (image == IMAGE_UBOOT) { 21523ba6841SJoseph Chen name = UBOOT_NAME; 21623ba6841SJoseph Chen magic = RK_UBOOT_MAGIC; 21723ba6841SJoseph Chen version = UBOOT_VERSION_STRING; 21823ba6841SJoseph Chen max_size = in_size ? in_size : UBOOT_MAX_SIZE; 21923ba6841SJoseph Chen max_num = in_num ? in_num : UBOOT_NUM; 22023ba6841SJoseph Chen loader_addr = 22123ba6841SJoseph Chen (in_loader_addr == -1) ? RK_UBOOT_RUNNING_ADDR : in_loader_addr; 22223ba6841SJoseph Chen } else if (image == IMAGE_TRUST) { 22323ba6841SJoseph Chen name = TRUST_NAME; 22423ba6841SJoseph Chen magic = RK_TRUST_MAGIC; 22523ba6841SJoseph Chen version = TRUST_VERSION_STRING; 22623ba6841SJoseph Chen max_size = in_size ? in_size : TRUST_MAX_SIZE; 22723ba6841SJoseph Chen max_num = in_num ? in_num : TRUST_NUM; 22823ba6841SJoseph Chen loader_addr = 22923ba6841SJoseph Chen (in_loader_addr == -1) ? RK_TRUST_RUNNING_ADDR : in_loader_addr; 230*c64e2562SYifeng Zhao } else if (image == IMAGE_KERNEL) { 231*c64e2562SYifeng Zhao name = KERNEL_NAME; 232*c64e2562SYifeng Zhao magic = RK_KERNEL_MAGIC; 233*c64e2562SYifeng Zhao version = KERNEL_VERSION_STRING; 234*c64e2562SYifeng Zhao max_size = in_size ? in_size : KERNEL_MAX_SIZE; 235*c64e2562SYifeng Zhao max_num = in_num ? in_num : KERNEL_NUM; 236*c64e2562SYifeng Zhao loader_addr = 237*c64e2562SYifeng Zhao (in_loader_addr == -1) ? RK_KERNEL_RUNNING_ADDR : in_loader_addr; 238*c64e2562SYifeng Zhao 23923ba6841SJoseph Chen } else if (mode == MODE_INFO) { 24023ba6841SJoseph Chen 24123ba6841SJoseph Chen } else { 24223ba6841SJoseph Chen exit(EXIT_FAILURE); 24323ba6841SJoseph Chen } 24423ba6841SJoseph Chen 24523ba6841SJoseph Chen if (mode == MODE_PACK) { 24623ba6841SJoseph Chen buf = calloc(max_size, max_num); 24723ba6841SJoseph Chen if (!buf) { 24823ba6841SJoseph Chen perror(file_out); 24923ba6841SJoseph Chen exit(EXIT_FAILURE); 25023ba6841SJoseph Chen } 25123ba6841SJoseph Chen printf("\n load addr is 0x%x!\n", loader_addr); 25252243bceSJoseph Chen 25352243bceSJoseph Chen /* Add prepath for file_in name */ 25452243bceSJoseph Chen if (prepath && strncmp(prepath, file_in, strlen(prepath))) { 25552243bceSJoseph Chen strcpy(file_name, prepath); 25652243bceSJoseph Chen strcat(file_name, file_in); 25752243bceSJoseph Chen file_in = file_name; 25852243bceSJoseph Chen } 25952243bceSJoseph Chen 26023ba6841SJoseph Chen if (!file_in || !file_out) { 26123ba6841SJoseph Chen usage(argv[0]); 26223ba6841SJoseph Chen exit(EXIT_FAILURE); 26323ba6841SJoseph Chen } 26423ba6841SJoseph Chen 26523ba6841SJoseph Chen /* file in */ 26623ba6841SJoseph Chen fi = fopen(file_in, "rb"); 26723ba6841SJoseph Chen if (!fi) { 26823ba6841SJoseph Chen perror(file_in); 26923ba6841SJoseph Chen exit(EXIT_FAILURE); 27023ba6841SJoseph Chen } 27123ba6841SJoseph Chen 27223ba6841SJoseph Chen /* file out */ 27323ba6841SJoseph Chen fo = fopen(file_out, "wb"); 27423ba6841SJoseph Chen if (!fo) { 27523ba6841SJoseph Chen perror(file_out); 27623ba6841SJoseph Chen exit(EXIT_FAILURE); 27723ba6841SJoseph Chen } 27823ba6841SJoseph Chen 27923ba6841SJoseph Chen printf("pack input %s \n", file_in); 28023ba6841SJoseph Chen fseek(fi, 0, SEEK_END); 28123ba6841SJoseph Chen size = ftell(fi); 28223ba6841SJoseph Chen fseek(fi, 0, SEEK_SET); 2832bbbd780SJoseph Chen printf("pack file size: %d(%d KB)\n", size, size / 1024); 28423ba6841SJoseph Chen if (size > max_size - sizeof(second_loader_hdr)) { 28523ba6841SJoseph Chen perror(file_out); 28623ba6841SJoseph Chen exit(EXIT_FAILURE); 28723ba6841SJoseph Chen } 28823ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr)); 28923ba6841SJoseph Chen memcpy((char *)hdr.magic, magic, LOADER_MAGIC_SIZE); 29023ba6841SJoseph Chen hdr.version = curr_version; 29123ba6841SJoseph Chen hdr.loader_load_addr = loader_addr; 29223ba6841SJoseph Chen if (!fread(buf + sizeof(second_loader_hdr), size, 1, fi)) 29323ba6841SJoseph Chen exit(EXIT_FAILURE); 29423ba6841SJoseph Chen 29523ba6841SJoseph Chen /* Aligned size to 4-byte, Rockchip HW Crypto need 4-byte align */ 29623ba6841SJoseph Chen size = (((size + 3) >> 2) << 2); 29723ba6841SJoseph Chen hdr.loader_load_size = size; 29823ba6841SJoseph Chen 29923ba6841SJoseph Chen hdr.crc32 = crc32_rk( 30023ba6841SJoseph Chen 0, (const unsigned char *)buf + sizeof(second_loader_hdr), size); 30123ba6841SJoseph Chen printf("crc = 0x%08x\n", hdr.crc32); 302*c64e2562SYifeng Zhao hdr.js_hash = js_hash((uint8_t *)buf + sizeof(second_loader_hdr), size); 30323ba6841SJoseph Chen #ifndef CONFIG_SECUREBOOT_SHA256 30423ba6841SJoseph Chen SHA_CTX ctx; 30523ba6841SJoseph Chen uint8_t *sha; 30623ba6841SJoseph Chen hdr.hash_len = (SHA_DIGEST_SIZE > LOADER_HASH_SIZE) ? LOADER_HASH_SIZE 30723ba6841SJoseph Chen : SHA_DIGEST_SIZE; 30823ba6841SJoseph Chen SHA_init(&ctx); 30923ba6841SJoseph Chen SHA_update(&ctx, buf + sizeof(second_loader_hdr), size); 31023ba6841SJoseph Chen if (hdr.version > 0) 31123ba6841SJoseph Chen SHA_update(&ctx, (void *)&hdr.version, 8); 31223ba6841SJoseph Chen 31323ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_addr, sizeof(hdr.loader_load_addr)); 31423ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_size, sizeof(hdr.loader_load_size)); 31523ba6841SJoseph Chen SHA_update(&ctx, &hdr.hash_len, sizeof(hdr.hash_len)); 31623ba6841SJoseph Chen sha = (uint8_t *)SHA_final(&ctx); 31723ba6841SJoseph Chen memcpy(hdr.hash, sha, hdr.hash_len); 31823ba6841SJoseph Chen #else 31923ba6841SJoseph Chen sha256_context ctx; 32023ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE]; 32123ba6841SJoseph Chen 32223ba6841SJoseph Chen memset(hash, 0, LOADER_HASH_SIZE); 32323ba6841SJoseph Chen 32423ba6841SJoseph Chen hdr.hash_len = 32; /* sha256 */ 32523ba6841SJoseph Chen sha256_starts(&ctx); 32623ba6841SJoseph Chen sha256_update(&ctx, (void *)buf + sizeof(second_loader_hdr), size); 32723ba6841SJoseph Chen if (hdr.version > 0) 32823ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.version, 8); 32923ba6841SJoseph Chen 33023ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_addr, 33123ba6841SJoseph Chen sizeof(hdr.loader_load_addr)); 33223ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_size, 33323ba6841SJoseph Chen sizeof(hdr.loader_load_size)); 33423ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.hash_len, sizeof(hdr.hash_len)); 33523ba6841SJoseph Chen sha256_finish(&ctx, hash); 33623ba6841SJoseph Chen memcpy(hdr.hash, hash, hdr.hash_len); 33723ba6841SJoseph Chen #endif /* CONFIG_SECUREBOOT_SHA256 */ 33823ba6841SJoseph Chen 33923ba6841SJoseph Chen printf("%s version: %s\n", name, version); 34023ba6841SJoseph Chen memcpy(buf, &hdr, sizeof(second_loader_hdr)); 341*c64e2562SYifeng Zhao if (image == IMAGE_KERNEL) 342*c64e2562SYifeng Zhao fwrite(buf, size + sizeof(second_loader_hdr), 1, fo); 343*c64e2562SYifeng Zhao else 34423ba6841SJoseph Chen for (i = 0; i < max_num; i++) 34523ba6841SJoseph Chen fwrite(buf, max_size, 1, fo); 34623ba6841SJoseph Chen 34723ba6841SJoseph Chen printf("pack %s success! \n", file_out); 34823ba6841SJoseph Chen fclose(fi); 34923ba6841SJoseph Chen fclose(fo); 35023ba6841SJoseph Chen } else if (mode == MODE_UNPACK) { 35123ba6841SJoseph Chen buf = calloc(max_size, max_num); 35223ba6841SJoseph Chen if (!buf) { 35323ba6841SJoseph Chen perror(file_out); 35423ba6841SJoseph Chen exit(EXIT_FAILURE); 35523ba6841SJoseph Chen } 35623ba6841SJoseph Chen if (!file_in || !file_out) { 35723ba6841SJoseph Chen usage(argv[0]); 35823ba6841SJoseph Chen exit(EXIT_FAILURE); 35923ba6841SJoseph Chen } 36023ba6841SJoseph Chen 36123ba6841SJoseph Chen /* file in */ 36223ba6841SJoseph Chen fi = fopen(file_in, "rb"); 36323ba6841SJoseph Chen if (!fi) { 36423ba6841SJoseph Chen perror(file_in); 36523ba6841SJoseph Chen exit(EXIT_FAILURE); 36623ba6841SJoseph Chen } 36723ba6841SJoseph Chen 36823ba6841SJoseph Chen /* file out */ 36923ba6841SJoseph Chen fo = fopen(file_out, "wb"); 37023ba6841SJoseph Chen if (!fo) { 37123ba6841SJoseph Chen perror(file_out); 37223ba6841SJoseph Chen exit(EXIT_FAILURE); 37323ba6841SJoseph Chen } 37423ba6841SJoseph Chen 37523ba6841SJoseph Chen printf("unpack input %s \n", file_in); 37623ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr)); 37723ba6841SJoseph Chen if (!fread(&hdr, sizeof(second_loader_hdr), 1, fi)) 37823ba6841SJoseph Chen exit(EXIT_FAILURE); 37923ba6841SJoseph Chen 38023ba6841SJoseph Chen if (!fread(buf, hdr.loader_load_size, 1, fi)) 38123ba6841SJoseph Chen exit(EXIT_FAILURE); 38223ba6841SJoseph Chen 38323ba6841SJoseph Chen fwrite(buf, hdr.loader_load_size, 1, fo); 38423ba6841SJoseph Chen printf("unpack %s success! \n", file_out); 38523ba6841SJoseph Chen fclose(fi); 38623ba6841SJoseph Chen fclose(fo); 38723ba6841SJoseph Chen } else if (mode == MODE_INFO) { 38823ba6841SJoseph Chen second_loader_hdr *hdr; 38923ba6841SJoseph Chen 39023ba6841SJoseph Chen hdr = malloc(sizeof(struct tag_second_loader_hdr)); 39123ba6841SJoseph Chen if (hdr == NULL) { 39223ba6841SJoseph Chen printf("Memory error!\n"); 39323ba6841SJoseph Chen exit(EXIT_FAILURE); 39423ba6841SJoseph Chen } 39523ba6841SJoseph Chen /* file in */ 39623ba6841SJoseph Chen fi = fopen(file_in, "rb"); 39723ba6841SJoseph Chen if (!fi) { 39823ba6841SJoseph Chen perror(file_in); 39923ba6841SJoseph Chen exit(EXIT_FAILURE); 40023ba6841SJoseph Chen } 40123ba6841SJoseph Chen 40223ba6841SJoseph Chen if (!fread(hdr, sizeof(struct tag_second_loader_hdr), 1, fi)) 40323ba6841SJoseph Chen exit(EXIT_FAILURE); 40423ba6841SJoseph Chen 40523ba6841SJoseph Chen if (!(memcmp(RK_UBOOT_MAGIC, hdr->magic, 5)) || 40623ba6841SJoseph Chen !(memcmp(RK_TRUST_MAGIC, hdr->magic, 3))) { 40723ba6841SJoseph Chen printf("The image info:\n"); 40823ba6841SJoseph Chen printf("Rollback index is %d\n", hdr->version); 40923ba6841SJoseph Chen printf("Load Addr is 0x%x\n", hdr->loader_load_addr); 41023ba6841SJoseph Chen } else { 41123ba6841SJoseph Chen printf("Please input the correct file.\n"); 41223ba6841SJoseph Chen } 41323ba6841SJoseph Chen 41423ba6841SJoseph Chen fclose(fi); 41523ba6841SJoseph Chen free(hdr); 41623ba6841SJoseph Chen } 41723ba6841SJoseph Chen free(buf); 41823ba6841SJoseph Chen 41923ba6841SJoseph Chen return 0; 42023ba6841SJoseph Chen } 421