2 * Poly1305 authenticator algorithm, RFC7539
4 * Copyright (C) 2015 Martin Willi
6 * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
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.
14 #include <crypto/algapi.h>
15 #include <crypto/internal/hash.h>
16 #include <linux/crypto.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
20 #define POLY1305_BLOCK_SIZE 16
21 #define POLY1305_KEY_SIZE 32
22 #define POLY1305_DIGEST_SIZE 16
24 struct poly1305_desc_ctx
{
32 u8 buf
[POLY1305_BLOCK_SIZE
];
33 /* bytes used in partial buffer */
35 /* r key has been set */
37 /* s key has been set */
41 static inline u64
mlt(u64 a
, u64 b
)
46 static inline u32
sr(u64 v
, u_char n
)
51 static inline u32
and(u32 v
, u32 mask
)
56 static inline u32
le32_to_cpuvp(const void *p
)
58 return le32_to_cpup(p
);
61 static int poly1305_init(struct shash_desc
*desc
)
63 struct poly1305_desc_ctx
*dctx
= shash_desc_ctx(desc
);
65 memset(dctx
->h
, 0, sizeof(dctx
->h
));
73 static int poly1305_setkey(struct crypto_shash
*tfm
,
74 const u8
*key
, unsigned int keylen
)
76 /* Poly1305 requires a unique key for each tag, which implies that
77 * we can't set it on the tfm that gets accessed by multiple users
78 * simultaneously. Instead we expect the key as the first 32 bytes in
79 * the update() call. */
83 static void poly1305_setrkey(struct poly1305_desc_ctx
*dctx
, const u8
*key
)
85 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
86 dctx
->r
[0] = (le32_to_cpuvp(key
+ 0) >> 0) & 0x3ffffff;
87 dctx
->r
[1] = (le32_to_cpuvp(key
+ 3) >> 2) & 0x3ffff03;
88 dctx
->r
[2] = (le32_to_cpuvp(key
+ 6) >> 4) & 0x3ffc0ff;
89 dctx
->r
[3] = (le32_to_cpuvp(key
+ 9) >> 6) & 0x3f03fff;
90 dctx
->r
[4] = (le32_to_cpuvp(key
+ 12) >> 8) & 0x00fffff;
93 static void poly1305_setskey(struct poly1305_desc_ctx
*dctx
, const u8
*key
)
95 dctx
->s
[0] = le32_to_cpuvp(key
+ 0);
96 dctx
->s
[1] = le32_to_cpuvp(key
+ 4);
97 dctx
->s
[2] = le32_to_cpuvp(key
+ 8);
98 dctx
->s
[3] = le32_to_cpuvp(key
+ 12);
101 static unsigned int poly1305_blocks(struct poly1305_desc_ctx
*dctx
,
102 const u8
*src
, unsigned int srclen
,
105 u32 r0
, r1
, r2
, r3
, r4
;
107 u32 h0
, h1
, h2
, h3
, h4
;
108 u64 d0
, d1
, d2
, d3
, d4
;
110 if (unlikely(!dctx
->sset
)) {
111 if (!dctx
->rset
&& srclen
>= POLY1305_BLOCK_SIZE
) {
112 poly1305_setrkey(dctx
, src
);
113 src
+= POLY1305_BLOCK_SIZE
;
114 srclen
-= POLY1305_BLOCK_SIZE
;
117 if (srclen
>= POLY1305_BLOCK_SIZE
) {
118 poly1305_setskey(dctx
, src
);
119 src
+= POLY1305_BLOCK_SIZE
;
120 srclen
-= POLY1305_BLOCK_SIZE
;
142 while (likely(srclen
>= POLY1305_BLOCK_SIZE
)) {
145 h0
+= (le32_to_cpuvp(src
+ 0) >> 0) & 0x3ffffff;
146 h1
+= (le32_to_cpuvp(src
+ 3) >> 2) & 0x3ffffff;
147 h2
+= (le32_to_cpuvp(src
+ 6) >> 4) & 0x3ffffff;
148 h3
+= (le32_to_cpuvp(src
+ 9) >> 6) & 0x3ffffff;
149 h4
+= (le32_to_cpuvp(src
+ 12) >> 8) | hibit
;
152 d0
= mlt(h0
, r0
) + mlt(h1
, s4
) + mlt(h2
, s3
) +
153 mlt(h3
, s2
) + mlt(h4
, s1
);
154 d1
= mlt(h0
, r1
) + mlt(h1
, r0
) + mlt(h2
, s4
) +
155 mlt(h3
, s3
) + mlt(h4
, s2
);
156 d2
= mlt(h0
, r2
) + mlt(h1
, r1
) + mlt(h2
, r0
) +
157 mlt(h3
, s4
) + mlt(h4
, s3
);
158 d3
= mlt(h0
, r3
) + mlt(h1
, r2
) + mlt(h2
, r1
) +
159 mlt(h3
, r0
) + mlt(h4
, s4
);
160 d4
= mlt(h0
, r4
) + mlt(h1
, r3
) + mlt(h2
, r2
) +
161 mlt(h3
, r1
) + mlt(h4
, r0
);
163 /* (partial) h %= p */
164 d1
+= sr(d0
, 26); h0
= and(d0
, 0x3ffffff);
165 d2
+= sr(d1
, 26); h1
= and(d1
, 0x3ffffff);
166 d3
+= sr(d2
, 26); h2
= and(d2
, 0x3ffffff);
167 d4
+= sr(d3
, 26); h3
= and(d3
, 0x3ffffff);
168 h0
+= sr(d4
, 26) * 5; h4
= and(d4
, 0x3ffffff);
169 h1
+= h0
>> 26; h0
= h0
& 0x3ffffff;
171 src
+= POLY1305_BLOCK_SIZE
;
172 srclen
-= POLY1305_BLOCK_SIZE
;
184 static int poly1305_update(struct shash_desc
*desc
,
185 const u8
*src
, unsigned int srclen
)
187 struct poly1305_desc_ctx
*dctx
= shash_desc_ctx(desc
);
190 if (unlikely(dctx
->buflen
)) {
191 bytes
= min(srclen
, POLY1305_BLOCK_SIZE
- dctx
->buflen
);
192 memcpy(dctx
->buf
+ dctx
->buflen
, src
, bytes
);
195 dctx
->buflen
+= bytes
;
197 if (dctx
->buflen
== POLY1305_BLOCK_SIZE
) {
198 poly1305_blocks(dctx
, dctx
->buf
,
199 POLY1305_BLOCK_SIZE
, 1 << 24);
204 if (likely(srclen
>= POLY1305_BLOCK_SIZE
)) {
205 bytes
= poly1305_blocks(dctx
, src
, srclen
, 1 << 24);
206 src
+= srclen
- bytes
;
210 if (unlikely(srclen
)) {
211 dctx
->buflen
= srclen
;
212 memcpy(dctx
->buf
, src
, srclen
);
218 static int poly1305_final(struct shash_desc
*desc
, u8
*dst
)
220 struct poly1305_desc_ctx
*dctx
= shash_desc_ctx(desc
);
221 __le32
*mac
= (__le32
*)dst
;
222 u32 h0
, h1
, h2
, h3
, h4
;
223 u32 g0
, g1
, g2
, g3
, g4
;
227 if (unlikely(!dctx
->sset
))
230 if (unlikely(dctx
->buflen
)) {
231 dctx
->buf
[dctx
->buflen
++] = 1;
232 memset(dctx
->buf
+ dctx
->buflen
, 0,
233 POLY1305_BLOCK_SIZE
- dctx
->buflen
);
234 poly1305_blocks(dctx
, dctx
->buf
, POLY1305_BLOCK_SIZE
, 0);
244 h2
+= (h1
>> 26); h1
= h1
& 0x3ffffff;
245 h3
+= (h2
>> 26); h2
= h2
& 0x3ffffff;
246 h4
+= (h3
>> 26); h3
= h3
& 0x3ffffff;
247 h0
+= (h4
>> 26) * 5; h4
= h4
& 0x3ffffff;
248 h1
+= (h0
>> 26); h0
= h0
& 0x3ffffff;
252 g1
= h1
+ (g0
>> 26); g0
&= 0x3ffffff;
253 g2
= h2
+ (g1
>> 26); g1
&= 0x3ffffff;
254 g3
= h3
+ (g2
>> 26); g2
&= 0x3ffffff;
255 g4
= h4
+ (g3
>> 26) - (1 << 26); g3
&= 0x3ffffff;
257 /* select h if h < p, or h + -p if h >= p */
258 mask
= (g4
>> ((sizeof(u32
) * 8) - 1)) - 1;
265 h0
= (h0
& mask
) | g0
;
266 h1
= (h1
& mask
) | g1
;
267 h2
= (h2
& mask
) | g2
;
268 h3
= (h3
& mask
) | g3
;
269 h4
= (h4
& mask
) | g4
;
271 /* h = h % (2^128) */
272 h0
= (h0
>> 0) | (h1
<< 26);
273 h1
= (h1
>> 6) | (h2
<< 20);
274 h2
= (h2
>> 12) | (h3
<< 14);
275 h3
= (h3
>> 18) | (h4
<< 8);
277 /* mac = (h + s) % (2^128) */
278 f
= (f
>> 32) + h0
+ dctx
->s
[0]; mac
[0] = cpu_to_le32(f
);
279 f
= (f
>> 32) + h1
+ dctx
->s
[1]; mac
[1] = cpu_to_le32(f
);
280 f
= (f
>> 32) + h2
+ dctx
->s
[2]; mac
[2] = cpu_to_le32(f
);
281 f
= (f
>> 32) + h3
+ dctx
->s
[3]; mac
[3] = cpu_to_le32(f
);
286 static struct shash_alg poly1305_alg
= {
287 .digestsize
= POLY1305_DIGEST_SIZE
,
288 .init
= poly1305_init
,
289 .update
= poly1305_update
,
290 .final
= poly1305_final
,
291 .setkey
= poly1305_setkey
,
292 .descsize
= sizeof(struct poly1305_desc_ctx
),
294 .cra_name
= "poly1305",
295 .cra_driver_name
= "poly1305-generic",
297 .cra_flags
= CRYPTO_ALG_TYPE_SHASH
,
298 .cra_alignmask
= sizeof(u32
) - 1,
299 .cra_blocksize
= POLY1305_BLOCK_SIZE
,
300 .cra_module
= THIS_MODULE
,
304 static int __init
poly1305_mod_init(void)
306 return crypto_register_shash(&poly1305_alg
);
309 static void __exit
poly1305_mod_exit(void)
311 crypto_unregister_shash(&poly1305_alg
);
314 module_init(poly1305_mod_init
);
315 module_exit(poly1305_mod_exit
);
317 MODULE_LICENSE("GPL");
318 MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");
319 MODULE_DESCRIPTION("Poly1305 authenticator");
320 MODULE_ALIAS_CRYPTO("poly1305");
321 MODULE_ALIAS_CRYPTO("poly1305-generic");