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
27 \file ifxmips_sha1_hmac.c
29 \brief SHA1-HMAC deu driver file
33 \defgroup IFX_SHA1_HMAC_FUNCTIONS IFX_SHA1_HMAC_FUNCTIONS
35 \brief ifx sha1 hmac 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 <linux/delay.h>
49 #include "ifxmips_deu.h"
51 #ifdef CONFIG_CRYPTO_DEV_IFXMIPS_SHA1_HMAC
53 #define SHA1_DIGEST_SIZE 20
54 #define SHA1_HMAC_BLOCK_SIZE 64
55 #define SHA1_HMAC_DBN_TEMP_SIZE 1024 // size in dword, needed for dbn workaround
56 #define HASH_START IFX_HASH_CON
58 static spinlock_t lock
;
59 #define CRTCL_SECT_INIT spin_lock_init(&lock)
60 #define CRTCL_SECT_START spin_lock_irqsave(&lock, flag)
61 #define CRTCL_SECT_END spin_unlock_irqrestore(&lock, flag)
63 struct sha1_hmac_ctx
{
68 u32 temp
[SHA1_HMAC_DBN_TEMP_SIZE
];
71 extern int disable_deudma
;
73 /*! \fn static void sha1_hmac_transform(struct crypto_tfm *tfm, u32 const *in)
74 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
75 * \brief save input block to context
76 * \param tfm linux crypto algo transform
77 * \param in 64-byte block of input
79 static void sha1_hmac_transform(struct crypto_tfm
*tfm
, u32
const *in
)
81 struct sha1_hmac_ctx
*sctx
= crypto_tfm_ctx(tfm
);
83 memcpy(&sctx
->temp
[sctx
->dbn
<<4], in
, 64); //dbn workaround
86 if ( (sctx
->dbn
<<4) > SHA1_HMAC_DBN_TEMP_SIZE
)
88 printk("SHA1_HMAC_DBN_TEMP_SIZE exceeded\n");
93 /*! \fn int sha1_hmac_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
94 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
95 * \brief sets sha1 hmac key
96 * \param tfm linux crypto algo transform
97 * \param key input key
98 * \param keylen key length greater than 64 bytes IS NOT SUPPORTED
100 int sha1_hmac_setkey(struct crypto_tfm
*tfm
, const u8
*key
, unsigned int keylen
)
102 volatile struct deu_hash_t
*hash
= (struct deu_hash_t
*) HASH_START
;
104 u32
*in_key
= (u32
*)key
;
106 hash
->KIDX
= 0x80000000; // reset all 16 words of the key to '0'
110 for (i
= 0; i
< keylen
; i
+=4)
114 hash
->KEY
= *((u32
*) in_key
+ j
);
121 /*! \fn void sha1_hmac_init(struct crypto_tfm *tfm)
122 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
123 * \brief initialize sha1 hmac context
124 * \param tfm linux crypto algo transform
126 void sha1_hmac_init(struct crypto_tfm
*tfm
)
128 struct sha1_hmac_ctx
*sctx
= crypto_tfm_ctx(tfm
);
130 memset(sctx
, 0, sizeof(struct sha1_hmac_ctx
));
131 sctx
->dbn
= 0; //dbn workaround
134 /*! \fn static void sha1_hmac_update(struct crypto_tfm *tfm, const u8 *data, unsigned int len)
135 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
136 * \brief on-the-fly sha1 hmac computation
137 * \param tfm linux crypto algo transform
138 * \param data input data
139 * \param len size of input data
141 static void sha1_hmac_update(struct crypto_tfm
*tfm
, const u8
*data
,
144 struct sha1_hmac_ctx
*sctx
= crypto_tfm_ctx(tfm
);
147 j
= (sctx
->count
>> 3) & 0x3f;
148 sctx
->count
+= len
<< 3;
149 //printk("sctx->count = %d\n", (sctx->count >> 3));
151 if ((j
+ len
) > 63) {
152 memcpy (&sctx
->buffer
[j
], data
, (i
= 64 - j
));
153 sha1_hmac_transform (tfm
, (const u32
*)sctx
->buffer
);
154 for (; i
+ 63 < len
; i
+= 64) {
155 sha1_hmac_transform (tfm
, (const u32
*)&data
[i
]);
163 memcpy (&sctx
->buffer
[j
], &data
[i
], len
- i
);
166 /*! \fn static void sha1_hmac_final(struct crypto_tfm *tfm, u8 *out)
167 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
168 * \brief ompute final sha1 hmac value
169 * \param tfm linux crypto algo transform
170 * \param out final sha1 hmac output value
172 static void sha1_hmac_final(struct crypto_tfm
*tfm
, u8
*out
)
174 struct sha1_hmac_ctx
*sctx
= crypto_tfm_ctx(tfm
);
178 static const u8 padding
[64] = { 0x80, };
179 volatile struct deu_hash_t
*hashs
= (struct deu_hash_t
*) HASH_START
;
183 u32
*in
= &sctx
->temp
[0];
185 t
= sctx
->count
+ 512; // need to add 512 bit of the IPAD operation
202 /* Pad out to 56 mod 64 */
203 index
= (sctx
->count
>> 3) & 0x3f;
204 padlen
= (index
< 56) ? (56 - index
) : ((64 + 56) - index
);
205 sha1_hmac_update (tfm
, padding
, padlen
);
208 sha1_hmac_update (tfm
, bits
, sizeof bits
);
212 hashs
->DBN
= sctx
->dbn
;
214 //for vr9 change, ENDI = 1
215 *IFX_HASH_CON
= HASH_CON_VALUE
;
217 //wait for processing
218 while (hashs
->controlr
.BSY
) {
219 // this will not take long
222 for (dbn
= 0; dbn
< sctx
->dbn
; dbn
++)
224 for (i
= 0; i
< 16; i
++) {
228 hashs
->controlr
.GO
= 1;
231 //wait for processing
232 while (hashs
->controlr
.BSY
) {
233 // this will not take long
241 //wait for digest ready
242 while (! hashs
->controlr
.DGRY
) {
243 // this will not take long
247 *((u32
*) out
+ 0) = hashs
->D1R
;
248 *((u32
*) out
+ 1) = hashs
->D2R
;
249 *((u32
*) out
+ 2) = hashs
->D3R
;
250 *((u32
*) out
+ 3) = hashs
->D4R
;
251 *((u32
*) out
+ 4) = hashs
->D5R
;
257 * \brief SHA1-HMAC function mappings
260 struct crypto_alg ifxdeu_sha1_hmac_alg
= {
261 .cra_name
= "hmac(sha1)",
262 .cra_driver_name
= "ifxdeu-sha1_hmac",
263 .cra_flags
= CRYPTO_ALG_TYPE_DIGEST
,
264 .cra_blocksize
= SHA1_HMAC_BLOCK_SIZE
,
265 .cra_ctxsize
= sizeof(struct sha1_hmac_ctx
),
266 .cra_module
= THIS_MODULE
,
268 .cra_list
= LIST_HEAD_INIT(ifxdeu_sha1_hmac_alg
.cra_list
),
269 .cra_u
= { .digest
= {
270 .dia_digestsize
= SHA1_DIGEST_SIZE
,
271 .dia_setkey
= sha1_hmac_setkey
,
272 .dia_init
= sha1_hmac_init
,
273 .dia_update
= sha1_hmac_update
,
274 .dia_final
= sha1_hmac_final
} }
278 /*! \fn int __init ifxdeu_init_sha1_hmac (void)
279 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
280 * \brief initialize sha1 hmac driver
282 int __init
ifxdeu_init_sha1_hmac (void)
286 if ((ret
= crypto_register_alg(&ifxdeu_sha1_hmac_alg
)))
291 printk (KERN_NOTICE
"IFX DEU SHA1_HMAC initialized%s.\n", disable_deudma
? "" : " (DMA)");
295 printk(KERN_ERR
"IFX DEU SHA1_HMAC initialization failed!\n");
299 /*! \fn void __exit ifxdeu_fini_sha1_hmac (void)
300 * \ingroup IFX_SHA1_HMAC_FUNCTIONS
301 * \brief unregister sha1 hmac driver
303 void __exit
ifxdeu_fini_sha1_hmac (void)
305 crypto_unregister_alg (&ifxdeu_sha1_hmac_alg
);