 /*
 * Copyright (C) 2011 The Chromium OS Authors <chromium-os-dev@chromium.org>
 *
 * Device-Mapper block hash tree interface.
 *
 * This file is released under the GPL.
 */

#include <errno.h>
#include <string.h>

#include <asm/atomic.h>
#include <asm/page.h>
#include <linux/device-mapper.h>
#include <linux/gfp.h>
#include <linux/scatterlist.h>

#include "verity/dm-bht.h"

#define DM_MSG_PREFIX "dm bht"

/**
 * dm_bht_compute_hash: hashes a page of data
 */
static int dm_bht_compute_hash(struct dm_bht *bht, struct page *pg,
			       unsigned int offset, u8 *digest)
{
	struct hash_desc *hash_desc = &bht->hash_desc[0];
	struct scatterlist sg;

	sg_init_table(&sg, 1);
	sg_set_page(&sg, pg, PAGE_SIZE, offset);
	/* Note, this is synchronous. */
	if (crypto_hash_init(hash_desc)) {
	  DMCRIT("failed to reinitialize crypto hash");
		return -EINVAL;
	}
	if (crypto_hash_update(hash_desc, &sg, PAGE_SIZE)) {
		DMCRIT("crypto_hash_update failed");
		return -EINVAL;
	}
	if (bht->have_salt) {
		sg_set_buf(&sg, bht->salt, sizeof(bht->salt));
		if (crypto_hash_update(hash_desc, &sg, sizeof(bht->salt))) {
			DMCRIT("crypto_hash_update failed");
			return -EINVAL;
		}
	}
	if (crypto_hash_final(hash_desc, digest)) {
		DMCRIT("crypto_hash_final failed");
		return -EINVAL;
	}

	return 0;
}

void dm_bht_set_buffer(struct dm_bht *bht, void *buffer) {
	int depth;

	for (depth = 0; depth < bht->depth; ++depth) {
		struct dm_bht_level *level = dm_bht_get_level(bht, depth);
		struct dm_bht_entry *entry_end = level->entries + level->count;
		struct dm_bht_entry *entry;

		for (entry = level->entries; entry < entry_end; ++entry) {
			entry->nodes = buffer;
			memset(buffer, 0, PAGE_SIZE);
			buffer += PAGE_SIZE;
		}
	}
}

/**
 * dm_bht_compute - computes and updates all non-block-level hashes in a tree
 * @bht:	pointer to a dm_bht_create()d bht
 *
 * Returns 0 on success, >0 when data is pending, and <0 when a IO or other
 * error has occurred.
 *
 * Walks the tree and computes the hashes at each level from the
 * hashes below.
 */
int dm_bht_compute(struct dm_bht *bht)
{
	int depth, r = 0;

	for (depth = bht->depth - 2; depth >= 0; depth--) {
		struct dm_bht_level *level = dm_bht_get_level(bht, depth);
		struct dm_bht_level *child_level = level + 1;
		struct dm_bht_entry *entry = level->entries;
		struct dm_bht_entry *child = child_level->entries;
		unsigned int i, j;

		for (i = 0; i < level->count; i++, entry++) {
			unsigned int count = bht->node_count;

			memset(entry->nodes, 0, PAGE_SIZE);
			atomic_set(&entry->state, DM_BHT_ENTRY_READY);

			if (i == (level->count - 1))
				count = child_level->count % bht->node_count;
			if (count == 0)
				count = bht->node_count;
			for (j = 0; j < count; j++, child++) {
				struct page *pg = virt_to_page(child->nodes);
				u8 *digest = dm_bht_node(bht, entry, j);

				r = dm_bht_compute_hash(bht, pg, 0, digest);
				if (r) {
					DMERR("Failed to update (d=%d,i=%u)",
					      depth, i);
					goto out;
				}
			}
		}
	}
	r = dm_bht_compute_hash(bht,
				virt_to_page(bht->levels[0].entries->nodes),
				0, bht->root_digest);
	if (r)
		DMERR("Failed to update root hash");

out:
	return r;
}

/**
 * dm_bht_store_block - sets a given block's hash in the tree
 * @bht:	pointer to a dm_bht_create()d bht
 * @block:	numeric index of the block in the tree
 * @block_data:	array of u8s containing the block of data to hash
 *
 * Returns 0 on success.
 *
 * If the containing entry in the tree is unallocated, it will allocate memory
 * and mark the entry as ready.  All other block entries will be 0s.
 *
 * It is up to the users of the update interface to ensure the entry data is
 * fully populated prior to use. The number of updated entries is NOT tracked.
 */
int dm_bht_store_block(struct dm_bht *bht, unsigned int block,
		       u8 *block_data)
{
	int depth = bht->depth;
	struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth - 1, block);
	u8 *node = dm_bht_get_node(bht, entry, depth, block);

	return dm_bht_compute_hash(bht, virt_to_page(block_data), 0, node);
}
