Loading Documentation/filesystems/fscrypt.rst +11 −0 Original line number Diff line number Diff line Loading @@ -633,6 +633,17 @@ from a passphrase or other low-entropy user credential. FS_IOC_GET_ENCRYPTION_PWSALT is deprecated. Instead, prefer to generate and manage any needed salt(s) in userspace. Getting a file's encryption nonce --------------------------------- Since Linux v5.7, the ioctl FS_IOC_GET_ENCRYPTION_NONCE is supported. On encrypted files and directories it gets the inode's 16-byte nonce. On unencrypted files and directories, it fails with ENODATA. This ioctl can be useful for automated tests which verify that the encryption is being done correctly. It is not needed for normal use of fscrypt. Adding keys ----------- Loading fs/crypto/fscrypt_private.h +20 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,26 @@ static inline int fscrypt_context_size(const union fscrypt_context *ctx) return 0; } /* Check whether an fscrypt_context has a recognized version number and size */ static inline bool fscrypt_context_is_valid(const union fscrypt_context *ctx, int ctx_size) { return ctx_size >= 1 && ctx_size == fscrypt_context_size(ctx); } /* Retrieve the context's nonce, assuming the context was already validated */ static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx) { switch (ctx->version) { case FSCRYPT_CONTEXT_V1: return ctx->v1.nonce; case FSCRYPT_CONTEXT_V2: return ctx->v2.nonce; } WARN_ON(1); return NULL; } #undef fscrypt_policy union fscrypt_policy { u8 version; Loading fs/crypto/keysetup.c +2 −14 Original line number Diff line number Diff line Loading @@ -501,20 +501,8 @@ int fscrypt_get_encryption_info(struct inode *inode) goto out; } switch (ctx.version) { case FSCRYPT_CONTEXT_V1: memcpy(crypt_info->ci_nonce, ctx.v1.nonce, memcpy(crypt_info->ci_nonce, fscrypt_context_nonce(&ctx), FS_KEY_DERIVATION_NONCE_SIZE); break; case FSCRYPT_CONTEXT_V2: memcpy(crypt_info->ci_nonce, ctx.v2.nonce, FS_KEY_DERIVATION_NONCE_SIZE); break; default: WARN_ON(1); res = -EINVAL; goto out; } if (!fscrypt_supported_policy(&crypt_info->ci_policy, inode)) { res = -EINVAL; Loading fs/crypto/policy.c +20 −1 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ int fscrypt_policy_from_context(union fscrypt_policy *policy_u, { memset(policy_u, 0, sizeof(*policy_u)); if (ctx_size <= 0 || ctx_size != fscrypt_context_size(ctx_u)) if (!fscrypt_context_is_valid(ctx_u, ctx_size)) return -EINVAL; switch (ctx_u->version) { Loading Loading @@ -485,6 +485,25 @@ int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *uarg) } EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_policy_ex); /* FS_IOC_GET_ENCRYPTION_NONCE: retrieve file's encryption nonce for testing */ int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg) { struct inode *inode = file_inode(filp); union fscrypt_context ctx; int ret; ret = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); if (ret < 0) return ret; if (!fscrypt_context_is_valid(&ctx, ret)) return -EINVAL; if (copy_to_user(arg, fscrypt_context_nonce(&ctx), FS_KEY_DERIVATION_NONCE_SIZE)) return -EFAULT; return 0; } EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_nonce); /** * fscrypt_has_permitted_context() - is a file's encryption policy permitted * within its directory? Loading include/linux/fscrypt.h +6 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ extern int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags); extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); extern int fscrypt_ioctl_get_policy(struct file *, void __user *); extern int fscrypt_ioctl_get_policy_ex(struct file *, void __user *); extern int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); extern int fscrypt_has_permitted_context(struct inode *, struct inode *); extern int fscrypt_inherit_context(struct inode *, struct inode *, void *, bool); Loading Loading @@ -302,6 +303,11 @@ static inline int fscrypt_ioctl_get_policy_ex(struct file *filp, return -EOPNOTSUPP; } static inline int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg) { return -EOPNOTSUPP; } static inline int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) { Loading Loading
Documentation/filesystems/fscrypt.rst +11 −0 Original line number Diff line number Diff line Loading @@ -633,6 +633,17 @@ from a passphrase or other low-entropy user credential. FS_IOC_GET_ENCRYPTION_PWSALT is deprecated. Instead, prefer to generate and manage any needed salt(s) in userspace. Getting a file's encryption nonce --------------------------------- Since Linux v5.7, the ioctl FS_IOC_GET_ENCRYPTION_NONCE is supported. On encrypted files and directories it gets the inode's 16-byte nonce. On unencrypted files and directories, it fails with ENODATA. This ioctl can be useful for automated tests which verify that the encryption is being done correctly. It is not needed for normal use of fscrypt. Adding keys ----------- Loading
fs/crypto/fscrypt_private.h +20 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,26 @@ static inline int fscrypt_context_size(const union fscrypt_context *ctx) return 0; } /* Check whether an fscrypt_context has a recognized version number and size */ static inline bool fscrypt_context_is_valid(const union fscrypt_context *ctx, int ctx_size) { return ctx_size >= 1 && ctx_size == fscrypt_context_size(ctx); } /* Retrieve the context's nonce, assuming the context was already validated */ static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx) { switch (ctx->version) { case FSCRYPT_CONTEXT_V1: return ctx->v1.nonce; case FSCRYPT_CONTEXT_V2: return ctx->v2.nonce; } WARN_ON(1); return NULL; } #undef fscrypt_policy union fscrypt_policy { u8 version; Loading
fs/crypto/keysetup.c +2 −14 Original line number Diff line number Diff line Loading @@ -501,20 +501,8 @@ int fscrypt_get_encryption_info(struct inode *inode) goto out; } switch (ctx.version) { case FSCRYPT_CONTEXT_V1: memcpy(crypt_info->ci_nonce, ctx.v1.nonce, memcpy(crypt_info->ci_nonce, fscrypt_context_nonce(&ctx), FS_KEY_DERIVATION_NONCE_SIZE); break; case FSCRYPT_CONTEXT_V2: memcpy(crypt_info->ci_nonce, ctx.v2.nonce, FS_KEY_DERIVATION_NONCE_SIZE); break; default: WARN_ON(1); res = -EINVAL; goto out; } if (!fscrypt_supported_policy(&crypt_info->ci_policy, inode)) { res = -EINVAL; Loading
fs/crypto/policy.c +20 −1 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ int fscrypt_policy_from_context(union fscrypt_policy *policy_u, { memset(policy_u, 0, sizeof(*policy_u)); if (ctx_size <= 0 || ctx_size != fscrypt_context_size(ctx_u)) if (!fscrypt_context_is_valid(ctx_u, ctx_size)) return -EINVAL; switch (ctx_u->version) { Loading Loading @@ -485,6 +485,25 @@ int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *uarg) } EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_policy_ex); /* FS_IOC_GET_ENCRYPTION_NONCE: retrieve file's encryption nonce for testing */ int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg) { struct inode *inode = file_inode(filp); union fscrypt_context ctx; int ret; ret = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); if (ret < 0) return ret; if (!fscrypt_context_is_valid(&ctx, ret)) return -EINVAL; if (copy_to_user(arg, fscrypt_context_nonce(&ctx), FS_KEY_DERIVATION_NONCE_SIZE)) return -EFAULT; return 0; } EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_nonce); /** * fscrypt_has_permitted_context() - is a file's encryption policy permitted * within its directory? Loading
include/linux/fscrypt.h +6 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ extern int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags); extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); extern int fscrypt_ioctl_get_policy(struct file *, void __user *); extern int fscrypt_ioctl_get_policy_ex(struct file *, void __user *); extern int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); extern int fscrypt_has_permitted_context(struct inode *, struct inode *); extern int fscrypt_inherit_context(struct inode *, struct inode *, void *, bool); Loading Loading @@ -302,6 +303,11 @@ static inline int fscrypt_ioctl_get_policy_ex(struct file *filp, return -EOPNOTSUPP; } static inline int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg) { return -EOPNOTSUPP; } static inline int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) { Loading