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