All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type
@ 2011-01-24 16:44 Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description Roberto Sassu
                   ` (11 more replies)
  0 siblings, 12 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 1565 bytes --]

This patch set adds support for the 'encrypted' key type in the eCryptfs
filesystem.

Changelog from version v2:
- rebased on the latest commit of the mainline kernel (d315777b32a);
- added two new functions ecryptfs_get_encrypted_key_payload_data() and
  ecryptfs_get_encrypted_key() in the file fs/ecryptfs/ecryptfs_kernel.h.

Roberto Sassu


Roberto Sassu (6):
  encrypted-keys: fixed valid_master_desc() function description
  encrypted-keys: added additional debug messages
  encrypted-keys: add key format support
  eCryptfs: export global eCryptfs definitions to
    include/linux/ecryptfs.h
  encrypted-keys: add ecryptfs format support
  eCryptfs: added support for the encrypted key type

 Documentation/keys-ecryptfs.txt          |   68 +++++++++
 Documentation/keys-trusted-encrypted.txt |   52 ++++---
 fs/ecryptfs/ecryptfs_kernel.h            |  150 +++++--------------
 fs/ecryptfs/keystore.c                   |   11 +-
 include/keys/encrypted-type.h            |   13 ++-
 include/linux/ecryptfs.h                 |  113 ++++++++++++++
 security/keys/Makefile                   |    2 +-
 security/keys/encrypted.c                |  242 ++++++++++++++++++++++++------
 security/keys/keys_ecryptfs.c            |   81 ++++++++++
 security/keys/keys_ecryptfs.h            |   30 ++++
 10 files changed, 577 insertions(+), 185 deletions(-)
 create mode 100644 Documentation/keys-ecryptfs.txt
 create mode 100644 include/linux/ecryptfs.h
 create mode 100644 security/keys/keys_ecryptfs.c
 create mode 100644 security/keys/keys_ecryptfs.h

-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages Roberto Sassu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 815 bytes --]

Valid key type prefixes for the parameter 'key-type' are: 'trusted' and
'user'.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
---
 security/keys/encrypted.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 9e7e4ce..6135836 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -84,7 +84,7 @@ static int aes_get_sizes(void)
 /*
  * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
  *
- * key-type:= "trusted:" | "encrypted:"
+ * key-type:= "trusted:" | "user:"
  * desc:= master-key description
  *
  * Verify that 'key-type' is valid and that 'desc' exists. On key update,
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support Roberto Sassu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 2644 bytes --]

Some debug messages have been added in the function datablob_parse() in
order to better identify errors returned when dealing with 'encrypted'
keys.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
---
 security/keys/encrypted.c |   44 +++++++++++++++++++++++++++++++++-----------
 1 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 6135836..322e979 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -133,46 +133,68 @@ static int datablob_parse(char *datablob, char **master_desc,
 	substring_t args[MAX_OPT_ARGS];
 	int ret = -EINVAL;
 	int key_cmd;
-	char *p;
+	char *keyword;
 
-	p = strsep(&datablob, " \t");
-	if (!p)
+	keyword = strsep(&datablob, " \t");
+	if (!keyword) {
+		pr_err("encrypted_key: insufficient parameters specified\n");
 		return ret;
-	key_cmd = match_token(p, key_tokens, args);
+	}
+	key_cmd = match_token(keyword, key_tokens, args);
 
 	*master_desc = strsep(&datablob, " \t");
-	if (!*master_desc)
+	if (!*master_desc) {
+		pr_err("encrypted_key: master key parameter is missing\n");
 		goto out;
+	}
 
-	if (valid_master_desc(*master_desc, NULL) < 0)
+	if (valid_master_desc(*master_desc, NULL) < 0) {
+		pr_err("encrypted_key: master key parameter \'%s\' "
+		       "is invalid\n", *master_desc);
 		goto out;
+	}
 
 	if (decrypted_datalen) {
 		*decrypted_datalen = strsep(&datablob, " \t");
-		if (!*decrypted_datalen)
+		if (!*decrypted_datalen) {
+			pr_err("encrypted_key: keylen parameter is missing\n");
 			goto out;
+		}
 	}
 
 	switch (key_cmd) {
 	case Opt_new:
-		if (!decrypted_datalen)
+		if (!decrypted_datalen) {
+			pr_err("encrypted_key: keyword \'%s\' not allowed when "
+			       "updating an existent key\n", keyword);
 			break;
+		}
 		ret = 0;
 		break;
 	case Opt_load:
-		if (!decrypted_datalen)
+		if (!decrypted_datalen) {
+			pr_err("encrypted_key: keyword \'%s\' not allowed when "
+			       "updating an existent key\n", keyword);
 			break;
+		}
 		*hex_encoded_iv = strsep(&datablob, " \t");
-		if (!*hex_encoded_iv)
+		if (!*hex_encoded_iv) {
+			pr_err("encrypted_key: hex blob is missing\n");
 			break;
+		}
 		ret = 0;
 		break;
 	case Opt_update:
-		if (decrypted_datalen)
+		if (decrypted_datalen) {
+			pr_err("encrypted_key: keyword \'%s\' not allowed when "
+			       "instantiating a new key\n", keyword);
 			break;
+		}
 		ret = 0;
 		break;
 	case Opt_err:
+		pr_err("encrypted_key: keyword \'%s\' not recognized\n",
+		       keyword);
 		break;
 	}
 out:
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 3/6] encrypted-keys: add key format support
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h Roberto Sassu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 18072 bytes --]

This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: Mimi Zohar <zohar@us.ibm.com>
---
 Documentation/keys-trusted-encrypted.txt |   48 +++++++----
 include/keys/encrypted-type.h            |   13 +++-
 security/keys/encrypted.c                |  141 +++++++++++++++++++++---------
 3 files changed, 142 insertions(+), 60 deletions(-)

diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
index 8fb79bc..0afcb50 100644
--- a/Documentation/keys-trusted-encrypted.txt
+++ b/Documentation/keys-trusted-encrypted.txt
@@ -53,12 +53,19 @@ they are only as secure as the user key encrypting them.  The master user key
 should therefore be loaded in as secure a way as possible, preferably early in
 boot.
 
+The decrypted portion of encrypted keys can contain either a simple symmetric
+key or a more complex structure. The format of the more complex structure is
+application specific, which is identified by 'format'.
+
 Usage:
-  keyctl add encrypted name "new key-type:master-key-name keylen" ring
-  keyctl add encrypted name "load hex_blob" ring
-  keyctl update keyid "update key-type:master-key-name"
+    keyctl add encrypted name "new [format] key-type:master-key-name keylen"
+        ring
+    keyctl add encrypted name "load hex_blob" ring
+    keyctl update keyid "update key-type:master-key-name"
+
+format:= 'default'
+key-type:= 'trusted' | 'user'
 
-where 'key-type' is either 'trusted' or 'user'.
 
 Examples of trusted and encrypted key usage:
 
@@ -114,15 +121,25 @@ Reseal a trusted key under new pcr values:
     7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
     df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8
 
-Create and save an encrypted key "evm" using the above trusted key "kmk":
+The initial consumer of trusted keys is EVM, which at boot time needs a high
+quality symmetric key for HMAC protection of file metadata.  The use of a
+trusted key provides strong guarantees that the EVM key has not been
+compromised by a user level problem, and when sealed to specific boot PCR
+values, protects against boot and offline attacks.  Create and save an
+encrypted key "evm" using the above trusted key "kmk":
 
+option 1: omitting 'format'
     $ keyctl add encrypted evm "new trusted:kmk 32" @u
     159771175
 
+option 2: explicitly defining 'format' as 'default'
+    $ keyctl add encrypted evm "new default trusted:kmk 32" @u
+    159771175
+
     $ keyctl print 159771175
-    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
-    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
-    5972dcb82ab2dde83376d82b2e3c09ffc
+    default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+    82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+    24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
 
     $ keyctl pipe 159771175 > evm.blob
 
@@ -132,14 +149,9 @@ Load an encrypted key "evm" from saved blob:
     831684262
 
     $ keyctl print 831684262
-    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
-    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
-    5972dcb82ab2dde83376d82b2e3c09ffc
-
+    default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3
+    82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0
+    24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
 
-The initial consumer of trusted keys is EVM, which at boot time needs a high
-quality symmetric key for HMAC protection of file metadata.  The use of a
-trusted key provides strong guarantees that the EVM key has not been
-compromised by a user level problem, and when sealed to specific boot PCR
-values, protects against boot and offline attacks.  Other uses for trusted and
-encrypted keys, such as for disk and file encryption are anticipated.
+Other uses for trusted and encrypted keys, such as for disk and file encryption
+are anticipated.
diff --git a/include/keys/encrypted-type.h b/include/keys/encrypted-type.h
index 9585501..1d45413 100644
--- a/include/keys/encrypted-type.h
+++ b/include/keys/encrypted-type.h
@@ -1,6 +1,11 @@
 /*
  * Copyright (C) 2010 IBM Corporation
- * Author: Mimi Zohar <zohar@us.ibm.com>
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ *                    TORSEC group -- http://security.polito.it
+ *
+ * Authors:
+ * Mimi Zohar <zohar@us.ibm.com>
+ * Roberto Sassu <roberto.sassu@polito.it>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -15,13 +20,17 @@
 
 struct encrypted_key_payload {
 	struct rcu_head rcu;
+	char *format;		/* datablob: format */
 	char *master_desc;	/* datablob: master key name */
 	char *datalen;		/* datablob: decrypted key length */
 	u8 *iv;			/* datablob: iv */
 	u8 *encrypted_data;	/* datablob: encrypted data */
 	unsigned short datablob_len;	/* length of datablob */
 	unsigned short decrypted_datalen;	/* decrypted data length */
-	u8 decrypted_data[0];	/* decrypted data +  datablob + hmac */
+	unsigned short payload_datalen;		/* payload data length */
+	unsigned short encrypted_key_format;	/* encrypted key format */
+	u8 *decrypted_data;	/* decrypted data */
+	u8 payload_data[0];	/* payload data + datablob + hmac */
 };
 
 extern struct key_type key_type_encrypted;
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 322e979..59f719e 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -1,8 +1,11 @@
 /*
  * Copyright (C) 2010 IBM Corporation
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ *                    TORSEC group -- http://security.polito.it
  *
- * Author:
+ * Authors:
  * Mimi Zohar <zohar@us.ibm.com>
+ * Roberto Sassu <roberto.sassu@polito.it>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,6 +40,7 @@ static const char KEY_USER_PREFIX[] = "user:";
 static const char hash_alg[] = "sha256";
 static const char hmac_alg[] = "hmac(sha256)";
 static const char blkcipher_alg[] = "cbc(aes)";
+static const char key_format_default[] = "default";
 static unsigned int ivsize;
 static int blksize;
 
@@ -58,6 +62,15 @@ enum {
 	Opt_err = -1, Opt_new, Opt_load, Opt_update
 };
 
+enum {
+	Opt_error = -1, Opt_default
+};
+
+static const match_table_t key_format_tokens = {
+	{Opt_default, "default"},
+	{Opt_error, NULL}
+};
+
 static const match_table_t key_tokens = {
 	{Opt_new, "new"},
 	{Opt_load, "load"},
@@ -118,8 +131,9 @@ out:
  * datablob_parse - parse the keyctl data
  *
  * datablob format:
- * new <master-key name> <decrypted data length>
- * load <master-key name> <decrypted data length> <encrypted iv + data>
+ * new [<format>] <master-key name> <decrypted data length>
+ * load [<format>] <master-key name> <decrypted data length>
+ *     <encrypted iv + data>
  * update <new-master-key name>
  *
  * Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,13 +141,15 @@ out:
  *
  * On success returns 0, otherwise -EINVAL.
  */
-static int datablob_parse(char *datablob, char **master_desc,
-			  char **decrypted_datalen, char **hex_encoded_iv)
+static int datablob_parse(char *datablob, const char **format,
+			  char **master_desc, char **decrypted_datalen,
+			  char **hex_encoded_iv)
 {
 	substring_t args[MAX_OPT_ARGS];
 	int ret = -EINVAL;
 	int key_cmd;
-	char *keyword;
+	int key_format;
+	char *p, *keyword;
 
 	keyword = strsep(&datablob, " \t");
 	if (!keyword) {
@@ -142,7 +158,24 @@ static int datablob_parse(char *datablob, char **master_desc,
 	}
 	key_cmd = match_token(keyword, key_tokens, args);
 
-	*master_desc = strsep(&datablob, " \t");
+	/* Get optional format: default */
+	p = strsep(&datablob, " \t");
+	if (!p) {
+		pr_err("encrypted_key: insufficient parameters specified\n");
+		return ret;
+	}
+
+	key_format = match_token(p, key_format_tokens, args);
+	switch (key_format) {
+	case Opt_default:
+		*format = p;
+		*master_desc = strsep(&datablob, " \t");
+		break;
+	case Opt_error:
+		*master_desc = p;
+		break;
+	}
+
 	if (!*master_desc) {
 		pr_err("encrypted_key: master key parameter is missing\n");
 		goto out;
@@ -219,8 +252,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
 	ascii_buf[asciiblob_len] = '\0';
 
 	/* copy datablob master_desc and datalen strings */
-	len = sprintf(ascii_buf, "%s %s ", epayload->master_desc,
-		      epayload->datalen);
+	len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
+		      epayload->master_desc, epayload->datalen);
 
 	/* convert the hex encoded iv, encrypted-data and HMAC to ascii */
 	bufp = &ascii_buf[len];
@@ -461,9 +494,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
 	if (ret < 0)
 		goto out;
 
-	digest = epayload->master_desc + epayload->datablob_len;
+	digest = epayload->format + epayload->datablob_len;
 	ret = calc_hmac(digest, derived_key, sizeof derived_key,
-			epayload->master_desc, epayload->datablob_len);
+			epayload->format, epayload->datablob_len);
 	if (!ret)
 		dump_hmac(NULL, digest, HASH_SIZE);
 out:
@@ -472,26 +505,35 @@ out:
 
 /* verify HMAC before decrypting encrypted key */
 static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
-				const u8 *master_key, size_t master_keylen)
+				const u8 *format, const u8 *master_key,
+				size_t master_keylen)
 {
 	u8 derived_key[HASH_SIZE];
 	u8 digest[HASH_SIZE];
 	int ret;
+	char *p;
+	unsigned short len;
 
 	ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
 	if (ret < 0)
 		goto out;
 
-	ret = calc_hmac(digest, derived_key, sizeof derived_key,
-			epayload->master_desc, epayload->datablob_len);
+	len = epayload->datablob_len;
+	if (!format) {
+		p = epayload->master_desc;
+		len -= strlen(epayload->format) + 1;
+	} else
+		p = epayload->format;
+
+	ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
 	if (ret < 0)
 		goto out;
-	ret = memcmp(digest, epayload->master_desc + epayload->datablob_len,
+	ret = memcmp(digest, epayload->format + epayload->datablob_len,
 		     sizeof digest);
 	if (ret) {
 		ret = -EINVAL;
 		dump_hmac("datablob",
-			  epayload->master_desc + epayload->datablob_len,
+			  epayload->format + epayload->datablob_len,
 			  HASH_SIZE);
 		dump_hmac("calc", digest, HASH_SIZE);
 	}
@@ -536,13 +578,16 @@ out:
 
 /* Allocate memory for decrypted key and datablob. */
 static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
+							 const char *format,
 							 const char *master_desc,
 							 const char *datalen)
 {
 	struct encrypted_key_payload *epayload = NULL;
 	unsigned short datablob_len;
 	unsigned short decrypted_datalen;
+	unsigned short payload_datalen;
 	unsigned int encrypted_datalen;
+	unsigned int format_len;
 	long dlen;
 	int ret;
 
@@ -550,29 +595,32 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
 	if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
 		return ERR_PTR(-EINVAL);
 
+	format_len = (!format) ? strlen(key_format_default) : strlen(format);
 	decrypted_datalen = dlen;
+	payload_datalen = decrypted_datalen;
 	encrypted_datalen = roundup(decrypted_datalen, blksize);
 
-	datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1
-	    + ivsize + 1 + encrypted_datalen;
+	datablob_len = format_len + 1 + strlen(master_desc) + 1
+	    + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
 
-	ret = key_payload_reserve(key, decrypted_datalen + datablob_len
+	ret = key_payload_reserve(key, payload_datalen + datablob_len
 				  + HASH_SIZE + 1);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
-	epayload = kzalloc(sizeof(*epayload) + decrypted_datalen +
+	epayload = kzalloc(sizeof(*epayload) + payload_datalen +
 			   datablob_len + HASH_SIZE + 1, GFP_KERNEL);
 	if (!epayload)
 		return ERR_PTR(-ENOMEM);
 
+	epayload->payload_datalen = payload_datalen;
 	epayload->decrypted_datalen = decrypted_datalen;
 	epayload->datablob_len = datablob_len;
 	return epayload;
 }
 
 static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
-				 const char *hex_encoded_iv)
+				 const char *format, const char *hex_encoded_iv)
 {
 	struct key *mkey;
 	u8 derived_key[HASH_SIZE];
@@ -593,14 +641,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
 	hex2bin(epayload->iv, hex_encoded_iv, ivsize);
 	hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
 
-	hmac = epayload->master_desc + epayload->datablob_len;
+	hmac = epayload->format + epayload->datablob_len;
 	hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
 
 	mkey = request_master_key(epayload, &master_key, &master_keylen);
 	if (IS_ERR(mkey))
 		return PTR_ERR(mkey);
 
-	ret = datablob_hmac_verify(epayload, master_key, master_keylen);
+	ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
 	if (ret < 0) {
 		pr_err("encrypted_key: bad hmac (%d)\n", ret);
 		goto out;
@@ -620,14 +668,23 @@ out:
 }
 
 static void __ekey_init(struct encrypted_key_payload *epayload,
-			const char *master_desc, const char *datalen)
+			const char *format, const char *master_desc,
+			const char *datalen)
 {
-	epayload->master_desc = epayload->decrypted_data
-	    + epayload->decrypted_datalen;
+	unsigned int format_len;
+
+	format_len = (!format) ? strlen(key_format_default) : strlen(format);
+	epayload->format = epayload->payload_data + epayload->payload_datalen;
+	epayload->master_desc = epayload->format + format_len + 1;
 	epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
 	epayload->iv = epayload->datalen + strlen(datalen) + 1;
 	epayload->encrypted_data = epayload->iv + ivsize + 1;
+	epayload->decrypted_data = epayload->payload_data;
 
+	if (!format)
+		memcpy(epayload->format, key_format_default, format_len);
+	else
+		memcpy(epayload->format, format, format_len);
 	memcpy(epayload->master_desc, master_desc, strlen(master_desc));
 	memcpy(epayload->datalen, datalen, strlen(datalen));
 }
@@ -639,19 +696,19 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
  * itself.  For an old key, decrypt the hex encoded data.
  */
 static int encrypted_init(struct encrypted_key_payload *epayload,
-			  const char *master_desc, const char *datalen,
-			  const char *hex_encoded_iv)
+			  const char *format, const char *master_desc,
+			  const char *datalen, const char *hex_encoded_iv)
 {
 	int ret = 0;
 
-	__ekey_init(epayload, master_desc, datalen);
+	__ekey_init(epayload, format, master_desc, datalen);
 	if (!hex_encoded_iv) {
 		get_random_bytes(epayload->iv, ivsize);
 
 		get_random_bytes(epayload->decrypted_data,
 				 epayload->decrypted_datalen);
 	} else
-		ret = encrypted_key_decrypt(epayload, hex_encoded_iv);
+		ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
 	return ret;
 }
 
@@ -668,6 +725,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
 {
 	struct encrypted_key_payload *epayload = NULL;
 	char *datablob = NULL;
+	const char *format = NULL;
 	char *master_desc = NULL;
 	char *decrypted_datalen = NULL;
 	char *hex_encoded_iv = NULL;
@@ -681,17 +739,18 @@ static int encrypted_instantiate(struct key *key, const void *data,
 		return -ENOMEM;
 	datablob[datalen] = 0;
 	memcpy(datablob, data, datalen);
-	ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
-			     &hex_encoded_iv);
+	ret = datablob_parse(datablob, &format, &master_desc,
+			     &decrypted_datalen, &hex_encoded_iv);
 	if (ret < 0)
 		goto out;
 
-	epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen);
+	epayload = encrypted_key_alloc(key, format, master_desc,
+				       decrypted_datalen);
 	if (IS_ERR(epayload)) {
 		ret = PTR_ERR(epayload);
 		goto out;
 	}
-	ret = encrypted_init(epayload, master_desc, decrypted_datalen,
+	ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
 			     hex_encoded_iv);
 	if (ret < 0) {
 		kfree(epayload);
@@ -728,6 +787,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
 	struct encrypted_key_payload *new_epayload;
 	char *buf;
 	char *new_master_desc = NULL;
+	const char *format = NULL;
 	int ret = 0;
 
 	if (datalen <= 0 || datalen > 32767 || !data)
@@ -739,7 +799,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
 
 	buf[datalen] = 0;
 	memcpy(buf, data, datalen);
-	ret = datablob_parse(buf, &new_master_desc, NULL, NULL);
+	ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -747,18 +807,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
 	if (ret < 0)
 		goto out;
 
-	new_epayload = encrypted_key_alloc(key, new_master_desc,
-					   epayload->datalen);
+	new_epayload = encrypted_key_alloc(key, epayload->format,
+					   new_master_desc, epayload->datalen);
 	if (IS_ERR(new_epayload)) {
 		ret = PTR_ERR(new_epayload);
 		goto out;
 	}
 
-	__ekey_init(new_epayload, new_master_desc, epayload->datalen);
+	__ekey_init(new_epayload, epayload->format, new_master_desc,
+		    epayload->datalen);
 
 	memcpy(new_epayload->iv, epayload->iv, ivsize);
-	memcpy(new_epayload->decrypted_data, epayload->decrypted_data,
-	       epayload->decrypted_datalen);
+	memcpy(new_epayload->payload_data, epayload->payload_data,
+	       epayload->payload_datalen);
 
 	rcu_assign_pointer(key->payload.data, new_epayload);
 	call_rcu(&epayload->rcu, encrypted_rcu_free);
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (2 preceding siblings ...)
  2011-01-24 16:44 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-24 16:44 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support Roberto Sassu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 10261 bytes --]

Some eCryptfs specific definitions, such as the current version and the
authentication token structure, are moved to the new include file
'include/linux/ecryptfs.h', in order to be available for all kernel
subsystems.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
---
 fs/ecryptfs/ecryptfs_kernel.h |  109 +---------------------------------------
 include/linux/ecryptfs.h      |  113 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+), 108 deletions(-)
 create mode 100644 include/linux/ecryptfs.h

diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index dbc84ed..2e2242f 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -36,125 +36,18 @@
 #include <linux/hash.h>
 #include <linux/nsproxy.h>
 #include <linux/backing-dev.h>
+#include <linux/ecryptfs.h>
 
-/* Version verification for shared data structures w/ userspace */
-#define ECRYPTFS_VERSION_MAJOR 0x00
-#define ECRYPTFS_VERSION_MINOR 0x04
-#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
-/* These flags indicate which features are supported by the kernel
- * module; userspace tools such as the mount helper read
- * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
- * how to behave. */
-#define ECRYPTFS_VERSIONING_PASSPHRASE            0x00000001
-#define ECRYPTFS_VERSIONING_PUBKEY                0x00000002
-#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
-#define ECRYPTFS_VERSIONING_POLICY                0x00000008
-#define ECRYPTFS_VERSIONING_XATTR                 0x00000010
-#define ECRYPTFS_VERSIONING_MULTKEY               0x00000020
-#define ECRYPTFS_VERSIONING_DEVMISC               0x00000040
-#define ECRYPTFS_VERSIONING_HMAC                  0x00000080
-#define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION   0x00000100
-#define ECRYPTFS_VERSIONING_GCM                   0x00000200
-#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
-				  | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
-				  | ECRYPTFS_VERSIONING_PUBKEY \
-				  | ECRYPTFS_VERSIONING_XATTR \
-				  | ECRYPTFS_VERSIONING_MULTKEY \
-				  | ECRYPTFS_VERSIONING_DEVMISC \
-				  | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
-#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
-#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
-#define ECRYPTFS_SALT_SIZE 8
-#define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2)
-/* The original signature size is only for what is stored on disk; all
- * in-memory representations are expanded hex, so it better adapted to
- * be passed around or referenced on the command line */
-#define ECRYPTFS_SIG_SIZE 8
-#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
-#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
-#define ECRYPTFS_MAX_KEY_BYTES 64
-#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
 #define ECRYPTFS_DEFAULT_IV_BYTES 16
-#define ECRYPTFS_FILE_VERSION 0x03
 #define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
 #define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
 #define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32
 #define ECRYPTFS_DEFAULT_SEND_TIMEOUT HZ
 #define ECRYPTFS_MAX_MSG_CTX_TTL (HZ*3)
-#define ECRYPTFS_MAX_PKI_NAME_BYTES 16
 #define ECRYPTFS_DEFAULT_NUM_USERS 4
 #define ECRYPTFS_MAX_NUM_USERS 32768
 #define ECRYPTFS_XATTR_NAME "user.ecryptfs"
 
-#define RFC2440_CIPHER_DES3_EDE 0x02
-#define RFC2440_CIPHER_CAST_5 0x03
-#define RFC2440_CIPHER_BLOWFISH 0x04
-#define RFC2440_CIPHER_AES_128 0x07
-#define RFC2440_CIPHER_AES_192 0x08
-#define RFC2440_CIPHER_AES_256 0x09
-#define RFC2440_CIPHER_TWOFISH 0x0a
-#define RFC2440_CIPHER_CAST_6 0x0b
-
-#define RFC2440_CIPHER_RSA 0x01
-
-/**
- * For convenience, we may need to pass around the encrypted session
- * key between kernel and userspace because the authentication token
- * may not be extractable.  For example, the TPM may not release the
- * private key, instead requiring the encrypted data and returning the
- * decrypted data.
- */
-struct ecryptfs_session_key {
-#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
-#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
-#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
-#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
-	u32 flags;
-	u32 encrypted_key_size;
-	u32 decrypted_key_size;
-	u8 encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
-	u8 decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
-};
-
-struct ecryptfs_password {
-	u32 password_bytes;
-	s32 hash_algo;
-	u32 hash_iterations;
-	u32 session_key_encryption_key_bytes;
-#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
-#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
-	u32 flags;
-	/* Iterated-hash concatenation of salt and passphrase */
-	u8 session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
-	u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
-	/* Always in expanded hex */
-	u8 salt[ECRYPTFS_SALT_SIZE];
-};
-
-enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
-
-struct ecryptfs_private_key {
-	u32 key_size;
-	u32 data_len;
-	u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
-	char pki_type[ECRYPTFS_MAX_PKI_NAME_BYTES + 1];
-	u8 data[];
-};
-
-/* May be a password or a private key */
-struct ecryptfs_auth_tok {
-	u16 version; /* 8-bit major and 8-bit minor */
-	u16 token_type;
-#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
-	u32 flags;
-	struct ecryptfs_session_key session_key;
-	u8 reserved[32];
-	union {
-		struct ecryptfs_password password;
-		struct ecryptfs_private_key private_key;
-	} token;
-} __attribute__ ((packed));
-
 void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok);
 extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size);
 extern void ecryptfs_from_hex(char *dst, char *src, int dst_size);
diff --git a/include/linux/ecryptfs.h b/include/linux/ecryptfs.h
new file mode 100644
index 0000000..2224a8c
--- /dev/null
+++ b/include/linux/ecryptfs.h
@@ -0,0 +1,113 @@
+#ifndef _LINUX_ECRYPTFS_H
+#define _LINUX_ECRYPTFS_H
+
+/* Version verification for shared data structures w/ userspace */
+#define ECRYPTFS_VERSION_MAJOR 0x00
+#define ECRYPTFS_VERSION_MINOR 0x04
+#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
+/* These flags indicate which features are supported by the kernel
+ * module; userspace tools such as the mount helper read
+ * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
+ * how to behave. */
+#define ECRYPTFS_VERSIONING_PASSPHRASE            0x00000001
+#define ECRYPTFS_VERSIONING_PUBKEY                0x00000002
+#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
+#define ECRYPTFS_VERSIONING_POLICY                0x00000008
+#define ECRYPTFS_VERSIONING_XATTR                 0x00000010
+#define ECRYPTFS_VERSIONING_MULTKEY               0x00000020
+#define ECRYPTFS_VERSIONING_DEVMISC               0x00000040
+#define ECRYPTFS_VERSIONING_HMAC                  0x00000080
+#define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION   0x00000100
+#define ECRYPTFS_VERSIONING_GCM                   0x00000200
+#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
+				  | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
+				  | ECRYPTFS_VERSIONING_PUBKEY \
+				  | ECRYPTFS_VERSIONING_XATTR \
+				  | ECRYPTFS_VERSIONING_MULTKEY \
+				  | ECRYPTFS_VERSIONING_DEVMISC \
+				  | ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION)
+#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
+#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
+#define ECRYPTFS_SALT_SIZE 8
+#define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2)
+/* The original signature size is only for what is stored on disk; all
+ * in-memory representations are expanded hex, so it better adapted to
+ * be passed around or referenced on the command line */
+#define ECRYPTFS_SIG_SIZE 8
+#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
+#define ECRYPTFS_MAX_KEY_BYTES 64
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
+#define ECRYPTFS_FILE_VERSION 0x03
+#define ECRYPTFS_MAX_PKI_NAME_BYTES 16
+
+#define RFC2440_CIPHER_DES3_EDE 0x02
+#define RFC2440_CIPHER_CAST_5 0x03
+#define RFC2440_CIPHER_BLOWFISH 0x04
+#define RFC2440_CIPHER_AES_128 0x07
+#define RFC2440_CIPHER_AES_192 0x08
+#define RFC2440_CIPHER_AES_256 0x09
+#define RFC2440_CIPHER_TWOFISH 0x0a
+#define RFC2440_CIPHER_CAST_6 0x0b
+
+#define RFC2440_CIPHER_RSA 0x01
+
+/**
+ * For convenience, we may need to pass around the encrypted session
+ * key between kernel and userspace because the authentication token
+ * may not be extractable.  For example, the TPM may not release the
+ * private key, instead requiring the encrypted data and returning the
+ * decrypted data.
+ */
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
+	u32 flags;
+	u32 encrypted_key_size;
+	u32 decrypted_key_size;
+	u8 encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+	u8 decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
+};
+
+struct ecryptfs_password {
+	u32 password_bytes;
+	s32 hash_algo;
+	u32 hash_iterations;
+	u32 session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+	u32 flags;
+	/* Iterated-hash concatenation of salt and passphrase */
+	u8 session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+	u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+	/* Always in expanded hex */
+	u8 salt[ECRYPTFS_SALT_SIZE];
+};
+
+enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
+
+struct ecryptfs_private_key {
+	u32 key_size;
+	u32 data_len;
+	u8 signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+	char pki_type[ECRYPTFS_MAX_PKI_NAME_BYTES + 1];
+	u8 data[];
+};
+
+/* May be a password or a private key */
+struct ecryptfs_auth_tok {
+	u16 version; /* 8-bit major and 8-bit minor */
+	u16 token_type;
+#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
+	u32 flags;
+	struct ecryptfs_session_key session_key;
+	u8 reserved[32];
+	union {
+		struct ecryptfs_password password;
+		struct ecryptfs_private_key private_key;
+	} token;
+} __attribute__ ((packed));
+
+#endif /* _LINUX_ECRYPTFS_H */
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (3 preceding siblings ...)
  2011-01-24 16:44 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-25 22:57   ` Tyler Hicks
  2011-01-24 16:44 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 15458 bytes --]

