2 * CTS: Cipher Text Stealing mode
5 * The Regents of the University of Michigan
8 * Permission is granted to use, copy, create derivative works
9 * and redistribute this software and such derivative works
10 * for any purpose, so long as the name of The University of
11 * Michigan is not used in any advertising or publicity
12 * pertaining to the use of distribution of this software
13 * without specific, written prior authorization. If the
14 * above copyright notice or any other identification of the
15 * University of Michigan is included in any copy of any
16 * portion of this software, then the disclaimer below must
19 * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION
20 * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY
21 * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF
22 * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
23 * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
25 * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE
26 * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR
27 * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING
28 * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN
29 * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF
33 /* Derived from various:
34 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
38 * This is the Cipher Text Stealing mode as described by
39 * Section 8 of rfc2040 and referenced by rfc3962.
40 * rfc3962 includes errata information in its Appendix A.
43 #include <crypto/algapi.h>
44 #include <linux/err.h>
45 #include <linux/init.h>
46 #include <linux/kernel.h>
47 #include <linux/log2.h>
48 #include <linux/module.h>
49 #include <linux/scatterlist.h>
50 #include <crypto/scatterwalk.h>
51 #include <linux/slab.h>
53 struct crypto_cts_ctx
{
54 struct crypto_blkcipher
*child
;
57 static int crypto_cts_setkey(struct crypto_tfm
*parent
, const u8
*key
,
60 struct crypto_cts_ctx
*ctx
= crypto_tfm_ctx(parent
);
61 struct crypto_blkcipher
*child
= ctx
->child
;
64 crypto_blkcipher_clear_flags(child
, CRYPTO_TFM_REQ_MASK
);
65 crypto_blkcipher_set_flags(child
, crypto_tfm_get_flags(parent
) &
67 err
= crypto_blkcipher_setkey(child
, key
, keylen
);
68 crypto_tfm_set_flags(parent
, crypto_blkcipher_get_flags(child
) &
73 static int cts_cbc_encrypt(struct crypto_cts_ctx
*ctx
,
74 struct blkcipher_desc
*desc
,
75 struct scatterlist
*dst
,
76 struct scatterlist
*src
,
80 int bsize
= crypto_blkcipher_blocksize(desc
->tfm
);
81 u8 tmp
[bsize
], tmp2
[bsize
];
82 struct blkcipher_desc lcldesc
;
83 struct scatterlist sgsrc
[1], sgdst
[1];
84 int lastn
= nbytes
- bsize
;
86 u8 s
[bsize
* 2], d
[bsize
* 2];
92 sg_init_table(sgsrc
, 1);
93 sg_init_table(sgdst
, 1);
95 memset(s
, 0, sizeof(s
));
96 scatterwalk_map_and_copy(s
, src
, offset
, nbytes
, 0);
98 memcpy(iv
, desc
->info
, bsize
);
100 lcldesc
.tfm
= ctx
->child
;
102 lcldesc
.flags
= desc
->flags
;
104 sg_set_buf(&sgsrc
[0], s
, bsize
);
105 sg_set_buf(&sgdst
[0], tmp
, bsize
);
106 err
= crypto_blkcipher_encrypt_iv(&lcldesc
, sgdst
, sgsrc
, bsize
);
108 memcpy(d
+ bsize
, tmp
, lastn
);
112 sg_set_buf(&sgsrc
[0], s
+ bsize
, bsize
);
113 sg_set_buf(&sgdst
[0], tmp2
, bsize
);
114 err
= crypto_blkcipher_encrypt_iv(&lcldesc
, sgdst
, sgsrc
, bsize
);
116 memcpy(d
, tmp2
, bsize
);
118 scatterwalk_map_and_copy(d
, dst
, offset
, nbytes
, 1);
120 memcpy(desc
->info
, tmp2
, bsize
);
125 static int crypto_cts_encrypt(struct blkcipher_desc
*desc
,
126 struct scatterlist
*dst
, struct scatterlist
*src
,
129 struct crypto_cts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
130 int bsize
= crypto_blkcipher_blocksize(desc
->tfm
);
131 int tot_blocks
= (nbytes
+ bsize
- 1) / bsize
;
132 int cbc_blocks
= tot_blocks
> 2 ? tot_blocks
- 2 : 0;
133 struct blkcipher_desc lcldesc
;
136 lcldesc
.tfm
= ctx
->child
;
137 lcldesc
.info
= desc
->info
;
138 lcldesc
.flags
= desc
->flags
;
140 if (tot_blocks
== 1) {
141 err
= crypto_blkcipher_encrypt_iv(&lcldesc
, dst
, src
, bsize
);
142 } else if (nbytes
<= bsize
* 2) {
143 err
= cts_cbc_encrypt(ctx
, desc
, dst
, src
, 0, nbytes
);
145 /* do normal function for tot_blocks - 2 */
146 err
= crypto_blkcipher_encrypt_iv(&lcldesc
, dst
, src
,
149 /* do cts for final two blocks */
150 err
= cts_cbc_encrypt(ctx
, desc
, dst
, src
,
152 nbytes
- (cbc_blocks
* bsize
));
159 static int cts_cbc_decrypt(struct crypto_cts_ctx
*ctx
,
160 struct blkcipher_desc
*desc
,
161 struct scatterlist
*dst
,
162 struct scatterlist
*src
,
166 int bsize
= crypto_blkcipher_blocksize(desc
->tfm
);
168 struct blkcipher_desc lcldesc
;
169 struct scatterlist sgsrc
[1], sgdst
[1];
170 int lastn
= nbytes
- bsize
;
172 u8 s
[bsize
* 2], d
[bsize
* 2];
178 sg_init_table(sgsrc
, 1);
179 sg_init_table(sgdst
, 1);
181 scatterwalk_map_and_copy(s
, src
, offset
, nbytes
, 0);
183 lcldesc
.tfm
= ctx
->child
;
185 lcldesc
.flags
= desc
->flags
;
187 /* 1. Decrypt Cn-1 (s) to create Dn (tmp)*/
188 memset(iv
, 0, sizeof(iv
));
189 sg_set_buf(&sgsrc
[0], s
, bsize
);
190 sg_set_buf(&sgdst
[0], tmp
, bsize
);
191 err
= crypto_blkcipher_decrypt_iv(&lcldesc
, sgdst
, sgsrc
, bsize
);
194 /* 2. Pad Cn with zeros at the end to create C of length BB */
195 memset(iv
, 0, sizeof(iv
));
196 memcpy(iv
, s
+ bsize
, lastn
);
197 /* 3. Exclusive-or Dn (tmp) with C (iv) to create Xn (tmp) */
198 crypto_xor(tmp
, iv
, bsize
);
199 /* 4. Select the first Ln bytes of Xn (tmp) to create Pn */
200 memcpy(d
+ bsize
, tmp
, lastn
);
202 /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */
203 memcpy(s
+ bsize
+ lastn
, tmp
+ lastn
, bsize
- lastn
);
204 /* 6. Decrypt En to create Pn-1 */
205 memzero_explicit(iv
, sizeof(iv
));
207 sg_set_buf(&sgsrc
[0], s
+ bsize
, bsize
);
208 sg_set_buf(&sgdst
[0], d
, bsize
);
209 err
= crypto_blkcipher_decrypt_iv(&lcldesc
, sgdst
, sgsrc
, bsize
);
211 /* XOR with previous block */
212 crypto_xor(d
, desc
->info
, bsize
);
214 scatterwalk_map_and_copy(d
, dst
, offset
, nbytes
, 1);
216 memcpy(desc
->info
, s
, bsize
);
220 static int crypto_cts_decrypt(struct blkcipher_desc
*desc
,
221 struct scatterlist
*dst
, struct scatterlist
*src
,
224 struct crypto_cts_ctx
*ctx
= crypto_blkcipher_ctx(desc
->tfm
);
225 int bsize
= crypto_blkcipher_blocksize(desc
->tfm
);
226 int tot_blocks
= (nbytes
+ bsize
- 1) / bsize
;
227 int cbc_blocks
= tot_blocks
> 2 ? tot_blocks
- 2 : 0;
228 struct blkcipher_desc lcldesc
;
231 lcldesc
.tfm
= ctx
->child
;
232 lcldesc
.info
= desc
->info
;
233 lcldesc
.flags
= desc
->flags
;
235 if (tot_blocks
== 1) {
236 err
= crypto_blkcipher_decrypt_iv(&lcldesc
, dst
, src
, bsize
);
237 } else if (nbytes
<= bsize
* 2) {
238 err
= cts_cbc_decrypt(ctx
, desc
, dst
, src
, 0, nbytes
);
240 /* do normal function for tot_blocks - 2 */
241 err
= crypto_blkcipher_decrypt_iv(&lcldesc
, dst
, src
,
244 /* do cts for final two blocks */
245 err
= cts_cbc_decrypt(ctx
, desc
, dst
, src
,
247 nbytes
- (cbc_blocks
* bsize
));
253 static int crypto_cts_init_tfm(struct crypto_tfm
*tfm
)
255 struct crypto_instance
*inst
= (void *)tfm
->__crt_alg
;
256 struct crypto_spawn
*spawn
= crypto_instance_ctx(inst
);
257 struct crypto_cts_ctx
*ctx
= crypto_tfm_ctx(tfm
);
258 struct crypto_blkcipher
*cipher
;
260 cipher
= crypto_spawn_blkcipher(spawn
);
262 return PTR_ERR(cipher
);
268 static void crypto_cts_exit_tfm(struct crypto_tfm
*tfm
)
270 struct crypto_cts_ctx
*ctx
= crypto_tfm_ctx(tfm
);
271 crypto_free_blkcipher(ctx
->child
);
274 static struct crypto_instance
*crypto_cts_alloc(struct rtattr
**tb
)
276 struct crypto_instance
*inst
;
277 struct crypto_alg
*alg
;
280 err
= crypto_check_attr_type(tb
, CRYPTO_ALG_TYPE_BLKCIPHER
);
284 alg
= crypto_attr_alg(tb
[1], CRYPTO_ALG_TYPE_BLKCIPHER
,
285 CRYPTO_ALG_TYPE_MASK
);
287 return ERR_CAST(alg
);
289 inst
= ERR_PTR(-EINVAL
);
290 if (!is_power_of_2(alg
->cra_blocksize
))
293 inst
= crypto_alloc_instance("cts", alg
);
297 inst
->alg
.cra_flags
= CRYPTO_ALG_TYPE_BLKCIPHER
;
298 inst
->alg
.cra_priority
= alg
->cra_priority
;
299 inst
->alg
.cra_blocksize
= alg
->cra_blocksize
;
300 inst
->alg
.cra_alignmask
= alg
->cra_alignmask
;
301 inst
->alg
.cra_type
= &crypto_blkcipher_type
;
303 /* We access the data as u32s when xoring. */
304 inst
->alg
.cra_alignmask
|= __alignof__(u32
) - 1;
306 inst
->alg
.cra_blkcipher
.ivsize
= alg
->cra_blocksize
;
307 inst
->alg
.cra_blkcipher
.min_keysize
= alg
->cra_blkcipher
.min_keysize
;
308 inst
->alg
.cra_blkcipher
.max_keysize
= alg
->cra_blkcipher
.max_keysize
;
310 inst
->alg
.cra_blkcipher
.geniv
= "seqiv";
312 inst
->alg
.cra_ctxsize
= sizeof(struct crypto_cts_ctx
);
314 inst
->alg
.cra_init
= crypto_cts_init_tfm
;
315 inst
->alg
.cra_exit
= crypto_cts_exit_tfm
;
317 inst
->alg
.cra_blkcipher
.setkey
= crypto_cts_setkey
;
318 inst
->alg
.cra_blkcipher
.encrypt
= crypto_cts_encrypt
;
319 inst
->alg
.cra_blkcipher
.decrypt
= crypto_cts_decrypt
;
326 static void crypto_cts_free(struct crypto_instance
*inst
)
328 crypto_drop_spawn(crypto_instance_ctx(inst
));
332 static struct crypto_template crypto_cts_tmpl
= {
334 .alloc
= crypto_cts_alloc
,
335 .free
= crypto_cts_free
,
336 .module
= THIS_MODULE
,
339 static int __init
crypto_cts_module_init(void)
341 return crypto_register_template(&crypto_cts_tmpl
);
344 static void __exit
crypto_cts_module_exit(void)
346 crypto_unregister_template(&crypto_cts_tmpl
);
349 module_init(crypto_cts_module_init
);
350 module_exit(crypto_cts_module_exit
);
352 MODULE_LICENSE("Dual BSD/GPL");
353 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC");