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