162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * This contains functions for filename crypto management 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2015, Google, Inc. 662306a36Sopenharmony_ci * Copyright (C) 2015, Motorola Mobility 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Written by Uday Savagaonkar, 2014. 962306a36Sopenharmony_ci * Modified by Jaegeuk Kim, 2015. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * This has not yet undergone a rigorous security audit. 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/namei.h> 1562306a36Sopenharmony_ci#include <linux/scatterlist.h> 1662306a36Sopenharmony_ci#include <crypto/hash.h> 1762306a36Sopenharmony_ci#include <crypto/sha2.h> 1862306a36Sopenharmony_ci#include <crypto/skcipher.h> 1962306a36Sopenharmony_ci#include "fscrypt_private.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * The minimum message length (input and output length), in bytes, for all 2362306a36Sopenharmony_ci * filenames encryption modes. Filenames shorter than this will be zero-padded 2462306a36Sopenharmony_ci * before being encrypted. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ci#define FSCRYPT_FNAME_MIN_MSG_LEN 16 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * struct fscrypt_nokey_name - identifier for directory entry when key is absent 3062306a36Sopenharmony_ci * 3162306a36Sopenharmony_ci * When userspace lists an encrypted directory without access to the key, the 3262306a36Sopenharmony_ci * filesystem must present a unique "no-key name" for each filename that allows 3362306a36Sopenharmony_ci * it to find the directory entry again if requested. Naively, that would just 3462306a36Sopenharmony_ci * mean using the ciphertext filenames. However, since the ciphertext filenames 3562306a36Sopenharmony_ci * can contain illegal characters ('\0' and '/'), they must be encoded in some 3662306a36Sopenharmony_ci * way. We use base64url. But that can cause names to exceed NAME_MAX (255 3762306a36Sopenharmony_ci * bytes), so we also need to use a strong hash to abbreviate long names. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * The filesystem may also need another kind of hash, the "dirhash", to quickly 4062306a36Sopenharmony_ci * find the directory entry. Since filesystems normally compute the dirhash 4162306a36Sopenharmony_ci * over the on-disk filename (i.e. the ciphertext), it's not computable from 4262306a36Sopenharmony_ci * no-key names that abbreviate the ciphertext using the strong hash to fit in 4362306a36Sopenharmony_ci * NAME_MAX. It's also not computable if it's a keyed hash taken over the 4462306a36Sopenharmony_ci * plaintext (but it may still be available in the on-disk directory entry); 4562306a36Sopenharmony_ci * casefolded directories use this type of dirhash. At least in these cases, 4662306a36Sopenharmony_ci * each no-key name must include the name's dirhash too. 4762306a36Sopenharmony_ci * 4862306a36Sopenharmony_ci * To meet all these requirements, we base64url-encode the following 4962306a36Sopenharmony_ci * variable-length structure. It contains the dirhash, or 0's if the filesystem 5062306a36Sopenharmony_ci * didn't provide one; up to 149 bytes of the ciphertext name; and for 5162306a36Sopenharmony_ci * ciphertexts longer than 149 bytes, also the SHA-256 of the remaining bytes. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * This ensures that each no-key name contains everything needed to find the 5462306a36Sopenharmony_ci * directory entry again, contains only legal characters, doesn't exceed 5562306a36Sopenharmony_ci * NAME_MAX, is unambiguous unless there's a SHA-256 collision, and that we only 5662306a36Sopenharmony_ci * take the performance hit of SHA-256 on very long filenames (which are rare). 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_cistruct fscrypt_nokey_name { 5962306a36Sopenharmony_ci u32 dirhash[2]; 6062306a36Sopenharmony_ci u8 bytes[149]; 6162306a36Sopenharmony_ci u8 sha256[SHA256_DIGEST_SIZE]; 6262306a36Sopenharmony_ci}; /* 189 bytes => 252 bytes base64url-encoded, which is <= NAME_MAX (255) */ 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* 6562306a36Sopenharmony_ci * Decoded size of max-size no-key name, i.e. a name that was abbreviated using 6662306a36Sopenharmony_ci * the strong hash and thus includes the 'sha256' field. This isn't simply 6762306a36Sopenharmony_ci * sizeof(struct fscrypt_nokey_name), as the padding at the end isn't included. 6862306a36Sopenharmony_ci */ 6962306a36Sopenharmony_ci#define FSCRYPT_NOKEY_NAME_MAX offsetofend(struct fscrypt_nokey_name, sha256) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* Encoded size of max-size no-key name */ 7262306a36Sopenharmony_ci#define FSCRYPT_NOKEY_NAME_MAX_ENCODED \ 7362306a36Sopenharmony_ci FSCRYPT_BASE64URL_CHARS(FSCRYPT_NOKEY_NAME_MAX) 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic inline bool fscrypt_is_dot_dotdot(const struct qstr *str) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci if (str->len == 1 && str->name[0] == '.') 7862306a36Sopenharmony_ci return true; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.') 8162306a36Sopenharmony_ci return true; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci return false; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/** 8762306a36Sopenharmony_ci * fscrypt_fname_encrypt() - encrypt a filename 8862306a36Sopenharmony_ci * @inode: inode of the parent directory (for regular filenames) 8962306a36Sopenharmony_ci * or of the symlink (for symlink targets). Key must already be 9062306a36Sopenharmony_ci * set up. 9162306a36Sopenharmony_ci * @iname: the filename to encrypt 9262306a36Sopenharmony_ci * @out: (output) the encrypted filename 9362306a36Sopenharmony_ci * @olen: size of the encrypted filename. It must be at least @iname->len. 9462306a36Sopenharmony_ci * Any extra space is filled with NUL padding before encryption. 9562306a36Sopenharmony_ci * 9662306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ciint fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, 9962306a36Sopenharmony_ci u8 *out, unsigned int olen) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci struct skcipher_request *req = NULL; 10262306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 10362306a36Sopenharmony_ci const struct fscrypt_info *ci = inode->i_crypt_info; 10462306a36Sopenharmony_ci struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; 10562306a36Sopenharmony_ci union fscrypt_iv iv; 10662306a36Sopenharmony_ci struct scatterlist sg; 10762306a36Sopenharmony_ci int res; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * Copy the filename to the output buffer for encrypting in-place and 11162306a36Sopenharmony_ci * pad it with the needed number of NUL bytes. 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci if (WARN_ON_ONCE(olen < iname->len)) 11462306a36Sopenharmony_ci return -ENOBUFS; 11562306a36Sopenharmony_ci memcpy(out, iname->name, iname->len); 11662306a36Sopenharmony_ci memset(out + iname->len, 0, olen - iname->len); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci /* Initialize the IV */ 11962306a36Sopenharmony_ci fscrypt_generate_iv(&iv, 0, ci); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci /* Set up the encryption request */ 12262306a36Sopenharmony_ci req = skcipher_request_alloc(tfm, GFP_NOFS); 12362306a36Sopenharmony_ci if (!req) 12462306a36Sopenharmony_ci return -ENOMEM; 12562306a36Sopenharmony_ci skcipher_request_set_callback(req, 12662306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 12762306a36Sopenharmony_ci crypto_req_done, &wait); 12862306a36Sopenharmony_ci sg_init_one(&sg, out, olen); 12962306a36Sopenharmony_ci skcipher_request_set_crypt(req, &sg, &sg, olen, &iv); 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci /* Do the encryption */ 13262306a36Sopenharmony_ci res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait); 13362306a36Sopenharmony_ci skcipher_request_free(req); 13462306a36Sopenharmony_ci if (res < 0) { 13562306a36Sopenharmony_ci fscrypt_err(inode, "Filename encryption failed: %d", res); 13662306a36Sopenharmony_ci return res; 13762306a36Sopenharmony_ci } 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci return 0; 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_fname_encrypt); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/** 14462306a36Sopenharmony_ci * fname_decrypt() - decrypt a filename 14562306a36Sopenharmony_ci * @inode: inode of the parent directory (for regular filenames) 14662306a36Sopenharmony_ci * or of the symlink (for symlink targets) 14762306a36Sopenharmony_ci * @iname: the encrypted filename to decrypt 14862306a36Sopenharmony_ci * @oname: (output) the decrypted filename. The caller must have allocated 14962306a36Sopenharmony_ci * enough space for this, e.g. using fscrypt_fname_alloc_buffer(). 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_cistatic int fname_decrypt(const struct inode *inode, 15462306a36Sopenharmony_ci const struct fscrypt_str *iname, 15562306a36Sopenharmony_ci struct fscrypt_str *oname) 15662306a36Sopenharmony_ci{ 15762306a36Sopenharmony_ci struct skcipher_request *req = NULL; 15862306a36Sopenharmony_ci DECLARE_CRYPTO_WAIT(wait); 15962306a36Sopenharmony_ci struct scatterlist src_sg, dst_sg; 16062306a36Sopenharmony_ci const struct fscrypt_info *ci = inode->i_crypt_info; 16162306a36Sopenharmony_ci struct crypto_skcipher *tfm = ci->ci_enc_key.tfm; 16262306a36Sopenharmony_ci union fscrypt_iv iv; 16362306a36Sopenharmony_ci int res; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci /* Allocate request */ 16662306a36Sopenharmony_ci req = skcipher_request_alloc(tfm, GFP_NOFS); 16762306a36Sopenharmony_ci if (!req) 16862306a36Sopenharmony_ci return -ENOMEM; 16962306a36Sopenharmony_ci skcipher_request_set_callback(req, 17062306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, 17162306a36Sopenharmony_ci crypto_req_done, &wait); 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci /* Initialize IV */ 17462306a36Sopenharmony_ci fscrypt_generate_iv(&iv, 0, ci); 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* Create decryption request */ 17762306a36Sopenharmony_ci sg_init_one(&src_sg, iname->name, iname->len); 17862306a36Sopenharmony_ci sg_init_one(&dst_sg, oname->name, oname->len); 17962306a36Sopenharmony_ci skcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, &iv); 18062306a36Sopenharmony_ci res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait); 18162306a36Sopenharmony_ci skcipher_request_free(req); 18262306a36Sopenharmony_ci if (res < 0) { 18362306a36Sopenharmony_ci fscrypt_err(inode, "Filename decryption failed: %d", res); 18462306a36Sopenharmony_ci return res; 18562306a36Sopenharmony_ci } 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci oname->len = strnlen(oname->name, iname->len); 18862306a36Sopenharmony_ci return 0; 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic const char base64url_table[65] = 19262306a36Sopenharmony_ci "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define FSCRYPT_BASE64URL_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/** 19762306a36Sopenharmony_ci * fscrypt_base64url_encode() - base64url-encode some binary data 19862306a36Sopenharmony_ci * @src: the binary data to encode 19962306a36Sopenharmony_ci * @srclen: the length of @src in bytes 20062306a36Sopenharmony_ci * @dst: (output) the base64url-encoded string. Not NUL-terminated. 20162306a36Sopenharmony_ci * 20262306a36Sopenharmony_ci * Encodes data using base64url encoding, i.e. the "Base 64 Encoding with URL 20362306a36Sopenharmony_ci * and Filename Safe Alphabet" specified by RFC 4648. '='-padding isn't used, 20462306a36Sopenharmony_ci * as it's unneeded and not required by the RFC. base64url is used instead of 20562306a36Sopenharmony_ci * base64 to avoid the '/' character, which isn't allowed in filenames. 20662306a36Sopenharmony_ci * 20762306a36Sopenharmony_ci * Return: the length of the resulting base64url-encoded string in bytes. 20862306a36Sopenharmony_ci * This will be equal to FSCRYPT_BASE64URL_CHARS(srclen). 20962306a36Sopenharmony_ci */ 21062306a36Sopenharmony_cistatic int fscrypt_base64url_encode(const u8 *src, int srclen, char *dst) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci u32 ac = 0; 21362306a36Sopenharmony_ci int bits = 0; 21462306a36Sopenharmony_ci int i; 21562306a36Sopenharmony_ci char *cp = dst; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci for (i = 0; i < srclen; i++) { 21862306a36Sopenharmony_ci ac = (ac << 8) | src[i]; 21962306a36Sopenharmony_ci bits += 8; 22062306a36Sopenharmony_ci do { 22162306a36Sopenharmony_ci bits -= 6; 22262306a36Sopenharmony_ci *cp++ = base64url_table[(ac >> bits) & 0x3f]; 22362306a36Sopenharmony_ci } while (bits >= 6); 22462306a36Sopenharmony_ci } 22562306a36Sopenharmony_ci if (bits) 22662306a36Sopenharmony_ci *cp++ = base64url_table[(ac << (6 - bits)) & 0x3f]; 22762306a36Sopenharmony_ci return cp - dst; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/** 23162306a36Sopenharmony_ci * fscrypt_base64url_decode() - base64url-decode a string 23262306a36Sopenharmony_ci * @src: the string to decode. Doesn't need to be NUL-terminated. 23362306a36Sopenharmony_ci * @srclen: the length of @src in bytes 23462306a36Sopenharmony_ci * @dst: (output) the decoded binary data 23562306a36Sopenharmony_ci * 23662306a36Sopenharmony_ci * Decodes a string using base64url encoding, i.e. the "Base 64 Encoding with 23762306a36Sopenharmony_ci * URL and Filename Safe Alphabet" specified by RFC 4648. '='-padding isn't 23862306a36Sopenharmony_ci * accepted, nor are non-encoding characters such as whitespace. 23962306a36Sopenharmony_ci * 24062306a36Sopenharmony_ci * This implementation hasn't been optimized for performance. 24162306a36Sopenharmony_ci * 24262306a36Sopenharmony_ci * Return: the length of the resulting decoded binary data in bytes, 24362306a36Sopenharmony_ci * or -1 if the string isn't a valid base64url string. 24462306a36Sopenharmony_ci */ 24562306a36Sopenharmony_cistatic int fscrypt_base64url_decode(const char *src, int srclen, u8 *dst) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci u32 ac = 0; 24862306a36Sopenharmony_ci int bits = 0; 24962306a36Sopenharmony_ci int i; 25062306a36Sopenharmony_ci u8 *bp = dst; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci for (i = 0; i < srclen; i++) { 25362306a36Sopenharmony_ci const char *p = strchr(base64url_table, src[i]); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci if (p == NULL || src[i] == 0) 25662306a36Sopenharmony_ci return -1; 25762306a36Sopenharmony_ci ac = (ac << 6) | (p - base64url_table); 25862306a36Sopenharmony_ci bits += 6; 25962306a36Sopenharmony_ci if (bits >= 8) { 26062306a36Sopenharmony_ci bits -= 8; 26162306a36Sopenharmony_ci *bp++ = (u8)(ac >> bits); 26262306a36Sopenharmony_ci } 26362306a36Sopenharmony_ci } 26462306a36Sopenharmony_ci if (ac & ((1 << bits) - 1)) 26562306a36Sopenharmony_ci return -1; 26662306a36Sopenharmony_ci return bp - dst; 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cibool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy, 27062306a36Sopenharmony_ci u32 orig_len, u32 max_len, 27162306a36Sopenharmony_ci u32 *encrypted_len_ret) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci int padding = 4 << (fscrypt_policy_flags(policy) & 27462306a36Sopenharmony_ci FSCRYPT_POLICY_FLAGS_PAD_MASK); 27562306a36Sopenharmony_ci u32 encrypted_len; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci if (orig_len > max_len) 27862306a36Sopenharmony_ci return false; 27962306a36Sopenharmony_ci encrypted_len = max_t(u32, orig_len, FSCRYPT_FNAME_MIN_MSG_LEN); 28062306a36Sopenharmony_ci encrypted_len = round_up(encrypted_len, padding); 28162306a36Sopenharmony_ci *encrypted_len_ret = min(encrypted_len, max_len); 28262306a36Sopenharmony_ci return true; 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci/** 28662306a36Sopenharmony_ci * fscrypt_fname_encrypted_size() - calculate length of encrypted filename 28762306a36Sopenharmony_ci * @inode: parent inode of dentry name being encrypted. Key must 28862306a36Sopenharmony_ci * already be set up. 28962306a36Sopenharmony_ci * @orig_len: length of the original filename 29062306a36Sopenharmony_ci * @max_len: maximum length to return 29162306a36Sopenharmony_ci * @encrypted_len_ret: where calculated length should be returned (on success) 29262306a36Sopenharmony_ci * 29362306a36Sopenharmony_ci * Filenames that are shorter than the maximum length may have their lengths 29462306a36Sopenharmony_ci * increased slightly by encryption, due to padding that is applied. 29562306a36Sopenharmony_ci * 29662306a36Sopenharmony_ci * Return: false if the orig_len is greater than max_len. Otherwise, true and 29762306a36Sopenharmony_ci * fill out encrypted_len_ret with the length (up to max_len). 29862306a36Sopenharmony_ci */ 29962306a36Sopenharmony_cibool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, 30062306a36Sopenharmony_ci u32 max_len, u32 *encrypted_len_ret) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci return __fscrypt_fname_encrypted_size(&inode->i_crypt_info->ci_policy, 30362306a36Sopenharmony_ci orig_len, max_len, 30462306a36Sopenharmony_ci encrypted_len_ret); 30562306a36Sopenharmony_ci} 30662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_fname_encrypted_size); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci/** 30962306a36Sopenharmony_ci * fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames 31062306a36Sopenharmony_ci * @max_encrypted_len: maximum length of encrypted filenames the buffer will be 31162306a36Sopenharmony_ci * used to present 31262306a36Sopenharmony_ci * @crypto_str: (output) buffer to allocate 31362306a36Sopenharmony_ci * 31462306a36Sopenharmony_ci * Allocate a buffer that is large enough to hold any decrypted or encoded 31562306a36Sopenharmony_ci * filename (null-terminated), for the given maximum encrypted filename length. 31662306a36Sopenharmony_ci * 31762306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 31862306a36Sopenharmony_ci */ 31962306a36Sopenharmony_ciint fscrypt_fname_alloc_buffer(u32 max_encrypted_len, 32062306a36Sopenharmony_ci struct fscrypt_str *crypto_str) 32162306a36Sopenharmony_ci{ 32262306a36Sopenharmony_ci u32 max_presented_len = max_t(u32, FSCRYPT_NOKEY_NAME_MAX_ENCODED, 32362306a36Sopenharmony_ci max_encrypted_len); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci crypto_str->name = kmalloc(max_presented_len + 1, GFP_NOFS); 32662306a36Sopenharmony_ci if (!crypto_str->name) 32762306a36Sopenharmony_ci return -ENOMEM; 32862306a36Sopenharmony_ci crypto_str->len = max_presented_len; 32962306a36Sopenharmony_ci return 0; 33062306a36Sopenharmony_ci} 33162306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_fname_alloc_buffer); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci/** 33462306a36Sopenharmony_ci * fscrypt_fname_free_buffer() - free a buffer for presented filenames 33562306a36Sopenharmony_ci * @crypto_str: the buffer to free 33662306a36Sopenharmony_ci * 33762306a36Sopenharmony_ci * Free a buffer that was allocated by fscrypt_fname_alloc_buffer(). 33862306a36Sopenharmony_ci */ 33962306a36Sopenharmony_civoid fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str) 34062306a36Sopenharmony_ci{ 34162306a36Sopenharmony_ci if (!crypto_str) 34262306a36Sopenharmony_ci return; 34362306a36Sopenharmony_ci kfree(crypto_str->name); 34462306a36Sopenharmony_ci crypto_str->name = NULL; 34562306a36Sopenharmony_ci} 34662306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_fname_free_buffer); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/** 34962306a36Sopenharmony_ci * fscrypt_fname_disk_to_usr() - convert an encrypted filename to 35062306a36Sopenharmony_ci * user-presentable form 35162306a36Sopenharmony_ci * @inode: inode of the parent directory (for regular filenames) 35262306a36Sopenharmony_ci * or of the symlink (for symlink targets) 35362306a36Sopenharmony_ci * @hash: first part of the name's dirhash, if applicable. This only needs to 35462306a36Sopenharmony_ci * be provided if the filename is located in an indexed directory whose 35562306a36Sopenharmony_ci * encryption key may be unavailable. Not needed for symlink targets. 35662306a36Sopenharmony_ci * @minor_hash: second part of the name's dirhash, if applicable 35762306a36Sopenharmony_ci * @iname: encrypted filename to convert. May also be "." or "..", which 35862306a36Sopenharmony_ci * aren't actually encrypted. 35962306a36Sopenharmony_ci * @oname: output buffer for the user-presentable filename. The caller must 36062306a36Sopenharmony_ci * have allocated enough space for this, e.g. using 36162306a36Sopenharmony_ci * fscrypt_fname_alloc_buffer(). 36262306a36Sopenharmony_ci * 36362306a36Sopenharmony_ci * If the key is available, we'll decrypt the disk name. Otherwise, we'll 36462306a36Sopenharmony_ci * encode it for presentation in fscrypt_nokey_name format. 36562306a36Sopenharmony_ci * See struct fscrypt_nokey_name for details. 36662306a36Sopenharmony_ci * 36762306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 36862306a36Sopenharmony_ci */ 36962306a36Sopenharmony_ciint fscrypt_fname_disk_to_usr(const struct inode *inode, 37062306a36Sopenharmony_ci u32 hash, u32 minor_hash, 37162306a36Sopenharmony_ci const struct fscrypt_str *iname, 37262306a36Sopenharmony_ci struct fscrypt_str *oname) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci const struct qstr qname = FSTR_TO_QSTR(iname); 37562306a36Sopenharmony_ci struct fscrypt_nokey_name nokey_name; 37662306a36Sopenharmony_ci u32 size; /* size of the unencoded no-key name */ 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci if (fscrypt_is_dot_dotdot(&qname)) { 37962306a36Sopenharmony_ci oname->name[0] = '.'; 38062306a36Sopenharmony_ci oname->name[iname->len - 1] = '.'; 38162306a36Sopenharmony_ci oname->len = iname->len; 38262306a36Sopenharmony_ci return 0; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci if (iname->len < FSCRYPT_FNAME_MIN_MSG_LEN) 38662306a36Sopenharmony_ci return -EUCLEAN; 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci if (fscrypt_has_encryption_key(inode)) 38962306a36Sopenharmony_ci return fname_decrypt(inode, iname, oname); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci /* 39262306a36Sopenharmony_ci * Sanity check that struct fscrypt_nokey_name doesn't have padding 39362306a36Sopenharmony_ci * between fields and that its encoded size never exceeds NAME_MAX. 39462306a36Sopenharmony_ci */ 39562306a36Sopenharmony_ci BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, dirhash) != 39662306a36Sopenharmony_ci offsetof(struct fscrypt_nokey_name, bytes)); 39762306a36Sopenharmony_ci BUILD_BUG_ON(offsetofend(struct fscrypt_nokey_name, bytes) != 39862306a36Sopenharmony_ci offsetof(struct fscrypt_nokey_name, sha256)); 39962306a36Sopenharmony_ci BUILD_BUG_ON(FSCRYPT_NOKEY_NAME_MAX_ENCODED > NAME_MAX); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci nokey_name.dirhash[0] = hash; 40262306a36Sopenharmony_ci nokey_name.dirhash[1] = minor_hash; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci if (iname->len <= sizeof(nokey_name.bytes)) { 40562306a36Sopenharmony_ci memcpy(nokey_name.bytes, iname->name, iname->len); 40662306a36Sopenharmony_ci size = offsetof(struct fscrypt_nokey_name, bytes[iname->len]); 40762306a36Sopenharmony_ci } else { 40862306a36Sopenharmony_ci memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes)); 40962306a36Sopenharmony_ci /* Compute strong hash of remaining part of name. */ 41062306a36Sopenharmony_ci sha256(&iname->name[sizeof(nokey_name.bytes)], 41162306a36Sopenharmony_ci iname->len - sizeof(nokey_name.bytes), 41262306a36Sopenharmony_ci nokey_name.sha256); 41362306a36Sopenharmony_ci size = FSCRYPT_NOKEY_NAME_MAX; 41462306a36Sopenharmony_ci } 41562306a36Sopenharmony_ci oname->len = fscrypt_base64url_encode((const u8 *)&nokey_name, size, 41662306a36Sopenharmony_ci oname->name); 41762306a36Sopenharmony_ci return 0; 41862306a36Sopenharmony_ci} 41962306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_fname_disk_to_usr); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci/** 42262306a36Sopenharmony_ci * fscrypt_setup_filename() - prepare to search a possibly encrypted directory 42362306a36Sopenharmony_ci * @dir: the directory that will be searched 42462306a36Sopenharmony_ci * @iname: the user-provided filename being searched for 42562306a36Sopenharmony_ci * @lookup: 1 if we're allowed to proceed without the key because it's 42662306a36Sopenharmony_ci * ->lookup() or we're finding the dir_entry for deletion; 0 if we cannot 42762306a36Sopenharmony_ci * proceed without the key because we're going to create the dir_entry. 42862306a36Sopenharmony_ci * @fname: the filename information to be filled in 42962306a36Sopenharmony_ci * 43062306a36Sopenharmony_ci * Given a user-provided filename @iname, this function sets @fname->disk_name 43162306a36Sopenharmony_ci * to the name that would be stored in the on-disk directory entry, if possible. 43262306a36Sopenharmony_ci * If the directory is unencrypted this is simply @iname. Else, if we have the 43362306a36Sopenharmony_ci * directory's encryption key, then @iname is the plaintext, so we encrypt it to 43462306a36Sopenharmony_ci * get the disk_name. 43562306a36Sopenharmony_ci * 43662306a36Sopenharmony_ci * Else, for keyless @lookup operations, @iname should be a no-key name, so we 43762306a36Sopenharmony_ci * decode it to get the struct fscrypt_nokey_name. Non-@lookup operations will 43862306a36Sopenharmony_ci * be impossible in this case, so we fail them with ENOKEY. 43962306a36Sopenharmony_ci * 44062306a36Sopenharmony_ci * If successful, fscrypt_free_filename() must be called later to clean up. 44162306a36Sopenharmony_ci * 44262306a36Sopenharmony_ci * Return: 0 on success, -errno on failure 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_ciint fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, 44562306a36Sopenharmony_ci int lookup, struct fscrypt_name *fname) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci struct fscrypt_nokey_name *nokey_name; 44862306a36Sopenharmony_ci int ret; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci memset(fname, 0, sizeof(struct fscrypt_name)); 45162306a36Sopenharmony_ci fname->usr_fname = iname; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci if (!IS_ENCRYPTED(dir) || fscrypt_is_dot_dotdot(iname)) { 45462306a36Sopenharmony_ci fname->disk_name.name = (unsigned char *)iname->name; 45562306a36Sopenharmony_ci fname->disk_name.len = iname->len; 45662306a36Sopenharmony_ci return 0; 45762306a36Sopenharmony_ci } 45862306a36Sopenharmony_ci ret = fscrypt_get_encryption_info(dir, lookup); 45962306a36Sopenharmony_ci if (ret) 46062306a36Sopenharmony_ci return ret; 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_ci if (fscrypt_has_encryption_key(dir)) { 46362306a36Sopenharmony_ci if (!fscrypt_fname_encrypted_size(dir, iname->len, NAME_MAX, 46462306a36Sopenharmony_ci &fname->crypto_buf.len)) 46562306a36Sopenharmony_ci return -ENAMETOOLONG; 46662306a36Sopenharmony_ci fname->crypto_buf.name = kmalloc(fname->crypto_buf.len, 46762306a36Sopenharmony_ci GFP_NOFS); 46862306a36Sopenharmony_ci if (!fname->crypto_buf.name) 46962306a36Sopenharmony_ci return -ENOMEM; 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci ret = fscrypt_fname_encrypt(dir, iname, fname->crypto_buf.name, 47262306a36Sopenharmony_ci fname->crypto_buf.len); 47362306a36Sopenharmony_ci if (ret) 47462306a36Sopenharmony_ci goto errout; 47562306a36Sopenharmony_ci fname->disk_name.name = fname->crypto_buf.name; 47662306a36Sopenharmony_ci fname->disk_name.len = fname->crypto_buf.len; 47762306a36Sopenharmony_ci return 0; 47862306a36Sopenharmony_ci } 47962306a36Sopenharmony_ci if (!lookup) 48062306a36Sopenharmony_ci return -ENOKEY; 48162306a36Sopenharmony_ci fname->is_nokey_name = true; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci /* 48462306a36Sopenharmony_ci * We don't have the key and we are doing a lookup; decode the 48562306a36Sopenharmony_ci * user-supplied name 48662306a36Sopenharmony_ci */ 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED) 48962306a36Sopenharmony_ci return -ENOENT; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci fname->crypto_buf.name = kmalloc(FSCRYPT_NOKEY_NAME_MAX, GFP_KERNEL); 49262306a36Sopenharmony_ci if (fname->crypto_buf.name == NULL) 49362306a36Sopenharmony_ci return -ENOMEM; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci ret = fscrypt_base64url_decode(iname->name, iname->len, 49662306a36Sopenharmony_ci fname->crypto_buf.name); 49762306a36Sopenharmony_ci if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) || 49862306a36Sopenharmony_ci (ret > offsetof(struct fscrypt_nokey_name, sha256) && 49962306a36Sopenharmony_ci ret != FSCRYPT_NOKEY_NAME_MAX)) { 50062306a36Sopenharmony_ci ret = -ENOENT; 50162306a36Sopenharmony_ci goto errout; 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci fname->crypto_buf.len = ret; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci nokey_name = (void *)fname->crypto_buf.name; 50662306a36Sopenharmony_ci fname->hash = nokey_name->dirhash[0]; 50762306a36Sopenharmony_ci fname->minor_hash = nokey_name->dirhash[1]; 50862306a36Sopenharmony_ci if (ret != FSCRYPT_NOKEY_NAME_MAX) { 50962306a36Sopenharmony_ci /* The full ciphertext filename is available. */ 51062306a36Sopenharmony_ci fname->disk_name.name = nokey_name->bytes; 51162306a36Sopenharmony_ci fname->disk_name.len = 51262306a36Sopenharmony_ci ret - offsetof(struct fscrypt_nokey_name, bytes); 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci return 0; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cierrout: 51762306a36Sopenharmony_ci kfree(fname->crypto_buf.name); 51862306a36Sopenharmony_ci return ret; 51962306a36Sopenharmony_ci} 52062306a36Sopenharmony_ciEXPORT_SYMBOL(fscrypt_setup_filename); 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci/** 52362306a36Sopenharmony_ci * fscrypt_match_name() - test whether the given name matches a directory entry 52462306a36Sopenharmony_ci * @fname: the name being searched for 52562306a36Sopenharmony_ci * @de_name: the name from the directory entry 52662306a36Sopenharmony_ci * @de_name_len: the length of @de_name in bytes 52762306a36Sopenharmony_ci * 52862306a36Sopenharmony_ci * Normally @fname->disk_name will be set, and in that case we simply compare 52962306a36Sopenharmony_ci * that to the name stored in the directory entry. The only exception is that 53062306a36Sopenharmony_ci * if we don't have the key for an encrypted directory and the name we're 53162306a36Sopenharmony_ci * looking for is very long, then we won't have the full disk_name and instead 53262306a36Sopenharmony_ci * we'll need to match against a fscrypt_nokey_name that includes a strong hash. 53362306a36Sopenharmony_ci * 53462306a36Sopenharmony_ci * Return: %true if the name matches, otherwise %false. 53562306a36Sopenharmony_ci */ 53662306a36Sopenharmony_cibool fscrypt_match_name(const struct fscrypt_name *fname, 53762306a36Sopenharmony_ci const u8 *de_name, u32 de_name_len) 53862306a36Sopenharmony_ci{ 53962306a36Sopenharmony_ci const struct fscrypt_nokey_name *nokey_name = 54062306a36Sopenharmony_ci (const void *)fname->crypto_buf.name; 54162306a36Sopenharmony_ci u8 digest[SHA256_DIGEST_SIZE]; 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci if (likely(fname->disk_name.name)) { 54462306a36Sopenharmony_ci if (de_name_len != fname->disk_name.len) 54562306a36Sopenharmony_ci return false; 54662306a36Sopenharmony_ci return !memcmp(de_name, fname->disk_name.name, de_name_len); 54762306a36Sopenharmony_ci } 54862306a36Sopenharmony_ci if (de_name_len <= sizeof(nokey_name->bytes)) 54962306a36Sopenharmony_ci return false; 55062306a36Sopenharmony_ci if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes))) 55162306a36Sopenharmony_ci return false; 55262306a36Sopenharmony_ci sha256(&de_name[sizeof(nokey_name->bytes)], 55362306a36Sopenharmony_ci de_name_len - sizeof(nokey_name->bytes), digest); 55462306a36Sopenharmony_ci return !memcmp(digest, nokey_name->sha256, sizeof(digest)); 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_match_name); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci/** 55962306a36Sopenharmony_ci * fscrypt_fname_siphash() - calculate the SipHash of a filename 56062306a36Sopenharmony_ci * @dir: the parent directory 56162306a36Sopenharmony_ci * @name: the filename to calculate the SipHash of 56262306a36Sopenharmony_ci * 56362306a36Sopenharmony_ci * Given a plaintext filename @name and a directory @dir which uses SipHash as 56462306a36Sopenharmony_ci * its dirhash method and has had its fscrypt key set up, this function 56562306a36Sopenharmony_ci * calculates the SipHash of that name using the directory's secret dirhash key. 56662306a36Sopenharmony_ci * 56762306a36Sopenharmony_ci * Return: the SipHash of @name using the hash key of @dir 56862306a36Sopenharmony_ci */ 56962306a36Sopenharmony_ciu64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name) 57062306a36Sopenharmony_ci{ 57162306a36Sopenharmony_ci const struct fscrypt_info *ci = dir->i_crypt_info; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci WARN_ON_ONCE(!ci->ci_dirhash_key_initialized); 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci return siphash(name->name, name->len, &ci->ci_dirhash_key); 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_fname_siphash); 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci/* 58062306a36Sopenharmony_ci * Validate dentries in encrypted directories to make sure we aren't potentially 58162306a36Sopenharmony_ci * caching stale dentries after a key has been added. 58262306a36Sopenharmony_ci */ 58362306a36Sopenharmony_ciint fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags) 58462306a36Sopenharmony_ci{ 58562306a36Sopenharmony_ci struct dentry *dir; 58662306a36Sopenharmony_ci int err; 58762306a36Sopenharmony_ci int valid; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci /* 59062306a36Sopenharmony_ci * Plaintext names are always valid, since fscrypt doesn't support 59162306a36Sopenharmony_ci * reverting to no-key names without evicting the directory's inode 59262306a36Sopenharmony_ci * -- which implies eviction of the dentries in the directory. 59362306a36Sopenharmony_ci */ 59462306a36Sopenharmony_ci if (!(dentry->d_flags & DCACHE_NOKEY_NAME)) 59562306a36Sopenharmony_ci return 1; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci /* 59862306a36Sopenharmony_ci * No-key name; valid if the directory's key is still unavailable. 59962306a36Sopenharmony_ci * 60062306a36Sopenharmony_ci * Although fscrypt forbids rename() on no-key names, we still must use 60162306a36Sopenharmony_ci * dget_parent() here rather than use ->d_parent directly. That's 60262306a36Sopenharmony_ci * because a corrupted fs image may contain directory hard links, which 60362306a36Sopenharmony_ci * the VFS handles by moving the directory's dentry tree in the dcache 60462306a36Sopenharmony_ci * each time ->lookup() finds the directory and it already has a dentry 60562306a36Sopenharmony_ci * elsewhere. Thus ->d_parent can be changing, and we must safely grab 60662306a36Sopenharmony_ci * a reference to some ->d_parent to prevent it from being freed. 60762306a36Sopenharmony_ci */ 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci if (flags & LOOKUP_RCU) 61062306a36Sopenharmony_ci return -ECHILD; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci dir = dget_parent(dentry); 61362306a36Sopenharmony_ci /* 61462306a36Sopenharmony_ci * Pass allow_unsupported=true, so that files with an unsupported 61562306a36Sopenharmony_ci * encryption policy can be deleted. 61662306a36Sopenharmony_ci */ 61762306a36Sopenharmony_ci err = fscrypt_get_encryption_info(d_inode(dir), true); 61862306a36Sopenharmony_ci valid = !fscrypt_has_encryption_key(d_inode(dir)); 61962306a36Sopenharmony_ci dput(dir); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci if (err < 0) 62262306a36Sopenharmony_ci return err; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci return valid; 62562306a36Sopenharmony_ci} 62662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(fscrypt_d_revalidate); 627