at v2.6.33-rc2 387 lines 10 kB view raw
1/* 2 * Asynchronous block chaining cipher operations. 3 * 4 * This is the asynchronous version of blkcipher.c indicating completion 5 * via a callback. 6 * 7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms of the GNU General Public License as published by the Free 11 * Software Foundation; either version 2 of the License, or (at your option) 12 * any later version. 13 * 14 */ 15 16#include <crypto/internal/skcipher.h> 17#include <linux/cpumask.h> 18#include <linux/err.h> 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/rtnetlink.h> 23#include <linux/sched.h> 24#include <linux/slab.h> 25#include <linux/seq_file.h> 26 27#include "internal.h" 28 29static const char *skcipher_default_geniv __read_mostly; 30 31static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, 32 unsigned int keylen) 33{ 34 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); 35 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); 36 int ret; 37 u8 *buffer, *alignbuffer; 38 unsigned long absize; 39 40 absize = keylen + alignmask; 41 buffer = kmalloc(absize, GFP_ATOMIC); 42 if (!buffer) 43 return -ENOMEM; 44 45 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 46 memcpy(alignbuffer, key, keylen); 47 ret = cipher->setkey(tfm, alignbuffer, keylen); 48 memset(alignbuffer, 0, keylen); 49 kfree(buffer); 50 return ret; 51} 52 53static int setkey(struct crypto_ablkcipher *tfm, const u8 *key, 54 unsigned int keylen) 55{ 56 struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm); 57 unsigned long alignmask = crypto_ablkcipher_alignmask(tfm); 58 59 if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) { 60 crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 61 return -EINVAL; 62 } 63 64 if ((unsigned long)key & alignmask) 65 return setkey_unaligned(tfm, key, keylen); 66 67 return cipher->setkey(tfm, key, keylen); 68} 69 70static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type, 71 u32 mask) 72{ 73 return alg->cra_ctxsize; 74} 75 76int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req) 77{ 78 return crypto_ablkcipher_encrypt(&req->creq); 79} 80 81int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req) 82{ 83 return crypto_ablkcipher_decrypt(&req->creq); 84} 85 86static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, 87 u32 mask) 88{ 89 struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; 90 struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; 91 92 if (alg->ivsize > PAGE_SIZE / 8) 93 return -EINVAL; 94 95 crt->setkey = setkey; 96 crt->encrypt = alg->encrypt; 97 crt->decrypt = alg->decrypt; 98 if (!alg->ivsize) { 99 crt->givencrypt = skcipher_null_givencrypt; 100 crt->givdecrypt = skcipher_null_givdecrypt; 101 } 102 crt->base = __crypto_ablkcipher_cast(tfm); 103 crt->ivsize = alg->ivsize; 104 105 return 0; 106} 107 108static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) 109 __attribute__ ((unused)); 110static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) 111{ 112 struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher; 113 114 seq_printf(m, "type : ablkcipher\n"); 115 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 116 "yes" : "no"); 117 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 118 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); 119 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); 120 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); 121 seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<default>"); 122} 123 124const struct crypto_type crypto_ablkcipher_type = { 125 .ctxsize = crypto_ablkcipher_ctxsize, 126 .init = crypto_init_ablkcipher_ops, 127#ifdef CONFIG_PROC_FS 128 .show = crypto_ablkcipher_show, 129#endif 130}; 131EXPORT_SYMBOL_GPL(crypto_ablkcipher_type); 132 133static int no_givdecrypt(struct skcipher_givcrypt_request *req) 134{ 135 return -ENOSYS; 136} 137 138static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type, 139 u32 mask) 140{ 141 struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; 142 struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher; 143 144 if (alg->ivsize > PAGE_SIZE / 8) 145 return -EINVAL; 146 147 crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ? 148 alg->setkey : setkey; 149 crt->encrypt = alg->encrypt; 150 crt->decrypt = alg->decrypt; 151 crt->givencrypt = alg->givencrypt; 152 crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt; 153 crt->base = __crypto_ablkcipher_cast(tfm); 154 crt->ivsize = alg->ivsize; 155 156 return 0; 157} 158 159static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) 160 __attribute__ ((unused)); 161static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) 162{ 163 struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher; 164 165 seq_printf(m, "type : givcipher\n"); 166 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 167 "yes" : "no"); 168 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 169 seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize); 170 seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize); 171 seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize); 172 seq_printf(m, "geniv : %s\n", ablkcipher->geniv ?: "<built-in>"); 173} 174 175const struct crypto_type crypto_givcipher_type = { 176 .ctxsize = crypto_ablkcipher_ctxsize, 177 .init = crypto_init_givcipher_ops, 178#ifdef CONFIG_PROC_FS 179 .show = crypto_givcipher_show, 180#endif 181}; 182EXPORT_SYMBOL_GPL(crypto_givcipher_type); 183 184const char *crypto_default_geniv(const struct crypto_alg *alg) 185{ 186 if (((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 187 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : 188 alg->cra_ablkcipher.ivsize) != 189 alg->cra_blocksize) 190 return "chainiv"; 191 192 return alg->cra_flags & CRYPTO_ALG_ASYNC ? 193 "eseqiv" : skcipher_default_geniv; 194} 195 196static int crypto_givcipher_default(struct crypto_alg *alg, u32 type, u32 mask) 197{ 198 struct rtattr *tb[3]; 199 struct { 200 struct rtattr attr; 201 struct crypto_attr_type data; 202 } ptype; 203 struct { 204 struct rtattr attr; 205 struct crypto_attr_alg data; 206 } palg; 207 struct crypto_template *tmpl; 208 struct crypto_instance *inst; 209 struct crypto_alg *larval; 210 const char *geniv; 211 int err; 212 213 larval = crypto_larval_lookup(alg->cra_driver_name, 214 (type & ~CRYPTO_ALG_TYPE_MASK) | 215 CRYPTO_ALG_TYPE_GIVCIPHER, 216 mask | CRYPTO_ALG_TYPE_MASK); 217 err = PTR_ERR(larval); 218 if (IS_ERR(larval)) 219 goto out; 220 221 err = -EAGAIN; 222 if (!crypto_is_larval(larval)) 223 goto drop_larval; 224 225 ptype.attr.rta_len = sizeof(ptype); 226 ptype.attr.rta_type = CRYPTOA_TYPE; 227 ptype.data.type = type | CRYPTO_ALG_GENIV; 228 /* GENIV tells the template that we're making a default geniv. */ 229 ptype.data.mask = mask | CRYPTO_ALG_GENIV; 230 tb[0] = &ptype.attr; 231 232 palg.attr.rta_len = sizeof(palg); 233 palg.attr.rta_type = CRYPTOA_ALG; 234 /* Must use the exact name to locate ourselves. */ 235 memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME); 236 tb[1] = &palg.attr; 237 238 tb[2] = NULL; 239 240 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 241 CRYPTO_ALG_TYPE_BLKCIPHER) 242 geniv = alg->cra_blkcipher.geniv; 243 else 244 geniv = alg->cra_ablkcipher.geniv; 245 246 if (!geniv) 247 geniv = crypto_default_geniv(alg); 248 249 tmpl = crypto_lookup_template(geniv); 250 err = -ENOENT; 251 if (!tmpl) 252 goto kill_larval; 253 254 inst = tmpl->alloc(tb); 255 err = PTR_ERR(inst); 256 if (IS_ERR(inst)) 257 goto put_tmpl; 258 259 if ((err = crypto_register_instance(tmpl, inst))) { 260 tmpl->free(inst); 261 goto put_tmpl; 262 } 263 264 /* Redo the lookup to use the instance we just registered. */ 265 err = -EAGAIN; 266 267put_tmpl: 268 crypto_tmpl_put(tmpl); 269kill_larval: 270 crypto_larval_kill(larval); 271drop_larval: 272 crypto_mod_put(larval); 273out: 274 crypto_mod_put(alg); 275 return err; 276} 277 278static struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, 279 u32 mask) 280{ 281 struct crypto_alg *alg; 282 283 alg = crypto_alg_mod_lookup(name, type, mask); 284 if (IS_ERR(alg)) 285 return alg; 286 287 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 288 CRYPTO_ALG_TYPE_GIVCIPHER) 289 return alg; 290 291 if (!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 292 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : 293 alg->cra_ablkcipher.ivsize)) 294 return alg; 295 296 crypto_mod_put(alg); 297 alg = crypto_alg_mod_lookup(name, type | CRYPTO_ALG_TESTED, 298 mask & ~CRYPTO_ALG_TESTED); 299 if (IS_ERR(alg)) 300 return alg; 301 302 if ((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 303 CRYPTO_ALG_TYPE_GIVCIPHER) { 304 if ((alg->cra_flags ^ type ^ ~mask) & CRYPTO_ALG_TESTED) { 305 crypto_mod_put(alg); 306 alg = ERR_PTR(-ENOENT); 307 } 308 return alg; 309 } 310 311 BUG_ON(!((alg->cra_flags & CRYPTO_ALG_TYPE_MASK) == 312 CRYPTO_ALG_TYPE_BLKCIPHER ? alg->cra_blkcipher.ivsize : 313 alg->cra_ablkcipher.ivsize)); 314 315 return ERR_PTR(crypto_givcipher_default(alg, type, mask)); 316} 317 318int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, 319 u32 type, u32 mask) 320{ 321 struct crypto_alg *alg; 322 int err; 323 324 type = crypto_skcipher_type(type); 325 mask = crypto_skcipher_mask(mask); 326 327 alg = crypto_lookup_skcipher(name, type, mask); 328 if (IS_ERR(alg)) 329 return PTR_ERR(alg); 330 331 err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask); 332 crypto_mod_put(alg); 333 return err; 334} 335EXPORT_SYMBOL_GPL(crypto_grab_skcipher); 336 337struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name, 338 u32 type, u32 mask) 339{ 340 struct crypto_tfm *tfm; 341 int err; 342 343 type = crypto_skcipher_type(type); 344 mask = crypto_skcipher_mask(mask); 345 346 for (;;) { 347 struct crypto_alg *alg; 348 349 alg = crypto_lookup_skcipher(alg_name, type, mask); 350 if (IS_ERR(alg)) { 351 err = PTR_ERR(alg); 352 goto err; 353 } 354 355 tfm = __crypto_alloc_tfm(alg, type, mask); 356 if (!IS_ERR(tfm)) 357 return __crypto_ablkcipher_cast(tfm); 358 359 crypto_mod_put(alg); 360 err = PTR_ERR(tfm); 361 362err: 363 if (err != -EAGAIN) 364 break; 365 if (signal_pending(current)) { 366 err = -EINTR; 367 break; 368 } 369 } 370 371 return ERR_PTR(err); 372} 373EXPORT_SYMBOL_GPL(crypto_alloc_ablkcipher); 374 375static int __init skcipher_module_init(void) 376{ 377 skcipher_default_geniv = num_possible_cpus() > 1 ? 378 "eseqiv" : "chainiv"; 379 return 0; 380} 381 382static void skcipher_module_exit(void) 383{ 384} 385 386module_init(skcipher_module_init); 387module_exit(skcipher_module_exit);