All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vivek Goyal <vgoyal@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: ebiederm@xmission.com, hpa@zytor.com, mjg59@srcf.ucam.org,
	greg@kroah.com, bp@alien8.de, dyoung@redhat.com,
	chaowang@redhat.com, bhe@redhat.com, akpm@linux-foundation.org,
	dhowells@redhat.com, pjones@redhat.com,
	Vivek Goyal <vgoyal@redhat.com>
Subject: [PATCH 4/9] pefile: Strip the wrapper off of the cert data block
Date: Thu,  3 Jul 2014 17:07:16 -0400	[thread overview]
Message-ID: <1404421641-12691-5-git-send-email-vgoyal@redhat.com> (raw)
In-Reply-To: <1404421641-12691-1-git-send-email-vgoyal@redhat.com>

The certificate data block in a PE binary has a wrapper around the PKCS#7
signature we actually want to get at.  Strip this off and check that we've got
something that appears to be a PKCS#7 signature.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
 arch/x86/kernel/pefile_parser.c | 73 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/arch/x86/kernel/pefile_parser.c b/arch/x86/kernel/pefile_parser.c
index 72bc2bb..088779e 100644
--- a/arch/x86/kernel/pefile_parser.c
+++ b/arch/x86/kernel/pefile_parser.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/pe.h>
+#include <linux/asn1.h>
 #include <keys/asymmetric-subtype.h>
 #include <keys/asymmetric-parser.h>
 #include <crypto/hash.h>
@@ -27,6 +28,74 @@
 	pr_devel("<== %s()"FMT"\n", __func__, ##__VA_ARGS__)
 
 /*
+ * Check and strip the PE wrapper from around the signature and check that the
+ * remnant looks something like PKCS#7.
+ */
+static int pefile_strip_sig_wrapper(const void *pebuf,
+				    struct pefile_context *ctx)
+{
+	struct win_certificate wrapper;
+	const u8 *pkcs7;
+
+	if (ctx->sig_len < sizeof(wrapper)) {
+		pr_debug("Signature wrapper too short\n");
+		return -ELIBBAD;
+	}
+
+	memcpy(&wrapper, pebuf + ctx->sig_offset, sizeof(wrapper));
+	pr_debug("sig wrapper = { %x, %x, %x }\n",
+		 wrapper.length, wrapper.revision, wrapper.cert_type);
+
+	/*
+	 * Both pesign and sbsign round up the length of certificate table
+	 * (in optional header data directories) to 8 byte alignment.
+	 */
+	if (round_up(wrapper.length, 8) != ctx->sig_len) {
+		pr_debug("Signature wrapper len wrong\n");
+		return -ELIBBAD;
+	}
+	if (wrapper.revision != WIN_CERT_REVISION_2_0) {
+		pr_debug("Signature is not revision 2.0\n");
+		return -ENOTSUPP;
+	}
+	if (wrapper.cert_type != WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
+		pr_debug("Signature certificate type is not PKCS\n");
+		return -ENOTSUPP;
+	}
+
+	/*
+	 * Looks like actual pkcs signature length is in wrapper->length.
+	 * size obtained from data dir entries lists the total size of
+	 * certificate table which is also aligned to octawrod boundary.
+	 *
+	 * So set signature length field appropriately.
+	 */
+	ctx->sig_len = wrapper.length;
+	ctx->sig_offset += sizeof(wrapper);
+	ctx->sig_len -= sizeof(wrapper);
+	if (ctx->sig_len == 0) {
+		pr_debug("Signature data missing\n");
+		return -EKEYREJECTED;
+	}
+
+	/* What's left should a PKCS#7 cert */
+	pkcs7 = pebuf + ctx->sig_offset;
+	if (pkcs7[0] == (ASN1_CONS_BIT | ASN1_SEQ)) {
+		if (pkcs7[1] == 0x82 &&
+		    pkcs7[2] == (((ctx->sig_len - 4) >> 8) & 0xff) &&
+		    pkcs7[3] ==  ((ctx->sig_len - 4)       & 0xff))
+			return 0;
+		if (pkcs7[1] == 0x80)
+			return 0;
+		if (pkcs7[1] > 0x82)
+			return -EMSGSIZE;
+	}
+
+	pr_debug("Signature data not PKCS#7\n");
+	return -ELIBBAD;
+}
+
+/*
  * Parse a PE binary.
  */
 static int pefile_parse_binary(const void *pebuf, unsigned int pelen,
@@ -140,6 +209,10 @@ int pefile_parse_verify_sig(const void *pebuf, unsigned int pelen)
 	if (ret < 0)
 		return ret;
 
+	ret = pefile_strip_sig_wrapper(pebuf, &ctx);
+	if (ret < 0)
+		return ret;
+
 	/* Not yet complete */
 	return -ENOANO;
 }
-- 
1.9.0


  parent reply	other threads:[~2014-07-03 21:08 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-03 21:07 [RFC PATCH 0/9] kexec: Verify signature of PE signed bzImage Vivek Goyal
2014-07-03 21:07 ` [PATCH 1/9] pkcs7: Forward declare struct key in pkcs7.h Vivek Goyal
2014-07-03 21:07 ` [PATCH 2/9] Provide PE binary definitions Vivek Goyal
2014-07-04 19:12   ` Anca Emanuel
2014-07-04 19:14     ` H. Peter Anvin
2014-07-04 19:16     ` Matthew Garrett
2014-07-03 21:07 ` [PATCH 3/9] pefile: Parse a PE binary and verify signature Vivek Goyal
2014-07-03 21:07 ` Vivek Goyal [this message]
2014-07-03 21:07 ` [PATCH 5/9] pefile: Parse the presumed PKCS#7 content of the certificate blob Vivek Goyal
2014-07-03 21:07 ` [PATCH 6/9] pefile: Parse the "Microsoft individual code signing" data blob Vivek Goyal
2014-07-03 21:07 ` [PATCH 7/9] pefile: Digest the PE binary and compare to the PKCS#7 data Vivek Goyal
2014-07-03 21:07 ` [PATCH 8/9] PEFILE: Validate PKCS#7 trust chain Vivek Goyal
2014-07-03 21:07 ` [PATCH 9/9] kexec: Verify the signature of signed PE bzImage Vivek Goyal
2014-07-04 14:51 ` [RFC PATCH 0/9] kexec: Verify signature of PE signed bzImage Borislav Petkov
2014-07-05  3:01   ` Vivek Goyal
2014-07-08 15:54     ` Borislav Petkov
2014-07-08 16:07       ` Vivek Goyal
2014-07-08 16:12         ` Borislav Petkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1404421641-12691-5-git-send-email-vgoyal@redhat.com \
    --to=vgoyal@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=bhe@redhat.com \
    --cc=bp@alien8.de \
    --cc=chaowang@redhat.com \
    --cc=dhowells@redhat.com \
    --cc=dyoung@redhat.com \
    --cc=ebiederm@xmission.com \
    --cc=greg@kroah.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=pjones@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.