]> git.sesse.net Git - bcachefs-tools-debian/blob - c_src/linux/crypto/poly1305_generic.c
acb554c04015d5ff87b7b5d23d8e5e2acf7b500c
[bcachefs-tools-debian] / c_src / linux / crypto / poly1305_generic.c
1 /*
2  * Poly1305 authenticator algorithm, RFC7539
3  *
4  * Copyright (C) 2015 Martin Willi
5  *
6  * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/byteorder.h>
15 #include <linux/errno.h>
16 #include <linux/kernel.h>
17 #include <asm/unaligned.h>
18
19 #include <linux/crypto.h>
20 #include <crypto/algapi.h>
21 #include <crypto/hash.h>
22 #include <crypto/poly1305.h>
23
24 static struct shash_alg poly1305_alg;
25
26 struct poly1305_desc_ctx {
27         bool                                    key_done;
28         crypto_onetimeauth_poly1305_state       s;
29 };
30
31 static int poly1305_init(struct shash_desc *desc)
32 {
33         struct poly1305_desc_ctx *state = (void *) desc->ctx;
34
35         state->key_done = false;
36         return 0;
37 }
38
39 static int poly1305_update(struct shash_desc *desc,
40                            const u8 *src, unsigned len)
41 {
42         struct poly1305_desc_ctx *state = (void *) desc->ctx;
43
44         if (!state->key_done) {
45                 BUG_ON(len != crypto_onetimeauth_poly1305_KEYBYTES);
46
47                 state->key_done = true;
48                 return crypto_onetimeauth_poly1305_init(&state->s, src);
49         }
50
51         return crypto_onetimeauth_poly1305_update(&state->s, src, len);
52 }
53
54 static int poly1305_final(struct shash_desc *desc, u8 *out)
55 {
56         struct poly1305_desc_ctx *state = (void *) desc->ctx;
57
58         return crypto_onetimeauth_poly1305_final(&state->s, out);
59 }
60
61 static void *poly1305_alloc_tfm(void)
62 {
63         struct crypto_shash *tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
64
65         if (!tfm)
66                 return NULL;
67
68         tfm->base.alg = &poly1305_alg.base;
69         tfm->descsize = sizeof(struct poly1305_desc_ctx);
70         return tfm;
71 }
72
73 static struct shash_alg poly1305_alg = {
74         .digestsize     = crypto_onetimeauth_poly1305_BYTES,
75         .init           = poly1305_init,
76         .update         = poly1305_update,
77         .final          = poly1305_final,
78         .descsize       = sizeof(struct poly1305_desc_ctx),
79
80         .base.cra_name  = "poly1305",
81         .base.alloc_tfm = poly1305_alloc_tfm,
82 };
83
84 __attribute__((constructor(110)))
85 static int poly1305_mod_init(void)
86 {
87         return crypto_register_shash(&poly1305_alg);
88 }