^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include "ubifs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) return ubifs_xattr_get(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) ctx, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) size_t len, void *fs_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Creating an encryption context is done unlocked since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * operate on a new inode which is not visible to other users
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * at this point. So, no need to check whether inode is locked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) ctx, len, 0, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static bool ubifs_crypt_empty_dir(struct inode *inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) return ubifs_check_dir_empty(inode) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) unsigned int in_len, unsigned int *out_len, int block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct ubifs_info *c = inode->i_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) void *p = &dn->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) ubifs_assert(c, pad_len <= *out_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) dn->compr_size = cpu_to_le16(in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* pad to full block cipher length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (pad_len != in_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) memset(p + in_len, 0, pad_len - in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) err = fscrypt_encrypt_block_inplace(inode, virt_to_page(p), pad_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) offset_in_page(p), block, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ubifs_err(c, "fscrypt_encrypt_block_inplace() failed: %d", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *out_len = pad_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int *out_len, int block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct ubifs_info *c = inode->i_sb->s_fs_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned int clen = le16_to_cpu(dn->compr_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int dlen = *out_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (clen <= 0 || clen > UBIFS_BLOCK_SIZE || clen > dlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ubifs_err(c, "bad compr_size: %i", clen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ubifs_assert(c, dlen <= UBIFS_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) err = fscrypt_decrypt_block_inplace(inode, virt_to_page(&dn->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dlen, offset_in_page(&dn->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ubifs_err(c, "fscrypt_decrypt_block_inplace() failed: %d", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *out_len = clen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const struct fscrypt_operations ubifs_crypt_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .flags = FS_CFLG_OWN_PAGES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .key_prefix = "ubifs:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .get_context = ubifs_crypt_get_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .set_context = ubifs_crypt_set_context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .empty_dir = ubifs_crypt_empty_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .max_namelen = UBIFS_MAX_NLEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };