Loading fs/crypto/fscrypt_private.h +5 −2 Original line number Diff line number Diff line Loading @@ -326,7 +326,8 @@ extern void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf); /* inline_crypt.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT extern void fscrypt_select_encryption_impl(struct fscrypt_info *ci); extern int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key); static inline bool fscrypt_using_inline_encryption(const struct fscrypt_info *ci) Loading Loading @@ -370,8 +371,10 @@ fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ static inline void fscrypt_select_encryption_impl(struct fscrypt_info *ci) static inline int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key) { return 0; } static inline bool fscrypt_using_inline_encryption( Loading fs/crypto/inline_crypt.c +58 −12 Original line number Diff line number Diff line Loading @@ -25,26 +25,76 @@ struct fscrypt_blk_crypto_key { struct request_queue *devs[]; }; static int fscrypt_get_num_devices(struct super_block *sb) { if (sb->s_cop->get_num_devices) return sb->s_cop->get_num_devices(sb); return 1; } static void fscrypt_get_devices(struct super_block *sb, int num_devs, struct request_queue **devs) { if (num_devs == 1) devs[0] = bdev_get_queue(sb->s_bdev); else sb->s_cop->get_devices(sb, devs); } /* Enable inline encryption for this file if supported. */ void fscrypt_select_encryption_impl(struct fscrypt_info *ci) int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; struct request_queue **devs; int num_devs; int i; /* The file must need contents encryption, not filenames encryption */ if (!S_ISREG(inode->i_mode)) return; return 0; /* blk-crypto must implement the needed encryption algorithm */ if (ci->ci_mode->blk_crypto_mode == BLK_ENCRYPTION_MODE_INVALID) return; if (crypto_mode == BLK_ENCRYPTION_MODE_INVALID) return 0; /* The filesystem must be mounted with -o inlinecrypt */ if (!sb->s_cop->inline_crypt_enabled || !sb->s_cop->inline_crypt_enabled(sb)) return; return 0; /* * The needed encryption settings must be supported either by * blk-crypto-fallback, or by hardware on all the filesystem's devices. */ if (IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) && !is_hw_wrapped_key) { ci->ci_inlinecrypt = true; return 0; } num_devs = fscrypt_get_num_devices(sb); devs = kmalloc_array(num_devs, sizeof(*devs), GFP_NOFS); if (!devs) return -ENOMEM; fscrypt_get_devices(sb, num_devs, devs); for (i = 0; i < num_devs; i++) { if (!keyslot_manager_crypto_mode_supported(devs[i]->ksm, crypto_mode, sb->s_blocksize, is_hw_wrapped_key)) goto out_free_devs; } ci->ci_inlinecrypt = true; out_free_devs: kfree(devs); return 0; } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, Loading @@ -56,14 +106,13 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; int num_devs = 1; int num_devs; int queue_refs = 0; struct fscrypt_blk_crypto_key *blk_key; int err; int i; if (sb->s_cop->get_num_devices) num_devs = sb->s_cop->get_num_devices(sb); num_devs = fscrypt_get_num_devices(sb); if (WARN_ON(num_devs < 1)) return -EINVAL; Loading @@ -72,10 +121,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, return -ENOMEM; blk_key->num_devs = num_devs; if (num_devs == 1) blk_key->devs[0] = bdev_get_queue(sb->s_bdev); else sb->s_cop->get_devices(sb, blk_key->devs); fscrypt_get_devices(sb, num_devs, blk_key->devs); BUILD_BUG_ON(FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE > BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE); Loading fs/crypto/keysetup.c +8 −2 Original line number Diff line number Diff line Loading @@ -335,8 +335,6 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, struct fscrypt_key_specifier mk_spec; int err; fscrypt_select_encryption_impl(ci); switch (ci->ci_policy.version) { case FSCRYPT_POLICY_V1: mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; Loading @@ -361,6 +359,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, ci->ci_policy.version != FSCRYPT_POLICY_V1) return PTR_ERR(key); err = fscrypt_select_encryption_impl(ci, false); if (err) return err; /* * As a legacy fallback for v1 policies, search for the key in * the current task's subscribed keyrings too. Don't move this Loading Loading @@ -395,6 +397,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, goto out_release_key; } err = fscrypt_select_encryption_impl(ci, mk->mk_secret.is_hw_wrapped); if (err) goto out_release_key; switch (ci->ci_policy.version) { case FSCRYPT_POLICY_V1: err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw); Loading Loading
fs/crypto/fscrypt_private.h +5 −2 Original line number Diff line number Diff line Loading @@ -326,7 +326,8 @@ extern void fscrypt_destroy_hkdf(struct fscrypt_hkdf *hkdf); /* inline_crypt.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT extern void fscrypt_select_encryption_impl(struct fscrypt_info *ci); extern int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key); static inline bool fscrypt_using_inline_encryption(const struct fscrypt_info *ci) Loading Loading @@ -370,8 +371,10 @@ fscrypt_is_key_prepared(struct fscrypt_prepared_key *prep_key, #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ static inline void fscrypt_select_encryption_impl(struct fscrypt_info *ci) static inline int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key) { return 0; } static inline bool fscrypt_using_inline_encryption( Loading
fs/crypto/inline_crypt.c +58 −12 Original line number Diff line number Diff line Loading @@ -25,26 +25,76 @@ struct fscrypt_blk_crypto_key { struct request_queue *devs[]; }; static int fscrypt_get_num_devices(struct super_block *sb) { if (sb->s_cop->get_num_devices) return sb->s_cop->get_num_devices(sb); return 1; } static void fscrypt_get_devices(struct super_block *sb, int num_devs, struct request_queue **devs) { if (num_devs == 1) devs[0] = bdev_get_queue(sb->s_bdev); else sb->s_cop->get_devices(sb, devs); } /* Enable inline encryption for this file if supported. */ void fscrypt_select_encryption_impl(struct fscrypt_info *ci) int fscrypt_select_encryption_impl(struct fscrypt_info *ci, bool is_hw_wrapped_key) { const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; struct request_queue **devs; int num_devs; int i; /* The file must need contents encryption, not filenames encryption */ if (!S_ISREG(inode->i_mode)) return; return 0; /* blk-crypto must implement the needed encryption algorithm */ if (ci->ci_mode->blk_crypto_mode == BLK_ENCRYPTION_MODE_INVALID) return; if (crypto_mode == BLK_ENCRYPTION_MODE_INVALID) return 0; /* The filesystem must be mounted with -o inlinecrypt */ if (!sb->s_cop->inline_crypt_enabled || !sb->s_cop->inline_crypt_enabled(sb)) return; return 0; /* * The needed encryption settings must be supported either by * blk-crypto-fallback, or by hardware on all the filesystem's devices. */ if (IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) && !is_hw_wrapped_key) { ci->ci_inlinecrypt = true; return 0; } num_devs = fscrypt_get_num_devices(sb); devs = kmalloc_array(num_devs, sizeof(*devs), GFP_NOFS); if (!devs) return -ENOMEM; fscrypt_get_devices(sb, num_devs, devs); for (i = 0; i < num_devs; i++) { if (!keyslot_manager_crypto_mode_supported(devs[i]->ksm, crypto_mode, sb->s_blocksize, is_hw_wrapped_key)) goto out_free_devs; } ci->ci_inlinecrypt = true; out_free_devs: kfree(devs); return 0; } int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, Loading @@ -56,14 +106,13 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, const struct inode *inode = ci->ci_inode; struct super_block *sb = inode->i_sb; enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode; int num_devs = 1; int num_devs; int queue_refs = 0; struct fscrypt_blk_crypto_key *blk_key; int err; int i; if (sb->s_cop->get_num_devices) num_devs = sb->s_cop->get_num_devices(sb); num_devs = fscrypt_get_num_devices(sb); if (WARN_ON(num_devs < 1)) return -EINVAL; Loading @@ -72,10 +121,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, return -ENOMEM; blk_key->num_devs = num_devs; if (num_devs == 1) blk_key->devs[0] = bdev_get_queue(sb->s_bdev); else sb->s_cop->get_devices(sb, blk_key->devs); fscrypt_get_devices(sb, num_devs, blk_key->devs); BUILD_BUG_ON(FSCRYPT_MAX_HW_WRAPPED_KEY_SIZE > BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE); Loading
fs/crypto/keysetup.c +8 −2 Original line number Diff line number Diff line Loading @@ -335,8 +335,6 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, struct fscrypt_key_specifier mk_spec; int err; fscrypt_select_encryption_impl(ci); switch (ci->ci_policy.version) { case FSCRYPT_POLICY_V1: mk_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; Loading @@ -361,6 +359,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, ci->ci_policy.version != FSCRYPT_POLICY_V1) return PTR_ERR(key); err = fscrypt_select_encryption_impl(ci, false); if (err) return err; /* * As a legacy fallback for v1 policies, search for the key in * the current task's subscribed keyrings too. Don't move this Loading Loading @@ -395,6 +397,10 @@ static int setup_file_encryption_key(struct fscrypt_info *ci, goto out_release_key; } err = fscrypt_select_encryption_impl(ci, mk->mk_secret.is_hw_wrapped); if (err) goto out_release_key; switch (ci->ci_policy.version) { case FSCRYPT_POLICY_V1: err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw); Loading