diff options
| author | 2012-02-28 12:42:14 +0000 | |
|---|---|---|
| committer | 2012-02-28 12:42:21 +0000 | |
| commit | fb0b82b32ce17564bc64cede50bf4a3204eecc60 (patch) | |
| tree | 00b5e466074c6fb373d64c493b3341186024acc7 /fs/ecryptfs/crypto.c | |
| parent | Merge branch 'kirkwood/board' into next/boards (diff) | |
| parent | ARM: pxa: add dummy clock for pxa25x and pxa27x (diff) | |
| download | wireguard-linux-fb0b82b32ce17564bc64cede50bf4a3204eecc60.tar.xz wireguard-linux-fb0b82b32ce17564bc64cede50bf4a3204eecc60.zip | |
Merge branch 'board-specific' of git://github.com/hzhuang1/linux into next/boards
* 'board-specific' of git://github.com/hzhuang1/linux: (5 commits)
  ARM: pxa: add dummy clock for pxa25x and pxa27x
  ARM: mmp: append irq name of gpio device
  pxa/hx4700: Fix PXA_GPIO_IRQ_BASE/IRQ_NUM values
  pxa/hx4700: Add ASIC3 LED support
  pxa/hx4700: Correct StrataFlash block size discovery
(update to v3.3-rc5)
Diffstat (limited to 'fs/ecryptfs/crypto.c')
| -rw-r--r-- | fs/ecryptfs/crypto.c | 68 | 
1 files changed, 61 insertions, 7 deletions
| diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 63ab24510649..ea9931281557 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -1990,6 +1990,17 @@ out:  	return;  } +static size_t ecryptfs_max_decoded_size(size_t encoded_size) +{ +	/* Not exact; conservatively long. Every block of 4 +	 * encoded characters decodes into a block of 3 +	 * decoded characters. This segment of code provides +	 * the caller with the maximum amount of allocated +	 * space that @dst will need to point to in a +	 * subsequent call. */ +	return ((encoded_size + 1) * 3) / 4; +} +  /**   * ecryptfs_decode_from_filename   * @dst: If NULL, this function only sets @dst_size and returns. If @@ -2008,13 +2019,7 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size,  	size_t dst_byte_offset = 0;  	if (dst == NULL) { -		/* Not exact; conservatively long. Every block of 4 -		 * encoded characters decodes into a block of 3 -		 * decoded characters. This segment of code provides -		 * the caller with the maximum amount of allocated -		 * space that @dst will need to point to in a -		 * subsequent call. */ -		(*dst_size) = (((src_size + 1) * 3) / 4); +		(*dst_size) = ecryptfs_max_decoded_size(src_size);  		goto out;  	}  	while (src_byte_offset < src_size) { @@ -2239,3 +2244,52 @@ out_free:  out:  	return rc;  } + +#define ENC_NAME_MAX_BLOCKLEN_8_OR_16	143 + +int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, +			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat) +{ +	struct blkcipher_desc desc; +	struct mutex *tfm_mutex; +	size_t cipher_blocksize; +	int rc; + +	if (!(mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { +		(*namelen) = lower_namelen; +		return 0; +	} + +	rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex, +			mount_crypt_stat->global_default_fn_cipher_name); +	if (unlikely(rc)) { +		(*namelen) = 0; +		return rc; +	} + +	mutex_lock(tfm_mutex); +	cipher_blocksize = crypto_blkcipher_blocksize(desc.tfm); +	mutex_unlock(tfm_mutex); + +	/* Return an exact amount for the common cases */ +	if (lower_namelen == NAME_MAX +	    && (cipher_blocksize == 8 || cipher_blocksize == 16)) { +		(*namelen) = ENC_NAME_MAX_BLOCKLEN_8_OR_16; +		return 0; +	} + +	/* Return a safe estimate for the uncommon cases */ +	(*namelen) = lower_namelen; +	(*namelen) -= ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE; +	/* Since this is the max decoded size, subtract 1 "decoded block" len */ +	(*namelen) = ecryptfs_max_decoded_size(*namelen) - 3; +	(*namelen) -= ECRYPTFS_TAG_70_MAX_METADATA_SIZE; +	(*namelen) -= ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES; +	/* Worst case is that the filename is padded nearly a full block size */ +	(*namelen) -= cipher_blocksize - 1; + +	if ((*namelen) < 0) +		(*namelen) = 0; + +	return 0; +} | 
