at v6.19-rc8 100 lines 2.5 kB view raw
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/poly1305.h> 11#include <linux/export.h> 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/string.h> 15#include <linux/unaligned.h> 16 17#ifdef CONFIG_CRYPTO_LIB_POLY1305_ARCH 18#include "poly1305.h" /* $(SRCARCH)/poly1305.h */ 19#else 20#define poly1305_block_init poly1305_block_init_generic 21#define poly1305_blocks poly1305_blocks_generic 22#define poly1305_emit poly1305_emit_generic 23#endif 24 25void poly1305_init(struct poly1305_desc_ctx *desc, 26 const u8 key[POLY1305_KEY_SIZE]) 27{ 28 desc->s[0] = get_unaligned_le32(key + 16); 29 desc->s[1] = get_unaligned_le32(key + 20); 30 desc->s[2] = get_unaligned_le32(key + 24); 31 desc->s[3] = get_unaligned_le32(key + 28); 32 desc->buflen = 0; 33 poly1305_block_init(&desc->state, key); 34} 35EXPORT_SYMBOL(poly1305_init); 36 37void poly1305_update(struct poly1305_desc_ctx *desc, 38 const u8 *src, unsigned int nbytes) 39{ 40 if (desc->buflen + nbytes >= POLY1305_BLOCK_SIZE) { 41 unsigned int bulk_len; 42 43 if (desc->buflen) { 44 unsigned int l = POLY1305_BLOCK_SIZE - desc->buflen; 45 46 memcpy(&desc->buf[desc->buflen], src, l); 47 src += l; 48 nbytes -= l; 49 50 poly1305_blocks(&desc->state, desc->buf, 51 POLY1305_BLOCK_SIZE, 1); 52 desc->buflen = 0; 53 } 54 55 bulk_len = round_down(nbytes, POLY1305_BLOCK_SIZE); 56 nbytes %= POLY1305_BLOCK_SIZE; 57 58 if (bulk_len) { 59 poly1305_blocks(&desc->state, src, bulk_len, 1); 60 src += bulk_len; 61 } 62 } 63 if (nbytes) { 64 memcpy(&desc->buf[desc->buflen], src, nbytes); 65 desc->buflen += nbytes; 66 } 67} 68EXPORT_SYMBOL(poly1305_update); 69 70void poly1305_final(struct poly1305_desc_ctx *desc, u8 *dst) 71{ 72 if (unlikely(desc->buflen)) { 73 desc->buf[desc->buflen++] = 1; 74 memset(desc->buf + desc->buflen, 0, 75 POLY1305_BLOCK_SIZE - desc->buflen); 76 poly1305_blocks(&desc->state, desc->buf, POLY1305_BLOCK_SIZE, 77 0); 78 } 79 80 poly1305_emit(&desc->state.h, dst, desc->s); 81 *desc = (struct poly1305_desc_ctx){}; 82} 83EXPORT_SYMBOL(poly1305_final); 84 85#ifdef poly1305_mod_init_arch 86static int __init poly1305_mod_init(void) 87{ 88 poly1305_mod_init_arch(); 89 return 0; 90} 91subsys_initcall(poly1305_mod_init); 92 93static void __exit poly1305_mod_exit(void) 94{ 95} 96module_exit(poly1305_mod_exit); 97#endif 98 99MODULE_LICENSE("GPL"); 100MODULE_DESCRIPTION("Poly1305 authenticator algorithm, RFC7539");