From patchwork Tue Nov 26 00:51:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 1200683 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="nC/iSxgn"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 47MQL86nX7z9s3Z for ; Tue, 26 Nov 2019 11:50:24 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 5B309C21E30; Tue, 26 Nov 2019 00:50:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C6A9FC21C6A; Tue, 26 Nov 2019 00:50:18 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 82B4DC21C6A; Tue, 26 Nov 2019 00:50:17 +0000 (UTC) Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) by lists.denx.de (Postfix) with ESMTPS id C3620C21C27 for ; Tue, 26 Nov 2019 00:50:16 +0000 (UTC) Received: by mail-pj1-f47.google.com with SMTP id s8so7433678pji.2 for ; Mon, 25 Nov 2019 16:50:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=68yv8IGJ1y0WbaUENgxntQdRCDDaxzb5zm4dAX0dEJg=; b=nC/iSxgn7OsIMzMnuacfO8lBKPykROv4c/+V0ddxa1DYen2NgYLOskS2GNt5tR9J7Z rbvYneOYbXaVGAnZv9VEkxQQMW6GPqqBPJE9Rpi5fft8pwXTwQD/g8Kz3SI4n11cbFhd XikAQTZDCIdx/sbak6kesNtQiuIRz2rN+cl0nYzUnZwAIFtCXTfAz4+0g6KZ9r4pQgq/ /1UtNL2nrPg667P0h/pPJnpBTLrpxkV2kv9446hS/2pq7Bo9MQ8qUXSUAMCQSKStOHwl bf9d4uobVZwIrAWg5nlB9lA9s/HgGLz/dXNZvPOFgRdF/xsFWjZnkQNyXHJK/Yq8MlkQ p3UA== 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:mime-version :content-transfer-encoding; bh=68yv8IGJ1y0WbaUENgxntQdRCDDaxzb5zm4dAX0dEJg=; b=oLYH7G+ey8RiS+A38JIqAjth/PbLoIycrb6iC2T2e5g5m4sAR1m/nrEr//sFh2s781 Jq2xxoHlGfIbEx8LGcvQpk9RBS8Ha9K8NYKDSjn6dBi5Zq6AI0l1TEHbyYP3YAZL55LZ eXMi+bc+maXitu87EGBCJoLEgIIBuCT0ds/JuAKjnFi3sz0oZ1v5NSyq5wUHrQp8glyM UcthruxnJ7NT5vhdanDmLPGl1QTd9dzuza5JkXFMPpF4L4VaVJntHFcXM+CJqgCC/69V WHUmPsfz7n5UpQq6eZxRO37Z7AyHqR5utxmEz9Ukw4yWSdn00SZXTpVYz+3twA8NDMOk +IWA== X-Gm-Message-State: APjAAAW29xr969YDFMzExT1eUKevoWVxr6MdTPhtEkYn25YB8nFiKrDf +SR9VM003DBbEhxyMZbmKQVqjg== X-Google-Smtp-Source: APXvYqyzAAgiHWiJE1dbLXR9eodY3YuSdCKuLkhZ0lz3VLoS5DsHX6oIoDVk6PLqCWrdcEnZifineQ== X-Received: by 2002:a17:90a:178e:: with SMTP id q14mr2677582pja.134.1574729414775; Mon, 25 Nov 2019 16:50:14 -0800 (PST) Received: from linaro.org ([121.95.100.191]) by smtp.googlemail.com with ESMTPSA id j14sm539753pje.17.2019.11.25.16.50.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 25 Nov 2019 16:50:13 -0800 (PST) From: AKASHI Takahiro To: xypron.glpk@gmx.de, agraf@csgraf.de, trini@konsulko.com Date: Tue, 26 Nov 2019 09:51:04 +0900 Message-Id: <20191126005120.31156-1-takahiro.akashi@linaro.org> X-Mailer: git-send-email 2.24.0 MIME-Version: 1.0 Cc: u-boot@lists.denx.de, mail@patrick-wildt.de Subject: [U-Boot] [PATCH v2 00/16] efi_loader: add secure boot support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" One of major missing features in current UEFI implementation is "secure boot." The ultimate goal of my attempt is to implement image authentication based on signature and provide UEFI secure boot support which would be fully compliant with UEFI specification, section 32[1]. (The code was originally developed by Patrick Wildt.) While this patch/RFC is still rough-edged, the aim here is to get early feedbacks from the community as the patch is quite huge (in total) and also as it's a security enhancement. Please note, however, this patch doesn't work on its own; there are a couple of functional dependencies[2] and [3], that I have submitted before. For complete workable patch set, see my repository[4], which also contains exeperimental timestamp-based revocation suuport. My "non-volatile" support[5], which is under discussion, is not mandatory and so not included here, but this inevitably implies that, for example, signature database variables, like db and dbx, won't be persistent unless you explicitly run "env save" command and that UEFI variables are not separated from U-Boot environment. Anyhow, Linaro is also working on implementing real "secure storage" solution based on TF-A and OP-TEE. Supported features: * image authentication based on db and dbx * supported signature types are EFI_CERT_SHA256_GUID (SHA256 digest for unsigned images) EFI_CERT_X509_GUID (x509 certificate for signed images) * SecureBoot/SignatureSupport variables * SetupMode and user mode * variable authentication based on PK and KEK EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS * basic pytest test cases Unsupported features: (marked as TODO in most cases in the source code, and won't be included in this series) * hash algorithms other than SHA256 * dbt: timestamp(RFC6131)-based certificate revocation * dbr: OS recovery * xxxDefault: default values for signature stores * transition to AuditMode and DeployedMode * recording rejected images in EFI_IMAGE_EXECUTION_INFO_TABLE * verification "policy", in particular, check against signature's owner * private authenticated variables * variable authentication with EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS * real secure storage support, including hardware-specific PK (Platform Key) installation TODO's other than "Unsupported features": (won't be included in this series) * struct efi_image_regions cannot have arbitrary number of regions * fail recovery, in particular, in modifying authenticated variables * support read-only attributes of well-defined global variables in particular, "SignatureSupport" * Extensive test suite (or more test cases) to confirm compatibility with EDK2 => I requested EDK SCT community to add tests[6]. Test: * my pytest, included in this patch set, passed. * efi_selftest passed. (At least no reguression.) * Travis CI tests, except the following two, have passed: - test/py sandbox test/py/tests/test_fs/test_unlink.py test_unlink2 - test/py sandbox with clang cmd/efidebug.c:703:15: error: result of comparison of constant 9223372036854775822 with expression of type 'int' is always false [-Werror,-Wtautological-constant-out-of-range-compare] But as you can see, those have nothing to do with my UEFI secure boot patch and are existing bugs. Known issues: * efitools is used in pytest, and its version must be v1.5.2 or later. (Solution: You can define EFITOOLS_PATH in defs.py for your own efitools.) * Pytest depends on standalone "helloworld" app for sandbox (Solution: You can define HELLO_PATH in defs.py or Heinrich's [7].) * Travis CI errors mentioned above => I will send *separate* bug-fix patches once fixed. Hints about how to use: (Please see other documents, or my pytest scripts, for details.) * You can create your own certificates with openssl. * You can sign your application with sbsign (on Ubuntu). * You can create raw data for signature database with efitools, and install/manage authenticated variables with "env -set -e" command or efitools' "UpdateVars.efi" application. [1] https://uefi.org/sites/default/files/resources/UEFI_Spec_2_8_final.pdf [2] https://lists.denx.de/pipermail/u-boot/2019-November/390127.html (import x509/pkcs7 parsers from linux) [3] https://lists.denx.de/pipermail/u-boot/2019-November/390150.html (extend rsa_verify() for UEFI secure boot) [4] http://git.linaro.org/people/takahiro.akashi/u-boot.git/ efi/secboot [5] https://lists.denx.de/pipermail/u-boot/2019-September/382835.html (non-volatile variables support) [6] https://bugzilla.tianocore.org/show_bug.cgi?id=2230 [7] https://lists.denx.de/pipermail/u-boot/2019-November/389593.html Changes in v2 (Nov 26, 2019) * rebased to v2020.01-rc3 * rename IMAGE_DIRECTORY_ENTRY_CERTTABLE to IMAGE_DIRECTORY_ENTRY_SECURITY (patch#1,#9) * add comments (patch#1) * drop v1's patch#2 as it is no longer necessary * drop v1's patch#3 as other "SECURE_BOOT" architectures have renamed this option and no longer use it * add structure descriptions (patch#3) * rework hash calculation code in efi_signature_verify() and remove an odd constant, WinIndrectSha256 (patch#3) * move travis.yml changes to a seprate patch (patch#12, #16) * yield_fixture() -> fixture() (patch#12) * call console.restart_uboot() at every test case (13,#14) * add patch#15; enable UEFI-related configurations by default on sandbox * add patch#16; modify Travis CI environment to run UEFI secure boot test Changes in v1 (Nov 13, 2019) * rebased to v2020.01-rc * remove already-merged patches * re-work the patch set for easier reviews, including - move a config definition patch forward (patch#4) - refactor/rename verification functions (patch#5/#10) - split signature database parser as a separate patch (patch#6) - split secure state transition code as a separate patch (patch#8) - move most part of init_secure_boot() into init_variables() (patch#8) - split test environment setup from test patches (patch#14) * add function descriptions (patch#5-#11) * make sure the section list is sorted in ascending order in hash calculation of PE image (patch#10) * add a new "-at" (authenticated access) option to "env -e" (patch#13) * list required host packages, in particular udisks2, in pytest (patch#14) * modify conftest.py to run under python3 (patch#14) * use a partition on a disk instead of a whole disk without partition table (patch#14) * reduce depencendy on efitools, yet relying on its host tools (patch#14) * modify pytests to catch up wth latest changes of "env -e" syntax (patch#15,#16) RFC (Sept 18, 2019) AKASHI Takahiro (16): include: pe.h: add signature-related definitions efi_loader: add CONFIG_EFI_SECURE_BOOT config option efi_loader: add signature verification functions efi_loader: add signature database parser efi_loader: variable: support variable authentication efi_loader: variable: add secure boot state transition efi_loader: variable: add VendorKeys variable efi_loader: image_loader: support image authentication efi_loader: set up secure boot cmd: env: use appropriate guid for authenticated UEFI variable cmd: env: add "-at" option to "env set -e" command efi_loader, pytest: set up secure boot environment efi_loader, pytest: add UEFI secure boot tests (authenticated variables) efi_loader, pytest: add UEFI secure boot tests (image) sandbox: add extra configurations for UEFI and related tests travis: add packages for UEFI secure boot test .travis.yml | 11 +- cmd/nvedit.c | 5 +- cmd/nvedit_efi.c | 23 +- configs/sandbox64_defconfig | 3 + configs/sandbox_defconfig | 3 + include/efi_api.h | 87 ++ include/efi_loader.h | 85 +- include/pe.h | 18 + lib/efi_loader/Kconfig | 16 + lib/efi_loader/Makefile | 1 + lib/efi_loader/efi_boottime.c | 2 +- lib/efi_loader/efi_image_loader.c | 443 +++++++- lib/efi_loader/efi_setup.c | 38 + lib/efi_loader/efi_signature.c | 811 +++++++++++++++ lib/efi_loader/efi_variable.c | 950 ++++++++++++++++-- test/py/README.md | 8 + test/py/tests/test_efi_secboot/conftest.py | 151 +++ test/py/tests/test_efi_secboot/defs.py | 21 + .../py/tests/test_efi_secboot/test_authvar.py | 282 ++++++ test/py/tests/test_efi_secboot/test_signed.py | 99 ++ .../tests/test_efi_secboot/test_unsigned.py | 103 ++ 21 files changed, 3032 insertions(+), 128 deletions(-) create mode 100644 lib/efi_loader/efi_signature.c create mode 100644 test/py/tests/test_efi_secboot/conftest.py create mode 100644 test/py/tests/test_efi_secboot/defs.py create mode 100644 test/py/tests/test_efi_secboot/test_authvar.py create mode 100644 test/py/tests/test_efi_secboot/test_signed.py create mode 100644 test/py/tests/test_efi_secboot/test_unsigned.py Tested-by: Ilias Apalodimas