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/aead.h> 11 #include <linux/cryptouser.h> 12 #include <linux/errno.h> 13 #include <linux/init.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/slab.h> 17 #include <linux/seq_file.h> 18 #include <linux/string.h> 19 #include <net/netlink.h> 20 21 #include "internal.h" 22 23 static inline struct crypto_istat_aead *aead_get_stat(struct aead_alg *alg) 24 { 25 #ifdef CONFIG_CRYPTO_STATS 26 return &alg->stat; 27 #else 28 return NULL; 29 #endif 30 } 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 kfree_sensitive(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 int err; 57 58 if ((unsigned long)key & alignmask) 59 err = setkey_unaligned(tfm, key, keylen); 60 else 61 err = crypto_aead_alg(tfm)->setkey(tfm, key, keylen); 62 63 if (unlikely(err)) { 64 crypto_aead_set_flags(tfm, CRYPTO_TFM_NEED_KEY); 65 return err; 66 } 67 68 crypto_aead_clear_flags(tfm, CRYPTO_TFM_NEED_KEY); 69 return 0; 70 } 71 EXPORT_SYMBOL_GPL(crypto_aead_setkey); 72 73 int crypto_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) 74 { 75 int err; 76 77 if ((!authsize && crypto_aead_maxauthsize(tfm)) || 78 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 inline int crypto_aead_errstat(struct crypto_istat_aead *istat, int err) 93 { 94 if (!IS_ENABLED(CONFIG_CRYPTO_STATS)) 95 return err; 96 97 if (err && err != -EINPROGRESS && err != -EBUSY) 98 atomic64_inc(&istat->err_cnt); 99 100 return err; 101 } 102 103 int crypto_aead_encrypt(struct aead_request *req) 104 { 105 struct crypto_aead *aead = crypto_aead_reqtfm(req); 106 struct aead_alg *alg = crypto_aead_alg(aead); 107 struct crypto_istat_aead *istat; 108 int ret; 109 110 istat = aead_get_stat(alg); 111 112 if (IS_ENABLED(CONFIG_CRYPTO_STATS)) { 113 atomic64_inc(&istat->encrypt_cnt); 114 atomic64_add(req->cryptlen, &istat->encrypt_tlen); 115 } 116 117 if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY) 118 ret = -ENOKEY; 119 else 120 ret = alg->encrypt(req); 121 122 return crypto_aead_errstat(istat, ret); 123 } 124 EXPORT_SYMBOL_GPL(crypto_aead_encrypt); 125 126 int crypto_aead_decrypt(struct aead_request *req) 127 { 128 struct crypto_aead *aead = crypto_aead_reqtfm(req); 129 struct aead_alg *alg = crypto_aead_alg(aead); 130 struct crypto_istat_aead *istat; 131 int ret; 132 133 istat = aead_get_stat(alg); 134 135 if (IS_ENABLED(CONFIG_CRYPTO_STATS)) { 136 atomic64_inc(&istat->encrypt_cnt); 137 atomic64_add(req->cryptlen, &istat->encrypt_tlen); 138 } 139 140 if (crypto_aead_get_flags(aead) & CRYPTO_TFM_NEED_KEY) 141 ret = -ENOKEY; 142 else if (req->cryptlen < crypto_aead_authsize(aead)) 143 ret = -EINVAL; 144 else 145 ret = alg->decrypt(req); 146 147 return crypto_aead_errstat(istat, ret); 148 } 149 EXPORT_SYMBOL_GPL(crypto_aead_decrypt); 150 151 static void crypto_aead_exit_tfm(struct crypto_tfm *tfm) 152 { 153 struct crypto_aead *aead = __crypto_aead_cast(tfm); 154 struct aead_alg *alg = crypto_aead_alg(aead); 155 156 alg->exit(aead); 157 } 158 159 static int crypto_aead_init_tfm(struct crypto_tfm *tfm) 160 { 161 struct crypto_aead *aead = __crypto_aead_cast(tfm); 162 struct aead_alg *alg = crypto_aead_alg(aead); 163 164 crypto_aead_set_flags(aead, CRYPTO_TFM_NEED_KEY); 165 166 aead->authsize = alg->maxauthsize; 167 168 if (alg->exit) 169 aead->base.exit = crypto_aead_exit_tfm; 170 171 if (alg->init) 172 return alg->init(aead); 173 174 return 0; 175 } 176 177 static int __maybe_unused crypto_aead_report( 178 struct sk_buff *skb, struct crypto_alg *alg) 179 { 180 struct crypto_report_aead raead; 181 struct aead_alg *aead = container_of(alg, struct aead_alg, base); 182 183 memset(&raead, 0, sizeof(raead)); 184 185 strscpy(raead.type, "aead", sizeof(raead.type)); 186 strscpy(raead.geniv, "<none>", sizeof(raead.geniv)); 187 188 raead.blocksize = alg->cra_blocksize; 189 raead.maxauthsize = aead->maxauthsize; 190 raead.ivsize = aead->ivsize; 191 192 return nla_put(skb, CRYPTOCFGA_REPORT_AEAD, sizeof(raead), &raead); 193 } 194 195 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 196 __maybe_unused; 197 static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) 198 { 199 struct aead_alg *aead = container_of(alg, struct aead_alg, base); 200 201 seq_printf(m, "type : aead\n"); 202 seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? 203 "yes" : "no"); 204 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); 205 seq_printf(m, "ivsize : %u\n", aead->ivsize); 206 seq_printf(m, "maxauthsize : %u\n", aead->maxauthsize); 207 seq_printf(m, "geniv : <none>\n"); 208 } 209 210 static void crypto_aead_free_instance(struct crypto_instance *inst) 211 { 212 struct aead_instance *aead = aead_instance(inst); 213 214 aead->free(aead); 215 } 216 217 static int __maybe_unused crypto_aead_report_stat( 218 struct sk_buff *skb, struct crypto_alg *alg) 219 { 220 struct aead_alg *aead = container_of(alg, struct aead_alg, base); 221 struct crypto_istat_aead *istat = aead_get_stat(aead); 222 struct crypto_stat_aead raead; 223 224 memset(&raead, 0, sizeof(raead)); 225 226 strscpy(raead.type, "aead", sizeof(raead.type)); 227 228 raead.stat_encrypt_cnt = atomic64_read(&istat->encrypt_cnt); 229 raead.stat_encrypt_tlen = atomic64_read(&istat->encrypt_tlen); 230 raead.stat_decrypt_cnt = atomic64_read(&istat->decrypt_cnt); 231 raead.stat_decrypt_tlen = atomic64_read(&istat->decrypt_tlen); 232 raead.stat_err_cnt = atomic64_read(&istat->err_cnt); 233 234 return nla_put(skb, CRYPTOCFGA_STAT_AEAD, sizeof(raead), &raead); 235 } 236 237 static const struct crypto_type crypto_aead_type = { 238 .extsize = crypto_alg_extsize, 239 .init_tfm = crypto_aead_init_tfm, 240 .free = crypto_aead_free_instance, 241 #ifdef CONFIG_PROC_FS 242 .show = crypto_aead_show, 243 #endif 244 #if IS_ENABLED(CONFIG_CRYPTO_USER) 245 .report = crypto_aead_report, 246 #endif 247 #ifdef CONFIG_CRYPTO_STATS 248 .report_stat = crypto_aead_report_stat, 249 #endif 250 .maskclear = ~CRYPTO_ALG_TYPE_MASK, 251 .maskset = CRYPTO_ALG_TYPE_MASK, 252 .type = CRYPTO_ALG_TYPE_AEAD, 253 .tfmsize = offsetof(struct crypto_aead, base), 254 }; 255 256 int crypto_grab_aead(struct crypto_aead_spawn *spawn, 257 struct crypto_instance *inst, 258 const char *name, u32 type, u32 mask) 259 { 260 spawn->base.frontend = &crypto_aead_type; 261 return crypto_grab_spawn(&spawn->base, inst, name, type, mask); 262 } 263 EXPORT_SYMBOL_GPL(crypto_grab_aead); 264 265 struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask) 266 { 267 return crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask); 268 } 269 EXPORT_SYMBOL_GPL(crypto_alloc_aead); 270 271 static int aead_prepare_alg(struct aead_alg *alg) 272 { 273 struct crypto_istat_aead *istat = aead_get_stat(alg); 274 struct crypto_alg *base = &alg->base; 275 276 if (max3(alg->maxauthsize, alg->ivsize, alg->chunksize) > 277 PAGE_SIZE / 8) 278 return -EINVAL; 279 280 if (!alg->chunksize) 281 alg->chunksize = base->cra_blocksize; 282 283 base->cra_type = &crypto_aead_type; 284 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; 285 base->cra_flags |= CRYPTO_ALG_TYPE_AEAD; 286 287 if (IS_ENABLED(CONFIG_CRYPTO_STATS)) 288 memset(istat, 0, sizeof(*istat)); 289 290 return 0; 291 } 292 293 int crypto_register_aead(struct aead_alg *alg) 294 { 295 struct crypto_alg *base = &alg->base; 296 int err; 297 298 err = aead_prepare_alg(alg); 299 if (err) 300 return err; 301 302 return crypto_register_alg(base); 303 } 304 EXPORT_SYMBOL_GPL(crypto_register_aead); 305 306 void crypto_unregister_aead(struct aead_alg *alg) 307 { 308 crypto_unregister_alg(&alg->base); 309 } 310 EXPORT_SYMBOL_GPL(crypto_unregister_aead); 311 312 int crypto_register_aeads(struct aead_alg *algs, int count) 313 { 314 int i, ret; 315 316 for (i = 0; i < count; i++) { 317 ret = crypto_register_aead(&algs[i]); 318 if (ret) 319 goto err; 320 } 321 322 return 0; 323 324 err: 325 for (--i; i >= 0; --i) 326 crypto_unregister_aead(&algs[i]); 327 328 return ret; 329 } 330 EXPORT_SYMBOL_GPL(crypto_register_aeads); 331 332 void crypto_unregister_aeads(struct aead_alg *algs, int count) 333 { 334 int i; 335 336 for (i = count - 1; i >= 0; --i) 337 crypto_unregister_aead(&algs[i]); 338 } 339 EXPORT_SYMBOL_GPL(crypto_unregister_aeads); 340 341 int aead_register_instance(struct crypto_template *tmpl, 342 struct aead_instance *inst) 343 { 344 int err; 345 346 if (WARN_ON(!inst->free)) 347 return -EINVAL; 348 349 err = aead_prepare_alg(&inst->alg); 350 if (err) 351 return err; 352 353 return crypto_register_instance(tmpl, aead_crypto_instance(inst)); 354 } 355 EXPORT_SYMBOL_GPL(aead_register_instance); 356 357 MODULE_LICENSE("GPL"); 358 MODULE_DESCRIPTION("Authenticated Encryption with Associated Data (AEAD)"); 359