mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: linux-security-module@vger.kernel.org, linux-efi@vger.kernel.org,
	linux-pm@vger.kernel.org, linux-crypto@vger.kernel.org,
	opensuse-kernel@opensuse.org, David Howells <dhowells@redhat.com>,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	Len Brown <len.brown@intel.com>, Pavel Machek <pavel@ucw.cz>,
	Josh Boyer <jwboyer@redhat.com>, Vojtech Pavlik <vojtech@suse.cz>,
	Matt Fleming <matt.fleming@intel.com>,
	James Bottomley <james.bottomley@hansenpartnership.com>,
	Greg KH <gregkh@linuxfoundation.org>,
	JKosina@suse.com, Rusty Russell <rusty@rustcorp.com.au>,
	Herbert Xu <herbert@gondor.hengli.com.au>,
	"David S. Miller" <davem@davemloft.net>,
	"H. Peter Anvin" <hpa@zytor.com>, Michal Marek <mmarek@suse.cz>,
	Gary Lin <GLin@suse.com>, Vivek Goyal <vgoyal@redhat.com>,
	"Lee, Chun-Yi" <jlee@suse.com>
Subject: [PATCH V4 14/15] Hibernate: notify bootloader regenerate key-pair for snapshot verification
Date: Sun, 15 Sep 2013 08:57:00 +0800	[thread overview]
Message-ID: <1379206621-18639-15-git-send-email-jlee@suse.com> (raw)
In-Reply-To: <1379206621-18639-1-git-send-email-jlee@suse.com>

This patch introduced SNAPSHOT_REGEN_KEYS kernel config, enable this
option let kernel notify booloader (e.g. shim) to regenerate key-pair of
snapshot verification for each hibernate.

Kernel loaded S4 sign key in efi stub, so the private key forward from
efi bootloader to kernel in UEFI secure environment. Regenerate key-pair
for each hibernate will gain more security but it hurt the lifetime of
EFI flash memory.

Kernel write an non-volatile runtime efi variable, the name is
GenS4Key-fe141863-c070-478e-b8a3-878a5dc9ef21, to notify efi bootloader
regenerate key-pair for next hibernate cycle.

Userland hibernate tool can write GenS4Key at runtime, kernel will
respect the value but not overwrite it when S4. This mechanism let
userland tool can also notify bootloader to regenerate key-pair through
GenS4Key flag.

V4:
- Use efivar API to access GenS4Key variable.
- Call set_key_regen_flag() in hibernate.c and user.c

Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
---
 kernel/power/Kconfig          |   15 +++++++++
 kernel/power/hibernate.c      |    4 ++-
 kernel/power/hibernate_keys.c |   67 +++++++++++++++++++++++++++++++++++++++++
 kernel/power/power.h          |    5 +++
 kernel/power/user.c           |    6 +++-
 5 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 79b34fa..63bda98 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -78,6 +78,21 @@ config SNAPSHOT_VERIFICATION
 	  dependent on UEFI environment. EFI bootloader should generate the
 	  key-pair.
 
+config SNAPSHOT_REGEN_KEYS
+	bool "Regenerate key-pair for each snapshot verification"
+        depends on SNAPSHOT_VERIFICATION
+	help
+	  Enabled this option let kernel notify booloader (e.g. shim) to
+	  regenerate key-pair of snapshot verification for each hibernate.
+	  Linux kernel write an non-volatile runtime EFI variable, the name
+	  is GenS4Key-fe141863-c070-478e-b8a3-878a5dc9ef21, to notify EFI
+	  bootloader regenerate key-pair for next hibernate cycle.
+
+	  Userland hibernate tool can write GenS4Key at runtime then kernel
+	  will respect the value but not overwrite it when S4. This mechanism
+	  let userland tool can also notify bootloader to regenerate key-pair
+	  through GenS4Key flag.
+
 choice
 	prompt "Which hash algorithm should snapshot be signed with?"
         depends on SNAPSHOT_VERIFICATION
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 90a25c7..6336499 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -675,8 +675,10 @@ int hibernate(void)
 		pr_debug("PM: writing image.\n");
 		error = swsusp_write(flags);
 		swsusp_free();
