44
44
*
45
45
*/
46
46
47
- #include <linux/unaligned.h>
48
- #include <crypto/algapi.h>
49
47
#include <crypto/gf128mul.h>
50
- #include <crypto/polyval.h>
51
48
#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>
54
52
#include <linux/kernel.h>
55
53
#include <linux/module.h>
54
+ #include <linux/string.h>
55
+ #include <linux/unaligned.h>
56
56
57
57
struct polyval_tfm_ctx {
58
58
struct gf128mul_4k * gf128 ;
@@ -63,7 +63,6 @@ struct polyval_desc_ctx {
63
63
u8 buffer [POLYVAL_BLOCK_SIZE ];
64
64
be128 buffer128 ;
65
65
};
66
- u32 bytes ;
67
66
};
68
67
69
68
static void copy_and_reverse (u8 dst [POLYVAL_BLOCK_SIZE ],
@@ -76,46 +75,6 @@ static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE],
76
75
put_unaligned (swab64 (b ), (u64 * )& dst [0 ]);
77
76
}
78
77
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
-
119
78
static int polyval_setkey (struct crypto_shash * tfm ,
120
79
const u8 * key , unsigned int keylen )
121
80
{
@@ -154,56 +113,53 @@ static int polyval_update(struct shash_desc *desc,
154
113
{
155
114
struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
156
115
const struct polyval_tfm_ctx * ctx = crypto_shash_ctx (desc -> tfm );
157
- u8 * pos ;
158
116
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 ++ ;
170
117
171
- if (!dctx -> bytes )
172
- gf128mul_4k_lle (& dctx -> buffer128 , ctx -> gf128 );
173
- }
174
-
175
- while (srclen >= POLYVAL_BLOCK_SIZE ) {
118
+ do {
176
119
copy_and_reverse (tmp , src );
177
120
crypto_xor (dctx -> buffer , tmp , POLYVAL_BLOCK_SIZE );
178
121
gf128mul_4k_lle (& dctx -> buffer128 , ctx -> gf128 );
179
122
src += POLYVAL_BLOCK_SIZE ;
180
123
srclen -= POLYVAL_BLOCK_SIZE ;
181
- }
124
+ } while (srclen >= POLYVAL_BLOCK_SIZE );
125
+
126
+ return srclen ;
127
+ }
182
128
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 );
188
139
}
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 );
189
147
148
+ copy_and_reverse (out , dctx -> buffer );
190
149
return 0 ;
191
150
}
192
151
193
- static int polyval_final (struct shash_desc * desc , u8 * dst )
152
+ static int polyval_import (struct shash_desc * desc , const void * in )
194
153
{
195
154
struct polyval_desc_ctx * dctx = shash_desc_ctx (desc );
196
- const struct polyval_tfm_ctx * ctx = crypto_shash_ctx (desc -> tfm );
197
155
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 );
201
157
return 0 ;
202
158
}
203
159
204
- static void polyval_exit_tfm (struct crypto_tfm * tfm )
160
+ static void polyval_exit_tfm (struct crypto_shash * tfm )
205
161
{
206
- struct polyval_tfm_ctx * ctx = crypto_tfm_ctx (tfm );
162
+ struct polyval_tfm_ctx * ctx = crypto_shash_ctx (tfm );
207
163
208
164
gf128mul_free_4k (ctx -> gf128 );
209
165
}
@@ -212,17 +168,21 @@ static struct shash_alg polyval_alg = {
212
168
.digestsize = POLYVAL_DIGEST_SIZE ,
213
169
.init = polyval_init ,
214
170
.update = polyval_update ,
215
- .final = polyval_final ,
171
+ .finup = polyval_finup ,
216
172
.setkey = polyval_setkey ,
173
+ .export = polyval_export ,
174
+ .import = polyval_import ,
175
+ .exit_tfm = polyval_exit_tfm ,
176
+ .statesize = sizeof (struct polyval_desc_ctx ),
217
177
.descsize = sizeof (struct polyval_desc_ctx ),
218
178
.base = {
219
179
.cra_name = "polyval" ,
220
180
.cra_driver_name = "polyval-generic" ,
221
181
.cra_priority = 100 ,
182
+ .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY ,
222
183
.cra_blocksize = POLYVAL_BLOCK_SIZE ,
223
184
.cra_ctxsize = sizeof (struct polyval_tfm_ctx ),
224
185
.cra_module = THIS_MODULE ,
225
- .cra_exit = polyval_exit_tfm ,
226
186
},
227
187
};
228
188
0 commit comments