[ubicom32]: move new files out from platform support patch
[openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / crypto / des_ubicom32.c
1 /*
2  * arch/ubicom32/crypto/des_ubicom32.c
3  *   Ubicom32 implementation of the DES Cipher Algorithm.
4  *
5  * (C) Copyright 2009, Ubicom, Inc.
6  *
7  * This file is part of the Ubicom32 Linux Kernel Port.
8  *
9  * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10  * it and/or modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation, either version 2 of the
12  * License, or (at your option) any later version.
13  *
14  * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  * the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with the Ubicom32 Linux Kernel Port.  If not,
21  * see <http://www.gnu.org/licenses/>.
22  *
23  * Ubicom32 implementation derived from (with many thanks):
24  *   arch/m68knommu
25  *   arch/blackfin
26  *   arch/parisc
27  */
28 #include <crypto/algapi.h>
29 #include <linux/init.h>
30 #include <linux/module.h>
31
32 #include "crypto_ubicom32.h"
33 extern int crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags);
34
35 #define DES_BLOCK_SIZE 8
36 #define DES_KEY_SIZE 8
37
38 #define DES3_192_KEY_SIZE       (3 * DES_KEY_SIZE)
39 #define DES3_192_BLOCK_SIZE     DES_BLOCK_SIZE
40
41 #define DES3_SUB_KEY(key, i)    (((u8 *)key) + (i * DES_KEY_SIZE))
42
43 enum des_ops {
44         DES_ENCRYPT,
45         DES_DECRYPT,
46
47         DES3_EDE_ENCRYPT,
48         DES3_EDE_DECRYPT,
49
50 #ifdef DES3_EEE
51         DES3_EEE_ENCRYPT,
52         DES3_EEE_DECRYPT,
53 #endif
54 };
55
56 struct ubicom32_des_ctx {
57         u8 key[3 * DES_KEY_SIZE];
58         u32 ctrl;
59         int key_len;
60 };
61
62 static inline void des_hw_set_key(const u8 *key, u8 key_len)
63 {
64         /*
65          * HW 3DES is not tested yet, use DES just as ipOS
66          */
67         DES_SET_KEY(key);
68 }
69
70 static inline void des_hw_cipher(u8 *out, const u8 *in)
71 {
72         SEC_SET_INPUT_2W(in);
73
74         asm volatile (
75         "       ; start DES by writing 0x38(SECURITY_BASE)      \n\t"
76         "       move.4 0x38(%0), #0x01                          \n\t"
77         "       pipe_flush 0                                    \n\t"
78         "                                                       \n\t"
79         "       ; wait for the module to calculate the output   \n\t"
80         "       btst 0x04(%0), #0                               \n\t"
81         "       jmpne.f .-4                                     \n\t"
82                 :
83                 : "a" (SEC_BASE)
84                 : "cc"
85         );
86
87         SEC_GET_OUTPUT_2W(out);
88 }
89
90
91 static void inline des3_hw_ede_encrypt(u8 *keys, u8 *out, const u8 *in)
92 {
93         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
94         des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
95         des_hw_cipher(out, in);
96
97         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
98         des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
99         des_hw_cipher(out, out);
100
101         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
102         des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
103         des_hw_cipher(out, out);
104 }
105
106 static void inline des3_hw_ede_decrypt(u8 *keys, u8 *out, const u8 *in)
107 {
108         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
109         des_hw_set_key(DES3_SUB_KEY(keys, 2), DES_KEY_SIZE);
110         des_hw_cipher(out, in);
111
112         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
113         des_hw_set_key(DES3_SUB_KEY(keys, 1), DES_KEY_SIZE);
114         des_hw_cipher(out, out);
115
116         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
117         des_hw_set_key(DES3_SUB_KEY(keys, 0), DES_KEY_SIZE);
118         des_hw_cipher(out, out);
119 }
120
121 #ifdef DES3_EEE
122 static void inline des3_hw_eee_encrypt(u8 *keys, u8 *out, const u8 *in)
123 {
124         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
125         des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
126         des_hw_cipher(out, in);
127
128         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
129         des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
130         des_hw_cipher(out, out);
131
132         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
133         des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
134         des_hw_cipher(out, out);
135 }
136
137 static void inline des3_hw_eee_decrypt(u8 *keys, u8 *out, const u8 *in)
138 {
139         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
140         des_hw_set_key(DES3_SUB_KEY(keys, 2), 2);
141         des_hw_cipher(out, in);
142
143         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
144         des_hw_set_key(DES3_SUB_KEY(keys, 1), 2);
145         des_hw_cipher(out, out);
146
147         hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
148         des_hw_set_key(DES3_SUB_KEY(keys, 0), 2);
149         des_hw_cipher(out, out);
150 }
151 #endif
152
153 static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
154                       unsigned int keylen)
155 {
156         struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
157         u32 *flags = &tfm->crt_flags;
158         int ret;
159
160         /* test if key is valid (not a weak key) */
161         ret = crypto_des_check_key(key, keylen, flags);
162         if (ret == 0) {
163                 memcpy(dctx->key, key, keylen);
164                 dctx->key_len = keylen;
165                 //dctx->ctrl = (keylen == DES_KEY_SIZE) ? SEC_ALG_DES : SEC_ALG_3DES
166                 /* 2DES and 3DES are both implemented with DES hw function */
167                 dctx->ctrl = SEC_ALG_DES;
168         }
169         return ret;
170 }
171
172 static inline void des_cipher_1b(struct crypto_tfm *tfm, u8 *out, const u8 *in, u32 extra_flags)
173 {
174         const struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
175
176         hw_crypto_lock();
177         hw_crypto_check();
178         hw_crypto_set_ctrl(uctx->ctrl | extra_flags);
179
180         des_hw_set_key(uctx->key, uctx->key_len);
181         des_hw_cipher(out, in);
182
183         hw_crypto_unlock();
184 }
185
186 static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
187 {
188         des_cipher_1b(tfm, out, in, SEC_DIR_ENCRYPT);
189 }
190
191 static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
192 {
193         des_cipher_1b(tfm, out, in, SEC_DIR_DECRYPT);
194 }
195
196 static struct crypto_alg des_alg = {
197         .cra_name               =       "des",
198         .cra_driver_name        =       "des-ubicom32",
199         .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
200         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
201         .cra_blocksize          =       DES_BLOCK_SIZE,
202         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
203         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
204         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
205         .cra_module             =       THIS_MODULE,
206         .cra_list               =       LIST_HEAD_INIT(des_alg.cra_list),
207         .cra_u                  = {
208                 .cipher = {
209                         .cia_min_keysize        =       DES_KEY_SIZE,
210                         .cia_max_keysize        =       DES_KEY_SIZE,
211                         .cia_setkey             =       des_setkey,
212                         .cia_encrypt            =       des_encrypt,
213                         .cia_decrypt            =       des_decrypt,
214                 }
215         }
216 };
217
218 static void ecb_des_ciper_loop(u8 *out, u8 *in, unsigned int n)
219 {
220         while (likely(n)) {
221                 des_hw_cipher(out, in);
222                 out += DES_BLOCK_SIZE;
223                 in += DES_BLOCK_SIZE;
224                 n -= DES_BLOCK_SIZE;
225         }
226 }
227
228 static void ecb_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
229 {
230         while (likely(n)) {
231                 des3_hw_ede_encrypt(keys, out, in);
232
233                 out += DES_BLOCK_SIZE;
234                 in += DES_BLOCK_SIZE;
235                 n -= DES_BLOCK_SIZE;
236         }
237 }
238
239 static void ecb_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
240 {
241         while (likely(n)) {
242                 des3_hw_ede_decrypt(keys, out, in);
243
244                 out += DES_BLOCK_SIZE;
245                 in += DES_BLOCK_SIZE;
246                 n -= DES_BLOCK_SIZE;
247         }
248 }
249
250 #ifdef DES3_EEE
251 static void ecb_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
252 {
253         while (likely(n)) {
254                 des3_hw_eee_encrypt(keys, out, in);
255
256                 out += DES_BLOCK_SIZE;
257                 in += DES_BLOCK_SIZE;
258                 n -= DES_BLOCK_SIZE;
259         }
260 }
261
262 static void ecb_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, unsigned int n)
263 {
264         while (likely(n)) {
265                 des3_hw_eee_decrypt(keys, out, in);
266
267                 out += DES_BLOCK_SIZE;
268                 in += DES_BLOCK_SIZE;
269                 n -= DES_BLOCK_SIZE;
270         }
271 }
272 #endif
273
274 static inline void ecb_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, unsigned int n)
275 {
276         switch (op) {
277         case DES_ENCRYPT:
278         case DES_DECRYPT:
279                 /* set the right algo, direction and key once */
280                 hw_crypto_set_ctrl(SEC_ALG_DES | (op == DES_ENCRYPT ? SEC_DIR_ENCRYPT : 0));
281                 des_hw_set_key(uctx->key, uctx->key_len);
282                 ecb_des_ciper_loop(out, in, n);
283                 break;
284
285         case DES3_EDE_ENCRYPT:
286                 ecb_des3_ede_encrypt_loop(uctx->key, out, in, n);
287                 break;
288
289         case DES3_EDE_DECRYPT:
290                 ecb_des3_ede_decrypt_loop(uctx->key, out, in, n);
291                 break;
292
293 #ifdef DES3_EEE
294         case DES3_EEE_ENCRYPT:
295                 ecb_des3_eee_encrypt_loop(uctx->key, out, in, n);
296                 break;
297
298         case DES3_EEE_DECRYPT:
299                 ecb_des3_eee_decrypt_loop(uctx->key, out, in, n);
300                 break;
301 #endif
302         }
303 }
304
305 static inline void des_xor_2w(u32 *data, u32 *iv)
306 {
307         data[0] ^= iv[0];
308         data[1] ^= iv[1];
309 }
310
311 static void cbc_des_encrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
312 {
313         while (likely(n)) {
314                 des_xor_2w((u32 *)in, (u32 *)iv);
315                 des_hw_cipher(out, in);
316                 SEC_COPY_2W(iv, out);
317                 out += DES_BLOCK_SIZE;
318                 in += DES_BLOCK_SIZE;
319                 n -= DES_BLOCK_SIZE;
320         }
321 }
322
323 static void cbc_des_decrypt_loop(u8 *out, u8 *in, u8 *iv, unsigned int n)
324 {
325         u8 next_iv[DES_BLOCK_SIZE];
326         while (likely(n)) {
327                 SEC_COPY_2W(next_iv, in);
328                 des_hw_cipher(out, in);
329                 des_xor_2w((u32 *)out, (u32 *)iv);
330                 SEC_COPY_2W(iv, next_iv);
331
332                 out += DES_BLOCK_SIZE;
333                 in += DES_BLOCK_SIZE;
334                 n -= DES_BLOCK_SIZE;
335         }
336 }
337
338 static void cbc_des3_ede_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
339 {
340         while (likely(n)) {
341                 des_xor_2w((u32 *)in, (u32 *)iv);
342                 des3_hw_ede_encrypt(keys, out, in);
343                 SEC_COPY_2W(iv, out);
344
345                 out += DES_BLOCK_SIZE;
346                 in += DES_BLOCK_SIZE;
347                 n -= DES_BLOCK_SIZE;
348         }
349 }
350
351 static void cbc_des3_ede_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
352 {
353         u8 next_iv[DES_BLOCK_SIZE];
354         while (likely(n)) {
355                 SEC_COPY_2W(next_iv, in);
356                 des3_hw_ede_decrypt(keys, out, in);
357                 des_xor_2w((u32 *)out, (u32 *)iv);
358                 SEC_COPY_2W(iv, next_iv);
359
360                 out += DES_BLOCK_SIZE;
361                 in += DES_BLOCK_SIZE;
362                 n -= DES_BLOCK_SIZE;
363         }
364 }
365
366 #ifdef DES3_EEE
367 static void cbc_des3_eee_encrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
368 {
369         while (likely(n)) {
370                 des_xor_2w((u32 *)in, (u32 *)iv);
371                 des3_hw_eee_encrypt(keys, out, in);
372                 SEC_COPY_2W(iv, out);
373
374                 out += DES_BLOCK_SIZE;
375                 in += DES_BLOCK_SIZE;
376                 n -= DES_BLOCK_SIZE;
377         }
378 }
379
380 static void cbc_des3_eee_decrypt_loop(u8 *keys, u8 *out, u8 *in, u8 *iv, unsigned int n)
381 {
382         u8 next_iv[DES_BLOCK_SIZE];
383         while (likely(n)) {
384                 SEC_COPY_2W(next_iv, in);
385                 des3_hw_eee_decrypt(keys, out, in);
386                 des_xor_2w((u32 *)out, (u32 *)iv);
387                 SEC_COPY_2W(iv, next_iv);
388
389                 out += DES_BLOCK_SIZE;
390                 in += DES_BLOCK_SIZE;
391                 n -= DES_BLOCK_SIZE;
392         }
393 }
394 #endif
395
396 static inline void cbc_des_cipher_n(struct ubicom32_des_ctx *uctx, enum des_ops op, u8 *out, u8 *in, u8 *iv, unsigned int n)
397 {
398         switch (op) {
399         case DES_ENCRYPT:
400                 hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_ENCRYPT);
401                 des_hw_set_key(uctx->key, uctx->key_len);
402                 cbc_des_encrypt_loop(out, in, iv, n);
403                 break;
404
405         case DES_DECRYPT:
406                 /* set the right algo, direction and key once */
407                 hw_crypto_set_ctrl(SEC_ALG_DES | SEC_DIR_DECRYPT);
408                 des_hw_set_key(uctx->key, uctx->key_len);
409                 cbc_des_decrypt_loop(out, in, iv, n);
410                 break;
411
412         case DES3_EDE_ENCRYPT:
413                 cbc_des3_ede_encrypt_loop(uctx->key, out, in, iv, n);
414                 break;
415
416         case DES3_EDE_DECRYPT:
417                 cbc_des3_ede_decrypt_loop(uctx->key, out, in, iv, n);
418                 break;
419
420 #ifdef DES3_EEE
421         case DES3_EEE_ENCRYPT:
422                 cbc_des3_eee_encrypt_loop(uctx->key, out, in, iv, n);
423                 break;
424
425         case DES3_EEE_DECRYPT:
426                 cbc_des3_eee_decrypt_loop(uctx->key, out, in, iv, n);
427                 break;
428 #endif
429         }
430 }
431
432 static int des_cipher(struct blkcipher_desc *desc, struct scatterlist *dst,
433                       struct scatterlist *src, unsigned int nbytes, u32 extra_flags, enum des_ops op)
434 {
435         struct ubicom32_des_ctx *uctx = crypto_blkcipher_ctx(desc->tfm);
436         int ret;
437
438         struct blkcipher_walk walk;
439         blkcipher_walk_init(&walk, dst, src, nbytes);
440         ret = blkcipher_walk_virt(desc, &walk);
441         if (ret) {
442                 return ret;
443         }
444
445         hw_crypto_lock();
446         hw_crypto_check();
447
448         while ((nbytes = walk.nbytes)) {
449                 /* only use complete blocks */
450                 unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
451                 u8 *out = walk.dst.virt.addr;
452                 u8 *in = walk.src.virt.addr;
453
454                 /* finish n/16 blocks */
455                 if (extra_flags & SEC_CBC_SET) {
456                         cbc_des_cipher_n(uctx, op, out, in, walk.iv, n);
457                 } else {
458                         ecb_des_cipher_n(uctx, op, out, in, n);
459                 }
460
461                 nbytes &= DES_BLOCK_SIZE - 1;
462                 ret = blkcipher_walk_done(desc, &walk, nbytes);
463         }
464
465         hw_crypto_unlock();
466         return ret;
467 }
468
469 static int ecb_des_encrypt(struct blkcipher_desc *desc,
470                            struct scatterlist *dst, struct scatterlist *src,
471                            unsigned int nbytes)
472 {
473         return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_ENCRYPT);
474 }
475
476 static int ecb_des_decrypt(struct blkcipher_desc *desc,
477                            struct scatterlist *dst, struct scatterlist *src,
478                            unsigned int nbytes)
479 {
480         return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES_DECRYPT);
481 }
482
483 static struct crypto_alg ecb_des_alg = {
484         .cra_name               =       "ecb(des)",
485         .cra_driver_name        =       "ecb-des-ubicom32",
486         .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
487         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
488         .cra_blocksize          =       DES_BLOCK_SIZE,
489         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
490         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
491         .cra_type               =       &crypto_blkcipher_type,
492         .cra_module             =       THIS_MODULE,
493         .cra_list               =       LIST_HEAD_INIT(ecb_des_alg.cra_list),
494         .cra_u                  = {
495                 .blkcipher = {
496                         .min_keysize            =       DES_KEY_SIZE,
497                         .max_keysize            =       DES_KEY_SIZE,
498                         .setkey                 =       des_setkey,
499                         .encrypt                =       ecb_des_encrypt,
500                         .decrypt                =       ecb_des_decrypt,
501                 }
502         }
503 };
504
505 static int cbc_des_encrypt(struct blkcipher_desc *desc,
506                            struct scatterlist *dst, struct scatterlist *src,
507                            unsigned int nbytes)
508 {
509         return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_ENCRYPT);
510 }
511
512 static int cbc_des_decrypt(struct blkcipher_desc *desc,
513                            struct scatterlist *dst, struct scatterlist *src,
514                            unsigned int nbytes)
515 {
516         return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES_DECRYPT);
517 }
518
519 static struct crypto_alg cbc_des_alg = {
520         .cra_name               =       "cbc(des)",
521         .cra_driver_name        =       "cbc-des-ubicom32",
522         .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
523         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
524         .cra_blocksize          =       DES_BLOCK_SIZE,
525         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
526         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
527         .cra_type               =       &crypto_blkcipher_type,
528         .cra_module             =       THIS_MODULE,
529         .cra_list               =       LIST_HEAD_INIT(cbc_des_alg.cra_list),
530         .cra_u                  = {
531                 .blkcipher = {
532                         .min_keysize            =       DES_KEY_SIZE,
533                         .max_keysize            =       DES_KEY_SIZE,
534                         .ivsize                 =       DES_BLOCK_SIZE,
535                         .setkey                 =       des_setkey,
536                         .encrypt                =       cbc_des_encrypt,
537                         .decrypt                =       cbc_des_decrypt,
538                 }
539         }
540 };
541
542 /*
543  * RFC2451:
544  *
545  *   For DES-EDE3, there is no known need to reject weak or
546  *   complementation keys.  Any weakness is obviated by the use of
547  *   multiple keys.
548  *
549  *   However, if the first two or last two independent 64-bit keys are
550  *   equal (k1 == k2 or k2 == k3), then the DES3 operation is simply the
551  *   same as DES.  Implementers MUST reject keys that exhibit this
552  *   property.
553  *
554  */
555 static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
556                            unsigned int keylen)
557 {
558         int i, ret;
559         struct ubicom32_des_ctx *dctx = crypto_tfm_ctx(tfm);
560         const u8 *temp_key = key;
561         u32 *flags = &tfm->crt_flags;
562
563         if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
564             memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
565                    DES_KEY_SIZE))) {
566
567                 *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
568                 return -EINVAL;
569         }
570         for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
571                 ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
572                 if (ret < 0)
573                         return ret;
574         }
575         memcpy(dctx->key, key, keylen);
576         dctx->ctrl = SEC_ALG_DES;       //hw 3DES not working yet
577         dctx->key_len = keylen;
578         return 0;
579 }
580
581 static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
582 {
583         struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
584
585         hw_crypto_lock();
586         hw_crypto_check();
587
588         des3_hw_ede_encrypt(uctx->key, dst, src);
589
590         hw_crypto_unlock();
591 }
592
593 static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
594 {
595         struct ubicom32_des_ctx *uctx = crypto_tfm_ctx(tfm);
596
597         hw_crypto_lock();
598         hw_crypto_check();
599
600         des3_hw_ede_decrypt(uctx->key, dst, src);
601
602         hw_crypto_unlock();
603 }
604
605 static struct crypto_alg des3_192_alg = {
606         .cra_name               =       "des3_ede",
607         .cra_driver_name        =       "des3_ede-ubicom32",
608         .cra_priority           =       CRYPTO_UBICOM32_PRIORITY,
609         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
610         .cra_blocksize          =       DES3_192_BLOCK_SIZE,
611         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
612         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
613         .cra_module             =       THIS_MODULE,
614         .cra_list               =       LIST_HEAD_INIT(des3_192_alg.cra_list),
615         .cra_u                  = {
616                 .cipher = {
617                         .cia_min_keysize        =       DES3_192_KEY_SIZE,
618                         .cia_max_keysize        =       DES3_192_KEY_SIZE,
619                         .cia_setkey             =       des3_192_setkey,
620                         .cia_encrypt            =       des3_192_encrypt,
621                         .cia_decrypt            =       des3_192_decrypt,
622                 }
623         }
624 };
625
626 static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
627                                 struct scatterlist *dst,
628                                 struct scatterlist *src, unsigned int nbytes)
629 {
630         return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_ENCRYPT);
631 }
632
633 static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
634                                 struct scatterlist *dst,
635                                 struct scatterlist *src, unsigned int nbytes)
636 {
637         return des_cipher(desc, dst, src, nbytes, SEC_CBC_NONE, DES3_EDE_DECRYPT);
638 }
639
640 static struct crypto_alg ecb_des3_192_alg = {
641         .cra_name               =       "ecb(des3_ede)",
642         .cra_driver_name        =       "ecb-des3_ede-ubicom32",
643         .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
644         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
645         .cra_blocksize          =       DES3_192_BLOCK_SIZE,
646         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
647         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
648         .cra_type               =       &crypto_blkcipher_type,
649         .cra_module             =       THIS_MODULE,
650         .cra_list               =       LIST_HEAD_INIT(
651                                                 ecb_des3_192_alg.cra_list),
652         .cra_u                  = {
653                 .blkcipher = {
654                         .min_keysize            =       DES3_192_KEY_SIZE,
655                         .max_keysize            =       DES3_192_KEY_SIZE,
656                         .setkey                 =       des3_192_setkey,
657                         .encrypt                =       ecb_des3_192_encrypt,
658                         .decrypt                =       ecb_des3_192_decrypt,
659                 }
660         }
661 };
662
663 static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
664                                 struct scatterlist *dst,
665                                 struct scatterlist *src, unsigned int nbytes)
666 {
667         return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_ENCRYPT);
668 }
669
670 static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
671                                 struct scatterlist *dst,
672                                 struct scatterlist *src, unsigned int nbytes)
673 {
674         return des_cipher(desc, dst, src, nbytes, SEC_CBC_SET, DES3_EDE_DECRYPT);
675 }
676
677 static struct crypto_alg cbc_des3_192_alg = {
678         .cra_name               =       "cbc(des3_ede)",
679         .cra_driver_name        =       "cbc-des3_ede-ubicom32",
680         .cra_priority           =       CRYPTO_UBICOM32_COMPOSITE_PRIORITY,
681         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
682         .cra_blocksize          =       DES3_192_BLOCK_SIZE,
683         .cra_ctxsize            =       sizeof(struct ubicom32_des_ctx),
684         .cra_alignmask          =       CRYPTO_UBICOM32_ALIGNMENT - 1,
685         .cra_type               =       &crypto_blkcipher_type,
686         .cra_module             =       THIS_MODULE,
687         .cra_list               =       LIST_HEAD_INIT(
688                                                 cbc_des3_192_alg.cra_list),
689         .cra_u                  = {
690                 .blkcipher = {
691                         .min_keysize            =       DES3_192_KEY_SIZE,
692                         .max_keysize            =       DES3_192_KEY_SIZE,
693                         .ivsize                 =       DES3_192_BLOCK_SIZE,
694                         .setkey                 =       des3_192_setkey,
695                         .encrypt                =       cbc_des3_192_encrypt,
696                         .decrypt                =       cbc_des3_192_decrypt,
697                 }
698         }
699 };
700
701 static int init(void)
702 {
703         int ret = 0;
704
705         hw_crypto_init();
706
707         ret = crypto_register_alg(&des_alg);
708         if (ret)
709                 goto des_err;
710         ret = crypto_register_alg(&ecb_des_alg);
711         if (ret)
712                 goto ecb_des_err;
713         ret = crypto_register_alg(&cbc_des_alg);
714         if (ret)
715                 goto cbc_des_err;
716
717         ret = crypto_register_alg(&des3_192_alg);
718         if (ret)
719                 goto des3_192_err;
720         ret = crypto_register_alg(&ecb_des3_192_alg);
721         if (ret)
722                 goto ecb_des3_192_err;
723         ret = crypto_register_alg(&cbc_des3_192_alg);
724         if (ret)
725                 goto cbc_des3_192_err;
726
727 out:
728         return ret;
729
730 cbc_des3_192_err:
731         crypto_unregister_alg(&ecb_des3_192_alg);
732 ecb_des3_192_err:
733         crypto_unregister_alg(&des3_192_alg);
734 des3_192_err:
735         crypto_unregister_alg(&cbc_des_alg);
736 cbc_des_err:
737         crypto_unregister_alg(&ecb_des_alg);
738 ecb_des_err:
739         crypto_unregister_alg(&des_alg);
740 des_err:
741         goto out;
742 }
743
744 static void __exit fini(void)
745 {
746         crypto_unregister_alg(&cbc_des3_192_alg);
747         crypto_unregister_alg(&ecb_des3_192_alg);
748         crypto_unregister_alg(&des3_192_alg);
749         crypto_unregister_alg(&cbc_des_alg);
750         crypto_unregister_alg(&ecb_des_alg);
751         crypto_unregister_alg(&des_alg);
752 }
753
754 module_init(init);
755 module_exit(fini);
756
757 MODULE_ALIAS("des");
758 MODULE_ALIAS("des3_ede");
759
760 MODULE_LICENSE("GPL");
761 MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms");