diff options
| author | Adrian Freihofer <adrian.freihofer@gmail.com> | 2025-03-17 18:13:56 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2025-03-18 10:27:31 +0000 |
| commit | 12801c7bbbcf902102c3350e91d9256844e2492a (patch) | |
| tree | 63e59385a20191272a58d10bca74cf071381a0de | |
| parent | 4632788c431b1348f0c281f8894acff994b3e45f (diff) | |
| download | poky-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.py | 117 |
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" | |||
| 1209 | UBOOT_FIT_GENERATE_KEYS = "1" | 1280 | UBOOT_FIT_GENERATE_KEYS = "1" |
| 1210 | UBOOT_FIT_HASH_ALG = "sha256" | 1281 | UBOOT_FIT_HASH_ALG = "sha256" |
| 1211 | UBOOT_SIGN_ENABLE = "1" | 1282 | UBOOT_SIGN_ENABLE = "1" |
| 1212 | FIT_GENERATE_KEYS = "1" | ||
| 1213 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | 1283 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" |
| 1214 | UBOOT_SIGN_IMG_KEYNAME = "img-oe-selftest" | ||
| 1215 | UBOOT_SIGN_KEYNAME = "cfg-oe-selftest" | 1284 | UBOOT_SIGN_KEYNAME = "cfg-oe-selftest" |
| 1216 | FIT_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 | ||
| 1442 | MACHINE = "beaglebone-yocto" | ||
| 1443 | UBOOT_SIGN_ENABLE = "1" | ||
| 1444 | UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys" | ||
| 1445 | UBOOT_SIGN_KEYNAME = "the-kernel-config-key" | ||
| 1446 | UBOOT_SIGN_IMG_KEYNAME = "the-kernel-image-key" | ||
| 1447 | UBOOT_MKIMAGE_DTCOPTS="-I dts -O dtb -p 2000" | ||
| 1448 | FIT_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) | ||
