1 // SPDX-License-Identifier: GPL-2.0-or-later << 2 /* 1 /* 3 * Shared crypto simd helpers 2 * Shared crypto simd helpers 4 * 3 * 5 * Copyright (c) 2012 Jussi Kivilinna <jussi.k 4 * Copyright (c) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 6 * Copyright (c) 2016 Herbert Xu <herbert@gond 5 * Copyright (c) 2016 Herbert Xu <herbert@gondor.apana.org.au> 7 * Copyright (c) 2019 Google LLC << 8 * 6 * 9 * Based on aesni-intel_glue.c by: 7 * Based on aesni-intel_glue.c by: 10 * Copyright (C) 2008, Intel Corp. 8 * Copyright (C) 2008, Intel Corp. 11 * Author: Huang Ying <ying.huang@intel.com 9 * Author: Huang Ying <ying.huang@intel.com> 12 */ << 13 << 14 /* << 15 * Shared crypto SIMD helpers. These function << 16 * an skcipher or AEAD algorithm that wraps an << 17 * wrapper ensures that the internal algorithm << 18 * where SIMD instructions are usable, i.e. wh << 19 * If SIMD is already usable, the wrapper dire << 20 * Otherwise it defers execution to a workqueu << 21 * 10 * 22 * This is an alternative to the internal algo !! 11 * This program is free software; you can redistribute it and/or modify 23 * the !may_use_simd() case itself. !! 12 * it under the terms of the GNU General Public License as published by >> 13 * the Free Software Foundation; either version 2 of the License, or >> 14 * (at your option) any later version. >> 15 * >> 16 * This program is distributed in the hope that it will be useful, >> 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of >> 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> 19 * GNU General Public License for more details. >> 20 * >> 21 * You should have received a copy of the GNU General Public License >> 22 * along with this program; if not, write to the Free Software >> 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 >> 24 * USA 24 * 25 * 25 * Note that the wrapper algorithm is asynchro << 26 * CRYPTO_ALG_ASYNC flag set. Therefore it wo << 27 * explicitly allocate a synchronous algorithm << 28 */ 26 */ 29 27 30 #include <crypto/cryptd.h> 28 #include <crypto/cryptd.h> 31 #include <crypto/internal/aead.h> << 32 #include <crypto/internal/simd.h> 29 #include <crypto/internal/simd.h> 33 #include <crypto/internal/skcipher.h> 30 #include <crypto/internal/skcipher.h> 34 #include <linux/kernel.h> 31 #include <linux/kernel.h> 35 #include <linux/module.h> 32 #include <linux/module.h> 36 #include <linux/preempt.h> 33 #include <linux/preempt.h> 37 #include <asm/simd.h> 34 #include <asm/simd.h> 38 35 39 /* skcipher support */ << 40 << 41 struct simd_skcipher_alg { 36 struct simd_skcipher_alg { 42 const char *ialg_name; 37 const char *ialg_name; 43 struct skcipher_alg alg; 38 struct skcipher_alg alg; 44 }; 39 }; 45 40 46 struct simd_skcipher_ctx { 41 struct simd_skcipher_ctx { 47 struct cryptd_skcipher *cryptd_tfm; 42 struct cryptd_skcipher *cryptd_tfm; 48 }; 43 }; 49 44 50 static int simd_skcipher_setkey(struct crypto_ 45 static int simd_skcipher_setkey(struct crypto_skcipher *tfm, const u8 *key, 51 unsigned int k 46 unsigned int key_len) 52 { 47 { 53 struct simd_skcipher_ctx *ctx = crypto 48 struct simd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 54 struct crypto_skcipher *child = &ctx-> 49 struct crypto_skcipher *child = &ctx->cryptd_tfm->base; >> 50 int err; 55 51 56 crypto_skcipher_clear_flags(child, CRY 52 crypto_skcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 57 crypto_skcipher_set_flags(child, crypt 53 crypto_skcipher_set_flags(child, crypto_skcipher_get_flags(tfm) & 58 CRYPT 54 CRYPTO_TFM_REQ_MASK); 59 return crypto_skcipher_setkey(child, k !! 55 err = crypto_skcipher_setkey(child, key, key_len); >> 56 crypto_skcipher_set_flags(tfm, crypto_skcipher_get_flags(child) & >> 57 CRYPTO_TFM_RES_MASK); >> 58 return err; 60 } 59 } 61 60 62 static int simd_skcipher_encrypt(struct skciph 61 static int simd_skcipher_encrypt(struct skcipher_request *req) 63 { 62 { 64 struct crypto_skcipher *tfm = crypto_s 63 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 65 struct simd_skcipher_ctx *ctx = crypto 64 struct simd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 66 struct skcipher_request *subreq; 65 struct skcipher_request *subreq; 67 struct crypto_skcipher *child; 66 struct crypto_skcipher *child; 68 67 69 subreq = skcipher_request_ctx(req); 68 subreq = skcipher_request_ctx(req); 70 *subreq = *req; 69 *subreq = *req; 71 70 72 if (!crypto_simd_usable() || !! 71 if (!may_use_simd() || 73 (in_atomic() && cryptd_skcipher_qu 72 (in_atomic() && cryptd_skcipher_queued(ctx->cryptd_tfm))) 74 child = &ctx->cryptd_tfm->base 73 child = &ctx->cryptd_tfm->base; 75 else 74 else 76 child = cryptd_skcipher_child( 75 child = cryptd_skcipher_child(ctx->cryptd_tfm); 77 76 78 skcipher_request_set_tfm(subreq, child 77 skcipher_request_set_tfm(subreq, child); 79 78 80 return crypto_skcipher_encrypt(subreq) 79 return crypto_skcipher_encrypt(subreq); 81 } 80 } 82 81 83 static int simd_skcipher_decrypt(struct skciph 82 static int simd_skcipher_decrypt(struct skcipher_request *req) 84 { 83 { 85 struct crypto_skcipher *tfm = crypto_s 84 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 86 struct simd_skcipher_ctx *ctx = crypto 85 struct simd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 87 struct skcipher_request *subreq; 86 struct skcipher_request *subreq; 88 struct crypto_skcipher *child; 87 struct crypto_skcipher *child; 89 88 90 subreq = skcipher_request_ctx(req); 89 subreq = skcipher_request_ctx(req); 91 *subreq = *req; 90 *subreq = *req; 92 91 93 if (!crypto_simd_usable() || !! 92 if (!may_use_simd() || 94 (in_atomic() && cryptd_skcipher_qu 93 (in_atomic() && cryptd_skcipher_queued(ctx->cryptd_tfm))) 95 child = &ctx->cryptd_tfm->base 94 child = &ctx->cryptd_tfm->base; 96 else 95 else 97 child = cryptd_skcipher_child( 96 child = cryptd_skcipher_child(ctx->cryptd_tfm); 98 97 99 skcipher_request_set_tfm(subreq, child 98 skcipher_request_set_tfm(subreq, child); 100 99 101 return crypto_skcipher_decrypt(subreq) 100 return crypto_skcipher_decrypt(subreq); 102 } 101 } 103 102 104 static void simd_skcipher_exit(struct crypto_s 103 static void simd_skcipher_exit(struct crypto_skcipher *tfm) 105 { 104 { 106 struct simd_skcipher_ctx *ctx = crypto 105 struct simd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 107 106 108 cryptd_free_skcipher(ctx->cryptd_tfm); 107 cryptd_free_skcipher(ctx->cryptd_tfm); 109 } 108 } 110 109 111 static int simd_skcipher_init(struct crypto_sk 110 static int simd_skcipher_init(struct crypto_skcipher *tfm) 112 { 111 { 113 struct simd_skcipher_ctx *ctx = crypto 112 struct simd_skcipher_ctx *ctx = crypto_skcipher_ctx(tfm); 114 struct cryptd_skcipher *cryptd_tfm; 113 struct cryptd_skcipher *cryptd_tfm; 115 struct simd_skcipher_alg *salg; 114 struct simd_skcipher_alg *salg; 116 struct skcipher_alg *alg; 115 struct skcipher_alg *alg; 117 unsigned reqsize; 116 unsigned reqsize; 118 117 119 alg = crypto_skcipher_alg(tfm); 118 alg = crypto_skcipher_alg(tfm); 120 salg = container_of(alg, struct simd_s 119 salg = container_of(alg, struct simd_skcipher_alg, alg); 121 120 122 cryptd_tfm = cryptd_alloc_skcipher(sal 121 cryptd_tfm = cryptd_alloc_skcipher(salg->ialg_name, 123 CRY 122 CRYPTO_ALG_INTERNAL, 124 CRY 123 CRYPTO_ALG_INTERNAL); 125 if (IS_ERR(cryptd_tfm)) 124 if (IS_ERR(cryptd_tfm)) 126 return PTR_ERR(cryptd_tfm); 125 return PTR_ERR(cryptd_tfm); 127 126 128 ctx->cryptd_tfm = cryptd_tfm; 127 ctx->cryptd_tfm = cryptd_tfm; 129 128 130 reqsize = crypto_skcipher_reqsize(cryp !! 129 reqsize = sizeof(struct skcipher_request); 131 reqsize = max(reqsize, crypto_skcipher !! 130 reqsize += crypto_skcipher_reqsize(&cryptd_tfm->base); 132 reqsize += sizeof(struct skcipher_requ << 133 131 134 crypto_skcipher_set_reqsize(tfm, reqsi 132 crypto_skcipher_set_reqsize(tfm, reqsize); 135 133 136 return 0; 134 return 0; 137 } 135 } 138 136 139 struct simd_skcipher_alg *simd_skcipher_create 137 struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname, 140 138 const char *drvname, 141 139 const char *basename) 142 { 140 { 143 struct simd_skcipher_alg *salg; 141 struct simd_skcipher_alg *salg; 144 struct crypto_skcipher *tfm; 142 struct crypto_skcipher *tfm; 145 struct skcipher_alg *ialg; 143 struct skcipher_alg *ialg; 146 struct skcipher_alg *alg; 144 struct skcipher_alg *alg; 147 int err; 145 int err; 148 146 149 tfm = crypto_alloc_skcipher(basename, 147 tfm = crypto_alloc_skcipher(basename, CRYPTO_ALG_INTERNAL, 150 CRYPTO_ALG 148 CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC); 151 if (IS_ERR(tfm)) 149 if (IS_ERR(tfm)) 152 return ERR_CAST(tfm); 150 return ERR_CAST(tfm); 153 151 154 ialg = crypto_skcipher_alg(tfm); 152 ialg = crypto_skcipher_alg(tfm); 155 153 156 salg = kzalloc(sizeof(*salg), GFP_KERN 154 salg = kzalloc(sizeof(*salg), GFP_KERNEL); 157 if (!salg) { 155 if (!salg) { 158 salg = ERR_PTR(-ENOMEM); 156 salg = ERR_PTR(-ENOMEM); 159 goto out_put_tfm; 157 goto out_put_tfm; 160 } 158 } 161 159 162 salg->ialg_name = basename; 160 salg->ialg_name = basename; 163 alg = &salg->alg; 161 alg = &salg->alg; 164 162 165 err = -ENAMETOOLONG; 163 err = -ENAMETOOLONG; 166 if (snprintf(alg->base.cra_name, CRYPT 164 if (snprintf(alg->base.cra_name, CRYPTO_MAX_ALG_NAME, "%s", algname) >= 167 CRYPTO_MAX_ALG_NAME) 165 CRYPTO_MAX_ALG_NAME) 168 goto out_free_salg; 166 goto out_free_salg; 169 167 170 if (snprintf(alg->base.cra_driver_name 168 if (snprintf(alg->base.cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 171 drvname) >= CRYPTO_MAX_AL 169 drvname) >= CRYPTO_MAX_ALG_NAME) 172 goto out_free_salg; 170 goto out_free_salg; 173 171 174 alg->base.cra_flags = CRYPTO_ALG_ASYNC !! 172 alg->base.cra_flags = CRYPTO_ALG_ASYNC; 175 (ialg->base.cra_flags & CRYPTO << 176 alg->base.cra_priority = ialg->base.cr 173 alg->base.cra_priority = ialg->base.cra_priority; 177 alg->base.cra_blocksize = ialg->base.c 174 alg->base.cra_blocksize = ialg->base.cra_blocksize; 178 alg->base.cra_alignmask = ialg->base.c 175 alg->base.cra_alignmask = ialg->base.cra_alignmask; 179 alg->base.cra_module = ialg->base.cra_ 176 alg->base.cra_module = ialg->base.cra_module; 180 alg->base.cra_ctxsize = sizeof(struct 177 alg->base.cra_ctxsize = sizeof(struct simd_skcipher_ctx); 181 178 182 alg->ivsize = ialg->ivsize; 179 alg->ivsize = ialg->ivsize; 183 alg->chunksize = ialg->chunksize; 180 alg->chunksize = ialg->chunksize; 184 alg->min_keysize = ialg->min_keysize; 181 alg->min_keysize = ialg->min_keysize; 185 alg->max_keysize = ialg->max_keysize; 182 alg->max_keysize = ialg->max_keysize; 186 183 187 alg->init = simd_skcipher_init; 184 alg->init = simd_skcipher_init; 188 alg->exit = simd_skcipher_exit; 185 alg->exit = simd_skcipher_exit; 189 186 190 alg->setkey = simd_skcipher_setkey; 187 alg->setkey = simd_skcipher_setkey; 191 alg->encrypt = simd_skcipher_encrypt; 188 alg->encrypt = simd_skcipher_encrypt; 192 alg->decrypt = simd_skcipher_decrypt; 189 alg->decrypt = simd_skcipher_decrypt; 193 190 194 err = crypto_register_skcipher(alg); 191 err = crypto_register_skcipher(alg); 195 if (err) 192 if (err) 196 goto out_free_salg; 193 goto out_free_salg; 197 194 198 out_put_tfm: 195 out_put_tfm: 199 crypto_free_skcipher(tfm); 196 crypto_free_skcipher(tfm); 200 return salg; 197 return salg; 201 198 202 out_free_salg: 199 out_free_salg: 203 kfree(salg); 200 kfree(salg); 204 salg = ERR_PTR(err); 201 salg = ERR_PTR(err); 205 goto out_put_tfm; 202 goto out_put_tfm; 206 } 203 } 207 EXPORT_SYMBOL_GPL(simd_skcipher_create_compat) 204 EXPORT_SYMBOL_GPL(simd_skcipher_create_compat); 208 205 209 struct simd_skcipher_alg *simd_skcipher_create 206 struct simd_skcipher_alg *simd_skcipher_create(const char *algname, 210 207 const char *basename) 211 { 208 { 212 char drvname[CRYPTO_MAX_ALG_NAME]; 209 char drvname[CRYPTO_MAX_ALG_NAME]; 213 210 214 if (snprintf(drvname, CRYPTO_MAX_ALG_N 211 if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >= 215 CRYPTO_MAX_ALG_NAME) 212 CRYPTO_MAX_ALG_NAME) 216 return ERR_PTR(-ENAMETOOLONG); 213 return ERR_PTR(-ENAMETOOLONG); 217 214 218 return simd_skcipher_create_compat(alg 215 return simd_skcipher_create_compat(algname, drvname, basename); 219 } 216 } 220 EXPORT_SYMBOL_GPL(simd_skcipher_create); 217 EXPORT_SYMBOL_GPL(simd_skcipher_create); 221 218 222 void simd_skcipher_free(struct simd_skcipher_a 219 void simd_skcipher_free(struct simd_skcipher_alg *salg) 223 { 220 { 224 crypto_unregister_skcipher(&salg->alg) 221 crypto_unregister_skcipher(&salg->alg); 225 kfree(salg); 222 kfree(salg); 226 } 223 } 227 EXPORT_SYMBOL_GPL(simd_skcipher_free); 224 EXPORT_SYMBOL_GPL(simd_skcipher_free); 228 225 229 int simd_register_skciphers_compat(struct skci << 230 struct simd << 231 { << 232 int err; << 233 int i; << 234 const char *algname; << 235 const char *drvname; << 236 const char *basename; << 237 struct simd_skcipher_alg *simd; << 238 << 239 err = crypto_register_skciphers(algs, << 240 if (err) << 241 return err; << 242 << 243 for (i = 0; i < count; i++) { << 244 WARN_ON(strncmp(algs[i].base.c << 245 WARN_ON(strncmp(algs[i].base.c << 246 algname = algs[i].base.cra_nam << 247 drvname = algs[i].base.cra_dri << 248 basename = algs[i].base.cra_dr << 249 simd = simd_skcipher_create_co << 250 err = PTR_ERR(simd); << 251 if (IS_ERR(simd)) << 252 goto err_unregister; << 253 simd_algs[i] = simd; << 254 } << 255 return 0; << 256 << 257 err_unregister: << 258 simd_unregister_skciphers(algs, count, << 259 return err; << 260 } << 261 EXPORT_SYMBOL_GPL(simd_register_skciphers_comp << 262 << 263 void simd_unregister_skciphers(struct skcipher << 264 struct simd_skc << 265 { << 266 int i; << 267 << 268 crypto_unregister_skciphers(algs, coun << 269 << 270 for (i = 0; i < count; i++) { << 271 if (simd_algs[i]) { << 272 simd_skcipher_free(sim << 273 simd_algs[i] = NULL; << 274 } << 275 } << 276 } << 277 EXPORT_SYMBOL_GPL(simd_unregister_skciphers); << 278 << 279 /* AEAD support */ << 280 << 281 struct simd_aead_alg { << 282 const char *ialg_name; << 283 struct aead_alg alg; << 284 }; << 285 << 286 struct simd_aead_ctx { << 287 struct cryptd_aead *cryptd_tfm; << 288 }; << 289 << 290 static int simd_aead_setkey(struct crypto_aead << 291 unsigned int k << 292 { << 293 struct simd_aead_ctx *ctx = crypto_aea << 294 struct crypto_aead *child = &ctx->cryp << 295 << 296 crypto_aead_clear_flags(child, CRYPTO_ << 297 crypto_aead_set_flags(child, crypto_ae << 298 CRYPTO_TF << 299 return crypto_aead_setkey(child, key, << 300 } << 301 << 302 static int simd_aead_setauthsize(struct crypto << 303 { << 304 struct simd_aead_ctx *ctx = crypto_aea << 305 struct crypto_aead *child = &ctx->cryp << 306 << 307 return crypto_aead_setauthsize(child, << 308 } << 309 << 310 static int simd_aead_encrypt(struct aead_reque << 311 { << 312 struct crypto_aead *tfm = crypto_aead_ << 313 struct simd_aead_ctx *ctx = crypto_aea << 314 struct aead_request *subreq; << 315 struct crypto_aead *child; << 316 << 317 subreq = aead_request_ctx(req); << 318 *subreq = *req; << 319 << 320 if (!crypto_simd_usable() || << 321 (in_atomic() && cryptd_aead_queued << 322 child = &ctx->cryptd_tfm->base << 323 else << 324 child = cryptd_aead_child(ctx- << 325 << 326 aead_request_set_tfm(subreq, child); << 327 << 328 return crypto_aead_encrypt(subreq); << 329 } << 330 << 331 static int simd_aead_decrypt(struct aead_reque << 332 { << 333 struct crypto_aead *tfm = crypto_aead_ << 334 struct simd_aead_ctx *ctx = crypto_aea << 335 struct aead_request *subreq; << 336 struct crypto_aead *child; << 337 << 338 subreq = aead_request_ctx(req); << 339 *subreq = *req; << 340 << 341 if (!crypto_simd_usable() || << 342 (in_atomic() && cryptd_aead_queued << 343 child = &ctx->cryptd_tfm->base << 344 else << 345 child = cryptd_aead_child(ctx- << 346 << 347 aead_request_set_tfm(subreq, child); << 348 << 349 return crypto_aead_decrypt(subreq); << 350 } << 351 << 352 static void simd_aead_exit(struct crypto_aead << 353 { << 354 struct simd_aead_ctx *ctx = crypto_aea << 355 << 356 cryptd_free_aead(ctx->cryptd_tfm); << 357 } << 358 << 359 static int simd_aead_init(struct crypto_aead * << 360 { << 361 struct simd_aead_ctx *ctx = crypto_aea << 362 struct cryptd_aead *cryptd_tfm; << 363 struct simd_aead_alg *salg; << 364 struct aead_alg *alg; << 365 unsigned reqsize; << 366 << 367 alg = crypto_aead_alg(tfm); << 368 salg = container_of(alg, struct simd_a << 369 << 370 cryptd_tfm = cryptd_alloc_aead(salg->i << 371 CRYPTO_ << 372 if (IS_ERR(cryptd_tfm)) << 373 return PTR_ERR(cryptd_tfm); << 374 << 375 ctx->cryptd_tfm = cryptd_tfm; << 376 << 377 reqsize = crypto_aead_reqsize(cryptd_a << 378 reqsize = max(reqsize, crypto_aead_req << 379 reqsize += sizeof(struct aead_request) << 380 << 381 crypto_aead_set_reqsize(tfm, reqsize); << 382 << 383 return 0; << 384 } << 385 << 386 struct simd_aead_alg *simd_aead_create_compat( << 387 << 388 << 389 { << 390 struct simd_aead_alg *salg; << 391 struct crypto_aead *tfm; << 392 struct aead_alg *ialg; << 393 struct aead_alg *alg; << 394 int err; << 395 << 396 tfm = crypto_alloc_aead(basename, CRYP << 397 CRYPTO_ALG_INT << 398 if (IS_ERR(tfm)) << 399 return ERR_CAST(tfm); << 400 << 401 ialg = crypto_aead_alg(tfm); << 402 << 403 salg = kzalloc(sizeof(*salg), GFP_KERN << 404 if (!salg) { << 405 salg = ERR_PTR(-ENOMEM); << 406 goto out_put_tfm; << 407 } << 408 << 409 salg->ialg_name = basename; << 410 alg = &salg->alg; << 411 << 412 err = -ENAMETOOLONG; << 413 if (snprintf(alg->base.cra_name, CRYPT << 414 CRYPTO_MAX_ALG_NAME) << 415 goto out_free_salg; << 416 << 417 if (snprintf(alg->base.cra_driver_name << 418 drvname) >= CRYPTO_MAX_AL << 419 goto out_free_salg; << 420 << 421 alg->base.cra_flags = CRYPTO_ALG_ASYNC << 422 (ialg->base.cra_flags & CRYPTO << 423 alg->base.cra_priority = ialg->base.cr << 424 alg->base.cra_blocksize = ialg->base.c << 425 alg->base.cra_alignmask = ialg->base.c << 426 alg->base.cra_module = ialg->base.cra_ << 427 alg->base.cra_ctxsize = sizeof(struct << 428 << 429 alg->ivsize = ialg->ivsize; << 430 alg->maxauthsize = ialg->maxauthsize; << 431 alg->chunksize = ialg->chunksize; << 432 << 433 alg->init = simd_aead_init; << 434 alg->exit = simd_aead_exit; << 435 << 436 alg->setkey = simd_aead_setkey; << 437 alg->setauthsize = simd_aead_setauthsi << 438 alg->encrypt = simd_aead_encrypt; << 439 alg->decrypt = simd_aead_decrypt; << 440 << 441 err = crypto_register_aead(alg); << 442 if (err) << 443 goto out_free_salg; << 444 << 445 out_put_tfm: << 446 crypto_free_aead(tfm); << 447 return salg; << 448 << 449 out_free_salg: << 450 kfree(salg); << 451 salg = ERR_PTR(err); << 452 goto out_put_tfm; << 453 } << 454 EXPORT_SYMBOL_GPL(simd_aead_create_compat); << 455 << 456 struct simd_aead_alg *simd_aead_create(const c << 457 const c << 458 { << 459 char drvname[CRYPTO_MAX_ALG_NAME]; << 460 << 461 if (snprintf(drvname, CRYPTO_MAX_ALG_N << 462 CRYPTO_MAX_ALG_NAME) << 463 return ERR_PTR(-ENAMETOOLONG); << 464 << 465 return simd_aead_create_compat(algname << 466 } << 467 EXPORT_SYMBOL_GPL(simd_aead_create); << 468 << 469 void simd_aead_free(struct simd_aead_alg *salg << 470 { << 471 crypto_unregister_aead(&salg->alg); << 472 kfree(salg); << 473 } << 474 EXPORT_SYMBOL_GPL(simd_aead_free); << 475 << 476 int simd_register_aeads_compat(struct aead_alg << 477 struct simd_aea << 478 { << 479 int err; << 480 int i; << 481 const char *algname; << 482 const char *drvname; << 483 const char *basename; << 484 struct simd_aead_alg *simd; << 485 << 486 err = crypto_register_aeads(algs, coun << 487 if (err) << 488 return err; << 489 << 490 for (i = 0; i < count; i++) { << 491 WARN_ON(strncmp(algs[i].base.c << 492 WARN_ON(strncmp(algs[i].base.c << 493 algname = algs[i].base.cra_nam << 494 drvname = algs[i].base.cra_dri << 495 basename = algs[i].base.cra_dr << 496 simd = simd_aead_create_compat << 497 err = PTR_ERR(simd); << 498 if (IS_ERR(simd)) << 499 goto err_unregister; << 500 simd_algs[i] = simd; << 501 } << 502 return 0; << 503 << 504 err_unregister: << 505 simd_unregister_aeads(algs, count, sim << 506 return err; << 507 } << 508 EXPORT_SYMBOL_GPL(simd_register_aeads_compat); << 509 << 510 void simd_unregister_aeads(struct aead_alg *al << 511 struct simd_aead_al << 512 { << 513 int i; << 514 << 515 crypto_unregister_aeads(algs, count); << 516 << 517 for (i = 0; i < count; i++) { << 518 if (simd_algs[i]) { << 519 simd_aead_free(simd_al << 520 simd_algs[i] = NULL; << 521 } << 522 } << 523 } << 524 EXPORT_SYMBOL_GPL(simd_unregister_aeads); << 525 << 526 MODULE_DESCRIPTION("Shared crypto SIMD helpers << 527 MODULE_LICENSE("GPL"); 226 MODULE_LICENSE("GPL"); 528 227
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.