Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
 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/kernel.h>
12#include <linux/module.h>
13#include <asm/unaligned.h>
14
15void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 *key)
16{
17	poly1305_core_setkey(&desc->core_r, key);
18	desc->s[0] = get_unaligned_le32(key + 16);
19	desc->s[1] = get_unaligned_le32(key + 20);
20	desc->s[2] = get_unaligned_le32(key + 24);
21	desc->s[3] = get_unaligned_le32(key + 28);
22	poly1305_core_init(&desc->h);
23	desc->buflen = 0;
24	desc->sset = true;
25	desc->rset = 2;
26}
27EXPORT_SYMBOL_GPL(poly1305_init_generic);
28
29void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
30			     unsigned int nbytes)
31{
32	unsigned int bytes;
33
34	if (unlikely(desc->buflen)) {
35		bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen);
36		memcpy(desc->buf + desc->buflen, src, bytes);
37		src += bytes;
38		nbytes -= bytes;
39		desc->buflen += bytes;
40
41		if (desc->buflen == POLY1305_BLOCK_SIZE) {
42			poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf,
43					     1, 1);
44			desc->buflen = 0;
45		}
46	}
47
48	if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
49		poly1305_core_blocks(&desc->h, &desc->core_r, src,
50				     nbytes / POLY1305_BLOCK_SIZE, 1);
51		src += nbytes - (nbytes % POLY1305_BLOCK_SIZE);
52		nbytes %= POLY1305_BLOCK_SIZE;
53	}
54
55	if (unlikely(nbytes)) {
56		desc->buflen = nbytes;
57		memcpy(desc->buf, src, nbytes);
58	}
59}
60EXPORT_SYMBOL_GPL(poly1305_update_generic);
61
62void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst)
63{
64	if (unlikely(desc->buflen)) {
65		desc->buf[desc->buflen++] = 1;
66		memset(desc->buf + desc->buflen, 0,
67		       POLY1305_BLOCK_SIZE - desc->buflen);
68		poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf, 1, 0);
69	}
70
71	poly1305_core_emit(&desc->h, desc->s, dst);
72	*desc = (struct poly1305_desc_ctx){};
73}
74EXPORT_SYMBOL_GPL(poly1305_final_generic);
75
76MODULE_LICENSE("GPL");
77MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");