summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
authorJamin Lin <jamin_lin@aspeedtech.com>2025-02-17 16:52:33 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2025-02-27 10:55:17 +0000
commit0247289464b1b08e486b8358005e080926a0175e (patch)
tree9836087909de0dc42707004ce9d5d8844c1d9bee /meta/lib
parent7be7e16cbb26f87ed1fda853c037265c0cbb00a3 (diff)
downloadpoky-0247289464b1b08e486b8358005e080926a0175e.tar.gz
oe-selftest: fitimage: add testcases to test ATF and TEE
Add "test_uboot_atf_tee_fit_image" test caste to check u-boot FIT image and Image Tree Source(ITS) are built and the ITS has the correct fields. Add "test_sign_standalone_uboot_atf_tee_fit_image" test case to check if u-boot FIT image and Image Tree Source (ITS) are created and signed correctly for the scenario where only the u-boot proper fitImage is being created and signed. Currently, ATF and TEE(optee-os) recipes are placed in meta-arm layer. OpenEmbedded-Core is a basic and core meta layer. To avoid OpenEmbedded-core depends meta-arm, both test cases are used dummy images for testing. (From OE-Core rev: 92e51452f8831f74e0907b960135eef8cecd012a) Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Signed-off-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oeqa/selftest/cases/fitimage.py281
1 files changed, 281 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 5a400c200f..5af9ea8afc 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -894,3 +894,284 @@ FIT_HASH_ALG = "sha256"
894 # Check if the u-boot boot.scr script is in the fitImage 894 # Check if the u-boot boot.scr script is in the fitImage
895 dumpimage_result = self._run_dumpimage(fitimage_path, uboot_tools_bindir) 895 dumpimage_result = self._run_dumpimage(fitimage_path, uboot_tools_bindir)
896 self._verify_fitimage_uboot_env(dumpimage_result) 896 self._verify_fitimage_uboot_env(dumpimage_result)
897
898
899 def test_uboot_atf_tee_fit_image(self):
900 """
901 Summary: Check if U-boot FIT image and Image Tree Source
902 (its) are built and the Image Tree Source has the
903 correct fields.
904 Expected: 1. Create atf and tee dummy images
905 2. Both u-boot-fitImage and u-boot-its can be built
906 3. The os, load address, entrypoint address and
907 default values of U-boot, ATF and TEE images are
908 correct in the Image Tree Source. Not all the
909 fields are tested, only the key fields that wont
910 vary between different architectures.
911 Product: oe-core
912 Author: Jamin Lin <jamin_lin@aspeedtech.com>
913 """
914 config = """
915# We need at least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set
916MACHINE = "qemuarm"
917UBOOT_MACHINE = "am57xx_evm_defconfig"
918SPL_BINARY = "MLO"
919
920# Enable creation of the U-Boot fitImage
921UBOOT_FITIMAGE_ENABLE = "1"
922
923# (U-boot) fitImage properties
924UBOOT_LOADADDRESS = "0x80080000"
925UBOOT_ENTRYPOINT = "0x80080000"
926UBOOT_FIT_DESC = "A model description"
927
928# Enable creation of the TEE fitImage
929UBOOT_FIT_TEE = "1"
930
931# TEE fitImage properties
932UBOOT_FIT_TEE_IMAGE = "${TOPDIR}/tee-dummy.bin"
933UBOOT_FIT_TEE_LOADADDRESS = "0x80180000"
934UBOOT_FIT_TEE_ENTRYPOINT = "0x80180000"
935
936# Enable creation of the ATF fitImage
937UBOOT_FIT_ARM_TRUSTED_FIRMWARE = "1"
938
939# ATF fitImage properties
940UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE = "${TOPDIR}/atf-dummy.bin"
941UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS = "0x80280000"
942UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000"
943"""
944 self.write_config(config)
945
946 # Create an ATF dummy image
947 atf_dummy_image = os.path.join(self.builddir, "atf-dummy.bin")
948 cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (atf_dummy_image)
949 result = runCmd(cmd)
950 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
951
952 # Create a TEE dummy image
953 tee_dummy_image = os.path.join(self.builddir, "tee-dummy.bin")
954 cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (tee_dummy_image)
955 result = runCmd(cmd)
956 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
957
958 # The U-Boot fitImage is created as part of the U-Boot recipe
959 bitbake("virtual/bootloader")
960
961 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
962 machine = get_bb_var('MACHINE')
963 fitimage_its_path = os.path.join(deploy_dir_image,
964 "u-boot-its-%s" % (machine,))
965 fitimage_path = os.path.join(deploy_dir_image,
966 "u-boot-fitImage-%s" % (machine,))
967
968 self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path))
969 self.assertExists(fitimage_path, "%s FIT image doesn't exist" % (fitimage_path))
970
971 # Check that the type, load address, entrypoint address and default
972 # values for u-boot, ATF and TEE in Image Tree Source are as expected.
973 # The order of fields in the below array is important. Not all the
974 # fields are tested, only the key fields that wont vary between
975 # different architectures.
976 its_field_check = [
977 'description = "A model description";',
978 'type = "standalone";',
979 'load = <0x80080000>;',
980 'entry = <0x80080000>;',
981 'description = "Trusted Execution Environment";',
982 'os = "tee";',
983 'load = <0x80180000>;',
984 'entry = <0x80180000>;',
985 'description = "ARM Trusted Firmware";',
986 'os = "arm-trusted-firmware";',
987 'load = <0x80280000>;',
988 'entry = <0x80280000>;',
989 'default = "conf";',
990 'loadables = "atf", "tee", "uboot";',
991 'fdt = "fdt";'
992 ]
993
994 with open(fitimage_its_path) as its_file:
995 field_index = 0
996 for line in its_file:
997 if field_index == len(its_field_check):
998 break
999 if its_field_check[field_index] in line:
1000 field_index +=1
1001
1002 if field_index != len(its_field_check): # if its equal, the test passed
1003 self.assertTrue(field_index == len(its_field_check),
1004 "Fields in Image Tree Source File %s did not match, error in finding %s"
1005 % (fitimage_its_path, its_field_check[field_index]))
1006
1007
1008 def test_sign_standalone_uboot_atf_tee_fit_image(self):
1009 """
1010 Summary: Check if U-Boot FIT image and Image Tree Source (its) are
1011 created and signed correctly for the scenario where only
1012 the U-Boot proper fitImage is being created and signed.
1013 Expected: 1. Create atf and tee dummy images
1014 2. U-Boot its and FIT image are built successfully
1015 3. Scanning the its file indicates signing is enabled
1016 as requested by SPL_SIGN_ENABLE (using keys generated
1017 via UBOOT_FIT_GENERATE_KEYS)
1018 4. Dumping the FIT image indicates signature values
1019 are present
1020 5. Examination of the do_uboot_assemble_fitimage
1021 runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN
1022 and SPL_MKIMAGE_SIGN_ARGS are working as expected.
1023 Product: oe-core
1024 Author: Jamin Lin <jamin_lin@aspeedtech.com>
1025 """
1026 a_comment = "a smart U-Boot ATF TEE comment"
1027 config = """
1028# There's no U-boot deconfig with CONFIG_FIT_SIGNATURE yet, so we need at
1029# least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set
1030MACHINE = "qemuarm"
1031UBOOT_MACHINE = "am57xx_evm_defconfig"
1032SPL_BINARY = "MLO"
1033# The kernel-fitimage class is a dependency even if we're only
1034# creating/signing the U-Boot fitImage
1035KERNEL_CLASSES = " kernel-fitimage"
1036# Enable creation and signing of the U-Boot fitImage
1037UBOOT_FITIMAGE_ENABLE = "1"
1038SPL_SIGN_ENABLE = "1"
1039SPL_SIGN_KEYNAME = "spl-oe-selftest"
1040SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
1041UBOOT_DTB_BINARY = "u-boot.dtb"
1042UBOOT_ENTRYPOINT = "0x80000000"
1043UBOOT_LOADADDRESS = "0x80000000"
1044UBOOT_ARCH = "arm"
1045SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
1046SPL_MKIMAGE_SIGN_ARGS = "-c '%s'"
1047UBOOT_EXTLINUX = "0"
1048UBOOT_FIT_GENERATE_KEYS = "1"
1049UBOOT_FIT_HASH_ALG = "sha256"
1050
1051# Enable creation of the TEE fitImage
1052UBOOT_FIT_TEE = "1"
1053
1054# TEE fitImage properties
1055UBOOT_FIT_TEE_IMAGE = "${TOPDIR}/tee-dummy.bin"
1056UBOOT_FIT_TEE_LOADADDRESS = "0x80180000"
1057UBOOT_FIT_TEE_ENTRYPOINT = "0x80180000"
1058
1059# Enable creation of the ATF fitImage
1060UBOOT_FIT_ARM_TRUSTED_FIRMWARE = "1"
1061
1062# ATF fitImage properties
1063UBOOT_FIT_ARM_TRUSTED_FIRMWARE_IMAGE = "${TOPDIR}/atf-dummy.bin"
1064UBOOT_FIT_ARM_TRUSTED_FIRMWARE_LOADADDRESS = "0x80280000"
1065UBOOT_FIT_ARM_TRUSTED_FIRMWARE_ENTRYPOINT = "0x80280000"
1066""" % a_comment
1067
1068 self.write_config(config)
1069
1070 # Create an ATF dummy image
1071 atf_dummy_image = os.path.join(self.builddir, "atf-dummy.bin")
1072 cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (atf_dummy_image)
1073 result = runCmd(cmd)
1074 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
1075
1076 # Create a TEE dummy image
1077 tee_dummy_image = os.path.join(self.builddir, "tee-dummy.bin")
1078 cmd = 'dd if=/dev/random of=%s bs=1k count=64' % (tee_dummy_image)
1079 result = runCmd(cmd)
1080 self.logger.debug("%s\nreturned: %s\n%s", cmd, str(result.status), result.output)
1081
1082 # The U-Boot fitImage is created as part of the U-Boot recipe
1083 bitbake("virtual/bootloader")
1084
1085 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
1086 machine = get_bb_var('MACHINE')
1087 fitimage_its_path = os.path.join(deploy_dir_image,
1088 "u-boot-its-%s" % (machine,))
1089 fitimage_path = os.path.join(deploy_dir_image,
1090 "u-boot-fitImage-%s" % (machine,))
1091
1092 self.assertExists(fitimage_its_path, "%s image tree source doesn't exist" % (fitimage_its_path))
1093 self.assertExists(fitimage_path, "%s FIT image doesn't exist" % (fitimage_path))
1094
1095 req_itspaths = [
1096 ['/', 'images', 'uboot'],
1097 ['/', 'images', 'uboot', 'signature'],
1098 ['/', 'images', 'fdt'],
1099 ['/', 'images', 'fdt', 'signature'],
1100 ['/', 'images', 'tee'],
1101 ['/', 'images', 'tee', 'signature'],
1102 ['/', 'images', 'atf'],
1103 ['/', 'images', 'atf', 'signature'],
1104 ]
1105
1106 itspath = []
1107 itspaths = []
1108 linect = 0
1109 sigs = {}
1110 with open(fitimage_its_path) as its_file:
1111 linect += 1
1112 for line in its_file:
1113 line = line.strip()
1114 if line.endswith('};'):
1115 itspath.pop()
1116 elif line.endswith('{'):
1117 itspath.append(line[:-1].strip())
1118 itspaths.append(itspath[:])
1119 elif itspath and itspath[-1] == 'signature':
1120 itsdotpath = '.'.join(itspath)
1121 if not itsdotpath in sigs:
1122 sigs[itsdotpath] = {}
1123 if not '=' in line or not line.endswith(';'):
1124 self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line))
1125 key, value = line.split('=', 1)
1126 sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';')
1127
1128 for reqpath in req_itspaths:
1129 if not reqpath in itspaths:
1130 self.fail('Missing section in its file: %s' % reqpath)
1131
1132 reqsigvalues_image = {
1133 'algo': '"sha256,rsa2048"',
1134 'key-name-hint': '"spl-oe-selftest"',
1135 }
1136
1137 for itspath, values in sigs.items():
1138 reqsigvalues = reqsigvalues_image
1139 for reqkey, reqvalue in reqsigvalues.items():
1140 value = values.get(reqkey, None)
1141 if value is None:
1142 self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath))
1143 self.assertEqual(value, reqvalue)
1144
1145 # Dump the image to see if it really got signed
1146 uboot_tools_bindir = self._setup_uboot_tools_native()
1147 dumpimage_result = self._run_dumpimage(fitimage_path, uboot_tools_bindir)
1148 in_signed = None
1149 signed_sections = {}
1150 for line in dumpimage_result.output.splitlines():
1151 if line.startswith((' Image')):
1152 in_signed = re.search(r'\((.*)\)', line).groups()[0]
1153 elif re.match(' \w', line):
1154 in_signed = None
1155 elif in_signed:
1156 if not in_signed in signed_sections:
1157 signed_sections[in_signed] = {}
1158 key, value = line.split(':', 1)
1159 signed_sections[in_signed][key.strip()] = value.strip()
1160 self.assertIn('uboot', signed_sections)
1161 self.assertIn('fdt', signed_sections)
1162 self.assertIn('tee', signed_sections)
1163 self.assertIn('atf', signed_sections)
1164 for signed_section, values in signed_sections.items():
1165 value = values.get('Sign algo', None)
1166 self.assertEqual(value, 'sha256,rsa2048:spl-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
1167 value = values.get('Sign value', None)
1168 self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)
1169
1170 # Check for SPL_MKIMAGE_SIGN_ARGS
1171 # Looks like mkimage supports to add a comment but does not support to read it back.
1172 found_comments = FitImageTests._find_string_in_bin_file(fitimage_path, a_comment)
1173 self.assertEqual(found_comments, 4, "Expected 4 signed and commented section in the fitImage.")
1174
1175 # Verify the signature
1176 self._verify_fit_image_signature(uboot_tools_bindir, fitimage_path,
1177 os.path.join(deploy_dir_image, 'u-boot-spl.dtb'))