blob: cd8446949f60aa6db392ccbebbf9dd61ba0502e5 [file] [log] [blame]
Neeraj Soni36c65122018-04-18 21:04:46 +05301/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include "fscrypt_ice.h"
14
Blagovest Kolenichevf56989b2018-09-28 03:15:02 -070015extern int fscrypt_get_mode_key_size(int mode);
16
Neeraj Soni36c65122018-04-18 21:04:46 +053017int fscrypt_using_hardware_encryption(const struct inode *inode)
18{
19 struct fscrypt_info *ci = inode->i_crypt_info;
20
21 return S_ISREG(inode->i_mode) && ci &&
22 ci->ci_data_mode == FS_ENCRYPTION_MODE_PRIVATE;
23}
24EXPORT_SYMBOL(fscrypt_using_hardware_encryption);
25
Blagovest Kolenichevf56989b2018-09-28 03:15:02 -070026size_t fscrypt_get_ice_encryption_key_size(const struct inode *inode)
27{
28 struct fscrypt_info *ci = NULL;
29
30 if (inode)
31 ci = inode->i_crypt_info;
32 if (!ci)
33 return 0;
34
35 return fscrypt_get_mode_key_size(ci->ci_data_mode) / 2;
36}
37
38size_t fscrypt_get_ice_encryption_salt_size(const struct inode *inode)
39{
40 struct fscrypt_info *ci = NULL;
41
42 if (inode)
43 ci = inode->i_crypt_info;
44 if (!ci)
45 return 0;
46
47 return fscrypt_get_mode_key_size(ci->ci_data_mode) / 2;
48}
49
Neeraj Soni36c65122018-04-18 21:04:46 +053050/*
51 * Retrieves encryption key from the inode
52 */
53char *fscrypt_get_ice_encryption_key(const struct inode *inode)
54{
55 struct fscrypt_info *ci = NULL;
56
57 if (!inode)
58 return NULL;
59
60 ci = inode->i_crypt_info;
61 if (!ci)
62 return NULL;
63
64 return &(ci->ci_raw_key[0]);
65}
66
67/*
68 * Retrieves encryption salt from the inode
69 */
70char *fscrypt_get_ice_encryption_salt(const struct inode *inode)
71{
72 struct fscrypt_info *ci = NULL;
Blagovest Kolenichevf56989b2018-09-28 03:15:02 -070073 int size = 0;
Neeraj Soni36c65122018-04-18 21:04:46 +053074
75 if (!inode)
76 return NULL;
77
78 ci = inode->i_crypt_info;
79 if (!ci)
80 return NULL;
81
Blagovest Kolenichevf56989b2018-09-28 03:15:02 -070082 size = fscrypt_get_ice_encryption_key_size(inode);
83 if (!size)
84 return NULL;
85
86 return &(ci->ci_raw_key[size]);
Neeraj Soni36c65122018-04-18 21:04:46 +053087}
88
89/*
90 * returns true if the cipher mode in inode is AES XTS
91 */
92int fscrypt_is_aes_xts_cipher(const struct inode *inode)
93{
94 struct fscrypt_info *ci = inode->i_crypt_info;
95
96 if (!ci)
97 return 0;
98
99 return (ci->ci_data_mode == FS_ENCRYPTION_MODE_PRIVATE);
100}
101
102/*
103 * returns true if encryption info in both inodes is equal
104 */
105bool fscrypt_is_ice_encryption_info_equal(const struct inode *inode1,
106 const struct inode *inode2)
107{
108 char *key1 = NULL;
109 char *key2 = NULL;
110 char *salt1 = NULL;
111 char *salt2 = NULL;
112
113 if (!inode1 || !inode2)
114 return false;
115
116 if (inode1 == inode2)
117 return true;
118
119 /* both do not belong to ice, so we don't care, they are equal
120 *for us
121 */
122 if (!fscrypt_should_be_processed_by_ice(inode1) &&
123 !fscrypt_should_be_processed_by_ice(inode2))
124 return true;
125
126 /* one belongs to ice, the other does not -> not equal */
127 if (fscrypt_should_be_processed_by_ice(inode1) ^
128 fscrypt_should_be_processed_by_ice(inode2))
129 return false;
130
131 key1 = fscrypt_get_ice_encryption_key(inode1);
132 key2 = fscrypt_get_ice_encryption_key(inode2);
133 salt1 = fscrypt_get_ice_encryption_salt(inode1);
134 salt2 = fscrypt_get_ice_encryption_salt(inode2);
135
136 /* key and salt should not be null by this point */
137 if (!key1 || !key2 || !salt1 || !salt2 ||
138 (fscrypt_get_ice_encryption_key_size(inode1) !=
139 fscrypt_get_ice_encryption_key_size(inode2)) ||
140 (fscrypt_get_ice_encryption_salt_size(inode1) !=
141 fscrypt_get_ice_encryption_salt_size(inode2)))
142 return false;
143
144 if ((memcmp(key1, key2,
145 fscrypt_get_ice_encryption_key_size(inode1)) == 0) &&
146 (memcmp(salt1, salt2,
147 fscrypt_get_ice_encryption_salt_size(inode1)) == 0))
148 return true;
149
150 return false;
151}
152
153void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun)
154{
155 if (fscrypt_should_be_processed_by_ice(inode))
156 bio->bi_iter.bi_dun = dun;
157}
158EXPORT_SYMBOL(fscrypt_set_ice_dun);
159
Jaegeuk Kim3bd012f2018-04-20 19:26:09 -0700160void fscrypt_set_ice_skip(struct bio *bio, int bi_crypt_skip)
161{
162#ifdef CONFIG_DM_DEFAULT_KEY
163 bio->bi_crypt_skip = bi_crypt_skip;
164#endif
165}
166EXPORT_SYMBOL(fscrypt_set_ice_skip);
167
Neeraj Soni36c65122018-04-18 21:04:46 +0530168/*
169 * This function will be used for filesystem when deciding to merge bios.
170 * Basic assumption is, if inline_encryption is set, single bio has to
171 * guarantee consecutive LBAs as well as ino|pg->index.
172 */
Jaegeuk Kim3bd012f2018-04-20 19:26:09 -0700173bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted,
174 int bi_crypt_skip)
Neeraj Soni36c65122018-04-18 21:04:46 +0530175{
176 if (!bio)
177 return true;
178
Jaegeuk Kim3bd012f2018-04-20 19:26:09 -0700179#ifdef CONFIG_DM_DEFAULT_KEY
180 if (bi_crypt_skip != bio->bi_crypt_skip)
181 return false;
182#endif
Neeraj Soni36c65122018-04-18 21:04:46 +0530183 /* if both of them are not encrypted, no further check is needed */
184 if (!bio_dun(bio) && !bio_encrypted)
185 return true;
186
187 /* ICE allows only consecutive iv_key stream. */
188 return bio_end_dun(bio) == dun;
189}
190EXPORT_SYMBOL(fscrypt_mergeable_bio);