Add support for hardware signing of the SWU image via openssl engine
SWUPDATE_SIGNING_ENGINE will be used as the engine if it is set
SWUPDATE_SIGNING_ENGINE_PATH will be passed to openssl as
OPENSSL_ENGINES if set.
Signed-off-by: George McCollister <
george.mc...@gmail.com>
---
README | 27 +++++++++++++++++++++++++++
classes/swupdate.bbclass | 22 ++++++++++++++++++++--
2 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/README b/README
index 85faf8f..ad95902 100644
--- a/README
+++ b/README
@@ -31,6 +31,33 @@ sw-description.sig which is included in the SWU file.
Encrypted private keys are not currently supported since a secure
mechanism must exist to provide the passphrase.
+SWU image hardware signing
+--------------------------
+
+One may prefer to sign the SWU image with a hardware token or hardware security
+module (HSM) which doesn't expose the private key.
+
+To enable, SWUPDATE_SIGNING_ENGINE must be set to an available openssl engine.
+
+Example:
+ SWUPDATE_SIGNING_ENGINE = "pkcs11"
+
+SWUPDATE_SIGNING_ENGINE_PATH may need to be set so that openssl can locate the
+engine.
+
+Example:
+ SWUPDATE_SIGNING_ENGINE_PATH = "/usr/lib"
+
+Instead of setting SWUPDATE_PRIVATE_KEY to the full path of a file, set it to
+a key string recognized by the engine used.
+
+Example:
+ SWUPDATE_PRIVATE_KEY = "pkcs11:model=SoftHSM%20v2;" \
+ "manufacturer=SoftHSM%20project;" \
+ "serial=1234567890;" \
+ "token=test-token;pin-value=123456;" \
+ "object=swupdate-test"
+
Maintainer
----------
diff --git a/classes/swupdate.bbclass b/classes/swupdate.bbclass
index 5ef2ad8..dd1b526 100644
--- a/classes/swupdate.bbclass
+++ b/classes/swupdate.bbclass
@@ -144,16 +144,34 @@ python do_swuimage () {
privkey = d.getVar('SWUPDATE_PRIVATE_KEY', True)
if not privkey:
bb.fatal("SWUPDATE_PRIVATE_KEY isn't set")
- if not os.path.exists(privkey):
+
+ engine = d.getVar('SWUPDATE_SIGNING_ENGINE', True)
+ if engine:
+ engine = "-engine '%s' -keyform engine " % (engine)
+ elif not os.path.exists(privkey):
bb.fatal("SWUPDATE_PRIVATE_KEY %s doesn't exist" % (privkey))
+ else:
+ engine = ""
+
+ engine_path = d.getVar('SWUPDATE_SIGNING_ENGINE_PATH', True)
+ if engine and engine_path:
+ engine_path = 'OPENSSL_ENGINES="%s" ' % (engine_path)
+ else:
+ engine_path = ""
+
passout = d.getVar('SWUPDATE_PASSWORD_FILE', True)
if passout:
passout = "-passin file:'%s' " % (passout)
else:
passout = ""
- signcmd = "openssl dgst -sha256 -sign '%s' %s -out '%s' '%s'" % (
+
+ # Sign with openssl.real, provided by openssl-native so OPENSSL_ENGINES
+ # can be overridden
+ signcmd = "%sopenssl.real dgst -sha256 -sign '%s' %s%s -out '%s' '%s'" % (
+ engine_path,
privkey,
passout,
+ engine,
os.path.join(s, 'sw-description.sig'),
os.path.join(s, 'sw-description'))
if os.system(signcmd) != 0:
--
2.11.0