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.
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.
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.
16 * Copyright (C) 2010 Ralph Hempel <ralph.hempel@lantiq.com>
17 * Copyright (C) 2009 Mohammad Firdaus
21 \defgroup IFX_DEU IFX_DEU_DRIVERS
23 \brief ifx deu driver module
29 \brief SHA1 encryption deu driver file
33 \defgroup IFX_SHA1_FUNCTIONS IFX_SHA1_FUNCTIONS
35 \brief ifx deu sha1 functions
40 #include <linux/init.h>
41 #include <linux/module.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"
50 #define SHA1_DIGEST_SIZE 20
51 #define SHA1_HMAC_BLOCK_SIZE 64
52 #define HASH_START IFX_HASH_CON
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)
60 * \brief SHA1 private structure
68 extern int disable_deudma
;
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
77 static void sha1_transform (u32
*state
, const u32
*in
)
80 volatile struct deu_hash_t
*hashs
= (struct deu_hash_t
*) HASH_START
;
85 for (i
= 0; i
< 16; i
++) {
90 while (hashs
->controlr
.BSY
) {
91 // this will not take long
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
102 static void sha1_init(struct crypto_tfm
*tfm
)
104 struct sha1_ctx
*sctx
= crypto_tfm_ctx(tfm
);
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
118 static void sha1_update(struct crypto_tfm
*tfm
, const u8
*data
,
121 struct sha1_ctx
*sctx
= crypto_tfm_ctx(tfm
);
124 j
= (sctx
->count
>> 3) & 0x3f;
125 sctx
->count
+= len
<< 3;
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
]);
139 memcpy (&sctx
->buffer
[j
], &data
[i
], len
- i
);
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
148 static void sha1_final(struct crypto_tfm
*tfm
, u8
*out
)
150 struct sha1_ctx
*sctx
= crypto_tfm_ctx(tfm
);
154 static const u8 padding
[64] = { 0x80, };
155 volatile struct deu_hash_t
*hashs
= (struct deu_hash_t
*) HASH_START
;
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
);
181 sha1_update (tfm
, bits
, sizeof bits
);
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
;
194 memset (sctx
, 0, sizeof *sctx
);
198 * \brief SHA1 function mappings
200 struct crypto_alg ifxdeu_sha1_alg
= {
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
,
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
} }
216 /*! \fn int __init ifxdeu_init_sha1 (void)
217 * \ingroup IFX_SHA1_FUNCTIONS
218 * \brief initialize sha1 driver
220 int __init
ifxdeu_init_sha1 (void)
224 if ((ret
= crypto_register_alg(&ifxdeu_sha1_alg
)))
229 printk (KERN_NOTICE
"IFX DEU SHA1 initialized%s.\n", disable_deudma
? "" : " (DMA)");
233 printk(KERN_ERR
"IFX DEU SHA1 initialization failed!\n");
237 /*! \fn void __exit ifxdeu_fini_sha1 (void)
238 * \ingroup IFX_SHA1_FUNCTIONS
239 * \brief unregister sha1 driver
241 void __exit
ifxdeu_fini_sha1 (void)
243 crypto_unregister_alg (&ifxdeu_sha1_alg
);