diff options
author | Eric Biggers <ebiggers@google.com> | 2018-11-16 20:26:27 -0500 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2018-11-20 01:26:56 -0500 |
commit | 878afc35cd28bcd93cd3c5e1985ef39a104a4d45 (patch) | |
tree | e17291b3c2ea1c786fceb3ee4f78cf175273a0cc | |
parent | bdb063a79f6da589af1de3f10a7c8f654fba9ae8 (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.c | 20 | ||||
-rw-r--r-- | crypto/poly1305_generic.c | 52 | ||||
-rw-r--r-- | include/crypto/poly1305.h | 12 |
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); | |||
50 | static void poly1305_setrkey(struct poly1305_desc_ctx *dctx, const u8 *key) | 50 | static 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 | ||
60 | static void poly1305_setskey(struct poly1305_desc_ctx *dctx, const u8 *key) | 60 | static 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 | ||
16 | struct poly1305_key { | ||
17 | u32 r[5]; /* key, base 2^26 */ | ||
18 | }; | ||
19 | |||
20 | struct poly1305_state { | ||
21 | u32 h[5]; /* accumulator, base 2^26 */ | ||
22 | }; | ||
23 | |||
16 | struct poly1305_desc_ctx { | 24 | struct 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 */ |