diff options
author | Eddie James <eajames@us.ibm.com> | 2018-02-09 20:59:18 +0300 |
---|---|---|
committer | Brad Bishop <bradleyb@fuzziesquirrel.com> | 2018-03-30 20:31:20 +0300 |
commit | b2b7ff6804d128602d7db998c7b20be6821f9118 (patch) | |
tree | 6fcec77dcd2a094b43233614d33d221a352c9d30 | |
parent | 3b0639b35ec269e8b9fdd3635a1212206b456fb9 (diff) | |
download | openbmc-b2b7ff6804d128602d7db998c7b20be6821f9118.tar.xz |
Add image signing framework and open keys
In order to secure the BMC, we need to sign all the images and include a
public key in the package with which to verify future update images.
This commit adds a framework to sign the image files with an open
private key and generates a corresponding public key added to the image.
This isn't secure by itself (since the private key is available), but
additional changes can easily provide their own private key, creating a
secure BMC.
To use a secure private key:
export BB_ENV_EXTRAWHITE="$BB_ENV_EXTRAWHITE SIGNING_KEY"
SIGNING_KEY=/path/to/secure/key bitbake obmc-phosphor-image
Resolves openbmc/openbmc#2835
Resolves openbmc/openbmc#2836
Resolves openbmc/openbmc#2837
Change-Id: I28919b7de54e3a32e5efcbb4522fb39731e68384
Signed-off-by: Eddie James <eajames@us.ibm.com>
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
5 files changed, 105 insertions, 2 deletions
diff --git a/meta-phosphor/classes/image_types_phosphor.bbclass b/meta-phosphor/classes/image_types_phosphor.bbclass index de1883f3f..441d87fb3 100644 --- a/meta-phosphor/classes/image_types_phosphor.bbclass +++ b/meta-phosphor/classes/image_types_phosphor.bbclass @@ -44,6 +44,10 @@ FLASH_RWFS_OFFSET ?= "28672" FLASH_UBI_RWFS_SIZE ?= "6144" FLASH_UBI_RWFS_TXT_SIZE ?= "6MiB" +SIGNING_KEY ?= "${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv" +INSECURE_KEY = "${@'${SIGNING_KEY}' == '${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv'}" +SIGNING_KEY_DEPENDS = "${@oe.utils.conditional('INSECURE_KEY', 'True', 'phosphor-insecure-signing-key-native:do_populate_sysroot', '', d)}" + python() { # Compute rwfs LEB count and LEB size. page_size = d.getVar('FLASH_PAGE_SIZE', True) @@ -277,27 +281,64 @@ do_generate_static_tar[vardepsexclude] = "DATETIME" do_generate_ubi_tar() { ln -sf ${S}/MANIFEST MANIFEST + ln -sf ${S}/publickey publickey make_image_links ${FLASH_UBI_OVERLAY_BASETYPE} ${FLASH_UBI_BASETYPE} - make_tar_of_images ubi MANIFEST + for file in image-u-boot image-kernel image-rofs image-rwfs MANIFEST publickey; do + openssl dgst -sha256 -sign ${SIGNING_KEY} -out "${file}.sig" $file + done + make_tar_of_images ubi MANIFEST publickey *.sig } do_generate_ubi_tar[dirs] = " ${S}/ubi" do_generate_ubi_tar[depends] += " \ ${PN}:do_image_${@d.getVar('FLASH_UBI_BASETYPE', True).replace('-', '_')} \ virtual/kernel:do_deploy \ u-boot:do_populate_sysroot \ + openssl-native:do_populate_sysroot \ + ${SIGNING_KEY_DEPENDS} \ + ${PN}:do_copy_signing_pubkey \ " +def get_pubkey_basedir(d): + return os.path.join( + d.getVar('STAGING_DIR_TARGET', True), + d.getVar('sysconfdir', True).strip(os.sep), + 'activationdata') + +def get_pubkey_type(d): + return os.listdir(get_pubkey_basedir(d))[0] + +def get_pubkey_path(d): + return os.path.join( + get_pubkey_basedir(d), + get_pubkey_type(d), + 'publickey') + python do_generate_phosphor_manifest() { version = do_get_version(d) with open('MANIFEST', 'w') as fd: fd.write('purpose=xyz.openbmc_project.Software.Version.VersionPurpose.BMC\n') fd.write('version={}\n'.format(version.strip('"'))) + fd.write('KeyType={}\n'.format(get_pubkey_type(d))) + fd.write('HashType=RSA-SHA256\n') } do_generate_phosphor_manifest[dirs] = "${S}" do_generate_phosphor_manifest[depends] += " \ os-release:do_populate_sysroot \ + phosphor-image-signing:do_populate_sysroot \ + " + +python do_copy_signing_pubkey() { + with open(get_pubkey_path(d), 'r') as read_fd: + with open('publickey', 'w') as write_fd: + write_fd.write(read_fd.read()) +} + +do_copy_signing_pubkey[dirs] = "${S}" +do_copy_signing_pubkey[depends] += " \ + phosphor-image-signing:do_populate_sysroot \ " +addtask copy_signing_pubkey after do_rootfs addtask generate_phosphor_manifest after do_rootfs addtask generate_rwfs_static after do_rootfs addtask generate_rwfs_ubi after do_rootfs diff --git a/meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv b/meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv new file mode 100644 index 000000000..223d31809 --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri +PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B +zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k +D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU +zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/ +nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1 +h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt +rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE +x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5 +DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw +cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE +5yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4 +6ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m +F0nIdUAhR0yTfKM= +-----END PRIVATE KEY----- diff --git a/meta-phosphor/common/recipes-phosphor/flash/phosphor-image-signing.bb b/meta-phosphor/common/recipes-phosphor/flash/phosphor-image-signing.bb new file mode 100644 index 000000000..897bfdea4 --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/flash/phosphor-image-signing.bb @@ -0,0 +1,29 @@ +SUMMARY = "OpenBMC image signing public key" +DESCRIPTION = "Public key information to be included in images for image verification." +PR = "r1" + +inherit allarch +inherit obmc-phosphor-license + +INSECURE_KEY = "${@'${SIGNING_KEY}' == '${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv'}" + +DEPENDS += "openssl-native" +DEPENDS += "${@oe.utils.conditional('INSECURE_KEY', 'True', 'phosphor-insecure-signing-key-native', '', d)}" + +FILES_${PN} += "${sysconfdir}/activationdata/" + +SIGNING_KEY ?= "${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv" +SIGNING_KEY_TYPE = "${@os.path.splitext(os.path.basename('${SIGNING_KEY}'))[0]}" + +do_install() { + openssl pkey -in "${SIGNING_KEY}" -pubout -out ${WORKDIR}/publickey + echo HashType=RSA-SHA256 > "${WORKDIR}/hashfunc" + + idir="${D}${sysconfdir}/activationdata/${SIGNING_KEY_TYPE}" + + install -d ${idir} + install -m 644 ${WORKDIR}/publickey ${idir} + install -m 644 ${WORKDIR}/hashfunc ${idir} +} + +SYSROOT_DIRS_append = " ${sysconfdir}" diff --git a/meta-phosphor/common/recipes-phosphor/flash/phosphor-insecure-signing-key-native.bb b/meta-phosphor/common/recipes-phosphor/flash/phosphor-insecure-signing-key-native.bb new file mode 100644 index 000000000..55ebe5779 --- /dev/null +++ b/meta-phosphor/common/recipes-phosphor/flash/phosphor-insecure-signing-key-native.bb @@ -0,0 +1,15 @@ +SUMMARY = "Insecure private key for testing and development" +DESCRIPTION = "Do not use this key to sign images." +PR = "r1" + +inherit allarch +inherit native +inherit obmc-phosphor-license + +SRC_URI += "file://OpenBMC.priv" + +do_install() { + bbplain "Using an insecure image signing key!" + install -d ${D}${datadir} + install -m 400 ${WORKDIR}/OpenBMC.priv ${D}${datadir} +} diff --git a/meta-phosphor/common/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bb b/meta-phosphor/common/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bb index 11cfe3442..e7fe3708a 100644 --- a/meta-phosphor/common/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bb +++ b/meta-phosphor/common/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bb @@ -89,7 +89,9 @@ ${PN}-software-extras = " \ obmc-mgr-download \ " -${PN}-software-extras_df-obmc-ubi-fs = "" +${PN}-software-extras_df-obmc-ubi-fs = " \ + phosphor-image-signing \ + " SUMMARY_${PN}-software = "Software applications" RDEPENDS_${PN}-software = " \ |