The 'encrypted' key type defines its own payload format which contains a
symmetric key randomly generated that cannot be used directly to mount
an eCryptfs filesystem, because it expects an authentication token
structure.

This patch introduces the new format 'ecryptfs' that allows to store an
authentication token structure inside the encrypted key payload containing
a randomly generated symmetric key, as the same for the format 'default'.

More details about the usage of encrypted keys with the eCryptfs
filesystem can be found in the file 'Documentation/keys-ecryptfs.txt'.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
---
 Documentation/keys-ecryptfs.txt          |   68 +++++++++++++++++++++++++
 Documentation/keys-trusted-encrypted.txt |    6 ++-
 security/keys/Makefile                   |    2 +-
 security/keys/encrypted.c                |   75 +++++++++++++++++++++++++---
 security/keys/keys_ecryptfs.c            |   81 ++++++++++++++++++++++++++++++
 security/keys/keys_ecryptfs.h            |   30 +++++++++++
 6 files changed, 252 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/keys-ecryptfs.txt
 create mode 100644 security/keys/keys_ecryptfs.c
 create mode 100644 security/keys/keys_ecryptfs.h

diff --git a/Documentation/keys-ecryptfs.txt b/Documentation/keys-ecryptfs.txt
new file mode 100644
index 0000000..c3bbeba
--- /dev/null
+++ b/Documentation/keys-ecryptfs.txt
@@ -0,0 +1,68 @@
+		Encrypted keys for the eCryptfs filesystem
+
+ECryptfs is a stacked filesystem which transparently encrypts and decrypts each
+file using a randomly generated File Encryption Key (FEK).
+
+Each FEK is in turn encrypted with a File Encryption Key Encryption Key (FEFEK)
+either in kernel space or in user space with a daemon called 'ecryptfsd'.  In
+the former case the operation is performed directly by the kernel CryptoAPI
+using a key, the FEFEK, derived from a user prompted passphrase;  in the latter
+the FEK is encrypted by 'ecryptfsd' with the help of external libraries in order
+to support other mechanisms like public key cryptography, PKCS#11 and TPM based
+operations.
+
+The data structure defined by eCryptfs to contain information required for the
+FEK decryption is called authentication token and, currently, can be stored in a
+kernel key of the 'user' type, inserted in the user's session specific keyring
+by the userspace utility 'mount.ecryptfs' shipped with the package
+'ecryptfs-utils'.
+
+The 'encrypted' key type has been extended with the introduction of the new
+format 'ecryptfs' in order to be used in conjunction with the eCryptfs
+filesystem.  Encrypted keys of the newly introduced format store an
+authentication token in its payload with a FEFEK randomly generated by the
+kernel and protected by the parent master key.
+
+In order to avoid known-plaintext attacks, the datablob obtained through
+commands 'keyctl print' or 'keyctl pipe' does not contain the overall
+authentication token, which content is well known, but only the FEFEK in
+encrypted form.
+
+The eCryptfs filesystem may really benefit from using encrypted keys in that the
+required key can be securely generated by an Administrator and provided at boot
+time after the unsealing of a 'trusted' key in order to perform the mount in a
+controlled environment.  Another advantage is that the key is not exposed to
+threats of malicious software, because it is available in clear form only at
+kernel level.
+
+Usage:
+   keyctl add encrypted name "new ecryptfs key-type:master-key-name keylen" ring
+   keyctl add encrypted name "load hex_blob" ring
+   keyctl update keyid "update key-type:master-key-name"
+
+name:= '<16 hexadecimal characters>'
+key-type:= 'trusted' | 'user'
+keylen:= 64
+
+
+Example of encrypted key usage with the eCryptfs filesystem:
+
+Create an encrypted key "1000100010001000" of length 64 bytes with format
+'ecryptfs' and save it using a previously loaded user key "test":
+
+    $ keyctl add encrypted 1000100010001000 "new ecryptfs user:test 64" @u
+    19184530
+
+    $ keyctl print 19184530
+    ecryptfs user:test 64 490045d4bfe48c99f0d465fbbbb79e7500da954178e2de0697
+    dd85091f5450a0511219e9f7cd70dcd498038181466f78ac8d4c19504fcc72402bfc41c2
+    f253a41b7507ccaa4b2b03fff19a69d1cc0b16e71746473f023a95488b6edfd86f7fdd40
+    9d292e4bacded1258880122dd553a661
+
+    $ keyctl pipe 19184530 > ecryptfs.blob
+
+Mount an eCryptfs filesystem using the created encrypted key "1000100010001000"
+into the '/secret' directory:
+
+    $ mount -i -t ecryptfs -oecryptfs_sig=1000100010001000,\
+      ecryptfs_cipher=aes,ecryptfs_key_bytes=32 /secret /secret
diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
index 0afcb50..5f50cca 100644
--- a/Documentation/keys-trusted-encrypted.txt
+++ b/Documentation/keys-trusted-encrypted.txt
@@ -63,7 +63,7 @@ Usage:
     keyctl add encrypted name "load hex_blob" ring
     keyctl update keyid "update key-type:master-key-name"
 
