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