162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Common values for the Poly1305 algorithm 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _CRYPTO_POLY1305_H 762306a36Sopenharmony_ci#define _CRYPTO_POLY1305_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/types.h> 1062306a36Sopenharmony_ci#include <linux/crypto.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define POLY1305_BLOCK_SIZE 16 1362306a36Sopenharmony_ci#define POLY1305_KEY_SIZE 32 1462306a36Sopenharmony_ci#define POLY1305_DIGEST_SIZE 16 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* The poly1305_key and poly1305_state types are mostly opaque and 1762306a36Sopenharmony_ci * implementation-defined. Limbs might be in base 2^64 or base 2^26, or 1862306a36Sopenharmony_ci * different yet. The union type provided keeps these 64-bit aligned for the 1962306a36Sopenharmony_ci * case in which this is implemented using 64x64 multiplies. 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct poly1305_key { 2362306a36Sopenharmony_ci union { 2462306a36Sopenharmony_ci u32 r[5]; 2562306a36Sopenharmony_ci u64 r64[3]; 2662306a36Sopenharmony_ci }; 2762306a36Sopenharmony_ci}; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistruct poly1305_core_key { 3062306a36Sopenharmony_ci struct poly1305_key key; 3162306a36Sopenharmony_ci struct poly1305_key precomputed_s; 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistruct poly1305_state { 3562306a36Sopenharmony_ci union { 3662306a36Sopenharmony_ci u32 h[5]; 3762306a36Sopenharmony_ci u64 h64[3]; 3862306a36Sopenharmony_ci }; 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistruct poly1305_desc_ctx { 4262306a36Sopenharmony_ci /* partial buffer */ 4362306a36Sopenharmony_ci u8 buf[POLY1305_BLOCK_SIZE]; 4462306a36Sopenharmony_ci /* bytes used in partial buffer */ 4562306a36Sopenharmony_ci unsigned int buflen; 4662306a36Sopenharmony_ci /* how many keys have been set in r[] */ 4762306a36Sopenharmony_ci unsigned short rset; 4862306a36Sopenharmony_ci /* whether s[] has been set */ 4962306a36Sopenharmony_ci bool sset; 5062306a36Sopenharmony_ci /* finalize key */ 5162306a36Sopenharmony_ci u32 s[4]; 5262306a36Sopenharmony_ci /* accumulator */ 5362306a36Sopenharmony_ci struct poly1305_state h; 5462306a36Sopenharmony_ci /* key */ 5562306a36Sopenharmony_ci union { 5662306a36Sopenharmony_ci struct poly1305_key opaque_r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE]; 5762306a36Sopenharmony_ci struct poly1305_core_key core_r; 5862306a36Sopenharmony_ci }; 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_civoid poly1305_init_arch(struct poly1305_desc_ctx *desc, 6262306a36Sopenharmony_ci const u8 key[POLY1305_KEY_SIZE]); 6362306a36Sopenharmony_civoid poly1305_init_generic(struct poly1305_desc_ctx *desc, 6462306a36Sopenharmony_ci const u8 key[POLY1305_KEY_SIZE]); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic inline void poly1305_init(struct poly1305_desc_ctx *desc, const u8 *key) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 6962306a36Sopenharmony_ci poly1305_init_arch(desc, key); 7062306a36Sopenharmony_ci else 7162306a36Sopenharmony_ci poly1305_init_generic(desc, key); 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_civoid poly1305_update_arch(struct poly1305_desc_ctx *desc, const u8 *src, 7562306a36Sopenharmony_ci unsigned int nbytes); 7662306a36Sopenharmony_civoid poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src, 7762306a36Sopenharmony_ci unsigned int nbytes); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic inline void poly1305_update(struct poly1305_desc_ctx *desc, 8062306a36Sopenharmony_ci const u8 *src, unsigned int nbytes) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 8362306a36Sopenharmony_ci poly1305_update_arch(desc, src, nbytes); 8462306a36Sopenharmony_ci else 8562306a36Sopenharmony_ci poly1305_update_generic(desc, src, nbytes); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_civoid poly1305_final_arch(struct poly1305_desc_ctx *desc, u8 *digest); 8962306a36Sopenharmony_civoid poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *digest); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic inline void poly1305_final(struct poly1305_desc_ctx *desc, u8 *digest) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 9462306a36Sopenharmony_ci poly1305_final_arch(desc, digest); 9562306a36Sopenharmony_ci else 9662306a36Sopenharmony_ci poly1305_final_generic(desc, digest); 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#endif 100