aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2015-07-16 13:14:05 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-07-17 09:20:26 -0400
commit2546f811ef45fc47fcb65531bea98beeed0c97cc (patch)
tree953ec34e28547cb648f131bde32cb842d7348920
parent6692cbc28e88b4cbffaab84b82bfff888c03ed3a (diff)
crypto: poly1305 - Export common Poly1305 helpers
As architecture specific drivers need a software fallback, export Poly1305 init/update/final functions together with some helpers in a header file. Signed-off-by: Martin Willi <martin@strongswan.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--crypto/chacha20poly1305.c4
-rw-r--r--crypto/poly1305_generic.c73
-rw-r--r--include/crypto/poly1305.h41
3 files changed, 77 insertions, 41 deletions
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index 410554d3a1ff..b71445f282ad 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -14,6 +14,7 @@
14#include <crypto/internal/skcipher.h> 14#include <crypto/internal/skcipher.h>
15#include <crypto/scatterwalk.h> 15#include <crypto/scatterwalk.h>
16#include <crypto/chacha20.h> 16#include <crypto/chacha20.h>
17#include <crypto/poly1305.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
@@ -21,9 +22,6 @@
21 22
22#include "internal.h" 23#include "internal.h"
23 24
24#define POLY1305_BLOCK_SIZE 16
25#define POLY1305_DIGEST_SIZE 16
26#define POLY1305_KEY_SIZE 32
27#define CHACHAPOLY_IV_SIZE 12 25#define CHACHAPOLY_IV_SIZE 12
28 26
29struct chachapoly_instance_ctx { 27struct chachapoly_instance_ctx {
diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c
index 387b5c887a80..2df9835dfbc0 100644
--- a/crypto/poly1305_generic.c
+++ b/crypto/poly1305_generic.c
@@ -13,31 +13,11 @@
13 13
14#include <crypto/algapi.h> 14#include <crypto/algapi.h>
15#include <crypto/internal/hash.h> 15#include <crypto/internal/hash.h>
16#include <crypto/poly1305.h>
16#include <linux/crypto.h> 17#include <linux/crypto.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/module.h> 19#include <linux/module.h>
19 20
20#define POLY1305_BLOCK_SIZE 16
21#define POLY1305_KEY_SIZE 32
22#define POLY1305_DIGEST_SIZE 16
23
24struct poly1305_desc_ctx {
25 /* key */
26 u32 r[5];
27 /* finalize key */
28 u32 s[4];
29 /* accumulator */
30 u32 h[5];
31 /* partial buffer */
32 u8 buf[POLY1305_BLOCK_SIZE];
33 /* bytes used in partial buffer */
34 unsigned int buflen;
35 /* r key has been set */
36 bool rset;
37 /* s key has been set */
38 bool sset;
39};
40
41static inline u64 mlt(u64 a, u64 b) 21static inline u64 mlt(u64 a, u64 b)
42{ 22{
43 return a * b; 23 return a * b;
@@ -58,7 +38,7 @@ static inline u32 le32_to_cpuvp(const void *p)
58 return le32_to_cpup(p); 38 return le32_to_cpup(p);
59} 39}
60 40
61static int poly1305_init(struct shash_desc *desc) 41int crypto_poly1305_init(struct shash_desc *desc)
62{ 42{
63 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); 43 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
64 44
@@ -69,8 +49,9 @@ static int poly1305_init(struct shash_desc *desc)
69 49
70 return 0; 50 return 0;
71} 51}
52EXPORT_SYMBOL_GPL(crypto_poly1305_init);
72 53
73static int poly1305_setkey(struct crypto_shash *tfm, 54int crypto_poly1305_setkey(struct crypto_shash *tfm,
74 const u8 *key, unsigned int keylen) 55 const u8 *key, unsigned int keylen)
75{ 56{
76 /* Poly1305 requires a unique key for each tag, which implies that 57 /* Poly1305 requires a unique key for each tag, which implies that
@@ -79,6 +60,7 @@ static int poly1305_setkey(struct crypto_shash *tfm,
79 * the update() call. */ 60 * the update() call. */
80 return -ENOTSUPP; 61 return -ENOTSUPP;
81} 62}
63EXPORT_SYMBOL_GPL(crypto_poly1305_setkey);
82 64
83static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key) 65static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
84{ 66{
@@ -98,16 +80,10 @@ static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key)
98 dctx->s[3] = le32_to_cpuvp(key + 12); 80 dctx->s[3] = le32_to_cpuvp(key + 12);
99} 81}
100 82
101static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx, 83unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
102 const u8 *src, unsigned int srclen, 84 const u8 *src, unsigned int srclen)
103 u32 hibit)
104{ 85{
105 u32 r0, r1, r2, r3, r4; 86 if (!dctx->sset) {
106 u32 s1, s2, s3, s4;
107 u32 h0, h1, h2, h3, h4;
108 u64 d0, d1, d2, d3, d4;
109
110 if (unlikely(!dctx->sset)) {
111 if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) { 87 if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) {
112 poly1305_setrkey(dctx, src); 88 poly1305_setrkey(dctx, src);
113 src += POLY1305_BLOCK_SIZE; 89 src += POLY1305_BLOCK_SIZE;
@@ -121,6 +97,25 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
121 dctx->sset = true; 97 dctx->sset = true;
122 } 98 }
123 } 99 }
100 return srclen;
101}
102EXPORT_SYMBOL_GPL(crypto_poly1305_setdesckey);
103
104static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
105 const u8 *src, unsigned int srclen,
106 u32 hibit)
107{
108 u32 r0, r1, r2, r3, r4;
109 u32 s1, s2, s3, s4;
110 u32 h0, h1, h2, h3, h4;
111 u64 d0, d1, d2, d3, d4;
112 unsigned int datalen;
113
114 if (unlikely(!dctx->sset)) {
115 datalen = crypto_poly1305_setdesckey(dctx, src, srclen);
116 src += srclen - datalen;
117 srclen = datalen;
118 }
124 119
125 r0 = dctx->r[0]; 120 r0 = dctx->r[0];
126 r1 = dctx->r[1]; 121 r1 = dctx->r[1];
@@ -181,7 +176,7 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
181 return srclen; 176 return srclen;
182} 177}
183 178
184static int poly1305_update(struct shash_desc *desc, 179int crypto_poly1305_update(struct shash_desc *desc,
185 const u8 *src, unsigned int srclen) 180 const u8 *src, unsigned int srclen)
186{ 181{
187 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); 182 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
@@ -214,8 +209,9 @@ static int poly1305_update(struct shash_desc *desc,
214 209
215 return 0; 210 return 0;
216} 211}
212EXPORT_SYMBOL_GPL(crypto_poly1305_update);
217 213
218static int poly1305_final(struct shash_desc *desc, u8 *dst) 214int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
219{ 215{
220 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); 216 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
221 __le32 *mac = (__le32 *)dst; 217 __le32 *mac = (__le32 *)dst;
@@ -282,13 +278,14 @@ static int poly1305_final(struct shash_desc *desc, u8 *dst)
282 278
283 return 0; 279 return 0;
284} 280}
281EXPORT_SYMBOL_GPL(crypto_poly1305_final);
285 282
286static struct shash_alg poly1305_alg = { 283static struct shash_alg poly1305_alg = {
287 .digestsize = POLY1305_DIGEST_SIZE, 284 .digestsize = POLY1305_DIGEST_SIZE,
288 .init = poly1305_init, 285 .init = crypto_poly1305_init,
289 .update = poly1305_update, 286 .update = crypto_poly1305_update,
290 .final = poly1305_final, 287 .final = crypto_poly1305_final,
291 .setkey = poly1305_setkey, 288 .setkey = crypto_poly1305_setkey,
292 .descsize = sizeof(struct poly1305_desc_ctx), 289 .descsize = sizeof(struct poly1305_desc_ctx),
293 .base = { 290 .base = {
294 .cra_name = "poly1305", 291 .cra_name = "poly1305",
diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h
new file mode 100644
index 000000000000..894df59b74e4
--- /dev/null
+++ b/include/crypto/poly1305.h
@@ -0,0 +1,41 @@
1/*
2 * Common values for the Poly1305 algorithm
3 */
4
5#ifndef _CRYPTO_POLY1305_H
6#define _CRYPTO_POLY1305_H
7
8#include <linux/types.h>
9#include <linux/crypto.h>
10
11#define POLY1305_BLOCK_SIZE 16
12#define POLY1305_KEY_SIZE 32
13#define POLY1305_DIGEST_SIZE 16
14
15struct poly1305_desc_ctx {
16 /* key */
17 u32 r[5];
18 /* finalize key */
19 u32 s[4];
20 /* accumulator */
21 u32 h[5];
22 /* partial buffer */
23 u8 buf[POLY1305_BLOCK_SIZE];
24 /* bytes used in partial buffer */
25 unsigned int buflen;
26 /* r key has been set */
27 bool rset;
28 /* s key has been set */
29 bool sset;
30};
31
32int crypto_poly1305_init(struct shash_desc *desc);
33int crypto_poly1305_setkey(struct crypto_shash *tfm,
34 const u8 *key, unsigned int keylen);
35unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
36 const u8 *src, unsigned int srclen);
37int crypto_poly1305_update(struct shash_desc *desc,
38 const u8 *src, unsigned int srclen);
39int crypto_poly1305_final(struct shash_desc *desc, u8 *dst);
40
41#endif