summaryrefslogtreecommitdiff
path: root/util/ec_sign_rsa.py
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2014-09-26 15:20:42 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-10-02 23:18:25 +0000
commitbeaddbf1a365463cdef3ed9dd1d093ff6ff80d70 (patch)
tree2f6f7aeda02e320b0962da0a901bb67b3bbf753e /util/ec_sign_rsa.py
parent0330d9adf2602c44201d5e1b842747caf7dd83b1 (diff)
downloadchrome-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-xutil/ec_sign_rsa.py75
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()