diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-04-09 06:55:36 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-10 09:39:40 -0400 |
commit | 7c71f0f760d65f270aca0849caebb1fd5d53c66b (patch) | |
tree | dad64c5f6a8469f047f6249463a78fae1999ab93 /crypto | |
parent | b84a2a0b4ec214fc5d4ba1d3d5b26d4f88733dba (diff) |
crypto: sha1-generic - move to generic glue implementation
This updated the generic SHA-1 implementation to use the generic
shared SHA-1 glue code.
It also implements a .finup hook crypto_sha1_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/sha1_generic.c | 102 |
1 files changed, 20 insertions, 82 deletions
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c index a3e50c37eb6f..39e3acc438d9 100644 --- a/crypto/sha1_generic.c +++ b/crypto/sha1_generic.c | |||
@@ -23,111 +23,49 @@ | |||
23 | #include <linux/cryptohash.h> | 23 | #include <linux/cryptohash.h> |
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <crypto/sha.h> | 25 | #include <crypto/sha.h> |
26 | #include <crypto/sha1_base.h> | ||
26 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
27 | 28 | ||
28 | static int sha1_init(struct shash_desc *desc) | 29 | static void sha1_generic_block_fn(struct sha1_state *sst, u8 const *src, |
30 | int blocks) | ||
29 | { | 31 | { |
30 | struct sha1_state *sctx = shash_desc_ctx(desc); | 32 | u32 temp[SHA_WORKSPACE_WORDS]; |
31 | 33 | ||
32 | *sctx = (struct sha1_state){ | 34 | while (blocks--) { |
33 | .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, | 35 | sha_transform(sst->state, src, temp); |
34 | }; | 36 | src += SHA1_BLOCK_SIZE; |
35 | 37 | } | |
36 | return 0; | 38 | memzero_explicit(temp, sizeof(temp)); |
37 | } | 39 | } |
38 | 40 | ||
39 | int crypto_sha1_update(struct shash_desc *desc, const u8 *data, | 41 | int crypto_sha1_update(struct shash_desc *desc, const u8 *data, |
40 | unsigned int len) | 42 | unsigned int len) |
41 | { | 43 | { |
42 | struct sha1_state *sctx = shash_desc_ctx(desc); | 44 | return sha1_base_do_update(desc, data, len, sha1_generic_block_fn); |
43 | unsigned int partial, done; | ||
44 | const u8 *src; | ||
45 | |||
46 | partial = sctx->count % SHA1_BLOCK_SIZE; | ||
47 | sctx->count += len; | ||
48 | done = 0; | ||
49 | src = data; | ||
50 | |||
51 | if ((partial + len) >= SHA1_BLOCK_SIZE) { | ||
52 | u32 temp[SHA_WORKSPACE_WORDS]; | ||
53 | |||
54 | if (partial) { | ||
55 | done = -partial; | ||
56 | memcpy(sctx->buffer + partial, data, | ||
57 | done + SHA1_BLOCK_SIZE); | ||
58 | src = sctx->buffer; | ||
59 | } | ||
60 | |||
61 | do { | ||
62 | sha_transform(sctx->state, src, temp); | ||
63 | done += SHA1_BLOCK_SIZE; | ||
64 | src = data + done; | ||
65 | } while (done + SHA1_BLOCK_SIZE <= len); | ||
66 | |||
67 | memzero_explicit(temp, sizeof(temp)); | ||
68 | partial = 0; | ||
69 | } | ||
70 | memcpy(sctx->buffer + partial, src, len - done); | ||
71 | |||
72 | return 0; | ||
73 | } | 45 | } |
74 | EXPORT_SYMBOL(crypto_sha1_update); | 46 | EXPORT_SYMBOL(crypto_sha1_update); |
75 | 47 | ||
76 | |||
77 | /* Add padding and return the message digest. */ | ||
78 | static int sha1_final(struct shash_desc *desc, u8 *out) | 48 | static int sha1_final(struct shash_desc *desc, u8 *out) |
79 | { | 49 | { |
80 | struct sha1_state *sctx = shash_desc_ctx(desc); | 50 | sha1_base_do_finalize(desc, sha1_generic_block_fn); |
81 | __be32 *dst = (__be32 *)out; | 51 | return sha1_base_finish(desc, out); |
82 | u32 i, index, padlen; | ||
83 | __be64 bits; | ||
84 | static const u8 padding[64] = { 0x80, }; | ||
85 | |||
86 | bits = cpu_to_be64(sctx->count << 3); | ||
87 | |||
88 | /* Pad out to 56 mod 64 */ | ||
89 | index = sctx->count & 0x3f; | ||
90 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); | ||
91 | crypto_sha1_update(desc, padding, padlen); | ||
92 | |||
93 | /* Append length */ | ||
94 | crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits)); | ||
95 | |||
96 | /* Store state in digest */ | ||
97 | for (i = 0; i < 5; i++) | ||
98 | dst[i] = cpu_to_be32(sctx->state[i]); | ||
99 | |||
100 | /* Wipe context */ | ||
101 | memset(sctx, 0, sizeof *sctx); | ||
102 | |||
103 | return 0; | ||
104 | } | 52 | } |
105 | 53 | ||
106 | static int sha1_export(struct shash_desc *desc, void *out) | 54 | int crypto_sha1_finup(struct shash_desc *desc, const u8 *data, |
55 | unsigned int len, u8 *out) | ||
107 | { | 56 | { |
108 | struct sha1_state *sctx = shash_desc_ctx(desc); | 57 | sha1_base_do_update(desc, data, len, sha1_generic_block_fn); |
109 | 58 | return sha1_final(desc, out); | |
110 | memcpy(out, sctx, sizeof(*sctx)); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int sha1_import(struct shash_desc *desc, const void *in) | ||
115 | { | ||
116 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
117 | |||
118 | memcpy(sctx, in, sizeof(*sctx)); | ||
119 | return 0; | ||
120 | } | 59 | } |
60 | EXPORT_SYMBOL(crypto_sha1_finup); | ||
121 | 61 | ||
122 | static struct shash_alg alg = { | 62 | static struct shash_alg alg = { |
123 | .digestsize = SHA1_DIGEST_SIZE, | 63 | .digestsize = SHA1_DIGEST_SIZE, |
124 | .init = sha1_init, | 64 | .init = sha1_base_init, |
125 | .update = crypto_sha1_update, | 65 | .update = crypto_sha1_update, |
126 | .final = sha1_final, | 66 | .final = sha1_final, |
127 | .export = sha1_export, | 67 | .finup = crypto_sha1_finup, |
128 | .import = sha1_import, | ||
129 | .descsize = sizeof(struct sha1_state), | 68 | .descsize = sizeof(struct sha1_state), |
130 | .statesize = sizeof(struct sha1_state), | ||
131 | .base = { | 69 | .base = { |
132 | .cra_name = "sha1", | 70 | .cra_name = "sha1", |
133 | .cra_driver_name= "sha1-generic", | 71 | .cra_driver_name= "sha1-generic", |