2 * Image manipulator for Marvell SoCs
3 * supports Kirkwood, Dove, Armada 370, Armada XP, and Armada 38x
5 * (C) Copyright 2013 Thomas Petazzoni
6 * <thomas.petazzoni@free-electrons.com>
8 * SPDX-License-Identifier: GPL-2.0+
10 * Not implemented: support for the register headers in v1 images
13 #include "imagetool.h"
20 #ifdef CONFIG_KWB_SECURE
21 #include <openssl/rsa.h>
22 #include <openssl/pem.h>
23 #include <openssl/err.h>
24 #include <openssl/evp.h>
27 static struct image_cfg_element *image_cfg;
29 #ifdef CONFIG_KWB_SECURE
30 static int verbose_mode;
45 struct boot_mode boot_modes[] = {
56 struct nand_ecc_mode {
61 struct nand_ecc_mode nand_ecc_modes[] = {
69 /* Used to identify an undefined execution or destination address */
70 #define ADDR_INVALID ((uint32_t)-1)
72 #define BINARY_MAX_ARGS 8
74 /* In-memory representation of a line of the configuration file */
77 IMAGE_CFG_VERSION = 0x1,
82 IMAGE_CFG_NAND_BADBLK_LOCATION,
83 IMAGE_CFG_NAND_ECC_MODE,
84 IMAGE_CFG_NAND_PAGESZ,
96 IMAGE_CFG_SEC_COMMON_IMG,
97 IMAGE_CFG_SEC_SPECIALIZED_IMG,
98 IMAGE_CFG_SEC_BOOT_DEV,
99 IMAGE_CFG_SEC_FUSE_DUMP,
104 static const char * const id_strs[] = {
105 [IMAGE_CFG_VERSION] = "VERSION",
106 [IMAGE_CFG_BOOT_FROM] = "BOOT_FROM",
107 [IMAGE_CFG_DEST_ADDR] = "DEST_ADDR",
108 [IMAGE_CFG_EXEC_ADDR] = "EXEC_ADDR",
109 [IMAGE_CFG_NAND_BLKSZ] = "NAND_BLKSZ",
110 [IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
111 [IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
112 [IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
113 [IMAGE_CFG_BINARY] = "BINARY",
114 [IMAGE_CFG_PAYLOAD] = "PAYLOAD",
115 [IMAGE_CFG_DATA] = "DATA",
116 [IMAGE_CFG_BAUDRATE] = "BAUDRATE",
117 [IMAGE_CFG_DEBUG] = "DEBUG",
118 [IMAGE_CFG_KAK] = "KAK",
119 [IMAGE_CFG_CSK] = "CSK",
120 [IMAGE_CFG_CSK_INDEX] = "CSK_INDEX",
121 [IMAGE_CFG_JTAG_DELAY] = "JTAG_DELAY",
122 [IMAGE_CFG_BOX_ID] = "BOX_ID",
123 [IMAGE_CFG_FLASH_ID] = "FLASH_ID",
124 [IMAGE_CFG_SEC_COMMON_IMG] = "SEC_COMMON_IMG",
125 [IMAGE_CFG_SEC_SPECIALIZED_IMG] = "SEC_SPECIALIZED_IMG",
126 [IMAGE_CFG_SEC_BOOT_DEV] = "SEC_BOOT_DEV",
127 [IMAGE_CFG_SEC_FUSE_DUMP] = "SEC_FUSE_DUMP"
130 struct image_cfg_element {
131 enum image_cfg_type type;
133 unsigned int version;
134 unsigned int bootfrom;
137 unsigned int args[BINARY_MAX_ARGS];
141 unsigned int dstaddr;
142 unsigned int execaddr;
143 unsigned int nandblksz;
144 unsigned int nandbadblklocation;
145 unsigned int nandeccmode;
146 unsigned int nandpagesz;
147 struct ext_hdr_v0_reg regdata;
148 unsigned int baudrate;
150 const char *key_name;
155 bool sec_specialized_img;
156 unsigned int sec_boot_dev;
161 #define IMAGE_CFG_ELEMENT_MAX 256
164 * Utility functions to manipulate boot mode and ecc modes (convert
165 * them back and forth between description strings and the
166 * corresponding numerical identifiers).
169 static const char *image_boot_mode_name(unsigned int id)
173 for (i = 0; boot_modes[i].name; i++)
174 if (boot_modes[i].id == id)
175 return boot_modes[i].name;
179 int image_boot_mode_id(const char *boot_mode_name)
183 for (i = 0; boot_modes[i].name; i++)
184 if (!strcmp(boot_modes[i].name, boot_mode_name))
185 return boot_modes[i].id;
190 int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
194 for (i = 0; nand_ecc_modes[i].name; i++)
195 if (!strcmp(nand_ecc_modes[i].name, nand_ecc_mode_name))
196 return nand_ecc_modes[i].id;
200 static struct image_cfg_element *
201 image_find_option(unsigned int optiontype)
205 for (i = 0; i < cfgn; i++) {
206 if (image_cfg[i].type == optiontype)
207 return &image_cfg[i];
214 image_count_options(unsigned int optiontype)
217 unsigned int count = 0;
219 for (i = 0; i < cfgn; i++)
220 if (image_cfg[i].type == optiontype)
226 #if defined(CONFIG_KWB_SECURE)
228 static int image_get_csk_index(void)
230 struct image_cfg_element *e;
232 e = image_find_option(IMAGE_CFG_CSK_INDEX);
239 static bool image_get_spezialized_img(void)
241 struct image_cfg_element *e;
243 e = image_find_option(IMAGE_CFG_SEC_SPECIALIZED_IMG);
247 return e->sec_specialized_img;
253 * Compute a 8-bit checksum of a memory area. This algorithm follows
254 * the requirements of the Marvell SoC BootROM specifications.
256 static uint8_t image_checksum8(void *start, uint32_t len)
261 /* check len and return zero checksum if invalid */
273 static uint32_t image_checksum32(void *start, uint32_t len)
278 /* check len and return zero checksum if invalid */
282 if (len % sizeof(uint32_t)) {
283 fprintf(stderr, "Length %d is not in multiple of %zu\n",
284 len, sizeof(uint32_t));
291 len -= sizeof(uint32_t);
297 static uint8_t baudrate_to_option(unsigned int baudrate)
301 return MAIN_HDR_V1_OPT_BAUD_2400;
303 return MAIN_HDR_V1_OPT_BAUD_4800;
305 return MAIN_HDR_V1_OPT_BAUD_9600;
307 return MAIN_HDR_V1_OPT_BAUD_19200;
309 return MAIN_HDR_V1_OPT_BAUD_38400;
311 return MAIN_HDR_V1_OPT_BAUD_57600;
313 return MAIN_HDR_V1_OPT_BAUD_115200;
315 return MAIN_HDR_V1_OPT_BAUD_DEFAULT;
319 #if defined(CONFIG_KWB_SECURE)
320 static void kwb_msg(const char *fmt, ...)
326 vfprintf(stdout, fmt, ap);
331 static int openssl_err(const char *msg)
333 unsigned long ssl_err = ERR_get_error();
335 fprintf(stderr, "%s", msg);
336 fprintf(stderr, ": %s\n",
337 ERR_error_string(ssl_err, 0));
342 static int kwb_load_rsa_key(const char *keydir, const char *name, RSA **p_rsa)
351 snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
352 f = fopen(path, "r");
354 fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n",
355 path, strerror(errno));
359 rsa = PEM_read_RSAPrivateKey(f, 0, NULL, "");
361 openssl_err("Failure reading private key");
371 static int kwb_load_cfg_key(struct image_tool_params *params,
372 unsigned int cfg_option, const char *key_name,
375 struct image_cfg_element *e_key;
381 e_key = image_find_option(cfg_option);
383 fprintf(stderr, "%s not configured\n", key_name);
387 res = kwb_load_rsa_key(params->keydir, e_key->key_name, &key);
389 fprintf(stderr, "Failed to load %s\n", key_name);
398 static int kwb_load_kak(struct image_tool_params *params, RSA **p_kak)
400 return kwb_load_cfg_key(params, IMAGE_CFG_KAK, "KAK", p_kak);
403 static int kwb_load_csk(struct image_tool_params *params, RSA **p_csk)
405 return kwb_load_cfg_key(params, IMAGE_CFG_CSK, "CSK", p_csk);
408 static int kwb_compute_pubkey_hash(struct pubkey_der_v1 *pk,
409 struct hash_v1 *hash)
412 unsigned int key_size;
413 unsigned int hash_size;
416 if (!pk || !hash || pk->key[0] != 0x30 || pk->key[1] != 0x82)
419 key_size = (pk->key[2] << 8) + pk->key[3] + 4;
421 ctx = EVP_MD_CTX_create();
423 return openssl_err("EVP context creation failed");
425 EVP_MD_CTX_init(ctx);
426 if (!EVP_DigestInit(ctx, EVP_sha256())) {
427 ret = openssl_err("Digest setup failed");
431 if (!EVP_DigestUpdate(ctx, pk->key, key_size)) {
432 ret = openssl_err("Hashing data failed");
436 if (!EVP_DigestFinal(ctx, hash->hash, &hash_size)) {
437 ret = openssl_err("Could not obtain hash");
441 EVP_MD_CTX_cleanup(ctx);
444 EVP_MD_CTX_destroy(ctx);
448 static int kwb_import_pubkey(RSA **key, struct pubkey_der_v1 *src, char *keyname)
451 const unsigned char *ptr;
457 rsa = d2i_RSAPublicKey(key, &ptr, sizeof(src->key));
459 openssl_err("error decoding public key");
465 fprintf(stderr, "Failed to decode %s pubkey\n", keyname);
469 static int kwb_export_pubkey(RSA *key, struct pubkey_der_v1 *dst, FILE *hashf,
472 int size_exp, size_mod, size_seq;
474 char *errmsg = "Failed to encode %s\n";
476 if (!key || !key->e || !key->n || !dst) {
477 fprintf(stderr, "export pk failed: (%p, %p, %p, %p)",
478 key, key->e, key->n, dst);
479 fprintf(stderr, errmsg, keyname);
484 * According to the specs, the key should be PKCS#1 DER encoded.
485 * But unfortunately the really required encoding seems to be different;
486 * it violates DER...! (But it still conformes to BER.)
487 * (Length always in long form w/ 2 byte length code; no leading zero
488 * when MSB of first byte is set...)
489 * So we cannot use the encoding func provided by OpenSSL and have to
490 * do the encoding manually.
493 size_exp = BN_num_bytes(key->e);
494 size_mod = BN_num_bytes(key->n);
495 size_seq = 4 + size_mod + 4 + size_exp;
497 if (size_mod > 256) {
498 fprintf(stderr, "export pk failed: wrong mod size: %d\n",
500 fprintf(stderr, errmsg, keyname);
504 if (4 + size_seq > sizeof(dst->key)) {
505 fprintf(stderr, "export pk failed: seq too large (%d, %lu)\n",
506 4 + size_seq, sizeof(dst->key));
507 fprintf(stderr, errmsg, keyname);
513 /* PKCS#1 (RFC3447) RSAPublicKey structure */
514 *cur++ = 0x30; /* SEQUENCE */
516 *cur++ = (size_seq >> 8) & 0xFF;
517 *cur++ = size_seq & 0xFF;
519 *cur++ = 0x02; /* INTEGER */
521 *cur++ = (size_mod >> 8) & 0xFF;
522 *cur++ = size_mod & 0xFF;
523 BN_bn2bin(key->n, cur);
526 *cur++ = 0x02; /* INTEGER */
528 *cur++ = (size_exp >> 8) & 0xFF;
529 *cur++ = size_exp & 0xFF;
530 BN_bn2bin(key->e, cur);
533 struct hash_v1 pk_hash;
537 ret = kwb_compute_pubkey_hash(dst, &pk_hash);
539 fprintf(stderr, errmsg, keyname);
543 fprintf(hashf, "SHA256 = ");
544 for (i = 0 ; i < sizeof(pk_hash.hash); ++i)
545 fprintf(hashf, "%02X", pk_hash.hash[i]);
546 fprintf(hashf, "\n");
552 int kwb_sign(RSA *key, void *data, int datasz, struct sig_v1 *sig, char *signame)
556 unsigned int sig_size;
560 evp_key = EVP_PKEY_new();
562 return openssl_err("EVP_PKEY object creation failed");
564 if (!EVP_PKEY_set1_RSA(evp_key, key)) {
565 ret = openssl_err("EVP key setup failed");
569 size = EVP_PKEY_size(evp_key);
570 if (size > sizeof(sig->sig)) {
571 fprintf(stderr, "Buffer to small for signature (%d bytes)\n",
577 ctx = EVP_MD_CTX_create();
579 ret = openssl_err("EVP context creation failed");
582 EVP_MD_CTX_init(ctx);
583 if (!EVP_SignInit(ctx, EVP_sha256())) {
584 ret = openssl_err("Signer setup failed");
588 if (!EVP_SignUpdate(ctx, data, datasz)) {
589 ret = openssl_err("Signing data failed");
593 if (!EVP_SignFinal(ctx, sig->sig, &sig_size, evp_key)) {
594 ret = openssl_err("Could not obtain signature");
598 EVP_MD_CTX_cleanup(ctx);
599 EVP_MD_CTX_destroy(ctx);
600 EVP_PKEY_free(evp_key);
605 EVP_MD_CTX_destroy(ctx);
607 EVP_PKEY_free(evp_key);
608 fprintf(stderr, "Failed to create %s signature\n", signame);
612 int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
620 evp_key = EVP_PKEY_new();
622 return openssl_err("EVP_PKEY object creation failed");
624 if (!EVP_PKEY_set1_RSA(evp_key, key)) {
625 ret = openssl_err("EVP key setup failed");
629 size = EVP_PKEY_size(evp_key);
630 if (size > sizeof(sig->sig)) {
631 fprintf(stderr, "Invalid signature size (%d bytes)\n",
637 ctx = EVP_MD_CTX_create();
639 ret = openssl_err("EVP context creation failed");
642 EVP_MD_CTX_init(ctx);
643 if (!EVP_VerifyInit(ctx, EVP_sha256())) {
644 ret = openssl_err("Verifier setup failed");
648 if (!EVP_VerifyUpdate(ctx, data, datasz)) {
649 ret = openssl_err("Hashing data failed");
653 if (!EVP_VerifyFinal(ctx, sig->sig, sizeof(sig->sig), evp_key)) {
654 ret = openssl_err("Could not verify signature");
658 EVP_MD_CTX_cleanup(ctx);
659 EVP_MD_CTX_destroy(ctx);
660 EVP_PKEY_free(evp_key);
665 EVP_MD_CTX_destroy(ctx);
667 EVP_PKEY_free(evp_key);
668 fprintf(stderr, "Failed to verify %s signature\n", signame);
672 int kwb_sign_and_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
675 if (kwb_sign(key, data, datasz, sig, signame) < 0)
678 if (kwb_verify(key, data, datasz, sig, signame) < 0)
685 int kwb_dump_fuse_cmds_38x(FILE *out, struct secure_hdr_v1 *sec_hdr)
687 struct hash_v1 kak_pub_hash;
688 struct image_cfg_element *e;
689 unsigned int fuse_line;
695 if (!out || !sec_hdr)
698 ret = kwb_compute_pubkey_hash(&sec_hdr->kak, &kak_pub_hash);
702 fprintf(out, "# burn KAK pub key hash\n");
703 ptr = kak_pub_hash.hash;
704 for (fuse_line = 26; fuse_line <= 30; ++fuse_line) {
705 fprintf(out, "fuse prog -y %u 0 ", fuse_line);
707 for (i = 4; i-- > 0;)
708 fprintf(out, "%02hx", (ushort)ptr[i]);
712 if (fuse_line < 30) {
713 for (i = 3; i-- > 0;)
714 fprintf(out, "%02hx", (ushort)ptr[i]);
717 fprintf(out, "000000");
720 fprintf(out, " 1\n");
723 fprintf(out, "# burn CSK selection\n");
725 idx = image_get_csk_index();
726 if (idx < 0 || idx > 15) {
731 for (fuse_line = 31; fuse_line < 31 + idx; ++fuse_line)
732 fprintf(out, "fuse prog -y %u 0 00000001 00000000 1\n",
735 fprintf(out, "# CSK index is 0; no mods needed\n");
738 e = image_find_option(IMAGE_CFG_BOX_ID);
740 fprintf(out, "# set box ID\n");
741 fprintf(out, "fuse prog -y 48 0 %08x 00000000 1\n", e->boxid);
744 e = image_find_option(IMAGE_CFG_FLASH_ID);
746 fprintf(out, "# set flash ID\n");
747 fprintf(out, "fuse prog -y 47 0 %08x 00000000 1\n", e->flashid);
750 fprintf(out, "# enable secure mode ");
751 fprintf(out, "(must be the last fuse line written)\n");
754 e = image_find_option(IMAGE_CFG_SEC_BOOT_DEV);
756 fprintf(stderr, "ERROR: secured mode boot device not given\n");
761 if (e->sec_boot_dev > 0xff) {
762 fprintf(stderr, "ERROR: secured mode boot device invalid\n");
767 val |= (e->sec_boot_dev << 8);
769 fprintf(out, "fuse prog -y 24 0 %08x 0103e0a9 1\n", val);
771 fprintf(out, "# lock (unused) fuse lines (0-23)s\n");
772 for (fuse_line = 0; fuse_line < 24; ++fuse_line)
773 fprintf(out, "fuse prog -y %u 2 1\n", fuse_line);
775 fprintf(out, "# OK, that's all :-)\n");
781 static int kwb_dump_fuse_cmds(struct secure_hdr_v1 *sec_hdr)
784 struct image_cfg_element *e;
786 e = image_find_option(IMAGE_CFG_SEC_FUSE_DUMP);
790 if (!strcmp(e->name, "a38x")) {
791 FILE *out = fopen("kwb_fuses_a38x.txt", "w+");
793 kwb_dump_fuse_cmds_38x(out, sec_hdr);
806 static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
809 struct image_cfg_element *e;
811 struct main_hdr_v0 *main_hdr;
816 * Calculate the size of the header and the size of the
819 headersz = sizeof(struct main_hdr_v0);
821 if (image_count_options(IMAGE_CFG_DATA) > 0) {
823 headersz += sizeof(struct ext_hdr_v0);
826 if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
827 fprintf(stderr, "More than one payload, not possible\n");
831 image = malloc(headersz);
833 fprintf(stderr, "Cannot allocate memory for image\n");
837 memset(image, 0, headersz);
839 main_hdr = (struct main_hdr_v0 *)image;
841 /* Fill in the main header */
842 main_hdr->blocksize =
843 cpu_to_le32(payloadsz + sizeof(uint32_t) - headersz);
844 main_hdr->srcaddr = cpu_to_le32(headersz);
845 main_hdr->ext = has_ext;
846 main_hdr->destaddr = cpu_to_le32(params->addr);
847 main_hdr->execaddr = cpu_to_le32(params->ep);
849 e = image_find_option(IMAGE_CFG_BOOT_FROM);
851 main_hdr->blockid = e->bootfrom;
852 e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
854 main_hdr->nandeccmode = e->nandeccmode;
855 e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
857 main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
858 main_hdr->checksum = image_checksum8(image,
859 sizeof(struct main_hdr_v0));
861 /* Generate the ext header */
863 struct ext_hdr_v0 *ext_hdr;
866 ext_hdr = (struct ext_hdr_v0 *)
867 (image + sizeof(struct main_hdr_v0));
868 ext_hdr->offset = cpu_to_le32(0x40);
870 for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) {
871 e = &image_cfg[cfgi];
872 if (e->type != IMAGE_CFG_DATA)
875 ext_hdr->rcfg[datai].raddr =
876 cpu_to_le32(e->regdata.raddr);
877 ext_hdr->rcfg[datai].rdata =
878 cpu_to_le32(e->regdata.rdata);
882 ext_hdr->checksum = image_checksum8(ext_hdr,
883 sizeof(struct ext_hdr_v0));
890 static size_t image_headersz_v1(int *hasext)
892 struct image_cfg_element *binarye;
896 * Calculate the size of the header and the size of the
899 headersz = sizeof(struct main_hdr_v1);
901 if (image_count_options(IMAGE_CFG_BINARY) > 1) {
902 fprintf(stderr, "More than one binary blob, not supported\n");
906 if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
907 fprintf(stderr, "More than one payload, not possible\n");
911 binarye = image_find_option(IMAGE_CFG_BINARY);
916 ret = stat(binarye->binary.file, &s);
921 memset(cwd, 0, sizeof(cwd));
922 if (!getcwd(cwd, sizeof(cwd))) {
923 dir = "current working directory";
924 perror("getcwd() failed");
928 "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
929 "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
930 "image for your board. See 'kwbimage -x' to extract it from an existing image.\n",
931 binarye->binary.file, dir);
935 headersz += sizeof(struct opt_hdr_v1) +
937 (binarye->binary.nargs + 2) * sizeof(uint32_t);
942 #if defined(CONFIG_KWB_SECURE)
943 if (image_get_csk_index() >= 0) {
944 headersz += sizeof(struct secure_hdr_v1);
950 #if defined(CONFIG_SYS_U_BOOT_OFFS)
951 if (headersz > CONFIG_SYS_U_BOOT_OFFS) {
953 "Error: Image header (incl. SPL image) too big!\n");
954 fprintf(stderr, "header=0x%x CONFIG_SYS_U_BOOT_OFFS=0x%x!\n",
955 (int)headersz, CONFIG_SYS_U_BOOT_OFFS);
956 fprintf(stderr, "Increase CONFIG_SYS_U_BOOT_OFFS!\n");
960 headersz = CONFIG_SYS_U_BOOT_OFFS;
964 * The payload should be aligned on some reasonable
967 return ALIGN_SUP(headersz, 4096);
970 int add_binary_header_v1(uint8_t *cur)
972 struct image_cfg_element *binarye;
973 struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)cur;
981 binarye = image_find_option(IMAGE_CFG_BINARY);
986 hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
988 bin = fopen(binarye->binary.file, "r");
990 fprintf(stderr, "Cannot open binary file %s\n",
991 binarye->binary.file);
995 if (fstat(fileno(bin), &s)) {
996 fprintf(stderr, "Cannot stat binary file %s\n",
997 binarye->binary.file);
1001 binhdrsz = sizeof(struct opt_hdr_v1) +
1002 (binarye->binary.nargs + 2) * sizeof(uint32_t) +
1006 * The size includes the binary image size, rounded
1007 * up to a 4-byte boundary. Plus 4 bytes for the
1008 * next-header byte and 3-byte alignment at the end.
1010 binhdrsz = ALIGN_SUP(binhdrsz, 4) + 4;
1011 hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
1012 hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
1014 cur += sizeof(struct opt_hdr_v1);
1016 args = (uint32_t *)cur;
1017 *args = cpu_to_le32(binarye->binary.nargs);
1019 for (argi = 0; argi < binarye->binary.nargs; argi++)
1020 args[argi] = cpu_to_le32(binarye->binary.args[argi]);
1022 cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
1024 ret = fread(cur, s.st_size, 1, bin);
1027 "Could not read binary image %s\n",
1028 binarye->binary.file);
1034 cur += ALIGN_SUP(s.st_size, 4);
1037 * For now, we don't support more than one binary
1038 * header, and no other header types are
1039 * supported. So, the binary header is necessarily the
1042 *((uint32_t *)cur) = 0x00000000;
1044 cur += sizeof(uint32_t);
1054 #if defined(CONFIG_KWB_SECURE)
1056 int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
1061 hashf = fopen("pub_kak_hash.txt", "w");
1063 res = kwb_export_pubkey(kak, &secure_hdr->kak, hashf, "KAK");
1067 return res < 0 ? 1 : 0;
1070 int kwb_sign_csk_with_kak(struct image_tool_params *params,
1071 struct secure_hdr_v1 *secure_hdr, RSA *csk)
1074 RSA *kak_pub = NULL;
1075 int csk_idx = image_get_csk_index();
1076 struct sig_v1 tmp_sig;
1078 if (csk_idx >= 16) {
1079 fprintf(stderr, "Invalid CSK index %d\n", csk_idx);
1083 if (kwb_load_kak(params, &kak) < 0)
1086 if (export_pub_kak_hash(kak, secure_hdr))
1089 if (kwb_import_pubkey(&kak_pub, &secure_hdr->kak, "KAK") < 0)
1092 if (kwb_export_pubkey(csk, &secure_hdr->csk[csk_idx], NULL, "CSK") < 0)
1095 if (kwb_sign_and_verify(kak, &secure_hdr->csk,
1096 sizeof(secure_hdr->csk) +
1097 sizeof(secure_hdr->csksig),
1098 &tmp_sig, "CSK") < 0)
1101 if (kwb_verify(kak_pub, &secure_hdr->csk,
1102 sizeof(secure_hdr->csk) +
1103 sizeof(secure_hdr->csksig),
1104 &tmp_sig, "CSK (2)") < 0)
1107 secure_hdr->csksig = tmp_sig;
1112 int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
1113 int payloadsz, size_t headersz, uint8_t *image,
1114 struct secure_hdr_v1 *secure_hdr)
1116 struct image_cfg_element *e_jtagdelay;
1117 struct image_cfg_element *e_boxid;
1118 struct image_cfg_element *e_flashid;
1120 unsigned char *image_ptr;
1122 struct sig_v1 tmp_sig;
1123 bool specialized_img = image_get_spezialized_img();
1125 kwb_msg("Create secure header content\n");
1127 e_jtagdelay = image_find_option(IMAGE_CFG_JTAG_DELAY);
1128 e_boxid = image_find_option(IMAGE_CFG_BOX_ID);
1129 e_flashid = image_find_option(IMAGE_CFG_FLASH_ID);
1131 if (kwb_load_csk(params, &csk) < 0)
1134 secure_hdr->headertype = OPT_HDR_V1_SECURE_TYPE;
1135 secure_hdr->headersz_msb = 0;
1136 secure_hdr->headersz_lsb = cpu_to_le16(sizeof(struct secure_hdr_v1));
1138 secure_hdr->jtag_delay = e_jtagdelay->jtag_delay;
1139 if (e_boxid && specialized_img)
1140 secure_hdr->boxid = cpu_to_le32(e_boxid->boxid);
1141 if (e_flashid && specialized_img)
1142 secure_hdr->flashid = cpu_to_le32(e_flashid->flashid);
1144 if (kwb_sign_csk_with_kak(params, secure_hdr, csk))
1147 image_ptr = ptr + headersz;
1148 image_size = payloadsz - headersz;
1150 if (kwb_sign_and_verify(csk, image_ptr, image_size,
1151 &secure_hdr->imgsig, "image") < 0)
1154 if (kwb_sign_and_verify(csk, image, headersz, &tmp_sig, "header") < 0)
1157 secure_hdr->hdrsig = tmp_sig;
1159 kwb_dump_fuse_cmds(secure_hdr);
1165 static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
1166 uint8_t *ptr, int payloadsz)
1168 struct image_cfg_element *e;
1169 struct main_hdr_v1 *main_hdr;
1170 #if defined(CONFIG_KWB_SECURE)
1171 struct secure_hdr_v1 *secure_hdr = NULL;
1174 uint8_t *image, *cur;
1176 uint8_t *next_ext = NULL;
1179 * Calculate the size of the header and the size of the
1182 headersz = image_headersz_v1(&hasext);
1186 image = malloc(headersz);
1188 fprintf(stderr, "Cannot allocate memory for image\n");
1192 memset(image, 0, headersz);
1194 main_hdr = (struct main_hdr_v1 *)image;
1196 cur += sizeof(struct main_hdr_v1);
1197 next_ext = &main_hdr->ext;
1199 /* Fill the main header */
1200 main_hdr->blocksize =
1201 cpu_to_le32(payloadsz - headersz + sizeof(uint32_t));
1202 main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
1203 main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
1204 main_hdr->destaddr = cpu_to_le32(params->addr)
1205 - sizeof(image_header_t);
1206 main_hdr->execaddr = cpu_to_le32(params->ep);
1207 main_hdr->srcaddr = cpu_to_le32(headersz);
1208 main_hdr->ext = hasext;
1209 main_hdr->version = 1;
1210 e = image_find_option(IMAGE_CFG_BOOT_FROM);
1212 main_hdr->blockid = e->bootfrom;
1213 e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
1215 main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
1216 e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
1218 main_hdr->nandbadblklocation = e->nandbadblklocation;
1219 e = image_find_option(IMAGE_CFG_BAUDRATE);
1221 main_hdr->options = baudrate_to_option(e->baudrate);
1222 e = image_find_option(IMAGE_CFG_DEBUG);
1224 main_hdr->flags = e->debug ? 0x1 : 0;
1226 #if defined(CONFIG_KWB_SECURE)
1227 if (image_get_csk_index() >= 0) {
1229 * only reserve the space here; we fill the header later since
1230 * we need the header to be complete to compute the signatures
1232 secure_hdr = (struct secure_hdr_v1 *)cur;
1233 cur += sizeof(struct secure_hdr_v1);
1234 next_ext = &secure_hdr->next;
1239 if (add_binary_header_v1(cur))
1242 #if defined(CONFIG_KWB_SECURE)
1243 if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz,
1244 headersz, image, secure_hdr))
1248 /* Calculate and set the header checksum */
1249 main_hdr->checksum = image_checksum8(main_hdr, headersz);
1251 *imagesz = headersz;
1255 int recognize_keyword(char *keyword)
1259 for (kw_id = 1; kw_id < IMAGE_CFG_COUNT; ++kw_id)
1260 if (!strcmp(keyword, id_strs[kw_id]))
1266 static int image_create_config_parse_oneline(char *line,
1267 struct image_cfg_element *el)
1269 char *keyword, *saveptr, *value1, *value2;
1270 char delimiters[] = " \t";
1271 int keyword_id, ret, argi;
1272 char *unknown_msg = "Ignoring unknown line '%s'\n";
1274 keyword = strtok_r(line, delimiters, &saveptr);
1275 keyword_id = recognize_keyword(keyword);
1278 fprintf(stderr, unknown_msg, line);
1282 el->type = keyword_id;
1284 value1 = strtok_r(NULL, delimiters, &saveptr);
1287 fprintf(stderr, "Parameter missing in line '%s'\n", line);
1291 switch (keyword_id) {
1292 case IMAGE_CFG_VERSION:
1293 el->version = atoi(value1);
1295 case IMAGE_CFG_BOOT_FROM:
1296 ret = image_boot_mode_id(value1);
1299 fprintf(stderr, "Invalid boot media '%s'\n", value1);
1304 case IMAGE_CFG_NAND_BLKSZ:
1305 el->nandblksz = strtoul(value1, NULL, 16);
1307 case IMAGE_CFG_NAND_BADBLK_LOCATION:
1308 el->nandbadblklocation = strtoul(value1, NULL, 16);
1310 case IMAGE_CFG_NAND_ECC_MODE:
1311 ret = image_nand_ecc_mode_id(value1);
1314 fprintf(stderr, "Invalid NAND ECC mode '%s'\n", value1);
1317 el->nandeccmode = ret;
1319 case IMAGE_CFG_NAND_PAGESZ:
1320 el->nandpagesz = strtoul(value1, NULL, 16);
1322 case IMAGE_CFG_BINARY:
1325 el->binary.file = strdup(value1);
1327 char *value = strtok_r(NULL, delimiters, &saveptr);
1331 el->binary.args[argi] = strtoul(value, NULL, 16);
1333 if (argi >= BINARY_MAX_ARGS) {
1335 "Too many arguments for BINARY\n");
1339 el->binary.nargs = argi;
1341 case IMAGE_CFG_DATA:
1342 value2 = strtok_r(NULL, delimiters, &saveptr);
1344 if (!value1 || !value2) {
1346 "Invalid number of arguments for DATA\n");
1350 el->regdata.raddr = strtoul(value1, NULL, 16);
1351 el->regdata.rdata = strtoul(value2, NULL, 16);
1353 case IMAGE_CFG_BAUDRATE:
1354 el->baudrate = strtoul(value1, NULL, 10);
1356 case IMAGE_CFG_DEBUG:
1357 el->debug = strtoul(value1, NULL, 10);
1360 el->key_name = strdup(value1);
1363 el->key_name = strdup(value1);
1365 case IMAGE_CFG_CSK_INDEX:
1366 el->csk_idx = strtol(value1, NULL, 0);
1368 case IMAGE_CFG_JTAG_DELAY:
1369 el->jtag_delay = strtoul(value1, NULL, 0);
1371 case IMAGE_CFG_BOX_ID:
1372 el->boxid = strtoul(value1, NULL, 0);
1374 case IMAGE_CFG_FLASH_ID:
1375 el->flashid = strtoul(value1, NULL, 0);
1377 case IMAGE_CFG_SEC_SPECIALIZED_IMG:
1378 el->sec_specialized_img = true;
1380 case IMAGE_CFG_SEC_COMMON_IMG:
1381 el->sec_specialized_img = false;
1383 case IMAGE_CFG_SEC_BOOT_DEV:
1384 el->sec_boot_dev = strtoul(value1, NULL, 0);
1386 case IMAGE_CFG_SEC_FUSE_DUMP:
1387 el->name = strdup(value1);
1390 fprintf(stderr, unknown_msg, line);
1397 * Parse the configuration file 'fcfg' into the array of configuration
1398 * elements 'image_cfg', and return the number of configuration
1399 * elements in 'cfgn'.
1401 static int image_create_config_parse(FILE *fcfg)
1406 /* Parse the configuration file */
1407 while (!feof(fcfg)) {
1411 /* Read the current line */
1412 memset(buf, 0, sizeof(buf));
1413 line = fgets(buf, sizeof(buf), fcfg);
1417 /* Ignore useless lines */
1418 if (line[0] == '\n' || line[0] == '#')
1421 /* Strip final newline */
1422 if (line[strlen(line) - 1] == '\n')
1423 line[strlen(line) - 1] = 0;
1425 /* Parse the current line */
1426 ret = image_create_config_parse_oneline(line,
1433 if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
1435 "Too many configuration elements in .cfg file\n");
1444 static int image_get_version(void)
1446 struct image_cfg_element *e;
1448 e = image_find_option(IMAGE_CFG_VERSION);
1455 static int image_version_file(const char *input)
1461 fcfg = fopen(input, "r");
1463 fprintf(stderr, "Could not open input file %s\n", input);
1467 image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
1468 sizeof(struct image_cfg_element));
1470 fprintf(stderr, "Cannot allocate memory\n");
1475 memset(image_cfg, 0,
1476 IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
1479 ret = image_create_config_parse(fcfg);
1486 version = image_get_version();
1487 /* Fallback to version 0 is no version is provided in the cfg file */
1496 static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
1497 struct image_tool_params *params)
1502 size_t headersz = 0;
1507 fcfg = fopen(params->imagename, "r");
1509 fprintf(stderr, "Could not open input file %s\n",
1514 image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
1515 sizeof(struct image_cfg_element));
1517 fprintf(stderr, "Cannot allocate memory\n");
1522 memset(image_cfg, 0,
1523 IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
1526 ret = image_create_config_parse(fcfg);
1533 /* The MVEBU BootROM does not allow non word aligned payloads */
1534 sbuf->st_size = ALIGN_SUP(sbuf->st_size, 4);
1536 version = image_get_version();
1539 * Fallback to version 0 if no version is provided in the
1544 image = image_create_v0(&headersz, params, sbuf->st_size);
1548 image = image_create_v1(&headersz, params, ptr, sbuf->st_size);
1552 fprintf(stderr, "Unsupported version %d\n", version);
1558 fprintf(stderr, "Could not create image\n");
1565 /* Build and add image checksum header */
1567 cpu_to_le32(image_checksum32((uint32_t *)ptr, sbuf->st_size));
1568 size = write(ifd, &checksum, sizeof(uint32_t));
1569 if (size != sizeof(uint32_t)) {
1570 fprintf(stderr, "Error:%s - Checksum write %d bytes %s\n",
1571 params->cmdname, size, params->imagefile);
1575 sbuf->st_size += sizeof(uint32_t);
1577 /* Finally copy the header into the image area */
1578 memcpy(ptr, image, headersz);
1583 static void kwbimage_print_header(const void *ptr)
1585 struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
1587 printf("Image Type: MVEBU Boot from %s Image\n",
1588 image_boot_mode_name(mhdr->blockid));
1589 printf("Image version:%d\n", image_version((void *)ptr));
1590 printf("Data Size: ");
1591 genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
1592 printf("Load Address: %08x\n", mhdr->destaddr);
1593 printf("Entry Point: %08x\n", mhdr->execaddr);
1596 static int kwbimage_check_image_types(uint8_t type)
1598 if (type == IH_TYPE_KWBIMAGE)
1599 return EXIT_SUCCESS;
1601 return EXIT_FAILURE;
1604 static int kwbimage_verify_header(unsigned char *ptr, int image_size,
1605 struct image_tool_params *params)
1607 struct main_hdr_v0 *main_hdr;
1610 main_hdr = (struct main_hdr_v0 *)ptr;
1611 checksum = image_checksum8(ptr,
1612 sizeof(struct main_hdr_v0)
1614 if (checksum != main_hdr->checksum)
1615 return -FDT_ERR_BADSTRUCTURE;
1617 /* Only version 0 extended header has checksum */
1618 if (image_version((void *)ptr) == 0) {
1619 struct ext_hdr_v0 *ext_hdr;
1621 ext_hdr = (struct ext_hdr_v0 *)
1622 (ptr + sizeof(struct main_hdr_v0));
1623 checksum = image_checksum8(ext_hdr,
1624 sizeof(struct ext_hdr_v0)
1626 if (checksum != ext_hdr->checksum)
1627 return -FDT_ERR_BADSTRUCTURE;
1633 static int kwbimage_generate(struct image_tool_params *params,
1634 struct image_type_params *tparams)
1640 version = image_version_file(params->imagename);
1642 alloc_len = sizeof(struct main_hdr_v0) +
1643 sizeof(struct ext_hdr_v0);
1645 alloc_len = image_headersz_v1(NULL);
1648 hdr = malloc(alloc_len);
1650 fprintf(stderr, "%s: malloc return failure: %s\n",
1651 params->cmdname, strerror(errno));
1655 memset(hdr, 0, alloc_len);
1656 tparams->header_size = alloc_len;
1660 * The resulting image needs to be 4-byte aligned. At least
1661 * the Marvell hdrparser tool complains if its unaligned.
1662 * By returning 1 here in this function, called via
1663 * tparams->vrec_header() in mkimage.c, mkimage will
1664 * automatically pad the the resulting image to a 4-byte
1665 * size if necessary.
1671 * Report Error if xflag is set in addition to default
1673 static int kwbimage_check_params(struct image_tool_params *params)
1675 if (!strlen(params->imagename)) {
1676 char *msg = "Configuration file for kwbimage creation omitted";
1678 fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
1682 return (params->dflag && (params->fflag || params->lflag)) ||
1683 (params->fflag && (params->dflag || params->lflag)) ||
1684 (params->lflag && (params->dflag || params->fflag)) ||
1685 (params->xflag) || !(strlen(params->imagename));
1689 * kwbimage type parameters definition
1693 "Marvell MVEBU Boot Image support",
1696 kwbimage_check_params,
1697 kwbimage_verify_header,
1698 kwbimage_print_header,
1699 kwbimage_set_header,
1701 kwbimage_check_image_types,