V4L/DVB (9642): Add AC97 registers found on em28xx devices
[safe/jmp/linux-2.6] / fs / ecryptfs / crypto.c
index 942edfa..6046239 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/crypto.h>
 #include <linux/file.h>
 #include <linux/scatterlist.h>
+#include <asm/unaligned.h>
 #include "ecryptfs_kernel.h"
 
 static int
@@ -119,21 +120,21 @@ static int ecryptfs_calculate_md5(char *dst,
        if (rc) {
                printk(KERN_ERR
                       "%s: Error initializing crypto hash; rc = [%d]\n",
-                      __FUNCTION__, rc);
+                      __func__, rc);
                goto out;
        }
        rc = crypto_hash_update(&desc, &sg, len);
        if (rc) {
                printk(KERN_ERR
                       "%s: Error updating crypto hash; rc = [%d]\n",
-                      __FUNCTION__, rc);
+                      __func__, rc);
                goto out;
        }
        rc = crypto_hash_final(&desc, dst);
        if (rc) {
                printk(KERN_ERR
                       "%s: Error finalizing crypto hash; rc = [%d]\n",
-                      __FUNCTION__, rc);
+                      __func__, rc);
                goto out;
        }
 out:
@@ -437,7 +438,7 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
        if (rc < 0) {
                printk(KERN_ERR "%s: Error attempting to encrypt page with "
                       "page->index = [%ld], extent_offset = [%ld]; "
-                      "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
+                      "rc = [%d]\n", __func__, page->index, extent_offset,
                       rc);
                goto out;
        }
@@ -474,8 +475,8 @@ int ecryptfs_encrypt_page(struct page *page)
 {
        struct inode *ecryptfs_inode;
        struct ecryptfs_crypt_stat *crypt_stat;
-       char *enc_extent_virt = NULL;
-       struct page *enc_extent_page;
+       char *enc_extent_virt;
+       struct page *enc_extent_page = NULL;
        loff_t extent_offset;
        int rc = 0;
 
@@ -487,18 +488,18 @@ int ecryptfs_encrypt_page(struct page *page)
                                                       0, PAGE_CACHE_SIZE);
                if (rc)
                        printk(KERN_ERR "%s: Error attempting to copy "
-                              "page at index [%ld]\n", __FUNCTION__,
+                              "page at index [%ld]\n", __func__,
                               page->index);
                goto out;
        }
-       enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
-       if (!enc_extent_virt) {
+       enc_extent_page = alloc_page(GFP_USER);
+       if (!enc_extent_page) {
                rc = -ENOMEM;
                ecryptfs_printk(KERN_ERR, "Error allocating memory for "
                                "encrypted extent\n");
                goto out;
        }
-       enc_extent_page = virt_to_page(enc_extent_virt);
+       enc_extent_virt = kmap(enc_extent_page);
        for (extent_offset = 0;
             extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
             extent_offset++) {
@@ -508,7 +509,7 @@ int ecryptfs_encrypt_page(struct page *page)
                                             extent_offset);
                if (rc) {
                        printk(KERN_ERR "%s: Error encrypting extent; "
-                              "rc = [%d]\n", __FUNCTION__, rc);
+                              "rc = [%d]\n", __func__, rc);
                        goto out;
                }
                ecryptfs_lower_offset_for_extent(
@@ -526,7 +527,10 @@ int ecryptfs_encrypt_page(struct page *page)
                }
        }
 out:
-       kfree(enc_extent_virt);
+       if (enc_extent_page) {
+               kunmap(enc_extent_page);
+               __free_page(enc_extent_page);
+       }
        return rc;
 }
 
@@ -569,7 +573,7 @@ static int ecryptfs_decrypt_extent(struct page *page,
        if (rc < 0) {
                printk(KERN_ERR "%s: Error attempting to decrypt to page with "
                       "page->index = [%ld], extent_offset = [%ld]; "
-                      "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
+                      "rc = [%d]\n", __func__, page->index, extent_offset,
                       rc);
                goto out;
        }
@@ -608,8 +612,8 @@ int ecryptfs_decrypt_page(struct page *page)
 {
        struct inode *ecryptfs_inode;
        struct ecryptfs_crypt_stat *crypt_stat;
-       char *enc_extent_virt = NULL;
-       struct page *enc_extent_page;
+       char *enc_extent_virt;
+       struct page *enc_extent_page = NULL;
        unsigned long extent_offset;
        int rc = 0;
 
@@ -622,18 +626,18 @@ int ecryptfs_decrypt_page(struct page *page)
                                                      ecryptfs_inode);
                if (rc)
                        printk(KERN_ERR "%s: Error attempting to copy "
-                              "page at index [%ld]\n", __FUNCTION__,
+                              "page at index [%ld]\n", __func__,
                               page->index);
                goto out;
        }
