aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/sha1_generic.c
diff options
context:
space:
mode:
authorSebastian Siewior <sebastian@breakpoint.cc>2007-10-07 23:45:10 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:55:50 -0400
commitad5d27899fdbe7a66e57fdf1af883dbd7ff88dac (patch)
tree666a5809fd9a01e0798411b94962903c3431400c /crypto/sha1_generic.c
parentf8246af005d56b73f4f04304fc5b6fd9878af4ef (diff)
[CRYPTO] sha: Load the SHA[1|256] module by an alias
Loading the crypto algorithm by the alias instead of by module directly has the advantage that all possible implementations of this algorithm are loaded automatically and the crypto API can choose the best one depending on its priority. Additionally it ensures that the generic implementation as well as the HW driver (if available) is loaded in case the HW driver needs the generic version as fallback in corner cases. Also remove the probe for sha1 in padlock's init code. Quote from Herbert: The probe is actually pointless since we can always probe when the algorithm is actually used which does not lead to dead-locks like this. Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/sha1_generic.c')
-rw-r--r--crypto/sha1_generic.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c
new file mode 100644
index 000000000000..70364dd5c45a
--- /dev/null
+++ b/crypto/sha1_generic.c
@@ -0,0 +1,142 @@
1/*
2 * Cryptographic API.
3 *
4 * SHA1 Secure Hash Algorithm.
5 *
6 * Derived from cryptoapi implementation, adapted for in-place
7 * scatterlist interface.
8 *
9 * Copyright (c) Alan Smithee.
10 * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
11 * Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 */
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/mm.h>
22#include <linux/crypto.h>
23#include <linux/cryptohash.h>
24#include <linux/types.h>
25#include <asm/scatterlist.h>
26#include <asm/byteorder.h>
27
28#define SHA1_DIGEST_SIZE 20
29#define SHA1_HMAC_BLOCK_SIZE 64
30
31struct sha1_ctx {
32 u64 count;
33 u32 state[5];
34 u8 buffer[64];
35};
36
37static void sha1_init(struct crypto_tfm *tfm)
38{
39 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
40 static const struct sha1_ctx initstate = {
41 0,
42 { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
43 { 0, }
44 };
45
46 *sctx = initstate;
47}
48
49static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
50 unsigned int len)
51{
52 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
53 unsigned int partial, done;
54 const u8 *src;
55
56 partial = sctx->count & 0x3f;
57 sctx->count += len;
58 done = 0;
59 src = data;
60
61 if ((partial + len) > 63) {
62 u32 temp[SHA_WORKSPACE_WORDS];
63
64 if (partial) {
65 done = -partial;
66 memcpy(sctx->buffer + partial, data, done + 64);
67 src = sctx->buffer;
68 }
69
70 do {
71 sha_transform(sctx->state, src, temp);
72 done += 64;
73 src = data + done;
74 } while (done + 63 < len);
75
76 memset(temp, 0, sizeof(temp));
77 partial = 0;
78 }
79 memcpy(sctx->buffer + partial, src, len - done);
80}
81
82
83/* Add padding and return the message digest. */
84static void sha1_final(struct crypto_tfm *tfm, u8 *out)
85{
86 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
87 __be32 *dst = (__be32 *)out;
88 u32 i, index, padlen;
89 __be64 bits;
90 static const u8 padding[64] = { 0x80, };
91
92 bits = cpu_to_be64(sctx->count << 3);
93
94 /* Pad out to 56 mod 64 */
95 index = sctx->count & 0x3f;
96 padlen = (index < 56) ? (56 - index) : ((64+56) - index);
97 sha1_update(tfm, padding, padlen);
98
99 /* Append length */
100 sha1_update(tfm, (const u8 *)&bits, sizeof(bits));
101
102 /* Store state in digest */
103 for (i = 0; i < 5; i++)
104 dst[i] = cpu_to_be32(sctx->state[i]);
105
106 /* Wipe context */
107 memset(sctx, 0, sizeof *sctx);
108}
109
110static struct crypto_alg alg = {
111 .cra_name = "sha1",
112 .cra_driver_name= "sha1-generic",
113 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
114 .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
115 .cra_ctxsize = sizeof(struct sha1_ctx),
116 .cra_module = THIS_MODULE,
117 .cra_alignmask = 3,
118 .cra_list = LIST_HEAD_INIT(alg.cra_list),
119 .cra_u = { .digest = {
120 .dia_digestsize = SHA1_DIGEST_SIZE,
121 .dia_init = sha1_init,
122 .dia_update = sha1_update,
123 .dia_final = sha1_final } }
124};
125
126static int __init init(void)
127{
128 return crypto_register_alg(&alg);
129}
130
131static void __exit fini(void)
132{
133 crypto_unregister_alg(&alg);
134}
135
136module_init(init);
137module_exit(fini);
138
139MODULE_LICENSE("GPL");
140MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
141
142MODULE_ALIAS("sha1");