4444 *
4545 */
4646
47- #include <linux/unaligned.h>
48- #include <crypto/algapi.h>
4947#include <crypto/gf128mul.h>
50- #include <crypto/polyval.h>
5148#include <crypto/internal/hash.h>
52- #include <linux/crypto.h>
53- #include <linux/init.h>
49+ #include <crypto/polyval.h>
50+ #include <crypto/utils.h>
51+ #include <linux/errno.h>
5452#include <linux/kernel.h>
5553#include <linux/module.h>
54+ #include <linux/string.h>
55+ #include <linux/unaligned.h>
5656
5757struct polyval_tfm_ctx {
5858 struct gf128mul_4k * gf128 ;
@@ -63,7 +63,6 @@ struct polyval_desc_ctx {
6363 u8 buffer [POLYVAL_BLOCK_SIZE ];
6464 be128 buffer128 ;
6565 };
66- u32 bytes ;
6766};
6867
6968static void copy_and_reverse (u8 dst [POLYVAL_BLOCK_SIZE ],
@@ -76,46 +75,6 @@ static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE],
7675 put_unaligned (swab64 (b ), (u64 * )& dst [0 ]);
7776}
7877
79- /*
80- * Performs multiplication in the POLYVAL field using the GHASH field as a
81- * subroutine. This function is used as a fallback for hardware accelerated
82- * implementations when simd registers are unavailable.
83- *
84- * Note: This function is not used for polyval-generic, instead we use the 4k
85- * lookup table implementation for finite field multiplication.
86- */
87- void polyval_mul_non4k (u8 * op1 , const u8 * op2 )
88- {
89- be128 a , b ;
90-
91- // Assume one argument is in Montgomery form and one is not.
92- copy_and_reverse ((u8 * )& a , op1 );
93- copy_and_reverse ((u8 * )& b , op2 );
94- gf128mul_x_lle (& a , & a );
95- gf128mul_lle (& a , & b );
96- copy_and_reverse (op1 , (u8 * )& a );
97- }
98- EXPORT_SYMBOL_GPL (polyval_mul_non4k );
99-
100- /*
101- * Perform a POLYVAL update using non4k multiplication. This function is used
102- * as a fallback for hardware accelerated implementations when simd registers
103- * are unavailable.
104- *
105- * Note: This function is not used for polyval-generic, instead we use the 4k
106- * lookup table implementation of finite field multiplication.
107- */
108- void polyval_update_non4k (const u8 * key , const u8 * in ,
109- size_t nblocks , u8 * accumulator )
110- {
111- while (nblocks -- ) {
112- crypto_xor (accumulator , in , POLYVAL_BLOCK_SIZE );
113- polyval_mul_non4k (accumulator , key );
114- in += POLYVAL_BLOCK_SIZE ;
115- }
116- }
117- EXPORT_SYMBOL_GPL (polyval_update_non4k );
118-
11978static int polyval_setkey (struct crypto_shash * tfm ,
12079 const u8 * key , unsigned int keylen )
12180{
@@ -154,56 +113,53 @@ static int polyval_update(struct shash_desc *desc,
154113{
155114 struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
156115 const struct polyval_tfm_ctx * ctx = crypto_shash_ctx (desc -> tfm );
157- u8 * pos ;
158116 u8 tmp [POLYVAL_BLOCK_SIZE ];
159- int n ;
160-
161- if (dctx -> bytes ) {
162- n = min (srclen , dctx -> bytes );
163- pos = dctx -> buffer + dctx -> bytes - 1 ;
164-
165- dctx -> bytes -= n ;
166- srclen -= n ;
167-
168- while (n -- )
169- * pos -- ^= * src ++ ;
170117
171- if (!dctx -> bytes )
172- gf128mul_4k_lle (& dctx -> buffer128 , ctx -> gf128 );
173- }
174-
175- while (srclen >= POLYVAL_BLOCK_SIZE ) {
118+ do {
176119 copy_and_reverse (tmp , src );
177120 crypto_xor (dctx -> buffer , tmp , POLYVAL_BLOCK_SIZE );
178121 gf128mul_4k_lle (& dctx -> buffer128 , ctx -> gf128 );
179122 src += POLYVAL_BLOCK_SIZE ;
180123 srclen -= POLYVAL_BLOCK_SIZE ;
181- }
124+ } while (srclen >= POLYVAL_BLOCK_SIZE );
125+
126+ return srclen ;
127+ }
182128
183- if (srclen ) {
184- dctx -> bytes = POLYVAL_BLOCK_SIZE - srclen ;
185- pos = dctx -> buffer + POLYVAL_BLOCK_SIZE - 1 ;
186- while (srclen -- )
187- * pos -- ^= * src ++ ;
129+ static int polyval_finup (struct shash_desc * desc , const u8 * src ,
130+ unsigned int len , u8 * dst )
131+ {
132+ struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
133+
134+ if (len ) {
135+ u8 tmp [POLYVAL_BLOCK_SIZE ] = {};
136+
137+ memcpy (tmp , src , len );
138+ polyval_update (desc , tmp , POLYVAL_BLOCK_SIZE );
188139 }
140+ copy_and_reverse (dst , dctx -> buffer );
141+ return 0 ;
142+ }
143+
144+ static int polyval_export (struct shash_desc * desc , void * out )
145+ {
146+ struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
189147
148+ copy_and_reverse (out , dctx -> buffer );
190149 return 0 ;
191150}
192151
193- static int polyval_final (struct shash_desc * desc , u8 * dst )
152+ static int polyval_import (struct shash_desc * desc , const void * in )
194153{
195154 struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
196- const struct polyval_tfm_ctx * ctx = crypto_shash_ctx (desc -> tfm );
197155
198- if (dctx -> bytes )
199- gf128mul_4k_lle (& dctx -> buffer128 , ctx -> gf128 );
200- copy_and_reverse (dst , dctx -> buffer );
156+ copy_and_reverse (dctx -> buffer , in );
201157 return 0 ;
202158}
203159
204- static void polyval_exit_tfm (struct crypto_tfm * tfm )
160+ static void polyval_exit_tfm (struct crypto_shash * tfm )
205161{
206- struct polyval_tfm_ctx * ctx = crypto_tfm_ctx (tfm );
162+ struct polyval_tfm_ctx * ctx = crypto_shash_ctx (tfm );
207163
208164 gf128mul_free_4k (ctx -> gf128 );
209165}
@@ -212,17 +168,21 @@ static struct shash_alg polyval_alg = {
212168 .digestsize = POLYVAL_DIGEST_SIZE ,
213169 .init = polyval_init ,
214170 .update = polyval_update ,
215- .final = polyval_final ,
171+ .finup = polyval_finup ,
216172 .setkey = polyval_setkey ,
173+ .export = polyval_export ,
174+ .import = polyval_import ,
175+ .exit_tfm = polyval_exit_tfm ,
176+ .statesize = sizeof (struct polyval_desc_ctx ),
217177 .descsize = sizeof (struct polyval_desc_ctx ),
218178 .base = {
219179 .cra_name = "polyval" ,
220180 .cra_driver_name = "polyval-generic" ,
221181 .cra_priority = 100 ,
182+ .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY ,
222183 .cra_blocksize = POLYVAL_BLOCK_SIZE ,
223184 .cra_ctxsize = sizeof (struct polyval_tfm_ctx ),
224185 .cra_module = THIS_MODULE ,
225- .cra_exit = polyval_exit_tfm ,
226186 },
227187};
228188
0 commit comments