Root/target/linux/coldfire/patches/011-Add-CAU-driver-for-MCF5445x-and-MCF5441x.patch

1From 0419eb27af72bd37c3ef926169fe4db90e8690d3 Mon Sep 17 00:00:00 2001
2From: Alison Wang <b18965@freescale.com>
3Date: Thu, 4 Aug 2011 09:59:41 +0800
4Subject: [PATCH 11/52] Add CAU driver for MCF5445x and MCF5441x
5
6Add CAU driver support for MCF5445x and MCF5441x.
7
8Signed-off-by: Alison Wang <b18965@freescale.com>
9---
10 crypto/testmgr.c | 13 +-
11 drivers/crypto/Kconfig | 65 +++
12 drivers/crypto/Makefile | 5 +
13 drivers/crypto/mcfcau-aes.c | 367 ++++++++++++++++
14 drivers/crypto/mcfcau-des.c | 525 +++++++++++++++++++++++
15 drivers/crypto/mcfcau-md5.c | 972 ++++++++++++++++++++++++++++++++++++++++++
16 drivers/crypto/mcfcau-sha1.c | 331 ++++++++++++++
17 drivers/crypto/mcfcau.c | 33 ++
18 drivers/crypto/mcfcau.h | 101 +++++
19 9 files changed, 2410 insertions(+), 2 deletions(-)
20 create mode 100644 drivers/crypto/mcfcau-aes.c
21 create mode 100644 drivers/crypto/mcfcau-des.c
22 create mode 100644 drivers/crypto/mcfcau-md5.c
23 create mode 100644 drivers/crypto/mcfcau-sha1.c
24 create mode 100644 drivers/crypto/mcfcau.c
25 create mode 100644 drivers/crypto/mcfcau.h
26
27--- a/crypto/testmgr.c
28+++ b/crypto/testmgr.c
29@@ -705,6 +705,7 @@ static int test_cipher(struct crypto_cip
30     else
31         e = "decryption";
32 
33+ printk(KERN_INFO "%s testing %s %s\n", __func__, algo, e);
34     j = 0;
35     for (i = 0; i < tcount; i++) {
36         if (template[i].np)
37@@ -750,7 +751,9 @@ static int test_cipher(struct crypto_cip
38             hexdump(q, template[i].rlen);
39             ret = -EINVAL;
40             goto out;
41- }
42+ } else
43+ printk(KERN_INFO "alg: cipher: Test %d pass "
44+ "on %s for %s\n", j, e, algo);
45     }
46 
47     ret = 0;
48@@ -785,6 +788,7 @@ static int test_skcipher(struct crypto_a
49     else
50         e = "decryption";
51 
52+ printk(KERN_INFO "%s testing %s %s\n", __func__, algo, e);
53     init_completion(&result.completion);
54 
55     req = ablkcipher_request_alloc(tfm, GFP_KERNEL);
56@@ -863,10 +867,13 @@ static int test_skcipher(struct crypto_a
57                 hexdump(q, template[i].rlen);
58                 ret = -EINVAL;
59                 goto out;
60- }
61+ } else
62+ printk(KERN_INFO "alg: skcipher: Test %d "
63+ "pass on %s for %s\n", j, e, algo);
64         }
65     }
66 
67+ printk(KERN_INFO "\ntesting %s %s across pages (chunking)\n", algo, e);
68     j = 0;
69     for (i = 0; i < tcount; i++) {
70 
71@@ -2514,6 +2521,8 @@ int alg_test(const char *driver, const c
72     int j;
73     int rc;
74 
75+ printk(KERN_INFO "\ntesting %s\n", alg);
76+
77     if ((type & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_CIPHER) {
78         char nalg[CRYPTO_MAX_ALG_NAME];
79 
80--- a/drivers/crypto/Kconfig
81+++ b/drivers/crypto/Kconfig
82@@ -61,6 +61,71 @@ config CRYPTO_DEV_GEODE
83       To compile this driver as a module, choose M here: the module
84       will be called geode-aes.
85 
86+config CRYPTO_DEV_MCFCAU
87+ bool "Support for Freescale Coldfire Cryptographic Acceleration Unit (CAU)"
88+ depends on M5445X || M5441X
89+ select CRYPTO_ALGAPI
90+ help
91+ The cryptographic acceleration unit (CAU) is a ColdFire coprocessor
92+ implementing a set of specialized operations in hardware. For example,
93+ you can find it on MCF5445X, or M5441X.
94+
95+ Say Y here if you want to use CAU.
96+
97+config CRYPTO_DEV_MCFCAU_DES
98+ tristate "DES and Triple DES cipher algorithms (coldfire)"
99+ depends on CRYPTO_DEV_MCFCAU
100+ select CRYPTO_ALGAPI
101+ select CRYPTO_BLKCIPHER
102+ help
103+ DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
104+
105+ Say 'Y' here to use the CAU coprocessor for
106+ the CryptoAPI DES and 3DES alogrithms.
107+
108+ To compile this driver as a module, choose M here: the module
109+ will be called mcfcau-des.
110+
111+config CRYPTO_DEV_MCFCAU_AES
112+ tristate "AES cipher algorithm (coldfire)"
113+ depends on CRYPTO_DEV_MCFCAU
114+ select CRYPTO_ALGAPI
115+ select CRYPTO_BLKCIPHER
116+ help
117+ AES cipher algorithm (FIPS 197).
118+
119+ Say 'Y' here to use the CAU coprocessor for
120+ the CryptoAPI AES alogrithm.
121+
122+ To compile this driver as a module, choose M here: the module
123+ will be called mcfcau-aes.
124+
125+config CRYPTO_DEV_MCFCAU_MD5
126+ tristate "MD5 digest algorithm (coldfire)"
127+ depends on CRYPTO_DEV_MCFCAU
128+ select CRYPTO_ALGAPI
129+ help
130+ MD5 message digest algorithm (RFC1321).
131+
132+ Say 'Y' here to use the CAU coprocessor for
133+ the CryptoAPI MD5 alogrithm.
134+
135+ To compile this driver as a module, choose M here:
136+ the module will be called mcfcau-md5.
137+
138+config CRYPTO_DEV_MCFCAU_SHA1
139+ tristate "SHA1 digest algorithm (coldfire)"
140+ depends on CRYPTO_DEV_MCFCAU
141+ select CRYPTO_ALGAPI
142+ help
143+ SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
144+
145+ Say 'Y' here to use the CAU coprocessor for
146+ the CryptoAPI SHA1 alogrithm.
147+
148+ To compile this driver as a module, choose M here: the module
149+ will be called mcfcau-sha1.
150+
151 config ZCRYPT
152     tristate "Support for PCI-attached cryptographic adapters"
153     depends on S390
154--- a/drivers/crypto/Makefile
155+++ b/drivers/crypto/Makefile
156@@ -7,6 +7,11 @@ obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hi
157 obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
158 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
159 obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
160+obj-$(CONFIG_CRYPTO_DEV_MCFCAU) += mcfcau.o
161+obj-$(CONFIG_CRYPTO_DEV_MCFCAU_DES) += mcfcau-des.o
162+obj-$(CONFIG_CRYPTO_DEV_MCFCAU_AES) += mcfcau-aes.o
163+obj-$(CONFIG_CRYPTO_DEV_MCFCAU_MD5) += mcfcau-md5.o
164+obj-$(CONFIG_CRYPTO_DEV_MCFCAU_SHA1) += mcfcau-sha1.o
165 obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
166 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
167 obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
168--- /dev/null
169+++ b/drivers/crypto/mcfcau-aes.c
170@@ -0,0 +1,367 @@
171+/***************************************************************************
172+ * mcfcau-aes.c - Implementation of AES Cipher Algorithm
173+ * for Freescale ColdFire Cryptographic Acceleration Unit (CAU).
174+ *
175+ * Copyright (C) 2007-2011 Freescale Semiconductor Inc. All Rights Reserved.
176+ * Author: Andrey Butok
177+ * Shrek Wu B16972@freescale.com
178+ *
179+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
180+ *
181+ * This program is free software; you can redistribute it and/or modify it
182+ * under the terms of the GNU General Public License as published by the
183+ * Free Software Foundation; either version 2 of the License, or (at your
184+ * option) any later version.
185+ *
186+ * This program is distributed in the hope that it will be useful, but
187+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
188+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
189+ * for more details.
190+ *
191+ * You should have received a copy of the GNU General Public License
192+ * along with this program; if not, write to the Free Software Foundation,
193+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
194+ *
195+ ***************************************************************************
196+ * Changes:
197+ * v0.01 17 September 2007 Andrey Butok
198+ * Initial Release - developed on 2.6.20 Linux kernel.
199+ */
200+
201+#include <linux/module.h>
202+#include <linux/init.h>
203+#include <linux/types.h>
204+#include <linux/errno.h>
205+#include <linux/crypto.h>
206+
207+/*
208+#undef DEBUG
209+#define DEBUG 1
210+*/
211+
212+#include "mcfcau.h"
213+
214+#define MCFCAU_AES_MIN_KEY_SIZE (16)
215+#define MCFCAU_AES_MAX_KEY_SIZE (32)
216+#define MCFCAU_AES_BLOCK_SIZE (16)
217+
218+#define MCFCAU_AES_DRIVER_DESC "AES ColdFire CAU driver"
219+#define MCFCAU_AES_DRIVER_VERSION "v0.01"
220+
221+struct mcfcau_aes_ctx {
222+ int Nr_1;
223+ u32 buf[120];
224+ u32 buf_tmp[16];
225+};
226+
227+static u32 mcfcau_rco_tab[10]
228+ = { 0x01000000, 0x02000000, 0x04000000, 0x08000000,
229+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
230+ 0x1b000000, 0x36000000};
231+
232+int mcfcau_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,
233+ unsigned int key_len)
234+{
235+ struct mcfcau_aes_ctx *ctx = crypto_tfm_ctx(tfm);
236+ const u32 *key = (const u32 *)in_key;
237+ u32 *flags = &tfm->crt_flags;
238+ u32 i;
239+ u32 *key_sch = (&ctx->buf[0]);
240+ u32 *temp_p, *rcon_p;
241+ u32 Nx;
242+ u32 Nk;
243+ unsigned long iflags;
244+
245+ DBG("mcfcau_aes_setkey\n");
246+
247+ if (key_len % 8) {
248+ *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
249+ return -EINVAL;
250+ }
251+
252+ Nk = key_len>>2;
253+
254+ for (i = 0; i < Nk; i++)
255+ key_sch[i] = key[i];
256+
257+ ctx->Nr_1 = Nk+5;
258+
259+ /* Key Expansion */
260+ temp_p = &key_sch[Nk-1];
261+ rcon_p = &mcfcau_rco_tab[0];
262+
263+ spin_lock_irqsave(&mcfcau_lock, iflags);
264+
265+ asm volatile ("move.l %0, %%a1"
266+ : : "m"(temp_p) : "a1");
267+ asm volatile ("move.l %0, %%a3"
268+ : : "m"(rcon_p) : "a3");
269+ asm volatile ("move.l %0, %%a4"
270+ : : "m"(key_sch) : "a4");
271+
272+ Nx = (Nk+7)<<2; /* (Nr+1)*Nb */
273+
274+ for (i = Nk; i < Nx; i++) {
275+ /* temp = key_sch[Nk-1] */
276+ asm volatile ("cp0ld.l (%%a1)+,%%d0,#1,%0"
277+ : : "n"(MCFCAU_LDR+MCFCAU_CAA) : "a1");
278+
279+ if (i % Nk == 0) {
280+ asm volatile ("moveq #8, %%d0" : : : "d0");
281+ /* CAA=RotWord(temp) */
282+ asm volatile ("cp0ld.l %%d0,%%d0,#1,%0"
283+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA) : "d0");
284+ /* SubWord(CAA) */
285+ asm volatile ("cp0ld.l %%d0,%%d0,#1,%0"
286+ : : "n"(MCFCAU_AESS+MCFCAU_CAA));
287+ /* ACC xor rcon[i/Nk] */
288+ asm volatile ("cp0ld.l (%%a3)+,%%d0,#1,%0"
289+ : : "n"(MCFCAU_XOR+MCFCAU_CAA) : "a3");
290+
291+ } else if ((Nk > 6) && (i % Nk == 4)) {
292+ /* SubWord(ACC) */
293+ asm volatile ("cp0ld.l %%d0,%%d0,#1,%0"
294+ : : "n"(MCFCAU_AESS+MCFCAU_CAA));
295+ }
296+
297+ /* key_sch[i]^=key_sch[i-Nk]; store ACC to key_sch[i] */
298+ asm volatile ("cp0ld.l (%%a4)+,%%d0,#1,%0"
299+ : : "n"(MCFCAU_XOR+MCFCAU_CAA) : "a4");
300+ asm volatile ("cp0st.l %%d0,(%%a1),#1,%0"
301+ : : "n"(MCFCAU_STR+MCFCAU_CAA));
302+ }
303+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
304+
305+ return 0;
306+}
307+
308+
309+/* encrypt a block of text */
310+static void mcfcau_aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
311+{
312+ struct mcfcau_aes_ctx *ctx = crypto_tfm_ctx(tfm);
313+ const int Nr_1 = ctx->Nr_1;
314+
315+ u32 *key_sch = &(ctx->buf[0]);
316+ u32 i;
317+ unsigned long iflags;
318+
319+ DBG("mcfcau_aes_encrypt\n");
320+
321+ spin_lock_irqsave(&mcfcau_lock, iflags);
322+ asm("move.l %0, %%a1" : : "m"(in) : "a1");
323+ asm("move.l %0, %%a0" : : "m"(key_sch) : "a0");
324+ /* state=in */
325+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
326+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
327+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
328+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a1");
329+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
330+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a1");
331+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
332+ : : "n"(MCFCAU_LDR+MCFCAU_CA3) : "a1");
333+ /* AddRoundKey() */
334+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
335+ : : "n"(MCFCAU_XOR+MCFCAU_CA0) : "a0");
336+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
337+ : : "n"(MCFCAU_XOR+MCFCAU_CA1) : "a0");
338+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
339+ : : "n"(MCFCAU_XOR+MCFCAU_CA2) : "a0");
340+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
341+ : : "n"(MCFCAU_XOR+MCFCAU_CA3) : "a0");
342+
343+ for (i = Nr_1; i > 0; i--) {
344+ /* SubBytes(state) */
345+ asm("cp0ld.l %%d0,%%d0,#1,%0"
346+ : : "n"(MCFCAU_AESS+MCFCAU_CA0));
347+ asm("cp0ld.l %%d0,%%d0,#1,%0"
348+ : : "n"(MCFCAU_AESS+MCFCAU_CA1));
349+ asm("cp0ld.l %%d0,%%d0,#1,%0"
350+ : : "n"(MCFCAU_AESS+MCFCAU_CA2));
351+ asm("cp0ld.l %%d0,%%d0,#1,%0"
352+ : : "n"(MCFCAU_AESS+MCFCAU_CA3));
353+ /* ShiftRows(state) */
354+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESR));
355+ /* MixColumns(state); AddRoundKey() */
356+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
357+ : : "n"(MCFCAU_AESC+MCFCAU_CA0) : "a0");
358+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
359+ : : "n"(MCFCAU_AESC+MCFCAU_CA1) : "a0");
360+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
361+ : : "n"(MCFCAU_AESC+MCFCAU_CA2) : "a0");
362+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
363+ : : "n"(MCFCAU_AESC+MCFCAU_CA3) : "a0");
364+ }
365+ /* SubBytes(state)*/
366+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESS+MCFCAU_CA0));
367+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESS+MCFCAU_CA1));
368+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESS+MCFCAU_CA2));
369+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESS+MCFCAU_CA3));
370+ /* ShiftRows(state) */
371+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESR));
372+ /* AddRoundKey() */
373+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
374+ : : "n"(MCFCAU_XOR+MCFCAU_CA0) : "a0");
375+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
376+ : : "n"(MCFCAU_XOR+MCFCAU_CA1) : "a0");
377+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
378+ : : "n"(MCFCAU_XOR+MCFCAU_CA2) : "a0");
379+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
380+ : : "n"(MCFCAU_XOR+MCFCAU_CA3) : "a0");
381+ /* out = state */
382+ asm("move.l %0, %%a1" : : "m"(out) : "a1");
383+ asm("cp0st.l %%d0,%%d0,#1,%0"
384+ : : "n"(MCFCAU_STR+MCFCAU_CA0) : "d0");
385+ asm("cp0st.l %%d0,%%d1,#1,%0"
386+ : : "n"(MCFCAU_STR+MCFCAU_CA1) : "d1");
387+
388+ asm("move.l %%d0,(%%a1)+" : : : "a1");
389+ asm("move.l %%d1,(%%a1)+" : : : "a1");
390+
391+ asm("cp0st.l %%d0,%%d0,#1,%0"
392+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
393+ asm("cp0st.l %%d0,%%d1,#1,%0"
394+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
395+
396+ asm("move.l %%d0,(%%a1)+" : : : "a1");
397+ asm("move.l %%d1,(%%a1)+" : : : "a1");
398+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
399+}
400+
401+
402+/* decrypt a block of text */
403+static void mcfcau_aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
404+{
405+ struct mcfcau_aes_ctx *ctx = crypto_tfm_ctx(tfm);
406+ u32 *key_sch = &(ctx->buf[0]);
407+ u32 i;
408+ unsigned long iflags;
409+ const int Nr_1 = ctx->Nr_1;
410+ key_sch = &key_sch[(Nr_1+2)*4];
411+
412+ DBG("mcfcau_aes_decrypt\n");
413+
414+ spin_lock_irqsave(&mcfcau_lock, iflags);
415+
416+ asm("move.l %0, %%a1" : : "m"(in) : "a1");
417+ asm("move.l %0, %%a0" : : "m"(key_sch) : "a0");
418+ /* state=in */
419+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
420+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
421+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
422+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a1");
423+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
424+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a1");
425+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
426+ : : "n"(MCFCAU_LDR+MCFCAU_CA3) : "a1");
427+ /* AddRoundKey() */
428+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
429+ : : "n"(MCFCAU_XOR+MCFCAU_CA3) : "a0");
430+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
431+ : : "n"(MCFCAU_XOR+MCFCAU_CA2) : "a0");
432+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
433+ : : "n"(MCFCAU_XOR+MCFCAU_CA1) : "a0");
434+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
435+ : : "n"(MCFCAU_XOR+MCFCAU_CA0) : "a0");
436+
437+ for (i = Nr_1; i > 0; i--) {
438+ /* InvShiftRows(state) */
439+ asm("cp0ld.l %%d0,%%d0,#1,%0"
440+ : : "n"(MCFCAU_AESIR));
441+ /* InvSubBytes(state) */
442+ asm("cp0ld.l %%d0,%%d0,#1,%0"
443+ : : "n"(MCFCAU_AESIS+MCFCAU_CA3));
444+ asm("cp0ld.l %%d0,%%d0,#1,%0"
445+ : : "n"(MCFCAU_AESIS+MCFCAU_CA2));
446+ asm("cp0ld.l %%d0,%%d0,#1,%0"
447+ : : "n"(MCFCAU_AESIS+MCFCAU_CA1));
448+ asm("cp0ld.l %%d0,%%d0,#1,%0"
449+ : : "n"(MCFCAU_AESIS+MCFCAU_CA0));
450+ /* InvMixColumns(state); AddRoundKey() */
451+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
452+ : : "n"(MCFCAU_AESIC+MCFCAU_CA3) : "a0");
453+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
454+ : : "n"(MCFCAU_AESIC+MCFCAU_CA2) : "a0");
455+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
456+ : : "n"(MCFCAU_AESIC+MCFCAU_CA1) : "a0");
457+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
458+ : : "n"(MCFCAU_AESIC+MCFCAU_CA0) : "a0");
459+ }
460+ /* InvShiftRows(state) */
461+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESIR));
462+ /* InvSubBytes(state)*/
463+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESIS+MCFCAU_CA3));
464+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESIS+MCFCAU_CA2));
465+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESIS+MCFCAU_CA1));
466+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_AESIS+MCFCAU_CA0));
467+ /* AddRoundKey() */
468+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
469+ : : "n"(MCFCAU_XOR+MCFCAU_CA3) : "a0");
470+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
471+ : : "n"(MCFCAU_XOR+MCFCAU_CA2) : "a0");
472+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
473+ : : "n"(MCFCAU_XOR+MCFCAU_CA1) : "a0");
474+ asm("cp0ld.l -(%%a0),%%d0,#1,%0"
475+ : : "n"(MCFCAU_XOR+MCFCAU_CA0) : "a0");
476+ /* out = state */
477+ asm("move.l %0, %%a1" : : "m"(out) : "a1");
478+ asm("cp0st.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_STR+MCFCAU_CA0) : "d0");
479+ asm("cp0st.l %%d0,%%d1,#1,%0" : : "n"(MCFCAU_STR+MCFCAU_CA1) : "d1");
480+
481+ asm("move.l %%d0,(%%a1)+" : : : "a1");
482+ asm("move.l %%d1,(%%a1)+" : : : "a1");
483+
484+ asm("cp0st.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
485+ asm("cp0st.l %%d0,%%d1,#1,%0" : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
486+
487+ asm("move.l %%d0,(%%a1)+" : : : "a1");
488+ asm("move.l %%d1,(%%a1)+" : : : "a1");
489+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
490+
491+}
492+
493+
494+static struct crypto_alg mcfcau_aes_alg = {
495+ .cra_name = "aes",
496+ .cra_driver_name = "aes-mcfcau",
497+ .cra_priority = MCFCAU_CRA_PRIORITY,
498+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
499+ .cra_blocksize = MCFCAU_AES_BLOCK_SIZE,
500+ .cra_ctxsize = sizeof(struct mcfcau_aes_ctx),
501+ .cra_alignmask = 3,
502+ .cra_module = THIS_MODULE,
503+ .cra_list = LIST_HEAD_INIT(mcfcau_aes_alg.cra_list),
504+ .cra_u = {
505+ .cipher = {
506+ .cia_min_keysize = MCFCAU_AES_MIN_KEY_SIZE,
507+ .cia_max_keysize = MCFCAU_AES_MAX_KEY_SIZE,
508+ .cia_setkey = mcfcau_aes_setkey,
509+ .cia_encrypt = mcfcau_aes_encrypt,
510+ .cia_decrypt = mcfcau_aes_decrypt
511+ }
512+ }
513+};
514+
515+static int __init mcfcau_aes_init(void)
516+{
517+ int ret = crypto_register_alg(&mcfcau_aes_alg);
518+
519+ printk(KERN_INFO MCFCAU_AES_DRIVER_DESC " "
520+ MCFCAU_AES_DRIVER_VERSION " %s.\n",
521+ ret ? "failed" : "registered");
522+ return ret;
523+}
524+
525+static void __exit mcfcau_aes_fini(void)
526+{
527+ crypto_unregister_alg(&mcfcau_aes_alg);
528+ printk(KERN_INFO MCFCAU_AES_DRIVER_DESC " "
529+ MCFCAU_AES_DRIVER_VERSION " unregistered.\n");
530+}
531+
532+module_init(mcfcau_aes_init);
533+module_exit(mcfcau_aes_fini);
534+
535+MODULE_DESCRIPTION(MCFCAU_AES_DRIVER_DESC);
536+MODULE_LICENSE("Dual BSD/GPL");
537+MODULE_AUTHOR("Andrey Butok");
538--- /dev/null
539+++ b/drivers/crypto/mcfcau-des.c
540@@ -0,0 +1,525 @@
541+/***************************************************************************
542+ * mcfcau-des.c - Implementation of DES & Triple DES EDE Cipher Algorithms
543+ * for Freescale ColdFire Cryptographic Acceleration Unit (CAU).
544+ *
545+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
546+ * Author: Andrey Butok
547+ * Shrek Wu B16972@freescale.com
548+ *
549+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
550+ *
551+ * This program is free software; you can redistribute it and/or modify it
552+ * under the terms of the GNU General Public License as published by the
553+ * Free Software Foundation; either version 2 of the License, or (at your
554+ * option) any later version.
555+ *
556+ * This program is distributed in the hope that it will be useful, but
557+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
558+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
559+ * for more details.
560+ *
561+ * You should have received a copy of the GNU General Public License
562+ * along with this program; if not, write to the Free Software Foundation,
563+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
564+ *
565+ ***************************************************************************
566+ * Changes:
567+ * v0.01 14 August 2007 Andrey Butok
568+ * Initial Release - developed on 2.6.20 Linux kernel.
569+ */
570+
571+#include <linux/init.h>
572+#include <linux/module.h>
573+#include <linux/errno.h>
574+#include <linux/crypto.h>
575+#include <linux/types.h>
576+
577+/*
578+#undef DEBUG
579+#define DEBUG 1
580+*/
581+
582+#include "mcfcau.h"
583+
584+#define MCFCAU_DES_KEY_SIZE (8)
585+#define MCFCAU_DES_EXPKEY_WORDS (32)
586+#define MCFCAU_DES_BLOCK_SIZE (8)
587+
588+#define MCFCAU_DES3_EDE_KEY_SIZE (3 * MCFCAU_DES_KEY_SIZE)
589+#define MCFCAU_DES3_EDE_EXPKEY_WORDS (3 * MCFCAU_DES_EXPKEY_WORDS)
590+#define MCFCAU_DES3_EDE_BLOCK_SIZE (MCFCAU_DES_BLOCK_SIZE)
591+
592+#define MCFCAU_DES_DRIVER_DESC "DES & 3DES ColdFire CAU driver"
593+#define MCFCAU_DES_DRIVER_VERSION "v0.01"
594+
595+struct mcfcau_des_ctx {
596+ u32 expkey[MCFCAU_DES_EXPKEY_WORDS];
597+};
598+
599+struct mcfcau_des3_ede_ctx {
600+ u32 expkey[MCFCAU_DES3_EDE_EXPKEY_WORDS];
601+};
602+
603+/* DES round operations */
604+static inline void mcfcau_des_encipher(void)
605+{
606+ asm("cp0ld.l %%d0,%%d0,#1,%0"
607+ : : "n"(MCFCAU_DESK));
608+ asm("cp0ld.l %%d0,%%d0,#1,%0"
609+ : : "n"(MCFCAU_DESR+MCFCAU_IP+MCFCAU_KSL1));
610+ asm("cp0ld.l %%d0,%%d0,#1,%0"
611+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
612+ asm("cp0ld.l %%d0,%%d0,#1,%0"
613+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
614+ asm("cp0ld.l %%d0,%%d0,#1,%0"
615+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
616+ asm("cp0ld.l %%d0,%%d0,#1,%0"
617+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
618+ asm("cp0ld.l %%d0,%%d0,#1,%0"
619+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
620+ asm("cp0ld.l %%d0,%%d0,#1,%0"
621+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
622+ asm("cp0ld.l %%d0,%%d0,#1,%0"
623+ : : "n"(MCFCAU_DESR+MCFCAU_KSL1));
624+ asm("cp0ld.l %%d0,%%d0,#1,%0"
625+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
626+ asm("cp0ld.l %%d0,%%d0,#1,%0"
627+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
628+ asm("cp0ld.l %%d0,%%d0,#1,%0"
629+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
630+ asm("cp0ld.l %%d0,%%d0,#1,%0"
631+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
632+ asm("cp0ld.l %%d0,%%d0,#1,%0"
633+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
634+ asm("cp0ld.l %%d0,%%d0,#1,%0"
635+ : : "n"(MCFCAU_DESR+MCFCAU_KSL2));
636+ asm("cp0ld.l %%d0,%%d0,#1,%0"
637+ : : "n"(MCFCAU_DESR+MCFCAU_KSL1));
638+ asm("cp0ld.l %%d0,%%d0,#1,%0"
639+ : : "n"(MCFCAU_DESR+MCFCAU_FP+MCFCAU_KSL1));
640+}
641+
642+static inline void mcfcau_des_decipher(void)
643+{
644+ asm("cp0ld.l %%d0,%%d0,#1,%0"
645+ : : "n"(MCFCAU_DESK+MCFCAU_DC));
646+ asm("cp0ld.l %%d0,%%d0,#1,%0"
647+ : : "n"(MCFCAU_DESR+MCFCAU_IP+MCFCAU_KSR1));
648+ asm("cp0ld.l %%d0,%%d0,#1,%0"
649+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
650+ asm("cp0ld.l %%d0,%%d0,#1,%0"
651+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
652+ asm("cp0ld.l %%d0,%%d0,#1,%0"
653+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
654+ asm("cp0ld.l %%d0,%%d0,#1,%0"
655+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
656+ asm("cp0ld.l %%d0,%%d0,#1,%0"
657+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
658+ asm("cp0ld.l %%d0,%%d0,#1,%0"
659+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
660+ asm("cp0ld.l %%d0,%%d0,#1,%0"
661+ : : "n"(MCFCAU_DESR+MCFCAU_KSR1));
662+ asm("cp0ld.l %%d0,%%d0,#1,%0"
663+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
664+ asm("cp0ld.l %%d0,%%d0,#1,%0"
665+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
666+ asm("cp0ld.l %%d0,%%d0,#1,%0"
667+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
668+ asm("cp0ld.l %%d0,%%d0,#1,%0"
669+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
670+ asm("cp0ld.l %%d0,%%d0,#1,%0"
671+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
672+ asm("cp0ld.l %%d0,%%d0,#1,%0"
673+ : : "n"(MCFCAU_DESR+MCFCAU_KSR2));
674+ asm("cp0ld.l %%d0,%%d0,#1,%0"
675+ : : "n"(MCFCAU_DESR+MCFCAU_KSR1));
676+ asm("cp0ld.l %%d0,%%d0,#1,%0"
677+ : : "n"(MCFCAU_DESR+MCFCAU_FP+MCFCAU_KSL1));
678+}
679+
680+
681+static int mcfcau_des_setkey(struct crypto_tfm *tfm, const u8 *key_p,
682+ unsigned int keylen)
683+{
684+ struct mcfcau_des_ctx *dctx = crypto_tfm_ctx(tfm);
685+ u32 *flags = &tfm->crt_flags;
686+ u32 * key = (u32 *) key_p;
687+
688+ DBG("mcfcau_des_setkey\n");
689+
690+ /*
691+ * RFC2451: Weak key checks SHOULD be performed.
692+ *
693+ * FIPS 74:
694+ * Keys having duals are keys which produce all zeros, all ones, or
695+ * alternating zero-one patterns in the C and D registers
696+ * after Permuted
697+ * Choice 1 has operated on the key.
698+ *
699+ */
700+ if (*flags & CRYPTO_TFM_REQ_WEAK_KEY) { /* FIPS 74 */
701+ if (key[0] < 0xE001E00l) {
702+ if (key[0] < 0x1FE01FE0) {
703+ if (key[0] < 0x01E001E0) {
704+ if (((key[0] == 0x01010101) &&
705+ (key[1] == 0x01010101)) ||
706+ ((key[0] == 0x011F011F) &&
707+ (key[1] == 0x010E010E)))
708+ goto WEAK_KEY;
709+ } else {
710+ if (((key[0] == 0x01E001E0) &&
711+ (key[1] == 0x01F101F1)) ||
712+ ((key[0] == 0x01FE01FE) &&
713+ (key[1] == 0x01FE01FE)))
714+ goto WEAK_KEY;
715+ }
716+ } else {
717+ if (key[0] < 0x1F1F1F1F) {
718+ if (((key[0] == 0x1FE01FE0) &&
719+ (key[1] == 0x0EF10EF1)) ||
720+ ((key[0] == 0x1F011F0l) &&
721+ (key[1] == 0x0E010E01)))
722+ goto WEAK_KEY;
723+ } else{
724+ if (((key[0] == 0x1F1F1F1F) &&
725+ (key[1] == 0x0E0E0E0E)) ||
726+ ((key[0] == 0x1FFE1FFE) &&
727+ (key[1] == 0x0EFE0EFE)))
728+ goto WEAK_KEY;
729+ }
730+ }
731+ } else {
732+ if (key[0] < 0xFE01FE01) {
733+ if (key[0] < 0xE0E0E0E0) {
734+ if (((key[0] == 0xE001E00l) &&
735+ (key[1] == 0xF101F101)) ||
736+ ((key[0] == 0xE01FE01F) &&
737+ (key[1] == 0xF10EF10E)))
738+ goto WEAK_KEY;
739+ } else {
740+ if (((key[0] == 0xE0E0E0E0) &&
741+ (key[1] == 0xF1F1F1F1)) ||
742+ ((key[0] == 0xE0FEE0FE) &&
743+ (key[1] == 0xF1FEF1FE)))
744+ goto WEAK_KEY;
745+ }
746+ } else {
747+ if (key[0] < 0xFEE0FEE0) {
748+ if (((key[0] == 0xFE01FE01) &&
749+ (key[1] == 0xFE01FE01)) ||
750+ ((key[0] == 0xFE1FFE1F) &&
751+ (key[1] == 0xFE0EFE0E)))
752+ goto WEAK_KEY;
753+ } else {
754+ if (((key[0] == 0xFEE0FEE0) &&
755+ (key[1] == 0xFEF1FEF1)) ||
756+ ((key[0] == 0xFEFEFEFE)
757+ && (key[1] == 0xFEFEFEFE)))
758+ goto WEAK_KEY;
759+ }
760+ }
761+ }
762+ }
763+ memcpy(dctx->expkey, key_p, keylen);
764+ return 0;
765+WEAK_KEY:
766+ *flags |= CRYPTO_TFM_RES_WEAK_KEY;
767+ return -EINVAL;
768+}
769+
770+
771+void mcfcau_des_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
772+{
773+ struct mcfcau_des_ctx *ctx = crypto_tfm_ctx(tfm);
774+ u32 *des_key_tmp = ctx->expkey;
775+ unsigned long iflags;
776+
777+ DBG("mcfcau_des_encrypt\n");
778+
779+ spin_lock_irqsave(&mcfcau_lock, iflags);
780+
781+ asm("move.l %0, %%a0" : : "m"(src) : "a0");
782+ asm("move.l %0, %%a1" : : "m"(des_key_tmp) : "a1");
783+
784+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
785+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a0");
786+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
787+ : : "n"(MCFCAU_LDR+MCFCAU_CA3));
788+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
789+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
790+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
791+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
792+
793+ mcfcau_des_encipher();
794+
795+ asm("cp0st.l %%d0,%%d0,#1,%0"
796+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
797+ asm("cp0st.l %%d0,%%d1,#1,%0"
798+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
799+ asm("move.l %0, %%a1" : : "m"(dst) : "a1");
800+ asm("move.l %d0,(%a1)+");
801+ asm("move.l %d1,(%a1)");
802+
803+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
804+}
805+
806+
807+void mcfcau_des_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
808+{
809+ struct mcfcau_des_ctx *ctx = crypto_tfm_ctx(tfm);
810+ u32 *des_key_tmp = ctx->expkey;
811+ unsigned long iflags;
812+
813+ DBG("mcfcau_des_decrypt\n");
814+
815+ spin_lock_irqsave(&mcfcau_lock, iflags);
816+
817+ asm("move.l %0, %%a0" : : "m"(src) : "a0");
818+ asm("move.l %0, %%a1" : : "m"(des_key_tmp) : "a1");
819+
820+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
821+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a0");
822+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
823+ : : "n"(MCFCAU_LDR+MCFCAU_CA3));
824+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
825+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
826+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
827+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
828+
829+ mcfcau_des_decipher();
830+
831+ asm("move.l %0, %%a1" : : "m"(dst) : "a1");
832+ asm("cp0st.l %%d0,%%d0,#1,%0"
833+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
834+ asm("cp0st.l %%d0,%%d1,#1,%0"
835+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
836+ asm("move.l %d0,(%a1)+");
837+ asm("move.l %d1,(%a1)");
838+
839+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
840+}
841+
842+
843+/*
844+ * RFC2451:
845+ *
846+ * For DES-EDE3, there is no known need to reject weak or
847+ * complementation keys. Any weakness is obviated by the use of
848+ * multiple keys.
849+ *
850+ * However, if the first two or last two independent 64-bit keys are
851+ * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
852+ * same as DES. Implementers MUST reject keys that exhibit this
853+ * property.
854+ *
855+ */
856+
857+static int mcfcau_des3_ede_setkey(
858+ struct crypto_tfm *tfm, const u8 *key_p, unsigned int keylen)
859+{
860+ const u32 *key = (const u32 *)key_p;
861+ struct mcfcau_des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
862+ u32 *flags = &tfm->crt_flags;
863+
864+ DBG("mcfcau_des3_ede_setkey\n");
865+
866+ if (unlikely(!((key[0] ^ key[2]) | (key[1] ^ key[3])) ||
867+ !((key[2] ^ key[4]) | (key[3] ^ key[5])))) {
868+ *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
869+ return -EINVAL;
870+ }
871+
872+ memcpy(dctx->expkey, key_p, keylen);
873+
874+ return 0;
875+}
876+
877+static void mcfcau_des3_ede_encrypt(
878+ struct crypto_tfm *tfm, u8 *dst, const u8 *src)
879+{
880+ struct mcfcau_des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
881+ const u32 *des_key_tmp = dctx->expkey;
882+ unsigned long iflags;
883+
884+ DBG("mcfcau_des3_ede_encrypt\n");
885+
886+ spin_lock_irqsave(&mcfcau_lock, iflags);
887+
888+ /*EK1*/
889+ asm("move.l %0, %%a0"
890+ : : "m"(src) : "a0");
891+ asm("move.l %0, %%a1"
892+ : : "m"(des_key_tmp) : "a1");
893+
894+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
895+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a0");
896+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
897+ : : "n"(MCFCAU_LDR+MCFCAU_CA3));
898+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
899+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
900+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
901+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a1");
902+
903+ mcfcau_des_encipher();
904+
905+ /*DK2*/
906+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
907+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
908+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
909+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a1");
910+
911+ mcfcau_des_decipher();
912+
913+ /*EK3*/
914+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
915+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
916+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
917+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
918+
919+ mcfcau_des_encipher();
920+
921+ asm("move.l %0, %%a1"
922+ : : "m"(dst) : "a1");
923+ asm("cp0st.l %%d0,%%d0,#1,%0"
924+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
925+ asm("cp0st.l %%d0,%%d1,#1,%0"
926+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
927+ asm("move.l %d0,(%a1)+");
928+ asm("move.l %d1,(%a1)");
929+
930+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
931+}
932+
933+static void mcfcau_des3_ede_decrypt(
934+ struct crypto_tfm *tfm, u8 *dst, const u8 *src)
935+{
936+ struct mcfcau_des3_ede_ctx *dctx = crypto_tfm_ctx(tfm);
937+ const u32 *des_key_tmp = dctx->expkey + 6 - 2;
938+ unsigned long iflags;
939+
940+ DBG("mcfcau_des3_ede_decrypt\n");
941+
942+ spin_lock_irqsave(&mcfcau_lock, iflags);
943+
944+ /*DK3*/
945+ asm("move.l %0, %%a0"
946+ : : "m"(src) : "a0");
947+ asm("move.l %0, %%a1"
948+ : : "m"(des_key_tmp) : "a1");
949+
950+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
951+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a0");
952+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
953+ : : "n"(MCFCAU_LDR+MCFCAU_CA3));
954+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
955+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
956+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
957+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
958+
959+ mcfcau_des_decipher();
960+
961+ /*EK2*/
962+ asm("suba.l #12,%a1"); /*dec key pointer*/
963+
964+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
965+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
966+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
967+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
968+
969+ mcfcau_des_encipher();
970+
971+ /*DK1*/
972+ asm("suba.l #12,%a1"); /*dec key pointer*/
973+
974+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
975+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a1");
976+ asm("cp0ld.l (%%a1),%%d0,#1,%0"
977+ : : "n"(MCFCAU_LDR+MCFCAU_CA1));
978+
979+ mcfcau_des_decipher();
980+
981+ asm("move.l %0, %%a1"
982+ : : "m"(dst) : "a1");
983+ asm("cp0st.l %%d0,%%d0,#1,%0"
984+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "d0");
985+ asm("cp0st.l %%d0,%%d1,#1,%0"
986+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "d1");
987+ asm("move.l %d0,(%a1)+");
988+ asm("move.l %d1,(%a1)");
989+
990+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
991+}
992+
993+
994+static struct crypto_alg mcfcau_des_alg = {
995+ .cra_name = "des",
996+ .cra_driver_name = "des-mcfcau",
997+ .cra_priority = MCFCAU_CRA_PRIORITY,
998+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
999+ .cra_blocksize = MCFCAU_DES_BLOCK_SIZE,
1000+ .cra_ctxsize = sizeof(struct mcfcau_des_ctx),
1001+ .cra_module = THIS_MODULE,
1002+ .cra_alignmask = 3,
1003+ .cra_list = LIST_HEAD_INIT(mcfcau_des_alg.cra_list),
1004+ .cra_u = { .cipher = {
1005+ .cia_min_keysize = MCFCAU_DES_KEY_SIZE,
1006+ .cia_max_keysize = MCFCAU_DES_KEY_SIZE,
1007+ .cia_setkey = mcfcau_des_setkey,
1008+ .cia_encrypt = mcfcau_des_encrypt,
1009+ .cia_decrypt = mcfcau_des_decrypt } }
1010+};
1011+
1012+static struct crypto_alg mcfcau_des3_ede_alg = {
1013+ .cra_name = "des3_ede",
1014+ .cra_driver_name = "des3_ede-mcfcau",
1015+ .cra_priority = MCFCAU_CRA_PRIORITY,
1016+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1017+ .cra_blocksize = MCFCAU_DES3_EDE_BLOCK_SIZE,
1018+ .cra_ctxsize = sizeof(struct mcfcau_des3_ede_ctx),
1019+ .cra_module = THIS_MODULE,
1020+ .cra_alignmask = 3,
1021+ .cra_list =
1022+ LIST_HEAD_INIT(mcfcau_des3_ede_alg.cra_list),
1023+ .cra_u = { .cipher = {
1024+ .cia_min_keysize = MCFCAU_DES3_EDE_KEY_SIZE,
1025+ .cia_max_keysize = MCFCAU_DES3_EDE_KEY_SIZE,
1026+ .cia_setkey = mcfcau_des3_ede_setkey,
1027+ .cia_encrypt = mcfcau_des3_ede_encrypt,
1028+ .cia_decrypt = mcfcau_des3_ede_decrypt } }
1029+};
1030+
1031+MODULE_ALIAS("mcfcau_des3_ede");
1032+
1033+static int __init mcfcau_des_init(void)
1034+{
1035+ int ret;
1036+
1037+ ret = crypto_register_alg(&mcfcau_des_alg);
1038+ if (ret < 0)
1039+ goto out;
1040+
1041+ ret = crypto_register_alg(&mcfcau_des3_ede_alg);
1042+ if (ret < 0)
1043+ crypto_unregister_alg(&mcfcau_des_alg);
1044+out:
1045+ printk(KERN_INFO MCFCAU_DES_DRIVER_DESC " "
1046+ MCFCAU_DES_DRIVER_VERSION " %s.\n",
1047+ ret ? "failed" : "registered");
1048+ return ret;
1049+}
1050+
1051+static void __exit mcfcau_des_exit(void)
1052+{
1053+ crypto_unregister_alg(&mcfcau_des3_ede_alg);
1054+ crypto_unregister_alg(&mcfcau_des_alg);
1055+
1056+ printk(KERN_INFO MCFCAU_DES_DRIVER_DESC " "
1057+ MCFCAU_DES_DRIVER_VERSION " unregistered.\n");
1058+}
1059+
1060+module_init(mcfcau_des_init);
1061+module_exit(mcfcau_des_exit);
1062+
1063+MODULE_LICENSE("GPL");
1064+MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms for ColdFire CAU");
1065+MODULE_AUTHOR("Andrey Butok");
1066--- /dev/null
1067+++ b/drivers/crypto/mcfcau-md5.c
1068@@ -0,0 +1,972 @@
1069+/***************************************************************************
1070+ * mcfcau-md5.c - Implementation of MD5 Message Digest Algorithm (RFC1321)
1071+ * for Freescale ColdFire Cryptographic Acceleration Unit (CAU).
1072+ *
1073+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
1074+ * Author: Andrey Butok
1075+ * Shrek Wu B16972@freescale.com
1076+ * Alison Wang b18965@freescale.com
1077+ *
1078+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
1079+ *
1080+ * This program is free software; you can redistribute it and/or modify it
1081+ * under the terms of the GNU General Public License as published by the
1082+ * Free Software Foundation; either version 2 of the License, or (at your
1083+ * option) any later version.
1084+ *
1085+ * This program is distributed in the hope that it will be useful, but
1086+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1087+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1088+ * for more details.
1089+ *
1090+ * You should have received a copy of the GNU General Public License
1091+ * along with this program; if not, write to the Free Software Foundation,
1092+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1093+ *
1094+ ***************************************************************************
1095+ * Changes:
1096+ * v0.01 30 September 2007 Andrey Butok
1097+ * Initial Release - developed on 2.6.20 Linux kernel.
1098+ */
1099+#include <linux/init.h>
1100+#include <linux/module.h>
1101+#include <linux/string.h>
1102+#include <linux/crypto.h>
1103+#include <linux/types.h>
1104+#include <crypto/algapi.h>
1105+#include <crypto/hash.h>
1106+#include <crypto/internal/hash.h>
1107+#include <asm/byteorder.h>
1108+
1109+#include "mcfcau.h"
1110+
1111+#define MCFCAU_MD5_DIGEST_SIZE (16)
1112+#define MCFCAU_MD5_HMAC_BLOCK_SIZE (64)
1113+#define MCFCAU_MD5_BLOCK_WORDS (16)
1114+#define MCFCAU_MD5_HASH_WORDS (4)
1115+
1116+#define MCFCAU_MD5_DRIVER_DESC "MD5 ColdFire CAU driver"
1117+#define MCFCAU_MD5_DRIVER_VERSION "v0.01"
1118+
1119+
1120+struct mcfcau_md5_ctx {
1121+ u32 hash[MCFCAU_MD5_HASH_WORDS];
1122+ u32 block[MCFCAU_MD5_BLOCK_WORDS];
1123+ u64 byte_count;
1124+};
1125+
1126+u32 mcfcau_md5_t[64] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
1127+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
1128+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
1129+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
1130+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
1131+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
1132+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
1133+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
1134+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
1135+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
1136+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
1137+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
1138+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
1139+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
1140+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
1141+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
1142+
1143+
1144+
1145+static void mcfcau_md5_transform(u32 *hash, u32 const *in)
1146+{
1147+ int i;
1148+ u32 *md5_t_p = &mcfcau_md5_t[0];
1149+ unsigned long iflags;
1150+
1151+ spin_lock_irqsave(&mcfcau_lock, iflags);
1152+ asm("move.l %0, %%a1" : : "m"(hash) : "a1");
1153+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1154+ : : "n"(MCFCAU_LDR+MCFCAU_CAA) : "a1");/*a*/
1155+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1156+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a1");/*b*/
1157+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1158+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a1");/*c*/
1159+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1160+ : : "n"(MCFCAU_LDR+MCFCAU_CA3) : "a1");/*d*/
1161+ asm("move.l %0, %%a0" : : "m"(in) : "a0"); /* X[] */
1162+ asm("move.l %0, %%a3" : : "m"(md5_t_p) : "a3"); /* T[] */
1163+
1164+ /* Round 1 */
1165+ asm("moveq.l #7, %%d4" : : : "d4"); /* for rotating by 7 */
1166+ asm("moveq.l #12, %%d5" : : : "d5"); /* for rotating by 12 */
1167+ asm("moveq.l #17, %%d6" : : : "d6"); /* for rotating by 17 */
1168+ asm("moveq.l #22, %%d7" : : : "d7"); /* for rotating by 22 */
1169+
1170+ for (i = 0; i < 4; i++) {
1171+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1172+ : : "n"(MCFCAU_HASH+MCFCAU_HFF));
1173+ /* a+F(b,c,d) */
1174+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
1175+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1176+ /* add byterev x[i] */
1177+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1178+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1179+ /* add t[i] */
1180+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1181+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1182+ /* rotate by 7 */
1183+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1184+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1185+ /* add b */
1186+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1187+ : : "n"(MCFCAU_MDS));
1188+ /* register to register shift */
1189+
1190+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1191+ : : "n"(MCFCAU_HASH+MCFCAU_HFF));
1192+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
1193+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1194+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1195+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1196+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1197+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1198+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1199+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1200+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1201+ : : "n"(MCFCAU_MDS));
1202+
1203+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1204+ : : "n"(MCFCAU_HASH+MCFCAU_HFF));
1205+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
1206+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1207+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1208+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1209+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1210+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1211+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1212+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1213+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1214+ : : "n"(MCFCAU_MDS));
1215+
1216+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1217+ : : "n"(MCFCAU_HASH+MCFCAU_HFF));
1218+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
1219+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1220+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1221+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1222+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1223+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1224+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1225+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1226+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1227+ : : "n"(MCFCAU_MDS));
1228+ };
1229+
1230+
1231+ /* Round 2 */
1232+ asm("moveq.l #5, %%d4" : : : "d4"); /* for rotating by 5 */
1233+ asm("moveq.l #9, %%d5" : : : "d5"); /* for rotating by 9 */
1234+ asm("moveq.l #14, %%d6" : : : "d6"); /* for rotating by 14 */
1235+ asm("moveq.l #20, %%d7" : : : "d7"); /* for rotating by 20 */
1236+
1237+ asm("lea -60(%%a0),%%a0" : : : "a0");
1238+
1239+ for (i = 0; i < 2; i++) {
1240+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1241+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1242+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1243+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1244+ asm("lea 20(%%a0),%%a0" : : : "a0");
1245+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1246+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1247+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1248+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1249+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1250+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1251+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1252+ : : "n"(MCFCAU_MDS));
1253+
1254+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1255+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1256+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1257+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1258+ asm("lea 20(%%a0),%%a0" : : : "a0");
1259+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1260+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1261+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1262+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1263+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1264+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1265+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_MDS));
1266+
1267+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1268+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1269+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1270+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1271+ asm("lea -44(%%a0),%%a0" : : : "a0");
1272+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1273+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1274+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1275+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1276+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1277+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1278+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1279+ : : "n"(MCFCAU_MDS));
1280+
1281+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1282+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1283+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1284+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1285+ asm("lea 20(%%a0),%%a0" : : : "a0");
1286+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1287+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1288+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1289+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1290+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1291+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1292+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1293+ : : "n"(MCFCAU_MDS));
1294+ };
1295+
1296+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1297+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1298+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1299+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1300+ asm("lea 20(%%a0),%%a0"
1301+ : : : "a0");
1302+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1303+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1304+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1305+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1306+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1307+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1308+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1309+ : : "n"(MCFCAU_MDS));
1310+
1311+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1312+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1313+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1314+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1315+ asm("lea -44(%%a0),%%a0"
1316+ : : : "a0");
1317+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1318+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1319+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1320+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1321+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1322+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1323+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1324+ : : "n"(MCFCAU_MDS));
1325+
1326+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1327+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1328+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1329+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1330+ asm("lea 20(%%a0),%%a0"
1331+ : : : "a0");
1332+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1333+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1334+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1335+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1336+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1337+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1338+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1339+ : : "n"(MCFCAU_MDS));
1340+
1341+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1342+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1343+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1344+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1345+ asm("lea 20(%%a0),%%a0" : : : "a0");
1346+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1347+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1348+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1349+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1350+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1351+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1352+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1353+ : : "n"(MCFCAU_MDS));
1354+
1355+
1356+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1357+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1358+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1359+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1360+ asm("lea -44(%%a0),%%a0" : : : "a0");
1361+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1362+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1363+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1364+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1365+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1366+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1367+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1368+ : : "n"(MCFCAU_MDS));
1369+
1370+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1371+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1372+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1373+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1374+ asm("lea 20(%%a0),%%a0" : : : "a0");
1375+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1376+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1377+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1378+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1379+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1380+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1381+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1382+ : : "n"(MCFCAU_MDS));
1383+
1384+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1385+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1386+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1387+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1388+ asm("lea 20(%%a0),%%a0" : : : "a0");
1389+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1390+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1391+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1392+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1393+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1394+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1395+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1396+ : : "n"(MCFCAU_MDS));
1397+
1398+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1399+ : : "n"(MCFCAU_HASH+MCFCAU_HFG));
1400+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1401+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1402+ asm("lea -28(%%a0),%%a0" : : : "a0");
1403+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1404+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1405+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1406+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1407+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1408+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1409+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1410+ : : "n"(MCFCAU_MDS));
1411+
1412+
1413+ /* Round 3 */
1414+ asm("moveq.l #4, %%d4" : : : "d4"); /* for rotating by 5 */
1415+ asm("moveq.l #11, %%d5" : : : "d5"); /* for rotating by 9 */
1416+ asm("moveq.l #16, %%d6" : : : "d6"); /* for rotating by 14 */
1417+ asm("moveq.l #23, %%d7" : : : "d7"); /* for rotating by 20 */
1418+
1419+
1420+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1421+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1422+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1423+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1424+ asm("lea 12(%%a0),%%a0" : : : "a0");
1425+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1426+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1427+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1428+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1429+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1430+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1431+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1432+ : : "n"(MCFCAU_MDS));
1433+
1434+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1435+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1436+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1437+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1438+ asm("lea 12(%%a0),%%a0" : : : "a0");
1439+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1440+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1441+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1442+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1443+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1444+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1445+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1446+ : : "n"(MCFCAU_MDS));
1447+
1448+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1449+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1450+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1451+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1452+ asm("lea 12(%%a0),%%a0" : : : "a0");
1453+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1454+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1455+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1456+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1457+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1458+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1459+ asm("cp0ld.l %%d0,%%d0,#1,%0" : : "n"(MCFCAU_MDS));
1460+
1461+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1462+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1463+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1464+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1465+ asm("lea -52(%%a0),%%a0" : : : "a0");
1466+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1467+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1468+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1469+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1470+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1471+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1472+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1473+ : : "n"(MCFCAU_MDS));
1474+
1475+
1476+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1477+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1478+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1479+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1480+ asm("lea 12(%%a0),%%a0" : : : "a0");
1481+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1482+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1483+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1484+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1485+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1486+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1487+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1488+ : : "n"(MCFCAU_MDS));
1489+
1490+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1491+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1492+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1493+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1494+ asm("lea 12(%%a0),%%a0" : : : "a0");
1495+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1496+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1497+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1498+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1499+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1500+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1501+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1502+ : : "n"(MCFCAU_MDS));
1503+
1504+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1505+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1506+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1507+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1508+ asm("lea 12(%%a0),%%a0" : : : "a0");
1509+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1510+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1511+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1512+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1513+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1514+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1515+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1516+ : : "n"(MCFCAU_MDS));
1517+
1518+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1519+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1520+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1521+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1522+ asm("lea 12(%%a0),%%a0" : : : "a0");
1523+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1524+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1525+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1526+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1527+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1528+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1529+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1530+ : : "n"(MCFCAU_MDS));
1531+
1532+
1533+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1534+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1535+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1536+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1537+ asm("lea -52(%%a0),%%a0" : : : "a0");
1538+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1539+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1540+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1541+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1542+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1543+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1544+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1545+ : : "n"(MCFCAU_MDS));
1546+
1547+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1548+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1549+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1550+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1551+ asm("lea 12(%%a0),%%a0" : : : "a0");
1552+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1553+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1554+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1555+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1556+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1557+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1558+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1559+ : : "n"(MCFCAU_MDS));
1560+
1561+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1562+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1563+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1564+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1565+ asm("lea 12(%%a0),%%a0" : : : "a0");
1566+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1567+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1568+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1569+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1570+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1571+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1572+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1573+ : : "n"(MCFCAU_MDS));
1574+
1575+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1576+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1577+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1578+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1579+ asm("lea 12(%%a0),%%a0" : : : "a0");
1580+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1581+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1582+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1583+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1584+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1585+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1586+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1587+ : : "n"(MCFCAU_MDS));
1588+
1589+
1590+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1591+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1592+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1593+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1594+ asm("lea 12(%%a0),%%a0" : : : "a0");
1595+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1596+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1597+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1598+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1599+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1600+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1601+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1602+ : : "n"(MCFCAU_MDS));
1603+
1604+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1605+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1606+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1607+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1608+ asm("lea 12(%%a0),%%a0" : : : "a0");
1609+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1610+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1611+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1612+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1613+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1614+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1615+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1616+ : : "n"(MCFCAU_MDS));
1617+
1618+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1619+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1620+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1621+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1622+ asm("lea -52(%%a0),%%a0" : : : "a0");
1623+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1624+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1625+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1626+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1627+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1628+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1629+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1630+ : : "n"(MCFCAU_MDS));
1631+
1632+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1633+ : : "n"(MCFCAU_HASH+MCFCAU_HFH));
1634+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1635+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1636+ asm("lea -8(%%a0),%%a0" : : : "a0");
1637+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1638+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1639+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1640+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1641+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1642+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1643+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1644+ : : "n"(MCFCAU_MDS));
1645+
1646+ /* Round 4 */
1647+ asm("moveq.l #6, %%d4" : : : "d4"); /* for rotating by 6 */
1648+ asm("moveq.l #10, %%d5" : : : "d5"); /* for rotating by 10 */
1649+ asm("moveq.l #15, %%d6" : : : "d6"); /* for rotating by 15 */
1650+ asm("moveq.l #21, %%d7" : : : "d7"); /* for rotating by 21 */
1651+
1652+
1653+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1654+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1655+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1656+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1657+ asm("lea 28(%%a0),%%a0" : : : "a0");
1658+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1659+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1660+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1661+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1662+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1663+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1664+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1665+ : : "n"(MCFCAU_MDS));
1666+
1667+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1668+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1669+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1670+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1671+ asm("lea 28(%%a0),%%a0" : : : "a0");
1672+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1673+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1674+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1675+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1676+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1677+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1678+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1679+ : : "n"(MCFCAU_MDS));
1680+
1681+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1682+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1683+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1684+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1685+ asm("lea -36(%%a0),%%a0" : : : "a0");
1686+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1687+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1688+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1689+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1690+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1691+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1692+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1693+ : : "n"(MCFCAU_MDS));
1694+
1695+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1696+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1697+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1698+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1699+ asm("lea 28(%%a0),%%a0" : : : "a0");
1700+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1701+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1702+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1703+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1704+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1705+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1706+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1707+ : : "n"(MCFCAU_MDS));
1708+
1709+
1710+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1711+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1712+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1713+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1714+ asm("lea -36(%%a0),%%a0" : : : "a0");
1715+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1716+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1717+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1718+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1719+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1720+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1721+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1722+ : : "n"(MCFCAU_MDS));
1723+
1724+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1725+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1726+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1727+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1728+ asm("lea 28(%%a0),%%a0" : : : "a0");
1729+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1730+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1731+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1732+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1733+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1734+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1735+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1736+ : : "n"(MCFCAU_MDS));
1737+
1738+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1739+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1740+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1741+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1742+ asm("lea -36(%%a0),%%a0" : : : "a0");
1743+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1744+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1745+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1746+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1747+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1748+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1749+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1750+ : : "n"(MCFCAU_MDS));
1751+
1752+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1753+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1754+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1755+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1756+ asm("lea 28(%%a0),%%a0" : : : "a0");
1757+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1758+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1759+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1760+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1761+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1762+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1763+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1764+ : : "n"(MCFCAU_MDS));
1765+
1766+
1767+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1768+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1769+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1770+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1771+ asm("lea 28(%%a0),%%a0" : : : "a0");
1772+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1773+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1774+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1775+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1776+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1777+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1778+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1779+ : : "n"(MCFCAU_MDS));
1780+
1781+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1782+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1783+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1784+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1785+ asm("lea -36(%%a0),%%a0" : : : "a0");
1786+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1787+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1788+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1789+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1790+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1791+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1792+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1793+ : : "n"(MCFCAU_MDS));
1794+
1795+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1796+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1797+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1798+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1799+ asm("lea 28(%%a0),%%a0" : : : "a0");
1800+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1801+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1802+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1803+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1804+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1805+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1806+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1807+ : : "n"(MCFCAU_MDS));
1808+
1809+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1810+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1811+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1812+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1813+ asm("lea -36(%%a0),%%a0" : : : "a0");
1814+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1815+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1816+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1817+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1818+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1819+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1820+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1821+ : : "n"(MCFCAU_MDS));
1822+
1823+
1824+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1825+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1826+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1827+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1828+ asm("lea 28(%%a0),%%a0"
1829+ : : : "a0");
1830+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1831+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1832+ asm("cp0ld.l %%d4,%%d0,#1,%0"
1833+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1834+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1835+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1836+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1837+ : : "n"(MCFCAU_MDS));
1838+
1839+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1840+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1841+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1842+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1843+ asm("lea -36(%%a0),%%a0"
1844+ : : : "a0");
1845+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1846+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1847+ asm("cp0ld.l %%d5,%%d0,#1,%0"
1848+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1849+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1850+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1851+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1852+ : : "n"(MCFCAU_MDS));
1853+
1854+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1855+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1856+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1857+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1858+ asm("lea 28(%%a0),%%a0"
1859+ : : : "a0");
1860+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1861+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1862+ asm("cp0ld.l %%d6,%%d0,#1,%0"
1863+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1864+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1865+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1866+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1867+ : : "n"(MCFCAU_MDS));
1868+
1869+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1870+ : : "n"(MCFCAU_HASH+MCFCAU_HFI));
1871+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
1872+ : : "n"(MCFCAU_RADR+MCFCAU_CAA) : "a0");
1873+ asm("lea 28(%%a0),%%a0" : : : "a0");
1874+ asm("cp0ld.l (%%a3)+,%%d0,#1,%0"
1875+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a3");
1876+ asm("cp0ld.l %%d7,%%d0,#1,%0"
1877+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA));
1878+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1879+ : : "n"(MCFCAU_ADRA+MCFCAU_CA1));
1880+ asm("cp0ld.l %%d0,%%d0,#1,%0"
1881+ : : "n"(MCFCAU_MDS));
1882+
1883+
1884+ asm("move.l %0, %%a1" : : "m"(hash) : "a1");
1885+
1886+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1887+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a1");/*a*/
1888+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1889+ : : "n"(MCFCAU_ADR+MCFCAU_CA1) : "a1");/*b*/
1890+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1891+ : : "n"(MCFCAU_ADR+MCFCAU_CA2) : "a1");/*c*/
1892+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
1893+ : : "n"(MCFCAU_ADR+MCFCAU_CA3) : "a1");/*d*/
1894+
1895+ asm("cp0st.l %%d0,-(%%a1),#1,%0"
1896+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "a1");/*d*/
1897+ asm("cp0st.l %%d0,-(%%a1),#1,%0"
1898+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "a1");/*c*/
1899+ asm("cp0st.l %%d0,-(%%a1),#1,%0"
1900+ : : "n"(MCFCAU_STR+MCFCAU_CA1) : "a1");/*b*/
1901+ asm("cp0st.l %%d0,-(%%a1),#1,%0"
1902+ : : "n"(MCFCAU_STR+MCFCAU_CAA) : "a1");/*a*/
1903+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
1904+}
1905+
1906+static inline void le32_to_cpu_array(u32 *buf, unsigned int words)
1907+{
1908+ while (words--) {
1909+ __le32_to_cpus(buf);
1910+ buf++;
1911+ }
1912+}
1913+
1914+static inline void cpu_to_le32_array(u32 *buf, unsigned int words)
1915+{
1916+ while (words--) {
1917+ __cpu_to_le32s(buf);
1918+ buf++;
1919+ }
1920+}
1921+
1922+static int mcfcau_md5_initialization(struct shash_desc *desc)
1923+{
1924+ struct mcfcau_md5_ctx *mctx = shash_desc_ctx(desc);
1925+
1926+ DBG("mcfcau_md5_initialization\n");
1927+ mctx->hash[0] = 0x67452301;
1928+ mctx->hash[1] = 0xefcdab89;
1929+ mctx->hash[2] = 0x98badcfe;
1930+ mctx->hash[3] = 0x10325476;
1931+ mctx->byte_count = 0;
1932+
1933+ return 0;
1934+}
1935+
1936+static int mcfcau_md5_update(struct shash_desc *desc,
1937+ const u8 *data, unsigned int len)
1938+{
1939+ struct mcfcau_md5_ctx *mctx = shash_desc_ctx(desc);
1940+ const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f);
1941+
1942+ DBG("mcfcau_md5_update\n");
1943+ mctx->byte_count += len;
1944+
1945+ if (avail > len) {
1946+ memcpy((char *)mctx->block + (sizeof(mctx->block) - avail),
1947+ data, len);
1948+ } else {
1949+ memcpy((char *)mctx->block +
1950+ (sizeof(mctx->block) - avail), data, avail);
1951+
1952+ mcfcau_md5_transform(mctx->hash, mctx->block);
1953+ data += avail;
1954+ len -= avail;
1955+
1956+ while (len >= sizeof(mctx->block)) {
1957+ memcpy(mctx->block, data, sizeof(mctx->block));
1958+ mcfcau_md5_transform(mctx->hash, mctx->block);
1959+ data += sizeof(mctx->block);
1960+ len -= sizeof(mctx->block);
1961+ }
1962+
1963+ memcpy(mctx->block, data, len);
1964+ }
1965+
1966+ return 0;
1967+}
1968+
1969+static int mcfcau_md5_final(struct shash_desc *desc, u8 *out)
1970+{
1971+ struct mcfcau_md5_ctx *mctx = shash_desc_ctx(desc);
1972+ const unsigned int offset = mctx->byte_count & 0x3f;
1973+ char *p = (char *)mctx->block + offset;
1974+ int padding = 56 - (offset + 1);
1975+
1976+ DBG("mcfcau_md5_final\n");
1977+
1978+ *p++ = 0x80;
1979+ if (padding < 0) {
1980+ memset(p, 0x00, padding + sizeof(u64));
1981+ mcfcau_md5_transform(mctx->hash, mctx->block);
1982+ p = (char *)mctx->block;
1983+ padding = 56;
1984+ }
1985+
1986+ memset(p, 0, padding);
1987+ mctx->block[14] = mctx->byte_count << 3;
1988+ mctx->block[15] = mctx->byte_count >> 29;
1989+ le32_to_cpu_array(&mctx->block[14], 2);
1990+
1991+ mcfcau_md5_transform(mctx->hash, mctx->block);
1992+
1993+ cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32));
1994+ memcpy(out, mctx->hash, sizeof(mctx->hash));
1995+ memset(mctx, 0, sizeof(*mctx));
1996+
1997+ return 0;
1998+}
1999+
2000+static struct shash_alg mcfcau_md5_alg = {
2001+ .init = mcfcau_md5_initialization,
2002+ .update = mcfcau_md5_update,
2003+ .final = mcfcau_md5_final,
2004+ .digestsize = MCFCAU_MD5_DIGEST_SIZE,
2005+ .descsize = sizeof(struct mcfcau_md5_ctx),
2006+ .statesize = sizeof(struct mcfcau_md5_ctx),
2007+ .base = {
2008+ .cra_name = "md5",
2009+ .cra_driver_name = "md5-mcfcau",
2010+ .cra_blocksize = MCFCAU_MD5_HMAC_BLOCK_SIZE,
2011+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
2012+ .cra_priority = MCFCAU_CRA_PRIORITY,
2013+ .cra_module = THIS_MODULE
2014+ }
2015+};
2016+
2017+static int __init mcfcau_md5_init(void)
2018+{
2019+ int ret = 0;
2020+
2021+ ret = crypto_register_shash(&mcfcau_md5_alg);
2022+ printk(KERN_INFO MCFCAU_MD5_DRIVER_DESC " "
2023+ MCFCAU_MD5_DRIVER_VERSION " %s.\n",
2024+ ret ? "failed" : "registered");
2025+ return ret;
2026+}
2027+
2028+static void __exit mcfcau_md5_exit(void)
2029+{
2030+ crypto_unregister_shash(&mcfcau_md5_alg);
2031+ printk(KERN_INFO MCFCAU_MD5_DRIVER_DESC " "
2032+ MCFCAU_MD5_DRIVER_VERSION " unregistered.\n");
2033+}
2034+
2035+module_init(mcfcau_md5_init);
2036+module_exit(mcfcau_md5_exit);
2037+
2038+MODULE_LICENSE("GPL");
2039+MODULE_DESCRIPTION(MCFCAU_MD5_DRIVER_DESC);
2040+MODULE_AUTHOR("Andrey Butok");
2041--- /dev/null
2042+++ b/drivers/crypto/mcfcau-sha1.c
2043@@ -0,0 +1,331 @@
2044+/***************************************************************************
2045+ * mcfcau-sha1.c - Implementation of SHA1 Secure Hash Algorithm
2046+ * for Freescale ColdFire Cryptographic Acceleration Unit (CAU).
2047+ *
2048+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2049+ * Author: Andrey Butok
2050+ * Shrek Wu B16972@freescale.com
2051+ * Alison Wang b18965@freescale.com
2052+ *
2053+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
2054+ *
2055+ * This program is free software; you can redistribute it and/or modify it
2056+ * under the terms of the GNU General Public License as published by the
2057+ * Free Software Foundation; either version 2 of the License, or (at your
2058+ * option) any later version.
2059+ *
2060+ * This program is distributed in the hope that it will be useful, but
2061+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2062+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2063+ * for more details.
2064+ *
2065+ * You should have received a copy of the GNU General Public License
2066+ * along with this program; if not, write to the Free Software Foundation,
2067+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2068+ *
2069+ ***************************************************************************
2070+ * Changes:
2071+ * v0.01 15 October 2007 Andrey Butok
2072+ * Initial Release - developed on 2.6.20 Linux kernel.
2073+ */
2074+
2075+#include <linux/init.h>
2076+#include <linux/module.h>
2077+#include <linux/mm.h>
2078+#include <linux/crypto.h>
2079+#include <linux/types.h>
2080+#include <crypto/algapi.h>
2081+#include <crypto/hash.h>
2082+#include <crypto/internal/hash.h>
2083+
2084+#include "mcfcau.h"
2085+
2086+#define MCFCAU_SHA1_DIGEST_WORDS (5)
2087+#define MCFCAU_SHA1_WORKSPACE_WORDS (80)
2088+
2089+#define MCFCAU_SHA1_DIGEST_SIZE (20)
2090+#define MCFCAU_SHA1_HMAC_BLOCK_SIZE (64)
2091+
2092+#define MCFCAU_SHA1_DRIVER_DESC "SHA1 ColdFire CAU driver"
2093+#define MCFCAU_SHA1_DRIVER_VERSION "v0.01"
2094+
2095+static const u32 K[4] = {0x5A827999L, /* Rounds 0-19: sqrt(2) * 2^30 */
2096+ 0x6ED9EBA1L, /* Rounds 20-39: sqrt(3) * 2^30 */
2097+ 0x8F1BBCDCL, /* Rounds 40-59: sqrt(5) * 2^30 */
2098+ 0xCA62C1D6L}; /* Rounds 60-79: sqrt(10) * 2^30 */
2099+
2100+struct mcfcau_sha1_ctx {
2101+ u64 count;
2102+ u32 state[5];
2103+ u8 buffer[64];
2104+};
2105+
2106+static void mcfcau_sha1_transform(__u32 *digest, const char *in, __u32 *W)
2107+{
2108+ int i;
2109+ u32 *tmp_p;
2110+ unsigned long iflags;
2111+
2112+ /* (a) Devide M(i) into 16 words W */
2113+ for (i = 0; i < 16; i++)
2114+ W[i] = ((const u32 *)in)[i];
2115+
2116+ /* (b) W[i+16] = S^1(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i]) */
2117+ tmp_p = &W[16];
2118+
2119+ spin_lock_irqsave(&mcfcau_lock, iflags);
2120+ asm("move.l %0, %%a0" : : "m"(tmp_p) : "a0");
2121+ asm("moveq.l #1, %%d3" : : : "d3");
2122+
2123+ for (i = 0; i < 64; i++) {
2124+ asm("cp0ld.l -64(%%a0),%%d0,#1,%0"
2125+ : : "n"(MCFCAU_LDR+MCFCAU_CA0));
2126+ asm("cp0ld.l -56(%%a0),%%d0,#1,%0"
2127+ : : "n"(MCFCAU_XOR+MCFCAU_CA0));
2128+ asm("cp0ld.l -32(%%a0),%%d0,#1,%0"
2129+ : : "n"(MCFCAU_XOR+MCFCAU_CA0));
2130+ asm("cp0ld.l -12(%%a0),%%d0,#1,%0"
2131+ : : "n"(MCFCAU_XOR+MCFCAU_CA0));
2132+ asm("cp0ld.l %%d3,%%d0,#1,%0"
2133+ : : "n"(MCFCAU_ROTL+MCFCAU_CA0) : "d3");
2134+ asm("cp0st.l %%d0,(%%a0)+,#1,%0"
2135+ : : "n"(MCFCAU_STR+MCFCAU_CA0));
2136+ }
2137+
2138+ /* (c) */
2139+ asm("move.l %0, %%a0" : : "m"(digest) : "a0");
2140+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2141+ : : "n"(MCFCAU_LDR+MCFCAU_CA0) : "a0"); /* a */
2142+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2143+ : : "n"(MCFCAU_LDR+MCFCAU_CA1) : "a0"); /* b */
2144+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2145+ : : "n"(MCFCAU_LDR+MCFCAU_CA2) : "a0"); /* c */
2146+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2147+ : : "n"(MCFCAU_LDR+MCFCAU_CA3) : "a0"); /* d */
2148+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2149+ : : "n"(MCFCAU_LDR+MCFCAU_CA4) : "a0"); /* e */
2150+
2151+ /* (d) */
2152+ asm("moveq.l #5, %%d0" : : : "d0");
2153+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2154+ : : "n"(MCFCAU_MVRA+MCFCAU_CA0));
2155+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2156+ : : "n"(MCFCAU_ROTL+MCFCAU_CAA)); /*S^5(A)*/
2157+
2158+ tmp_p = (u32 *)K;
2159+ asm("move.l %0, %%a0" : : "m"(tmp_p) : "a0");
2160+ asm("move.l %0, %%a1" : : "m"(W) : "a1");
2161+
2162+ for (i = 0; i < 20; i++) {
2163+ /* t = f1(b, c, d) + K1 + rol32(a, 5) + e + W[i]; */
2164+ /* e = d; d = c; c = rol32(b, 30); b = a; a = t; */
2165+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2166+ : : "n"(MCFCAU_HASH+MCFCAU_HFC)); /*f(b,c,d)*/
2167+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2168+ : : "n"(MCFCAU_ADRA+MCFCAU_CA4)); /*+e*/
2169+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
2170+ : : "n"(MCFCAU_ADR+MCFCAU_CAA)); /*+K*/
2171+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
2172+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a1"); /*+W*/
2173+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2174+ : : "n"(MCFCAU_SHS));
2175+ }
2176+
2177+ asm("add.l #4,%%a0" : : : "a0"); /* update K */
2178+
2179+ for (; i < 40; i++) {
2180+ /* t = f2(b, c, d) + K2 + rol32(a, 5) + e + W[i]; */
2181+ /* e = d; d = c; c = rol32(b, 30); b = a; a = t; */
2182+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2183+ : : "n"(MCFCAU_HASH+MCFCAU_HFH)); /*f(b,c,d)*/
2184+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2185+ : : "n"(MCFCAU_ADRA+MCFCAU_CA4)); /*+e*/
2186+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
2187+ : : "n"(MCFCAU_ADR+MCFCAU_CAA)); /*+K*/
2188+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
2189+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a1"); /*+W*/
2190+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2191+ : : "n"(MCFCAU_SHS));
2192+ }
2193+
2194+ asm("add.l #4,%%a0" : : : "a0"); /* update K */
2195+
2196+ for (; i < 60; i++) {
2197+ /* t = f3(b, c, d) + K3 + rol32(a, 5) + e + W[i]; */
2198+ /* e = d; d = c; c = rol32(b, 30); b = a; a = t; */
2199+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2200+ : : "n"(MCFCAU_HASH+MCFCAU_HFM)); /*f(b,c,d)*/
2201+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2202+ : : "n"(MCFCAU_ADRA+MCFCAU_CA4)); /*+e*/
2203+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
2204+ : : "n"(MCFCAU_ADR+MCFCAU_CAA)); /*+K*/
2205+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
2206+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a1"); /*+W*/
2207+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2208+ : : "n"(MCFCAU_SHS));
2209+ }
2210+
2211+ asm("add.l #4,%%a0" : : : "a0"); /* update K */
2212+
2213+ for (; i < 80; i++) {
2214+ /* t = f2(b, c, d) + K4 + rol32(a, 5) + e + W[i]; */
2215+ /* e = d; d = c; c = rol32(b, 30); b = a; a = t; */
2216+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2217+ : : "n"(MCFCAU_HASH+MCFCAU_HFH)); /*f(b,c,d)*/
2218+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2219+ : : "n"(MCFCAU_ADRA+MCFCAU_CA4)); /*+e*/
2220+ asm("cp0ld.l (%%a0),%%d0,#1,%0"
2221+ : : "n"(MCFCAU_ADR+MCFCAU_CAA)); /*+K*/
2222+ asm("cp0ld.l (%%a1)+,%%d0,#1,%0"
2223+ : : "n"(MCFCAU_ADR+MCFCAU_CAA) : "a1"); /*+W*/
2224+ asm("cp0ld.l %%d0,%%d0,#1,%0"
2225+ : : "n"(MCFCAU_SHS));
2226+ }
2227+
2228+ /* (e) */
2229+ asm("move.l %0, %%a0" : : "m"(digest) : "a0");
2230+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2231+ : : "n"(MCFCAU_ADR+MCFCAU_CA0) : "a0"); /* +a */
2232+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2233+ : : "n"(MCFCAU_ADR+MCFCAU_CA1) : "a0"); /* +b */
2234+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2235+ : : "n"(MCFCAU_ADR+MCFCAU_CA2) : "a0"); /* +c */
2236+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2237+ : : "n"(MCFCAU_ADR+MCFCAU_CA3) : "a0"); /* +d */
2238+ asm("cp0ld.l (%%a0)+,%%d0,#1,%0"
2239+ : : "n"(MCFCAU_ADR+MCFCAU_CA4) : "a0"); /* +e */
2240+
2241+ asm("cp0st.l %%d0,-(%%a0),#1,%0"
2242+ : : "n"(MCFCAU_STR+MCFCAU_CA4) : "a0");
2243+ asm("cp0st.l %%d0,-(%%a0),#1,%0"
2244+ : : "n"(MCFCAU_STR+MCFCAU_CA3) : "a0");
2245+ asm("cp0st.l %%d0,-(%%a0),#1,%0"
2246+ : : "n"(MCFCAU_STR+MCFCAU_CA2) : "a0");
2247+ asm("cp0st.l %%d0,-(%%a0),#1,%0"
2248+ : : "n"(MCFCAU_STR+MCFCAU_CA1) : "a0");
2249+ asm("cp0st.l %%d0,-(%%a0),#1,%0"
2250+ : : "n"(MCFCAU_STR+MCFCAU_CA0) : "a0");
2251+ spin_unlock_irqrestore(&mcfcau_lock, iflags);
2252+}
2253+
2254+static int mcfcau_sha1_init(struct shash_desc *desc)
2255+{
2256+ struct mcfcau_sha1_ctx *sctx = shash_desc_ctx(desc);
2257+ static const struct mcfcau_sha1_ctx initstate = {
2258+ 0,
2259+ { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 },
2260+ { 0, }
2261+ };
2262+
2263+ DBG("mcfcau_sha1_init\n");
2264+ *sctx = initstate;
2265+
2266+ return 0;
2267+}
2268+
2269+static int mcfcau_sha1_update(struct shash_desc *desc, const u8 *data,
2270+ unsigned int len)
2271+{
2272+ struct mcfcau_sha1_ctx *sctx = shash_desc_ctx(desc);
2273+ unsigned int partial, done;
2274+ const u8 *src;
2275+
2276+ DBG("mcfcau_sha1_update\n");
2277+ partial = sctx->count & 0x3f;
2278+ sctx->count += len;
2279+ done = 0;
2280+ src = data;
2281+
2282+ if ((partial + len) > 63) {
2283+ u32 temp[MCFCAU_SHA1_WORKSPACE_WORDS];
2284+
2285+ if (partial) {
2286+ done = -partial;
2287+ memcpy(sctx->buffer + partial, data, done + 64);
2288+ src = sctx->buffer;
2289+ }
2290+
2291+ do {
2292+ mcfcau_sha1_transform(sctx->state, src, temp);
2293+ done += 64;
2294+ src = data + done;
2295+ } while (done + 63 < len);
2296+
2297+ memset(temp, 0, sizeof(temp));
2298+ partial = 0;
2299+ }
2300+ memcpy(sctx->buffer + partial, src, len - done);
2301+ return 0;
2302+}
2303+
2304+
2305+/* Add padding and return the message digest. */
2306+static int mcfcau_sha1_final(struct shash_desc *desc, u8 *out)
2307+{
2308+ struct mcfcau_sha1_ctx *sctx = shash_desc_ctx(desc);
2309+ u32 *dst = (u32 *)out;
2310+ u32 i, index, padlen;
2311+ u64 bits;
2312+ static const u8 padding[64] = { 0x80, };
2313+
2314+ DBG("mcfcau_sha1_final\n");
2315+ bits = sctx->count << 3;
2316+
2317+ /* Pad out to 56 mod 64 */
2318+ index = sctx->count & 0x3f;
2319+ padlen = (index < 56) ? (56 - index) : ((64+56) - index);
2320+ mcfcau_sha1_update(desc, padding, padlen);
2321+
2322+ /* Append length */
2323+ mcfcau_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
2324+
2325+ /* Store state in digest */
2326+ for (i = 0; i < 5; i++)
2327+ dst[i] = sctx->state[i];
2328+
2329+ /* Wipe context */
2330+ memset(sctx, 0, sizeof *sctx);
2331+
2332+ return 0;
2333+}
2334+
2335+static struct shash_alg mcfcau_sha1_alg = {
2336+ .init = mcfcau_sha1_init,
2337+ .update = mcfcau_sha1_update,
2338+ .final = mcfcau_sha1_final,
2339+ .digestsize = MCFCAU_SHA1_DIGEST_SIZE,
2340+ .descsize = sizeof(struct mcfcau_sha1_ctx),
2341+ .statesize = sizeof(struct mcfcau_sha1_ctx),
2342+ .base = {
2343+ .cra_name = "sha1",
2344+ .cra_driver_name = "sha1-mcfcau",
2345+ .cra_priority = MCFCAU_CRA_PRIORITY,
2346+ .cra_flags = CRYPTO_ALG_TYPE_SHASH,
2347+ .cra_blocksize = MCFCAU_SHA1_HMAC_BLOCK_SIZE,
2348+ .cra_module = THIS_MODULE,
2349+ .cra_alignmask = 3,
2350+ }
2351+};
2352+
2353+static int __init init(void)
2354+{
2355+ int ret = crypto_register_shash(&mcfcau_sha1_alg);
2356+ printk(KERN_INFO MCFCAU_SHA1_DRIVER_DESC " "
2357+ MCFCAU_SHA1_DRIVER_VERSION " %s.\n",
2358+ ret ? "failed" : "registered");
2359+ return ret;
2360+}
2361+
2362+static void __exit fini(void)
2363+{
2364+ crypto_unregister_shash(&mcfcau_sha1_alg);
2365+ printk(KERN_INFO MCFCAU_SHA1_DRIVER_DESC " "
2366+ MCFCAU_SHA1_DRIVER_VERSION " unregistered.\n");
2367+}
2368+
2369+module_init(init);
2370+module_exit(fini);
2371+
2372+MODULE_LICENSE("GPL");
2373+MODULE_DESCRIPTION(MCFCAU_SHA1_DRIVER_DESC);
2374+MODULE_AUTHOR("Andrey Butok");
2375--- /dev/null
2376+++ b/drivers/crypto/mcfcau.c
2377@@ -0,0 +1,33 @@
2378+/***************************************************************************
2379+ * mcfcau.c - Implementation of DES & Triple DES EDE Cipher Algorithms
2380+ * for Freescale ColdFire Cryptographic Acceleration Unit (CAU).
2381+ *
2382+ * Copyright (C) 2007-2011 Freescale Semiconductor Inc. All Rights Reserved.
2383+ * Author: Andrey Butok
2384+ * Shrek Wu B16972@freescale.com
2385+ *
2386+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
2387+ *
2388+ * This program is free software; you can redistribute it and/or modify it
2389+ * under the terms of the GNU General Public License as published by the
2390+ * Free Software Foundation; either version 2 of the License, or (at your
2391+ * option) any later version.
2392+ *
2393+ * This program is distributed in the hope that it will be useful, but
2394+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2395+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2396+ * for more details.
2397+ *
2398+ * You should have received a copy of the GNU General Public License
2399+ * along with this program; if not, write to the Free Software Foundation,
2400+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2401+ *
2402+ ***************************************************************************
2403+ * Changes:
2404+ * v0.01 28 September 2006 Andrey Butok
2405+ * Initial Release - developed on 2.6.20 Linux kernel.
2406+ */
2407+#include <linux/module.h>
2408+
2409+DEFINE_SPINLOCK(mcfcau_lock);
2410+EXPORT_SYMBOL(mcfcau_lock);
2411--- /dev/null
2412+++ b/drivers/crypto/mcfcau.h
2413@@ -0,0 +1,101 @@
2414+/***************************************************************************
2415+ * mcfcau.h - Common header file for Freescale ColdFire
2416+ * Cryptographic Acceleration Unit (CAU) drivers.
2417+ *
2418+ * Copyright (C) 2007-2011 Freescale Semiconductor, Inc. All Rights Reserved.
2419+ * Author: Andrey Butok
2420+ * Shrek Wu B16972@freescale.com
2421+ *
2422+ * NOTE: You can find the ColdFire CAU module on MCF5445X and MCF52235.
2423+ *
2424+ * This program is free software; you can redistribute it and/or modify it
2425+ * under the terms of the GNU General Public License as published by the
2426+ * Free Software Foundation; either version 2 of the License, or (at your
2427+ * option) any later version.
2428+ *
2429+ * This program is distributed in the hope that it will be useful, but
2430+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2431+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2432+ * for more details.
2433+ *
2434+ * You should have received a copy of the GNU General Public License
2435+ * along with this program; if not, write to the Free Software Foundation,
2436+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2437+ *
2438+ ***************************************************************************
2439+ * Changes:
2440+ * v0.01 14 August 2007 Andrey Butok
2441+ */
2442+
2443+#ifndef MCFCAU_H
2444+#define MCFCAU_H
2445+
2446+#include <linux/spinlock.h>
2447+
2448+/* CAU Registers (CAx) */
2449+#define MCFCAU_CASR (0x0)
2450+#define MCFCAU_CAA (0x1)
2451+#define MCFCAU_CA0 (0x2)
2452+#define MCFCAU_CA1 (0x3)
2453+#define MCFCAU_CA2 (0x4)
2454+#define MCFCAU_CA3 (0x5)
2455+#define MCFCAU_CA4 (0x6)
2456+#define MCFCAU_CA5 (0x7)
2457+
2458+ /* CAU Commands */
2459+#define MCFCAU_CNOP (0x000)
2460+#define MCFCAU_LDR (0x010)
2461+#define MCFCAU_STR (0x020)
2462+#define MCFCAU_ADR (0x030)
2463+#define MCFCAU_RADR (0x040)
2464+#define MCFCAU_ADRA (0x050)
2465+#define MCFCAU_XOR (0x060)
2466+#define MCFCAU_ROTL (0x070)
2467+#define MCFCAU_MVRA (0x080)
2468+#define MCFCAU_MVAR (0x090)
2469+#define MCFCAU_AESS (0x0A0)
2470+#define MCFCAU_AESIS (0x0B0)
2471+#define MCFCAU_AESC (0x0C0)
2472+#define MCFCAU_AESIC (0x0D0)
2473+#define MCFCAU_AESR (0x0E0)
2474+#define MCFCAU_AESIR (0x0F0)
2475+#define MCFCAU_DESR (0x100)
2476+#define MCFCAU_DESK (0x110)
2477+#define MCFCAU_HASH (0x120)
2478+#define MCFCAU_SHS (0x130)
2479+#define MCFCAU_MDS (0x140)
2480+#define MCFCAU_ILL (0x1F0)
2481+
2482+/* DESR Fields */
2483+#define MCFCAU_IP (0x08) /* initial permutation */
2484+#define MCFCAU_FP (0x04) /* final permutation */
2485+#define MCFCAU_KSL1 (0x00) /* key schedule left 1 bit */
2486+#define MCFCAU_KSL2 (0x01) /* key schedule left 2 bits */
2487+#define MCFCAU_KSR1 (0x02) /* key schedule right 1 bit */
2488+#define MCFCAU_KSR2 (0x03) /* key schedule right 2 bits */
2489+
2490+/* DESK Field */
2491+#define MCFCAU_DC (0x01) /* decrypt key schedule */
2492+#define MCFCAU_CP (0x02) /* check parity */
2493+
2494+/* HASH Functions Codes */
2495+#define MCFCAU_HFF (0x0) /* MD5 F() CA1&CA2 | ~CA1&CA3 */
2496+#define MCFCAU_HFG (0x1) /* MD5 G() CA1&CA3 | CA2&~CA3 */
2497+#define MCFCAU_HFH (0x2) /* MD5 H(), SHA Parity() CA1^CA2^CA3 */
2498+#define MCFCAU_HFI (0x3) /* MD5 I() CA2^(CA1|~CA3) */
2499+#define MCFCAU_HFC (0x4) /* SHA Ch() CA1&CA2 ^ ~CA1&CA3 */
2500+#define MCFCAU_HFM (0x5)
2501+/* SHA Maj() CA1&CA2 ^ CA1&CA3 ^ CA2&CA3 */
2502+
2503+#define MCFCAU_CRA_PRIORITY (300)
2504+
2505+extern spinlock_t mcfcau_lock;
2506+
2507+#ifdef DEBUG
2508+#define DBG(fmt, args...) printk(KERN_INFO "[%s] " fmt ,\
2509+ __func__, ## args)
2510+#else
2511+#define DBG(fmt, args...) do {} while (0)
2512+#endif
2513+
2514+#endif
2515

Archive Download this file



interactive