crypto_fname.c 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/*
 * linux/fs/ext4/crypto_fname.c
 *
 * Copyright (C) 2015, Google, Inc.
 *
 * This contains functions for filename crypto management in ext4
 *
 * Written by Uday Savagaonkar, 2014.
 *
 * This has not yet undergone a rigorous security audit.
 *
 */

#include <crypto/hash.h>
#include <crypto/sha.h>
#include <keys/encrypted-type.h>
#include <keys/user-type.h>
#include <linux/crypto.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/key.h>
#include <linux/list.h>
#include <linux/mempool.h>
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <linux/spinlock_types.h>

#include "ext4.h"
#include "ext4_crypto.h"
#include "xattr.h"

/**
 * ext4_dir_crypt_complete() -
 */
static void ext4_dir_crypt_complete(struct crypto_async_request *req, int res)
{
	struct ext4_completion_result *ecr = req->data;

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

bool ext4_valid_filenames_enc_mode(uint32_t mode)
{
	return (mode == EXT4_ENCRYPTION_MODE_AES_256_CTS);
}

50 51 52 53 54 55
static unsigned max_name_len(struct inode *inode)
{
	return S_ISLNK(inode->i_mode) ? inode->i_sb->s_blocksize :
		EXT4_NAME_LEN;
}

56 57 58 59 60 61 62
/**
 * ext4_fname_encrypt() -
 *
 * 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.
 */
63
static int ext4_fname_encrypt(struct inode *inode,
64 65 66 67 68 69
			      const struct qstr *iname,
			      struct ext4_str *oname)
{
	u32 ciphertext_len;
	struct ablkcipher_request *req = NULL;
	DECLARE_EXT4_COMPLETION_RESULT(ecr);
70 71
	struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
	struct crypto_ablkcipher *tfm = ci->ci_ctfm;
72 73
	int res = 0;
	char iv[EXT4_CRYPTO_BLOCK_SIZE];
74
	struct scatterlist src_sg, dst_sg;
75
	int padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
76
	char *workbuf, buf[32], *alloc_buf = NULL;
77
	unsigned lim = max_name_len(inode);
78

79
	if (iname->len <= 0 || iname->len > lim)
80 81 82 83
		return -EIO;

	ciphertext_len = (iname->len < EXT4_CRYPTO_BLOCK_SIZE) ?
		EXT4_CRYPTO_BLOCK_SIZE : iname->len;
84
	ciphertext_len = ext4_fname_crypto_round_up(ciphertext_len, padding);
85 86
	ciphertext_len = (ciphertext_len > lim)
			? lim : ciphertext_len;
87

88 89 90 91 92 93 94 95 96
	if (ciphertext_len <= sizeof(buf)) {
		workbuf = buf;
	} else {
		alloc_buf = kmalloc(ciphertext_len, GFP_NOFS);
		if (!alloc_buf)
			return -ENOMEM;
		workbuf = alloc_buf;
	}

97 98 99 100 101
	/* Allocate request */
	req = ablkcipher_request_alloc(tfm, GFP_NOFS);
	if (!req) {
		printk_ratelimited(
		    KERN_ERR "%s: crypto_request_alloc() failed\n", __func__);
102
		kfree(alloc_buf);
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
		return -ENOMEM;
	}
	ablkcipher_request_set_callback(req,
		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
		ext4_dir_crypt_complete, &ecr);

	/* 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 */
	memset(iv, 0, EXT4_CRYPTO_BLOCK_SIZE);

	/* Create encryption request */
118 119 120
	sg_init_one(&src_sg, workbuf, ciphertext_len);
	sg_init_one(&dst_sg, oname->name, ciphertext_len);
	ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
121 122 123 124 125
	res = crypto_ablkcipher_encrypt(req);
	if (res == -EINPROGRESS || res == -EBUSY) {
		wait_for_completion(&ecr.completion);
		res = ecr.res;
	}
126
	kfree(alloc_buf);
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	ablkcipher_request_free(req);
	if (res < 0) {
		printk_ratelimited(
		    KERN_ERR "%s: Error (error code %d)\n", __func__, res);
	}
	oname->len = ciphertext_len;
	return res;
}

/*
 * ext4_fname_decrypt()
 *	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.
 */
143
static int ext4_fname_decrypt(struct inode *inode,
144 145 146 147 148 149
			      const struct ext4_str *iname,
			      struct ext4_str *oname)
{
	struct ext4_str tmp_in[2], tmp_out[1];
	struct ablkcipher_request *req = NULL;
	DECLARE_EXT4_COMPLETION_RESULT(ecr);
150
	struct scatterlist src_sg, dst_sg;
151 152
	struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
	struct crypto_ablkcipher *tfm = ci->ci_ctfm;
153 154
	int res = 0;
	char iv[EXT4_CRYPTO_BLOCK_SIZE];
155
	unsigned lim = max_name_len(inode);
156

157
	if (iname->len <= 0 || iname->len > lim)
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
		return -EIO;

	tmp_in[0].name = iname->name;
	tmp_in[0].len = iname->len;
	tmp_out[0].name = oname->name;

	/* Allocate request */
	req = ablkcipher_request_alloc(tfm, GFP_NOFS);
	if (!req) {
		printk_ratelimited(
		    KERN_ERR "%s: crypto_request_alloc() failed\n",  __func__);
		return -ENOMEM;
	}
	ablkcipher_request_set_callback(req,
		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
		ext4_dir_crypt_complete, &ecr);

	/* Initialize IV */
	memset(iv, 0, EXT4_CRYPTO_BLOCK_SIZE);

	/* Create encryption request */
179 180 181
	sg_init_one(&src_sg, iname->name, iname->len);
	sg_init_one(&dst_sg, oname->name, oname->len);
	ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
	res = crypto_ablkcipher_decrypt(req);
	if (res == -EINPROGRESS || res == -EBUSY) {
		wait_for_completion(&ecr.completion);
		res = ecr.res;
	}
	ablkcipher_request_free(req);
	if (res < 0) {
		printk_ratelimited(
		    KERN_ERR "%s: Error in ext4_fname_encrypt (error code %d)\n",
		    __func__, res);
		return res;
	}

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

199 200 201
static const char *lookup_table =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";

202 203 204 205 206 207
/**
 * ext4_fname_encode_digest() -
 *
 * 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.
 */
208
static int digest_encode(const char *src, int len, char *dst)
209
{
210 211 212 213 214 215 216 217 218 219 220
	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);
221 222
		i++;
	}
223 224 225
	if (bits)
		*cp++ = lookup_table[ac & 0x3f];
	return cp - dst;
226 227
}

