1 /******************************************************************************
3 ** FILE NAME : ifxmips_des.c
5 ** MODULES : DEU Module
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
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.
20 ** $Date $Author $Comment
21 ** 08 Sept 2009 Mohammad Firdaus Initial UEIP release
22 *******************************************************************************/
25 \defgroup IFX_DEU IFX_DEU_DRIVERS
33 \brief DES encryption DEU driver file
37 \defgroup IFX_DES_FUNCTIONS IFX_DES_FUNCTIONS
39 \brief IFX DES Encryption functions
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 <crypto/des.h>
54 #include <crypto/internal/skcipher.h>
55 #include "ifxmips_deu.h"
57 #if defined(CONFIG_DANUBE)
58 #include "ifxmips_deu_danube.h"
59 extern int ifx_danube_pre_1_4
;
60 #elif defined(CONFIG_AR9)
61 #include "ifxmips_deu_ar9.h"
62 #elif defined(CONFIG_VR9) || defined(CONFIG_AR10)
63 #include "ifxmips_deu_vr9.h"
65 #error "Unkown platform"
68 /* DMA specific header and variables */
71 #define CRTCL_SECT_INIT
72 #define CRTCL_SECT_START
73 #define CRTCL_SECT_END
76 #define CRTCL_SECT_INIT spin_lock_init(&des_lock)
77 #define CRTCL_SECT_START spin_lock_irqsave(&des_lock, flag)
78 #define CRTCL_SECT_END spin_unlock_irqrestore(&des_lock, flag)
81 /* Preprocessor declerations */
83 extern char debug_level
;
84 #define DPRINTF(level, format, args...) if (level < debug_level) printk(KERN_INFO "[%s %s %d]: " format, __FILE__, __func__, __LINE__, ##args);
86 #define DPRINTF(level, format, args...)
88 #define DES_3DES_START IFX_DES_CON
89 #define DES_KEY_SIZE 8
90 #define DES_EXPKEY_WORDS 32
91 #define DES_BLOCK_SIZE 8
92 #define DES3_EDE_KEY_SIZE (3 * DES_KEY_SIZE)
93 #define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS)
94 #define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE
96 /* Function Declaration to prevent warning messages */
97 void des_chip_init (void);
98 u32
endian_swap(u32 input
);
99 u32
input_swap(u32 input
);
100 int aes_memory_allocate(int value
);
101 int des_memory_allocate(int value
);
102 void memory_release(u32
*buffer
);
103 u32
* memory_alignment(const u8
*arg
, u32
*buff_alloc
, int in_out
, int nbytes
);
104 void aes_dma_memory_copy(u32
*outcopy
, u32
*out_dma
, u8
*out_arg
, int nbytes
);
105 void des_dma_memory_copy(u32
*outcopy
, u32
*out_dma
, u8
*out_arg
, int nbytes
);
107 void ifx_deu_des (void *ctx_arg
, u8
*out_arg
, const u8
*in_arg
,
108 u8
*iv_arg
, u32 nbytes
, int encdec
, int mode
);
110 struct ifx_deu_des_ctx
{
113 u8 iv
[DES_BLOCK_SIZE
];
114 u32 expkey
[DES3_EDE_EXPKEY_WORDS
];
115 struct des_ctx des_context
;
116 struct des3_ede_ctx des3_ede_context
;
119 extern int disable_multiblock
;
120 extern int disable_deudma
;
123 /*! \fn int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
124 * \ingroup IFX_DES_FUNCTIONS
125 * \brief sets DES key
126 * \param tfm linux crypto algo transform
127 * \param key input key
128 * \param keylen key length
130 int des_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
133 struct ifx_deu_des_ctx
*dctx
= crypto_tfm_ctx(tfm
);
136 //printk("setkey in %s\n", __FILE__);
138 err
= des_expand_key(&dctx
->des_context
, key
, keylen
);
139 if (err
== -ENOKEY
) {
140 if (crypto_tfm_get_flags(tfm
) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS
)
146 dctx
->controlr_M
= 0; // des
147 dctx
->key_length
= keylen
;
149 memcpy ((u8
*) (dctx
->expkey
), key
, keylen
);
152 memset(dctx
, 0, sizeof(*dctx
));
158 /*! \fn int des_setkey_skcipher (struct crypto_skcipher *tfm, const uint8_t *in_key, unsigned int key_len)
159 * \ingroup IFX_AES_FUNCTIONS
160 * \brief sets the AES keys for skcipher
161 * \param tfm linux crypto skcipher
162 * \param in_key input key
163 * \param key_len key lengths of 16, 24 and 32 bytes supported
164 * \return -EINVAL - bad key length, 0 - SUCCESS
166 int des_setkey_skcipher (struct crypto_skcipher
*tfm
, const u8
*in_key
, unsigned int key_len
)
168 return des_setkey(crypto_skcipher_tfm(tfm
), in_key
, key_len
);
172 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
173 * \ingroup IFX_DES_FUNCTIONS
174 * \brief main interface to DES hardware
175 * \param ctx_arg crypto algo context
176 * \param out_arg output bytestream
177 * \param in_arg input bytestream
178 * \param iv_arg initialization vector
179 * \param nbytes length of bytestream
180 * \param encdec 1 for encrypt; 0 for decrypt
181 * \param mode operation mode such as ebc, cbc
184 void ifx_deu_des (void *ctx_arg
, u8
*out_arg
, const u8
*in_arg
,
185 u8
*iv_arg
, u32 nbytes
, int encdec
, int mode
)
187 volatile struct des_t
*des
= (struct des_t
*) DES_3DES_START
;
188 struct ifx_deu_des_ctx
*dctx
= ctx_arg
;
189 u32
*key
= dctx
->expkey
;
197 des
->controlr
.M
= dctx
->controlr_M
;
198 if (dctx
->controlr_M
== 0) // des
200 des
->K1HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 0));
201 des
->K1LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 1));
205 /* Hardware Section */
206 switch (dctx
->key_length
) {
208 des
->K3HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 4));
209 des
->K3LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 5));
213 des
->K2HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 2));
214 des
->K2LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 3));
218 des
->K1HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 0));
219 des
->K1LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 1));
228 des
->controlr
.E_D
= !encdec
; //encryption
229 des
->controlr
.O
= mode
; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
232 des
->IVHR
= DEU_ENDIAN_SWAP(*(u32
*) iv_arg
);
233 des
->IVLR
= DEU_ENDIAN_SWAP(*((u32
*) iv_arg
+ 1));
236 nblocks
= nbytes
/ 4;
238 for (i
= 0; i
< nblocks
; i
+= 2) {
239 /* wait for busy bit to clear */
241 /*--- Workaround ----------------------------------------------------
242 do a dummy read to the busy flag because it is not raised early
243 enough in CFB/OFB 3DES modes */
245 printk ("ihr: %x\n", (*((u32
*) in_arg
+ i
)));
246 printk ("ilr: %x\n", (*((u32
*) in_arg
+ 1 + i
)));
248 des
->IHR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ i
));
249 des
->ILR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ 1 + i
)); /* start crypto */
251 while (des
->controlr
.BUS
) {
252 // this will not take long
255 *((u32
*) out_arg
+ 0 + i
) = des
->OHR
;
256 *((u32
*) out_arg
+ 1 + i
) = des
->OLR
;
263 *(u32
*) iv_arg
= DEU_ENDIAN_SWAP(des
->IVHR
);
264 *((u32
*) iv_arg
+ 1) = DEU_ENDIAN_SWAP(des
->IVLR
);
270 //definitions from linux/include/crypto.h:
271 //#define CRYPTO_TFM_MODE_ECB 0x00000001
272 //#define CRYPTO_TFM_MODE_CBC 0x00000002
273 //#define CRYPTO_TFM_MODE_CFB 0x00000004
274 //#define CRYPTO_TFM_MODE_CTR 0x00000008
275 //#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
276 //but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
278 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
279 * \ingroup IFX_DES_FUNCTIONS
280 * \brief main interface to DES hardware
281 * \param ctx_arg crypto algo context
282 * \param out_arg output bytestream
283 * \param in_arg input bytestream
284 * \param iv_arg initialization vector
285 * \param nbytes length of bytestream
286 * \param encdec 1 for encrypt; 0 for decrypt
287 * \param mode operation mode such as ebc, cbc
292 /*! \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)
293 * \ingroup IFX_DES_FUNCTIONS
294 * \brief sets DES hardware to ECB mode
295 * \param ctx crypto algo context
296 * \param dst output bytestream
297 * \param src input bytestream
298 * \param iv initialization vector
299 * \param nbytes length of bytestream
300 * \param encdec 1 for encrypt; 0 for decrypt
301 * \param inplace not used
304 void ifx_deu_des_ecb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
305 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
307 ifx_deu_des (ctx
, dst
, src
, NULL
, nbytes
, encdec
, 0);
310 /*! \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)
311 * \ingroup IFX_DES_FUNCTIONS
312 * \brief sets DES hardware to CBC mode
313 * \param ctx crypto algo context
314 * \param dst output bytestream
315 * \param src input bytestream
316 * \param iv initialization vector
317 * \param nbytes length of bytestream
318 * \param encdec 1 for encrypt; 0 for decrypt
319 * \param inplace not used
321 void ifx_deu_des_cbc (void *ctx
, uint8_t *dst
, const uint8_t *src
,
322 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
324 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 1);
327 /*! \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)
328 * \ingroup IFX_DES_FUNCTIONS
329 * \brief sets DES hardware to OFB mode
330 * \param ctx crypto algo context
331 * \param dst output bytestream
332 * \param src input bytestream
333 * \param iv initialization vector
334 * \param nbytes length of bytestream
335 * \param encdec 1 for encrypt; 0 for decrypt
336 * \param inplace not used
338 void ifx_deu_des_ofb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
339 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
341 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 2);
344 /*! \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)
345 \ingroup IFX_DES_FUNCTIONS
346 \brief sets DES hardware to CFB mode
347 \param ctx crypto algo context
348 \param dst output bytestream
349 \param src input bytestream
350 \param iv initialization vector
351 \param nbytes length of bytestream
352 \param encdec 1 for encrypt; 0 for decrypt
353 \param inplace not used
355 void ifx_deu_des_cfb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
356 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
358 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 3);
361 /*! \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)
362 * \ingroup IFX_DES_FUNCTIONS
363 * \brief sets DES hardware to CTR mode
364 * \param ctx crypto algo context
365 * \param dst output bytestream
366 * \param src input bytestream
367 * \param iv initialization vector
368 * \param nbytes length of bytestream
369 * \param encdec 1 for encrypt; 0 for decrypt
370 * \param inplace not used
372 void ifx_deu_des_ctr (void *ctx
, uint8_t *dst
, const uint8_t *src
,
373 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
375 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 4);
378 /*! \fn void ifx_deu_des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
379 * \ingroup IFX_DES_FUNCTIONS
380 * \brief encrypt DES_BLOCK_SIZE of data
381 * \param tfm linux crypto algo transform
382 * \param out output bytestream
383 * \param in input bytestream
385 void ifx_deu_des_encrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
387 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
388 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
389 CRYPTO_DIR_ENCRYPT
, 0);
393 /*! \fn void ifx_deu_des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
394 * \ingroup IFX_DES_FUNCTIONS
395 * \brief encrypt DES_BLOCK_SIZE of data
396 * \param tfm linux crypto algo transform
397 * \param out output bytestream
398 * \param in input bytestream
400 void ifx_deu_des_decrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
402 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
403 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
404 CRYPTO_DIR_DECRYPT
, 0);
410 * For DES-EDE3, there is no known need to reject weak or
411 * complementation keys. Any weakness is obviated by the use of
414 * However, if the first two or last two independent 64-bit keys are
415 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
416 * same as DES. Implementers MUST reject keys that exhibit this
421 /*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
422 * \ingroup IFX_DES_FUNCTIONS
423 * \brief sets 3DES key
424 * \param tfm linux crypto algo transform
425 * \param key input key
426 * \param keylen key length
428 int des3_ede_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
431 struct ifx_deu_des_ctx
*dctx
= crypto_tfm_ctx(tfm
);
434 //printk("setkey in %s\n", __FILE__);
436 err
= des3_ede_expand_key(&dctx
->des3_ede_context
, key
, keylen
);
437 if (err
== -ENOKEY
) {
438 if (crypto_tfm_get_flags(tfm
) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS
)
444 dctx
->controlr_M
= keylen
/ 8 + 1; // 3DES EDE1 / EDE2 / EDE3 Mode
445 dctx
->key_length
= keylen
;
447 memcpy ((u8
*) (dctx
->expkey
), key
, keylen
);
450 memset(dctx
, 0, sizeof(*dctx
));
455 /*! \fn int des3_ede_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
456 * \ingroup IFX_DES_FUNCTIONS
457 * \brief sets 3DES key
458 * \param tfm linux crypto skcipher transform
459 * \param key input key
460 * \param keylen key length
462 int des3_ede_setkey_skcipher(struct crypto_skcipher
*tfm
, const u8
*key
,
465 return des3_ede_setkey(crypto_skcipher_tfm(tfm
), key
, keylen
);
469 * \brief DES function mappings
471 struct crypto_alg ifxdeu_des_alg
= {
473 .cra_driver_name
= "ifxdeu-des",
475 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
476 .cra_blocksize
= DES_BLOCK_SIZE
,
477 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
478 .cra_module
= THIS_MODULE
,
480 .cra_list
= LIST_HEAD_INIT(ifxdeu_des_alg
.cra_list
),
481 .cra_u
= { .cipher
= {
482 .cia_min_keysize
= DES_KEY_SIZE
,
483 .cia_max_keysize
= DES_KEY_SIZE
,
484 .cia_setkey
= des_setkey
,
485 .cia_encrypt
= ifx_deu_des_encrypt
,
486 .cia_decrypt
= ifx_deu_des_decrypt
} }
490 * \brief DES function mappings
492 struct crypto_alg ifxdeu_des3_ede_alg
= {
493 .cra_name
= "des3_ede",
494 .cra_driver_name
= "ifxdeu-des3_ede",
496 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
497 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
498 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
499 .cra_module
= THIS_MODULE
,
501 .cra_list
= LIST_HEAD_INIT(ifxdeu_des3_ede_alg
.cra_list
),
502 .cra_u
= { .cipher
= {
503 .cia_min_keysize
= DES3_EDE_KEY_SIZE
,
504 .cia_max_keysize
= DES3_EDE_KEY_SIZE
,
505 .cia_setkey
= des3_ede_setkey
,
506 .cia_encrypt
= ifx_deu_des_encrypt
,
507 .cia_decrypt
= ifx_deu_des_decrypt
} }
510 /*! \fn int ecb_des_encrypt(struct skcipher_req *req)
511 * \ingroup IFX_AES_FUNCTIONS
512 * \brief ECB DES encrypt using linux crypto skcipher
513 * \param req skcipher request
516 int ecb_des_encrypt(struct skcipher_request
*req
)
518 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
519 struct skcipher_walk walk
;
521 unsigned int enc_bytes
, nbytes
;
523 err
= skcipher_walk_virt(&walk
, req
, false);
525 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
526 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
527 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
528 NULL
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
529 nbytes
&= DES_BLOCK_SIZE
- 1;
530 err
= skcipher_walk_done(&walk
, nbytes
);
536 /*! \fn int ecb_des_decrypt(struct skcipher_req *req)
537 * \ingroup IFX_AES_FUNCTIONS
538 * \brief ECB DES decrypt using linux crypto skcipher
539 * \param req skcipher request
542 int ecb_des_decrypt(struct skcipher_request
*req
)
544 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
545 struct skcipher_walk walk
;
547 unsigned int dec_bytes
, nbytes
;
550 err
= skcipher_walk_virt(&walk
, req
, false);
552 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
553 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
554 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
555 NULL
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
556 nbytes
&= DES_BLOCK_SIZE
- 1;
557 err
= skcipher_walk_done(&walk
, nbytes
);
564 * \brief DES function mappings
566 struct skcipher_alg ifxdeu_ecb_des_alg
= {
567 .base
.cra_name
= "ecb(des)",
568 .base
.cra_driver_name
= "ifxdeu-ecb(des)",
569 .base
.cra_priority
= 400,
570 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
571 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
572 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
573 .base
.cra_module
= THIS_MODULE
,
574 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des_alg
.base
.cra_list
),
575 .min_keysize
= DES_KEY_SIZE
,
576 .max_keysize
= DES_KEY_SIZE
,
577 .setkey
= des_setkey_skcipher
,
578 .encrypt
= ecb_des_encrypt
,
579 .decrypt
= ecb_des_decrypt
,
583 * \brief DES function mappings
585 struct skcipher_alg ifxdeu_ecb_des3_ede_alg
= {
586 .base
.cra_name
= "ecb(des3_ede)",
587 .base
.cra_driver_name
= "ifxdeu-ecb(des3_ede)",
588 .base
.cra_priority
= 400,
589 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
590 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
591 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
592 .base
.cra_module
= THIS_MODULE
,
593 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg
.base
.cra_list
),
594 .min_keysize
= DES3_EDE_KEY_SIZE
,
595 .max_keysize
= DES3_EDE_KEY_SIZE
,
596 .setkey
= des3_ede_setkey_skcipher
,
597 .encrypt
= ecb_des_encrypt
,
598 .decrypt
= ecb_des_decrypt
,
601 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
602 * \ingroup IFX_AES_FUNCTIONS
603 * \brief CBC DES encrypt using linux crypto skcipher
604 * \param req skcipher request
607 int cbc_des_encrypt(struct skcipher_request
*req
)
609 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
610 struct skcipher_walk walk
;
612 unsigned int enc_bytes
, nbytes
;
615 err
= skcipher_walk_virt(&walk
, req
, false);
617 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
619 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
620 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
621 iv
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
622 nbytes
&= DES_BLOCK_SIZE
- 1;
623 err
= skcipher_walk_done(&walk
, nbytes
);
629 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
630 * \ingroup IFX_AES_FUNCTIONS
631 * \brief CBC DES decrypt using linux crypto skcipher
632 * \param req skcipher request
635 int cbc_des_decrypt(struct skcipher_request
*req
)
637 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
638 struct skcipher_walk walk
;
640 unsigned int dec_bytes
, nbytes
;
643 err
= skcipher_walk_virt(&walk
, req
, false);
645 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
647 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
648 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
649 iv
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
650 nbytes
&= DES_BLOCK_SIZE
- 1;
651 err
= skcipher_walk_done(&walk
, nbytes
);
658 * \brief DES function mappings
660 struct skcipher_alg ifxdeu_cbc_des_alg
= {
661 .base
.cra_name
= "cbc(des)",
662 .base
.cra_driver_name
= "ifxdeu-cbc(des)",
663 .base
.cra_priority
= 400,
664 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
665 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
666 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
667 .base
.cra_module
= THIS_MODULE
,
668 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des_alg
.base
.cra_list
),
669 .min_keysize
= DES_KEY_SIZE
,
670 .max_keysize
= DES_KEY_SIZE
,
671 .ivsize
= DES_BLOCK_SIZE
,
672 .setkey
= des_setkey_skcipher
,
673 .encrypt
= cbc_des_encrypt
,
674 .decrypt
= cbc_des_decrypt
,
678 * \brief DES function mappings
680 struct skcipher_alg ifxdeu_cbc_des3_ede_alg
= {
681 .base
.cra_name
= "cbc(des3_ede)",
682 .base
.cra_driver_name
= "ifxdeu-cbc(des3_ede)",
683 .base
.cra_priority
= 400,
684 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
685 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
686 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
687 .base
.cra_module
= THIS_MODULE
,
688 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg
.base
.cra_list
),
689 .min_keysize
= DES3_EDE_KEY_SIZE
,
690 .max_keysize
= DES3_EDE_KEY_SIZE
,
691 .ivsize
= DES_BLOCK_SIZE
,
692 .setkey
= des3_ede_setkey_skcipher
,
693 .encrypt
= cbc_des_encrypt
,
694 .decrypt
= cbc_des_decrypt
,
697 /*! \fn int ifxdeu_init_des (void)
698 * \ingroup IFX_DES_FUNCTIONS
699 * \brief initialize des driver
701 int ifxdeu_init_des (void)
707 ret
= crypto_register_alg(&ifxdeu_des_alg
);
711 ret
= crypto_register_skcipher(&ifxdeu_ecb_des_alg
);
715 ret
= crypto_register_skcipher(&ifxdeu_cbc_des_alg
);
719 ret
= crypto_register_alg(&ifxdeu_des3_ede_alg
);
723 ret
= crypto_register_skcipher(&ifxdeu_ecb_des3_ede_alg
);
725 goto ecb_des3_ede_err
;
727 ret
= crypto_register_skcipher(&ifxdeu_cbc_des3_ede_alg
);
729 goto cbc_des3_ede_err
;
735 printk (KERN_NOTICE
"IFX DEU DES initialized%s%s.\n", disable_multiblock
? "" : " (multiblock)", disable_deudma
? "" : " (DMA)");
739 crypto_unregister_alg(&ifxdeu_des_alg
);
740 printk(KERN_ERR
"IFX des initialization failed!\n");
743 crypto_unregister_skcipher(&ifxdeu_ecb_des_alg
);
744 printk (KERN_ERR
"IFX ecb_des initialization failed!\n");
747 crypto_unregister_skcipher(&ifxdeu_cbc_des_alg
);
748 printk (KERN_ERR
"IFX cbc_des initialization failed!\n");
751 crypto_unregister_alg(&ifxdeu_des3_ede_alg
);
752 printk(KERN_ERR
"IFX des3_ede initialization failed!\n");
755 crypto_unregister_skcipher(&ifxdeu_ecb_des3_ede_alg
);
756 printk (KERN_ERR
"IFX ecb_des3_ede initialization failed!\n");
759 crypto_unregister_skcipher(&ifxdeu_cbc_des3_ede_alg
);
760 printk (KERN_ERR
"IFX cbc_des3_ede initialization failed!\n");
765 /*! \fn void ifxdeu_fini_des (void)
766 * \ingroup IFX_DES_FUNCTIONS
767 * \brief unregister des driver
769 void ifxdeu_fini_des (void)
771 crypto_unregister_alg (&ifxdeu_des_alg
);
772 crypto_unregister_skcipher (&ifxdeu_ecb_des_alg
);
773 crypto_unregister_skcipher (&ifxdeu_cbc_des_alg
);
774 crypto_unregister_alg (&ifxdeu_des3_ede_alg
);
775 crypto_unregister_skcipher (&ifxdeu_ecb_des3_ede_alg
);
776 crypto_unregister_skcipher (&ifxdeu_cbc_des3_ede_alg
);