blob: 9523c355ca30aba9b132a0682472354d3ac885d0 [file] [log] [blame]
Neeraj Soni36c65122018-04-18 21:04:46 +05301/*
2 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/*
15 * Per-File-Key (PFK) - f2fs
16 *
17 * This driver is used for working with EXT4/F2FS crypt extension
18 *
19 * The key information is stored in node by EXT4/F2FS when file is first opened
20 * and will be later accessed by Block Device Driver to actually load the key
21 * to encryption hw.
22 *
23 * PFK exposes API's for loading and removing keys from encryption hw
24 * and also API to determine whether 2 adjacent blocks can be agregated by
25 * Block Layer in one request to encryption hw.
26 *
27 */
28
29
30/* Uncomment the line below to enable debug messages */
31#define DEBUG 1
32#define pr_fmt(fmt) "pfk_f2fs [%s]: " fmt, __func__
33
34#include <linux/module.h>
35#include <linux/fs.h>
36#include <linux/errno.h>
37#include <linux/printk.h>
38
39#include "fscrypt_ice.h"
40#include "pfk_f2fs.h"
41
42static bool pfk_f2fs_ready;
43
44/*
45 * pfk_f2fs_deinit() - Deinit function, should be invoked by upper PFK layer
46 */
47void pfk_f2fs_deinit(void)
48{
49 pfk_f2fs_ready = false;
50}
51
52/*
53 * pfk_f2fs_init() - Init function, should be invoked by upper PFK layer
54 */
55int __init pfk_f2fs_init(void)
56{
57 pfk_f2fs_ready = true;
58 pr_info("PFK F2FS inited successfully\n");
59
60 return 0;
61}
62
63/**
64 * pfk_f2fs_is_ready() - driver is initialized and ready.
65 *
66 * Return: true if the driver is ready.
67 */
68static inline bool pfk_f2fs_is_ready(void)
69{
70 return pfk_f2fs_ready;
71}
72
73/**
74 * pfk_is_f2fs_type() - return true if inode belongs to ICE F2FS PFE
75 * @inode: inode pointer
76 */
77bool pfk_is_f2fs_type(const struct inode *inode)
78{
79 if (!pfe_is_inode_filesystem_type(inode, "f2fs"))
80 return false;
81
82 return fscrypt_should_be_processed_by_ice(inode);
83}
84
85/**
86 * pfk_f2fs_parse_cipher() - parse cipher from inode to enum
87 * @inode: inode
88 * @algo: pointer to store the output enum (can be null)
89 *
90 * return 0 in case of success, error otherwise (i.e not supported cipher)
91 */
92static int pfk_f2fs_parse_cipher(const struct inode *inode,
93 enum ice_cryto_algo_mode *algo)
94{
95 /*
96 * currently only AES XTS algo is supported
97 * in the future, table with supported ciphers might
98 * be introduced
99 */
100 if (!inode)
101 return -EINVAL;
102
103 if (!fscrypt_is_aes_xts_cipher(inode)) {
104 pr_err("f2fs alghoritm is not supported by pfk\n");
105 return -EINVAL;
106 }
107
108 if (algo)
109 *algo = ICE_CRYPTO_ALGO_MODE_AES_XTS;
110
111 return 0;
112}
113
114
115int pfk_f2fs_parse_inode(const struct bio *bio,
116 const struct inode *inode,
117 struct pfk_key_info *key_info,
118 enum ice_cryto_algo_mode *algo,
Neeraj Soniefb33112018-08-17 20:39:35 +0530119 bool *is_pfe,
Neeraj Soniefb33112018-08-17 20:39:35 +0530120 const char *storage_type)
Neeraj Soni36c65122018-04-18 21:04:46 +0530121{
122 int ret = 0;
123
124 if (!is_pfe)
125 return -EINVAL;
126
127 /*
128 * only a few errors below can indicate that
129 * this function was not invoked within PFE context,
130 * otherwise we will consider it PFE
131 */
132 *is_pfe = true;
133
Neeraj Soni36c65122018-04-18 21:04:46 +0530134 if (!pfk_f2fs_is_ready())
135 return -ENODEV;
136
137 if (!inode)
138 return -EINVAL;
139
140 if (!key_info)
141 return -EINVAL;
142
143 key_info->key = fscrypt_get_ice_encryption_key(inode);
144 if (!key_info->key) {
145 pr_err("could not parse key from f2fs\n");
146 return -EINVAL;
147 }
148
149 key_info->key_size = fscrypt_get_ice_encryption_key_size(inode);
150 if (!key_info->key_size) {
151 pr_err("could not parse key size from f2fs\n");
152 return -EINVAL;
153 }
154
155 key_info->salt = fscrypt_get_ice_encryption_salt(inode);
156 if (!key_info->salt) {
157 pr_err("could not parse salt from f2fs\n");
158 return -EINVAL;
159 }
160
161 key_info->salt_size = fscrypt_get_ice_encryption_salt_size(inode);
162 if (!key_info->salt_size) {
163 pr_err("could not parse salt size from f2fs\n");
164 return -EINVAL;
165 }
166
167 ret = pfk_f2fs_parse_cipher(inode, algo);
168 if (ret != 0) {
169 pr_err("not supported cipher\n");
170 return ret;
171 }
172
173 return 0;
174}
175
176bool pfk_f2fs_allow_merge_bio(const struct bio *bio1,
177 const struct bio *bio2, const struct inode *inode1,
178 const struct inode *inode2)
179{
180 bool mergeable;
181
182 /* if there is no f2fs pfk, don't disallow merging blocks */
183 if (!pfk_f2fs_is_ready())
184 return true;
185
186 if (!inode1 || !inode2)
187 return false;
188
189 mergeable = fscrypt_is_ice_encryption_info_equal(inode1, inode2);
190 if (!mergeable)
191 return false;
192
193
194 /* ICE allows only consecutive iv_key stream. */
195 if (!bio_dun(bio1) && !bio_dun(bio2))
196 return true;
197 else if (!bio_dun(bio1) || !bio_dun(bio2))
198 return false;
199
200 return bio_end_dun(bio1) == bio_dun(bio2);
201}