-		if (!error)
+		if (!error) {
+			set_key_regen_flag();
 			power_down();
+		}
 		in_suspend = 0;
 		pm_restore_gfp_mask();
 	} else {
diff --git a/kernel/power/hibernate_keys.c b/kernel/power/hibernate_keys.c
index daf08e0..72d5c7a 100644
--- a/kernel/power/hibernate_keys.c
+++ b/kernel/power/hibernate_keys.c
@@ -14,6 +14,8 @@ struct forward_info {
 	unsigned char                   skey_data_buf[SKEY_DBUF_MAX_SIZE];
 };
 
+static efi_char16_t efi_gens4key_name[9] = { 'G', 'e', 'n', 'S', '4', 'K', 'e', 'y', 0 };
+
 static void *skey_data;
 static void *forward_info_buf;
 static unsigned long skey_dsize;
@@ -301,6 +303,70 @@ bool sig_enforced(void)
 	return sig_enforce;
 }
 
+int set_key_regen_flag(void)
+{
+#ifdef CONFIG_SNAPSHOT_REGEN_KEYS
+	struct efivar_entry *entry;
+	unsigned long datasize;
+	u8 gens4key;
+	int ret;
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	memcpy(entry->var.VariableName, efi_gens4key_name, sizeof(efi_gens4key_name));
+	memcpy(&(entry->var.VendorGuid), &EFI_HIBERNATE_GUID, sizeof(efi_guid_t));
+
+	/* existing flag may set by userland, respect it do not overwrite */
+	datasize = 0;
+	ret = efivar_entry_size(entry, &datasize);
+	if (!ret && datasize > 0) {
+		kfree(entry);
+		return 0;
+	}
+
+	/* set flag of key-pair regeneration */
+	gens4key = 1;
+	ret = efivar_entry_set(entry,
+			       EFI_VARIABLE_NON_VOLATILE |
+			       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			       EFI_VARIABLE_RUNTIME_ACCESS,
+			       1, (void *)&gens4key, false);
+	if (ret)
+		pr_err("PM: Set GenS4Key flag fail: %d\n", ret);
+
+	kfree(entry);
+
+	return ret;
+#else
+	return 0;
+#endif
+}
+
+static int clean_key_regen_flag(void)
+{
+	struct efivar_entry *entry;
+	int ret;
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	memcpy(entry->var.VariableName, efi_gens4key_name, sizeof(efi_gens4key_name));
+	memcpy(&(entry->var.VendorGuid), &EFI_HIBERNATE_GUID, sizeof(efi_guid_t));
+
+	/* clean flag of key-pair regeneration */
+	ret = efivar_entry_set(entry,
+			       EFI_VARIABLE_NON_VOLATILE |
+			       EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			       EFI_VARIABLE_RUNTIME_ACCESS,
+			       0, NULL, false);
+	kfree(entry);
+
+	return ret;
+}
+
 static int __init init_sign_key_data(void)
 {
 	skey_data = (void *)get_zeroed_page(GFP_KERNEL);
@@ -311,6 +377,7 @@ static int __init init_sign_key_data(void)
 		efi_erase_s4_skey_data();
 		pr_info("PM: Load s4 sign key from EFI\n");
 	}
+	clean_key_regen_flag();
 
 	return 0;
 }
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 4f411ac..da5733f 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -188,6 +188,7 @@ extern bool swsusp_page_is_sign_key(struct page *page);
 extern unsigned long get_sig_forward_info_pfn(void);
 extern void fill_sig_forward_info(void *page_addr, int sig_check_ret);
 extern bool sig_enforced(void);
+extern int set_key_regen_flag(void);
 #else
 static inline bool skey_data_available(void)
 {
@@ -202,6 +203,10 @@ static inline unsigned long get_sig_forward_info_pfn(void)
 {
 	return 0;
 }
+static inline int set_key_regen_flag(void)
+{
+	return 0;
+}
 #endif /* !CONFIG_SNAPSHOT_VERIFICATION */
 
 /* kernel/power/block_io.c */
diff --git a/kernel/power/user.c b/kernel/power/user.c
index e2088af..3d3632b 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -323,6 +323,8 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
 			error = -EPERM;
 			break;
 		}
