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/export.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/string.h> 16 #include <linux/unaligned.h> 17 18 void poly1305_init(struct poly1305_desc_ctx *desc, 19 const u8 key[POLY1305_KEY_SIZE]) 20 { 21 desc->s[0] = get_unaligned_le32(key + 16); 22 desc->s[1] = get_unaligned_le32(key + 20); 23 desc->s[2] = get_unaligned_le32(key + 24); 24 desc->s[3] = get_unaligned_le32(key + 28); 25 desc->buflen = 0; 26 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 27 poly1305_block_init_arch(&desc->state, key); 28 else 29 poly1305_block_init_generic(&desc->state, key); 30 } 31 EXPORT_SYMBOL(poly1305_init); 32 33 static inline void poly1305_blocks(struct poly1305_block_state *state, 34 const u8 *src, unsigned int len) 35 { 36 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 37 poly1305_blocks_arch(state, src, len, 1); 38 else 39 poly1305_blocks_generic(state, src, len, 1); 40 } 41 42 void poly1305_update(struct poly1305_desc_ctx *desc, 43 const u8 *src, unsigned int nbytes) 44 { 45 desc->buflen = BLOCK_HASH_UPDATE(poly1305_blocks, &desc->state, 46 src, nbytes, POLY1305_BLOCK_SIZE, 47 desc->buf, desc->buflen); 48 } 49 EXPORT_SYMBOL(poly1305_update); 50 51 void poly1305_final(struct poly1305_desc_ctx *desc, u8 *dst) 52 { 53 if (unlikely(desc->buflen)) { 54 desc->buf[desc->buflen++] = 1; 55 memset(desc->buf + desc->buflen, 0, 56 POLY1305_BLOCK_SIZE - desc->buflen); 57 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 58 poly1305_blocks_arch(&desc->state, desc->buf, 59 POLY1305_BLOCK_SIZE, 0); 60 else 61 poly1305_blocks_generic(&desc->state, desc->buf, 62 POLY1305_BLOCK_SIZE, 0); 63 } 64 65 if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305)) 66 poly1305_emit_arch(&desc->state.h, dst, desc->s); 67 else 68 poly1305_emit_generic(&desc->state.h, dst, desc->s); 69 *desc = (struct poly1305_desc_ctx){}; 70 } 71 EXPORT_SYMBOL(poly1305_final); 72 73 MODULE_LICENSE("GPL"); 74 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>"); 75 MODULE_DESCRIPTION("Poly1305 authenticator algorithm, RFC7539"); 76