aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/crypto.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2009-01-06 17:41:57 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:21 -0500
commit9c79f34f7ee71cd28272332b424ca64b2be006ab (patch)
tree1a818b78d8f0497c4b97a77a6464718dfaaf12c1 /fs/ecryptfs/crypto.c
parent14bca6c39d8245a0313f55309bfeb6bf60cc17c8 (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.c11
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 */
1156u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) 1157u8 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 }