From nobody Thu Dec 18 16:47:46 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1747301951; cv=none; d=zohomail.com; s=zohoarc; b=KEDB1bK1hQ/yWplEOaBSchr9BSrx2kdUoeSy2nXOQV8arGinJrSy5+4IXQtU+t3ALRbckDCU5q4gNGLvnMclZvliiRjRLRjlO3kuJf1rmZkZFDX6BSVdGwzk+sEFOXLGE8awis41EQAdV0VXtNiKizZIdGQUWJkghvBRHw+549g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747301951; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=mI8pwGmu4+lpXzloXzs62CfY/4mwVbPPP3HB7j9Crbc=; b=BBitTsT+yhXBtgQqV5n5dEXYJOP480mPHzmZQ8+lgW89/xVYKCTFG0gEFzd12Wc6YHg78dh6VPrk+NDwp22Tbw5si7JrvK6Jr1naRD5/5Xf/bOVyA3d+xacVX/tycngpDrg3fvL79SkCvw2F0nktpf3m0xqySN9u1SLfq8z7V/0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1747301951451945.1138706758895; Thu, 15 May 2025 02:39:11 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.985052.1371005 (Exim 4.92) (envelope-from ) id 1uFV3L-0006P7-2j; Thu, 15 May 2025 09:38:59 +0000 Received: by outflank-mailman (output) from mailman id 985052.1371005; Thu, 15 May 2025 09:38:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uFV3L-0006Oz-0B; Thu, 15 May 2025 09:38:59 +0000 Received: by outflank-mailman (input) for mailman id 985052; Thu, 15 May 2025 09:38:57 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uFV3J-00064K-RB for xen-devel@lists.xenproject.org; Thu, 15 May 2025 09:38:57 +0000 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [2a00:1450:4864:20::530]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 6c734429-3170-11f0-9eb6-5ba50f476ded; Thu, 15 May 2025 11:38:57 +0200 (CEST) Received: by mail-ed1-x530.google.com with SMTP id 4fb4d7f45d1cf-5f4d0da2d2cso1336216a12.3 for ; Thu, 15 May 2025 02:38:57 -0700 (PDT) Received: from rossla-pc.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ad23ad2b386sm895152066b.104.2025.05.15.02.38.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 May 2025 02:38:45 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 6c734429-3170-11f0-9eb6-5ba50f476ded DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1747301937; x=1747906737; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mI8pwGmu4+lpXzloXzs62CfY/4mwVbPPP3HB7j9Crbc=; b=LIOymE3HvUV6fV5iIeb/R+4iKaEvQjewGW5P3w5+L+sbDJxs7t/NfPpD6LCLG1dhjR i9zYR9s7YNnM5BBCESwp/yKdtQccmi6+aM74GQRm2XMZLWXS5XwIH/vlNnN7jC7VTLjI JrXQ89NfWIIxQh/jHiNc2FTfqQQkAQRNkrR4Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747301937; x=1747906737; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mI8pwGmu4+lpXzloXzs62CfY/4mwVbPPP3HB7j9Crbc=; b=nobgdEIxPWPerVEi7WUkpYf91CevOhGlq7TmLb0kwgXWuRvI65/Lz2S+bYzrZF5haK etEeIZ6I0N0+LpphDLpp3XlRLas4LmCQu4qgHMzQ4walm/EouQceSNqnwTvOUKVRUZ+g 9xI0NFyOM9w7oJD+dQrEvcdRyV+RkITQQ1KLwbXba9amd+E8rL4t3xitqOijP/yQ/87+ z4HSpl86fvSGFApG9jYjOwpFR+CcY+OMG39v7S5TJ7tFQF0W3BJnC6lzGmJ0gFthbjrs RZqy07GWMgzuGyjCTfVvDad3IEnKSD3U0pbaP4ZT9wW3mz0Hg7/V8eedHAZ7lbicMMHU /4bQ== X-Gm-Message-State: AOJu0YzTO/w5EDvE+4TmSRtB99k6N3JJTC5GUGIaHHSlJCflLzBA99c7 LMQV/G92AfdDXydH5aVdWqobLiFh8DbsU0iA+LBMa2NgI8anS9UrhgtVXsMFHqucwQzQbp/3/Cc = X-Gm-Gg: ASbGncvyt69qTOIpI0etAxKlfzVw09/hr7FEDR8ISNovwAYbjpwDhm+x7XTLFTsSCmj lRghvngGb6FzmhyNZ3mVLrPOtBnZdhE/p5tm8tvWZuPYyBXVzM9bFBwGW98gIbSBevbQKzlqA8L S237t40M4p8yokoRxhGeSX7Gtsix3Zh/Ko9bjUpuLncaN3ysaOG3PfVK+2r/ENerElvx8oifHtA /OxZv9Cwq8RA5AymlacxLjiO54yq/7P4ZF+Z7K2CDZcsyKAQkmRKPNUzJdvWisZEbWNNxO8I0at 8O6twg8ZLdmOs8stRfvNjvpwKtOuEXXtw3xn7ohsH2q9ekbIair096xFnGuDOWihE4iqZ7pCt0s = X-Google-Smtp-Source: AGHT+IEc0aCKX8aM831QI5j5in052DGx5TrDoOOTTvkREwyfXgYPfKZpNrkdblEGBzby2dBNg5eLVA== X-Received: by 2002:a17:907:7ba3:b0:aca:cac8:1cf9 with SMTP id a640c23a62f3a-ad515e73b6bmr140690166b.33.1747301925861; Thu, 15 May 2025 02:38:45 -0700 (PDT) From: Ross Lagerwall To: xen-devel@lists.xenproject.org Cc: Kevin Lampis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Ross Lagerwall Subject: [PATCH v2 2/5] livepatch: Embed public key in Xen Date: Thu, 15 May 2025 10:38:17 +0100 Message-ID: <20250515093822.659916-3-ross.lagerwall@citrix.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250515093822.659916-1-ross.lagerwall@citrix.com> References: <20250515093822.659916-1-ross.lagerwall@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1747301953136116600 Content-Type: text/plain; charset="utf-8" From: Kevin Lampis 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=3DXX/ST=3DStateName/L=3DCityName/O=3DCompanyName/OU=3DCompany= SectionName/CN=3DCommonNameOrHostname" openssl x509 -inform PEM -in pub.pem -outform PEM -pubkey -nocert -out veri= fy_key.pem Signed-off-by: Kevin Lampis Signed-off-by: Ross Lagerwall --- In v2: * Split the loading part into a separate patch. * Expect public key in object tree rather than source tree. * Rename Kconfig symbols and others to reflect that it is used for verification in Xen rather than signing. * Move extern declaration to a header. * Move raw key data to init.rodata. xen/common/Kconfig | 18 ++++++++++++++++++ xen/crypto/Makefile | 13 +++++++++++++ xen/include/xen/livepatch.h | 6 ++++++ xen/tools/extract-key.py | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100755 xen/tools/extract-key.py diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 6d43be2e6e8a..e4466db595c2 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -461,6 +461,24 @@ config LIVEPATCH =20 If unsure, say Y. =20 +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..64ed90ba55b1 100644 --- a/xen/crypto/Makefile +++ b/xen/crypto/Makefile @@ -1,2 +1,15 @@ obj-y +=3D rijndael.o obj-y +=3D vmac.o + +obj-$(CONFIG_PAYLOAD_VERIFY) +=3D builtin_payload_key.o + +ifeq ($(CONFIG_PAYLOAD_VERIFY),y) +key_path :=3D $(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 :=3D -i +$(obj)/builtin_payload_key.S: $(srctree)/tools/binfile $(obj)/builtin_payl= oad_key.bin FORCE + $(call if_changed,binfile,$(obj)/builtin_payload_key.bin xen_livepatch_ke= y_data) +endif diff --git a/xen/include/xen/livepatch.h b/xen/include/xen/livepatch.h index d074a5bebecc..0265f1fce057 100644 --- a/xen/include/xen/livepatch.h +++ b/xen/include/xen/livepatch.h @@ -18,6 +18,7 @@ struct xen_sysctl_livepatch_op; =20 #ifdef CONFIG_LIVEPATCH =20 +#include #include =20 /* @@ -143,6 +144,11 @@ struct payload; int revert_payload(struct payload *data); void revert_payload_tail(struct payload *data); =20 +#ifdef CONFIG_PAYLOAD_VERIFY +/* The public key data contained with Xen used to verify payload signature= s. */ +extern const uint8_t __initconst xen_livepatch_key_data[]; +#endif + #else =20 /* diff --git a/xen/tools/extract-key.py b/xen/tools/extract-key.py new file mode 100755 index 000000000000..2980264b757d --- /dev/null +++ b/xen/tools/extract-key.py @@ -0,0 +1,37 @@ +#!/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 =3D subprocess.check_output(['openssl', 'rsa', '-pubin', '-inform', 'P= EM', + '-noout', '-text'], stdin=3Dsys.stdin, + universal_newlines=3DTrue) +combined =3D '' +for line in out.split('\n'): + line =3D line.rstrip() + if line.startswith(' '): + combined +=3D line.strip().replace(':', '') + match =3D re.match(r'Exponent: .* \(0x(.*)\)', line) + if match: + e =3D match.group(1) + +n =3D combined.lstrip('0') +if len(n) % 2 =3D=3D 1: + n =3D '0' + n +n =3D binascii.unhexlify(n) +e =3D e.lstrip('0') +if len(e) % 2 =3D=3D 1: + e =3D '0' + e +e =3D binascii.unhexlify(e) + +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) --=20 2.49.0