From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1kXaii-0000Sp-6J for mharc-grub-devel@gnu.org; Tue, 27 Oct 2020 21:57:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46352) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kXaif-0000S7-Rp for grub-devel@gnu.org; Tue, 27 Oct 2020 21:57:45 -0400 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]:34191) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kXaid-0007ll-8A for grub-devel@gnu.org; Tue, 27 Oct 2020 21:57:45 -0400 Received: by mail-pl1-x62c.google.com with SMTP id r3so1728843plo.1 for ; Tue, 27 Oct 2020 18:57:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ysaFDuBnXXVt2MqlufQT/wDJelMiByMK1C4qmYw15bA=; b=o13VNfUxWir8cSKqwYuBfZdtN24SfKB5avDt9S92vgr0Js3+x3dkhyWN/ZprDVe9na i0MImwaqsbFPaoQ9mFVmBfRFQ4emrgbzbCv/pHPfLdT42IQHVriuBXjI0EfQFL/F9afk DWoUaE2sZwsLpazA9aUdiw+VTzD5yCmn8q0T8= 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=ysaFDuBnXXVt2MqlufQT/wDJelMiByMK1C4qmYw15bA=; b=fmNZQR/x12D/6jJ5MNtuXPYMQQotHvlJM1zgLXupjEpCfrGnRnMhpzRVX4LkTutpmH s9JHDrgOf0SNV4JrkczMcz95AiGroWlcX0d1p7KA3lO2g5SAm8kpjIcNCdFIPPL/u7ER W2p7WKaVF4FlX4YlKXKXPn7cohSYN0B5sbphxEZDFzqM81hK4Rta7xju6ZO9w6VM8BBQ 7ybWDBwu8M6ZOv1LcFADFuUPVYzKQ94wlUlKxZ/wH5myOs23KXtsLR8aInVheG76LgFC icqL9nge9154Y4bW26PToKH/7JyFjisZYwiq1Yhzod1jR056HdHRHAICx3wazWYEbnkH Zetg== X-Gm-Message-State: AOAM5307ycuF4d+AmVyIrI261H7ReqLiPaXtnCGGdG2Z+PNrfqJO3zm3 ta7OXl9N1TCPZIqTncDVTSl1oKOmz14opQ== X-Google-Smtp-Source: ABdhPJxZFn0hGe0wzh611PjXhWMdeeNtN3y00otr1UKm6L77TP42MQAsQyIR6W2q1Y75pKQerOWQPA== X-Received: by 2002:a17:90a:6984:: with SMTP id s4mr4870504pjj.206.1603850260337; Tue, 27 Oct 2020 18:57:40 -0700 (PDT) Received: from localhost (2001-44b8-1113-6700-b4f7-e8d4-abaa-2197.static.ipv6.internode.on.net. [2001:44b8:1113:6700:b4f7:e8d4:abaa:2197]) by smtp.gmail.com with ESMTPSA id w123sm3808588pfd.34.2020.10.27.18.57.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Oct 2020 18:57:39 -0700 (PDT) From: Daniel Axtens To: grub-devel@gnu.org Cc: rashmica.g@gmail.com, alastair@d-silva.org, Daniel Axtens Subject: [PATCH v2 00/18] Verify appended signatures from grub Date: Wed, 28 Oct 2020 12:57:17 +1100 Message-Id: <20201028015735.1131291-1-dja@axtens.net> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Received-SPF: pass client-ip=2607:f8b0:4864:20::62c; envelope-from=dja@axtens.net; helo=mail-pl1-x62c.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Oct 2020 01:57:46 -0000 v2: fix the grub-mkimage bug. I haven't changed any libtasn1 licensing because I don't think we reached any conclusion on whether anything was needed, and if so what. Part of a secure boot chain is allowing grub to verify the boot kernel. For UEFI platforms, this is usually delegated to the shim: see shim_lock.c. However, for platforms that do not implement UEFI, an alternative scheme is required. This series teaches grub how to verify Linux kernel-style 'appended signatures'. I talked about this in my recent Linux Plumbers talk: https://linuxplumbersconf.org/event/7/contributions/738/ and https://youtu.be/IJUNxHnopH4?t=510 In very short, an appended signature is a 'dumb' signature over the contents of a file. (It is distinct from schemes like Authenticode that are aware of the structure of the file and only sign certain parts.) The signature is wrapped in a PKCS#7 message, and is appended to the signed file along with some metadata and a magic string. The signatures are validated against a public key which is usually provided as an x509 certificate. Kernels on powerpc are already signed with this scheme and can be verified by IMA for kexec. As PKCS#7 messages and x509 certificates are both based on ASN.1, we import libtasn1 to parse them. Because ASN.1 isn't self-documenting, we import from GNUTLS the information we need to navigate their structure. This is a long series but it breaks down into some nice 'chunks': - patches 1 and 2 fix some documentation quirks I encountered - patch 3 is a small fix to allow persistent modules to work on the emu target. - patches 4 to 6 are small refactorings, mostly so I can reuse some code later. - patch 7 prepares posix_wrap for importing libtasn1 - patches 8 through 12 import libtasn1 and add tests. I've taken a different approach from gcrypt. We import gcrypt via a script that transforms the code into something that works for grub. We import libtasn1 through first just copying a subset of the code in (patch 8), then disabling parts we don't need for grub (patch 9), making changes for grub compatibility (patch 10) and then compiling it into a module (patch 11) and testing it (patch 12). This means that should we want to upgrade our version of libtasn1, we should be able to copy the new files in (repeat the process in patch 8) and then just cherry-pick/reapply patches 9 and 10 to repeat the process of disabling unused code and making grub compatiblity fixes. Hopefully that makes sense! - patch 13 allows x509 certificates to be built in to the grub core in much the same way as PGP keys. - patch 14 brings in the code from GNUTLS that allows us to parse PKCS#7 and x509 with libtasn1. - patch 15 is our PKCS#7 and x509 parser. They're minimal and fairly strict parsers that extract only the bits we need to verify the signatures. - patch 16 is the guts of the appended signature verifier. It uses the verifier infrastructure like shim_lock and pgp, and adds a number of user-friendly commands that mirror the pgp module. - patch 17 adds tests, and patch 18 adds documentation. The series applies on top of the previous series to allow grub itself to be signed with an appended signature: https://lists.gnu.org/archive/html/grub-devel/2020-08/msg00037.html The only dependency is that both that series and patch 13 of this series touch the grub-install/grub-mkimage code. (It's worth noting that even if we decide to take a different approach to signing grub, that doesn't affect any of the logic here.) I've also pushed this to https://github.com/daxtens/grub/tree/appendedsig That branch also contains the previous series. This patch series is easy to experiment with: it doesn't require any particular platform. It works under emu and passes tests under x86_64-efi. (Ironically, if you want to experiment with it on powerpc, you will need another patch to allocate more than 32MB of memory. You can expand HEAP_MAX_SIZE and HEAP_MAX_ADDR in grub-core/kern/ieee1275/init.c - see https://lists.gnu.org/archive/html/grub-devel/2020-10/msg00151.html Or there's an even crazier patch in my github branch that just grabs ~half of all available memory. We're still working internally on what the 'right' solution is and will send a followup patch.) This series implements enforcement similarly to the PGP verifier: enforcement is controlled by an environment variable that can be reset on the command line or via load_env. The series does not - in current form - provide the same sort of guarantees as UEFI secure boot. I've done this because I'm conscious of the long history of software freedom concerns that have accompanied strong secure-boot implementations. However, I'm also conscious of user requirements for UEFI-style secure boot chains. I've posted another patch that links signature enforcement to a device-tree property (/ibm,secure-boot) which is set on Power LPAR secure boot: https://lists.gnu.org/archive/html/grub-devel/2020-10/msg00048.html My hope is that by doing this in two stages, we can discuss whether this series is acceptable for upstream separately from any discussions about whether linking platform-secure-boot to signature enforcement is acceptable. I'm not expecting this to land upstream for 2.06. Patches 1 and 2 might be suitable but I don't really mind either way. Having said that, I'd appreciate any feedback before then. Alastair D'Silva (1): grub-install: support embedding x509 certificates Daniel Axtens (17): docs/grub: grub-install is no longer a shell script docs/grub: --pubkey has been supported for some time dl: provide a fake grub_dl_set_persistent for the emu target verifiers: factor unsafe module handling out of shim_lock pgp: factor out rsa_pad crypto: move storage for grub_crypto_pk_* to crypto.c posix_wrap: tweaks in preparation for libtasn1 libtasn1: import libtasn1-4.16.0 libtasn1: disable code not needed in grub libtasn1: changes for grub compatibility libtasn1: compile into asn1 module test_asn1: test module for libtasn1 appended signatures: import GNUTLS's ASN.1 description files appended signatures: parse PKCS#7 signedData and X.509 certificates appended signatures: support verifying appended signatures appended signatures: verification tests appended signatures: documentation .gitignore | 1 + Makefile.util.def | 6 + docs/grub.texi | 208 +- grub-core/Makefile.core.def | 54 + grub-core/commands/appendedsig/appendedsig.c | 644 +++++ grub-core/commands/appendedsig/appendedsig.h | 110 + grub-core/commands/appendedsig/asn1util.c | 102 + .../commands/appendedsig/gnutls_asn1_tab.c | 121 + grub-core/commands/appendedsig/pkcs7.c | 305 ++ .../commands/appendedsig/pkix_asn1_tab.c | 484 ++++ grub-core/commands/appendedsig/x509.c | 958 +++++++ grub-core/commands/efi/shim_lock.c | 45 +- grub-core/commands/pgp.c | 34 +- grub-core/commands/verifiers.c | 46 + grub-core/lib/crypto.c | 4 + grub-core/lib/libtasn1/LICENSE | 16 + grub-core/lib/libtasn1/README.md | 91 + grub-core/lib/libtasn1/lib/coding.c | 1423 ++++++++++ grub-core/lib/libtasn1/lib/decoding.c | 2481 +++++++++++++++++ grub-core/lib/libtasn1/lib/element.c | 1112 ++++++++ grub-core/lib/libtasn1/lib/element.h | 40 + grub-core/lib/libtasn1/lib/errors.c | 103 + grub-core/lib/libtasn1/lib/gstr.c | 74 + grub-core/lib/libtasn1/lib/gstr.h | 47 + grub-core/lib/libtasn1/lib/int.h | 221 ++ grub-core/lib/libtasn1/lib/parser_aux.c | 1174 ++++++++ grub-core/lib/libtasn1/lib/parser_aux.h | 172 ++ grub-core/lib/libtasn1/lib/structure.c | 1222 ++++++++ grub-core/lib/libtasn1/lib/structure.h | 45 + .../tests/CVE-2018-1000654-1_asn1_tab.h | 32 + .../tests/CVE-2018-1000654-2_asn1_tab.h | 36 + .../libtasn1_wrap/tests/CVE-2018-1000654.c | 61 + .../lib/libtasn1_wrap/tests/Test_overflow.c | 138 + .../lib/libtasn1_wrap/tests/Test_simple.c | 207 ++ .../lib/libtasn1_wrap/tests/Test_strings.c | 150 + .../libtasn1_wrap/tests/object-id-decoding.c | 116 + .../libtasn1_wrap/tests/object-id-encoding.c | 120 + .../lib/libtasn1_wrap/tests/octet-string.c | 211 ++ .../lib/libtasn1_wrap/tests/reproducers.c | 81 + grub-core/lib/libtasn1_wrap/wrap.c | 26 + grub-core/lib/libtasn1_wrap/wrap_tests.c | 75 + grub-core/lib/libtasn1_wrap/wrap_tests.h | 38 + grub-core/lib/pkcs1_v15.c | 59 + grub-core/lib/posix_wrap/limits.h | 1 + grub-core/lib/posix_wrap/stdlib.h | 8 + grub-core/lib/posix_wrap/sys/types.h | 1 + grub-core/tests/appended_signature_test.c | 250 ++ grub-core/tests/appended_signatures.h | 483 ++++ grub-core/tests/lib/functional_test.c | 1 + include/grub/dl.h | 11 + include/grub/file.h | 2 + include/grub/kernel.h | 3 +- include/grub/libtasn1.h | 589 ++++ include/grub/pkcs1_v15.h | 27 + include/grub/util/install.h | 7 +- include/grub/verify.h | 13 + tests/test_asn1.in | 12 + util/grub-install-common.c | 23 +- util/grub-mkimage.c | 15 +- util/mkimage.c | 41 +- 60 files changed, 14080 insertions(+), 100 deletions(-) create mode 100644 grub-core/commands/appendedsig/appendedsig.c create mode 100644 grub-core/commands/appendedsig/appendedsig.h create mode 100644 grub-core/commands/appendedsig/asn1util.c create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c create mode 100644 grub-core/commands/appendedsig/pkcs7.c create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c create mode 100644 grub-core/commands/appendedsig/x509.c create mode 100644 grub-core/lib/libtasn1/LICENSE create mode 100644 grub-core/lib/libtasn1/README.md create mode 100644 grub-core/lib/libtasn1/lib/coding.c create mode 100644 grub-core/lib/libtasn1/lib/decoding.c create mode 100644 grub-core/lib/libtasn1/lib/element.c create mode 100644 grub-core/lib/libtasn1/lib/element.h create mode 100644 grub-core/lib/libtasn1/lib/errors.c create mode 100644 grub-core/lib/libtasn1/lib/gstr.c create mode 100644 grub-core/lib/libtasn1/lib/gstr.h create mode 100644 grub-core/lib/libtasn1/lib/int.h create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h create mode 100644 grub-core/lib/libtasn1/lib/structure.c create mode 100644 grub-core/lib/libtasn1/lib/structure.h create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_overflow.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_simple.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_strings.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/octet-string.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/reproducers.c create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.c create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.h create mode 100644 grub-core/lib/pkcs1_v15.c create mode 100644 grub-core/tests/appended_signature_test.c create mode 100644 grub-core/tests/appended_signatures.h create mode 100644 include/grub/libtasn1.h create mode 100644 include/grub/pkcs1_v15.h create mode 100644 tests/test_asn1.in -- 2.25.1