1975 lines · 57.7 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * eCryptfs: Linux filesystem encryption layer * * Copyright (C) 1997-2004 Erez Zadok * Copyright (C) 2001-2004 Stony Brook University * Copyright (C) 2004-2007 International Business Machines Corp. *   Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> *   		Michael C. Thompson <mcthomps@us.ibm.com> */ #include <crypto/skcipher.h>#include <linux/fs.h>#include <linux/mount.h>#include <linux/pagemap.h>#include <linux/random.h>#include <linux/compiler.h>#include <linux/key.h>#include <linux/namei.h>#include <linux/file.h>#include <linux/scatterlist.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/unaligned.h>#include <linux/kernel.h>#include <linux/xattr.h>#include "ecryptfs_kernel.h" #define DECRYPT		0#define ENCRYPT		1 /** * ecryptfs_from_hex * @dst: Buffer to take the bytes from src hex; must be at least of *       size (src_size / 2) * @src: Buffer to be converted from a hex string representation to raw value * @dst_size: size of dst buffer, or number of hex characters pairs to convert */void ecryptfs_from_hex(char *dst, char *src, int dst_size){	int x;	char tmp[3] = { 0, }; 	for (x = 0; x < dst_size; x++) {		tmp[0] = src[x * 2];		tmp[1] = src[x * 2 + 1];		dst[x] = (unsigned char)simple_strtol(tmp, NULL, 16);	}} static int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,						  const char *cipher_name,						  const char *chaining_modifier){	(*algified_name) = kasprintf(GFP_KERNEL, "%s(%s)", chaining_modifier,				     cipher_name);	if (!(*algified_name))		return -ENOMEM; 	return 0;} /** * ecryptfs_derive_iv * @iv: destination for the derived iv value * @crypt_stat: Pointer to crypt_stat struct for the current inode * @offset: Offset of the extent whose IV we are to derive * * Generate the initialization vector from the given root IV and page * offset. */void ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,			loff_t offset){	char dst[MD5_DIGEST_SIZE];	char src[ECRYPTFS_MAX_IV_BYTES + 16]; 	if (unlikely(ecryptfs_verbosity > 0)) {		ecryptfs_printk(KERN_DEBUG, "root iv:\n");		ecryptfs_dump_hex(crypt_stat->root_iv, crypt_stat->iv_bytes);	}	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, "%lld", offset);	if (unlikely(ecryptfs_verbosity > 0)) {		ecryptfs_printk(KERN_DEBUG, "source:\n");		ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));	}	md5(src, crypt_stat->iv_bytes + 16, dst);	memcpy(iv, dst, crypt_stat->iv_bytes);	if (unlikely(ecryptfs_verbosity > 0)) {		ecryptfs_printk(KERN_DEBUG, "derived iv:\n");		ecryptfs_dump_hex(iv, crypt_stat->iv_bytes);	}} /** * ecryptfs_init_crypt_stat * @crypt_stat: Pointer to the crypt_stat struct to initialize. * * Initialize the crypt_stat structure. */void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat){	memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));	INIT_LIST_HEAD(&crypt_stat->keysig_list);	mutex_init(&crypt_stat->keysig_list_mutex);	mutex_init(&crypt_stat->cs_mutex);	mutex_init(&crypt_stat->cs_tfm_mutex);	crypt_stat->flags |= ECRYPTFS_STRUCT_INITIALIZED;} /** * ecryptfs_destroy_crypt_stat * @crypt_stat: Pointer to the crypt_stat struct to initialize. * * Releases all memory associated with a crypt_stat struct. */void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat){	struct ecryptfs_key_sig *key_sig, *key_sig_tmp; 	crypto_free_skcipher(crypt_stat->tfm);	list_for_each_entry_safe(key_sig, key_sig_tmp,				 &crypt_stat->keysig_list, crypt_stat_list) {		list_del(&key_sig->crypt_stat_list);		kmem_cache_free(ecryptfs_key_sig_cache, key_sig);	}	memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));} void ecryptfs_destroy_mount_crypt_stat(	struct ecryptfs_mount_crypt_stat *mount_crypt_stat){	struct ecryptfs_global_auth_tok *auth_tok, *auth_tok_tmp; 	if (!(mount_crypt_stat->flags & ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED))		return;	mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);	list_for_each_entry_safe(auth_tok, auth_tok_tmp,				 &mount_crypt_stat->global_auth_tok_list,				 mount_crypt_stat_list) {		list_del(&auth_tok->mount_crypt_stat_list);		if (!(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))			key_put(auth_tok->global_auth_tok_key);		kmem_cache_free(ecryptfs_global_auth_tok_cache, auth_tok);	}	mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);	memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));} /** * virt_to_scatterlist * @addr: Virtual address * @size: Size of data; should be an even multiple of the block size * @sg: Pointer to scatterlist array; set to NULL to obtain only *      the number of scatterlist structs required in array * @sg_size: Max array size * * Fills in a scatterlist array with page references for a passed * virtual address. * * Returns the number of scatterlist structs in array used */int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,			int sg_size){	int i = 0;	struct page *pg;	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);		sg_set_page(&sg[i], pg, 0, offset);		remainder_of_page = PAGE_SIZE - offset;		if (size >= remainder_of_page) {			sg[i].length = remainder_of_page;			addr += remainder_of_page;			size -= remainder_of_page;		} else {			sg[i].length = size;			addr += size;			size = 0;		}		i++;	}	if (size > 0)		return -ENOMEM;	return i;} /** * crypt_scatterlist * @crypt_stat: Pointer to the crypt_stat struct to initialize. * @dst_sg: Destination of the data after performing the crypto operation * @src_sg: Data to be encrypted or decrypted * @size: Length of data * @iv: IV to use * @op: ENCRYPT or DECRYPT to indicate the desired operation * * Returns the number of bytes encrypted or decrypted; negative value on error */static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat,			     struct scatterlist *dst_sg,			     struct scatterlist *src_sg, int size,			     unsigned char *iv, int op){	struct skcipher_request *req = NULL;	DECLARE_CRYPTO_WAIT(ecr);	int rc = 0; 	if (unlikely(ecryptfs_verbosity > 0)) {		ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n",				crypt_stat->key_size);		ecryptfs_dump_hex(crypt_stat->key,				  crypt_stat->key_size);	} 	mutex_lock(&crypt_stat->cs_tfm_mutex);	req = skcipher_request_alloc(crypt_stat->tfm, GFP_NOFS);	if (!req) {		mutex_unlock(&crypt_stat->cs_tfm_mutex);		rc = -ENOMEM;		goto out;	} 	skcipher_request_set_callback(req,			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,			crypto_req_done, &ecr);	/* Consider doing this once, when the file is opened */	if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) {		rc = crypto_skcipher_setkey(crypt_stat->tfm, crypt_stat->key,					    crypt_stat->key_size);		if (rc) {			ecryptfs_printk(KERN_ERR,					"Error setting key; rc = [%d]\n",					rc);			mutex_unlock(&crypt_stat->cs_tfm_mutex);			rc = -EINVAL;			goto out;		}		crypt_stat->flags |= ECRYPTFS_KEY_SET;	}	mutex_unlock(&crypt_stat->cs_tfm_mutex);	skcipher_request_set_crypt(req, src_sg, dst_sg, size, iv);	rc = op == ENCRYPT ? crypto_skcipher_encrypt(req) :			     crypto_skcipher_decrypt(req);	rc = crypto_wait_req(rc, &ecr);out:	skcipher_request_free(req);	return rc;} /* * lower_offset_for_page * * Convert an eCryptfs page index into a lower byte offset */static loff_t lower_offset_for_page(struct ecryptfs_crypt_stat *crypt_stat,				    struct folio *folio){	return ecryptfs_lower_header_size(crypt_stat) +	       (loff_t)folio->index * PAGE_SIZE;} /** * crypt_extent * @crypt_stat: crypt_stat containing cryptographic context for the *              encryption operation * @dst_page: The page to write the result into * @src_page: The page to read from * @page_index: The offset in the file (in units of PAGE_SIZE) * @extent_offset: Page extent offset for use in generating IV * @op: ENCRYPT or DECRYPT to indicate the desired operation * * Encrypts or decrypts one extent of data. * * Return zero on success; non-zero otherwise */static int crypt_extent(struct ecryptfs_crypt_stat *crypt_stat,			struct page *dst_page,			struct page *src_page,			pgoff_t page_index,			unsigned long extent_offset, int op){	loff_t extent_base;	char extent_iv[ECRYPTFS_MAX_IV_BYTES];	struct scatterlist src_sg, dst_sg;	size_t extent_size = crypt_stat->extent_size;	int rc; 	extent_base = (((loff_t)page_index) * (PAGE_SIZE / extent_size));	ecryptfs_derive_iv(extent_iv, crypt_stat, extent_base + extent_offset); 	sg_init_table(&src_sg, 1);	sg_init_table(&dst_sg, 1); 	sg_set_page(&src_sg, src_page, extent_size,		    extent_offset * extent_size);	sg_set_page(&dst_sg, dst_page, extent_size,		    extent_offset * extent_size); 	rc = crypt_scatterlist(crypt_stat, &dst_sg, &src_sg, extent_size,			       extent_iv, op);	if (rc < 0) {		printk(KERN_ERR "%s: Error attempting to crypt page with "		       "page_index = [%ld], extent_offset = [%ld]; "		       "rc = [%d]\n", __func__, page_index, extent_offset, rc);		goto out;	}	rc = 0;out:	return rc;} /** * ecryptfs_encrypt_page * @folio: Folio mapped from the eCryptfs inode for the file; contains *        decrypted content that needs to be encrypted (to a temporary *        page; not in place) and written out to the lower file * * Encrypt an eCryptfs page. This is done on a per-extent basis. Note * that eCryptfs pages may straddle the lower pages -- for instance, * if the file was created on a machine with an 8K page size * (resulting in an 8K header), and then the file is copied onto a * host with a 32K page size, then when reading page 0 of the eCryptfs * file, 24K of page 0 of the lower file will be read and decrypted, * and then 8K of page 1 of the lower file will be read and decrypted. * * Returns zero on success; negative on error */int ecryptfs_encrypt_page(struct folio *folio){	struct inode *ecryptfs_inode;	struct ecryptfs_crypt_stat *crypt_stat;	char *enc_extent_virt;	struct page *enc_extent_page = NULL;	loff_t extent_offset;	loff_t lower_offset;	int rc = 0; 	ecryptfs_inode = folio->mapping->host;	crypt_stat =		&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);	BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED));	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;	} 	for (extent_offset = 0;	     extent_offset < (PAGE_SIZE / crypt_stat->extent_size);	     extent_offset++) {		rc = crypt_extent(crypt_stat, enc_extent_page,				folio_page(folio, 0), folio->index,				extent_offset, ENCRYPT);		if (rc) {			printk(KERN_ERR "%s: Error encrypting extent; "			       "rc = [%d]\n", __func__, rc);			goto out;		}	} 	lower_offset = lower_offset_for_page(crypt_stat, folio);	enc_extent_virt = kmap_local_page(enc_extent_page);	rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, lower_offset,				  PAGE_SIZE);	kunmap_local(enc_extent_virt);	if (rc < 0) {		ecryptfs_printk(KERN_ERR,			"Error attempting to write lower page; rc = [%d]\n",			rc);		goto out;	}	rc = 0;out:	if (enc_extent_page) {		__free_page(enc_extent_page);	}	return rc;} /** * ecryptfs_decrypt_page * @folio: Folio mapped from the eCryptfs inode for the file; data read *        and decrypted from the lower file will be written into this *        page * * Decrypt an eCryptfs page. This is done on a per-extent basis. Note * that eCryptfs pages may straddle the lower pages -- for instance, * if the file was created on a machine with an 8K page size * (resulting in an 8K header), and then the file is copied onto a * host with a 32K page size, then when reading page 0 of the eCryptfs * file, 24K of page 0 of the lower file will be read and decrypted, * and then 8K of page 1 of the lower file will be read and decrypted. * * Returns zero on success; negative on error */int ecryptfs_decrypt_page(struct folio *folio){	struct inode *ecryptfs_inode;	struct ecryptfs_crypt_stat *crypt_stat;	char *page_virt;	unsigned long extent_offset;	loff_t lower_offset;	int rc = 0; 	ecryptfs_inode = folio->mapping->host;	crypt_stat =		&(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);	BUG_ON(!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)); 	lower_offset = lower_offset_for_page(crypt_stat, folio);	page_virt = kmap_local_folio(folio, 0);	rc = ecryptfs_read_lower(page_virt, lower_offset, PAGE_SIZE,				 ecryptfs_inode);	kunmap_local(page_virt);	if (rc < 0) {		ecryptfs_printk(KERN_ERR,			"Error attempting to read lower page; rc = [%d]\n",			rc);		goto out;	} 	for (extent_offset = 0;	     extent_offset < (PAGE_SIZE / crypt_stat->extent_size);	     extent_offset++) {		struct page *page = folio_page(folio, 0);		rc = crypt_extent(crypt_stat, page, page, folio->index,				extent_offset, DECRYPT);		if (rc) {			printk(KERN_ERR "%s: Error decrypting extent; "			       "rc = [%d]\n", __func__, rc);			goto out;		}	}out:	return rc;} #define ECRYPTFS_MAX_SCATTERLIST_LEN 4 /** * ecryptfs_init_crypt_ctx * @crypt_stat: Uninitialized crypt stats structure * * Initialize the crypto context. * * TODO: Performance: Keep a cache of initialized cipher contexts; * only init if needed */int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat){	char *full_alg_name;	int rc = -EINVAL; 	ecryptfs_printk(KERN_DEBUG,			"Initializing cipher [%s]; strlen = [%d]; "			"key_size_bits = [%zd]\n",			crypt_stat->cipher, (int)strlen(crypt_stat->cipher),			crypt_stat->key_size << 3);	mutex_lock(&crypt_stat->cs_tfm_mutex);	if (crypt_stat->tfm) {		rc = 0;		goto out_unlock;	}	rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,						    crypt_stat->cipher, "cbc");	if (rc)		goto out_unlock;	crypt_stat->tfm = crypto_alloc_skcipher(full_alg_name, 0, 0);	if (IS_ERR(crypt_stat->tfm)) {		rc = PTR_ERR(crypt_stat->tfm);		crypt_stat->tfm = NULL;		ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): "				"Error initializing cipher [%s]\n",				full_alg_name);		goto out_free;	}	crypto_skcipher_set_flags(crypt_stat->tfm,				  CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);	rc = 0;out_free:	kfree(full_alg_name);out_unlock:	mutex_unlock(&crypt_stat->cs_tfm_mutex);	return rc;} static void set_extent_mask_and_shift(struct ecryptfs_crypt_stat *crypt_stat){	int extent_size_tmp; 

Lines 1–500 of 1975.