2 * Copyright (C)2006 USAGI/WIDE Project
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.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * Kazunori Miyazawa <miyazawa@linux-ipv6.org>
21 #include <crypto/internal/hash.h>
22 #include <linux/err.h>
23 #include <linux/kernel.h>
24 #include <linux/module.h>
26 static u_int32_t ks
[12] = {0x01010101, 0x01010101, 0x01010101, 0x01010101,
27 0x02020202, 0x02020202, 0x02020202, 0x02020202,
28 0x03030303, 0x03030303, 0x03030303, 0x03030303};
31 * +------------------------
33 * +------------------------
35 * +------------------------
36 * | consts (block size * 2)
37 * +------------------------
40 struct crypto_cipher
*child
;
45 * +------------------------
47 * +------------------------
49 * +------------------------
51 * +------------------------
53 * +------------------------
55 struct xcbc_desc_ctx
{
60 #define XCBC_BLOCKSIZE 16
62 static int crypto_xcbc_digest_setkey(struct crypto_shash
*parent
,
63 const u8
*inkey
, unsigned int keylen
)
65 unsigned long alignmask
= crypto_shash_alignmask(parent
);
66 struct xcbc_tfm_ctx
*ctx
= crypto_shash_ctx(parent
);
67 u8
*consts
= PTR_ALIGN(&ctx
->ctx
[0], alignmask
+ 1);
69 u8 key1
[XCBC_BLOCKSIZE
];
70 int bs
= sizeof(key1
);
72 if ((err
= crypto_cipher_setkey(ctx
->child
, inkey
, keylen
)))
75 crypto_cipher_encrypt_one(ctx
->child
, consts
, (u8
*)ks
+ bs
);
76 crypto_cipher_encrypt_one(ctx
->child
, consts
+ bs
, (u8
*)ks
+ bs
* 2);
77 crypto_cipher_encrypt_one(ctx
->child
, key1
, (u8
*)ks
);
79 return crypto_cipher_setkey(ctx
->child
, key1
, bs
);
83 static int crypto_xcbc_digest_init(struct shash_desc
*pdesc
)
85 unsigned long alignmask
= crypto_shash_alignmask(pdesc
->tfm
);
86 struct xcbc_desc_ctx
*ctx
= shash_desc_ctx(pdesc
);
87 int bs
= crypto_shash_blocksize(pdesc
->tfm
);
88 u8
*prev
= PTR_ALIGN(&ctx
->ctx
[0], alignmask
+ 1) + bs
;
96 static int crypto_xcbc_digest_update(struct shash_desc
*pdesc
, const u8
*p
,
99 struct crypto_shash
*parent
= pdesc
->tfm
;
100 unsigned long alignmask
= crypto_shash_alignmask(parent
);
101 struct xcbc_tfm_ctx
*tctx
= crypto_shash_ctx(parent
);
102 struct xcbc_desc_ctx
*ctx
= shash_desc_ctx(pdesc
);
103 struct crypto_cipher
*tfm
= tctx
->child
;
104 int bs
= crypto_shash_blocksize(parent
);
105 u8
*odds
= PTR_ALIGN(&ctx
->ctx
[0], alignmask
+ 1);
106 u8
*prev
= odds
+ bs
;
108 /* checking the data can fill the block */
109 if ((ctx
->len
+ len
) <= bs
) {
110 memcpy(odds
+ ctx
->len
, p
, len
);
115 /* filling odds with new data and encrypting it */
116 memcpy(odds
+ ctx
->len
, p
, bs
- ctx
->len
);
117 len
-= bs
- ctx
->len
;
120 crypto_xor(prev
, odds
, bs
);
121 crypto_cipher_encrypt_one(tfm
, prev
, prev
);
123 /* clearing the length */
126 /* encrypting the rest of data */
128 crypto_xor(prev
, p
, bs
);
129 crypto_cipher_encrypt_one(tfm
, prev
, prev
);
134 /* keeping the surplus of blocksize */
136 memcpy(odds
, p
, len
);
143 static int crypto_xcbc_digest_final(struct shash_desc
*pdesc
, u8
*out
)
145 struct crypto_shash
*parent
= pdesc
->tfm
;
146 unsigned long alignmask
= crypto_shash_alignmask(parent
);
147 struct xcbc_tfm_ctx
*tctx
= crypto_shash_ctx(parent
);
148 struct xcbc_desc_ctx
*ctx
= shash_desc_ctx(pdesc
);
149 struct crypto_cipher
*tfm
= tctx
->child
;
150 int bs
= crypto_shash_blocksize(parent
);
151 u8
*consts
= PTR_ALIGN(&tctx
->ctx
[0], alignmask
+ 1);
152 u8
*odds
= PTR_ALIGN(&ctx
->ctx
[0], alignmask
+ 1);
153 u8
*prev
= odds
+ bs
;
154 unsigned int offset
= 0;
156 if (ctx
->len
!= bs
) {
158 u8
*p
= odds
+ ctx
->len
;
163 rlen
= bs
- ctx
->len
-1;
170 crypto_xor(prev
, odds
, bs
);
171 crypto_xor(prev
, consts
+ offset
, bs
);
173 crypto_cipher_encrypt_one(tfm
, out
, prev
);
178 static int xcbc_init_tfm(struct crypto_tfm
*tfm
)
180 struct crypto_cipher
*cipher
;
181 struct crypto_instance
*inst
= (void *)tfm
->__crt_alg
;
182 struct crypto_spawn
*spawn
= crypto_instance_ctx(inst
);
183 struct xcbc_tfm_ctx
*ctx
= crypto_tfm_ctx(tfm
);
185 cipher
= crypto_spawn_cipher(spawn
);
187 return PTR_ERR(cipher
);
194 static void xcbc_exit_tfm(struct crypto_tfm
*tfm
)
196 struct xcbc_tfm_ctx
*ctx
= crypto_tfm_ctx(tfm
);
197 crypto_free_cipher(ctx
->child
);
200 static int xcbc_create(struct crypto_template
*tmpl
, struct rtattr
**tb
)
202 struct shash_instance
*inst
;
203 struct crypto_alg
*alg
;
204 unsigned long alignmask
;
207 err
= crypto_check_attr_type(tb
, CRYPTO_ALG_TYPE_SHASH
);
211 alg
= crypto_get_attr_alg(tb
, CRYPTO_ALG_TYPE_CIPHER
,
212 CRYPTO_ALG_TYPE_MASK
);
216 switch(alg
->cra_blocksize
) {
223 inst
= shash_alloc_instance("xcbc", alg
);
228 err
= crypto_init_spawn(shash_instance_ctx(inst
), alg
,
229 shash_crypto_instance(inst
),
230 CRYPTO_ALG_TYPE_MASK
);
234 alignmask
= alg
->cra_alignmask
| 3;
235 inst
->alg
.base
.cra_alignmask
= alignmask
;
236 inst
->alg
.base
.cra_priority
= alg
->cra_priority
;
237 inst
->alg
.base
.cra_blocksize
= alg
->cra_blocksize
;
239 inst
->alg
.digestsize
= alg
->cra_blocksize
;
240 inst
->alg
.descsize
= ALIGN(sizeof(struct xcbc_desc_ctx
),
241 crypto_tfm_ctx_alignment()) +
243 ~(crypto_tfm_ctx_alignment() - 1)) +
244 alg
->cra_blocksize
* 2;
246 inst
->alg
.base
.cra_ctxsize
= ALIGN(sizeof(struct xcbc_tfm_ctx
),
248 alg
->cra_blocksize
* 2;
249 inst
->alg
.base
.cra_init
= xcbc_init_tfm
;
250 inst
->alg
.base
.cra_exit
= xcbc_exit_tfm
;
252 inst
->alg
.init
= crypto_xcbc_digest_init
;
253 inst
->alg
.update
= crypto_xcbc_digest_update
;
254 inst
->alg
.final
= crypto_xcbc_digest_final
;
255 inst
->alg
.setkey
= crypto_xcbc_digest_setkey
;
257 err
= shash_register_instance(tmpl
, inst
);
260 shash_free_instance(shash_crypto_instance(inst
));
268 static struct crypto_template crypto_xcbc_tmpl
= {
270 .create
= xcbc_create
,
271 .free
= shash_free_instance
,
272 .module
= THIS_MODULE
,
275 static int __init
crypto_xcbc_module_init(void)
277 return crypto_register_template(&crypto_xcbc_tmpl
);
280 static void __exit
crypto_xcbc_module_exit(void)
282 crypto_unregister_template(&crypto_xcbc_tmpl
);
285 module_init(crypto_xcbc_module_init
);
286 module_exit(crypto_xcbc_module_exit
);
288 MODULE_LICENSE("GPL");
289 MODULE_DESCRIPTION("XCBC keyed hash algorithm");
290 MODULE_ALIAS_CRYPTO("xcbc");