All of lore.kernel.org
 help / color / mirror / Atom feed
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [PATCH v5 12/16] efi_loader, pytest: set up secure boot environment
Date: Tue, 28 Jan 2020 17:25:28 +0900	[thread overview]
Message-ID: <20200128082532.15943-13-takahiro.akashi@linaro.org> (raw)
In-Reply-To: <20200128082532.15943-1-takahiro.akashi@linaro.org>

A fixture for UEFI secure boot tests (image authentication and variable
authentication) is defined. A small file system with test data in a single
partition formatted in fat is created.

This test requires efitools v1.5.2 or later. If the system's efitools
is older, you have to build it on your own and define EFITOOLS_PATH.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 test/py/README.md                          |   8 ++
 test/py/tests/test_efi_secboot/conftest.py | 151 +++++++++++++++++++++
 test/py/tests/test_efi_secboot/defs.py     |  21 +++
 3 files changed, 180 insertions(+)
 create mode 100644 test/py/tests/test_efi_secboot/conftest.py
 create mode 100644 test/py/tests/test_efi_secboot/defs.py

diff --git a/test/py/README.md b/test/py/README.md
index 3cbe01b73e28..aa8a5607b064 100644
--- a/test/py/README.md
+++ b/test/py/README.md
@@ -37,7 +37,15 @@ will be required.  The following is an incomplete list:
 | openssl        |
 | sudo OR guestmount |
 | e2fsprogs      |
+| util-linux     |
+| coreutils      |
 | dosfstools     |
+| efitools       |
+| mount          |
+| mtools         |
+| sbsigntool     |
+| udisks2        |
+
 
 Please use the apporirate commands for your distribution to match these tools
 up with the package that provides them.
diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py
new file mode 100644
index 000000000000..e542fef6e819
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/conftest.py
@@ -0,0 +1,151 @@
+# SPDX-License-Identifier:      GPL-2.0+
+# Copyright (c) 2019, Linaro Limited
+# Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+
+import os
+import os.path
+import pytest
+import re
+from subprocess import call, check_call, check_output, CalledProcessError
+from defs import *
+
+# from test/py/conftest.py
+def tool_is_in_path(tool):
+    for path in os.environ["PATH"].split(os.pathsep):
+        fn = os.path.join(path, tool)
+        if os.path.isfile(fn) and os.access(fn, os.X_OK):
+            return True
+    return False
+
+#
+# Fixture for UEFI secure boot test
+#
+ at pytest.fixture(scope='session')
+def efi_boot_env(request, u_boot_config):
+    """Set up a file system to be used in UEFI secure boot test.
+
+    Args:
+        request: Pytest request object.
+	u_boot_config: U-boot configuration.
+
+    Return:
+        A path to disk image to be used for testing
+    """
+    global HELLO_PATH
+
+    image_path = u_boot_config.persistent_data_dir
+    image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME
+    image_size = EFI_SECBOOT_IMAGE_SIZE
+    part_size = EFI_SECBOOT_PART_SIZE
+    fs_type = EFI_SECBOOT_FS_TYPE
+
+    if HELLO_PATH == '':
+        HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi'
+
+    try:
+        non_root = tool_is_in_path('udisksctl')
+
+        # create a disk/partition
+        check_call('dd if=/dev/zero of=%s bs=1MiB count=%d'
+                            % (image_path, image_size), shell=True)
+        check_call('sgdisk %s -n 1:0:+%dMiB'
+                            % (image_path, part_size), shell=True)
+        # create a file system
+        check_call('dd if=/dev/zero of=%s.tmp bs=1MiB count=%d'
+                            % (image_path, part_size), shell=True)
+        check_call('mkfs -t %s %s.tmp' % (fs_type, image_path), shell=True)
+        check_call('dd if=%s.tmp of=%s bs=1MiB seek=1 count=%d conv=notrunc'
+                            % (image_path, image_path, 1), shell=True)
+        check_call('rm %s.tmp' % image_path, shell=True)
+        if non_root:
+            out_data = check_output('udisksctl loop-setup -f %s -o %d'
+                                % (image_path, 1048576), shell=True).decode()
+            m = re.search('(?<= as )(.*)\.', out_data)
+            loop_dev = m.group(1)
+            # print 'loop device is: %s' % loop_dev
+            out_data = check_output('udisksctl info -b %s'
+                                % loop_dev, shell=True).decode()
+            m = re.search('MountPoints:[ \t]+(.*)', out_data)
+            mnt_point = m.group(1)
+        else:
+            loop_dev = check_output('sudo losetup -o 1MiB --sizelimit %dMiB --show -f %s | tr -d "\n"'
+                                % (part_size, image_path), shell=True).decode()
+            mnt_point = '/mnt'
+            check_output('sudo mount -t %s -o umask=000 %s %s'
+                                % (fs_type, loop_dev, mnt_point), shell=True)
+
+        # print 'mount point is: %s' % mnt_point
+
+        # suffix
+        # *.key: RSA private key in PEM
+        # *.crt: X509 certificate (self-signed) in PEM
+        # *.esl: signature list
+        # *.hash: message digest of image as signature list
+        # *.auth: signed signature list in signature database format
+        # *.efi: UEFI image
+        # *.efi.signed: signed UEFI image
+
+        # Create signature database
+        ## PK
+        check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ -keyout PK.key -out PK.crt -nodes -days 365'
+                            % mnt_point, shell=True)
+        check_call('cd %s; %scert-to-efi-sig-list -g %s PK.crt PK.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth'
+                            % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+                            shell=True)
+        ## PK_null for deletion
+        check_call('cd %s; sleep 2; touch PK_null.esl; %ssign-efi-sig-list -c PK.crt -k PK.key PK PK_null.esl PK_null.auth'
+                            % (mnt_point, EFITOOLS_PATH), shell=True)
+        ## KEK
+        check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ -keyout KEK.key -out KEK.crt -nodes -days 365'
+                            % mnt_point, shell=True)
+        check_call('cd %s; %scert-to-efi-sig-list -g %s KEK.crt KEK.esl; %ssign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth'
+                            % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+                            shell=True)
+        ## db
+        check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ -keyout db.key -out db.crt -nodes -days 365'
+                            % mnt_point, shell=True)
+        check_call('cd %s; %scert-to-efi-sig-list -g %s db.crt db.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db.esl db.auth'
+                            % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+                            shell=True)
+        ## db1
+        check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db1/ -keyout db1.key -out db1.crt -nodes -days 365'
+                            % mnt_point, shell=True)
+        check_call('cd %s; %scert-to-efi-sig-list -g %s db1.crt db1.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db1.esl db1.auth'
+                            % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+                            shell=True)
+        ## db1-update
+        check_call('cd %s; %ssign-efi-sig-list -a -c KEK.crt -k KEK.key db db1.esl db1-update.auth'
+                            % (mnt_point, EFITOOLS_PATH), shell=True)
+        ## dbx
+        check_call('cd %s; openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_dbx/ -keyout dbx.key -out dbx.crt -nodes -days 365'
+                            % mnt_point, shell=True)
+        check_call('cd %s; %scert-to-efi-sig-list -g %s dbx.crt dbx.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key dbx dbx.esl dbx.auth'
+                            % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH),
+                            shell=True)
+
+        # Copy image
+        check_call('cp %s %s' % (HELLO_PATH, mnt_point), shell=True)
+
+        ## Sign image
+        check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi'
+                            % mnt_point, shell=True)
+        ## Digest image
+        check_call('cd %s; %shash-to-efi-sig-list helloworld.efi db_hello.hash; %ssign-efi-sig-list -c KEK.crt -k KEK.key db db_hello.hash db_hello.auth'
+                            % (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH),
+                            shell=True)
+
+        if non_root:
+            check_call('udisksctl unmount -b %s' % loop_dev, shell=True)
+            # not needed
+            # check_call('udisksctl loop-delete -b %s' % loop_dev, shell=True)
+        else:
+            check_call('sudo umount %s' % loop_dev, shell=True)
+            check_call('sudo losetup -d %s' % loop_dev, shell=True)
+
+    except CalledProcessError as e:
+        pytest.skip('Setup failed: %s' % e.cmd)
+        return
+    else:
+        yield image_path
+    finally:
+        call('rm -f %s' % image_path, shell=True)
diff --git a/test/py/tests/test_efi_secboot/defs.py b/test/py/tests/test_efi_secboot/defs.py
new file mode 100644
index 000000000000..d6222809c547
--- /dev/null
+++ b/test/py/tests/test_efi_secboot/defs.py
@@ -0,0 +1,21 @@
+# SPDX-License-Identifier:      GPL-2.0+
+
+# Disk image name
+EFI_SECBOOT_IMAGE_NAME='test_efi_secboot.img'
+
+# Size in MiB
+EFI_SECBOOT_IMAGE_SIZE=16
+EFI_SECBOOT_PART_SIZE=8
+
+# Partition file system type
+EFI_SECBOOT_FS_TYPE='vfat'
+
+# Owner guid
+GUID='11111111-2222-3333-4444-123456789abc'
+
+# v1.5.1 or earlier of efitools has a bug in sha256 calculation, and
+# you need build a newer version on your own.
+EFITOOLS_PATH=''
+
+# Hello World application for sandbox
+HELLO_PATH=''
-- 
2.24.0

  parent reply	other threads:[~2020-01-28  8:25 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-28  8:25 [PATCH v5 00/16] efi_loader: add secure boot support AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 01/16] efi_loader: add CONFIG_EFI_SECURE_BOOT config option AKASHI Takahiro
