fname.c 10.5 KB
Newer Older
1
/*
2
 * This contains functions for filename crypto management
3 4 5 6 7
 *
 * Copyright (C) 2015, Google, Inc.
 * Copyright (C) 2015, Motorola Mobility
 *
 * Written by Uday Savagaonkar, 2014.
8
 * Modified by Jaegeuk Kim, 2015.
9 10 11
 *
 * This has not yet undergone a rigorous security audit.
 */
12

13 14
#include <linux/scatterlist.h>
#include <linux/ratelimit.h>
15
#include <linux/fscrypto.h>
16 17

/**
18 19 20
 * fname_crypt_complete() - completion callback for filename crypto
 * @req: The asynchronous cipher request context
 * @res: The result of the cipher operation
21
 */
22
static void fname_crypt_complete(struct crypto_async_request *req, int res)
23
{
24
	struct fscrypt_completion_result *ecr = req->data;
25 26 27 28 29 30 31 32

	if (res == -EINPROGRESS)
		return;
	ecr->res = res;
	complete(&ecr->completion);
}

/**
33
 * fname_encrypt() - encrypt a filename
34
 *
35 36 37
 * The caller must have allocated sufficient memory for the @oname string.
 *
 * Return: 0 on success, -errno on failure
38
 */
39 40
static int fname_encrypt(struct inode *inode,
			const struct qstr *iname, struct fscrypt_str *oname)
41 42
{
	u32 ciphertext_len;
H
Herbert Xu 已提交
43
	struct skcipher_request *req = NULL;
44 45
	DECLARE_FS_COMPLETION_RESULT(ecr);
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
46
	struct crypto_skcipher *tfm = ci->ci_ctfm;
47
	int res = 0;
48
	char iv[FS_CRYPTO_BLOCK_SIZE];
49
	struct scatterlist src_sg, dst_sg;
50
	int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
51
	char *workbuf, buf[32], *alloc_buf = NULL;
52
	unsigned lim;
53

54
	lim = inode->i_sb->s_cop->max_namelen(inode);
55 56 57
	if (iname->len <= 0 || iname->len > lim)
		return -EIO;

58 59 60
	ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE);
	ciphertext_len = round_up(ciphertext_len, padding);
	ciphertext_len = min(ciphertext_len, lim);
61 62 63 64 65 66 67 68 69 70 71

	if (ciphertext_len <= sizeof(buf)) {
		workbuf = buf;
	} else {
		alloc_buf = kmalloc(ciphertext_len, GFP_NOFS);
		if (!alloc_buf)
			return -ENOMEM;
		workbuf = alloc_buf;
	}

	/* Allocate request */
H
Herbert Xu 已提交
72
	req = skcipher_request_alloc(tfm, GFP_NOFS);
73 74 75 76 77 78
	if (!req) {
		printk_ratelimited(KERN_ERR
			"%s: crypto_request_alloc() failed\n", __func__);
		kfree(alloc_buf);
		return -ENOMEM;
	}
H
Herbert Xu 已提交
79
	skcipher_request_set_callback(req,
80
			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
81
			fname_crypt_complete, &ecr);
82 83 84 85 86 87 88

	/* Copy the input */
	memcpy(workbuf, iname->name, iname->len);
	if (iname->len < ciphertext_len)
		memset(workbuf + iname->len, 0, ciphertext_len - iname->len);

	/* Initialize IV */
89
	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
90 91 92 93

	/* Create encryption request */
	sg_init_one(&src_sg, workbuf, ciphertext_len);
	sg_init_one(&dst_sg, oname->name, ciphertext_len);
H
Herbert Xu 已提交
94 95
	skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
	res = crypto_skcipher_encrypt(req);
96 97 98 99 100
	if (res == -EINPROGRESS || res == -EBUSY) {
		wait_for_completion(&ecr.completion);
		res = ecr.res;
	}
	kfree(alloc_buf);
H
Herbert Xu 已提交
101
	skcipher_request_free(req);
102
	if (res < 0) {
103 104
		printk_ratelimited(KERN_ERR
				"%s: Error (error code %d)\n", __func__, res);
105 106
		return res;
	}
107

108
	oname->len = ciphertext_len;
109
	return 0;
110 111
}

112 113 114 115 116 117
/**
 * fname_decrypt() - decrypt a filename
 *
 * The caller must have allocated sufficient memory for the @oname string.
 *
 * Return: 0 on success, -errno on failure
118
 */
119 120 121
static int fname_decrypt(struct inode *inode,
				const struct fscrypt_str *iname,
				struct fscrypt_str *oname)
