summaryrefslogtreecommitdiff
path: root/util/signer/codesigner.cc
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2015-08-21 16:57:06 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-25 20:10:55 +0000
commitd9a614826b524c212b1ce449141a8af047178b38 (patch)
tree00e43f7828f374ad08f6aa6cd89619396e5abd49 /util/signer/codesigner.cc
parentb37514eed2873dcecc44619ea07542912aaf977b (diff)
downloadchrome-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.cc122
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;
+}