|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 2/5] livepatch: Embed public key in Xen
From: Kevin Lampis <kevin.lampis@xxxxxxxxx>
Make it possible to embed a public key in Xen to be used when verifying
live patch payloads. Inclusion of the public key is optional.
To avoid needing to include a DER / X.509 parser in the hypervisor, the
public key is unpacked at build time and included in a form that is
convenient for the hypervisor to consume. This is different approach
from that used by Linux which embeds the entire X.509 certificate and
builds in a parser for it.
A suitable key can be created using openssl:
openssl req -x509 -newkey rsa:2048 -keyout priv.pem -out pub.pem \
-sha256 -days 3650 -nodes \
-subj
"/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"
openssl x509 -inform PEM -in pub.pem -outform PEM -pubkey -nocert -out
verify_key.pem
Signed-off-by: Kevin Lampis <kevin.lampis@xxxxxxxxx>
Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
---
In v3:
* Drop unnecessary condition in Makefile
* Use dashes instead of underscores
* Drop section placement annotation on declaration
* Clarify endianness of embedded key
xen/common/Kconfig | 18 +++++++++++++++++
xen/crypto/Makefile | 11 ++++++++++
xen/include/xen/livepatch.h | 5 +++++
xen/tools/extract-key.py | 40 +++++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+)
create mode 100755 xen/tools/extract-key.py
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 0951d4c2f286..74673078202a 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -472,6 +472,24 @@ config LIVEPATCH
If unsure, say Y.
+config PAYLOAD_VERIFY
+ bool "Verify signed LivePatch payloads"
+ depends on LIVEPATCH
+ select CRYPTO
+ help
+ Verify signed LivePatch payloads using an RSA public key built
+ into the Xen hypervisor. Selecting this option requires a
+ public key in PEM format to be available for embedding during
+ the build.
+
+config PAYLOAD_VERIFY_KEY
+ string "File name of public key used to verify payloads"
+ default "verify_key.pem"
+ depends on PAYLOAD_VERIFY
+ help
+ The file name of an RSA public key in PEM format to be used for
+ verifying signed LivePatch payloads.
+
config FAST_SYMBOL_LOOKUP
bool "Fast symbol lookup (bigger binary)"
default y
diff --git a/xen/crypto/Makefile b/xen/crypto/Makefile
index db29655333a3..3d17232b78bc 100644
--- a/xen/crypto/Makefile
+++ b/xen/crypto/Makefile
@@ -1,2 +1,13 @@
obj-y += rijndael.o
obj-y += vmac.o
+
+obj-$(CONFIG_PAYLOAD_VERIFY) += builtin-payload-key.o
+
+key-path := $(objtree)/$(patsubst "%",%,$(CONFIG_PAYLOAD_VERIFY_KEY))
+$(obj)/builtin-payload-key.bin: $(key-path) $(srctree)/tools/extract-key.py
+ $(srctree)/tools/extract-key.py < $< > $@.new
+ $(call move-if-changed,$@.new,$@)
+
+$(obj)/builtin-payload-key.S: BINFILE_FLAGS := -i
+$(obj)/builtin-payload-key.S: $(srctree)/tools/binfile
$(obj)/builtin-payload-key.bin FORCE
+ $(call if_changed,binfile,$(obj)/builtin-payload-key.bin
xen_livepatch_key_data)
diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h
index d074a5bebecc..52f90cbed45b 100644
--- a/xen/include/xen/livepatch.h
+++ b/xen/include/xen/livepatch.h
@@ -143,6 +143,11 @@ struct payload;
int revert_payload(struct payload *data);
void revert_payload_tail(struct payload *data);
+#ifdef CONFIG_PAYLOAD_VERIFY
+/* The public key data contained with Xen used to verify payload signatures. */
+extern const uint8_t xen_livepatch_key_data[];
+#endif
+
#else
/*
diff --git a/xen/tools/extract-key.py b/xen/tools/extract-key.py
new file mode 100755
index 000000000000..05c6bc261b3f
--- /dev/null
+++ b/xen/tools/extract-key.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+
+# SPDX-License-Identifier: GPL-2.0
+
+import binascii
+import struct
+import sys
+import subprocess
+import re
+
+# Decode a certificate into a format suitable for embedding in Xen.
+
+out = subprocess.check_output(['openssl', 'rsa', '-pubin', '-inform', 'PEM',
+ '-noout', '-text'], stdin=sys.stdin,
+ universal_newlines=True)
+combined = ''
+for line in out.split('\n'):
+ line = line.rstrip()
+ if line.startswith(' '):
+ combined += line.strip().replace(':', '')
+ match = re.match(r'Exponent: .* \(0x(.*)\)', line)
+ if match:
+ e = match.group(1)
+
+n = combined.lstrip('0')
+if len(n) % 2 == 1:
+ n = '0' + n
+n = binascii.unhexlify(n)
+e = e.lstrip('0')
+if len(e) % 2 == 1:
+ e = '0' + e
+e = binascii.unhexlify(e)
+
+# Use little-endian for lengths.
+# Use big-endian for byte sequences (as openssl does).
+
+sys.stdout.buffer.write(struct.pack('<I', len(n)))
+sys.stdout.buffer.write(n)
+sys.stdout.buffer.write(struct.pack('<I', len(e)))
+sys.stdout.buffer.write(e)
--
2.49.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |