// SPDX-License-Identifier: GPL-2.0
/*
 * fs-verity hash algorithms
 *
 * Copyright 2019 Google LLC
 */

#include "fsverity_private.h"

#include <crypto/hash.h>
#include <linux/scatterlist.h>

/* The hash algorithms supported by fs-verity */
struct fsverity_hash_alg fsverity_hash_algs[] = {
	[FS_VERITY_HASH_ALG_SHA256] = {
		.name = "sha256",
		.digest_size = SHA256_DIGEST_SIZE,
		.block_size = SHA256_BLOCK_SIZE,
	},
	[FS_VERITY_HASH_ALG_SHA512] = {
		.name = "sha512",
		.digest_size = SHA512_DIGEST_SIZE,
		.block_size = SHA512_BLOCK_SIZE,
	},
};

static DEFINE_MUTEX(fsverity_hash_alg_init_mutex);

/**
 * fsverity_get_hash_alg() - validate and prepare a hash algorithm
 * @inode: optional inode for logging purposes
 * @num: the hash algorithm number
 *
 * Get the struct fsverity_hash_alg for the given hash algorithm number, and
 * ensure it has a hash transform ready to go.  The hash transforms are
 * allocated on-demand so that we don't waste resources unnecessarily, and
 * because the crypto modules may be initialized later than fs/verity/.
 *
 * Return: pointer to the hash alg on success, else an ERR_PTR()
 */
struct fsverity_hash_alg *fsverity_get_hash_alg(const struct inode *inode,
						unsigned int num)
{
	struct fsverity_hash_alg *alg;
	struct crypto_ahash *tfm;
	int err;

	if (num >= ARRAY_SIZE(fsverity_hash_algs) ||
	    !fsverity_hash_algs[num].name) {
		fsverity_warn(inode, "Unknown hash algorithm number: %u", num);
		return ERR_PTR(-EINVAL);
	}
	alg = &fsverity_hash_algs[num];

	/* pairs with smp_store_release() below */
	if (likely(smp_load_acquire(&alg->tfm) != NULL))
		return alg;

	mutex_lock(&fsverity_hash_alg_init_mutex);

	if (alg->tfm != NULL)
		goto out_unlock;

	/*
	 * Using the shash API would make things a bit simpler, but the ahash
	 * API is preferable as it allows the use of crypto accelerators.
	 */
	tfm = crypto_alloc_ahash(alg->name, 0, 0);
	if (IS_ERR(tfm)) {
		if (PTR_ERR(tfm) == -ENOENT) {
			fsverity_warn(inode,
				      "Missing crypto API support for hash algorithm \"%s\"",
				      alg->name);
			alg = ERR_PTR(-ENOPKG);
			goto out_unlock;
		}
		fsverity_err(inode,
			     "Error allocating hash algorithm \"%s\": %ld",
			     alg->name, PTR_ERR(tfm));
		alg = ERR_CAST(tfm);
		goto out_unlock;
	}

	err = -EINVAL;
	if (WARN_ON(alg->digest_size != crypto_ahash_digestsize(tfm)))
		goto err_free_tfm;
	if (WARN_ON(alg->block_size != crypto_ahash_blocksize(tfm)))
		goto err_free_tfm;

	err = mempool_init_kmalloc_pool(&alg->req_pool, 1,
					sizeof(struct ahash_request) +
					crypto_ahash_reqsize(tfm));
	if (err)
		goto err_free_tfm;

	pr_info("%s using implementation \"%s\"\n",
		alg->name, crypto_ahash_driver_name(tfm));

	/* pairs with smp_load_acquire() above */
	smp_store_release(&alg->tfm, tfm);
	goto out_unlock;

err_free_tfm:
	crypto_free_ahash(tfm);
	alg = ERR_PTR(err);
out_unlock:
	mutex_unlock(&fsverity_hash_alg_init_mutex);
	return alg;
}

/**
 * fsverity_alloc_hash_request() - allocate a hash request object
 * @alg: the hash algorithm for which to allocate the request
 * @gfp_flags: memory allocation flags
 *
 * This is mempool-backed, so this never fails if __GFP_DIRECT_RECLAIM is set in
 * @gfp_flags.  However, in that case this might need to wait for all
 * previously-allocated requests to be freed.  So to avoid deadlocks, callers
 * must never need multiple requests at a time to make forward progress.
 *
 * Return: the request object on success; NULL on failure (but see above)
 */
struct ahash_request *fsverity_alloc_hash_request(struct fsverity_hash_alg *alg,
						  gfp_t gfp_flags)
{
	struct ahash_request *req = mempool_alloc(&alg->req_pool, gfp_flags);

	if (req)
		ahash_request_set_tfm(req, alg->tfm);
	return req;
}

/**
 * fsverity_free_hash_request() - free a hash request object
 * @alg: the hash algorithm
 * @req: the hash request object to free
 */
void fsverity_free_hash_request(struct fsverity_hash_alg *alg,
				struct ahash_request *req)
{
	if (req) {
		ahash_request_zero(req);
		mempool_free(req, &alg->req_pool);
	}
}

/**
 * fsverity_prepare_hash_state() - precompute the initial hash state
 * @alg: hash algorithm
 * @salt: a salt which is to be prepended to all data to be hashed
 * @salt_size: salt size in bytes, possibly 0
 *
 * Return: NULL if the salt is empty, otherwise the kmalloc()'ed precomputed
 *	   initial hash state on success or an ERR_PTR() on failure.
 */