-       enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
-       if (!enc_extent_virt) {
+       enc_extent_page = alloc_page(GFP_USER);
+       if (!enc_extent_page) {
                rc = -ENOMEM;
                ecryptfs_printk(KERN_ERR, "Error allocating memory for "
                                "encrypted extent\n");
                goto out;
        }
-       enc_extent_page = virt_to_page(enc_extent_virt);
+       enc_extent_virt = kmap(enc_extent_page);
        for (extent_offset = 0;
             extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
             extent_offset++) {
@@ -656,12 +660,15 @@ int ecryptfs_decrypt_page(struct page *page)
                                             extent_offset);
                if (rc) {
                        printk(KERN_ERR "%s: Error encrypting extent; "
-                              "rc = [%d]\n", __FUNCTION__, rc);
+                              "rc = [%d]\n", __func__, rc);
                        goto out;
                }
        }
 out:
-       kfree(enc_extent_virt);
+       if (enc_extent_page) {
+               kunmap(enc_extent_page);
+               __free_page(enc_extent_page);
+       }
        return rc;
 }
 
@@ -1032,10 +1039,8 @@ static int contains_ecryptfs_marker(char *data)
 {
        u32 m_1, m_2;
 
-       memcpy(&m_1, data, 4);
-       m_1 = be32_to_cpu(m_1);
-       memcpy(&m_2, (data + 4), 4);
-       m_2 = be32_to_cpu(m_2);
+       m_1 = get_unaligned_be32(data);
+       m_2 = get_unaligned_be32(data + 4);
        if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
                return 1;
        ecryptfs_printk(KERN_DEBUG, "m_1 = [0x%.8x]; m_2 = [0x%.8x]; "
@@ -1073,8 +1078,7 @@ static int ecryptfs_process_flags(struct ecryptfs_crypt_stat *crypt_stat,
        int i;
        u32 flags;
 
-       memcpy(&flags, page_virt, 4);
-       flags = be32_to_cpu(flags);
+       flags = get_unaligned_be32(page_virt);
        for (i = 0; i < ((sizeof(ecryptfs_flag_map)
                          / sizeof(struct ecryptfs_flag_map_elem))); i++)
                if (flags & ecryptfs_flag_map[i].file_flag) {
@@ -1100,11 +1104,9 @@ static void write_ecryptfs_marker(char *page_virt, size_t *written)
 
        get_random_bytes(&m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
        m_2 = (m_1 ^ MAGIC_ECRYPTFS_MARKER);
-       m_1 = cpu_to_be32(m_1);
-       memcpy(page_virt, &m_1, (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
-       m_2 = cpu_to_be32(m_2);
-       memcpy(page_virt + (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2), &m_2,
-              (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2));
+       put_unaligned_be32(m_1, page_virt);
+       page_virt += (MAGIC_ECRYPTFS_MARKER_SIZE_BYTES / 2);
+       put_unaligned_be32(m_2, page_virt);
        (*written) = MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
 }
 
@@ -1121,14 +1123,13 @@ write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat,
                        flags |= ecryptfs_flag_map[i].file_flag;
        /* Version is in top 8 bits of the 32-bit flag vector */
        flags |= ((((u8)crypt_stat->file_version) << 24) & 0xFF000000);
-       flags = cpu_to_be32(flags);
-       memcpy(page_virt, &flags, 4);
+       put_unaligned_be32(flags, page_virt);
        (*written) = 4;
 }
 
 struct ecryptfs_cipher_code_str_map_elem {
        char cipher_str[16];
-       u16 cipher_code;
+       u8 cipher_code;
 };
 
 /* Add support for additional ciphers by adding elements here. The
@@ -1152,10 +1153,10 @@ ecryptfs_cipher_code_str_map[] = {
  *
  * Returns zero on no match, or the cipher code on match
  */
-u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
+u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
 {
        int i;
-       u16 code = 0;
+       u8 code = 0;
        struct ecryptfs_cipher_code_str_map_elem *map =
                ecryptfs_cipher_code_str_map;
 
@@ -1187,7 +1188,7 @@ u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat)
  *
  * Returns zero on success
  */
-int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
+int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code)
 {
        int rc = 0;
        int i;
@@ -1215,7 +1216,7 @@ int ecryptfs_read_and_validate_header_region(char *data,
                                 ecryptfs_inode);
        if (rc) {
                printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
-                      __FUNCTION__, rc);
+                      __func__, rc);
                goto out;
        }
        if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
@@ -1238,21 +1239,19 @@ ecryptfs_write_header_metadata(char *virt,
        num_header_extents_at_front =
                (u16)(crypt_stat->num_header_bytes_at_front
                      / crypt_stat->extent_size);
-       header_extent_size = cpu_to_be32(header_extent_size);
-       memcpy(virt, &header_extent_size, 4);
+       put_unaligned_be32(header_extent_size, virt);
        virt += 4;
-       num_header_extents_at_front = cpu_to_be16(num_header_extents_at_front);
-       memcpy(virt, &num_header_extents_at_front, 2);
+       put_unaligned_be16(num_header_extents_at_front, virt);
        (*written) = 6;
 }
 
-struct kmem_cache *ecryptfs_header_cache_0;
 struct kmem_cache *ecryptfs_header_cache_1;
 struct kmem_cache *ecryptfs_header_cache_2;
 
 /**
  * ecryptfs_write_headers_virt
  * @page_virt: The virtual address to write the headers to
+ * @max: The size of memory allocated at page_virt
  * @size: Set to the number of bytes written by this function
  * @crypt_stat: The cryptographic context
  * @ecryptfs_dentry: The eCryptfs dentry
@@ -1280,7 +1279,8 @@ struct kmem_cache *ecryptfs_header_cache_2;
  *
  * Returns zero on success
  */
-static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
+static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
+                                      size_t *size,
                                       struct ecryptfs_crypt_stat *crypt_stat,
                                       struct dentry *ecryptfs_dentry)
 {
@@ -1298,7 +1298,7 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
        offset += written;
        rc = ecryptfs_generate_key_packet_set((page_virt + offset), crypt_stat,
                                              ecryptfs_dentry, &written,
-                                             PAGE_CACHE_SIZE - offset);
+                                             max - offset);
        if (rc)
                ecryptfs_printk(KERN_WARNING, "Error generating key packet "
                                "set; rc = [%d]\n", rc);
@@ -1320,7 +1320,7 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
                                  0, crypt_stat->num_header_bytes_at_front);
        if (rc)
                printk(KERN_ERR "%s: Error attempting to write header "
-                      "information to lower file; rc = [%d]\n", __FUNCTION__,
+                      "information to lower file; rc = [%d]\n", __func__,
                       rc);
        return rc;
 }