122
{
H
Herbert Xu 已提交
123
	struct skcipher_request *req = NULL;
124
	DECLARE_FS_COMPLETION_RESULT(ecr);
125
	struct scatterlist src_sg, dst_sg;
126
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
127
	struct crypto_skcipher *tfm = ci->ci_ctfm;
128
	int res = 0;
129 130
	char iv[FS_CRYPTO_BLOCK_SIZE];
	unsigned lim;
131

132
	lim = inode->i_sb->s_cop->max_namelen(inode);
133 134 135 136
	if (iname->len <= 0 || iname->len > lim)
		return -EIO;

	/* Allocate request */
H
Herbert Xu 已提交
137
	req = skcipher_request_alloc(tfm, GFP_NOFS);
138 139 140 141 142
	if (!req) {
		printk_ratelimited(KERN_ERR
			"%s: crypto_request_alloc() failed\n",  __func__);
		return -ENOMEM;
	}
H
Herbert Xu 已提交
143
	skcipher_request_set_callback(req,
144
		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
145
		fname_crypt_complete, &ecr);
146 147

	/* Initialize IV */
148
	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
149 150 151 152

	/* Create decryption request */
	sg_init_one(&src_sg, iname->name, iname->len);
	sg_init_one(&dst_sg, oname->name, oname->len);
H
Herbert Xu 已提交
153 154
	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
	res = crypto_skcipher_decrypt(req);
155 156 157 158
	if (res == -EINPROGRESS || res == -EBUSY) {
		wait_for_completion(&ecr.completion);
		res = ecr.res;
	}
H
Herbert Xu 已提交
159
	skcipher_request_free(req);
160 161
	if (res < 0) {
		printk_ratelimited(KERN_ERR
162
				"%s: Error (error code %d)\n", __func__, res);
163 164 165 166
		return res;
	}

	oname->len = strnlen(oname->name, iname->len);
167
	return 0;
168 169 170 171 172 173
}

static const char *lookup_table =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";

/**
174
 * digest_encode() -
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
 *
 * Encodes the input digest using characters from the set [a-zA-Z0-9_+].
 * The encoded string is roughly 4/3 times the size of the input string.
 */
static int digest_encode(const char *src, int len, char *dst)
{
	int i = 0, bits = 0, ac = 0;
	char *cp = dst;

	while (i < len) {
		ac += (((unsigned char) src[i]) << bits);
		bits += 8;
		do {
			*cp++ = lookup_table[ac & 0x3f];
			ac >>= 6;
			bits -= 6;
		} while (bits >= 6);
		i++;
	}
	if (bits)
		*cp++ = lookup_table[ac & 0x3f];
	return cp - dst;
}

static int digest_decode(const char *src, int len, char *dst)
{
	int i = 0, bits = 0, ac = 0;
	const char *p;
	char *cp = dst;

	while (i < len) {
		p = strchr(lookup_table, src[i]);
		if (p == NULL || src[i] == 0)
			return -2;
		ac += (p - lookup_table) << bits;
		bits += 6;
		if (bits >= 8) {
			*cp++ = ac & 0xff;
			ac >>= 8;
			bits -= 8;
		}
		i++;
	}
	if (ac)
		return -1;
	return cp - dst;
}

223
u32 fscrypt_fname_encrypted_size(struct inode *inode, u32 ilen)
224
{
225
	int padding = 32;
226
	struct fscrypt_info *ci = inode->i_crypt_info;
227 228

	if (ci)
229
		padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
230 231
	ilen = max(ilen, (u32)FS_CRYPTO_BLOCK_SIZE);
	return round_up(ilen, padding);
232
}
233
EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
234 235

/**
236
 * fscrypt_fname_crypto_alloc_obuff() -
237 238 239 240
 *
 * Allocates an output buffer that is sufficient for the crypto operation
 * specified by the context and the direction.
 */
241 242
int fscrypt_fname_alloc_buffer(struct inode *inode,
				u32 ilen, struct fscrypt_str *crypto_str)
243
{
244
	unsigned int olen = fscrypt_fname_encrypted_size(inode, ilen);
245 246

	crypto_str->len = olen;
247 248 249 250 251 252
	if (olen < FS_FNAME_CRYPTO_DIGEST_SIZE * 2)
		olen = FS_FNAME_CRYPTO_DIGEST_SIZE * 2;
	/*
	 * Allocated buffer can hold one more character to null-terminate the
	 * string
	 */
253 254 255 256 257
	crypto_str->name = kmalloc(olen + 1, GFP_NOFS);
	if (!(crypto_str->name))
		return -ENOMEM;
	return 0;
}
258
EXPORT_SYMBOL(fscrypt_fname_alloc_buffer);
259 260

/**
261
 * fscrypt_fname_crypto_free_buffer() -
262 263 264
 *
 * Frees the buffer allocated for crypto operation.
 */
265
void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
266 267 268 269 270 271
{
	if (!crypto_str)
		return;
	kfree(crypto_str->name);
	crypto_str->name = NULL;
}
272
EXPORT_SYMBOL(fscrypt_fname_free_buffer);
273 274

/**
275 276
 * fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
 * space
277 278 279 280
 *
 * The caller must have allocated sufficient memory for the @oname string.
 *
 * Return: 0 on success, -errno on failure
281
 */
282 283 284 285
int fscrypt_fname_disk_to_usr(struct inode *inode,
			u32 hash, u32 minor_hash,
			const struct fscrypt_str *iname,
			struct fscrypt_str *oname)
