blob: 1de53d4ba7e39a78f4397b2ebe27b8ef5d365c2f [file] [log] [blame]
Zhen Kongee7bdc62019-03-14 10:55:19 -07001// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
4 */
5
6#include "fscrypt_ice.h"
7
8int fscrypt_using_hardware_encryption(const struct inode *inode)
9{
10 struct fscrypt_info *ci = inode->i_crypt_info;
11
12 return S_ISREG(inode->i_mode) && ci &&
13 ci->ci_data_mode == FS_ENCRYPTION_MODE_PRIVATE;
14}
15EXPORT_SYMBOL(fscrypt_using_hardware_encryption);
16
17/*
18 * Retrieves encryption key from the inode
19 */
20char *fscrypt_get_ice_encryption_key(const struct inode *inode)
21{
22 struct fscrypt_info *ci = NULL;
23
24 if (!inode)
25 return NULL;
26
27 ci = inode->i_crypt_info;
28 if (!ci)
29 return NULL;
30
31 return &(ci->ci_raw_key[0]);
32}
33
34/*
35 * Retrieves encryption salt from the inode
36 */
37char *fscrypt_get_ice_encryption_salt(const struct inode *inode)
38{
39 struct fscrypt_info *ci = NULL;
40
41 if (!inode)
42 return NULL;
43
44 ci = inode->i_crypt_info;
45 if (!ci)
46 return NULL;
47
48 return &(ci->ci_raw_key[fscrypt_get_ice_encryption_key_size(inode)]);
49}
50
51/*
52 * returns true if the cipher mode in inode is AES XTS
53 */
54int fscrypt_is_aes_xts_cipher(const struct inode *inode)
55{
56 struct fscrypt_info *ci = inode->i_crypt_info;
57
58 if (!ci)
59 return 0;
60
61 return (ci->ci_data_mode == FS_ENCRYPTION_MODE_PRIVATE);
62}
63
64/*
65 * returns true if encryption info in both inodes is equal
66 */
67bool fscrypt_is_ice_encryption_info_equal(const struct inode *inode1,
68 const struct inode *inode2)
69{
70 char *key1 = NULL;
71 char *key2 = NULL;
72 char *salt1 = NULL;
73 char *salt2 = NULL;
74
75 if (!inode1 || !inode2)
76 return false;
77
78 if (inode1 == inode2)
79 return true;
80
81 /*
82 * both do not belong to ice, so we don't care, they are equal
83 * for us
84 */
85 if (!fscrypt_should_be_processed_by_ice(inode1) &&
86 !fscrypt_should_be_processed_by_ice(inode2))
87 return true;
88
89 /* one belongs to ice, the other does not -> not equal */
90 if (fscrypt_should_be_processed_by_ice(inode1) ^
91 fscrypt_should_be_processed_by_ice(inode2))
92 return false;
93
94 key1 = fscrypt_get_ice_encryption_key(inode1);
95 key2 = fscrypt_get_ice_encryption_key(inode2);
96 salt1 = fscrypt_get_ice_encryption_salt(inode1);
97 salt2 = fscrypt_get_ice_encryption_salt(inode2);
98
99 /* key and salt should not be null by this point */
100 if (!key1 || !key2 || !salt1 || !salt2 ||
101 (fscrypt_get_ice_encryption_key_size(inode1) !=
102 fscrypt_get_ice_encryption_key_size(inode2)) ||
103 (fscrypt_get_ice_encryption_salt_size(inode1) !=
104 fscrypt_get_ice_encryption_salt_size(inode2)))
105 return false;
106
107 if ((memcmp(key1, key2,
108 fscrypt_get_ice_encryption_key_size(inode1)) == 0) &&
109 (memcmp(salt1, salt2,
110 fscrypt_get_ice_encryption_salt_size(inode1)) == 0))
111 return true;
112
113 return false;
114}
115
116void fscrypt_set_ice_dun(const struct inode *inode, struct bio *bio, u64 dun)
117{
118 if (fscrypt_should_be_processed_by_ice(inode))
119 bio->bi_iter.bi_dun = dun;
120}
121EXPORT_SYMBOL(fscrypt_set_ice_dun);
122
123/*
124 * This function will be used for filesystem when deciding to merge bios.
125 * Basic assumption is, if inline_encryption is set, single bio has to
126 * guarantee consecutive LBAs as well as ino|pg->index.
127 */
128bool fscrypt_mergeable_bio(struct bio *bio, u64 dun, bool bio_encrypted)
129{
130 if (!bio)
131 return true;
132
133 /* if both of them are not encrypted, no further check is needed */
134 if (!bio_dun(bio) && !bio_encrypted)
135 return true;
136
137 /* ICE allows only consecutive iv_key stream. */
138 return bio_end_dun(bio) == dun;
139}
140EXPORT_SYMBOL(fscrypt_mergeable_bio);