summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Freihofer <adrian.freihofer@gmail.com>2025-03-17 18:13:56 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-03-18 10:27:31 +0000
commit12801c7bbbcf902102c3350e91d9256844e2492a (patch)
tree63e59385a20191272a58d10bca74cf071381a0de
parent4632788c431b1348f0c281f8894acff994b3e45f (diff)
downloadpoky-12801c7bbbcf902102c3350e91d9256844e2492a.tar.gz
oe-selftest: fitimage add more u-boot tests
Add a new test function which checks 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. Use this new _check_kernel_dtb function in the existing test_sign_cascaded_uboot_fit_image test case which already creates a build configuration with UBOOT_SIGN_ENABLE = "1" and keys for the kernel. But so far there was no check that the keys for the kernel verification got added to U-Boot's DTB. This test case checks the configuration where only the configuration nodes of the kernel FIT image are signed. A new test case test_sign_uboot_kernel_individual checks the configuration with two keys and signed image and signed configuration nodes. This test case covers 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 This patch also fixes a few more details: - Simplify the code by moving all the U-Boot related variables to the _fit_get_bb_vars function. - Do not set FIT_GENERATE_KEYS = "1" without inheriting the kernel-fitimage.bbclass which handles this variable. (From OE-Core rev: dda1fcbc85c26d1851dda6ed235238b15939998e) Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/lib/oeqa/selftest/cases/fitimage.py117
1 files changed, 111 insertions, 6 deletions
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 666c4678ef..b39f2622df 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -112,6 +112,22 @@ class FitImageTestCase(OESelftestTestCase):
112 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output) 112 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
113 self.assertIn("Signature check OK", result.output) 113 self.assertIn("Signature check OK", result.output)
114 114
115 def _verify_dtb_property(self, dtc_bindir, dtb_path, node_path, property_name, req_property, absent=False):
116 """Verify device tree properties
117
118 The fdtget utility from dtc-native is called and the property is compared.
119 """
120 fdtget_path = os.path.join(dtc_bindir, 'fdtget')
121 cmd = '%s %s %s %s' % (fdtget_path, dtb_path, node_path, property_name)
122 if absent:
123 result = runCmd(cmd, ignore_status=True)
124 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
125 self.assertIn("FDT_ERR_NOTFOUND", result.output)
126 else:
127 result = runCmd(cmd)
128 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
129 self.assertEqual(req_property, result.output.strip())
130
115 @staticmethod 131 @staticmethod
116 def _find_string_in_bin_file(file_path, search_string): 132 def _find_string_in_bin_file(file_path, search_string):
117 """find strings in a binary file 133 """find strings in a binary file
@@ -879,12 +895,20 @@ class UBootFitImageTests(FitImageTestCase):
879 """ 895 """
880 internal_used = { 896 internal_used = {
881 'DEPLOY_DIR_IMAGE', 897 'DEPLOY_DIR_IMAGE',
898 'FIT_HASH_ALG',
899 'FIT_KEY_GENRSA_ARGS',
900 'FIT_KEY_REQ_ARGS',
901 'FIT_KEY_SIGN_PKCS',
902 'FIT_SIGN_ALG',
903 'FIT_SIGN_INDIVIDUAL',
904 'FIT_SIGN_NUMBITS',
882 'MACHINE', 905 'MACHINE',
883 'SPL_MKIMAGE_SIGN_ARGS', 906 'SPL_MKIMAGE_SIGN_ARGS',
884 'SPL_SIGN_ENABLE', 907 'SPL_SIGN_ENABLE',
885 'SPL_SIGN_KEYNAME', 908 'SPL_SIGN_KEYNAME',
886 'UBOOT_ARCH', 909 'UBOOT_ARCH',
887 'UBOOT_DTB_BINARY', 910 'UBOOT_DTB_BINARY',
911 'UBOOT_DTB_IMAGE',
888 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT', 912 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT',
889 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS', 913 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS',
890 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE', 914 'UBOOT_FIT_ARM_TRUSTED_FIRMWARE',
@@ -900,7 +924,10 @@ class UBootFitImageTests(FitImageTestCase):
900 'UBOOT_FIT_USER_SETTINGS', 924 'UBOOT_FIT_USER_SETTINGS',
901 'UBOOT_FITIMAGE_ENABLE', 925 'UBOOT_FITIMAGE_ENABLE',
902 'UBOOT_NODTB_BINARY', 926 'UBOOT_NODTB_BINARY',
927 'UBOOT_SIGN_ENABLE',
903 'UBOOT_SIGN_IMG_KEYNAME', 928 'UBOOT_SIGN_IMG_KEYNAME',
929 'UBOOT_SIGN_KEYDIR',
930 'UBOOT_SIGN_KEYNAME',
904 } 931 }
905 bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), "virtual/bootloader") 932 bb_vars = get_bb_vars(list(internal_used | set(additional_vars)), "virtual/bootloader")
906 self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4)) 933 self.logger.debug("bb_vars: %s" % pprint.pformat(bb_vars, indent=4))
@@ -1085,6 +1112,50 @@ class UBootFitImageTests(FitImageTestCase):
1085 self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." % 1112 self.assertEqual(found_comments, num_signatures, "Expected %d signed and commented (%s) sections in the fitImage." %
1086 (num_signatures, a_comment)) 1113 (num_signatures, a_comment))
1087 1114
1115 def _check_kernel_dtb(self, bb_vars):
1116 """
1117 Check if the device-tree from U-Boot has the kernel public key(s).
1118
1119 The concat_dtb function of the uboot-sign.bbclass injects the public keys
1120 which are required for verifying the kernel at run-time into the DTB from
1121 U-Boot. The following example is from a build with FIT_SIGN_INDIVIDUAL
1122 set to "1". If it is set to "0" the key-the-kernel-image-key node is not
1123 present.
1124 / {
1125 ...
1126 signature {
1127 key-the-kernel-image-key {
1128 required = "image";
1129 algo = "sha256,rsa2048";
1130 ...
1131 };
1132 key-the-kernel-config-key {
1133 required = "conf";
1134 algo = "sha256,rsa2048";
1135 ...
1136 };
1137 };
1138 """
1139 # Setup u-boot-tools-native
1140 dtc_bindir = FitImageTestCase._setup_native('dtc-native')
1141
1142 # Check if 1 or 2 signature sections are in the DTB.
1143 uboot_dtb_path = os.path.join(bb_vars['DEPLOY_DIR_IMAGE'], bb_vars['UBOOT_DTB_IMAGE'])
1144 algo = "%s,%s" % (bb_vars['FIT_HASH_ALG'], bb_vars['FIT_SIGN_ALG'])
1145 if bb_vars['FIT_SIGN_INDIVIDUAL'] == "1":
1146 uboot_sign_img_keyname = bb_vars['UBOOT_SIGN_IMG_KEYNAME']
1147 key_dtb_path = "/signature/key-" + uboot_sign_img_keyname
1148 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "required", "image")
1149 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "algo", algo)
1150 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "key-name-hint", uboot_sign_img_keyname)
1151
1152 uboot_sign_keyname = bb_vars['UBOOT_SIGN_KEYNAME']
1153 key_dtb_path = "/signature/key-" + uboot_sign_keyname
1154 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "required", "conf")
1155 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "algo", algo)
1156 self._verify_dtb_property(dtc_bindir, uboot_dtb_path, key_dtb_path, "key-name-hint", uboot_sign_keyname)
1157
1158
1088 def test_uboot_fit_image(self): 1159 def test_uboot_fit_image(self):
1089 """ 1160 """
1090 Summary: Check if Uboot FIT image and Image Tree Source 1161 Summary: Check if Uboot FIT image and Image Tree Source
@@ -1177,9 +1248,9 @@ UBOOT_FIT_HASH_ALG = "sha256"
1177 via UBOOT_FIT_GENERATE_KEYS) 1248 via UBOOT_FIT_GENERATE_KEYS)
1178 3) Dumping the FIT image indicates signature values 1249 3) Dumping the FIT image indicates signature values
1179 are present 1250 are present
1180 4) Examination of the do_uboot_assemble_fitimage 1251 4) Examination of the do_uboot_assemble_fitimage that
1181 runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN 1252 UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN and SPL_MKIMAGE_SIGN_ARGS
1182 and SPL_MKIMAGE_SIGN_ARGS are working as expected. 1253 are working as expected.
1183 Product: oe-core 1254 Product: oe-core
1184 Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> based upon 1255 Author: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com> based upon
1185 work by Paul Eggleton <paul.eggleton@microsoft.com> and 1256 work by Paul Eggleton <paul.eggleton@microsoft.com> and
@@ -1209,15 +1280,17 @@ UBOOT_EXTLINUX = "0"
1209UBOOT_FIT_GENERATE_KEYS = "1" 1280UBOOT_FIT_GENERATE_KEYS = "1"
1210UBOOT_FIT_HASH_ALG = "sha256" 1281UBOOT_FIT_HASH_ALG = "sha256"
1211UBOOT_SIGN_ENABLE = "1" 1282UBOOT_SIGN_ENABLE = "1"
1212FIT_GENERATE_KEYS = "1"
1213UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" 1283UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
1214UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest"
1215UBOOT_SIGN_KEYNAME = "cfg-oe-selftest" 1284UBOOT_SIGN_KEYNAME = "cfg-oe-selftest"
1216FIT_SIGN_INDIVIDUAL = "1"
1217""" 1285"""
1218 self.write_config(config) 1286 self.write_config(config)
1219 bb_vars = self._fit_get_bb_vars() 1287 bb_vars = self._fit_get_bb_vars()
1288
1289 # Using a static key. FIT_GENERATE_KEYS = "1" does not work without kernel-fitimage.bbclass
1290 self._gen_signing_key(bb_vars)
1291
1220 self._test_fitimage(bb_vars) 1292 self._test_fitimage(bb_vars)
1293 self._check_kernel_dtb(bb_vars)
1221 1294
1222 def test_uboot_atf_tee_fit_image(self): 1295 def test_uboot_atf_tee_fit_image(self):
1223 """ 1296 """
@@ -1352,3 +1425,35 @@ UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000"
1352 FitImageTestCase._gen_random_file(dummy_tee) 1425 FitImageTestCase._gen_random_file(dummy_tee)
1353 1426
1354 self._test_fitimage(bb_vars) 1427 self._test_fitimage(bb_vars)
1428
1429
1430 def test_sign_uboot_kernel_individual(self):
1431 """
1432 Summary: Check if the device-tree from U-Boot has two public keys
1433 for verifying the kernel FIT image created by the
1434 kernel-fitimage.bbclass included.
1435 This test sets: FIT_SIGN_INDIVIDUAL = "1"
1436 Expected: There must be two signature nodes. One is required for
1437 the individual image nodes, the other is required for the
1438 verification of the configuration section.
1439 """
1440 config = """
1441# Enable creation of fitImage
1442MACHINE = "beaglebone-yocto"
1443UBOOT_SIGN_ENABLE = "1"
1444UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
1445UBOOT_SIGN_KEYNAME = "the-kernel-config-key"
1446UBOOT_SIGN_IMG_KEYNAME = "the-kernel-image-key"
1447UBOOT_MKIMAGE_DTCOPTS="-I dts -O dtb -p 2000"
1448FIT_SIGN_INDIVIDUAL = "1"
1449"""
1450 self.write_config(config)
1451 bb_vars = self._fit_get_bb_vars()
1452
1453 # Using a static key. FIT_GENERATE_KEYS = "1" does not work without kernel-fitimage.bbclass
1454 self._gen_signing_key(bb_vars)
1455
1456 bitbake("virtual/bootloader")
1457
1458 # Just check the DTB of u-boot since there is no u-boot FIT image
1459 self._check_kernel_dtb(bb_vars)