286 287 288 289
{
	const struct qstr qname = FSTR_TO_QSTR(iname);
	char buf[24];

290
	if (fscrypt_is_dot_dotdot(&qname)) {
291 292 293
		oname->name[0] = '.';
		oname->name[iname->len - 1] = '.';
		oname->len = iname->len;
294
		return 0;
295 296
	}

297
	if (iname->len < FS_CRYPTO_BLOCK_SIZE)
298
		return -EUCLEAN;
299

300 301 302 303
	if (inode->i_crypt_info)
		return fname_decrypt(inode, iname, oname);

	if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) {
304 305 306
		oname->len = digest_encode(iname->name, iname->len,
					   oname->name);
		return 0;
307 308
	}
	if (hash) {
309 310 311
		memcpy(buf, &hash, 4);
		memcpy(buf + 4, &minor_hash, 4);
	} else {
312
		memset(buf, 0, 8);
313
	}
314 315
	memcpy(buf + 8, iname->name + iname->len - 16, 16);
	oname->name[0] = '_';
316 317
	oname->len = 1 + digest_encode(buf, 24, oname->name + 1);
	return 0;
318
}
319
EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
320 321

/**
322 323
 * fscrypt_fname_usr_to_disk() - converts a filename from user space to disk
 * space
324 325 326 327
 *
 * The caller must have allocated sufficient memory for the @oname string.
 *
 * Return: 0 on success, -errno on failure
328
 */
329
int fscrypt_fname_usr_to_disk(struct inode *inode,
330
			const struct qstr *iname,
331
			struct fscrypt_str *oname)
332
{
333
	if (fscrypt_is_dot_dotdot(iname)) {
334 335 336
		oname->name[0] = '.';
		oname->name[iname->len - 1] = '.';
		oname->len = iname->len;
337
		return 0;
338
	}
339 340 341 342
	if (inode->i_crypt_info)
		return fname_encrypt(inode, iname, oname);
	/*
	 * Without a proper key, a user is not allowed to modify the filenames
343
	 * in a directory. Consequently, a user space name cannot be mapped to
344 345
	 * a disk-space name
	 */
346 347
	return -EACCES;
}
348
EXPORT_SYMBOL(fscrypt_fname_usr_to_disk);
349

350 351
int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
			      int lookup, struct fscrypt_name *fname)
352 353 354
{
	int ret = 0, bigname = 0;

355
	memset(fname, 0, sizeof(struct fscrypt_name));
356 357
	fname->usr_fname = iname;

358 359
	if (!dir->i_sb->s_cop->is_encrypted(dir) ||
				fscrypt_is_dot_dotdot(iname)) {
360 361
		fname->disk_name.name = (unsigned char *)iname->name;
		fname->disk_name.len = iname->len;
362
		return 0;
363
	}
364 365
	ret = get_crypt_info(dir);
	if (ret && ret != -EOPNOTSUPP)
366
		return ret;
367 368 369 370

	if (dir->i_crypt_info) {
		ret = fscrypt_fname_alloc_buffer(dir, iname->len,
							&fname->crypto_buf);
371
		if (ret)
372
			return ret;
373
		ret = fname_encrypt(dir, iname, &fname->crypto_buf);
374
		if (ret)
375
			goto errout;
376 377
		fname->disk_name.name = fname->crypto_buf.name;
		fname->disk_name.len = fname->crypto_buf.len;
378
		return 0;
379
	}
380 381
	if (!lookup)
		return -EACCES;
382

383 384
	/*
	 * We don't have the key and we are doing a lookup; decode the
385 386 387 388
	 * user-supplied name
	 */
	if (iname->name[0] == '_')
		bigname = 1;
389
	if ((bigname && (iname->len != 33)) || (!bigname && (iname->len > 43)))
390 391
		return -ENOENT;

392
	fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
393 394
	if (fname->crypto_buf.name == NULL)
		return -ENOMEM;
395

396 397 398 399
	ret = digest_decode(iname->name + bigname, iname->len - bigname,
				fname->crypto_buf.name);
	if (ret < 0) {
		ret = -ENOENT;
400
		goto errout;
401 402 403 404
	}
	fname->crypto_buf.len = ret;
	if (bigname) {
		memcpy(&fname->hash, fname->crypto_buf.name, 4);
405
		memcpy(&fname->minor_hash, fname->crypto_buf.name + 4, 4);
406 407 408 409
	} else {
		fname->disk_name.name = fname->crypto_buf.name;
		fname->disk_name.len = fname->crypto_buf.len;
	}
410
	return 0;
411

412
errout:
413
	fscrypt_fname_free_buffer(&fname->crypto_buf);
414 415
	return ret;
}
416
EXPORT_SYMBOL(fscrypt_setup_filename);
417

418
void fscrypt_free_filename(struct fscrypt_name *fname)
419 420 421 422 423 424
{
	kfree(fname->crypto_buf.name);
	fname->crypto_buf.name = NULL;
	fname->usr_fname = NULL;
	fname->disk_name.name = NULL;
}
425
EXPORT_SYMBOL(fscrypt_free_filename);