diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index f252d4eda314..418a50a41747 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -363,16 +363,15 @@ fscrypt_using_inline_encryption(const struct fscrypt_info *ci) } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, - unsigned int raw_key_size, + const u8 *raw_key, size_t raw_key_size, bool is_hw_wrapped, const struct fscrypt_info *ci); void fscrypt_destroy_inline_crypt_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key); -int fscrypt_derive_sw_secret(struct super_block *sb, const u8 *wrapped_key, - unsigned int wrapped_key_size, +int fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]); /* @@ -385,7 +384,7 @@ fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, { /* * The two smp_load_acquire()'s here pair with the smp_store_release()'s - * in fscrypt_prepare_inline_crypt_key() and __fscrypt_prepare_key(). + * in fscrypt_prepare_inline_crypt_key() and fscrypt_prepare_key(). * I.e., in some cases (namely, if this prep_key is a per-mode * encryption key) another task can publish blk_key or tfm concurrently, * executing a RELEASE barrier. We need to use smp_load_acquire() here @@ -412,7 +411,7 @@ fscrypt_using_inline_encryption(const struct fscrypt_info *ci) static inline int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, unsigned int raw_key_size, + const u8 *raw_key, size_t raw_key_size, bool is_hw_wrapped, const struct fscrypt_info *ci) { @@ -427,8 +426,8 @@ fscrypt_destroy_inline_crypt_key(struct super_block *sb, } static inline int -fscrypt_derive_sw_secret(struct super_block *sb, const u8 *wrapped_key, - unsigned int wrapped_key_size, +fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) { fscrypt_warn(NULL, "kernel doesn't support hardware-wrapped keys"); diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index 77d0d86c578c..8d33accf0670 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -155,8 +155,7 @@ out_free_devs: } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, - unsigned int raw_key_size, + const u8 *raw_key, size_t raw_key_size, bool is_hw_wrapped, const struct fscrypt_info *ci) { @@ -240,19 +239,22 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb, * hardware-wrapped key. Returns -EOPNOTSUPP if hardware-wrapped keys aren't * supported on this filesystem or hardware. */ -int fscrypt_derive_sw_secret(struct super_block *sb, const u8 *wrapped_key, - unsigned int wrapped_key_size, +int fscrypt_derive_sw_secret(struct super_block *sb, + const u8 *wrapped_key, size_t wrapped_key_size, u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]) { - struct blk_crypto_profile *profile; struct block_device **devs; unsigned int num_devs; unsigned int i; int err; - /* The filesystem must be mounted with -o inlinecrypt */ - if (!(sb->s_flags & SB_INLINECRYPT)) + /* The filesystem must be mounted with -o inlinecrypt. */ + if (!(sb->s_flags & SB_INLINECRYPT)) { + fscrypt_warn(NULL, + "%s: filesystem not mounted with inlinecrypt\n", + sb->s_id); return -EOPNOTSUPP; + } /* * Hardware-wrapped keys might be specific to a particular storage @@ -263,17 +265,21 @@ int fscrypt_derive_sw_secret(struct super_block *sb, const u8 *wrapped_key, devs = fscrypt_get_devices(sb, &num_devs); if (IS_ERR(devs)) return PTR_ERR(devs); - profile = bdev_get_queue(devs[0])->crypto_profile; for (i = 1; i < num_devs; i++) { - if (bdev_get_queue(devs[i])->crypto_profile != profile) { + if (!blk_crypto_hw_wrapped_keys_compatible(devs[0], devs[i])) { fscrypt_warn(NULL, - "unsupported multi-device configuration for hardware-wrapped keys"); + "%s: unsupported multi-device configuration for hardware-wrapped keys", + sb->s_id); kfree(devs); return -EOPNOTSUPP; } } - err = blk_crypto_derive_sw_secret(profile, wrapped_key, + err = blk_crypto_derive_sw_secret(devs[0], wrapped_key, wrapped_key_size, sw_secret); + if (err == -EOPNOTSUPP) + fscrypt_warn(NULL, + "%s: block device doesn't support hardware-wrapped keys\n", + sb->s_id); kfree(devs); return err; } diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index aeb28d091a1e..672c3fbda0f3 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -782,11 +782,11 @@ fscrypt_get_test_dummy_secret(struct fscrypt_master_key_secret *secret) { static u8 test_key[FSCRYPT_MAX_STANDARD_KEY_SIZE]; - get_random_once(test_key, FSCRYPT_MAX_STANDARD_KEY_SIZE); + get_random_once(test_key, sizeof(test_key)); memset(secret, 0, sizeof(*secret)); - secret->size = FSCRYPT_MAX_STANDARD_KEY_SIZE; - memcpy(secret->raw, test_key, FSCRYPT_MAX_STANDARD_KEY_SIZE); + secret->size = sizeof(test_key); + memcpy(secret->raw, test_key, sizeof(test_key)); } int fscrypt_get_test_dummy_key_identifier( diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 8b0237241c2f..2c375f09af1e 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -130,23 +130,17 @@ err_free_tfm: * Prepare the crypto transform object or blk-crypto key in @prep_key, given the * raw key, encryption mode (@ci->ci_mode), flag indicating which encryption * implementation (fs-layer or blk-crypto) will be used (@ci->ci_inlinecrypt), - * and IV generation method (@ci->ci_policy.flags). The raw key can be either a - * standard key or a hardware-wrapped key, as indicated by @is_hw_wrapped; it - * can only be a hardware-wrapped key if blk-crypto will be used. + * and IV generation method (@ci->ci_policy.flags). */ -static int __fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, unsigned int raw_key_size, - bool is_hw_wrapped, - const struct fscrypt_info *ci) +int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, + const u8 *raw_key, const struct fscrypt_info *ci) { struct crypto_skcipher *tfm; if (fscrypt_using_inline_encryption(ci)) - return fscrypt_prepare_inline_crypt_key(prep_key, - raw_key, raw_key_size, is_hw_wrapped, ci); - - if (WARN_ON(is_hw_wrapped || raw_key_size != ci->ci_mode->keysize)) - return -EINVAL; + return fscrypt_prepare_inline_crypt_key(prep_key, raw_key, + ci->ci_mode->keysize, + false, ci); tfm = fscrypt_allocate_skcipher(ci->ci_mode, raw_key, ci->ci_inode); if (IS_ERR(tfm)) @@ -161,13 +155,6 @@ static int __fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, return 0; } -int fscrypt_prepare_key(struct fscrypt_prepared_key *prep_key, - const u8 *raw_key, const struct fscrypt_info *ci) -{ - return __fscrypt_prepare_key(prep_key, raw_key, ci->ci_mode->keysize, - false, ci); -} - /* Destroy a crypto transform object and/or blk-crypto key. */ void fscrypt_destroy_prepared_key(struct super_block *sb, struct fscrypt_prepared_key *prep_key) @@ -208,7 +195,7 @@ static int setup_per_mode_enc_key(struct fscrypt_info *ci, if (!fscrypt_using_inline_encryption(ci)) { if (sb->s_flags & SB_INLINECRYPT) fscrypt_warn(ci->ci_inode, - "Hardware-wrapped key required, but no suitable inline encryption hardware is available"); + "Hardware-wrapped key required, but no suitable inline encryption capabilities are available"); else fscrypt_warn(ci->ci_inode, "Hardware-wrapped keys require inline encryption (-o inlinecrypt)"); @@ -229,8 +216,10 @@ static int setup_per_mode_enc_key(struct fscrypt_info *ci, goto done_unlock; if (use_hw_wrapped_key) { - err = __fscrypt_prepare_key(prep_key, mk->mk_secret.raw, - mk->mk_secret.size, true, ci); + err = fscrypt_prepare_inline_crypt_key(prep_key, + mk->mk_secret.raw, + mk->mk_secret.size, true, + ci); if (err) goto out_unlock; goto done_unlock;