summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/crypto.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2016-09-29 16:20:19 -0400
committerRichard Weinberger <richard@nod.at>2016-12-12 17:07:38 -0500
commit7799953b34d1838b30e3d69fd36aa3288ac1e89d (patch)
tree30866ef1ac8df56932411a29f3d13159a0bd042d /fs/ubifs/crypto.c
parent1ee77870c9ea954871e4424a7b5ae260fe198b13 (diff)
ubifs: Implement encrypt/decrypt for all IO
Signed-off-by: Richard Weinberger <richard@nod.at> Signed-off-by: David Gstir <david@sigma-star.at> Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/crypto.c')
-rw-r--r--fs/ubifs/crypto.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c
index 25bb2062b8a3..aefa3c30b73b 100644
--- a/fs/ubifs/crypto.c
+++ b/fs/ubifs/crypto.c
@@ -35,6 +35,57 @@ static int ubifs_key_prefix(struct inode *inode, u8 **key)
35 return sizeof(prefix) - 1; 35 return sizeof(prefix) - 1;
36} 36}
37 37
38int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn,
39 unsigned int in_len, unsigned int *out_len, int block)
40{
41 struct ubifs_info *c = inode->i_sb->s_fs_info;
42 void *p = &dn->data;
43 struct page *ret;
44 unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE);
45
46 ubifs_assert(pad_len <= *out_len);
47 dn->compr_size = cpu_to_le16(in_len);
48
49 /* pad to full block cipher length */
50 if (pad_len != in_len)
51 memset(p + in_len, 0, pad_len - in_len);
52
53 ret = fscrypt_encrypt_page(inode, virt_to_page(&dn->data), pad_len,
54 offset_in_page(&dn->data), block, GFP_NOFS);
55 if (IS_ERR(ret)) {
56 ubifs_err(c, "fscrypt_encrypt_page failed: %ld", PTR_ERR(ret));
57 return PTR_ERR(ret);
58 }
59 *out_len = pad_len;
60
61 return 0;
62}
63
64int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn,
65 unsigned int *out_len, int block)
66{
67 struct ubifs_info *c = inode->i_sb->s_fs_info;
68 int err;
69 unsigned int clen = le16_to_cpu(dn->compr_size);
70 unsigned int dlen = *out_len;
71
72 if (clen <= 0 || clen > UBIFS_BLOCK_SIZE || clen > dlen) {
73 ubifs_err(c, "bad compr_size: %i", clen);
74 return -EINVAL;
75 }
76
77 ubifs_assert(dlen <= UBIFS_BLOCK_SIZE);
78 err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen,
79 offset_in_page(&dn->data), block);
80 if (err) {
81 ubifs_err(c, "fscrypt_decrypt_page failed: %i", err);
82 return err;
83 }
84 *out_len = clen;
85
86 return 0;
87}
88
38struct fscrypt_operations ubifs_crypt_operations = { 89struct fscrypt_operations ubifs_crypt_operations = {
39 .flags = FS_CFLG_INPLACE_ENCRYPTION, 90 .flags = FS_CFLG_INPLACE_ENCRYPTION,
40 .get_context = ubifs_crypt_get_context, 91 .get_context = ubifs_crypt_get_context,