-format:= 'default'
+format:= 'default | ecryptfs'
 key-type:= 'trusted' | 'user'
 
 
@@ -154,4 +154,6 @@ Load an encrypted key "evm" from saved blob:
     24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
 
 Other uses for trusted and encrypted keys, such as for disk and file encryption
-are anticipated.
+are anticipated.  In particular the new format 'ecryptfs' has been defined in
+in order to use encrypted keys to mount an eCryptfs filesystem.  More details
+about the usage can be found in the file 'Documentation/keys-ecryptfs.txt'.
diff --git a/security/keys/Makefile b/security/keys/Makefile
index 1bf090a..bf8c878 100644
--- a/security/keys/Makefile
+++ b/security/keys/Makefile
@@ -14,7 +14,7 @@ obj-y := \
 	user_defined.o
 
 obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
-obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o
+obj-$(CONFIG_ENCRYPTED_KEYS) += keys_ecryptfs.o encrypted.o
 obj-$(CONFIG_KEYS_COMPAT) += compat.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSCTL) += sysctl.o
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index 59f719e..a916ce2 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -29,11 +29,13 @@
 #include <linux/rcupdate.h>
 #include <linux/scatterlist.h>
 #include <linux/crypto.h>
+#include <linux/ctype.h>
 #include <crypto/hash.h>
 #include <crypto/sha.h>
 #include <crypto/aes.h>
 
 #include "encrypted.h"
