/* SHA-256 and SHA-512 implementation based on code by Oliver Gay
 * <olivier.gay@a3.epfl.ch> under a BSD-style license. See below.
 */
/*
 * FIPS 180-2 SHA-224/256/384/512 implementation
 * Last update: 02/02/2007
 * Issue date:  04/30/2005
 *
 * Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the project nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string.h>

#include "bdb.h"

#define VB2_SHA256_DIGEST_SIZE 32
#define VB2_SHA256_BLOCK_SIZE 64

struct vb2_sha256_context {
	uint32_t h[8];
	uint32_t total_size;
	uint32_t size;
	uint8_t block[2 * VB2_SHA256_BLOCK_SIZE];
};

#define SHFR(x, n)    (x >> n)
#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define CH(x, y, z)  ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
#define UNPACK32(x, str)				\
	{						\
		*((str) + 3) = (uint8_t) ((x)      );	\
		*((str) + 2) = (uint8_t) ((x) >>  8);	\
		*((str) + 1) = (uint8_t) ((x) >> 16);	\
		*((str) + 0) = (uint8_t) ((x) >> 24);	\
	}
#define PACK32(str, x)						\
	{							\
		*(x) =   ((uint32_t) *((str) + 3)      )	\
			| ((uint32_t) *((str) + 2) <<  8)       \
			| ((uint32_t) *((str) + 1) << 16)       \
			| ((uint32_t) *((str) + 0) << 24);      \
	}
#define SHA256_SCR(i)						\
	{							\
		w[i] =  SHA256_F4(w[i -  2]) + w[i -  7]	\
			+ SHA256_F3(w[i - 15]) + w[i - 16];	\
	}

static const uint32_t sha256_h0[8] = {
	0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
	0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};

static const uint32_t sha256_k[64] = {
	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
	0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
	0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
	0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
	0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
	0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
	0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
	0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
	0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
	0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
	0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
	0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
	0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
	0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
	0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
	0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

/* SHA-256 implementation from verified boot library */
void vb2_sha256_init(struct vb2_sha256_context *ctx)
{
	int i;
	for (i = 0; i < 8; i++) {
		ctx->h[i] = sha256_h0[i];
	}
	ctx->size = 0;
	ctx->total_size = 0;
}

static void vb2_sha256_transform(struct vb2_sha256_context *ctx,
				 const uint8_t *message,
				 unsigned int block_nb)
{
	/* Note that these arrays use 72*4=288 bytes of stack */
	uint32_t w[64];
	uint32_t wv[8];
	uint32_t t1, t2;
	const unsigned char *sub_block;
	int i;
	int j;
	for (i = 0; i < (int) block_nb; i++) {
		sub_block = message + (i << 6);
		for (j = 0; j < 16; j++) {
			PACK32(&sub_block[j << 2], &w[j]);
		}
		for (j = 16; j < 64; j++) {
			SHA256_SCR(j);
		}
		for (j = 0; j < 8; j++) {
			wv[j] = ctx->h[j];
		}
		for (j = 0; j < 64; j++) {
			t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])
				+ sha256_k[j] + w[j];
			t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
			wv[7] = wv[6];
			wv[6] = wv[5];
			wv[5] = wv[4];
			wv[4] = wv[3] + t1;
			wv[3] = wv[2];
			wv[2] = wv[1];
			wv[1] = wv[0];
			wv[0] = t1 + t2;
		}
		for (j = 0; j < 8; j++) {
			ctx->h[j] += wv[j];
		}
	}
}

void vb2_sha256_update(struct vb2_sha256_context *ctx,
		       const uint8_t *data,
		       uint32_t size)
{
	unsigned int block_nb;
	unsigned int new_size, rem_size, tmp_size;
	const uint8_t *shifted_data;
	tmp_size = VB2_SHA256_BLOCK_SIZE - ctx->size;
	rem_size = size < tmp_size ? size : tmp_size;
	memcpy(&ctx->block[ctx->size], data, rem_size);
	if (ctx->size + size < VB2_SHA256_BLOCK_SIZE) {
		ctx->size += size;
		return;
	}
	new_size = size - rem_size;
	block_nb = new_size / VB2_SHA256_BLOCK_SIZE;
	shifted_data = data + rem_size;
	vb2_sha256_transform(ctx, ctx->block, 1);
	vb2_sha256_transform(ctx, shifted_data, block_nb);
	rem_size = new_size % VB2_SHA256_BLOCK_SIZE;
	memcpy(ctx->block, &shifted_data[block_nb << 6],
	       rem_size);
	ctx->size = rem_size;
	ctx->total_size += (block_nb + 1) << 6;
}

void vb2_sha256_finalize(struct vb2_sha256_context *ctx, uint8_t *digest)
{
	unsigned int block_nb;
	unsigned int pm_size;
	unsigned int size_b;
	int i;
	block_nb = (1 + ((VB2_SHA256_BLOCK_SIZE - 9)
			 < (ctx->size % VB2_SHA256_BLOCK_SIZE)));
	size_b = (ctx->total_size + ctx->size) << 3;
	pm_size = block_nb << 6;
	memset(ctx->block + ctx->size, 0, pm_size - ctx->size);
	ctx->block[ctx->size] = 0x80;
	UNPACK32(size_b, ctx->block + pm_size - 4);
	vb2_sha256_transform(ctx, ctx->block, block_nb);
	for (i = 0 ; i < 8; i++) {
		UNPACK32(ctx->h[i], &digest[i << 2]);
	}
}

int bdb_sha256(void *digest, const void *buf, size_t size)
{
	struct vb2_sha256_context ctx;

	vb2_sha256_init(&ctx);
	vb2_sha256_update(&ctx, buf, size);
	vb2_sha256_finalize(&ctx, digest);

	return BDB_SUCCESS;
}
