From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.90_1) id 1kL6Qg-0004iY-GR for mharc-grub-devel@gnu.org; Wed, 23 Sep 2020 11:11:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33230) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kL6Qd-0004fC-HD for grub-devel@gnu.org; Wed, 23 Sep 2020 11:11:31 -0400 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:37534) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kL6QZ-0002eP-AA for grub-devel@gnu.org; Wed, 23 Sep 2020 11:11:31 -0400 Received: by mail-pl1-x641.google.com with SMTP id u4so1287188plr.4 for ; Wed, 23 Sep 2020 08:11:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:in-reply-to:references:date:message-id :mime-version; bh=rNevsmDdCsJvsc48rTmFb1ul9sToPipw79J9/+Qllts=; b=OLMemlw9Ryq3wxWnvJu1LuNLyM95gDkTStFHgGXuSVRGE9sUeXknuRAPpYJu2XTzzt p7AkzzpJYB5Ym0xeBRNLxuAadVW47U+/vAce5AFtIrrDmCrqdpnj5BDU4rpjY1Bv/Jwx ddOhOxyUkDg3TlD1bVbG5wVxaJTVZCakiP2/Y= 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:in-reply-to:references:date :message-id:mime-version; bh=rNevsmDdCsJvsc48rTmFb1ul9sToPipw79J9/+Qllts=; b=IuehxJaOHOI1QW1e9+Afm3idtuYAgWsOggHnBdIgXBAYFEzLkI4sZWbMtI1VA786A0 VhvAvE+1BBBQFHTLxIm+1Gs7hJ2VgQ/VB8F5tMBTwt5qDWQyeOg06G8uk2s9NsI1iPxm +NV0dwCl3fnp5MlGmjLJLQrZkPd0iyNVB++nQIBqs7Iq6AMgYLtFWz0DapByEcvwqBDV oVsTAQ6GFyQhs0VBtUEnrX02RYWykWXe1XE88aPjdhBClSu4opiRQGoemBsrWv3/P1/5 wSU0Tzs0/T04Nnj6cKZQU1VjzvBzoGD6ZWIRxKFEAyrNuFgVCRtbyy7Vog/2hS7xzWCW jxnw== X-Gm-Message-State: AOAM5320XptrxVMnXjABkKEI/ovZ2GNviPyn0qByAe9hXlI65Bzpwi7d +s292s0LcGi9AMxDz15DqJwbLEDcwF+/Rg== X-Google-Smtp-Source: ABdhPJzM9K7aJqK7yP9hf/msF8DAHsGih+cO6zKC8G0w6Aow4soekmFWeMLUaCxoh39bNmIYYFX0Og== X-Received: by 2002:a17:902:a60f:b029:d1:cbfc:7cec with SMTP id u15-20020a170902a60fb02900d1cbfc7cecmr272604plq.31.1600873881522; Wed, 23 Sep 2020 08:11:21 -0700 (PDT) Received: from localhost (2001-44b8-111e-5c00-b45d-1a4b-2a15-d1fa.static.ipv6.internode.on.net. [2001:44b8:111e:5c00:b45d:1a4b:2a15:d1fa]) by smtp.gmail.com with ESMTPSA id 84sm89908pfw.14.2020.09.23.08.11.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Sep 2020 08:11:20 -0700 (PDT) From: Daniel Axtens To: grub-devel@gnu.org, pjones@redhat.com, xnox@ubuntu.com Cc: rashmica.g@gmail.com, alastair@d-silva.org Subject: Re: [PATCH 0/3] Add support for signing grub with an appended signature In-Reply-To: <20200821023720.13747-1-dja@axtens.net> References: <20200821023720.13747-1-dja@axtens.net> Date: Thu, 24 Sep 2020 01:11:17 +1000 Message-ID: <87zh5go7e2.fsf@dja-thinkpad.axtens.net> MIME-Version: 1.0 Content-Type: text/plain Received-SPF: pass client-ip=2607:f8b0:4864:20::641; envelope-from=dja@axtens.net; helo=mail-pl1-x641.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, 23 Sep 2020 15:11:32 -0000 Hi, > Part of a secure boot chain is allowing boot firmware to verify the > grub core.img. For UEFI platforms, this is done by signing the PE > binary with a tool like pesign or sb-sign. However, for platforms that > don't implement UEFI, an alternative scheme is required. > > These patches provide some infrastructure and documentation for > signing grub's core.img with a Linux-kernel-module style appended > signature. > > Because some platforms, such as powerpc-ieee1275, load grub from a raw > disk partition rather than a filesystem, we extend grub-install to add > an ELF note that allows us to specify the size and location of the > signature. This is following up on the discussion out of Linux Plumbers [1]. Hopefully I've got the main question-askers, apologies if I've missed anyone or sent emails to the wrong people. I'm also emailing grub-devel@ in hopes of catching anyone else who is interested. One of the big requirements I heard was a desire to support key rotation, for example by being able to embed multiple signatures in a single signed grub. I checked, and this is possible with appended signatures as I have proposed them, because the size of the full signature block is known when grub-mkimage is called. You do have to do a bit of magic with openssl and sign-file, but it's not particuarly bad. This demonstrates the openssl side and it's easy to integrate with grub-mkimage: # sign data/hello-world with both signing1 and signing2, placing just the # PKCS#7 message in out/double-sig.p7s openssl cms -sign -binary -in data/hello-world \ -signer signing1.pem -inkey signing1.key \ -signer signing2.pem -inkey signing2.key \ -out out/double-sig.p7s -outform DER -noattr -md sha512 # append it to data/hello-world using sign-file's -s option, creating # out/hello-world-sha512-2keys ../tools/sign-file -s out/double-sig.p7s sha512 /dev/null data/hello-world out/hello-world-sha512-2keys # to verify, extract the cryptographic message with # extract-module-sig.pl from the kernel source ./extract-module-sig.pl -s out/hello-world-sha512-2keys > out/hello-world-sha512-2keys.sig 2> /dev/null if ! cmp out/double-sig.p7s out/hello-world-sha512-2keys.sig ; then echo "Input signature and data from extract-module-sig.pl -s do not agree!" exit 1; fi # openssl's verify requires that _both_ signatures are made with # embedded certs which validate against a trusted CA openssl cms -verify -binary -in out/hello-world-sha512-2keys.sig -inform der \ -content hello-world -CAfile ca.pem -out /dev/null if [ $? -ne 0 ]; then echo "OpenSSL failed to verify with both keys" exit 1 fi For our application, firmware will allow a grub binary to boot if any of the signatures in the PKCS#7 message match a key that is trusted by firmware. This should allow keys to be rotated with firmware releases without breaking backwards compatibility. I've updated https://github.com/daxtens/SLOF to demonstrate this: if any signature can be validated by a built-in key, it will pass verification. Another thing that was raised was the ability to make multiple signatures separated in time, where the second signer didn't have access to the private keys for the first signer. The example given was for someone to sign a distro binary with a second set of keys (e.g. specific keys for a data center) - then the binary would be bootable on machines with distro keys, and also on machines that have only the second set of keys. This is not so easy. For grub, with the elf note, the data over which the signature is made contains the size of the signature. To add a signature would be to change the size of the signature stored in the signed data. That would either break the old signature, or we would need to make it not a true appended signature any more: rather than being a 'dumb' signature over everything before the start of the appended signature data, it'd be more complex. We'd need to teach the signer and verifier how to deal with that, and then we've thrown away the advantages of appended signatures and reinvented many of the complexities of Authenticode. One thing we could potentially do without going down that route is to include a quantity of 'blank space' for signatures - we could for example always allocate a few kilobytes for signatures. The distro signatures would take up the first part of the buffer, leaving space for some for 'user' signatures. We can get this to work with the appended-signature format "as is": we specify how big the PKCS#7 message is, and if the message happens to be smaller than the size we give, both openssl and mbedtls will just ignore any trailing data. This does at least kinda-sorta work, but OpenSSL's 'cms -resign' command only works if we include signed attributes and at the moment our mbedtls implementation cannot handle that. I don't think the PKCS#7 standard mandates that behaviour, so maybe we can hack around it with the OpenSSL C API. Or maybe we can extend mbedtls to handle signed attributes. (eek!) The concern I have is that this approach creates a big block of arbitrary unsigned data in the grub binary. An attacker under our threat model (root on the host) could put any data they like into that space. I worry that in combination with some other vulernability, this could be used to more easily pass useful data in to grub. However, maybe that's not that much of a win for the attacker: if they are root they also have complete control of grub.cfg and can instruct grub to do quite a bit as it is. I'm also not sure that the use-case is quite as likely with Power systems vs x86 systems. But if I'm overthinking the security implications of a blank space in the binary, it seems like we could get it to work and I'd be happy to chase it up further. Thoughts? (on or off-list is fine.) Kind regards, Daniel [1] https://linuxplumbersconf.org/event/7/contributions/738/ https://youtu.be/IJUNxHnopH4?t=537 > More details are in patch 1, including a link to an open-source firmware > capable of verifying a grub image signed this way. > > Daniel Axtens (2): > docs/grub: Document signing grub under UEFI > docs/grub: Document signing grub with an appended signature > > Rashmica Gupta (1): > Add suport for signing grub with an appended signature > > docs/grub.texi | 64 ++++++++++++++++++++++++++++++++++++- > include/grub/util/install.h | 8 +++-- > include/grub/util/mkimage.h | 4 +-- > util/grub-install-common.c | 16 ++++++++-- > util/grub-mkimage.c | 11 +++++++ > util/grub-mkimagexx.c | 39 +++++++++++++++++++++- > util/mkimage.c | 10 +++--- > 7 files changed, 138 insertions(+), 14 deletions(-) > > -- > 2.25.1