1 /* 2 * CTS: Cipher Text Stealing mode 3 * 4 * COPYRIGHT (c) 2008 5 * The Regents of the University of Michigan 6 * ALL RIGHTS RESERVED 7 * 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 17 * also be included. 18 * 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 30 * SUCH DAMAGES. 31 */ 32 33 /* Derived from various: 34 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 35 */ 36 37 /* 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. 41 */ 42 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> 52 53 struct crypto_cts_ctx { 54 struct crypto_blkcipher *child; 55 }; 56 57 static int crypto_cts_setkey(struct crypto_tfm *parent, const u8 *key, 58 unsigned int keylen) 59 { 60 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(parent); 61 struct crypto_blkcipher *child = ctx->child; 62 int err; 63 64 crypto_blkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 65 crypto_blkcipher_set_flags(child, crypto_tfm_get_flags(parent) & 66 CRYPTO_TFM_REQ_MASK); 67 err = crypto_blkcipher_setkey(child, key, keylen); 68 crypto_tfm_set_flags(parent, crypto_blkcipher_get_flags(child) & 69 CRYPTO_TFM_RES_MASK); 70 return err; 71 } 72 73 static int cts_cbc_encrypt(struct crypto_cts_ctx *ctx, 74 struct blkcipher_desc *desc, 75 struct scatterlist *dst, 76 struct scatterlist *src, 77 unsigned int offset, 78 unsigned int nbytes) 79 { 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; 85 u8 iv[bsize]; 86 u8 s[bsize * 2], d[bsize * 2]; 87 int err; 88 89 if (lastn < 0) 90 return -EINVAL; 91 92 sg_init_table(sgsrc, 1); 93 sg_init_table(sgdst, 1); 94 95 memset(s, 0, sizeof(s)); 96 scatterwalk_map_and_copy(s, src, offset, nbytes, 0); 97 98 memcpy(iv, desc->info, bsize); 99 100 lcldesc.tfm = ctx->child; 101 lcldesc.info = iv; 102 lcldesc.flags = desc->flags; 103 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); 107 108 memcpy(d + bsize, tmp, lastn); 109 110 lcldesc.info = tmp; 111 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); 115 116 memcpy(d, tmp2, bsize); 117 118 scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); 119 120 memcpy(desc->info, tmp2, bsize); 121 122 return err; 123 } 124 125 static int crypto_cts_encrypt(struct blkcipher_desc *desc, 126 struct scatterlist *dst, struct scatterlist *src, 127 unsigned int nbytes) 128 { 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; 134 int err; 135 136 lcldesc.tfm = ctx->child; 137 lcldesc.info = desc->info; 138 lcldesc.flags = desc->flags; 139 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); 144 } else { 145 /* do normal function for tot_blocks - 2 */ 146 err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, 147 cbc_blocks * bsize); 148 if (err == 0) { 149 /* do cts for final two blocks */ 150 err = cts_cbc_encrypt(ctx, desc, dst, src, 151 cbc_blocks * bsize, 152 nbytes - (cbc_blocks * bsize)); 153 } 154 } 155 156 return err; 157 } 158 159 static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx, 160 struct blkcipher_desc *desc, 161 struct scatterlist *dst, 162 struct scatterlist *src, 163 unsigned int offset, 164 unsigned int nbytes) 165 { 166 int bsize = crypto_blkcipher_blocksize(desc->tfm); 167 u8 tmp[bsize]; 168 struct blkcipher_desc lcldesc; 169 struct scatterlist sgsrc[1], sgdst[1]; 170 int lastn = nbytes - bsize; 171 u8 iv[bsize]; 172 u8 s[bsize * 2], d[bsize * 2]; 173 int err; 174 175 if (lastn < 0) 176 return -EINVAL; 177 178 sg_init_table(sgsrc, 1); 179 sg_init_table(sgdst, 1); 180 181 scatterwalk_map_and_copy(s, src, offset, nbytes, 0); 182 183 lcldesc.tfm = ctx->child; 184 lcldesc.info = iv; 185 lcldesc.flags = desc->flags; 186 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); 192 if (err) 193 return err; 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); 201 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 memset(iv, 0, sizeof(iv)); 206 sg_set_buf(&sgsrc[0], s + bsize, bsize); 207 sg_set_buf(&sgdst[0], d, bsize); 208 err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 209 210 /* XOR with previous block */ 211 crypto_xor(d, desc->info, bsize); 212 213 scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); 214 215 memcpy(desc->info, s, bsize); 216 return err; 217 } 218 219 static int crypto_cts_decrypt(struct blkcipher_desc *desc, 220 struct scatterlist *dst, struct scatterlist *src, 221 unsigned int nbytes) 222 { 223 struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 224 int bsize = crypto_blkcipher_blocksize(desc->tfm); 225 int tot_blocks = (nbytes + bsize - 1) / bsize; 226 int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; 227 struct blkcipher_desc lcldesc; 228 int err; 229 230 lcldesc.tfm = ctx->child; 231 lcldesc.info = desc->info; 232 lcldesc.flags = desc->flags; 233 234 if (tot_blocks == 1) { 235 err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, bsize); 236 } else if (nbytes <= bsize * 2) { 237 err = cts_cbc_decrypt(ctx, desc, dst, src, 0, nbytes); 238 } else { 239 /* do normal function for tot_blocks - 2 */ 240 err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, 241 cbc_blocks * bsize); 242 if (err == 0) { 243 /* do cts for final two blocks */ 244 err = cts_cbc_decrypt(ctx, desc, dst, src, 245 cbc_blocks * bsize, 246 nbytes - (cbc_blocks * bsize)); 247 } 248 } 249 return err; 250 } 251 252 static int crypto_cts_init_tfm(struct crypto_tfm *tfm) 253 { 254 struct crypto_instance *inst = (void *)tfm->__crt_alg; 255 struct crypto_spawn *spawn = crypto_instance_ctx(inst); 256 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); 257 struct crypto_blkcipher *cipher; 258 259 cipher = crypto_spawn_blkcipher(spawn); 260 if (IS_ERR(cipher)) 261 return PTR_ERR(cipher); 262 263 ctx->child = cipher; 264 return 0; 265 } 266 267 static void crypto_cts_exit_tfm(struct crypto_tfm *tfm) 268 { 269 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); 270 crypto_free_blkcipher(ctx->child); 271 } 272 273 static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) 274 { 275 struct crypto_instance *inst; 276 struct crypto_alg *alg; 277 int err; 278 279 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); 280 if (err) 281 return ERR_PTR(err); 282 283 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, 284 CRYPTO_ALG_TYPE_MASK); 285 err = PTR_ERR(alg); 286 if (IS_ERR(alg)) 287 return ERR_PTR(err); 288 289 inst = ERR_PTR(-EINVAL); 290 if (!is_power_of_2(alg->cra_blocksize)) 291 goto out_put_alg; 292 293 inst = crypto_alloc_instance("cts", alg); 294 if (IS_ERR(inst)) 295 goto out_put_alg; 296 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; 302 303 /* We access the data as u32s when xoring. */ 304 inst->alg.cra_alignmask |= __alignof__(u32) - 1; 305 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; 309 310 inst->alg.cra_blkcipher.geniv = "seqiv"; 311 312 inst->alg.cra_ctxsize = sizeof(struct crypto_cts_ctx); 313 314 inst->alg.cra_init = crypto_cts_init_tfm; 315 inst->alg.cra_exit = crypto_cts_exit_tfm; 316 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; 320 321 out_put_alg: 322 crypto_mod_put(alg); 323 return inst; 324 } 325 326 static void crypto_cts_free(struct crypto_instance *inst) 327 { 328 crypto_drop_spawn(crypto_instance_ctx(inst)); 329 kfree(inst); 330 } 331 332 static struct crypto_template crypto_cts_tmpl = { 333 .name = "cts", 334 .alloc = crypto_cts_alloc, 335 .free = crypto_cts_free, 336 .module = THIS_MODULE, 337 }; 338 339 static int __init crypto_cts_module_init(void) 340 { 341 return crypto_register_template(&crypto_cts_tmpl); 342 } 343 344 static void __exit crypto_cts_module_exit(void) 345 { 346 crypto_unregister_template(&crypto_cts_tmpl); 347 } 348 349 module_init(crypto_cts_module_init); 350 module_exit(crypto_cts_module_exit); 351 352 MODULE_LICENSE("Dual BSD/GPL"); 353 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC"); 354