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