^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Poly1305 authenticator algorithm, RFC7539
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2015 Martin Willi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <crypto/internal/poly1305.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) void poly1305_init_generic(struct poly1305_desc_ctx *desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) const u8 key[POLY1305_KEY_SIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) poly1305_core_setkey(&desc->core_r, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) desc->s[0] = get_unaligned_le32(key + 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) desc->s[1] = get_unaligned_le32(key + 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) desc->s[2] = get_unaligned_le32(key + 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) desc->s[3] = get_unaligned_le32(key + 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) poly1305_core_init(&desc->h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) desc->buflen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) desc->sset = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) desc->rset = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) EXPORT_SYMBOL_GPL(poly1305_init_generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) unsigned int nbytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned int bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (unlikely(desc->buflen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) memcpy(desc->buf + desc->buflen, src, bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) src += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) nbytes -= bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) desc->buflen += bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (desc->buflen == POLY1305_BLOCK_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) desc->buflen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) poly1305_core_blocks(&desc->h, &desc->core_r, src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) nbytes / POLY1305_BLOCK_SIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) src += nbytes - (nbytes % POLY1305_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) nbytes %= POLY1305_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (unlikely(nbytes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) desc->buflen = nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) memcpy(desc->buf, src, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) EXPORT_SYMBOL_GPL(poly1305_update_generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (unlikely(desc->buflen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) desc->buf[desc->buflen++] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) memset(desc->buf + desc->buflen, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) POLY1305_BLOCK_SIZE - desc->buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) poly1305_core_emit(&desc->h, desc->s, dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *desc = (struct poly1305_desc_ctx){};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) EXPORT_SYMBOL_GPL(poly1305_final_generic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");