Boot: Add RSA-3072 support to imgtool script
PSA TBSA-M recommends to use RSA signature for firmware
authentication with at least 3072 bits length key size.
This change is based on:
https://github.com/JuulLabs-OSS/mcuboot/pull/476
authored by Fabio Utzig <utzig@apache.org>
Change-Id: I78fb0c9732aa6942b6fcb46fef5e1965c9dccaa5
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/ext/mcuboot/scripts/imgtool.py b/bl2/ext/mcuboot/scripts/imgtool.py
index 924fa96..43d7d15 100644
--- a/bl2/ext/mcuboot/scripts/imgtool.py
+++ b/bl2/ext/mcuboot/scripts/imgtool.py
@@ -80,10 +80,14 @@
return newVersion
def gen_rsa2048(args):
- keys.RSA2048.generate().export_private(args.key)
+ keys.RSAutil.generate().export_private(args.key)
+
+def gen_rsa3072(args):
+ keys.RSAutil.generate(key_size=3072).export_private(args.key)
keygens = {
- 'rsa-2048': gen_rsa2048, }
+ 'rsa-2048': gen_rsa2048,
+ 'rsa-3072': gen_rsa3072, }
def do_keygen(args):
if args.type not in keygens:
diff --git a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
index bd1bf5d..ff137a5 100644
--- a/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
+++ b/bl2/ext/mcuboot/scripts/imgtool_lib/image.py
@@ -36,6 +36,7 @@
'KEYHASH': 0x01,
'SHA256' : 0x10,
'RSA2048': 0x20,
+ 'RSA3072': 0x23,
'SEC_CNT': 0x50, }
TLV_INFO_SIZE = 4
diff --git a/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py b/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
index fda3ed6..f17f173 100644
--- a/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
+++ b/bl2/ext/mcuboot/scripts/imgtool_lib/keys.py
@@ -1,5 +1,5 @@
# Copyright 2017 Linaro Limited
-# Copyright (c) 2017-2018, Arm Limited.
+# Copyright (c) 2017-2019, Arm Limited.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,25 +25,37 @@
from pyasn1.type import namedtype, univ
from pyasn1.codec.der.encoder import encode
+# Sizes that bootutil will recognize
+RSA_KEY_SIZES = [2048, 3072]
+
# By default, we use RSA-PSS (PKCS 2.1). That can be overridden on
# the command line to support the older (less secure) PKCS1.5
sign_rsa_pss = True
AUTOGEN_MESSAGE = "/* Autogenerated by imgtool.py, do not edit. */"
+class RSAUsageError(Exception):
+ pass
+
class RSAPublicKey(univ.Sequence):
componentType = namedtype.NamedTypes(
namedtype.NamedType('modulus', univ.Integer()),
namedtype.NamedType('publicExponent', univ.Integer()))
-class RSA2048():
+class RSAutil():
def __init__(self, key):
- """Construct an RSA2048 key with the given key data"""
+ """Construct an RSA key with the given key data"""
self.key = key
+ def key_size(self):
+ return self.key.n.bit_length()
+
@staticmethod
- def generate():
- return RSA2048(RSA.generate(2048))
+ def generate(key_size=2048):
+ if key_size not in RSA_KEY_SIZES:
+ raise RSAUsageError("Key size {} is not supported by MCUboot"
+ .format(key_size))
+ return RSAutil(RSA.generate(key_size))
def export_private(self, path):
with open(path, 'wb') as f:
@@ -71,15 +83,15 @@
def sig_type(self):
"""Return the type of this signature (as a string)"""
if sign_rsa_pss:
- return "PKCS1_PSS_RSA2048_SHA256"
+ return "PKCS1_PSS_RSA{}_SHA256".format(self.key_size())
else:
- return "PKCS15_RSA2048_SHA256"
+ return "PKCS15_RSA{}_SHA256".format(self.key_size())
def sig_len(self):
- return 256
+ return 256 if self.key_size() == 2048 else 384
def sig_tlv(self):
- return "RSA2048"
+ return "RSA2048" if self.key_size() == 2048 else "RSA3072"
def sign(self, payload):
converted_payload = bytes(payload)
@@ -97,8 +109,6 @@
pem = f.read()
try:
key = RSA.importKey(pem)
- if key.n.bit_length() != 2048:
- raise Exception("Unsupported RSA bit length, only 2048 supported")
- return RSA2048(key)
+ return RSAutil(key)
except ValueError:
raise Exception("Unsupported RSA key file")