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

/**
23
 * dir_crypt_complete() -
24
 */
25
static void dir_crypt_complete(struct crypto_async_request *req, int res)
26
{
27
	struct fscrypt_completion_result *ecr = req->data;
28 29 30 31 32 33 34 35

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

/**
36
 * fname_encrypt() -
37 38 39 40 41
 *
 * 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.
 */
42 43
static int fname_encrypt(struct inode *inode,
			const struct qstr *iname, struct fscrypt_str *oname)
44 45
{
	u32 ciphertext_len;
H
Herbert Xu 已提交
46
	struct skcipher_request *req = NULL;
47 48
	DECLARE_FS_COMPLETION_RESULT(ecr);
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
49
	struct crypto_skcipher *tfm = ci->ci_ctfm;
50
	int res = 0;
51
	char iv[FS_CRYPTO_BLOCK_SIZE];
52
	struct scatterlist src_sg, dst_sg;
53
	int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK);
54
	char *workbuf, buf[32], *alloc_buf = NULL;
55
	unsigned lim;
56

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

61 62 63
	ciphertext_len = (iname->len < FS_CRYPTO_BLOCK_SIZE) ?
					FS_CRYPTO_BLOCK_SIZE : iname->len;
	ciphertext_len = size_round_up(ciphertext_len, padding);
64 65 66 67 68 69 70 71 72 73 74 75
	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 已提交
76
	req = skcipher_request_alloc(tfm, GFP_NOFS);
77 78 79 80 81 82
	if (!req) {
		printk_ratelimited(KERN_ERR
			"%s: crypto_request_alloc() failed\n", __func__);
		kfree(alloc_buf);
		return -ENOMEM;
	}
H
Herbert Xu 已提交
83
	skcipher_request_set_callback(req,
84
			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
85
			dir_crypt_complete, &ecr);
86 87 88 89 90 91 92

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

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

110 111 112 113 114
	oname->len = ciphertext_len;
	return res;
}

/*
115
 * fname_decrypt()
116 117 118 119 120
 *	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.
 */
121 122 123
static int fname_decrypt(struct inode *inode,
				const struct fscrypt_str *iname,
				struct fscrypt_str *oname)
124
{
H
Herbert Xu 已提交
125
	struct skcipher_request *req = NULL;
126
	DECLARE_FS_COMPLETION_RESULT(ecr);
127
	struct scatterlist src_sg, dst_sg;
128
	struct fscrypt_info *ci = inode->i_crypt_info;
H
Herbert Xu 已提交
129
	struct crypto_skcipher *tfm = ci->ci_ctfm;
130
	int res = 0;
131 132
	char iv[FS_CRYPTO_BLOCK_SIZE];
	unsigned lim;
133

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

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

	/* Initialize IV */
150
	memset(iv, 0, FS_CRYPTO_BLOCK_SIZE);
151 152 153 154

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

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

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

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

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

	if (ci)
231 232 233 234
		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);
235
}
236
EXPORT_SYMBOL(fscrypt_fname_encrypted_size);
237 238

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

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

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

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

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

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 307 308
		ret = digest_encode(iname->name, iname->len, oname->name);
		oname->len = ret;
		return ret;
	}
	if (hash) {
309 310 311
		memcpy(buf, &hash, 4);
		memcpy(buf + 4, &minor_hash, 4);
	} else {
312
		memset(buf, 0, 8);
313
	}
314 315 316 317 318 319
	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;
}
320
EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
321 322

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

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

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

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

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

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

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

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

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

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