[CRYPTO] null: Add null blkcipher algorithm
[linux-2.6.git] / crypto / crypto_null.c
1 /* 
2  * Cryptographic API.
3  *
4  * Null algorithms, aka Much Ado About Nothing.
5  *
6  * These are needed for IPsec, and may be useful in general for
7  * testing & debugging.
8  * 
9  * The null cipher is compliant with RFC2410.
10  *
11  * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  */
19
20 #include <crypto/internal/skcipher.h>
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/mm.h>
24 #include <linux/string.h>
25
26 #define NULL_KEY_SIZE           0
27 #define NULL_BLOCK_SIZE         1
28 #define NULL_DIGEST_SIZE        0
29 #define NULL_IV_SIZE            0
30
31 static int null_compress(struct crypto_tfm *tfm, const u8 *src,
32                          unsigned int slen, u8 *dst, unsigned int *dlen)
33 {
34         if (slen > *dlen)
35                 return -EINVAL;
36         memcpy(dst, src, slen);
37         *dlen = slen;
38         return 0;
39 }
40
41 static void null_init(struct crypto_tfm *tfm)
42 { }
43
44 static void null_update(struct crypto_tfm *tfm, const u8 *data,
45                         unsigned int len)
46 { }
47
48 static void null_final(struct crypto_tfm *tfm, u8 *out)
49 { }
50
51 static int null_setkey(struct crypto_tfm *tfm, const u8 *key,
52                        unsigned int keylen)
53 { return 0; }
54
55 static void null_crypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
56 {
57         memcpy(dst, src, NULL_BLOCK_SIZE);
58 }
59
60 static int skcipher_null_crypt(struct blkcipher_desc *desc,
61                                struct scatterlist *dst,
62                                struct scatterlist *src, unsigned int nbytes)
63 {
64         struct blkcipher_walk walk;
65         int err;
66
67         blkcipher_walk_init(&walk, dst, src, nbytes);
68         err = blkcipher_walk_virt(desc, &walk);
69
70         while (walk.nbytes) {
71                 if (walk.src.virt.addr != walk.dst.virt.addr)
72                         memcpy(walk.dst.virt.addr, walk.src.virt.addr,
73                                walk.nbytes);
74                 err = blkcipher_walk_done(desc, &walk, 0);
75         }
76
77         return err;
78 }
79
80 static struct crypto_alg compress_null = {
81         .cra_name               =       "compress_null",
82         .cra_flags              =       CRYPTO_ALG_TYPE_COMPRESS,
83         .cra_blocksize          =       NULL_BLOCK_SIZE,
84         .cra_ctxsize            =       0,
85         .cra_module             =       THIS_MODULE,
86         .cra_list               =       LIST_HEAD_INIT(compress_null.cra_list),
87         .cra_u                  =       { .compress = {
88         .coa_compress           =       null_compress,
89         .coa_decompress         =       null_compress } }
90 };
91
92 static struct crypto_alg digest_null = {
93         .cra_name               =       "digest_null",
94         .cra_flags              =       CRYPTO_ALG_TYPE_DIGEST,
95         .cra_blocksize          =       NULL_BLOCK_SIZE,
96         .cra_ctxsize            =       0,
97         .cra_module             =       THIS_MODULE,
98         .cra_list               =       LIST_HEAD_INIT(digest_null.cra_list),   
99         .cra_u                  =       { .digest = {
100         .dia_digestsize         =       NULL_DIGEST_SIZE,
101         .dia_init               =       null_init,
102         .dia_update             =       null_update,
103         .dia_final              =       null_final } }
104 };
105
106 static struct crypto_alg cipher_null = {
107         .cra_name               =       "cipher_null",
108         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
109         .cra_blocksize          =       NULL_BLOCK_SIZE,
110         .cra_ctxsize            =       0,
111         .cra_module             =       THIS_MODULE,
112         .cra_list               =       LIST_HEAD_INIT(cipher_null.cra_list),
113         .cra_u                  =       { .cipher = {
114         .cia_min_keysize        =       NULL_KEY_SIZE,
115         .cia_max_keysize        =       NULL_KEY_SIZE,
116         .cia_setkey             =       null_setkey,
117         .cia_encrypt            =       null_crypt,
118         .cia_decrypt            =       null_crypt } }
119 };
120
121 static struct crypto_alg skcipher_null = {
122         .cra_name               =       "ecb(cipher_null)",
123         .cra_driver_name        =       "ecb-cipher_null",
124         .cra_priority           =       100,
125         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
126         .cra_blocksize          =       NULL_BLOCK_SIZE,
127         .cra_type               =       &crypto_blkcipher_type,
128         .cra_ctxsize            =       0,
129         .cra_module             =       THIS_MODULE,
130         .cra_list               =       LIST_HEAD_INIT(skcipher_null.cra_list),
131         .cra_u                  =       { .blkcipher = {
132         .min_keysize            =       NULL_KEY_SIZE,
133         .max_keysize            =       NULL_KEY_SIZE,
134         .ivsize                 =       NULL_IV_SIZE,
135         .setkey                 =       null_setkey,
136         .encrypt                =       skcipher_null_crypt,
137         .decrypt                =       skcipher_null_crypt } }
138 };
139
140 MODULE_ALIAS("compress_null");
141 MODULE_ALIAS("digest_null");
142 MODULE_ALIAS("cipher_null");
143
144 static int __init init(void)
145 {
146         int ret = 0;
147         
148         ret = crypto_register_alg(&cipher_null);
149         if (ret < 0)
150                 goto out;
151
152         ret = crypto_register_alg(&skcipher_null);
153         if (ret < 0)
154                 goto out_unregister_cipher;
155
156         ret = crypto_register_alg(&digest_null);
157         if (ret < 0)
158                 goto out_unregister_skcipher;
159
160         ret = crypto_register_alg(&compress_null);
161         if (ret < 0)
162                 goto out_unregister_digest;
163
164 out:    
165         return ret;
166
167 out_unregister_digest:
168         crypto_unregister_alg(&digest_null);
169 out_unregister_skcipher:
170         crypto_unregister_alg(&skcipher_null);
171 out_unregister_cipher:
172         crypto_unregister_alg(&cipher_null);
173         goto out;
174 }
175
176 static void __exit fini(void)
177 {
178         crypto_unregister_alg(&compress_null);
179         crypto_unregister_alg(&digest_null);
180         crypto_unregister_alg(&skcipher_null);
181         crypto_unregister_alg(&cipher_null);
182 }
183
184 module_init(init);
185 module_exit(fini);
186
187 MODULE_LICENSE("GPL");
188 MODULE_DESCRIPTION("Null Cryptographic Algorithms");