diff mbox series

[7/7] oe-selftest: fitimage add more kernel tests

Message ID 20250310093641.1983560-8-adrian.freihofer@siemens.com
State Accepted, archived
Commit 0a5b65b83dcd9f8d1d22d074fdfad1f1e472827c
Headers show
Series oe-selftest FIT image cleanup | expand

Commit Message

Adrian Freihofer March 10, 2025, 9:35 a.m. UTC
* Test with only one externally provided ssh key not only with two
  keys generated by the kernel-fitimage.bbclass itself.
* Add a test which signs only the configuration but not the image nodes.
  There was no test case which covered the probably much more important
  use case of setting FIT_SIGN_INDIVIDUAL = "0".
* Cover also the unbundled initramfs use case. Also this use case is
  probably much more relevant than the bundled initramnfs use case.

Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com>
---
 meta/lib/oeqa/selftest/cases/fitimage.py | 151 ++++++++++++++++++++++-
 1 file changed, 149 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/meta/lib/oeqa/selftest/cases/fitimage.py b/meta/lib/oeqa/selftest/cases/fitimage.py
index 6f3bf296d56..721628d8e73 100644
--- a/meta/lib/oeqa/selftest/cases/fitimage.py
+++ b/meta/lib/oeqa/selftest/cases/fitimage.py
@@ -39,6 +39,52 @@  class FitImageTestCase(OESelftestTestCase):
     MKIMAGE_HASH_LENGTHS = { 'sha256': 64, 'sha384': 96, 'sha512': 128 }
     MKIMAGE_SIGNATURE_LENGTHS = { 'rsa2048': 512 }
 
+    def _gen_signing_key(self, bb_vars):
+        """Generate a key pair and a singing certificate
+
+        Generate a UBOOT_SIGN_KEYNAME in the UBOOT_SIGN_KEYDIR similar to what
+        the FIT_GENERATE_KEYS feature does. However, having a static key is
+        probably a more realistic use case than generating a random key with
+        each clean build. So this needs to be tested as well.
+        The FIT_GENERATE_KEYS generates 2 keys: The UBOOT_SIGN_KEYNAME and the
+        UBOOT_SIGN_IMG_KEYNAME. The UBOOT_SIGN_IMG_KEYNAME is used by the
+        FIT_SIGN_INDIVIDUAL feature only. Testing if everything is working if
+        there is only one key available is important as well. Therefore this
+        function generates only the keys which are really needed, not just two.
+        """
+
+        # Define some variables which are usually defined by the kernel-fitimage.bbclass.
+        # But for testing purpose check if the uboot-sign.bbclass is independent from
+        # the kernel-fitimage.bbclass
+        fit_sign_numbits = bb_vars['FIT_SIGN_NUMBITS'] or "2048"
+        fit_key_genrsa_args = bb_vars['FIT_KEY_GENRSA_ARGS'] or "-F4"
+        fit_key_req_args =  bb_vars['FIT_KEY_REQ_ARGS'] or "-batch -new"
+        fit_key_sign_pkcs = bb_vars['FIT_KEY_SIGN_PKCS'] or "-x509"
+
+        uboot_sign_keydir = bb_vars['UBOOT_SIGN_KEYDIR']
+        sign_keys = [bb_vars['UBOOT_SIGN_KEYNAME']]
+        if bb_vars['FIT_SIGN_INDIVIDUAL'] == "1":
+            sign_keys.append(bb_vars['UBOOT_SIGN_IMG_KEYNAME'])
+        for sign_key in sign_keys:
+            sing_key_path = os.path.join(uboot_sign_keydir, sign_key)
+            if not os.path.isdir(uboot_sign_keydir):
+                os.makedirs(uboot_sign_keydir)
+            openssl_bindir = FitImageTestCase._setup_native('openssl-native')
+            openssl_path = os.path.join(openssl_bindir, 'openssl')
+            runCmd("%s genrsa %s -out %s.key %s" % (
+                openssl_path,
+                fit_key_genrsa_args,
+                sing_key_path,
+                fit_sign_numbits
+            ))
+            runCmd("%s req %s %s -key %s.key -out %s.crt" % (
+                openssl_path,
+                fit_key_req_args,
+                fit_key_sign_pkcs,
+                sing_key_path,
+                sing_key_path
+            ))
+
     @staticmethod
     def _gen_random_file(file_path, num_bytes=65536):
         with open(file_path, 'wb') as file_out:
@@ -632,7 +678,50 @@  FIT_DESC = "A model description"
         self._test_fitimage(bb_vars)
 
 
