fname.c 10.6 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
static u32 size_round_up(size_t size, size_t blksize)
{
	return ((size + blksize - 1) / blksize) * blksize;
}
21 22

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

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

/**
38
 * fname_encrypt() -
39 40 41 42 43
 *
 * This function encrypts the input filename, and returns the length of the
 * ciphertext. Errors are returned as negative numbers.  We trust the caller to
 * allocate sufficient memory to oname string.
 */
44 45
static int fname_encrypt(struct inode *inode,
			const struct qstr *iname, struct fscrypt_str *oname)
46 47
{
	u32 ciphertext_len;
H
Herbert Xu 已提交
48
	struct skcipher_request *req = NULL;
49 50
	DECLARE_FS_COMPLETION_RESULT(ecr);
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
51
	struct crypto_skcipher *tfm = ci->ci_ctfm;
52
	int res = 0;
53
	char iv[FS_CRYPTO_BLOCK_SIZE];
54
	struct scatterlist src_sg, dst_sg;
55
	int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
56
	char *workbuf, buf[32], *alloc_buf = NULL;
57
	unsigned lim;
58

59
	lim = inode->i_sb->s_cop->max_namelen(inode);
60 61 62
	if (iname->len <= 0 || iname->len > lim)
		return -EIO;

63 64 65
	ciphertext_len = (iname->len < FS_CRYPTO_BLOCK_SIZE) ?
					FS_CRYPTO_BLOCK_SIZE : iname->len;
	ciphertext_len = size_round_up(ciphertext_len, padding);
66 67 68 69 70 71 72 73 74 75 76 77
	ciphertext_len = (ciphertext_len > lim) ? lim : ciphertext_len;

	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 已提交
78
	req = skcipher_request_alloc(tfm, GFP_NOFS);
79 80 81 82 83 84
	if (!req) {
		printk_ratelimited(KERN_ERR
			"%s: crypto_request_alloc() failed\n", __func__);
		kfree(alloc_buf);
		return -ENOMEM;
	}
H
Herbert Xu 已提交
85
	skcipher_request_set_callback(req,
86
			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
87
			fname_crypt_complete, &ecr);
88 89 90 91 92 93 94

	/* 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 */
95
	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
96 97 98 99

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

112 113 114 115 116
	oname->len = ciphertext_len;
	return res;
}

/*
117
 * fname_decrypt()
118 119 120 121 122
 *	This function decrypts the input filename, and returns
 *	the length of the plaintext.
 *	Errors are returned as negative numbers.
 *	We trust the caller to allocate sufficient memory to oname string.
 */
123 124 125
static int fname_decrypt(struct inode *inode,
				const struct fscrypt_str *iname,
				struct fscrypt_str *oname)
126
{
H
Herbert Xu 已提交
127
	struct skcipher_request *req = NULL;
128
	DECLARE_FS_COMPLETION_RESULT(ecr);
129
	struct scatterlist src_sg, dst_sg;
130
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
131
	struct crypto_skcipher *tfm = ci->ci_ctfm;
132
	int res = 0;
133 134
	char iv[FS_CRYPTO_BLOCK_SIZE];
	unsigned lim;
135

136
	lim = inode->i_sb->s_cop->max_namelen(inode);
137 138 139 140
	if (iname->len <= 0 || iname->len > lim)
		return -EIO;

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

	/* Initialize IV */
152
	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
153 154 155 156

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

	oname->len = strnlen(oname->name, iname->len);
	return oname->len;
}

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

/**
178
 * digest_encode() -
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 223 224 225 226
 *
 * 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;
}

227
u32 fscrypt_fname_encrypted_size(struct inode *inode, u32 ilen)
228
{
229
	int padding = 32;
230
	struct fscrypt_info *ci = inode->i_crypt_info;
231 232

	if (ci)
233 234 235 236
		padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
	if (ilen < FS_CRYPTO_BLOCK_SIZE)
		ilen = FS_CRYPTO_BLOCK_SIZE;
	return size_round_up(ilen, padding);
237
}
238
EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
239 240

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

	crypto_str->len = olen;
252 253 254 255 256 257
	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
	 */
258 259 260 261 262
	crypto_str->name = kmalloc(olen + 1, GFP_NOFS);
	if (!(crypto_str->name))
		return -ENOMEM;
	return 0;
}
263
EXPORT_SYMBOL(fscrypt_fname_alloc_buffer);
264 265

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

/**
280 281
 * fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
 * space
282
 */
283 284 285 286
int fscrypt_fname_disk_to_usr(struct inode *inode,
			u32 hash, u32 minor_hash,
			const struct fscrypt_str *iname,
			struct fscrypt_str *oname)
287 288 289 290 291
{
	const struct qstr qname = FSTR_TO_QSTR(iname);
	char buf[24];
	int ret;

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

299
	if (iname->len < FS_CRYPTO_BLOCK_SIZE)
300
		return -EUCLEAN;
301

302 303 304 305
	if (inode->i_crypt_info)
		return fname_decrypt(inode, iname, oname);

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

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

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

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

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

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

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

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

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

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

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