// 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_pbkdf2.h>
#include <tee/tee_cryp_utl.h>
#include <utee_defines.h>

struct hmac_parms {
	uint32_t algo;
	size_t hash_len;
	void *ctx;
};

struct pbkdf2_parms {
	const uint8_t *password;
	size_t password_len;
	const uint8_t *salt;
	size_t salt_len;
	uint32_t iteration_count;
};

static TEE_Result pbkdf2_f(uint8_t *out, size_t len, uint32_t idx,
			   struct hmac_parms *h, struct pbkdf2_parms *p)
{
	TEE_Result res;
	uint8_t u[TEE_MAX_HASH_SIZE];
	uint32_t be_index;
	size_t i, j;

	memset(out, 0, len);
	for (i = 1; i <= p->iteration_count; i++) {
		res = crypto_mac_init(h->ctx, p->password, p->password_len);
		if (res != TEE_SUCCESS)
			return res;

		if (i == 1) {
			if (p->salt && p->salt_len) {
				res = crypto_mac_update(h->ctx, p->salt,
							p->salt_len);
				if (res != TEE_SUCCESS)
					return res;
			}

			be_index = TEE_U32_TO_BIG_ENDIAN(idx);

			res = crypto_mac_update(h->ctx, (uint8_t *)&be_index,
						sizeof(be_index));
			if (res != TEE_SUCCESS)
				return res;
		} else {
			res = crypto_mac_update(h->ctx, u, h->hash_len);
			if (res != TEE_SUCCESS)
				return res;
		}

		res = crypto_mac_final(h->ctx, u, sizeof(u));
		if (res != TEE_SUCCESS)
			return res;

		for (j = 0; j < len; j++)
			out[j] ^= u[j];
	}
	return TEE_SUCCESS;
}

TEE_Result tee_cryp_pbkdf2(uint32_t hash_id, const uint8_t *password,
			   size_t password_len, const uint8_t *salt,
			   size_t salt_len, uint32_t iteration_count,
			   uint8_t *derived_key, size_t derived_key_len)
{
	TEE_Result res;
	size_t i, l, r;
	uint8_t *out = derived_key;
	struct pbkdf2_parms pbkdf2_parms;
	struct hmac_parms hmac_parms = {0, };

	hmac_parms.algo = TEE_ALG_HMAC_ALGO(hash_id);

	res = tee_mac_get_digest_size(hmac_parms.algo, &hmac_parms.hash_len);
	if (res != TEE_SUCCESS)
		return res;

	res = crypto_mac_alloc_ctx(&hmac_parms.ctx, hmac_parms.algo);
	if (res != TEE_SUCCESS)
		return res;

	pbkdf2_parms.password = password;
	pbkdf2_parms.password_len = password_len;
	pbkdf2_parms.salt = salt;
	pbkdf2_parms.salt_len = salt_len;
	pbkdf2_parms.iteration_count = iteration_count;

	l = derived_key_len / hmac_parms.hash_len;
	r = derived_key_len % hmac_parms.hash_len;

	for (i = 1; i <= l; i++) {
		res = pbkdf2_f(out, hmac_parms.hash_len, i, &hmac_parms,
			       &pbkdf2_parms);
		if (res != TEE_SUCCESS)
			goto out;
		out += hmac_parms.hash_len;
	}
	if (r)
		res = pbkdf2_f(out, r, i, &hmac_parms, &pbkdf2_parms);

out:
	crypto_mac_free_ctx(hmac_parms.ctx);
	return res;
}