-    def test_sign_fit_image(self):
+    def test_sign_fit_image_configurations(self):
+        """
+        Summary:     Check if FIT image and Image Tree Source (its) are created
+                     and the configuration nodes are signed correctly.
+        Expected:    1) its and FIT image are built successfully
+                     2) Scanning the its file indicates signing is enabled
+                        as requested by UBOOT_SIGN_ENABLE (using 1 key
+                        generated by the test not via FIT_GENERATE_KEYS)
+                     3) Dumping the FIT image indicates signature values
+                        are present (only for the configuration nodes as
+                        FIT_SIGN_INDIVIDUAL is disabled)
+                     4) Verify the FIT image contains the comments passed via
+                        UBOOT_MKIMAGE_SIGN_ARGS once per configuration node.
+        """
+        # Generate a configuration section which gets included into the local.conf file
+        config = """
+# Enable creation of fitImage
+MACHINE = "beaglebone-yocto"
+KERNEL_IMAGETYPES += " fitImage "
+KERNEL_CLASSES = " kernel-fitimage "
+UBOOT_SIGN_ENABLE = "1"
+UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
+UBOOT_SIGN_KEYNAME = "dev"
+UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
+"""
+        config = self._config_add_uboot_env(config)
+        self.write_config(config)
+
+        # Retrieve some variables from bitbake
+        bb_vars = self._fit_get_bb_vars([
+            'FIT_KEY_GENRSA_ARGS',
+            'FIT_KEY_REQ_ARGS',
+            'FIT_KEY_SIGN_PKCS',
+            'FIT_SIGN_NUMBITS',
+            'UBOOT_SIGN_KEYDIR',
+        ])
+
+        # Do not use the random keys generated by FIT_GENERATE_KEYS.
+        # Using a static key is probably a more realistic scenario.
+        self._gen_signing_key(bb_vars)
+
+        self._test_fitimage(bb_vars)
+
+    def test_sign_fit_image_individual(self):
         """
         Summary:     Check if FIT image and Image Tree Source (its) are created
                      and all nodes are signed correctly.
@@ -673,8 +762,66 @@  UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
         bb_vars = self._fit_get_bb_vars()
         self._test_fitimage(bb_vars)
 
+    def test_fit_image_sign_initramfs(self):
+        """
+        Summary:     Verifies the content of the initramfs node in the FIT Image Tree Source (its)
+                     The FIT settings are set by the test case.
+                     The machine used is beaglebone-yocto.
+        Expected:    1. The ITS is generated with initramfs support
+                     2. All the fields in the kernel node are as expected (matching the
+                        conf settings)
+                     3. The kernel is included in all the available configurations and
+                        its hash is included in the configuration signature
 
-    def test_initramfs_bundle(self):
+        Product:     oe-core
+        Author:      Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+        """
+
+        config = """
+DISTRO="poky"
+MACHINE = "beaglebone-yocto"
+INITRAMFS_IMAGE = "core-image-minimal-initramfs"
+INITRAMFS_SCRIPTS = ""
+UBOOT_MACHINE = "am335x_evm_defconfig"
+KERNEL_CLASSES = " kernel-fitimage "
+KERNEL_IMAGETYPES = "fitImage"
+UBOOT_SIGN_ENABLE = "1"
+UBOOT_SIGN_KEYNAME = "beaglebonekey"
+UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}"
+UBOOT_DTB_BINARY = "u-boot.dtb"
+UBOOT_ENTRYPOINT  = "0x80000000"
+UBOOT_LOADADDRESS = "0x80000000"
+UBOOT_RD_LOADADDRESS = "0x88000000"
+UBOOT_RD_ENTRYPOINT = "0x88000000"
+UBOOT_DTB_LOADADDRESS = "0x82000000"
+UBOOT_ARCH = "arm"
+UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
+UBOOT_MKIMAGE_KERNEL_TYPE = "kernel"
+UBOOT_EXTLINUX = "0"
+FIT_GENERATE_KEYS = "1"
+KERNEL_IMAGETYPE_REPLACEMENT = "zImage"
+FIT_KERNEL_COMP_ALG = "none"
+FIT_HASH_ALG = "sha256"
+"""
+        config = self._config_add_uboot_env(config)
+        self.write_config(config)
+
+        # Retrieve some variables from bitbake
+        bb_vars = self._fit_get_bb_vars([
+            'FIT_KEY_GENRSA_ARGS',
+            'FIT_KEY_REQ_ARGS',
+            'FIT_KEY_SIGN_PKCS',
+            'FIT_SIGN_NUMBITS',
+            'UBOOT_SIGN_KEYDIR',
+        ])
+
+        # Do not use the random keys generated by FIT_GENERATE_KEYS.
+        # Using a static key is probably a more realistic scenario.
+        self._gen_signing_key(bb_vars)
+
+        self._test_fitimage(bb_vars)
+
+    def test_fit_image_sign_initramfs_bundle(self):
         """
         Summary:     Verifies the content of the initramfs bundle node in the FIT Image Tree Source (its)
                      The FIT settings are set by the test case.