diff options
Diffstat (limited to 'fs')
-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 | } |