aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/md5.c40
-rw-r--r--include/crypto/md5.h17
2 files changed, 41 insertions, 16 deletions
diff --git a/crypto/md5.c b/crypto/md5.c
index 83eb52961750..9fda213a592e 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -16,17 +16,13 @@
16 * 16 *
17 */ 17 */
18#include <crypto/internal/hash.h> 18#include <crypto/internal/hash.h>
19#include <crypto/md5.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/string.h> 22#include <linux/string.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <asm/byteorder.h> 24#include <asm/byteorder.h>
24 25
25#define MD5_DIGEST_SIZE 16
26#define MD5_HMAC_BLOCK_SIZE 64
27#define MD5_BLOCK_WORDS 16
28#define MD5_HASH_WORDS 4
29
30#define F1(x, y, z) (z ^ (x & (y ^ z))) 26#define F1(x, y, z) (z ^ (x & (y ^ z)))
31#define F2(x, y, z) F1(z, x, y) 27#define F2(x, y, z) F1(z, x, y)
32#define F3(x, y, z) (x ^ y ^ z) 28#define F3(x, y, z) (x ^ y ^ z)
@@ -35,12 +31,6 @@
35#define MD5STEP(f, w, x, y, z, in, s) \ 31#define MD5STEP(f, w, x, y, z, in, s) \
36 (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) 32 (w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x)
37 33
38struct md5_ctx {
39 u32 hash[MD5_HASH_WORDS];
40 u32 block[MD5_BLOCK_WORDS];
41 u64 byte_count;
42};
43
44static void md5_transform(u32 *hash, u32 const *in) 34static void md5_transform(u32 *hash, u32 const *in)
45{ 35{
46 u32 a, b, c, d; 36 u32 a, b, c, d;
@@ -141,7 +131,7 @@ static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
141 } 131 }
142} 132}
143 133
144static inline void md5_transform_helper(struct md5_ctx *ctx) 134static inline void md5_transform_helper(struct md5_state *ctx)
145{ 135{
146 le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); 136 le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32));
147 md5_transform(ctx->hash, ctx->block); 137 md5_transform(ctx->hash, ctx->block);
@@ -149,7 +139,7 @@ static inline void md5_transform_helper(struct md5_ctx *ctx)
149 139
150static int md5_init(struct shash_desc *desc) 140static int md5_init(struct shash_desc *desc)
151{ 141{
152 struct md5_ctx *mctx = shash_desc_ctx(desc); 142 struct md5_state *mctx = shash_desc_ctx(desc);
153 143
154 mctx->hash[0] = 0x67452301; 144 mctx->hash[0] = 0x67452301;
155 mctx->hash[1] = 0xefcdab89; 145 mctx->hash[1] = 0xefcdab89;
@@ -162,7 +152,7 @@ static int md5_init(struct shash_desc *desc)
162 152
163static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len) 153static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
164{ 154{
165 struct md5_ctx *mctx = shash_desc_ctx(desc); 155 struct md5_state *mctx = shash_desc_ctx(desc);
166 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); 156 const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
167 157
168 mctx->byte_count += len; 158 mctx->byte_count += len;
@@ -194,7 +184,7 @@ static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len)
194 184
195static int md5_final(struct shash_desc *desc, u8 *out) 185static int md5_final(struct shash_desc *desc, u8 *out)
196{ 186{
197 struct md5_ctx *mctx = shash_desc_ctx(desc); 187 struct md5_state *mctx = shash_desc_ctx(desc);
198 const unsigned int offset = mctx->byte_count & 0x3f; 188 const unsigned int offset = mctx->byte_count & 0x3f;
199 char *p = (char *)mctx->block + offset; 189 char *p = (char *)mctx->block + offset;
200 int padding = 56 - (offset + 1); 190 int padding = 56 - (offset + 1);
@@ -220,12 +210,30 @@ static int md5_final(struct shash_desc *desc, u8 *out)
220 return 0; 210 return 0;
221} 211}
222 212
213static int md5_export(struct shash_desc *desc, void *out)
214{
215 struct md5_state *ctx = shash_desc_ctx(desc);
216
217 memcpy(out, ctx, sizeof(*ctx));
218 return 0;
219}
220
221static int md5_import(struct shash_desc *desc, const void *in)
222{
223 struct md5_state *ctx = shash_desc_ctx(desc);
224
225 memcpy(ctx, in, sizeof(*ctx));
226 return 0;
227}
228
223static struct shash_alg alg = { 229static struct shash_alg alg = {
224 .digestsize = MD5_DIGEST_SIZE, 230 .digestsize = MD5_DIGEST_SIZE,
225 .init = md5_init, 231 .init = md5_init,
226 .update = md5_update, 232 .update = md5_update,
227 .final = md5_final, 233 .final = md5_final,
228 .descsize = sizeof(struct md5_ctx), 234 .export = md5_export,
235 .import = md5_import,
236 .descsize = sizeof(struct md5_state),
229 .base = { 237 .base = {
230 .cra_name = "md5", 238 .cra_name = "md5",
231 .cra_flags = CRYPTO_ALG_TYPE_SHASH, 239 .cra_flags = CRYPTO_ALG_TYPE_SHASH,
diff --git a/include/crypto/md5.h b/include/crypto/md5.h
new file mode 100644
index 000000000000..65f299b08b0d
--- /dev/null
+++ b/include/crypto/md5.h
@@ -0,0 +1,17 @@
1#ifndef _CRYPTO_MD5_H
2#define _CRYPTO_MD5_H
3
4#include <linux/types.h>
5
6#define MD5_DIGEST_SIZE 16
7#define MD5_HMAC_BLOCK_SIZE 64
8#define MD5_BLOCK_WORDS 16
9#define MD5_HASH_WORDS 4
10
11struct md5_state {
12 u32 hash[MD5_HASH_WORDS];
13 u32 block[MD5_BLOCK_WORDS];
14 u64 byte_count;
15};
16
17#endif