2 * CBC: Cipher Block Chaining mode
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
13 #include <crypto/algapi.h>
14 #include <linux/err.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
18 #include <linux/scatterlist.h>
19 #include <linux/slab.h>
21 struct crypto_cbc_ctx
{
22 struct crypto_cipher
*child
;
23 void (*xor)(u8
*dst
, const u8
*src
, unsigned int bs
);
26 static int crypto_cbc_setkey(struct crypto_tfm
*parent
, const u8
*key
,
29 struct crypto_cbc_ctx
*ctx
= crypto_tfm_ctx(parent
);
30 struct crypto_cipher
*child
= ctx
->child
;
33 crypto_cipher_clear_flags(child
, CRYPTO_TFM_REQ_MASK
);
34 crypto_cipher_set_flags(child
, crypto_tfm_get_flags(parent
) &
36 err
= crypto_cipher_setkey(child
, key
, keylen
);
37 crypto_tfm_set_flags(parent
, crypto_cipher_get_flags(child
) &
42 static int crypto_cbc_encrypt_segment(struct blkcipher_desc
*desc
,
43 struct blkcipher_walk
*walk
,
44 struct crypto_cipher
*tfm
,
45 void (*xor)(u8
*, const u8
*,
48 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
49 crypto_cipher_alg(tfm
)->cia_encrypt
;
50 int bsize
= crypto_cipher_blocksize(tfm
);
51 unsigned int nbytes
= walk
->nbytes
;
52 u8
*src
= walk
->src
.virt
.addr
;
53 u8
*dst
= walk
->dst
.virt
.addr
;
58 fn(crypto_cipher_tfm(tfm
), dst
, iv
);
59 memcpy(iv
, dst
, bsize
);
63 } while ((nbytes
-= bsize
) >= bsize
);
68 static int crypto_cbc_encrypt_inplace(struct blkcipher_desc
*desc
,
69 struct blkcipher_walk
*walk
,
70 struct crypto_cipher
*tfm
,
71 void (*xor)(u8
*, const u8
*,
74 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
75 crypto_cipher_alg(tfm
)->cia_encrypt
;
76 int bsize
= crypto_cipher_blocksize(tfm
);
77 unsigned int nbytes
= walk
->nbytes
;
78 u8
*src
= walk
->src
.virt
.addr
;
83 fn(crypto_cipher_tfm(tfm
), src
, src
);
87 } while ((nbytes
-= bsize
) >= bsize
);
89 memcpy(walk
->iv
, iv
, bsize
);
94 static int crypto_cbc_encrypt(struct blkcipher_desc
*desc
,
95 struct scatterlist
*dst
, struct scatterlist
*src
,
98 struct blkcipher_walk walk
;
99 struct crypto_blkcipher
*tfm
= desc
->tfm
;
100 struct crypto_cbc_ctx
*ctx
= crypto_blkcipher_ctx(tfm
);
101 struct crypto_cipher
*child
= ctx
->child
;
102 void (*xor)(u8
*, const u8
*, unsigned int bs
) = ctx
->xor;
105 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
106 err
= blkcipher_walk_virt(desc
, &walk
);
108 while ((nbytes
= walk
.nbytes
)) {
109 if (walk
.src
.virt
.addr
== walk
.dst
.virt
.addr
)
110 nbytes
= crypto_cbc_encrypt_inplace(desc
, &walk
, child
,
113 nbytes
= crypto_cbc_encrypt_segment(desc
, &walk
, child
,
115 err
= blkcipher_walk_done(desc
, &walk
, nbytes
);
121 static int crypto_cbc_decrypt_segment(struct blkcipher_desc
*desc
,
122 struct blkcipher_walk
*walk
,
123 struct crypto_cipher
*tfm
,
124 void (*xor)(u8
*, const u8
*,
127 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
128 crypto_cipher_alg(tfm
)->cia_decrypt
;
129 int bsize
= crypto_cipher_blocksize(tfm
);
130 unsigned int nbytes
= walk
->nbytes
;
131 u8
*src
= walk
->src
.virt
.addr
;
132 u8
*dst
= walk
->dst
.virt
.addr
;
136 fn(crypto_cipher_tfm(tfm
), dst
, src
);
142 } while ((nbytes
-= bsize
) >= bsize
);
144 memcpy(walk
->iv
, iv
, bsize
);
149 static int crypto_cbc_decrypt_inplace(struct blkcipher_desc
*desc
,
150 struct blkcipher_walk
*walk
,
151 struct crypto_cipher
*tfm
,
152 void (*xor)(u8
*, const u8
*,
155 void (*fn
)(struct crypto_tfm
*, u8
*, const u8
*) =
156 crypto_cipher_alg(tfm
)->cia_decrypt
;
157 int bsize
= crypto_cipher_blocksize(tfm
);
158 unsigned long alignmask
= crypto_cipher_alignmask(tfm
);
159 unsigned int nbytes
= walk
->nbytes
;
160 u8
*src
= walk
->src
.virt
.addr
;
161 u8 stack
[bsize
+ alignmask
];
162 u8
*first_iv
= (u8
*)ALIGN((unsigned long)stack
, alignmask
+ 1);
164 memcpy(first_iv
, walk
->iv
, bsize
);
166 /* Start of the last block. */
167 src
+= nbytes
- nbytes
% bsize
- bsize
;
168 memcpy(walk
->iv
, src
, bsize
);
171 fn(crypto_cipher_tfm(tfm
), src
, src
);
172 if ((nbytes
-= bsize
) < bsize
)
174 xor(src
, src
- bsize
, bsize
);
178 xor(src
, first_iv
, bsize
);
183 static int crypto_cbc_decrypt(struct blkcipher_desc
*desc
,
184 struct scatterlist
*dst
, struct scatterlist
*src
,
187 struct blkcipher_walk walk
;
188 struct crypto_blkcipher
*tfm
= desc
->tfm
;
189 struct crypto_cbc_ctx
*ctx
= crypto_blkcipher_ctx(tfm
);
190 struct crypto_cipher
*child
= ctx
->child
;
191 void (*xor)(u8
*, const u8
*, unsigned int bs
) = ctx
->xor;
194 blkcipher_walk_init(&walk
, dst
, src
, nbytes
);
195 err
= blkcipher_walk_virt(desc
, &walk
);
197 while ((nbytes
= walk
.nbytes
)) {
198 if (walk
.src
.virt
.addr
== walk
.dst
.virt
.addr
)
199 nbytes
= crypto_cbc_decrypt_inplace(desc
, &walk
, child
,
202 nbytes
= crypto_cbc_decrypt_segment(desc
, &walk
, child
,
204 err
= blkcipher_walk_done(desc
, &walk
, nbytes
);
210 static void xor_byte(u8
*a
, const u8
*b
, unsigned int bs
)
217 static void xor_quad(u8
*dst
, const u8
*src
, unsigned int bs
)
227 static void xor_64(u8
*a
, const u8
*b
, unsigned int bs
)
229 ((u32
*)a
)[0] ^= ((u32
*)b
)[0];
230 ((u32
*)a
)[1] ^= ((u32
*)b
)[1];
233 static void xor_128(u8
*a
, const u8
*b
, unsigned int bs
)
235 ((u32
*)a
)[0] ^= ((u32
*)b
)[0];
236 ((u32
*)a
)[1] ^= ((u32
*)b
)[1];
237 ((u32
*)a
)[2] ^= ((u32
*)b
)[2];
238 ((u32
*)a
)[3] ^= ((u32
*)b
)[3];
241 static int crypto_cbc_init_tfm(struct crypto_tfm
*tfm
)
243 struct crypto_instance
*inst
= (void *)tfm
->__crt_alg
;
244 struct crypto_spawn
*spawn
= crypto_instance_ctx(inst
);
245 struct crypto_cbc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
247 switch (crypto_tfm_alg_blocksize(tfm
)) {
257 if (crypto_tfm_alg_blocksize(tfm
) % 4)
263 tfm
= crypto_spawn_tfm(spawn
);
267 ctx
->child
= crypto_cipher_cast(tfm
);
271 static void crypto_cbc_exit_tfm(struct crypto_tfm
*tfm
)
273 struct crypto_cbc_ctx
*ctx
= crypto_tfm_ctx(tfm
);
274 crypto_free_cipher(ctx
->child
);
277 static struct crypto_instance
*crypto_cbc_alloc(void *param
, unsigned int len
)
279 struct crypto_instance
*inst
;
280 struct crypto_alg
*alg
;
282 alg
= crypto_get_attr_alg(param
, len
, CRYPTO_ALG_TYPE_CIPHER
,
283 CRYPTO_ALG_TYPE_MASK
| CRYPTO_ALG_ASYNC
);
285 return ERR_PTR(PTR_ERR(alg
));
287 inst
= crypto_alloc_instance("cbc", alg
);
291 inst
->alg
.cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
;
292 inst
->alg
.cra_priority
= alg
->cra_priority
;
293 inst
->alg
.cra_blocksize
= alg
->cra_blocksize
;
294 inst
->alg
.cra_alignmask
= alg
->cra_alignmask
;
295 inst
->alg
.cra_type
= &crypto_blkcipher_type
;
297 if (!(alg
->cra_blocksize
% 4))
298 inst
->alg
.cra_alignmask
|= 3;
299 inst
->alg
.cra_blkcipher
.ivsize
= alg
->cra_blocksize
;
300 inst
->alg
.cra_blkcipher
.min_keysize
= alg
->cra_cipher
.cia_min_keysize
;
301 inst
->alg
.cra_blkcipher
.max_keysize
= alg
->cra_cipher
.cia_max_keysize
;
303 inst
->alg
.cra_ctxsize
= sizeof(struct crypto_cbc_ctx
);
305 inst
->alg
.cra_init
= crypto_cbc_init_tfm
;
306 inst
->alg
.cra_exit
= crypto_cbc_exit_tfm
;
308 inst
->alg
.cra_blkcipher
.setkey
= crypto_cbc_setkey
;
309 inst
->alg
.cra_blkcipher
.encrypt
= crypto_cbc_encrypt
;
310 inst
->alg
.cra_blkcipher
.decrypt
= crypto_cbc_decrypt
;
317 static void crypto_cbc_free(struct crypto_instance
*inst
)
319 crypto_drop_spawn(crypto_instance_ctx(inst
));
323 static struct crypto_template crypto_cbc_tmpl
= {
325 .alloc
= crypto_cbc_alloc
,
326 .free
= crypto_cbc_free
,
327 .module
= THIS_MODULE
,
330 static int __init
crypto_cbc_module_init(void)
332 return crypto_register_template(&crypto_cbc_tmpl
);
335 static void __exit
crypto_cbc_module_exit(void)
337 crypto_unregister_template(&crypto_cbc_tmpl
);
340 module_init(crypto_cbc_module_init
);
341 module_exit(crypto_cbc_module_exit
);
343 MODULE_LICENSE("GPL");
344 MODULE_DESCRIPTION("CBC block cipher algorithm");