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" 2123ba6841SJoseph Chen #define OPT_SIZE "--size" 2223ba6841SJoseph Chen #define OPT_VERSION "--version" 2323ba6841SJoseph Chen #define OPT_INFO "--info" 24*52243bceSJoseph Chen #define OPT_PREPATH "--prepath" 2523ba6841SJoseph Chen 2623ba6841SJoseph Chen /* pack or unpack */ 2723ba6841SJoseph Chen #define MODE_PACK 0 2823ba6841SJoseph Chen #define MODE_UNPACK 1 2923ba6841SJoseph Chen #define MODE_INFO 2 3023ba6841SJoseph Chen #define CONFIG_SECUREBOOT_SHA256 3123ba6841SJoseph Chen 3223ba6841SJoseph Chen /* image type */ 3323ba6841SJoseph Chen #define IMAGE_UBOOT 0 3423ba6841SJoseph Chen #define IMAGE_TRUST 1 3523ba6841SJoseph Chen 3623ba6841SJoseph Chen /* magic and hash size */ 3723ba6841SJoseph Chen #define LOADER_MAGIC_SIZE 8 3823ba6841SJoseph Chen #define LOADER_HASH_SIZE 32 3923ba6841SJoseph Chen 4023ba6841SJoseph Chen /* uboot image config */ 4123ba6841SJoseph Chen #define UBOOT_NAME "uboot" 4223ba6841SJoseph Chen #ifdef CONFIG_RK_NVME_BOOT_EN 4323ba6841SJoseph Chen #define UBOOT_NUM 2 4423ba6841SJoseph Chen #define UBOOT_MAX_SIZE 512 * 1024 4523ba6841SJoseph Chen #else 4623ba6841SJoseph Chen #define UBOOT_NUM 4 4723ba6841SJoseph Chen #define UBOOT_MAX_SIZE 1024 * 1024 4823ba6841SJoseph Chen #endif 4923ba6841SJoseph Chen 5023ba6841SJoseph Chen #define UBOOT_VERSION_STRING \ 5123ba6841SJoseph Chen U_BOOT_VERSION " (" U_BOOT_DATE " - " U_BOOT_TIME ")" CONFIG_IDENT_STRING 5223ba6841SJoseph Chen 5323ba6841SJoseph Chen #define RK_UBOOT_MAGIC "LOADER " 5423ba6841SJoseph Chen #define RK_UBOOT_RUNNING_ADDR CONFIG_SYS_TEXT_BASE 5523ba6841SJoseph Chen 5623ba6841SJoseph Chen /* trust image config */ 5723ba6841SJoseph Chen #define TRUST_NAME "trustos" 5823ba6841SJoseph Chen #define TRUST_NUM 4 5923ba6841SJoseph Chen #define TRUST_MAX_SIZE 1024 * 1024 6023ba6841SJoseph Chen #define TRUST_VERSION_STRING "Trust os" 6123ba6841SJoseph Chen 6223ba6841SJoseph Chen #define RK_TRUST_MAGIC "TOS " 6323ba6841SJoseph Chen #define RK_TRUST_RUNNING_ADDR (CONFIG_SYS_TEXT_BASE + SZ_128M + SZ_4M) 6423ba6841SJoseph Chen 6523ba6841SJoseph Chen typedef struct tag_second_loader_hdr { 6623ba6841SJoseph Chen uint8_t magic[LOADER_MAGIC_SIZE]; /* magic */ 6723ba6841SJoseph Chen uint32_t version; 6823ba6841SJoseph Chen uint32_t reserved0; 6923ba6841SJoseph Chen uint32_t loader_load_addr; /* physical load addr */ 7023ba6841SJoseph Chen uint32_t loader_load_size; /* size in bytes */ 7123ba6841SJoseph Chen uint32_t crc32; /* crc32 */ 7223ba6841SJoseph Chen uint32_t hash_len; /* 20 or 32 , 0 is no hash */ 7323ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE]; /* sha */ 7423ba6841SJoseph Chen 7523ba6841SJoseph Chen uint8_t reserved[1024 - 32 - 32]; 7623ba6841SJoseph Chen uint32_t signTag; /* 0x4E474953 */ 7723ba6841SJoseph Chen uint32_t signlen; /* maybe 128 or 256 */ 7823ba6841SJoseph Chen uint8_t rsaHash[256]; /* maybe 128 or 256, using max size 256 */ 7923ba6841SJoseph Chen uint8_t reserved2[2048 - 1024 - 256 - 8]; 8023ba6841SJoseph Chen } second_loader_hdr; 8123ba6841SJoseph Chen 8223ba6841SJoseph Chen void usage(const char *prog) 8323ba6841SJoseph Chen { 8423ba6841SJoseph Chen fprintf(stderr, "Usage: %s [--pack|--unpack] [--uboot|--trustos]\ 8523ba6841SJoseph Chen file_in " 8623ba6841SJoseph Chen "file_out [load_addr] [--size] [size number]\ 8723ba6841SJoseph Chen [--version] " 8823ba6841SJoseph Chen "[version] | [--info] [file]\n", 8923ba6841SJoseph Chen prog); 9023ba6841SJoseph Chen } 9123ba6841SJoseph Chen 9223ba6841SJoseph Chen unsigned int str2hex(char *str) 9323ba6841SJoseph Chen { 9423ba6841SJoseph Chen int i = 0; 9523ba6841SJoseph Chen unsigned int value = 0; 9623ba6841SJoseph Chen 9723ba6841SJoseph Chen if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) 9823ba6841SJoseph Chen str += 2; 9923ba6841SJoseph Chen if (*str == 'x' || *str == 'X') 10023ba6841SJoseph Chen str += 1; 10123ba6841SJoseph Chen 10223ba6841SJoseph Chen for (i = 0; *str != '\0'; i++, ++str) { 10323ba6841SJoseph Chen if (*str >= '0' && *str <= '9') 10423ba6841SJoseph Chen value = value * 16 + *str - '0'; 10523ba6841SJoseph Chen else if (*str >= 'a' && *str <= 'f') 10623ba6841SJoseph Chen value = value * 16 + *str - 'a' + 10; 10723ba6841SJoseph Chen else if (*str >= 'A' && *str <= 'F') 10823ba6841SJoseph Chen value = value * 16 + *str - 'A' + 10; 10923ba6841SJoseph Chen else 11023ba6841SJoseph Chen break; 11123ba6841SJoseph Chen } 11223ba6841SJoseph Chen return value; 11323ba6841SJoseph Chen } 11423ba6841SJoseph Chen 11523ba6841SJoseph Chen int main(int argc, char *argv[]) 11623ba6841SJoseph Chen { 11723ba6841SJoseph Chen int mode = -1, image = -1; 11823ba6841SJoseph Chen int max_size, max_num; 11923ba6841SJoseph Chen int size, i; 12023ba6841SJoseph Chen uint32_t loader_addr, in_loader_addr = -1; 12123ba6841SJoseph Chen char *magic, *version, *name; 12223ba6841SJoseph Chen FILE *fi, *fo; 12323ba6841SJoseph Chen second_loader_hdr hdr; 12423ba6841SJoseph Chen char *buf = 0; 12523ba6841SJoseph Chen uint32_t in_size = 0, in_num = 0; 12623ba6841SJoseph Chen char *file_in = NULL, *file_out = NULL; 127*52243bceSJoseph Chen char *prepath = NULL; 128*52243bceSJoseph Chen char file_name[1024]; 12923ba6841SJoseph Chen uint32_t curr_version = 0; 13023ba6841SJoseph Chen 13123ba6841SJoseph Chen if (argc < 3) { 13223ba6841SJoseph Chen usage(argv[0]); 13323ba6841SJoseph Chen exit(EXIT_FAILURE); 13423ba6841SJoseph Chen } 13523ba6841SJoseph Chen 13623ba6841SJoseph Chen for (i = 1; i < argc; i++) { 13723ba6841SJoseph Chen if (!strcmp(argv[i], OPT_PACK)) { 13823ba6841SJoseph Chen mode = MODE_PACK; 13923ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UNPACK)) { 14023ba6841SJoseph Chen mode = MODE_UNPACK; 14123ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_UBOOT)) { 14223ba6841SJoseph Chen image = IMAGE_UBOOT; 14323ba6841SJoseph Chen file_in = argv[++i]; 14423ba6841SJoseph Chen file_out = argv[++i]; 14523ba6841SJoseph Chen /* detect whether loader address is delivered */ 14623ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2))) 14723ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]); 14823ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_TRUSTOS)) { 14923ba6841SJoseph Chen image = IMAGE_TRUST; 15023ba6841SJoseph Chen file_in = argv[++i]; 15123ba6841SJoseph Chen file_out = argv[++i]; 15223ba6841SJoseph Chen /* detect whether loader address is delivered */ 15323ba6841SJoseph Chen if ((argv[i + 1]) && (strncmp(argv[i + 1], "--", 2))) 15423ba6841SJoseph Chen in_loader_addr = str2hex(argv[++i]); 15523ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_SIZE)) { 15623ba6841SJoseph Chen in_size = strtoul(argv[++i], NULL, 10); 15723ba6841SJoseph Chen /* 15823ba6841SJoseph Chen * Usually, it must be at 512kb align due to preloader 15923ba6841SJoseph Chen * detects every 512kb. But some product has critial 16023ba6841SJoseph Chen * flash size requirement, we have to make it small than 16123ba6841SJoseph Chen * 512KB. 16223ba6841SJoseph Chen */ 16323ba6841SJoseph Chen if (in_size % 64) { 16423ba6841SJoseph Chen usage(argv[0]); 16523ba6841SJoseph Chen exit(EXIT_FAILURE); 16623ba6841SJoseph Chen } 16723ba6841SJoseph Chen in_size *= 1024; 16823ba6841SJoseph Chen 16923ba6841SJoseph Chen in_num = strtoul(argv[++i], NULL, 10); 17023ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_VERSION)) { 17123ba6841SJoseph Chen curr_version = strtoul(argv[++i], NULL, 10); 17223ba6841SJoseph Chen printf("curr_version = 0x%x\n", curr_version); 17323ba6841SJoseph Chen } else if (!strcmp(argv[i], OPT_INFO)) { 17423ba6841SJoseph Chen mode = MODE_INFO; 17523ba6841SJoseph Chen file_in = argv[++i]; 176*52243bceSJoseph Chen } else if (!strcmp(argv[i], OPT_PREPATH)) { 177*52243bceSJoseph Chen prepath = argv[++i]; 17823ba6841SJoseph Chen } else { 17923ba6841SJoseph Chen usage(argv[0]); 18023ba6841SJoseph Chen exit(EXIT_FAILURE); 18123ba6841SJoseph Chen } 18223ba6841SJoseph Chen } 18323ba6841SJoseph Chen 18423ba6841SJoseph Chen /* config image information */ 18523ba6841SJoseph Chen if (image == IMAGE_UBOOT) { 18623ba6841SJoseph Chen name = UBOOT_NAME; 18723ba6841SJoseph Chen magic = RK_UBOOT_MAGIC; 18823ba6841SJoseph Chen version = UBOOT_VERSION_STRING; 18923ba6841SJoseph Chen max_size = in_size ? in_size : UBOOT_MAX_SIZE; 19023ba6841SJoseph Chen max_num = in_num ? in_num : UBOOT_NUM; 19123ba6841SJoseph Chen loader_addr = 19223ba6841SJoseph Chen (in_loader_addr == -1) ? RK_UBOOT_RUNNING_ADDR : in_loader_addr; 19323ba6841SJoseph Chen } else if (image == IMAGE_TRUST) { 19423ba6841SJoseph Chen name = TRUST_NAME; 19523ba6841SJoseph Chen magic = RK_TRUST_MAGIC; 19623ba6841SJoseph Chen version = TRUST_VERSION_STRING; 19723ba6841SJoseph Chen max_size = in_size ? in_size : TRUST_MAX_SIZE; 19823ba6841SJoseph Chen max_num = in_num ? in_num : TRUST_NUM; 19923ba6841SJoseph Chen loader_addr = 20023ba6841SJoseph Chen (in_loader_addr == -1) ? RK_TRUST_RUNNING_ADDR : in_loader_addr; 20123ba6841SJoseph Chen } else if (mode == MODE_INFO) { 20223ba6841SJoseph Chen 20323ba6841SJoseph Chen } else { 20423ba6841SJoseph Chen exit(EXIT_FAILURE); 20523ba6841SJoseph Chen } 20623ba6841SJoseph Chen 20723ba6841SJoseph Chen if (mode == MODE_PACK) { 20823ba6841SJoseph Chen buf = calloc(max_size, max_num); 20923ba6841SJoseph Chen if (!buf) { 21023ba6841SJoseph Chen perror(file_out); 21123ba6841SJoseph Chen exit(EXIT_FAILURE); 21223ba6841SJoseph Chen } 21323ba6841SJoseph Chen printf("\n load addr is 0x%x!\n", loader_addr); 214*52243bceSJoseph Chen 215*52243bceSJoseph Chen /* Add prepath for file_in name */ 216*52243bceSJoseph Chen if (prepath && strncmp(prepath, file_in, strlen(prepath))) { 217*52243bceSJoseph Chen strcpy(file_name, prepath); 218*52243bceSJoseph Chen strcat(file_name, file_in); 219*52243bceSJoseph Chen file_in = file_name; 220*52243bceSJoseph Chen } 221*52243bceSJoseph Chen 22223ba6841SJoseph Chen if (!file_in || !file_out) { 22323ba6841SJoseph Chen usage(argv[0]); 22423ba6841SJoseph Chen exit(EXIT_FAILURE); 22523ba6841SJoseph Chen } 22623ba6841SJoseph Chen 22723ba6841SJoseph Chen /* file in */ 22823ba6841SJoseph Chen fi = fopen(file_in, "rb"); 22923ba6841SJoseph Chen if (!fi) { 23023ba6841SJoseph Chen perror(file_in); 23123ba6841SJoseph Chen exit(EXIT_FAILURE); 23223ba6841SJoseph Chen } 23323ba6841SJoseph Chen 23423ba6841SJoseph Chen /* file out */ 23523ba6841SJoseph Chen fo = fopen(file_out, "wb"); 23623ba6841SJoseph Chen if (!fo) { 23723ba6841SJoseph Chen perror(file_out); 23823ba6841SJoseph Chen exit(EXIT_FAILURE); 23923ba6841SJoseph Chen } 24023ba6841SJoseph Chen 24123ba6841SJoseph Chen printf("pack input %s \n", file_in); 24223ba6841SJoseph Chen fseek(fi, 0, SEEK_END); 24323ba6841SJoseph Chen size = ftell(fi); 24423ba6841SJoseph Chen fseek(fi, 0, SEEK_SET); 2452bbbd780SJoseph Chen printf("pack file size: %d(%d KB)\n", size, size / 1024); 24623ba6841SJoseph Chen if (size > max_size - sizeof(second_loader_hdr)) { 24723ba6841SJoseph Chen perror(file_out); 24823ba6841SJoseph Chen exit(EXIT_FAILURE); 24923ba6841SJoseph Chen } 25023ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr)); 25123ba6841SJoseph Chen memcpy((char *)hdr.magic, magic, LOADER_MAGIC_SIZE); 25223ba6841SJoseph Chen hdr.version = curr_version; 25323ba6841SJoseph Chen hdr.loader_load_addr = loader_addr; 25423ba6841SJoseph Chen if (!fread(buf + sizeof(second_loader_hdr), size, 1, fi)) 25523ba6841SJoseph Chen exit(EXIT_FAILURE); 25623ba6841SJoseph Chen 25723ba6841SJoseph Chen /* Aligned size to 4-byte, Rockchip HW Crypto need 4-byte align */ 25823ba6841SJoseph Chen size = (((size + 3) >> 2) << 2); 25923ba6841SJoseph Chen hdr.loader_load_size = size; 26023ba6841SJoseph Chen 26123ba6841SJoseph Chen hdr.crc32 = crc32_rk( 26223ba6841SJoseph Chen 0, (const unsigned char *)buf + sizeof(second_loader_hdr), size); 26323ba6841SJoseph Chen printf("crc = 0x%08x\n", hdr.crc32); 26423ba6841SJoseph Chen 26523ba6841SJoseph Chen #ifndef CONFIG_SECUREBOOT_SHA256 26623ba6841SJoseph Chen SHA_CTX ctx; 26723ba6841SJoseph Chen uint8_t *sha; 26823ba6841SJoseph Chen hdr.hash_len = (SHA_DIGEST_SIZE > LOADER_HASH_SIZE) ? LOADER_HASH_SIZE 26923ba6841SJoseph Chen : SHA_DIGEST_SIZE; 27023ba6841SJoseph Chen SHA_init(&ctx); 27123ba6841SJoseph Chen SHA_update(&ctx, buf + sizeof(second_loader_hdr), size); 27223ba6841SJoseph Chen if (hdr.version > 0) 27323ba6841SJoseph Chen SHA_update(&ctx, (void *)&hdr.version, 8); 27423ba6841SJoseph Chen 27523ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_addr, sizeof(hdr.loader_load_addr)); 27623ba6841SJoseph Chen SHA_update(&ctx, &hdr.loader_load_size, sizeof(hdr.loader_load_size)); 27723ba6841SJoseph Chen SHA_update(&ctx, &hdr.hash_len, sizeof(hdr.hash_len)); 27823ba6841SJoseph Chen sha = (uint8_t *)SHA_final(&ctx); 27923ba6841SJoseph Chen memcpy(hdr.hash, sha, hdr.hash_len); 28023ba6841SJoseph Chen #else 28123ba6841SJoseph Chen sha256_context ctx; 28223ba6841SJoseph Chen uint8_t hash[LOADER_HASH_SIZE]; 28323ba6841SJoseph Chen 28423ba6841SJoseph Chen memset(hash, 0, LOADER_HASH_SIZE); 28523ba6841SJoseph Chen 28623ba6841SJoseph Chen hdr.hash_len = 32; /* sha256 */ 28723ba6841SJoseph Chen sha256_starts(&ctx); 28823ba6841SJoseph Chen sha256_update(&ctx, (void *)buf + sizeof(second_loader_hdr), size); 28923ba6841SJoseph Chen if (hdr.version > 0) 29023ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.version, 8); 29123ba6841SJoseph Chen 29223ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_addr, 29323ba6841SJoseph Chen sizeof(hdr.loader_load_addr)); 29423ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.loader_load_size, 29523ba6841SJoseph Chen sizeof(hdr.loader_load_size)); 29623ba6841SJoseph Chen sha256_update(&ctx, (void *)&hdr.hash_len, sizeof(hdr.hash_len)); 29723ba6841SJoseph Chen sha256_finish(&ctx, hash); 29823ba6841SJoseph Chen memcpy(hdr.hash, hash, hdr.hash_len); 29923ba6841SJoseph Chen #endif /* CONFIG_SECUREBOOT_SHA256 */ 30023ba6841SJoseph Chen 30123ba6841SJoseph Chen printf("%s version: %s\n", name, version); 30223ba6841SJoseph Chen memcpy(buf, &hdr, sizeof(second_loader_hdr)); 30323ba6841SJoseph Chen for (i = 0; i < max_num; i++) 30423ba6841SJoseph Chen fwrite(buf, max_size, 1, fo); 30523ba6841SJoseph Chen 30623ba6841SJoseph Chen printf("pack %s success! \n", file_out); 30723ba6841SJoseph Chen fclose(fi); 30823ba6841SJoseph Chen fclose(fo); 30923ba6841SJoseph Chen } else if (mode == MODE_UNPACK) { 31023ba6841SJoseph Chen buf = calloc(max_size, max_num); 31123ba6841SJoseph Chen if (!buf) { 31223ba6841SJoseph Chen perror(file_out); 31323ba6841SJoseph Chen exit(EXIT_FAILURE); 31423ba6841SJoseph Chen } 31523ba6841SJoseph Chen if (!file_in || !file_out) { 31623ba6841SJoseph Chen usage(argv[0]); 31723ba6841SJoseph Chen exit(EXIT_FAILURE); 31823ba6841SJoseph Chen } 31923ba6841SJoseph Chen 32023ba6841SJoseph Chen /* file in */ 32123ba6841SJoseph Chen fi = fopen(file_in, "rb"); 32223ba6841SJoseph Chen if (!fi) { 32323ba6841SJoseph Chen perror(file_in); 32423ba6841SJoseph Chen exit(EXIT_FAILURE); 32523ba6841SJoseph Chen } 32623ba6841SJoseph Chen 32723ba6841SJoseph Chen /* file out */ 32823ba6841SJoseph Chen fo = fopen(file_out, "wb"); 32923ba6841SJoseph Chen if (!fo) { 33023ba6841SJoseph Chen perror(file_out); 33123ba6841SJoseph Chen exit(EXIT_FAILURE); 33223ba6841SJoseph Chen } 33323ba6841SJoseph Chen 33423ba6841SJoseph Chen printf("unpack input %s \n", file_in); 33523ba6841SJoseph Chen memset(&hdr, 0, sizeof(second_loader_hdr)); 33623ba6841SJoseph Chen if (!fread(&hdr, sizeof(second_loader_hdr), 1, fi)) 33723ba6841SJoseph Chen exit(EXIT_FAILURE); 33823ba6841SJoseph Chen 33923ba6841SJoseph Chen if (!fread(buf, hdr.loader_load_size, 1, fi)) 34023ba6841SJoseph Chen exit(EXIT_FAILURE); 34123ba6841SJoseph Chen 34223ba6841SJoseph Chen fwrite(buf, hdr.loader_load_size, 1, fo); 34323ba6841SJoseph Chen printf("unpack %s success! \n", file_out); 34423ba6841SJoseph Chen fclose(fi); 34523ba6841SJoseph Chen fclose(fo); 34623ba6841SJoseph Chen } else if (mode == MODE_INFO) { 34723ba6841SJoseph Chen second_loader_hdr *hdr; 34823ba6841SJoseph Chen 34923ba6841SJoseph Chen hdr = malloc(sizeof(struct tag_second_loader_hdr)); 35023ba6841SJoseph Chen if (hdr == NULL) { 35123ba6841SJoseph Chen printf("Memory error!\n"); 35223ba6841SJoseph Chen exit(EXIT_FAILURE); 35323ba6841SJoseph Chen } 35423ba6841SJoseph Chen /* file in */ 35523ba6841SJoseph Chen fi = fopen(file_in, "rb"); 35623ba6841SJoseph Chen if (!fi) { 35723ba6841SJoseph Chen perror(file_in); 35823ba6841SJoseph Chen exit(EXIT_FAILURE); 35923ba6841SJoseph Chen } 36023ba6841SJoseph Chen 36123ba6841SJoseph Chen if (!fread(hdr, sizeof(struct tag_second_loader_hdr), 1, fi)) 36223ba6841SJoseph Chen exit(EXIT_FAILURE); 36323ba6841SJoseph Chen 36423ba6841SJoseph Chen if (!(memcmp(RK_UBOOT_MAGIC, hdr->magic, 5)) || 36523ba6841SJoseph Chen !(memcmp(RK_TRUST_MAGIC, hdr->magic, 3))) { 36623ba6841SJoseph Chen printf("The image info:\n"); 36723ba6841SJoseph Chen printf("Rollback index is %d\n", hdr->version); 36823ba6841SJoseph Chen printf("Load Addr is 0x%x\n", hdr->loader_load_addr); 36923ba6841SJoseph Chen } else { 37023ba6841SJoseph Chen printf("Please input the correct file.\n"); 37123ba6841SJoseph Chen } 37223ba6841SJoseph Chen 37323ba6841SJoseph Chen fclose(fi); 37423ba6841SJoseph Chen free(hdr); 37523ba6841SJoseph Chen } 37623ba6841SJoseph Chen free(buf); 37723ba6841SJoseph Chen 37823ba6841SJoseph Chen return 0; 37923ba6841SJoseph Chen } 380