aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/crypto.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:27:53 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:10 -0400
commitf4aad16adfb8f0a2d666fdf8af4bd0dff2ce75e4 (patch)
tree42e7f191d1a3a1e1375af24acc5c336b30c5c4d1 /fs/ecryptfs/crypto.c
parentcce76f9b9696a59974be9ed43478c000c57e597a (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/crypto.c')
-rw-r--r--fs/ecryptfs/crypto.c208
1 files changed, 174 insertions, 34 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
204ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 204ecryptfs_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 */
219void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 221void 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
228void ecryptfs_destruct_mount_crypt_stat( 239void 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
957static 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);
977out:
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 */
974int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) 1021int 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);
1060out:
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 */
1788int 1833int
1789ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, 1834ecryptfs_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,
1829out: 1874out:
1830 return rc; 1875 return rc;
1831} 1876}
1877
1878struct kmem_cache *ecryptfs_key_tfm_cache;
1879struct list_head key_tfm_list;
1880struct mutex key_tfm_list_mutex;
1881
1882int ecryptfs_init_crypto(void)
1883{
1884 mutex_init(&key_tfm_list_mutex);
1885 INIT_LIST_HEAD(&key_tfm_list);
1886 return 0;
1887}
1888
1889int 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
1905int
1906ecryptfs_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);
1939out:
1940 return rc;
1941}
1942
1943int 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;
1969out:
1970 return rc;
1971}