at v2.6.26-rc5 489 lines 12 kB view raw
1/* 2 * AEAD: Authenticated Encryption with Associated Data 3 * 4 * This file provides API support for AEAD algorithms. 5 * 6 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 * 13 */ 14 15#include <crypto/internal/aead.h> 16#include <linux/err.h> 17#include <linux/init.h> 18#include <linux/kernel.h> 19#include <linux/module.h> 20#include <linux/rtnetlink.h> 21#include <linux/slab.h> 22#include <linux/seq_file.h> 23 24#include "internal.h" 25 26static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key, 27 unsigned int keylen) 28{ 29 struct aead_alg *aead = crypto_aead_alg(tfm); 30 unsigned long alignmask = crypto_aead_alignmask(tfm); 31 int ret; 32 u8 *buffer, *alignbuffer; 33 unsigned long absize; 34 35 absize = keylen + alignmask; 36 buffer = kmalloc(absize, GFP_ATOMIC); 37 if (!buffer) 38 return -ENOMEM; 39 40 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); 41 memcpy(alignbuffer, key, keylen); 42 ret = aead->setkey(tfm, alignbuffer, keylen); 43 memset(alignbuffer, 0, keylen); 44 kfree(buffer); 45 return ret; 46} 47 48static int setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) 49{ 50 struct aead_alg *aead = crypto_aead_alg(tfm); 51 unsigned long alignmask = crypto_aead_alignmask(tfm); 52 53 if ((unsigned long)key & alignmask) 54 return setkey_unaligned(tfm, key, keylen); 55 56 return aead->setkey(tfm, key, keylen); 57} 58 59int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) 60{ 61 struct aead_tfm *crt = crypto_aead_crt(tfm); 62 int err; 63 64 if (authsize > crypto_aead_alg(tfm)->maxauthsize) 65 return -EINVAL; 66 67 if (crypto_aead_alg(tfm)->setauthsize) { 68 err = crypto_aead_alg(tfm)->setauthsize(crt->base, authsize); 69 if (err) 70 return err; 71 } 72 73 crypto_aead_crt(crt->base)->authsize = authsize; 74 crt->authsize = authsize; 75 return 0; 76} 77EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); 78 79static unsigned int crypto_aead_ctxsize(struct crypto_alg *alg, u32 type, 80 u32 mask) 81{ 82 return alg->cra_ctxsize; 83} 84 85static int no_givcrypt(struct aead_givcrypt_request *req) 86{ 87 return -ENOSYS; 88} 89 90static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 91{ 92 struct aead_alg *alg = &tfm->__crt_alg->cra_aead; 93 struct aead_tfm *crt = &tfm->crt_aead; 94 95 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) 96 return -EINVAL; 97 98 crt->setkey = tfm->__crt_alg->cra_flags & CRYPTO_ALG_GENIV ? 99 alg->setkey : setkey; 100 crt->encrypt = alg->encrypt; 101 crt->decrypt = alg->decrypt; 102 crt->givencrypt = alg->givencrypt ?: no_givcrypt; 103 crt->givdecrypt = alg->givdecrypt ?: no_givcrypt; 104 crt->base = __crypto_aead_cast(tfm); 105 crt->ivsize = alg->ivsize; 106 crt->authsize = alg->maxauthsize; 107 108 return 0; 109} 110 111static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 112 __attribute__ ((unused)); 113static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 114{ 115 struct aead_alg *aead = &alg->cra_aead; 116 117 seq_printf(m, "type : aead\n"); 118 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 119 "yes" : "no"); 120 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 121 seq_printf(m, "ivsize : %u\n", aead->ivsize); 122 seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); 123 seq_printf(m, "geniv : %s\n", aead->geniv ?: "<built-in>"); 124} 125 126const struct crypto_type crypto_aead_type = { 127 .ctxsize = crypto_aead_ctxsize, 128 .init = crypto_init_aead_ops, 129#ifdef CONFIG_PROC_FS 130 .show = crypto_aead_show, 131#endif 132}; 133EXPORT_SYMBOL_GPL(crypto_aead_type); 134 135static int aead_null_givencrypt(struct aead_givcrypt_request *req) 136{ 137 return crypto_aead_encrypt(&req->areq); 138} 139 140static int aead_null_givdecrypt(struct aead_givcrypt_request *req) 141{ 142 return crypto_aead_decrypt(&req->areq); 143} 144 145static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) 146{ 147 struct aead_alg *alg = &tfm->__crt_alg->cra_aead; 148 struct aead_tfm *crt = &tfm->crt_aead; 149 150 if (max(alg->maxauthsize, alg->ivsize) > PAGE_SIZE / 8) 151 return -EINVAL; 152 153 crt->setkey = setkey; 154 crt->encrypt = alg->encrypt; 155 crt->decrypt = alg->decrypt; 156 if (!alg->ivsize) { 157 crt->givencrypt = aead_null_givencrypt; 158 crt->givdecrypt = aead_null_givdecrypt; 159 } 160 crt->base = __crypto_aead_cast(tfm); 161 crt->ivsize = alg->ivsize; 162 crt->authsize = alg->maxauthsize; 163 164 return 0; 165} 166 167static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) 168 __attribute__ ((unused)); 169static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) 170{ 171 struct aead_alg *aead = &alg->cra_aead; 172 173 seq_printf(m, "type : nivaead\n"); 174 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 175 "yes" : "no"); 176 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 177 seq_printf(m, "ivsize : %u\n", aead->ivsize); 178 seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); 179 seq_printf(m, "geniv : %s\n", aead->geniv); 180} 181 182const struct crypto_type crypto_nivaead_type = { 183 .ctxsize = crypto_aead_ctxsize, 184 .init = crypto_init_nivaead_ops, 185#ifdef CONFIG_PROC_FS 186 .show = crypto_nivaead_show, 187#endif 188}; 189EXPORT_SYMBOL_GPL(crypto_nivaead_type); 190 191static int crypto_grab_nivaead(struct crypto_aead_spawn *spawn, 192 const char *name, u32 type, u32 mask) 193{ 194 struct crypto_alg *alg; 195 int err; 196 197 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 198 type |= CRYPTO_ALG_TYPE_AEAD; 199 mask |= CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV; 200 201 alg = crypto_alg_mod_lookup(name, type, mask); 202 if (IS_ERR(alg)) 203 return PTR_ERR(alg); 204 205 err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask); 206 crypto_mod_put(alg); 207 return err; 208} 209 210struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl, 211 struct rtattr **tb, u32 type, 212 u32 mask) 213{ 214 const char *name; 215 struct crypto_aead_spawn *spawn; 216 struct crypto_attr_type *algt; 217 struct crypto_instance *inst; 218 struct crypto_alg *alg; 219 int err; 220 221 algt = crypto_get_attr_type(tb); 222 err = PTR_ERR(algt); 223 if (IS_ERR(algt)) 224 return ERR_PTR(err); 225 226 if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV)) & 227 algt->mask) 228 return ERR_PTR(-EINVAL); 229 230 name = crypto_attr_alg_name(tb[1]); 231 err = PTR_ERR(name); 232 if (IS_ERR(name)) 233 return ERR_PTR(err); 234 235 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 236 if (!inst) 237 return ERR_PTR(-ENOMEM); 238 239 spawn = crypto_instance_ctx(inst); 240 241 /* Ignore async algorithms if necessary. */ 242 mask |= crypto_requires_sync(algt->type, algt->mask); 243 244 crypto_set_aead_spawn(spawn, inst); 245 err = crypto_grab_nivaead(spawn, name, type, mask); 246 if (err) 247 goto err_free_inst; 248 249 alg = crypto_aead_spawn_alg(spawn); 250 251 err = -EINVAL; 252 if (!alg->cra_aead.ivsize) 253 goto err_drop_alg; 254 255 /* 256 * This is only true if we're constructing an algorithm with its 257 * default IV generator. For the default generator we elide the 258 * template name and double-check the IV generator. 259 */ 260 if (algt->mask & CRYPTO_ALG_GENIV) { 261 if (strcmp(tmpl->name, alg->cra_aead.geniv)) 262 goto err_drop_alg; 263 264 memcpy(inst->alg.cra_name, alg->cra_name, CRYPTO_MAX_ALG_NAME); 265 memcpy(inst->alg.cra_driver_name, alg->cra_driver_name, 266 CRYPTO_MAX_ALG_NAME); 267 } else { 268 err = -ENAMETOOLONG; 269 if (snprintf(inst->alg.cra_name, CRYPTO_MAX_ALG_NAME, 270 "%s(%s)", tmpl->name, alg->cra_name) >= 271 CRYPTO_MAX_ALG_NAME) 272 goto err_drop_alg; 273 if (snprintf(inst->alg.cra_driver_name, CRYPTO_MAX_ALG_NAME, 274 "%s(%s)", tmpl->name, alg->cra_driver_name) >= 275 CRYPTO_MAX_ALG_NAME) 276 goto err_drop_alg; 277 } 278 279 inst->alg.cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV; 280 inst->alg.cra_flags |= alg->cra_flags & CRYPTO_ALG_ASYNC; 281 inst->alg.cra_priority = alg->cra_priority; 282 inst->alg.cra_blocksize = alg->cra_blocksize; 283 inst->alg.cra_alignmask = alg->cra_alignmask; 284 inst->alg.cra_type = &crypto_aead_type; 285 286 inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize; 287 inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize; 288 inst->alg.cra_aead.geniv = alg->cra_aead.geniv; 289 290 inst->alg.cra_aead.setkey = alg->cra_aead.setkey; 291 inst->alg.cra_aead.setauthsize = alg->cra_aead.setauthsize; 292 inst->alg.cra_aead.encrypt = alg->cra_aead.encrypt; 293 inst->alg.cra_aead.decrypt = alg->cra_aead.decrypt; 294 295out: 296 return inst; 297 298err_drop_alg: 299 crypto_drop_aead(spawn); 300err_free_inst: 301 kfree(inst); 302 inst = ERR_PTR(err); 303 goto out; 304} 305EXPORT_SYMBOL_GPL(aead_geniv_alloc); 306 307void aead_geniv_free(struct crypto_instance *inst) 308{ 309 crypto_drop_aead(crypto_instance_ctx(inst)); 310 kfree(inst); 311} 312EXPORT_SYMBOL_GPL(aead_geniv_free); 313 314int aead_geniv_init(struct crypto_tfm *tfm) 315{ 316 struct crypto_instance *inst = (void *)tfm->__crt_alg; 317 struct crypto_aead *aead; 318 319 aead = crypto_spawn_aead(crypto_instance_ctx(inst)); 320 if (IS_ERR(aead)) 321 return PTR_ERR(aead); 322 323 tfm->crt_aead.base = aead; 324 tfm->crt_aead.reqsize += crypto_aead_reqsize(aead); 325 326 return 0; 327} 328EXPORT_SYMBOL_GPL(aead_geniv_init); 329 330void aead_geniv_exit(struct crypto_tfm *tfm) 331{ 332 crypto_free_aead(tfm->crt_aead.base); 333} 334EXPORT_SYMBOL_GPL(aead_geniv_exit); 335 336static int crypto_nivaead_default(struct crypto_alg *alg, u32 type, u32 mask) 337{ 338 struct rtattr *tb[3]; 339 struct { 340 struct rtattr attr; 341 struct crypto_attr_type data; 342 } ptype; 343 struct { 344 struct rtattr attr; 345 struct crypto_attr_alg data; 346 } palg; 347 struct crypto_template *tmpl; 348 struct crypto_instance *inst; 349 struct crypto_alg *larval; 350 const char *geniv; 351 int err; 352 353 larval = crypto_larval_lookup(alg->cra_driver_name, 354 CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_GENIV, 355 CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 356 err = PTR_ERR(larval); 357 if (IS_ERR(larval)) 358 goto out; 359 360 err = -EAGAIN; 361 if (!crypto_is_larval(larval)) 362 goto drop_larval; 363 364 ptype.attr.rta_len = sizeof(ptype); 365 ptype.attr.rta_type = CRYPTOA_TYPE; 366 ptype.data.type = type | CRYPTO_ALG_GENIV; 367 /* GENIV tells the template that we're making a default geniv. */ 368 ptype.data.mask = mask | CRYPTO_ALG_GENIV; 369 tb[0] = &ptype.attr; 370 371 palg.attr.rta_len = sizeof(palg); 372 palg.attr.rta_type = CRYPTOA_ALG; 373 /* Must use the exact name to locate ourselves. */ 374 memcpy(palg.data.name, alg->cra_driver_name, CRYPTO_MAX_ALG_NAME); 375 tb[1] = &palg.attr; 376 377 tb[2] = NULL; 378 379 geniv = alg->cra_aead.geniv; 380 381 tmpl = crypto_lookup_template(geniv); 382 err = -ENOENT; 383 if (!tmpl) 384 goto kill_larval; 385 386 inst = tmpl->alloc(tb); 387 err = PTR_ERR(inst); 388 if (IS_ERR(inst)) 389 goto put_tmpl; 390 391 if ((err = crypto_register_instance(tmpl, inst))) { 392 tmpl->free(inst); 393 goto put_tmpl; 394 } 395 396 /* Redo the lookup to use the instance we just registered. */ 397 err = -EAGAIN; 398 399put_tmpl: 400 crypto_tmpl_put(tmpl); 401kill_larval: 402 crypto_larval_kill(larval); 403drop_larval: 404 crypto_mod_put(larval); 405out: 406 crypto_mod_put(alg); 407 return err; 408} 409 410static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type, 411 u32 mask) 412{ 413 struct crypto_alg *alg; 414 415 alg = crypto_alg_mod_lookup(name, type, mask); 416 if (IS_ERR(alg)) 417 return alg; 418 419 if (alg->cra_type == &crypto_aead_type) 420 return alg; 421 422 if (!alg->cra_aead.ivsize) 423 return alg; 424 425 return ERR_PTR(crypto_nivaead_default(alg, type, mask)); 426} 427 428int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, 429 u32 type, u32 mask) 430{ 431 struct crypto_alg *alg; 432 int err; 433 434 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 435 type |= CRYPTO_ALG_TYPE_AEAD; 436 mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 437 mask |= CRYPTO_ALG_TYPE_MASK; 438 439 alg = crypto_lookup_aead(name, type, mask); 440 if (IS_ERR(alg)) 441 return PTR_ERR(alg); 442 443 err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask); 444 crypto_mod_put(alg); 445 return err; 446} 447EXPORT_SYMBOL_GPL(crypto_grab_aead); 448 449struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask) 450{ 451 struct crypto_tfm *tfm; 452 int err; 453 454 type &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 455 type |= CRYPTO_ALG_TYPE_AEAD; 456 mask &= ~(CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_GENIV); 457 mask |= CRYPTO_ALG_TYPE_MASK; 458 459 for (;;) { 460 struct crypto_alg *alg; 461 462 alg = crypto_lookup_aead(alg_name, type, mask); 463 if (IS_ERR(alg)) { 464 err = PTR_ERR(alg); 465 goto err; 466 } 467 468 tfm = __crypto_alloc_tfm(alg, type, mask); 469 if (!IS_ERR(tfm)) 470 return __crypto_aead_cast(tfm); 471 472 crypto_mod_put(alg); 473 err = PTR_ERR(tfm); 474 475err: 476 if (err != -EAGAIN) 477 break; 478 if (signal_pending(current)) { 479 err = -EINTR; 480 break; 481 } 482 } 483 484 return ERR_PTR(err); 485} 486EXPORT_SYMBOL_GPL(crypto_alloc_aead); 487 488MODULE_LICENSE("GPL"); 489MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)");