// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Glue code for MD5 implementation for PPC assembler
 *
 * Based on generic implementation.
 *
 * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
 */

#include <crypto/internal/hash.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/cryptohash.h>
#include <linux/types.h>
#include <crypto/md5.h>
#include <asm/byteorder.h>

extern void ppc_md5_transform(u32 *state, const u8 *src, u32 blocks);

static inline void ppc_md5_clear_context(struct md5_state *sctx)
{
	int count = sizeof(struct md5_state) >> 2;
	u32 *ptr = (u32 *)sctx;

	/* make sure we can clear the fast way */
	BUILD_BUG_ON(sizeof(struct md5_state) % 4);
	do { *ptr++ = 0; } while (--count);
}

static int ppc_md5_init(struct shash_desc *desc)
{
	struct md5_state *sctx = shash_desc_ctx(desc);

	sctx->hash[0] = MD5_H0;
	sctx->hash[1] = MD5_H1;
	sctx->hash[2] = MD5_H2;
	sctx->hash[3] =	MD5_H3;
	sctx->byte_count = 0;

	return 0;
}

static int ppc_md5_update(struct shash_desc *desc, const u8 *data,
			unsigned int len)
{
	struct md5_state *sctx = shash_desc_ctx(desc);
	const unsigned int offset = sctx->byte_count & 0x3f;
	unsigned int avail = 64 - offset;
	const u8 *src = data;

	sctx->byte_count += len;

	if (avail > len) {
		memcpy((char *)sctx->block + offset, src, len);
		return 0;
	}

	if (offset) {
		memcpy((char *)sctx->block + offset, src, avail);
		ppc_md5_transform(sctx->hash, (const u8 *)sctx->block, 1);
		len -= avail;
		src += avail;
	}

	if (len > 63) {
		ppc_md5_transform(sctx->hash, src, len >> 6);
		src += len & ~0x3f;
		len &= 0x3f;
	}

	memcpy((char *)sctx->block, src, len);
	return 0;
}

static int ppc_md5_final(struct shash_desc *desc, u8 *out)
{
	struct md5_state *sctx = shash_desc_ctx(desc);
	const unsigned int offset = sctx->byte_count & 0x3f;
	const u8 *src = (const u8 *)sctx->block;
	u8 *p = (u8 *)src + offset;
	int padlen = 55 - offset;
	__le64 *pbits = (__le64 *)((char *)sctx->block + 56);
	__le32 *dst = (__le32 *)out;

	*p++ = 0x80;

	if (padlen < 0) {
		memset(p, 0x00, padlen + sizeof (u64));
		ppc_md5_transform(sctx->hash, src, 1);
		p = (char *)sctx->block;
		padlen = 56;
	}

	memset(p, 0, padlen);
	*pbits = cpu_to_le64(sctx->byte_count << 3);
	ppc_md5_transform(sctx->hash, src, 1);

	dst[0] = cpu_to_le32(sctx->hash[0]);
	dst[1] = cpu_to_le32(sctx->hash[1]);
	dst[2] = cpu_to_le32(sctx->hash[2]);
	dst[3] = cpu_to_le32(sctx->hash[3]);

	ppc_md5_clear_context(sctx);
	return 0;
}

static int ppc_md5_export(struct shash_desc *desc, void *out)
{
	struct md5_state *sctx = shash_desc_ctx(desc);

	memcpy(out, sctx, sizeof(*sctx));
	return 0;
}

static int ppc_md5_import(struct shash_desc *desc, const void *in)
{
	struct md5_state *sctx = shash_desc_ctx(desc);

	memcpy(sctx, in, sizeof(*sctx));
	return 0;
}

static struct shash_alg alg = {
	.digestsize	=	MD5_DIGEST_SIZE,
	.init		=	ppc_md5_init,
	.update		=	ppc_md5_update,
	.final		=	ppc_md5_final,
	.export		=	ppc_md5_export,
	.import		=	ppc_md5_import,
	.descsize	=	sizeof(struct md5_state),
	.statesize	=	sizeof(struct md5_state),
	.base		=	{
		.cra_name	=	"md5",
		.cra_driver_name=	"md5-ppc",
		.cra_priority	=	200,
		.cra_blocksize	=	MD5_HMAC_BLOCK_SIZE,
		.cra_module	=	THIS_MODULE,
	}
};

static int __init ppc_md5_mod_init(void)
{
	return crypto_register_shash(&alg);
}

static void __exit ppc_md5_mod_fini(void)
{
	crypto_unregister_shash(&alg);
}

module_init(ppc_md5_mod_init);
module_exit(ppc_md5_mod_fini);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, PPC assembler");

MODULE_ALIAS_CRYPTO("md5");
MODULE_ALIAS_CRYPTO("md5-ppc");
