deptest: Do not clobber the base build and staging dirs
[openwrt/svn-archive/archive.git] / target / linux / ifxmips / files-2.6.33 / drivers / crypto / ifxmips / ifxmips_sha1.c
1 /*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
15 *
16 * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
17 * Copyright (C) 2009 Mohammad Firdaus
18 */
19
20 /*!
21 \defgroup IFX_DEU IFX_DEU_DRIVERS
22 \ingroup API
23 \brief ifx deu driver module
24 */
25
26 /*!
27 \file ifxmips_sha1.c
28 \ingroup IFX_DEU
29 \brief SHA1 encryption deu driver file
30 */
31
32 /*!
33 \defgroup IFX_SHA1_FUNCTIONS IFX_SHA1_FUNCTIONS
34 \ingroup IFX_DEU
35 \brief ifx deu sha1 functions
36 */
37
38
39 /* Project header */
40 #include <linux/init.h>
41 #include <linux/module.h>
42 #include <linux/mm.h>
43 #include <linux/crypto.h>
44 #include <linux/cryptohash.h>
45 #include <linux/types.h>
46 #include <asm/scatterlist.h>
47 #include <asm/byteorder.h>
48 #include "ifxmips_deu.h"
49
50 #define SHA1_DIGEST_SIZE 20
51 #define SHA1_HMAC_BLOCK_SIZE 64
52 #define HASH_START IFX_HASH_CON
53
54 static spinlock_t lock;
55 #define CRTCL_SECT_INIT spin_lock_init(&lock)
56 #define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
57 #define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
58
59 /*
60 * \brief SHA1 private structure
61 */
62 struct sha1_ctx {
63 u64 count;
64 u32 state[5];
65 u8 buffer[64];
66 };
67
68 extern int disable_deudma;
69
70
71 /*! \fn static void sha1_transform (u32 *state, const u32 *in)
72 * \ingroup IFX_SHA1_FUNCTIONS
73 * \brief main interface to sha1 hardware
74 * \param state current state
75 * \param in 64-byte block of input
76 */
77 static void sha1_transform (u32 *state, const u32 *in)
78 {
79 int i = 0;
80 volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
81 u32 flag;
82
83 CRTCL_SECT_START;
84
85 for (i = 0; i < 16; i++) {
86 hashs->MR = in[i];
87 };
88
89 //wait for processing
90 while (hashs->controlr.BSY) {
91 // this will not take long
92 }
93
94 CRTCL_SECT_END;
95 }
96
97 /*! \fn static void sha1_init(struct crypto_tfm *tfm)
98 * \ingroup IFX_SHA1_FUNCTIONS
99 * \brief initialize sha1 hardware
100 * \param tfm linux crypto algo transform
101 */
102 static void sha1_init(struct crypto_tfm *tfm)
103 {
104 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
105
106 SHA_HASH_INIT;
107
108 sctx->count = 0;
109 }
110
111 /*! \fn static void sha1_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
112 * \ingroup IFX_SHA1_FUNCTIONS
113 * \brief on-the-fly sha1 computation
114 * \param tfm linux crypto algo transform
115 * \param data input data
116 * \param len size of input data
117 */
118 static void sha1_update(struct crypto_tfm *tfm, const u8 *data,
119 unsigned int len)
120 {
121 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
122 unsigned int i, j;
123
124 j = (sctx->count >> 3) & 0x3f;
125 sctx->count += len << 3;
126
127 if ((j + len) > 63) {
128 memcpy (&sctx->buffer[j], data, (i = 64 - j));
129 sha1_transform (sctx->state, (const u32 *)sctx->buffer);
130 for (; i + 63 < len; i += 64) {
131 sha1_transform (sctx->state, (const u32 *)&data[i]);
132 }
133
134 j = 0;
135 }
136 else
137 i = 0;
138
139 memcpy (&sctx->buffer[j], &data[i], len - i);
140 }
141
142 /*! \fn static void sha1_final(struct crypto_tfm *tfm, u8 *out)
143 * \ingroup IFX_SHA1_FUNCTIONS
144 * \brief compute final sha1 value
145 * \param tfm linux crypto algo transform
146 * \param out final md5 output value
147 */
148 static void sha1_final(struct crypto_tfm *tfm, u8 *out)
149 {
150 struct sha1_ctx *sctx = crypto_tfm_ctx(tfm);
151 u32 index, padlen;
152 u64 t;
153 u8 bits[8] = { 0, };
154 static const u8 padding[64] = { 0x80, };
155 volatile struct deu_hash_t *hashs = (struct deu_hash_t *) HASH_START;
156 ulong flag;
157
158 t = sctx->count;
159 bits[7] = 0xff & t;
160 t >>= 8;
161 bits[6] = 0xff & t;
162 t >>= 8;
163 bits[5] = 0xff & t;
164 t >>= 8;
165 bits[4] = 0xff & t;
166 t >>= 8;
167 bits[3] = 0xff & t;
168 t >>= 8;
169 bits[2] = 0xff & t;
170 t >>= 8;
171 bits[1] = 0xff & t;
172 t >>= 8;
173 bits[0] = 0xff & t;
174
175 /* Pad out to 56 mod 64 */
176 index = (sctx->count >> 3) & 0x3f;
177 padlen = (index < 56) ? (56 - index) : ((64 + 56) - index);
178 sha1_update (tfm, padding, padlen);
179
180 /* Append length */
181 sha1_update (tfm, bits, sizeof bits);
182
183 CRTCL_SECT_START;
184
185 *((u32 *) out + 0) = hashs->D1R;
186 *((u32 *) out + 1) = hashs->D2R;
187 *((u32 *) out + 2) = hashs->D3R;
188 *((u32 *) out + 3) = hashs->D4R;
189 *((u32 *) out + 4) = hashs->D5R;
190
191 CRTCL_SECT_END;
192
193 // Wipe context
194 memset (sctx, 0, sizeof *sctx);
195 }
196
197 /*
198 * \brief SHA1 function mappings
199 */
200 struct crypto_alg ifxdeu_sha1_alg = {
201 .cra_name = "sha1",
202 .cra_driver_name= "ifxdeu-sha1",
203 .cra_flags = CRYPTO_ALG_TYPE_DIGEST,
204 .cra_blocksize = SHA1_HMAC_BLOCK_SIZE,
205 .cra_ctxsize = sizeof(struct sha1_ctx),
206 .cra_module = THIS_MODULE,
207 .cra_alignmask = 3,
208 .cra_list = LIST_HEAD_INIT(ifxdeu_sha1_alg.cra_list),
209 .cra_u = { .digest = {
210 .dia_digestsize = SHA1_DIGEST_SIZE,
211 .dia_init = sha1_init,
212 .dia_update = sha1_update,
213 .dia_final = sha1_final } }
214 };
215
216 /*! \fn int __init ifxdeu_init_sha1 (void)
217 * \ingroup IFX_SHA1_FUNCTIONS
218 * \brief initialize sha1 driver
219 */
220 int __init ifxdeu_init_sha1 (void)
221 {
222 int ret;
223
224 if ((ret = crypto_register_alg(&ifxdeu_sha1_alg)))
225 goto sha1_err;
226
227 CRTCL_SECT_INIT;
228
229 printk (KERN_NOTICE "IFX DEU SHA1 initialized%s.\n", disable_deudma ? "" : " (DMA)");
230 return ret;
231
232 sha1_err:
233 printk(KERN_ERR "IFX DEU SHA1 initialization failed!\n");
234 return ret;
235 }
236
237 /*! \fn void __exit ifxdeu_fini_sha1 (void)
238 * \ingroup IFX_SHA1_FUNCTIONS
239 * \brief unregister sha1 driver
240 */
241 void __exit ifxdeu_fini_sha1 (void)
242 {
243 crypto_unregister_alg (&ifxdeu_sha1_alg);
244 }