add chaos_calmer branch
[15.05/openwrt.git] / package / kernel / lantiq / ltq-deu / src / ifxmips_aes.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : ifxmips_aes.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 AES 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  \defgroup IFX_DEU IFX_DEU_DRIVERS
25  \ingroup API
26  \brief ifx DEU driver module
27 */
28
29 /*!
30   \file ifxmips_aes.c
31   \ingroup IFX_DEU
32   \brief AES Encryption Driver main file
33 */
34
35 /*!
36  \defgroup IFX_AES_FUNCTIONS IFX_AES_FUNCTIONS
37  \ingroup IFX_DEU
38  \brief IFX AES driver Functions 
39 */
40
41
42 /* Project Header Files */
43 #if defined(CONFIG_MODVERSIONS)
44 #define MODVERSIONS
45 #include <linux/modeversions>
46 #endif
47
48 #include <linux/version.h>
49 #include <linux/module.h>
50 #include <linux/init.h>
51 #include <linux/proc_fs.h>
52 #include <linux/fs.h>
53 #include <linux/types.h>
54 #include <linux/errno.h>
55 #include <linux/crypto.h>
56 #include <linux/interrupt.h>
57 #include <linux/delay.h>
58 #include <asm/byteorder.h>
59 #include <crypto/algapi.h>
60
61 #include "ifxmips_deu.h"
62
63 #if defined(CONFIG_DANUBE) 
64 #include "ifxmips_deu_danube.h"
65 extern int ifx_danube_pre_1_4;
66 #elif defined(CONFIG_AR9)
67 #include "ifxmips_deu_ar9.h"
68 #elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
69 #include "ifxmips_deu_vr9.h"
70 #else
71 #error "Unkown platform"
72 #endif
73
74 /* DMA related header and variables */
75
76 spinlock_t aes_lock;
77 #define CRTCL_SECT_INIT        spin_lock_init(&aes_lock)
78 #define CRTCL_SECT_START       spin_lock_irqsave(&aes_lock, flag)
79 #define CRTCL_SECT_END         spin_unlock_irqrestore(&aes_lock, flag)
80
81 /* Definition of constants */
82 #define AES_START   IFX_AES_CON
83 #define AES_MIN_KEY_SIZE    16
84 #define AES_MAX_KEY_SIZE    32
85 #define AES_BLOCK_SIZE      16
86 #define CTR_RFC3686_NONCE_SIZE    4
87 #define CTR_RFC3686_IV_SIZE       8
88 #define CTR_RFC3686_MAX_KEY_SIZE  (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE)
89
90 #ifdef CRYPTO_DEBUG
91 extern char debug_level;
92 #define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
93 #else
94 #define DPRINTF(level, format, args...)
95 #endif /* CRYPTO_DEBUG */
96
97 /* Function decleration */
98 int aes_chip_init(void);
99 u32 endian_swap(u32 input);
100 u32 input_swap(u32 input);
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 int aes_memory_allocate(int value);
105 int des_memory_allocate(int value);
106 void memory_release(u32 *addr); 
107
108
109 extern void ifx_deu_aes (void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg,
110         uint8_t *iv_arg, size_t nbytes, int encdec, int mode);
111 /* End of function decleration */
112
113 struct aes_ctx {
114     int key_length;
115     u32 buf[AES_MAX_KEY_SIZE];
116     u8 nonce[CTR_RFC3686_NONCE_SIZE];
117 };
118
119 extern int disable_deudma;
120 extern int disable_multiblock; 
121
122 /*! \fn int aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
123  *  \ingroup IFX_AES_FUNCTIONS 
124  *  \brief sets the AES keys    
125  *  \param tfm linux crypto algo transform  
126  *  \param in_key input key  
127  *  \param key_len key lengths of 16, 24 and 32 bytes supported  
128  *  \return -EINVAL - bad key length, 0 - SUCCESS
129 */                                 
130 int aes_set_key (struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
131 {
132     struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
133     unsigned long *flags = (unsigned long *) &tfm->crt_flags;
134
135     //printk("set_key in %s\n", __FILE__);
136
137     //aes_chip_init();
138
139     if (key_len != 16 && key_len != 24 && key_len != 32) {
140         *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
141         return -EINVAL;
142     }
143
144     ctx->key_length = key_len;
145     DPRINTF(0, "ctx @%p, key_len %d, ctx->key_length %d\n", ctx, key_len, ctx->key_length);
146     memcpy ((u8 *) (ctx->buf), in_key, key_len);
147
148     return 0;
149 }
150
151
152 /*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, size_t nbytes, int encdec, int mode)
153  *  \ingroup IFX_AES_FUNCTIONS
154  *  \brief main interface to AES hardware
155  *  \param ctx_arg crypto algo context  
156  *  \param out_arg output bytestream  
157  *  \param in_arg input bytestream   
158  *  \param iv_arg initialization vector  
159  *  \param nbytes length of bytestream  
160  *  \param encdec 1 for encrypt; 0 for decrypt  
161  *  \param mode operation mode such as ebc, cbc, ctr  
162  *
163 */                                 
164 void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg,
165         u8 *iv_arg, size_t nbytes, int encdec, int mode)
166
167 {
168     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
169     volatile struct aes_t *aes = (volatile struct aes_t *) AES_START;
170     struct aes_ctx *ctx = (struct aes_ctx *)ctx_arg;
171     u32 *in_key = ctx->buf;
172     unsigned long flag;
173     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
174     int key_len = ctx->key_length;
175
176     int i = 0;
177     int byte_cnt = nbytes; 
178
179
180     CRTCL_SECT_START;
181     /* 128, 192 or 256 bit key length */
182     aes->controlr.K = key_len / 8 - 2;
183         if (key_len == 128 / 8) {
184         aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
185         aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
186         aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
187         aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
188     }
189     else if (key_len == 192 / 8) {
190         aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
191         aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
192         aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
193         aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
194         aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
195         aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
196     }
197     else if (key_len == 256 / 8) {
198         aes->K7R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 0));
199         aes->K6R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 1));
200         aes->K5R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 2));
201         aes->K4R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 3));
202         aes->K3R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 4));
203         aes->K2R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 5));
204         aes->K1R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 6));
205         aes->K0R = DEU_ENDIAN_SWAP(*((u32 *) in_key + 7));
206     }
207     else {
208         printk (KERN_ERR "[%s %s %d]: Invalid key_len : %d\n", __FILE__, __func__, __LINE__, key_len);
209         CRTCL_SECT_END;
210         return;// -EINVAL;
211     }
212
213     /* let HW pre-process DEcryption key in any case (even if
214        ENcryption is used). Key Valid (KV) bit is then only
215        checked in decryption routine! */
216     aes->controlr.PNK = 1;
217
218
219     aes->controlr.E_D = !encdec;    //encryption
220     aes->controlr.O = mode; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR 
221
222     //aes->controlr.F = 128; //default; only for CFB and OFB modes; change only for customer-specific apps
223     if (mode > 0) {
224         aes->IV3R = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
225         aes->IV2R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
226         aes->IV1R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));
227         aes->IV0R = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));
228     };
229
230
231     i = 0;
232     while (byte_cnt >= 16) {
233
234         aes->ID3R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 0));
235         aes->ID2R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 1));
236         aes->ID1R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 2));
237         aes->ID0R = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + (i * 4) + 3));    /* start crypto */
238         
239         while (aes->controlr.BUS) {
240             // this will not take long
241         }
242
243         *((volatile u32 *) out_arg + (i * 4) + 0) = aes->OD3R;
244         *((volatile u32 *) out_arg + (i * 4) + 1) = aes->OD2R;
245         *((volatile u32 *) out_arg + (i * 4) + 2) = aes->OD1R;
246         *((volatile u32 *) out_arg + (i * 4) + 3) = aes->OD0R;
247
248         i++;
249         byte_cnt -= 16;
250     }
251
252
253     //tc.chen : copy iv_arg back
254     if (mode > 0) {
255         *((u32 *) iv_arg) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg));
256         *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));             
257         *((u32 *) iv_arg + 2) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 2));             
258         *((u32 *) iv_arg + 3) = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 3));              
259     }
260
261     CRTCL_SECT_END;
262 }
263
264 /*!
265  *  \fn int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
266  *  \ingroup IFX_AES_FUNCTIONS
267  *  \brief sets RFC3686 key   
268  *  \param tfm linux crypto algo transform  
269  *  \param in_key input key  
270  *  \param key_len key lengths of 20, 28 and 36 bytes supported; last 4 bytes is nonce 
271  *  \return 0 - SUCCESS
272  *          -EINVAL - bad key length
273 */                                 
274 int ctr_rfc3686_aes_set_key (struct crypto_tfm *tfm, const uint8_t *in_key, unsigned int key_len)
275 {
276     struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
277     unsigned long *flags = (unsigned long *)&tfm->crt_flags;
278
279     //printk("ctr_rfc3686_aes_set_key in %s\n", __FILE__);
280
281     memcpy(ctx->nonce, in_key + (key_len - CTR_RFC3686_NONCE_SIZE),
282            CTR_RFC3686_NONCE_SIZE);
283
284     key_len -= CTR_RFC3686_NONCE_SIZE; // remove 4 bytes of nonce
285
286     if (key_len != 16 && key_len != 24 && key_len != 32) {
287         *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
288         return -EINVAL;
289     }
290
291     ctx->key_length = key_len;
292     
293     memcpy ((u8 *) (ctx->buf), in_key, key_len);
294
295     return 0;
296 }
297
298 /*! \fn void ifx_deu_aes (void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
299  *  \ingroup IFX_AES_FUNCTIONS
300  *  \brief main interface with deu hardware in DMA mode
301  *  \param ctx_arg crypto algo context 
302  *  \param out_arg output bytestream   
303  *  \param in_arg input bytestream   
304  *  \param iv_arg initialization vector  
305  *  \param nbytes length of bytestream  
306  *  \param encdec 1 for encrypt; 0 for decrypt  
307  *  \param mode operation mode such as ebc, cbc, ctr  
308 */
309
310
311 //definitions from linux/include/crypto.h:
312 //#define CRYPTO_TFM_MODE_ECB       0x00000001
313 //#define CRYPTO_TFM_MODE_CBC       0x00000002
314 //#define CRYPTO_TFM_MODE_CFB       0x00000004
315 //#define CRYPTO_TFM_MODE_CTR       0x00000008
316 //#define CRYPTO_TFM_MODE_OFB       0x00000010 // not even defined
317 //but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
318
319 /*! \fn void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
320  *  \ingroup IFX_AES_FUNCTIONS
321  *  \brief sets AES hardware to ECB mode   
322  *  \param ctx crypto algo context  
323  *  \param dst output bytestream  
324  *  \param src input bytestream  
325  *  \param iv initialization vector   
326  *  \param nbytes length of bytestream  
327  *  \param encdec 1 for encrypt; 0 for decrypt  
328  *  \param inplace not used  
329 */                                 
330 void ifx_deu_aes_ecb (void *ctx, uint8_t *dst, const uint8_t *src,
331         uint8_t *iv, size_t nbytes, int encdec, int inplace)
332 {
333      ifx_deu_aes (ctx, dst, src, NULL, nbytes, encdec, 0);
334 }
335
336 /*! \fn void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
337  *  \ingroup IFX_AES_FUNCTIONS
338  *  \brief sets AES hardware to CBC mode   
339  *  \param ctx crypto algo context  
340  *  \param dst output bytestream  
341  *  \param src input bytestream  
342  *  \param iv initialization vector   
343  *  \param nbytes length of bytestream  
344  *  \param encdec 1 for encrypt; 0 for decrypt  
345  *  \param inplace not used  
346 */                                 
347 void ifx_deu_aes_cbc (void *ctx, uint8_t *dst, const uint8_t *src,
348         uint8_t *iv, size_t nbytes, int encdec, int inplace)
349 {
350      ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 1);
351 }
352
353 /*! \fn void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
354  *  \ingroup IFX_AES_FUNCTIONS
355  *  \brief sets AES hardware to OFB mode   
356  *  \param ctx crypto algo context  
357  *  \param dst output bytestream  
358  *  \param src input bytestream  
359  *  \param iv initialization vector   
360  *  \param nbytes length of bytestream  
361  *  \param encdec 1 for encrypt; 0 for decrypt  
362  *  \param inplace not used  
363 */                                 
364 void ifx_deu_aes_ofb (void *ctx, uint8_t *dst, const uint8_t *src,
365         uint8_t *iv, size_t nbytes, int encdec, int inplace)
366 {
367      ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 2);
368 }
369
370 /*! \fn void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
371  *  \ingroup IFX_AES_FUNCTIONS
372  *  \brief sets AES hardware to CFB mode   
373  *  \param ctx crypto algo context  
374  *  \param dst output bytestream  
375  *  \param src input bytestream  
376  *  \param iv initialization vector   
377  *  \param nbytes length of bytestream  
378  *  \param encdec 1 for encrypt; 0 for decrypt  
379  *  \param inplace not used  
380 */                                 
381 void ifx_deu_aes_cfb (void *ctx, uint8_t *dst, const uint8_t *src,
382         uint8_t *iv, size_t nbytes, int encdec, int inplace)
383 {
384      ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 3);
385 }
386
387 /*! \fn void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src, uint8_t *iv, size_t nbytes, int encdec, int inplace)
388  *  \ingroup IFX_AES_FUNCTIONS
389  *  \brief sets AES hardware to CTR mode   
390  *  \param ctx crypto algo context  
391  *  \param dst output bytestream  
392  *  \param src input bytestream  
393  *  \param iv initialization vector   
394  *  \param nbytes length of bytestream  
395  *  \param encdec 1 for encrypt; 0 for decrypt  
396  *  \param inplace not used  
397 */                                 
398 void ifx_deu_aes_ctr (void *ctx, uint8_t *dst, const uint8_t *src,
399         uint8_t *iv, size_t nbytes, int encdec, int inplace)
400 {
401      ifx_deu_aes (ctx, dst, src, iv, nbytes, encdec, 4);
402 }
403
404 /*! \fn void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
405  *  \ingroup IFX_AES_FUNCTIONS
406  *  \brief encrypt AES_BLOCK_SIZE of data   
407  *  \param tfm linux crypto algo transform  
408  *  \param out output bytestream  
409  *  \param in input bytestream  
410 */                                 
411 void aes_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
412 {
413     struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
414     ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
415             CRYPTO_DIR_ENCRYPT, 0);
416 }
417
418 /*! \fn void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
419  *  \ingroup IFX_AES_FUNCTIONS
420  *  \brief decrypt AES_BLOCK_SIZE of data   
421  *  \param tfm linux crypto algo transform  
422  *  \param out output bytestream  
423  *  \param in input bytestream  
424 */                                 
425 void aes_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
426 {
427     struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
428     ifx_deu_aes (ctx, out, in, NULL, AES_BLOCK_SIZE,
429             CRYPTO_DIR_DECRYPT, 0);
430 }
431
432 /* 
433  * \brief AES function mappings 
434 */
435 struct crypto_alg ifxdeu_aes_alg = {
436     .cra_name       =   "aes",
437     .cra_driver_name    =   "ifxdeu-aes",
438     .cra_flags      =   CRYPTO_ALG_TYPE_CIPHER,
439     .cra_blocksize      =   AES_BLOCK_SIZE,
440     .cra_ctxsize        =   sizeof(struct aes_ctx),
441     .cra_module     =   THIS_MODULE,
442     .cra_list       =   LIST_HEAD_INIT(ifxdeu_aes_alg.cra_list),
443     .cra_u          =   {
444         .cipher = {
445             .cia_min_keysize    =   AES_MIN_KEY_SIZE,
446             .cia_max_keysize    =   AES_MAX_KEY_SIZE,
447             .cia_setkey     =   aes_set_key,
448             .cia_encrypt        =   aes_encrypt,
449             .cia_decrypt        =   aes_decrypt,
450         }
451     }
452 };
453
454 /*! \fn int ecb_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
455  *  \ingroup IFX_AES_FUNCTIONS
456  *  \brief ECB AES encrypt using linux crypto blkcipher    
457  *  \param desc blkcipher descriptor  
458  *  \param dst output scatterlist  
459  *  \param src input scatterlist  
460  *  \param nbytes data size in bytes  
461  *  \return err
462 */                                 
463 int ecb_aes_encrypt(struct blkcipher_desc *desc,
464                struct scatterlist *dst, struct scatterlist *src,
465                unsigned int nbytes)
466 {
467     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
468     struct blkcipher_walk walk;
469     int err;
470     
471     blkcipher_walk_init(&walk, dst, src, nbytes);
472     err = blkcipher_walk_virt(desc, &walk);
473
474     while ((nbytes = walk.nbytes)) {
475             nbytes -= (nbytes % AES_BLOCK_SIZE); 
476         ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
477                        NULL, nbytes, CRYPTO_DIR_ENCRYPT, 0);
478                 nbytes &= AES_BLOCK_SIZE - 1;
479         err = blkcipher_walk_done(desc, &walk, nbytes);
480     }
481
482     return err;
483 }
484
485 /*! \fn int ecb_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
486  *  \ingroup IFX_AES_FUNCTIONS
487  *  \brief ECB AES decrypt using linux crypto blkcipher    
488  *  \param desc blkcipher descriptor  
489  *  \param dst output scatterlist  
490  *  \param src input scatterlist  
491  *  \param nbytes data size in bytes  
492  *  \return err
493 */                                 
494 int ecb_aes_decrypt(struct blkcipher_desc *desc,
495                struct scatterlist *dst, struct scatterlist *src,
496                unsigned int nbytes)
497 {
498     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
499     struct blkcipher_walk walk;
500     int err;
501
502     blkcipher_walk_init(&walk, dst, src, nbytes);
503     err = blkcipher_walk_virt(desc, &walk);
504
505     while ((nbytes = walk.nbytes)) {
506             nbytes -= (nbytes % AES_BLOCK_SIZE); 
507         ifx_deu_aes_ecb(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
508                        NULL, nbytes, CRYPTO_DIR_DECRYPT, 0);
509         nbytes &= AES_BLOCK_SIZE - 1;
510         err = blkcipher_walk_done(desc, &walk, nbytes);
511     }
512
513     return err;
514 }
515
516 /* 
517  * \brief AES function mappings
518 */
519 struct crypto_alg ifxdeu_ecb_aes_alg = {
520     .cra_name       =   "ecb(aes)",
521     .cra_driver_name    =   "ifxdeu-ecb(aes)",
522     .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
523     .cra_blocksize      =   AES_BLOCK_SIZE,
524     .cra_ctxsize        =   sizeof(struct aes_ctx),
525     .cra_type       =   &crypto_blkcipher_type,
526     .cra_module     =   THIS_MODULE,
527     .cra_list       =   LIST_HEAD_INIT(ifxdeu_ecb_aes_alg.cra_list),
528     .cra_u          =   {
529         .blkcipher = {
530             .min_keysize        =   AES_MIN_KEY_SIZE,
531             .max_keysize        =   AES_MAX_KEY_SIZE,
532             .setkey         =   aes_set_key,
533             .encrypt        =   ecb_aes_encrypt,
534             .decrypt        =   ecb_aes_decrypt,
535         }
536     }
537 };
538
539
540 /*! \fn int cbc_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
541  *  \ingroup IFX_AES_FUNCTIONS
542  *  \brief CBC AES encrypt using linux crypto blkcipher    
543  *  \param desc blkcipher descriptor  
544  *  \param dst output scatterlist  
545  *  \param src input scatterlist  
546  *  \param nbytes data size in bytes  
547  *  \return err
548 */                                 
549 int cbc_aes_encrypt(struct blkcipher_desc *desc,
550                struct scatterlist *dst, struct scatterlist *src,
551                unsigned int nbytes)
552 {
553     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
554     struct blkcipher_walk walk;
555     int err;
556
557     blkcipher_walk_init(&walk, dst, src, nbytes);
558     err = blkcipher_walk_virt(desc, &walk);
559
560     while ((nbytes = walk.nbytes)) {
561             u8 *iv = walk.iv;
562             nbytes -= (nbytes % AES_BLOCK_SIZE);            
563             ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
564                        iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
565         nbytes &= AES_BLOCK_SIZE - 1;
566         err = blkcipher_walk_done(desc, &walk, nbytes);
567     }
568
569     return err;
570 }
571
572 /*! \fn int cbc_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
573  *  \ingroup IFX_AES_FUNCTIONS
574  *  \brief CBC AES decrypt using linux crypto blkcipher    
575  *  \param desc blkcipher descriptor  
576  *  \param dst output scatterlist  
577  *  \param src input scatterlist  
578  *  \param nbytes data size in bytes  
579  *  \return err
580 */                                 
581 int cbc_aes_decrypt(struct blkcipher_desc *desc,
582                struct scatterlist *dst, struct scatterlist *src,
583                unsigned int nbytes)
584 {
585     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
586     struct blkcipher_walk walk;
587     int err;
588
589     blkcipher_walk_init(&walk, dst, src, nbytes);
590     err = blkcipher_walk_virt(desc, &walk);
591
592     while ((nbytes = walk.nbytes)) {
593         u8 *iv = walk.iv;
594             nbytes -= (nbytes % AES_BLOCK_SIZE);        
595             ifx_deu_aes_cbc(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
596                        iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
597         nbytes &= AES_BLOCK_SIZE - 1;
598         err = blkcipher_walk_done(desc, &walk, nbytes);
599     }
600
601     return err;
602 }
603
604 /*
605  * \brief AES function mappings
606 */
607 struct crypto_alg ifxdeu_cbc_aes_alg = {
608     .cra_name       =   "cbc(aes)",
609     .cra_driver_name    =   "ifxdeu-cbc(aes)",
610     .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
611     .cra_blocksize      =   AES_BLOCK_SIZE,
612     .cra_ctxsize        =   sizeof(struct aes_ctx),
613     .cra_type       =   &crypto_blkcipher_type,
614     .cra_module     =   THIS_MODULE,
615     .cra_list       =   LIST_HEAD_INIT(ifxdeu_cbc_aes_alg.cra_list),
616     .cra_u          =   {
617         .blkcipher = {
618             .min_keysize        =   AES_MIN_KEY_SIZE,
619             .max_keysize        =   AES_MAX_KEY_SIZE,
620             .ivsize         =   AES_BLOCK_SIZE,
621             .setkey         =   aes_set_key,
622             .encrypt        =   cbc_aes_encrypt,
623             .decrypt        =   cbc_aes_decrypt,
624         }
625     }
626 };
627
628
629 /*! \fn int ctr_basic_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
630  *  \ingroup IFX_AES_FUNCTIONS
631  *  \brief Counter mode AES encrypt using linux crypto blkcipher    
632  *  \param desc blkcipher descriptor  
633  *  \param dst output scatterlist  
634  *  \param src input scatterlist  
635  *  \param nbytes data size in bytes  
636  *  \return err
637 */                                 
638 int ctr_basic_aes_encrypt(struct blkcipher_desc *desc,
639                struct scatterlist *dst, struct scatterlist *src,
640                unsigned int nbytes)
641 {
642     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
643     struct blkcipher_walk walk;
644     int err;
645
646     blkcipher_walk_init(&walk, dst, src, nbytes);
647     err = blkcipher_walk_virt(desc, &walk);
648
649     while ((nbytes = walk.nbytes)) {
650             u8 *iv = walk.iv;
651             nbytes -= (nbytes % AES_BLOCK_SIZE);            
652             ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
653                        iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
654         nbytes &= AES_BLOCK_SIZE - 1;
655         err = blkcipher_walk_done(desc, &walk, nbytes);
656     }
657
658     return err;
659 }
660
661 /*! \fn  int ctr_basic_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
662  *  \ingroup IFX_AES_FUNCTIONS
663  *  \brief Counter mode AES decrypt using linux crypto blkcipher    
664  *  \param desc blkcipher descriptor  
665  *  \param dst output scatterlist  
666  *  \param src input scatterlist  
667  *  \param nbytes data size in bytes  
668  *  \return err
669 */                                 
670 int ctr_basic_aes_decrypt(struct blkcipher_desc *desc,
671                struct scatterlist *dst, struct scatterlist *src,
672                unsigned int nbytes)
673 {
674     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
675     struct blkcipher_walk walk;
676     int err;
677
678     blkcipher_walk_init(&walk, dst, src, nbytes);
679     err = blkcipher_walk_virt(desc, &walk);
680
681     while ((nbytes = walk.nbytes)) {
682         u8 *iv = walk.iv;
683             nbytes -= (nbytes % AES_BLOCK_SIZE);        
684             ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
685                        iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
686         nbytes &= AES_BLOCK_SIZE - 1;
687         err = blkcipher_walk_done(desc, &walk, nbytes);
688     }
689
690     return err;
691 }
692
693 /* 
694  * \brief AES function mappings
695 */
696 struct crypto_alg ifxdeu_ctr_basic_aes_alg = {
697     .cra_name       =   "ctr(aes)",
698     .cra_driver_name    =   "ifxdeu-ctr(aes)",
699     .cra_flags      =   CRYPTO_ALG_TYPE_BLKCIPHER,
700     .cra_blocksize      =   AES_BLOCK_SIZE,
701     .cra_ctxsize        =   sizeof(struct aes_ctx),
702     .cra_type       =   &crypto_blkcipher_type,
703     .cra_module     =   THIS_MODULE,
704     .cra_list       =   LIST_HEAD_INIT(ifxdeu_ctr_basic_aes_alg.cra_list),
705     .cra_u          =   {
706         .blkcipher = {
707             .min_keysize        =   AES_MIN_KEY_SIZE,
708             .max_keysize        =   AES_MAX_KEY_SIZE,
709             .ivsize         =   AES_BLOCK_SIZE,
710             .setkey         =   aes_set_key,
711             .encrypt        =   ctr_basic_aes_encrypt,
712             .decrypt        =   ctr_basic_aes_decrypt,
713         }
714     }
715 };
716
717
718 /*! \fn  int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
719  *  \ingroup IFX_AES_FUNCTIONS
720  *  \brief Counter mode AES (rfc3686) encrypt using linux crypto blkcipher    
721  *  \param desc blkcipher descriptor  
722  *  \param dst output scatterlist  
723  *  \param src input scatterlist  
724  *  \param nbytes data size in bytes  
725  *  \return err
726 */                                 
727 int ctr_rfc3686_aes_encrypt(struct blkcipher_desc *desc,
728                struct scatterlist *dst, struct scatterlist *src,
729                unsigned int nbytes)
730 {
731     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
732     struct blkcipher_walk walk;
733     int err;
734     u8 rfc3686_iv[16];
735
736     blkcipher_walk_init(&walk, dst, src, nbytes);
737     err = blkcipher_walk_virt(desc, &walk);
738     
739     /* set up counter block */
740     memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 
741     memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
742
743     /* initialize counter portion of counter block */
744     *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
745         cpu_to_be32(1);
746
747     while ((nbytes = walk.nbytes)) {
748             nbytes -= (nbytes % AES_BLOCK_SIZE);            
749             ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
750                        rfc3686_iv, nbytes, CRYPTO_DIR_ENCRYPT, 0);  
751         nbytes &= AES_BLOCK_SIZE - 1;
752         err = blkcipher_walk_done(desc, &walk, nbytes);
753     }
754    
755     return err;
756 }
757
758 /*! \fn int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes)
759  *  \ingroup IFX_AES_FUNCTIONS
760  *  \brief Counter mode AES (rfc3686) decrypt using linux crypto blkcipher    
761  *  \param desc blkcipher descriptor  
762  *  \param dst output scatterlist  
763  *  \param src input scatterlist  
764  *  \param nbytes data size in bytes  
765  *  \return err
766 */                                 
767 int ctr_rfc3686_aes_decrypt(struct blkcipher_desc *desc,
768                struct scatterlist *dst, struct scatterlist *src,
769                unsigned int nbytes)
770 {
771     struct aes_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
772     struct blkcipher_walk walk;
773     int err;
774     u8 rfc3686_iv[16];
775
776     blkcipher_walk_init(&walk, dst, src, nbytes);
777     err = blkcipher_walk_virt(desc, &walk);
778
779     /* set up counter block */
780     memcpy(rfc3686_iv, ctx->nonce, CTR_RFC3686_NONCE_SIZE); 
781     memcpy(rfc3686_iv + CTR_RFC3686_NONCE_SIZE, walk.iv, CTR_RFC3686_IV_SIZE);
782
783     /* initialize counter portion of counter block */
784     *(__be32 *)(rfc3686_iv + CTR_RFC3686_NONCE_SIZE + CTR_RFC3686_IV_SIZE) =
785         cpu_to_be32(1);
786
787     while ((nbytes = walk.nbytes)) {
788             nbytes -= (nbytes % AES_BLOCK_SIZE);        
789             ifx_deu_aes_ctr(ctx, walk.dst.virt.addr, walk.src.virt.addr, 
790                        rfc3686_iv, nbytes, CRYPTO_DIR_DECRYPT, 0);
791         nbytes &= AES_BLOCK_SIZE - 1;
792         err = blkcipher_walk_done(desc, &walk, nbytes);
793     }
794
795     return err;
796 }
797
798 /* 
799  * \brief AES function mappings
800 */
801 struct crypto_alg ifxdeu_ctr_rfc3686_aes_alg = {
802     .cra_name           =   "rfc3686(ctr(aes))",
803     .cra_driver_name    =   "ifxdeu-ctr-rfc3686(aes)",
804     .cra_flags          =   CRYPTO_ALG_TYPE_BLKCIPHER,
805     .cra_blocksize      =   AES_BLOCK_SIZE,
806     .cra_ctxsize        =   sizeof(struct aes_ctx),
807     .cra_type           =   &crypto_blkcipher_type,
808     .cra_module         =   THIS_MODULE,
809     .cra_list           =   LIST_HEAD_INIT(ifxdeu_ctr_rfc3686_aes_alg.cra_list),
810     .cra_u          =   {
811         .blkcipher = {
812             .min_keysize        =   AES_MIN_KEY_SIZE,
813             .max_keysize        =   CTR_RFC3686_MAX_KEY_SIZE,
814             .ivsize         =   CTR_RFC3686_IV_SIZE,
815             .setkey         =   ctr_rfc3686_aes_set_key,
816             .encrypt        =   ctr_rfc3686_aes_encrypt,
817             .decrypt        =   ctr_rfc3686_aes_decrypt,
818         }
819     }
820 };
821
822
823 /*! \fn int __init ifxdeu_init_aes (void)
824  *  \ingroup IFX_AES_FUNCTIONS
825  *  \brief function to initialize AES driver   
826  *  \return ret 
827 */                                 
828 int __init ifxdeu_init_aes (void)
829 {
830     int ret = -ENOSYS;
831
832
833  
834 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
835     if (!disable_multiblock) {
836         ifxdeu_aes_alg.cra_u.cipher.cia_max_nbytes = AES_BLOCK_SIZE;    //(size_t)-1;
837         ifxdeu_aes_alg.cra_u.cipher.cia_req_align = 16;
838         ifxdeu_aes_alg.cra_u.cipher.cia_ecb = ifx_deu_aes_ecb;
839         ifxdeu_aes_alg.cra_u.cipher.cia_cbc = ifx_deu_aes_cbc;
840         ifxdeu_aes_alg.cra_u.cipher.cia_cfb = ifx_deu_aes_cfb;
841         ifxdeu_aes_alg.cra_u.cipher.cia_ofb = ifx_deu_aes_ofb;
842     }
843 #endif
844
845     if ((ret = crypto_register_alg(&ifxdeu_aes_alg)))
846         goto aes_err;
847
848     if ((ret = crypto_register_alg(&ifxdeu_ecb_aes_alg)))
849         goto ecb_aes_err;
850
851     if ((ret = crypto_register_alg(&ifxdeu_cbc_aes_alg)))
852         goto cbc_aes_err;
853
854     if ((ret = crypto_register_alg(&ifxdeu_ctr_basic_aes_alg)))
855         goto ctr_basic_aes_err;
856
857     if ((ret = crypto_register_alg(&ifxdeu_ctr_rfc3686_aes_alg)))
858         goto ctr_rfc3686_aes_err;
859
860     aes_chip_init ();
861
862     CRTCL_SECT_INIT;
863
864
865     printk (KERN_NOTICE "IFX DEU AES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
866     return ret;
867
868 ctr_rfc3686_aes_err:
869     crypto_unregister_alg(&ifxdeu_ctr_rfc3686_aes_alg);
870     printk (KERN_ERR "IFX ctr_rfc3686_aes initialization failed!\n");
871     return ret;
872 ctr_basic_aes_err:
873     crypto_unregister_alg(&ifxdeu_ctr_basic_aes_alg);
874     printk (KERN_ERR "IFX ctr_basic_aes initialization failed!\n");
875     return ret;
876 cbc_aes_err:
877     crypto_unregister_alg(&ifxdeu_cbc_aes_alg);
878     printk (KERN_ERR "IFX cbc_aes initialization failed!\n");
879     return ret;
880 ecb_aes_err:
881     crypto_unregister_alg(&ifxdeu_ecb_aes_alg);
882     printk (KERN_ERR "IFX aes initialization failed!\n");
883     return ret;
884 aes_err:
885     printk(KERN_ERR "IFX DEU AES initialization failed!\n");
886
887     return ret;
888 }
889
890 /*! \fn void __exit ifxdeu_fini_aes (void)
891  *  \ingroup IFX_AES_FUNCTIONS
892  *  \brief unregister aes driver   
893 */                                 
894 void __exit ifxdeu_fini_aes (void)
895 {
896     crypto_unregister_alg (&ifxdeu_aes_alg);
897     crypto_unregister_alg (&ifxdeu_ecb_aes_alg);
898     crypto_unregister_alg (&ifxdeu_cbc_aes_alg);
899     crypto_unregister_alg (&ifxdeu_ctr_basic_aes_alg);
900     crypto_unregister_alg (&ifxdeu_ctr_rfc3686_aes_alg);
901
902 }
903
904