@@ -1365,22 +1365,22 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                }
        } else {
                printk(KERN_WARNING "%s: Encrypted flag not set\n",
-                      __FUNCTION__);
+                      __func__);
                rc = -EINVAL;
                goto out;
        }
        /* Released in this function */
-       virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL);
+       virt = (char *)get_zeroed_page(GFP_KERNEL);
        if (!virt) {
-               printk(KERN_ERR "%s: Out of memory\n", __FUNCTION__);
+               printk(KERN_ERR "%s: Out of memory\n", __func__);
                rc = -ENOMEM;
                goto out;
        }
-       rc = ecryptfs_write_headers_virt(virt, &size, crypt_stat,
-                                        ecryptfs_dentry);
+       rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size,
+                                        crypt_stat, ecryptfs_dentry);
        if (unlikely(rc)) {
                printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n",
-                      __FUNCTION__, rc);
+                      __func__, rc);
                goto out_free;
        }
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
@@ -1391,12 +1391,11 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                                                         ecryptfs_dentry, virt);
        if (rc) {
                printk(KERN_ERR "%s: Error writing metadata out to lower file; "
-                      "rc = [%d]\n", __FUNCTION__, rc);
+                      "rc = [%d]\n", __func__, rc);
                goto out_free;
        }
 out_free:
-       memset(virt, 0, crypt_stat->num_header_bytes_at_front);
-       kfree(virt);
+       free_page((unsigned long)virt);
 out:
        return rc;
 }
@@ -1411,15 +1410,13 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
        u32 header_extent_size;
        u16 num_header_extents_at_front;
 
-       memcpy(&header_extent_size, virt, sizeof(u32));
-       header_extent_size = be32_to_cpu(header_extent_size);
-       virt += sizeof(u32);
-       memcpy(&num_header_extents_at_front, virt, sizeof(u16));
-       num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
+       header_extent_size = get_unaligned_be32(virt);
+       virt += sizeof(__be32);
+       num_header_extents_at_front = get_unaligned_be16(virt);
        crypt_stat->num_header_bytes_at_front =
                (((size_t)num_header_extents_at_front
                  * (size_t)header_extent_size));