228
static int digest_decode(const char *src, int len, char *dst)
229
{
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
	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++;
246
	}
247 248 249
	if (ac)
		return -1;
	return cp - dst;
250 251 252 253 254 255 256 257 258 259 260 261
}

/**
 * ext4_fname_crypto_round_up() -
 *
 * Return: The next multiple of block size
 */
u32 ext4_fname_crypto_round_up(u32 size, u32 blksize)
{
	return ((size+blksize-1)/blksize)*blksize;
}

262 263 264 265 266 267 268 269 270 271 272 273 274 275
unsigned ext4_fname_encrypted_size(struct inode *inode, u32 ilen)
{
	struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
	int padding = 32;

	if (ci)
		padding = 4 << (ci->ci_flags & EXT4_POLICY_FLAGS_PAD_MASK);
	if (ilen < EXT4_CRYPTO_BLOCK_SIZE)
		ilen = EXT4_CRYPTO_BLOCK_SIZE;
	return ext4_fname_crypto_round_up(ilen, padding);
}

/*
 * ext4_fname_crypto_alloc_buffer() -
276 277 278 279
 *
 * Allocates an output buffer that is sufficient for the crypto operation
 * specified by the context and the direction.
 */
280
int ext4_fname_crypto_alloc_buffer(struct inode *inode,
281 282
				   u32 ilen, struct ext4_str *crypto_str)
{
283
	unsigned int olen = ext4_fname_encrypted_size(inode, ilen);
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311

	crypto_str->len = olen;
	if (olen < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2)
		olen = EXT4_FNAME_CRYPTO_DIGEST_SIZE*2;
	/* Allocated buffer can hold one more character to null-terminate the
	 * string */
	crypto_str->name = kmalloc(olen+1, GFP_NOFS);
	if (!(crypto_str->name))
		return -ENOMEM;
	return 0;
}

/**
 * ext4_fname_crypto_free_buffer() -
 *
 * Frees the buffer allocated for crypto operation.
 */
void ext4_fname_crypto_free_buffer(struct ext4_str *crypto_str)
{
	if (!crypto_str)
		return;
	kfree(crypto_str->name);
	crypto_str->name = NULL;
}

/**
 * ext4_fname_disk_to_usr() - converts a filename from disk space to user space
 */
312
int _ext4_fname_disk_to_usr(struct inode *inode,
313 314 315
			    struct dx_hash_info *hinfo,
			    const struct ext4_str *iname,
			    struct ext4_str *oname)
316
{
317 318 319
	char buf[24];
	int ret;

320 321 322 323 324 325 326 327 328
	if (iname->len < 3) {
		/*Check for . and .. */
		if (iname->name[0] == '.' && iname->name[iname->len-1] == '.') {
			oname->name[0] = '.';
			oname->name[iname->len-1] = '.';
			oname->len = iname->len;
			return oname->len;
		}
	}
329 330 331 332
	if (iname->len < EXT4_CRYPTO_BLOCK_SIZE) {
		EXT4_ERROR_INODE(inode, "encrypted inode too small");
		return -EUCLEAN;
	}
333 334
	if (EXT4_I(inode)->i_crypt_info)
		return ext4_fname_decrypt(inode, iname, oname);
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350

	if (iname->len <= EXT4_FNAME_CRYPTO_DIGEST_SIZE) {
		ret = digest_encode(iname->name, iname->len, oname->name);
		oname->len = ret;
		return ret;
	}
	if (hinfo) {
		memcpy(buf, &hinfo->hash, 4);
		memcpy(buf+4, &hinfo->minor_hash, 4);
	} else
		memset(buf, 0, 8);
	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;
351 352
}

