diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2009-01-06 17:41:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 18:59:21 -0500 |
commit | 9c79f34f7ee71cd28272332b424ca64b2be006ab (patch) | |
tree | 1a818b78d8f0497c4b97a77a6464718dfaaf12c1 /fs/ecryptfs/crypto.c | |
parent | 14bca6c39d8245a0313f55309bfeb6bf60cc17c8 (diff) |
eCryptfs: Filename Encryption: Tag 70 packets
This patchset implements filename encryption via a passphrase-derived
mount-wide Filename Encryption Key (FNEK) specified as a mount parameter.
Each encrypted filename has a fixed prefix indicating that eCryptfs should
try to decrypt the filename. When eCryptfs encounters this prefix, it
decodes the filename into a tag 70 packet and then decrypts the packet
contents using the FNEK, setting the filename to the decrypted filename.
Both unencrypted and encrypted filenames can reside in the same lower
filesystem.
Because filename encryption expands the length of the filename during the
encoding stage, eCryptfs will not properly handle filenames that are
already near the maximum filename length.
In the present implementation, eCryptfs must be able to produce a match
against the lower encrypted and encoded filename representation when given
a plaintext filename. Therefore, two files having the same plaintext name
will encrypt and encode into the same lower filename if they are both
encrypted using the same FNEK. This can be changed by finding a way to
replace the prepended bytes in the blocked-aligned filename with random
characters; they are hashes of the FNEK right now, so that it is possible
to deterministically map from a plaintext filename to an encrypted and
encoded filename in the lower filesystem. An implementation using random
characters will have to decode and decrypt every single directory entry in
any given directory any time an event occurs wherein the VFS needs to
determine whether a particular file exists in the lower directory and the
decrypted and decoded filenames have not yet been extracted for that
directory.
Thanks to Tyler Hicks and David Kleikamp for assistance in the development
of this patchset.
This patch:
A tag 70 packet contains a filename encrypted with a Filename Encryption
Key (FNEK). This patch implements functions for writing and parsing tag
70 packets. This patch also adds definitions and extends structures to
support filename encryption.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Cc: Dustin Kirkland <dustin.kirkland@gmail.com>
Cc: Eric Sandeen <sandeen@redhat.com>
Cc: Tyler Hicks <tchicks@us.ibm.com>
Cc: David Kleikamp <shaggy@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/crypto.c')
-rw-r--r-- | fs/ecryptfs/crypto.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 6046239465a1..485732751f09 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -1149,19 +1149,20 @@ ecryptfs_cipher_code_str_map[] = { | |||
1149 | 1149 | ||
1150 | /** | 1150 | /** |
1151 | * ecryptfs_code_for_cipher_string | 1151 | * ecryptfs_code_for_cipher_string |
1152 | * @crypt_stat: The cryptographic context | 1152 | * @cipher_name: The string alias for the cipher |
1153 | * @key_bytes: Length of key in bytes; used for AES code selection | ||
1153 | * | 1154 | * |
1154 | * Returns zero on no match, or the cipher code on match | 1155 | * Returns zero on no match, or the cipher code on match |
1155 | */ | 1156 | */ |
1156 | u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | 1157 | u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes) |
1157 | { | 1158 | { |
1158 | int i; | 1159 | int i; |
1159 | u8 code = 0; | 1160 | u8 code = 0; |
1160 | struct ecryptfs_cipher_code_str_map_elem *map = | 1161 | struct ecryptfs_cipher_code_str_map_elem *map = |
1161 | ecryptfs_cipher_code_str_map; | 1162 | ecryptfs_cipher_code_str_map; |
1162 | 1163 | ||
1163 | if (strcmp(crypt_stat->cipher, "aes") == 0) { | 1164 | if (strcmp(cipher_name, "aes") == 0) { |
1164 | switch (crypt_stat->key_size) { | 1165 | switch (key_bytes) { |
1165 | case 16: | 1166 | case 16: |
1166 | code = RFC2440_CIPHER_AES_128; | 1167 | code = RFC2440_CIPHER_AES_128; |
1167 | break; | 1168 | break; |
@@ -1173,7 +1174,7 @@ u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | |||
1173 | } | 1174 | } |
1174 | } else { | 1175 | } else { |
1175 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) | 1176 | for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) |
1176 | if (strcmp(crypt_stat->cipher, map[i].cipher_str) == 0){ | 1177 | if (strcmp(cipher_name, map[i].cipher_str) == 0) { |
1177 | code = map[i].cipher_code; | 1178 | code = map[i].cipher_code; |
1178 | break; | 1179 | break; |
1179 | } | 1180 | } |