summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2018-11-16 20:26:27 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2018-11-20 01:26:56 -0500
commit878afc35cd28bcd93cd3c5e1985ef39a104a4d45 (patch)
treee17291b3c2ea1c786fceb3ee4f78cf175273a0cc
parentbdb063a79f6da589af1de3f10a7c8f654fba9ae8 (diff)
crypto: poly1305 - use structures for key and accumulator
In preparation for exposing a low-level Poly1305 API which implements the ε-almost-∆-universal (εA∆U) hash function underlying the Poly1305 MAC and supports block-aligned inputs only, create structures poly1305_key and poly1305_state which hold the limbs of the Poly1305 "r" key and accumulator, respectively. These structures could actually have the same type (e.g. poly1305_val), but different types are preferable, to prevent misuse. Acked-by: Martin Willi <martin@strongswan.org> Signed-off-by: Eric Biggers <ebiggers@google.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/x86/crypto/poly1305_glue.c20
-rw-r--r--crypto/poly1305_generic.c52
-rw-r--r--include/crypto/poly1305.h12
3 files changed, 47 insertions, 37 deletions
diff --git a/arch/x86/crypto/poly1305_glue.c b/arch/x86/crypto/poly1305_glue.c
index f012b7e28ad1..88cc01506c84 100644
--- a/arch/x86/crypto/poly1305_glue.c
+++ b/arch/x86/crypto/poly1305_glue.c
@@ -83,35 +83,37 @@ static unsigned int poly1305_simd_blocks(struct poly1305_desc_ctx *dctx,
83 if (poly1305_use_avx2 && srclen >= POLY1305_BLOCK_SIZE * 4) { 83 if (poly1305_use_avx2 && srclen >= POLY1305_BLOCK_SIZE * 4) {
84 if (unlikely(!sctx->wset)) { 84 if (unlikely(!sctx->wset)) {
85 if (!sctx->uset) { 85 if (!sctx->uset) {
86 memcpy(sctx->u, dctx->r, sizeof(sctx->u)); 86 memcpy(sctx->u, dctx->r.r, sizeof(sctx->u));
87 poly1305_simd_mult(sctx->u, dctx->r); 87 poly1305_simd_mult(sctx->u, dctx->r.r);
88 sctx->uset = true; 88 sctx->uset = true;
89 } 89 }
90 memcpy(sctx->u + 5, sctx->u, sizeof(sctx->u)); 90 memcpy(sctx->u + 5, sctx->u, sizeof(sctx->u));
91 poly1305_simd_mult(sctx->u + 5, dctx->r); 91 poly1305_simd_mult(sctx->u + 5, dctx->r.r);
92 memcpy(sctx->u + 10, sctx->u + 5, sizeof(sctx->u)); 92 memcpy(sctx->u + 10, sctx->u + 5, sizeof(sctx->u));
93 poly1305_simd_mult(sctx->u + 10, dctx->r); 93 poly1305_simd_mult(sctx->u + 10, dctx->r.r);
94 sctx->wset = true; 94 sctx->wset = true;
95 } 95 }
96 blocks = srclen / (POLY1305_BLOCK_SIZE * 4); 96 blocks = srclen / (POLY1305_BLOCK_SIZE * 4);
97 poly1305_4block_avx2(dctx->h, src, dctx->r, blocks, sctx->u); 97 poly1305_4block_avx2(dctx->h.h, src, dctx->r.r, blocks,
98 sctx->u);
98 src += POLY1305_BLOCK_SIZE * 4 * blocks; 99 src += POLY1305_BLOCK_SIZE * 4 * blocks;
99 srclen -= POLY1305_BLOCK_SIZE * 4 * blocks; 100 srclen -= POLY1305_BLOCK_SIZE * 4 * blocks;
100 } 101 }
101#endif 102#endif
102 if (likely(srclen >= POLY1305_BLOCK_SIZE * 2)) { 103 if (likely(srclen >= POLY1305_BLOCK_SIZE * 2)) {
103 if (unlikely(!sctx->uset)) { 104 if (unlikely(!sctx->uset)) {
104 memcpy(sctx->u, dctx->r, sizeof(sctx->u)); 105 memcpy(sctx->u, dctx->r.r, sizeof(sctx->u));
105 poly1305_simd_mult(sctx->u, dctx->r); 106 poly1305_simd_mult(sctx->u, dctx->r.r);
106 sctx->uset = true; 107 sctx->uset = true;
107 } 108 }
108 blocks = srclen / (POLY1305_BLOCK_SIZE * 2); 109 blocks = srclen / (POLY1305_BLOCK_SIZE * 2);
109 poly1305_2block_sse2(dctx->h, src, dctx->r, blocks, sctx->u); 110 poly1305_2block_sse2(dctx->h.h, src, dctx->r.r, blocks,
111 sctx->u);
110 src += POLY1305_BLOCK_SIZE * 2 * blocks; 112 src += POLY1305_BLOCK_SIZE * 2 * blocks;
111 srclen -= POLY1305_BLOCK_SIZE * 2 * blocks; 113 srclen -= POLY1305_BLOCK_SIZE * 2 * blocks;
112 } 114 }
113 if (srclen >= POLY1305_BLOCK_SIZE) { 115 if (srclen >= POLY1305_BLOCK_SIZE) {
114 poly1305_block_sse2(dctx->h, src, dctx->r, 1); 116 poly1305_block_sse2(dctx->h.h, src, dctx->r.r, 1);
115 srclen -= POLY1305_BLOCK_SIZE; 117 srclen -= POLY1305_BLOCK_SIZE;
116 } 118 }
117 return srclen; 119 return srclen;
diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c
index 47d3a6b83931..a23173f351b7 100644
--- a/crypto/poly1305_generic.c
+++ b/crypto/poly1305_generic.c
@@ -38,7 +38,7 @@ int crypto_poly1305_init(struct shash_desc *desc)
38{ 38{
39 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); 39 struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
40 40
41 memset(dctx->h, 0, sizeof(dctx->h)); 41 memset(dctx->h.h, 0, sizeof(dctx->h.h));
42 dctx->buflen = 0; 42 dctx->buflen = 0;
43 dctx->rset = false; 43 dctx->rset = false;
44 dctx->sset = false; 44 dctx->sset = false;
@@ -50,11 +50,11 @@ EXPORT_SYMBOL_GPL(crypto_poly1305_init);
50static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key) 50static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key)
51{ 51{
52 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ 52 /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
53 dctx->r[0] = (get_unaligned_le32(key + 0) >> 0) & 0x3ffffff; 53 dctx->r.r[0] = (get_unaligned_le32(key + 0) >> 0) & 0x3ffffff;
54 dctx->r[1] = (get_unaligned_le32(key + 3) >> 2) & 0x3ffff03; 54 dctx->r.r[1] = (get_unaligned_le32(key + 3) >> 2) & 0x3ffff03;
55 dctx->r[2] = (get_unaligned_le32(key + 6) >> 4) & 0x3ffc0ff; 55 dctx->r.r[2] = (get_unaligned_le32(key + 6) >> 4) & 0x3ffc0ff;
56 dctx->r[3] = (get_unaligned_le32(key + 9) >> 6) & 0x3f03fff; 56 dctx->r.r[3] = (get_unaligned_le32(key + 9) >> 6) & 0x3f03fff;
57 dctx->r[4] = (get_unaligned_le32(key + 12) >> 8) & 0x00fffff; 57 dctx->r.r[4] = (get_unaligned_le32(key + 12) >> 8) & 0x00fffff;
58} 58}
59 59
60static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key) 60static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key)
@@ -107,22 +107,22 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
107 srclen = datalen; 107 srclen = datalen;
108 } 108 }
109 109
110 r0 = dctx->r[0]; 110 r0 = dctx->r.r[0];
111 r1 = dctx->r[1]; 111 r1 = dctx->r.r[1];
112 r2 = dctx->r[2]; 112 r2 = dctx->r.r[2];
113 r3 = dctx->r[3]; 113 r3 = dctx->r.r[3];
114 r4 = dctx->r[4]; 114 r4 = dctx->r.r[4];
115 115
116 s1 = r1 * 5; 116 s1 = r1 * 5;
117 s2 = r2 * 5; 117 s2 = r2 * 5;
118 s3 = r3 * 5; 118 s3 = r3 * 5;
119 s4 = r4 * 5; 119 s4 = r4 * 5;
120 120
121 h0 = dctx->h[0]; 121 h0 = dctx->h.h[0];
122 h1 = dctx->h[1]; 122 h1 = dctx->h.h[1];
123 h2 = dctx->h[2]; 123 h2 = dctx->h.h[2];
124 h3 = dctx->h[3]; 124 h3 = dctx->h.h[3];
125 h4 = dctx->h[4]; 125 h4 = dctx->h.h[4];
126 126
127 while (likely(srclen >= POLY1305_BLOCK_SIZE)) { 127 while (likely(srclen >= POLY1305_BLOCK_SIZE)) {
128 128
@@ -157,11 +157,11 @@ static unsigned int poly1305_blocks(struct poly1305_desc_ctx *dctx,
157 srclen -= POLY1305_BLOCK_SIZE; 157 srclen -= POLY1305_BLOCK_SIZE;
158 } 158 }
159 159
160 dctx->h[0] = h0; 160 dctx->h.h[0] = h0;
161 dctx->h[1] = h1; 161 dctx->h.h[1] = h1;
162 dctx->h[2] = h2; 162 dctx->h.h[2] = h2;
163 dctx->h[3] = h3; 163 dctx->h.h[3] = h3;
164 dctx->h[4] = h4; 164 dctx->h.h[4] = h4;
165 165
166 return srclen; 166 return srclen;
167} 167}
@@ -220,11 +220,11 @@ int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
220 } 220 }
221 221
222 /* fully carry h */ 222 /* fully carry h */
223 h0 = dctx->h[0]; 223 h0 = dctx->h.h[0];
224 h1 = dctx->h[1]; 224 h1 = dctx->h.h[1];
225 h2 = dctx->h[2]; 225 h2 = dctx->h.h[2];
226 h3 = dctx->h[3]; 226 h3 = dctx->h.h[3];
227 h4 = dctx->h[4]; 227 h4 = dctx->h.h[4];
228 228
229 h2 += (h1 >> 26); h1 = h1 & 0x3ffffff; 229 h2 += (h1 >> 26); h1 = h1 & 0x3ffffff;
230 h3 += (h2 >> 26); h2 = h2 & 0x3ffffff; 230 h3 += (h2 >> 26); h2 = h2 & 0x3ffffff;
diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h
index f718a19da82f..493244c46664 100644
--- a/include/crypto/poly1305.h
+++ b/include/crypto/poly1305.h
@@ -13,13 +13,21 @@
13#define POLY1305_KEY_SIZE 32 13#define POLY1305_KEY_SIZE 32
14#define POLY1305_DIGEST_SIZE 16 14#define POLY1305_DIGEST_SIZE 16
15 15
16struct poly1305_key {
17 u32 r[5]; /* key, base 2^26 */
18};
19
20struct poly1305_state {
21 u32 h[5]; /* accumulator, base 2^26 */
22};
23
16struct poly1305_desc_ctx { 24struct poly1305_desc_ctx {
17 /* key */ 25 /* key */
18 u32 r[5]; 26 struct poly1305_key r;
19 /* finalize key */ 27 /* finalize key */
20 u32 s[4]; 28 u32 s[4];
21 /* accumulator */ 29 /* accumulator */
22 u32 h[5]; 30 struct poly1305_state h;
23 /* partial buffer */ 31 /* partial buffer */
24 u8 buf[POLY1305_BLOCK_SIZE]; 32 u8 buf[POLY1305_BLOCK_SIZE];
25 /* bytes used in partial buffer */ 33 /* bytes used in partial buffer */