// SPDX-License-Identifier: GPL-2.0
/*
 * This file is part of UBIFS.
 *
 * Copyright (C) 2018 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
 */

/*
 * This file implements various helper functions for UBIFS authentication support
 */

#include <linux/crypto.h>
#include <crypto/hash.h>
#include <crypto/sha.h>
#include <crypto/algapi.h>
#include <keys/user-type.h>

#include "ubifs.h"

/**
 * ubifs_node_calc_hash - calculate the hash of a UBIFS node
 * @c: UBIFS file-system description object
 * @node: the node to calculate a hash for
 * @hash: the returned hash
 *
 * Returns 0 for success or a negative error code otherwise.
 */
int __ubifs_node_calc_hash(const struct ubifs_info *c, const void *node,
			    u8 *hash)
{
	const struct ubifs_ch *ch = node;
	SHASH_DESC_ON_STACK(shash, c->hash_tfm);
	int err;

	shash->tfm = c->hash_tfm;

	err = crypto_shash_digest(shash, node, le32_to_cpu(ch->len), hash);
	if (err < 0)
		return err;
	return 0;
}

/**
 * ubifs_hash_calc_hmac - calculate a HMAC from a hash
 * @c: UBIFS file-system description object
 * @hash: the node to calculate a HMAC for
 * @hmac: the returned HMAC
 *
 * Returns 0 for success or a negative error code otherwise.
 */
static int ubifs_hash_calc_hmac(const struct ubifs_info *c, const u8 *hash,
				 u8 *hmac)
{
	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
	int err;

	shash->tfm = c->hmac_tfm;

	err = crypto_shash_digest(shash, hash, c->hash_len, hmac);
	if (err < 0)
		return err;
	return 0;
}

/**
 * ubifs_prepare_auth_node - Prepare an authentication node
 * @c: UBIFS file-system description object
 * @node: the node to calculate a hash for
 * @hash: input hash of previous nodes
 *
 * This function prepares an authentication node for writing onto flash.
 * It creates a HMAC from the given input hash and writes it to the node.
 *
 * Returns 0 for success or a negative error code otherwise.
 */
int ubifs_prepare_auth_node(struct ubifs_info *c, void *node,
			     struct shash_desc *inhash)
{
	struct ubifs_auth_node *auth = node;
	u8 *hash;
	int err;

	hash = kmalloc(crypto_shash_descsize(c->hash_tfm), GFP_NOFS);
	if (!hash)
		return -ENOMEM;

	{
		SHASH_DESC_ON_STACK(hash_desc, c->hash_tfm);

		hash_desc->tfm = c->hash_tfm;
		ubifs_shash_copy_state(c, inhash, hash_desc);

		err = crypto_shash_final(hash_desc, hash);
		if (err)
			goto out;
	}

	err = ubifs_hash_calc_hmac(c, hash, auth->hmac);
	if (err)
		goto out;

	auth->ch.node_type = UBIFS_AUTH_NODE;
	ubifs_prepare_node(c, auth, ubifs_auth_node_sz(c), 0);

	err = 0;
out:
	kfree(hash);

	return err;
}

static struct shash_desc *ubifs_get_desc(const struct ubifs_info *c,
					 struct crypto_shash *tfm)
{
	struct shash_desc *desc;
	int err;

	if (!ubifs_authenticated(c))
		return NULL;

	desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL);
	if (!desc)
		return ERR_PTR(-ENOMEM);

	desc->tfm = tfm;

	err = crypto_shash_init(desc);
	if (err) {
		kfree(desc);
		return ERR_PTR(err);
	}

	return desc;
}

/**
 * __ubifs_hash_get_desc - get a descriptor suitable for hashing a node
 * @c: UBIFS file-system description object
 *
 * This function returns a descriptor suitable for hashing a node. Free after use
 * with kfree.
 */
struct shash_desc *__ubifs_hash_get_desc(const struct ubifs_info *c)
{
	return ubifs_get_desc(c, c->hash_tfm);
}

/**
 * ubifs_bad_hash - Report hash mismatches
 * @c: UBIFS file-system description object
 * @node: the node
 * @hash: the expected hash
 * @lnum: the LEB @node was read from
 * @offs: offset in LEB @node was read from
 *
 * This function reports a hash mismatch when a node has a different hash than
 * expected.
 */
void ubifs_bad_hash(const struct ubifs_info *c, const void *node, const u8 *hash,
		    int lnum, int offs)
{
	int len = min(c->hash_len, 20);
	int cropped = len != c->hash_len;
	const char *cont = cropped ? "..." : "";

	u8 calc[UBIFS_HASH_ARR_SZ];

	__ubifs_node_calc_hash(c, node, calc);

	ubifs_err(c, "hash mismatch on node at LEB %d:%d", lnum, offs);
	ubifs_err(c, "hash expected:   %*ph%s", len, hash, cont);
	ubifs_err(c, "hash calculated: %*ph%s", len, calc, cont);
}