const u8 *fsverity_prepare_hash_state(struct fsverity_hash_alg *alg,
				      const u8 *salt, size_t salt_size)
{
	u8 *hashstate = NULL;
	struct ahash_request *req = NULL;
	u8 *padded_salt = NULL;
	size_t padded_salt_size;
	struct scatterlist sg;
	DECLARE_CRYPTO_WAIT(wait);
	int err;

	if (salt_size == 0)
		return NULL;

	hashstate = kmalloc(crypto_ahash_statesize(alg->tfm), GFP_KERNEL);
	if (!hashstate)
		return ERR_PTR(-ENOMEM);

	/* This allocation never fails, since it's mempool-backed. */
	req = fsverity_alloc_hash_request(alg, GFP_KERNEL);

	/*
	 * Zero-pad the salt to the next multiple of the input size of the hash
	 * algorithm's compression function, e.g. 64 bytes for SHA-256 or 128
	 * bytes for SHA-512.  This ensures that the hash algorithm won't have
	 * any bytes buffered internally after processing the salt, thus making
	 * salted hashing just as fast as unsalted hashing.
	 */
	padded_salt_size = round_up(salt_size, alg->block_size);
	padded_salt = kzalloc(padded_salt_size, GFP_KERNEL);
	if (!padded_salt) {
		err = -ENOMEM;
		goto err_free;
	}
	memcpy(padded_salt, salt, salt_size);

	sg_init_one(&sg, padded_salt, padded_salt_size);
	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
					CRYPTO_TFM_REQ_MAY_BACKLOG,
				   crypto_req_done, &wait);
	ahash_request_set_crypt(req, &sg, NULL, padded_salt_size);

	err = crypto_wait_req(crypto_ahash_init(req), &wait);
	if (err)
		goto err_free;

	err = crypto_wait_req(crypto_ahash_update(req), &wait);
	if (err)
		goto err_free;

	err = crypto_ahash_export(req, hashstate);
	if (err)
		goto err_free;
out:
	fsverity_free_hash_request(alg, req);
	kfree(padded_salt);
	return hashstate;

err_free:
	kfree(hashstate);
	hashstate = ERR_PTR(err);
	goto out;
}

/**
 * fsverity_hash_page() - hash a single data or hash page
 * @params: the Merkle tree's parameters
 * @inode: inode for which the hashing is being done
 * @req: preallocated hash request
 * @page: the page to hash
 * @out: output digest, size 'params->digest_size' bytes
 *
 * Hash a single data or hash block, assuming block_size == PAGE_SIZE.
 * The hash is salted if a salt is specified in the Merkle tree parameters.
 *
 * Return: 0 on success, -errno on failure
 */
int fsverity_hash_page(const struct merkle_tree_params *params,
		       const struct inode *inode,
		       struct ahash_request *req, struct page *page, u8 *out)
{
	struct scatterlist sg;
	DECLARE_CRYPTO_WAIT(wait);
	int err;

	if (WARN_ON(params->block_size != PAGE_SIZE))
		return -EINVAL;

	sg_init_table(&sg, 1);
	sg_set_page(&sg, page, PAGE_SIZE, 0);
	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
					CRYPTO_TFM_REQ_MAY_BACKLOG,
				   crypto_req_done, &wait);
	ahash_request_set_crypt(req, &sg, out, PAGE_SIZE);

	if (params->hashstate) {
		err = crypto_ahash_import(req, params->hashstate);
		if (err) {
			fsverity_err(inode,
				     "Error %d importing hash state", err);
			return err;
		}
		err = crypto_ahash_finup(req);
	} else {
		err = crypto_ahash_digest(req);
	}

	err = crypto_wait_req(err, &wait);
	if (err)
		fsverity_err(inode, "Error %d computing page hash", err);
	return err;
}

/**
 * fsverity_hash_buffer() - hash some data
 * @alg: the hash algorithm to use
 * @data: the data to hash
 * @size: size of data to hash, in bytes
 * @out: output digest, size 'alg->digest_size' bytes
 *
 * Hash some data which is located in physically contiguous memory (i.e. memory
 * allocated by kmalloc(), not by vmalloc()).  No salt is used.
 *
 * Return: 0 on success, -errno on failure
 */
int fsverity_hash_buffer(struct fsverity_hash_alg *alg,
			 const void *data, size_t size, u8 *out)
{
	struct ahash_request *req;
	struct scatterlist sg;
	DECLARE_CRYPTO_WAIT(wait);
	int err;

	/* This allocation never fails, since it's mempool-backed. */
	req = fsverity_alloc_hash_request(alg, GFP_KERNEL);

	sg_init_one(&sg, data, size);
	ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP |
					CRYPTO_TFM_REQ_MAY_BACKLOG,
				   crypto_req_done, &wait);
	ahash_request_set_crypt(req, &sg, out, size);

	err = crypto_wait_req(crypto_ahash_digest(req), &wait);

	fsverity_free_hash_request(alg, req);
	return err;
}

void __init fsverity_check_hash_algs(void)
{
	size_t i;

	/*
	 * Sanity check the hash algorithms (could be a build-time check, but
	 * they're in an array)
	 */
	for (i = 0; i < ARRAY_SIZE(fsverity_hash_algs); i++) {
		const struct fsverity_hash_alg *alg = &fsverity_hash_algs[i];

		if (!alg->name)
			continue;

		BUG_ON(alg->digest_size > FS_VERITY_MAX_DIGEST_SIZE);

		/*
		 * For efficiency, the implementation currently assumes the
		 * digest and block sizes are powers of 2.  This limitation can
		 * be lifted if the code is updated to handle other values.
		 */
		BUG_ON(!is_power_of_2(alg->digest_size));
		BUG_ON(!is_power_of_2(alg->block_size));
	}
}
