1*48ea8c6eSArd Biesheuvel /* SPDX-License-Identifier: GPL-2.0 */ 2*48ea8c6eSArd Biesheuvel /* 3*48ea8c6eSArd Biesheuvel * Common values for the Poly1305 algorithm 4*48ea8c6eSArd Biesheuvel */ 5*48ea8c6eSArd Biesheuvel 6*48ea8c6eSArd Biesheuvel #ifndef _CRYPTO_INTERNAL_POLY1305_H 7*48ea8c6eSArd Biesheuvel #define _CRYPTO_INTERNAL_POLY1305_H 8*48ea8c6eSArd Biesheuvel 9*48ea8c6eSArd Biesheuvel #include <asm/unaligned.h> 10*48ea8c6eSArd Biesheuvel #include <linux/types.h> 11*48ea8c6eSArd Biesheuvel #include <crypto/poly1305.h> 12*48ea8c6eSArd Biesheuvel 13*48ea8c6eSArd Biesheuvel struct shash_desc; 14*48ea8c6eSArd Biesheuvel 15*48ea8c6eSArd Biesheuvel /* 16*48ea8c6eSArd Biesheuvel * Poly1305 core functions. These implement the ε-almost-∆-universal hash 17*48ea8c6eSArd Biesheuvel * function underlying the Poly1305 MAC, i.e. they don't add an encrypted nonce 18*48ea8c6eSArd Biesheuvel * ("s key") at the end. They also only support block-aligned inputs. 19*48ea8c6eSArd Biesheuvel */ 20*48ea8c6eSArd Biesheuvel void poly1305_core_setkey(struct poly1305_key *key, const u8 *raw_key); 21*48ea8c6eSArd Biesheuvel static inline void poly1305_core_init(struct poly1305_state *state) 22*48ea8c6eSArd Biesheuvel { 23*48ea8c6eSArd Biesheuvel *state = (struct poly1305_state){}; 24*48ea8c6eSArd Biesheuvel } 25*48ea8c6eSArd Biesheuvel 26*48ea8c6eSArd Biesheuvel void poly1305_core_blocks(struct poly1305_state *state, 27*48ea8c6eSArd Biesheuvel const struct poly1305_key *key, const void *src, 28*48ea8c6eSArd Biesheuvel unsigned int nblocks, u32 hibit); 29*48ea8c6eSArd Biesheuvel void poly1305_core_emit(const struct poly1305_state *state, void *dst); 30*48ea8c6eSArd Biesheuvel 31*48ea8c6eSArd Biesheuvel /* Crypto API helper functions for the Poly1305 MAC */ 32*48ea8c6eSArd Biesheuvel int crypto_poly1305_init(struct shash_desc *desc); 33*48ea8c6eSArd Biesheuvel 34*48ea8c6eSArd Biesheuvel int crypto_poly1305_update(struct shash_desc *desc, 35*48ea8c6eSArd Biesheuvel const u8 *src, unsigned int srclen); 36*48ea8c6eSArd Biesheuvel int crypto_poly1305_final(struct shash_desc *desc, u8 *dst); 37*48ea8c6eSArd Biesheuvel 38*48ea8c6eSArd Biesheuvel /* 39*48ea8c6eSArd Biesheuvel * Poly1305 requires a unique key for each tag, which implies that we can't set 40*48ea8c6eSArd Biesheuvel * it on the tfm that gets accessed by multiple users simultaneously. Instead we 41*48ea8c6eSArd Biesheuvel * expect the key as the first 32 bytes in the update() call. 42*48ea8c6eSArd Biesheuvel */ 43*48ea8c6eSArd Biesheuvel static inline 44*48ea8c6eSArd Biesheuvel unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx, 45*48ea8c6eSArd Biesheuvel const u8 *src, unsigned int srclen) 46*48ea8c6eSArd Biesheuvel { 47*48ea8c6eSArd Biesheuvel if (!dctx->sset) { 48*48ea8c6eSArd Biesheuvel if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) { 49*48ea8c6eSArd Biesheuvel poly1305_core_setkey(&dctx->r, src); 50*48ea8c6eSArd Biesheuvel src += POLY1305_BLOCK_SIZE; 51*48ea8c6eSArd Biesheuvel srclen -= POLY1305_BLOCK_SIZE; 52*48ea8c6eSArd Biesheuvel dctx->rset = true; 53*48ea8c6eSArd Biesheuvel } 54*48ea8c6eSArd Biesheuvel if (srclen >= POLY1305_BLOCK_SIZE) { 55*48ea8c6eSArd Biesheuvel dctx->s[0] = get_unaligned_le32(src + 0); 56*48ea8c6eSArd Biesheuvel dctx->s[1] = get_unaligned_le32(src + 4); 57*48ea8c6eSArd Biesheuvel dctx->s[2] = get_unaligned_le32(src + 8); 58*48ea8c6eSArd Biesheuvel dctx->s[3] = get_unaligned_le32(src + 12); 59*48ea8c6eSArd Biesheuvel src += POLY1305_BLOCK_SIZE; 60*48ea8c6eSArd Biesheuvel srclen -= POLY1305_BLOCK_SIZE; 61*48ea8c6eSArd Biesheuvel dctx->sset = true; 62*48ea8c6eSArd Biesheuvel } 63*48ea8c6eSArd Biesheuvel } 64*48ea8c6eSArd Biesheuvel return srclen; 65*48ea8c6eSArd Biesheuvel } 66*48ea8c6eSArd Biesheuvel 67*48ea8c6eSArd Biesheuvel #endif 68