/**
 * __ubifs_node_check_hash - check the hash of a node against given hash
 * @c: UBIFS file-system description object
 * @node: the node
 * @expected: the expected hash
 *
 * This function calculates a hash over a node and compares it to the given hash.
 * Returns 0 if both hashes are equal or authentication is disabled, otherwise a
 * negative error code is returned.
 */
int __ubifs_node_check_hash(const struct ubifs_info *c, const void *node,
			    const u8 *expected)
{
	u8 calc[UBIFS_HASH_ARR_SZ];
	int err;

	err = __ubifs_node_calc_hash(c, node, calc);
	if (err)
		return err;

	if (ubifs_check_hash(c, expected, calc))
		return -EPERM;

	return 0;
}

/**
 * ubifs_init_authentication - initialize UBIFS authentication support
 * @c: UBIFS file-system description object
 *
 * This function returns 0 for success or a negative error code otherwise.
 */
int ubifs_init_authentication(struct ubifs_info *c)
{
	struct key *keyring_key;
	const struct user_key_payload *ukp;
	int err;
	char hmac_name[CRYPTO_MAX_ALG_NAME];

	if (!c->auth_hash_name) {
		ubifs_err(c, "authentication hash name needed with authentication");
		return -EINVAL;
	}

	c->auth_hash_algo = match_string(hash_algo_name, HASH_ALGO__LAST,
					 c->auth_hash_name);
	if ((int)c->auth_hash_algo < 0) {
		ubifs_err(c, "Unknown hash algo %s specified",
			  c->auth_hash_name);
		return -EINVAL;
	}

	snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
		 c->auth_hash_name);

	keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL);

	if (IS_ERR(keyring_key)) {
		ubifs_err(c, "Failed to request key: %ld",
			  PTR_ERR(keyring_key));
		return PTR_ERR(keyring_key);
	}

	down_read(&keyring_key->sem);

	if (keyring_key->type != &key_type_logon) {
		ubifs_err(c, "key type must be logon");
		err = -ENOKEY;
		goto out;
	}

	ukp = user_key_payload_locked(keyring_key);
	if (!ukp) {
		/* key was revoked before we acquired its semaphore */
		err = -EKEYREVOKED;
		goto out;
	}

	c->hash_tfm = crypto_alloc_shash(c->auth_hash_name, 0, 0);
	if (IS_ERR(c->hash_tfm)) {
		err = PTR_ERR(c->hash_tfm);
		ubifs_err(c, "Can not allocate %s: %d",
			  c->auth_hash_name, err);
		goto out;
	}

	c->hash_len = crypto_shash_digestsize(c->hash_tfm);
	if (c->hash_len > UBIFS_HASH_ARR_SZ) {
		ubifs_err(c, "hash %s is bigger than maximum allowed hash size (%d > %d)",
			  c->auth_hash_name, c->hash_len, UBIFS_HASH_ARR_SZ);
		err = -EINVAL;
		goto out_free_hash;
	}

	c->hmac_tfm = crypto_alloc_shash(hmac_name, 0, 0);
	if (IS_ERR(c->hmac_tfm)) {
		err = PTR_ERR(c->hmac_tfm);
		ubifs_err(c, "Can not allocate %s: %d", hmac_name, err);
		goto out_free_hash;
	}

	c->hmac_desc_len = crypto_shash_digestsize(c->hmac_tfm);
	if (c->hmac_desc_len > UBIFS_HMAC_ARR_SZ) {
		ubifs_err(c, "hmac %s is bigger than maximum allowed hmac size (%d > %d)",
			  hmac_name, c->hmac_desc_len, UBIFS_HMAC_ARR_SZ);
		err = -EINVAL;
		goto out_free_hash;
	}

	err = crypto_shash_setkey(c->hmac_tfm, ukp->data, ukp->datalen);
	if (err)
		goto out_free_hmac;

	c->authenticated = true;

	c->log_hash = ubifs_hash_get_desc(c);
	if (IS_ERR(c->log_hash))
		goto out_free_hmac;

	err = 0;

out_free_hmac:
	if (err)
		crypto_free_shash(c->hmac_tfm);
out_free_hash:
	if (err)
		crypto_free_shash(c->hash_tfm);
out:
	up_read(&keyring_key->sem);
	key_put(keyring_key);

	return err;
}

/**
 * __ubifs_exit_authentication - release resource
 * @c: UBIFS file-system description object
 *
 * This function releases the authentication related resources.
 */
void __ubifs_exit_authentication(struct ubifs_info *c)
{
	if (!ubifs_authenticated(c))
		return;

	crypto_free_shash(c->hmac_tfm);
	crypto_free_shash(c->hash_tfm);
	kfree(c->log_hash);
}

