1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Poly1305 authenticator algorithm, RFC7539 4 * 5 * Copyright (C) 2015 Martin Willi 6 * 7 * Based on public domain code by Andrew Moon and Daniel J. Bernstein. 8 */ 9 10 #include <crypto/internal/blockhash.h> 11 #include <crypto/internal/poly1305.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/string.h> 15 #include <linux/unaligned.h> 16 17 void poly1305_init(struct poly1305_desc_ctx *desc, 18 const u8 key[POLY1305_KEY_SIZE]) 19 { 20 desc->s[0] = get_unaligned_le32(key + 16); 21 desc->s[1] = get_unaligned_le32(key + 20); 22 desc->s[2] = get_unaligned_le32(key + 24); 23 desc->s[3] = get_unaligned_le32(key + 28); 24 desc->buflen = 0; 25 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 26 poly1305_block_init_arch(&desc->state, key); 27 else 28 poly1305_block_init_generic(&desc->state, key); 29 } 30 EXPORT_SYMBOL(poly1305_init); 31 32 static inline void poly1305_blocks(struct poly1305_block_state *state, 33 const u8 *src, unsigned int len) 34 { 35 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 36 poly1305_blocks_arch(state, src, len, 1); 37 else 38 poly1305_blocks_generic(state, src, len, 1); 39 } 40 41 void poly1305_update(struct poly1305_desc_ctx *desc, 42 const u8 *src, unsigned int nbytes) 43 { 44 desc->buflen = BLOCK_HASH_UPDATE(poly1305_blocks, &desc->state, 45 src, nbytes, POLY1305_BLOCK_SIZE, 46 desc->buf, desc->buflen); 47 } 48 EXPORT_SYMBOL(poly1305_update); 49 50 void poly1305_final(struct poly1305_desc_ctx *desc, u8 *dst) 51 { 52 if (unlikely(desc->buflen)) { 53 desc->buf[desc->buflen++] = 1; 54 memset(desc->buf + desc->buflen, 0, 55 POLY1305_BLOCK_SIZE - desc->buflen); 56 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 57 poly1305_blocks_arch(&desc->state, desc->buf, 58 POLY1305_BLOCK_SIZE, 0); 59 else 60 poly1305_blocks_generic(&desc->state, desc->buf, 61 POLY1305_BLOCK_SIZE, 0); 62 } 63 64 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 65 poly1305_emit_arch(&desc->state.h, dst, desc->s); 66 else 67 poly1305_emit_generic(&desc->state.h, dst, desc->s); 68 *desc = (struct poly1305_desc_ctx){}; 69 } 70 EXPORT_SYMBOL(poly1305_final); 71 72 MODULE_LICENSE("GPL"); 73 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); 74 MODULE_DESCRIPTION("Poly1305 authenticator algorithm, RFC7539"); 75