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