crypto: xcbc - Fix incorrect error value when creating instance
[safe/jmp/linux-2.6] / crypto / xcbc.c
1 /*
2  * Copyright (C)2006 USAGI/WIDE Project
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  * Author:
19  *      Kazunori Miyazawa <miyazawa@linux-ipv6.org>
20  */
21
22 #include <crypto/internal/hash.h>
23 #include <linux/err.h>
24 #include <linux/kernel.h>
25
26 static u_int32_t ks[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
27                            0x02020202, 0x02020202, 0x02020202, 0x02020202,
28                            0x03030303, 0x03030303, 0x03030303, 0x03030303};
29 /*
30  * +------------------------
31  * | <parent tfm>
32  * +------------------------
33  * | crypto_xcbc_ctx
34  * +------------------------
35  * | odds (block size)
36  * +------------------------
37  * | prev (block size)
38  * +------------------------
39  * | key (block size)
40  * +------------------------
41  * | consts (block size * 3)
42  * +------------------------
43  */
44 struct crypto_xcbc_ctx {
45         struct crypto_cipher *child;
46         u8 *odds;
47         u8 *prev;
48         u8 *key;
49         u8 *consts;
50         void (*xor)(u8 *a, const u8 *b, unsigned int bs);
51         unsigned int keylen;
52         unsigned int len;
53 };
54
55 static void xor_128(u8 *a, const u8 *b, unsigned int bs)
56 {
57         ((u32 *)a)[0] ^= ((u32 *)b)[0];
58         ((u32 *)a)[1] ^= ((u32 *)b)[1];
59         ((u32 *)a)[2] ^= ((u32 *)b)[2];
60         ((u32 *)a)[3] ^= ((u32 *)b)[3];
61 }
62
63 static int _crypto_xcbc_digest_setkey(struct crypto_shash *parent,
64                                       struct crypto_xcbc_ctx *ctx)
65 {
66         int bs = crypto_shash_blocksize(parent);
67         int err = 0;
68         u8 key1[bs];
69
70         if ((err = crypto_cipher_setkey(ctx->child, ctx->key, ctx->keylen)))
71             return err;
72
73         crypto_cipher_encrypt_one(ctx->child, key1, ctx->consts);
74
75         return crypto_cipher_setkey(ctx->child, key1, bs);
76 }
77
78 static int crypto_xcbc_digest_setkey(struct crypto_shash *parent,
79                                      const u8 *inkey, unsigned int keylen)
80 {
81         struct crypto_xcbc_ctx *ctx = crypto_shash_ctx(parent);
82
83         if (keylen != crypto_cipher_blocksize(ctx->child))
84                 return -EINVAL;
85
86         ctx->keylen = keylen;
87         memcpy(ctx->key, inkey, keylen);
88         ctx->consts = (u8*)ks;
89
90         return _crypto_xcbc_digest_setkey(parent, ctx);
91 }
92
93 static int crypto_xcbc_digest_init(struct shash_desc *pdesc)
94 {
95         struct crypto_xcbc_ctx *ctx = crypto_shash_ctx(pdesc->tfm);
96         int bs = crypto_shash_blocksize(pdesc->tfm);
97
98         ctx->len = 0;
99         memset(ctx->odds, 0, bs);
100         memset(ctx->prev, 0, bs);
101
102         return 0;
103 }
104
105 static int crypto_xcbc_digest_update(struct shash_desc *pdesc, const u8 *p,
106                                      unsigned int len)
107 {
108         struct crypto_shash *parent = pdesc->tfm;
109         struct crypto_xcbc_ctx *ctx = crypto_shash_ctx(parent);
110         struct crypto_cipher *tfm = ctx->child;
111         int bs = crypto_shash_blocksize(parent);
112
113         /* checking the data can fill the block */
114         if ((ctx->len + len) <= bs) {
115                 memcpy(ctx->odds + ctx->len, p, len);
116                 ctx->len += len;
117                 return 0;
118         }
119
120         /* filling odds with new data and encrypting it */
121         memcpy(ctx->odds + ctx->len, p, bs - ctx->len);
122         len -= bs - ctx->len;
123         p += bs - ctx->len;
124
125         ctx->xor(ctx->prev, ctx->odds, bs);
126         crypto_cipher_encrypt_one(tfm, ctx->prev, ctx->prev);
127
128         /* clearing the length */
129         ctx->len = 0;
130
131         /* encrypting the rest of data */
132         while (len > bs) {
133                 ctx->xor(ctx->prev, p, bs);
134                 crypto_cipher_encrypt_one(tfm, ctx->prev, ctx->prev);
135                 p += bs;
136                 len -= bs;
137         }
138
139         /* keeping the surplus of blocksize */
140         if (len) {
141                 memcpy(ctx->odds, p, len);
142                 ctx->len = len;
143         }
144
145         return 0;
146 }
147
148 static int crypto_xcbc_digest_final(struct shash_desc *pdesc, u8 *out)
149 {
150         struct crypto_shash *parent = pdesc->tfm;
151         struct crypto_xcbc_ctx *ctx = crypto_shash_ctx(parent);
152         struct crypto_cipher *tfm = ctx->child;
153         int bs = crypto_shash_blocksize(parent);
154         int err = 0;
155
156         if (ctx->len == bs) {
157                 u8 key2[bs];
158
159                 if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
160                         return err;
161
162                 crypto_cipher_encrypt_one(tfm, key2,
163                                           (u8 *)(ctx->consts + bs));
164
165                 ctx->xor(ctx->prev, ctx->odds, bs);
166                 ctx->xor(ctx->prev, key2, bs);
167                 _crypto_xcbc_digest_setkey(parent, ctx);
168
169                 crypto_cipher_encrypt_one(tfm, out, ctx->prev);
170         } else {
171                 u8 key3[bs];
172                 unsigned int rlen;
173                 u8 *p = ctx->odds + ctx->len;
174                 *p = 0x80;
175                 p++;
176
177                 rlen = bs - ctx->len -1;
178                 if (rlen)
179                         memset(p, 0, rlen);
180
181                 if ((err = crypto_cipher_setkey(tfm, ctx->key, ctx->keylen)) != 0)
182                         return err;
183
184                 crypto_cipher_encrypt_one(tfm, key3,
185                                           (u8 *)(ctx->consts + bs * 2));
186
187                 ctx->xor(ctx->prev, ctx->odds, bs);
188                 ctx->xor(ctx->prev, key3, bs);
189
190                 _crypto_xcbc_digest_setkey(parent, ctx);
191
192                 crypto_cipher_encrypt_one(tfm, out, ctx->prev);
193         }
194
195         return 0;
196 }
197
198 static int xcbc_init_tfm(struct crypto_tfm *tfm)
199 {
200         struct crypto_cipher *cipher;
201         struct crypto_instance *inst = (void *)tfm->__crt_alg;
202         struct crypto_spawn *spawn = crypto_instance_ctx(inst);
203         struct crypto_xcbc_ctx *ctx = crypto_tfm_ctx(tfm);
204         int bs = crypto_tfm_alg_blocksize(tfm);
205
206         cipher = crypto_spawn_cipher(spawn);
207         if (IS_ERR(cipher))
208                 return PTR_ERR(cipher);
209
210         switch(bs) {
211         case 16:
212                 ctx->xor = xor_128;
213                 break;
214         default:
215                 return -EINVAL;
216         }
217
218         ctx->child = cipher;
219         ctx->odds = (u8*)(ctx+1);
220         ctx->prev = ctx->odds + bs;
221         ctx->key = ctx->prev + bs;
222
223         return 0;
224 };
225
226 static void xcbc_exit_tfm(struct crypto_tfm *tfm)
227 {
228         struct crypto_xcbc_ctx *ctx = crypto_tfm_ctx(tfm);
229         crypto_free_cipher(ctx->child);
230 }
231
232 static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
233 {
234         struct shash_instance *inst;
235         struct crypto_alg *alg;
236         int err;
237
238         err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
239         if (err)
240                 return err;
241
242         alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
243                                   CRYPTO_ALG_TYPE_MASK);
244         if (IS_ERR(alg))
245                 return PTR_ERR(alg);
246
247         switch(alg->cra_blocksize) {
248         case 16:
249                 break;
250         default:
251                 goto out_put_alg;
252         }
253
254         inst = shash_alloc_instance("xcbc", alg);
255         err = PTR_ERR(inst);
256         if (IS_ERR(inst))
257                 goto out_put_alg;
258
259         err = crypto_init_spawn(shash_instance_ctx(inst), alg,
260                                 shash_crypto_instance(inst),
261                                 CRYPTO_ALG_TYPE_MASK);
262         if (err)
263                 goto out_free_inst;
264
265         inst->alg.base.cra_priority = alg->cra_priority;
266         inst->alg.base.cra_blocksize = alg->cra_blocksize;
267         inst->alg.base.cra_alignmask = alg->cra_alignmask;
268
269         inst->alg.digestsize = alg->cra_blocksize;
270         inst->alg.base.cra_ctxsize = sizeof(struct crypto_xcbc_ctx) +
271                                      ALIGN(alg->cra_blocksize * 3,
272                                            sizeof(void *));
273         inst->alg.base.cra_init = xcbc_init_tfm;
274         inst->alg.base.cra_exit = xcbc_exit_tfm;
275
276         inst->alg.init = crypto_xcbc_digest_init;
277         inst->alg.update = crypto_xcbc_digest_update;
278         inst->alg.final = crypto_xcbc_digest_final;
279         inst->alg.setkey = crypto_xcbc_digest_setkey;
280
281         err = shash_register_instance(tmpl, inst);
282         if (err) {
283 out_free_inst:
284                 shash_free_instance(shash_crypto_instance(inst));
285         }
286
287 out_put_alg:
288         crypto_mod_put(alg);
289         return err;
290 }
291
292 static struct crypto_template crypto_xcbc_tmpl = {
293         .name = "xcbc",
294         .create = xcbc_create,
295         .free = shash_free_instance,
296         .module = THIS_MODULE,
297 };
298
299 static int __init crypto_xcbc_module_init(void)
300 {
301         return crypto_register_template(&crypto_xcbc_tmpl);
302 }
303
304 static void __exit crypto_xcbc_module_exit(void)
305 {
306         crypto_unregister_template(&crypto_xcbc_tmpl);
307 }
308
309 module_init(crypto_xcbc_module_init);
310 module_exit(crypto_xcbc_module_exit);
311
312 MODULE_LICENSE("GPL");
313 MODULE_DESCRIPTION("XCBC keyed hash algorithm");