diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-10-16 04:27:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-16 12:43:10 -0400 |
commit | f4aad16adfb8f0a2d666fdf8af4bd0dff2ce75e4 (patch) | |
tree | 42e7f191d1a3a1e1375af24acc5c336b30c5c4d1 /fs/ecryptfs | |
parent | cce76f9b9696a59974be9ed43478c000c57e597a (diff) |
eCryptfs: add key list structure; search keyring
Add support structures for handling multiple keys. The list in crypt_stat
contains the key identifiers for all of the keys that should be used for
encrypting each file's File Encryption Key (FEK). For now, each inode
inherits this list from the mount-wide crypt_stat struct, via the
ecryptfs_copy_mount_wide_sigs_to_inode_sigs() function.
This patch also removes the global key tfm from the mount-wide crypt_stat
struct, instead keeping a list of tfm's meant for dealing with the various
inode FEK's. eCryptfs will now search the user's keyring for FEK's parsed
from the existing file metadata, so the user can make keys available at any
time before or after mounting.
Now that multiple FEK packets can be written to the file metadata, we need to
be more meticulous about size limits. The updates to the code for writing out
packets to the file metadata makes sizes and limits more explicit, uniformly
expressed, and (hopefully) easier to follow.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Cc: "Serge E. Hallyn" <serge@hallyn.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs')
-rw-r--r-- | fs/ecryptfs/crypto.c | 208 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 71 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 743 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 121 |
4 files changed, 742 insertions, 401 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 6ac630625b70..4f7d89591970 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -204,6 +204,8 @@ void | |||
204 | ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | 204 | ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) |
205 | { | 205 | { |
206 | memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | 206 | memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); |
207 | INIT_LIST_HEAD(&crypt_stat->keysig_list); | ||
208 | mutex_init(&crypt_stat->keysig_list_mutex); | ||
207 | mutex_init(&crypt_stat->cs_mutex); | 209 | mutex_init(&crypt_stat->cs_mutex); |
208 | mutex_init(&crypt_stat->cs_tfm_mutex); | 210 | mutex_init(&crypt_stat->cs_tfm_mutex); |
209 | mutex_init(&crypt_stat->cs_hash_tfm_mutex); | 211 | mutex_init(&crypt_stat->cs_hash_tfm_mutex); |
@@ -218,20 +220,41 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | |||
218 | */ | 220 | */ |
219 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) | 221 | void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) |
220 | { | 222 | { |
223 | struct ecryptfs_key_sig *key_sig, *key_sig_tmp; | ||
224 | |||
221 | if (crypt_stat->tfm) | 225 | if (crypt_stat->tfm) |
222 | crypto_free_blkcipher(crypt_stat->tfm); | 226 | crypto_free_blkcipher(crypt_stat->tfm); |
223 | if (crypt_stat->hash_tfm) | 227 | if (crypt_stat->hash_tfm) |
224 | crypto_free_hash(crypt_stat->hash_tfm); | 228 | crypto_free_hash(crypt_stat->hash_tfm); |
229 | mutex_lock(&crypt_stat->keysig_list_mutex); | ||
230 | list_for_each_entry_safe(key_sig, key_sig_tmp, | ||
231 | &crypt_stat->keysig_list, crypt_stat_list) { | ||
232 | list_del(&key_sig->crypt_stat_list); | ||
233 | kmem_cache_free(ecryptfs_key_sig_cache, key_sig); | ||
234 | } | ||
235 | mutex_unlock(&crypt_stat->keysig_list_mutex); | ||
225 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); | 236 | memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); |
226 | } | 237 | } |
227 | 238 | ||
228 | void ecryptfs_destruct_mount_crypt_stat( | 239 | void ecryptfs_destruct_mount_crypt_stat( |
229 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | 240 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
230 | { | 241 | { |
231 | if (mount_crypt_stat->global_auth_tok_key) | 242 | struct ecryptfs_global_auth_tok *auth_tok, *auth_tok_tmp; |
232 | key_put(mount_crypt_stat->global_auth_tok_key); | 243 | |
233 | if (mount_crypt_stat->global_key_tfm) | 244 | if (!(mount_crypt_stat->flags & ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED)) |
234 | crypto_free_blkcipher(mount_crypt_stat->global_key_tfm); | 245 | return; |
246 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
247 | list_for_each_entry_safe(auth_tok, auth_tok_tmp, | ||
248 | &mount_crypt_stat->global_auth_tok_list, | ||
249 | mount_crypt_stat_list) { | ||
250 | list_del(&auth_tok->mount_crypt_stat_list); | ||
251 | mount_crypt_stat->num_global_auth_toks--; | ||
252 | if (auth_tok->global_auth_tok_key | ||
253 | && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID)) | ||
254 | key_put(auth_tok->global_auth_tok_key); | ||
255 | kmem_cache_free(ecryptfs_global_auth_tok_cache, auth_tok); | ||
256 | } | ||
257 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
235 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); | 258 | memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); |
236 | } | 259 | } |
237 | 260 | ||
@@ -931,6 +954,30 @@ static void ecryptfs_copy_mount_wide_flags_to_inode_flags( | |||
931 | crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; | 954 | crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; |
932 | } | 955 | } |
933 | 956 | ||
957 | static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs( | ||
958 | struct ecryptfs_crypt_stat *crypt_stat, | ||
959 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
960 | { | ||
961 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
962 | int rc = 0; | ||
963 | |||
964 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
965 | list_for_each_entry(global_auth_tok, | ||
966 | &mount_crypt_stat->global_auth_tok_list, | ||
967 | mount_crypt_stat_list) { | ||
968 | rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig); | ||
969 | if (rc) { | ||
970 | printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc); | ||
971 | mutex_unlock( | ||
972 | &mount_crypt_stat->global_auth_tok_list_mutex); | ||
973 | goto out; | ||
974 | } | ||
975 | } | ||
976 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
977 | out: | ||
978 | return rc; | ||
979 | } | ||
980 | |||
934 | /** | 981 | /** |
935 | * ecryptfs_set_default_crypt_stat_vals | 982 | * ecryptfs_set_default_crypt_stat_vals |
936 | * @crypt_stat | 983 | * @crypt_stat |
@@ -973,46 +1020,44 @@ static void ecryptfs_set_default_crypt_stat_vals( | |||
973 | /* Associate an authentication token(s) with the file */ | 1020 | /* Associate an authentication token(s) with the file */ |
974 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) | 1021 | int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) |
975 | { | 1022 | { |
976 | int rc = 0; | ||
977 | struct ecryptfs_crypt_stat *crypt_stat = | 1023 | struct ecryptfs_crypt_stat *crypt_stat = |
978 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1024 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
979 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1025 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
980 | &ecryptfs_superblock_to_private( | 1026 | &ecryptfs_superblock_to_private( |
981 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1027 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
982 | int cipher_name_len; | 1028 | int cipher_name_len; |
1029 | int rc = 0; | ||
983 | 1030 | ||
984 | ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat); | 1031 | ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat); |
985 | /* See if there are mount crypt options */ | 1032 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
986 | if (mount_crypt_stat->global_auth_tok) { | 1033 | BUG_ON(mount_crypt_stat->num_global_auth_toks == 0); |
987 | ecryptfs_printk(KERN_DEBUG, "Initializing context for new " | 1034 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
988 | "file using mount_crypt_stat\n"); | 1035 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; |
989 | crypt_stat->flags |= ECRYPTFS_ENCRYPTED; | 1036 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
990 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | 1037 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, |
991 | ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, | 1038 | mount_crypt_stat); |
992 | mount_crypt_stat); | 1039 | rc = ecryptfs_copy_mount_wide_sigs_to_inode_sigs(crypt_stat, |
993 | memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], | 1040 | mount_crypt_stat); |
994 | mount_crypt_stat->global_auth_tok_sig, | 1041 | if (rc) { |
995 | ECRYPTFS_SIG_SIZE_HEX); | 1042 | printk(KERN_ERR "Error attempting to copy mount-wide key sigs " |
996 | cipher_name_len = | 1043 | "to the inode key sigs; rc = [%d]\n", rc); |
997 | strlen(mount_crypt_stat->global_default_cipher_name); | 1044 | goto out; |
998 | memcpy(crypt_stat->cipher, | 1045 | } |
999 | mount_crypt_stat->global_default_cipher_name, | 1046 | cipher_name_len = |
1000 | cipher_name_len); | 1047 | strlen(mount_crypt_stat->global_default_cipher_name); |
1001 | crypt_stat->cipher[cipher_name_len] = '\0'; | 1048 | memcpy(crypt_stat->cipher, |
1002 | crypt_stat->key_size = | 1049 | mount_crypt_stat->global_default_cipher_name, |
1003 | mount_crypt_stat->global_default_cipher_key_size; | 1050 | cipher_name_len); |
1004 | ecryptfs_generate_new_key(crypt_stat); | 1051 | crypt_stat->cipher[cipher_name_len] = '\0'; |
1005 | } else | 1052 | crypt_stat->key_size = |
1006 | /* We should not encounter this scenario since we | 1053 | mount_crypt_stat->global_default_cipher_key_size; |
1007 | * should detect lack of global_auth_tok at mount time | 1054 | ecryptfs_generate_new_key(crypt_stat); |
1008 | * TODO: Applies to 0.1 release only; remove in future | ||
1009 | * release */ | ||
1010 | BUG(); | ||
1011 | rc = ecryptfs_init_crypt_ctx(crypt_stat); | 1055 | rc = ecryptfs_init_crypt_ctx(crypt_stat); |
1012 | if (rc) | 1056 | if (rc) |
1013 | ecryptfs_printk(KERN_ERR, "Error initializing cryptographic " | 1057 | ecryptfs_printk(KERN_ERR, "Error initializing cryptographic " |
1014 | "context for cipher [%s]: rc = [%d]\n", | 1058 | "context for cipher [%s]: rc = [%d]\n", |
1015 | crypt_stat->cipher, rc); | 1059 | crypt_stat->cipher, rc); |
1060 | out: | ||
1016 | return rc; | 1061 | return rc; |
1017 | } | 1062 | } |
1018 | 1063 | ||
@@ -1776,7 +1821,7 @@ out: | |||
1776 | } | 1821 | } |
1777 | 1822 | ||
1778 | /** | 1823 | /** |
1779 | * ecryptfs_process_cipher - Perform cipher initialization. | 1824 | * ecryptfs_process_key_cipher - Perform key cipher initialization. |
1780 | * @key_tfm: Crypto context for key material, set by this function | 1825 | * @key_tfm: Crypto context for key material, set by this function |
1781 | * @cipher_name: Name of the cipher | 1826 | * @cipher_name: Name of the cipher |
1782 | * @key_size: Size of the key in bytes | 1827 | * @key_size: Size of the key in bytes |
@@ -1786,8 +1831,8 @@ out: | |||
1786 | * event, regardless of whether this function succeeds for fails. | 1831 | * event, regardless of whether this function succeeds for fails. |
1787 | */ | 1832 | */ |
1788 | int | 1833 | int |
1789 | ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, | 1834 | ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, |
1790 | size_t *key_size) | 1835 | char *cipher_name, size_t *key_size) |
1791 | { | 1836 | { |
1792 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; | 1837 | char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; |
1793 | char *full_alg_name; | 1838 | char *full_alg_name; |
@@ -1829,3 +1874,98 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, | |||
1829 | out: | 1874 | out: |
1830 | return rc; | 1875 | return rc; |
1831 | } | 1876 | } |
1877 | |||
1878 | struct kmem_cache *ecryptfs_key_tfm_cache; | ||
1879 | struct list_head key_tfm_list; | ||
1880 | struct mutex key_tfm_list_mutex; | ||
1881 | |||
1882 | int ecryptfs_init_crypto(void) | ||
1883 | { | ||
1884 | mutex_init(&key_tfm_list_mutex); | ||
1885 | INIT_LIST_HEAD(&key_tfm_list); | ||
1886 | return 0; | ||
1887 | } | ||
1888 | |||
1889 | int ecryptfs_destruct_crypto(void) | ||
1890 | { | ||
1891 | struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp; | ||
1892 | |||
1893 | mutex_lock(&key_tfm_list_mutex); | ||
1894 | list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list, | ||
1895 | key_tfm_list) { | ||
1896 | list_del(&key_tfm->key_tfm_list); | ||
1897 | if (key_tfm->key_tfm) | ||
1898 | crypto_free_blkcipher(key_tfm->key_tfm); | ||
1899 | kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm); | ||
1900 | } | ||
1901 | mutex_unlock(&key_tfm_list_mutex); | ||
1902 | return 0; | ||
1903 | } | ||
1904 | |||
1905 | int | ||
1906 | ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, | ||
1907 | size_t key_size) | ||
1908 | { | ||
1909 | struct ecryptfs_key_tfm *tmp_tfm; | ||
1910 | int rc = 0; | ||
1911 | |||
1912 | tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL); | ||
1913 | if (key_tfm != NULL) | ||
1914 | (*key_tfm) = tmp_tfm; | ||
1915 | if (!tmp_tfm) { | ||
1916 | rc = -ENOMEM; | ||
1917 | printk(KERN_ERR "Error attempting to allocate from " | ||
1918 | "ecryptfs_key_tfm_cache\n"); | ||
1919 | goto out; | ||
1920 | } | ||
1921 | mutex_init(&tmp_tfm->key_tfm_mutex); | ||
1922 | strncpy(tmp_tfm->cipher_name, cipher_name, | ||
1923 | ECRYPTFS_MAX_CIPHER_NAME_SIZE); | ||
1924 | tmp_tfm->key_size = key_size; | ||
1925 | if ((rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm, | ||
1926 | tmp_tfm->cipher_name, | ||
1927 | &tmp_tfm->key_size))) { | ||
1928 | printk(KERN_ERR "Error attempting to initialize key TFM " | ||
1929 | "cipher with name = [%s]; rc = [%d]\n", | ||
1930 | tmp_tfm->cipher_name, rc); | ||
1931 | kmem_cache_free(ecryptfs_key_tfm_cache, tmp_tfm); | ||
1932 | if (key_tfm != NULL) | ||
1933 | (*key_tfm) = NULL; | ||
1934 | goto out; | ||
1935 | } | ||
1936 | mutex_lock(&key_tfm_list_mutex); | ||
1937 | list_add(&tmp_tfm->key_tfm_list, &key_tfm_list); | ||
1938 | mutex_unlock(&key_tfm_list_mutex); | ||
1939 | out: | ||
1940 | return rc; | ||
1941 | } | ||
1942 | |||
1943 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | ||
1944 | struct mutex **tfm_mutex, | ||
1945 | char *cipher_name) | ||
1946 | { | ||
1947 | struct ecryptfs_key_tfm *key_tfm; | ||
1948 | int rc = 0; | ||
1949 | |||
1950 | (*tfm) = NULL; | ||
1951 | (*tfm_mutex) = NULL; | ||
1952 | mutex_lock(&key_tfm_list_mutex); | ||
1953 | list_for_each_entry(key_tfm, &key_tfm_list, key_tfm_list) { | ||
1954 | if (strcmp(key_tfm->cipher_name, cipher_name) == 0) { | ||
1955 | (*tfm) = key_tfm->key_tfm; | ||
1956 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; | ||
1957 | mutex_unlock(&key_tfm_list_mutex); | ||
1958 | goto out; | ||
1959 | } | ||
1960 | } | ||
1961 | mutex_unlock(&key_tfm_list_mutex); | ||
1962 | if ((rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0))) { | ||
1963 | printk(KERN_ERR "Error adding new key_tfm to list; rc = [%d]\n", | ||
1964 | rc); | ||
1965 | goto out; | ||
1966 | } | ||
1967 | (*tfm) = key_tfm->key_tfm; | ||
1968 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; | ||
1969 | out: | ||
1970 | return rc; | ||
1971 | } | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 1b9dd9a96f19..6ddab6c856ac 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -48,10 +48,12 @@ | |||
48 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 | 48 | #define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 |
49 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 | 49 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 |
50 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 | 50 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 |
51 | #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 | ||
51 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | 52 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ |
52 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ | 53 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ |
53 | | ECRYPTFS_VERSIONING_PUBKEY \ | 54 | | ECRYPTFS_VERSIONING_PUBKEY \ |
54 | | ECRYPTFS_VERSIONING_XATTR) | 55 | | ECRYPTFS_VERSIONING_XATTR \ |
56 | | ECRYPTFS_VERSIONING_MULTKEY) | ||
55 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | 57 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 |
56 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | 58 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH |
57 | #define ECRYPTFS_SALT_SIZE 8 | 59 | #define ECRYPTFS_SALT_SIZE 8 |
@@ -144,6 +146,7 @@ struct ecryptfs_private_key { | |||
144 | struct ecryptfs_auth_tok { | 146 | struct ecryptfs_auth_tok { |
145 | u16 version; /* 8-bit major and 8-bit minor */ | 147 | u16 version; /* 8-bit major and 8-bit minor */ |
146 | u16 token_type; | 148 | u16 token_type; |
149 | #define ECRYPTFS_ENCRYPT_ONLY 0x00000001 | ||
147 | u32 flags; | 150 | u32 flags; |
148 | struct ecryptfs_session_key session_key; | 151 | struct ecryptfs_session_key session_key; |
149 | u8 reserved[32]; | 152 | u8 reserved[32]; |
@@ -153,6 +156,7 @@ struct ecryptfs_auth_tok { | |||
153 | } token; | 156 | } token; |
154 | } __attribute__ ((packed)); | 157 | } __attribute__ ((packed)); |
155 | 158 | ||
159 | int ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok); | ||
156 | void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok); | 160 | void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok); |
157 | extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size); | 161 | extern void ecryptfs_to_hex(char *dst, char *src, size_t src_size); |
158 | extern void ecryptfs_from_hex(char *dst, char *src, int dst_size); | 162 | extern void ecryptfs_from_hex(char *dst, char *src, int dst_size); |
@@ -194,7 +198,6 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
194 | #define ECRYPTFS_MAX_KEYSET_SIZE 1024 | 198 | #define ECRYPTFS_MAX_KEYSET_SIZE 1024 |
195 | #define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 | 199 | #define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 |
196 | #define ECRYPTFS_MAX_NUM_ENC_KEYS 64 | 200 | #define ECRYPTFS_MAX_NUM_ENC_KEYS 64 |
197 | #define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */ | ||
198 | #define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ | 201 | #define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ |
199 | #define ECRYPTFS_SALT_BYTES 2 | 202 | #define ECRYPTFS_SALT_BYTES 2 |
200 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 | 203 | #define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 |
@@ -212,6 +215,11 @@ ecryptfs_get_key_payload_data(struct key *key) | |||
212 | #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 | 215 | #define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 |
213 | #define MD5_DIGEST_SIZE 16 | 216 | #define MD5_DIGEST_SIZE 16 |
214 | 217 | ||
218 | struct ecryptfs_key_sig { | ||
219 | struct list_head crypt_stat_list; | ||
220 | char keysig[ECRYPTFS_SIG_SIZE_HEX]; | ||
221 | }; | ||
222 | |||
215 | /** | 223 | /** |
216 | * This is the primary struct associated with each encrypted file. | 224 | * This is the primary struct associated with each encrypted file. |
217 | * | 225 | * |
@@ -231,7 +239,6 @@ struct ecryptfs_crypt_stat { | |||
231 | u32 flags; | 239 | u32 flags; |
232 | unsigned int file_version; | 240 | unsigned int file_version; |
233 | size_t iv_bytes; | 241 | size_t iv_bytes; |
234 | size_t num_keysigs; | ||
235 | size_t header_extent_size; | 242 | size_t header_extent_size; |
236 | size_t num_header_extents_at_front; | 243 | size_t num_header_extents_at_front; |
237 | size_t extent_size; /* Data extent size; default is 4096 */ | 244 | size_t extent_size; /* Data extent size; default is 4096 */ |
@@ -245,7 +252,8 @@ struct ecryptfs_crypt_stat { | |||
245 | unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; | 252 | unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; |
246 | unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; | 253 | unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; |
247 | unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; | 254 | unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; |
248 | unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; | 255 | struct list_head keysig_list; |
256 | struct mutex keysig_list_mutex; | ||
249 | struct mutex cs_tfm_mutex; | 257 | struct mutex cs_tfm_mutex; |
250 | struct mutex cs_hash_tfm_mutex; | 258 | struct mutex cs_hash_tfm_mutex; |
251 | struct mutex cs_mutex; | 259 | struct mutex cs_mutex; |
@@ -265,6 +273,26 @@ struct ecryptfs_dentry_info { | |||
265 | struct ecryptfs_crypt_stat *crypt_stat; | 273 | struct ecryptfs_crypt_stat *crypt_stat; |
266 | }; | 274 | }; |
267 | 275 | ||
276 | struct ecryptfs_global_auth_tok { | ||
277 | #define ECRYPTFS_AUTH_TOK_INVALID 0x00000001 | ||
278 | u32 flags; | ||
279 | struct list_head mount_crypt_stat_list; | ||
280 | struct key *global_auth_tok_key; | ||
281 | struct ecryptfs_auth_tok *global_auth_tok; | ||
282 | unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
283 | }; | ||
284 | |||
285 | struct ecryptfs_key_tfm { | ||
286 | struct crypto_blkcipher *key_tfm; | ||
287 | size_t key_size; | ||
288 | struct mutex key_tfm_mutex; | ||
289 | struct list_head key_tfm_list; | ||
290 | unsigned char cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; | ||
291 | }; | ||
292 | |||
293 | extern struct list_head key_tfm_list; | ||
294 | extern struct mutex key_tfm_list_mutex; | ||
295 | |||
268 | /** | 296 | /** |
269 | * This struct is to enable a mount-wide passphrase/salt combo. This | 297 | * This struct is to enable a mount-wide passphrase/salt combo. This |
270 | * is more or less a stopgap to provide similar functionality to other | 298 | * is more or less a stopgap to provide similar functionality to other |
@@ -276,15 +304,14 @@ struct ecryptfs_mount_crypt_stat { | |||
276 | #define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 | 304 | #define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 |
277 | #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 | 305 | #define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 |
278 | #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 | 306 | #define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 |
307 | #define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008 | ||
279 | u32 flags; | 308 | u32 flags; |
280 | struct ecryptfs_auth_tok *global_auth_tok; | 309 | struct list_head global_auth_tok_list; |
281 | struct key *global_auth_tok_key; | 310 | struct mutex global_auth_tok_list_mutex; |
311 | size_t num_global_auth_toks; | ||
282 | size_t global_default_cipher_key_size; | 312 | size_t global_default_cipher_key_size; |
283 | struct crypto_blkcipher *global_key_tfm; | ||
284 | struct mutex global_key_tfm_mutex; | ||
285 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE | 313 | unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE |
286 | + 1]; | 314 | + 1]; |
287 | unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1]; | ||
288 | }; | 315 | }; |
289 | 316 | ||
290 | /* superblock private data. */ | 317 | /* superblock private data. */ |
@@ -468,6 +495,9 @@ extern struct kmem_cache *ecryptfs_header_cache_2; | |||
468 | extern struct kmem_cache *ecryptfs_xattr_cache; | 495 | extern struct kmem_cache *ecryptfs_xattr_cache; |
469 | extern struct kmem_cache *ecryptfs_lower_page_cache; | 496 | extern struct kmem_cache *ecryptfs_lower_page_cache; |
470 | extern struct kmem_cache *ecryptfs_key_record_cache; | 497 | extern struct kmem_cache *ecryptfs_key_record_cache; |
498 | extern struct kmem_cache *ecryptfs_key_sig_cache; | ||
499 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; | ||
500 | extern struct kmem_cache *ecryptfs_key_tfm_cache; | ||
471 | 501 | ||
472 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 502 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
473 | struct dentry *this_dentry, struct super_block *sb, | 503 | struct dentry *this_dentry, struct super_block *sb, |
@@ -538,9 +568,8 @@ int | |||
538 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | 568 | ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, |
539 | unsigned char *src, struct dentry *ecryptfs_dentry); | 569 | unsigned char *src, struct dentry *ecryptfs_dentry); |
540 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | 570 | int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); |
541 | int | 571 | int ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm, |
542 | ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, | 572 | char *cipher_name, size_t *key_size); |
543 | size_t *key_size); | ||
544 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | 573 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); |
545 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | 574 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); |
546 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | 575 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); |
@@ -580,6 +609,24 @@ void | |||
580 | ecryptfs_write_header_metadata(char *virt, | 609 | ecryptfs_write_header_metadata(char *virt, |
581 | struct ecryptfs_crypt_stat *crypt_stat, | 610 | struct ecryptfs_crypt_stat *crypt_stat, |
582 | size_t *written); | 611 | size_t *written); |
612 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig); | ||
613 | int | ||
614 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
615 | char *sig); | ||
616 | int ecryptfs_get_global_auth_tok_for_sig( | ||
617 | struct ecryptfs_global_auth_tok **global_auth_tok, | ||
618 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig); | ||
619 | int | ||
620 | ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, | ||
621 | size_t key_size); | ||
622 | int ecryptfs_init_crypto(void); | ||
623 | int ecryptfs_destruct_crypto(void); | ||
624 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | ||
625 | struct mutex **tfm_mutex, | ||
626 | char *cipher_name); | ||
627 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | ||
628 | struct ecryptfs_auth_tok **auth_tok, | ||
629 | char *sig); | ||
583 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, | 630 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, |
584 | int num_zeros); | 631 | int num_zeros); |
585 | 632 | ||
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index b550dea8eee6..a1764fe3318c 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -402,20 +402,24 @@ out: | |||
402 | * | 402 | * |
403 | * Returns Zero on success; non-zero error otherwise. | 403 | * Returns Zero on success; non-zero error otherwise. |
404 | */ | 404 | */ |
405 | static int decrypt_pki_encrypted_session_key( | 405 | static int |
406 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | 406 | decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, |
407 | struct ecryptfs_auth_tok *auth_tok, | 407 | struct ecryptfs_crypt_stat *crypt_stat) |
408 | struct ecryptfs_crypt_stat *crypt_stat) | ||
409 | { | 408 | { |
410 | u16 cipher_code = 0; | 409 | u16 cipher_code = 0; |
411 | struct ecryptfs_msg_ctx *msg_ctx; | 410 | struct ecryptfs_msg_ctx *msg_ctx; |
412 | struct ecryptfs_message *msg = NULL; | 411 | struct ecryptfs_message *msg = NULL; |
412 | char *auth_tok_sig; | ||
413 | char *netlink_message; | 413 | char *netlink_message; |
414 | size_t netlink_message_length; | 414 | size_t netlink_message_length; |
415 | int rc; | 415 | int rc; |
416 | 416 | ||
417 | rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig, | 417 | if ((rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok))) { |
418 | &(auth_tok->session_key), | 418 | printk(KERN_ERR "Unrecognized auth tok type: [%d]\n", |
419 | auth_tok->token_type); | ||
420 | goto out; | ||
421 | } | ||
422 | rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key), | ||
419 | &netlink_message, &netlink_message_length); | 423 | &netlink_message, &netlink_message_length); |
420 | if (rc) { | 424 | if (rc) { |
421 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); | 425 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); |
@@ -921,126 +925,241 @@ out: | |||
921 | return rc; | 925 | return rc; |
922 | } | 926 | } |
923 | 927 | ||
928 | static int | ||
929 | ecryptfs_find_global_auth_tok_for_sig( | ||
930 | struct ecryptfs_global_auth_tok **global_auth_tok, | ||
931 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig) | ||
932 | { | ||
933 | struct ecryptfs_global_auth_tok *walker; | ||
934 | int rc = 0; | ||
935 | |||
936 | (*global_auth_tok) = NULL; | ||
937 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
938 | list_for_each_entry(walker, | ||
939 | &mount_crypt_stat->global_auth_tok_list, | ||
940 | mount_crypt_stat_list) { | ||
941 | if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) { | ||
942 | (*global_auth_tok) = walker; | ||
943 | goto out; | ||
944 | } | ||
945 | } | ||
946 | rc = -EINVAL; | ||
947 | out: | ||
948 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
949 | return rc; | ||
950 | } | ||
951 | |||
924 | /** | 952 | /** |
925 | * decrypt_session_key - Decrypt the session key with the given auth_tok. | 953 | * ecryptfs_verify_version |
954 | * @version: The version number to confirm | ||
955 | * | ||
956 | * Returns zero on good version; non-zero otherwise | ||
957 | */ | ||
958 | static int ecryptfs_verify_version(u16 version) | ||
959 | { | ||
960 | int rc = 0; | ||
961 | unsigned char major; | ||
962 | unsigned char minor; | ||
963 | |||
964 | major = ((version >> 8) & 0xFF); | ||
965 | minor = (version & 0xFF); | ||
966 | if (major != ECRYPTFS_VERSION_MAJOR) { | ||
967 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | ||
968 | "Expected [%d]; got [%d]\n", | ||
969 | ECRYPTFS_VERSION_MAJOR, major); | ||
970 | rc = -EINVAL; | ||
971 | goto out; | ||
972 | } | ||
973 | if (minor != ECRYPTFS_VERSION_MINOR) { | ||
974 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | ||
975 | "Expected [%d]; got [%d]\n", | ||
976 | ECRYPTFS_VERSION_MINOR, minor); | ||
977 | rc = -EINVAL; | ||
978 | goto out; | ||
979 | } | ||
980 | out: | ||
981 | return rc; | ||
982 | } | ||
983 | |||
984 | int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | ||
985 | struct ecryptfs_auth_tok **auth_tok, | ||
986 | char *sig) | ||
987 | { | ||
988 | int rc = 0; | ||
989 | |||
990 | (*auth_tok_key) = request_key(&key_type_user, sig, NULL); | ||
991 | if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { | ||
992 | printk(KERN_ERR "Could not find key with description: [%s]\n", | ||
993 | sig); | ||
994 | process_request_key_err(PTR_ERR(*auth_tok_key)); | ||
995 | rc = -EINVAL; | ||
996 | goto out; | ||
997 | } | ||
998 | (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); | ||
999 | if (ecryptfs_verify_version((*auth_tok)->version)) { | ||
1000 | printk(KERN_ERR | ||
1001 | "Data structure version mismatch. " | ||
1002 | "Userspace tools must match eCryptfs " | ||
1003 | "kernel module with major version [%d] " | ||
1004 | "and minor version [%d]\n", | ||
1005 | ECRYPTFS_VERSION_MAJOR, | ||
1006 | ECRYPTFS_VERSION_MINOR); | ||
1007 | rc = -EINVAL; | ||
1008 | goto out; | ||
1009 | } | ||
1010 | if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD | ||
1011 | && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
1012 | printk(KERN_ERR "Invalid auth_tok structure " | ||
1013 | "returned from key query\n"); | ||
1014 | rc = -EINVAL; | ||
1015 | goto out; | ||
1016 | } | ||
1017 | out: | ||
1018 | return rc; | ||
1019 | } | ||
1020 | |||
1021 | /** | ||
1022 | * ecryptfs_find_auth_tok_for_sig | ||
1023 | * @auth_tok: Set to the matching auth_tok; NULL if not found | ||
1024 | * @crypt_stat: inode crypt_stat crypto context | ||
1025 | * @sig: Sig of auth_tok to find | ||
1026 | * | ||
1027 | * For now, this function simply looks at the registered auth_tok's | ||
1028 | * linked off the mount_crypt_stat, so all the auth_toks that can be | ||
1029 | * used must be registered at mount time. This function could | ||
1030 | * potentially try a lot harder to find auth_tok's (e.g., by calling | ||
1031 | * out to ecryptfsd to dynamically retrieve an auth_tok object) so | ||
1032 | * that static registration of auth_tok's will no longer be necessary. | ||
1033 | * | ||
1034 | * Returns zero on no error; non-zero on error | ||
1035 | */ | ||
1036 | static int | ||
1037 | ecryptfs_find_auth_tok_for_sig( | ||
1038 | struct ecryptfs_auth_tok **auth_tok, | ||
1039 | struct ecryptfs_crypt_stat *crypt_stat, char *sig) | ||
1040 | { | ||
1041 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1042 | crypt_stat->mount_crypt_stat; | ||
1043 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
1044 | int rc = 0; | ||
1045 | |||
1046 | (*auth_tok) = NULL; | ||
1047 | if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | ||
1048 | mount_crypt_stat, sig)) { | ||
1049 | struct key *auth_tok_key; | ||
1050 | |||
1051 | rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok, | ||
1052 | sig); | ||
1053 | } else | ||
1054 | (*auth_tok) = global_auth_tok->global_auth_tok; | ||
1055 | return rc; | ||
1056 | } | ||
1057 | |||
1058 | /** | ||
1059 | * decrypt_passphrase_encrypted_session_key - Decrypt the session key | ||
1060 | * with the given auth_tok. | ||
926 | * | 1061 | * |
927 | * Returns Zero on success; non-zero error otherwise. | 1062 | * Returns Zero on success; non-zero error otherwise. |
928 | */ | 1063 | */ |
929 | static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | 1064 | static int |
930 | struct ecryptfs_crypt_stat *crypt_stat) | 1065 | decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, |
1066 | struct ecryptfs_crypt_stat *crypt_stat) | ||
931 | { | 1067 | { |
932 | struct ecryptfs_password *password_s_ptr; | 1068 | struct scatterlist dst_sg; |
933 | struct scatterlist src_sg[2], dst_sg[2]; | 1069 | struct scatterlist src_sg; |
934 | struct mutex *tfm_mutex = NULL; | 1070 | struct mutex *tfm_mutex = NULL; |
935 | char *encrypted_session_key; | ||
936 | char *session_key; | ||
937 | struct blkcipher_desc desc = { | 1071 | struct blkcipher_desc desc = { |
938 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | 1072 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP |
939 | }; | 1073 | }; |
940 | int rc = 0; | 1074 | int rc = 0; |
941 | 1075 | ||
942 | password_s_ptr = &auth_tok->token.password; | 1076 | if (unlikely(ecryptfs_verbosity > 0)) { |
943 | if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) | 1077 | ecryptfs_printk( |
944 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key " | 1078 | KERN_DEBUG, "Session key encryption key (size [%d]):\n", |
945 | "set; skipping key generation\n"); | 1079 | auth_tok->token.password.session_key_encryption_key_bytes); |
946 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" | 1080 | ecryptfs_dump_hex( |
947 | ":\n", | 1081 | auth_tok->token.password.session_key_encryption_key, |
948 | password_s_ptr->session_key_encryption_key_bytes); | 1082 | auth_tok->token.password.session_key_encryption_key_bytes); |
949 | if (ecryptfs_verbosity > 0) | 1083 | } |
950 | ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key, | 1084 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, |
951 | password_s_ptr-> | 1085 | crypt_stat->cipher); |
952 | session_key_encryption_key_bytes); | 1086 | if (unlikely(rc)) { |
953 | if (!strcmp(crypt_stat->cipher, | 1087 | printk(KERN_ERR "Internal error whilst attempting to get " |
954 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | 1088 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
955 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | 1089 | crypt_stat->cipher, rc); |
956 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | 1090 | goto out; |
957 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | ||
958 | } else { | ||
959 | char *full_alg_name; | ||
960 | |||
961 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, | ||
962 | crypt_stat->cipher, | ||
963 | "ecb"); | ||
964 | if (rc) | ||
965 | goto out; | ||
966 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
967 | CRYPTO_ALG_ASYNC); | ||
968 | kfree(full_alg_name); | ||
969 | if (IS_ERR(desc.tfm)) { | ||
970 | rc = PTR_ERR(desc.tfm); | ||
971 | printk(KERN_ERR "Error allocating crypto context; " | ||
972 | "rc = [%d]\n", rc); | ||
973 | goto out; | ||
974 | } | ||
975 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); | ||
976 | } | 1091 | } |
977 | if (tfm_mutex) | 1092 | if ((rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key, |
978 | mutex_lock(tfm_mutex); | 1093 | auth_tok->session_key.encrypted_key_size, |
979 | rc = crypto_blkcipher_setkey(desc.tfm, | 1094 | &src_sg, 1)) != 1) { |
980 | password_s_ptr->session_key_encryption_key, | 1095 | printk(KERN_ERR "Internal error whilst attempting to convert " |
981 | crypt_stat->key_size); | 1096 | "auth_tok->session_key.encrypted_key to scatterlist; " |
982 | if (rc < 0) { | 1097 | "expected rc = 1; got rc = [%d]. " |
1098 | "auth_tok->session_key.encrypted_key_size = [%d]\n", rc, | ||
1099 | auth_tok->session_key.encrypted_key_size); | ||
1100 | goto out; | ||
1101 | } | ||
1102 | auth_tok->session_key.decrypted_key_size = | ||
1103 | auth_tok->session_key.encrypted_key_size; | ||
1104 | if ((rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key, | ||
1105 | auth_tok->session_key.decrypted_key_size, | ||
1106 | &dst_sg, 1)) != 1) { | ||
1107 | printk(KERN_ERR "Internal error whilst attempting to convert " | ||
1108 | "auth_tok->session_key.decrypted_key to scatterlist; " | ||
1109 | "expected rc = 1; got rc = [%d]\n", rc); | ||
1110 | goto out; | ||
1111 | } | ||
1112 | mutex_lock(tfm_mutex); | ||
1113 | rc = crypto_blkcipher_setkey( | ||
1114 | desc.tfm, auth_tok->token.password.session_key_encryption_key, | ||
1115 | crypt_stat->key_size); | ||
1116 | if (unlikely(rc < 0)) { | ||
1117 | mutex_unlock(tfm_mutex); | ||
983 | printk(KERN_ERR "Error setting key for crypto context\n"); | 1118 | printk(KERN_ERR "Error setting key for crypto context\n"); |
984 | rc = -EINVAL; | 1119 | rc = -EINVAL; |
985 | goto out_free_tfm; | 1120 | goto out; |
986 | } | ||
987 | /* TODO: virt_to_scatterlist */ | ||
988 | encrypted_session_key = (char *)__get_free_page(GFP_KERNEL); | ||
989 | if (!encrypted_session_key) { | ||
990 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
991 | rc = -ENOMEM; | ||
992 | goto out_free_tfm; | ||
993 | } | 1121 | } |
994 | session_key = (char *)__get_free_page(GFP_KERNEL); | 1122 | rc = crypto_blkcipher_decrypt(&desc, &dst_sg, &src_sg, |
995 | if (!session_key) { | ||
996 | kfree(encrypted_session_key); | ||
997 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | ||
998 | rc = -ENOMEM; | ||
999 | goto out_free_tfm; | ||
1000 | } | ||
1001 | memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key, | ||
1002 | auth_tok->session_key.encrypted_key_size); | ||
1003 | src_sg[0].page = virt_to_page(encrypted_session_key); | ||
1004 | src_sg[0].offset = 0; | ||
1005 | BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE); | ||
1006 | src_sg[0].length = auth_tok->session_key.encrypted_key_size; | ||
1007 | dst_sg[0].page = virt_to_page(session_key); | ||
1008 | dst_sg[0].offset = 0; | ||
1009 | auth_tok->session_key.decrypted_key_size = | ||
1010 | auth_tok->session_key.encrypted_key_size; | ||
1011 | dst_sg[0].length = auth_tok->session_key.encrypted_key_size; | ||
1012 | rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg, | ||
1013 | auth_tok->session_key.encrypted_key_size); | 1123 | auth_tok->session_key.encrypted_key_size); |
1014 | if (rc) { | 1124 | mutex_unlock(tfm_mutex); |
1125 | if (unlikely(rc)) { | ||
1015 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); | 1126 | printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); |
1016 | goto out_free_memory; | 1127 | goto out; |
1017 | } | 1128 | } |
1018 | auth_tok->session_key.decrypted_key_size = | ||
1019 | auth_tok->session_key.encrypted_key_size; | ||
1020 | memcpy(auth_tok->session_key.decrypted_key, session_key, | ||
1021 | auth_tok->session_key.decrypted_key_size); | ||
1022 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; | 1129 | auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; |
1023 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, | 1130 | memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, |
1024 | auth_tok->session_key.decrypted_key_size); | 1131 | auth_tok->session_key.decrypted_key_size); |
1025 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; | 1132 | crypt_stat->flags |= ECRYPTFS_KEY_VALID; |
1026 | ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); | 1133 | if (unlikely(ecryptfs_verbosity > 0)) { |
1027 | if (ecryptfs_verbosity > 0) | 1134 | ecryptfs_printk(KERN_DEBUG, "FEK of size [%d]:\n", |
1135 | crypt_stat->key_size); | ||
1028 | ecryptfs_dump_hex(crypt_stat->key, | 1136 | ecryptfs_dump_hex(crypt_stat->key, |
1029 | crypt_stat->key_size); | 1137 | crypt_stat->key_size); |
1030 | out_free_memory: | 1138 | } |
1031 | memset(encrypted_session_key, 0, PAGE_CACHE_SIZE); | ||
1032 | free_page((unsigned long)encrypted_session_key); | ||
1033 | memset(session_key, 0, PAGE_CACHE_SIZE); | ||
1034 | free_page((unsigned long)session_key); | ||
1035 | out_free_tfm: | ||
1036 | if (tfm_mutex) | ||
1037 | mutex_unlock(tfm_mutex); | ||
1038 | else | ||
1039 | crypto_free_blkcipher(desc.tfm); | ||
1040 | out: | 1139 | out: |
1041 | return rc; | 1140 | return rc; |
1042 | } | 1141 | } |
1043 | 1142 | ||
1143 | int ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok) | ||
1144 | { | ||
1145 | int rc = 0; | ||
1146 | |||
1147 | (*sig) = NULL; | ||
1148 | switch (auth_tok->token_type) { | ||
1149 | case ECRYPTFS_PASSWORD: | ||
1150 | (*sig) = auth_tok->token.password.signature; | ||
1151 | break; | ||
1152 | case ECRYPTFS_PRIVATE_KEY: | ||
1153 | (*sig) = auth_tok->token.private_key.signature; | ||
1154 | break; | ||
1155 | default: | ||
1156 | printk(KERN_ERR "Cannot get sig for auth_tok of type [%d]\n", | ||
1157 | auth_tok->token_type); | ||
1158 | rc = -EINVAL; | ||
1159 | } | ||
1160 | return rc; | ||
1161 | } | ||
1162 | |||
1044 | /** | 1163 | /** |
1045 | * ecryptfs_parse_packet_set | 1164 | * ecryptfs_parse_packet_set |
1046 | * @dest: The header page in memory | 1165 | * @dest: The header page in memory |
@@ -1058,25 +1177,22 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
1058 | struct dentry *ecryptfs_dentry) | 1177 | struct dentry *ecryptfs_dentry) |
1059 | { | 1178 | { |
1060 | size_t i = 0; | 1179 | size_t i = 0; |
1061 | size_t found_auth_tok = 0; | 1180 | size_t found_auth_tok; |
1062 | size_t next_packet_is_auth_tok_packet; | 1181 | size_t next_packet_is_auth_tok_packet; |
1063 | char sig[ECRYPTFS_SIG_SIZE_HEX]; | ||
1064 | struct list_head auth_tok_list; | 1182 | struct list_head auth_tok_list; |
1065 | struct list_head *walker; | 1183 | struct ecryptfs_auth_tok *matching_auth_tok = NULL; |
1066 | struct ecryptfs_auth_tok *chosen_auth_tok = NULL; | ||
1067 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1068 | &ecryptfs_superblock_to_private( | ||
1069 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
1070 | struct ecryptfs_auth_tok *candidate_auth_tok = NULL; | 1184 | struct ecryptfs_auth_tok *candidate_auth_tok = NULL; |
1185 | char *candidate_auth_tok_sig; | ||
1071 | size_t packet_size; | 1186 | size_t packet_size; |
1072 | struct ecryptfs_auth_tok *new_auth_tok; | 1187 | struct ecryptfs_auth_tok *new_auth_tok; |
1073 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; | 1188 | unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; |
1189 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
1074 | size_t tag_11_contents_size; | 1190 | size_t tag_11_contents_size; |
1075 | size_t tag_11_packet_size; | 1191 | size_t tag_11_packet_size; |
1076 | int rc = 0; | 1192 | int rc = 0; |
1077 | 1193 | ||
1078 | INIT_LIST_HEAD(&auth_tok_list); | 1194 | INIT_LIST_HEAD(&auth_tok_list); |
1079 | /* Parse the header to find as many packets as we can, these will be | 1195 | /* Parse the header to find as many packets as we can; these will be |
1080 | * added the our &auth_tok_list */ | 1196 | * added the our &auth_tok_list */ |
1081 | next_packet_is_auth_tok_packet = 1; | 1197 | next_packet_is_auth_tok_packet = 1; |
1082 | while (next_packet_is_auth_tok_packet) { | 1198 | while (next_packet_is_auth_tok_packet) { |
@@ -1155,73 +1271,86 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, | |||
1155 | } | 1271 | } |
1156 | } | 1272 | } |
1157 | if (list_empty(&auth_tok_list)) { | 1273 | if (list_empty(&auth_tok_list)) { |
1158 | rc = -EINVAL; /* Do not support non-encrypted files in | 1274 | printk(KERN_ERR "The lower file appears to be a non-encrypted " |
1159 | * the 0.1 release */ | 1275 | "eCryptfs file; this is not supported in this version " |
1276 | "of the eCryptfs kernel module\n"); | ||
1277 | rc = -EINVAL; | ||
1160 | goto out; | 1278 | goto out; |
1161 | } | 1279 | } |
1162 | /* If we have a global auth tok, then we should try to use | 1280 | /* auth_tok_list contains the set of authentication tokens |
1163 | * it */ | 1281 | * parsed from the metadata. We need to find a matching |
1164 | if (mount_crypt_stat->global_auth_tok) { | 1282 | * authentication token that has the secret component(s) |
1165 | memcpy(sig, mount_crypt_stat->global_auth_tok_sig, | 1283 | * necessary to decrypt the EFEK in the auth_tok parsed from |
1166 | ECRYPTFS_SIG_SIZE_HEX); | 1284 | * the metadata. There may be several potential matches, but |
1167 | chosen_auth_tok = mount_crypt_stat->global_auth_tok; | 1285 | * just one will be sufficient to decrypt to get the FEK. */ |
1168 | } else | 1286 | find_next_matching_auth_tok: |
1169 | BUG(); /* We should always have a global auth tok in | 1287 | found_auth_tok = 0; |
1170 | * the 0.1 release */ | 1288 | list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) { |
1171 | /* Scan list to see if our chosen_auth_tok works */ | ||
1172 | list_for_each(walker, &auth_tok_list) { | ||
1173 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item; | ||
1174 | auth_tok_list_item = | ||
1175 | list_entry(walker, struct ecryptfs_auth_tok_list_item, | ||
1176 | list); | ||
1177 | candidate_auth_tok = &auth_tok_list_item->auth_tok; | 1289 | candidate_auth_tok = &auth_tok_list_item->auth_tok; |
1178 | if (unlikely(ecryptfs_verbosity > 0)) { | 1290 | if (unlikely(ecryptfs_verbosity > 0)) { |
1179 | ecryptfs_printk(KERN_DEBUG, | 1291 | ecryptfs_printk(KERN_DEBUG, |
1180 | "Considering cadidate auth tok:\n"); | 1292 | "Considering cadidate auth tok:\n"); |
1181 | ecryptfs_dump_auth_tok(candidate_auth_tok); | 1293 | ecryptfs_dump_auth_tok(candidate_auth_tok); |
1182 | } | 1294 | } |
1183 | /* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */ | 1295 | if ((rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig, |
1184 | if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD | 1296 | candidate_auth_tok))) { |
1185 | && !strncmp(candidate_auth_tok->token.password.signature, | 1297 | printk(KERN_ERR |
1186 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | 1298 | "Unrecognized candidate auth tok type: [%d]\n", |
1187 | found_auth_tok = 1; | 1299 | candidate_auth_tok->token_type); |
1188 | goto leave_list; | 1300 | rc = -EINVAL; |
1189 | /* TODO: Transfer the common salt into the | 1301 | goto out_wipe_list; |
1190 | * crypt_stat salt */ | 1302 | } |
1191 | } else if ((candidate_auth_tok->token_type | 1303 | if ((rc = ecryptfs_find_auth_tok_for_sig( |
1192 | == ECRYPTFS_PRIVATE_KEY) | 1304 | &matching_auth_tok, crypt_stat, |
1193 | && !strncmp(candidate_auth_tok->token.private_key.signature, | 1305 | candidate_auth_tok_sig))) |
1194 | sig, ECRYPTFS_SIG_SIZE_HEX)) { | 1306 | rc = 0; |
1307 | if (matching_auth_tok) { | ||
1195 | found_auth_tok = 1; | 1308 | found_auth_tok = 1; |
1196 | goto leave_list; | 1309 | goto found_matching_auth_tok; |
1197 | } | 1310 | } |
1198 | } | 1311 | } |
1199 | if (!found_auth_tok) { | 1312 | if (!found_auth_tok) { |
1200 | ecryptfs_printk(KERN_ERR, "Could not find authentication " | 1313 | ecryptfs_printk(KERN_ERR, "Could not find a usable " |
1201 | "token on temporary list for sig [%.*s]\n", | 1314 | "authentication token\n"); |
1202 | ECRYPTFS_SIG_SIZE_HEX, sig); | ||
1203 | rc = -EIO; | 1315 | rc = -EIO; |
1204 | goto out_wipe_list; | 1316 | goto out_wipe_list; |
1205 | } | 1317 | } |
1206 | leave_list: | 1318 | found_matching_auth_tok: |
1207 | rc = -ENOTSUPP; | ||
1208 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | 1319 | if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
1209 | memcpy(&(candidate_auth_tok->token.private_key), | 1320 | memcpy(&(candidate_auth_tok->token.private_key), |
1210 | &(chosen_auth_tok->token.private_key), | 1321 | &(matching_auth_tok->token.private_key), |
1211 | sizeof(struct ecryptfs_private_key)); | 1322 | sizeof(struct ecryptfs_private_key)); |
1212 | rc = decrypt_pki_encrypted_session_key(mount_crypt_stat, | 1323 | rc = decrypt_pki_encrypted_session_key(candidate_auth_tok, |
1213 | candidate_auth_tok, | ||
1214 | crypt_stat); | 1324 | crypt_stat); |
1215 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { | 1325 | } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { |
1216 | memcpy(&(candidate_auth_tok->token.password), | 1326 | memcpy(&(candidate_auth_tok->token.password), |
1217 | &(chosen_auth_tok->token.password), | 1327 | &(matching_auth_tok->token.password), |
1218 | sizeof(struct ecryptfs_password)); | 1328 | sizeof(struct ecryptfs_password)); |
1219 | rc = decrypt_session_key(candidate_auth_tok, crypt_stat); | 1329 | rc = decrypt_passphrase_encrypted_session_key( |
1330 | candidate_auth_tok, crypt_stat); | ||
1220 | } | 1331 | } |
1221 | if (rc) { | 1332 | if (rc) { |
1222 | ecryptfs_printk(KERN_ERR, "Error decrypting the " | 1333 | struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp; |
1223 | "session key; rc = [%d]\n", rc); | 1334 | |
1224 | goto out_wipe_list; | 1335 | ecryptfs_printk(KERN_WARNING, "Error decrypting the " |
1336 | "session key for authentication token with sig " | ||
1337 | "[%.*s]; rc = [%d]. Removing auth tok " | ||
1338 | "candidate from the list and searching for " | ||
1339 | "the next match.\n", candidate_auth_tok_sig, | ||
1340 | ECRYPTFS_SIG_SIZE_HEX, rc); | ||
1341 | list_for_each_entry_safe(auth_tok_list_item, | ||
1342 | auth_tok_list_item_tmp, | ||
1343 | &auth_tok_list, list) { | ||
1344 | if (candidate_auth_tok | ||
1345 | == &auth_tok_list_item->auth_tok) { | ||
1346 | list_del(&auth_tok_list_item->list); | ||
1347 | kmem_cache_free( | ||
1348 | ecryptfs_auth_tok_list_item_cache, | ||
1349 | auth_tok_list_item); | ||
1350 | goto find_next_matching_auth_tok; | ||
1351 | } | ||
1352 | } | ||
1353 | BUG(); | ||
1225 | } | 1354 | } |
1226 | rc = ecryptfs_compute_root_iv(crypt_stat); | 1355 | rc = ecryptfs_compute_root_iv(crypt_stat); |
1227 | if (rc) { | 1356 | if (rc) { |
@@ -1240,6 +1369,7 @@ out_wipe_list: | |||
1240 | out: | 1369 | out: |
1241 | return rc; | 1370 | return rc; |
1242 | } | 1371 | } |
1372 | |||
1243 | static int | 1373 | static int |
1244 | pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, | 1374 | pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, |
1245 | struct ecryptfs_crypt_stat *crypt_stat, | 1375 | struct ecryptfs_crypt_stat *crypt_stat, |
@@ -1291,15 +1421,15 @@ out: | |||
1291 | * Returns zero on success; non-zero on error. | 1421 | * Returns zero on success; non-zero on error. |
1292 | */ | 1422 | */ |
1293 | static int | 1423 | static int |
1294 | write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | 1424 | write_tag_1_packet(char *dest, size_t *remaining_bytes, |
1425 | struct ecryptfs_auth_tok *auth_tok, | ||
1295 | struct ecryptfs_crypt_stat *crypt_stat, | 1426 | struct ecryptfs_crypt_stat *crypt_stat, |
1296 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
1297 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 1427 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
1298 | { | 1428 | { |
1299 | size_t i; | 1429 | size_t i; |
1300 | size_t encrypted_session_key_valid = 0; | 1430 | size_t encrypted_session_key_valid = 0; |
1301 | size_t key_rec_size; | ||
1302 | size_t packet_size_length; | 1431 | size_t packet_size_length; |
1432 | size_t max_packet_size; | ||
1303 | int rc = 0; | 1433 | int rc = 0; |
1304 | 1434 | ||
1305 | (*packet_size) = 0; | 1435 | (*packet_size) = 0; |
@@ -1329,37 +1459,23 @@ write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
1329 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); | 1459 | ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); |
1330 | } | 1460 | } |
1331 | encrypted_session_key_set: | 1461 | encrypted_session_key_set: |
1332 | /* Now we have a valid key_rec. Append it to the | 1462 | /* This format is inspired by OpenPGP; see RFC 2440 |
1333 | * key_rec set. */ | 1463 | * packet tag 1 */ |
1334 | key_rec_size = (sizeof(struct ecryptfs_key_record) | 1464 | max_packet_size = (1 /* Tag 1 identifier */ |
1335 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | 1465 | + 3 /* Max Tag 1 packet size */ |
1336 | + (key_rec->enc_key_size)); | 1466 | + 1 /* Version */ |
1337 | /* TODO: Include a packet size limit as a parameter to this | 1467 | + ECRYPTFS_SIG_SIZE /* Key identifier */ |
1338 | * function once we have multi-packet headers (for versions | 1468 | + 1 /* Cipher identifier */ |
1339 | * later than 0.1 */ | 1469 | + key_rec->enc_key_size); /* Encrypted key size */ |
1340 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | 1470 | if (max_packet_size > (*remaining_bytes)) { |
1341 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | 1471 | printk(KERN_ERR "Packet length larger than maximum allowable; " |
1342 | rc = -EINVAL; | 1472 | "need up to [%d] bytes, but there are only [%d] " |
1343 | goto out; | 1473 | "available\n", max_packet_size, (*remaining_bytes)); |
1344 | } | ||
1345 | /* ***** TAG 1 Packet Format ***** | ||
1346 | * | version number | 1 byte | | ||
1347 | * | key ID | 8 bytes | | ||
1348 | * | public key algorithm | 1 byte | | ||
1349 | * | encrypted session key | arbitrary | | ||
1350 | */ | ||
1351 | if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) { | ||
1352 | ecryptfs_printk(KERN_ERR, | ||
1353 | "Authentication token is too large\n"); | ||
1354 | rc = -EINVAL; | 1474 | rc = -EINVAL; |
1355 | goto out; | 1475 | goto out; |
1356 | } | 1476 | } |
1357 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | 1477 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; |
1358 | /* This format is inspired by OpenPGP; see RFC 2440 | 1478 | rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4), |
1359 | * packet tag 1 */ | ||
1360 | rc = write_packet_length(&dest[(*packet_size)], | ||
1361 | (0x02 + ECRYPTFS_SIG_SIZE + | ||
1362 | key_rec->enc_key_size), | ||
1363 | &packet_size_length); | 1479 | &packet_size_length); |
1364 | if (rc) { | 1480 | if (rc) { |
1365 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | 1481 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " |
@@ -1377,6 +1493,8 @@ encrypted_session_key_set: | |||
1377 | out: | 1493 | out: |
1378 | if (rc) | 1494 | if (rc) |
1379 | (*packet_size) = 0; | 1495 | (*packet_size) = 0; |
1496 | else | ||
1497 | (*remaining_bytes) -= (*packet_size); | ||
1380 | return rc; | 1498 | return rc; |
1381 | } | 1499 | } |
1382 | 1500 | ||
@@ -1448,19 +1566,22 @@ write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, | |||
1448 | * Returns zero on success; non-zero on error. | 1566 | * Returns zero on success; non-zero on error. |
1449 | */ | 1567 | */ |
1450 | static int | 1568 | static int |
1451 | write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | 1569 | write_tag_3_packet(char *dest, size_t *remaining_bytes, |
1570 | struct ecryptfs_auth_tok *auth_tok, | ||
1452 | struct ecryptfs_crypt_stat *crypt_stat, | 1571 | struct ecryptfs_crypt_stat *crypt_stat, |
1453 | struct ecryptfs_key_record *key_rec, size_t *packet_size) | 1572 | struct ecryptfs_key_record *key_rec, size_t *packet_size) |
1454 | { | 1573 | { |
1455 | size_t i; | 1574 | size_t i; |
1456 | size_t encrypted_session_key_valid = 0; | 1575 | size_t encrypted_session_key_valid = 0; |
1457 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; | 1576 | char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; |
1458 | struct scatterlist dest_sg[2]; | 1577 | struct scatterlist dst_sg; |
1459 | struct scatterlist src_sg[2]; | 1578 | struct scatterlist src_sg; |
1460 | struct mutex *tfm_mutex = NULL; | 1579 | struct mutex *tfm_mutex = NULL; |
1461 | size_t key_rec_size; | ||
1462 | size_t packet_size_length; | ||
1463 | size_t cipher_code; | 1580 | size_t cipher_code; |
1581 | size_t packet_size_length; | ||
1582 | size_t max_packet_size; | ||
1583 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | ||
1584 | crypt_stat->mount_crypt_stat; | ||
1464 | struct blkcipher_desc desc = { | 1585 | struct blkcipher_desc desc = { |
1465 | .tfm = NULL, | 1586 | .tfm = NULL, |
1466 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP | 1587 | .flags = CRYPTO_TFM_REQ_MAY_SLEEP |
@@ -1470,16 +1591,25 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
1470 | (*packet_size) = 0; | 1591 | (*packet_size) = 0; |
1471 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, | 1592 | ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, |
1472 | ECRYPTFS_SIG_SIZE); | 1593 | ECRYPTFS_SIG_SIZE); |
1473 | encrypted_session_key_valid = 0; | 1594 | rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, |
1474 | for (i = 0; i < crypt_stat->key_size; i++) | 1595 | crypt_stat->cipher); |
1475 | encrypted_session_key_valid |= | 1596 | if (unlikely(rc)) { |
1476 | auth_tok->session_key.encrypted_key[i]; | 1597 | printk(KERN_ERR "Internal error whilst attempting to get " |
1477 | if (encrypted_session_key_valid) { | 1598 | "tfm and mutex for cipher name [%s]; rc = [%d]\n", |
1478 | memcpy(key_rec->enc_key, | 1599 | crypt_stat->cipher, rc); |
1479 | auth_tok->session_key.encrypted_key, | 1600 | goto out; |
1480 | auth_tok->session_key.encrypted_key_size); | 1601 | } |
1481 | goto encrypted_session_key_set; | 1602 | if (mount_crypt_stat->global_default_cipher_key_size == 0) { |
1603 | struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm); | ||
1604 | |||
1605 | printk(KERN_WARNING "No key size specified at mount; " | ||
1606 | "defaulting to [%d]\n", alg->max_keysize); | ||
1607 | mount_crypt_stat->global_default_cipher_key_size = | ||
1608 | alg->max_keysize; | ||
1482 | } | 1609 | } |
1610 | if (crypt_stat->key_size == 0) | ||
1611 | crypt_stat->key_size = | ||
1612 | mount_crypt_stat->global_default_cipher_key_size; | ||
1483 | if (auth_tok->session_key.encrypted_key_size == 0) | 1613 | if (auth_tok->session_key.encrypted_key_size == 0) |
1484 | auth_tok->session_key.encrypted_key_size = | 1614 | auth_tok->session_key.encrypted_key_size = |
1485 | crypt_stat->key_size; | 1615 | crypt_stat->key_size; |
@@ -1487,9 +1617,24 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
1487 | && strcmp("aes", crypt_stat->cipher) == 0) { | 1617 | && strcmp("aes", crypt_stat->cipher) == 0) { |
1488 | memset((crypt_stat->key + 24), 0, 8); | 1618 | memset((crypt_stat->key + 24), 0, 8); |
1489 | auth_tok->session_key.encrypted_key_size = 32; | 1619 | auth_tok->session_key.encrypted_key_size = 32; |
1490 | } | 1620 | } else |
1621 | auth_tok->session_key.encrypted_key_size = crypt_stat->key_size; | ||
1491 | key_rec->enc_key_size = | 1622 | key_rec->enc_key_size = |
1492 | auth_tok->session_key.encrypted_key_size; | 1623 | auth_tok->session_key.encrypted_key_size; |
1624 | encrypted_session_key_valid = 0; | ||
1625 | for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++) | ||
1626 | encrypted_session_key_valid |= | ||
1627 | auth_tok->session_key.encrypted_key[i]; | ||
1628 | if (encrypted_session_key_valid) { | ||
1629 | ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; " | ||
1630 | "using auth_tok->session_key.encrypted_key, " | ||
1631 | "where key_rec->enc_key_size = [%d]\n", | ||
1632 | key_rec->enc_key_size); | ||
1633 | memcpy(key_rec->enc_key, | ||
1634 | auth_tok->session_key.encrypted_key, | ||
1635 | key_rec->enc_key_size); | ||
1636 | goto encrypted_session_key_set; | ||
1637 | } | ||
1493 | if (auth_tok->token.password.flags & | 1638 | if (auth_tok->token.password.flags & |
1494 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { | 1639 | ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { |
1495 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " | 1640 | ecryptfs_printk(KERN_DEBUG, "Using previously generated " |
@@ -1508,54 +1653,32 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
1508 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); | 1653 | ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); |
1509 | ecryptfs_dump_hex(session_key_encryption_key, 16); | 1654 | ecryptfs_dump_hex(session_key_encryption_key, 16); |
1510 | } | 1655 | } |
1511 | rc = virt_to_scatterlist(crypt_stat->key, | 1656 | if ((rc = virt_to_scatterlist(crypt_stat->key, |
1512 | key_rec->enc_key_size, src_sg, 2); | 1657 | key_rec->enc_key_size, &src_sg, 1)) |
1513 | if (!rc) { | 1658 | != 1) { |
1514 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1659 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
1515 | "for crypt_stat session key\n"); | 1660 | "for crypt_stat session key; expected rc = 1; " |
1661 | "got rc = [%d]. key_rec->enc_key_size = [%d]\n", | ||
1662 | rc, key_rec->enc_key_size); | ||
1516 | rc = -ENOMEM; | 1663 | rc = -ENOMEM; |
1517 | goto out; | 1664 | goto out; |
1518 | } | 1665 | } |
1519 | rc = virt_to_scatterlist(key_rec->enc_key, | 1666 | if ((rc = virt_to_scatterlist(key_rec->enc_key, |
1520 | key_rec->enc_key_size, dest_sg, 2); | 1667 | key_rec->enc_key_size, &dst_sg, 1)) |
1521 | if (!rc) { | 1668 | != 1) { |
1522 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " | 1669 | ecryptfs_printk(KERN_ERR, "Error generating scatterlist " |
1523 | "for crypt_stat encrypted session key\n"); | 1670 | "for crypt_stat encrypted session key; " |
1671 | "expected rc = 1; got rc = [%d]. " | ||
1672 | "key_rec->enc_key_size = [%d]\n", rc, | ||
1673 | key_rec->enc_key_size); | ||
1524 | rc = -ENOMEM; | 1674 | rc = -ENOMEM; |
1525 | goto out; | 1675 | goto out; |
1526 | } | 1676 | } |
1527 | if (!strcmp(crypt_stat->cipher, | 1677 | mutex_lock(tfm_mutex); |
1528 | crypt_stat->mount_crypt_stat->global_default_cipher_name) | ||
1529 | && crypt_stat->mount_crypt_stat->global_key_tfm) { | ||
1530 | desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; | ||
1531 | tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex; | ||
1532 | } else { | ||
1533 | char *full_alg_name; | ||
1534 | |||
1535 | rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name, | ||
1536 | crypt_stat->cipher, | ||
1537 | "ecb"); | ||
1538 | if (rc) | ||
1539 | goto out; | ||
1540 | desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0, | ||
1541 | CRYPTO_ALG_ASYNC); | ||
1542 | kfree(full_alg_name); | ||
1543 | if (IS_ERR(desc.tfm)) { | ||
1544 | rc = PTR_ERR(desc.tfm); | ||
1545 | ecryptfs_printk(KERN_ERR, "Could not initialize crypto " | ||
1546 | "context for cipher [%s]; rc = [%d]\n", | ||
1547 | crypt_stat->cipher, rc); | ||
1548 | goto out; | ||
1549 | } | ||
1550 | crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY); | ||
1551 | } | ||
1552 | if (tfm_mutex) | ||
1553 | mutex_lock(tfm_mutex); | ||
1554 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, | 1678 | rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, |
1555 | crypt_stat->key_size); | 1679 | crypt_stat->key_size); |
1556 | if (rc < 0) { | 1680 | if (rc < 0) { |
1557 | if (tfm_mutex) | 1681 | mutex_unlock(tfm_mutex); |
1558 | mutex_unlock(tfm_mutex); | ||
1559 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " | 1682 | ecryptfs_printk(KERN_ERR, "Error setting key for crypto " |
1560 | "context; rc = [%d]\n", rc); | 1683 | "context; rc = [%d]\n", rc); |
1561 | goto out; | 1684 | goto out; |
@@ -1563,56 +1686,53 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, | |||
1563 | rc = 0; | 1686 | rc = 0; |
1564 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", | 1687 | ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", |
1565 | crypt_stat->key_size); | 1688 | crypt_stat->key_size); |
1566 | rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg, | 1689 | rc = crypto_blkcipher_encrypt(&desc, &dst_sg, &src_sg, |
1567 | (*key_rec).enc_key_size); | 1690 | (*key_rec).enc_key_size); |
1691 | mutex_unlock(tfm_mutex); | ||
1568 | if (rc) { | 1692 | if (rc) { |
1569 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); | 1693 | printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); |
1570 | goto out; | 1694 | goto out; |
1571 | } | 1695 | } |
1572 | if (tfm_mutex) | ||
1573 | mutex_unlock(tfm_mutex); | ||
1574 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); | 1696 | ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); |
1575 | if (ecryptfs_verbosity > 0) | 1697 | if (ecryptfs_verbosity > 0) { |
1698 | ecryptfs_printk(KERN_DEBUG, "EFEK of size [%d]:\n", | ||
1699 | key_rec->enc_key_size); | ||
1576 | ecryptfs_dump_hex(key_rec->enc_key, | 1700 | ecryptfs_dump_hex(key_rec->enc_key, |
1577 | key_rec->enc_key_size); | 1701 | key_rec->enc_key_size); |
1578 | encrypted_session_key_set: | ||
1579 | /* Now we have a valid key_rec. Append it to the | ||
1580 | * key_rec set. */ | ||
1581 | key_rec_size = (sizeof(struct ecryptfs_key_record) | ||
1582 | - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES | ||
1583 | + (key_rec->enc_key_size)); | ||
1584 | /* TODO: Include a packet size limit as a parameter to this | ||
1585 | * function once we have multi-packet headers (for versions | ||
1586 | * later than 0.1 */ | ||
1587 | if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { | ||
1588 | ecryptfs_printk(KERN_ERR, "Keyset too large\n"); | ||
1589 | rc = -EINVAL; | ||
1590 | goto out; | ||
1591 | } | 1702 | } |
1592 | /* TODO: Packet size limit */ | 1703 | encrypted_session_key_set: |
1593 | /* We have 5 bytes of surrounding packet data */ | 1704 | /* This format is inspired by OpenPGP; see RFC 2440 |
1594 | if ((0x05 + ECRYPTFS_SALT_SIZE | 1705 | * packet tag 3 */ |
1595 | + key_rec->enc_key_size) >= max) { | 1706 | max_packet_size = (1 /* Tag 3 identifier */ |
1596 | ecryptfs_printk(KERN_ERR, "Authentication token is too " | 1707 | + 3 /* Max Tag 3 packet size */ |
1597 | "large\n"); | 1708 | + 1 /* Version */ |
1709 | + 1 /* Cipher code */ | ||
1710 | + 1 /* S2K specifier */ | ||
1711 | + 1 /* Hash identifier */ | ||
1712 | + ECRYPTFS_SALT_SIZE /* Salt */ | ||
1713 | + 1 /* Hash iterations */ | ||
1714 | + key_rec->enc_key_size); /* Encrypted key size */ | ||
1715 | if (max_packet_size > (*remaining_bytes)) { | ||
1716 | printk(KERN_ERR "Packet too large; need up to [%d] bytes, but " | ||
1717 | "there are only [%d] available\n", max_packet_size, | ||
1718 | (*remaining_bytes)); | ||
1598 | rc = -EINVAL; | 1719 | rc = -EINVAL; |
1599 | goto out; | 1720 | goto out; |
1600 | } | 1721 | } |
1601 | /* This format is inspired by OpenPGP; see RFC 2440 | ||
1602 | * packet tag 3 */ | ||
1603 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; | 1722 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; |
1604 | /* ver+cipher+s2k+hash+salt+iter+enc_key */ | 1723 | /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3) |
1605 | rc = write_packet_length(&dest[(*packet_size)], | 1724 | * to get the number of octets in the actual Tag 3 packet */ |
1606 | (0x05 + ECRYPTFS_SALT_SIZE | 1725 | rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4), |
1607 | + key_rec->enc_key_size), | ||
1608 | &packet_size_length); | 1726 | &packet_size_length); |
1609 | if (rc) { | 1727 | if (rc) { |
1610 | ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " | 1728 | printk(KERN_ERR "Error generating tag 3 packet header; cannot " |
1611 | "header; cannot generate packet length\n"); | 1729 | "generate packet length. rc = [%d]\n", rc); |
1612 | goto out; | 1730 | goto out; |
1613 | } | 1731 | } |
1614 | (*packet_size) += packet_size_length; | 1732 | (*packet_size) += packet_size_length; |
1615 | dest[(*packet_size)++] = 0x04; /* version 4 */ | 1733 | dest[(*packet_size)++] = 0x04; /* version 4 */ |
1734 | /* TODO: Break from RFC2440 so that arbitrary ciphers can be | ||
1735 | * specified with strings */ | ||
1616 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); | 1736 | cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); |
1617 | if (cipher_code == 0) { | 1737 | if (cipher_code == 0) { |
1618 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " | 1738 | ecryptfs_printk(KERN_WARNING, "Unable to generate code for " |
@@ -1631,10 +1751,10 @@ encrypted_session_key_set: | |||
1631 | key_rec->enc_key_size); | 1751 | key_rec->enc_key_size); |
1632 | (*packet_size) += key_rec->enc_key_size; | 1752 | (*packet_size) += key_rec->enc_key_size; |
1633 | out: | 1753 | out: |
1634 | if (desc.tfm && !tfm_mutex) | ||
1635 | crypto_free_blkcipher(desc.tfm); | ||
1636 | if (rc) | 1754 | if (rc) |
1637 | (*packet_size) = 0; | 1755 | (*packet_size) = 0; |
1756 | else | ||
1757 | (*remaining_bytes) -= (*packet_size); | ||
1638 | return rc; | 1758 | return rc; |
1639 | } | 1759 | } |
1640 | 1760 | ||
@@ -1662,24 +1782,43 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1662 | size_t max) | 1782 | size_t max) |
1663 | { | 1783 | { |
1664 | struct ecryptfs_auth_tok *auth_tok; | 1784 | struct ecryptfs_auth_tok *auth_tok; |
1785 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
1665 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1786 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
1666 | &ecryptfs_superblock_to_private( | 1787 | &ecryptfs_superblock_to_private( |
1667 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1788 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1668 | size_t written; | 1789 | size_t written; |
1669 | struct ecryptfs_key_record *key_rec; | 1790 | struct ecryptfs_key_record *key_rec; |
1791 | struct ecryptfs_key_sig *key_sig; | ||
1670 | int rc = 0; | 1792 | int rc = 0; |
1671 | 1793 | ||
1672 | (*len) = 0; | 1794 | (*len) = 0; |
1795 | mutex_lock(&crypt_stat->keysig_list_mutex); | ||
1673 | key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); | 1796 | key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); |
1674 | if (!key_rec) { | 1797 | if (!key_rec) { |
1675 | rc = -ENOMEM; | 1798 | rc = -ENOMEM; |
1676 | goto out; | 1799 | goto out; |
1677 | } | 1800 | } |
1678 | if (mount_crypt_stat->global_auth_tok) { | 1801 | list_for_each_entry(key_sig, &crypt_stat->keysig_list, |
1679 | auth_tok = mount_crypt_stat->global_auth_tok; | 1802 | crypt_stat_list) { |
1803 | memset(key_rec, 0, sizeof(*key_rec)); | ||
1804 | rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok, | ||
1805 | mount_crypt_stat, | ||
1806 | key_sig->keysig); | ||
1807 | if (rc) { | ||
1808 | printk(KERN_ERR "Error attempting to get the global " | ||
1809 | "auth_tok; rc = [%d]\n", rc); | ||
1810 | goto out_free; | ||
1811 | } | ||
1812 | if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) { | ||
1813 | printk(KERN_WARNING | ||
1814 | "Skipping invalid auth tok with sig = [%s]\n", | ||
1815 | global_auth_tok->sig); | ||
1816 | continue; | ||
1817 | } | ||
1818 | auth_tok = global_auth_tok->global_auth_tok; | ||
1680 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { | 1819 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { |
1681 | rc = write_tag_3_packet((dest_base + (*len)), | 1820 | rc = write_tag_3_packet((dest_base + (*len)), |
1682 | max, auth_tok, | 1821 | &max, auth_tok, |
1683 | crypt_stat, key_rec, | 1822 | crypt_stat, key_rec, |
1684 | &written); | 1823 | &written); |
1685 | if (rc) { | 1824 | if (rc) { |
@@ -1689,10 +1828,9 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1689 | } | 1828 | } |
1690 | (*len) += written; | 1829 | (*len) += written; |
1691 | /* Write auth tok signature packet */ | 1830 | /* Write auth tok signature packet */ |
1692 | rc = write_tag_11_packet( | 1831 | rc = write_tag_11_packet((dest_base + (*len)), &max, |
1693 | (dest_base + (*len)), | 1832 | key_rec->sig, |
1694 | (max - (*len)), | 1833 | ECRYPTFS_SIG_SIZE, &written); |
1695 | key_rec->sig, ECRYPTFS_SIG_SIZE, &written); | ||
1696 | if (rc) { | 1834 | if (rc) { |
1697 | ecryptfs_printk(KERN_ERR, "Error writing " | 1835 | ecryptfs_printk(KERN_ERR, "Error writing " |
1698 | "auth tok signature packet\n"); | 1836 | "auth tok signature packet\n"); |
@@ -1701,9 +1839,8 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1701 | (*len) += written; | 1839 | (*len) += written; |
1702 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | 1840 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
1703 | rc = write_tag_1_packet(dest_base + (*len), | 1841 | rc = write_tag_1_packet(dest_base + (*len), |
1704 | max, auth_tok, | 1842 | &max, auth_tok, |
1705 | crypt_stat,mount_crypt_stat, | 1843 | crypt_stat, key_rec, &written); |
1706 | key_rec, &written); | ||
1707 | if (rc) { | 1844 | if (rc) { |
1708 | ecryptfs_printk(KERN_WARNING, "Error " | 1845 | ecryptfs_printk(KERN_WARNING, "Error " |
1709 | "writing tag 1 packet\n"); | 1846 | "writing tag 1 packet\n"); |
@@ -1716,19 +1853,69 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1716 | rc = -EINVAL; | 1853 | rc = -EINVAL; |
1717 | goto out_free; | 1854 | goto out_free; |
1718 | } | 1855 | } |
1719 | } else | 1856 | } |
1720 | BUG(); | 1857 | if (likely(max > 0)) { |
1721 | if (likely((max - (*len)) > 0)) { | ||
1722 | dest_base[(*len)] = 0x00; | 1858 | dest_base[(*len)] = 0x00; |
1723 | } else { | 1859 | } else { |
1724 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); | 1860 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); |
1725 | rc = -EIO; | 1861 | rc = -EIO; |
1726 | } | 1862 | } |
1727 | |||
1728 | out_free: | 1863 | out_free: |
1729 | kmem_cache_free(ecryptfs_key_record_cache, key_rec); | 1864 | kmem_cache_free(ecryptfs_key_record_cache, key_rec); |
1730 | out: | 1865 | out: |
1731 | if (rc) | 1866 | if (rc) |
1732 | (*len) = 0; | 1867 | (*len) = 0; |
1868 | mutex_unlock(&crypt_stat->keysig_list_mutex); | ||
1869 | return rc; | ||
1870 | } | ||
1871 | |||
1872 | struct kmem_cache *ecryptfs_key_sig_cache; | ||
1873 | |||
1874 | int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig) | ||
1875 | { | ||
1876 | struct ecryptfs_key_sig *new_key_sig; | ||
1877 | int rc = 0; | ||
1878 | |||
1879 | new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL); | ||
1880 | if (!new_key_sig) { | ||
1881 | rc = -ENOMEM; | ||
1882 | printk(KERN_ERR | ||
1883 | "Error allocating from ecryptfs_key_sig_cache\n"); | ||
1884 | goto out; | ||
1885 | } | ||
1886 | memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX); | ||
1887 | mutex_lock(&crypt_stat->keysig_list_mutex); | ||
1888 | list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list); | ||
1889 | mutex_unlock(&crypt_stat->keysig_list_mutex); | ||
1890 | out: | ||
1733 | return rc; | 1891 | return rc; |
1734 | } | 1892 | } |
1893 | |||
1894 | struct kmem_cache *ecryptfs_global_auth_tok_cache; | ||
1895 | |||
1896 | int | ||
1897 | ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat, | ||
1898 | char *sig) | ||
1899 | { | ||
1900 | struct ecryptfs_global_auth_tok *new_auth_tok; | ||
1901 | int rc = 0; | ||
1902 | |||
1903 | new_auth_tok = kmem_cache_alloc(ecryptfs_global_auth_tok_cache, | ||
1904 | GFP_KERNEL); | ||
1905 | if (!new_auth_tok) { | ||
1906 | rc = -ENOMEM; | ||
1907 | printk(KERN_ERR "Error allocating from " | ||
1908 | "ecryptfs_global_auth_tok_cache\n"); | ||
1909 | goto out; | ||
1910 | } | ||
1911 | memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX); | ||
1912 | new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | ||
1913 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
1914 | list_add(&new_auth_tok->mount_crypt_stat_list, | ||
1915 | &mount_crypt_stat->global_auth_tok_list); | ||
1916 | mount_crypt_stat->num_global_auth_toks++; | ||
1917 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
1918 | out: | ||
1919 | return rc; | ||
1920 | } | ||
1921 | |||
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index a98497264fe8..6e2170c96c02 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -179,38 +179,40 @@ static match_table_t tokens = { | |||
179 | {ecryptfs_opt_err, NULL} | 179 | {ecryptfs_opt_err, NULL} |
180 | }; | 180 | }; |
181 | 181 | ||
182 | /** | 182 | static int ecryptfs_init_global_auth_toks( |
183 | * ecryptfs_verify_version | 183 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) |
184 | * @version: The version number to confirm | ||
185 | * | ||
186 | * Returns zero on good version; non-zero otherwise | ||
187 | */ | ||
188 | static int ecryptfs_verify_version(u16 version) | ||
189 | { | 184 | { |
185 | struct ecryptfs_global_auth_tok *global_auth_tok; | ||
190 | int rc = 0; | 186 | int rc = 0; |
191 | unsigned char major; | 187 | |
192 | unsigned char minor; | 188 | list_for_each_entry(global_auth_tok, |
193 | 189 | &mount_crypt_stat->global_auth_tok_list, | |
194 | major = ((version >> 8) & 0xFF); | 190 | mount_crypt_stat_list) { |
195 | minor = (version & 0xFF); | 191 | if ((rc = ecryptfs_keyring_auth_tok_for_sig( |
196 | if (major != ECRYPTFS_VERSION_MAJOR) { | 192 | &global_auth_tok->global_auth_tok_key, |
197 | ecryptfs_printk(KERN_ERR, "Major version number mismatch. " | 193 | &global_auth_tok->global_auth_tok, |
198 | "Expected [%d]; got [%d]\n", | 194 | global_auth_tok->sig))) { |
199 | ECRYPTFS_VERSION_MAJOR, major); | 195 | printk(KERN_ERR "Could not find valid key in user " |
200 | rc = -EINVAL; | 196 | "session keyring for sig specified in mount " |
201 | goto out; | 197 | "option: [%s]\n", global_auth_tok->sig); |
202 | } | 198 | global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID; |
203 | if (minor != ECRYPTFS_VERSION_MINOR) { | 199 | rc = 0; |
204 | ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " | 200 | } else |
205 | "Expected [%d]; got [%d]\n", | 201 | global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID; |
206 | ECRYPTFS_VERSION_MINOR, minor); | ||
207 | rc = -EINVAL; | ||
208 | goto out; | ||
209 | } | 202 | } |
210 | out: | ||
211 | return rc; | 203 | return rc; |
212 | } | 204 | } |
213 | 205 | ||
206 | static void ecryptfs_init_mount_crypt_stat( | ||
207 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat) | ||
208 | { | ||
209 | memset((void *)mount_crypt_stat, 0, | ||
210 | sizeof(struct ecryptfs_mount_crypt_stat)); | ||
211 | INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list); | ||
212 | mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex); | ||
213 | mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED; | ||
214 | } | ||
215 | |||
214 | /** | 216 | /** |
215 | * ecryptfs_parse_options | 217 | * ecryptfs_parse_options |
216 | * @sb: The ecryptfs super block | 218 | * @sb: The ecryptfs super block |
@@ -264,14 +266,13 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
264 | case ecryptfs_opt_sig: | 266 | case ecryptfs_opt_sig: |
265 | case ecryptfs_opt_ecryptfs_sig: | 267 | case ecryptfs_opt_ecryptfs_sig: |
266 | sig_src = args[0].from; | 268 | sig_src = args[0].from; |
267 | sig_dst = | 269 | rc = ecryptfs_add_global_auth_tok(mount_crypt_stat, |
268 | mount_crypt_stat->global_auth_tok_sig; | 270 | sig_src); |
269 | memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX); | 271 | if (rc) { |
270 | sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0'; | 272 | printk(KERN_ERR "Error attempting to register " |
271 | ecryptfs_printk(KERN_DEBUG, | 273 | "global sig; rc = [%d]\n", rc); |
272 | "The mount_crypt_stat " | 274 | goto out; |
273 | "global_auth_tok_sig set to: " | 275 | } |
274 | "[%s]\n", sig_dst); | ||
275 | sig_set = 1; | 276 | sig_set = 1; |
276 | break; | 277 | break; |
277 | case ecryptfs_opt_debug: | 278 | case ecryptfs_opt_debug: |
@@ -358,55 +359,21 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
358 | if (!cipher_key_bytes_set) { | 359 | if (!cipher_key_bytes_set) { |
359 | mount_crypt_stat->global_default_cipher_key_size = 0; | 360 | mount_crypt_stat->global_default_cipher_key_size = 0; |
360 | } | 361 | } |
361 | rc = ecryptfs_process_cipher( | 362 | if ((rc = ecryptfs_add_new_key_tfm( |
362 | &mount_crypt_stat->global_key_tfm, | 363 | NULL, mount_crypt_stat->global_default_cipher_name, |
363 | mount_crypt_stat->global_default_cipher_name, | 364 | mount_crypt_stat->global_default_cipher_key_size))) { |
364 | &mount_crypt_stat->global_default_cipher_key_size); | 365 | printk(KERN_ERR "Error attempting to initialize cipher with " |
365 | if (rc) { | 366 | "name = [%s] and key size = [%d]; rc = [%d]\n", |
366 | printk(KERN_ERR "Error attempting to initialize cipher [%s] " | ||
367 | "with key size [%Zd] bytes; rc = [%d]\n", | ||
368 | mount_crypt_stat->global_default_cipher_name, | 367 | mount_crypt_stat->global_default_cipher_name, |
369 | mount_crypt_stat->global_default_cipher_key_size, rc); | 368 | mount_crypt_stat->global_default_cipher_key_size, rc); |
370 | mount_crypt_stat->global_key_tfm = NULL; | ||
371 | mount_crypt_stat->global_auth_tok_key = NULL; | ||
372 | rc = -EINVAL; | ||
373 | goto out; | ||
374 | } | ||
375 | mutex_init(&mount_crypt_stat->global_key_tfm_mutex); | ||
376 | ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: " | ||
377 | "[%s]\n", mount_crypt_stat->global_auth_tok_sig); | ||
378 | /* The reference to this key is held until umount is done The | ||
379 | * call to key_put is done in ecryptfs_put_super() */ | ||
380 | auth_tok_key = request_key(&key_type_user, | ||
381 | mount_crypt_stat->global_auth_tok_sig, | ||
382 | NULL); | ||
383 | if (!auth_tok_key || IS_ERR(auth_tok_key)) { | ||
384 | ecryptfs_printk(KERN_ERR, "Could not find key with " | ||
385 | "description: [%s]\n", | ||
386 | mount_crypt_stat->global_auth_tok_sig); | ||
387 | process_request_key_err(PTR_ERR(auth_tok_key)); | ||
388 | rc = -EINVAL; | 369 | rc = -EINVAL; |
389 | goto out; | 370 | goto out; |
390 | } | 371 | } |
391 | auth_tok = ecryptfs_get_key_payload_data(auth_tok_key); | 372 | if ((rc = ecryptfs_init_global_auth_toks(mount_crypt_stat))) { |
392 | if (ecryptfs_verify_version(auth_tok->version)) { | 373 | printk(KERN_WARNING "One or more global auth toks could not " |
393 | ecryptfs_printk(KERN_ERR, "Data structure version mismatch. " | 374 | "properly register; rc = [%d]\n", rc); |
394 | "Userspace tools must match eCryptfs kernel " | ||
395 | "module with major version [%d] and minor " | ||
396 | "version [%d]\n", ECRYPTFS_VERSION_MAJOR, | ||
397 | ECRYPTFS_VERSION_MINOR); | ||
398 | rc = -EINVAL; | ||
399 | goto out; | ||
400 | } | ||
401 | if (auth_tok->token_type != ECRYPTFS_PASSWORD | ||
402 | && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) { | ||
403 | ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure " | ||
404 | "returned from key query\n"); | ||
405 | rc = -EINVAL; | ||
406 | goto out; | ||
407 | } | 375 | } |
408 | mount_crypt_stat->global_auth_tok_key = auth_tok_key; | 376 | rc = 0; |
409 | mount_crypt_stat->global_auth_tok = auth_tok; | ||
410 | out: | 377 | out: |
411 | return rc; | 378 | return rc; |
412 | } | 379 | } |