Files
OpenCellular/util/ec_sign_rsa.py
Vincent Palatin b63b0d70f5 rsa: add support for 4096 and 8192 bit keys
Allow to use larger RSA keys by setting CONFIG_RSA_KEY_SIZE to 4096 or
8192 rather than using the default 2048-bit size.

It's mainly for benchmarking purpose right now as we don't have the RAM
to store the 3x key size buffer and the flash space for the public key
structure.

Signed-off-by: Vincent Palatin <vpalatin@chromium.org>

BRANCH=samus
BUG=none
TEST=build Zinger with CONFIG_RSA_KEY_SIZE equals to 4096 and run it.

Change-Id: I9839121bf158d0a30dde1e48d875f345191bfec2
Reviewed-on: https://chromium-review.googlesource.com/228925
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Tested-by: Vincent Palatin <vpalatin@chromium.org>
2014-11-15 06:00:02 +00:00

86 lines
2.4 KiB
Python
Executable File

#!/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
# OpenSSL command to sign with SHA256andRSA
RSA_CMD = ["openssl", "dgst", "-sha256", "-sign"]
# supported RSA key sizes
RSA_KEY_SIZES=[2048, 4096, 8192]
def align16(v):
return (v + 15) / 16 * 16
def main():
# Parse command line arguments
if len(sys.argv) < 3:
sys.stderr.write("Usage: %s [--rw] [--4096|--8192] <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
# Default to a 2048-bit RSA signature
RSANUMBYTES = 2048 / 8
for sz in RSA_KEY_SIZES:
param = "--%d" % (sz)
if param in sys.argv:
sys.argv.remove(param)
RSANUMBYTES = sz / 8
pemfile = sys.argv[1]
ecfile = sys.argv[2]
# Length reserved at the end of the RO partition for the public key
PUBKEY_RESERVED_SPACE = align16(2 * RSANUMBYTES + 4)
# 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()