ar71xx: don't use the unknown LED on the ZCN-1523-5 board
[openwrt.git] / target / linux / coldfire / patches / 011-Add-CAU-driver-for-MCF5445x-and-MCF5441x.patch
1 From 0419eb27af72bd37c3ef926169fe4db90e8690d3 Mon Sep 17 00:00:00 2001
2 From: Alison Wang <b18965@freescale.com>
3 Date: Thu, 4 Aug 2011 09:59:41 +0800
4 Subject: [PATCH 11/52] Add CAU driver for MCF5445x and MCF5441x
5
6 Add CAU driver support for MCF5445x and MCF5441x.
7
8 Signed-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