]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/ecryptfs/crypto.c
kobject: convert ecryptfs to use kobject_create
[mv-sheeva.git] / fs / ecryptfs / crypto.c
index 55110ffe9ebd5a724efdcf3760a5614f26dcb88f..f8ef0af919e70d27acdb9292acbd0d3d95669bd7 100644 (file)
@@ -115,11 +115,29 @@ static int ecryptfs_calculate_md5(char *dst,
                }
                crypt_stat->hash_tfm = desc.tfm;
        }
-       crypto_hash_init(&desc);
-       crypto_hash_update(&desc, &sg, len);
-       crypto_hash_final(&desc, dst);
-       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
+       rc = crypto_hash_init(&desc);
+       if (rc) {
+               printk(KERN_ERR
+                      "%s: Error initializing crypto hash; rc = [%d]\n",
+                      __FUNCTION__, 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);
+               goto out;
+       }
+       rc = crypto_hash_final(&desc, dst);
+       if (rc) {
+               printk(KERN_ERR
+                      "%s: Error finalizing crypto hash; rc = [%d]\n",
+                      __FUNCTION__, rc);
+               goto out;
+       }
 out:
+       mutex_unlock(&crypt_stat->cs_hash_tfm_mutex);
        return rc;
 }
 
@@ -149,7 +167,7 @@ out:
  * ecryptfs_derive_iv
  * @iv: destination for the derived iv vale
  * @crypt_stat: Pointer to crypt_stat struct for the current inode
- * @offset: Offset of the page whose's iv we are to derive
+ * @offset: Offset of the extent whose IV we are to derive
  *
  * Generate the initialization vector from the given root IV and page
  * offset.
@@ -157,7 +175,7 @@ out:
  * Returns zero on success; non-zero on error.
  */
 static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
-                             pgoff_t offset)
+                             loff_t offset)
 {
        int rc = 0;
        char dst[MD5_DIGEST_SIZE];
@@ -173,7 +191,7 @@ static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
         * hashing business. -Halcrow */
        memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes);
        memset((src + crypt_stat->iv_bytes), 0, 16);
-       snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset);
+       snprintf((src + crypt_stat->iv_bytes), 16, "%lld", offset);
        if (unlikely(ecryptfs_verbosity > 0)) {
                ecryptfs_printk(KERN_DEBUG, "source:\n");
                ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));
@@ -279,13 +297,13 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
        int offset;
        int remainder_of_page;
 
