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 memset(s, 0, sizeof(s)); 93 scatterwalk_map_and_copy(s, src, offset, nbytes, 0); 94 95 memcpy(iv, desc->info, bsize); 96 97 lcldesc.tfm = ctx->child; 98 lcldesc.info = iv; 99 lcldesc.flags = desc->flags; 100 101 sg_set_buf(&sgsrc[0], s, bsize); 102 sg_set_buf(&sgdst[0], tmp, bsize); 103 err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 104 105 memcpy(d + bsize, tmp, lastn); 106 107 lcldesc.info = tmp; 108 109 sg_set_buf(&sgsrc[0], s + bsize, bsize); 110 sg_set_buf(&sgdst[0], tmp2, bsize); 111 err = crypto_blkcipher_encrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 112 113 memcpy(d, tmp2, bsize); 114 115 scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); 116 117 memcpy(desc->info, tmp2, bsize); 118 119 return err; 120 } 121 122 static int crypto_cts_encrypt(struct blkcipher_desc *desc, 123 struct scatterlist *dst, struct scatterlist *src, 124 unsigned int nbytes) 125 { 126 struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 127 int bsize = crypto_blkcipher_blocksize(desc->tfm); 128 int tot_blocks = (nbytes + bsize - 1) / bsize; 129 int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; 130 struct blkcipher_desc lcldesc; 131 int err; 132 133 lcldesc.tfm = ctx->child; 134 lcldesc.info = desc->info; 135 lcldesc.flags = desc->flags; 136 137 if (tot_blocks == 1) { 138 err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, bsize); 139 } else if (nbytes <= bsize * 2) { 140 err = cts_cbc_encrypt(ctx, desc, dst, src, 0, nbytes); 141 } else { 142 /* do normal function for tot_blocks - 2 */ 143 err = crypto_blkcipher_encrypt_iv(&lcldesc, dst, src, 144 cbc_blocks * bsize); 145 if (err == 0) { 146 /* do cts for final two blocks */ 147 err = cts_cbc_encrypt(ctx, desc, dst, src, 148 cbc_blocks * bsize, 149 nbytes - (cbc_blocks * bsize)); 150 } 151 } 152 153 return err; 154 } 155 156 static int cts_cbc_decrypt(struct crypto_cts_ctx *ctx, 157 struct blkcipher_desc *desc, 158 struct scatterlist *dst, 159 struct scatterlist *src, 160 unsigned int offset, 161 unsigned int nbytes) 162 { 163 int bsize = crypto_blkcipher_blocksize(desc->tfm); 164 u8 tmp[bsize]; 165 struct blkcipher_desc lcldesc; 166 struct scatterlist sgsrc[1], sgdst[1]; 167 int lastn = nbytes - bsize; 168 u8 iv[bsize]; 169 u8 s[bsize * 2], d[bsize * 2]; 170 int err; 171 172 if (lastn < 0) 173 return -EINVAL; 174 175 scatterwalk_map_and_copy(s, src, offset, nbytes, 0); 176 177 lcldesc.tfm = ctx->child; 178 lcldesc.info = iv; 179 lcldesc.flags = desc->flags; 180 181 /* 1. Decrypt Cn-1 (s) to create Dn (tmp)*/ 182 memset(iv, 0, sizeof(iv)); 183 sg_set_buf(&sgsrc[0], s, bsize); 184 sg_set_buf(&sgdst[0], tmp, bsize); 185 err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 186 if (err) 187 return err; 188 /* 2. Pad Cn with zeros at the end to create C of length BB */ 189 memset(iv, 0, sizeof(iv)); 190 memcpy(iv, s + bsize, lastn); 191 /* 3. Exclusive-or Dn (tmp) with C (iv) to create Xn (tmp) */ 192 crypto_xor(tmp, iv, bsize); 193 /* 4. Select the first Ln bytes of Xn (tmp) to create Pn */ 194 memcpy(d + bsize, tmp, lastn); 195 196 /* 5. Append the tail (BB - Ln) bytes of Xn (tmp) to Cn to create En */ 197 memcpy(s + bsize + lastn, tmp + lastn, bsize - lastn); 198 /* 6. Decrypt En to create Pn-1 */ 199 memset(iv, 0, sizeof(iv)); 200 sg_set_buf(&sgsrc[0], s + bsize, bsize); 201 sg_set_buf(&sgdst[0], d, bsize); 202 err = crypto_blkcipher_decrypt_iv(&lcldesc, sgdst, sgsrc, bsize); 203 204 /* XOR with previous block */ 205 crypto_xor(d, desc->info, bsize); 206 207 scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); 208 209 memcpy(desc->info, s, bsize); 210 return err; 211 } 212 213 static int crypto_cts_decrypt(struct blkcipher_desc *desc, 214 struct scatterlist *dst, struct scatterlist *src, 215 unsigned int nbytes) 216 { 217 struct crypto_cts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); 218 int bsize = crypto_blkcipher_blocksize(desc->tfm); 219 int tot_blocks = (nbytes + bsize - 1) / bsize; 220 int cbc_blocks = tot_blocks > 2 ? tot_blocks - 2 : 0; 221 struct blkcipher_desc lcldesc; 222 int err; 223 224 lcldesc.tfm = ctx->child; 225 lcldesc.info = desc->info; 226 lcldesc.flags = desc->flags; 227 228 if (tot_blocks == 1) { 229 err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, bsize); 230 } else if (nbytes <= bsize * 2) { 231 err = cts_cbc_decrypt(ctx, desc, dst, src, 0, nbytes); 232 } else { 233 /* do normal function for tot_blocks - 2 */ 234 err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, 235 cbc_blocks * bsize); 236 if (err == 0) { 237 /* do cts for final two blocks */ 238 err = cts_cbc_decrypt(ctx, desc, dst, src, 239 cbc_blocks * bsize, 240 nbytes - (cbc_blocks * bsize)); 241 } 242 } 243 return err; 244 } 245 246 static int crypto_cts_init_tfm(struct crypto_tfm *tfm) 247 { 248 struct crypto_instance *inst = (void *)tfm->__crt_alg; 249 struct crypto_spawn *spawn = crypto_instance_ctx(inst); 250 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); 251 struct crypto_blkcipher *cipher; 252 253 cipher = crypto_spawn_blkcipher(spawn); 254 if (IS_ERR(cipher)) 255 return PTR_ERR(cipher); 256 257 ctx->child = cipher; 258 return 0; 259 } 260 261 static void crypto_cts_exit_tfm(struct crypto_tfm *tfm) 262 { 263 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); 264 crypto_free_blkcipher(ctx->child); 265 } 266 267 static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) 268 { 269 struct crypto_instance *inst; 270 struct crypto_alg *alg; 271 int err; 272 273 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); 274 if (err) 275 return ERR_PTR(err); 276 277 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, 278 CRYPTO_ALG_TYPE_MASK); 279 err = PTR_ERR(alg); 280 if (IS_ERR(alg)) 281 return ERR_PTR(err); 282 283 inst = ERR_PTR(-EINVAL); 284 if (!is_power_of_2(alg->cra_blocksize)) 285 goto out_put_alg; 286 287 inst = crypto_alloc_instance("cts", alg); 288 if (IS_ERR(inst)) 289 goto out_put_alg; 290 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; 296 297 /* We access the data as u32s when xoring. */ 298 inst->alg.cra_alignmask |= __alignof__(u32) - 1; 299 300 inst->alg.cra_blkcipher.ivsize = alg->cra_blocksize; 301 inst->alg.cra_blkcipher.min_keysize = alg->cra_blkcipher.min_keysize; 302 inst->alg.cra_blkcipher.max_keysize = alg->cra_blkcipher.max_keysize; 303 304 inst->alg.cra_blkcipher.geniv = "seqiv"; 305 306 inst->alg.cra_ctxsize = sizeof(struct crypto_cts_ctx); 307 308 inst->alg.cra_init = crypto_cts_init_tfm; 309 inst->alg.cra_exit = crypto_cts_exit_tfm; 310 311 inst->alg.cra_blkcipher.setkey = crypto_cts_setkey; 312 inst->alg.cra_blkcipher.encrypt = crypto_cts_encrypt; 313 inst->alg.cra_blkcipher.decrypt = crypto_cts_decrypt; 314 315 out_put_alg: 316 crypto_mod_put(alg); 317 return inst; 318 } 319 320 static void crypto_cts_free(struct crypto_instance *inst) 321 { 322 crypto_drop_spawn(crypto_instance_ctx(inst)); 323 kfree(inst); 324 } 325 326 static struct crypto_template crypto_cts_tmpl = { 327 .name = "cts", 328 .alloc = crypto_cts_alloc, 329 .free = crypto_cts_free, 330 .module = THIS_MODULE, 331 }; 332 333 static int __init crypto_cts_module_init(void) 334 { 335 return crypto_register_template(&crypto_cts_tmpl); 336 } 337 338 static void __exit crypto_cts_module_exit(void) 339 { 340 crypto_unregister_template(&crypto_cts_tmpl); 341 } 342 343 module_init(crypto_cts_module_init); 344 module_exit(crypto_cts_module_exit); 345 346 MODULE_LICENSE("Dual BSD/GPL"); 347 MODULE_DESCRIPTION("CTS-CBC CipherText Stealing for CBC"); 348