/*
 * Copyright (c) 2017-2021 Nordic Semiconductor ASA
 * Copyright (c) 2015 Runtime Inc
 * Copyright (c) 2017 Linaro Ltd
 * Copyright (c) 2020 Gerson Fernando Budke <nandojve@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <stddef.h>
#include <sys/types.h>
#include <device.h>
#include <storage/flash_map.h>
#include "flash_map_priv.h"
#include <drivers/flash.h>
#include <soc.h>
#include <init.h>

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY)
#define SHA256_DIGEST_SIZE 32
#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
#include <tinycrypt/constants.h>
#include <tinycrypt/sha256.h>
#else
#include <mbedtls/md.h>
#endif
#include <string.h>
#endif /* CONFIG_FLASH_AREA_CHECK_INTEGRITY */

int flash_area_check_int_sha256(const struct flash_area *fa,
				const struct flash_area_check *fac)
{
	unsigned char hash[SHA256_DIGEST_SIZE];
#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
	struct tc_sha256_state_struct sha;
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
	mbedtls_md_context_t mbed_hash_ctx;
	const mbedtls_md_info_t *mbed_hash_info;
#endif
	const struct device *dev;
	int to_read;
	int pos;
	int rc;

	if (fa == NULL || fac == NULL || fac->match == NULL ||
	    fac->rbuf == NULL || fac->clen == 0 || fac->rblen == 0) {
		return -EINVAL;
	}

	if (!is_in_flash_area_bounds(fa, fac->off, fac->clen)) {
		return -EINVAL;
	}

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
	if (tc_sha256_init(&sha) != TC_CRYPTO_SUCCESS) {
		return -ESRCH;
	}
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
	mbed_hash_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);

	mbedtls_md_init(&mbed_hash_ctx);

	if (mbedtls_md_setup(&mbed_hash_ctx, mbed_hash_info, 0) != 0) {
		return -ESRCH;
	}

	if (mbedtls_md_starts(&mbed_hash_ctx)) {
		rc = -ESRCH;
		goto error;
	}
#endif

	dev = device_get_binding(fa->fa_dev_name);
	to_read = fac->rblen;

	for (pos = 0; pos < fac->clen; pos += to_read) {
		if (pos + to_read > fac->clen) {
			to_read = fac->clen - pos;
		}

		rc = flash_read(dev, (fa->fa_off + fac->off + pos),
				fac->rbuf, to_read);
		if (rc != 0) {
#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
			return rc;
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
			goto error;
#endif
		}

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
		if (tc_sha256_update(&sha,
				     fac->rbuf,
				     to_read) != TC_CRYPTO_SUCCESS) {
			return -ESRCH;
		}
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
		if (mbedtls_md_update(&mbed_hash_ctx, fac->rbuf, to_read) != 0) {
			rc = -ESRCH;
			goto error;
		}
#endif
	}

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
	if (tc_sha256_final(hash, &sha) != TC_CRYPTO_SUCCESS) {
		return -ESRCH;
	}
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
	if (mbedtls_md_finish(&mbed_hash_ctx, hash) != 0) {
		rc = -ESRCH;
		goto error;
	}
#endif

	if (memcmp(hash, fac->match, SHA256_DIGEST_SIZE)) {
#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_TC)
		return -EILSEQ;
#else /* CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS */
		rc = -EILSEQ;
		goto error;
#endif
	}

#if defined(CONFIG_FLASH_AREA_CHECK_INTEGRITY_MBEDTLS)
error:
	mbedtls_md_free(&mbed_hash_ctx);
#endif
	return rc;
}
