From patchwork Fri Jul 17 07:16:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 235682 Delivered-To: patch@linaro.org Received: by 2002:a92:d244:0:0:0:0:0 with SMTP id v4csp1458184ilg; Fri, 17 Jul 2020 00:18:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWTqu175ljrjq4HjKMAyfpIWEcjlPPmU3yZI9b5Sl2rI9jnmlu9DDonhgU3mSj+TXqfvuT X-Received: by 2002:aa7:db4f:: with SMTP id n15mr7806182edt.193.1594970305927; Fri, 17 Jul 2020 00:18:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594970305; cv=none; d=google.com; s=arc-20160816; b=ai/aByUkOddMp/1HWl6cUQZC6lREY2K0jZOwop+2coAEkkoMW4KewPao2+5hQfFgcq gGr17SxU+K/ooHpMluoFeS16U3CVfI/r4YX8mRTigspErxSIC9ZYttxs08Z5VdTyfom4 CZ5ab2sqSLBgSXLnRjiMYQQJ226xYQ4cSVLxh3NCNrovG5QBQERpY7TVwpwSoBKt9jOX uuEHriIhBadcnL4doB59D0P8tjRTk0+epmDsXxpbLvFcSXSfb0eYfzv9fcTKfXCVE+by BgdtTts5I67zev9bpebVWMKISFfES9sHMUTyEOO+qdvCwaivCjZJ2ZDwmtnAgin7P/G1 oJVQ== 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:dkim-signature; bh=WmmNO6/VS8xZdj99DcbwWaMQVXqO7YjOdmyKu/QUUTU=; b=AdGBqLiqdK6vkSxmL2rbKWtGLBx8dobFhcU3erfwPmWWS+//NVDb6ctH3RCO7KnLJT jGSDTV4Vig0I9dTt3VA1C2zIurSG1MVISX8JTI89uYBa1hqesOV6JArUII+A8HR0vBVD 94O5BZLztY8RYgK7p7CgmHcZRR/wB0WTMIo2FWZkQLHtoJp/2ZLp+9n8uTjf8yrDOHBS MpQrvrXQe/JfN1cggJQDMJngjuAuWLIkDm2vpL5fkRfVALHivJoyshHccr9EAaZlNiiV 5lP64BeLXSOH0JH94bPhsOSLAVefx2eu9jlxfksJMBcq38BFMQC9WeJskFLF6uRbiSGg +tXQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UwzcR2yM; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id k8si4622784ejc.257.2020.07.17.00.18.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jul 2020 00:18:25 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=UwzcR2yM; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (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 C81EE81D71; Fri, 17 Jul 2020 09:17:43 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="UwzcR2yM"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id E1A4281CEA; Fri, 17 Jul 2020 09:17:22 +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=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-pj1-x1036.google.com (mail-pj1-x1036.google.com [IPv6:2607:f8b0:4864:20::1036]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 8901481C29 for ; Fri, 17 Jul 2020 09:17:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=takahiro.akashi@linaro.org Received: by mail-pj1-x1036.google.com with SMTP id mn17so6106855pjb.4 for ; Fri, 17 Jul 2020 00:17:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WmmNO6/VS8xZdj99DcbwWaMQVXqO7YjOdmyKu/QUUTU=; b=UwzcR2yMHpBPqWc3c1ChnI8M59JeiWi4B3UIzvg+DI1US5p+SdWU7apH2HH77DH7of lMkH4pU23H3VHOOF3CXdoFxBhdD76mQ/d55qguo7TYA2oIugapvBrdThr7PspO4qaMON vdgb8y/ZOUrPTboooLg7PoggG+kJVF05G6fcgj2tbTZTf0LBziPJfs5H0Q0fsVCaWumr 18WW+O43PDSxX9uABEGEx5rZQwnWSKwYb0R5Vs/aXrtC/NSMB2W8TcxxP+93W6WhM0Sa XsCF+UFZypZ8ECBStIlMEXYXN02dXaBMDY8pGv7++rs1ia8pcpxT/WwR204jzdXG/uDo wLZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WmmNO6/VS8xZdj99DcbwWaMQVXqO7YjOdmyKu/QUUTU=; b=q80Q8GClaVmhCFu/3v9QBaAGT16VKRTrtHxqjzZjSirLjpMWETxHCHcYAT4yVxDf55 UA0FW9RHYDYIthyo3kxrxEtJfYIP/t34wflh8PO5mebhff90w04McdGQ97pks2YUcrqF GxRHGZfXg6pi45sfwCeoCMG5Pj08OOM8G0kCbU5ioSQY9OyO/+hRn8Mh5pxPIYHiVxVz rqQgjdMf3fC1SqMTUuFohMRhLlZbErFoS6od2Nj3hHdzrRTknGpOL0wijd09sFCx25wa hEII+YCLZTIjIr9h8UsPBveB+INGLeYR6FO0ccnoVAxJWv8OkjoaTYqTJNJSKRwwPy51 8Jlw== X-Gm-Message-State: AOAM531oPDJN/wW+NaZLYkeLQb20b7zlOrtHgSJ+sd1MqxlnsBRsmy2m VnhxZkZ3PXeh6M/RGBvUQonK7w== X-Received: by 2002:a17:90a:3602:: with SMTP id s2mr8203660pjb.161.1594970232929; Fri, 17 Jul 2020 00:17:12 -0700 (PDT) Received: from localhost.localdomain (p6e424d9a.tkyea130.ap.so-net.ne.jp. [110.66.77.154]) by smtp.gmail.com with ESMTPSA id g12sm6749388pfb.190.2020.07.17.00.17.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Jul 2020 00:17:12 -0700 (PDT) From: AKASHI Takahiro To: xypron.glpk@gmx.de, agraf@csgraf.de Cc: sughosh.ganu@linaro.org, mail@patrick-wildt.de, u-boot@lists.denx.de, AKASHI Takahiro Subject: [PATCH v4 7/7] test/py: efi_secboot: add test for intermediate certificates Date: Fri, 17 Jul 2020 16:16:30 +0900 Message-Id: <20200717071630.7363-8-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200717071630.7363-1-takahiro.akashi@linaro.org> References: <20200717071630.7363-1-takahiro.akashi@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 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.102.3 at phobos.denx.de X-Virus-Status: Clean In this test case, an image may have a signature with additional intermediate certificates. A chain of trust will be followed and all the certificates in the middle of chain must be verified before loading. Signed-off-by: AKASHI Takahiro --- test/py/tests/test_efi_secboot/conftest.py | 134 ++++++++++++++++- test/py/tests/test_efi_secboot/defs.py | 8 +- test/py/tests/test_efi_secboot/openssl.cnf | 48 +++++++ .../test_efi_secboot/test_signed_intca.py | 135 ++++++++++++++++++ 4 files changed, 317 insertions(+), 8 deletions(-) create mode 100644 test/py/tests/test_efi_secboot/openssl.cnf create mode 100644 test/py/tests/test_efi_secboot/test_signed_intca.py -- 2.27.0 diff --git a/test/py/tests/test_efi_secboot/conftest.py b/test/py/tests/test_efi_secboot/conftest.py index c6709700a876..20d0cbf3ab01 100644 --- a/test/py/tests/test_efi_secboot/conftest.py +++ b/test/py/tests/test_efi_secboot/conftest.py @@ -37,7 +37,7 @@ def efi_boot_env(request, u_boot_config): global HELLO_PATH image_path = u_boot_config.persistent_data_dir - image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME + image_path = image_path + '/' + EFI_SECBOOT_IMAGE_NAME + '.img' if HELLO_PATH == '': HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi' @@ -87,21 +87,21 @@ def efi_boot_env(request, u_boot_config): # db1-update check_call('cd %s; %ssign-efi-sig-list -t "2020-04-06" -a -c KEK.crt -k KEK.key db db1.esl db1-update.auth' % (mnt_point, EFITOOLS_PATH), shell=True) - ## dbx (TEST_dbx certificate) + # dbx (TEST_dbx certificate) 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 -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx.esl dbx.auth' % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), shell=True) - ## dbx_hash (digest of TEST_db certificate) + # dbx_hash (digest of TEST_db certificate) check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db.crt dbx_hash.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx_hash.crl dbx_hash.auth' % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), shell=True) - ## dbx_hash1 (digest of TEST_db1 certificate) + # dbx_hash1 (digest of TEST_db1 certificate) check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 db1.crt dbx_hash1.crl; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx_hash1.crl dbx_hash1.auth' % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), shell=True) - ## dbx_db (with TEST_db certificate) + # dbx_db (with TEST_db certificate) check_call('cd %s; %ssign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx db.esl dbx_db.auth' % (mnt_point, EFITOOLS_PATH), shell=True) @@ -112,10 +112,10 @@ def efi_boot_env(request, u_boot_config): # Sign image check_call('cd %s; sbsign --key db.key --cert db.crt helloworld.efi' % mnt_point, shell=True) - ## Sign already-signed image with another key + # Sign already-signed image with another key check_call('cd %s; sbsign --key db1.key --cert db1.crt --output helloworld.efi.signed_2sigs helloworld.efi.signed' % mnt_point, shell=True) - ## Digest image + # Digest image check_call('cd %s; %shash-to-efi-sig-list helloworld.efi db_hello.hash; %ssign-efi-sig-list -t "2020-04-07" -c KEK.crt -k KEK.key db db_hello.hash db_hello.auth' % (mnt_point, EFITOOLS_PATH, EFITOOLS_PATH), shell=True) @@ -136,3 +136,123 @@ def efi_boot_env(request, u_boot_config): yield image_path finally: call('rm -f %s' % image_path, shell=True) + +# +# Fixture for UEFI secure boot test of intermediate certificates +# + + +@pytest.fixture(scope='session') +def efi_boot_env_intca(request, u_boot_config): + """Set up a file system to be used in UEFI secure boot test + of intermediate certificates. + + 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 + '_intca.img' + + if HELLO_PATH == '': + HELLO_PATH = u_boot_config.build_dir + '/lib/efi_loader/helloworld.efi' + + try: + mnt_point = u_boot_config.build_dir + '/mnt_efisecure' + check_call('rm -rf {}'.format(mnt_point), shell=True) + check_call('mkdir -p {}'.format(mnt_point), shell=True) + + # 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) + # 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) + + # We will have three-tier hierarchy of certificates: + # TestRoot: Root CA (self-signed) + # TestSub: Intermediate CA (signed by Root CA) + # TestCert: User certificate (signed by Intermediate CA, and used + # for signing an image) + # + # NOTE: + # I consulted the following EDK2 document for certificate options: + # BaseTools/Source/Python/Pkcs7Sign/Readme.md + # Please not use them as they are in product system. They are + # for test purpose only. + + # TestRoot + check_call('cp %s/test/py/tests/test_efi_secboot/openssl.cnf %s' + % (u_boot_config.source_dir, mnt_point), shell=True) + check_call('cd %s; openssl genrsa -out TestRoot.key 2048; openssl req --config openssl.cnf -extensions v3_ca -new -x509 -days 365 -key TestRoot.key -out TestRoot.crt -subj "/CN=TEST_root/"; touch index.txt' + % mnt_point, shell=True) + # TestSub + check_call('cd %s; openssl genrsa -out TestSub.key 2048; openssl req -new -key TestSub.key -out TestSub.csr -subj "/CN=TEST_sub/"; openssl ca --config openssl.cnf -in TestSub.csr -out TestSub.crt -extensions v3_int_ca -days 365 -batch -rand_serial -cert TestRoot.crt -keyfile TestRoot.key' + % mnt_point, shell=True) + # TestCert + check_call('cd %s; openssl genrsa -out TestCert.key 2048; openssl req -new -key TestCert.key -out TestCert.csr -subj "/CN=TEST_cert/"; openssl ca --config openssl.cnf -in TestCert.csr -out TestCert.crt -extensions usr_cert -days 365 -batch -rand_serial -cert TestSub.crt -keyfile TestSub.key' + % mnt_point, shell=True) + # db + # for TestCert + check_call('cd %s; %scert-to-efi-sig-list -g %s TestCert.crt TestCert.esl; %ssign-efi-sig-list -c KEK.crt -k KEK.key db TestCert.esl db_a.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + # for TestSub + check_call('cd %s; %scert-to-efi-sig-list -g %s TestSub.crt TestSub.esl; %ssign-efi-sig-list -t "2020-07-16" -c KEK.crt -k KEK.key db TestSub.esl db_b.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + # for TestRoot + check_call('cd %s; %scert-to-efi-sig-list -g %s TestRoot.crt TestRoot.esl; %ssign-efi-sig-list -t "2020-07-17" -c KEK.crt -k KEK.key db TestRoot.esl db_c.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + ## dbx (hash of certificate with revocation time) + # for TestCert + check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 TestCert.crt TestCert.crl; %ssign-efi-sig-list -c KEK.crt -k KEK.key dbx TestCert.crl dbx_a.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + # for TestSub + check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 TestSub.crt TestSub.crl; %ssign-efi-sig-list -t "2020-07-18" -c KEK.crt -k KEK.key dbx TestSub.crl dbx_b.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + # for TestRoot + check_call('cd %s; %scert-to-efi-hash-list -g %s -t 0 -s 256 TestRoot.crt TestRoot.crl; %ssign-efi-sig-list -t "2020-07-19" -c KEK.crt -k KEK.key dbx TestRoot.crl dbx_c.auth' + % (mnt_point, EFITOOLS_PATH, GUID, EFITOOLS_PATH), + shell=True) + + # Sign image + # additional intermediate certificates may be included + # in SignedData + + check_call('cp %s %s' % (HELLO_PATH, mnt_point), shell=True) + # signed by TestCert + check_call('cd %s; %ssbsign --key TestCert.key --cert TestCert.crt --out helloworld.efi.signed_a helloworld.efi' + % (mnt_point, SBSIGN_PATH), shell=True) + # signed by TestCert with TestSub in signature + check_call('cd %s; %ssbsign --key TestCert.key --cert TestCert.crt --addcert TestSub.crt --out helloworld.efi.signed_ab helloworld.efi' + % (mnt_point, SBSIGN_PATH), shell=True) + # signed by TestCert with TestSub and TestRoot in signature + check_call('cd %s; cat TestSub.crt TestRoot.crt > TestSubRoot.crt; %ssbsign --key TestCert.key --cert TestCert.crt --addcert TestSubRoot.crt --out helloworld.efi.signed_abc helloworld.efi' + % (mnt_point, SBSIGN_PATH), shell=True) + + check_call('virt-make-fs --partition=gpt --size=+1M --type=vfat {} {}'.format(mnt_point, image_path), shell=True) + check_call('rm -rf {}'.format(mnt_point), 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 index ba6b9f391e60..a26bbc103cd9 100644 --- a/test/py/tests/test_efi_secboot/defs.py +++ b/test/py/tests/test_efi_secboot/defs.py @@ -1,14 +1,20 @@ # SPDX-License-Identifier: GPL-2.0+ # Disk image name -EFI_SECBOOT_IMAGE_NAME = 'test_efi_secboot.img' +EFI_SECBOOT_IMAGE_NAME = 'test_efi_secboot' # 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. +# The path must terminate with '/'. EFITOOLS_PATH = '' +# "--addcert" option of sbsign must be available, otherwise +# you need build a newer version on your own. +# The path must terminate with '/'. +SBSIGN_PATH = '' + # Hello World application for sandbox HELLO_PATH = '' diff --git a/test/py/tests/test_efi_secboot/openssl.cnf b/test/py/tests/test_efi_secboot/openssl.cnf new file mode 100644 index 000000000000..f684f1df7e69 --- /dev/null +++ b/test/py/tests/test_efi_secboot/openssl.cnf @@ -0,0 +1,48 @@ +[ ca ] +default_ca = CA_default + +[ CA_default ] +new_certs_dir = . +database = ./index.txt +serial = ./serial +default_md = sha256 +policy = policy_min + +[ req ] +distinguished_name = def_distinguished_name + +[def_distinguished_name] + +# Extensions +# -addext " ... = ..." +# +[ v3_ca ] + # Extensions for a typical Root CA. + basicConstraints = critical,CA:TRUE + keyUsage = critical, digitalSignature, cRLSign, keyCertSign + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + +[ v3_int_ca ] + # Extensions for a typical intermediate CA. + basicConstraints = critical, CA:TRUE + keyUsage = critical, digitalSignature, cRLSign, keyCertSign + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid:always,issuer + +[ usr_cert ] + # Extensions for user end certificates. + basicConstraints = CA:FALSE + keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment + extendedKeyUsage = clientAuth, emailProtection + subjectKeyIdentifier = hash + authorityKeyIdentifier = keyid,issuer + +[ policy_min ] + countryName = optional + stateOrProvinceName = optional + localityName = optional + organizationName = optional + organizationalUnitName = optional + commonName = supplied + emailAddress = optional diff --git a/test/py/tests/test_efi_secboot/test_signed_intca.py b/test/py/tests/test_efi_secboot/test_signed_intca.py new file mode 100644 index 000000000000..1240174758cf --- /dev/null +++ b/test/py/tests/test_efi_secboot/test_signed_intca.py @@ -0,0 +1,135 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (c) 2020, Linaro Limited +# Author: AKASHI Takahiro +# +# U-Boot UEFI: Image Authentication Test (signature with certificates chain) + +""" +This test verifies image authentication for a signed image which is signed +by user certificate and contains additional intermediate certificates in its +signature. +""" + +import pytest + + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('efi_secure_boot') +@pytest.mark.buildconfigspec('cmd_efidebug') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_nvedit_efi') +@pytest.mark.slow +class TestEfiSignedImageExt(object): + def test_efi_signed_image_ext1(self, u_boot_console, efi_boot_env_intca): + """ + Test Case 1 - authenticated by root CA in db + """ + u_boot_console.restart_uboot() + disk_img = efi_boot_env_intca + with u_boot_console.log.section('Test Case 1a'): + # Test Case 1a, with no Int CA and not authenticated by root CA + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatload host 0:1 4000000 db_c.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db', + 'fatload host 0:1 4000000 KEK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK', + 'fatload host 0:1 4000000 PK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK']) + assert 'Failed to set EFI variable' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'efidebug boot add 1 HELLO_a host 0:1 /helloworld.efi.signed_a ""', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert '\'HELLO_a\' failed' in ''.join(output) + assert 'efi_start_image() returned: 26' in ''.join(output) + + with u_boot_console.log.section('Test Case 1b'): + # Test Case 1b, signed and authenticated by root CA + output = u_boot_console.run_command_list([ + 'efidebug boot add 2 HELLO_ab host 0:1 /helloworld.efi.signed_ab ""', + 'efidebug boot next 2', + 'bootefi bootmgr']) + assert 'Hello, world!' in ''.join(output) + + def test_efi_signed_image_ext2(self, u_boot_console, efi_boot_env_intca): + """ + Test Case 2 - authenticated by root CA in db + """ + u_boot_console.restart_uboot() + disk_img = efi_boot_env_intca + with u_boot_console.log.section('Test Case 2a'): + # Test Case 2a, unsigned and not authenticated by root CA + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatload host 0:1 4000000 KEK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK', + 'fatload host 0:1 4000000 PK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK']) + assert 'Failed to set EFI variable' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert '\'HELLO_abc\' failed' in ''.join(output) + assert 'efi_start_image() returned: 26' in ''.join(output) + + with u_boot_console.log.section('Test Case 2b'): + # Test Case 2b, signed and authenticated by root CA + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 db_b.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert '\'HELLO_abc\' failed' in ''.join(output) + assert 'efi_start_image() returned: 26' in ''.join(output) + + with u_boot_console.log.section('Test Case 2c'): + # Test Case 2c, signed and authenticated by root CA + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 db_c.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert 'Hello, world!' in ''.join(output) + + def test_efi_signed_image_ext3(self, u_boot_console, efi_boot_env_intca): + """ + Test Case 3 - revoked by dbx + """ + u_boot_console.restart_uboot() + disk_img = efi_boot_env_intca + with u_boot_console.log.section('Test Case 3a'): + # Test Case 3a, revoked by int CA in dbx + output = u_boot_console.run_command_list([ + 'host bind 0 %s' % disk_img, + 'fatload host 0:1 4000000 dbx_b.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize dbx', + 'fatload host 0:1 4000000 db_c.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize db', + 'fatload host 0:1 4000000 KEK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize KEK', + 'fatload host 0:1 4000000 PK.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize PK']) + assert 'Failed to set EFI variable' not in ''.join(output) + + output = u_boot_console.run_command_list([ + 'efidebug boot add 1 HELLO_abc host 0:1 /helloworld.efi.signed_abc ""', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert 'Hello, world!' in ''.join(output) + # Or, + # assert '\'HELLO_abc\' failed' in ''.join(output) + # assert 'efi_start_image() returned: 26' in ''.join(output) + + with u_boot_console.log.section('Test Case 3b'): + # Test Case 3b, revoked by root CA in dbx + output = u_boot_console.run_command_list([ + 'fatload host 0:1 4000000 dbx_c.auth', + 'setenv -e -nv -bs -rt -at -i 4000000,$filesize dbx', + 'efidebug boot next 1', + 'efidebug test bootmgr']) + assert '\'HELLO_abc\' failed' in ''.join(output) + assert 'efi_start_image() returned: 26' in ''.join(output)