/* SPDX-License-Identifier: GPL-2.0 OR MIT */
/*
 * Helper functions for BLAKE2s implementations.
 * Keep this in sync with the corresponding BLAKE2b header.
 */

#ifndef _CRYPTO_INTERNAL_BLAKE2S_H
#define _CRYPTO_INTERNAL_BLAKE2S_H

#include <crypto/blake2s.h>
#include <crypto/internal/hash.h>
#include <linux/string.h>

void blake2s_compress_generic(struct blake2s_state *state,const u8 *block,
			      size_t nblocks, const u32 inc);

void blake2s_compress_arch(struct blake2s_state *state,const u8 *block,
			   size_t nblocks, const u32 inc);

bool blake2s_selftest(void);

static inline void blake2s_set_lastblock(struct blake2s_state *state)
{
	state->f[0] = -1;
}

typedef void (*blake2s_compress_t)(struct blake2s_state *state,
				   const u8 *block, size_t nblocks, u32 inc);

/* Helper functions for BLAKE2s shared by the library and shash APIs */

static inline void __blake2s_update(struct blake2s_state *state,
				    const u8 *in, size_t inlen,
				    blake2s_compress_t compress)
{
	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;

	if (unlikely(!inlen))
		return;
	if (inlen > fill) {
		memcpy(state->buf + state->buflen, in, fill);
		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
		state->buflen = 0;
		in += fill;
		inlen -= fill;
	}
	if (inlen > BLAKE2S_BLOCK_SIZE) {
		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
		/* Hash one less (full) block than strictly possible */
		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
	}
	memcpy(state->buf + state->buflen, in, inlen);
	state->buflen += inlen;
}

static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
				   blake2s_compress_t compress)
{
	blake2s_set_lastblock(state);
	memset(state->buf + state->buflen, 0,
	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
	(*compress)(state, state->buf, 1, state->buflen);
	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
	memcpy(out, state->h, state->outlen);
}

/* Helper functions for shash implementations of BLAKE2s */

struct blake2s_tfm_ctx {
	u8 key[BLAKE2S_KEY_SIZE];
	unsigned int keylen;
};

static inline int crypto_blake2s_setkey(struct crypto_shash *tfm,
					const u8 *key, unsigned int keylen)
{
	struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);

	if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE)
		return -EINVAL;

	memcpy(tctx->key, key, keylen);
	tctx->keylen = keylen;

	return 0;
}

static inline int crypto_blake2s_init(struct shash_desc *desc)
{
	const struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
	struct blake2s_state *state = shash_desc_ctx(desc);
	unsigned int outlen = crypto_shash_digestsize(desc->tfm);

	__blake2s_init(state, outlen, tctx->key, tctx->keylen);
	return 0;
}

static inline int crypto_blake2s_update(struct shash_desc *desc,
					const u8 *in, unsigned int inlen,
					blake2s_compress_t compress)
{
	struct blake2s_state *state = shash_desc_ctx(desc);

	__blake2s_update(state, in, inlen, compress);
	return 0;
}

static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
				       blake2s_compress_t compress)
{
	struct blake2s_state *state = shash_desc_ctx(desc);

	__blake2s_final(state, out, compress);
	return 0;
}

#endif /* _CRYPTO_INTERNAL_BLAKE2S_H */
