As security becomes more and more important, we add the in-kernel
encryption support for hibernation.
This prototype is a trial version to implement the hibernation
encryption in the kernel. This patch set is divided
into two parts:
1. The hibernation snapshot encryption in kernel space.
2. The key derivation implementation in user space.
The whole process is illustrated below:
1. install the kernel module:
modprobe crypto_hibernation
2. run the tool to generate the key from
user provided passphrase (salt has been read
from kernel).
3. launch the hibernation process, the kernel
uses the key in step 2 to encrypt the
hibernation snapshot.
4. resume the system and the initrd will
launch cryto_hibernate to read previous salt
from kernel and probe the user passphrase
and generate the same key.
5. kernel uses this key to decrypt the hibernation
snapshot and restore to previous system.
Chen Yu (4):
PM / Hibernate: Add helper functions for hibernation encryption
PM / hibernate: Install crypto hooks for hibernation encryption
PM / Hibernate: Encrypt the snapshot pages before submitted to the
block device
tools: create power/crypto utility
include/linux/suspend.h | 40 +++
kernel/power/Kconfig | 14 ++
kernel/power/Makefile | 1 +
kernel/power/crypto_hibernation.c | 421 +++++++++++++++++++++++++++++++
kernel/power/hibernate.c | 67 +++++
kernel/power/power.h | 67 +++++
kernel/power/swap.c | 182 +++++++++++++-
tools/power/crypto/Makefile | 24 ++
tools/power/crypto/crypto_hibernate.c | 462 ++++++++++++++++++++++++++++++++++
9 files changed, 1270 insertions(+), 8 deletions(-)
create mode 100644 kernel/power/crypto_hibernation.c
create mode 100644 tools/power/crypto/Makefile
create mode 100644 tools/power/crypto/crypto_hibernate.c
--
2.7.4
Basically, the in-kernel hibernation encryption solution is
to encrypt the pages before they go to the block device.
Why we do this?
1. One advantage is: Users do not have to
encrypt the whole swap partition as other tools.
2. Ideally kernel memory should be encrypted by the
kernel itself. We have uswsusp to support user
space hibernation, however doing the encryption
in kernel space has more advantages:
2.1 Not having to transfer plain text kernel memory to
user space. Per Lee, Chun-Yi, uswsusp is disabled
when the kernel is locked down:
https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
linux-fs.git/commit/?h=lockdown-20180410&
id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
due to:
"There have some functions be locked-down because
there have no appropriate mechanisms to check the
integrity of writing data."
2.2 Not having to copy each page to user space
one by one not in parallel, which might introduce
significant amount of copy_to_user() and it might
not be efficient on servers having large amount of DRAM.
2.3 Distribution has requirement to do snapshot
signature for verification, which can be built
by leveraging this patch set.
2.4 The encryption is in the kernel, so it doesn't
have to worry too much about bugs in user space
utilities and similar, for example.
For the key derivation solution, there was a discussion
on the mailing list on whether the key should be derived
in kernel or in user space. And it turns out to be generating
the key by user space is more applicable[1]. So the procedure
is illustrated below:
1. The user space reads the salt from kernel and
generates a symmetrical key(512bits for now)
based on user passphrase. Then the kernel uses
that key to encrypt the hibernation image.
2. The salt will be saved in image header and passed to
the restore kernel.
3. During restore, the userspace reads the salt
from the kernel first and then probe passphrase
from the user to generate the same key and pass
that key back to kernel.
4. The restore kernel uses that key to decrypt the image.
[1] https://www.spinics.net/lists/linux-crypto/msg33145.html
Suggested-by: Rafael J. Wysocki <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Len Brown <[email protected]>
Cc: "Lee, Chun-Yi" <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: "Theodore Ts'o" <[email protected]>
Cc: Stephan Mueller <[email protected]>
Cc: Denis Kenzior <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Chen Yu <[email protected]>
---
kernel/power/Kconfig | 14 ++
kernel/power/Makefile | 1 +
kernel/power/crypto_hibernation.c | 411 ++++++++++++++++++++++++++++++++++++++
kernel/power/power.h | 42 ++++
4 files changed, 468 insertions(+)
create mode 100644 kernel/power/crypto_hibernation.c
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index e880ca2..fd39c30 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -101,6 +101,20 @@ config PM_STD_PARTITION
suspended image to. It will simply pick the first available swap
device.
+config CRYPTO_HIBERNATION
+ tristate "Encryption/signature of snapshot for hibernation"
+ depends on HIBERNATION && CRYPTO_AES && CRYPTO_HASH2 && KEYS
+ default n
+ help
+ Allow the kernel to encrypt/signature the snapshot data
+ based on user provided passphrase. The user should provide
+ a valid symmetrical key to the kernel either by ioctl or
+ by keyctl, so the kernel could use that key either to encrypt
+ the hibernation snapshot pages, or get signature of these pages.
+ The user facility could be found under tools/power/crypto/.
+
+ If in doubt, say N.
+
config PM_SLEEP
def_bool y
depends on SUSPEND || HIBERNATE_CALLBACKS
diff --git a/kernel/power/Makefile b/kernel/power/Makefile
index a3f79f0e..52c68a4 100644
--- a/kernel/power/Makefile
+++ b/kernel/power/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_FREEZER) += process.o
obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o
obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o
+obj-$(CONFIG_CRYPTO_HIBERNATION) += crypto_hibernation.o
obj-$(CONFIG_PM_AUTOSLEEP) += autosleep.o
obj-$(CONFIG_PM_WAKELOCKS) += wakelock.o
diff --git a/kernel/power/crypto_hibernation.c b/kernel/power/crypto_hibernation.c
new file mode 100644
index 0000000..406bb0c
--- /dev/null
+++ b/kernel/power/crypto_hibernation.c
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/kernel/power/crypto_hibernation.c
+ *
+ * This file provides in-kernel encrypted/signature hibernation support.
+ *
+ * Copyright (c) 2018, Rafael J. Wysocki <[email protected]>
+ * Copyright (c) 2018, Chen, Yu <[email protected]>
+ * Copyright (c) 2018, Lee, Chun-Yi <[email protected]>
+ *
+ * Basically, this solution encrypts the pages before they go to
+ * the block device, the procedure is illustrated below:
+ * 1. The user space reads the salt from the kernel, generates
+ * a symmetrical key, the kernel uses that key to encrypt the
+ * hibernation image.
+ * 2. The salt is saved in image header and passed to
+ * the restore kernel.
+ * 3. During restore, the userspace needs to read the salt
+ * from the kernel and probe passphrase from the user
+ * to generate the key and pass that key back to kernel.
+ * 4. The restore kernel uses that key to decrypt the image.
+ *
+ * After all, ideally kernel memory should be encrypted
+ * by the kernel itself.
+ */
+#define pr_fmt(fmt) "PM: " fmt
+
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+#include <linux/random.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/cdev.h>
+#include <linux/major.h>
+#include <crypto/skcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/aes.h>
+#include <crypto/hash.h>
+#include <crypto/sha.h>
+#include "power.h"
+
+static int crypto_data(const char *inbuf,
+ int inlen,
+ char *outbuf,
+ int outlen,
+ unsigned int cmd,
+ int page_idx);
+static void crypto_save(void *buf);
+static void crypto_restore(void *buf);
+static int crypto_init(bool suspend);
+
+static struct hibernation_crypto hib_crypto;
+
+/* return the key value. */
+static char *get_key_ptr(void)
+{
+ return hib_crypto.keys.derived_key;
+}
+
+/* return the salt value. */
+static char *get_salt_ptr(void)
+{
+ return hib_crypto.keys.salt;
+}
+
+/* Encrypt algorithm. */
+static struct hibernate_crypt_mode {
+ const char *friendly_name;
+ const char *cipher_str;
+ int keysize;
+} available_modes[] = {
+ [HIBERNATE_ENCRYPTION_MODE_AES_256_XTS] = {
+ .friendly_name = "AES-256-XTS",
+ .cipher_str = "xts(aes)",
+ .keysize = 64,
+ },
+};
+
+/**
+ * crypto_data() - en/decrypt/digest the data
+ * @inbuf: the source buffer
+ * @inlen: the length of source buffer
+ * @outbuf: the dest buffer
+ * @outlen: the length of dest buffer
+ * @cmd: combination mask of encrypt/decrypt/signature
+ * @page_idx: the index of that page been manipulated
+ *
+ * Return: 0 on success, non-zero for other cases.
+ *
+ * Better use SKCIPHER_REQUEST_ON_STACK to support multi-thread
+ * encryption, however hibernation does not support multi-threaded
+ * swap page write out due to the fact that the swap_map has to be
+ * accessed sequently.
+ */
+static int crypto_data(const char *inbuf,
+ int inlen,
+ char *outbuf,
+ int outlen,
+ unsigned int cmd,
+ int page_idx)
+{
+ struct scatterlist src, dst;
+ int ret;
+ struct {
+ __le64 idx;
+ u8 padding[HIBERNATE_IV_SIZE - sizeof(__le64)];
+ } iv;
+
+ if (cmd | CMD_CRYPT) {
+ bool encrypt = (cmd & CMD_ENCRYPT) ? true : false;
+
+ iv.idx = cpu_to_le64(page_idx);
+ memset(iv.padding, 0, sizeof(iv.padding));
+
+ /*
+ * Do a AES-256 encryption on every page-index
+ * to generate the IV.
+ */
+ crypto_cipher_encrypt_one(hib_crypto.essiv_tfm, (u8 *)&iv,
+ (u8 *)&iv);
+ sg_init_one(&src, inbuf, inlen);
+ sg_init_one(&dst, outbuf, outlen);
+ skcipher_request_set_crypt(hib_crypto.req_sk,
+ &src, &dst, outlen, &iv);
+
+ if (encrypt)
+ ret = crypto_skcipher_encrypt(hib_crypto.req_sk);
+ else
+ ret = crypto_skcipher_decrypt(hib_crypto.req_sk);
+ if (ret)
+ pr_err("%s %scrypt failed: %d\n", __func__,
+ encrypt ? "en" : "de", ret);
+ goto out;
+ }
+
+ out:
+ return ret;
+}
+
+/* Invoked across hibernate/restore. */
+static void crypto_save(void *buf)
+{
+ memcpy(buf, get_salt_ptr(), HIBERNATE_MAX_SALT_BYTES);
+}
+
+static void crypto_restore(void *buf)
+{
+ memcpy(get_salt_ptr(), buf, HIBERNATE_MAX_SALT_BYTES);
+}
+
+/*
+ * Copied from init_essiv_generator().
+ * Using SHA256 to derive the key and
+ * save it.
+ */
+static int init_iv_generator(const u8 *raw_key, int keysize)
+{
+ int ret = -EINVAL;
+ u8 salt[SHA256_DIGEST_SIZE];
+
+ /* 1. IV generator initialization. */
+ if (!hib_crypto.essiv_hash_tfm) {
+ hib_crypto.essiv_hash_tfm = crypto_alloc_shash("sha256", 0, 0);
+ if (IS_ERR(hib_crypto.essiv_hash_tfm)) {
+ pr_err("crypto_hibernate: error allocating SHA-256 transform for IV: %ld\n",
+ PTR_ERR(hib_crypto.essiv_hash_tfm));
+ return -ENOMEM;
+ }
+ }
+
+ if (!hib_crypto.essiv_tfm) {
+ hib_crypto.essiv_tfm = crypto_alloc_cipher("aes", 0, 0);
+ if (IS_ERR(hib_crypto.essiv_tfm)) {
+ pr_err("crypto_hibernate: error allocating cipher aes for IV generation: %ld\n",
+ PTR_ERR(hib_crypto.essiv_tfm));
+ ret = -ENOMEM;
+ goto free_essiv_hash;
+ }
+ }
+
+ {
+ /* 2. Using hash to generate the 256bits AES key */
+ SHASH_DESC_ON_STACK(desc, hib_crypto.essiv_hash_tfm);
+
+ desc->tfm = hib_crypto.essiv_hash_tfm;
+ desc->flags = 0;
+ ret = crypto_shash_digest(desc, raw_key, keysize, salt);
+ if (ret) {
+ pr_err("crypto_hibernate: error get digest for raw_key\n");
+ goto free_essiv_hash;
+ }
+ }
+ /* 3. Switch to the 256bits AES key for later IV generation. */
+ ret = crypto_cipher_setkey(hib_crypto.essiv_tfm, salt, sizeof(salt));
+
+ free_essiv_hash:
+ crypto_free_shash(hib_crypto.essiv_hash_tfm);
+ hib_crypto.essiv_hash_tfm = NULL;
+ return ret;
+}
+
+static int init_crypto_helper(void)
+{
+ int ret = 0;
+ struct hibernate_crypt_mode *mode;
+
+ /* Choose the user specified encryption algorithm */
+ mode = &available_modes[hib_crypto.keys.contents_encryption_mode];
+ if (IS_ERR(mode))
+ return -EINVAL;
+
+ pr_info("Hibernate crypto: choose %s for encryption.\n",
+ mode->friendly_name);
+ /* Symmetric encryption initialization. */
+ if (!hib_crypto.tfm_sk) {
+ hib_crypto.tfm_sk =
+ crypto_alloc_skcipher(mode->cipher_str,
+ 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hib_crypto.tfm_sk)) {
+ pr_err("Failed to load transform for aes: %ld\n",
+ PTR_ERR(hib_crypto.tfm_sk));
+ return -ENOMEM;
+ }
+ }
+
+ if (!hib_crypto.req_sk) {
+ hib_crypto.req_sk =
+ skcipher_request_alloc(hib_crypto.tfm_sk, GFP_KERNEL);
+ if (!hib_crypto.req_sk) {
+ pr_err("Failed to allocate request\n");
+ ret = -ENOMEM;
+ goto free_tfm_sk;
+ }
+ }
+ skcipher_request_set_callback(hib_crypto.req_sk, 0, NULL, NULL);
+
+ /* Switch to the image key, and prepare for page en/decryption. */
+ ret = crypto_skcipher_setkey(hib_crypto.tfm_sk, get_key_ptr(),
+ mode->keysize);
+ if (ret) {
+ pr_err("Failed to set the image key. (%d)\n", ret);
+ goto free_req_sk;
+ }
+
+ ret = init_iv_generator(get_key_ptr(),
+ mode->keysize);
+ if (ret) {
+ pr_err("Failed to init the iv generator. (%d)\n", ret);
+ goto free_req_sk;
+ }
+ return 0;
+
+ free_req_sk:
+ skcipher_request_free(hib_crypto.req_sk);
+ hib_crypto.req_sk = NULL;
+ free_tfm_sk:
+ crypto_free_skcipher(hib_crypto.tfm_sk);
+ hib_crypto.tfm_sk = NULL;
+ return ret;
+}
+
+/*
+ * Either invoked during suspend or resume.
+ */
+static int crypto_init(bool suspend)
+{
+ int ret = 0;
+
+ pr_info("Prepared to %scrypt the image data.\n",
+ suspend ? "en" : "de");
+ if (!hib_crypto.keys.user_key_valid) {
+ pr_err("Need to get user provided key first!(eg, via ioctl)\n");
+ return -EINVAL;
+ }
+
+ ret = init_crypto_helper();
+ if (ret) {
+ pr_err("Failed to initialize basic crypto helpers. (%d)\n",
+ ret);
+ return ret;
+ }
+
+ pr_info("Key generated, waiting for data encryption/decrytion.\n");
+ return 0;
+}
+
+/* key/salt probing via ioctl. */
+dev_t crypto_dev;
+static struct class *crypto_dev_class;
+static struct cdev crypto_cdev;
+
+#define HIBERNATE_SALT_READ _IOW('C', 0x18, int)
+#define HIBERNATE_KEY_WRITE _IOW('C', 0x19, int)
+
+static DEFINE_MUTEX(crypto_mutex);
+
+static long crypto_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = 0;
+
+ mutex_lock(&crypto_mutex);
+ switch (cmd) {
+ case HIBERNATE_SALT_READ:
+ if (copy_to_user((void __user *)arg,
+ get_salt_ptr(),
+ HIBERNATE_MAX_SALT_BYTES))
+ ret = -EFAULT;
+ break;
+ case HIBERNATE_KEY_WRITE:
+ if (copy_from_user(&hib_crypto.keys,
+ (void __user *)arg,
+ sizeof(struct hibernation_crypto_keys))) {
+ hib_crypto.keys.user_key_valid = 0;
+ ret = -EFAULT;
+ } else
+ hib_crypto.keys.user_key_valid = 1;
+ break;
+ default:
+ break;
+ }
+ mutex_unlock(&crypto_mutex);
+
+ return ret;
+}
+
+static int crypto_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int crypto_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations crypto_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = crypto_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = crypto_ioctl,
+#endif
+ .open = crypto_open,
+ .release = crypto_release,
+ .llseek = noop_llseek,
+};
+
+/*
+ * For key/salt exchange between user and kernel space
+ * via ioctl(TODO: keyring).
+ */
+static int crypto_hibernate_init(void)
+{
+ if ((alloc_chrdev_region(&crypto_dev, 0, 1, "crypto")) < 0) {
+ pr_err("Cannot allocate major number for crypto hibernate.\n");
+ return -ENOMEM;
+ }
+
+ cdev_init(&crypto_cdev, &crypto_fops);
+ crypto_cdev.owner = THIS_MODULE;
+ crypto_cdev.ops = &crypto_fops;
+
+ if ((cdev_add(&crypto_cdev, crypto_dev, 1)) < 0) {
+ pr_err("Cannot add the crypto device.\n");
+ goto r_chrdev;
+ }
+
+ crypto_dev_class = class_create(THIS_MODULE,
+ "crypto_class");
+ if (crypto_dev_class == NULL) {
+ pr_err("Cannot create the crypto_class.\n");
+ goto r_cdev;
+ }
+
+ if ((device_create(crypto_dev_class, NULL, crypto_dev, NULL,
+ "crypto_hibernate")) == NULL){
+ pr_err("Cannot create the crypto device node.\n");
+ goto r_device;
+ }
+ /* generate the random salt */
+ get_random_bytes(get_salt_ptr(), HIBERNATE_MAX_SALT_BYTES);
+
+ return 0;
+
+ r_device:
+ class_destroy(crypto_dev_class);
+ r_cdev:
+ cdev_del(&crypto_cdev);
+ r_chrdev:
+ unregister_chrdev_region(crypto_dev, 1);
+ return -EINVAL;
+}
+
+static void crypto_hibernate_exit(void)
+{
+ device_destroy(crypto_dev_class, crypto_dev);
+ class_destroy(crypto_dev_class);
+ cdev_del(&crypto_cdev);
+ unregister_chrdev_region(crypto_dev, 1);
+}
+
+MODULE_AUTHOR("Yu Chen <[email protected]>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hibernation crypto facility");
+
+module_init(crypto_hibernate_init);
+module_exit(crypto_hibernate_exit);
diff --git a/kernel/power/power.h b/kernel/power/power.h
index 9e58bdc..a539bdb 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -69,6 +69,48 @@ extern void enable_restore_image_protection(void);
static inline void enable_restore_image_protection(void) {}
#endif /* CONFIG_STRICT_KERNEL_RWX */
+#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION)
+#define HIBERNATE_MAX_SALT_BYTES 16
+#define HIBERNATE_MAX_KEY_BYTES 64
+#define HIBERNATE_IV_SIZE 16
+
+/* Do data encryption */
+#define CMD_ENCRYPT 0x1
+/* Do data decryption */
+#define CMD_DECRYPT 0x2
+/* Do data signature update */
+#define CMD_SIG_UPDATE 0x4
+/* Do data signature final */
+#define CMD_SIG_FINAL 0x8
+#define CMD_CRYPT (CMD_ENCRYPT | CMD_DECRYPT)
+
+/* Add any encryption algorithm here. */
+#define HIBERNATE_ENCRYPTION_MODE_AES_256_XTS 1
+
+struct hibernation_crypto_keys {
+ char derived_key[HIBERNATE_MAX_KEY_BYTES];
+ char salt[HIBERNATE_MAX_SALT_BYTES];
+ int contents_encryption_mode;
+ int user_key_valid;
+};
+
+struct hibernation_crypto {
+ /* For data encryption */
+ struct crypto_skcipher *tfm_sk;
+ struct skcipher_request *req_sk;
+
+ /* For IV generation */
+ struct crypto_cipher *essiv_tfm;
+ struct crypto_shash *essiv_hash_tfm;
+
+ /* Private key info */
+ struct hibernation_crypto_keys keys;
+};
+
+#else
+#define HIBERNATE_MAX_SALT_BYTES 0
+#endif
+
#else /* !CONFIG_HIBERNATION */
static inline void hibernate_reserved_size_init(void) {}
--
2.7.4
crypto_hibernate is a user-space utility to generate
512bits key and pass it to the kernel via ioctl
for hibernation encryption.(We can also add the key
into kernel via keyctl if necessary.)
The key derivation is based on a simplified implementation
of PBKDF2[1] in e2fsprogs - both the key length and the hash
bytes are the same - 512bits. crypto_hibernate will firstly
read the salt from kernel and probe the user for passphrase,
then uses the salt of passphrase to generate a 512bits key
based on PBKDF2.
Usage:
1. install the kernel module:
modprobe crypto_hibernation
2. run this tool to generate the key from
user provided passphrase (salt has been read from kernel).
3. launch the hibernation process, the kernel
uses the key in step 2 to encrypt the
hibernation snapshot.
4. resume the system and the initrd will
launch cryto_hibernate to read previous salt
from kernel and probe the user passphrase
and generate the same key.
5. kernel uses this key to decrypt the hibernation
snapshot and restore to previous system.
[1] https://www.ietf.org/rfc/rfc2898.txt (5.2 PBKDF2)
Suggested-by: "Theodore Ts'o" <[email protected]>
Suggested-by: Eric Biggers <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: "Theodore Ts'o" <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: Stephan Mueller <[email protected]>
Cc: Denis Kenzior <[email protected]>
Cc: "Lee, Chun-Yi" <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Chen Yu <[email protected]>
---
tools/power/crypto/Makefile | 24 ++
tools/power/crypto/crypto_hibernate.c | 462 ++++++++++++++++++++++++++++++++++
2 files changed, 486 insertions(+)
create mode 100644 tools/power/crypto/Makefile
create mode 100644 tools/power/crypto/crypto_hibernate.c
diff --git a/tools/power/crypto/Makefile b/tools/power/crypto/Makefile
new file mode 100644
index 0000000..3544e64
--- /dev/null
+++ b/tools/power/crypto/Makefile
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0
+CC = $(CROSS_COMPILE)gcc
+BUILD_OUTPUT := $(CURDIR)
+PREFIX ?= /usr
+DESTDIR ?=
+
+ifeq ("$(origin O)", "command line")
+ BUILD_OUTPUT := $(O)
+endif
+
+crypto_hibernate : crypto_hibernate.c
+CFLAGS += -Wall
+
+%: %.c
+ @mkdir -p $(BUILD_OUTPUT)
+ $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@
+
+.PHONY : clean
+clean :
+ @rm -f $(BUILD_OUTPUT)/crypto_hibernate
+
+install : crypto_hibernate
+ install -d $(DESTDIR)$(PREFIX)/bin
+ install $(BUILD_OUTPUT)/crypto_hibernate $(DESTDIR)$(PREFIX)/bin/crypto_hibernate
diff --git a/tools/power/crypto/crypto_hibernate.c b/tools/power/crypto/crypto_hibernate.c
new file mode 100644
index 0000000..10de295
--- /dev/null
+++ b/tools/power/crypto/crypto_hibernate.c
@@ -0,0 +1,462 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * The key based derived function algorithm for hibernation
+ * (copied from e2fsprogs)
+ *
+ * Copyright (C) 2004 Sam Hocevar <[email protected]>
+ * Copyright (C) 2018 Theodore Ts'o <[email protected]>
+ * Copyright (C) 2018 Yu Chen <[email protected]>
+ *
+ * The key derivation is based on a simplified implementation
+ * of PBKDF2 in e2fsprogs - both the key length and the hash
+ * bytes are the same - 512bits. crypto_hibernate will firstly
+ * reads the salt from kernel and probe the user for passphrase,
+ * then uses them to generate a 512bits key by SHA512 hash and PBKDF2.
+ *
+ * A typical usage:
+ * 1. install the kernel module:
+ * modprobe crypto_hibernation
+ * 2. run this tool to generate the key from
+ * user provided passphrase. (salt is read from kernel)
+ * 3. launch the hibernation process, the kernel
+ * uses the key from step 2 to encrypt the
+ * hibernation snapshot.
+ * 4. resume the system and the initrd will
+ * launch cryto_hibernate to read previous salt
+ * from kernel and then probe the user passphrase
+ * and finally generate the same key.
+ * 5. kernel uses this key to decrypt the hibernation
+ * snapshot.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Library
+ * General Public License, version 2.
+ * %End-Header%
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#define PBKDF2_ITERATIONS 0xFFFF
+#define SHA512_BLOCKSIZE 128
+#define SHA512_LENGTH 64
+#define HIBERNATE_MAX_SALT_BYTES 16
+#define HIBERNATE_MAX_KEY_BYTES SHA512_LENGTH
+#define MAX_PASSPHRASE_SIZE 1024
+
+/*
+ * Add more encryption algorithm here, but need
+ * to add corresponding support in kernel too.
+ */
+#define HIBERNATE_ENCRYPTION_MODE_AES_256_XTS 1
+
+/* Same structure as kernel */
+struct hibernation_crypto_keys {
+ char derived_key[HIBERNATE_MAX_KEY_BYTES];
+ char salt[HIBERNATE_MAX_SALT_BYTES];
+ int contents_encryption_mode;
+ int user_key_valid;
+};
+
+struct hibernation_crypto_keys hib_keys;
+
+static char *get_key_ptr(void)
+{
+ return hib_keys.derived_key;
+}
+
+static char *get_salt_ptr(void)
+{
+ return hib_keys.salt;
+}
+
+static const unsigned int K[64] = {
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+};
+
+/* Various logical functions */
+#define Ch(x, y, z) (z ^ (x & (y ^ z)))
+#define Maj(x, y, z) (((x | y) & z) | (x & y))
+#define S(x, n) RORc((x), (n))
+#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
+#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+#define RORc(x, y) \
+ (((((unsigned int)(x)&0xFFFFFFFFUL)>>(unsigned int)((y)&31)) |\
+ ((unsigned int)(x)<<(unsigned int)(32-((y)&31)))) & 0xFFFFFFFFUL)
+
+#define RND(a, b, c, d, e, f, g, h, i) \
+ do { \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1; \
+ } while (0)
+
+#define STORE64H(x, y) \
+ do { \
+ (y)[0] = (unsigned char)(((x)>>56)&255);\
+ (y)[1] = (unsigned char)(((x)>>48)&255);\
+ (y)[2] = (unsigned char)(((x)>>40)&255);\
+ (y)[3] = (unsigned char)(((x)>>32)&255);\
+ (y)[4] = (unsigned char)(((x)>>24)&255);\
+ (y)[5] = (unsigned char)(((x)>>16)&255);\
+ (y)[6] = (unsigned char)(((x)>>8)&255);\
+ (y)[7] = (unsigned char)((x)&255); \
+ } while (0)
+
+#define STORE32H(x, y) \
+ do { \
+ (y)[0] = (unsigned char)(((x)>>24)&255);\
+ (y)[1] = (unsigned char)(((x)>>16)&255);\
+ (y)[2] = (unsigned char)(((x)>>8)&255);\
+ (y)[3] = (unsigned char)((x)&255); \
+ } while (0)
+
+#define LOAD32H(x, y) \
+ (x = ((unsigned int)((y)[0] & 255)<<24) |\
+ ((unsigned int)((y)[1] & 255)<<16) |\
+ ((unsigned int)((y)[2] & 255)<<8) |\
+ ((unsigned int)((y)[3] & 255)))
+
+struct sha512_state {
+ unsigned long long length;
+ unsigned int state[8], curlen;
+ unsigned char buf[64];
+};
+
+/* This is a highly simplified version from libtomcrypt */
+struct hash_state {
+ struct sha512_state sha512;
+};
+
+static void sha512_compress(struct hash_state *md,
+ const unsigned char *buf)
+{
+ unsigned int S[8], W[64], t0, t1;
+ unsigned int t;
+ int i;
+
+ /* copy state into S */
+ for (i = 0; i < 8; i++)
+ S[i] = md->sha512.state[i];
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ LOAD32H(W[i], buf + (4*i));
+
+ /* fill W[16..63] */
+ for (i = 16; i < 64; i++)
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] +
+ Gamma0(W[i - 15]) + W[i - 16];
+
+ /* Compress */
+ for (i = 0; i < 64; ++i) {
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
+ t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
+ S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
+ }
+
+ /* feedback */
+ for (i = 0; i < 8; i++)
+ md->sha512.state[i] = md->sha512.state[i] + S[i];
+}
+
+static void sha512_init(struct hash_state *md)
+{
+ md->sha512.curlen = 0;
+ md->sha512.length = 0;
+ md->sha512.state[0] = 0x6A09E667UL;
+ md->sha512.state[1] = 0xBB67AE85UL;
+ md->sha512.state[2] = 0x3C6EF372UL;
+ md->sha512.state[3] = 0xA54FF53AUL;
+ md->sha512.state[4] = 0x510E527FUL;
+ md->sha512.state[5] = 0x9B05688CUL;
+ md->sha512.state[6] = 0x1F83D9ABUL;
+ md->sha512.state[7] = 0x5BE0CD19UL;
+}
+
+#define MIN(x, y) (((x) < (y))?(x):(y))
+
+static void sha512_process(struct hash_state *md,
+ const unsigned char *in, unsigned long inlen)
+{
+ unsigned long n;
+
+ while (inlen > 0) {
+ if (md->sha512.curlen == 0 && inlen >= SHA512_BLOCKSIZE) {
+ sha512_compress(md, in);
+ md->sha512.length += SHA512_BLOCKSIZE * 8;
+ in += SHA512_BLOCKSIZE;
+ inlen -= SHA512_BLOCKSIZE;
+ } else {
+ n = MIN(inlen, (SHA512_BLOCKSIZE - md->sha512.curlen));
+ memcpy(md->sha512.buf + md->sha512.curlen,
+ in, (size_t)n);
+ md->sha512.curlen += n;
+ in += n;
+ inlen -= n;
+ if (md->sha512.curlen == SHA512_BLOCKSIZE) {
+ sha512_compress(md, md->sha512.buf);
+ md->sha512.length += 8*SHA512_BLOCKSIZE;
+ md->sha512.curlen = 0;
+ }
+ }
+ }
+}
+
+static void sha512_done(struct hash_state *md, unsigned char *out)
+{
+ int i;
+
+ /* increase the length of the message */
+ md->sha512.length += md->sha512.curlen * 8;
+
+ /* append the '1' bit */
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
+
+ /* if the length is currently above 56 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+ if (md->sha512.curlen > 56) {
+ while (md->sha512.curlen < 64)
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
+
+ sha512_compress(md, md->sha512.buf);
+ md->sha512.curlen = 0;
+ }
+
+ /* pad upto 56 bytes of zeroes */
+ while (md->sha512.curlen < 56)
+ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
+
+ /* store length */
+ STORE64H(md->sha512.length, md->sha512.buf+56);
+ sha512_compress(md, md->sha512.buf);
+
+ /* copy output */
+ for (i = 0; i < 8; i++)
+ STORE32H(md->sha512.state[i], out+(4*i));
+}
+
+static void start_sha512(const unsigned char *in, unsigned long in_size,
+ unsigned char out[SHA512_LENGTH])
+{
+ struct hash_state md;
+
+ sha512_init(&md);
+ sha512_process(&md, in, in_size);
+ sha512_done(&md, out);
+}
+
+static void pbkdf2_sha512(const char *passphrase, const char *salt,
+ unsigned int count,
+ char *derived_key)
+{
+ size_t passphrase_size = strlen(passphrase);
+ unsigned char buf[SHA512_LENGTH + MAX_PASSPHRASE_SIZE] = {0};
+ unsigned char tempbuf[SHA512_LENGTH] = {0};
+ char final[SHA512_LENGTH] = {0};
+ unsigned char saltbuf[HIBERNATE_MAX_SALT_BYTES +
+ MAX_PASSPHRASE_SIZE] = {0};
+ int actual_buf_len = SHA512_LENGTH + passphrase_size;
+ int actual_saltbuf_len = HIBERNATE_MAX_SALT_BYTES + passphrase_size;
+ unsigned int x, y;
+ unsigned int *final_u32 = (unsigned int *)final;
+ unsigned int *temp_u32 = (unsigned int *)tempbuf;
+
+ memcpy(saltbuf, salt, HIBERNATE_MAX_SALT_BYTES);
+ memcpy(&saltbuf[HIBERNATE_MAX_SALT_BYTES], passphrase, passphrase_size);
+ memcpy(&buf[SHA512_LENGTH], passphrase, passphrase_size);
+
+ for (x = 0; x < count; ++x) {
+ if (x == 0) {
+ start_sha512(saltbuf, actual_saltbuf_len, tempbuf);
+ } else {
+ /*
+ * buf: [previous hash || passphrase]
+ */
+ memcpy(buf, tempbuf, SHA512_LENGTH);
+ start_sha512(buf, actual_buf_len, tempbuf);
+ }
+ for (y = 0; y < (sizeof(final) / sizeof(*final_u32)); ++y)
+ final_u32[y] = final_u32[y] ^ temp_u32[y];
+ }
+ memcpy(derived_key, final, HIBERNATE_MAX_KEY_BYTES);
+}
+
+#define HIBERNATE_SALT_READ _IOW('C', 0x18, int)
+#define HIBERNATE_KEY_WRITE _IOW('C', 0x19, int)
+
+static int disable_echo(struct termios *saved_settings)
+{
+ struct termios current_settings;
+ int rc = 0;
+
+ rc = tcgetattr(0, ¤t_settings);
+ if (rc)
+ return rc;
+ *saved_settings = current_settings;
+ current_settings.c_lflag &= ~ECHO;
+ rc = tcsetattr(0, TCSANOW, ¤t_settings);
+
+ return rc;
+}
+
+static void get_passphrase(char *passphrase, int len)
+{
+ char *p;
+ struct termios current_settings;
+
+ assert(len > 0);
+ disable_echo(¤t_settings);
+ p = fgets(passphrase, len, stdin);
+ tcsetattr(0, TCSANOW, ¤t_settings);
+ printf("\n");
+ if (!p) {
+ printf("Aborting.\n");
+ exit(1);
+ }
+ p = strrchr(passphrase, '\n');
+ if (!p)
+ p = passphrase + len - 1;
+ *p = '\0';
+}
+
+#define CRYPTO_FILE "/dev/crypto_hibernate"
+
+static int write_keys(void)
+{
+ int fd, ret;
+
+ fd = open(CRYPTO_FILE, O_RDWR);
+ if (fd < 0) {
+ printf("Cannot open device file...\n");
+ return -ENODEV;
+ }
+ /* Choose xts(aes) encryption for now */
+ hib_keys.contents_encryption_mode =
+ HIBERNATE_ENCRYPTION_MODE_AES_256_XTS;
+
+ ret = ioctl(fd, HIBERNATE_KEY_WRITE, &hib_keys);
+ if (ret) {
+ printf("ioctl write key failed with return val (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int read_salt(void)
+{
+ int fd, ret;
+
+ fd = open(CRYPTO_FILE, O_RDWR);
+ if (fd < 0) {
+ printf("Cannot open device file...\n");
+ return -ENODEV;
+ }
+ ret = ioctl(fd, HIBERNATE_SALT_READ, get_salt_ptr());
+ if (ret) {
+ printf("ioctl read salt failed with return val (%d)\n", ret);
+ return ret;
+ }
+ return 0;
+}
+
+static int key_derive_from_passphrase(const char *pass)
+{
+ /* Need to get salt from
+ * kernel first.
+ */
+ if (read_salt())
+ exit(1);
+ /*
+ * Derive key by using passphrase and salt,
+ * and store the derived key in key buffer.
+ * Then pass this key to the kernel.
+ */
+ pbkdf2_sha512(pass, get_salt_ptr(), PBKDF2_ITERATIONS, get_key_ptr());
+ if (write_keys())
+ exit(1);
+
+ return 0;
+}
+
+void help(void)
+{
+ printf(
+ "Usage: crypto_hibernate [OPTIONS]\n"
+ "-p passphrase [or probed from user if not given]\n");
+}
+
+int main(int argc, char *argv[])
+{
+ int opt, option_index = 0, has_passphrase = 0;
+ char in_passphrase[MAX_PASSPHRASE_SIZE];
+
+ while ((opt = getopt_long_only(argc, argv, "+p:h",
+ NULL, &option_index)) != -1) {
+ switch (opt) {
+ case 'p':
+ {
+ char *p = optarg;
+
+ if (strlen(p) >= MAX_PASSPHRASE_SIZE) {
+ printf("Max length:%d bytes.\n",
+ MAX_PASSPHRASE_SIZE-1);
+ exit(1);
+ }
+ strcpy(in_passphrase, p);
+ has_passphrase = 1;
+ }
+ break;
+ case 'h':
+ default:
+ help();
+ exit(1);
+ }
+ }
+
+ /* No passphrase specified, probe from user... */
+ if (!has_passphrase) {
+ printf("Enter passphrase (echo disabled): ");
+ get_passphrase(in_passphrase, sizeof(in_passphrase));
+ }
+
+ if (key_derive_from_passphrase(in_passphrase))
+ exit(1);
+
+ return 0;
+}
--
2.7.4
The encryption helper functions are installed into hibernation
framework for later use.
Suggested-by: Rafael J. Wysocki <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: Len Brown <[email protected]>
Cc: "Lee, Chun-Yi" <[email protected]>
Cc: Eric Biggers <[email protected]>
Cc: "Theodore Ts'o" <[email protected]>
Cc: Stephan Mueller <[email protected]>
Cc: Denis Kenzior <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Chen Yu <[email protected]>
---
include/linux/suspend.h | 40 +++++++++++++++++++++++
kernel/power/crypto_hibernation.c | 10 ++++++
kernel/power/hibernate.c | 67 +++++++++++++++++++++++++++++++++++++++
kernel/power/power.h | 2 ++
4 files changed, 119 insertions(+)
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 440b62f..b45a857 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -391,6 +391,46 @@ extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
extern int hibernate(void);
extern bool system_entering_hibernation(void);
extern bool hibernation_available(void);
+#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION)
+struct hibernation_crypto_ops {
+ int (*crypto_data)(
+ const char *inbuf, int inlen,
+ char *outbuf, int outlen,
+ unsigned int cmd,
+ int page_idx);
+ void (*save)(void *buf);
+ void (*restore)(void *buf);
+ int (*init)(bool suspend);
+};
+
+extern void hibernation_set_crypto_ops(
+ const struct hibernation_crypto_ops *ops);
+extern int hibernation_crypto_data(
+ const char *inbuf,
+ int inlen,
+ char *outbuf,
+ int outlen,
+ unsigned int cmd,
+ int page_idx);
+extern void hibernation_crypto_save(void *outbuf);
+extern void hibernation_crypto_restore(void *inbuf);
+extern int hibernation_crypto_init(bool suspend);
+extern int hibernation_crypto_mode;
+#else
+static inline int hibernation_crypto_data(
+ const char *inbuf,
+ int inlen,
+ char *outbuf,
+ int outlen,
+ unsigned int cmd,
+ int page_idx) { return 0; }
+static inline void hibernation_crypto_save(void *outbuf) {}
+static inline void hibernation_crypto_restore(void *inbuf) {}
+static inline int hibernation_crypto_init(bool suspend)
+{
+ return 0;
+}
+#endif
asmlinkage int swsusp_save(void);
extern struct pbe *restore_pblist;
#else /* CONFIG_HIBERNATION */
diff --git a/kernel/power/crypto_hibernation.c b/kernel/power/crypto_hibernation.c
index 406bb0c..845eb54 100644
--- a/kernel/power/crypto_hibernation.c
+++ b/kernel/power/crypto_hibernation.c
@@ -36,6 +36,7 @@
#include <linux/moduleparam.h>
#include <linux/cdev.h>
#include <linux/major.h>
+#include <linux/suspend.h>
#include <crypto/skcipher.h>
#include <crypto/akcipher.h>
#include <crypto/aes.h>
@@ -288,6 +289,13 @@ static int crypto_init(bool suspend)
return 0;
}
+static const struct hibernation_crypto_ops crypto_ops = {
+ .crypto_data = crypto_data,
+ .save = crypto_save,
+ .restore = crypto_restore,
+ .init = crypto_init,
+};
+
/* key/salt probing via ioctl. */
dev_t crypto_dev;
static struct class *crypto_dev_class;
@@ -384,6 +392,8 @@ static int crypto_hibernate_init(void)
/* generate the random salt */
get_random_bytes(get_salt_ptr(), HIBERNATE_MAX_SALT_BYTES);
+ hibernation_set_crypto_ops(&crypto_ops);
+
return 0;
r_device:
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 9c85c78..a9e82f8 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -59,6 +59,16 @@ enum {
/* keep last */
__HIBERNATION_AFTER_LAST
};
+
+#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION)
+enum {
+ HIBERNATION_ENCRYPT,
+ HIBERNATION_SIGNATURE,
+ HIBERNATION_ENCRYPT_SIGNATURE,
+};
+int hibernation_crypto_mode = HIBERNATION_ENCRYPT;
+#endif
+
#define HIBERNATION_MAX (__HIBERNATION_AFTER_LAST-1)
#define HIBERNATION_FIRST (HIBERNATION_INVALID + 1)
@@ -96,6 +106,63 @@ void hibernation_set_ops(const struct platform_hibernation_ops *ops)
}
EXPORT_SYMBOL_GPL(hibernation_set_ops);
+#if IS_ENABLED(CONFIG_CRYPTO_HIBERNATION)
+/* Install encryption/decryption/signature hooks. */
+static const struct hibernation_crypto_ops *hibernation_crypto_ops;
+
+void hibernation_set_crypto_ops(const struct hibernation_crypto_ops *ops)
+{
+ hibernation_crypto_ops = ops;
+}
+EXPORT_SYMBOL_GPL(hibernation_set_crypto_ops);
+
+int hibernation_crypto_data(
+ const char *inbuf,
+ int inlen,
+ char *outbuf,
+ int outlen,
+ unsigned int mode,
+ int page_idx)
+{
+ if (hibernation_crypto_ops &&
+ hibernation_crypto_ops->crypto_data)
+ return hibernation_crypto_ops->crypto_data(inbuf,
+ inlen, outbuf, outlen, mode, page_idx);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(hibernation_crypto_data);
+
+/* Invoked before hibernate. */
+void hibernation_crypto_save(void *outbuf)
+{
+ if (hibernation_crypto_ops &&
+ hibernation_crypto_ops->save)
+ hibernation_crypto_ops->save(outbuf);
+}
+EXPORT_SYMBOL_GPL(hibernation_crypto_save);
+
+/* Invoked before resumed. */
+void hibernation_crypto_restore(void *inbuf)
+{
+ if (hibernation_crypto_ops &&
+ hibernation_crypto_ops->restore)
+ hibernation_crypto_ops->restore(inbuf);
+}
+EXPORT_SYMBOL_GPL(hibernation_crypto_restore);
+
+/* Initialization for crypto helper facilities. */
+int hibernation_crypto_init(bool suspend)
+{
+ if (hibernation_crypto_ops &&
+ hibernation_crypto_ops->init)
+ return hibernation_crypto_ops->init(suspend);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(hibernation_crypto_init);
+
+#endif
static bool entering_platform_hibernation;
bool system_entering_hibernation(void)
diff --git a/kernel/power/power.h b/kernel/power/power.h
index a539bdb..ba3b24c 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -107,6 +107,8 @@ struct hibernation_crypto {
struct hibernation_crypto_keys keys;
};
+extern void hibernation_set_crypto_ops(
+ const struct hibernation_crypto_ops *ops);
#else
#define HIBERNATE_MAX_SALT_BYTES 0
#endif
--
2.7.4
On Thu 2018-07-19 00:38:06, Chen Yu wrote:
> As security becomes more and more important, we add the in-kernel
> encryption support for hibernation.
Sorry, this does not really explain what security benefit it is
supposed have to against what attack scenarios.
Which unfortunately means it can not reviewed.
Note that uswsusp already provides encryption. If this is supposed to
have advantages over it, please say so.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi,
On Wed, Jul 18, 2018 at 10:22:35PM +0200, Pavel Machek wrote:
> On Thu 2018-07-19 00:38:06, Chen Yu wrote:
> > As security becomes more and more important, we add the in-kernel
> > encryption support for hibernation.
>
> Sorry, this does not really explain what security benefit it is
> supposed have to against what attack scenarios.
>
> Which unfortunately means it can not reviewed.
>
> Note that uswsusp already provides encryption. If this is supposed to
> have advantages over it, please say so.
>
The advantages are described in detail in
[PATCH 1/4]'s log, please refer to that.
Thanks,
Yu
> Pavel
>
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Thu 2018-07-19 07:58:51, Yu Chen wrote:
> Hi,
> On Wed, Jul 18, 2018 at 10:22:35PM +0200, Pavel Machek wrote:
> > On Thu 2018-07-19 00:38:06, Chen Yu wrote:
> > > As security becomes more and more important, we add the in-kernel
> > > encryption support for hibernation.
> >
> > Sorry, this does not really explain what security benefit it is
> > supposed have to against what attack scenarios.
> >
> > Which unfortunately means it can not reviewed.
> >
> > Note that uswsusp already provides encryption. If this is supposed to
> > have advantages over it, please say so.
> >
> The advantages are described in detail in
> [PATCH 1/4]'s log, please refer to that.
Are you refering to this?
# Generally the advantage is: Users do not have to
# encrypt the whole swap partition as other tools.
# After all, ideally kernel memory should be encrypted
# by the kernel itself.
Sorry, this does not really explain what security benefit it is
supposed have to against what attack scenarios.
Note that uswsusp already provides encryption. If this is supposed to
have advantages over it, please say so.
Also note that joeyli <[email protected]> has patch series which encrypts
both in-kernel and uswsusp hibernation methods. His motivation is
secure boot. How does this compare to his work?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Thu, Jul 19, 2018 at 01:01:49PM +0200, Pavel Machek wrote:
> On Thu 2018-07-19 07:58:51, Yu Chen wrote:
> > Hi,
> > On Wed, Jul 18, 2018 at 10:22:35PM +0200, Pavel Machek wrote:
> > > On Thu 2018-07-19 00:38:06, Chen Yu wrote:
> > > > As security becomes more and more important, we add the in-kernel
> > > > encryption support for hibernation.
> > >
> > > Sorry, this does not really explain what security benefit it is
> > > supposed have to against what attack scenarios.
> > >
> > > Which unfortunately means it can not reviewed.
> > >
> > > Note that uswsusp already provides encryption. If this is supposed to
> > > have advantages over it, please say so.
> > >
> > The advantages are described in detail in
> > [PATCH 1/4]'s log, please refer to that.
>
> Are you refering to this?
>
Not this one. I've sent v2 of this patch set which
explain more on this:
https://patchwork.kernel.org/patch/10532935/
Let me paste the log here:
1. (This is not to compare with uswsusp but other
tools) One advantage is: Users do not have to
encrypt the whole swap partition as other tools.
2. Ideally kernel memory should be encrypted by the
kernel itself. We have uswsusp to support user
space hibernation, however doing the encryption
in kernel space has more advantages:
2.1 Not having to transfer plain text kernel memory to
user space. Per Lee, Chun-Yi, uswsusp is disabled
when the kernel is locked down:
https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
linux-fs.git/commit/?h=lockdown-20180410&
id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
due to:
"There have some functions be locked-down because
there have no appropriate mechanisms to check the
integrity of writing data."
https://patchwork.kernel.org/patch/10476751/
2.2 Not having to copy each page to user space
one by one not in parallel, which might introduce
significant amount of copy_to_user() and it might
not be efficient on servers having large amount of DRAM.
2.3 Distribution has requirement to do snapshot
signature for verification, which can be built
by leveraging this patch set.
2.4 The encryption is in the kernel, so it doesn't
have to worry too much about bugs in user space
utilities and similar, for example.
> # Generally the advantage is: Users do not have to
> # encrypt the whole swap partition as other tools.
> # After all, ideally kernel memory should be encrypted
> # by the kernel itself.
>
> Sorry, this does not really explain what security benefit it is
> supposed have to against what attack scenarios.
>
> Note that uswsusp already provides encryption. If this is supposed to
> have advantages over it, please say so.
>
> Also note that joeyli <[email protected]> has patch series which encrypts
> both in-kernel and uswsusp hibernation methods. His motivation is
> secure boot. How does this compare to his work?
>
Joey Lee and I had a discussion on his previous work at
https://patchwork.kernel.org/patch/10476751
We collaborate on this task and his snapshot signature
feature can be based on this patch set.
Thanks,
Yu
Hi,
On Thu, Jul 19, 2018 at 01:01:49PM +0200, Pavel Machek wrote:
> On Thu 2018-07-19 07:58:51, Yu Chen wrote:
> > Hi,
> > On Wed, Jul 18, 2018 at 10:22:35PM +0200, Pavel Machek wrote:
> > > On Thu 2018-07-19 00:38:06, Chen Yu wrote:
> > > > As security becomes more and more important, we add the in-kernel
> > > > encryption support for hibernation.
> > >
> > > Sorry, this does not really explain what security benefit it is
> > > supposed have to against what attack scenarios.
> > >
> > > Which unfortunately means it can not reviewed.
> > >
> > > Note that uswsusp already provides encryption. If this is supposed to
> > > have advantages over it, please say so.
> > >
> > The advantages are described in detail in
> > [PATCH 1/4]'s log, please refer to that.
>
> Are you refering to this?
>
> # Generally the advantage is: Users do not have to
> # encrypt the whole swap partition as other tools.
> # After all, ideally kernel memory should be encrypted
> # by the kernel itself.
>
> Sorry, this does not really explain what security benefit it is
> supposed have to against what attack scenarios.
>
> Note that uswsusp already provides encryption. If this is supposed to
> have advantages over it, please say so.
>
> Also note that joeyli <[email protected]> has patch series which encrypts
> both in-kernel and uswsusp hibernation methods. His motivation is
> secure boot. How does this compare to his work?
>
My patchset signs and encrypts the snapshot image pages in memory. The
main logic is applied to snapshot.c
https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
The pros of my solution is that the signed/encrypted snapshot image can
be stored to anywhere. Both in-kernel and userspace.
Yu's patch is encrypt the page buffer before sending to block io layer
for writing to swap. The main logic is applied to swap.c. It's against
the swap solution in-kernel.
The pros of Yu's solution is that it encrypts the compressed image data.
So, for the huge system memory case, it has better performance.
Yu's plan is using the sysfs to switch different encrypt/sign solutions.
And, we will share encrypt/sign helper and key manager in the above two
solutions.
Thanks a lot!
Joey Lee
Hi!
> > > > > As security becomes more and more important, we add the in-kernel
> > > > > encryption support for hibernation.
> > > >
> > > > Sorry, this does not really explain what security benefit it is
> > > > supposed have to against what attack scenarios.
> > > >
> > > > Which unfortunately means it can not reviewed.
> > > >
> > > > Note that uswsusp already provides encryption. If this is supposed to
> > > > have advantages over it, please say so.
> > > >
> > > The advantages are described in detail in
> > > [PATCH 1/4]'s log, please refer to that.
> >
> > Are you refering to this?
> >
> Not this one. I've sent v2 of this patch set which
> explain more on this:
> https://patchwork.kernel.org/patch/10532935/
Aha, sorry about that.
> Let me paste the log here:
>
> 1. (This is not to compare with uswsusp but other
> tools) One advantage is: Users do not have to
> encrypt the whole swap partition as other tools.
Well.. encrypting the partition seems like good idea anyway.
> 2. Ideally kernel memory should be encrypted by the
> kernel itself. We have uswsusp to support user
> space hibernation, however doing the encryption
> in kernel space has more advantages:
> 2.1 Not having to transfer plain text kernel memory to
> user space. Per Lee, Chun-Yi, uswsusp is disabled
> when the kernel is locked down:
> https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> linux-fs.git/commit/?h=lockdown-20180410&
> id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> due to:
> "There have some functions be locked-down because
> there have no appropriate mechanisms to check the
> integrity of writing data."
> https://patchwork.kernel.org/patch/10476751/
So your goal is to make hibernation compatible with kernel
lockdown? Do your patches provide sufficient security that hibernation
can be enabled with kernel lockdown?
> 2.2 Not having to copy each page to user space
> one by one not in parallel, which might introduce
> significant amount of copy_to_user() and it might
> not be efficient on servers having large amount of DRAM.
So how big speedup can be attributed by not doing copy_to_user?
> 2.3 Distribution has requirement to do snapshot
> signature for verification, which can be built
> by leveraging this patch set.
Signatures can be done by uswsusp, too, right?
> 2.4 The encryption is in the kernel, so it doesn't
> have to worry too much about bugs in user space
> utilities and similar, for example.
Answer to bugs in userspace is _not_ to move code from userspace to kernel.
> > Also note that joeyli <[email protected]> has patch series which encrypts
> > both in-kernel and uswsusp hibernation methods. His motivation is
> > secure boot. How does this compare to his work?
> >
> Joey Lee and I had a discussion on his previous work at
> https://patchwork.kernel.org/patch/10476751
> We collaborate on this task and his snapshot signature
> feature can be based on this patch set.
Well, his work can also work without your patchset, right?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Fr, 2018-07-20 at 12:25 +0200, Pavel Machek wrote:
> Hi!
Hello,
> > Let me paste the log here:
> >
> > 1. (This is not to compare with uswsusp but other
> > tools) One advantage is: Users do not have to
> > encrypt the whole swap partition as other tools.
>
> Well.. encrypting the partition seems like good idea anyway.
Yes, but it is a policy decision the kernel should not force.
STD needs to work anyway.
> > 2. Ideally kernel memory should be encrypted by the
> > kernel itself. We have uswsusp to support user
> > space hibernation, however doing the encryption
> > in kernel space has more advantages:
> > 2.1 Not having to transfer plain text kernel memory to
> > user space. Per Lee, Chun-Yi, uswsusp is disabled
> > when the kernel is locked down:
> > https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> > linux-fs.git/commit/?h=lockdown-20180410&
> > id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> > due to:
> > "There have some functions be locked-down because
> > there have no appropriate mechanisms to check the
> > integrity of writing data."
> > https://patchwork.kernel.org/patch/10476751/
>
> So your goal is to make hibernation compatible with kernel
> lockdown? Do your patches provide sufficient security that hibernation
> can be enabled with kernel lockdown?
OK, maybe I am dense, but if the key comes from user space, will that
be enough?
> > 2.2 Not having to copy each page to user space
> > one by one not in parallel, which might introduce
> > significant amount of copy_to_user() and it might
> > not be efficient on servers having large amount of DRAM.
>
> So how big speedup can be attributed by not doing copy_to_user?
That would be an argument for compression in kernel space.
Not encrpting would always be faster.
> > 2.3 Distribution has requirement to do snapshot
> > signature for verification, which can be built
> > by leveraging this patch set.
>
> Signatures can be done by uswsusp, too, right?
Not if you want to keep the chain of trust intact. User space
is not signed.
> > 2.4 The encryption is in the kernel, so it doesn't
> > have to worry too much about bugs in user space
> > utilities and similar, for example.
>
> Answer to bugs in userspace is _not_ to move code from userspace to kernel.
Indeed.
> > Joey Lee and I had a discussion on his previous work at
> > https://patchwork.kernel.org/patch/10476751
> > We collaborate on this task and his snapshot signature
> > feature can be based on this patch set.
>
> Well, his work can also work without your patchset, right?
Yes. But you are objecting to encryption in kernel space at all,
aren't you?
Regards
Oliver
Hi!
> > > 2. Ideally kernel memory should be encrypted by the
> > > kernel itself. We have uswsusp to support user
> > > space hibernation, however doing the encryption
> > > in kernel space has more advantages:
> > > 2.1 Not having to transfer plain text kernel memory to
> > > user space. Per Lee, Chun-Yi, uswsusp is disabled
> > > when the kernel is locked down:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> > > linux-fs.git/commit/?h=lockdown-20180410&
> > > id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> > > due to:
> > > "There have some functions be locked-down because
> > > there have no appropriate mechanisms to check the
> > > integrity of writing data."
> > > https://patchwork.kernel.org/patch/10476751/
> >
> > So your goal is to make hibernation compatible with kernel
> > lockdown? Do your patches provide sufficient security that hibernation
> > can be enabled with kernel lockdown?
>
> OK, maybe I am dense, but if the key comes from user space, will that
> be enough?
Yes, that seems to be one of problems of Yu Chen's patchset.
> > > Joey Lee and I had a discussion on his previous work at
> > > https://patchwork.kernel.org/patch/10476751
> > > We collaborate on this task and his snapshot signature
> > > feature can be based on this patch set.
> >
> > Well, his work can also work without your patchset, right?
>
> Yes. But you are objecting to encryption in kernel space at all,
> aren't you?
I don't particulary love the idea of doing hibernation encryption in
the kernel, correct.
But we have this weird thing called secure boot, some people seem to
want. So we may need some crypto in the kernel -- but I'd like
something that works with uswsusp, too. Plus, it is mandatory that
patch explains what security guarantees they want to provide against
what kinds of attacks...
Lee, Chun-Yi's patch seemed more promising. Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi,
On Mon, Jul 23, 2018 at 01:42:36PM +0200, Oliver Neukum wrote:
> On Fr, 2018-07-20 at 12:25 +0200, Pavel Machek wrote:
> > Hi!
>
> Hello,
>
> > > Let me paste the log here:
> > >
> > > 1. (This is not to compare with uswsusp but other
> > > tools) One advantage is: Users do not have to
> > > encrypt the whole swap partition as other tools.
> >
> > Well.. encrypting the partition seems like good idea anyway.
>
> Yes, but it is a policy decision the kernel should not force.
> STD needs to work anyway.
>
If the swap partition is too large, and there's low usage
of memory, then it might a little time costly to encrypt
the whole partition. You are right, people has choice to
choose which mode they like.
> > > 2. Ideally kernel memory should be encrypted by the
> > > kernel itself. We have uswsusp to support user
> > > space hibernation, however doing the encryption
> > > in kernel space has more advantages:
> > > 2.1 Not having to transfer plain text kernel memory to
> > > user space. Per Lee, Chun-Yi, uswsusp is disabled
> > > when the kernel is locked down:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> > > linux-fs.git/commit/?h=lockdown-20180410&
> > > id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> > > due to:
> > > "There have some functions be locked-down because
> > > there have no appropriate mechanisms to check the
> > > integrity of writing data."
> > > https://patchwork.kernel.org/patch/10476751/
> >
> > So your goal is to make hibernation compatible with kernel
> > lockdown? Do your patches provide sufficient security that hibernation
> > can be enabled with kernel lockdown?
>
> OK, maybe I am dense, but if the key comes from user space, will that
> be enough?
>
Good point, we once tried to generate key in kernel, but people
suggest to generate key in userspace and provide it to the
kernel, which is what ecryptfs do currently, so it seems this
should also be safe for encryption in kernel.
https://www.spinics.net/lists/linux-crypto/msg33145.html
Thus Chun-Yi's signature can use EFI key and both the key from
user space.
Best,
Yu
> > > 2.2 Not having to copy each page to user space
> > > one by one not in parallel, which might introduce
> > > significant amount of copy_to_user() and it might
> > > not be efficient on servers having large amount of DRAM.
> >
> > So how big speedup can be attributed by not doing copy_to_user?
>
> That would be an argument for compression in kernel space.
> Not encrpting would always be faster.
>
> > > 2.3 Distribution has requirement to do snapshot
> > > signature for verification, which can be built
> > > by leveraging this patch set.
> >
> > Signatures can be done by uswsusp, too, right?
>
> Not if you want to keep the chain of trust intact. User space
> is not signed.
>
> > > 2.4 The encryption is in the kernel, so it doesn't
> > > have to worry too much about bugs in user space
> > > utilities and similar, for example.
> >
> > Answer to bugs in userspace is _not_ to move code from userspace to kernel.
>
> Indeed.
>
> > > Joey Lee and I had a discussion on his previous work at
> > > https://patchwork.kernel.org/patch/10476751
> > > We collaborate on this task and his snapshot signature
> > > feature can be based on this patch set.
> >
> > Well, his work can also work without your patchset, right?
>
> Yes. But you are objecting to encryption in kernel space at all,
> aren't you?
>
> Regards
> Oliver
>
Hello,
On Mon, Jul 23, 2018 at 02:22:27PM +0200, Pavel Machek wrote:
> Hi!
>
> > > > 2. Ideally kernel memory should be encrypted by the
> > > > kernel itself. We have uswsusp to support user
> > > > space hibernation, however doing the encryption
> > > > in kernel space has more advantages:
> > > > 2.1 Not having to transfer plain text kernel memory to
> > > > user space. Per Lee, Chun-Yi, uswsusp is disabled
> > > > when the kernel is locked down:
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> > > > linux-fs.git/commit/?h=lockdown-20180410&
> > > > id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> > > > due to:
> > > > "There have some functions be locked-down because
> > > > there have no appropriate mechanisms to check the
> > > > integrity of writing data."
> > > > https://patchwork.kernel.org/patch/10476751/
> > >
> > > So your goal is to make hibernation compatible with kernel
> > > lockdown? Do your patches provide sufficient security that hibernation
> > > can be enabled with kernel lockdown?
> >
> > OK, maybe I am dense, but if the key comes from user space, will that
> > be enough?
>
> Yes, that seems to be one of problems of Yu Chen's patchset.
>
It is a trade off to derive the key in user space, we once
tried to derive the key in user space, and people suggested
a better way is to do it in user space. And there is a similar
user case of kernel using key from user space is derived from ecryptfs
for ext4.
> > > > Joey Lee and I had a discussion on his previous work at
> > > > https://patchwork.kernel.org/patch/10476751
> > > > We collaborate on this task and his snapshot signature
> > > > feature can be based on this patch set.
> > >
> > > Well, his work can also work without your patchset, right?
> >
> > Yes. But you are objecting to encryption in kernel space at all,
> > aren't you?
>
> I don't particulary love the idea of doing hibernation encryption in
> the kernel, correct.
>
> But we have this weird thing called secure boot, some people seem to
> want. So we may need some crypto in the kernel -- but I'd like
> something that works with uswsusp, too. Plus, it is mandatory that
> patch explains what security guarantees they want to provide against
> what kinds of attacks...
>
> Lee, Chun-Yi's patch seemed more promising. Pavel
>
The only difference between Chun-Yi's hibernation encrytion solution
and our solution is that his strategy encrypts the snapshot from sratch,
and ours encryts each page before them going to block device. The benefit
of his solution is that the snapshot can be encrypt in kernel first
thus the uswsusp is allowed to read it to user space even kernel
is lock down. And I had a discussion with Chun-Yi that we can use
his snapshot solution to make uswsusp happy, and we share the crypto
help code and he can also use our user provided key for his signature.
From this point of view, our code are actually the same, except that
we can help clean up the code and also enhance some encrytion process
for his solution. I don't know why you don't like encryption in kernel,
because from my point of view, without encryption hibernation in kernel,
uswsusp could not be enabled if kernel is lock down : -) Or do I miss something?
Best,
Yu
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> Hi,
> On Mon, Jul 23, 2018 at 01:42:36PM +0200, Oliver Neukum wrote:
> > On Fr, 2018-07-20 at 12:25 +0200, Pavel Machek wrote:
> > > So your goal is to make hibernation compatible with kernel
> > > lockdown? Do your patches provide sufficient security that hibernation
> > > can be enabled with kernel lockdown?
> >
> > OK, maybe I am dense, but if the key comes from user space, will that
> > be enough?
> >
>
> Good point, we once tried to generate key in kernel, but people
> suggest to generate key in userspace and provide it to the
> kernel, which is what ecryptfs do currently, so it seems this
> should also be safe for encryption in kernel.
> https://www.spinics.net/lists/linux-crypto/msg33145.html
> Thus Chun-Yi's signature can use EFI key and both the key from
> user space.
It seems to me that your initial reasoning was correct and the key
should be generated in kernel space.
Regards
Oliver
On Mo, 2018-07-23 at 14:22 +0200, Pavel Machek wrote:
> > Yes. But you are objecting to encryption in kernel space at all,
> > aren't you?
>
> I don't particulary love the idea of doing hibernation encryption in
> the kernel, correct.
>
> But we have this weird thing called secure boot, some people seem to
> want. So we may need some crypto in the kernel -- but I'd like
> something that works with uswsusp, too. Plus, it is mandatory that
> patch explains what security guarantees they want to provide against
> what kinds of attacks...
Hi,
very well, maybe we should state clearly that the goal of these
patch set is to make Secure Boot and STD coexist. Anything else
is a nice side effect, but not the primary justification, right?
And we further agree that the model of Secure Boot requires the
encryption to be done in kernel space, don't we?
Furthermore IMHO the key must also be generated in trusted code,
hence in kernel space. Yu Chen, I really cannot see how
a symmetrical encryption with a known key can be secure.
Regards
Oliver
Hi!
> > > > "There have some functions be locked-down because
> > > > there have no appropriate mechanisms to check the
> > > > integrity of writing data."
> > > > https://patchwork.kernel.org/patch/10476751/
> > >
> > > So your goal is to make hibernation compatible with kernel
> > > lockdown? Do your patches provide sufficient security that hibernation
> > > can be enabled with kernel lockdown?
> >
> > OK, maybe I am dense, but if the key comes from user space, will that
> > be enough?
> >
> Good point, we once tried to generate key in kernel, but people
> suggest to generate key in userspace and provide it to the
> kernel, which is what ecryptfs do currently, so it seems this
> should also be safe for encryption in kernel.
Safe against what kind of attack? Please describe what kind of
security you are trying to provide.
I don't think generating key in userspace is good enough for providing
guarantees for secure-boot.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi!
> > > Yes. But you are objecting to encryption in kernel space at all,
> > > aren't you?
> >
> > I don't particulary love the idea of doing hibernation encryption in
> > the kernel, correct.
> >
> > But we have this weird thing called secure boot, some people seem to
> > want. So we may need some crypto in the kernel -- but I'd like
> > something that works with uswsusp, too. Plus, it is mandatory that
> > patch explains what security guarantees they want to provide against
> > what kinds of attacks...
> >
> > Lee, Chun-Yi's patch seemed more promising. Pavel
> >
> The only difference between Chun-Yi's hibernation encrytion solution
> and our solution is that his strategy encrypts the snapshot from sratch,
> and ours encryts each page before them going to block device. The benefit
> of his solution is that the snapshot can be encrypt in kernel first
> thus the uswsusp is allowed to read it to user space even kernel
> is lock down. And I had a discussion with Chun-Yi that we can use
> his snapshot solution to make uswsusp happy, and we share the crypto
> help code and he can also use our user provided key for his signature.
> >From this point of view, our code are actually the same, except that
> we can help clean up the code and also enhance some encrytion process
> for his solution. I don't know why you don't like encryption in kernel,
> because from my point of view, without encryption hibernation in kernel,
> uswsusp could not be enabled if kernel is lock down : -) Or do I miss something?
We can do encryption in kernel if really needed, but I don't have to
like it, do I? :-).
I understand what Chun-Yi's code is trying to do. I can't say the same
about yours.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Di, 2018-07-24 at 14:01 +0200, Pavel Machek wrote:
> Hi!
>
> > > > > "There have some functions be locked-down because
> > > > > there have no appropriate mechanisms to check the
> > > > > integrity of writing data."
> > > > > https://patchwork.kernel.org/patch/10476751/
> > > >
> > > > So your goal is to make hibernation compatible with kernel
> > > > lockdown? Do your patches provide sufficient security that hibernation
> > > > can be enabled with kernel lockdown?
> > >
> > > OK, maybe I am dense, but if the key comes from user space, will that
> > > be enough?
> > >
> >
> > Good point, we once tried to generate key in kernel, but people
> > suggest to generate key in userspace and provide it to the
> > kernel, which is what ecryptfs do currently, so it seems this
> > should also be safe for encryption in kernel.
>
> Safe against what kind of attack? Please describe what kind of
> security you are trying to provide.
Unsigned code must not take over the priviledge level of signed code.
Hence:
1. Unsigned code must not allowed to read sensitive parts of signed
code's memory space
2. Unsigned code must not be able to alter the memory space of
signed code -> snapshots that are changed must not be able to be
resumed
> I don't think generating key in userspace is good enough for providing
> guarantees for secure-boot.
Why?
Regards
Oliver
On Tue 2018-07-24 14:47:54, Oliver Neukum wrote:
> On Di, 2018-07-24 at 14:01 +0200, Pavel Machek wrote:
> > Hi!
> >
> > > > > > "There have some functions be locked-down because
> > > > > > there have no appropriate mechanisms to check the
> > > > > > integrity of writing data."
> > > > > > https://patchwork.kernel.org/patch/10476751/
> > > > >
> > > > > So your goal is to make hibernation compatible with kernel
> > > > > lockdown? Do your patches provide sufficient security that hibernation
> > > > > can be enabled with kernel lockdown?
> > > >
> > > > OK, maybe I am dense, but if the key comes from user space, will that
> > > > be enough?
> > > >
> > >
> > > Good point, we once tried to generate key in kernel, but people
> > > suggest to generate key in userspace and provide it to the
> > > kernel, which is what ecryptfs do currently, so it seems this
> > > should also be safe for encryption in kernel.
> >
> > Safe against what kind of attack? Please describe what kind of
> > security you are trying to provide.
>
> Unsigned code must not take over the priviledge level of signed code.
> Hence:
>
> 1. Unsigned code must not allowed to read sensitive parts of signed
> code's memory space
>
> 2. Unsigned code must not be able to alter the memory space of
> signed code -> snapshots that are changed must not be able to be
> resumed
Ok.
> > I don't think generating key in userspace is good enough for providing
> > guarantees for secure-boot.
>
> Why?
Because then, userpace has both key (now) and encrypted image (after
reboot), so it can decrypt, modify, re-encrypt...?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Tue 2018-07-24 13:49:41, Oliver Neukum wrote:
> On Mo, 2018-07-23 at 14:22 +0200, Pavel Machek wrote:
>
> > > Yes. But you are objecting to encryption in kernel space at all,
> > > aren't you?
> >
> > I don't particulary love the idea of doing hibernation encryption in
> > the kernel, correct.
> >
> > But we have this weird thing called secure boot, some people seem to
> > want. So we may need some crypto in the kernel -- but I'd like
> > something that works with uswsusp, too. Plus, it is mandatory that
> > patch explains what security guarantees they want to provide against
> > what kinds of attacks...
>
> Hi,
>
> very well, maybe we should state clearly that the goal of these
> patch set is to make Secure Boot and STD coexist. Anything else
> is a nice side effect, but not the primary justification, right?
>
> And we further agree that the model of Secure Boot requires the
> encryption to be done in kernel space, don't we?
> Furthermore IMHO the key must also be generated in trusted code,
> hence in kernel space. Yu Chen, I really cannot see how
> a symmetrical encryption with a known key can be secure.
Nicely said. Yes, this is the message I was trying to get across.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Di, 2018-07-24 at 15:03 +0200, Pavel Machek wrote:
> On Tue 2018-07-24 14:47:54, Oliver Neukum wrote:
> > On Di, 2018-07-24 at 14:01 +0200, Pavel Machek wrote:
Hi,
> > > Safe against what kind of attack? Please describe what kind of
> > > security you are trying to provide.
> >
> > Unsigned code must not take over the priviledge level of signed code.
> > Hence:
> >
> > 1. Unsigned code must not allowed to read sensitive parts of signed
> > code's memory space
> >
> > 2. Unsigned code must not be able to alter the memory space of
> > signed code -> snapshots that are changed must not be able to be
> > resumed
>
> Ok.
>
> > > I don't think generating key in userspace is good enough for providing
> > > guarantees for secure-boot.
> >
> > Why?
>
> Because then, userpace has both key (now) and encrypted image (after
> reboot), so it can decrypt, modify, re-encrypt...?
Right. I was dense. But if the key is generated in kernel space,
the method works, doesn't it?
Regards
Oliver
Hi Oliver,
On Mon, Jul 23, 2018 at 01:42:36PM +0200, Oliver Neukum wrote:
> On Fr, 2018-07-20 at 12:25 +0200, Pavel Machek wrote:
> > Hi!
>
> Hello,
>
> > > Let me paste the log here:
> > >
> > > 1. (This is not to compare with uswsusp but other
> > > tools) One advantage is: Users do not have to
> > > encrypt the whole swap partition as other tools.
> >
> > Well.. encrypting the partition seems like good idea anyway.
>
> Yes, but it is a policy decision the kernel should not force.
> STD needs to work anyway.
>
> > > 2. Ideally kernel memory should be encrypted by the
> > > kernel itself. We have uswsusp to support user
> > > space hibernation, however doing the encryption
> > > in kernel space has more advantages:
> > > 2.1 Not having to transfer plain text kernel memory to
> > > user space. Per Lee, Chun-Yi, uswsusp is disabled
> > > when the kernel is locked down:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/
> > > linux-fs.git/commit/?h=lockdown-20180410&
> > > id=8732c1663d7c0305ae01ba5a1ee4d2299b7b4612
> > > due to:
> > > "There have some functions be locked-down because
> > > there have no appropriate mechanisms to check the
> > > integrity of writing data."
> > > https://patchwork.kernel.org/patch/10476751/
> >
> > So your goal is to make hibernation compatible with kernel
> > lockdown? Do your patches provide sufficient security that hibernation
> > can be enabled with kernel lockdown?
>
> OK, maybe I am dense, but if the key comes from user space, will that
> be enough?
>
> > > 2.2 Not having to copy each page to user space
> > > one by one not in parallel, which might introduce
> > > significant amount of copy_to_user() and it might
> > > not be efficient on servers having large amount of DRAM.
> >
> > So how big speedup can be attributed by not doing copy_to_user?
>
> That would be an argument for compression in kernel space.
> Not encrpting would always be faster.
>
> > > 2.3 Distribution has requirement to do snapshot
> > > signature for verification, which can be built
> > > by leveraging this patch set.
> >
> > Signatures can be done by uswsusp, too, right?
>
> Not if you want to keep the chain of trust intact. User space
> is not signed.
Yes, any user space key helper must be authenticated for secure boot
(or the kernel locked-down mode).
If user choices the user space helper, then they should awares that
this approach can not be trusted when kernel is in locked-down mode.
The user space helper be protected by IMA/EVM, or the initrd be
authentricated with trusted boot.
The user space key helper is useful when the machine doesn't have
TPM or EFI firmware, but user still wants to use the hibernation
encryption/verification.
For kernel locked-down mode, EFI key or trusted key TPM can be
trusted because they can only be created/visibled in kernel space.
Thanks
Joey Lee
On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
>
> Good point, we once tried to generate key in kernel, but people
> suggest to generate key in userspace and provide it to the
> kernel, which is what ecryptfs do currently, so it seems this
> should also be safe for encryption in kernel.
> https://www.spinics.net/lists/linux-crypto/msg33145.html
> Thus Chun-Yi's signature can use EFI key and both the key from
> user space.
Hi,
ecryptfs can trust user space. It is supposed to keep data
safe while the system is inoperative. The whole point of Secure
Boot is a cryptographic system of trust that does not include
user space.
I seriously doubt we want to use trusted computing here. So the
key needs to be generated in kernel space and stored in a safe
manner. As we have a saolution doing that, can we come to ausable
synthesis?
Regards
Oliver
On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> >
> > Good point, we once tried to generate key in kernel, but people
> > suggest to generate key in userspace and provide it to the
> > kernel, which is what ecryptfs do currently, so it seems this
> > should also be safe for encryption in kernel.
> > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > Thus Chun-Yi's signature can use EFI key and both the key from
> > user space.
>
> Hi,
>
> ecryptfs can trust user space. It is supposed to keep data
> safe while the system is inoperative. The whole point of Secure
> Boot is a cryptographic system of trust that does not include
> user space.
>
> I seriously doubt we want to use trusted computing here. So the
> key needs to be generated in kernel space and stored in a safe
> manner. As we have a saolution doing that, can we come to ausable
> synthesis?
>
> Regards
> Oliver
Crurently there have two solutions, they are trusted key and EFI key.
Both of them are generated in kernel and are not visible in user space.
The trusted key is generated by kernel then sealed by the TPM's
SRK. So the trusted key can be stored in anywhere then be enrolled
to kernel when we need it. EVM already uses it.
The EFI key is Jiri Kosina's idea. It is stored in boot services
variable, which means that it can only be access by signed EFI binary
(e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
this solution a couple of years.
I am working on put the EFI key to key retention service. Then
EFI key can be a master key of encrypted key. EVM can also use
it:
https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
That's why I want to use key retention service in hibernation
encryption/authentication. Which means that we can use key
API to access trusted key and EFI key.
Thanks
Joey Lee
Hi all,
On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > >
> > > Good point, we once tried to generate key in kernel, but people
> > > suggest to generate key in userspace and provide it to the
> > > kernel, which is what ecryptfs do currently, so it seems this
> > > should also be safe for encryption in kernel.
> > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > user space.
> >
> > Hi,
> >
> > ecryptfs can trust user space. It is supposed to keep data
> > safe while the system is inoperative. The whole point of Secure
> > Boot is a cryptographic system of trust that does not include
> > user space.
> >
> > I seriously doubt we want to use trusted computing here. So the
> > key needs to be generated in kernel space and stored in a safe
> > manner. As we have a saolution doing that, can we come to ausable
> > synthesis?
> >
> > Regards
> > Oliver
>
> Crurently there have two solutions, they are trusted key and EFI key.
> Both of them are generated in kernel and are not visible in user space.
>
> The trusted key is generated by kernel then sealed by the TPM's
> SRK. So the trusted key can be stored in anywhere then be enrolled
> to kernel when we need it. EVM already uses it.
>
> The EFI key is Jiri Kosina's idea. It is stored in boot services
> variable, which means that it can only be access by signed EFI binary
> (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> this solution a couple of years.
>
> I am working on put the EFI key to key retention service. Then
> EFI key can be a master key of encrypted key. EVM can also use
> it:
> https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
>
> That's why I want to use key retention service in hibernation
> encryption/authentication. Which means that we can use key
> API to access trusted key and EFI key.
>
Here is a proof of concept for using the key retention service
to encrypt/sign snapshot image. It's using EFI key now, I will
add encrypted key support in the key handler later:
https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
My next step is that cleaning up the my EFI key type patches and
submit it to EFI/keys subsystem ASAP. Then I will clean up
my hibernation encryption/authentication solution for reviewing.
Thanks
Joey Lee
Hi Joey,
On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> Hi all,
>
> On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > >
> > > > Good point, we once tried to generate key in kernel, but people
> > > > suggest to generate key in userspace and provide it to the
> > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > should also be safe for encryption in kernel.
> > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > user space.
> > >
> > > Hi,
> > >
> > > ecryptfs can trust user space. It is supposed to keep data
> > > safe while the system is inoperative. The whole point of Secure
> > > Boot is a cryptographic system of trust that does not include
> > > user space.
> > >
> > > I seriously doubt we want to use trusted computing here. So the
> > > key needs to be generated in kernel space and stored in a safe
> > > manner. As we have a saolution doing that, can we come to ausable
> > > synthesis?
> > >
> > > Regards
> > > Oliver
> >
> > Crurently there have two solutions, they are trusted key and EFI key.
> > Both of them are generated in kernel and are not visible in user space.
> >
> > The trusted key is generated by kernel then sealed by the TPM's
> > SRK. So the trusted key can be stored in anywhere then be enrolled
> > to kernel when we need it. EVM already uses it.
> >
> > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > variable, which means that it can only be access by signed EFI binary
> > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > this solution a couple of years.
> >
> > I am working on put the EFI key to key retention service. Then
> > EFI key can be a master key of encrypted key. EVM can also use
> > it:
> > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> >
> > That's why I want to use key retention service in hibernation
> > encryption/authentication. Which means that we can use key
> > API to access trusted key and EFI key.
> >
>
> Here is a proof of concept for using the key retention service
> to encrypt/sign snapshot image. It's using EFI key now, I will
> add encrypted key support in the key handler later:
> https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
>
Thanks for the work, I have two questions here:
1. Could you please describe a little more about the scenario on
how the user could use the secret key for hibernation encryption?
A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
during resume. I was thinking how user could interact with
the security key mechanism here.
2. The generation of secret key in EFI boot environment is
using a non standard derivation method in generate_secret_key(),
I'm not sure if this is safe enough. This is why we tried to put
PBKDF2 into kernel at first and leave it to the user space then.
Best,
Yu
> My next step is that cleaning up the my EFI key type patches and
> submit it to EFI/keys subsystem ASAP. Then I will clean up
> my hibernation encryption/authentication solution for reviewing.
>
> Thanks
> Joey Lee
On Fri, Aug 03, 2018 at 11:37:02AM +0800, Yu Chen wrote:
> Hi Joey,
> On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> > Hi all,
> >
> > On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > >
> > > > > Good point, we once tried to generate key in kernel, but people
> > > > > suggest to generate key in userspace and provide it to the
> > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > should also be safe for encryption in kernel.
> > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > user space.
> > > >
> > > > Hi,
> > > >
> > > > ecryptfs can trust user space. It is supposed to keep data
> > > > safe while the system is inoperative. The whole point of Secure
> > > > Boot is a cryptographic system of trust that does not include
> > > > user space.
> > > >
> > > > I seriously doubt we want to use trusted computing here. So the
> > > > key needs to be generated in kernel space and stored in a safe
> > > > manner. As we have a saolution doing that, can we come to ausable
> > > > synthesis?
> > > >
> > > > Regards
> > > > Oliver
> > >
> > > Crurently there have two solutions, they are trusted key and EFI key.
> > > Both of them are generated in kernel and are not visible in user space.
> > >
> > > The trusted key is generated by kernel then sealed by the TPM's
> > > SRK. So the trusted key can be stored in anywhere then be enrolled
> > > to kernel when we need it. EVM already uses it.
> > >
> > > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > > variable, which means that it can only be access by signed EFI binary
> > > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > > this solution a couple of years.
> > >
> > > I am working on put the EFI key to key retention service. Then
> > > EFI key can be a master key of encrypted key. EVM can also use
> > > it:
> > > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> > >
> > > That's why I want to use key retention service in hibernation
> > > encryption/authentication. Which means that we can use key
> > > API to access trusted key and EFI key.
> > >
> >
> > Here is a proof of concept for using the key retention service
> > to encrypt/sign snapshot image. It's using EFI key now, I will
> > add encrypted key support in the key handler later:
> > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
> >
> Thanks for the work, I have two questions here:
My EFI key patch set is almost done. I will send it soon.
> 1. Could you please describe a little more about the scenario on
> how the user could use the secret key for hibernation encryption?
> A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
> during resume. I was thinking how user could interact with
> the security key mechanism here.
>
User space doesn't need to involve. The EFI root key is generated by
EFI boot stub and be transfer to kernel. It's stored in EFI boot service
variable that it can only be accessed by trusted EFI binary when
secure boot is enabled.
> 2. The generation of secret key in EFI boot environment is
> using a non standard derivation method in generate_secret_key(),
> I'm not sure if this is safe enough. This is why we tried to put
> PBKDF2 into kernel at first and leave it to the user space then.
>
Thank you for point out.
The generate_secret_key() reuse the logic in kaslr_get_random_long()
that it produces random seed by RDRAND, RDTSC and i8254. It doesn't
standard like PBKDF2, but we do not have too many choices in the
early boot stage. At least KASLR is using the same logic.
We can relay on user space helper. But the helper must be authenticated
by kernel. Currently we do not have kernel mechanism to verity user
space process.
Regards
Joey Lee
On Fri, Aug 3, 2018 at 1:35 PM joeyli <[email protected]> wrote:
>
> On Fri, Aug 03, 2018 at 11:37:02AM +0800, Yu Chen wrote:
> > Hi Joey,
> > On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> > > Hi all,
> > >
> > > On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > > >
> > > > > > Good point, we once tried to generate key in kernel, but people
> > > > > > suggest to generate key in userspace and provide it to the
> > > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > > should also be safe for encryption in kernel.
> > > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > > user space.
> > > > >
> > > > > Hi,
> > > > >
> > > > > ecryptfs can trust user space. It is supposed to keep data
> > > > > safe while the system is inoperative. The whole point of Secure
> > > > > Boot is a cryptographic system of trust that does not include
> > > > > user space.
> > > > >
> > > > > I seriously doubt we want to use trusted computing here. So the
> > > > > key needs to be generated in kernel space and stored in a safe
> > > > > manner. As we have a saolution doing that, can we come to ausable
> > > > > synthesis?
> > > > >
> > > > > Regards
> > > > > Oliver
> > > >
> > > > Crurently there have two solutions, they are trusted key and EFI key.
> > > > Both of them are generated in kernel and are not visible in user space.
> > > >
> > > > The trusted key is generated by kernel then sealed by the TPM's
> > > > SRK. So the trusted key can be stored in anywhere then be enrolled
> > > > to kernel when we need it. EVM already uses it.
> > > >
> > > > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > > > variable, which means that it can only be access by signed EFI binary
> > > > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > > > this solution a couple of years.
> > > >
> > > > I am working on put the EFI key to key retention service. Then
> > > > EFI key can be a master key of encrypted key. EVM can also use
> > > > it:
> > > > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > > > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> > > >
> > > > That's why I want to use key retention service in hibernation
> > > > encryption/authentication. Which means that we can use key
> > > > API to access trusted key and EFI key.
> > > >
> > >
> > > Here is a proof of concept for using the key retention service
> > > to encrypt/sign snapshot image. It's using EFI key now, I will
> > > add encrypted key support in the key handler later:
> > > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
> > >
> > Thanks for the work, I have two questions here:
>
> My EFI key patch set is almost done. I will send it soon.
>
Okay, please send them out then we can have further discussion
on that.
> > 1. Could you please describe a little more about the scenario on
> > how the user could use the secret key for hibernation encryption?
> > A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
> > during resume. I was thinking how user could interact with
> > the security key mechanism here.
> >
>
> User space doesn't need to involve. The EFI root key is generated by
> EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> variable that it can only be accessed by trusted EFI binary when
> secure boot is enabled.
>
Okay, this apply to the 'suspend' phase, right?
I'm still a little confused about the 'resume' phase.
Taking encryption as example(not signature),
the purpose of doing hibernation encryption is to prevent other users
from stealing ram content. Say, user A uses a passphrase to generate the
key and encrypted the hibernation snapshot and stores it on the disk .
Then if user
B wants to do a hibernation resume to A's previous environment, B has
to provide the same passphrase.
If I understand correctly, the secret key is saved in header and stored
on the disk. Which means, any one can read the header from the disk
to get the secret key in trampoline thus decrypt the image, which is not
safe.
Best,
Yu
> > 2. The generation of secret key in EFI boot environment is
> > using a non standard derivation method in generate_secret_key(),
> > I'm not sure if this is safe enough. This is why we tried to put
> > PBKDF2 into kernel at first and leave it to the user space then.
> >
>
> Thank you for point out.
>
> The generate_secret_key() reuse the logic in kaslr_get_random_long()
> that it produces random seed by RDRAND, RDTSC and i8254. It doesn't
> standard like PBKDF2, but we do not have too many choices in the
> early boot stage. At least KASLR is using the same logic.
>
> We can relay on user space helper. But the helper must be authenticated
> by kernel. Currently we do not have kernel mechanism to verity user
> space process.
>
> Regards
> Joey Lee
--
Thanks,
Ryan
On Fri, Aug 03, 2018 at 09:14:22PM +0800, Ryan Chen wrote:
> On Fri, Aug 3, 2018 at 1:35 PM joeyli <[email protected]> wrote:
> >
> > On Fri, Aug 03, 2018 at 11:37:02AM +0800, Yu Chen wrote:
> > > Hi Joey,
> > > On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> > > > Hi all,
> > > >
> > > > On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > > > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > > > >
> > > > > > > Good point, we once tried to generate key in kernel, but people
> > > > > > > suggest to generate key in userspace and provide it to the
> > > > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > > > should also be safe for encryption in kernel.
> > > > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > > > user space.
> > > > > >
> > > > > > Hi,
> > > > > >
> > > > > > ecryptfs can trust user space. It is supposed to keep data
> > > > > > safe while the system is inoperative. The whole point of Secure
> > > > > > Boot is a cryptographic system of trust that does not include
> > > > > > user space.
> > > > > >
> > > > > > I seriously doubt we want to use trusted computing here. So the
> > > > > > key needs to be generated in kernel space and stored in a safe
> > > > > > manner. As we have a saolution doing that, can we come to ausable
> > > > > > synthesis?
> > > > > >
> > > > > > Regards
> > > > > > Oliver
> > > > >
> > > > > Crurently there have two solutions, they are trusted key and EFI key.
> > > > > Both of them are generated in kernel and are not visible in user space.
> > > > >
> > > > > The trusted key is generated by kernel then sealed by the TPM's
> > > > > SRK. So the trusted key can be stored in anywhere then be enrolled
> > > > > to kernel when we need it. EVM already uses it.
> > > > >
> > > > > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > > > > variable, which means that it can only be access by signed EFI binary
> > > > > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > > > > this solution a couple of years.
> > > > >
> > > > > I am working on put the EFI key to key retention service. Then
> > > > > EFI key can be a master key of encrypted key. EVM can also use
> > > > > it:
> > > > > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > > > > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> > > > >
> > > > > That's why I want to use key retention service in hibernation
> > > > > encryption/authentication. Which means that we can use key
> > > > > API to access trusted key and EFI key.
> > > > >
> > > >
> > > > Here is a proof of concept for using the key retention service
> > > > to encrypt/sign snapshot image. It's using EFI key now, I will
> > > > add encrypted key support in the key handler later:
> > > > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
> > > >
> > > Thanks for the work, I have two questions here:
> >
> > My EFI key patch set is almost done. I will send it soon.
> >
> Okay, please send them out then we can have further discussion
> on that.
> > > 1. Could you please describe a little more about the scenario on
> > > how the user could use the secret key for hibernation encryption?
> > > A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
> > > during resume. I was thinking how user could interact with
> > > the security key mechanism here.
> > >
> >
> > User space doesn't need to involve. The EFI root key is generated by
> > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > variable that it can only be accessed by trusted EFI binary when
> > secure boot is enabled.
> >
> Okay, this apply to the 'suspend' phase, right?
> I'm still a little confused about the 'resume' phase.
> Taking encryption as example(not signature),
> the purpose of doing hibernation encryption is to prevent other users
> from stealing ram content. Say, user A uses a passphrase to generate the
> key and encrypted the hibernation snapshot and stores it on the disk .
> Then if user
> B wants to do a hibernation resume to A's previous environment, B has
> to provide the same passphrase.
> If I understand correctly, the secret key is saved in header and stored
> on the disk. Which means, any one can read the header from the disk
> to get the secret key in trampoline thus decrypt the image, which is not
> safe.
The secret key that it's saved in snapshot header is a session key which
is encrypted by ERK (EFI root key). The ERK only lives in kernel space.
So the session key is still secure.
When resume, the session key will be decrypted/verified by ERK. Then
kernel uses the session key to decrypted/verified snapshot image.
Of course that we can direct use ERK to encrypt/authenticate snapshot
image. Actually the first version of hibernation verification in SLE
direct uses ERK. So the snapshot header only keeps signature but no
encrypted session key.
I add session key in new version because I want to align with
the use case of TPM trusted key + encrypted key. Then hibernation
can use key retention service API to access EFI key or encrypted key.
Compare the trusted key with EFI secure key:
TPM SRK ----seal-----> Trusted key ---encrypt---> Encrypted key
ERK ---encrypt---> EFI secure key ---encrypt---> Encrypted key
Both of them can be the master key of encrypted key.
If EFI key can not be accepted by kernel community, then the TPM
trusted key + encrypted key will be the only solution. We can very
easy to switch to encrypted key by using key retention service
API.
Thanks a lot!
Joey Lee
On Fri, Aug 3, 2018 at 10:06 PM joeyli <[email protected]> wrote:
>
> On Fri, Aug 03, 2018 at 09:14:22PM +0800, Ryan Chen wrote:
> > On Fri, Aug 3, 2018 at 1:35 PM joeyli <[email protected]> wrote:
> > >
> > > On Fri, Aug 03, 2018 at 11:37:02AM +0800, Yu Chen wrote:
> > > > Hi Joey,
> > > > On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> > > > > Hi all,
> > > > >
> > > > > On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > > > > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > > > > >
> > > > > > > > Good point, we once tried to generate key in kernel, but people
> > > > > > > > suggest to generate key in userspace and provide it to the
> > > > > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > > > > should also be safe for encryption in kernel.
> > > > > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > > > > user space.
> > > > > > >
> > > > > > > Hi,
> > > > > > >
> > > > > > > ecryptfs can trust user space. It is supposed to keep data
> > > > > > > safe while the system is inoperative. The whole point of Secure
> > > > > > > Boot is a cryptographic system of trust that does not include
> > > > > > > user space.
> > > > > > >
> > > > > > > I seriously doubt we want to use trusted computing here. So the
> > > > > > > key needs to be generated in kernel space and stored in a safe
> > > > > > > manner. As we have a saolution doing that, can we come to ausable
> > > > > > > synthesis?
> > > > > > >
> > > > > > > Regards
> > > > > > > Oliver
> > > > > >
> > > > > > Crurently there have two solutions, they are trusted key and EFI key.
> > > > > > Both of them are generated in kernel and are not visible in user space.
> > > > > >
> > > > > > The trusted key is generated by kernel then sealed by the TPM's
> > > > > > SRK. So the trusted key can be stored in anywhere then be enrolled
> > > > > > to kernel when we need it. EVM already uses it.
> > > > > >
> > > > > > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > > > > > variable, which means that it can only be access by signed EFI binary
> > > > > > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > > > > > this solution a couple of years.
> > > > > >
> > > > > > I am working on put the EFI key to key retention service. Then
> > > > > > EFI key can be a master key of encrypted key. EVM can also use
> > > > > > it:
> > > > > > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > > > > > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> > > > > >
> > > > > > That's why I want to use key retention service in hibernation
> > > > > > encryption/authentication. Which means that we can use key
> > > > > > API to access trusted key and EFI key.
> > > > > >
> > > > >
> > > > > Here is a proof of concept for using the key retention service
> > > > > to encrypt/sign snapshot image. It's using EFI key now, I will
> > > > > add encrypted key support in the key handler later:
> > > > > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
> > > > >
> > > > Thanks for the work, I have two questions here:
> > >
> > > My EFI key patch set is almost done. I will send it soon.
> > >
> > Okay, please send them out then we can have further discussion
> > on that.
> > > > 1. Could you please describe a little more about the scenario on
> > > > how the user could use the secret key for hibernation encryption?
> > > > A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
> > > > during resume. I was thinking how user could interact with
> > > > the security key mechanism here.
> > > >
> > >
> > > User space doesn't need to involve. The EFI root key is generated by
> > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > variable that it can only be accessed by trusted EFI binary when
> > > secure boot is enabled.
> > >
> > Okay, this apply to the 'suspend' phase, right?
> > I'm still a little confused about the 'resume' phase.
> > Taking encryption as example(not signature),
> > the purpose of doing hibernation encryption is to prevent other users
> > from stealing ram content. Say, user A uses a passphrase to generate the
> > key and encrypted the hibernation snapshot and stores it on the disk .
> > Then if user
> > B wants to do a hibernation resume to A's previous environment, B has
> > to provide the same passphrase.
> > If I understand correctly, the secret key is saved in header and stored
> > on the disk. Which means, any one can read the header from the disk
> > to get the secret key in trampoline thus decrypt the image, which is not
> > safe.
>
> The secret key that it's saved in snapshot header is a session key which
> is encrypted by ERK (EFI root key). The ERK only lives in kernel space.
> So the session key is still secure.
>
> When resume, the session key will be decrypted/verified by ERK. Then
> kernel uses the session key to decrypted/verified snapshot image.
>
OK, I see.
> Of course that we can direct use ERK to encrypt/authenticate snapshot
> image. Actually the first version of hibernation verification in SLE
> direct uses ERK. So the snapshot header only keeps signature but no
> encrypted session key.
>
> I add session key in new version because I want to align with
> the use case of TPM trusted key + encrypted key. Then hibernation
> can use key retention service API to access EFI key or encrypted key.
>
> Compare the trusted key with EFI secure key:
>
> TPM SRK ----seal-----> Trusted key ---encrypt---> Encrypted key
> ERK ---encrypt---> EFI secure key ---encrypt---> Encrypted key
>
> Both of them can be the master key of encrypted key.
>
So either Trusted key or EFI secure key(session key) could be used
for snapshot encryption, right?
> If EFI key can not be accepted by kernel community, then the TPM
> trusted key + encrypted key will be the only solution. We can very
> easy to switch to encrypted key by using key retention service
> API.
>
Back to question raised previously, how could TPM or EFI key be used to
prevent user B from resuming to the environment of A? It appears to me
that, although A is the user who launches the hibernation, B could
resume to the context of A because there's no certification during
resume. Is there any way to introduce the password based verification?
Best,
Yu
> Thanks a lot!
> Joey Lee
On Sat, Aug 04, 2018 at 12:09:08AM +0800, Ryan Chen wrote:
> On Fri, Aug 3, 2018 at 10:06 PM joeyli <[email protected]> wrote:
> >
> > On Fri, Aug 03, 2018 at 09:14:22PM +0800, Ryan Chen wrote:
> > > On Fri, Aug 3, 2018 at 1:35 PM joeyli <[email protected]> wrote:
> > > >
> > > > On Fri, Aug 03, 2018 at 11:37:02AM +0800, Yu Chen wrote:
> > > > > Hi Joey,
> > > > > On Tue, Jul 31, 2018 at 01:04:15AM +0800, joeyli wrote:
> > > > > > Hi all,
> > > > > >
> > > > > > On Thu, Jul 26, 2018 at 04:14:04PM +0800, joeyli wrote:
> > > > > > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > > > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > > > > > >
> > > > > > > > > Good point, we once tried to generate key in kernel, but people
> > > > > > > > > suggest to generate key in userspace and provide it to the
> > > > > > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > > > > > should also be safe for encryption in kernel.
> > > > > > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > > > > > user space.
> > > > > > > >
> > > > > > > > Hi,
> > > > > > > >
> > > > > > > > ecryptfs can trust user space. It is supposed to keep data
> > > > > > > > safe while the system is inoperative. The whole point of Secure
> > > > > > > > Boot is a cryptographic system of trust that does not include
> > > > > > > > user space.
> > > > > > > >
> > > > > > > > I seriously doubt we want to use trusted computing here. So the
> > > > > > > > key needs to be generated in kernel space and stored in a safe
> > > > > > > > manner. As we have a saolution doing that, can we come to ausable
> > > > > > > > synthesis?
> > > > > > > >
> > > > > > > > Regards
> > > > > > > > Oliver
> > > > > > >
> > > > > > > Crurently there have two solutions, they are trusted key and EFI key.
> > > > > > > Both of them are generated in kernel and are not visible in user space.
> > > > > > >
> > > > > > > The trusted key is generated by kernel then sealed by the TPM's
> > > > > > > SRK. So the trusted key can be stored in anywhere then be enrolled
> > > > > > > to kernel when we need it. EVM already uses it.
> > > > > > >
> > > > > > > The EFI key is Jiri Kosina's idea. It is stored in boot services
> > > > > > > variable, which means that it can only be access by signed EFI binary
> > > > > > > (e.g. signed EFI boot stub) when secure boot be enabled. SLE applied
> > > > > > > this solution a couple of years.
> > > > > > >
> > > > > > > I am working on put the EFI key to key retention service. Then
> > > > > > > EFI key can be a master key of encrypted key. EVM can also use
> > > > > > > it:
> > > > > > > https://github.com/joeyli/linux-s4sign/commit/bae39460393ada4c0226dd07cd5e3afcef86b71f
> > > > > > > https://github.com/joeyli/linux-s4sign/commit/f552f97cc3cca5acd84f424b7f946ffb5fe8e9ec
> > > > > > >
> > > > > > > That's why I want to use key retention service in hibernation
> > > > > > > encryption/authentication. Which means that we can use key
> > > > > > > API to access trusted key and EFI key.
> > > > > > >
> > > > > >
> > > > > > Here is a proof of concept for using the key retention service
> > > > > > to encrypt/sign snapshot image. It's using EFI key now, I will
> > > > > > add encrypted key support in the key handler later:
> > > > > > https://github.com/joeyli/linux-s4sign/commit/6311e97038974bc5de8121769fb4d34470009566
> > > > > >
> > > > > Thanks for the work, I have two questions here:
> > > >
> > > > My EFI key patch set is almost done. I will send it soon.
> > > >
> > > Okay, please send them out then we can have further discussion
> > > on that.
> > > > > 1. Could you please describe a little more about the scenario on
> > > > > how the user could use the secret key for hibernation encryption?
> > > > > A requirement is that, the user should provide a passphrase(for key derivation, i.e.)
> > > > > during resume. I was thinking how user could interact with
> > > > > the security key mechanism here.
> > > > >
> > > >
> > > > User space doesn't need to involve. The EFI root key is generated by
> > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > variable that it can only be accessed by trusted EFI binary when
> > > > secure boot is enabled.
> > > >
> > > Okay, this apply to the 'suspend' phase, right?
> > > I'm still a little confused about the 'resume' phase.
> > > Taking encryption as example(not signature),
> > > the purpose of doing hibernation encryption is to prevent other users
> > > from stealing ram content. Say, user A uses a passphrase to generate the
> > > key and encrypted the hibernation snapshot and stores it on the disk .
> > > Then if user
> > > B wants to do a hibernation resume to A's previous environment, B has
> > > to provide the same passphrase.
> > > If I understand correctly, the secret key is saved in header and stored
> > > on the disk. Which means, any one can read the header from the disk
> > > to get the secret key in trampoline thus decrypt the image, which is not
> > > safe.
> >
> > The secret key that it's saved in snapshot header is a session key which
> > is encrypted by ERK (EFI root key). The ERK only lives in kernel space.
> > So the session key is still secure.
> >
> > When resume, the session key will be decrypted/verified by ERK. Then
> > kernel uses the session key to decrypted/verified snapshot image.
> >
> OK, I see.
> > Of course that we can direct use ERK to encrypt/authenticate snapshot
> > image. Actually the first version of hibernation verification in SLE
> > direct uses ERK. So the snapshot header only keeps signature but no
> > encrypted session key.
> >
> > I add session key in new version because I want to align with
> > the use case of TPM trusted key + encrypted key. Then hibernation
> > can use key retention service API to access EFI key or encrypted key.
> >
> > Compare the trusted key with EFI secure key:
> >
> > TPM SRK ----seal-----> Trusted key ---encrypt---> Encrypted key
> > ERK ---encrypt---> EFI secure key ---encrypt---> Encrypted key
> >
> > Both of them can be the master key of encrypted key.
> >
> So either Trusted key or EFI secure key(session key) could be used
> for snapshot encryption, right?
Yes. Or we can use encrypted key. It depends on different use case.
If the trusted key is sealed with PCRs, then we can not generate
new trusted key after PCRs be capped. Then we can only use the
encrypted key as the session key.
> > If EFI key can not be accepted by kernel community, then the TPM
> > trusted key + encrypted key will be the only solution. We can very
> > easy to switch to encrypted key by using key retention service
> > API.
> >
> Back to question raised previously, how could TPM or EFI key be used to
> prevent user B from resuming to the environment of A? It appears to me
> that, although A is the user who launches the hibernation, B could
> resume to the context of A because there's no certification during
> resume. Is there any way to introduce the password based verification?
I see you point. Yes, TPM or EFI key can only be used to prevent that the
content in snapshot image be detected on other machine. It can not be used
to prevent the snapshot image be resumed on _the same_ machine by different
user. Sounds like B can physical accessing the machine. Could you please
explain more detail for the case?
As you said, password is useful in this case. But I have no idea for how
to introduce password without user space helper. And user space helper
must be authenticate by kernel. Which means that we need to add mechanism
to verify user space binary.
Thanks
Joey Lee
Hi!
> > User space doesn't need to involve. The EFI root key is generated by
> > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > variable that it can only be accessed by trusted EFI binary when
> > secure boot is enabled.
> >
> Okay, this apply to the 'suspend' phase, right?
> I'm still a little confused about the 'resume' phase.
> Taking encryption as example(not signature),
> the purpose of doing hibernation encryption is to prevent other users
> from stealing ram content. Say, user A uses a passphrase to generate the
No, I don't think that's purpose here.
Purpose here is to prevent user from reading/modifying kernel memory
content on machine he owns.
Strange as it may sound, that is what "secure" boot requires (and what
Disney wants).
I guess it may have some non-evil uses,
too... https://www.linux.com/news/matthew-garrett-explains-how-increase-security-boot-time
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi Oliver,
On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> >
> > Good point, we once tried to generate key in kernel, but people
> > suggest to generate key in userspace and provide it to the
> > kernel, which is what ecryptfs do currently, so it seems this
> > should also be safe for encryption in kernel.
> > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > Thus Chun-Yi's signature can use EFI key and both the key from
> > user space.
>
> Hi,
>
> ecryptfs can trust user space. It is supposed to keep data
> safe while the system is inoperative.
Humm, I did not quite get the point here, let's take fscrypt
for example, the kernel gets user generated key from user space,
and uses per-inode nonce(random bytes) as the master key to
do a KDF(key derivation function) on user provided key, and uses
that key for encryption. We can also added similar mechanism
to generate the key in kernel space but the key should be
original from user's provided key(password derived), because
the security boot/signature mechanism could not cover the case
that, two different users could resume to each other's context
because there isn't any certification during resume if it is
on the same physical hardware.
Best,
Yu
> The whole point of Secure
> Boot is a cryptographic system of trust that does not include
> user space.
>
> I seriously doubt we want to use trusted computing here. So the
> key needs to be generated in kernel space and stored in a safe
> manner. As we have a saolution doing that, can we come to ausable
> synthesis?
>
> Regards
> Oliver
>
Hi Pavel,
On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> Hi!
>
> > > User space doesn't need to involve. The EFI root key is generated by
> > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > variable that it can only be accessed by trusted EFI binary when
> > > secure boot is enabled.
> > >
> > Okay, this apply to the 'suspend' phase, right?
> > I'm still a little confused about the 'resume' phase.
> > Taking encryption as example(not signature),
> > the purpose of doing hibernation encryption is to prevent other users
> > from stealing ram content. Say, user A uses a passphrase to generate the
>
> No, I don't think that's purpose here.
>
> Purpose here is to prevent user from reading/modifying kernel memory
> content on machine he owns.
>
Say, A puts his laptop into hibernation and walks away,
and B walks by, and opens A's laptop and wakes up the system and he
can do what he wants. Although EFI key/TPM trusted key is enabled,
currently there's no certification during resume, which sounds
unsafe to me. Afterall, the original requirement is to probe
user for password during resume, which sounds more natural.
> Strange as it may sound, that is what "secure" boot requires (and what
> Disney wants).
>
Ok, I understand this requirement, and I'm also concerning how to
distinguish different users from seeing data of each other.
Joey,
I'm thinking of a possible direction which could take advantage
of the password. It leverages either EFI key or TPM
trusted key to get it done. Does it make sense?
1. The user space generates a symetric key key_user using
the password, and passes the key_user to the kernel as the master
key.
2. The kernel uses the EFI key or TPM trusted key to encrypt
the key_user thus gets a encrypt_key.
3. Uses the encrypt_key to do snapshot encryption
4. During resume, the same encrypt_key is generated following
the same steps(I assume the same EFI key or TPM key could be fetched
during resumed, right?) and do the snapshot decryption.
And this is what fscrypt is doing:
Documentation/filesystems/fscrypt.rst
Best,
Yu
> I guess it may have some non-evil uses,
> too... https://www.linux.com/news/matthew-garrett-explains-how-increase-security-boot-time
>
>
> Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Mon, Aug 06, 2018 at 03:57:54PM +0800, Yu Chen wrote:
> Hi Oliver,
> On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > >
> > > Good point, we once tried to generate key in kernel, but people
> > > suggest to generate key in userspace and provide it to the
> > > kernel, which is what ecryptfs do currently, so it seems this
> > > should also be safe for encryption in kernel.
> > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > user space.
As Ard and James's comments, the EFI key can not be accepted:
https://lkml.org/lkml/2018/8/5/135
The lower entropy problem can be covered by RDRAND or EFI random
protocol. But the key point is that we can not fully trust manufacturer.
And, the secure boot relies on Microsoft's business interests. It's
not designed for confidentiality.
So I will move to TPM trusted key + encrypted key.
> >
> > Hi,
> >
> > ecryptfs can trust user space. It is supposed to keep data
> > safe while the system is inoperative.
> Humm, I did not quite get the point here, let's take fscrypt
> for example, the kernel gets user generated key from user space,
> and uses per-inode nonce(random bytes) as the master key to
> do a KDF(key derivation function) on user provided key, and uses
> that key for encryption. We can also added similar mechanism
> to generate the key in kernel space but the key should be
> original from user's provided key(password derived), because
> the security boot/signature mechanism could not cover the case
> that, two different users could resume to each other's context
> because there isn't any certification during resume if it is
> on the same physical hardware.
>
Sounds there have two different purposes. One is to prevent that
the secret in snapshop image be detected/changed outside the machine.
Another one try to prevent that B user resumes to A user's context
on the same machine.
In the case of B resumes A's context, I still think that the attacker
must physical accesses the machine. Which means that it's out of EFI
secure boot's design. Could you please explan the detail for the attack?
So I think that the password from user space is for user authentication,
and the TPM trusted key is for snapshot image encryption/verification.
Thanks
Joey Lee
On Mon, Aug 06, 2018 at 05:48:04PM +0800, joeyli wrote:
> On Mon, Aug 06, 2018 at 03:57:54PM +0800, Yu Chen wrote:
> > Hi Oliver,
> > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > >
> > > > Good point, we once tried to generate key in kernel, but people
> > > > suggest to generate key in userspace and provide it to the
> > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > should also be safe for encryption in kernel.
> > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > user space.
>
> As Ard and James's comments, the EFI key can not be accepted:
> https://lkml.org/lkml/2018/8/5/135
>
> The lower entropy problem can be covered by RDRAND or EFI random
> protocol. But the key point is that we can not fully trust manufacturer.
> And, the secure boot relies on Microsoft's business interests. It's
> not designed for confidentiality.
>
> So I will move to TPM trusted key + encrypted key.
>
OK.
> > >
> > > Hi,
> > >
> > > ecryptfs can trust user space. It is supposed to keep data
> > > safe while the system is inoperative.
> > Humm, I did not quite get the point here, let's take fscrypt
> > for example, the kernel gets user generated key from user space,
> > and uses per-inode nonce(random bytes) as the master key to
> > do a KDF(key derivation function) on user provided key, and uses
> > that key for encryption. We can also added similar mechanism
> > to generate the key in kernel space but the key should be
> > original from user's provided key(password derived), because
> > the security boot/signature mechanism could not cover the case
> > that, two different users could resume to each other's context
> > because there isn't any certification during resume if it is
> > on the same physical hardware.
> >
>
> Sounds there have two different purposes. One is to prevent that
> the secret in snapshop image be detected/changed outside the machine.
> Another one try to prevent that B user resumes to A user's context
> on the same machine.
>
Yes, it aims to prevent B from resuming to A's context no matter
whether it is on the same hardware or not, and prevents others
from getting the plain content on the disk.
> In the case of B resumes A's context, I still think that the attacker
> must physical accesses the machine. Which means that it's out of EFI
> secure boot's design. Could you please explan the detail for the attack?
>
May I know what attack does it refer to? please refer to another mail I sent to Pavel,
a simple use case has been described.
> So I think that the password from user space is for user authentication,
> and the TPM trusted key is for snapshot image encryption/verification.
>
password generated key could also be used as encryption.
Best,
Yu
> Thanks
> Joey Lee
On Mo, 2018-08-06 at 15:57 +0800, Yu Chen wrote:
> Hi Oliver,
> On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > >
> > > Good point, we once tried to generate key in kernel, but people
> > > suggest to generate key in userspace and provide it to the
> > > kernel, which is what ecryptfs do currently, so it seems this
> > > should also be safe for encryption in kernel.
> > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > user space.
> >
> > Hi,
> >
> > ecryptfs can trust user space. It is supposed to keep data
> > safe while the system is inoperative.
>
> Humm, I did not quite get the point here, let's take fscrypt
While the system is running and the fs is mounted, your data
is as secure as root access to your machine, right? You encrypt
a disk primarily so data cannot be recovered (and altered) while
the system is not running.
Secure Boot does not trust root fully. There is a cryptographic
chain of trust and user space is not part of it.
> for example, the kernel gets user generated key from user space,
> and uses per-inode nonce(random bytes) as the master key to
> do a KDF(key derivation function) on user provided key, and uses
> that key for encryption. We can also added similar mechanism
> to generate the key in kernel space but the key should be
> original from user's provided key(password derived), because
> the security boot/signature mechanism could not cover the case
> that, two different users could resume to each other's context
> because there isn't any certification during resume if it is
> on the same physical hardware.
Please explain. You will always have to suspend the whole machine
with all tasks of all users. And STD with Secure Boot need not
imply that you encrypt your discs. You need to encrypt only
kernel memory to meet the requirements.
As STD affects the whole machine it must require root rights.
So I cannot see how you can talk about a session belonging
to a user. Please explain.
It seems to me that you can in theory encrypt the password
by a key coming from user space, so that you need to know
an additional key to resume the system, but that seems to me
above and beyond what Secure Boot requires.
Regards
Oliver
On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> Hi Pavel,
> On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > Hi!
> >
> > > > User space doesn't need to involve. The EFI root key is generated by
> > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > variable that it can only be accessed by trusted EFI binary when
> > > > secure boot is enabled.
> > > >
> > > Okay, this apply to the 'suspend' phase, right?
> > > I'm still a little confused about the 'resume' phase.
> > > Taking encryption as example(not signature),
> > > the purpose of doing hibernation encryption is to prevent other users
> > > from stealing ram content. Say, user A uses a passphrase to generate the
> >
> > No, I don't think that's purpose here.
> >
> > Purpose here is to prevent user from reading/modifying kernel memory
> > content on machine he owns.
> >
> Say, A puts his laptop into hibernation and walks away,
> and B walks by, and opens A's laptop and wakes up the system and he
> can do what he wants. Although EFI key/TPM trusted key is enabled,
> currently there's no certification during resume, which sounds
> unsafe to me. Afterall, the original requirement is to probe
> user for password during resume, which sounds more natural.
OK, I saw your case. This is a physical accessing.
I have a question: The suspend to memory also has the same behavior
and more people are using suspend. Should we think a common solution
to cover S3 and S4?
> > Strange as it may sound, that is what "secure" boot requires (and what
> > Disney wants).
> >
> Ok, I understand this requirement, and I'm also concerning how to
> distinguish different users from seeing data of each other.
>
> Joey,
> I'm thinking of a possible direction which could take advantage
> of the password. It leverages either EFI key or TPM
> trusted key to get it done. Does it make sense?
>
> 1. The user space generates a symetric key key_user using
> the password, and passes the key_user to the kernel as the master
> key.
> 2. The kernel uses the EFI key or TPM trusted key to encrypt
> the key_user thus gets a encrypt_key.
> 3. Uses the encrypt_key to do snapshot encryption
> 4. During resume, the same encrypt_key is generated following
> the same steps(I assume the same EFI key or TPM key could be fetched
> during resumed, right?) and do the snapshot decryption.
>
Yes, we can use TPM key to protect the user key. But I suggest that we
should give user a function to disable the user key because not everyone
want to key-in a password for hibernate/resume and also snapshot image
encryption.
Two policies:
- When user key-in user key, the snapshot image must be encryption.
- Without key-in user key, I still want the snapshot image can be encryption.
No matter that the user key be key-in or not, the snapshot image must be
encrypted by a kernel key. So I suggest that we treat the user key as a salt
for snapshot image encryption and authentication. If the user key
be disabled, then kernel just generates a random number as a salt.
Actually, the kernel must compares the user key before snapshot decryption.
If the user key doesn't match but user space still triggers furture resume
process. Then kernel direct drops the snapshot image.
> And this is what fscrypt is doing:
> Documentation/filesystems/fscrypt.rst
>
The use case is different. We have two key for two purposes. And the two
functions can be separated.
Thanks
Joey Lee
On Mon, Aug 06, 2018 at 12:20:20PM +0200, Oliver Neukum wrote:
> On Mo, 2018-08-06 at 15:57 +0800, Yu Chen wrote:
> > Hi Oliver,
> > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > >
> > > > Good point, we once tried to generate key in kernel, but people
> > > > suggest to generate key in userspace and provide it to the
> > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > should also be safe for encryption in kernel.
> > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > user space.
> > >
> > > Hi,
> > >
> > > ecryptfs can trust user space. It is supposed to keep data
> > > safe while the system is inoperative.
> >
> > Humm, I did not quite get the point here, let's take fscrypt
>
> While the system is running and the fs is mounted, your data
> is as secure as root access to your machine, right? You encrypt
> a disk primarily so data cannot be recovered (and altered) while
> the system is not running.
>
> Secure Boot does not trust root fully. There is a cryptographic
> chain of trust and user space is not part of it.
>
Okay, I see. So if we want to use secure boot mechanism for
hibernation encryption, user space is trusted.
> > for example, the kernel gets user generated key from user space,
> > and uses per-inode nonce(random bytes) as the master key to
> > do a KDF(key derivation function) on user provided key, and uses
> > that key for encryption. We can also added similar mechanism
> > to generate the key in kernel space but the key should be
> > original from user's provided key(password derived), because
> > the security boot/signature mechanism could not cover the case
> > that, two different users could resume to each other's context
> > because there isn't any certification during resume if it is
> > on the same physical hardware.
>
> Please explain. You will always have to suspend the whole machine
> with all tasks of all users. And STD with Secure Boot need not
> imply that you encrypt your discs. You need to encrypt only
> kernel memory to meet the requirements.
>
> As STD affects the whole machine it must require root rights.
> So I cannot see how you can talk about a session belonging
> to a user. Please explain.
>
The case is for physical access, not the 'user' in OS.
> It seems to me that you can in theory encrypt the password
> by a key coming from user space, so that you need to know
> an additional key to resume the system, but that seems to me
> above and beyond what Secure Boot requires.
>
Understand.
Best,
Yu
> Regards
> Oliver
>
On Mon, Aug 06, 2018 at 06:39:58PM +0800, joeyli wrote:
> On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> > Hi Pavel,
> > On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > > Hi!
> > >
> > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > secure boot is enabled.
> > > > >
> > > > Okay, this apply to the 'suspend' phase, right?
> > > > I'm still a little confused about the 'resume' phase.
> > > > Taking encryption as example(not signature),
> > > > the purpose of doing hibernation encryption is to prevent other users
> > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > >
> > > No, I don't think that's purpose here.
> > >
> > > Purpose here is to prevent user from reading/modifying kernel memory
> > > content on machine he owns.
> > >
> > Say, A puts his laptop into hibernation and walks away,
> > and B walks by, and opens A's laptop and wakes up the system and he
> > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > currently there's no certification during resume, which sounds
> > unsafe to me. Afterall, the original requirement is to probe
> > user for password during resume, which sounds more natural.
>
> OK, I saw your case. This is a physical accessing.
>
> I have a question: The suspend to memory also has the same behavior
> and more people are using suspend. Should we think a common solution
> to cover S3 and S4?
>
Since STD behaves more likely a boot up, STR does not have solid
requirement for certification.
> > > Strange as it may sound, that is what "secure" boot requires (and what
> > > Disney wants).
> > >
> > Ok, I understand this requirement, and I'm also concerning how to
> > distinguish different users from seeing data of each other.
> >
> > Joey,
> > I'm thinking of a possible direction which could take advantage
> > of the password. It leverages either EFI key or TPM
> > trusted key to get it done. Does it make sense?
> >
> > 1. The user space generates a symetric key key_user using
> > the password, and passes the key_user to the kernel as the master
> > key.
> > 2. The kernel uses the EFI key or TPM trusted key to encrypt
> > the key_user thus gets a encrypt_key.
> > 3. Uses the encrypt_key to do snapshot encryption
> > 4. During resume, the same encrypt_key is generated following
> > the same steps(I assume the same EFI key or TPM key could be fetched
> > during resumed, right?) and do the snapshot decryption.
> >
>
> Yes, we can use TPM key to protect the user key. But I suggest that we
> should give user a function to disable the user key because not everyone
> want to key-in a password for hibernate/resume and also snapshot image
> encryption.
>
> Two policies:
> - When user key-in user key, the snapshot image must be encryption.
> - Without key-in user key, I still want the snapshot image can be encryption.
>
> No matter that the user key be key-in or not, the snapshot image must be
> encrypted by a kernel key. So I suggest that we treat the user key as a salt
> for snapshot image encryption and authentication. If the user key
> be disabled, then kernel just generates a random number as a salt.
>
> Actually, the kernel must compares the user key before snapshot decryption.
> If the user key doesn't match but user space still triggers furture resume
> process. Then kernel direct drops the snapshot image.
>
Anyway I'm ok with using TPM for major 'security', please feel free
to send a second version out, and for certification implementation
we can have further discussion on that later.
Best,
Yu
> > And this is what fscrypt is doing:
> > Documentation/filesystems/fscrypt.rst
> >
> The use case is different. We have two key for two purposes. And the two
> functions can be separated.
>
> Thanks
> Joey Lee
On Tue, Aug 7, 2018 at 3:33 PM Yu Chen <[email protected]> wrote:
>
> On Mon, Aug 06, 2018 at 12:20:20PM +0200, Oliver Neukum wrote:
> > On Mo, 2018-08-06 at 15:57 +0800, Yu Chen wrote:
> > > Hi Oliver,
> > > On Thu, Jul 26, 2018 at 09:30:46AM +0200, Oliver Neukum wrote:
> > > > On Di, 2018-07-24 at 00:23 +0800, Yu Chen wrote:
> > > > >
> > > > > Good point, we once tried to generate key in kernel, but people
> > > > > suggest to generate key in userspace and provide it to the
> > > > > kernel, which is what ecryptfs do currently, so it seems this
> > > > > should also be safe for encryption in kernel.
> > > > > https://www.spinics.net/lists/linux-crypto/msg33145.html
> > > > > Thus Chun-Yi's signature can use EFI key and both the key from
> > > > > user space.
> > > >
> > > > Hi,
> > > >
> > > > ecryptfs can trust user space. It is supposed to keep data
> > > > safe while the system is inoperative.
> > >
> > > Humm, I did not quite get the point here, let's take fscrypt
> >
> > While the system is running and the fs is mounted, your data
> > is as secure as root access to your machine, right? You encrypt
> > a disk primarily so data cannot be recovered (and altered) while
> > the system is not running.
> >
> > Secure Boot does not trust root fully. There is a cryptographic
> > chain of trust and user space is not part of it.
> >
> Okay, I see. So if we want to use secure boot mechanism for
> hibernation encryption, user space is trusted.
s/ is trusted/is not trusted/
On Di, 2018-08-07 at 15:38 +0800, Yu Chen wrote:
> > As STD affects the whole machine it must require root rights.
> > So I cannot see how you can talk about a session belonging
> > to a user. Please explain.
> >
>
> The case is for physical access, not the 'user' in OS.
Well, yes, but Secure Boot does not guard against anybody
booting or halting the machine. It limits what you can
boot by a chain of trust.
I think you are trying to add a feature to Secure Boot.
Regards
Oliver
On Tue, Aug 07, 2018 at 03:43:12PM +0800, Yu Chen wrote:
> On Mon, Aug 06, 2018 at 06:39:58PM +0800, joeyli wrote:
> > On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> > > Hi Pavel,
> > > On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > > > Hi!
> > > >
> > > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > > secure boot is enabled.
> > > > > >
> > > > > Okay, this apply to the 'suspend' phase, right?
> > > > > I'm still a little confused about the 'resume' phase.
> > > > > Taking encryption as example(not signature),
> > > > > the purpose of doing hibernation encryption is to prevent other users
> > > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > > >
> > > > No, I don't think that's purpose here.
> > > >
> > > > Purpose here is to prevent user from reading/modifying kernel memory
> > > > content on machine he owns.
> > > >
> > > Say, A puts his laptop into hibernation and walks away,
> > > and B walks by, and opens A's laptop and wakes up the system and he
> > > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > > currently there's no certification during resume, which sounds
> > > unsafe to me. Afterall, the original requirement is to probe
> > > user for password during resume, which sounds more natural.
> >
> > OK, I saw your case. This is a physical accessing.
> >
> > I have a question: The suspend to memory also has the same behavior
> > and more people are using suspend. Should we think a common solution
> > to cover S3 and S4?
> >
> Since STD behaves more likely a boot up, STR does not have solid
> requirement for certification.
In your A/B user case, when STR, B user can still open A's laptop
and wakes up the system and do what he wants because he can get
the console like resume from STD. I didn't see difference.
> > > > Strange as it may sound, that is what "secure" boot requires (and what
> > > > Disney wants).
> > > >
> > > Ok, I understand this requirement, and I'm also concerning how to
> > > distinguish different users from seeing data of each other.
> > >
> > > Joey,
> > > I'm thinking of a possible direction which could take advantage
> > > of the password. It leverages either EFI key or TPM
> > > trusted key to get it done. Does it make sense?
> > >
> > > 1. The user space generates a symetric key key_user using
> > > the password, and passes the key_user to the kernel as the master
> > > key.
> > > 2. The kernel uses the EFI key or TPM trusted key to encrypt
> > > the key_user thus gets a encrypt_key.
> > > 3. Uses the encrypt_key to do snapshot encryption
> > > 4. During resume, the same encrypt_key is generated following
> > > the same steps(I assume the same EFI key or TPM key could be fetched
> > > during resumed, right?) and do the snapshot decryption.
> > >
> >
> > Yes, we can use TPM key to protect the user key. But I suggest that we
> > should give user a function to disable the user key because not everyone
> > want to key-in a password for hibernate/resume and also snapshot image
> > encryption.
> >
> > Two policies:
> > - When user key-in user key, the snapshot image must be encryption.
> > - Without key-in user key, I still want the snapshot image can be encryption.
> >
> > No matter that the user key be key-in or not, the snapshot image must be
> > encrypted by a kernel key. So I suggest that we treat the user key as a salt
> > for snapshot image encryption and authentication. If the user key
> > be disabled, then kernel just generates a random number as a salt.
> >
> > Actually, the kernel must compares the user key before snapshot decryption.
> > If the user key doesn't match but user space still triggers furture resume
> > process. Then kernel direct drops the snapshot image.
> >
> Anyway I'm ok with using TPM for major 'security', please feel free
> to send a second version out, and for certification implementation
> we can have further discussion on that later.
>
Regards
Joey Lee
Hi!
> > > > User space doesn't need to involve. The EFI root key is generated by
> > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > variable that it can only be accessed by trusted EFI binary when
> > > > secure boot is enabled.
> > > >
> > > Okay, this apply to the 'suspend' phase, right?
> > > I'm still a little confused about the 'resume' phase.
> > > Taking encryption as example(not signature),
> > > the purpose of doing hibernation encryption is to prevent other users
> > > from stealing ram content. Say, user A uses a passphrase to generate the
> >
> > No, I don't think that's purpose here.
> >
> > Purpose here is to prevent user from reading/modifying kernel memory
> > content on machine he owns.
> >
> Say, A puts his laptop into hibernation and walks away,
> and B walks by, and opens A's laptop and wakes up the system and he
> can do what he wants. Although EFI key/TPM trusted key is enabled,
> currently there's no certification during resume, which sounds
> unsafe to me. Afterall, the original requirement is to probe
Define unsafe.
If you want security against bad people resuming your machines, please
take a look at existing uswsusp solutions. It defends against that.
If you want security against bad people tampering with your machines
physically, sorry, there's no way to defend against that.
But I thought you were trying to do something for secure boot, and "bad
person resumes your machine" is out of scope there.
So please always explain security against _what kind of attack_ you
are trying to improve; intelligent communication is not possible
without that.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Mon 2018-08-06 18:39:58, joeyli wrote:
> On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> > Hi Pavel,
> > On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > > Hi!
> > >
> > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > secure boot is enabled.
> > > > >
> > > > Okay, this apply to the 'suspend' phase, right?
> > > > I'm still a little confused about the 'resume' phase.
> > > > Taking encryption as example(not signature),
> > > > the purpose of doing hibernation encryption is to prevent other users
> > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > >
> > > No, I don't think that's purpose here.
> > >
> > > Purpose here is to prevent user from reading/modifying kernel memory
> > > content on machine he owns.
> > >
> > Say, A puts his laptop into hibernation and walks away,
> > and B walks by, and opens A's laptop and wakes up the system and he
> > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > currently there's no certification during resume, which sounds
> > unsafe to me. Afterall, the original requirement is to probe
> > user for password during resume, which sounds more natural.
>
> OK, I saw your case. This is a physical accessing.
>
> I have a question: The suspend to memory also has the same behavior
> and more people are using suspend. Should we think a common solution
> to cover S3 and S4?
Well, we have similar problem during runtime, too ;-).
Anyway, I don't think we should encrypt memory during S3 in kernel.
If you wanted to do that, you could use uswsusp to take snapshot,
store it in ram, encrypt, erase originals (new API might be
needed... hmm. does not exactly sound easy... kexec?), trigger S3, decrypt,
resume from snapshot...
Sounds like a bit of work...
Best regards,
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi Pavel, Joey, Oliver
Please let me describe the original requirement and my
understanding about hibernation encryption here, thus
help us sync on the same thread:
On Wed, Aug 08, 2018 at 07:50:36PM +0200, Pavel Machek wrote:
> Hi!
>
> > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > secure boot is enabled.
> > > > >
> > > > Okay, this apply to the 'suspend' phase, right?
> > > > I'm still a little confused about the 'resume' phase.
> > > > Taking encryption as example(not signature),
> > > > the purpose of doing hibernation encryption is to prevent other users
> > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > >
> > > No, I don't think that's purpose here.
> > >
> > > Purpose here is to prevent user from reading/modifying kernel memory
> > > content on machine he owns.
> > >
> > Say, A puts his laptop into hibernation and walks away,
> > and B walks by, and opens A's laptop and wakes up the system and he
> > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > currently there's no certification during resume, which sounds
> > unsafe to me. Afterall, the original requirement is to probe
>
> Define unsafe.
>
> If you want security against bad people resuming your machines, please
Yes, this is one of the requirements.
> take a look at existing uswsusp solutions. It defends against that.
>
> If you want security against bad people tampering with your machines
> physically, sorry, there's no way to defend against that.
No, this is not the requirement.
>
> But I thought you were trying to do something for secure boot, and "bad
> person resumes your machine" is out of scope there.
>
Not exactly, secure boot is one solution to meet the requirement.
> So please always explain security against _what kind of attack_ you
> are trying to improve; intelligent communication is not possible
> without that.
>
User requirement:
A is the user, B is the attacker, user A launches a STD and
encrypts A's ram data, then writes these encrypted data onto
the disk, so that: Even if user B has access to the disk,
B could not know the content of A. Which implies:
1. If B unplugs the disk from A's machine, and plugs the disk onto
another machine, B could not decode the content without A's
'permission'.
2. If B is using the same machine as A, even A has walked away leaving
the system suspend, B could not resume to A's context without
A's 'permission'.
Previously, there are three proposal for this:
a. Enhance the uswsusp(Pavel)
b. Using user provided password to generate the key, for encryption(Yu)
c. Using security boot(TPM or EFI key) for encryption(Joey)
Since I was proposing solution b, I'll say a little more about it.
The original idea was that, the user provides a password, then this
password is used to generate the key, which means, if user B has provided
an incorrect password, the kernel will fail to decrypt the data and is
likely to fail the resume process. That is to say, no matter
which physical machine B is using, only if he has provided the
password, he would be able to resume. In the first version, the key
deviration was firstly done in kernel space, which satisfies the
requirement and both saftey. Unfortunately it was rejected and
people would like to see the key generated in user space instead.
However, using user provided key directly is not safe, according
to the discussion in the thread. I don't have good idea on
how to improve this, but only have some workarounds, say, ask the
kernel to use TPM key to protects the user provided 'key', etc.
Then let's talk a little more about secure boot. According
to my understanding, the situation secure boot tries to deal
with is a little different from the user case we raised above -
It is an enhancement for case 1, because it refuses to resume
once the machine is changed. And it does not cover case 2. But
if it is a requirement from the user, that's ok.
uswsusp is to do all the staff in user space, and other two
aim to do all the staff in kernel space. I'm not arguing
which one is better, but I'm not sure how often user is using
it, as we don't get uswsusp related bug report on kernel
bugzilla (both internally)recent years. Another point is,
why the compression is in kernel rather than in uswsusp,
it looks like the same case as encryption here.
Best,
Yu
Hi,
On Wed, Aug 08, 2018 at 07:58:45PM +0200, Pavel Machek wrote:
> On Mon 2018-08-06 18:39:58, joeyli wrote:
> > On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> > > Hi Pavel,
> > > On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > > > Hi!
> > > >
> > > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > > secure boot is enabled.
> > > > > >
> > > > > Okay, this apply to the 'suspend' phase, right?
> > > > > I'm still a little confused about the 'resume' phase.
> > > > > Taking encryption as example(not signature),
> > > > > the purpose of doing hibernation encryption is to prevent other users
> > > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > > >
> > > > No, I don't think that's purpose here.
> > > >
> > > > Purpose here is to prevent user from reading/modifying kernel memory
> > > > content on machine he owns.
> > > >
> > > Say, A puts his laptop into hibernation and walks away,
> > > and B walks by, and opens A's laptop and wakes up the system and he
> > > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > > currently there's no certification during resume, which sounds
> > > unsafe to me. Afterall, the original requirement is to probe
> > > user for password during resume, which sounds more natural.
> >
> > OK, I saw your case. This is a physical accessing.
> >
> > I have a question: The suspend to memory also has the same behavior
> > and more people are using suspend. Should we think a common solution
> > to cover S3 and S4?
>
> Well, we have similar problem during runtime, too ;-).
>
> Anyway, I don't think we should encrypt memory during S3 in kernel.
>
It seems that Joey was talking about certification(something like login)
rather than encryption?
Best,
Yu
> If you wanted to do that, you could use uswsusp to take snapshot,
> store it in ram, encrypt, erase originals (new API might be
> needed... hmm. does not exactly sound easy... kexec?), trigger S3, decrypt,
> resume from snapshot...
>
> Sounds like a bit of work...
>
> Best regards,
>
> Pavel
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
Hi!
> > Define unsafe.
> >
> > If you want security against bad people resuming your machines, please
> Yes, this is one of the requirements.
> > But I thought you were trying to do something for secure boot, and "bad
> > person resumes your machine" is out of scope there.
> >
> Not exactly, secure boot is one solution to meet the requirement.
Is it? AFAICT secure boot is something else. "Not even owner can see
kernel memory".
> > So please always explain security against _what kind of attack_ you
> > are trying to improve; intelligent communication is not possible
> > without that.
> >
> User requirement:
> A is the user, B is the attacker, user A launches a STD and
> encrypts A's ram data, then writes these encrypted data onto
> the disk, so that: Even if user B has access to the disk,
> B could not know the content of A. Which implies:
> 1. If B unplugs the disk from A's machine, and plugs the disk onto
> another machine, B could not decode the content without A's
> 'permission'.
> 2. If B is using the same machine as A, even A has walked away leaving
> the system suspend, B could not resume to A's context without
> A's 'permission'.
Ok. Let's call this "effective resume password".
> Previously, there are three proposal for this:
> a. Enhance the uswsusp(Pavel)
Actually you don't have to enhance anything. Uswsusp already provides
"effective resume password".
If you only want to ask for password on resume, RSA is needed.
> Then let's talk a little more about secure boot. According
> to my understanding, the situation secure boot tries to deal
> with is a little different from the user case we raised above -
> It is an enhancement for case 1, because it refuses to resume
> once the machine is changed. And it does not cover case 2. But
> if it is a requirement from the user, that's ok.
That does not match my understanding of secure boot.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Thu, Aug 09, 2018 at 11:43:20AM +0800, Yu Chen wrote:
> Hi,
> On Wed, Aug 08, 2018 at 07:58:45PM +0200, Pavel Machek wrote:
> > On Mon 2018-08-06 18:39:58, joeyli wrote:
> > > On Mon, Aug 06, 2018 at 04:45:34PM +0800, Yu Chen wrote:
> > > > Hi Pavel,
> > > > On Sun, Aug 05, 2018 at 12:02:00PM +0200, Pavel Machek wrote:
> > > > > Hi!
> > > > >
> > > > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > > > secure boot is enabled.
> > > > > > >
> > > > > > Okay, this apply to the 'suspend' phase, right?
> > > > > > I'm still a little confused about the 'resume' phase.
> > > > > > Taking encryption as example(not signature),
> > > > > > the purpose of doing hibernation encryption is to prevent other users
> > > > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > > > >
> > > > > No, I don't think that's purpose here.
> > > > >
> > > > > Purpose here is to prevent user from reading/modifying kernel memory
> > > > > content on machine he owns.
> > > > >
> > > > Say, A puts his laptop into hibernation and walks away,
> > > > and B walks by, and opens A's laptop and wakes up the system and he
> > > > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > > > currently there's no certification during resume, which sounds
> > > > unsafe to me. Afterall, the original requirement is to probe
> > > > user for password during resume, which sounds more natural.
> > >
> > > OK, I saw your case. This is a physical accessing.
> > >
> > > I have a question: The suspend to memory also has the same behavior
> > > and more people are using suspend. Should we think a common solution
> > > to cover S3 and S4?
> >
> > Well, we have similar problem during runtime, too ;-).
> >
> > Anyway, I don't think we should encrypt memory during S3 in kernel.
> >
> It seems that Joey was talking about certification(something like login)
> rather than encryption?
>
Actually I do not have good idea.
Joey Lee
On Do, 2018-08-09 at 11:01 +0800, Yu Chen wrote:
Hi,
> User requirement:
> A is the user, B is the attacker, user A launches a STD and
> encrypts A's ram data, then writes these encrypted data onto
> the disk, so that: Even if user B has access to the disk,
> B could not know the content of A. Which implies:
> 1. If B unplugs the disk from A's machine, and plugs the disk onto
> another machine, B could not decode the content without A's
> 'permission'.
That is what encrypted STD does.
> 2. If B is using the same machine as A, even A has walked away leaving
> the system suspend, B could not resume to A's context without
> A's 'permission'.
No, that is out of scope for Secure Boot
> Previously, there are three proposal for this:
> a. Enhance the uswsusp(Pavel)
> b. Using user provided password to generate the key, for encryption(Yu)
> c. Using security boot(TPM or EFI key) for encryption(Joey)
>
> Since I was proposing solution b, I'll say a little more about it.
> The original idea was that, the user provides a password, then this
> password is used to generate the key, which means, if user B has provided
> an incorrect password, the kernel will fail to decrypt the data and is
> likely to fail the resume process. That is to say, no matter
> which physical machine B is using, only if he has provided the
> password, he would be able to resume. In the first version, the key
> deviration was firstly done in kernel space, which satisfies the
> requirement and both saftey. Unfortunately it was rejected and
> people would like to see the key generated in user space instead.
> However, using user provided key directly is not safe, according
> to the discussion in the thread. I don't have good idea on
> how to improve this, but only have some workarounds, say, ask the
> kernel to use TPM key to protects the user provided 'key', etc.
Well, this has no relation to Secure Boot.
Secure Boot will not prevent you from booting the machine.
It restricts the OS you can boot to a cryptographically signed subset.
If you want to demand a password to resume a machine, you can
do so. But it has no relation to encrypted STD, other than that
you need encrypted STD for this to make sense.
> Then let's talk a little more about secure boot. According
> to my understanding, the situation secure boot tries to deal
> with is a little different from the user case we raised above -
> It is an enhancement for case 1, because it refuses to resume
> once the machine is changed. And it does not cover case 2. But
> if it is a requirement from the user, that's ok.
>
> uswsusp is to do all the staff in user space, and other two
> aim to do all the staff in kernel space. I'm not arguing
> which one is better, but I'm not sure how often user is using
> it, as we don't get uswsusp related bug report on kernel
> bugzilla (both internally)recent years. Another point is,
> why the compression is in kernel rather than in uswsusp,
> it looks like the same case as encryption here.
Secure Boot has no concept of users. Code is trusted, not users.
For Secure Boot to work, you need a key generated and RAM encrypted
in kernel space.
If you want a requirement to restrict booting or resuming, you need
to encrypt the key. These are different things.
Regards
Oliver
On Thu, Aug 09, 2018 at 11:01:35AM +0800, Yu Chen wrote:
> Hi Pavel, Joey, Oliver
> Please let me describe the original requirement and my
> understanding about hibernation encryption here, thus
> help us sync on the same thread:
> On Wed, Aug 08, 2018 at 07:50:36PM +0200, Pavel Machek wrote:
> > Hi!
> >
> > > > > > User space doesn't need to involve. The EFI root key is generated by
> > > > > > EFI boot stub and be transfer to kernel. It's stored in EFI boot service
> > > > > > variable that it can only be accessed by trusted EFI binary when
> > > > > > secure boot is enabled.
> > > > > >
> > > > > Okay, this apply to the 'suspend' phase, right?
> > > > > I'm still a little confused about the 'resume' phase.
> > > > > Taking encryption as example(not signature),
> > > > > the purpose of doing hibernation encryption is to prevent other users
> > > > > from stealing ram content. Say, user A uses a passphrase to generate the
> > > >
> > > > No, I don't think that's purpose here.
> > > >
> > > > Purpose here is to prevent user from reading/modifying kernel memory
> > > > content on machine he owns.
> > > >
> > > Say, A puts his laptop into hibernation and walks away,
> > > and B walks by, and opens A's laptop and wakes up the system and he
> > > can do what he wants. Although EFI key/TPM trusted key is enabled,
> > > currently there's no certification during resume, which sounds
> > > unsafe to me. Afterall, the original requirement is to probe
> >
> > Define unsafe.
> >
> > If you want security against bad people resuming your machines, please
> Yes, this is one of the requirements.
> > take a look at existing uswsusp solutions. It defends against that.
> >
> > If you want security against bad people tampering with your machines
> > physically, sorry, there's no way to defend against that.
> No, this is not the requirement.
> >
> > But I thought you were trying to do something for secure boot, and "bad
> > person resumes your machine" is out of scope there.
> >
> Not exactly, secure boot is one solution to meet the requirement.
> > So please always explain security against _what kind of attack_ you
> > are trying to improve; intelligent communication is not possible
> > without that.
> >
> User requirement:
> A is the user, B is the attacker, user A launches a STD and
> encrypts A's ram data, then writes these encrypted data onto
> the disk, so that: Even if user B has access to the disk,
> B could not know the content of A. Which implies:
> 1. If B unplugs the disk from A's machine, and plugs the disk onto
> another machine, B could not decode the content without A's
> 'permission'.
> 2. If B is using the same machine as A, even A has walked away leaving
> the system suspend, B could not resume to A's context without
> A's 'permission'.
>
> Previously, there are three proposal for this:
> a. Enhance the uswsusp(Pavel)
> b. Using user provided password to generate the key, for encryption(Yu)
Base on your A/B users case. Your requirement is a" resume password",
it doesn't really neeed encryption.
Of course we can use the password to encrypt image, but it's not the
key point for your requirement.
> c. Using security boot(TPM or EFI key) for encryption(Joey)
>
No! The EFI key that relies on secure boot is failed. The only
solution is TPM trusted key.
I agreed with Ard's comment on my EFI secure key patches:
https://lkml.org/lkml/2018/8/5/31
"'Secure boot' is a misnomer, since it is too vague: it should be called
'authenticated boot', and the catch is that authentication using
public-key crypto does not involve secrets at all."
So the EFI key can not be accepted because the secure boot is not designed
for confidentiality. So, please forget EFI key. The only solution to
me (or secure boot) is TPM trusted key.
My purpose for developing the hibernation encryption/authentication
is to prevent that the snapshot image be malicious modified. This will
cause that the kernel space is not safe for secure boot (or we call
it authenticated boot). In kernel space, we want to use locked-down
mode to keep kernel space safe.
That's also why I said that user space helper must be authenticated by
kernel. It also prevents malicious key can be enroll to kernel space.
> Since I was proposing solution b, I'll say a little more about it.
> The original idea was that, the user provides a password, then this
> password is used to generate the key, which means, if user B has provided
> an incorrect password, the kernel will fail to decrypt the data and is
> likely to fail the resume process. That is to say, no matter
> which physical machine B is using, only if he has provided the
> password, he would be able to resume. In the first version, the key
> deviration was firstly done in kernel space, which satisfies the
> requirement and both saftey. Unfortunately it was rejected and
> people would like to see the key generated in user space instead.
> However, using user provided key directly is not safe, according
> to the discussion in the thread. I don't have good idea on
> how to improve this, but only have some workarounds, say, ask the
> kernel to use TPM key to protects the user provided 'key', etc.
Do not need to combind two purposes to one solution. Your requirement
is a "resume password", not snapshot encryption. So we can just
encrypt snapshot by TPM encrypted key but still use your tool (or
uswsusp) to provide "resume password" to user. It's not conflict.
If we still want to use the "resume password" to encrypt snapashot
image. That's fine, but hibernation function must be locked-down
when kernel runs in lock-down mode. Because "resume password"
doesn't help anything in lockdown mode. Unless we found a way to
authenticate the user space helper by kernel.
Regards
Joey Lee