1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * drivers/hyperhold/hp_device.c
4  *
5  * Copyright (c) 2020-2022 Huawei Technologies Co., Ltd.
6  */
7 
8 #define pr_fmt(fmt) "[HYPERHOLD]" fmt
9 
10 #include <linux/random.h>
11 #include <linux/blk-crypto.h>
12 #include <linux/scatterlist.h>
13 #include <linux/version.h>
14 
15 #include "hp_device.h"
16 
17 #define HP_CIPHER_MODE BLK_ENCRYPTION_MODE_AES_256_XTS
18 #define HP_CIPHER_NAME "xts(aes)"
19 #define HP_KEY_SIZE (64)
20 #define HP_IV_SIZE (16)
21 
22 union hp_iv {
23 	__le64 index;
24 	__le64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
25 };
26 
unbind_bdev(struct hp_device *dev)27 void unbind_bdev(struct hp_device *dev)
28 {
29 	int ret;
30 
31 	if (!dev->bdev)
32 		goto close;
33 	if (!dev->old_block_size)
34 		goto put;
35 	ret = set_blocksize(dev->bdev, dev->old_block_size);
36 	if (ret)
37 		pr_err("set old block size %d failed, err = %d!\n",
38 				dev->old_block_size, ret);
39 	dev->old_block_size = 0;
40 put:
41 	blkdev_put(dev->bdev, FMODE_READ | FMODE_WRITE);
42 	dev->bdev = NULL;
43 close:
44 	if (dev->filp)
45 		filp_close(dev->filp, NULL);
46 	dev->filp = NULL;
47 
48 	pr_info("hyperhold bdev unbinded.\n");
49 }
50 
bind_bdev(struct hp_device *dev, const char *name)51 bool bind_bdev(struct hp_device *dev, const char *name)
52 {
53 	struct inode *inode = NULL;
54 	int ret;
55 
56 	dev->filp = filp_open(name, O_RDWR | O_LARGEFILE, 0);
57 	if (IS_ERR(dev->filp)) {
58 		pr_err("open file %s failed, err = %ld!\n", name, PTR_ERR(dev->filp));
59 		dev->filp = NULL;
60 		goto err;
61 	}
62 	inode = dev->filp->f_mapping->host;
63 	if (!S_ISBLK(inode->i_mode)) {
64 		pr_err("%s is not a block device!\n", name);
65 		goto err;
66 	}
67 #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
68 	dev->bdev = blkdev_get_by_dev(inode->i_rdev, BLK_OPEN_READ | BLK_OPEN_WRITE, dev, NULL);
69 #else
70 	dev->bdev = blkdev_get_by_dev(inode->i_rdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, dev);
71 #endif
72 	if (IS_ERR(dev->bdev)) {
73 		ret = PTR_ERR(dev->bdev);
74 		dev->bdev = NULL;
75 		pr_err("get blkdev %s failed, err = %d!\n", name, ret);
76 		goto err;
77 	}
78 	dev->old_block_size = block_size(dev->bdev);
79 	ret = set_blocksize(dev->bdev, PAGE_SIZE);
80 	if (ret) {
81 		pr_err("set %s block size failed, err = %d!\n", name, ret);
82 		goto err;
83 	}
84 	dev->dev_size = (u64)i_size_read(inode);
85 	dev->sec_size = SECTOR_SIZE;
86 
87 	pr_info("hyperhold bind bdev %s of size %llu / %u succ.\n",
88 			name, dev->dev_size, dev->sec_size);
89 
90 	return true;
91 err:
92 	unbind_bdev(dev);
93 
94 	return false;
95 }
96 
soft_crypt_page(struct crypto_skcipher *ctfm, struct page *dst_page, struct page *src_page, unsigned int op)97 int soft_crypt_page(struct crypto_skcipher *ctfm, struct page *dst_page,
98 		    struct page *src_page, unsigned int op)
99 {
100 	struct skcipher_request *req = NULL;
101 	DECLARE_CRYPTO_WAIT(wait);
102 	struct scatterlist dst, src;
103 	int ret = 0;
104 	union hp_iv iv;
105 
106 	memset(&iv, 0, sizeof(union hp_iv));
107 	iv.index = cpu_to_le64(src_page->index);
108 
109 	req = skcipher_request_alloc(ctfm, GFP_NOIO);
110 	if (!req) {
111 		pr_err("alloc skcipher request failed!\n");
112 		return -ENOMEM;
113 	}
114 
115 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
116 			crypto_req_done, &wait);
117 	sg_init_table(&dst, 1);
118 	sg_set_page(&dst, dst_page, PAGE_SIZE, 0);
119 	sg_init_table(&src, 1);
120 	sg_set_page(&src, src_page, PAGE_SIZE, 0);
121 	skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, &iv);
122 	if (op == HP_DEV_ENCRYPT)
123 		ret = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
124 	else if (op == HP_DEV_DECRYPT)
125 		ret = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
126 	else
127 		BUG();
128 
129 	skcipher_request_free(req);
130 
131 	if (ret)
132 		pr_err("%scrypt failed!\n", op == HP_DEV_ENCRYPT ? "en" : "de");
133 
134 	return ret;
135 }
136 
soft_crypto_init(const u8 *key)137 static struct crypto_skcipher *soft_crypto_init(const u8 *key)
138 {
139 	char *cipher = HP_CIPHER_NAME;
140 	u32 key_len = HP_KEY_SIZE;
141 	struct crypto_skcipher *ctfm = NULL;
142 	int ret;
143 
144 	ctfm = crypto_alloc_skcipher(cipher, 0, 0);
145 	if (IS_ERR(ctfm)) {
146 		pr_err("alloc ctfm failed, ret = %ld!\n", PTR_ERR(ctfm));
147 		ctfm = NULL;
148 		goto err;
149 	}
150 	crypto_skcipher_clear_flags(ctfm, ~0);
151 	crypto_skcipher_set_flags(ctfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
152 	ret = crypto_skcipher_setkey(ctfm, key, key_len);
153 	if (ret) {
154 		pr_err("ctfm setkey failed, ret = %d!\n", ret);
155 		goto err;
156 	}
157 
158 	return ctfm;
159 err:
160 	if (ctfm)
161 		crypto_free_skcipher(ctfm);
162 
163 	return NULL;
164 }
165 
166 #ifdef CONFIG_BLK_INLINE_ENCRYPTION
inline_crypt_bio(struct blk_crypto_key *blk_key, struct bio *bio)167 void inline_crypt_bio(struct blk_crypto_key *blk_key, struct bio *bio)
168 {
169 	union hp_iv iv;
170 
171 	memset(&iv, 0, sizeof(union hp_iv));
172 	iv.index = cpu_to_le64(bio->bi_iter.bi_sector);
173 
174 	bio_crypt_set_ctx(bio, blk_key, iv.dun, GFP_NOIO);
175 }
176 
inline_crypto_init(const u8 *key)177 static struct blk_crypto_key *inline_crypto_init(const u8 *key)
178 {
179 	struct blk_crypto_key *blk_key = NULL;
180 	u32 dun_bytes = HP_IV_SIZE - sizeof(__le64);
181 	int ret;
182 
183 	blk_key = kzalloc(sizeof(struct blk_crypto_key), GFP_KERNEL);
184 	if (!blk_key) {
185 		pr_err("blk key alloc failed!\n");
186 		goto err;
187 	}
188 	ret = blk_crypto_init_key(blk_key, key, HP_CIPHER_MODE, dun_bytes, PAGE_SIZE);
189 	if (ret) {
190 		pr_err("blk key init failed, ret = %d!\n", ret);
191 		goto err;
192 	}
193 
194 	return blk_key;
195 err:
196 	if (blk_key)
197 		kfree_sensitive(blk_key);
198 
199 	return NULL;
200 }
201 #else
inline_crypt_bio(struct blk_crypto_key *blk_key, struct bio *bio)202 void inline_crypt_bio(struct blk_crypto_key *blk_key, struct bio *bio) {}
inline_crypto_init(const u8 *key)203 static struct blk_crypto_key *inline_crypto_init(const u8 *key)
204 {
205 	pr_err("CONFIG_BLK_INLINE_ENCRYPTION is not enabled!\n");
206 	return NULL;
207 }
208 #endif
209 
crypto_init(struct hp_device *dev, bool soft)210 bool crypto_init(struct hp_device *dev, bool soft)
211 {
212 	u8 key[HP_KEY_SIZE];
213 	bool ret = false;
214 
215 	get_random_bytes(key, HP_KEY_SIZE);
216 	if (soft) {
217 		dev->ctfm = soft_crypto_init(key);
218 		ret = dev->ctfm;
219 	} else {
220 		dev->blk_key = inline_crypto_init(key);
221 		ret = dev->blk_key;
222 		if (ret)
223 			pr_warn("soft crypt has been turned off, now apply hard crypt!\n");
224 	}
225 	memzero_explicit(key, HP_KEY_SIZE);
226 
227 	return ret;
228 }
229 
crypto_deinit(struct hp_device *dev)230 void crypto_deinit(struct hp_device *dev)
231 {
232 	if (dev->ctfm) {
233 		crypto_free_skcipher(dev->ctfm);
234 		dev->ctfm = NULL;
235 	}
236 	if (dev->blk_key) {
237 		kfree_sensitive(dev->blk_key);
238 		dev->blk_key = NULL;
239 	}
240 }
241