Re: [PATCH v3] fscrypt: Add support for AES-128-CBC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[resend without the HTML crap - sorry about that!]

Hi Eric!

Thanks for the thorough review! :)

> On 17 May 2017, at 20:08, Eric Biggers <ebiggers3@xxxxxxxxx> wrote:
> 
> Hi David, thanks for the update!
> 
> On Wed, May 17, 2017 at 01:21:04PM +0200, David Gstir wrote:
>> From: Daniel Walter <dwalter@xxxxxxxxxxxxx>
>> 
>> fscrypt provides facilities to use different encryption algorithms which
>> are selectable by userspace when setting the encryption policy. Currently,
>> only AES-256-XTS for file contents and AES-256-CBC-CTS for file names are
>> implemented. This is a clear case of kernel offers the mechanism and
>> userspace selects a policy. Similar to what dm-crypt and ecryptfs have.
>> 
>> This patch adds support for using AES-128-CBC for file contents and
>> AES-128-CBC-CTS for file name encryption. To mitigate watermarking
>> attacks, IVs are generated using the ESSIV algorithm. While AES-CBC is
>> actually slightly less secure than AES-XTS from a security point of view,
>> there is more widespread hardware support. Especially low-powered embedded
>> devices with crypto accelerators such as CAAM or CESA support only
>> AES-CBC-128 with an acceptable speed. Using AES-CBC gives us the acceptable
>> performance while still providing a moderate level of security for
>> persistent storage.
> 
> You covered this briefly in an email, but can you include more detail in the
> commit message on the reasoning behind choosing AES-128 instead of AES-256?
> Note that this is independent of the decision of CBC vs. XTS.

Sure, I'll extend the commit message to include that.


> 
>> @@ -129,27 +136,37 @@ static int determine_cipher_type(struct fscrypt_info *ci, struct inode *inode,
>> 				 const char **cipher_str_ret, int *keysize_ret)
>> {
>> 	if (S_ISREG(inode->i_mode)) {
>> -		if (ci->ci_data_mode == FS_ENCRYPTION_MODE_AES_256_XTS) {
>> +		switch (ci->ci_data_mode) {
>> +		case FS_ENCRYPTION_MODE_AES_256_XTS:
>> 			*cipher_str_ret = "xts(aes)";
>> 			*keysize_ret = FS_AES_256_XTS_KEY_SIZE;
>> 			return 0;
>> +		case FS_ENCRYPTION_MODE_AES_128_CBC:
>> +			*cipher_str_ret = "cbc(aes)";
>> +			*keysize_ret = FS_AES_128_CBC_KEY_SIZE;
>> +			return 0;
>> +		default:
>> +			pr_warn_once("fscrypto: unsupported contents encryption mode %d for inode %lu\n",
>> +				     ci->ci_data_mode, inode->i_ino);
>> +			return -ENOKEY;
>> 		}
>> -		pr_warn_once("fscrypto: unsupported contents encryption mode "
>> -			     "%d for inode %lu\n",
>> -			     ci->ci_data_mode, inode->i_ino);
>> -		return -ENOKEY;
>> 	}
>> 
>> 	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) {
>> -		if (ci->ci_filename_mode == FS_ENCRYPTION_MODE_AES_256_CTS) {
>> +		switch (ci->ci_filename_mode) {
>> +		case FS_ENCRYPTION_MODE_AES_256_CTS:
>> 			*cipher_str_ret = "cts(cbc(aes))";
>> 			*keysize_ret = FS_AES_256_CTS_KEY_SIZE;
>> 			return 0;
>> +		case FS_ENCRYPTION_MODE_AES_128_CTS:
>> +			*cipher_str_ret = "cts(cbc(aes))";
>> +			*keysize_ret = FS_AES_128_CTS_KEY_SIZE;
>> +			return 0;
>> +		default:
>> +			pr_warn_once("fscrypto: unsupported filenames encryption mode %d for inode %lu\n",
>> +				     ci->ci_filename_mode, inode->i_ino);
>> +			return -ENOKEY;
>> 		}
>> -		pr_warn_once("fscrypto: unsupported filenames encryption mode "
>> -			     "%d for inode %lu\n",
>> -			     ci->ci_filename_mode, inode->i_ino);
>> -		return -ENOKEY;
>> 	}
> 
> With the added call to fscrypt_valid_enc_modes() earlier, the warnings about
> unsupported encryption modes are no longer reachable.  IMO, the
> fscrypt_valid_enc_modes() check should be moved into this function, a proper
> warning message added for it, and the redundant warnings removed.  Also now that
> there will be more modes I think it would be appropriate to put the algorithm
> names and key sizes in a table, to avoid the ugly switch statements.  

I agree. I'll clean this up.



>> +	int err;
>> +
>> +	/* init hash transform on demand */
>> +	if (unlikely(essiv_hash_tfm == NULL)) {
>> +		mutex_lock(&essiv_hash_lock);
>> +		if (essiv_hash_tfm == NULL) {
>> +			essiv_hash_tfm = crypto_alloc_shash("sha256", 0, 0);
>> +			if (IS_ERR(essiv_hash_tfm)) {
>> +				pr_warn_ratelimited("fscrypt: error allocating SHA-256 transform: %ld\n",
>> +						    PTR_ERR(essiv_hash_tfm));
>> +				err = PTR_ERR(essiv_hash_tfm);
>> +				essiv_hash_tfm = NULL;
>> +				mutex_unlock(&essiv_hash_lock);
>> +				return err;
>> +			}
>> +		}
>> +		mutex_unlock(&essiv_hash_lock);
>> +	}
> 
> There is a bug here: a thread can set essiv_hash_tfm to an ERR_PTR(), and
> another thread can use it before it's set back to NULL.  

Sorry, I missed that... :-(



>> +	err = crypto_cipher_setkey(essiv_tfm, salt, SHA256_DIGEST_SIZE);
>> +	if (err)
>> +		goto out;
> 
> sizeof(salt) instead of hardcoding SHA256_DIGEST_SIZE.
> 
> I think there should also be a brief comment explaining that the ESSIV cipher
> uses AES-256 so that its key size matches the size of the hash, even though the
> "real" encryption may use AES-128.

Good point!


> 
>> +void fscrypt_essiv_cleanup(void)
>> +{
>> +	crypto_free_shash(essiv_hash_tfm);
>> +	essiv_hash_tfm = NULL;
>> +}
> 
> This is called from fscrypt_destroy(), which is a little weird because
> fscrypt_destroy() is meant to clean up only from "fscrypt_initialize()", which
> only allocates certain things.  I think it should be called from
> "fscrypt_exit()" instead.  Then you could also add the __exit annotation, and
> remove setting essiv_hash_tfm to NULL which would clearly be unnecessary.

fscrypt_destroy() is actually also called from fscrypt_exit(). Thats why I chose it,
but changing this fscrypt_exit() seems the cleaner approach. :)

Thanks,
David

--
To unsubscribe from this list: send the line "unsubscribe linux-fscrypt" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [linux Cryptography]     [Asterisk App Development]     [PJ SIP]     [Gnu Gatekeeper]     [IETF Sipping]     [Info Cyrus]     [ALSA User]     [Fedora Linux Users]     [Linux SCTP]     [DCCP]     [Gimp]     [Yosemite News]     [Deep Creek Hot Springs]     [Yosemite Campsites]     [ISDN Cause Codes]

  Powered by Linux