// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright (c) 2014, Linaro Limited
 */

#include <crypto/crypto.h>
#include <stdlib.h>
#include <string.h>
#include <tee/tee_cryp_hkdf.h>
#include <tee/tee_cryp_utl.h>
#include <utee_defines.h>


static const uint8_t zero_salt[TEE_MAX_HASH_SIZE];

static TEE_Result hkdf_extract(uint32_t hash_id, const uint8_t *ikm,
			       size_t ikm_len, const uint8_t *salt,
			       size_t salt_len, uint8_t *prk, size_t *prk_len)
{
	TEE_Result res;
	void *ctx = NULL;
	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
	uint32_t hmac_algo = (TEE_OPERATION_MAC << 28) | hash_id;

	if (!salt || !salt_len) {
		/*
		 * RFC 5869 section 2.2:
		 * If not provided, [the salt] is set to a string of HashLen
		 * zeros
		 */
		salt = zero_salt;
		res = tee_hash_get_digest_size(hash_algo, &salt_len);
		if (res != TEE_SUCCESS)
			goto out;
	}

	res = crypto_mac_alloc_ctx(&ctx, hmac_algo);
	if (res)
		goto out;

	/*
	 * RFC 5869 section 2.1: "Note that in the extract step, 'IKM' is used
	 * as the HMAC input, not as the HMAC key."
	 * Therefore, salt is the HMAC key in the formula from section 2.2:
	 * "PRK = HMAC-Hash(salt, IKM)"
	 */
	res = crypto_mac_init(ctx, salt, salt_len);
	if (res != TEE_SUCCESS)
		goto out;

	res = crypto_mac_update(ctx, ikm, ikm_len);
	if (res != TEE_SUCCESS)
		goto out;

	res = crypto_mac_final(ctx, prk, *prk_len);
	if (res != TEE_SUCCESS)
		goto out;

	res = tee_hash_get_digest_size(hash_algo, prk_len);
out:
	crypto_mac_free_ctx(ctx);
	return res;
}

static TEE_Result hkdf_expand(uint32_t hash_id, const uint8_t *prk,
			      size_t prk_len, const uint8_t *info,
			      size_t info_len, uint8_t *okm, size_t okm_len)
{
	uint8_t tn[TEE_MAX_HASH_SIZE];
	size_t tn_len, hash_len, i, n, where;
	TEE_Result res = TEE_SUCCESS;
	void *ctx = NULL;
	uint32_t hash_algo = TEE_ALG_HASH_ALGO(hash_id);
	uint32_t hmac_algo = TEE_ALG_HMAC_ALGO(hash_id);

	res = tee_hash_get_digest_size(hash_algo, &hash_len);
	if (res != TEE_SUCCESS)
		goto out;

	if (!okm || prk_len < hash_len) {
		res = TEE_ERROR_BAD_STATE;
		goto out;
	}

	if (!info)
		info_len = 0;

	res = crypto_mac_alloc_ctx(&ctx, hmac_algo);
	if (res)
		goto out;

	/* N = ceil(L/HashLen) */
	n = okm_len / hash_len;
	if ((okm_len % hash_len) != 0)
		n++;

	if (n > 255) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}


	/*
	 * RFC 5869 section 2.3
	 *   T = T(1) | T(2) | T(3) | ... | T(N)
	 *   OKM = first L octets of T
	 *   T(0) = empty string (zero length)
	 *   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
	 *   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
	 *   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
	 *   ...
	 */
	tn_len = 0;
	where = 0;
	for (i = 1; i <= n; i++) {
		uint8_t c = i;

		res = crypto_mac_init(ctx, prk, prk_len);
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_mac_update(ctx, tn, tn_len);
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_mac_update(ctx, info, info_len);
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_mac_update(ctx, &c, 1);
		if (res != TEE_SUCCESS)
			goto out;
		res = crypto_mac_final(ctx, tn, sizeof(tn));
		if (res != TEE_SUCCESS)
			goto out;

		memcpy(okm + where, tn, (i < n) ? hash_len : (okm_len - where));
		where += hash_len;
		tn_len = hash_len;
	}

out:
	crypto_mac_free_ctx(ctx);
	return res;
}

TEE_Result tee_cryp_hkdf(uint32_t hash_id, const uint8_t *ikm, size_t ikm_len,
			 const uint8_t *salt, size_t salt_len,
			 const uint8_t *info, size_t info_len, uint8_t *okm,
			 size_t okm_len)
{
	TEE_Result res;
	uint8_t prk[TEE_MAX_HASH_SIZE];
	size_t prk_len = sizeof(prk);

	res = hkdf_extract(hash_id, ikm, ikm_len, salt, salt_len, prk,
			   &prk_len);
	if (res != TEE_SUCCESS)
		return res;
	res = hkdf_expand(hash_id, prk, prk_len, info, info_len, okm,
			  okm_len);

	return res;
}