353
int ext4_fname_disk_to_usr(struct inode *inode,
354
			   struct dx_hash_info *hinfo,
355 356 357 358 359 360
			   const struct ext4_dir_entry_2 *de,
			   struct ext4_str *oname)
{
	struct ext4_str iname = {.name = (unsigned char *) de->name,
				 .len = de->name_len };

361
	return _ext4_fname_disk_to_usr(inode, hinfo, &iname, oname);
362 363 364 365 366 367
}


/**
 * ext4_fname_usr_to_disk() - converts a filename from user space to disk space
 */
368
int ext4_fname_usr_to_disk(struct inode *inode,
369 370 371 372
			   const struct qstr *iname,
			   struct ext4_str *oname)
{
	int res;
373
	struct ext4_crypt_info *ci = EXT4_I(inode)->i_crypt_info;
374 375 376 377 378 379 380 381 382 383 384

	if (iname->len < 3) {
		/*Check for . and .. */
		if (iname->name[0] == '.' &&
				iname->name[iname->len-1] == '.') {
			oname->name[0] = '.';
			oname->name[iname->len-1] = '.';
			oname->len = iname->len;
			return oname->len;
		}
	}
385 386
	if (ci) {
		res = ext4_fname_encrypt(inode, iname, oname);
387 388 389 390 391 392 393 394
		return res;
	}
	/* Without a proper key, a user is not allowed to modify the filenames
	 * in a directory. Consequently, a user space name cannot be mapped to
	 * a disk-space name */
	return -EACCES;
}

395 396
int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
			      int lookup, struct ext4_filename *fname)
397
{
398
	struct ext4_crypt_info *ci;
399 400 401 402
	int ret = 0, bigname = 0;

	memset(fname, 0, sizeof(struct ext4_filename));
	fname->usr_fname = iname;
403

404
	if (!ext4_encrypted_inode(dir) ||
405 406 407
	    ((iname->name[0] == '.') &&
	     ((iname->len == 1) ||
	      ((iname->name[1] == '.') && (iname->len == 2))))) {
408 409
		fname->disk_name.name = (unsigned char *) iname->name;
		fname->disk_name.len = iname->len;
410
		return 0;
411
	}
412
	ret = ext4_get_encryption_info(dir);
413 414 415 416 417
	if (ret)
		return ret;
	ci = EXT4_I(dir)->i_crypt_info;
	if (ci) {
		ret = ext4_fname_crypto_alloc_buffer(dir, iname->len,
418 419
						     &fname->crypto_buf);
		if (ret < 0)
420
			return ret;
421
		ret = ext4_fname_encrypt(dir, iname, &fname->crypto_buf);
422
		if (ret < 0)
423
			goto errout;
424 425
		fname->disk_name.name = fname->crypto_buf.name;
		fname->disk_name.len = fname->crypto_buf.len;
426
		return 0;
427
	}
428 429
	if (!lookup)
		return -EACCES;
430

431 432 433 434 435 436
	/* We don't have the key and we are doing a lookup; decode the
	 * user-supplied name
	 */
	if (iname->name[0] == '_')
		bigname = 1;
	if ((bigname && (iname->len != 33)) ||
437 438 439
	    (!bigname && (iname->len > 43)))
		return -ENOENT;

440
	fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
441 442
	if (fname->crypto_buf.name == NULL)
		return -ENOMEM;
443 444 445 446
	ret = digest_decode(iname->name + bigname, iname->len - bigname,
			    fname->crypto_buf.name);
	if (ret < 0) {
		ret = -ENOENT;
447
		goto errout;
448 449 450 451 452 453 454 455 456
	}
	fname->crypto_buf.len = ret;
	if (bigname) {
		memcpy(&fname->hinfo.hash, fname->crypto_buf.name, 4);
		memcpy(&fname->hinfo.minor_hash, fname->crypto_buf.name + 4, 4);
	} else {
		fname->disk_name.name = fname->crypto_buf.name;
		fname->disk_name.len = fname->crypto_buf.len;
	}
457 458 459 460
	return 0;
errout:
	kfree(fname->crypto_buf.name);
	fname->crypto_buf.name = NULL;
461 462 463
	return ret;
}

464
void ext4_fname_free_filename(struct ext4_filename *fname)
465
{
466 467 468 469
	kfree(fname->crypto_buf.name);
	fname->crypto_buf.name = NULL;
	fname->usr_fname = NULL;
	fname->disk_name.name = NULL;
470
}