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