+#include "keys_ecryptfs.h"
 
 static const char KEY_TRUSTED_PREFIX[] = "trusted:";
 static const char KEY_USER_PREFIX[] = "user:";
@@ -41,11 +43,13 @@ static const char hash_alg[] = "sha256";
 static const char hmac_alg[] = "hmac(sha256)";
 static const char blkcipher_alg[] = "cbc(aes)";
 static const char key_format_default[] = "default";
+static const char key_format_ecryptfs[] = "ecryptfs";
 static unsigned int ivsize;
 static int blksize;
 
 #define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
 #define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
+#define KEY_ECRYPTFS_DESC_LEN 16
 #define HASH_SIZE SHA256_DIGEST_SIZE
 #define MAX_DATA_SIZE 4096
 #define MIN_DATA_SIZE  20
@@ -63,11 +67,12 @@ enum {
 };
 
 enum {
-	Opt_error = -1, Opt_default
+	Opt_error = -1, Opt_default, Opt_ecryptfs
 };
 
 static const match_table_t key_format_tokens = {
 	{Opt_default, "default"},
+	{Opt_ecryptfs, "ecryptfs"},
 	{Opt_error, NULL}
 };
 
@@ -95,6 +100,34 @@ static int aes_get_sizes(void)
 }
 
 /*
+ * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
+ *
+ * The description of a encrypted key with format 'ecryptfs' must contain
+ * exactly 16 hexadecimal characters.
+ *
+ */
+static int valid_ecryptfs_desc(const char *ecryptfs_desc)
+{
+	int i;
+
+	if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
+		pr_err("encrypted_key: key description must be %d hexadecimal "
+		       "characters long\n", KEY_ECRYPTFS_DESC_LEN);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
+		if (!isxdigit(ecryptfs_desc[i])) {
+			pr_err("encrypted_key: key description must contain "
+			       "only hexadecimal characters\n");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
  *
  * key-type:= "trusted:" | "user:"
@@ -158,7 +191,7 @@ static int datablob_parse(char *datablob, const char **format,
 	}
 	key_cmd = match_token(keyword, key_tokens, args);
 
-	/* Get optional format: default */
+	/* Get optional format: default | ecryptfs */
 	p = strsep(&datablob, " \t");
 	if (!p) {
 		pr_err("encrypted_key: insufficient parameters specified\n");
@@ -167,6 +200,7 @@ static int datablob_parse(char *datablob, const char **format,
 
 	key_format = match_token(p, key_format_tokens, args);
 	switch (key_format) {
+	case Opt_ecryptfs:
 	case Opt_default:
 		*format = p;
 		*master_desc = strsep(&datablob, " \t");
@@ -598,6 +632,17 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
 	format_len = (!format) ? strlen(key_format_default) : strlen(format);
 	decrypted_datalen = dlen;
 	payload_datalen = decrypted_datalen;
+	if (format && !strcmp(format, key_format_ecryptfs)) {
+		if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
+			pr_err("encrypted_key: keylen for the ecryptfs format "
+			       "must be equal to %d bytes\n",
+			       ECRYPTFS_MAX_KEY_BYTES);
+			return ERR_PTR(-EINVAL);
+		}
+		decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
+		payload_datalen = sizeof(struct ecryptfs_auth_tok);
+	}
+
 	encrypted_datalen = roundup(decrypted_datalen, blksize);
 
 	datablob_len = format_len + 1 + strlen(master_desc) + 1
@@ -683,8 +728,14 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
 
 	if (!format)
 		memcpy(epayload->format, key_format_default, format_len);
-	else
+	else {
+		if (!strcmp(format, key_format_ecryptfs))
+			epayload->decrypted_data =
+				ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
+
 		memcpy(epayload->format, format, format_len);
+	}
+
 	memcpy(epayload->master_desc, master_desc, strlen(master_desc));
 	memcpy(epayload->datalen, datalen, strlen(datalen));
 }
@@ -696,11 +747,21 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
  * itself.  For an old key, decrypt the hex encoded data.
  */
 static int encrypted_init(struct encrypted_key_payload *epayload,
-			  const char *format, const char *master_desc,
-			  const char *datalen, const char *hex_encoded_iv)
+			  const char *key_desc, const char *format,
+			  const char *master_desc, const char *datalen,
+			  const char *hex_encoded_iv)
 {
 	int ret = 0;
 
+	if (format && !strcmp(format, key_format_ecryptfs)) {
+		ret = valid_ecryptfs_desc(key_desc);
+		if (ret < 0)
+			return ret;
+
+		ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
+				       key_desc);
+	}
+
 	__ekey_init(epayload, format, master_desc, datalen);
 	if (!hex_encoded_iv) {
 		get_random_bytes(epayload->iv, ivsize);
@@ -750,8 +811,8 @@ static int encrypted_instantiate(struct key *key, const void *data,
 		ret = PTR_ERR(epayload);
 		goto out;
 	}
-	ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
-			     hex_encoded_iv);
+	ret = encrypted_init(epayload, key->description, format, master_desc,
+			     decrypted_datalen, hex_encoded_iv);
 	if (ret < 0) {
 		kfree(epayload);
 		goto out;
diff --git a/security/keys/keys_ecryptfs.c b/security/keys/keys_ecryptfs.c
new file mode 100644
index 0000000..6144b91
--- /dev/null
+++ b/security/keys/keys_ecryptfs.c
@@ -0,0 +1,81 @@
+/*
+ * keys_ecryptfs.c: helper functions for the encrypted key type
+ *
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ *                    TORSEC group -- http://security.polito.it
+ *
+ * Authors:
+ * Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Tyler Hicks <tyhicks@ou.edu>
+ * Roberto Sassu <roberto.sassu@polito.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#include <linux/module.h>
+#include "keys_ecryptfs.h"
+
+u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
+{
+	return auth_tok->token.password.session_key_encryption_key;
+}
+EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
+
+/*
+ * ecryptfs_get_versions()
+ *
+ * Source code taken from the software 'ecryptfs-utils' version 83.
+ *
+ */
+void ecryptfs_get_versions(int *major, int *minor, int *file_version)
+{
+	*major = ECRYPTFS_VERSION_MAJOR;
+	*minor = ECRYPTFS_VERSION_MINOR;
+	if (file_version)
+		*file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
+}
+EXPORT_SYMBOL(ecryptfs_get_versions);
+
+/*
+ * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
+ *
+ * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
+ * The source code is inspired to the original function generate_payload()
+ * shipped with the software 'ecryptfs-utils' version 83.
+ *
+ */
+int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
+			   const char *key_desc)
+{
+	int major, minor;
+
+	ecryptfs_get_versions(&major, &minor, NULL);
+	auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
+			     | ((uint16_t)minor & 0x00FF));
+	auth_tok->token_type = ECRYPTFS_PASSWORD;
+	strncpy((char *)auth_tok->token.password.signature, key_desc,
+		ECRYPTFS_PASSWORD_SIG_SIZE);
+	auth_tok->token.password.session_key_encryption_key_bytes =
+		ECRYPTFS_MAX_KEY_BYTES;
+	/*
+	 * Removed auth_tok->token.password.salt and
+	 * auth_tok->token.password.session_key_encryption_key
+	 * initialization from the original code
+	 */
+	/* TODO: Make the hash parameterizable via policy */
+	auth_tok->token.password.flags |=
+		ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
+	/* The kernel code will encrypt the session key. */
+	auth_tok->session_key.encrypted_key[0] = 0;
+	auth_tok->session_key.encrypted_key_size = 0;
+	/* Default; subject to change by kernel eCryptfs */
+	auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
+	auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
+	return 0;
+}
+EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
+
+MODULE_LICENSE("GPL");
diff --git a/security/keys/keys_ecryptfs.h b/security/keys/keys_ecryptfs.h
new file mode 100644
index 0000000..87f77ca
--- /dev/null
+++ b/security/keys/keys_ecryptfs.h
@@ -0,0 +1,30 @@
+/*
+ * keys_ecryptfs.h: helper functions for the encrypted key type
+ *
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Copyright (C) 2010 Politecnico di Torino, Italy
+ *                    TORSEC group -- http://security.polito.it
+ *
+ * Authors:
+ * Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Tyler Hicks <tyhicks@ou.edu>
+ * Roberto Sassu <roberto.sassu@polito.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 of the License.
+ */
+
+#ifndef __KEYS_ECRYPTFS_H
+#define __KEYS_ECRYPTFS_H
+
+#include <linux/ecryptfs.h>
+
+#define PGP_DIGEST_ALGO_SHA512   10
+
+u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
+void ecryptfs_get_versions(int *major, int *minor, int *file_version);
+int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
+			   const char *key_desc);
+
+#endif /* __KEYS_ECRYPTFS_H */
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (4 preceding siblings ...)
  2011-01-24 16:44 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support Roberto Sassu
