@@ -112,6 +112,22 @@ class FitImageTestCase(OESelftestTestCase):
self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
self.assertIn("Signature check OK", result.output)
+ def _verify_dtb_property(self, dtc_bindir, dtb_path, node_path, property_name, req_property, absent=False):
+ """Verify device tree properties
+
+ The fdtget utility from ftc-native is called and the property is compared.
+ """
+ fdtget_path = os.path.join(dtc_bindir, 'fdtget')
+ cmd = '%s %s %s %s' % (fdtget_path, dtb_path, node_path, property_name)
+ if absent:
+ result = runCmd(cmd, ignore_status=True)
+ self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
+ self.assertIn("FDT_ERR_NOTFOUND", result.output)
+ else:
+ result = runCmd(cmd)
+ self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
+ self.assertEqual(req_property, result.output.strip())
+
@staticmethod
def _find_string_in_bin_file(file_path, search_string):
"""find strings in a binary file
@@ -1349,3 +1365,108 @@ UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000"
FitImageTestCase._gen_random_file(dummy_tee)
self._test_fitimage(bb_vars)
+
+
+ def _test_sign_uboot_kernel(self, individual):
+ """
+ Check if the device-tree from U-Boot has the kernel public key(s).
+
+ The concat_dtb function of the uboot-sign.bbclass injects the public keys
+ which are required for verifying the kernel at run-time into the DTB from
+ U-Boot. The following example is from a build with FIT_SIGN_INDIVIDUAL
+ set to "1". If it is set to "0" the key-the-kernel-image-key node is not
+ present.
+ / {
+ ...
+ signature {
+ key-the-kernel-image-key {
+ required = "image";
+ algo = "sha256,rsa2048";
+ ...
+ };
+ key-the-kernel-config-key {
+ required = "conf";
+ algo = "sha256,rsa2048";
+ ...
+ };
+ };
+ """
+ # Generate a configuration section which gets included into the local.conf file
+ config = """
+# Enable creation of fitImage
+MACHINE = "beaglebone-yocto"
+UBOOT_SIGN_ENABLE = "1"
+UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
+UBOOT_SIGN_KEYNAME = "the-kernel-config-key"
+UBOOT_SIGN_IMG_KEYNAME = "the-kernel-image-key"
+UBOOT_MKIMAGE_DTCOPTS="-I dts -O dtb -p 2000"
+FIT_SIGN_INDIVIDUAL = "%s"
+""" % individual
+ self.write_config(config)
+
+ # Retrieve some variables from bitbake
+ bb_vars = self._fit_get_bb_vars([
+ 'FIT_HASH_ALG',
+ 'FIT_KEY_GENRSA_ARGS',
+ 'FIT_KEY_REQ_ARGS',
+ 'FIT_KEY_SIGN_PKCS',
+ 'FIT_SIGN_ALG',
+ 'FIT_SIGN_INDIVIDUAL',
+ 'FIT_SIGN_NUMBITS',
+ 'UBOOT_DTB_IMAGE',
+ 'UBOOT_SIGN_ENABLE',
+ 'UBOOT_SIGN_IMG_KEYNAME',
+ 'UBOOT_SIGN_KEYDIR',
+ 'UBOOT_SIGN_KEYNAME',
+ ])
+
+ # Using a static key. FIT_GENERATE_KEYS = "1" does not work without kernel-fitimage.bbclass
+ self._gen_signing_key(bb_vars)
+
+ bitbake("virtual/bootloader")
+
+ uboot_dtb_path = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], bb_vars['UBOOT_DTB_IMAGE'])
+
+ # Setup u-boot-tools-native
+ dtc_bindir = FitImageTestCase._setup_native('dtc-native')
+
+ # Check if 1 or 2 signature sections are in the DBP.
+ uboot_sign_img_keyname = bb_vars['UBOOT_SIGN_IMG_KEYNAME']
+ key_dtb_path = "/signature/key-" + uboot_sign_img_keyname
+ algo = "%s,%s" % (bb_vars['FIT_HASH_ALG'], bb_vars['FIT_SIGN_ALG'])
+ if bb_vars['FIT_SIGN_INDIVIDUAL'] == "1":
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "required", "image")
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "algo", algo)
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "key-name-hint", uboot_sign_img_keyname)
+ else:
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "required", "image", True)
+
+ uboot_sign_keyname = bb_vars['UBOOT_SIGN_KEYNAME']
+ key_dtb_path = "/signature/key-" + uboot_sign_keyname
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "required", "conf")
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "algo", algo)
+ self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "key-name-hint", uboot_sign_keyname)
+
+
+ def test_sign_uboot_kernel_configurations(self):
+ """
+ Summary: Check if the device-tree from U-Boot has the public key
+ for verifying the kernel FIT image created by the
+ kernel-fitimage.bbclass included.
+ This test sets: FIT_SIGN_INDIVIDUAL = "0"
+ Expected: There is only one signature node which is required for
+ the verification of the configuration section.
+ """
+ self._test_sign_uboot_kernel("0")
+
+ def test_sign_uboot_kernel_individual(self):
+ """
+ Summary: Check if the device-tree from U-Boot has two public keys
+ for verifying the kernel FIT image created by the
+ kernel-fitimage.bbclass included.
+ This test sets: FIT_SIGN_INDIVIDUAL = "1"
+ Expected: There must be two signature nodes. One is required for
+ the individual image nodes, the other is required for the
+ verification of the configuration section.
+ """
+ self._test_sign_uboot_kernel("1")
Add two test cases which check that the device-tree of u-boot contains the public keys which are required for checking the signature of the kernel FIT image at run-time. One test case checks the configuration where only the configuration nodes of the kernel FIT image are signed. The other test case checks the configuration with two keys and signed image and signed configuration nodes. This is the use case which recently broke with commit: OE-Core rev: 259bfa86f384206f0d0a96a5b84887186c5f689e u-boot: kernel-fitimage: Fix dependency loop if UBOOT_SIGN_ENABLE and UBOOT_ENV enabled and got fixed with commit OE-Core rev: 0106e5efab99c8016836a2ab71e2327ce58a9a9d u-boot: kernel-fitimage: Restore FIT_SIGN_INDIVIDUAL="1" behavior Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> --- meta/lib/oeqa/selftest/cases/fitimage.py | 121 +++++++++++++++++++++++ 1 file changed, 121 insertions(+)