From patchwork Sat Jun 24 13:41:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 695737 Delivered-To: patch@linaro.org Received: by 2002:adf:e885:0:0:0:0:0 with SMTP id d5csp2551824wrm; Sat, 24 Jun 2023 13:50:30 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5GYMnXNdyDF588ZRpGwu776bXOr+7xXiB55150gprq8OOD8Fr5/UWZRlSGd7QHDYbydv9s X-Received: by 2002:a05:620a:479e:b0:765:47cc:ccbb with SMTP id dt30-20020a05620a479e00b0076547ccccbbmr5876347qkb.36.1687639829889; Sat, 24 Jun 2023 13:50:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687639829; cv=none; d=google.com; s=arc-20160816; b=aGW54cYNkHW/hg8UBL9gIfQZVKwYIEI9ei9KgtGASY2enhbBG5hjJVw297vImrRzkA /eQsGnghCyZD82AnY06Qx/LgrNlfVUSXTXIz+ScuGdaqEMFxXTw9XjG9MwKVzVaj3zNp LU1wbG8qccERAvAJlv40FH/NVdPa/arQUx6799s5xYmrT+XOIuB5LnlZUOO7xVRdj0vn x33mHX/G/4QVnWxndiFzlwuENg81vBlniy3KBeQuZWDY/HrSwSkmNnQOt+kuOHtQ5kz3 IPXTZbbFcXMqHnwjMhQc5QDDfdnjxrPvJnQk6KHulrvjVJu7/cBxq51KXSD5LlPmx3S3 zSYg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=CCnUPjXlSHt72w44suhUdnwy6kjbv2XbrMNW872EvNA=; fh=lu5TYXXCc9HXOnqxAkmvhXm+orfKNM3ataUOg5fXk40=; b=o6zurByjkGAkJrwNJp6tI2VX9kkq6vADvln7yBTpY8gbDdeoau3DmiDqIseqZ2bMJL KvHkTPAkhA2mnEXbZfryYwDIObx2cI9cae90Y9n878+b+d96u2J9emOz60B2t6t5fE0H wQdVML66qOUeUS7aiEQQBay/4cTDsai0svWAvKiKHsgYrfVikcBqVeWGKAf60vCz/mJa p4u3FI7rYnWfhs6jlnhcSwiq/S9t11GSZxMWiqcfmxJXhMfnForMrBSbwarOa08wSeD7 5xLskeo02oxHeXjXQ+/CUBgR1hGPraZdY4Pc2eAPD4KTFUqUR60g8qDc9mEdO+M4vQrw mwfg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id f11-20020a05620a408b00b00763a3fca13bsi822237qko.132.2023.06.24.13.50.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Jun 2023 13:50:29 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 9D33786290; Sat, 24 Jun 2023 22:49:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id 0583F847E3; Sat, 24 Jun 2023 22:49:16 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,SPF_HELO_NONE, SPF_SOFTFAIL,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id B3E9385FE2 for ; Sat, 24 Jun 2023 22:49:01 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E4D0F106F; Sat, 24 Jun 2023 06:42:41 -0700 (PDT) Received: from a076522.blr.arm.com (unknown [10.162.46.7]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4B7713F663; Sat, 24 Jun 2023 06:41:55 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Michal Simek , Takahiro Akashi , Malte Schmidt , Tom Rini , Sughosh Ganu Subject: [PATCH v2 3/8] test: py: Change capsule authenticate test flow Date: Sat, 24 Jun 2023 19:11:13 +0530 Message-Id: <20230624134118.944567-4-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230624134118.944567-1-sughosh.ganu@linaro.org> References: <20230624134118.944567-1-sughosh.ganu@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Currently, the keys and the EFI Signature List(ESL) file used for testing capsule authentication functionality are being generated after the u-boot image has been built. The ESL file is then embedded into the platform's DTB for capsule authentication. This flow has been changed through an earlier commit, which embeds the ESL file into the platform's dtb(s) as part of the u-boot build. This requires generating the keys and the ESL file prior to invoking the u-boot build. Bring about the same sequence of generating these files prior to invoking the u-boot build while testing. For testing the EFI capsule functionality through manual invocation of pytest, changes have been made to the configuration to generate the openssl keys and the ESL file prior to u-boot build. Similar changes have been made in the CI test environment to generate the keys and the ESL prior to the u-boot build. The binman node needed for invoking the corresponding entry module for embedding the ESL has been added for sandbox to facilitate testing. Signed-off-by: Sughosh Ganu --- Changes since V1: * Add the logic to generate the keys in the yml files which get used in the CI setup. * Add a fdt-esl-embed node in sandbox's binman node with capsule authentication enabled. .azure-pipelines.yml | 17 ++++++ .gitlab-ci.yml | 15 +++++ arch/sandbox/dts/sandbox.dts | 4 ++ arch/sandbox/dts/sandbox_capsule.dtsi | 12 ++++ arch/sandbox/dts/test.dts | 4 ++ configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + test/py/conftest.py | 64 ++++++++++++++++++++ test/py/tests/test_efi_capsule/conftest.py | 37 +++-------- test/py/tests/test_efi_capsule/signature.dts | 10 --- 10 files changed, 125 insertions(+), 40 deletions(-) create mode 100644 arch/sandbox/dts/sandbox_capsule.dtsi delete mode 100644 test/py/tests/test_efi_capsule/signature.dts diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 3c1846a5bc..7681fabdac 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -398,6 +398,14 @@ stages: wget -O - https://github.com/riscv/opensbi/releases/download/v0.9/opensbi-0.9-rv-bin.tar.xz | tar -C /tmp -xJ; export OPENSBI=/tmp/opensbi-0.9-rv-bin/share/opensbi/lp64/generic/firmware/fw_dynamic.bin; fi + if [[ "${TEST_PY_BD}" == "sandbox" ]] || [[ "${TEST_PY_BD}" == "sandbox_flattree" ]]; then + if [ ! -d "/tmp/capsules/" ]; then + mkdir -p /tmp/capsules/; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER.key -out /tmp/capsules/SIGNER.crt -nodes -days 365; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER2.key -out /tmp/capsules/SIGNER2.crt -nodes -days 365; + cert-to-efi-sig-list /tmp/capsules/SIGNER.crt /tmp/capsules/SIGNER.esl; + fi + fi # the below corresponds to .gitlab-ci.yml "script" cd ${WORK_DIR} export UBOOT_TRAVIS_BUILD_DIR=/tmp/${TEST_PY_BD}; @@ -580,6 +588,15 @@ stages: cd ${WORK_DIR} # make environment variables available as tests are running inside a container export BUILDMAN="${BUILDMAN}" + if [[ "${BUILDMAN}" == "sandbox" ]] || [[ "${BUILDMAN}" == "sandbox x86" ]]; then + if [ ! -d "/tmp/capsules/" ]; then + mkdir -p /tmp/capsules/; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER.key -out /tmp/capsules/SIGNER.crt -nodes -days 365; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER2.key -out /tmp/capsules/SIGNER2.crt -nodes -days 365; + cert-to-efi-sig-list /tmp/capsules/SIGNER.crt /tmp/capsules/SIGNER.esl; + fi + fi + git config --global --add safe.directory ${WORK_DIR} EOF cat << "EOF" >> build.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e6c6ab3586..caf2db9476 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,6 +37,14 @@ stages: export OPENSBI=/tmp/opensbi-0.9-rv-bin/share/opensbi/lp64/generic/firmware/fw_dynamic.bin; fi + - if [[ "${TEST_PY_BD}" == "sandbox" ]] || [[ "${TEST_PY_BD}" == "sandbox_flattree" ]]; then + if [ ! -d "/tmp/capsules/" ]; then + mkdir -p /tmp/capsules/; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER.key -out /tmp/capsules/SIGNER.crt -nodes -days 365; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER2.key -out /tmp/capsules/SIGNER2.crt -nodes -days 365; + cert-to-efi-sig-list /tmp/capsules/SIGNER.crt /tmp/capsules/SIGNER.esl; + fi + fi after_script: - cp -v /tmp/${TEST_PY_BD}/*.{html,css} . - rm -rf /tmp/uboot-test-hooks /tmp/venv @@ -132,6 +140,13 @@ build all other platforms: script: - ret=0; git config --global --add safe.directory "${CI_PROJECT_DIR}"; + if [ ! -d "/tmp/capsules/" ]; then + mkdir -p /tmp/capsules/; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER.key -out /tmp/capsules/SIGNER.crt -nodes -days 365; + openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_SIGNER/ -keyout /tmp/capsules/SIGNER2.key -out /tmp/capsules/SIGNER2.crt -nodes -days 365; + cert-to-efi-sig-list /tmp/capsules/SIGNER.crt /tmp/capsules/SIGNER.esl; + fi + ./tools/buildman/buildman -o /tmp -PEWM -x arm,powerpc || ret=$?; if [[ $ret -ne 0 ]]; then ./tools/buildman/buildman -o /tmp -seP; diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts index 12d3eff5fa..81a865eac8 100644 --- a/arch/sandbox/dts/sandbox.dts +++ b/arch/sandbox/dts/sandbox.dts @@ -106,3 +106,7 @@ #if IS_ENABLED(CONFIG_SUPPORT_VPL) #include "sandbox_vpl.dtsi" #endif + +#ifdef CONFIG_EFI_CAPSULE_AUTHENTICATE +#include "sandbox_capsule.dtsi" +#endif diff --git a/arch/sandbox/dts/sandbox_capsule.dtsi b/arch/sandbox/dts/sandbox_capsule.dtsi new file mode 100644 index 0000000000..59ef8d121b --- /dev/null +++ b/arch/sandbox/dts/sandbox_capsule.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Devicetree file for embedding ESL into test DTB + */ + +&binman { + fdt-esl-embed { + esl-file = CONFIG_EFI_CAPSULE_ESL_FILE; + dtb = "test.dtb", "u-boot.dtb"; + concat = "./u-boot-nodtb.bin", "./u-boot.dtb", "./u-boot.bin"; + }; +}; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index ff9f9222e6..06e1092400 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1828,3 +1828,7 @@ #ifdef CONFIG_SANDBOX_VPL #include "sandbox_vpl.dtsi" #endif + +#ifdef CONFIG_EFI_CAPSULE_AUTHENTICATE +#include "sandbox_capsule.dtsi" +#endif diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 1ec44d5b33..d8a2386bb0 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -339,6 +339,7 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y CONFIG_EFI_CAPSULE_AUTHENTICATE=y +CONFIG_EFI_CAPSULE_ESL_FILE="/tmp/capsules/SIGNER.esl" CONFIG_EFI_SECURE_BOOT=y CONFIG_TEST_FDTDEC=y CONFIG_UNIT_TEST=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index e7657d40dc..8d60744771 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -226,6 +226,7 @@ CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_ON_DISK=y CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y CONFIG_EFI_CAPSULE_AUTHENTICATE=y +CONFIG_EFI_CAPSULE_ESL_FILE="/tmp/capsules/SIGNER.esl" CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y diff --git a/test/py/conftest.py b/test/py/conftest.py index fc9dd3a83f..45bd1749ee 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -80,6 +80,65 @@ def pytest_addoption(parser): help='Run sandbox under gdbserver. The argument is the channel '+ 'over which gdbserver should communicate, e.g. localhost:1234') +def setup_capsule_auth_build(source_dir, build_dir, board_type, log): + """Setup the platform's build for capsule authenticate + + This generates the keys needed for signing the capsules along + with the EFI Signature List(ESL) file, with the capsule + authentication feature enabled. + + The ESL file is subsequently embedded into the platform's + dtb during the u-boot build, to be used for capsule + authentication. + + Two sets of keys are generated, namely SIGNER and SIGNER2. + The SIGNER2 key pair is used as a malicious key for testing the + the capsule authentication functionality. + + Args: + soruce_dir (str): Directory containing source code + build_dir (str): Directory to build in + board_type (str): board_type parameter (e.g. 'sandbox') + log (Logfile): Log file to use + + Returns: + Nothing. + """ + def run_command(name, cmd, source_dir): + with log.section(name): + if isinstance(cmd, str): + cmd = cmd.split() + runner = log.get_runner(name, None) + runner.run(cmd, cwd=source_dir) + runner.close() + log.status_pass('OK') + + capsule_sig_dir = '/tmp/capsules/' + sig_name = 'SIGNER' + mkdir_p(capsule_sig_dir) + name = 'openssl' + cmd = ( 'openssl req -x509 -sha256 -newkey rsa:2048 ' + '-subj /CN=TEST_SIGNER/ -keyout %s%s.key ' + '-out %s%s.crt -nodes -days 365' + % (capsule_sig_dir, sig_name, capsule_sig_dir, sig_name) + ) + run_command(name, cmd, source_dir) + + name = 'cert-to-efi-sig-list' + cmd = ( 'cert-to-efi-sig-list %s%s.crt %s%s.esl' + % (capsule_sig_dir, sig_name, capsule_sig_dir, sig_name) + ) + run_command(name, cmd, source_dir) + + sig_name = 'SIGNER2' + name = 'openssl' + cmd = ( 'openssl req -x509 -sha256 -newkey rsa:2048 ' + '-subj /CN=TEST_SIGNER/ -keyout %s%s.key ' + '-out %s%s.crt -nodes -days 365' + % (capsule_sig_dir, sig_name, capsule_sig_dir, sig_name) + ) + run_command(name, cmd, source_dir) + def run_build(config, source_dir, build_dir, board_type, log): """run_build: Build U-Boot @@ -102,6 +161,11 @@ def run_build(config, source_dir, build_dir, board_type, log): o_opt = 'O=%s' % build_dir else: o_opt = '' + + capsule_auth_boards = ( 'sandbox', 'sandbox_flattree' ) + if board_type in capsule_auth_boards: + setup_capsule_auth_build(source_dir, build_dir, board_type, log) + cmds = ( ['make', o_opt, '-s', board_type + '_defconfig'], ['make', o_opt, '-s', '-j{}'.format(os.cpu_count())], diff --git a/test/py/tests/test_efi_capsule/conftest.py b/test/py/tests/test_efi_capsule/conftest.py index a337e62936..cec733942f 100644 --- a/test/py/tests/test_efi_capsule/conftest.py +++ b/test/py/tests/test_efi_capsule/conftest.py @@ -32,36 +32,6 @@ def efi_capsule_data(request, u_boot_config): check_call('mkdir -p %s' % data_dir, shell=True) check_call('mkdir -p %s' % install_dir, shell=True) - capsule_auth_enabled = u_boot_config.buildconfig.get( - 'config_efi_capsule_authenticate') - if capsule_auth_enabled: - # Create private key (SIGNER.key) and certificate (SIGNER.crt) - check_call('cd %s; ' - 'openssl req -x509 -sha256 -newkey rsa:2048 ' - '-subj /CN=TEST_SIGNER/ -keyout SIGNER.key ' - '-out SIGNER.crt -nodes -days 365' - % data_dir, shell=True) - check_call('cd %s; %scert-to-efi-sig-list SIGNER.crt SIGNER.esl' - % (data_dir, EFITOOLS_PATH), shell=True) - - # Update dtb adding capsule certificate - check_call('cd %s; ' - 'cp %s/test/py/tests/test_efi_capsule/signature.dts .' - % (data_dir, u_boot_config.source_dir), shell=True) - check_call('cd %s; ' - 'dtc -@ -I dts -O dtb -o signature.dtbo signature.dts; ' - 'fdtoverlay -i %s/arch/sandbox/dts/test.dtb ' - '-o test_sig.dtb signature.dtbo' - % (data_dir, u_boot_config.build_dir), shell=True) - - # Create *malicious* private key (SIGNER2.key) and certificate - # (SIGNER2.crt) - check_call('cd %s; ' - 'openssl req -x509 -sha256 -newkey rsa:2048 ' - '-subj /CN=TEST_SIGNER/ -keyout SIGNER2.key ' - '-out SIGNER2.crt -nodes -days 365' - % data_dir, shell=True) - # Create capsule files # two regions: one for u-boot.bin and the other for u-boot.env check_call('cd %s; echo -n u-boot:Old > u-boot.bin.old; echo -n u-boot:New > u-boot.bin.new; echo -n u-boot-env:Old > u-boot.env.old; echo -n u-boot-env:New > u-boot.env.new' % data_dir, @@ -88,7 +58,14 @@ def efi_capsule_data(request, u_boot_config): (data_dir, u_boot_config.build_dir), shell=True) + capsule_auth_enabled = u_boot_config.buildconfig.get( + 'config_efi_capsule_authenticate') if capsule_auth_enabled: + capsules_path_dir = '/tmp/capsules/' + check_call('mv %s/* %s ' %(capsules_path_dir, data_dir), shell=True) + check_call('cp %s/arch/sandbox/dts/test.dtb %s/test_sig.dtb' % + (u_boot_config.build_dir, data_dir), shell=True) + # raw firmware signed with proper key check_call('cd %s; ' '%s/tools/mkeficapsule --index 1 --monotonic-count 1 ' diff --git a/test/py/tests/test_efi_capsule/signature.dts b/test/py/tests/test_efi_capsule/signature.dts deleted file mode 100644 index 078cfc76c9..0000000000 --- a/test/py/tests/test_efi_capsule/signature.dts +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ - -/dts-v1/; -/plugin/; - -&{/} { - signature { - capsule-key = /incbin/("SIGNER.esl"); - }; -};