* [PATCH 1/12] asm/scatterlist.h -> linux/scatterlist.h
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
@ 2006-06-20 21:22 ` Mike Halcrow
2006-06-20 21:22 ` [PATCH 2/12] Support for larger maximum key size Mike Halcrow
` (10 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Grab the scatterlist header from the right place.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 1 -
fs/ecryptfs/keystore.c | 2 +-
fs/ecryptfs/mmap.c | 2 +-
3 files changed, 2 insertions(+), 3 deletions(-)
bdf5f99c53c8be77cdef2aa1aacdc30383676255
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 49b7eb3..5de537c 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -33,7 +33,6 @@ #include <linux/namei.h>
#include <linux/crypto.h>
#include <linux/file.h>
#include <linux/scatterlist.h>
-#include <asm/scatterlist.h>
#include "ecryptfs_kernel.h"
/**
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 7c5ac0d..c250888 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -31,7 +31,7 @@ #include <linux/pagemap.h>
#include <linux/key.h>
#include <linux/random.h>
#include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include "ecryptfs_kernel.h"
/**
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index e9cff02..ad48b3e 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -31,7 +31,7 @@ #include <linux/page-flags.h>
#include <linux/mount.h>
#include <linux/file.h>
#include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include "ecryptfs_kernel.h"
struct kmem_cache *ecryptfs_lower_page_cache;
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 2/12] Support for larger maximum key size
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
2006-06-20 21:22 ` [PATCH 1/12] asm/scatterlist.h -> linux/scatterlist.h Mike Halcrow
@ 2006-06-20 21:22 ` Mike Halcrow
2006-06-21 14:49 ` Timothy R. Chavez
2006-06-20 21:23 ` [PATCH 3/12] Add codes for additional ciphers Mike Halcrow
` (9 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Support for larger maximum key size. Necessary for future patches that
will enable cipher selection and keysize specification. Increments the
version number because ECRYPTFS_MAX_KEY_BYTES changes, which changes a
struct that is accessed in both userspace and kernel space.
Note that with this patch, users must upgrade their userspace utility
package to one prefixed ``ecryptfs-util-git-2.6.17-rc6-mm2++'' or
higher (see the eCryptfs SourceForge page for userspace utilities).
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/ecryptfs_kernel.h | 4 ++--
fs/ecryptfs/keystore.c | 34 ++++++++++++++++++----------------
2 files changed, 20 insertions(+), 18 deletions(-)
d13ab4035bb6c56bfb7d82523069324523e99f62
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 8e35dbd..1fd6039 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -32,7 +32,7 @@ #include <linux/scatterlist.h>
/* Version verification for shared data structures w/ userspace */
#define ECRYPTFS_VERSION_MAJOR 0x00
-#define ECRYPTFS_VERSION_MINOR 0x01
+#define ECRYPTFS_VERSION_MINOR 0x02
#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x01
#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
@@ -45,7 +45,7 @@ #define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS
#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 16
+#define ECRYPTFS_MAX_KEY_BYTES 64
#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
#define ECRYPTFS_DEFAULT_IV_BYTES 16
#define ECRYPTFS_FILE_VERSION 0x01
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index c250888..a83914c 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -486,8 +486,17 @@ static int decrypt_session_key(struct ec
rc = -ENOMEM;
goto out;
}
+ if (password_s_ptr->session_key_encryption_key_bytes
+ < crypto_tfm_alg_min_keysize(tfm)) {
+ printk(KERN_WARNING "Session key encryption key is [%d] bytes; "
+ "minimum keysize for selected cipher is [%d] bytes.\n",
+ password_s_ptr->session_key_encryption_key_bytes,
+ crypto_tfm_alg_min_keysize(tfm));
+ rc = -EINVAL;
+ goto out;
+ }
crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
- password_s_ptr->session_key_encryption_key_bytes);
+ (crypt_stat->key_size_bits / 8));
/* TODO: virt_to_scatterlist */
encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
if (!encrypted_session_key) {
@@ -806,24 +815,18 @@ write_tag_3_packet(char *dest, int max,
ECRYPTFS_SIG_SIZE);
(*key_rec).enc_key_size_bits = crypt_stat->key_size_bits;
encrypted_session_key_valid = 0;
- if (auth_tok->session_key.encrypted_key_size == 0)
- auth_tok->session_key.encrypted_key_size =
- ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES;
- for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)
+ for (i = 0; i < (crypt_stat->key_size_bits / 8); i++)
encrypted_session_key_valid |=
auth_tok->session_key.encrypted_key[i];
- if (auth_tok->session_key.encrypted_key_size == 0) {
- ecryptfs_printk(KERN_WARNING, "auth_tok->session_key."
- "encrypted_key_size == 0");
- auth_tok->session_key.encrypted_key_size =
- ECRYPTFS_DEFAULT_KEY_BYTES;
- }
if (encrypted_session_key_valid) {
memcpy((*key_rec).enc_key,
auth_tok->session_key.encrypted_key,
auth_tok->session_key.encrypted_key_size);
goto encrypted_session_key_set;
}
+ if (auth_tok->session_key.encrypted_key_size == 0)
+ auth_tok->session_key.encrypted_key_size =
+ (crypt_stat->key_size_bits / 8);
if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
ecryptfs_printk(KERN_DEBUG, "Using previously generated "
@@ -832,8 +835,7 @@ write_tag_3_packet(char *dest, int max,
session_key_encryption_key_bytes);
memcpy(session_key_encryption_key,
auth_tok->token.password.session_key_encryption_key,
- auth_tok->token.password.
- session_key_encryption_key_bytes);
+ (crypt_stat->key_size_bits / 8));
ecryptfs_printk(KERN_DEBUG,
"Cached session key " "encryption key: \n");
if (ecryptfs_verbosity > 0)
@@ -870,7 +872,7 @@ write_tag_3_packet(char *dest, int max,
goto out;
}
rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
- ECRYPTFS_DEFAULT_KEY_BYTES);
+ (crypt_stat->key_size_bits / 8));
if (rc < 0) {
ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
"context\n");
@@ -880,7 +882,7 @@ write_tag_3_packet(char *dest, int max,
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
crypt_stat->key_size_bits / 8);
crypto_cipher_encrypt(tfm, dest_sg, src_sg,
- crypt_stat->key_size_bits / 8);
+ (crypt_stat->key_size_bits / 8));
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex((*key_rec).enc_key,
@@ -889,7 +891,7 @@ encrypted_session_key_set:
/* Now we have a valid key_rec. Append it to the
* key_rec set. */
key_rec_size = (sizeof(struct ecryptfs_key_record)
- - ECRYPTFS_MAX_KEY_BYTES
+ - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
+ ((*key_rec).enc_key_size_bits / 8) );
/* TODO: Include a packet size limit as a parameter to this
* function once we have multi-packet headers (for versions
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 2/12] Support for larger maximum key size
2006-06-20 21:22 ` [PATCH 2/12] Support for larger maximum key size Mike Halcrow
@ 2006-06-21 14:49 ` Timothy R. Chavez
2006-06-21 15:50 ` Michael Halcrow
0 siblings, 1 reply; 16+ messages in thread
From: Timothy R. Chavez @ 2006-06-21 14:49 UTC (permalink / raw)
To: Mike Halcrow; +Cc: Andrew Morton, linux-kernel, linux-fsdevel, Mike Halcrow
<snip>
> @@ -806,24 +815,18 @@ write_tag_3_packet(char *dest, int max,
> ECRYPTFS_SIG_SIZE);
> (*key_rec).enc_key_size_bits = crypt_stat->key_size_bits;
> encrypted_session_key_valid = 0;
> - if (auth_tok->session_key.encrypted_key_size == 0)
> - auth_tok->session_key.encrypted_key_size =
> - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES;
> - for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)
> + for (i = 0; i < (crypt_stat->key_size_bits / 8); i++)
Hey Mike,
Why don't you just do this particular calculation once? Just looking
down, you do this same calculation at least 4 other potential times.
int key_size_bytes = crypt_stat->key_size_bits / 8;
for (i = 0; i < key_size_bytes; i++)
-tim
> encrypted_session_key_valid |=
> auth_tok->session_key.encrypted_key[i];
> - if (auth_tok->session_key.encrypted_key_size == 0) {
> - ecryptfs_printk(KERN_WARNING, "auth_tok->session_key."
> - "encrypted_key_size == 0");
> - auth_tok->session_key.encrypted_key_size =
> - ECRYPTFS_DEFAULT_KEY_BYTES;
> - }
> if (encrypted_session_key_valid) {
> memcpy((*key_rec).enc_key,
> auth_tok->session_key.encrypted_key,
> auth_tok->session_key.encrypted_key_size);
> goto encrypted_session_key_set;
> }
> + if (auth_tok->session_key.encrypted_key_size == 0)
> + auth_tok->session_key.encrypted_key_size =
> + (crypt_stat->key_size_bits / 8);
> if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
> ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
> ecryptfs_printk(KERN_DEBUG, "Using previously generated "
> @@ -832,8 +835,7 @@ write_tag_3_packet(char *dest, int max,
> session_key_encryption_key_bytes);
> memcpy(session_key_encryption_key,
> auth_tok->token.password.session_key_encryption_key,
> - auth_tok->token.password.
> - session_key_encryption_key_bytes);
> + (crypt_stat->key_size_bits / 8));
> ecryptfs_printk(KERN_DEBUG,
> "Cached session key " "encryption key: \n");
> if (ecryptfs_verbosity > 0)
> @@ -870,7 +872,7 @@ write_tag_3_packet(char *dest, int max,
> goto out;
> }
> rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
> - ECRYPTFS_DEFAULT_KEY_BYTES);
> + (crypt_stat->key_size_bits / 8));
> if (rc < 0) {
> ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
> "context\n");
> @@ -880,7 +882,7 @@ write_tag_3_packet(char *dest, int max,
> ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
> crypt_stat->key_size_bits / 8);
> crypto_cipher_encrypt(tfm, dest_sg, src_sg,
> - crypt_stat->key_size_bits / 8);
> + (crypt_stat->key_size_bits / 8));
> ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
> if (ecryptfs_verbosity > 0)
> ecryptfs_dump_hex((*key_rec).enc_key,
> @@ -889,7 +891,7 @@ encrypted_session_key_set:
> /* Now we have a valid key_rec. Append it to the
> * key_rec set. */
> key_rec_size = (sizeof(struct ecryptfs_key_record)
> - - ECRYPTFS_MAX_KEY_BYTES
> + - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
> + ((*key_rec).enc_key_size_bits / 8) );
> /* TODO: Include a packet size limit as a parameter to this
> * function once we have multi-packet headers (for versions
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH 2/12] Support for larger maximum key size
2006-06-21 14:49 ` Timothy R. Chavez
@ 2006-06-21 15:50 ` Michael Halcrow
0 siblings, 0 replies; 16+ messages in thread
From: Michael Halcrow @ 2006-06-21 15:50 UTC (permalink / raw)
To: Timothy R. Chavez
Cc: Andrew Morton, linux-kernel, linux-fsdevel, Mike Halcrow
[-- Attachment #1: Type: text/plain, Size: 496 bytes --]
On Wed, Jun 21, 2006 at 09:49:57AM -0500, Timothy R. Chavez wrote:
> > - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES;
> > - for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)
> > + for (i = 0; i < (crypt_stat->key_size_bits / 8); i++)
>
> Why don't you just do this particular calculation once? Just looking
> down, you do this same calculation at least 4 other potential times.
Patch #10 in this set changes the keysize to bytes, so this is a
resolved issue.
Thanks,
Mike
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 481 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/12] Add codes for additional ciphers
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
2006-06-20 21:22 ` [PATCH 1/12] asm/scatterlist.h -> linux/scatterlist.h Mike Halcrow
2006-06-20 21:22 ` [PATCH 2/12] Support for larger maximum key size Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-21 15:08 ` Timothy R. Chavez
2006-06-20 21:23 ` [PATCH 4/12] Unencrypted key size based on encrypted key size Mike Halcrow
` (8 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Add a few codes for additional ciphers to be supported by eCryptfs,
enabled by future patches in this set.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
339e1f091cdadd99ee536c058f31ba28682fac88
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 5de537c..c278c20 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1018,10 +1018,14 @@ struct ecryptfs_cipher_code_str_map_elem
/* List in order of probability. */
static struct ecryptfs_cipher_code_str_map_elem
ecryptfs_cipher_code_str_map[] = {
- {"aes", 0x07},
+ {"aes", 0x07}, /* AES-128 */
{"blowfish", 0x04},
{"des3_ede", 0x02},
- {"cast5", 0x03}
+ {"cast5", 0x03},
+ {"twofish", 0x0a},
+ {"cast6", 0x0b},
+ {"aes", 0x08}, /* AES-192 */
+ {"aes", 0x09} /* AES-256 */
};
/**
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* Re: [PATCH 3/12] Add codes for additional ciphers
2006-06-20 21:23 ` [PATCH 3/12] Add codes for additional ciphers Mike Halcrow
@ 2006-06-21 15:08 ` Timothy R. Chavez
0 siblings, 0 replies; 16+ messages in thread
From: Timothy R. Chavez @ 2006-06-21 15:08 UTC (permalink / raw)
To: Mike Halcrow; +Cc: Andrew Morton, linux-kernel, linux-fsdevel, Mike Halcrow
<snip>
> @@ -1018,10 +1018,14 @@ struct ecryptfs_cipher_code_str_map_elem
> /* List in order of probability. */
> static struct ecryptfs_cipher_code_str_map_elem
> ecryptfs_cipher_code_str_map[] = {
> - {"aes", 0x07},
> + {"aes", 0x07}, /* AES-128 */
> {"blowfish", 0x04},
> {"des3_ede", 0x02},
> - {"cast5", 0x03}
> + {"cast5", 0x03},
> + {"twofish", 0x0a},
> + {"cast6", 0x0b},
> + {"aes", 0x08}, /* AES-192 */
> + {"aes", 0x09} /* AES-256 */
> };
A ridiculously trivial suggestion here, but maybe just add the last
element of this table as such: {"aes", 0x09},... Not that it's overly
important, but it'll kill a couple unnecessary lines in the next patch
to this table. Also, why not simply include the key-size in the name
(e.g. {"aes192", 0x08},}? Granted, I haven't looked around at how this
string is being used in your code...
-tim
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 4/12] Unencrypted key size based on encrypted key size
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (2 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 3/12] Add codes for additional ciphers Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-20 21:23 ` [PATCH 5/12] Packet and key management update for variable " Mike Halcrow
` (7 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Set the unencrypted key size based on the encrypted key size. Code to
handle the special case of AES-192; since the encrypted key size must
be a multiple of the cipher block size, we have 32 bytes of encrypted
key data, and we only take the first 24 bytes of the decrypted key
data.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/keystore.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
de5316936897d0a932f5bf15f5dfb1325db39fc0
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index a83914c..253901a 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -247,15 +247,12 @@ parse_tag_3_packet(struct ecryptfs_crypt
/* A little extra work to differentiate among the AES key
* sizes; see RFC2440 */
switch(data[(*packet_size)++]) {
- case 0x07:
- crypt_stat->key_size_bits = 128;
- break;
case 0x08:
crypt_stat->key_size_bits = 192;
break;
- case 0x09:
- crypt_stat->key_size_bits = 256;
- break;
+ default:
+ crypt_stat->key_size_bits =
+ (*new_auth_tok)->session_key.encrypted_key_size << 3;
}
if (unlikely((*packet_size) > max_packet_size)) {
ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 5/12] Packet and key management update for variable key size
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (3 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 4/12] Unencrypted key size based on encrypted key size Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-20 21:23 ` [PATCH 6/12] Add ecryptfs_ prefix to mount options; key size parameter Mike Halcrow
` (6 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Modify packet and session key management code to support different key
sizes.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/keystore.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)
9d85fe55c87fbfe9476f37078f05c40c1d1319ed
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 1a9917d..101773f 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -530,8 +530,6 @@ static int decrypt_session_key(struct ec
memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
auth_tok->session_key.decrypted_key_size);
ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
- crypt_stat->key_size_bits =
- auth_tok->session_key.decrypted_key_size * 8;
ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex(crypt_stat->key,
@@ -810,11 +808,10 @@ write_tag_3_packet(char *dest, int max,
BUG();
ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature,
ECRYPTFS_SIG_SIZE);
- (*key_rec).enc_key_size_bits = crypt_stat->key_size_bits;
encrypted_session_key_valid = 0;
for (i = 0; i < (crypt_stat->key_size_bits / 8); i++)
encrypted_session_key_valid |=
- auth_tok->session_key.encrypted_key[i];
+ auth_tok->session_key.encrypted_key[i];
if (encrypted_session_key_valid) {
memcpy((*key_rec).enc_key,
auth_tok->session_key.encrypted_key,
@@ -824,6 +821,13 @@ write_tag_3_packet(char *dest, int max,
if (auth_tok->session_key.encrypted_key_size == 0)
auth_tok->session_key.encrypted_key_size =
(crypt_stat->key_size_bits / 8);
+ if (crypt_stat->key_size_bits == 192
+ && strcmp("aes", crypt_stat->cipher) == 0) {
+ memset((crypt_stat->key + 24), 0, 8);
+ auth_tok->session_key.encrypted_key_size = 32;
+ }
+ (*key_rec).enc_key_size_bits =
+ auth_tok->session_key.encrypted_key_size << 3;
if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
ecryptfs_printk(KERN_DEBUG, "Using previously generated "
@@ -839,14 +843,11 @@ write_tag_3_packet(char *dest, int max,
ecryptfs_dump_hex(session_key_encryption_key, 16);
}
if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Session key encryption key:"
- "\n");
+ ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");
ecryptfs_dump_hex(session_key_encryption_key, 16);
}
- /* Encrypt the key with the key encryption key */
- /* Set up the scatterlists */
rc = virt_to_scatterlist(crypt_stat->key,
- crypt_stat->key_size_bits / 8, src_sg, 2);
+ (*key_rec).enc_key_size_bits / 8, src_sg, 2);
if (!rc) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
"for crypt_stat session key\n");
@@ -879,7 +880,7 @@ write_tag_3_packet(char *dest, int max,
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
crypt_stat->key_size_bits / 8);
crypto_cipher_encrypt(tfm, dest_sg, src_sg,
- (crypt_stat->key_size_bits / 8));
+ (*key_rec).enc_key_size_bits / 8);
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex((*key_rec).enc_key,
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 6/12] Add ecryptfs_ prefix to mount options; key size parameter
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (4 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 5/12] Packet and key management update for variable " Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-20 21:23 ` [PATCH 7/12] Set the key size from the default for the mount Mike Halcrow
` (5 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Add ecryptfs_ prefix to ecryptfs-specific mount options to avoid
conflicts from changes to /bin/mount. Debian's addition of ``keybits''
in its mount program left us scratching our heads when we happened to
pick the exact same parameter name at first for this patch. This patch
includes an aptly-named parameter to set the number of key bytes.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/ecryptfs_kernel.h | 1 +
fs/ecryptfs/main.c | 36 +++++++++++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletions(-)
5488f5ad764088bb99ba1980d9967da3aeb2ff12
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 1fd6039..4dc95af 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -220,6 +220,7 @@ struct ecryptfs_mount_crypt_stat {
/* Pointers to memory we do not own, do not free these */
struct ecryptfs_auth_tok *global_auth_tok;
struct key *global_auth_tok_key;
+ unsigned int global_default_cipher_key_bits;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1];
unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 5cbc948..57bbce7 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -125,13 +125,19 @@ out:
return rc;
}
-enum { ecryptfs_opt_sig, ecryptfs_opt_debug, ecryptfs_opt_cipher,
+enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug,
+ ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher,
+ ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes,
ecryptfs_opt_err };
static match_table_t tokens = {
{ecryptfs_opt_sig, "sig=%s"},
+ {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"},
{ecryptfs_opt_debug, "debug=%u"},
+ {ecryptfs_opt_ecryptfs_debug, "ecryptfs_debug=%u"},
{ecryptfs_opt_cipher, "cipher=%s"},
+ {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"},
+ {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"},
{ecryptfs_opt_err, NULL}
};
@@ -192,6 +198,8 @@ static int ecryptfs_parse_options(struct
int rc = 0;
int sig_set = 0;
int cipher_name_set = 0;
+ int cipher_key_bytes;
+ int cipher_key_bytes_set = 0;
struct key *auth_tok_key = NULL;
struct ecryptfs_auth_tok *auth_tok = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
@@ -203,6 +211,7 @@ static int ecryptfs_parse_options(struct
char *debug_src;
char *cipher_name_dst;
char *cipher_name_src;
+ char *cipher_key_bytes_src;
int cipher_name_len;
if (!options) {
@@ -215,6 +224,7 @@ static int ecryptfs_parse_options(struct
token = match_token(p, tokens, args);
switch (token) {
case ecryptfs_opt_sig:
+ case ecryptfs_opt_ecryptfs_sig:
sig_src = args[0].from;
sig_dst =
mount_crypt_stat->global_auth_tok_sig;
@@ -227,6 +237,7 @@ static int ecryptfs_parse_options(struct
sig_set = 1;
break;
case ecryptfs_opt_debug:
+ case ecryptfs_opt_ecryptfs_debug:
debug_src = args[0].from;
ecryptfs_verbosity =
(int)simple_strtol(debug_src, &debug_src,
@@ -236,6 +247,7 @@ static int ecryptfs_parse_options(struct
ecryptfs_verbosity);
break;
case ecryptfs_opt_cipher:
+ case ecryptfs_opt_ecryptfs_cipher:
cipher_name_src = args[0].from;
cipher_name_dst =
mount_crypt_stat->
@@ -248,6 +260,20 @@ static int ecryptfs_parse_options(struct
"[%s]\n", cipher_name_dst);
cipher_name_set = 1;
break;
+ case ecryptfs_opt_ecryptfs_key_bytes:
+ cipher_key_bytes_src = args[0].from;
+ cipher_key_bytes =
+ (int)simple_strtol(cipher_key_bytes_src,
+ &cipher_key_bytes_src, 0);
+ mount_crypt_stat->global_default_cipher_key_bits =
+ cipher_key_bytes << 3;
+ ecryptfs_printk(KERN_DEBUG,
+ "The mount_crypt_stat "
+ "global_default_cipher_key_bits "
+ "set to: [%d]\n", mount_crypt_stat->
+ global_default_cipher_key_bits);
+ cipher_key_bytes_set = 1;
+ break;
case ecryptfs_opt_err:
default:
ecryptfs_printk(KERN_WARNING,
@@ -277,6 +303,14 @@ static int ecryptfs_parse_options(struct
mount_crypt_stat->global_default_cipher_name[cipher_name_len]
= '\0';
}
+ if (!cipher_key_bytes_set) {
+ mount_crypt_stat->global_default_cipher_key_bits =
+ ECRYPTFS_DEFAULT_KEY_BYTES << 3;
+ ecryptfs_printk(KERN_DEBUG, "Cipher key bits were not "
+ "specified. Defaulting to [%d]\n",
+ mount_crypt_stat->
+ global_default_cipher_key_bits);
+ }
ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
"[%s]\n", mount_crypt_stat->global_auth_tok_sig);
/* The reference to this key is held until umount is done The
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 7/12] Set the key size from the default for the mount
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (5 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 6/12] Add ecryptfs_ prefix to mount options; key size parameter Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-20 21:23 ` [PATCH 8/12] Check for weak keys Mike Halcrow
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Remove the hard-coded key size and use the one specified through the
mount parameter.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 34 +++++++++++++++++++++-------------
1 files changed, 21 insertions(+), 13 deletions(-)
1c89f303eaa145c890c10369fa8a6835fbf0fbd8
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index c278c20..966426d 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -730,8 +730,10 @@ int ecryptfs_init_crypt_ctx(struct ecryp
goto out;
}
ecryptfs_printk(KERN_DEBUG,
- "Initializing cipher [%s]; strlen = [%d]\n",
- crypt_stat->cipher, (int)strlen(crypt_stat->cipher));
+ "Initializing cipher [%s]; strlen = [%d]; "
+ "key_size_bits = [%d]\n",
+ crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
+ crypt_stat->key_size_bits);
if (crypt_stat->tfm) {
rc = 0;
goto out;
@@ -816,6 +818,18 @@ out:
return rc;
}
+static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
+{
+ get_random_bytes(crypt_stat->key, (crypt_stat->key_size_bits >> 3));
+ ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
+ ecryptfs_compute_root_iv(crypt_stat);
+ if (unlikely(ecryptfs_verbosity > 0)) {
+ ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
+ ecryptfs_dump_hex(crypt_stat->key,
+ crypt_stat->key_size_bits / 8);
+ }
+}
+
/**
* ecryptfs_set_default_crypt_stat_vals
* @crypt_stat
@@ -825,19 +839,10 @@ out:
static void
ecryptfs_set_default_crypt_stat_vals(struct ecryptfs_crypt_stat *crypt_stat)
{
- int key_size_bits = ECRYPTFS_DEFAULT_KEY_BYTES * 8;
-
ecryptfs_set_default_sizes(crypt_stat);
strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
- crypt_stat->key_size_bits = key_size_bits;
- get_random_bytes(crypt_stat->key, key_size_bits / 8);
- ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
- ecryptfs_compute_root_iv(crypt_stat);
- if (unlikely(ecryptfs_verbosity > 0)) {
- ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
- ecryptfs_dump_hex(crypt_stat->key,
- crypt_stat->key_size_bits / 8);
- }
+ crypt_stat->key_size_bits = ECRYPTFS_DEFAULT_KEY_BYTES << 3;
+ ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
}
@@ -887,6 +892,9 @@ int ecryptfs_new_file_context(struct den
mount_crypt_stat->global_default_cipher_name,
cipher_name_len);
crypt_stat->cipher[cipher_name_len] = '\0';
+ crypt_stat->key_size_bits =
+ mount_crypt_stat->global_default_cipher_key_bits;
+ ecryptfs_generate_new_key(crypt_stat);
} else
/* We should not encounter this scenario since we
* should detect lack of global_auth_tok at mount time
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 8/12] Check for weak keys
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (6 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 7/12] Set the key size from the default for the mount Mike Halcrow
@ 2006-06-20 21:23 ` Mike Halcrow
2006-06-20 21:24 ` [PATCH 9/12] Add #define values for cipher codes from RFC2440 (OpenPGP) Mike Halcrow
` (3 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:23 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Check for weak keys.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
54bfaad87b42a4bfe9bb0890eebc3a69d877d03e
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 966426d..5292220 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -739,7 +739,8 @@ int ecryptfs_init_crypt_ctx(struct ecryp
goto out;
}
crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
- ECRYPTFS_DEFAULT_CHAINING_MODE);
+ ECRYPTFS_DEFAULT_CHAINING_MODE
+ | CRYPTO_TFM_REQ_WEAK_KEY);
if (crypt_stat->tfm == NULL) {
ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): Error "
"initializing cipher [%s]\n",
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 9/12] Add #define values for cipher codes from RFC2440 (OpenPGP)
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (7 preceding siblings ...)
2006-06-20 21:23 ` [PATCH 8/12] Check for weak keys Mike Halcrow
@ 2006-06-20 21:24 ` Mike Halcrow
2006-06-20 21:24 ` [PATCH 10/12] Convert bits to bytes Mike Halcrow
` (2 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:24 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Add #define values for cipher codes from RFC2440 (OpenPGP).
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 19 +++++++++----------
fs/ecryptfs/ecryptfs_kernel.h | 9 +++++++++
fs/ecryptfs/keystore.c | 8 ++++----
3 files changed, 22 insertions(+), 14 deletions(-)
892f18996cb6a98db0065db51395998eea989fa8
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 5292220..426e5e4 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1023,18 +1023,17 @@ struct ecryptfs_cipher_code_str_map_elem
/* Add support for additional ciphers by adding elements here. The
* cipher_code is whatever OpenPGP applicatoins use to identify the
- * ciphers. */
-/* List in order of probability. */
+ * ciphers. List in order of probability. */
static struct ecryptfs_cipher_code_str_map_elem
ecryptfs_cipher_code_str_map[] = {
- {"aes", 0x07}, /* AES-128 */
- {"blowfish", 0x04},
- {"des3_ede", 0x02},
- {"cast5", 0x03},
- {"twofish", 0x0a},
- {"cast6", 0x0b},
- {"aes", 0x08}, /* AES-192 */
- {"aes", 0x09} /* AES-256 */
+ {"aes",RFC2440_CIPHER_AES_128 },
+ {"blowfish", RFC2440_CIPHER_BLOWFISH},
+ {"des3_ede", RFC2440_CIPHER_DES3_EDE},
+ {"cast5", RFC2440_CIPHER_CAST_5},
+ {"twofish", RFC2440_CIPHER_TWOFISH},
+ {"cast6", RFC2440_CIPHER_CAST_6},
+ {"aes", RFC2440_CIPHER_AES_192},
+ {"aes", RFC2440_CIPHER_AES_256}
};
/**
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 4dc95af..39057a8 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -53,6 +53,15 @@ #define ECRYPTFS_DEFAULT_HEADER_EXTENT_S
#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
+#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 ECRYPTFS_SET_FLAG(flag_bit_vector, flag) (flag_bit_vector |= (flag))
#define ECRYPTFS_CLEAR_FLAG(flag_bit_vector, flag) (flag_bit_vector &= ~(flag))
#define ECRYPTFS_CHECK_FLAG(flag_bit_vector, flag) (flag_bit_vector & (flag))
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 101773f..d301ac8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -247,7 +247,7 @@ parse_tag_3_packet(struct ecryptfs_crypt
/* A little extra work to differentiate among the AES key
* sizes; see RFC2440 */
switch(data[(*packet_size)++]) {
- case 0x08:
+ case RFC2440_CIPHER_AES_192:
crypt_stat->key_size_bits = 192;
break;
default:
@@ -931,15 +931,15 @@ encrypted_session_key_set:
goto out;
}
/* If it is AES, we need to get more specific. */
- if (cipher_code == 0x07) {
+ if (cipher_code == RFC2440_CIPHER_AES_128){
switch (crypt_stat->key_size_bits) {
case 128:
break;
case 192:
- cipher_code = 0x08; /* AES-192 */
+ cipher_code = RFC2440_CIPHER_AES_192;
break;
case 256:
- cipher_code = 0x09; /* AES-256 */
+ cipher_code = RFC2440_CIPHER_AES_256;
break;
default:
rc = -EINVAL;
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 10/12] Convert bits to bytes
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (8 preceding siblings ...)
2006-06-20 21:24 ` [PATCH 9/12] Add #define values for cipher codes from RFC2440 (OpenPGP) Mike Halcrow
@ 2006-06-20 21:24 ` Mike Halcrow
2006-06-20 21:24 ` [PATCH 11/12] More elegant AES key size manipulation Mike Halcrow
2006-06-20 21:24 ` [PATCH 12/12] More intelligent use of TFM objects Mike Halcrow
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:24 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Convert bits to bytes, since we only deal with bytes in the code.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 22 ++++++++---------
fs/ecryptfs/ecryptfs_kernel.h | 6 ++---
fs/ecryptfs/keystore.c | 54 +++++++++++++++++++++--------------------
fs/ecryptfs/main.c | 16 ++++++------
4 files changed, 49 insertions(+), 49 deletions(-)
9dfc9585b6a06bc80648fba36a415defaf215427
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 426e5e4..ab47899 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -249,13 +249,13 @@ static int encrypt_scatterlist(struct ec
ECRYPTFS_STRUCT_INITIALIZED));
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG, "Key size [%d]; key:\n",
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
ecryptfs_dump_hex(crypt_stat->key,
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
}
/* Consider doing this once, when the file is opened */
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
@@ -646,7 +646,7 @@ static int decrypt_scatterlist(struct ec
/* Consider doing this once, when the file is opened */
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
@@ -733,7 +733,7 @@ int ecryptfs_init_crypt_ctx(struct ecryp
"Initializing cipher [%s]; strlen = [%d]; "
"key_size_bits = [%d]\n",
crypt_stat->cipher, (int)strlen(crypt_stat->cipher),
- crypt_stat->key_size_bits);
+ crypt_stat->key_size << 3);
if (crypt_stat->tfm) {
rc = 0;
goto out;
@@ -803,7 +803,7 @@ int ecryptfs_compute_root_iv(struct ecry
goto out;
}
rc = ecryptfs_calculate_md5(dst, crypt_stat, crypt_stat->key,
- (crypt_stat->key_size_bits / 8));
+ crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error attempting to compute "
"MD5 while generating root IV\n");
@@ -821,13 +821,13 @@ out:
static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
{
- get_random_bytes(crypt_stat->key, (crypt_stat->key_size_bits >> 3));
+ get_random_bytes(crypt_stat->key, crypt_stat->key_size);
ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
ecryptfs_compute_root_iv(crypt_stat);
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(KERN_DEBUG, "Generated new session key:\n");
ecryptfs_dump_hex(crypt_stat->key,
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
}
}
@@ -842,7 +842,7 @@ ecryptfs_set_default_crypt_stat_vals(str
{
ecryptfs_set_default_sizes(crypt_stat);
strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
- crypt_stat->key_size_bits = ECRYPTFS_DEFAULT_KEY_BYTES << 3;
+ crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
}
@@ -893,8 +893,8 @@ int ecryptfs_new_file_context(struct den
mount_crypt_stat->global_default_cipher_name,
cipher_name_len);
crypt_stat->cipher[cipher_name_len] = '\0';
- crypt_stat->key_size_bits =
- mount_crypt_stat->global_default_cipher_key_bits;
+ crypt_stat->key_size =
+ mount_crypt_stat->global_default_cipher_key_size;
ecryptfs_generate_new_key(crypt_stat);
} else
/* We should not encounter this scenario since we
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 39057a8..cc88dc5 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -123,7 +123,7 @@ extern void ecryptfs_to_hex(char *dst, c
extern void ecryptfs_from_hex(char *dst, char *src, int dst_size);
struct ecryptfs_key_record {
- u16 enc_key_size_bits;
+ u16 enc_key_size;
unsigned char type;
unsigned char sig[ECRYPTFS_SIG_SIZE];
unsigned char enc_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
@@ -193,7 +193,7 @@ #define ECRYPTFS_KEY_VALID 0x00
unsigned int header_extent_size;
unsigned int num_header_extents_at_front;
unsigned int extent_size; /* Data extent size; default is 4096 */
- unsigned int key_size_bits;
+ unsigned int key_size;
unsigned int extent_shift;
unsigned int extent_mask;
struct crypto_tfm *tfm;
@@ -229,7 +229,7 @@ struct ecryptfs_mount_crypt_stat {
/* Pointers to memory we do not own, do not free these */
struct ecryptfs_auth_tok *global_auth_tok;
struct key *global_auth_tok_key;
- unsigned int global_default_cipher_key_bits;
+ unsigned int global_default_cipher_key_size;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1];
unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index d301ac8..37fa03b 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -248,11 +248,11 @@ parse_tag_3_packet(struct ecryptfs_crypt
* sizes; see RFC2440 */
switch(data[(*packet_size)++]) {
case RFC2440_CIPHER_AES_192:
- crypt_stat->key_size_bits = 192;
+ crypt_stat->key_size = 24;
break;
default:
- crypt_stat->key_size_bits =
- (*new_auth_tok)->session_key.encrypted_key_size << 3;
+ crypt_stat->key_size =
+ (*new_auth_tok)->session_key.encrypted_key_size;
}
if (unlikely((*packet_size) > max_packet_size)) {
ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n");
@@ -493,7 +493,7 @@ static int decrypt_session_key(struct ec
goto out;
}
crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
- (crypt_stat->key_size_bits / 8));
+ crypt_stat->key_size);
/* TODO: virt_to_scatterlist */
encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
if (!encrypted_session_key) {
@@ -533,7 +533,7 @@ static int decrypt_session_key(struct ec
ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex(crypt_stat->key,
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
free_page((unsigned long)encrypted_session_key);
memset(session_key, 0, PAGE_CACHE_SIZE);
@@ -809,7 +809,7 @@ write_tag_3_packet(char *dest, int max,
ecryptfs_from_hex((*key_rec).sig, auth_tok->token.password.signature,
ECRYPTFS_SIG_SIZE);
encrypted_session_key_valid = 0;
- for (i = 0; i < (crypt_stat->key_size_bits / 8); i++)
+ for (i = 0; i < crypt_stat->key_size; i++)
encrypted_session_key_valid |=
auth_tok->session_key.encrypted_key[i];
if (encrypted_session_key_valid) {
@@ -820,14 +820,14 @@ write_tag_3_packet(char *dest, int max,
}
if (auth_tok->session_key.encrypted_key_size == 0)
auth_tok->session_key.encrypted_key_size =
- (crypt_stat->key_size_bits / 8);
- if (crypt_stat->key_size_bits == 192
+ crypt_stat->key_size;
+ if (crypt_stat->key_size == 24
&& strcmp("aes", crypt_stat->cipher) == 0) {
memset((crypt_stat->key + 24), 0, 8);
auth_tok->session_key.encrypted_key_size = 32;
}
- (*key_rec).enc_key_size_bits =
- auth_tok->session_key.encrypted_key_size << 3;
+ (*key_rec).enc_key_size =
+ auth_tok->session_key.encrypted_key_size;
if (ECRYPTFS_CHECK_FLAG(auth_tok->token.password.flags,
ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET)) {
ecryptfs_printk(KERN_DEBUG, "Using previously generated "
@@ -836,7 +836,7 @@ write_tag_3_packet(char *dest, int max,
session_key_encryption_key_bytes);
memcpy(session_key_encryption_key,
auth_tok->token.password.session_key_encryption_key,
- (crypt_stat->key_size_bits / 8));
+ crypt_stat->key_size);
ecryptfs_printk(KERN_DEBUG,
"Cached session key " "encryption key: \n");
if (ecryptfs_verbosity > 0)
@@ -847,7 +847,7 @@ write_tag_3_packet(char *dest, int max,
ecryptfs_dump_hex(session_key_encryption_key, 16);
}
rc = virt_to_scatterlist(crypt_stat->key,
- (*key_rec).enc_key_size_bits / 8, src_sg, 2);
+ (*key_rec).enc_key_size, src_sg, 2);
if (!rc) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
"for crypt_stat session key\n");
@@ -855,7 +855,7 @@ write_tag_3_packet(char *dest, int max,
goto out;
}
rc = virt_to_scatterlist((*key_rec).enc_key,
- (*key_rec).enc_key_size_bits / 8, dest_sg, 2);
+ (*key_rec).enc_key_size, dest_sg, 2);
if (!rc) {
ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
"for crypt_stat encrypted session key\n");
@@ -870,7 +870,7 @@ write_tag_3_packet(char *dest, int max,
goto out;
}
rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
- (crypt_stat->key_size_bits / 8));
+ crypt_stat->key_size);
if (rc < 0) {
ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
"context\n");
@@ -878,19 +878,19 @@ write_tag_3_packet(char *dest, int max,
}
rc = 0;
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
- crypt_stat->key_size_bits / 8);
+ crypt_stat->key_size);
crypto_cipher_encrypt(tfm, dest_sg, src_sg,
- (*key_rec).enc_key_size_bits / 8);
+ (*key_rec).enc_key_size);
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex((*key_rec).enc_key,
- (*key_rec).enc_key_size_bits / 8);
+ (*key_rec).enc_key_size);
encrypted_session_key_set:
/* Now we have a valid key_rec. Append it to the
* key_rec set. */
key_rec_size = (sizeof(struct ecryptfs_key_record)
- ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
- + ((*key_rec).enc_key_size_bits / 8) );
+ + ((*key_rec).enc_key_size));
/* TODO: Include a packet size limit as a parameter to this
* function once we have multi-packet headers (for versions
* later than 0.1 */
@@ -902,7 +902,7 @@ encrypted_session_key_set:
/* TODO: Packet size limit */
/* We have 5 bytes of surrounding packet data */
if ((0x05 + ECRYPTFS_SALT_SIZE
- + ((*key_rec).enc_key_size_bits / 8)) >= PAGE_CACHE_SIZE) {
+ + (*key_rec).enc_key_size) >= PAGE_CACHE_SIZE) {
ecryptfs_printk(KERN_ERR, "Authentication token is too "
"large\n");
rc = -EINVAL;
@@ -914,7 +914,7 @@ encrypted_session_key_set:
/* ver+cipher+s2k+hash+salt+iter+enc_key */
rc = write_packet_length(&dest[(*packet_size)],
(0x05 + ECRYPTFS_SALT_SIZE
- + ((*key_rec).enc_key_size_bits / 8)),
+ + (*key_rec).enc_key_size),
&packet_size_length);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet "
@@ -932,20 +932,20 @@ encrypted_session_key_set:
}
/* If it is AES, we need to get more specific. */
if (cipher_code == RFC2440_CIPHER_AES_128){
- switch (crypt_stat->key_size_bits) {
- case 128:
+ switch (crypt_stat->key_size) {
+ case 16:
break;
- case 192:
+ case 24:
cipher_code = RFC2440_CIPHER_AES_192;
break;
- case 256:
+ case 32:
cipher_code = RFC2440_CIPHER_AES_256;
break;
default:
rc = -EINVAL;
ecryptfs_printk(KERN_WARNING, "Unsupported AES key "
"size: [%d]\n",
- crypt_stat->key_size_bits);
+ crypt_stat->key_size);
goto out;
}
}
@@ -957,8 +957,8 @@ encrypted_session_key_set:
(*packet_size) += ECRYPTFS_SALT_SIZE; /* salt */
dest[(*packet_size)++] = 0x60; /* hash iterations (65536) */
memcpy(&dest[(*packet_size)], (*key_rec).enc_key,
- (*key_rec).enc_key_size_bits / 8);
- (*packet_size) += ((*key_rec).enc_key_size_bits / 8);
+ (*key_rec).enc_key_size);
+ (*packet_size) += (*key_rec).enc_key_size;
out:
if (tfm)
crypto_free_tfm(tfm);
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 57bbce7..3a19e00 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -265,13 +265,13 @@ static int ecryptfs_parse_options(struct
cipher_key_bytes =
(int)simple_strtol(cipher_key_bytes_src,
&cipher_key_bytes_src, 0);
- mount_crypt_stat->global_default_cipher_key_bits =
- cipher_key_bytes << 3;
+ mount_crypt_stat->global_default_cipher_key_size =
+ cipher_key_bytes;
ecryptfs_printk(KERN_DEBUG,
"The mount_crypt_stat "
- "global_default_cipher_key_bits "
+ "global_default_cipher_key_size "
"set to: [%d]\n", mount_crypt_stat->
- global_default_cipher_key_bits);
+ global_default_cipher_key_size);
cipher_key_bytes_set = 1;
break;
case ecryptfs_opt_err:
@@ -304,12 +304,12 @@ static int ecryptfs_parse_options(struct
= '\0';
}
if (!cipher_key_bytes_set) {
- mount_crypt_stat->global_default_cipher_key_bits =
- ECRYPTFS_DEFAULT_KEY_BYTES << 3;
- ecryptfs_printk(KERN_DEBUG, "Cipher key bits were not "
+ mount_crypt_stat->global_default_cipher_key_size =
+ ECRYPTFS_DEFAULT_KEY_BYTES;
+ ecryptfs_printk(KERN_DEBUG, "Cipher key size was not "
"specified. Defaulting to [%d]\n",
mount_crypt_stat->
- global_default_cipher_key_bits);
+ global_default_cipher_key_size);
}
ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
"[%s]\n", mount_crypt_stat->global_auth_tok_sig);
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 11/12] More elegant AES key size manipulation
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (9 preceding siblings ...)
2006-06-20 21:24 ` [PATCH 10/12] Convert bits to bytes Mike Halcrow
@ 2006-06-20 21:24 ` Mike Halcrow
2006-06-20 21:24 ` [PATCH 12/12] More intelligent use of TFM objects Mike Halcrow
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:24 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
Move logic to deal with AES special cases into the function that
performs string to cipher code mapping.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 35 +++++++++++++++++++++++++++--------
fs/ecryptfs/ecryptfs_kernel.h | 2 +-
fs/ecryptfs/keystore.c | 21 +--------------------
3 files changed, 29 insertions(+), 29 deletions(-)
340ac69819b8ff314c0b2f7d3d648d3535fd8135
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index ab47899..5727753 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -1042,16 +1042,35 @@ ecryptfs_cipher_code_str_map[] = {
*
* Returns zero on no match, or the cipher code on match
*/
-u16 ecryptfs_code_for_cipher_string(char *str)
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
{
int i;
-
- for (i = 0; i < (sizeof(ecryptfs_cipher_code_str_map)
- / sizeof(struct ecryptfs_cipher_code_str_map_elem));
- i++)
- if (strcmp(str, ecryptfs_cipher_code_str_map[i].cipher_str)==0)
- return ecryptfs_cipher_code_str_map[i].cipher_code;
- return 0;
+ u16 code = 0;
+ struct ecryptfs_cipher_code_str_map_elem *map =
+ ecryptfs_cipher_code_str_map;
+
+ if (strcmp(crypt_stat->cipher, "aes") == 0)
+ switch (crypt_stat->key_size) {
+ case 16:
+ code = RFC2440_CIPHER_AES_128;
+ break;
+ case 24:
+ code = RFC2440_CIPHER_AES_192;
+ break;
+ case 32:
+ code = RFC2440_CIPHER_AES_256;
+ }
+ else
+ for (i = 0; i < (sizeof(ecryptfs_cipher_code_str_map)
+ / sizeof(struct
+ ecryptfs_cipher_code_str_map_elem));
+ i++)
+ if (strcmp(crypt_stat->cipher, map[i].cipher_str)
+ == 0) {
+ code = map[i].cipher_code;
+ break;
+ }
+ return code;
}
/**
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index cc88dc5..d0b9151 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -454,7 +454,7 @@ int ecryptfs_new_file_context(struct den
int contains_ecryptfs_marker(char *data);
int ecryptfs_read_header_region(char *data, struct dentry *dentry,
struct nameidata *nd);
-u16 ecryptfs_code_for_cipher_string(char *str);
+u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code);
void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat);
int ecryptfs_generate_key_packet_set(char *dest_base,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 37fa03b..09a56f3 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -923,32 +923,13 @@ encrypted_session_key_set:
}
(*packet_size) += packet_size_length;
dest[(*packet_size)++] = 0x04; /* version 4 */
- cipher_code = ecryptfs_code_for_cipher_string(crypt_stat->cipher);
+ cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);
if (cipher_code == 0) {
ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
"cipher [%s]\n", crypt_stat->cipher);
rc = -EINVAL;
goto out;
}
- /* If it is AES, we need to get more specific. */
- if (cipher_code == RFC2440_CIPHER_AES_128){
- switch (crypt_stat->key_size) {
- case 16:
- break;
- case 24:
- cipher_code = RFC2440_CIPHER_AES_192;
- break;
- case 32:
- cipher_code = RFC2440_CIPHER_AES_256;
- break;
- default:
- rc = -EINVAL;
- ecryptfs_printk(KERN_WARNING, "Unsupported AES key "
- "size: [%d]\n",
- crypt_stat->key_size);
- goto out;
- }
- }
dest[(*packet_size)++] = cipher_code;
dest[(*packet_size)++] = 0x03; /* S2K */
dest[(*packet_size)++] = 0x01; /* MD5 (TODO: parameterize) */
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread* [PATCH 12/12] More intelligent use of TFM objects
2006-06-20 21:21 [PATCH 0/12] eCryptfs minor fixes; support for cipher/key size selection Michael Halcrow
` (10 preceding siblings ...)
2006-06-20 21:24 ` [PATCH 11/12] More elegant AES key size manipulation Mike Halcrow
@ 2006-06-20 21:24 ` Mike Halcrow
11 siblings, 0 replies; 16+ messages in thread
From: Mike Halcrow @ 2006-06-20 21:24 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-kernel, linux-fsdevel, Mike Halcrow, Mike Halcrow
More intelligent use of crypto context (tfm) objects. Add locking for
tfm's belonging to inode's. Make the mount-wide crypt_stat referenced
by each inode crypt_stat. Add a cipher validity check on mount. Use
the mount's tfm for key encryption operations, since such operations
only occur on file open.
This patch finishes the set of patches that, among a few other things,
provides the ability for the user to specify his cipher and key size
at mount time.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
---
fs/ecryptfs/crypto.c | 129 ++++++++++++++++++++++++++++++++++++++---
fs/ecryptfs/ecryptfs_kernel.h | 10 +++
fs/ecryptfs/keystore.c | 45 +++++++++++---
fs/ecryptfs/main.c | 57 ++++++++++++------
fs/ecryptfs/super.c | 4 +
5 files changed, 208 insertions(+), 37 deletions(-)
fb18cbd2fde3da3c3a38f95ca2f33343669493cc
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 5727753..0ea3f5c 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -158,10 +158,13 @@ out:
*
* Initialize the crypt_stat structure.
*/
-void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
+void
+ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
{
memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
mutex_init(&crypt_stat->cs_mutex);
+ mutex_init(&crypt_stat->cs_tfm_mutex);
+ mutex_init(&crypt_stat->cs_md5_tfm_mutex);
ECRYPTFS_SET_FLAG(crypt_stat->flags, ECRYPTFS_STRUCT_INITIALIZED);
}
@@ -180,6 +183,17 @@ void ecryptfs_destruct_crypt_stat(struct
memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
}
+void ecryptfs_destruct_mount_crypt_stat(
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
+{
+ printk(KERN_INFO "%s\n", __FUNCTION__);
+ if (mount_crypt_stat->global_auth_tok_key)
+ key_put(mount_crypt_stat->global_auth_tok_key);
+ if (mount_crypt_stat->global_key_tfm)
+ crypto_free_tfm(mount_crypt_stat->global_key_tfm);
+ memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
+}
+
/**
* virt_to_scatterlist
* @addr: Virtual address
@@ -254,16 +268,19 @@ static int encrypt_scatterlist(struct ec
crypt_stat->key_size);
}
/* Consider doing this once, when the file is opened */
+ mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = -EINVAL;
goto out;
}
ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes.\n", size);
crypto_cipher_encrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size, iv);
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
out:
return rc;
}
@@ -645,17 +662,20 @@ static int decrypt_scatterlist(struct ec
int rc = 0;
/* Consider doing this once, when the file is opened */
+ mutex_lock(&crypt_stat->cs_tfm_mutex);
rc = crypto_cipher_setkey(crypt_stat->tfm, crypt_stat->key,
crypt_stat->key_size);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n",
rc);
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
rc = -EINVAL;
goto out;
}
ecryptfs_printk(KERN_DEBUG, "Decrypting [%d] bytes.\n", size);
rc = crypto_cipher_decrypt_iv(crypt_stat->tfm, dest_sg, src_sg, size,
iv);
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error decrypting; rc = [%d]\n",
rc);
@@ -725,7 +745,7 @@ int ecryptfs_init_crypt_ctx(struct ecryp
{
int rc = -EINVAL;
- if (crypt_stat->cipher == NULL) {
+ if (!crypt_stat->cipher) {
ecryptfs_printk(KERN_ERR, "No cipher specified\n");
goto out;
}
@@ -738,12 +758,14 @@ int ecryptfs_init_crypt_ctx(struct ecryp
rc = 0;
goto out;
}
+ mutex_lock(&crypt_stat->cs_tfm_mutex);
crypt_stat->tfm = crypto_alloc_tfm(crypt_stat->cipher,
ECRYPTFS_DEFAULT_CHAINING_MODE
| CRYPTO_TFM_REQ_WEAK_KEY);
- if (crypt_stat->tfm == NULL) {
- ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): Error "
- "initializing cipher [%s]\n",
+ mutex_unlock(&crypt_stat->cs_tfm_mutex);
+ if (!crypt_stat->tfm) {
+ ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
+ "Error initializing cipher [%s]\n",
crypt_stat->cipher);
goto out;
}
@@ -837,14 +859,16 @@ static void ecryptfs_generate_new_key(st
*
* Default values in the event that policy does not override them.
*/
-static void
-ecryptfs_set_default_crypt_stat_vals(struct ecryptfs_crypt_stat *crypt_stat)
+static void ecryptfs_set_default_crypt_stat_vals(
+ struct ecryptfs_crypt_stat *crypt_stat,
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
ecryptfs_set_default_sizes(crypt_stat);
strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER);
crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES;
ECRYPTFS_CLEAR_FLAG(crypt_stat->flags, ECRYPTFS_KEY_VALID);
crypt_stat->file_version = ECRYPTFS_FILE_VERSION;
+ crypt_stat->mount_crypt_stat = mount_crypt_stat;
}
/**
@@ -877,7 +901,7 @@ int ecryptfs_new_file_context(struct den
ecryptfs_dentry->d_sb)->mount_crypt_stat;
int cipher_name_len;
- ecryptfs_set_default_crypt_stat_vals(crypt_stat);
+ ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat);
/* See if there are mount crypt options */
if (mount_crypt_stat->global_auth_tok) {
ecryptfs_printk(KERN_DEBUG, "Initializing context for new "
@@ -1353,6 +1377,8 @@ int ecryptfs_read_headers_virt(char *pag
int bytes_read;
ecryptfs_set_default_sizes(crypt_stat);
+ crypt_stat->mount_crypt_stat = &ecryptfs_superblock_to_private(
+ ecryptfs_dentry->d_sb)->mount_crypt_stat;
offset = ECRYPTFS_FILE_SIZE_BYTES;
rc = contains_ecryptfs_marker(page_virt + offset);
if (rc == 0) {
@@ -1536,3 +1562,90 @@ ecryptfs_decode_filename(struct ecryptfs
out:
return error;
}
+
+/**
+ * ecryptfs_process_cipher - Perform cipher initialization.
+ * @tfm: Crypto context set by this function
+ * @key_tfm: Crypto context for key material, set by this function
+ * @cipher_name: Name of the cipher.
+ * @key_size: Size of the key in bytes.
+ *
+ * Returns zero on success. Any crypto_tfm structs allocated here
+ * should be released by other functions, such as on a superblock put
+ * event, regardless of whether this function succeeds for fails.
+ */
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+ char *cipher_name, unsigned int key_size)
+{
+ char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
+ int rc;
+
+ *tfm = *key_tfm = NULL;
+ if (key_size > ECRYPTFS_MAX_KEY_BYTES) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Requested key size is [%d] bytes; maximum "
+ "allowable is [%d]\n", key_size, ECRYPTFS_MAX_KEY_BYTES);
+ goto out;
+ }
+ *tfm = crypto_alloc_tfm(cipher_name, (ECRYPTFS_DEFAULT_CHAINING_MODE
+ | CRYPTO_TFM_REQ_WEAK_KEY));
+ if (!(*tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Unable to allocate crypto cipher with name "
+ "[%s]\n", cipher_name);
+ goto out;
+ }
+ *key_tfm = crypto_alloc_tfm(cipher_name, CRYPTO_TFM_REQ_WEAK_KEY);
+ if (!(*key_tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Unable to allocate crypto cipher with name "
+ "[%s]\n", cipher_name);
+ goto out;
+ }
+ if (key_size < crypto_tfm_alg_min_keysize(*tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Request key size is [%d]; minimum key size "
+ "supported by cipher [%s] is [%d]\n", key_size,
+ cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+ goto out;
+ }
+ if (key_size < crypto_tfm_alg_min_keysize(*key_tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Request key size is [%d]; minimum key size "
+ "supported by cipher [%s] is [%d]\n", key_size,
+ cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+ goto out;
+ }
+ if (key_size > crypto_tfm_alg_max_keysize(*tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Request key size is [%d]; maximum key size "
+ "supported by cipher [%s] is [%d]\n", key_size,
+ cipher_name, crypto_tfm_alg_min_keysize(*tfm));
+ goto out;
+ }
+ if (key_size > crypto_tfm_alg_max_keysize(*key_tfm)) {
+ rc = -EINVAL;
+ printk(KERN_ERR "Request key size is [%d]; maximum key size "
+ "supported by cipher [%s] is [%d]\n", key_size,
+ cipher_name, crypto_tfm_alg_min_keysize(*key_tfm));
+ goto out;
+ }
+ get_random_bytes(dummy_key, key_size);
+ rc = crypto_cipher_setkey(*tfm, dummy_key, key_size);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to set key of size [%d] for "
+ "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = crypto_cipher_setkey(*key_tfm, dummy_key, key_size);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to set key of size [%d] for "
+ "cipher [%s]; rc = [%d]\n", key_size, cipher_name, rc);
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index d0b9151..c37a452 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -196,6 +196,7 @@ #define ECRYPTFS_KEY_VALID 0x00
unsigned int key_size;
unsigned int extent_shift;
unsigned int extent_mask;
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
struct crypto_tfm *tfm;
struct crypto_tfm *md5_tfm; /* Crypto context for generating
* the initialization vectors */
@@ -203,6 +204,8 @@ #define ECRYPTFS_KEY_VALID 0x00
unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX];
+ struct mutex cs_tfm_mutex;
+ struct mutex cs_md5_tfm_mutex;
struct mutex cs_mutex;
};
@@ -230,6 +233,8 @@ struct ecryptfs_mount_crypt_stat {
struct ecryptfs_auth_tok *global_auth_tok;
struct key *global_auth_tok_key;
unsigned int global_default_cipher_key_size;
+ struct crypto_tfm *global_key_tfm;
+ struct mutex global_key_tfm_mutex;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
+ 1];
unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
@@ -408,6 +413,8 @@ int ecryptfs_compute_root_iv(struct ecry
void ecryptfs_rotate_iv(unsigned char *iv);
void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_destruct_mount_crypt_stat(
+ struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
int ecryptfs_write_inode_size_to_header(struct file *lower_file,
struct inode *lower_inode,
@@ -465,5 +472,8 @@ int
ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
unsigned char *src, struct dentry *ecryptfs_dentry);
int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
+int
+ecryptfs_process_cipher(struct crypto_tfm **tfm, struct crypto_tfm **key_tfm,
+ char *cipher_name, unsigned int key_size);
#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 09a56f3..e80d7a6 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -460,6 +460,7 @@ static int decrypt_session_key(struct ec
struct ecryptfs_password *password_s_ptr;
struct crypto_tfm *tfm = NULL;
struct scatterlist src_sg[2], dst_sg[2];
+ struct mutex *tfm_mutex = NULL;
/* TODO: Use virt_to_scatterlist for these */
char *encrypted_session_key;
char *session_key;
@@ -476,12 +477,19 @@ static int decrypt_session_key(struct ec
ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key,
password_s_ptr->
session_key_encryption_key_bytes);
- tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
- if (!tfm) {
- ecryptfs_printk(KERN_ERR, "Error allocating crypto "
- "context\n");
- rc = -ENOMEM;
- goto out;
+ if (!strcmp(crypt_stat->cipher,
+ crypt_stat->mount_crypt_stat->global_default_cipher_name)
+ && crypt_stat->mount_crypt_stat->global_key_tfm) {
+ tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+ tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+ } else {
+ tfm = crypto_alloc_tfm(crypt_stat->cipher,
+ CRYPTO_TFM_REQ_WEAK_KEY);
+ if (!tfm) {
+ printk(KERN_ERR "Error allocating crypto context\n");
+ rc = -ENOMEM;
+ goto out;
+ }
}
if (password_s_ptr->session_key_encryption_key_bytes
< crypto_tfm_alg_min_keysize(tfm)) {
@@ -492,6 +500,8 @@ static int decrypt_session_key(struct ec
rc = -EINVAL;
goto out;
}
+ if (tfm_mutex)
+ mutex_lock(tfm_mutex);
crypto_cipher_setkey(tfm, password_s_ptr->session_key_encryption_key,
crypt_stat->key_size);
/* TODO: virt_to_scatterlist */
@@ -539,7 +549,10 @@ static int decrypt_session_key(struct ec
memset(session_key, 0, PAGE_CACHE_SIZE);
free_page((unsigned long)session_key);
out_free_tfm:
- crypto_free_tfm(tfm);
+ if (tfm_mutex)
+ mutex_unlock(tfm_mutex);
+ else
+ crypto_free_tfm(tfm);
out:
return rc;
}
@@ -796,6 +809,7 @@ write_tag_3_packet(char *dest, int max,
struct scatterlist dest_sg[2];
struct scatterlist src_sg[2];
struct crypto_tfm *tfm = NULL;
+ struct mutex *tfm_mutex = NULL;
int key_rec_size;
int packet_size_length;
int cipher_code;
@@ -862,16 +876,27 @@ write_tag_3_packet(char *dest, int max,
rc = -ENOMEM;
goto out;
}
- if ((tfm = crypto_alloc_tfm(crypt_stat->cipher, 0)) == NULL) {
+ if (!strcmp(crypt_stat->cipher,
+ crypt_stat->mount_crypt_stat->global_default_cipher_name)
+ && crypt_stat->mount_crypt_stat->global_key_tfm) {
+ tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
+ tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
+ } else
+ tfm = crypto_alloc_tfm(crypt_stat->cipher, 0);
+ if (!tfm) {
ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
"context for cipher [%s]\n",
crypt_stat->cipher);
rc = -EINVAL;
goto out;
}
+ if (tfm_mutex)
+ mutex_lock(tfm_mutex);
rc = crypto_cipher_setkey(tfm, session_key_encryption_key,
crypt_stat->key_size);
if (rc < 0) {
+ if (tfm_mutex)
+ mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
"context\n");
goto out;
@@ -881,6 +906,8 @@ write_tag_3_packet(char *dest, int max,
crypt_stat->key_size);
crypto_cipher_encrypt(tfm, dest_sg, src_sg,
(*key_rec).enc_key_size);
+ if (tfm_mutex)
+ mutex_unlock(tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
if (ecryptfs_verbosity > 0)
ecryptfs_dump_hex((*key_rec).enc_key,
@@ -941,7 +968,7 @@ encrypted_session_key_set:
(*key_rec).enc_key_size);
(*packet_size) += (*key_rec).enc_key_size;
out:
- if (tfm)
+ if (tfm && !tfm_mutex)
crypto_free_tfm(tfm);
if (rc)
(*packet_size) = 0;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 3a19e00..7598ba0 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -28,6 +28,7 @@ #include <linux/file.h>
#include <linux/module.h>
#include <linux/namei.h>
#include <linux/skbuff.h>
+#include <linux/crypto.h>
#include <linux/netlink.h>
#include <linux/mount.h>
#include <linux/dcache.h>
@@ -212,6 +213,7 @@ static int ecryptfs_parse_options(struct
char *cipher_name_dst;
char *cipher_name_src;
char *cipher_key_bytes_src;
+ struct crypto_tfm *tmp_tfm;
int cipher_name_len;
if (!options) {
@@ -311,6 +313,22 @@ static int ecryptfs_parse_options(struct
mount_crypt_stat->
global_default_cipher_key_size);
}
+ rc = ecryptfs_process_cipher(
+ &tmp_tfm,
+ &mount_crypt_stat->global_key_tfm,
+ mount_crypt_stat->global_default_cipher_name,
+ mount_crypt_stat->global_default_cipher_key_size);
+ if (tmp_tfm)
+ crypto_free_tfm(tmp_tfm);
+ if (rc) {
+ printk(KERN_ERR "Error attempting to initialize cipher [%s] "
+ "with key size [%d] bytes; rc = [%d]\n",
+ mount_crypt_stat->global_default_cipher_name,
+ mount_crypt_stat->global_default_cipher_key_size, rc);
+ rc = -EINVAL;
+ goto out;
+ }
+ mutex_init(&mount_crypt_stat->global_key_tfm_mutex);
ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: "
"[%s]\n", mount_crypt_stat->global_auth_tok_sig);
/* The reference to this key is held until umount is done The
@@ -494,11 +512,13 @@ static struct super_block *ecryptfs_get_
}
rc = ecryptfs_parse_options(sb, raw_data);
if (rc) {
+ deactivate_super(sb);
sb = ERR_PTR(rc);
goto out;
}
rc = ecryptfs_read_super(sb, dev_name);
if (rc) {
+ deactivate_super(sb);
sb = ERR_PTR(rc);
ecryptfs_printk(KERN_ERR, "Reading sb failed. "
"sb = [%p]\n", sb);
@@ -516,10 +536,9 @@ out:
*/
static void ecryptfs_kill_block_super(struct super_block *sb)
{
- struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
- &(ecryptfs_superblock_to_private(sb)->mount_crypt_stat);
-
- memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
+ printk(KERN_INFO "%s\n", __FUNCTION__);
+/* ecryptfs_destruct_mount_crypt_stat(
+ &(ecryptfs_superblock_to_private(sb)->mount_crypt_stat)); */
generic_shutdown_super(sb);
}
@@ -549,19 +568,19 @@ inode_info_init_once(void *vptr, struct
/* This provides a means of backing out cache creations out of the kernel
* so that we can elegantly fail should we run out of memory.
*/
-#define ECRYPTFS_AUTH_TOK_LIST_ITEM_CACHE 0x0001
-#define ECRYPTFS_AUTH_TOK_PKT_SET_CACHE 0x0002
-#define ECRYPTFS_AUTH_TOK_REQUEST_CACHE 0x0004
-#define ECRYPTFS_AUTH_TOK_REQUEST_BLOB_CACHE 0x0008
-#define ECRYPTFS_FILE_INFO_CACHE 0x0010
-#define ECRYPTFS_DENTRY_INFO_CACHE 0x0020
-#define ECRYPTFS_INODE_INFO_CACHE 0x0040
-#define ECRYPTFS_SB_INFO_CACHE 0x0080
-#define ECRYPTFS_HEADER_CACHE_0 0x0100
-#define ECRYPTFS_HEADER_CACHE_1 0x0200
-#define ECRYPTFS_HEADER_CACHE_2 0x0400
-#define ECRYPTFS_LOWER_PAGE_CACHE 0x0800
-#define ECRYPTFS_CACHE_CREATION_SUCCESS 0x0FF1
+#define ECRYPTFS_AUTH_TOK_LIST_ITEM_CACHE 0x0001
+#define ECRYPTFS_AUTH_TOK_PKT_SET_CACHE 0x0002
+#define ECRYPTFS_AUTH_TOK_REQUEST_CACHE 0x0004
+#define ECRYPTFS_AUTH_TOK_REQUEST_BLOB_CACHE 0x0008
+#define ECRYPTFS_FILE_INFO_CACHE 0x0010
+#define ECRYPTFS_DENTRY_INFO_CACHE 0x0020
+#define ECRYPTFS_INODE_INFO_CACHE 0x0040
+#define ECRYPTFS_SB_INFO_CACHE 0x0080
+#define ECRYPTFS_HEADER_CACHE_0 0x0100
+#define ECRYPTFS_HEADER_CACHE_1 0x0200
+#define ECRYPTFS_HEADER_CACHE_2 0x0400
+#define ECRYPTFS_LOWER_PAGE_CACHE 0x0800
+#define ECRYPTFS_CACHE_CREATION_SUCCESS 0x0FF1
static short ecryptfs_allocated_caches;
@@ -599,13 +618,13 @@ static int ecryptfs_init_kmem_caches(voi
"kmem_cache_create failed\n");
ecryptfs_dentry_info_cache =
- kmem_cache_create("ecryptfs_dentry_cache",
+ kmem_cache_create("ecryptfs_dentry_info_cache",
sizeof(struct ecryptfs_dentry_info),
0, SLAB_HWCACHE_ALIGN, NULL, NULL);
if (ecryptfs_dentry_info_cache)
rc |= ECRYPTFS_DENTRY_INFO_CACHE;
else
- ecryptfs_printk(KERN_WARNING, "ecryptfs_dentry_cache "
+ ecryptfs_printk(KERN_WARNING, "ecryptfs_dentry_info_cache "
"kmem_cache_create failed\n");
ecryptfs_inode_info_cache =
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 94c50f1..b60bf07 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -27,6 +27,7 @@ #include <linux/fs.h>
#include <linux/mount.h>
#include <linux/key.h>
#include <linux/seq_file.h>
+#include <linux/crypto.h>
#include "ecryptfs_kernel.h"
struct kmem_cache *ecryptfs_inode_info_cache;
@@ -107,8 +108,9 @@ static void ecryptfs_put_super(struct su
{
struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
+ printk(KERN_INFO "%s\n", __FUNCTION__);
mntput(sb_info->lower_mnt);
- key_put(sb_info->mount_crypt_stat.global_auth_tok_key);
+ ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
ecryptfs_set_superblock_private(sb, NULL);
}
--
1.3.3
^ permalink raw reply related [flat|nested] 16+ messages in thread