diff options
author | Vincent Palatin <vpalatin@chromium.org> | 2014-09-26 15:20:42 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-10-02 23:18:25 +0000 |
commit | beaddbf1a365463cdef3ed9dd1d093ff6ff80d70 (patch) | |
tree | 2f6f7aeda02e320b0962da0a901bb67b3bbf753e /util/ec_sign_rsa.py | |
parent | 0330d9adf2602c44201d5e1b842747caf7dd83b1 (diff) | |
download | chrome-ec-beaddbf1a365463cdef3ed9dd1d093ff6ff80d70.tar.gz |
zinger: check RW firmware signature
The Zinger RW is now signed with 2048-bit RSA key (using SHA-256 as
digest).
This CL implements the verification mechanism.
note: the RSA key used for signing must be provided as a .pem file.
The path to .pem file must be provided in the PEM environment variable.
By default, it's using the dev key stored in zinger_dev_key.pem.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
BRANCH=samus
BUG=chrome-os-partner:28336
TEST=on Zinger, run with properly signed RW firmware and corrupted
firmware and check the serial traces.
Change-Id: Ia58482458904a3ed72d6b0e95996cae86a0ead83
Reviewed-on: https://chromium-review.googlesource.com/220178
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'util/ec_sign_rsa.py')
-rwxr-xr-x | util/ec_sign_rsa.py | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/util/ec_sign_rsa.py b/util/ec_sign_rsa.py new file mode 100755 index 0000000000..661ed37653 --- /dev/null +++ b/util/ec_sign_rsa.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# Copyright (c) 2014 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. +"""Sign EC firmware with 2048-bit RSA signature. + + Insert the RSA signature (256 bytes) at the end of the RW firmware + and replace the public key constants with the new key in RO firmware. + + Example: + ./util/sign_rsa [--rw] <pem> <ecfile> + + ./util/sign_rsa board/zinger/zinger_dev_key.pem build/zinger/ec.bin +""" +import logging +import sys + +from subprocess import Popen, PIPE +from pem_extract_pubkey import extract_pubkey + +# Size of a 2048-bit RSA signature +RSANUMBYTES = 256 +# OpenSSL command to sign with SHA256andRSA +RSA_CMD = ["openssl", "dgst", "-sha256", "-sign"] + +# Length reserved at the end of the RO partition for the public key +PUBKEY_RESERVED_SPACE = 528 + +def main(): + # Parse command line arguments + if len(sys.argv) < 3: + sys.stderr.write("Usage: %s [--rw] <pem> <ecfile>\n" % sys.argv[0]) + sys.exit(-1) + if "--rw" in sys.argv: + sys.argv.remove("--rw") + has_ro = False + else: + has_ro = True + pemfile = sys.argv[1] + ecfile = sys.argv[2] + + # Get EC firmware content + try: + ec = file(ecfile).read() + except: + logging.error('cannot read firmware binary %s', ecfile) + sys.exit(-1) + + # Extract the padded RW firmware to sign + imglen = len(ec)/2 + rwdata = ec[imglen:-RSANUMBYTES] if has_ro else ec[:-RSANUMBYTES] + # Compute the RSA signature using the OpenSSL binary + RSA_CMD.append(pemfile) + openssl = Popen(RSA_CMD, stdin=PIPE, stdout=PIPE) + signature,_ = openssl.communicate(rwdata) + + if has_ro: + # Get the public key values from the .pem file + pubkey = extract_pubkey(pemfile, headerMode=False) + # Add padding + pubkey = pubkey + "\xff" * (PUBKEY_RESERVED_SPACE - len(pubkey)) + + # Write back the signed EC firmware + with open(ecfile, 'w') as fd: + if has_ro: + fd.write(ec[:imglen-len(pubkey)]) + fd.write(pubkey) + fd.write(rwdata) + fd.write(signature) + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + sys.exit() |