@ 2011-01-24 16:44 ` Roberto Sassu
  2011-01-25 22:41   ` Tyler Hicks
  2011-01-26 10:49 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages David Howells
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 19+ messages in thread
From: Roberto Sassu @ 2011-01-24 16:44 UTC (permalink / raw)
  To: linux-security-module
  Cc: keyrings, linux-fsdevel, linux-kernel, dhowells, jmorris, zohar,
	safford, ramunno, tyhicks, kirkland, Roberto Sassu

[-- Attachment #1: Type: text/plain, Size: 2991 bytes --]

The function ecryptfs_keyring_auth_tok_for_sig() has been modified in order
to search keys of both 'user' and 'encrypted' types.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
---
 fs/ecryptfs/ecryptfs_kernel.h |   41 +++++++++++++++++++++++++++++++++++++++--
 fs/ecryptfs/keystore.c        |   11 +++++++----
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 2e2242f..2b50397 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -29,6 +29,7 @@
 #define ECRYPTFS_KERNEL_H
 
 #include <keys/user-type.h>
+#include <keys/encrypted-type.h>
 #include <linux/fs.h>
 #include <linux/fs_stack.h>
 #include <linux/namei.h>
@@ -78,11 +79,47 @@ struct ecryptfs_page_crypt_context {
 	} param;
 };
 
+#if defined(CONFIG_ENCRYPTED_KEYS) || defined(CONFIG_ENCRYPTED_KEYS_MODULE)
+static inline struct ecryptfs_auth_tok *
+ecryptfs_get_encrypted_key_payload_data(struct key *key)
+{
+	if (key->type == &key_type_encrypted)
+		return (struct ecryptfs_auth_tok *)
+			(&((struct encrypted_key_payload *)key->payload.data)->payload_data);
+	else
+		return NULL;
+}
+
+static inline struct key *ecryptfs_get_encrypted_key(char *sig)
+{
+	return request_key(&key_type_encrypted, sig, NULL);
+}
+
+#else
+static inline struct ecryptfs_auth_tok *
+ecryptfs_get_encrypted_key_payload_data(struct key *key)
+{
+	return NULL;
+}
+
+static inline struct key *ecryptfs_get_encrypted_key(char *sig)
+{
+	return ERR_PTR(-ENOKEY);
+}
+
+#endif /* CONFIG_ENCRYPTED_KEYS */
+
 static inline struct ecryptfs_auth_tok *
 ecryptfs_get_key_payload_data(struct key *key)
 {
-	return (struct ecryptfs_auth_tok *)
-		(((struct user_key_payload*)key->payload.data)->data);
+	struct ecryptfs_auth_tok *auth_tok;
+
+	auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
+	if (!auth_tok)
+		return (struct ecryptfs_auth_tok *)
+			(((struct user_key_payload *)key->payload.data)->data);
+	else
+		return auth_tok;
 }
 
 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index c1436cf..17194b8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1560,10 +1560,13 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
 
 	(*auth_tok_key) = request_key(&key_type_user, sig, NULL);
 	if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
