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