+		/* set regenerate S4 key flag */
+		set_key_regen_flag();
 		/*
 		 * Tasks are frozen and the notifiers have been called with
 		 * PM_HIBERNATION_PREPARE
@@ -336,8 +338,10 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
 		break;
 
 	case SNAPSHOT_POWER_OFF:
-		if (data->platform_support)
+		if (data->platform_support) {
+			set_key_regen_flag();
 			error = hibernation_platform_enter();
+		}
 		break;
 
 	case SNAPSHOT_SET_SWAP_AREA:
-- 
1.6.0.2


  parent reply	other threads:[~2013-09-15  0:58 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-15  0:56 [RFC V4 PATCH 00/15] Signature verification of hibernate snapshot Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 01/15] asymmetric keys: add interface and skeleton for implement signature generation Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 02/15] asymmetric keys: implement EMSA_PKCS1-v1_5-ENCODE in rsa Lee, Chun-Yi
2013-09-17 21:51   ` Dmitry Kasatkin
2013-09-18  9:08     ` joeyli
2013-09-17 22:29   ` Dmitry Kasatkin
2013-09-23 16:49   ` Phil Carmody
2013-09-26  7:08     ` joeyli
2013-09-15  0:56 ` [PATCH V4 03/15] asymmetric keys: separate the length checking of octet string from RSA_I2OSP Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 04/15] asymmetric keys: implement OS2IP in rsa Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 05/15] asymmetric keys: implement RSASP1 Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 06/15] asymmetric keys: support parsing PKCS #8 private key information Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 07/15] asymmetric keys: explicitly add the leading zero byte to encoded message Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 08/15] Hibernate: introduced RSA key-pair to verify signature of snapshot Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 09/15] Hibernate: generate and " Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH 10/15] Hibernate: Avoid S4 sign key data included in snapshot image Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 11/15] Hibernate: taint kernel when signature check fail Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 12/15] Hibernate: show the verification time for monitor performance Lee, Chun-Yi
2013-09-15  0:56 ` [PATCH V4 13/15] Hibernate: introduced SNAPSHOT_SIG_HASH config for select hash algorithm Lee, Chun-Yi
2013-09-18 13:45   ` Pavel Machek
2013-09-26  1:43     ` joeyli
2013-09-26  8:21       ` Pavel Machek
2013-09-15  0:57 ` Lee, Chun-Yi [this message]
2013-09-15  0:57 ` [PATCH V4 15/15] Hibernate: adapt to UEFI secure boot with signature check Lee, Chun-Yi
2013-09-25 21:04 ` [RFC V4 PATCH 00/15] Signature verification of hibernate snapshot David Howells
2013-09-25 21:25   ` Alan Stern
2013-09-25 22:16     ` James Bottomley
2013-09-26  0:27       ` Pavel Machek
2013-09-26  2:32         ` James Bottomley
2013-09-26  6:24           ` Jiri Kosina
2013-09-26 14:44             ` James Bottomley
2013-09-26 14:48               ` Jiri Kosina
2013-09-26 14:56                 ` Vojtech Pavlik
2013-09-26  4:40         ` joeyli
2013-09-26  1:11       ` Alan Stern
2013-09-26  2:19     ` joeyli
2013-09-26 10:43       ` joeyli
2013-09-26 12:06         ` Pavel Machek
2013-09-26 12:21           ` Michal Marek
2013-09-26 12:23             ` Vojtech Pavlik
2013-09-26 12:22           ` Vojtech Pavlik
2013-09-26 13:20             ` joeyli
2013-09-26 12:56           ` joeyli
2013-09-26  1:36   ` joeyli
2013-10-17 14:18 ` Rafael J. Wysocki

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=1379206621-18639-15-git-send-email-jlee@suse.com \
    --to=joeyli.kernel@gmail.com \
    --cc=GLin@suse.com \
    --cc=JKosina@suse.com \
    --cc=davem@davemloft.net \
    --cc=dhowells@redhat.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=herbert@gondor.hengli.com.au \
    --cc=hpa@zytor.com \
    --cc=james.bottomley@hansenpartnership.com \
    --cc=jlee@suse.com \
    --cc=jwboyer@redhat.com \
    --cc=len.brown@intel.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=matt.fleming@intel.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=mmarek@suse.cz \
    --cc=opensuse-kernel@opensuse.org \
    --cc=pavel@ucw.cz \
    --cc=rjw@sisk.pl \
    --cc=rusty@rustcorp.com.au \
    --cc=vgoyal@redhat.com \
    --cc=vojtech@suse.cz \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®