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 memzero_explicit(iv, sizeof(iv)); 206 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); 210 211 /* XOR with previous block */ 212 crypto_xor(d, desc->info, bsize); 213 214 scatterwalk_map_and_copy(d, dst, offset, nbytes, 1); 215 216 memcpy(desc->info, s, bsize); 217 return err; 218 } 219 220 static int crypto_cts_decrypt(struct blkcipher_desc *desc, 221 struct scatterlist *dst, struct scatterlist *src, 222 unsigned int nbytes) 223 { 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; 229 int err; 230 231 lcldesc.tfm = ctx->child; 232 lcldesc.info = desc->info; 233 lcldesc.flags = desc->flags; 234 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); 239 } else { 240 /* do normal function for tot_blocks - 2 */ 241 err = crypto_blkcipher_decrypt_iv(&lcldesc, dst, src, 242 cbc_blocks * bsize); 243 if (err == 0) { 244 /* do cts for final two blocks */ 245 err = cts_cbc_decrypt(ctx, desc, dst, src, 246 cbc_blocks * bsize, 247 nbytes - (cbc_blocks * bsize)); 248 } 249 } 250 return err; 251 } 252 253 static int crypto_cts_init_tfm(struct crypto_tfm *tfm) 254 { 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; 259 260 cipher = crypto_spawn_blkcipher(spawn); 261 if (IS_ERR(cipher)) 262 return PTR_ERR(cipher); 263 264 ctx->child = cipher; 265 return 0; 266 } 267 268 static void crypto_cts_exit_tfm(struct crypto_tfm *tfm) 269 { 270 struct crypto_cts_ctx *ctx = crypto_tfm_ctx(tfm); 271 crypto_free_blkcipher(ctx->child); 272 } 273 274 static struct crypto_instance *crypto_cts_alloc(struct rtattr **tb) 275 { 276 struct crypto_instance *inst; 277 struct crypto_alg *alg; 278 int err; 279 280 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER); 281 if (err) 282 return ERR_PTR(err); 283 284 alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_BLKCIPHER, 285 CRYPTO_ALG_TYPE_MASK); 286 if (IS_ERR(alg)) 287 return ERR_CAST(alg); 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