Re: [dm-crypt] Re: dm-crypt crypt_status reports key?

From: Fruhwirth Clemens
Date: Fri Feb 04 2005 - 08:35:21 EST


On Thu, Feb 03, 2005 at 03:18:20PM +0100, Fruhwirth Clemens wrote:

> Way too complicated. This is a crypto project, why does nobody think of
> crypto to solve the problem :). Here's the idea:

> [see original post, http://lkml.org/lkml/2005/2/3/109 , for idea]

Very simple patch. With that, it's really hard for root to reveal his real
keys accidentally.

Of course the intended

dmsetup table foo > foo-table
dmsetup remove foo
dmsetup create foo foo-table

works. If anyone is interested in that feature, this fellow has to clean the
patch and push it.

--- linux-2.6.11-rc1-mm1-therp/drivers/md/dm-crypt.c.orig 2005-02-04 12:53:57.000000000 +0100
+++ linux-2.6.11-rc1-mm1-therp/drivers/md/dm-crypt.c 2005-02-04 14:14:34.927560784 +0100
@@ -18,6 +18,7 @@
#include <asm/scatterlist.h>
#include <asm/page.h>

+#include <linux/random.h>
#include "dm.h"

#define PFX "crypt: "
@@ -488,6 +489,33 @@
queue_work(_kcryptd_workqueue, &io->work);
}

+/* Trigger safety */
+
+static char *asure_dc_secret(int want_size) {
+ static char *secret = NULL;
+ static int secret_size = 0;
+
+ // FIXME: obtain some lock
+ if(secret_size < want_size) {
+ char *new_secret = kmalloc(want_size,GFP_KERNEL);
+ // FIXME malloc fail check
+ if(secret) {
+ memcpy(new_secret, secret, secret_size);
+ kfree(secret);
+ }
+
+ get_random_bytes(new_secret+secret_size, want_size - secret_size);
+ secret = new_secret; secret_size = want_size;
+ }
+ return secret;
+}
+
+static void xor_with_secret(char *p, int size) {
+ char *secret = asure_dc_secret(size);
+ while(size--)
+ *p++ ^= *secret++;
+}
+
/*
* Decode key from its hex representation
*/
@@ -496,9 +524,14 @@
char buffer[3];
char *endp;
unsigned int i;
+ int post_process = 0;

buffer[2] = '\0';

+ if(*hex == '!') {
+ post_process = 1;
+ hex++;
+ }
for(i = 0; i < size; i++) {
buffer[0] = *hex++;
buffer[1] = *hex++;
@@ -512,6 +545,9 @@
if (*hex != '\0')
return -EINVAL;

+ if (post_process)
+ xor_with_secret(key,size);
+
return 0;
}

@@ -522,6 +558,7 @@
{
unsigned int i;

+ *hex++ = '!';
for(i = 0; i < size; i++) {
sprintf(hex, "%02x", *key);
hex += 2;
@@ -689,6 +726,8 @@
} else
cc->iv_mode = NULL;

+ xor_with_secret(cc->key, cc->key_size);
+
ti->private = cc;
return 0;

@@ -899,11 +938,11 @@
DMEMIT("%s-%s ", cipher, chainmode);

if (cc->key_size > 0) {
- if ((maxlen - sz) < ((cc->key_size << 1) + 1))
+ if ((maxlen - sz) < ((cc->key_size << 1) + 2))
return -ENOMEM;

crypt_encode_key(result + sz, cc->key, cc->key_size);
- sz += cc->key_size << 1;
+ sz += (cc->key_size << 1) + 1;
} else {
if (sz >= maxlen)
return -ENOMEM;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/