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