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));
216 des
->K1HR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 0));
217 des
->K1LR
= DEU_ENDIAN_SWAP(*((u32
*) key
+ 1));
226 des
->controlr
.E_D
= !encdec
; //encryption
227 des
->controlr
.O
= mode
; //0 ECB 1 CBC 2 OFB 3 CFB 4 CTR hexdump(prin,sizeof(*des));
230 des
->IVHR
= DEU_ENDIAN_SWAP(*(u32
*) iv_arg
);
231 des
->IVLR
= DEU_ENDIAN_SWAP(*((u32
*) iv_arg
+ 1));
234 nblocks
= nbytes
/ 4;
236 for (i
= 0; i
< nblocks
; i
+= 2) {
237 /* wait for busy bit to clear */
239 /*--- Workaround ----------------------------------------------------
240 do a dummy read to the busy flag because it is not raised early
241 enough in CFB/OFB 3DES modes */
243 printk ("ihr: %x\n", (*((u32
*) in_arg
+ i
)));
244 printk ("ilr: %x\n", (*((u32
*) in_arg
+ 1 + i
)));
246 des
->IHR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ i
));
247 des
->ILR
= INPUT_ENDIAN_SWAP(*((u32
*) in_arg
+ 1 + i
)); /* start crypto */
249 while (des
->controlr
.BUS
) {
250 // this will not take long
253 *((u32
*) out_arg
+ 0 + i
) = des
->OHR
;
254 *((u32
*) out_arg
+ 1 + i
) = des
->OLR
;
261 *(u32
*) iv_arg
= DEU_ENDIAN_SWAP(des
->IVHR
);
262 *((u32
*) iv_arg
+ 1) = DEU_ENDIAN_SWAP(des
->IVLR
);
268 //definitions from linux/include/crypto.h:
269 //#define CRYPTO_TFM_MODE_ECB 0x00000001
270 //#define CRYPTO_TFM_MODE_CBC 0x00000002
271 //#define CRYPTO_TFM_MODE_CFB 0x00000004
272 //#define CRYPTO_TFM_MODE_CTR 0x00000008
273 //#define CRYPTO_TFM_MODE_OFB 0x00000010 // not even defined
274 //but hardware definition: 0 ECB 1 CBC 2 OFB 3 CFB 4 CTR
276 /*! \fn void ifx_deu_des(void *ctx_arg, u8 *out_arg, const u8 *in_arg, u8 *iv_arg, u32 nbytes, int encdec, int mode)
277 * \ingroup IFX_DES_FUNCTIONS
278 * \brief main interface to DES hardware
279 * \param ctx_arg crypto algo context
280 * \param out_arg output bytestream
281 * \param in_arg input bytestream
282 * \param iv_arg initialization vector
283 * \param nbytes length of bytestream
284 * \param encdec 1 for encrypt; 0 for decrypt
285 * \param mode operation mode such as ebc, cbc
288 /*! \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)
289 * \ingroup IFX_DES_FUNCTIONS
290 * \brief sets DES hardware to ECB mode
291 * \param ctx crypto algo context
292 * \param dst output bytestream
293 * \param src input bytestream
294 * \param iv initialization vector
295 * \param nbytes length of bytestream
296 * \param encdec 1 for encrypt; 0 for decrypt
297 * \param inplace not used
299 void ifx_deu_des_ecb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
300 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
302 ifx_deu_des (ctx
, dst
, src
, NULL
, nbytes
, encdec
, 0);
305 /*! \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)
306 * \ingroup IFX_DES_FUNCTIONS
307 * \brief sets DES hardware to CBC mode
308 * \param ctx crypto algo context
309 * \param dst output bytestream
310 * \param src input bytestream
311 * \param iv initialization vector
312 * \param nbytes length of bytestream
313 * \param encdec 1 for encrypt; 0 for decrypt
314 * \param inplace not used
316 void ifx_deu_des_cbc (void *ctx
, uint8_t *dst
, const uint8_t *src
,
317 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
319 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 1);
322 /*! \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)
323 * \ingroup IFX_DES_FUNCTIONS
324 * \brief sets DES hardware to OFB mode
325 * \param ctx crypto algo context
326 * \param dst output bytestream
327 * \param src input bytestream
328 * \param iv initialization vector
329 * \param nbytes length of bytestream
330 * \param encdec 1 for encrypt; 0 for decrypt
331 * \param inplace not used
333 void ifx_deu_des_ofb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
334 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
336 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 2);
339 /*! \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)
340 \ingroup IFX_DES_FUNCTIONS
341 \brief sets DES hardware to CFB mode
342 \param ctx crypto algo context
343 \param dst output bytestream
344 \param src input bytestream
345 \param iv initialization vector
346 \param nbytes length of bytestream
347 \param encdec 1 for encrypt; 0 for decrypt
348 \param inplace not used
350 void ifx_deu_des_cfb (void *ctx
, uint8_t *dst
, const uint8_t *src
,
351 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
353 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 3);
356 /*! \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)
357 * \ingroup IFX_DES_FUNCTIONS
358 * \brief sets DES hardware to CTR mode
359 * \param ctx crypto algo context
360 * \param dst output bytestream
361 * \param src input bytestream
362 * \param iv initialization vector
363 * \param nbytes length of bytestream
364 * \param encdec 1 for encrypt; 0 for decrypt
365 * \param inplace not used
367 void ifx_deu_des_ctr (void *ctx
, uint8_t *dst
, const uint8_t *src
,
368 uint8_t *iv
, size_t nbytes
, int encdec
, int inplace
)
370 ifx_deu_des (ctx
, dst
, src
, iv
, nbytes
, encdec
, 4);
373 /*! \fn void ifx_deu_des_encrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
374 * \ingroup IFX_DES_FUNCTIONS
375 * \brief encrypt DES_BLOCK_SIZE of data
376 * \param tfm linux crypto algo transform
377 * \param out output bytestream
378 * \param in input bytestream
380 void ifx_deu_des_encrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
382 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
383 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
384 CRYPTO_DIR_ENCRYPT
, 0);
388 /*! \fn void ifx_deu_des_decrypt (struct crypto_tfm *tfm, uint8_t *out, const uint8_t *in)
389 * \ingroup IFX_DES_FUNCTIONS
390 * \brief encrypt DES_BLOCK_SIZE of data
391 * \param tfm linux crypto algo transform
392 * \param out output bytestream
393 * \param in input bytestream
395 void ifx_deu_des_decrypt (struct crypto_tfm
*tfm
, uint8_t * out
, const uint8_t * in
)
397 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(tfm
);
398 ifx_deu_des (ctx
, out
, in
, NULL
, DES_BLOCK_SIZE
,
399 CRYPTO_DIR_DECRYPT
, 0);
405 * For DES-EDE3, there is no known need to reject weak or
406 * complementation keys. Any weakness is obviated by the use of
409 * However, if the first two or last two independent 64-bit keys are
410 * equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
411 * same as DES. Implementers MUST reject keys that exhibit this
416 /*! \fn int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
417 * \ingroup IFX_DES_FUNCTIONS
418 * \brief sets 3DES key
419 * \param tfm linux crypto algo transform
420 * \param key input key
421 * \param keylen key length
423 int des3_ede_setkey(struct crypto_tfm
*tfm
, const u8
*key
,
426 struct ifx_deu_des_ctx
*dctx
= crypto_tfm_ctx(tfm
);
429 //printk("setkey in %s\n", __FILE__);
431 err
= des3_ede_expand_key(&dctx
->des3_ede_context
, key
, keylen
);
432 if (err
== -ENOKEY
) {
433 if (crypto_tfm_get_flags(tfm
) & CRYPTO_TFM_REQ_FORBID_WEAK_KEYS
)
439 dctx
->controlr_M
= keylen
/ 8 + 1; // 3DES EDE1 / EDE2 / EDE3 Mode
440 dctx
->key_length
= keylen
;
442 memcpy ((u8
*) (dctx
->expkey
), key
, keylen
);
445 memset(dctx
, 0, sizeof(*dctx
));
450 /*! \fn int des3_ede_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen)
451 * \ingroup IFX_DES_FUNCTIONS
452 * \brief sets 3DES key
453 * \param tfm linux crypto skcipher transform
454 * \param key input key
455 * \param keylen key length
457 int des3_ede_setkey_skcipher(struct crypto_skcipher
*tfm
, const u8
*key
,
460 return des3_ede_setkey(crypto_skcipher_tfm(tfm
), key
, keylen
);
464 * \brief DES function mappings
466 struct crypto_alg ifxdeu_des_alg
= {
468 .cra_driver_name
= "ifxdeu-des",
470 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
471 .cra_blocksize
= DES_BLOCK_SIZE
,
472 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
473 .cra_module
= THIS_MODULE
,
475 .cra_list
= LIST_HEAD_INIT(ifxdeu_des_alg
.cra_list
),
476 .cra_u
= { .cipher
= {
477 .cia_min_keysize
= DES_KEY_SIZE
,
478 .cia_max_keysize
= DES_KEY_SIZE
,
479 .cia_setkey
= des_setkey
,
480 .cia_encrypt
= ifx_deu_des_encrypt
,
481 .cia_decrypt
= ifx_deu_des_decrypt
} }
485 * \brief DES function mappings
487 struct crypto_alg ifxdeu_des3_ede_alg
= {
488 .cra_name
= "des3_ede",
489 .cra_driver_name
= "ifxdeu-des3_ede",
491 .cra_flags
= CRYPTO_ALG_TYPE_CIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
492 .cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
493 .cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
494 .cra_module
= THIS_MODULE
,
496 .cra_list
= LIST_HEAD_INIT(ifxdeu_des3_ede_alg
.cra_list
),
497 .cra_u
= { .cipher
= {
498 .cia_min_keysize
= DES3_EDE_KEY_SIZE
,
499 .cia_max_keysize
= DES3_EDE_KEY_SIZE
,
500 .cia_setkey
= des3_ede_setkey
,
501 .cia_encrypt
= ifx_deu_des_encrypt
,
502 .cia_decrypt
= ifx_deu_des_decrypt
} }
505 /*! \fn int ecb_des_encrypt(struct skcipher_req *req)
506 * \ingroup IFX_AES_FUNCTIONS
507 * \brief ECB DES encrypt using linux crypto skcipher
508 * \param req skcipher request
511 int ecb_des_encrypt(struct skcipher_request
*req
)
513 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
514 struct skcipher_walk walk
;
516 unsigned int enc_bytes
, nbytes
;
518 err
= skcipher_walk_virt(&walk
, req
, false);
520 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
521 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
522 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
523 NULL
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
524 nbytes
&= DES_BLOCK_SIZE
- 1;
525 err
= skcipher_walk_done(&walk
, nbytes
);
531 /*! \fn int ecb_des_decrypt(struct skcipher_req *req)
532 * \ingroup IFX_AES_FUNCTIONS
533 * \brief ECB DES decrypt using linux crypto skcipher
534 * \param req skcipher request
537 int ecb_des_decrypt(struct skcipher_request
*req
)
539 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
540 struct skcipher_walk walk
;
542 unsigned int dec_bytes
, nbytes
;
545 err
= skcipher_walk_virt(&walk
, req
, false);
547 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
548 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
549 ifx_deu_des_ecb(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
550 NULL
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
551 nbytes
&= DES_BLOCK_SIZE
- 1;
552 err
= skcipher_walk_done(&walk
, nbytes
);
559 * \brief DES function mappings
561 struct skcipher_alg ifxdeu_ecb_des_alg
= {
562 .base
.cra_name
= "ecb(des)",
563 .base
.cra_driver_name
= "ifxdeu-ecb(des)",
564 .base
.cra_priority
= 400,
565 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
566 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
567 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
568 .base
.cra_module
= THIS_MODULE
,
569 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des_alg
.base
.cra_list
),
570 .min_keysize
= DES_KEY_SIZE
,
571 .max_keysize
= DES_KEY_SIZE
,
572 .setkey
= des_setkey_skcipher
,
573 .encrypt
= ecb_des_encrypt
,
574 .decrypt
= ecb_des_decrypt
,
578 * \brief DES function mappings
580 struct skcipher_alg ifxdeu_ecb_des3_ede_alg
= {
581 .base
.cra_name
= "ecb(des3_ede)",
582 .base
.cra_driver_name
= "ifxdeu-ecb(des3_ede)",
583 .base
.cra_priority
= 400,
584 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
585 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
586 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
587 .base
.cra_module
= THIS_MODULE
,
588 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_ecb_des3_ede_alg
.base
.cra_list
),
589 .min_keysize
= DES3_EDE_KEY_SIZE
,
590 .max_keysize
= DES3_EDE_KEY_SIZE
,
591 .setkey
= des3_ede_setkey_skcipher
,
592 .encrypt
= ecb_des_encrypt
,
593 .decrypt
= ecb_des_decrypt
,
596 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
597 * \ingroup IFX_AES_FUNCTIONS
598 * \brief CBC DES encrypt using linux crypto skcipher
599 * \param req skcipher request
602 int cbc_des_encrypt(struct skcipher_request
*req
)
604 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
605 struct skcipher_walk walk
;
607 unsigned int enc_bytes
, nbytes
;
610 err
= skcipher_walk_virt(&walk
, req
, false);
612 while ((nbytes
= enc_bytes
= walk
.nbytes
)) {
614 enc_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
615 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
616 iv
, enc_bytes
, CRYPTO_DIR_ENCRYPT
, 0);
617 nbytes
&= DES_BLOCK_SIZE
- 1;
618 err
= skcipher_walk_done(&walk
, nbytes
);
624 /*! \fn int cbc_des_encrypt(struct skcipher_req *req)
625 * \ingroup IFX_AES_FUNCTIONS
626 * \brief CBC DES decrypt using linux crypto skcipher
627 * \param req skcipher request
630 int cbc_des_decrypt(struct skcipher_request
*req
)
632 struct ifx_deu_des_ctx
*ctx
= crypto_tfm_ctx(req
->base
.tfm
);
633 struct skcipher_walk walk
;
635 unsigned int dec_bytes
, nbytes
;
638 err
= skcipher_walk_virt(&walk
, req
, false);
640 while ((nbytes
= dec_bytes
= walk
.nbytes
)) {
642 dec_bytes
-= (nbytes
% DES_BLOCK_SIZE
);
643 ifx_deu_des_cbc(ctx
, walk
.dst
.virt
.addr
, walk
.src
.virt
.addr
,
644 iv
, dec_bytes
, CRYPTO_DIR_DECRYPT
, 0);
645 nbytes
&= DES_BLOCK_SIZE
- 1;
646 err
= skcipher_walk_done(&walk
, nbytes
);
653 * \brief DES function mappings
655 struct skcipher_alg ifxdeu_cbc_des_alg
= {
656 .base
.cra_name
= "cbc(des)",
657 .base
.cra_driver_name
= "ifxdeu-cbc(des)",
658 .base
.cra_priority
= 400,
659 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
660 .base
.cra_blocksize
= DES_BLOCK_SIZE
,
661 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
662 .base
.cra_module
= THIS_MODULE
,
663 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des_alg
.base
.cra_list
),
664 .min_keysize
= DES_KEY_SIZE
,
665 .max_keysize
= DES_KEY_SIZE
,
666 .ivsize
= DES_BLOCK_SIZE
,
667 .setkey
= des_setkey_skcipher
,
668 .encrypt
= cbc_des_encrypt
,
669 .decrypt
= cbc_des_decrypt
,
673 * \brief DES function mappings
675 struct skcipher_alg ifxdeu_cbc_des3_ede_alg
= {
676 .base
.cra_name
= "cbc(des3_ede)",
677 .base
.cra_driver_name
= "ifxdeu-cbc(des3_ede)",
678 .base
.cra_priority
= 400,
679 .base
.cra_flags
= CRYPTO_ALG_TYPE_SKCIPHER
| CRYPTO_ALG_KERN_DRIVER_ONLY
,
680 .base
.cra_blocksize
= DES3_EDE_BLOCK_SIZE
,
681 .base
.cra_ctxsize
= sizeof(struct ifx_deu_des_ctx
),
682 .base
.cra_module
= THIS_MODULE
,
683 .base
.cra_list
= LIST_HEAD_INIT(ifxdeu_cbc_des3_ede_alg
.base
.cra_list
),
684 .min_keysize
= DES3_EDE_KEY_SIZE
,
685 .max_keysize
= DES3_EDE_KEY_SIZE
,
686 .ivsize
= DES_BLOCK_SIZE
,
687 .setkey
= des3_ede_setkey_skcipher
,
688 .encrypt
= cbc_des_encrypt
,
689 .decrypt
= cbc_des_decrypt
,
692 /*! \fn int ifxdeu_init_des (void)
693 * \ingroup IFX_DES_FUNCTIONS
694 * \brief initialize des driver
696 int ifxdeu_init_des (void)
702 ret
= crypto_register_alg(&ifxdeu_des_alg
);
706 ret
= crypto_register_skcipher(&ifxdeu_ecb_des_alg
);
710 ret
= crypto_register_skcipher(&ifxdeu_cbc_des_alg
);
714 ret
= crypto_register_alg(&ifxdeu_des3_ede_alg
);
718 ret
= crypto_register_skcipher(&ifxdeu_ecb_des3_ede_alg
);
720 goto ecb_des3_ede_err
;
722 ret
= crypto_register_skcipher(&ifxdeu_cbc_des3_ede_alg
);
724 goto cbc_des3_ede_err
;
730 printk (KERN_NOTICE
"IFX DEU DES initialized%s%s.\n", disable_multiblock
? "" : " (multiblock)", disable_deudma
? "" : " (DMA)");
734 crypto_unregister_alg(&ifxdeu_des_alg
);
735 printk(KERN_ERR
"IFX des initialization failed!\n");
738 crypto_unregister_skcipher(&ifxdeu_ecb_des_alg
);
739 printk (KERN_ERR
"IFX ecb_des initialization failed!\n");
742 crypto_unregister_skcipher(&ifxdeu_cbc_des_alg
);
743 printk (KERN_ERR
"IFX cbc_des initialization failed!\n");
746 crypto_unregister_alg(&ifxdeu_des3_ede_alg
);
747 printk(KERN_ERR
"IFX des3_ede initialization failed!\n");
750 crypto_unregister_skcipher(&ifxdeu_ecb_des3_ede_alg
);
751 printk (KERN_ERR
"IFX ecb_des3_ede initialization failed!\n");
754 crypto_unregister_skcipher(&ifxdeu_cbc_des3_ede_alg
);
755 printk (KERN_ERR
"IFX cbc_des3_ede initialization failed!\n");
760 /*! \fn void ifxdeu_fini_des (void)
761 * \ingroup IFX_DES_FUNCTIONS
762 * \brief unregister des driver
764 void ifxdeu_fini_des (void)
766 crypto_unregister_alg (&ifxdeu_des_alg
);
767 crypto_unregister_skcipher (&ifxdeu_ecb_des_alg
);
768 crypto_unregister_skcipher (&ifxdeu_cbc_des_alg
);
769 crypto_unregister_alg (&ifxdeu_des3_ede_alg
);
770 crypto_unregister_skcipher (&ifxdeu_ecb_des3_ede_alg
);
771 crypto_unregister_skcipher (&ifxdeu_cbc_des3_ede_alg
);