+       sg_init_table(sg, sg_size);
+
        while (size > 0 && i < sg_size) {
                pg = virt_to_page(addr);
                offset = offset_in_page(addr);
-               if (sg) {
-                       sg[i].page = pg;
-                       sg[i].offset = offset;
-               }
+               if (sg)
+                       sg_set_page(&sg[i], pg, 0, offset);
                remainder_of_page = PAGE_CACHE_SIZE - offset;
                if (size >= remainder_of_page) {
                        if (sg)
@@ -353,119 +371,6 @@ out:
        return rc;
 }
 
-static void
-ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx,
-                                        int *byte_offset,
-                                        struct ecryptfs_crypt_stat *crypt_stat,
-                                        unsigned long extent_num)
-{
-       unsigned long lower_extent_num;
-       int extents_occupied_by_headers_at_front;
-       int bytes_occupied_by_headers_at_front;
-       int extent_offset;
-       int extents_per_page;
-
-       bytes_occupied_by_headers_at_front =
-               (crypt_stat->extent_size
-                * crypt_stat->num_header_extents_at_front);
-       extents_occupied_by_headers_at_front =
-               ( bytes_occupied_by_headers_at_front
-                 / crypt_stat->extent_size );
-       lower_extent_num = extents_occupied_by_headers_at_front + extent_num;
-       extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
-       (*lower_page_idx) = lower_extent_num / extents_per_page;
-       extent_offset = lower_extent_num % extents_per_page;
-       (*byte_offset) = extent_offset * crypt_stat->extent_size;
-       ecryptfs_printk(KERN_DEBUG, " * crypt_stat->extent_size = "
-                       "[%d]\n", crypt_stat->extent_size);
-       ecryptfs_printk(KERN_DEBUG, " * crypt_stat->"
-                       "num_header_extents_at_front = [%d]\n",
-                       crypt_stat->num_header_extents_at_front);
-       ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_"
-                       "front = [%d]\n", extents_occupied_by_headers_at_front);
-       ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n",
-                       lower_extent_num);
-       ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n",
-                       extents_per_page);
-       ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n",
-                       (*lower_page_idx));
-       ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n",
-                       extent_offset);
-       ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n",
-                       (*byte_offset));
-}
-
-static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx,
-                                  struct page *lower_page,
-                                  struct inode *lower_inode,
-                                  int byte_offset_in_page, int bytes_to_write)
-{
-       int rc = 0;
-
-       if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
-               rc = ecryptfs_commit_lower_page(lower_page, lower_inode,
-                                               ctx->param.lower_file,
-                                               byte_offset_in_page,
-                                               bytes_to_write);
-               if (rc) {
-                       ecryptfs_printk(KERN_ERR, "Error calling lower "
-                                       "commit; rc = [%d]\n", rc);
-                       goto out;
-               }
-       } else {
-               rc = ecryptfs_writepage_and_release_lower_page(lower_page,
-                                                              lower_inode,
-                                                              ctx->param.wbc);
-               if (rc) {
-                       ecryptfs_printk(KERN_ERR, "Error calling lower "
-                                       "writepage(); rc = [%d]\n", rc);
-                       goto out;
-               }
-       }
-out:
-       return rc;
-}
-
-static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx,
-                                struct page **lower_page,
-                                struct inode *lower_inode,
-                                unsigned long lower_page_idx,
-                                int byte_offset_in_page)
-{
-       int rc = 0;
-
-       if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) {
-               /* TODO: Limit this to only the data extents that are
-                * needed */
-               rc = ecryptfs_get_lower_page(lower_page, lower_inode,
-                                            ctx->param.lower_file,
-                                            lower_page_idx,
-                                            byte_offset_in_page,
-                                            (PAGE_CACHE_SIZE
-                                             - byte_offset_in_page));
-               if (rc) {
-                       ecryptfs_printk(
-                               KERN_ERR, "Error attempting to grab, map, "
-                               "and prepare_write lower page with index "
-                               "[0x%.16x]; rc = [%d]\n", lower_page_idx, rc);
-                       goto out;
-               }
-       } else {
-               *lower_page = grab_cache_page(lower_inode->i_mapping,
-                                             lower_page_idx);
-               if (!(*lower_page)) {
-                       rc = -EINVAL;
-                       ecryptfs_printk(
-                               KERN_ERR, "Error attempting to grab and map "
-                               "lower page with index [0x%.16x]; rc = [%d]\n",
-                               lower_page_idx, rc);
-                       goto out;
-               }
-       }
-out:
-       return rc;
-}
-
 /**
  * ecryptfs_lower_offset_for_extent
  *
@@ -497,11 +402,11 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
                                   struct page *page,
                                   unsigned long extent_offset)
 {
-       unsigned long extent_base;
+       loff_t extent_base;
        char extent_iv[ECRYPTFS_MAX_IV_BYTES];
        int rc;
 
-       extent_base = (page->index
+       extent_base = (((loff_t)page->index)
                       * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
        rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
                                (extent_base + extent_offset));
@@ -605,8 +510,9 @@ int ecryptfs_encrypt_page(struct page *page)
                        goto out;
                }
                ecryptfs_lower_offset_for_extent(
-                       &offset, ((page->index * (PAGE_CACHE_SIZE
-                                                 / crypt_stat->extent_size))
+                       &offset, ((((loff_t)page->index)
+                                  * (PAGE_CACHE_SIZE
+                                     / crypt_stat->extent_size))
                                  + extent_offset), crypt_stat);
                rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
                                          offset, crypt_stat->extent_size);
@@ -616,7 +522,6 @@ int ecryptfs_encrypt_page(struct page *page)
                                        "\n", rc);
                        goto out;
                }
-               extent_offset++;
        }
 out:
        kfree(enc_extent_virt);
@@ -628,11 +533,11 @@ static int ecryptfs_decrypt_extent(struct page *page,
                                   struct page *enc_extent_page,
                                   unsigned long extent_offset)
 {
-       unsigned long extent_base;
+       loff_t extent_base;
        char extent_iv[ECRYPTFS_MAX_IV_BYTES];
        int rc;
 
-       extent_base = (page->index
+       extent_base = (((loff_t)page->index)
                       * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
        rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
                                (extent_base + extent_offset));
@@ -717,14 +622,14 @@ int ecryptfs_decrypt_page(struct page *page)
                        printk(KERN_ERR "%s: Error attempting to copy "
                               "page at index [%ld]\n", __FUNCTION__,
                               page->index);
-               goto out_clear_uptodate;
+               goto out;
        }
        enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
        if (!enc_extent_virt) {
                rc = -ENOMEM;
                ecryptfs_printk(KERN_ERR, "Error allocating memory for "
                                "encrypted extent\n");
-               goto out_clear_uptodate;
+               goto out;
        }
        enc_extent_page = virt_to_page(enc_extent_virt);
        for (extent_offset = 0;
@@ -743,21 +648,16 @@ int ecryptfs_decrypt_page(struct page *page)
                        ecryptfs_printk(KERN_ERR, "Error attempting "
                                        "to read lower page; rc = [%d]"
                                        "\n", rc);
-                       goto out_clear_uptodate;
+                       goto out;
                }
                rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page,
                                             extent_offset);
                if (rc) {
                        printk(KERN_ERR "%s: Error encrypting extent; "
                               "rc = [%d]\n", __FUNCTION__, rc);
-                       goto out_clear_uptodate;
+                       goto out;
                }
-               extent_offset++;
        }
-       SetPageUptodate(page);
-       goto out;
-out_clear_uptodate:
-       ClearPageUptodate(page);
 out:
        kfree(enc_extent_virt);
        return rc;
@@ -829,12 +729,11 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
        struct scatterlist src_sg, dst_sg;
 
-       src_sg.page = src_page;
-       src_sg.offset = src_offset;
-       src_sg.length = size;
-       dst_sg.page = dst_page;
-       dst_sg.offset = dst_offset;
-       dst_sg.length = size;
+       sg_init_table(&src_sg, 1);
+       sg_init_table(&dst_sg, 1);
+
+       sg_set_page(&src_sg, src_page, size, src_offset);
+       sg_set_page(&dst_sg, dst_page, size, dst_offset);
        return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
@@ -858,12 +757,12 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
 {
        struct scatterlist src_sg, dst_sg;
 
-       src_sg.page = src_page;
-       src_sg.offset = src_offset;
-       src_sg.length = size;
-       dst_sg.page = dst_page;
-       dst_sg.offset = dst_offset;
-       dst_sg.length = size;
+       sg_init_table(&src_sg, 1);
+       sg_set_page(&src_sg, src_page, size, src_offset);
+
+       sg_init_table(&dst_sg, 1);
+       sg_set_page(&dst_sg, dst_page, size, dst_offset);
+
        return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
@@ -900,7 +799,7 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
        rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
                                                    crypt_stat->cipher, "cbc");
        if (rc)
-               goto out;
+               goto out_unlock;
        crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0,
                                                 CRYPTO_ALG_ASYNC);
        kfree(full_alg_name);
@@ -909,12 +808,12 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat)
                ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "
                                "Error initializing cipher [%s]\n",
                                crypt_stat->cipher);
-               mutex_unlock(&crypt_stat->cs_tfm_mutex);
-               goto out;
+               goto out_unlock;
        }
        crypto_blkcipher_set_flags(crypt_stat->tfm, CRYPTO_TFM_REQ_WEAK_KEY);
-       mutex_unlock(&crypt_stat->cs_tfm_mutex);
        rc = 0;
+out_unlock:
+       mutex_unlock(&crypt_stat->cs_tfm_mutex);
 out:
        return rc;
 }
@@ -1305,43 +1204,6 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
        return rc;
 }
 
-/**
- * ecryptfs_read_header_region
- * @data: The virtual address to write header region data into
- * @dentry: The lower dentry
- * @mnt: The lower VFS mount
- *
- * Returns zero on success; non-zero otherwise
- */
-static int ecryptfs_read_header_region(char *data, struct dentry *dentry,
-                                      struct vfsmount *mnt)
-{
-       struct file *lower_file;
-       mm_segment_t oldfs;
-       int rc;
-
-       rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt, O_RDONLY);
-       if (rc) {
-               printk(KERN_ERR
-                      "Error opening lower_file to read header region\n");
-               goto out;
-       }
-       lower_file->f_pos = 0;
-       oldfs = get_fs();
-       set_fs(get_ds());
-       rc = lower_file->f_op->read(lower_file, (char __user *)data,
-                             ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
-       set_fs(oldfs);
-       rc = ecryptfs_close_lower_file(lower_file);
-       if (rc) {
-               printk(KERN_ERR "Error closing lower_file\n");
-               goto out;
-       }
-       rc = 0;
-out:
-       return rc;
-}
-
 int ecryptfs_read_and_validate_header_region(char *data,
                                             struct inode *ecryptfs_inode)
 {
@@ -1471,7 +1333,7 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
        while (current_header_page < header_pages) {
                loff_t offset;
 
-               offset = (current_header_page << PAGE_CACHE_SHIFT);
+               offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT);
                if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode,
                                               page_virt, offset,
                                               PAGE_CACHE_SIZE))) {
@@ -1575,10 +1437,10 @@ 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, 4);
+       memcpy(&header_extent_size, virt, sizeof(u32));
        header_extent_size = be32_to_cpu(header_extent_size);
-       virt += 4;
-       memcpy(&num_header_extents_at_front, virt, 2);
+       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);
        crypt_stat->num_header_extents_at_front =
                (int)num_header_extents_at_front;
@@ -1673,7 +1535,7 @@ out:
 /**
  * ecryptfs_read_xattr_region
  * @page_virt: The vitual address into which to read the xattr data
- * @ecryptfs_dentry: The eCryptfs dentry
+ * @ecryptfs_inode: The eCryptfs inode
  *
  * Attempts to read the crypto metadata from the extended attribute
  * region of the lower file.
@@ -1985,6 +1847,7 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
        mutex_init(&tmp_tfm->key_tfm_mutex);
        strncpy(tmp_tfm->cipher_name, cipher_name,
                ECRYPTFS_MAX_CIPHER_NAME_SIZE);
+       tmp_tfm->cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0';
        tmp_tfm->key_size = key_size;
        rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm,
                                         tmp_tfm->cipher_name,