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