-       (*bytes_read) = (sizeof(u32) + sizeof(u16));
+       (*bytes_read) = (sizeof(__be32) + sizeof(__be16));
        if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
            && (crypt_stat->num_header_bytes_at_front
                < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
@@ -1585,7 +1582,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
        if (!page_virt) {
                rc = -ENOMEM;
                printk(KERN_ERR "%s: Unable to allocate page_virt\n",
-                      __FUNCTION__);
+                      __func__);
                goto out;
        }
        rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size,
@@ -1779,7 +1776,7 @@ out:
 
 struct kmem_cache *ecryptfs_key_tfm_cache;
 static struct list_head key_tfm_list;
-static struct mutex key_tfm_list_mutex;
+struct mutex key_tfm_list_mutex;
 
 int ecryptfs_init_crypto(void)
 {
@@ -1788,6 +1785,11 @@ int ecryptfs_init_crypto(void)
        return 0;
 }
 
+/**
+ * ecryptfs_destroy_crypto - free all cached key_tfms on key_tfm_list
+ *
+ * Called only at module unload time
+ */
 int ecryptfs_destroy_crypto(void)
 {
        struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp;
@@ -1811,6 +1813,8 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
        struct ecryptfs_key_tfm *tmp_tfm;
        int rc = 0;
 
+       BUG_ON(!mutex_is_locked(&key_tfm_list_mutex));
+
        tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL);
        if (key_tfm != NULL)
                (*key_tfm) = tmp_tfm;
@@ -1837,13 +1841,50 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
                        (*key_tfm) = NULL;
                goto out;
        }
-       mutex_lock(&key_tfm_list_mutex);
        list_add(&tmp_tfm->key_tfm_list, &key_tfm_list);
-       mutex_unlock(&key_tfm_list_mutex);
 out:
        return rc;
 }
 
+/**
+ * ecryptfs_tfm_exists - Search for existing tfm for cipher_name.
+ * @cipher_name: the name of the cipher to search for
+ * @key_tfm: set to corresponding tfm if found
+ *
+ * Searches for cached key_tfm matching @cipher_name
+ * Must be called with &key_tfm_list_mutex held
+ * Returns 1 if found, with @key_tfm set
+ * Returns 0 if not found, with @key_tfm set to NULL
+ */
+int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm)
+{
+       struct ecryptfs_key_tfm *tmp_key_tfm;
+
+       BUG_ON(!mutex_is_locked(&key_tfm_list_mutex));
+
+       list_for_each_entry(tmp_key_tfm, &key_tfm_list, key_tfm_list) {
+               if (strcmp(tmp_key_tfm->cipher_name, cipher_name) == 0) {
+                       if (key_tfm)
+                               (*key_tfm) = tmp_key_tfm;
+                       return 1;
+               }
+       }
+       if (key_tfm)
+               (*key_tfm) = NULL;
+       return 0;
+}
+
+/**
+ * ecryptfs_get_tfm_and_mutex_for_cipher_name
+ *
+ * @tfm: set to cached tfm found, or new tfm created
+ * @tfm_mutex: set to mutex for cached tfm found, or new tfm created
+ * @cipher_name: the name of the cipher to search for and/or add
+ *
+ * Sets pointers to @tfm & @tfm_mutex matching @cipher_name.
+ * Searches for cached item first, and creates new if not found.
+ * Returns 0 on success, non-zero if adding new cipher failed
+ */
 int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
                                               struct mutex **tfm_mutex,
                                               char *cipher_name)
@@ -1853,24 +1894,19 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
 
        (*tfm) = NULL;
        (*tfm_mutex) = NULL;
+
        mutex_lock(&key_tfm_list_mutex);
-       list_for_each_entry(key_tfm, &key_tfm_list, key_tfm_list) {
-               if (strcmp(key_tfm->cipher_name, cipher_name) == 0) {
-                       (*tfm) = key_tfm->key_tfm;
-                       (*tfm_mutex) = &key_tfm->key_tfm_mutex;
-                       mutex_unlock(&key_tfm_list_mutex);
+       if (!ecryptfs_tfm_exists(cipher_name, &key_tfm)) {
+               rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0);
+               if (rc) {
+                       printk(KERN_ERR "Error adding new key_tfm to list; "
+                                       "rc = [%d]\n", rc);
                        goto out;
                }
        }
-       mutex_unlock(&key_tfm_list_mutex);
-       rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0);
-       if (rc) {
-               printk(KERN_ERR "Error adding new key_tfm to list; rc = [%d]\n",
-                      rc);
-               goto out;
-       }
        (*tfm) = key_tfm->key_tfm;
        (*tfm_mutex) = &key_tfm->key_tfm_mutex;
 out:
+       mutex_unlock(&key_tfm_list_mutex);
        return rc;
 }