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
;
122 /*! \fn int des_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
123 * \ingroup IFX_DES_FUNCTIONS
124 * \brief sets DES key
125 * \param tfm linux crypto algo transform
126 * \param key input key
127 * \param keylen key length
129 int des_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
132 struct ifx_deu_des_ctx
*dctx
= crypto_tfm_ctx(tfm
);
135 //printk("setkey in %s\n", __FILE__);
137 err
= des_expand_key(&dctx
->des_context
, key
, keylen
);
138 if (err
== -ENOKEY
) {
139 if (crypto_tfm_get_flags(tfm
) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS
)
145 dctx
->controlr_M
= 0; // des
146 dctx
->key_length
= keylen
;
148 memcpy ((u8
*) (dctx
->expkey
), key
, keylen
);
151 memset(dctx
, 0, sizeof(*dctx
));
156 /*! \fn int des_setkey_skcipher (struct crypto_skcipher *tfm, const uint8_t *in_key, unsigned int key_len)
157 * \ingroup IFX_AES_FUNCTIONS
158 * \brief sets the AES keys for skcipher
159 * \param tfm linux crypto skcipher
160 * \param in_key input key
161 * \param key_len key lengths of 16, 24 and 32 bytes supported
162 * \return -EINVAL - bad key length, 0 - SUCCESS
164 int des_setkey_skcipher (struct crypto_skcipher
*tfm
, const u8
*in_key
, unsigned int key_len
)
166 return des_setkey(crypto_skcipher_tfm(tfm
), in_key
, key_len
);
169 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
170 * \ingroup IFX_DES_FUNCTIONS
171 * \brief main interface to DES hardware
172 * \param ctx_arg crypto algo context
173 * \param out_arg output bytestream
174 * \param in_arg input bytestream
175 * \param iv_arg initialization vector
176 * \param nbytes length of bytestream
177 * \param encdec 1 for encrypt; 0 for decrypt
178 * \param mode operation mode such as ebc, cbc
181 void ifx_deu_des (void *ctx_arg
, u8
*out_arg
, const u8
*in_arg
,
182 u8
*iv_arg
, u32 nbytes
, int encdec
, int mode
)
184 volatile struct des_t
*des
= (struct des_t
*) DES_3DES_START
;
185 struct ifx_deu_des_ctx
*dctx
= ctx_arg
;
186 u32
*key
= dctx
->expkey
;
194 des
->controlr
.M
= dctx
->controlr_M
;
195 if (dctx
->controlr_M
== 0) // des
197 des
->K1HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 0));
198 des
->K1LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 1));
202 /* Hardware Section */
203 switch (dctx
->key_length
) {
205 des
->K3HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 4));
206 des
->K3LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 5));
210 des
->K2HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 2));
211 des
->K2LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 3));
215 des
->K1HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 0));
216 des
->K1LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 1));
225 des
->controlr
.E_D
= !encdec
; //encryption
226 des
->controlr
.O
= mode
; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
229 des
->IVHR
= DEU_ENDIAN_SWAP(*(u32
*) iv_arg
);
230 des
->IVLR
= DEU_ENDIAN_SWAP(*((u32
*) iv_arg
+ 1));
233 nblocks
= nbytes
/ 4;
235 for (i
= 0; i
< nblocks
; i
+= 2) {
236 /* wait for busy bit to clear */
238 /*--- Workaround ----------------------------------------------------
239 do a dummy read to the busy flag because it is not raised early
240 enough in CFB/OFB 3DES modes */
242 printk ("ihr: %x\n", (*((u32
*) in_arg
+ i
)));
243 printk ("ilr: %x\n", (*((u32
*) in_arg
+ 1 + i
)));
245 des
->IHR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ i
));
246 des
->ILR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ 1 + i
)); /* start crypto */
248 while (des
->controlr
.BUS
) {
249 // this will not take long
252 *((u32
*) out_arg
+ 0 + i
) = des
->OHR
;
253 *((u32
*) out_arg
+ 1 + i
) = des
->OLR
;
260 *(u32
*) iv_arg
= DEU_ENDIAN_SWAP(des
->IVHR
);
261 *((u32
*) iv_arg
+ 1) = DEU_ENDIAN_SWAP(des
->IVLR
);
267 //definitions from linux/include/crypto.h:
268 //#define CRYPTO_TFM_MODE_ECB 0x00000001
269 //#define CRYPTO_TFM_MODE_CBC 0x00000002
270 //#define CRYPTO_TFM_MODE_CFB 0x00000004
271 //#define CRYPTO_TFM_MODE_CTR 0x00000008
272 //#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
273 //but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
275 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
276 * \ingroup IFX_DES_FUNCTIONS
277 * \brief main interface to DES hardware
278 * \param ctx_arg crypto algo context
279 * \param out_arg output bytestream
280 * \param in_arg input bytestream
281 * \param iv_arg initialization vector
282 * \param nbytes length of bytestream
283 * \param encdec 1 for encrypt; 0 for decrypt
284 * \param mode operation mode such as ebc, cbc
287 /*! \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)
288 * \ingroup IFX_DES_FUNCTIONS
289 * \brief sets DES hardware to ECB mode
290 * \param ctx crypto algo context
291 * \param dst output bytestream
292 * \param src input bytestream
293 * \param iv initialization vector
294 * \param nbytes length of bytestream
295 * \param encdec 1 for encrypt; 0 for decrypt
296 * \param inplace not used
298 void ifx_deu_des_ecb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
299 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
301 ifx_deu_des (ctx
, dst
, src
, NULL
, nbytes
, encdec
, 0);
304 /*! \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)
305 * \ingroup IFX_DES_FUNCTIONS
306 * \brief sets DES hardware to CBC mode
307 * \param ctx crypto algo context
308 * \param dst output bytestream
309 * \param src input bytestream
310 * \param iv initialization vector
311 * \param nbytes length of bytestream
312 * \param encdec 1 for encrypt; 0 for decrypt
313 * \param inplace not used
315 void ifx_deu_des_cbc (void *ctx
, uint8_t *dst
, const uint8_t *src
,
316 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
318 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 1);
321 /*! \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)
322 * \ingroup IFX_DES_FUNCTIONS
323 * \brief sets DES hardware to OFB mode
324 * \param ctx crypto algo context
325 * \param dst output bytestream
326 * \param src input bytestream
327 * \param iv initialization vector
328 * \param nbytes length of bytestream
329 * \param encdec 1 for encrypt; 0 for decrypt
330 * \param inplace not used
332 void ifx_deu_des_ofb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
333 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
335 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 2);
338 /*! \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)
339 \ingroup IFX_DES_FUNCTIONS
340 \brief sets DES hardware to CFB mode
341 \param ctx crypto algo context
342 \param dst output bytestream
343 \param src input bytestream
344 \param iv initialization vector
345 \param nbytes length of bytestream
346 \param encdec 1 for encrypt; 0 for decrypt
347 \param inplace not used
349 void ifx_deu_des_cfb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
350 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
352 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 3);
355 /*! \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)
356 * \ingroup IFX_DES_FUNCTIONS
357 * \brief sets DES hardware to CTR mode
358 * \param ctx crypto algo context
359 * \param dst output bytestream
360 * \param src input bytestream
361 * \param iv initialization vector
362 * \param nbytes length of bytestream
363 * \param encdec 1 for encrypt; 0 for decrypt
364 * \param inplace not used
366 void ifx_deu_des_ctr (void *ctx
, uint8_t *dst
, const uint8_t *src
,
367 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
369 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 4);
372 /*! \fn void ifx_deu_des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
373 * \ingroup IFX_DES_FUNCTIONS
374 * \brief encrypt DES_BLOCK_SIZE of data
375 * \param tfm linux crypto algo transform
376 * \param out output bytestream
377 * \param in input bytestream
379 void ifx_deu_des_encrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
381 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
382 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
383 CRYPTO_DIR_ENCRYPT
, 0);
387 /*! \fn void ifx_deu_des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
388 * \ingroup IFX_DES_FUNCTIONS
389 * \brief encrypt DES_BLOCK_SIZE of data
390 * \param tfm linux crypto algo transform
391 * \param out output bytestream
392 * \param in input bytestream
394 void ifx_deu_des_decrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
396 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
397 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
398 CRYPTO_DIR_DECRYPT
, 0);
404 * For DES-EDE3, there is no known need to reject weak or
405 * complementation keys. Any weakness is obviated by the use of
408 * However, if the first two or last two independent 64-bit keys are
409 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
410 * same as DES. Implementers MUST reject keys that exhibit this
415 /*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
416 * \ingroup IFX_DES_FUNCTIONS
417 * \brief sets 3DES key
418 * \param tfm linux crypto algo transform
419 * \param key input key
420 * \param keylen key length
422 int des3_ede_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
425 struct ifx_deu_des_ctx
*dctx
= crypto_tfm_ctx(tfm
);
428 //printk("setkey in %s\n", __FILE__);
430 err
= des3_ede_expand_key(&dctx
->des3_ede_context
, key
, keylen
);
431 if (err
== -ENOKEY
) {
432 if (crypto_tfm_get_flags(tfm
) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS
)
438 dctx
->controlr_M
= keylen
/ 8 + 1; // 3DES EDE1 / EDE2 / EDE3 Mode
439 dctx
->key_length
= keylen
;
441 memcpy ((u8
*) (dctx
->expkey
), key
, keylen
);
444 memset(dctx
, 0, sizeof(*dctx
));
449 /*! \fn int des3_ede_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
450 * \ingroup IFX_DES_FUNCTIONS
451 * \brief sets 3DES key
452 * \param tfm linux crypto skcipher transform
453 * \param key input key
454 * \param keylen key length
456 int des3_ede_setkey_skcipher(struct crypto_skcipher
*tfm
, const u8
*key
,
459 return des3_ede_setkey(crypto_skcipher_tfm(tfm
), key
, keylen
);
463 * \brief DES function mappings
465 struct crypto_alg ifxdeu_des_alg
= {
467 .cra_driver_name
= "ifxdeu-des",
469 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
470 .cra_blocksize
= DES_BLOCK_SIZE
,
471 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
472 .cra_module
= THIS_MODULE
,
474 .cra_list
= LIST_HEAD_INIT(ifxdeu_des_alg
.cra_list
),
475 .cra_u
= { .cipher
= {
476 .cia_min_keysize
= DES_KEY_SIZE
,
477 .cia_max_keysize
= DES_KEY_SIZE
,
478 .cia_setkey
= des_setkey
,
479 .cia_encrypt
= ifx_deu_des_encrypt
,
480 .cia_decrypt
= ifx_deu_des_decrypt
} }
484 * \brief DES function mappings
486 struct crypto_alg ifxdeu_des3_ede_alg
= {
487 .cra_name
= "des3_ede",
488 .cra_driver_name
= "ifxdeu-des3_ede",
490 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
491 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
492 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
493 .cra_module
= THIS_MODULE
,
495 .cra_list
= LIST_HEAD_INIT(ifxdeu_des3_ede_alg
.cra_list
),
496 .cra_u
= { .cipher
= {
497 .cia_min_keysize
= DES3_EDE_KEY_SIZE
,
498 .cia_max_keysize
= DES3_EDE_KEY_SIZE
,
499 .cia_setkey
= des3_ede_setkey
,
500 .cia_encrypt
= ifx_deu_des_encrypt
,
501 .cia_decrypt
= ifx_deu_des_decrypt
} }
504 /*! \fn int ecb_des_encrypt(struct skcipher_req *req)
505 * \ingroup IFX_AES_FUNCTIONS
506 * \brief ECB DES encrypt using linux crypto skcipher
507 * \param req skcipher request
510 int ecb_des_encrypt(struct skcipher_request
*req
)
512 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
513 struct skcipher_walk walk
;
515 unsigned int enc_bytes
, nbytes
;
517 err
= skcipher_walk_virt(&walk
, req
, false);
519 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
520 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
521 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
522 NULL
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
523 nbytes
&= DES_BLOCK_SIZE
- 1;
524 err
= skcipher_walk_done(&walk
, nbytes
);
530 /*! \fn int ecb_des_decrypt(struct skcipher_req *req)
531 * \ingroup IFX_AES_FUNCTIONS
532 * \brief ECB DES decrypt using linux crypto skcipher
533 * \param req skcipher request
536 int ecb_des_decrypt(struct skcipher_request
*req
)
538 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
539 struct skcipher_walk walk
;
541 unsigned int dec_bytes
, nbytes
;
544 err
= skcipher_walk_virt(&walk
, req
, false);
546 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
547 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
548 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
549 NULL
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
550 nbytes
&= DES_BLOCK_SIZE
- 1;
551 err
= skcipher_walk_done(&walk
, nbytes
);
558 * \brief DES function mappings
560 struct skcipher_alg ifxdeu_ecb_des_alg
= {
561 .base
.cra_name
= "ecb(des)",
562 .base
.cra_driver_name
= "ifxdeu-ecb(des)",
563 .base
.cra_priority
= 400,
564 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
565 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
566 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
567 .base
.cra_module
= THIS_MODULE
,
568 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des_alg
.base
.cra_list
),
569 .min_keysize
= DES_KEY_SIZE
,
570 .max_keysize
= DES_KEY_SIZE
,
571 .setkey
= des_setkey_skcipher
,
572 .encrypt
= ecb_des_encrypt
,
573 .decrypt
= ecb_des_decrypt
,
577 * \brief DES function mappings
579 struct skcipher_alg ifxdeu_ecb_des3_ede_alg
= {
580 .base
.cra_name
= "ecb(des3_ede)",
581 .base
.cra_driver_name
= "ifxdeu-ecb(des3_ede)",
582 .base
.cra_priority
= 400,
583 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
584 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
585 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
586 .base
.cra_module
= THIS_MODULE
,
587 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg
.base
.cra_list
),
588 .min_keysize
= DES3_EDE_KEY_SIZE
,
589 .max_keysize
= DES3_EDE_KEY_SIZE
,
590 .setkey
= des3_ede_setkey_skcipher
,
591 .encrypt
= ecb_des_encrypt
,
592 .decrypt
= ecb_des_decrypt
,
595 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
596 * \ingroup IFX_AES_FUNCTIONS
597 * \brief CBC DES encrypt using linux crypto skcipher
598 * \param req skcipher request
601 int cbc_des_encrypt(struct skcipher_request
*req
)
603 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
604 struct skcipher_walk walk
;
606 unsigned int enc_bytes
, nbytes
;
609 err
= skcipher_walk_virt(&walk
, req
, false);
611 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
613 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
614 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
615 iv
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
616 nbytes
&= DES_BLOCK_SIZE
- 1;
617 err
= skcipher_walk_done(&walk
, nbytes
);
623 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
624 * \ingroup IFX_AES_FUNCTIONS
625 * \brief CBC DES decrypt using linux crypto skcipher
626 * \param req skcipher request
629 int cbc_des_decrypt(struct skcipher_request
*req
)
631 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
632 struct skcipher_walk walk
;
634 unsigned int dec_bytes
, nbytes
;
637 err
= skcipher_walk_virt(&walk
, req
, false);
639 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
641 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
642 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
643 iv
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
644 nbytes
&= DES_BLOCK_SIZE
- 1;
645 err
= skcipher_walk_done(&walk
, nbytes
);
652 * \brief DES function mappings
654 struct skcipher_alg ifxdeu_cbc_des_alg
= {
655 .base
.cra_name
= "cbc(des)",
656 .base
.cra_driver_name
= "ifxdeu-cbc(des)",
657 .base
.cra_priority
= 400,
658 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
659 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
660 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
661 .base
.cra_module
= THIS_MODULE
,
662 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des_alg
.base
.cra_list
),
663 .min_keysize
= DES_KEY_SIZE
,
664 .max_keysize
= DES_KEY_SIZE
,
665 .ivsize
= DES_BLOCK_SIZE
,
666 .setkey
= des_setkey_skcipher
,
667 .encrypt
= cbc_des_encrypt
,
668 .decrypt
= cbc_des_decrypt
,
672 * \brief DES function mappings
674 struct skcipher_alg ifxdeu_cbc_des3_ede_alg
= {
675 .base
.cra_name
= "cbc(des3_ede)",
676 .base
.cra_driver_name
= "ifxdeu-cbc(des3_ede)",
677 .base
.cra_priority
= 400,
678 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
679 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
680 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
681 .base
.cra_module
= THIS_MODULE
,
682 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg
.base
.cra_list
),
683 .min_keysize
= DES3_EDE_KEY_SIZE
,
684 .max_keysize
= DES3_EDE_KEY_SIZE
,
685 .ivsize
= DES_BLOCK_SIZE
,
686 .setkey
= des3_ede_setkey_skcipher
,
687 .encrypt
= cbc_des_encrypt
,
688 .decrypt
= cbc_des_decrypt
,
691 /*! \fn int ifxdeu_init_des (void)
692 * \ingroup IFX_DES_FUNCTIONS
693 * \brief initialize des driver
695 int ifxdeu_init_des (void)
701 ret
= crypto_register_alg(&ifxdeu_des_alg
);
705 ret
= crypto_register_skcipher(&ifxdeu_ecb_des_alg
);
709 ret
= crypto_register_skcipher(&ifxdeu_cbc_des_alg
);
713 ret
= crypto_register_alg(&ifxdeu_des3_ede_alg
);
717 ret
= crypto_register_skcipher(&ifxdeu_ecb_des3_ede_alg
);
719 goto ecb_des3_ede_err
;
721 ret
= crypto_register_skcipher(&ifxdeu_cbc_des3_ede_alg
);
723 goto cbc_des3_ede_err
;
729 printk (KERN_NOTICE
"IFX DEU DES initialized%s%s.\n", disable_multiblock
? "" : " (multiblock)", disable_deudma
? "" : " (DMA)");
733 crypto_unregister_alg(&ifxdeu_des_alg
);
734 printk(KERN_ERR
"IFX des initialization failed!\n");
737 crypto_unregister_skcipher(&ifxdeu_ecb_des_alg
);
738 printk (KERN_ERR
"IFX ecb_des initialization failed!\n");
741 crypto_unregister_skcipher(&ifxdeu_cbc_des_alg
);
742 printk (KERN_ERR
"IFX cbc_des initialization failed!\n");
745 crypto_unregister_alg(&ifxdeu_des3_ede_alg
);
746 printk(KERN_ERR
"IFX des3_ede initialization failed!\n");
749 crypto_unregister_skcipher(&ifxdeu_ecb_des3_ede_alg
);
750 printk (KERN_ERR
"IFX ecb_des3_ede initialization failed!\n");
753 crypto_unregister_skcipher(&ifxdeu_cbc_des3_ede_alg
);
754 printk (KERN_ERR
"IFX cbc_des3_ede initialization failed!\n");
759 /*! \fn void ifxdeu_fini_des (void)
760 * \ingroup IFX_DES_FUNCTIONS
761 * \brief unregister des driver
763 void ifxdeu_fini_des (void)
765 crypto_unregister_alg (&ifxdeu_des_alg
);
766 crypto_unregister_skcipher (&ifxdeu_ecb_des_alg
);
767 crypto_unregister_skcipher (&ifxdeu_cbc_des_alg
);
768 crypto_unregister_alg (&ifxdeu_des3_ede_alg
);
769 crypto_unregister_skcipher (&ifxdeu_ecb_des3_ede_alg
);
770 crypto_unregister_skcipher (&ifxdeu_cbc_des3_ede_alg
);