1 /* 2 * AEAD: Authenticated Encryption with Associated Data 3 * 4 * This file provides API support for AEAD algorithms. 5 * 6 * Copyright (c) 2007-2015 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/geniv.h> 16 #include <crypto/internal/rng.h> 17 #include <crypto/null.h> 18 #include <crypto/scatterwalk.h> 19 #include <linux/err.h> 20 #include <linux/init.h> 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/rtnetlink.h> 24 #include <linux/slab.h> 25 #include <linux/seq_file.h> 26 #include <linux/cryptouser.h> 27 #include <linux/compiler.h> 28 #include <net/netlink.h> 29 30 #include "internal.h" 31 32 static int setkey_unaligned(struct crypto_aead *tfm, const u8 *key, 33 unsigned int keylen) 34 { 35 unsigned long alignmask = crypto_aead_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 = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen); 48 memset(alignbuffer, 0, keylen); 49 kfree(buffer); 50 return ret; 51 } 52 53 int crypto_aead_setkey(struct crypto_aead *tfm, 54 const u8 *key, unsigned int keylen) 55 { 56 unsigned long alignmask = crypto_aead_alignmask(tfm); 57 58 if ((unsigned long)key & alignmask) 59 return setkey_unaligned(tfm, key, keylen); 60 61 return crypto_aead_alg(tfm)->setkey(tfm, key, keylen); 62 } 63 EXPORT_SYMBOL_GPL(crypto_aead_setkey); 64 65 int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) 66 { 67 int err; 68 69 if (authsize > crypto_aead_maxauthsize(tfm)) 70 return -EINVAL; 71 72 if (crypto_aead_alg(tfm)->setauthsize) { 73 err = crypto_aead_alg(tfm)->setauthsize(tfm, authsize); 74 if (err) 75 return err; 76 } 77 78 tfm->authsize = authsize; 79 return 0; 80 } 81 EXPORT_SYMBOL_GPL(crypto_aead_setauthsize); 82 83 static void crypto_aead_exit_tfm(struct crypto_tfm *tfm) 84 { 85 struct crypto_aead *aead = __crypto_aead_cast(tfm); 86 struct aead_alg *alg = crypto_aead_alg(aead); 87 88 alg->exit(aead); 89 } 90 91 static int crypto_aead_init_tfm(struct crypto_tfm *tfm) 92 { 93 struct crypto_aead *aead = __crypto_aead_cast(tfm); 94 struct aead_alg *alg = crypto_aead_alg(aead); 95 96 aead->authsize = alg->maxauthsize; 97 98 if (alg->exit) 99 aead->base.exit = crypto_aead_exit_tfm; 100 101 if (alg->init) 102 return alg->init(aead); 103 104 return 0; 105 } 106 107 #ifdef CONFIG_NET 108 static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) 109 { 110 struct crypto_report_aead raead; 111 struct aead_alg *aead = container_of(alg, struct aead_alg, base); 112 113 strncpy(raead.type, "aead", sizeof(raead.type)); 114 strncpy(raead.geniv, "<none>", sizeof(raead.geniv)); 115 116 raead.blocksize = alg->cra_blocksize; 117 raead.maxauthsize = aead->maxauthsize; 118 raead.ivsize = aead->ivsize; 119 120 if (nla_put(skb, CRYPTOCFGA_REPORT_AEAD, 121 sizeof(struct crypto_report_aead), &raead)) 122 goto nla_put_failure; 123 return 0; 124 125 nla_put_failure: 126 return -EMSGSIZE; 127 } 128 #else 129 static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) 130 { 131 return -ENOSYS; 132 } 133 #endif 134 135 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 136 __maybe_unused; 137 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 138 { 139 struct aead_alg *aead = container_of(alg, struct aead_alg, base); 140 141 seq_printf(m, "type : aead\n"); 142 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 143 "yes" : "no"); 144 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 145 seq_printf(m, "ivsize : %u\n", aead->ivsize); 146 seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); 147 seq_printf(m, "geniv : <none>\n"); 148 } 149 150 static void crypto_aead_free_instance(struct crypto_instance *inst) 151 { 152 struct aead_instance *aead = aead_instance(inst); 153 154 if (!aead->free) { 155 inst->tmpl->free(inst); 156 return; 157 } 158 159 aead->free(aead); 160 } 161 162 static const struct crypto_type crypto_aead_type = { 163 .extsize = crypto_alg_extsize, 164 .init_tfm = crypto_aead_init_tfm, 165 .free = crypto_aead_free_instance, 166 #ifdef CONFIG_PROC_FS 167 .show = crypto_aead_show, 168 #endif 169 .report = crypto_aead_report, 170 .maskclear = ~CRYPTO_ALG_TYPE_MASK, 171 .maskset = CRYPTO_ALG_TYPE_MASK, 172 .type = CRYPTO_ALG_TYPE_AEAD, 173 .tfmsize = offsetof(struct crypto_aead, base), 174 }; 175 176 static int aead_geniv_setkey(struct crypto_aead *tfm, 177 const u8 *key, unsigned int keylen) 178 { 179 struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 180 181 return crypto_aead_setkey(ctx->child, key, keylen); 182 } 183 184 static int aead_geniv_setauthsize(struct crypto_aead *tfm, 185 unsigned int authsize) 186 { 187 struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 188 189 return crypto_aead_setauthsize(ctx->child, authsize); 190 } 191 192 struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl, 193 struct rtattr **tb, u32 type, u32 mask) 194 { 195 const char *name; 196 struct crypto_aead_spawn *spawn; 197 struct crypto_attr_type *algt; 198 struct aead_instance *inst; 199 struct aead_alg *alg; 200 unsigned int ivsize; 201 unsigned int maxauthsize; 202 int err; 203 204 algt = crypto_get_attr_type(tb); 205 if (IS_ERR(algt)) 206 return ERR_CAST(algt); 207 208 if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask) 209 return ERR_PTR(-EINVAL); 210 211 name = crypto_attr_alg_name(tb[1]); 212 if (IS_ERR(name)) 213 return ERR_CAST(name); 214 215 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL); 216 if (!inst) 217 return ERR_PTR(-ENOMEM); 218 219 spawn = aead_instance_ctx(inst); 220 221 /* Ignore async algorithms if necessary. */ 222 mask |= crypto_requires_sync(algt->type, algt->mask); 223 224 crypto_set_aead_spawn(spawn, aead_crypto_instance(inst)); 225 err = crypto_grab_aead(spawn, name, type, mask); 226 if (err) 227 goto err_free_inst; 228 229 alg = crypto_spawn_aead_alg(spawn); 230 231 ivsize = crypto_aead_alg_ivsize(alg); 232 maxauthsize = crypto_aead_alg_maxauthsize(alg); 233 234 err = -EINVAL; 235 if (ivsize < sizeof(u64)) 236 goto err_drop_alg; 237 238 err = -ENAMETOOLONG; 239 if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, 240 "%s(%s)", tmpl->name, alg->base.cra_name) >= 241 CRYPTO_MAX_ALG_NAME) 242 goto err_drop_alg; 243 if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME, 244 "%s(%s)", tmpl->name, alg->base.cra_driver_name) >= 245 CRYPTO_MAX_ALG_NAME) 246 goto err_drop_alg; 247 248 inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC; 249 inst->alg.base.cra_priority = alg->base.cra_priority; 250 inst->alg.base.cra_blocksize = alg->base.cra_blocksize; 251 inst->alg.base.cra_alignmask = alg->base.cra_alignmask; 252 inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx); 253 254 inst->alg.setkey = aead_geniv_setkey; 255 inst->alg.setauthsize = aead_geniv_setauthsize; 256 257 inst->alg.ivsize = ivsize; 258 inst->alg.maxauthsize = maxauthsize; 259 260 out: 261 return inst; 262 263 err_drop_alg: 264 crypto_drop_aead(spawn); 265 err_free_inst: 266 kfree(inst); 267 inst = ERR_PTR(err); 268 goto out; 269 } 270 EXPORT_SYMBOL_GPL(aead_geniv_alloc); 271 272 void aead_geniv_free(struct aead_instance *inst) 273 { 274 crypto_drop_aead(aead_instance_ctx(inst)); 275 kfree(inst); 276 } 277 EXPORT_SYMBOL_GPL(aead_geniv_free); 278 279 int aead_init_geniv(struct crypto_aead *aead) 280 { 281 struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead); 282 struct aead_instance *inst = aead_alg_instance(aead); 283 struct crypto_aead *child; 284 int err; 285 286 spin_lock_init(&ctx->lock); 287 288 err = crypto_get_default_rng(); 289 if (err) 290 goto out; 291 292 err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt, 293 crypto_aead_ivsize(aead)); 294 crypto_put_default_rng(); 295 if (err) 296 goto out; 297 298 ctx->sknull = crypto_get_default_null_skcipher2(); 299 err = PTR_ERR(ctx->sknull); 300 if (IS_ERR(ctx->sknull)) 301 goto out; 302 303 child = crypto_spawn_aead(aead_instance_ctx(inst)); 304 err = PTR_ERR(child); 305 if (IS_ERR(child)) 306 goto drop_null; 307 308 ctx->child = child; 309 crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) + 310 sizeof(struct aead_request)); 311 312 err = 0; 313 314 out: 315 return err; 316 317 drop_null: 318 crypto_put_default_null_skcipher2(); 319 goto out; 320 } 321 EXPORT_SYMBOL_GPL(aead_init_geniv); 322 323 void aead_exit_geniv(struct crypto_aead *tfm) 324 { 325 struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm); 326 327 crypto_free_aead(ctx->child); 328 crypto_put_default_null_skcipher2(); 329 } 330 EXPORT_SYMBOL_GPL(aead_exit_geniv); 331 332 int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name, 333 u32 type, u32 mask) 334 { 335 spawn->base.frontend = &crypto_aead_type; 336 return crypto_grab_spawn(&spawn->base, name, type, mask); 337 } 338 EXPORT_SYMBOL_GPL(crypto_grab_aead); 339 340 struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask) 341 { 342 return crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask); 343 } 344 EXPORT_SYMBOL_GPL(crypto_alloc_aead); 345 346 static int aead_prepare_alg(struct aead_alg *alg) 347 { 348 struct crypto_alg *base = &alg->base; 349 350 if (max3(alg->maxauthsize, alg->ivsize, alg->chunksize) > 351 PAGE_SIZE / 8) 352 return -EINVAL; 353 354 if (!alg->chunksize) 355 alg->chunksize = base->cra_blocksize; 356 357 base->cra_type = &crypto_aead_type; 358 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; 359 base->cra_flags |= CRYPTO_ALG_TYPE_AEAD; 360 361 return 0; 362 } 363 364 int crypto_register_aead(struct aead_alg *alg) 365 { 366 struct crypto_alg *base = &alg->base; 367 int err; 368 369 err = aead_prepare_alg(alg); 370 if (err) 371 return err; 372 373 return crypto_register_alg(base); 374 } 375 EXPORT_SYMBOL_GPL(crypto_register_aead); 376 377 void crypto_unregister_aead(struct aead_alg *alg) 378 { 379 crypto_unregister_alg(&alg->base); 380 } 381 EXPORT_SYMBOL_GPL(crypto_unregister_aead); 382 383 int crypto_register_aeads(struct aead_alg *algs, int count) 384 { 385 int i, ret; 386 387 for (i = 0; i < count; i++) { 388 ret = crypto_register_aead(&algs[i]); 389 if (ret) 390 goto err; 391 } 392 393 return 0; 394 395 err: 396 for (--i; i >= 0; --i) 397 crypto_unregister_aead(&algs[i]); 398 399 return ret; 400 } 401 EXPORT_SYMBOL_GPL(crypto_register_aeads); 402 403 void crypto_unregister_aeads(struct aead_alg *algs, int count) 404 { 405 int i; 406 407 for (i = count - 1; i >= 0; --i) 408 crypto_unregister_aead(&algs[i]); 409 } 410 EXPORT_SYMBOL_GPL(crypto_unregister_aeads); 411 412 int aead_register_instance(struct crypto_template *tmpl, 413 struct aead_instance *inst) 414 { 415 int err; 416 417 err = aead_prepare_alg(&inst->alg); 418 if (err) 419 return err; 420 421 return crypto_register_instance(tmpl, aead_crypto_instance(inst)); 422 } 423 EXPORT_SYMBOL_GPL(aead_register_instance); 424 425 MODULE_LICENSE("GPL"); 426 MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)"); 427