ltq-deu: remove compiler warning and shorten locked sections
[openwrt/staging/stintel.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 <crypto/des.h>
54 #include <crypto/internal/skcipher.h>
55 #include "ifxmips_deu.h"
56
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"
64 #else
65 #error "Unkown platform"
66 #endif
67
68 /* DMA specific header and variables */
69
70 #if 0
71 #define CRTCL_SECT_INIT
72 #define CRTCL_SECT_START
73 #define CRTCL_SECT_END
74 #else
75 spinlock_t des_lock;
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)
79 #endif
80
81 /* Preprocessor declerations */
82 #ifdef CRYPTO_DEBUG
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);
85 #else
86 #define DPRINTF(level, format, args...)
87 #endif
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
95
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);
106
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);
109
110 struct ifx_deu_des_ctx {
111 int controlr_M;
112 int key_length;
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;
117 };
118
119 extern int disable_multiblock;
120 extern int disable_deudma;
121
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
128 */
129 int des_setkey(struct crypto_tfm *tfm, const u8 *key,
130 unsigned int keylen)
131 {
132 struct ifx_deu_des_ctx *dctx = crypto_tfm_ctx(tfm);
133 int err;
134
135 //printk("setkey in %s\n", __FILE__);
136
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)
140 err = -EINVAL;
141 else
142 err = 0;
143 }
144
145 dctx->controlr_M = 0; // des
146 dctx->key_length = keylen;
147
148 memcpy ((u8 *) (dctx->expkey), key, keylen);
149
150 if (err)
151 memset(dctx, 0, sizeof(*dctx));
152
153 return err;
154 }
155
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
163 */
164 int des_setkey_skcipher (struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len)
165 {
166 return des_setkey(crypto_skcipher_tfm(tfm), in_key, key_len);
167 }
168
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
179 */
180
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)
183 {
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;
187 unsigned long flag;
188
189 int i = 0;
190 int nblocks = 0;
191
192 CRTCL_SECT_START;
193
194 des->controlr.M = dctx->controlr_M;
195 if (dctx->controlr_M == 0) // des
196 {
197 des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
198 des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
199
200 }
201 else {
202 /* Hardware Section */
203 switch (dctx->key_length) {
204 case 24:
205 des->K3HR = DEU_ENDIAN_SWAP(*((u32 *) key + 4));
206 des->K3LR = DEU_ENDIAN_SWAP(*((u32 *) key + 5));
207 /* no break; */
208
209 case 16:
210 des->K2HR = DEU_ENDIAN_SWAP(*((u32 *) key + 2));
211 des->K2LR = DEU_ENDIAN_SWAP(*((u32 *) key + 3));
212
213 /* no break; */
214 case 8:
215 des->K1HR = DEU_ENDIAN_SWAP(*((u32 *) key + 0));
216 des->K1LR = DEU_ENDIAN_SWAP(*((u32 *) key + 1));
217 break;
218
219 default:
220 CRTCL_SECT_END;
221 return;
222 }
223 }
224
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));
227
228 if (mode > 0) {
229 des->IVHR = DEU_ENDIAN_SWAP(*(u32 *) iv_arg);
230 des->IVLR = DEU_ENDIAN_SWAP(*((u32 *) iv_arg + 1));
231 };
232
233 nblocks = nbytes / 4;
234
235 for (i = 0; i < nblocks; i += 2) {
236 /* wait for busy bit to clear */
237
238 /*--- Workaround ----------------------------------------------------
239 do a dummy read to the busy flag because it is not raised early
240 enough in CFB/OFB 3DES modes */
241 #ifdef CRYPTO_DEBUG
242 printk ("ihr: %x\n", (*((u32 *) in_arg + i)));
243 printk ("ilr: %x\n", (*((u32 *) in_arg + 1 + i)));
244 #endif
245 des->IHR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + i));
246 des->ILR = INPUT_ENDIAN_SWAP(*((u32 *) in_arg + 1 + i)); /* start crypto */
247
248 while (des->controlr.BUS) {
249 // this will not take long
250 }
251
252 *((u32 *) out_arg + 0 + i) = des->OHR;
253 *((u32 *) out_arg + 1 + i) = des->OLR;
254
255 }
256
257
258
259 if (mode > 0) {
260 *(u32 *) iv_arg = DEU_ENDIAN_SWAP(des->IVHR);
261 *((u32 *) iv_arg + 1) = DEU_ENDIAN_SWAP(des->IVLR);
262 };
263
264 CRTCL_SECT_END;
265 }
266
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
274
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
285 */
286
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
297 */
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)
300 {
301 ifx_deu_des (ctx, dst, src, NULL, nbytes, encdec, 0);
302 }
303
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
314 */
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)
317 {
318 ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 1);
319 }
320
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
331 */
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)
334 {
335 ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 2);
336 }
337
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
348 */
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)
351 {
352 ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 3);
353 }
354
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
365 */
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)
368 {
369 ifx_deu_des (ctx, dst, src, iv, nbytes, encdec, 4);
370 }
371
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
378 */
379 void ifx_deu_des_encrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
380 {
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);
384
385 }
386
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
393 */
394 void ifx_deu_des_decrypt (struct crypto_tfm *tfm, uint8_t * out, const uint8_t * in)
395 {
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);
399 }
400
401 /*
402 * \brief RFC2451:
403 *
404 * For DES-EDE3, there is no known need to reject weak or
405 * complementation keys. Any weakness is obviated by the use of
406 * multiple keys.
407 *
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
411 * property.
412 *
413 */
414
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
421 */
422 int des3_ede_setkey(struct crypto_tfm *tfm, const u8 *key,
423 unsigned int keylen)
424 {
425 struct ifx_deu_des_ctx *dctx = crypto_tfm_ctx(tfm);
426 int err;
427
428 //printk("setkey in %s\n", __FILE__);
429
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)
433 err = -EINVAL;
434 else
435 err = 0;
436 }
437
438 dctx->controlr_M = keylen / 8 + 1; // 3DES EDE1 / EDE2 / EDE3 Mode
439 dctx->key_length = keylen;
440
441 memcpy ((u8 *) (dctx->expkey), key, keylen);
442
443 if (err)
444 memset(dctx, 0, sizeof(*dctx));
445
446 return err;
447 }
448
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
455 */
456 int des3_ede_setkey_skcipher(struct crypto_skcipher *tfm, const u8 *key,
457 unsigned int keylen)
458 {
459 return des3_ede_setkey(crypto_skcipher_tfm(tfm), key, keylen);
460 }
461
462 /*
463 * \brief DES function mappings
464 */
465 struct crypto_alg ifxdeu_des_alg = {
466 .cra_name = "des",
467 .cra_driver_name = "ifxdeu-des",
468 .cra_priority = 300,
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,
473 .cra_alignmask = 3,
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 } }
481 };
482
483 /*
484 * \brief DES function mappings
485 */
486 struct crypto_alg ifxdeu_des3_ede_alg = {
487 .cra_name = "des3_ede",
488 .cra_driver_name = "ifxdeu-des3_ede",
489 .cra_priority = 300,
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,
494 .cra_alignmask = 3,
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 } }
502 };
503
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
508 * \return err
509 */
510 int ecb_des_encrypt(struct skcipher_request *req)
511 {
512 struct ifx_deu_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
513 struct skcipher_walk walk;
514 int err;
515 unsigned int enc_bytes, nbytes;
516
517 err = skcipher_walk_virt(&walk, req, false);
518
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);
525 }
526
527 return err;
528 }
529
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
534 * \return err
535 */
536 int ecb_des_decrypt(struct skcipher_request *req)
537 {
538 struct ifx_deu_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
539 struct skcipher_walk walk;
540 int err;
541 unsigned int dec_bytes, nbytes;
542
543 DPRINTF(1, "\n");
544 err = skcipher_walk_virt(&walk, req, false);
545
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);
552 }
553
554 return err;
555 }
556
557 /*
558 * \brief DES function mappings
559 */
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,
574 };
575
576 /*
577 * \brief DES function mappings
578 */
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,
593 };
594
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
599 * \return err
600 */
601 int cbc_des_encrypt(struct skcipher_request *req)
602 {
603 struct ifx_deu_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
604 struct skcipher_walk walk;
605 int err;
606 unsigned int enc_bytes, nbytes;
607
608 DPRINTF(1, "\n");
609 err = skcipher_walk_virt(&walk, req, false);
610
611 while ((nbytes = enc_bytes = walk.nbytes)) {
612 u8 *iv = walk.iv;
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);
618 }
619
620 return err;
621 }
622
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
627 * \return err
628 */
629 int cbc_des_decrypt(struct skcipher_request *req)
630 {
631 struct ifx_deu_des_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
632 struct skcipher_walk walk;
633 int err;
634 unsigned int dec_bytes, nbytes;
635
636 DPRINTF(1, "\n");
637 err = skcipher_walk_virt(&walk, req, false);
638
639 while ((nbytes = dec_bytes = walk.nbytes)) {
640 u8 *iv = walk.iv;
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);
646 }
647
648 return err;
649 }
650
651 /*
652 * \brief DES function mappings
653 */
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,
669 };
670
671 /*
672 * \brief DES function mappings
673 */
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,
689 };
690
691 /*! \fn int ifxdeu_init_des (void)
692 * \ingroup IFX_DES_FUNCTIONS
693 * \brief initialize des driver
694 */
695 int ifxdeu_init_des (void)
696 {
697 int ret = -ENOSYS;
698
699 des_chip_init();
700
701 ret = crypto_register_alg(&ifxdeu_des_alg);
702 if (ret < 0)
703 goto des_err;
704
705 ret = crypto_register_skcipher(&ifxdeu_ecb_des_alg);
706 if (ret < 0)
707 goto ecb_des_err;
708
709 ret = crypto_register_skcipher(&ifxdeu_cbc_des_alg);
710 if (ret < 0)
711 goto cbc_des_err;
712
713 ret = crypto_register_alg(&ifxdeu_des3_ede_alg);
714 if (ret < 0)
715 goto des3_ede_err;
716
717 ret = crypto_register_skcipher(&ifxdeu_ecb_des3_ede_alg);
718 if (ret < 0)
719 goto ecb_des3_ede_err;
720
721 ret = crypto_register_skcipher(&ifxdeu_cbc_des3_ede_alg);
722 if (ret < 0)
723 goto cbc_des3_ede_err;
724
725 CRTCL_SECT_INIT;
726
727
728
729 printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)");
730 return ret;
731
732 des_err:
733 crypto_unregister_alg(&ifxdeu_des_alg);
734 printk(KERN_ERR "IFX des initialization failed!\n");
735 return ret;
736 ecb_des_err:
737 crypto_unregister_skcipher(&ifxdeu_ecb_des_alg);
738 printk (KERN_ERR "IFX ecb_des initialization failed!\n");
739 return ret;
740 cbc_des_err:
741 crypto_unregister_skcipher(&ifxdeu_cbc_des_alg);
742 printk (KERN_ERR "IFX cbc_des initialization failed!\n");
743 return ret;
744 des3_ede_err:
745 crypto_unregister_alg(&ifxdeu_des3_ede_alg);
746 printk(KERN_ERR "IFX des3_ede initialization failed!\n");
747 return ret;
748 ecb_des3_ede_err:
749 crypto_unregister_skcipher(&ifxdeu_ecb_des3_ede_alg);
750 printk (KERN_ERR "IFX ecb_des3_ede initialization failed!\n");
751 return ret;
752 cbc_des3_ede_err:
753 crypto_unregister_skcipher(&ifxdeu_cbc_des3_ede_alg);
754 printk (KERN_ERR "IFX cbc_des3_ede initialization failed!\n");
755 return ret;
756
757 }
758
759 /*! \fn void ifxdeu_fini_des (void)
760 * \ingroup IFX_DES_FUNCTIONS
761 * \brief unregister des driver
762 */
763 void ifxdeu_fini_des (void)
764 {
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);
771
772 }