diff options
Diffstat (limited to 'util/signer/image.cc')
-rw-r--r-- | util/signer/image.cc | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/util/signer/image.cc b/util/signer/image.cc index c7c4e0a63b..3fb7968f67 100644 --- a/util/signer/image.cc +++ b/util/signer/image.cc @@ -30,6 +30,12 @@ using namespace std; +extern bool FLAGS_verbose; + +#define VERBOSE(...) do{if(FLAGS_verbose)fprintf(stderr, __VA_ARGS__);}while(0) +#define WARN(...) do{fprintf(stderr, __VA_ARGS__);}while(0) +#define FATAL(...) do{fprintf(stderr, __VA_ARGS__);abort();}while(0) + static const int FLASH_START = 0x4000; static const int FLASH_END = FLASH_START + 512 * 1024; @@ -54,34 +60,34 @@ bool Image::fromElf(const string& filename) { int fd; if ((fd = open(filename.c_str(), O_RDONLY)) < 0) { - fprintf(stderr, "failed to open '%s'\n", filename.c_str()); + WARN("failed to open '%s'\n", filename.c_str()); goto fail; } if ((fstat(fd, &elf_stats)) < 0) { - fprintf(stderr, "cannot stat '%s'\n", filename.c_str()); + WARN("cannot stat '%s'\n", filename.c_str()); goto fail; } // printf("Elf filesize: %lu\n", elf_stats.st_size); if ((base_ptr = (char*) malloc(elf_stats.st_size)) == NULL) { - fprintf(stderr, "cannot malloc %lu\n", elf_stats.st_size); + WARN("cannot malloc %lu\n", elf_stats.st_size); goto fail; } if (read(fd, base_ptr, elf_stats.st_size) < elf_stats.st_size) { - fprintf(stderr, "cannot read from '%s'\n", filename.c_str()); + WARN("cannot read from '%s'\n", filename.c_str()); goto fail; } // Sniff content for sanity if (*(uint32_t*) base_ptr != 0x464c457f) { -// fprintf(stderr, "'%s' is not elf file\n", filename); +// WARN("'%s' is not elf file\n", filename); goto fail; } if (elf_version(EV_CURRENT) == EV_NONE) { - fprintf(stderr, "Warning: elf library is out of data!\n"); + WARN("Warning: elf library is out of date!\n"); } elf = elf_begin(fd, ELF_C_READ, NULL); @@ -90,9 +96,9 @@ bool Image::fromElf(const string& filename) { while ((scn = elf_nextscn(elf, scn)) != 0) { gelf_getshdr(scn, &shdr); - printf("type %08x; flags %08lx ", shdr.sh_type, shdr.sh_flags); - printf("%08lx(@%08lx)[%08lx] align %lu\n", - shdr.sh_addr, shdr.sh_offset, shdr.sh_size, shdr.sh_addralign); + VERBOSE("type %08x; flags %08lx ", shdr.sh_type, shdr.sh_flags); + VERBOSE("%08lx(@%08lx)[%08lx] align %lu\n", + shdr.sh_addr, shdr.sh_offset, shdr.sh_size, shdr.sh_addralign); // Ignore sections that are not alloc if (!(shdr.sh_flags & SHF_ALLOC)) { @@ -121,11 +127,11 @@ bool Image::fromElf(const string& filename) { // Load image per program headers and track total ro segment for (int index = 0; gelf_getphdr(elf, index, &phdr); ++index) { - printf("phdr %08lx(@%08lx) [%08lx/%08lx]", - phdr.p_vaddr, phdr.p_paddr, phdr.p_filesz, phdr.p_memsz); + VERBOSE("phdr %08lx(@%08lx) [%08lx/%08lx]", + phdr.p_vaddr, phdr.p_paddr, phdr.p_filesz, phdr.p_memsz); if (phdr.p_filesz != phdr.p_memsz) { - printf(" (not loading)\n"); + VERBOSE(" (not loading)\n"); continue; } @@ -135,7 +141,7 @@ bool Image::fromElf(const string& filename) { continue; } - printf("\n"); + VERBOSE("\n"); // Track ro boundaries if (phdr.p_paddr < ro_base_) { @@ -162,9 +168,9 @@ bool Image::fromElf(const string& filename) { high_ = ((high_ + 2047) / 2048) * 2048; // Round image to multiple of 2K. - printf("Rounded image size %lu\n", size()); - printf("ro_base %08lx..%08lx\n", ro_base_, ro_max_); - printf("rx_base %08lx..%08lx\n", rx_base_, rx_max_); + VERBOSE("Rounded image size %lu\n", size()); + VERBOSE("ro_base %08lx..%08lx\n", ro_base_, ro_max_); + VERBOSE("rx_base %08lx..%08lx\n", rx_base_, rx_max_); result = true; @@ -188,12 +194,12 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { if (strchr(line, '\n')) *strchr(line, '\n') = 0; if (line[0] != ':') continue; // assume comment line if (strlen(line) < 9) { - fprintf(stderr, "short record %s", line); + WARN("short record %s", line); success_ = false; continue; } if (line[7] != '0') { - fprintf(stderr, "unknown record type %s", line); + WARN("unknown record type %s", line); success_ = false; } else switch (line[8]) { case '1': { // 01 eof @@ -205,10 +211,10 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { if (s != 0x1000) { if (s >= FLASH_START && s <= FLASH_END) { seg = s - FLASH_START; - //fprintf(stderr, "at segment %04x\n", seg); + //WARN("at segment %04x\n", seg); } else { - fprintf(stderr, "data should in range %x-%x: %s\n", - FLASH_START, FLASH_END, line); + WARN("data should in range %x-%x: %s\n", + FLASH_START, FLASH_END, line); success_ = false; } } @@ -224,8 +230,8 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { if (isRam) { int v = parseByte(&p); if (v != 0) { - fprintf(stderr, "WARNING: non-zero RAM byte %02x at %04x\n", - v, adr); + WARN("WARNING: non-zero RAM byte %02x at %04x\n", + v, adr); } ++adr; @@ -237,14 +243,14 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { case '3': { // 03 entry point } break; default: { - fprintf(stderr, "unknown record type %s", line); + WARN("unknown record type %s", line); success_ = false; } break; } } fclose(fp); } else { - fprintf(stderr, "failed to open file '%s'\n", filename.c_str()); + WARN("failed to open file '%s'\n", filename.c_str()); success_ = false; } @@ -254,20 +260,20 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { if (withSignature) { // signed images start on 2K boundary. if ((low_ & 2047) != 0) { - fprintf(stderr, "signed images should start on 2K boundary, not %08x\n", low_); + WARN("signed images should start on 2K boundary, not %08x\n", low_); } base_ = low_; } else { // unsigned images start on odd 1K boundary. if ((low_ & 2047) != 1024) { - fprintf(stderr, "unsigned images should start odd 1K boundary, not %08x\n", low_); + WARN("unsigned images should start odd 1K boundary, not %08x\n", low_); } base_ = low_ - sizeof(SignedHeader); } } if (success_) { - fprintf(stderr, "low %08x, high %08x\n", + VERBOSE("low %08x, high %08x\n", FLASH_START * 16 + low_, FLASH_START * 16 + high_); // Round image to multiple of 2K. high_ = ((high_ + 2047) / 2048) * 2048; @@ -275,7 +281,7 @@ bool Image::fromIntelHex(const string& filename, bool withSignature) { rx_base_ = FLASH_START * 16 + base_; ro_max_ = FLASH_START * 16 + base_ + size(); rx_max_ = FLASH_START * 16 + base_ + size(); - fprintf(stderr, "base %08lx, size %08lx\n", ro_base_, size()); + VERBOSE("base %08lx, size %08lx\n", ro_base_, size()); } return success_; @@ -327,7 +333,7 @@ int Image::nibble(char n) { case 'e': case 'E': return 14; case 'f': case 'F': return 15; default: - fprintf(stderr, "bad hex digit '%c'\n", n); + WARN("bad hex digit '%c'\n", n); success_ = false; return 0; } @@ -351,7 +357,7 @@ int Image::parseWord(char** p) { void Image::store(int adr, int v) { if (adr < 0 || (size_t)(adr) >= sizeof(mem_)) { - fprintf(stderr, "illegal adr %04x\n", adr); + WARN("illegal adr %04x\n", adr); success_ = false; return; } @@ -376,49 +382,53 @@ bool Image::sign(PublicKey& key, const SignedHeader* input_hdr, } hashes; memcpy(hdr, input_hdr, sizeof(SignedHeader)); + hdr->image_size = this->size(); + // Fill in key traits + hdr->keyid = key.n0inv(); + key.modToArray(hdr->key, key.rwords()); + // Hash img int size = this->size() - offsetof(SignedHeader, tag); SHA256_Init(&sha256); SHA256_Update(&sha256, &hdr->tag, size); SHA256_Final(hashes.img_hash, &sha256); - fprintf(stderr, "img hash :"); + VERBOSE("img hash :"); for (size_t i = 0; i < sizeof(hashes.img_hash); ++i) { - fprintf(stderr, "%02x", hashes.img_hash[i]); + VERBOSE("%02x", hashes.img_hash[i]); } - fprintf(stderr, "\n"); + VERBOSE("\n"); // Hash fuses SHA256_Init(&sha256); SHA256_Update(&sha256, fuses, FUSE_MAX * sizeof(uint32_t)); SHA256_Final(hashes.fuses_hash, &sha256); - fprintf(stderr, "fuses hash:"); + VERBOSE("fuses hash:"); for (size_t i = 0; i < sizeof(hashes.fuses_hash); ++i) { - fprintf(stderr, "%02x", hashes.fuses_hash[i]); + VERBOSE("%02x", hashes.fuses_hash[i]); } - fprintf(stderr, "\n"); + VERBOSE("\n"); // Hash info SHA256_Init(&sha256); SHA256_Update(&sha256, info, INFO_MAX * sizeof(uint32_t)); SHA256_Final(hashes.info_hash, &sha256); - fprintf(stderr, "info hash :"); + VERBOSE("info hash :"); for (size_t i = 0; i < sizeof(hashes.info_hash); ++i) { - fprintf(stderr, "%02x", hashes.info_hash[i]); + VERBOSE("%02x", hashes.info_hash[i]); } - fprintf(stderr, "\n"); + VERBOSE("\n"); result = key.sign(&hashes, sizeof(hashes), &sig); if (result != 1) { - fprintf(stderr, "key.sign:%d\n", result); + WARN("key.sign: %d\n", result); } else { - size_t rwords = key.rwords(); - key.toArray(hdr->signature, rwords, sig); + key.toArray(hdr->signature, key.rwords(), sig); } if (sig) BN_free(sig); |