diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-04-09 06:55:37 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-10 09:39:41 -0400 |
commit | a2e5ba4fedd6e590bb2cd83817c2bf0cd0de69d1 (patch) | |
tree | 25f6860a8439cf44ded9380229fe687b49d3c66a /crypto | |
parent | 7c71f0f760d65f270aca0849caebb1fd5d53c66b (diff) |
crypto: sha256-generic - move to generic glue implementation
This updates the generic SHA-256 implementation to use the
new shared SHA-256 glue code.
It also implements a .finup hook crypto_sha256_finup() and exports
it to other modules. The import and export() functions and the
.statesize member are dropped, since the default implementation
is perfectly suitable for this module.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/sha256_generic.c | 133 |
1 files changed, 20 insertions, 113 deletions
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index b001ff5c2efc..78431163ed3c 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <crypto/sha.h> | 25 | #include <crypto/sha.h> |
26 | #include <crypto/sha256_base.h> | ||
26 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
27 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
28 | 29 | ||
@@ -214,138 +215,43 @@ static void sha256_transform(u32 *state, const u8 *input) | |||
214 | memzero_explicit(W, 64 * sizeof(u32)); | 215 | memzero_explicit(W, 64 * sizeof(u32)); |
215 | } | 216 | } |
216 | 217 | ||
217 | static int sha224_init(struct shash_desc *desc) | 218 | static void sha256_generic_block_fn(struct sha256_state *sst, u8 const *src, |
219 | int blocks) | ||
218 | { | 220 | { |
219 | struct sha256_state *sctx = shash_desc_ctx(desc); | 221 | while (blocks--) { |
220 | sctx->state[0] = SHA224_H0; | 222 | sha256_transform(sst->state, src); |
221 | sctx->state[1] = SHA224_H1; | 223 | src += SHA256_BLOCK_SIZE; |
222 | sctx->state[2] = SHA224_H2; | 224 | } |
223 | sctx->state[3] = SHA224_H3; | ||
224 | sctx->state[4] = SHA224_H4; | ||
225 | sctx->state[5] = SHA224_H5; | ||
226 | sctx->state[6] = SHA224_H6; | ||
227 | sctx->state[7] = SHA224_H7; | ||
228 | sctx->count = 0; | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | static int sha256_init(struct shash_desc *desc) | ||
234 | { | ||
235 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
236 | sctx->state[0] = SHA256_H0; | ||
237 | sctx->state[1] = SHA256_H1; | ||
238 | sctx->state[2] = SHA256_H2; | ||
239 | sctx->state[3] = SHA256_H3; | ||
240 | sctx->state[4] = SHA256_H4; | ||
241 | sctx->state[5] = SHA256_H5; | ||
242 | sctx->state[6] = SHA256_H6; | ||
243 | sctx->state[7] = SHA256_H7; | ||
244 | sctx->count = 0; | ||
245 | |||
246 | return 0; | ||
247 | } | 225 | } |
248 | 226 | ||
249 | int crypto_sha256_update(struct shash_desc *desc, const u8 *data, | 227 | int crypto_sha256_update(struct shash_desc *desc, const u8 *data, |
250 | unsigned int len) | 228 | unsigned int len) |
251 | { | 229 | { |
252 | struct sha256_state *sctx = shash_desc_ctx(desc); | 230 | return sha256_base_do_update(desc, data, len, sha256_generic_block_fn); |
253 | unsigned int partial, done; | ||
254 | const u8 *src; | ||
255 | |||
256 | partial = sctx->count & 0x3f; | ||
257 | sctx->count += len; | ||
258 | done = 0; | ||
259 | src = data; | ||
260 | |||
261 | if ((partial + len) > 63) { | ||
262 | if (partial) { | ||
263 | done = -partial; | ||
264 | memcpy(sctx->buf + partial, data, done + 64); | ||
265 | src = sctx->buf; | ||
266 | } | ||
267 | |||
268 | do { | ||
269 | sha256_transform(sctx->state, src); | ||
270 | done += 64; | ||
271 | src = data + done; | ||
272 | } while (done + 63 < len); | ||
273 | |||
274 | partial = 0; | ||
275 | } | ||
276 | memcpy(sctx->buf + partial, src, len - done); | ||
277 | |||
278 | return 0; | ||
279 | } | 231 | } |
280 | EXPORT_SYMBOL(crypto_sha256_update); | 232 | EXPORT_SYMBOL(crypto_sha256_update); |
281 | 233 | ||
282 | static int sha256_final(struct shash_desc *desc, u8 *out) | 234 | static int sha256_final(struct shash_desc *desc, u8 *out) |
283 | { | 235 | { |
284 | struct sha256_state *sctx = shash_desc_ctx(desc); | 236 | sha256_base_do_finalize(desc, sha256_generic_block_fn); |
285 | __be32 *dst = (__be32 *)out; | 237 | return sha256_base_finish(desc, out); |
286 | __be64 bits; | ||
287 | unsigned int index, pad_len; | ||
288 | int i; | ||
289 | static const u8 padding[64] = { 0x80, }; | ||
290 | |||
291 | /* Save number of bits */ | ||
292 | bits = cpu_to_be64(sctx->count << 3); | ||
293 | |||
294 | /* Pad out to 56 mod 64. */ | ||
295 | index = sctx->count & 0x3f; | ||
296 | pad_len = (index < 56) ? (56 - index) : ((64+56) - index); | ||
297 | crypto_sha256_update(desc, padding, pad_len); | ||
298 | |||
299 | /* Append length (before padding) */ | ||
300 | crypto_sha256_update(desc, (const u8 *)&bits, sizeof(bits)); | ||
301 | |||
302 | /* Store state in digest */ | ||
303 | for (i = 0; i < 8; i++) | ||
304 | dst[i] = cpu_to_be32(sctx->state[i]); | ||
305 | |||
306 | /* Zeroize sensitive information. */ | ||
307 | memset(sctx, 0, sizeof(*sctx)); | ||
308 | |||
309 | return 0; | ||
310 | } | 238 | } |
311 | 239 | ||
312 | static int sha224_final(struct shash_desc *desc, u8 *hash) | 240 | int crypto_sha256_finup(struct shash_desc *desc, const u8 *data, |
241 | unsigned int len, u8 *hash) | ||
313 | { | 242 | { |
314 | u8 D[SHA256_DIGEST_SIZE]; | 243 | sha256_base_do_update(desc, data, len, sha256_generic_block_fn); |
315 | 244 | return sha256_final(desc, hash); | |
316 | sha256_final(desc, D); | ||
317 | |||
318 | memcpy(hash, D, SHA224_DIGEST_SIZE); | ||
319 | memzero_explicit(D, SHA256_DIGEST_SIZE); | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int sha256_export(struct shash_desc *desc, void *out) | ||
325 | { | ||
326 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
327 | |||
328 | memcpy(out, sctx, sizeof(*sctx)); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | static int sha256_import(struct shash_desc *desc, const void *in) | ||
333 | { | ||
334 | struct sha256_state *sctx = shash_desc_ctx(desc); | ||
335 | |||
336 | memcpy(sctx, in, sizeof(*sctx)); | ||
337 | return 0; | ||
338 | } | 245 | } |
246 | EXPORT_SYMBOL(crypto_sha256_finup); | ||
339 | 247 | ||
340 | static struct shash_alg sha256_algs[2] = { { | 248 | static struct shash_alg sha256_algs[2] = { { |
341 | .digestsize = SHA256_DIGEST_SIZE, | 249 | .digestsize = SHA256_DIGEST_SIZE, |
342 | .init = sha256_init, | 250 | .init = sha256_base_init, |
343 | .update = crypto_sha256_update, | 251 | .update = crypto_sha256_update, |
344 | .final = sha256_final, | 252 | .final = sha256_final, |
345 | .export = sha256_export, | 253 | .finup = crypto_sha256_finup, |
346 | .import = sha256_import, | ||
347 | .descsize = sizeof(struct sha256_state), | 254 | .descsize = sizeof(struct sha256_state), |
348 | .statesize = sizeof(struct sha256_state), | ||
349 | .base = { | 255 | .base = { |
350 | .cra_name = "sha256", | 256 | .cra_name = "sha256", |
351 | .cra_driver_name= "sha256-generic", | 257 | .cra_driver_name= "sha256-generic", |
@@ -355,9 +261,10 @@ static struct shash_alg sha256_algs[2] = { { | |||
355 | } | 261 | } |
356 | }, { | 262 | }, { |
357 | .digestsize = SHA224_DIGEST_SIZE, | 263 | .digestsize = SHA224_DIGEST_SIZE, |
358 | .init = sha224_init, | 264 | .init = sha224_base_init, |
359 | .update = crypto_sha256_update, | 265 | .update = crypto_sha256_update, |
360 | .final = sha224_final, | 266 | .final = sha256_final, |
267 | .finup = crypto_sha256_finup, | ||
361 | .descsize = sizeof(struct sha256_state), | 268 | .descsize = sizeof(struct sha256_state), |
362 | .base = { | 269 | .base = { |
363 | .cra_name = "sha224", | 270 | .cra_name = "sha224", |