-		printk(KERN_ERR "Could not find key with description: [%s]\n",
-		       sig);
-		rc = process_request_key_err(PTR_ERR(*auth_tok_key));
-		goto out;
+		(*auth_tok_key) = ecryptfs_get_encrypted_key(sig);
+		if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
+			printk(KERN_ERR "Could not find key with description: [%s]\n",
+			      sig);
+			rc = process_request_key_err(PTR_ERR(*auth_tok_key));
+			goto out;
+		}
 	}
 	(*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
 	if (ecryptfs_verify_version((*auth_tok)->version)) {
-- 
1.7.3.4


[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 2061 bytes --]

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type
  2011-01-24 16:44 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type Roberto Sassu
@ 2011-01-25 22:41   ` Tyler Hicks
  0 siblings, 0 replies; 19+ messages in thread
From: Tyler Hicks @ 2011-01-25 22:41 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: linux-security-module, keyrings, linux-fsdevel, linux-kernel,
	dhowells, jmorris, zohar, safford, ramunno, kirkland

On Mon Jan 24, 2011 at 05:44:54PM +0100, Roberto Sassu <roberto.sassu@polito.it> wrote:
> The function ecryptfs_keyring_auth_tok_for_sig() has been modified in order
> to search keys of both 'user' and 'encrypted' types.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
> Acked-by: Gianluca Ramunno <ramunno@polito.it>

Thanks for the new revision.

Acked-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

> ---
>  fs/ecryptfs/ecryptfs_kernel.h |   41 +++++++++++++++++++++++++++++++++++++++--
>  fs/ecryptfs/keystore.c        |   11 +++++++----
>  2 files changed, 46 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
> index 2e2242f..2b50397 100644
> --- a/fs/ecryptfs/ecryptfs_kernel.h
> +++ b/fs/ecryptfs/ecryptfs_kernel.h
> @@ -29,6 +29,7 @@
>  #define ECRYPTFS_KERNEL_H
> 
>  #include <keys/user-type.h>
> +#include <keys/encrypted-type.h>
>  #include <linux/fs.h>
>  #include <linux/fs_stack.h>
>  #include <linux/namei.h>
> @@ -78,11 +79,47 @@ struct ecryptfs_page_crypt_context {
>  	} param;
>  };
> 
> +#if defined(CONFIG_ENCRYPTED_KEYS) || defined(CONFIG_ENCRYPTED_KEYS_MODULE)
> +static inline struct ecryptfs_auth_tok *
> +ecryptfs_get_encrypted_key_payload_data(struct key *key)
> +{
> +	if (key->type == &key_type_encrypted)
> +		return (struct ecryptfs_auth_tok *)
> +			(&((struct encrypted_key_payload *)key->payload.data)->payload_data);
> +	else
> +		return NULL;
> +}
> +
> +static inline struct key *ecryptfs_get_encrypted_key(char *sig)
> +{
> +	return request_key(&key_type_encrypted, sig, NULL);
> +}
> +
> +#else
> +static inline struct ecryptfs_auth_tok *
> +ecryptfs_get_encrypted_key_payload_data(struct key *key)
> +{
> +	return NULL;
> +}
> +
> +static inline struct key *ecryptfs_get_encrypted_key(char *sig)
> +{
> +	return ERR_PTR(-ENOKEY);
> +}
> +
> +#endif /* CONFIG_ENCRYPTED_KEYS */
> +
>  static inline struct ecryptfs_auth_tok *
>  ecryptfs_get_key_payload_data(struct key *key)
>  {
> -	return (struct ecryptfs_auth_tok *)
> -		(((struct user_key_payload*)key->payload.data)->data);
> +	struct ecryptfs_auth_tok *auth_tok;
> +
> +	auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
> +	if (!auth_tok)
> +		return (struct ecryptfs_auth_tok *)
> +			(((struct user_key_payload *)key->payload.data)->data);
> +	else
> +		return auth_tok;
>  }
> 
>  #define ECRYPTFS_MAX_KEYSET_SIZE 1024
> diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
> index c1436cf..17194b8 100644
> --- a/fs/ecryptfs/keystore.c
> +++ b/fs/ecryptfs/keystore.c
> @@ -1560,10 +1560,13 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
> 
>  	(*auth_tok_key) = request_key(&key_type_user, sig, NULL);
>  	if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> -		printk(KERN_ERR "Could not find key with description: [%s]\n",
> -		       sig);
> -		rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> -		goto out;
> +		(*auth_tok_key) = ecryptfs_get_encrypted_key(sig);
> +		if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> +			printk(KERN_ERR "Could not find key with description: [%s]\n",
> +			      sig);
> +			rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> +			goto out;
> +		}
>  	}
>  	(*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
>  	if (ecryptfs_verify_version((*auth_tok)->version)) {
> -- 
> 1.7.3.4
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support
  2011-01-24 16:44 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support Roberto Sassu
@ 2011-01-25 22:57   ` Tyler Hicks
  0 siblings, 0 replies; 19+ messages in thread
From: Tyler Hicks @ 2011-01-25 22:57 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: linux-security-module, keyrings, linux-fsdevel, linux-kernel,
	dhowells, jmorris, zohar, safford, ramunno, kirkland

On Mon Jan 24, 2011 at 05:44:53PM +0100, Roberto Sassu <roberto.sassu@polito.it> wrote:
> The 'encrypted' key type defines its own payload format which contains a
> symmetric key randomly generated that cannot be used directly to mount
> an eCryptfs filesystem, because it expects an authentication token
> structure.
> 
> This patch introduces the new format 'ecryptfs' that allows to store an
> authentication token structure inside the encrypted key payload containing
> a randomly generated symmetric key, as the same for the format 'default'.
> 
> More details about the usage of encrypted keys with the eCryptfs
> filesystem can be found in the file 'Documentation/keys-ecryptfs.txt'.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
> Acked-by: Gianluca Ramunno <ramunno@polito.it>

Reviewed-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

> ---
>  Documentation/keys-ecryptfs.txt          |   68 +++++++++++++++++++++++++
>  Documentation/keys-trusted-encrypted.txt |    6 ++-
>  security/keys/Makefile                   |    2 +-
>  security/keys/encrypted.c                |   75 +++++++++++++++++++++++++---
>  security/keys/keys_ecryptfs.c            |   81 ++++++++++++++++++++++++++++++
>  security/keys/keys_ecryptfs.h            |   30 +++++++++++
>  6 files changed, 252 insertions(+), 10 deletions(-)
>  create mode 100644 Documentation/keys-ecryptfs.txt
>  create mode 100644 security/keys/keys_ecryptfs.c
>  create mode 100644 security/keys/keys_ecryptfs.h
> 
> diff --git a/Documentation/keys-ecryptfs.txt b/Documentation/keys-ecryptfs.txt
> new file mode 100644
> index 0000000..c3bbeba
> --- /dev/null
> +++ b/Documentation/keys-ecryptfs.txt
> @@ -0,0 +1,68 @@
> +		Encrypted keys for the eCryptfs filesystem
> +
> +ECryptfs is a stacked filesystem which transparently encrypts and decrypts each
> +file using a randomly generated File Encryption Key (FEK).
> +
> +Each FEK is in turn encrypted with a File Encryption Key Encryption Key (FEFEK)
> +either in kernel space or in user space with a daemon called 'ecryptfsd'.  In
> +the former case the operation is performed directly by the kernel CryptoAPI
> +using a key, the FEFEK, derived from a user prompted passphrase;  in the latter
> +the FEK is encrypted by 'ecryptfsd' with the help of external libraries in order
> +to support other mechanisms like public key cryptography, PKCS#11 and TPM based
> +operations.
> +
> +The data structure defined by eCryptfs to contain information required for the
> +FEK decryption is called authentication token and, currently, can be stored in a
> +kernel key of the 'user' type, inserted in the user's session specific keyring
> +by the userspace utility 'mount.ecryptfs' shipped with the package
> +'ecryptfs-utils'.
> +
> +The 'encrypted' key type has been extended with the introduction of the new
> +format 'ecryptfs' in order to be used in conjunction with the eCryptfs
> +filesystem.  Encrypted keys of the newly introduced format store an
> +authentication token in its payload with a FEFEK randomly generated by the
> +kernel and protected by the parent master key.
> +
> +In order to avoid known-plaintext attacks, the datablob obtained through
> +commands 'keyctl print' or 'keyctl pipe' does not contain the overall
> +authentication token, which content is well known, but only the FEFEK in
> +encrypted form.
> +
> +The eCryptfs filesystem may really benefit from using encrypted keys in that the
> +required key can be securely generated by an Administrator and provided at boot
> +time after the unsealing of a 'trusted' key in order to perform the mount in a
> +controlled environment.  Another advantage is that the key is not exposed to
> +threats of malicious software, because it is available in clear form only at
> +kernel level.
> +
> +Usage:
> +   keyctl add encrypted name "new ecryptfs key-type:master-key-name keylen" ring
> +   keyctl add encrypted name "load hex_blob" ring
> +   keyctl update keyid "update key-type:master-key-name"
> +
> +name:= '<16 hexadecimal characters>'
> +key-type:= 'trusted' | 'user'
> +keylen:= 64
> +
> +
> +Example of encrypted key usage with the eCryptfs filesystem:
> +
> +Create an encrypted key "1000100010001000" of length 64 bytes with format
> +'ecryptfs' and save it using a previously loaded user key "test":
> +
> +    $ keyctl add encrypted 1000100010001000 "new ecryptfs user:test 64" @u
> +    19184530
> +
> +    $ keyctl print 19184530
> +    ecryptfs user:test 64 490045d4bfe48c99f0d465fbbbb79e7500da954178e2de0697
> +    dd85091f5450a0511219e9f7cd70dcd498038181466f78ac8d4c19504fcc72402bfc41c2
> +    f253a41b7507ccaa4b2b03fff19a69d1cc0b16e71746473f023a95488b6edfd86f7fdd40
> +    9d292e4bacded1258880122dd553a661
> +
> +    $ keyctl pipe 19184530 > ecryptfs.blob
> +
> +Mount an eCryptfs filesystem using the created encrypted key "1000100010001000"
> +into the '/secret' directory:
> +
> +    $ mount -i -t ecryptfs -oecryptfs_sig=1000100010001000,\
> +      ecryptfs_cipher=aes,ecryptfs_key_bytes=32 /secret /secret
> diff --git a/Documentation/keys-trusted-encrypted.txt b/Documentation/keys-trusted-encrypted.txt
> index 0afcb50..5f50cca 100644
> --- a/Documentation/keys-trusted-encrypted.txt
> +++ b/Documentation/keys-trusted-encrypted.txt
> @@ -63,7 +63,7 @@ Usage:
>      keyctl add encrypted name "load hex_blob" ring
>      keyctl update keyid "update key-type:master-key-name"
> 
> -format:= 'default'
> +format:= 'default | ecryptfs'
>  key-type:= 'trusted' | 'user'
> 
> 
> @@ -154,4 +154,6 @@ Load an encrypted key "evm" from saved blob:
>      24717c64 5972dcb82ab2dde83376d82b2e3c09ffc
> 
>  Other uses for trusted and encrypted keys, such as for disk and file encryption
> -are anticipated.
> +are anticipated.  In particular the new format 'ecryptfs' has been defined in
> +in order to use encrypted keys to mount an eCryptfs filesystem.  More details
> +about the usage can be found in the file 'Documentation/keys-ecryptfs.txt'.
> diff --git a/security/keys/Makefile b/security/keys/Makefile
> index 1bf090a..bf8c878 100644
> --- a/security/keys/Makefile
> +++ b/security/keys/Makefile
> @@ -14,7 +14,7 @@ obj-y := \
>  	user_defined.o
> 
>  obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
> -obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o
> +obj-$(CONFIG_ENCRYPTED_KEYS) += keys_ecryptfs.o encrypted.o
>  obj-$(CONFIG_KEYS_COMPAT) += compat.o
>  obj-$(CONFIG_PROC_FS) += proc.o
>  obj-$(CONFIG_SYSCTL) += sysctl.o
> diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
> index 59f719e..a916ce2 100644
> --- a/security/keys/encrypted.c
> +++ b/security/keys/encrypted.c
> @@ -29,11 +29,13 @@
>  #include <linux/rcupdate.h>
>  #include <linux/scatterlist.h>
>  #include <linux/crypto.h>
> +#include <linux/ctype.h>
>  #include <crypto/hash.h>
>  #include <crypto/sha.h>
>  #include <crypto/aes.h>
> 
>  #include "encrypted.h"
> +#include "keys_ecryptfs.h"
> 
>  static const char KEY_TRUSTED_PREFIX[] = "trusted:";
>  static const char KEY_USER_PREFIX[] = "user:";
> @@ -41,11 +43,13 @@ static const char hash_alg[] = "sha256";
>  static const char hmac_alg[] = "hmac(sha256)";
>  static const char blkcipher_alg[] = "cbc(aes)";
>  static const char key_format_default[] = "default";
> +static const char key_format_ecryptfs[] = "ecryptfs";
>  static unsigned int ivsize;
>  static int blksize;
> 
>  #define KEY_TRUSTED_PREFIX_LEN (sizeof (KEY_TRUSTED_PREFIX) - 1)
>  #define KEY_USER_PREFIX_LEN (sizeof (KEY_USER_PREFIX) - 1)
> +#define KEY_ECRYPTFS_DESC_LEN 16
>  #define HASH_SIZE SHA256_DIGEST_SIZE
>  #define MAX_DATA_SIZE 4096
>  #define MIN_DATA_SIZE  20
> @@ -63,11 +67,12 @@ enum {
>  };
> 
>  enum {
> -	Opt_error = -1, Opt_default
> +	Opt_error = -1, Opt_default, Opt_ecryptfs
>  };
> 
>  static const match_table_t key_format_tokens = {
>  	{Opt_default, "default"},
> +	{Opt_ecryptfs, "ecryptfs"},
>  	{Opt_error, NULL}
>  };
> 
> @@ -95,6 +100,34 @@ static int aes_get_sizes(void)
>  }
> 
>  /*
> + * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
> + *
> + * The description of a encrypted key with format 'ecryptfs' must contain
> + * exactly 16 hexadecimal characters.
> + *
> + */
> +static int valid_ecryptfs_desc(const char *ecryptfs_desc)
> +{
> +	int i;
> +
> +	if (strlen(ecryptfs_desc) != KEY_ECRYPTFS_DESC_LEN) {
> +		pr_err("encrypted_key: key description must be %d hexadecimal "
> +		       "characters long\n", KEY_ECRYPTFS_DESC_LEN);
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < KEY_ECRYPTFS_DESC_LEN; i++) {
> +		if (!isxdigit(ecryptfs_desc[i])) {
> +			pr_err("encrypted_key: key description must contain "
> +			       "only hexadecimal characters\n");
> +			return -EINVAL;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/*
>   * valid_master_desc - verify the 'key-type:desc' of a new/updated master-key
>   *
>   * key-type:= "trusted:" | "user:"
> @@ -158,7 +191,7 @@ static int datablob_parse(char *datablob, const char **format,
>  	}
>  	key_cmd = match_token(keyword, key_tokens, args);
> 
> -	/* Get optional format: default */
> +	/* Get optional format: default | ecryptfs */
>  	p = strsep(&datablob, " \t");
>  	if (!p) {
>  		pr_err("encrypted_key: insufficient parameters specified\n");
> @@ -167,6 +200,7 @@ static int datablob_parse(char *datablob, const char **format,
> 
>  	key_format = match_token(p, key_format_tokens, args);
>  	switch (key_format) {
> +	case Opt_ecryptfs:
>  	case Opt_default:
>  		*format = p;
>  		*master_desc = strsep(&datablob, " \t");
> @@ -598,6 +632,17 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
>  	format_len = (!format) ? strlen(key_format_default) : strlen(format);
>  	decrypted_datalen = dlen;
>  	payload_datalen = decrypted_datalen;
> +	if (format && !strcmp(format, key_format_ecryptfs)) {
> +		if (dlen != ECRYPTFS_MAX_KEY_BYTES) {
> +			pr_err("encrypted_key: keylen for the ecryptfs format "
> +			       "must be equal to %d bytes\n",
> +			       ECRYPTFS_MAX_KEY_BYTES);
> +			return ERR_PTR(-EINVAL);
> +		}
> +		decrypted_datalen = ECRYPTFS_MAX_KEY_BYTES;
> +		payload_datalen = sizeof(struct ecryptfs_auth_tok);
> +	}
> +
>  	encrypted_datalen = roundup(decrypted_datalen, blksize);
> 
>  	datablob_len = format_len + 1 + strlen(master_desc) + 1
> @@ -683,8 +728,14 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
> 
>  	if (!format)
>  		memcpy(epayload->format, key_format_default, format_len);
> -	else
> +	else {
> +		if (!strcmp(format, key_format_ecryptfs))
> +			epayload->decrypted_data =
> +				ecryptfs_get_auth_tok_key((struct ecryptfs_auth_tok *)epayload->payload_data);
> +
>  		memcpy(epayload->format, format, format_len);
> +	}
> +
>  	memcpy(epayload->master_desc, master_desc, strlen(master_desc));
>  	memcpy(epayload->datalen, datalen, strlen(datalen));
>  }
> @@ -696,11 +747,21 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
>   * itself.  For an old key, decrypt the hex encoded data.
>   */
>  static int encrypted_init(struct encrypted_key_payload *epayload,
> -			  const char *format, const char *master_desc,
> -			  const char *datalen, const char *hex_encoded_iv)
> +			  const char *key_desc, const char *format,
> +			  const char *master_desc, const char *datalen,
> +			  const char *hex_encoded_iv)
>  {
>  	int ret = 0;
> 
> +	if (format && !strcmp(format, key_format_ecryptfs)) {
> +		ret = valid_ecryptfs_desc(key_desc);
> +		if (ret < 0)
> +			return ret;
> +
> +		ecryptfs_fill_auth_tok((struct ecryptfs_auth_tok *)epayload->payload_data,
> +				       key_desc);
> +	}
> +
>  	__ekey_init(epayload, format, master_desc, datalen);
>  	if (!hex_encoded_iv) {
>  		get_random_bytes(epayload->iv, ivsize);
> @@ -750,8 +811,8 @@ static int encrypted_instantiate(struct key *key, const void *data,
>  		ret = PTR_ERR(epayload);
>  		goto out;
>  	}
> -	ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
> -			     hex_encoded_iv);
> +	ret = encrypted_init(epayload, key->description, format, master_desc,
> +			     decrypted_datalen, hex_encoded_iv);
>  	if (ret < 0) {
>  		kfree(epayload);
>  		goto out;
> diff --git a/security/keys/keys_ecryptfs.c b/security/keys/keys_ecryptfs.c
> new file mode 100644
> index 0000000..6144b91
> --- /dev/null
> +++ b/security/keys/keys_ecryptfs.c
> @@ -0,0 +1,81 @@
> +/*
> + * keys_ecryptfs.c: helper functions for the encrypted key type
> + *
> + * Copyright (C) 2006 International Business Machines Corp.
> + * Copyright (C) 2010 Politecnico di Torino, Italy
> + *                    TORSEC group -- http://security.polito.it
> + *
> + * Authors:
> + * Michael A. Halcrow <mahalcro@us.ibm.com>
> + * Tyler Hicks <tyhicks@ou.edu>
> + * Roberto Sassu <roberto.sassu@polito.it>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 2 of the License.
> + */
> +
> +#include <linux/module.h>
> +#include "keys_ecryptfs.h"
> +
> +u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok)
> +{
> +	return auth_tok->token.password.session_key_encryption_key;
> +}
> +EXPORT_SYMBOL(ecryptfs_get_auth_tok_key);
> +
> +/*
> + * ecryptfs_get_versions()
> + *
> + * Source code taken from the software 'ecryptfs-utils' version 83.
> + *
> + */
> +void ecryptfs_get_versions(int *major, int *minor, int *file_version)
> +{
> +	*major = ECRYPTFS_VERSION_MAJOR;
> +	*minor = ECRYPTFS_VERSION_MINOR;
> +	if (file_version)
> +		*file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
> +}
> +EXPORT_SYMBOL(ecryptfs_get_versions);
> +
> +/*
> + * ecryptfs_fill_auth_tok - fill the ecryptfs_auth_tok structure
> + *
> + * Fill the ecryptfs_auth_tok structure with required ecryptfs data.
> + * The source code is inspired to the original function generate_payload()
> + * shipped with the software 'ecryptfs-utils' version 83.
> + *
> + */
> +int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
> +			   const char *key_desc)
> +{
> +	int major, minor;
> +
> +	ecryptfs_get_versions(&major, &minor, NULL);
> +	auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
> +			     | ((uint16_t)minor & 0x00FF));
> +	auth_tok->token_type = ECRYPTFS_PASSWORD;
> +	strncpy((char *)auth_tok->token.password.signature, key_desc,
> +		ECRYPTFS_PASSWORD_SIG_SIZE);
> +	auth_tok->token.password.session_key_encryption_key_bytes =
> +		ECRYPTFS_MAX_KEY_BYTES;
> +	/*
> +	 * Removed auth_tok->token.password.salt and
> +	 * auth_tok->token.password.session_key_encryption_key
> +	 * initialization from the original code
> +	 */
> +	/* TODO: Make the hash parameterizable via policy */
> +	auth_tok->token.password.flags |=
> +		ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
> +	/* The kernel code will encrypt the session key. */
> +	auth_tok->session_key.encrypted_key[0] = 0;
> +	auth_tok->session_key.encrypted_key_size = 0;
> +	/* Default; subject to change by kernel eCryptfs */
> +	auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
> +	auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
> +	return 0;
> +}
> +EXPORT_SYMBOL(ecryptfs_fill_auth_tok);
> +
> +MODULE_LICENSE("GPL");
> diff --git a/security/keys/keys_ecryptfs.h b/security/keys/keys_ecryptfs.h
> new file mode 100644
> index 0000000..87f77ca
> --- /dev/null
> +++ b/security/keys/keys_ecryptfs.h
> @@ -0,0 +1,30 @@
> +/*
> + * keys_ecryptfs.h: helper functions for the encrypted key type
> + *
> + * Copyright (C) 2006 International Business Machines Corp.
> + * Copyright (C) 2010 Politecnico di Torino, Italy
> + *                    TORSEC group -- http://security.polito.it
> + *
> + * Authors:
> + * Michael A. Halcrow <mahalcro@us.ibm.com>
> + * Tyler Hicks <tyhicks@ou.edu>
> + * Roberto Sassu <roberto.sassu@polito.it>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 2 of the License.
> + */
> +
> +#ifndef __KEYS_ECRYPTFS_H
> +#define __KEYS_ECRYPTFS_H
> +
> +#include <linux/ecryptfs.h>
> +
> +#define PGP_DIGEST_ALGO_SHA512   10
> +
> +u8 *ecryptfs_get_auth_tok_key(struct ecryptfs_auth_tok *auth_tok);
> +void ecryptfs_get_versions(int *major, int *minor, int *file_version);
> +int ecryptfs_fill_auth_tok(struct ecryptfs_auth_tok *auth_tok,
> +			   const char *key_desc);
> +
> +#endif /* __KEYS_ECRYPTFS_H */
> -- 
> 1.7.3.4
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (5 preceding siblings ...)
  2011-01-24 16:44 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type Roberto Sassu
@ 2011-01-26 10:49 ` David Howells
  2011-01-26 11:03 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support David Howells
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: David Howells @ 2011-01-26 10:49 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

> +		pr_err("encrypted_key: insufficient parameters specified\n");

I think pr_err() is probably too high a message level.  This is a user error
not a kernel error.  I would recommend something like pr_info() or possibly
pr_debug().

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 3/6] encrypted-keys: add key format support
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (6 preceding siblings ...)
  2011-01-26 10:49 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages David Howells
@ 2011-01-26 11:03 ` David Howells
  2011-01-26 11:52   ` Mimi Zohar
  2011-01-26 13:01   ` David Howells
  2011-01-26 11:05 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h David Howells
                   ` (3 subsequent siblings)
  11 siblings, 2 replies; 19+ messages in thread
From: David Howells @ 2011-01-26 11:03 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

> This patch introduces a new parameter, called 'format', that defines the
> format of data stored by encrypted keys. The 'default' format identifies
> encrypted keys containing only the symmetric key, while other formats can
> be defined to support additional information. The 'format' parameter is
> written in the datablob produced by commands 'keyctl print' or
> 'keyctl pipe' and is integrity protected by the HMAC.

Would it make more sense to take key=val pairs where you have the <format>
parameter?  Then you could have a format=default|foo|whatever argument and
you'd leave room for future addition of qualifiers.

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (7 preceding siblings ...)
  2011-01-26 11:03 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support David Howells
@ 2011-01-26 11:05 ` David Howells
  2011-01-26 11:05 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description David Howells
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 19+ messages in thread
From: David Howells @ 2011-01-26 11:05 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

> Some eCryptfs specific definitions, such as the current version and the
> authentication token structure, are moved to the new include file
> 'include/linux/ecryptfs.h', in order to be available for all kernel
> subsystems.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
> Acked-by: Gianluca Ramunno <ramunno@polito.it>
> Acked-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (8 preceding siblings ...)
  2011-01-26 11:05 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h David Howells
@ 2011-01-26 11:05 ` David Howells
  2011-01-26 11:18 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support David Howells
  2011-01-26 11:28 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type David Howells
  11 siblings, 0 replies; 19+ messages in thread
From: David Howells @ 2011-01-26 11:05 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

> Valid key type prefixes for the parameter 'key-type' are: 'trusted' and
> 'user'.
> 
> Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
> Acked-by: Gianluca Ramunno <ramunno@polito.it>
> Acked-by: Mimi Zohar <zohar@us.ibm.com>

Acked-by: David Howells <dhowells@redhat.com>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (9 preceding siblings ...)
  2011-01-26 11:05 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description David Howells
@ 2011-01-26 11:18 ` David Howells
  2011-01-26 12:57   ` Mimi Zohar
  2011-01-26 11:28 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type David Howells
  11 siblings, 1 reply; 19+ messages in thread
From: David Howells @ 2011-01-26 11:18 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

>  security/keys/keys_ecryptfs.c            |   81 ++++++++++++++++++++++++++++++
>  security/keys/keys_ecryptfs.h            |   30 +++++++++++

Can you rename these files please?  The 'keys' prefix is redundant.  They're
obviously about keys, or they shouldn't be in this directory.  I'd suggest
something like 'ecryptfs_format.[ch]'.

You might want to make a subdir here specifically for the trusted and
encrypted keys and all their formats and move those files into it if you're
going to have lots of formats.

>  /*
> + * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
> + *
> + * The description of a encrypted key with format 'ecryptfs' must contain
> + * exactly 16 hexadecimal characters.
> + *
> + */
> +static int valid_ecryptfs_desc(const char *ecryptfs_desc)
> +{

I think we need an additional key type operation - one that allows you to pass
judgement on the description to be given for a key in key_alloc().  On the
other hand, this doesn't help here as you can't do a full check on the key
description without the payload.

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type
  2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
                   ` (10 preceding siblings ...)
  2011-01-26 11:18 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support David Howells
@ 2011-01-26 11:28 ` David Howells
  2011-01-27 18:59   ` Roberto Sassu
  11 siblings, 1 reply; 19+ messages in thread
From: David Howells @ 2011-01-26 11:28 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: dhowells, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, zohar, safford, ramunno, tyhicks,
	kirkland

Roberto Sassu <roberto.sassu@polito.it> wrote:

>  	(*auth_tok_key) = request_key(&key_type_user, sig, NULL);
>  	if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> -		printk(KERN_ERR "Could not find key with description: [%s]\n",
> -		       sig);
> -		rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> -		goto out;
> +		(*auth_tok_key) = ecryptfs_get_encrypted_key(sig);
> +		if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> +			printk(KERN_ERR "Could not find key with description: [%s]\n",
> +			      sig);
> +			rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> +			goto out;
> +		}
>  	}
>  	(*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
>  	if (ecryptfs_verify_version((*auth_tok)->version)) {

You need some locking here, even if it's only use of the RCU read lock.
Encrypted-type keys have an update method and so may change under you.

David
---

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 3/6] encrypted-keys: add key format support
  2011-01-26 11:03 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support David Howells
@ 2011-01-26 11:52   ` Mimi Zohar
  2011-01-26 13:01   ` David Howells
  1 sibling, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2011-01-26 11:52 UTC (permalink / raw)
  To: David Howells
  Cc: Roberto Sassu, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, safford, ramunno, tyhicks, kirkland

On Wed, 2011-01-26 at 11:03 +0000, David Howells wrote:
> Roberto Sassu <roberto.sassu@polito.it> wrote:
> 
> > This patch introduces a new parameter, called 'format', that defines the
> > format of data stored by encrypted keys. The 'default' format identifies
> > encrypted keys containing only the symmetric key, while other formats can
> > be defined to support additional information. The 'format' parameter is
> > written in the datablob produced by commands 'keyctl print' or
> > 'keyctl pipe' and is integrity protected by the HMAC.
> 
> Would it make more sense to take key=val pairs where you have the <format>
> parameter?  Then you could have a format=default|foo|whatever argument and
> you'd leave room for future addition of qualifiers.
> 
> David

Either way it is extensible.  The current format is:

keyctl add encrypted name "new [format] key-type:master-key-name keylen" ring

As none of the other encrypted key parameters are defined as keypairs,
I'd prefer leaving the format option as it is.

thanks,

Mimi


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support
  2011-01-26 11:18 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support David Howells
@ 2011-01-26 12:57   ` Mimi Zohar
  0 siblings, 0 replies; 19+ messages in thread
From: Mimi Zohar @ 2011-01-26 12:57 UTC (permalink / raw)
  To: David Howells
  Cc: Roberto Sassu, linux-security-module, keyrings, linux-fsdevel,
	linux-kernel, jmorris, safford, ramunno, tyhicks, kirkland

On Wed, 2011-01-26 at 11:18 +0000, David Howells wrote:
> Roberto Sassu <roberto.sassu@polito.it> wrote:
> 
> >  security/keys/keys_ecryptfs.c            |   81 ++++++++++++++++++++++++++++++
> >  security/keys/keys_ecryptfs.h            |   30 +++++++++++
> 
> Can you rename these files please?  The 'keys' prefix is redundant.  They're
> obviously about keys, or they shouldn't be in this directory.  I'd suggest
> something like 'ecryptfs_format.[ch]'.
> 
> You might want to make a subdir here specifically for the trusted and
> encrypted keys and all their formats and move those files into it if you're
> going to have lots of formats.

We think most other encrypted key usages will be unformatted. Perhaps,
for the time being, we should wait and see before making an 'encrypted'
subdirectory. 

Mimi

> >  /*
> > + * valid_ecryptfs_desc - verify the description of a new/loaded encrypted key
> > + *
> > + * The description of a encrypted key with format 'ecryptfs' must contain
> > + * exactly 16 hexadecimal characters.
> > + *
> > + */
> > +static int valid_ecryptfs_desc(const char *ecryptfs_desc)
> > +{
> 
> I think we need an additional key type operation - one that allows you to pass
> judgement on the description to be given for a key in key_alloc().  On the
> other hand, this doesn't help here as you can't do a full check on the key
> description without the payload.
> 
> David
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 3/6] encrypted-keys: add key format support
  2011-01-26 11:03 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support David Howells
  2011-01-26 11:52   ` Mimi Zohar
@ 2011-01-26 13:01   ` David Howells
  1 sibling, 0 replies; 19+ messages in thread
From: David Howells @ 2011-01-26 13:01 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: dhowells, Roberto Sassu, linux-security-module, keyrings,
	linux-fsdevel, linux-kernel, jmorris, safford, ramunno, tyhicks,
	kirkland

Mimi Zohar <zohar@linux.vnet.ibm.com> wrote:

> Either way it is extensible.  The current format is:
> 
> keyctl add encrypted name "new [format] key-type:master-key-name keylen" ring
> 
> As none of the other encrypted key parameters are defined as keypairs,
> I'd prefer leaving the format option as it is.

Okay.  Feel free to add my Acked-by then.

David

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type
  2011-01-26 11:28 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type David Howells
@ 2011-01-27 18:59   ` Roberto Sassu
  0 siblings, 0 replies; 19+ messages in thread
From: Roberto Sassu @ 2011-01-27 18:59 UTC (permalink / raw)
  To: David Howells
  Cc: linux-security-module, keyrings, linux-fsdevel, linux-kernel,
	jmorris, zohar, safford, ramunno, tyhicks, kirkland

Hi David

thanks for the review!
I just need a clarification about the comment of this patch.
Regarding the locking issue, this also applies for the unpatched
version of eCryptfs, because the 'user' key type has the
'update' method defined. However, i think the read lock is not
enough because eCryptfs directly writes on the key's payload
in order to update the state of the authentication token.

I've developed a small patch, i will post shortly with Tyler Hicks
in CC, that locks requested keys for writing.

Roberto Sassu


On Wednesday, January 26, 2011 12:28:36 pm David Howells wrote:
> Roberto Sassu <roberto.sassu@polito.it> wrote:
> 
> >  	(*auth_tok_key) = request_key(&key_type_user, sig, NULL);
> >  	if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> > -		printk(KERN_ERR "Could not find key with description: [%s]\n",
> > -		       sig);
> > -		rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> > -		goto out;
> > +		(*auth_tok_key) = ecryptfs_get_encrypted_key(sig);
> > +		if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
> > +			printk(KERN_ERR "Could not find key with description: [%s]\n",
> > +			      sig);
> > +			rc = process_request_key_err(PTR_ERR(*auth_tok_key));
> > +			goto out;
> > +		}
> >  	}
> >  	(*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
> >  	if (ecryptfs_verify_version((*auth_tok)->version)) {
> 
> You need some locking here, even if it's only use of the RCU read lock.
> Encrypted-type keys have an update method and so may change under you.
> 
> David
> ---
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-01-27 18:59 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-24 16:44 [RFC][PATCH v3 0/6] eCryptfs: added support for the encrypted key type Roberto Sassu
2011-01-24 16:44 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description Roberto Sassu
2011-01-24 16:44 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages Roberto Sassu
2011-01-24 16:44 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support Roberto Sassu
2011-01-24 16:44 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h Roberto Sassu
2011-01-24 16:44 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support Roberto Sassu
2011-01-25 22:57   ` Tyler Hicks
2011-01-24 16:44 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type Roberto Sassu
2011-01-25 22:41   ` Tyler Hicks
2011-01-26 10:49 ` [RFC][PATCH v3 2/6] encrypted-keys: added additional debug messages David Howells
2011-01-26 11:03 ` [RFC][PATCH v3 3/6] encrypted-keys: add key format support David Howells
2011-01-26 11:52   ` Mimi Zohar
2011-01-26 13:01   ` David Howells
2011-01-26 11:05 ` [RFC][PATCH v3 4/6] eCryptfs: export global eCryptfs definitions to include/linux/ecryptfs.h David Howells
2011-01-26 11:05 ` [RFC][PATCH v3 1/6] encrypted-keys: fixed valid_master_desc() function description David Howells
2011-01-26 11:18 ` [RFC][PATCH v3 5/6] encrypted-keys: add ecryptfs format support David Howells
2011-01-26 12:57   ` Mimi Zohar
2011-01-26 11:28 ` [RFC][PATCH v3 6/6] eCryptfs: added support for the encrypted key type David Howells
2011-01-27 18:59   ` Roberto Sassu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.