From: Andreas Steinmetz <ast@domdv.de>
To: Pavel Machek <pavel@ucw.cz>
Cc: Linux Kernel Mailinglist <linux-kernel@vger.kernel.org>
Subject: [PATCH encrypted swsusp 1/3] core functionality
Date: Mon, 11 Apr 2005 01:19:16 +0200 [thread overview]
Message-ID: <4259B474.4040407@domdv.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 158 bytes --]
The following patch adds the core functionality for the encrypted
suspend image.
--
Andreas Steinmetz SPAMmers use robotrap@domdv.de
[-- Attachment #2: swsusp-encrypt-core.diff --]
[-- Type: text/plain, Size: 7462 bytes --]
--- linux-2.6.11.2/kernel/power/swsusp.c.ast 2005-04-10 14:08:55.000000000 +0200
+++ linux-2.6.11.2/kernel/power/swsusp.c 2005-04-11 00:50:45.000000000 +0200
@@ -31,6 +31,9 @@
* Alex Badea <vampire@go.ro>:
* Fixed runaway init
*
+ * Andreas Steinmetz <ast@domdv.de>:
+ * Added encrypted suspend option
+ *
* More state savers are welcome. Especially for the scsi layer...
*
* For TODOs,FIXMEs also look in Documentation/power/swsusp.txt
@@ -72,6 +75,16 @@
#include "power.h"
+#ifdef CONFIG_SWSUSP_ENCRYPT
+#include <linux/random.h>
+#include <linux/crypto.h>
+#include <asm/scatterlist.h>
+#endif
+
+#define CIPHER "aes"
+#define MAXKEY 32
+#define MAXIV 32
+
/* References to section boundaries */
extern const void __nosave_begin, __nosave_end;
@@ -103,15 +116,27 @@
#define SWSUSP_SIG "S1SUSPEND"
-static struct swsusp_header {
- char reserved[PAGE_SIZE - 20 - sizeof(swp_entry_t)];
+struct swsusp_header {
+ char reserved[PAGE_SIZE - 20 - MAXKEY - MAXIV - sizeof(swp_entry_t)];
+ u8 key[MAXKEY];
+ u8 iv[MAXIV];
swp_entry_t swsusp_info;
char orig_sig[10];
char sig[10];
-} __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
+} __attribute__((packed, aligned(PAGE_SIZE)));
+
+static union {
+ struct swsusp_header __attribute__((packed, aligned(PAGE_SIZE))) swsusp_header;
+ u8 buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
+} __attribute__((packed, aligned(PAGE_SIZE))) u;
static struct swsusp_info swsusp_info;
+#ifdef CONFIG_SWSUSP_ENCRYPT
+static u8 key[MAXKEY];
+static u8 iv[MAXIV];
+#endif
+
/*
* XXX: We try to keep some more pages free so that I/O operations succeed
* without paging. Might this be more?
@@ -130,22 +155,72 @@
static unsigned short swapfile_used[MAX_SWAPFILES];
static unsigned short root_swap;
+#ifdef CONFIG_SWSUSP_ENCRYPT
+static struct crypto_tfm *crypto_init(int mode)
+{
+ struct crypto_tfm *tfm;
+ int len;
+
+ tfm = crypto_alloc_tfm(CIPHER, CRYPTO_TFM_MODE_CBC);
+ if(!tfm) {
+ printk(KERN_ERR "swsusp: no tfm, suspend not possible\n");
+ return NULL;
+ }
+
+ if(sizeof(key) < crypto_tfm_alg_min_keysize(tfm)) {
+ printk("swsusp: key buffer too small, suspend not possible\n");
+ crypto_free_tfm(tfm);
+ return NULL;
+ }
+
+ if (sizeof(iv) < crypto_tfm_alg_ivsize(tfm)) {
+ printk("swsusp: iv buffer too small, suspend not possible\n");
+ crypto_free_tfm(tfm);
+ return NULL;
+ }
+
+ if (mode) {
+ get_random_bytes(key, MAXKEY);
+ get_random_bytes(iv, MAXIV);
+ }
+
+ len = crypto_tfm_alg_max_keysize(tfm);
+ if (len > sizeof(key))
+ len = sizeof(key);
+
+ if (crypto_cipher_setkey(tfm, key, len)) {
+ printk(KERN_ERR "swsusp: key setup failure, suspend not possible\n");
+ crypto_free_tfm(tfm);
+ return NULL;
+ }
+
+ len = crypto_tfm_alg_blocksize(tfm);
+ crypto_cipher_set_iv(tfm, iv, len);
+
+ return tfm;
+}
+#endif
+
static int mark_swapfiles(swp_entry_t prev)
{
int error;
rw_swap_page_sync(READ,
swp_entry(root_swap, 0),
- virt_to_page((unsigned long)&swsusp_header));
- if (!memcmp("SWAP-SPACE",swsusp_header.sig, 10) ||
- !memcmp("SWAPSPACE2",swsusp_header.sig, 10)) {
- memcpy(swsusp_header.orig_sig,swsusp_header.sig, 10);
- memcpy(swsusp_header.sig,SWSUSP_SIG, 10);
- swsusp_header.swsusp_info = prev;
+ virt_to_page((unsigned long)&u.swsusp_header));
+ if (!memcmp("SWAP-SPACE",u.swsusp_header.sig, 10) ||
+ !memcmp("SWAPSPACE2",u.swsusp_header.sig, 10)) {
+ memcpy(u.swsusp_header.orig_sig,u.swsusp_header.sig, 10);
+ memcpy(u.swsusp_header.sig,SWSUSP_SIG, 10);
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ memcpy(u.swsusp_header.key, key, MAXKEY);
+ memcpy(u.swsusp_header.iv, iv, MAXIV);
+#endif
+ u.swsusp_header.swsusp_info = prev;
error = rw_swap_page_sync(WRITE,
swp_entry(root_swap, 0),
virt_to_page((unsigned long)
- &swsusp_header));
+ &u.swsusp_header));
} else {
pr_debug("swsusp: Partition is not swap space.\n");
error = -ENODEV;
@@ -294,6 +369,19 @@
int error = 0;
int i;
unsigned int mod = nr_copy_pages / 100;
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ struct crypto_tfm *tfm;
+ struct scatterlist src, dst;
+
+ if (!(tfm = crypto_init(1)))
+ return -EINVAL;
+
+ src.offset = 0;
+ src.length = PAGE_SIZE;
+ dst.page = virt_to_page(u.buffer);
+ dst.offset = 0;
+ dst.length = PAGE_SIZE;
+#endif
if (!mod)
mod = 1;
@@ -302,10 +390,22 @@
for (i = 0; i < nr_copy_pages && !error; i++) {
if (!(i%mod))
printk( "\b\b\b\b%3d%%", i / mod );
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ src.page = virt_to_page((pagedir_nosave+i)->address);
+ error = crypto_cipher_encrypt_iv(tfm, &dst, &src,
+ PAGE_SIZE, iv);
+ if (!error)
+ error = write_page((unsigned long)u.buffer,
+ &((pagedir_nosave+i)->swap_address));
+#else
error = write_page((pagedir_nosave+i)->address,
&((pagedir_nosave+i)->swap_address));
+#endif
}
printk("\b\b\b\bdone\n");
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ crypto_free_tfm(tfm);
+#endif
return error;
}
@@ -404,6 +504,10 @@
if ((error = close_swap()))
goto FreePagedir;
Done:
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ memset(key, 0, MAXKEY);
+ memset(iv, 0, MAXIV);
+#endif
return error;
FreePagedir:
free_pagedir_entries();
@@ -1101,7 +1205,7 @@
const char * reason = NULL;
int error;
- if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
+ if ((error = bio_read_page(swp_offset(u.swsusp_header.swsusp_info), &swsusp_info)))
return error;
/* Is this same machine? */
@@ -1118,16 +1222,21 @@
{
int error;
- memset(&swsusp_header, 0, sizeof(swsusp_header));
- if ((error = bio_read_page(0, &swsusp_header)))
+ memset(&u.swsusp_header, 0, sizeof(u.swsusp_header));
+ if ((error = bio_read_page(0, &u.swsusp_header)))
return error;
- if (!memcmp(SWSUSP_SIG, swsusp_header.sig, 10)) {
- memcpy(swsusp_header.sig, swsusp_header.orig_sig, 10);
-
+ if (!memcmp(SWSUSP_SIG, u.swsusp_header.sig, 10)) {
+ memcpy(u.swsusp_header.sig, u.swsusp_header.orig_sig, 10);
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ memcpy(key, u.swsusp_header.key, MAXKEY);
+ memcpy(iv, u.swsusp_header.iv, MAXIV);
+ memset(u.swsusp_header.key, 0, MAXKEY);
+ memset(u.swsusp_header.iv, 0, MAXIV);
+#endif
/*
* Reset swap signature now.
*/
- error = bio_write_page(0, &swsusp_header);
+ error = bio_write_page(0, &u.swsusp_header);
} else {
pr_debug(KERN_ERR "swsusp: Suspend partition has wrong signature?\n");
return -EINVAL;
@@ -1150,6 +1259,18 @@
int error;
int i;
int mod = nr_copy_pages / 100;
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ struct crypto_tfm *tfm;
+ struct scatterlist src, dst;
+
+ if (!(tfm = crypto_init(0)))
+ return -EINVAL;
+
+ src.offset = 0;
+ src.length = PAGE_SIZE;
+ dst.offset = 0;
+ dst.length = PAGE_SIZE;
+#endif
if (!mod)
mod = 1;
@@ -1163,8 +1284,18 @@
printk( "\b\b\b\b%3d%%", i / mod );
error = bio_read_page(swp_offset(p->swap_address),
(void *)p->address);
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ if (!error) {
+ src.page = dst.page = virt_to_page((void *)p->address);
+ error = crypto_cipher_decrypt_iv(tfm, &dst, &src,
+ PAGE_SIZE, iv);
+ }
+#endif
}
printk(" %d done.\n",i);
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ crypto_free_tfm(tfm);
+#endif
return error;
}
@@ -1233,6 +1364,11 @@
} else
error = PTR_ERR(resume_bdev);
+#ifdef CONFIG_SWSUSP_ENCRYPT
+ memset(key, 0, MAXKEY);
+ memset(iv, 0, MAXIV);
+#endif
+
if (!error)
pr_debug("Reading resume file was successful\n");
else
next reply other threads:[~2005-04-10 23:35 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-10 23:19 Andreas Steinmetz [this message]
2005-04-11 10:25 ` [PATCH encrypted swsusp 1/3] core functionality Pavel Machek
2005-04-11 10:36 ` folkert
2005-04-11 11:01 ` Pavel Machek
2005-04-11 11:38 ` folkert
2005-04-11 16:28 ` Andreas Steinmetz
2005-04-11 16:36 ` Pavel Machek
2005-04-11 13:08 ` Andreas Steinmetz
2005-04-11 11:08 ` Pavel Machek
2005-04-11 13:11 ` Andreas Steinmetz
2005-04-11 16:11 ` Andreas Steinmetz
2005-04-11 20:57 ` Rafael J. Wysocki
2005-04-11 21:08 ` Pavel Machek
2005-04-11 21:35 ` Rafael J. Wysocki
2005-04-12 10:07 ` Andreas Steinmetz
2005-04-12 10:52 ` Andreas Steinmetz
2005-04-12 13:17 ` Andreas Steinmetz
2005-04-13 11:59 ` Herbert Xu
2005-04-13 12:59 ` Andreas Steinmetz
2005-04-13 21:27 ` Herbert Xu
2005-04-13 22:29 ` Andreas Steinmetz
2005-04-13 23:10 ` Herbert Xu
2005-04-13 23:24 ` Pavel Machek
2005-04-13 23:39 ` Herbert Xu
2005-04-13 23:46 ` Pavel Machek
2005-04-14 0:35 ` Matt Mackall
2005-04-14 6:51 ` Pavel Machek
2005-04-14 8:08 ` Herbert Xu
2005-04-14 9:04 ` Rafael J. Wysocki
2005-04-14 17:11 ` Matt Mackall
2005-04-14 19:27 ` Stefan Seyfried
2005-04-14 19:53 ` Matt Mackall
2005-04-14 20:18 ` Pavel Machek
2005-04-14 22:27 ` Matt Mackall
2005-04-14 22:11 ` Andy Isaacson
2005-04-14 22:48 ` Matt Mackall
2005-04-15 9:44 ` Andreas Steinmetz
2005-04-15 9:44 ` Andreas Steinmetz
2005-04-15 17:00 ` Matt Mackall
2005-04-14 20:13 ` Pavel Machek
2005-04-14 9:05 ` Pavel Machek
2005-04-15 9:44 ` Andreas Steinmetz
2005-04-15 9:47 ` Pavel Machek
2005-04-14 1:13 ` Bernd Eckenfels
2005-04-14 8:27 ` Pavel Machek
2005-04-14 8:31 ` encrypted swap (was Re: [PATCH encrypted swsusp 1/3] core functionality) Andy Isaacson
2005-04-14 8:38 ` Herbert Xu
2005-04-14 8:49 ` Arjan van de Ven
2005-04-14 1:11 ` [PATCH encrypted swsusp 1/3] core functionality Bernd Eckenfels
2005-04-13 13:22 ` Pavel Machek
2005-04-13 14:45 ` Andreas Steinmetz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4259B474.4040407@domdv.de \
--to=ast@domdv.de \
--cc=linux-kernel@vger.kernel.org \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox