brintos

brintos / linux-shallow public Read only

0
0
Text · 20.7 KiB · 0ad52fb Raw
621 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * This contains functions for filename crypto management4 *5 * Copyright (C) 2015, Google, Inc.6 * Copyright (C) 2015, Motorola Mobility7 *8 * Written by Uday Savagaonkar, 2014.9 * Modified by Jaegeuk Kim, 2015.10 *11 * This has not yet undergone a rigorous security audit.12 */13 14#include <linux/namei.h>15#include <linux/scatterlist.h>16#include <crypto/hash.h>17#include <crypto/sha2.h>18#include <crypto/skcipher.h>19#include "fscrypt_private.h"20 21/*22 * The minimum message length (input and output length), in bytes, for all23 * filenames encryption modes.  Filenames shorter than this will be zero-padded24 * before being encrypted.25 */26#define FSCRYPT_FNAME_MIN_MSG_LEN 1627 28/*29 * struct fscrypt_nokey_name - identifier for directory entry when key is absent30 *31 * When userspace lists an encrypted directory without access to the key, the32 * filesystem must present a unique "no-key name" for each filename that allows33 * it to find the directory entry again if requested.  Naively, that would just34 * mean using the ciphertext filenames.  However, since the ciphertext filenames35 * can contain illegal characters ('\0' and '/'), they must be encoded in some36 * way.  We use base64url.  But that can cause names to exceed NAME_MAX (25537 * bytes), so we also need to use a strong hash to abbreviate long names.38 *39 * The filesystem may also need another kind of hash, the "dirhash", to quickly40 * find the directory entry.  Since filesystems normally compute the dirhash41 * over the on-disk filename (i.e. the ciphertext), it's not computable from42 * no-key names that abbreviate the ciphertext using the strong hash to fit in43 * NAME_MAX.  It's also not computable if it's a keyed hash taken over the44 * plaintext (but it may still be available in the on-disk directory entry);45 * casefolded directories use this type of dirhash.  At least in these cases,46 * each no-key name must include the name's dirhash too.47 *48 * To meet all these requirements, we base64url-encode the following49 * variable-length structure.  It contains the dirhash, or 0's if the filesystem50 * didn't provide one; up to 149 bytes of the ciphertext name; and for51 * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes.52 *53 * This ensures that each no-key name contains everything needed to find the54 * directory entry again, contains only legal characters, doesn't exceed55 * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only56 * take the performance hit of SHA-256 on very long filenames (which are rare).57 */58struct fscrypt_nokey_name {59	u32 dirhash[2];60	u8 bytes[149];61	u8 sha256[SHA256_DIGEST_SIZE];62}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */63 64/*65 * Decoded size of max-size no-key name, i.e. a name that was abbreviated using66 * the strong hash and thus includes the 'sha256' field.  This isn't simply67 * sizeof(struct fscrypt_nokey_name), as the padding at the end isn't included.68 */69#define FSCRYPT_NOKEY_NAME_MAX	offsetofend(struct fscrypt_nokey_name, sha256)70 71/* Encoded size of max-size no-key name */72#define FSCRYPT_NOKEY_NAME_MAX_ENCODED \73		FSCRYPT_BASE64URL_CHARS(FSCRYPT_NOKEY_NAME_MAX)74 75static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)76{77	return is_dot_dotdot(str->name, str->len);78}79 80/**81 * fscrypt_fname_encrypt() - encrypt a filename82 * @inode: inode of the parent directory (for regular filenames)83 *	   or of the symlink (for symlink targets). Key must already be84 *	   set up.85 * @iname: the filename to encrypt86 * @out: (output) the encrypted filename87 * @olen: size of the encrypted filename.  It must be at least @iname->len.88 *	  Any extra space is filled with NUL padding before encryption.89 *90 * Return: 0 on success, -errno on failure91 */92int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,93			  u8 *out, unsigned int olen)94{95	struct skcipher_request *req = NULL;96	DECLARE_CRYPTO_WAIT(wait);97	const struct fscrypt_inode_info *ci = inode->i_crypt_info;98	struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;99	union fscrypt_iv iv;100	struct scatterlist sg;101	int res;102 103	/*104	 * Copy the filename to the output buffer for encrypting in-place and105	 * pad it with the needed number of NUL bytes.106	 */107	if (WARN_ON_ONCE(olen < iname->len))108		return -ENOBUFS;109	memcpy(out, iname->name, iname->len);110	memset(out + iname->len, 0, olen - iname->len);111 112	/* Initialize the IV */113	fscrypt_generate_iv(&iv, 0, ci);114 115	/* Set up the encryption request */116	req = skcipher_request_alloc(tfm, GFP_NOFS);117	if (!req)118		return -ENOMEM;119	skcipher_request_set_callback(req,120			CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,121			crypto_req_done, &wait);122	sg_init_one(&sg, out, olen);123	skcipher_request_set_crypt(req, &sg, &sg, olen, &iv);124 125	/* Do the encryption */126	res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);127	skcipher_request_free(req);128	if (res < 0) {129		fscrypt_err(inode, "Filename encryption failed: %d", res);130		return res;131	}132 133	return 0;134}135EXPORT_SYMBOL_GPL(fscrypt_fname_encrypt);136 137/**138 * fname_decrypt() - decrypt a filename139 * @inode: inode of the parent directory (for regular filenames)140 *	   or of the symlink (for symlink targets)141 * @iname: the encrypted filename to decrypt142 * @oname: (output) the decrypted filename.  The caller must have allocated143 *	   enough space for this, e.g. using fscrypt_fname_alloc_buffer().144 *145 * Return: 0 on success, -errno on failure146 */147static int fname_decrypt(const struct inode *inode,148			 const struct fscrypt_str *iname,149			 struct fscrypt_str *oname)150{151	struct skcipher_request *req = NULL;152	DECLARE_CRYPTO_WAIT(wait);153	struct scatterlist src_sg, dst_sg;154	const struct fscrypt_inode_info *ci = inode->i_crypt_info;155	struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;156	union fscrypt_iv iv;157	int res;158 159	/* Allocate request */160	req = skcipher_request_alloc(tfm, GFP_NOFS);161	if (!req)162		return -ENOMEM;163	skcipher_request_set_callback(req,164		CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,165		crypto_req_done, &wait);166 167	/* Initialize IV */168	fscrypt_generate_iv(&iv, 0, ci);169 170	/* Create decryption request */171	sg_init_one(&src_sg, iname->name, iname->len);172	sg_init_one(&dst_sg, oname->name, oname->len);173	skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv);174	res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);175	skcipher_request_free(req);176	if (res < 0) {177		fscrypt_err(inode, "Filename decryption failed: %d", res);178		return res;179	}180 181	oname->len = strnlen(oname->name, iname->len);182	return 0;183}184 185static const char base64url_table[65] =186	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";187 188#define FSCRYPT_BASE64URL_CHARS(nbytes)	DIV_ROUND_UP((nbytes) * 4, 3)189 190/**191 * fscrypt_base64url_encode() - base64url-encode some binary data192 * @src: the binary data to encode193 * @srclen: the length of @src in bytes194 * @dst: (output) the base64url-encoded string.  Not NUL-terminated.195 *196 * Encodes data using base64url encoding, i.e. the "Base 64 Encoding with URL197 * and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't used,198 * as it's unneeded and not required by the RFC.  base64url is used instead of199 * base64 to avoid the '/' character, which isn't allowed in filenames.200 *201 * Return: the length of the resulting base64url-encoded string in bytes.202 *	   This will be equal to FSCRYPT_BASE64URL_CHARS(srclen).203 */204static int fscrypt_base64url_encode(const u8 *src, int srclen, char *dst)205{206	u32 ac = 0;207	int bits = 0;208	int i;209	char *cp = dst;210 211	for (i = 0; i < srclen; i++) {212		ac = (ac << 8) | src[i];213		bits += 8;214		do {215			bits -= 6;216			*cp++ = base64url_table[(ac >> bits) & 0x3f];217		} while (bits >= 6);218	}219	if (bits)220		*cp++ = base64url_table[(ac << (6 - bits)) & 0x3f];221	return cp - dst;222}223 224/**225 * fscrypt_base64url_decode() - base64url-decode a string226 * @src: the string to decode.  Doesn't need to be NUL-terminated.227 * @srclen: the length of @src in bytes228 * @dst: (output) the decoded binary data229 *230 * Decodes a string using base64url encoding, i.e. the "Base 64 Encoding with231 * URL and Filename Safe Alphabet" specified by RFC 4648.  '='-padding isn't232 * accepted, nor are non-encoding characters such as whitespace.233 *234 * This implementation hasn't been optimized for performance.235 *236 * Return: the length of the resulting decoded binary data in bytes,237 *	   or -1 if the string isn't a valid base64url string.238 */239static int fscrypt_base64url_decode(const char *src, int srclen, u8 *dst)240{241	u32 ac = 0;242	int bits = 0;243	int i;244	u8 *bp = dst;245 246	for (i = 0; i < srclen; i++) {247		const char *p = strchr(base64url_table, src[i]);248 249		if (p == NULL || src[i] == 0)250			return -1;251		ac = (ac << 6) | (p - base64url_table);252		bits += 6;253		if (bits >= 8) {254			bits -= 8;255			*bp++ = (u8)(ac >> bits);256		}257	}258	if (ac & ((1 << bits) - 1))259		return -1;260	return bp - dst;261}262 263bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,264				    u32 orig_len, u32 max_len,265				    u32 *encrypted_len_ret)266{267	int padding = 4 << (fscrypt_policy_flags(policy) &268			    FSCRYPT_POLICY_FLAGS_PAD_MASK);269	u32 encrypted_len;270 271	if (orig_len > max_len)272		return false;273	encrypted_len = max_t(u32, orig_len, FSCRYPT_FNAME_MIN_MSG_LEN);274	encrypted_len = round_up(encrypted_len, padding);275	*encrypted_len_ret = min(encrypted_len, max_len);276	return true;277}278 279/**280 * fscrypt_fname_encrypted_size() - calculate length of encrypted filename281 * @inode:		parent inode of dentry name being encrypted. Key must282 *			already be set up.283 * @orig_len:		length of the original filename284 * @max_len:		maximum length to return285 * @encrypted_len_ret:	where calculated length should be returned (on success)286 *287 * Filenames that are shorter than the maximum length may have their lengths288 * increased slightly by encryption, due to padding that is applied.289 *290 * Return: false if the orig_len is greater than max_len. Otherwise, true and291 *	   fill out encrypted_len_ret with the length (up to max_len).292 */293bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,294				  u32 max_len, u32 *encrypted_len_ret)295{296	return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy,297					      orig_len, max_len,298					      encrypted_len_ret);299}300EXPORT_SYMBOL_GPL(fscrypt_fname_encrypted_size);301 302/**303 * fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames304 * @max_encrypted_len: maximum length of encrypted filenames the buffer will be305 *		       used to present306 * @crypto_str: (output) buffer to allocate307 *308 * Allocate a buffer that is large enough to hold any decrypted or encoded309 * filename (null-terminated), for the given maximum encrypted filename length.310 *311 * Return: 0 on success, -errno on failure312 */313int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,314			       struct fscrypt_str *crypto_str)315{316	u32 max_presented_len = max_t(u32, FSCRYPT_NOKEY_NAME_MAX_ENCODED,317				      max_encrypted_len);318 319	crypto_str->name = kmalloc(max_presented_len + 1, GFP_NOFS);320	if (!crypto_str->name)321		return -ENOMEM;322	crypto_str->len = max_presented_len;323	return 0;324}325EXPORT_SYMBOL(fscrypt_fname_alloc_buffer);326 327/**328 * fscrypt_fname_free_buffer() - free a buffer for presented filenames329 * @crypto_str: the buffer to free330 *331 * Free a buffer that was allocated by fscrypt_fname_alloc_buffer().332 */333void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)334{335	if (!crypto_str)336		return;337	kfree(crypto_str->name);338	crypto_str->name = NULL;339}340EXPORT_SYMBOL(fscrypt_fname_free_buffer);341 342/**343 * fscrypt_fname_disk_to_usr() - convert an encrypted filename to344 *				 user-presentable form345 * @inode: inode of the parent directory (for regular filenames)346 *	   or of the symlink (for symlink targets)347 * @hash: first part of the name's dirhash, if applicable.  This only needs to348 *	  be provided if the filename is located in an indexed directory whose349 *	  encryption key may be unavailable.  Not needed for symlink targets.350 * @minor_hash: second part of the name's dirhash, if applicable351 * @iname: encrypted filename to convert.  May also be "." or "..", which352 *	   aren't actually encrypted.353 * @oname: output buffer for the user-presentable filename.  The caller must354 *	   have allocated enough space for this, e.g. using355 *	   fscrypt_fname_alloc_buffer().356 *357 * If the key is available, we'll decrypt the disk name.  Otherwise, we'll358 * encode it for presentation in fscrypt_nokey_name format.359 * See struct fscrypt_nokey_name for details.360 *361 * Return: 0 on success, -errno on failure362 */363int fscrypt_fname_disk_to_usr(const struct inode *inode,364			      u32 hash, u32 minor_hash,365			      const struct fscrypt_str *iname,366			      struct fscrypt_str *oname)367{368	const struct qstr qname = FSTR_TO_QSTR(iname);369	struct fscrypt_nokey_name nokey_name;370	u32 size; /* size of the unencoded no-key name */371 372	if (fscrypt_is_dot_dotdot(&qname)) {373		oname->name[0] = '.';374		oname->name[iname->len - 1] = '.';375		oname->len = iname->len;376		return 0;377	}378 379	if (iname->len < FSCRYPT_FNAME_MIN_MSG_LEN)380		return -EUCLEAN;381 382	if (fscrypt_has_encryption_key(inode))383		return fname_decrypt(inode, iname, oname);384 385	/*386	 * Sanity check that struct fscrypt_nokey_name doesn't have padding387	 * between fields and that its encoded size never exceeds NAME_MAX.388	 */389	BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, dirhash) !=390		     offsetof(struct fscrypt_nokey_name, bytes));391	BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, bytes) !=392		     offsetof(struct fscrypt_nokey_name, sha256));393	BUILD_BUG_ON(FSCRYPT_NOKEY_NAME_MAX_ENCODED > NAME_MAX);394 395	nokey_name.dirhash[0] = hash;396	nokey_name.dirhash[1] = minor_hash;397 398	if (iname->len <= sizeof(nokey_name.bytes)) {399		memcpy(nokey_name.bytes, iname->name, iname->len);400		size = offsetof(struct fscrypt_nokey_name, bytes[iname->len]);401	} else {402		memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes));403		/* Compute strong hash of remaining part of name. */404		sha256(&iname->name[sizeof(nokey_name.bytes)],405		       iname->len - sizeof(nokey_name.bytes),406		       nokey_name.sha256);407		size = FSCRYPT_NOKEY_NAME_MAX;408	}409	oname->len = fscrypt_base64url_encode((const u8 *)&nokey_name, size,410					      oname->name);411	return 0;412}413EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);414 415/**416 * fscrypt_setup_filename() - prepare to search a possibly encrypted directory417 * @dir: the directory that will be searched418 * @iname: the user-provided filename being searched for419 * @lookup: 1 if we're allowed to proceed without the key because it's420 *	->lookup() or we're finding the dir_entry for deletion; 0 if we cannot421 *	proceed without the key because we're going to create the dir_entry.422 * @fname: the filename information to be filled in423 *424 * Given a user-provided filename @iname, this function sets @fname->disk_name425 * to the name that would be stored in the on-disk directory entry, if possible.426 * If the directory is unencrypted this is simply @iname.  Else, if we have the427 * directory's encryption key, then @iname is the plaintext, so we encrypt it to428 * get the disk_name.429 *430 * Else, for keyless @lookup operations, @iname should be a no-key name, so we431 * decode it to get the struct fscrypt_nokey_name.  Non-@lookup operations will432 * be impossible in this case, so we fail them with ENOKEY.433 *434 * If successful, fscrypt_free_filename() must be called later to clean up.435 *436 * Return: 0 on success, -errno on failure437 */438int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,439			      int lookup, struct fscrypt_name *fname)440{441	struct fscrypt_nokey_name *nokey_name;442	int ret;443 444	memset(fname, 0, sizeof(struct fscrypt_name));445	fname->usr_fname = iname;446 447	if (!IS_ENCRYPTED(dir) || fscrypt_is_dot_dotdot(iname)) {448		fname->disk_name.name = (unsigned char *)iname->name;449		fname->disk_name.len = iname->len;450		return 0;451	}452	ret = fscrypt_get_encryption_info(dir, lookup);453	if (ret)454		return ret;455 456	if (fscrypt_has_encryption_key(dir)) {457		if (!fscrypt_fname_encrypted_size(dir, iname->len, NAME_MAX,458						  &fname->crypto_buf.len))459			return -ENAMETOOLONG;460		fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,461						 GFP_NOFS);462		if (!fname->crypto_buf.name)463			return -ENOMEM;464 465		ret = fscrypt_fname_encrypt(dir, iname, fname->crypto_buf.name,466					    fname->crypto_buf.len);467		if (ret)468			goto errout;469		fname->disk_name.name = fname->crypto_buf.name;470		fname->disk_name.len = fname->crypto_buf.len;471		return 0;472	}473	if (!lookup)474		return -ENOKEY;475	fname->is_nokey_name = true;476 477	/*478	 * We don't have the key and we are doing a lookup; decode the479	 * user-supplied name480	 */481 482	if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED)483		return -ENOENT;484 485	fname->crypto_buf.name = kmalloc(FSCRYPT_NOKEY_NAME_MAX, GFP_KERNEL);486	if (fname->crypto_buf.name == NULL)487		return -ENOMEM;488 489	ret = fscrypt_base64url_decode(iname->name, iname->len,490				       fname->crypto_buf.name);491	if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) ||492	    (ret > offsetof(struct fscrypt_nokey_name, sha256) &&493	     ret != FSCRYPT_NOKEY_NAME_MAX)) {494		ret = -ENOENT;495		goto errout;496	}497	fname->crypto_buf.len = ret;498 499	nokey_name = (void *)fname->crypto_buf.name;500	fname->hash = nokey_name->dirhash[0];501	fname->minor_hash = nokey_name->dirhash[1];502	if (ret != FSCRYPT_NOKEY_NAME_MAX) {503		/* The full ciphertext filename is available. */504		fname->disk_name.name = nokey_name->bytes;505		fname->disk_name.len =506			ret - offsetof(struct fscrypt_nokey_name, bytes);507	}508	return 0;509 510errout:511	kfree(fname->crypto_buf.name);512	return ret;513}514EXPORT_SYMBOL(fscrypt_setup_filename);515 516/**517 * fscrypt_match_name() - test whether the given name matches a directory entry518 * @fname: the name being searched for519 * @de_name: the name from the directory entry520 * @de_name_len: the length of @de_name in bytes521 *522 * Normally @fname->disk_name will be set, and in that case we simply compare523 * that to the name stored in the directory entry.  The only exception is that524 * if we don't have the key for an encrypted directory and the name we're525 * looking for is very long, then we won't have the full disk_name and instead526 * we'll need to match against a fscrypt_nokey_name that includes a strong hash.527 *528 * Return: %true if the name matches, otherwise %false.529 */530bool fscrypt_match_name(const struct fscrypt_name *fname,531			const u8 *de_name, u32 de_name_len)532{533	const struct fscrypt_nokey_name *nokey_name =534		(const void *)fname->crypto_buf.name;535	u8 digest[SHA256_DIGEST_SIZE];536 537	if (likely(fname->disk_name.name)) {538		if (de_name_len != fname->disk_name.len)539			return false;540		return !memcmp(de_name, fname->disk_name.name, de_name_len);541	}542	if (de_name_len <= sizeof(nokey_name->bytes))543		return false;544	if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes)))545		return false;546	sha256(&de_name[sizeof(nokey_name->bytes)],547	       de_name_len - sizeof(nokey_name->bytes), digest);548	return !memcmp(digest, nokey_name->sha256, sizeof(digest));549}550EXPORT_SYMBOL_GPL(fscrypt_match_name);551 552/**553 * fscrypt_fname_siphash() - calculate the SipHash of a filename554 * @dir: the parent directory555 * @name: the filename to calculate the SipHash of556 *557 * Given a plaintext filename @name and a directory @dir which uses SipHash as558 * its dirhash method and has had its fscrypt key set up, this function559 * calculates the SipHash of that name using the directory's secret dirhash key.560 *561 * Return: the SipHash of @name using the hash key of @dir562 */563u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name)564{565	const struct fscrypt_inode_info *ci = dir->i_crypt_info;566 567	WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);568 569	return siphash(name->name, name->len, &ci->ci_dirhash_key);570}571EXPORT_SYMBOL_GPL(fscrypt_fname_siphash);572 573/*574 * Validate dentries in encrypted directories to make sure we aren't potentially575 * caching stale dentries after a key has been added.576 */577int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)578{579	struct dentry *dir;580	int err;581	int valid;582 583	/*584	 * Plaintext names are always valid, since fscrypt doesn't support585	 * reverting to no-key names without evicting the directory's inode586	 * -- which implies eviction of the dentries in the directory.587	 */588	if (!(dentry->d_flags & DCACHE_NOKEY_NAME))589		return 1;590 591	/*592	 * No-key name; valid if the directory's key is still unavailable.593	 *594	 * Although fscrypt forbids rename() on no-key names, we still must use595	 * dget_parent() here rather than use ->d_parent directly.  That's596	 * because a corrupted fs image may contain directory hard links, which597	 * the VFS handles by moving the directory's dentry tree in the dcache598	 * each time ->lookup() finds the directory and it already has a dentry599	 * elsewhere.  Thus ->d_parent can be changing, and we must safely grab600	 * a reference to some ->d_parent to prevent it from being freed.601	 */602 603	if (flags & LOOKUP_RCU)604		return -ECHILD;605 606	dir = dget_parent(dentry);607	/*608	 * Pass allow_unsupported=true, so that files with an unsupported609	 * encryption policy can be deleted.610	 */611	err = fscrypt_get_encryption_info(d_inode(dir), true);612	valid = !fscrypt_has_encryption_key(d_inode(dir));613	dput(dir);614 615	if (err < 0)616		return err;617 618	return valid;619}620EXPORT_SYMBOL_GPL(fscrypt_d_revalidate);621