lantiq: Tune the XWAY subtarget cflags
[openwrt.git] / package / platform / lantiq / ltq-deu / src / ifxmips_des.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : ifxmips_des.c
4 ** PROJECT      : IFX UEIP
5 ** MODULES      : DEU Module
6 **
7 ** DATE         : September 8, 2009
8 ** AUTHOR       : Mohammad Firdaus
9 ** DESCRIPTION  : Data Encryption Unit Driver for DES Algorithm
10 ** COPYRIGHT    :       Copyright (c) 2009
11 **                      Infineon Technologies AG
12 **                      Am Campeon 1-12, 85579 Neubiberg, Germany
13 **
14 **    This program is free software; you can redistribute it and/or modify
15 **    it under the terms of the GNU General Public License as published by
16 **    the Free Software Foundation; either version 2 of the License, or
17 **    (at your option) any later version.
18 **
19 ** HISTORY
20 ** $Date        $Author             $Comment
21 ** 08 Sept 2009 Mohammad Firdaus    Initial UEIP release
22 *******************************************************************************/
23
24 /*!
25   \defgroup IFX_DEU IFX_DEU_DRIVERS
26   \ingroup API
27   \brief ifx deu driver
28 */
29
30 /*!
31   \file         ifxmips_des.c
32   \ingroup      IFX_DEU
33   \brief        DES encryption DEU driver file
34 */
35
36 /*!
37   \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
38   \ingroup IFX_DEU
39   \brief IFX DES Encryption functions
40 */
41
42 /* Project Header Files */
43 #include <linux/version.h>
44 #include <linux/module.h>
45 #include <linux/init.h>
46 #include <linux/types.h>
47 #include <linux/errno.h>
48 #include <linux/crypto.h>
49 #include <linux/interrupt.h>
50 #include <linux/delay.h>
51 #include <asm/byteorder.h>
52 #include <crypto/algapi.h>
53 #include "ifxmips_deu.h"
54
55 #if defined(CONFIG_DANUBE) 
56 #include "ifxmips_deu_danube.h"
57 extern int ifx_danube_pre_1_4;
58 #elif defined(CONFIG_AR9)
59 #include "ifxmips_deu_ar9.h"
60 #elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
61 #include "ifxmips_deu_vr9.h"
62 #else
63 #error "Unkown platform"
64 #endif
65
66 /* DMA specific header and variables */
67
68 #if 0
69      #define CRTCL_SECT_INIT        
70      #define CRTCL_SECT_START        
71      #define CRTCL_SECT_END         
72 #else
73 spinlock_t des_lock;
74 #define CRTCL_SECT_INIT        spin_lock_init(&des_lock)
75 #define CRTCL_SECT_START       spin_lock_irqsave(&des_lock, flag)
76 #define CRTCL_SECT_END         spin_unlock_irqrestore(&des_lock, flag)
77 #endif
78
79 /* Preprocessor declerations */
80 #ifdef CRYPTO_DEBUG
81 extern char debug_level;
82 #define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
83 #else
84 #define DPRINTF(level, format, args...)
85 #endif
86 #define DES_3DES_START  IFX_DES_CON
87 #define DES_KEY_SIZE            8
88 #define DES_EXPKEY_WORDS        32
89 #define DES_BLOCK_SIZE          8
90 #define DES3_EDE_KEY_SIZE       (3 * DES_KEY_SIZE)
91 #define DES3_EDE_EXPKEY_WORDS   (3 * DES_EXPKEY_WORDS)
92 #define DES3_EDE_BLOCK_SIZE     DES_BLOCK_SIZE
93
94 /* Function Declaration to prevent warning messages */
95 void des_chip_init (void);
96 u32 endian_swap(u32 input);
97 u32 input_swap(u32 input);
98 int aes_memory_allocate(int value);
99 int des_memory_allocate(int value);
100 void memory_release(u32 *buffer);
101 u32* memory_alignment(const u8 *arg, u32 *buff_alloc, int in_out, int nbytes);
102 void aes_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
103 void des_dma_memory_copy(u32 *outcopy, u32 *out_dma, u8 *out_arg, int nbytes);
104
105 void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
106              u8 *iv_arg, u32 nbytes, int encdec, int mode);
107
108 struct des_ctx {
109         int controlr_M;
110         int key_length;
111         u8 iv[DES_BLOCK_SIZE];
112         u32 expkey[DES3_EDE_EXPKEY_WORDS];
113 };
114
115 extern int disable_multiblock;
116 extern int disable_deudma;
117
118
119 /*! \fn int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
120  *  \ingroup IFX_DES_FUNCTIONS
121  *  \brief sets DES key   
122  *  \param tfm linux crypto algo transform  
123  *  \param key input key  
124  *  \param keylen key length  
125 */                                 
126 int des_setkey(struct crypto_tfm *tfm, const u8 *key,
127                       unsigned int keylen)
128 {
129         struct des_ctx *dctx = crypto_tfm_ctx(tfm);
130
131         //printk("setkey in %s\n", __FILE__);
132
133         dctx->controlr_M = 0;   // des
134         dctx->key_length = keylen;
135
136         memcpy ((u8 *) (dctx->expkey), key, keylen);
137
138         return 0;
139 }
140
141
142 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
143  *  \ingroup IFX_DES_FUNCTIONS
144  *  \brief main interface to DES hardware   
145  *  \param ctx_arg crypto algo context  
146  *  \param out_arg output bytestream  
147  *  \param in_arg input bytestream   
148  *  \param iv_arg initialization vector  
149  *  \param nbytes length of bytestream  
150  *  \param encdec 1 for encrypt; 0 for decrypt  
151  *  \param mode operation mode such as ebc, cbc 
152 */                                 
153
154 void ifx_deu_des (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
155              u8 *iv_arg, u32 nbytes, int encdec, int mode)
156 {
157         volatile struct des_t *des = (struct des_t *) DES_3DES_START;
158         struct des_ctx *dctx = ctx_arg;
159         u32 *key = dctx->expkey;
160         unsigned long flag;
161
162         int i = 0;
163         int nblocks = 0;
164         
165         CRTCL_SECT_START;
166
167         des->controlr.M = dctx->controlr_M;
168         if (dctx->controlr_M == 0)      // des
169         {
170                 des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
171                 des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
172
173         }
174         else {
175                 /* Hardware Section */
176                 switch (dctx->key_length) {
177                 case 24:
178                         des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
179                         des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
180                         /* no break; */
181
182                 case 16:
183                         des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
184                         des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
185
186                         /* no break; */
187                 case 8:
188                         des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
189                         des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
190                         break;
191
192                 default:
193                         CRTCL_SECT_END;
194                         return;
195                 }
196         }
197
198         des->controlr.E_D = !encdec;    //encryption
199         des->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
200
201         if (mode > 0) {
202                 des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
203                 des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
204         };
205
206         nblocks = nbytes / 4;
207
208         for (i = 0; i < nblocks; i += 2) {
209                 /* wait for busy bit to clear */
210
211                 /*--- Workaround ----------------------------------------------------
212                 do a dummy read to the busy flag because it is not raised early
213                 enough in CFB/OFB 3DES modes */
214 #ifdef CRYPTO_DEBUG
215                 printk ("ihr: %x\n", (*((u32 *) in_arg + i)));
216                 printk ("ilr: %x\n", (*((u32 *) in_arg + 1 + i)));
217 #endif           
218                 des->IHR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + i));
219                 des->ILR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + 1 + i)); /* start crypto */
220                 
221                 while (des->controlr.BUS) {
222                         // this will not take long
223                 }
224
225                 *((u32 *) out_arg + 0 + i) = des->OHR;
226                 *((u32 *) out_arg + 1 + i) = des->OLR;
227
228         }
229
230
231     
232     if (mode > 0) {
233         *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
234         *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
235     };
236
237     CRTCL_SECT_END;
238 }
239
240 //definitions from linux/include/crypto.h:
241 //#define CRYPTO_TFM_MODE_ECB           0x00000001
242 //#define CRYPTO_TFM_MODE_CBC           0x00000002
243 //#define CRYPTO_TFM_MODE_CFB           0x00000004
244 //#define CRYPTO_TFM_MODE_CTR           0x00000008
245 //#define CRYPTO_TFM_MODE_OFB           0x00000010 // not even defined
246 //but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
247
248 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
249  *  \ingroup IFX_DES_FUNCTIONS
250  *  \brief main interface to DES hardware   
251  *  \param ctx_arg crypto algo context  
252  *  \param out_arg output bytestream  
253  *  \param in_arg input bytestream   
254  *  \param iv_arg initialization vector  
255  *  \param nbytes length of bytestream  
256  *  \param encdec 1 for encrypt; 0 for decrypt  
257  *  \param mode operation mode such as ebc, cbc 
258 */   
259
260
261
262 /*! \fn  void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
263  *  \ingroup IFX_DES_FUNCTIONS
264  *  \brief sets DES hardware to ECB mode   
265  *  \param ctx crypto algo context  
266  *  \param dst output bytestream  
267  *  \param src input bytestream  
268  *  \param iv initialization vector   
269  *  \param nbytes length of bytestream  
270  *  \param encdec 1 for encrypt; 0 for decrypt  
271  *  \param inplace not used  
272 */
273     
274 void ifx_deu_des_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
275                 uint8_t *iv, size_t nbytes, int encdec, int inplace)
276 {
277      ifx_deu_des (ctx, dst, src, NULL, nbytes, encdec, 0);
278 }
279
280 /*! \fn  void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
281  *  \ingroup IFX_DES_FUNCTIONS
282  *  \brief sets DES hardware to CBC mode   
283  *  \param ctx crypto algo context  
284  *  \param dst output bytestream  
285  *  \param src input bytestream  
286  *  \param iv initialization vector   
287  *  \param nbytes length of bytestream  
288  *  \param encdec 1 for encrypt; 0 for decrypt  
289  *  \param inplace not used  
290 */                                 
291 void ifx_deu_des_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
292                 uint8_t *iv, size_t nbytes, int encdec, int inplace)
293 {
294      ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 1);
295 }
296
297 /*! \fn  void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
298  *  \ingroup IFX_DES_FUNCTIONS
299  *  \brief sets DES hardware to OFB mode   
300  *  \param ctx crypto algo context  
301  *  \param dst output bytestream  
302  *  \param src input bytestream  
303  *  \param iv initialization vector   
304  *  \param nbytes length of bytestream  
305  *  \param encdec 1 for encrypt; 0 for decrypt  
306  *  \param inplace not used  
307 */                                 
308 void ifx_deu_des_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
309                 uint8_t *iv, size_t nbytes, int encdec, int inplace)
310 {
311      ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 2);
312 }
313
314 /*! \fn void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
315     \ingroup IFX_DES_FUNCTIONS
316     \brief sets DES hardware to CFB mode   
317     \param ctx crypto algo context  
318     \param dst output bytestream  
319     \param src input bytestream  
320     \param iv initialization vector   
321     \param nbytes length of bytestream  
322     \param encdec 1 for encrypt; 0 for decrypt  
323     \param inplace not used  
324 */                                 
325 void ifx_deu_des_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
326                 uint8_t *iv, size_t nbytes, int encdec, int inplace)
327 {
328      ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 3);
329 }
330
331 /*! \fn void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
332  *  \ingroup IFX_DES_FUNCTIONS
333  *  \brief sets DES hardware to CTR mode   
334  *  \param ctx crypto algo context  
335  *  \param dst output bytestream  
336  *  \param src input bytestream  
337  *  \param iv initialization vector   
338  *  \param nbytes length of bytestream  
339  *  \param encdec 1 for encrypt; 0 for decrypt  
340  *  \param inplace not used  
341 */                                 
342 void ifx_deu_des_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
343                 uint8_t *iv, size_t nbytes, int encdec, int inplace)
344 {
345      ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 4);
346 }
347
348 /*! \fn void des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
349  *  \ingroup IFX_DES_FUNCTIONS
350  *  \brief encrypt DES_BLOCK_SIZE of data   
351  *  \param tfm linux crypto algo transform  
352  *  \param out output bytestream  
353  *  \param in input bytestream  
354 */                                               
355 void des_encrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
356 {
357      struct des_ctx *ctx = crypto_tfm_ctx(tfm);
358      ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
359                     CRYPTO_DIR_ENCRYPT, 0);
360
361 }
362
363 /*! \fn void des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
364  *  \ingroup IFX_DES_FUNCTIONS
365  *  \brief encrypt DES_BLOCK_SIZE of data   
366  *  \param tfm linux crypto algo transform  
367  *  \param out output bytestream  
368  *  \param in input bytestream  
369 */                                               
370 void des_decrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
371 {
372      struct des_ctx *ctx = crypto_tfm_ctx(tfm);
373      ifx_deu_des (ctx, out, in, NULL, DES_BLOCK_SIZE,
374                     CRYPTO_DIR_DECRYPT, 0);
375 }
376
377 /*
378  *   \brief RFC2451:
379  *
380  *   For DES-EDE3, there is no known need to reject weak or
381  *   complementation keys.  Any weakness is obviated by the use of
382  *   multiple keys.
383  *
384  *   However, if the first two or last two independent 64-bit keys are
385  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
386  *   same as DES.  Implementers MUST reject keys that exhibit this
387  *   property.
388  *
389  */
390
391 /*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
392  *  \ingroup IFX_DES_FUNCTIONS
393  *  \brief sets 3DES key   
394  *  \param tfm linux crypto algo transform  
395  *  \param key input key  
396  *  \param keylen key length  
397 */                                 
398 int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
399                     unsigned int keylen)
400 {
401         struct des_ctx *dctx = crypto_tfm_ctx(tfm);
402
403         //printk("setkey in %s\n", __FILE__);
404
405         dctx->controlr_M = keylen / 8 + 1;      // 3DES EDE1 / EDE2 / EDE3 Mode
406         dctx->key_length = keylen;
407
408         memcpy ((u8 *) (dctx->expkey), key, keylen);
409
410         return 0;
411 }
412
413 /*
414  * \brief DES function mappings
415 */ 
416 struct crypto_alg ifxdeu_des_alg = {
417         .cra_name               =       "des",
418         .cra_driver_name        =       "ifxdeu-des",
419         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
420         .cra_blocksize          =       DES_BLOCK_SIZE,
421         .cra_ctxsize            =       sizeof(struct des_ctx),
422         .cra_module             =       THIS_MODULE,
423         .cra_alignmask          =       3,
424         .cra_list               =       LIST_HEAD_INIT(ifxdeu_des_alg.cra_list),
425         .cra_u                  =       { .cipher = {
426         .cia_min_keysize        =       DES_KEY_SIZE,
427         .cia_max_keysize        =       DES_KEY_SIZE,
428         .cia_setkey             =       des_setkey,
429         .cia_encrypt            =       des_encrypt,
430         .cia_decrypt            =       des_decrypt } }
431 };
432
433 /*
434  * \brief DES function mappings
435 */ 
436 struct crypto_alg ifxdeu_des3_ede_alg = {
437         .cra_name               =       "des3_ede",
438         .cra_driver_name        =       "ifxdeu-des3_ede",
439         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
440         .cra_blocksize          =       DES_BLOCK_SIZE,
441         .cra_ctxsize            =       sizeof(struct des_ctx),
442         .cra_module             =       THIS_MODULE,
443         .cra_alignmask          =       3,
444         .cra_list               =       LIST_HEAD_INIT(ifxdeu_des3_ede_alg.cra_list),
445         .cra_u                  =       { .cipher = {
446         .cia_min_keysize        =       DES_KEY_SIZE,
447         .cia_max_keysize        =       DES_KEY_SIZE,
448         .cia_setkey             =       des3_ede_setkey,
449         .cia_encrypt            =       des_encrypt,
450         .cia_decrypt            =       des_decrypt } }
451 };
452
453 /*! \fn int ecb_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
454  *  \ingroup IFX_DES_FUNCTIONS
455  *  \brief ECB DES encrypt using linux crypto blkcipher    
456  *  \param desc blkcipher descriptor  
457  *  \param dst output scatterlist  
458  *  \param src input scatterlist  
459  *  \param nbytes data size in bytes  
460 */                                 
461 int ecb_des_encrypt(struct blkcipher_desc *desc,
462                     struct scatterlist *dst, struct scatterlist *src,
463                     unsigned int nbytes)
464 {
465         struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
466         struct blkcipher_walk walk;
467         int err;
468
469         blkcipher_walk_init(&walk, dst, src, nbytes);
470         err = blkcipher_walk_virt(desc, &walk);
471
472         while ((nbytes = walk.nbytes)) {
473                 nbytes -= (nbytes % DES_BLOCK_SIZE); 
474                 ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
475                                NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
476                 nbytes &= DES_BLOCK_SIZE - 1;
477                 err = blkcipher_walk_done(desc, &walk, nbytes);
478         }
479
480         return err;
481 }
482
483 /*! \fn int ecb_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
484  *  \ingroup IFX_DES_FUNCTIONS
485  *  \brief ECB DES decrypt using linux crypto blkcipher    
486  *  \param desc blkcipher descriptor  
487  *  \param dst output scatterlist  
488  *  \param src input scatterlist  
489  *  \param nbytes data size in bytes  
490  *  \return err
491 */                                 
492 int ecb_des_decrypt(struct blkcipher_desc *desc,
493                     struct scatterlist *dst, struct scatterlist *src,
494                     unsigned int nbytes)
495 {
496         struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
497         struct blkcipher_walk walk;
498         int err;
499
500         DPRINTF(1, "\n");
501         blkcipher_walk_init(&walk, dst, src, nbytes);
502         err = blkcipher_walk_virt(desc, &walk);
503
504         while ((nbytes = walk.nbytes)) {
505                 nbytes -= (nbytes % DES_BLOCK_SIZE); 
506                 ifx_deu_des_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
507                                NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
508                 nbytes &= DES_BLOCK_SIZE - 1;
509                 err = blkcipher_walk_done(desc, &walk, nbytes);
510         }
511
512         return err;
513 }
514
515 /*
516  * \brief DES function mappings
517 */ 
518 struct crypto_alg ifxdeu_ecb_des_alg = {
519         .cra_name               =       "ecb(des)",
520         .cra_driver_name        =       "ifxdeu-ecb(des)",
521         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
522         .cra_blocksize          =       DES_BLOCK_SIZE,
523         .cra_ctxsize            =       sizeof(struct des_ctx),
524         .cra_type               =       &crypto_blkcipher_type,
525         .cra_module             =       THIS_MODULE,
526         .cra_list               =       LIST_HEAD_INIT(ifxdeu_ecb_des_alg.cra_list),
527         .cra_u                  =       {
528                 .blkcipher = {
529                         .min_keysize            =       DES_KEY_SIZE,
530                         .max_keysize            =       DES_KEY_SIZE,
531                         .setkey                 =       des_setkey,
532                         .encrypt                =       ecb_des_encrypt,
533                         .decrypt                =       ecb_des_decrypt,
534                 }
535         }
536 };
537
538 /*
539  * \brief DES function mappings
540 */ 
541 struct crypto_alg ifxdeu_ecb_des3_ede_alg = {
542         .cra_name               =       "ecb(des3_ede)",
543         .cra_driver_name        =       "ifxdeu-ecb(des3_ede)",
544         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
545         .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
546         .cra_ctxsize            =       sizeof(struct des_ctx),
547         .cra_type               =       &crypto_blkcipher_type,
548         .cra_module             =       THIS_MODULE,
549         .cra_list               =       LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg.cra_list),
550         .cra_u                  =       {
551                 .blkcipher = {
552                         .min_keysize            =       DES3_EDE_KEY_SIZE,
553                         .max_keysize            =       DES3_EDE_KEY_SIZE,
554                         .setkey                 =       des3_ede_setkey,
555                         .encrypt                =       ecb_des_encrypt,
556                         .decrypt                =       ecb_des_decrypt,
557                 }
558         }
559 };
560
561 /*! \fn int cbc_des_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
562  *  \ingroup IFX_DES_FUNCTIONS
563  *  \brief CBC DES encrypt using linux crypto blkcipher    
564  *  \param desc blkcipher descriptor  
565  *  \param dst output scatterlist  
566  *  \param src input scatterlist  
567  *  \param nbytes data size in bytes  
568  *  \return err
569 */                                 
570 int cbc_des_encrypt(struct blkcipher_desc *desc,
571                     struct scatterlist *dst, struct scatterlist *src,
572                     unsigned int nbytes)
573 {
574         struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
575         struct blkcipher_walk walk;
576         int err;
577
578         DPRINTF(1, "\n");
579         blkcipher_walk_init(&walk, dst, src, nbytes);
580         err = blkcipher_walk_virt(desc, &walk);
581
582         while ((nbytes = walk.nbytes)) {
583                 u8 *iv = walk.iv;
584                 nbytes -= (nbytes % DES_BLOCK_SIZE); 
585                 ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
586                                iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);      
587                 nbytes &= DES_BLOCK_SIZE - 1;
588                 err = blkcipher_walk_done(desc, &walk, nbytes);
589         }
590
591         return err;
592 }
593
594 /*! \fn int cbc_des_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
595  *  \ingroup IFX_DES_FUNCTIONS
596  *  \brief CBC DES decrypt using linux crypto blkcipher    
597  *  \param desc blkcipher descriptor  
598  *  \param dst output scatterlist  
599  *  \param src input scatterlist  
600  *  \param nbytes data size in bytes  
601  *  \return err
602 */                                 
603 int cbc_des_decrypt(struct blkcipher_desc *desc,
604                     struct scatterlist *dst, struct scatterlist *src,
605                     unsigned int nbytes)
606 {
607         struct des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
608         struct blkcipher_walk walk;
609         int err;
610
611         DPRINTF(1, "\n");
612         blkcipher_walk_init(&walk, dst, src, nbytes);
613         err = blkcipher_walk_virt(desc, &walk);
614
615         while ((nbytes = walk.nbytes)) {
616                 u8 *iv = walk.iv;
617                 nbytes -= (nbytes % DES_BLOCK_SIZE); 
618                 ifx_deu_des_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
619                                iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
620                 nbytes &= DES_BLOCK_SIZE - 1;
621                 err = blkcipher_walk_done(desc, &walk, nbytes);
622         }
623
624         return err;
625 }
626
627 /*
628  * \brief DES function mappings
629 */ 
630 struct crypto_alg ifxdeu_cbc_des_alg = {
631         .cra_name               =       "cbc(des)",
632         .cra_driver_name        =       "ifxdeu-cbc(des)",
633         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
634         .cra_blocksize          =       DES_BLOCK_SIZE,
635         .cra_ctxsize            =       sizeof(struct des_ctx),
636         .cra_type               =       &crypto_blkcipher_type,
637         .cra_module             =       THIS_MODULE,
638         .cra_list               =       LIST_HEAD_INIT(ifxdeu_cbc_des_alg.cra_list),
639         .cra_u                  =       {
640                 .blkcipher = {
641                         .min_keysize            =       DES_KEY_SIZE,
642                         .max_keysize            =       DES_KEY_SIZE,
643                         .ivsize                 =       DES_BLOCK_SIZE,
644                         .setkey                 =       des_setkey,
645                         .encrypt                =       cbc_des_encrypt,
646                         .decrypt                =       cbc_des_decrypt,
647                 }
648         }
649 };
650
651 /*
652  * \brief DES function mappings
653 */ 
654 struct crypto_alg ifxdeu_cbc_des3_ede_alg = {
655         .cra_name               =       "cbc(des3_ede)",
656         .cra_driver_name        =       "ifxdeu-cbc(des3_ede)",
657         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
658         .cra_blocksize          =       DES3_EDE_BLOCK_SIZE,
659         .cra_ctxsize            =       sizeof(struct des_ctx),
660         .cra_type               =       &crypto_blkcipher_type,
661         .cra_module             =       THIS_MODULE,
662         .cra_list               =       LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg.cra_list),
663         .cra_u                  =       {
664                 .blkcipher = {
665                         .min_keysize            =       DES3_EDE_KEY_SIZE,
666                         .max_keysize            =       DES3_EDE_KEY_SIZE,
667                         .ivsize                 =       DES_BLOCK_SIZE,
668                         .setkey                 =       des3_ede_setkey,
669                         .encrypt                =       cbc_des_encrypt,
670                         .decrypt                =       cbc_des_decrypt,
671                 }
672         }
673 };
674
675 /*! \fn int __init ifxdeu_init_des (void)
676  *  \ingroup IFX_DES_FUNCTIONS
677  *  \brief initialize des driver      
678 */                                 
679 int __init ifxdeu_init_des (void)
680 {
681     int ret = -ENOSYS;
682
683
684 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
685      if (!disable_multiblock) {
686                 ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE;    //(size_t)-1;
687                 ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16;
688                 ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb;
689                 ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc;
690                 ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb;
691                 ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb;
692         }
693 #endif
694
695         ret = crypto_register_alg(&ifxdeu_des_alg);
696         if (ret < 0)
697                 goto des_err;
698
699         ret = crypto_register_alg(&ifxdeu_ecb_des_alg);
700         if (ret < 0)
701                 goto ecb_des_err;
702
703         ret = crypto_register_alg(&ifxdeu_cbc_des_alg);
704         if (ret < 0)
705                 goto cbc_des_err;
706
707         ret = crypto_register_alg(&ifxdeu_des3_ede_alg);
708         if (ret < 0)
709                 goto des3_ede_err;
710
711         ret = crypto_register_alg(&ifxdeu_ecb_des3_ede_alg);
712         if (ret < 0)
713                 goto ecb_des3_ede_err;
714
715         ret = crypto_register_alg(&ifxdeu_cbc_des3_ede_alg);
716         if (ret < 0)
717                 goto cbc_des3_ede_err;
718
719         des_chip_init();
720         CRTCL_SECT_INIT;
721
722
723
724          printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
725         return ret;
726
727 des_err:
728         crypto_unregister_alg(&ifxdeu_des_alg);
729         printk(KERN_ERR "IFX des initialization failed!\n");
730         return ret;
731 ecb_des_err:
732         crypto_unregister_alg(&ifxdeu_ecb_des_alg);
733         printk (KERN_ERR "IFX ecb_des initialization failed!\n");
734         return ret;
735 cbc_des_err:
736         crypto_unregister_alg(&ifxdeu_cbc_des_alg);
737         printk (KERN_ERR "IFX cbc_des initialization failed!\n");
738         return ret;
739 des3_ede_err:
740         crypto_unregister_alg(&ifxdeu_des3_ede_alg);
741         printk(KERN_ERR "IFX des3_ede initialization failed!\n");
742         return ret;
743 ecb_des3_ede_err:
744         crypto_unregister_alg(&ifxdeu_ecb_des3_ede_alg);
745         printk (KERN_ERR "IFX ecb_des3_ede initialization failed!\n");
746         return ret;
747 cbc_des3_ede_err:
748         crypto_unregister_alg(&ifxdeu_cbc_des3_ede_alg);
749         printk (KERN_ERR "IFX cbc_des3_ede initialization failed!\n");
750         return ret;
751
752 }
753
754 /*! \fn void __exit ifxdeu_fini_des (void)
755  *  \ingroup IFX_DES_FUNCTIONS
756  *  \brief unregister des driver    
757 */                                 
758 void __exit ifxdeu_fini_des (void)
759 {
760         crypto_unregister_alg (&ifxdeu_des_alg);
761         crypto_unregister_alg (&ifxdeu_ecb_des_alg);
762         crypto_unregister_alg (&ifxdeu_cbc_des_alg);
763         crypto_unregister_alg (&ifxdeu_des3_ede_alg);
764         crypto_unregister_alg (&ifxdeu_ecb_des3_ede_alg);
765         crypto_unregister_alg (&ifxdeu_cbc_des3_ede_alg);
766
767 }
768