/**
 * ubifs_node_calc_hmac - calculate the HMAC of a UBIFS node
 * @c: UBIFS file-system description object
 * @node: the node to insert a HMAC into.
 * @len: the length of the node
 * @ofs_hmac: the offset in the node where the HMAC is inserted
 * @hmac: returned HMAC
 *
 * This function calculates a HMAC of a UBIFS node. The HMAC is expected to be
 * embedded into the node, so this area is not covered by the HMAC. Also not
 * covered is the UBIFS_NODE_MAGIC and the CRC of the node.
 */
static int ubifs_node_calc_hmac(const struct ubifs_info *c, const void *node,
				int len, int ofs_hmac, void *hmac)
{
	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
	int hmac_len = c->hmac_desc_len;
	int err;

	ubifs_assert(c, ofs_hmac > 8);
	ubifs_assert(c, ofs_hmac + hmac_len < len);

	shash->tfm = c->hmac_tfm;

	err = crypto_shash_init(shash);
	if (err)
		return err;

	/* behind common node header CRC up to HMAC begin */
	err = crypto_shash_update(shash, node + 8, ofs_hmac - 8);
	if (err < 0)
		return err;

	/* behind HMAC, if any */
	if (len - ofs_hmac - hmac_len > 0) {
		err = crypto_shash_update(shash, node + ofs_hmac + hmac_len,
			    len - ofs_hmac - hmac_len);
		if (err < 0)
			return err;
	}

	return crypto_shash_final(shash, hmac);
}

/**
 * __ubifs_node_insert_hmac - insert a HMAC into a UBIFS node
 * @c: UBIFS file-system description object
 * @node: the node to insert a HMAC into.
 * @len: the length of the node
 * @ofs_hmac: the offset in the node where the HMAC is inserted
 *
 * This function inserts a HMAC at offset @ofs_hmac into the node given in
 * @node.
 *
 * This function returns 0 for success or a negative error code otherwise.
 */
int __ubifs_node_insert_hmac(const struct ubifs_info *c, void *node, int len,
			    int ofs_hmac)
{
	return ubifs_node_calc_hmac(c, node, len, ofs_hmac, node + ofs_hmac);
}

/**
 * __ubifs_node_verify_hmac - verify the HMAC of UBIFS node
 * @c: UBIFS file-system description object
 * @node: the node to insert a HMAC into.
 * @len: the length of the node
 * @ofs_hmac: the offset in the node where the HMAC is inserted
 *
 * This function verifies the HMAC at offset @ofs_hmac of the node given in
 * @node. Returns 0 if successful or a negative error code otherwise.
 */
int __ubifs_node_verify_hmac(const struct ubifs_info *c, const void *node,
			     int len, int ofs_hmac)
{
	int hmac_len = c->hmac_desc_len;
	u8 *hmac;
	int err;

	hmac = kmalloc(hmac_len, GFP_NOFS);
	if (!hmac)
		return -ENOMEM;

	err = ubifs_node_calc_hmac(c, node, len, ofs_hmac, hmac);
	if (err)
		return err;

	err = crypto_memneq(hmac, node + ofs_hmac, hmac_len);

	kfree(hmac);

	if (!err)
		return 0;

	return -EPERM;
}

int __ubifs_shash_copy_state(const struct ubifs_info *c, struct shash_desc *src,
			     struct shash_desc *target)
{
	u8 *state;
	int err;

	state = kmalloc(crypto_shash_descsize(src->tfm), GFP_NOFS);
	if (!state)
		return -ENOMEM;

	err = crypto_shash_export(src, state);
	if (err)
		goto out;

	err = crypto_shash_import(target, state);

out:
	kfree(state);

	return err;
}

/**
 * ubifs_hmac_wkm - Create a HMAC of the well known message
 * @c: UBIFS file-system description object
 * @hmac: The HMAC of the well known message
 *
 * This function creates a HMAC of a well known message. This is used
 * to check if the provided key is suitable to authenticate a UBIFS
 * image. This is only a convenience to the user to provide a better
 * error message when the wrong key is provided.
 *
 * This function returns 0 for success or a negative error code otherwise.
 */
int ubifs_hmac_wkm(struct ubifs_info *c, u8 *hmac)
{
	SHASH_DESC_ON_STACK(shash, c->hmac_tfm);
	int err;
	const char well_known_message[] = "UBIFS";

	if (!ubifs_authenticated(c))
		return 0;

	shash->tfm = c->hmac_tfm;

	err = crypto_shash_init(shash);
	if (err)
		return err;

	err = crypto_shash_update(shash, well_known_message,
				  sizeof(well_known_message) - 1);
	if (err < 0)
		return err;

	err = crypto_shash_final(shash, hmac);
	if (err)
		return err;
	return 0;
}
