summaryrefslogtreecommitdiffstats
path: root/meta/lib
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@microsoft.com>2020-12-16 18:51:42 -0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-12-20 00:03:04 +0000
commit87b38ee1c14d5fa0d4ad8256b1828fb218951bdd (patch)
tree35a7d527a43bef965ec2011e2184c069b250fa98 /meta/lib
parentb23d338176136cae7d3f0d9ce930b03158ecbbc8 (diff)
downloadpoky-87b38ee1c14d5fa0d4ad8256b1828fb218951bdd.tar.gz
oe-selftest: fitimage: add test for signing FIT images
Add a new test to verify signing FIT images. Also includes testing for the newly introduced FIT_SIGN_INDIVIDUAL, UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN, and UBOOT_MKIMAGE_SIGN_ARGS variables. (From OE-Core rev: 3c054762278fd8c5dd827dbac15f4fa066e6c19e) Signed-off-by: Paul Eggleton <paul.eggleton@microsoft.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/lib')
-rw-r--r--meta/lib/oeqa/selftest/cases/fitimage.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 2a02c60251..19b9f53ee4 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -6,6 +6,7 @@ from oeqa.selftest.case import OESelftestTestCase
6from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu 6from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu
7import os 7import os
8import json 8import json
9import re
9 10
10class FitImageTests(OESelftestTestCase): 11class FitImageTests(OESelftestTestCase):
11 12
@@ -85,3 +86,148 @@ FIT_DESC = "A model description"
85 self.assertTrue(field_index == len(its_field_check), 86 self.assertTrue(field_index == len(its_field_check),
86 "Fields in Image Tree Source File %s did not match, error in finding %s" 87 "Fields in Image Tree Source File %s did not match, error in finding %s"
87 % (fitimage_its_path, its_field_check[field_index])) 88 % (fitimage_its_path, its_field_check[field_index]))
89
90
91 def test_sign_fit_image(self):
92 """
93 Summary: Check if FIT image and Image Tree Source (its) are created
94 and signed correctly.
95 Expected: 1) its and FIT image are built successfully
96 2) Scanning the its file indicates signing is enabled
97 as requested by UBOOT_SIGN_ENABLE (using keys generated
98 via FIT_GENERATE_KEYS)
99 3) Dumping the FIT image indicates signature values
100 are present (including for images as enabled via
101 FIT_SIGN_INDIVIDUAL)
102 4) Examination of the do_assemble_fitimage runfile/logfile
103 indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN and
104 UBOOT_MKIMAGE_SIGN_ARGS are working as expected.
105 Product: oe-core
106 Author: Paul Eggleton <paul.eggleton@microsoft.com> based upon
107 work by Usama Arif <usama.arif@arm.com>
108 """
109 config = """
110# Enable creation of fitImage
111MACHINE = "beaglebone-yocto"
112KERNEL_IMAGETYPES += " fitImage "
113KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
114UBOOT_SIGN_ENABLE = "1"
115FIT_GENERATE_KEYS = "1"
116UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
117UBOOT_SIGN_KEYNAME = "oe-selftest"
118FIT_SIGN_INDIVIDUAL = "1"
119UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
120"""
121 self.write_config(config)
122
123 # fitImage is created as part of linux recipe
124 bitbake("virtual/kernel")
125
126 image_type = "core-image-minimal"
127 deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
128 machine = get_bb_var('MACHINE')
129 fitimage_its_path = os.path.join(deploy_dir_image,
130 "fitImage-its-%s" % (machine,))
131 fitimage_path = os.path.join(deploy_dir_image,
132 "fitImage-%s.bin" % (machine,))
133
134 self.assertTrue(os.path.exists(fitimage_its_path),
135 "%s image tree source doesn't exist" % (fitimage_its_path))
136 self.assertTrue(os.path.exists(fitimage_path),
137 "%s FIT image doesn't exist" % (fitimage_path))
138
139 req_itspaths = [
140 ['/', 'images', 'kernel@1'],
141 ['/', 'images', 'kernel@1', 'signature@1'],
142 ['/', 'images', 'fdt@am335x-boneblack.dtb'],
143 ['/', 'images', 'fdt@am335x-boneblack.dtb', 'signature@1'],
144 ['/', 'configurations', 'conf@am335x-boneblack.dtb'],
145 ['/', 'configurations', 'conf@am335x-boneblack.dtb', 'signature@1'],
146 ]
147
148 itspath = []
149 itspaths = []
150 linect = 0
151 sigs = {}
152 with open(fitimage_its_path) as its_file:
153 linect += 1
154 for line in its_file:
155 line = line.strip()
156 if line.endswith('};'):
157 itspath.pop()
158 elif line.endswith('{'):
159 itspath.append(line[:-1].strip())
160 itspaths.append(itspath[:])
161 elif itspath and itspath[-1] == 'signature@1':
162 itsdotpath = '.'.join(itspath)
163 if not itsdotpath in sigs:
164 sigs[itsdotpath] = {}
165 if not '=' in line or not line.endswith(';'):
166 self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line))
167 key, value = line.split('=', 1)
168 sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';')
169
170 for reqpath in req_itspaths:
171 if not reqpath in itspaths:
172 self.fail('Missing section in its file: %s' % reqpath)
173
174 reqsigvalues_image = {
175 'algo': '"sha256,rsa2048"',
176 'key-name-hint': '"oe-selftest"',
177 }
178 reqsigvalues_config = {
179 'algo': '"sha256,rsa2048"',
180 'key-name-hint': '"oe-selftest"',
181 'sign-images': '"kernel", "fdt"',
182 }
183
184 for itspath, values in sigs.items():
185 if 'conf@' in itspath:
186 reqsigvalues = reqsigvalues_config
187 else:
188 reqsigvalues = reqsigvalues_image
189 for reqkey, reqvalue in reqsigvalues.items():
190 value = values.get(reqkey, None)
191 if value is None:
192 self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath))
193 self.assertEqual(value, reqvalue)
194
195 # Dump the image to see if it really got signed
196 bitbake("u-boot-tools-native -c addto_recipe_sysroot")
197 result = runCmd('bitbake -e u-boot-tools-native | grep ^RECIPE_SYSROOT_NATIVE=')
198 recipe_sysroot_native = result.output.split('=')[1].strip('"')
199 dumpimage_path = os.path.join(recipe_sysroot_native, 'usr', 'bin', 'dumpimage')
200 result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path))
201 in_signed = None
202 signed_sections = {}
203 for line in result.output.splitlines():
204 if line.startswith((' Configuration', ' Image')):
205 in_signed = re.search('\((.*)\)', line).groups()[0]
206 elif re.match('^ *', line) in (' ', ''):
207 in_signed = None
208 elif in_signed:
209 if not in_signed in signed_sections:
210 signed_sections[in_signed] = {}
211 key, value = line.split(':', 1)
212 signed_sections[in_signed][key.strip()] = value.strip()
213 self.assertIn('kernel@1', signed_sections)
214 self.assertIn('fdt@am335x-boneblack.dtb', signed_sections)
215 self.assertIn('conf@am335x-boneblack.dtb', signed_sections)
216 for signed_section, values in signed_sections.items():
217 value = values.get('Sign algo', None)
218 self.assertEqual(value, 'sha256,rsa2048:oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
219 value = values.get('Sign value', None)
220 self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)
221
222 # Check for UBOOT_MKIMAGE_SIGN_ARGS
223 result = runCmd('bitbake -e virtual/kernel | grep ^T=')
224 tempdir = result.output.split('=', 1)[1].strip().strip('')
225 result = runCmd('grep "a smart comment" %s/run.do_assemble_fitimage' % tempdir, ignore_status=True)
226 self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN_ARGS value did not get used')
227
228 # Check for evidence of test-mkimage-wrapper class
229 result = runCmd('grep "### uboot-mkimage wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True)
230 self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE did not work')
231 result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True)
232 self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work')
233