Branch data Line data Source code
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 <crypto/internal/hash.h>
20 : : #include <linux/init.h>
21 : : #include <linux/module.h>
22 : : #include <linux/mm.h>
23 : : #include <linux/cryptohash.h>
24 : : #include <linux/types.h>
25 : : #include <crypto/sha.h>
26 : : #include <asm/byteorder.h>
27 : :
28 : 0 : static int sha1_init(struct shash_desc *desc)
29 : : {
30 : : struct sha1_state *sctx = shash_desc_ctx(desc);
31 : :
32 : 0 : *sctx = (struct sha1_state){
33 : : .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
34 : : };
35 : :
36 : 0 : return 0;
37 : : }
38 : :
39 : 0 : int crypto_sha1_update(struct shash_desc *desc, const u8 *data,
40 : : unsigned int len)
41 : : {
42 : : struct sha1_state *sctx = shash_desc_ctx(desc);
43 : : unsigned int partial, done;
44 : : const u8 *src;
45 : :
46 : 0 : partial = sctx->count % SHA1_BLOCK_SIZE;
47 : 0 : sctx->count += len;
48 : : done = 0;
49 : : src = data;
50 : :
51 [ # # ]: 0 : if ((partial + len) >= SHA1_BLOCK_SIZE) {
52 : : u32 temp[SHA_WORKSPACE_WORDS];
53 : :
54 [ # # ]: 0 : if (partial) {
55 : 0 : done = -partial;
56 : 0 : memcpy(sctx->buffer + partial, data,
57 : : done + SHA1_BLOCK_SIZE);
58 : 0 : src = sctx->buffer;
59 : : }
60 : :
61 : : do {
62 : 0 : sha_transform(sctx->state, src, temp);
63 : 0 : done += SHA1_BLOCK_SIZE;
64 : 0 : src = data + done;
65 [ # # ]: 0 : } while (done + SHA1_BLOCK_SIZE <= len);
66 : :
67 : 0 : memset(temp, 0, sizeof(temp));
68 : : partial = 0;
69 : : }
70 : 0 : memcpy(sctx->buffer + partial, src, len - done);
71 : :
72 : 0 : return 0;
73 : : }
74 : : EXPORT_SYMBOL(crypto_sha1_update);
75 : :
76 : :
77 : : /* Add padding and return the message digest. */
78 : 0 : static int sha1_final(struct shash_desc *desc, u8 *out)
79 : : {
80 : 0 : struct sha1_state *sctx = shash_desc_ctx(desc);
81 : : __be32 *dst = (__be32 *)out;
82 : : u32 i, index, padlen;
83 : : __be64 bits;
84 : : static const u8 padding[64] = { 0x80, };
85 : :
86 [ # # ]: 0 : bits = cpu_to_be64(sctx->count << 3);
87 : :
88 : : /* Pad out to 56 mod 64 */
89 : 0 : index = sctx->count & 0x3f;
90 [ # # ]: 0 : padlen = (index < 56) ? (56 - index) : ((64+56) - index);
91 : 0 : crypto_sha1_update(desc, padding, padlen);
92 : :
93 : : /* Append length */
94 : 0 : crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
95 : :
96 : : /* Store state in digest */
97 [ # # ]: 0 : for (i = 0; i < 5; i++)
98 [ # # ]: 0 : dst[i] = cpu_to_be32(sctx->state[i]);
99 : :
100 : : /* Wipe context */
101 : 0 : memset(sctx, 0, sizeof *sctx);
102 : :
103 : 0 : return 0;
104 : : }
105 : :
106 : 0 : static int sha1_export(struct shash_desc *desc, void *out)
107 : : {
108 : 0 : struct sha1_state *sctx = shash_desc_ctx(desc);
109 : :
110 : 0 : memcpy(out, sctx, sizeof(*sctx));
111 : 0 : return 0;
112 : : }
113 : :
114 : 0 : static int sha1_import(struct shash_desc *desc, const void *in)
115 : : {
116 : 0 : struct sha1_state *sctx = shash_desc_ctx(desc);
117 : :
118 : 0 : memcpy(sctx, in, sizeof(*sctx));
119 : 0 : return 0;
120 : : }
121 : :
122 : : static struct shash_alg alg = {
123 : : .digestsize = SHA1_DIGEST_SIZE,
124 : : .init = sha1_init,
125 : : .update = crypto_sha1_update,
126 : : .final = sha1_final,
127 : : .export = sha1_export,
128 : : .import = sha1_import,
129 : : .descsize = sizeof(struct sha1_state),
130 : : .statesize = sizeof(struct sha1_state),
131 : : .base = {
132 : : .cra_name = "sha1",
133 : : .cra_driver_name= "sha1-generic",
134 : : .cra_flags = CRYPTO_ALG_TYPE_SHASH,
135 : : .cra_blocksize = SHA1_BLOCK_SIZE,
136 : : .cra_module = THIS_MODULE,
137 : : }
138 : : };
139 : :
140 : 0 : static int __init sha1_generic_mod_init(void)
141 : : {
142 : 0 : return crypto_register_shash(&alg);
143 : : }
144 : :
145 : 0 : static void __exit sha1_generic_mod_fini(void)
146 : : {
147 : 0 : crypto_unregister_shash(&alg);
148 : 0 : }
149 : :
150 : : module_init(sha1_generic_mod_init);
151 : : module_exit(sha1_generic_mod_fini);
152 : :
153 : : MODULE_LICENSE("GPL");
154 : : MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm");
155 : :
156 : : MODULE_ALIAS("sha1");
|