OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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, |
||
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, |
||
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, |
||
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, |
||
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, |
||
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, |
||
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 | |||
694 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) |
||
695 | if (!disable_multiblock) { |
||
696 | ifxdeu_des_alg.cra_u.cipher.cia_max_nbytes = DES_BLOCK_SIZE; //(size_t)-1; |
||
697 | ifxdeu_des_alg.cra_u.cipher.cia_req_align = 16; |
||
698 | ifxdeu_des_alg.cra_u.cipher.cia_ecb = ifx_deu_des_ecb; |
||
699 | ifxdeu_des_alg.cra_u.cipher.cia_cbc = ifx_deu_des_cbc; |
||
700 | ifxdeu_des_alg.cra_u.cipher.cia_cfb = ifx_deu_des_cfb; |
||
701 | ifxdeu_des_alg.cra_u.cipher.cia_ofb = ifx_deu_des_ofb; |
||
702 | } |
||
703 | #endif |
||
704 | |||
705 | ret = crypto_register_alg(&ifxdeu_des_alg); |
||
706 | if (ret < 0) |
||
707 | goto des_err; |
||
708 | |||
709 | ret = crypto_register_alg(&ifxdeu_ecb_des_alg); |
||
710 | if (ret < 0) |
||
711 | goto ecb_des_err; |
||
712 | |||
713 | ret = crypto_register_alg(&ifxdeu_cbc_des_alg); |
||
714 | if (ret < 0) |
||
715 | goto cbc_des_err; |
||
716 | |||
717 | ret = crypto_register_alg(&ifxdeu_des3_ede_alg); |
||
718 | if (ret < 0) |
||
719 | goto des3_ede_err; |
||
720 | |||
721 | ret = crypto_register_alg(&ifxdeu_ecb_des3_ede_alg); |
||
722 | if (ret < 0) |
||
723 | goto ecb_des3_ede_err; |
||
724 | |||
725 | ret = crypto_register_alg(&ifxdeu_cbc_des3_ede_alg); |
||
726 | if (ret < 0) |
||
727 | goto cbc_des3_ede_err; |
||
728 | |||
729 | des_chip_init(); |
||
730 | CRTCL_SECT_INIT; |
||
731 | |||
732 | |||
733 | |||
734 | printk (KERN_NOTICE "IFX DEU DES initialized%s%s.\n", disable_multiblock ? "" : " (multiblock)", disable_deudma ? "" : " (DMA)"); |
||
735 | return ret; |
||
736 | |||
737 | des_err: |
||
738 | crypto_unregister_alg(&ifxdeu_des_alg); |
||
739 | printk(KERN_ERR "IFX des initialization failed!\n"); |
||
740 | return ret; |
||
741 | ecb_des_err: |
||
742 | crypto_unregister_alg(&ifxdeu_ecb_des_alg); |
||
743 | printk (KERN_ERR "IFX ecb_des initialization failed!\n"); |
||
744 | return ret; |
||
745 | cbc_des_err: |
||
746 | crypto_unregister_alg(&ifxdeu_cbc_des_alg); |
||
747 | printk (KERN_ERR "IFX cbc_des initialization failed!\n"); |
||
748 | return ret; |
||
749 | des3_ede_err: |
||
750 | crypto_unregister_alg(&ifxdeu_des3_ede_alg); |
||
751 | printk(KERN_ERR "IFX des3_ede initialization failed!\n"); |
||
752 | return ret; |
||
753 | ecb_des3_ede_err: |
||
754 | crypto_unregister_alg(&ifxdeu_ecb_des3_ede_alg); |
||
755 | printk (KERN_ERR "IFX ecb_des3_ede initialization failed!\n"); |
||
756 | return ret; |
||
757 | cbc_des3_ede_err: |
||
758 | crypto_unregister_alg(&ifxdeu_cbc_des3_ede_alg); |
||
759 | printk (KERN_ERR "IFX cbc_des3_ede initialization failed!\n"); |
||
760 | return ret; |
||
761 | |||
762 | } |
||
763 | |||
764 | /*! \fn void ifxdeu_fini_des (void) |
||
765 | * \ingroup IFX_DES_FUNCTIONS |
||
766 | * \brief unregister des driver |
||
767 | */ |
||
768 | void ifxdeu_fini_des (void) |
||
769 | { |
||
770 | crypto_unregister_alg (&ifxdeu_des_alg); |
||
771 | crypto_unregister_alg (&ifxdeu_ecb_des_alg); |
||
772 | crypto_unregister_alg (&ifxdeu_cbc_des_alg); |
||
773 | crypto_unregister_alg (&ifxdeu_des3_ede_alg); |
||
774 | crypto_unregister_alg (&ifxdeu_ecb_des3_ede_alg); |
||
775 | crypto_unregister_alg (&ifxdeu_cbc_des3_ede_alg); |
||
776 | |||
777 | } |
||
778 |