/*
 * Cryptographic API.
 *
 * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
 * SHA-256 is used as an underlying hash function.
 *
 * Author : Igor Shcheglakov (i.shcheglako@samsung.com)
 * Date   : 15 Dec 2017
 *
 * Copyright (C) 2017 Samsung Electronics Co., Ltd.
 *
 */

#include <linux/kernel.h>
#include <linux/string.h>

#include "hmac-sha256.h"
#include "sha256.h"

int hmac_sha256_init(struct hmac_sha256_ctx *ctx, const u8 *key, unsigned int key_len)
{
	int ret = -1;
	unsigned int i;
	u8 key_buf[SHA256_BLOCK_SIZE];
	unsigned int key_buf_len;
	u8 inner_pad[SHA256_BLOCK_SIZE];
	u8 outer_pad[SHA256_BLOCK_SIZE];
	unsigned int block_size = SHA256_BLOCK_SIZE;
	unsigned int digest_size = SHA256_DIGEST_SIZE;

	if (!ctx || !key)
		goto err;

	// long keys are hashed
	if (key_len > block_size) {

		if (fmp_sha256(key, key_len, key_buf))
			goto err;

		key_buf_len = digest_size;
	} else {
		memcpy(key_buf, key, key_len);
		key_buf_len = key_len;
	}

	// short keys are padded with zeroes to the right
	if (key_buf_len != block_size)
		memset(&key_buf[key_buf_len], 0, sizeof(key_buf) - key_buf_len);

	// inner and outer padding calculation
	for (i = 0; i < block_size; i++) {
		inner_pad[i] = 0x36 ^ key_buf[i];
		outer_pad[i] = 0x5c ^ key_buf[i];
	}

	// inner hash context preparation
	if (fmp_sha256_init(&ctx->inner_ctx))
		goto err;

	if (fmp_sha256_update(&ctx->inner_ctx, inner_pad, sizeof(inner_pad)))
		goto err;

	// outer hash context preparation
	if (fmp_sha256_init(&ctx->outer_ctx))
		goto err;

	if (fmp_sha256_update(&ctx->outer_ctx, outer_pad, sizeof(outer_pad)))
		goto err;

	ret = 0;

err:
	memset(key_buf, 0, sizeof(key_buf));
	memset(inner_pad, 0, sizeof(inner_pad));
	memset(outer_pad, 0, sizeof(outer_pad));

	return ret;
}

int hmac_sha256_update(struct hmac_sha256_ctx *ctx, const u8 *data, unsigned int data_len)
{
	if (!ctx || !data)
		return 0;

	return fmp_sha256_update(&ctx->inner_ctx, data, data_len);
}

int hmac_sha256_final(struct hmac_sha256_ctx *ctx, u8 *out)
{
	int ret = -1;
	u8 result[SHA256_DIGEST_SIZE];

	if (!ctx || !out)
		goto err;

	if (fmp_sha256_final(&ctx->inner_ctx, result))
		goto err;

	if (fmp_sha256_update(&ctx->outer_ctx, result, sizeof(result)))
		goto err;

	if (fmp_sha256_final(&ctx->outer_ctx, result))
		goto err;

	memcpy(out, result, sizeof(result));

	ret = 0;

err:
	return ret;
}

int hmac_sha256(const u8 *key, unsigned int key_len, const u8 *data, unsigned int data_len, u8 *out)
{
	int ret = -1;
	struct hmac_sha256_ctx ctx;

	if (hmac_sha256_init(&ctx, key, key_len))
		goto err;

	if (hmac_sha256_update(&ctx, data, data_len))
		goto err;

	if (hmac_sha256_final(&ctx, out))
		goto err;

	ret = 0;

err:
	return ret;
}

void hmac_sha256_ctx_cleanup(struct hmac_sha256_ctx *ctx)
{
	memset(ctx, 0, sizeof(struct hmac_sha256_ctx));
}
