18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Common values for the Poly1305 algorithm
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _CRYPTO_POLY1305_H
78c2ecf20Sopenharmony_ci#define _CRYPTO_POLY1305_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/types.h>
108c2ecf20Sopenharmony_ci#include <linux/crypto.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define POLY1305_BLOCK_SIZE	16
138c2ecf20Sopenharmony_ci#define POLY1305_KEY_SIZE	32
148c2ecf20Sopenharmony_ci#define POLY1305_DIGEST_SIZE	16
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/* The poly1305_key and poly1305_state types are mostly opaque and
178c2ecf20Sopenharmony_ci * implementation-defined. Limbs might be in base 2^64 or base 2^26, or
188c2ecf20Sopenharmony_ci * different yet. The union type provided keeps these 64-bit aligned for the
198c2ecf20Sopenharmony_ci * case in which this is implemented using 64x64 multiplies.
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistruct poly1305_key {
238c2ecf20Sopenharmony_ci	union {
248c2ecf20Sopenharmony_ci		u32 r[5];
258c2ecf20Sopenharmony_ci		u64 r64[3];
268c2ecf20Sopenharmony_ci	};
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistruct poly1305_core_key {
308c2ecf20Sopenharmony_ci	struct poly1305_key key;
318c2ecf20Sopenharmony_ci	struct poly1305_key precomputed_s;
328c2ecf20Sopenharmony_ci};
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistruct poly1305_state {
358c2ecf20Sopenharmony_ci	union {
368c2ecf20Sopenharmony_ci		u32 h[5];
378c2ecf20Sopenharmony_ci		u64 h64[3];
388c2ecf20Sopenharmony_ci	};
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistruct poly1305_desc_ctx {
428c2ecf20Sopenharmony_ci	/* partial buffer */
438c2ecf20Sopenharmony_ci	u8 buf[POLY1305_BLOCK_SIZE];
448c2ecf20Sopenharmony_ci	/* bytes used in partial buffer */
458c2ecf20Sopenharmony_ci	unsigned int buflen;
468c2ecf20Sopenharmony_ci	/* how many keys have been set in r[] */
478c2ecf20Sopenharmony_ci	unsigned short rset;
488c2ecf20Sopenharmony_ci	/* whether s[] has been set */
498c2ecf20Sopenharmony_ci	bool sset;
508c2ecf20Sopenharmony_ci	/* finalize key */
518c2ecf20Sopenharmony_ci	u32 s[4];
528c2ecf20Sopenharmony_ci	/* accumulator */
538c2ecf20Sopenharmony_ci	struct poly1305_state h;
548c2ecf20Sopenharmony_ci	/* key */
558c2ecf20Sopenharmony_ci	union {
568c2ecf20Sopenharmony_ci		struct poly1305_key opaque_r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE];
578c2ecf20Sopenharmony_ci		struct poly1305_core_key core_r;
588c2ecf20Sopenharmony_ci	};
598c2ecf20Sopenharmony_ci};
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_civoid poly1305_init_arch(struct poly1305_desc_ctx *desc,
628c2ecf20Sopenharmony_ci			const u8 key[POLY1305_KEY_SIZE]);
638c2ecf20Sopenharmony_civoid poly1305_init_generic(struct poly1305_desc_ctx *desc,
648c2ecf20Sopenharmony_ci			   const u8 key[POLY1305_KEY_SIZE]);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic inline void poly1305_init(struct poly1305_desc_ctx *desc, const u8 *key)
678c2ecf20Sopenharmony_ci{
688c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305))
698c2ecf20Sopenharmony_ci		poly1305_init_arch(desc, key);
708c2ecf20Sopenharmony_ci	else
718c2ecf20Sopenharmony_ci		poly1305_init_generic(desc, key);
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_civoid poly1305_update_arch(struct poly1305_desc_ctx *desc, const u8 *src,
758c2ecf20Sopenharmony_ci			  unsigned int nbytes);
768c2ecf20Sopenharmony_civoid poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
778c2ecf20Sopenharmony_ci			     unsigned int nbytes);
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic inline void poly1305_update(struct poly1305_desc_ctx *desc,
808c2ecf20Sopenharmony_ci				   const u8 *src, unsigned int nbytes)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305))
838c2ecf20Sopenharmony_ci		poly1305_update_arch(desc, src, nbytes);
848c2ecf20Sopenharmony_ci	else
858c2ecf20Sopenharmony_ci		poly1305_update_generic(desc, src, nbytes);
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_civoid poly1305_final_arch(struct poly1305_desc_ctx *desc, u8 *digest);
898c2ecf20Sopenharmony_civoid poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *digest);
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic inline void poly1305_final(struct poly1305_desc_ctx *desc, u8 *digest)
928c2ecf20Sopenharmony_ci{
938c2ecf20Sopenharmony_ci	if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305))
948c2ecf20Sopenharmony_ci		poly1305_final_arch(desc, digest);
958c2ecf20Sopenharmony_ci	else
968c2ecf20Sopenharmony_ci		poly1305_final_generic(desc, digest);
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#endif
100