leon: R.I.P.
[openwrt/svn-archive/archive.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