diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2015-08-21 16:57:06 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-08-25 20:10:55 +0000 |
commit | d9a614826b524c212b1ce449141a8af047178b38 (patch) | |
tree | 00e43f7828f374ad08f6aa6cd89619396e5abd49 /util/signer/codesigner.cc | |
parent | b37514eed2873dcecc44619ea07542912aaf977b (diff) | |
download | chrome-ec-d9a614826b524c212b1ce449141a8af047178b38.tar.gz |
cr50: add code for the signer utility
This utility reads a binary file, verifies that the first 1024 bytes
of the file are set to zero and replaces this block with a header,
containing the signature and other information required by the recent
CR50 ROM.
A test private key is included, it matches the FPGA ROM public key.
The use convention is simple: two parameters are required, the private
key file name and the binary file name. The signed binary file is saved
in the file with extension ".signed".
BRANCH=none
BUG=chrome-os-partner:43025
TEST=the utility builds using
g++ -std=c++0x -I . -o signer codesigner.cc publickey.cc -lcrypto
ec.RO.flat signed with this utility can be successfully bootstrapped
a CR50 over SPS
Change-Id: I046b13d20f0dd8cff884e37ef966593e01dcb043
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/295208
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Diffstat (limited to 'util/signer/codesigner.cc')
-rw-r--r-- | util/signer/codesigner.cc | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/util/signer/codesigner.cc b/util/signer/codesigner.cc new file mode 100644 index 0000000000..989e87b3c5 --- /dev/null +++ b/util/signer/codesigner.cc @@ -0,0 +1,122 @@ +// +// Copyright 2015 The Chromium OS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include <iostream> +#include <fstream> +#include <sstream> +#include <ios> +#include <string> + + +#include <openssl/pem.h> + + + +#include <signed_header.h> +#include <publickey.h> + +using namespace std; +static uint8_t *mem; // this is where the file to sign is loaded +// Size of the file to be signed (including 1Kb signature). +static size_t flat_size; + + +int LoadFlatFile(const char *name, size_t header_size) +{ + ifstream::pos_type fileSize; + ifstream FlatFile (name, ios::in | ios::binary | ios::ate); + + if(!FlatFile.is_open()) { + fprintf(stderr, "failed to open %s\n", name); + return -1; + } + + flat_size = FlatFile.tellg(); + + mem = new uint8_t[flat_size]; + FlatFile.seekg(0, ios::beg); + if(!FlatFile.read((char *)mem, flat_size)) { + fprintf(stderr, "failed to read file %s\n", name); + return -1; + } + FlatFile.close(); + + // verify that there is enough room at the bottom + for (size_t i = 0; i < header_size; i++) + if (mem[i]) { + fprintf(stderr, "nonzero value at offset %zd\n", i); + return -1; + } + + return 0; +} + +int SaveSignedFile(const char *name) +{ + FILE* fp = fopen(name, "wb"); + + if (!fp) { + fprintf(stderr, "failed to open file '%s': %s\n", name, strerror(errno)); + return -1; + } + if (fwrite(mem, 1, flat_size, fp) != flat_size) { + fprintf(stderr, "failed to write %zd bytes to '%s': %s\n", + flat_size, name, strerror(errno)); + return -1; + } + fclose(fp); + + return 0; +} + +// Sing the previously read file. Return zero on success, nonzero on failure. +static int sign(PublicKey& key, const SignedHeader* input_hdr) { + BIGNUM* sig = NULL; + SignedHeader* hdr = (SignedHeader*)(&mem[0]); + int result; + + memcpy(hdr, input_hdr, sizeof(SignedHeader)); + + result = key.sign(&hdr->tag, flat_size - offsetof(SignedHeader, tag), &sig); + + if (result == 1) { + hdr->image_size = flat_size; + size_t nwords = key.nwords(); + key.toArray(hdr->signature, nwords, sig); + } else { + fprintf(stderr, "ossl_sign:%d\n", result); + } + + if (sig) + BN_free(sig); + + return result != 1; +} + +int main(int argc, char* argv[]) { + if (argc < 3) { + fprintf(stderr, "Usage: %s pem-file [hexfile|flatfile]\n", argv[0]); + exit(1); + } + const char* arg = argv[2]; + PublicKey key(argv[1]); + + if (!key.ok()) return -1; + + SignedHeader hdr; + + // Load input file + if (LoadFlatFile(arg, sizeof(hdr))) + return -2; + + if (sign(key, &hdr)) + return -3; + + if (SaveSignedFile((std::string(arg) + std::string(".signed")).c_str())) + return -4; + + return 0; +} |