2020-02-23 10:56   ` Heinrich Schuchardt
2020-02-25  5:02     ` AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 02/16] efi_loader: add signature verification functions AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 03/16] efi_loader: add signature database parser AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 04/16] efi_loader: variable: support variable authentication AKASHI Takahiro
2020-02-23 11:20   ` Heinrich Schuchardt
2020-02-25  5:10     ` AKASHI Takahiro
2020-02-25  6:46   ` Heinrich Schuchardt
2020-02-26  0:51     ` AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 05/16] efi_loader: variable: add secure boot state transition AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 06/16] efi_loader: variable: add VendorKeys variable AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 07/16] efi_loader: image_loader: support image authentication AKASHI Takahiro
2020-02-24 18:29   ` Heinrich Schuchardt
2020-02-25  5:25     ` AKASHI Takahiro
2020-02-25  6:40       ` Heinrich Schuchardt
2020-02-25  6:57         ` AKASHI Takahiro
2020-02-25  6:44   ` Heinrich Schuchardt
2020-02-26  0:50     ` AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 08/16] efi_loader: set up secure boot AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 09/16] cmd: env: use appropriate guid for authenticated UEFI variable AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 10/16] cmd: env: add "-at" option to "env set -e" command AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 11/16] cmd: efidebug: add "test bootmgr" sub-command AKASHI Takahiro
2020-01-28  8:25 ` AKASHI Takahiro [this message]
2020-01-28  8:25 ` [PATCH v5 13/16] efi_loader, pytest: add UEFI secure boot tests (authenticated variables) AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 14/16] efi_loader, pytest: add UEFI secure boot tests (image) AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 15/16] sandbox: add extra configurations for UEFI and related tests AKASHI Takahiro
2020-01-28  8:25 ` [PATCH v5 16/16] travis: add packages for UEFI secure boot test AKASHI Takahiro
2020-02-23 11:46   ` Heinrich Schuchardt
2020-02-25  5:16     ` AKASHI Takahiro
2020-02-23 11:53 ` [PATCH v5 00/16] efi_loader: add secure boot support Heinrich Schuchardt
2020-02-25  5:19   ` AKASHI Takahiro
2020-02-23 21:48 ` Heinrich Schuchardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200128082532.15943-13-takahiro.akashi@linaro.org \
    --to=takahiro.akashi@linaro.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.