Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: api - Add support for duplicating algorithms before registration

If the bit CRYPTO_ALG_DUP_FIRST is set, an algorithm will be
duplicated by kmemdup before registration. This is inteded for
hardware-based algorithms that may be unplugged at will.

Do not use this if the algorithm data structure is embedded in a
bigger data structure. Perform the duplication in the driver
instead.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

+61 -14
+1
crypto/acompress.c
··· 150 150 .maskset = CRYPTO_ALG_TYPE_ACOMPRESS_MASK, 151 151 .type = CRYPTO_ALG_TYPE_ACOMPRESS, 152 152 .tfmsize = offsetof(struct crypto_acomp, base), 153 + .algsize = offsetof(struct acomp_alg, base), 153 154 }; 154 155 155 156 struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type,
+1
crypto/aead.c
··· 186 186 .maskset = CRYPTO_ALG_TYPE_MASK, 187 187 .type = CRYPTO_ALG_TYPE_AEAD, 188 188 .tfmsize = offsetof(struct crypto_aead, base), 189 + .algsize = offsetof(struct aead_alg, base), 189 190 }; 190 191 191 192 int crypto_grab_aead(struct crypto_aead_spawn *spawn,
+1
crypto/ahash.c
··· 792 792 .maskset = CRYPTO_ALG_TYPE_AHASH_MASK, 793 793 .type = CRYPTO_ALG_TYPE_AHASH, 794 794 .tfmsize = offsetof(struct crypto_ahash, base), 795 + .algsize = offsetof(struct ahash_alg, halg.base), 795 796 }; 796 797 797 798 int crypto_grab_ahash(struct crypto_ahash_spawn *spawn,
+1
crypto/akcipher.c
··· 97 97 .maskset = CRYPTO_ALG_TYPE_AHASH_MASK, 98 98 .type = CRYPTO_ALG_TYPE_AKCIPHER, 99 99 .tfmsize = offsetof(struct crypto_akcipher, base), 100 + .algsize = offsetof(struct akcipher_alg, base), 100 101 }; 101 102 102 103 int crypto_grab_akcipher(struct crypto_akcipher_spawn *spawn,
+28 -13
crypto/algapi.c
··· 66 66 67 67 static void crypto_free_instance(struct crypto_instance *inst) 68 68 { 69 - struct crypto_alg *alg = &inst->alg; 70 - const struct crypto_type *type; 71 - 72 - type = alg->cra_type; 73 - if (type->destroy) 74 - type->destroy(alg); 75 - type->free(inst); 69 + inst->alg.cra_type->free(inst); 76 70 } 77 71 78 72 static void crypto_destroy_instance_workfn(struct work_struct *w) ··· 418 424 } 419 425 EXPORT_SYMBOL_GPL(crypto_remove_final); 420 426 427 + static void crypto_free_alg(struct crypto_alg *alg) 428 + { 429 + unsigned int algsize = alg->cra_type->algsize; 430 + u8 *p = (u8 *)alg - algsize; 431 + 432 + crypto_destroy_alg(alg); 433 + kfree(p); 434 + } 435 + 421 436 int crypto_register_alg(struct crypto_alg *alg) 422 437 { 423 438 struct crypto_larval *larval; ··· 439 436 if (err) 440 437 return err; 441 438 439 + if (alg->cra_flags & CRYPTO_ALG_DUP_FIRST && 440 + !WARN_ON_ONCE(alg->cra_destroy)) { 441 + unsigned int algsize = alg->cra_type->algsize; 442 + u8 *p = (u8 *)alg - algsize; 443 + 444 + p = kmemdup(p, algsize + sizeof(*alg), GFP_KERNEL); 445 + if (!p) 446 + return -ENOMEM; 447 + 448 + alg = (void *)(p + algsize); 449 + alg->cra_destroy = crypto_free_alg; 450 + } 451 + 442 452 down_write(&crypto_alg_sem); 443 453 larval = __crypto_register_alg(alg, &algs_to_put); 444 454 if (!IS_ERR_OR_NULL(larval)) { ··· 460 444 } 461 445 up_write(&crypto_alg_sem); 462 446 463 - if (IS_ERR(larval)) 447 + if (IS_ERR(larval)) { 448 + crypto_alg_put(alg); 464 449 return PTR_ERR(larval); 450 + } 465 451 466 452 if (test_started) 467 453 crypto_schedule_test(larval); ··· 499 481 if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name)) 500 482 return; 501 483 502 - if (alg->cra_destroy) 503 - crypto_alg_put(alg); 504 - else if (!WARN_ON(refcount_read(&alg->cra_refcnt) != 1) && 505 - alg->cra_type && alg->cra_type->destroy) 506 - alg->cra_type->destroy(alg); 484 + WARN_ON(!alg->cra_destroy && refcount_read(&alg->cra_refcnt) != 1); 507 485 486 + list_add(&alg->cra_list, &list); 508 487 crypto_remove_final(&list); 509 488 } 510 489 EXPORT_SYMBOL_GPL(crypto_unregister_alg);
+9
crypto/api.c
··· 703 703 } 704 704 EXPORT_SYMBOL_GPL(crypto_req_done); 705 705 706 + void crypto_destroy_alg(struct crypto_alg *alg) 707 + { 708 + if (alg->cra_type && alg->cra_type->destroy) 709 + alg->cra_type->destroy(alg); 710 + if (alg->cra_destroy) 711 + alg->cra_destroy(alg); 712 + } 713 + EXPORT_SYMBOL_GPL(crypto_destroy_alg); 714 + 706 715 MODULE_DESCRIPTION("Cryptographic core API"); 707 716 MODULE_LICENSE("GPL");
+4 -1
crypto/internal.h
··· 46 46 unsigned int maskclear; 47 47 unsigned int maskset; 48 48 unsigned int tfmsize; 49 + unsigned int algsize; 49 50 }; 50 51 51 52 enum { ··· 163 162 return alg; 164 163 } 165 164 165 + void crypto_destroy_alg(struct crypto_alg *alg); 166 + 166 167 static inline void crypto_alg_put(struct crypto_alg *alg) 167 168 { 168 169 if (refcount_dec_and_test(&alg->cra_refcnt)) 169 - alg->cra_destroy(alg); 170 + crypto_destroy_alg(alg); 170 171 } 171 172 172 173 static inline int crypto_tmpl_get(struct crypto_template *tmpl)
+1
crypto/kpp.c
··· 80 80 .maskset = CRYPTO_ALG_TYPE_MASK, 81 81 .type = CRYPTO_ALG_TYPE_KPP, 82 82 .tfmsize = offsetof(struct crypto_kpp, base), 83 + .algsize = offsetof(struct kpp_alg, base), 83 84 }; 84 85 85 86 struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask)
+1
crypto/lskcipher.c
··· 294 294 .maskset = CRYPTO_ALG_TYPE_MASK, 295 295 .type = CRYPTO_ALG_TYPE_LSKCIPHER, 296 296 .tfmsize = offsetof(struct crypto_lskcipher, base), 297 + .algsize = offsetof(struct lskcipher_alg, co.base), 297 298 }; 298 299 299 300 static void crypto_lskcipher_exit_tfm_sg(struct crypto_tfm *tfm)
+1
crypto/rng.c
··· 98 98 .maskset = CRYPTO_ALG_TYPE_MASK, 99 99 .type = CRYPTO_ALG_TYPE_RNG, 100 100 .tfmsize = offsetof(struct crypto_rng, base), 101 + .algsize = offsetof(struct rng_alg, base), 101 102 }; 102 103 103 104 struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask)
+1
crypto/scompress.c
··· 347 347 .maskset = CRYPTO_ALG_TYPE_MASK, 348 348 .type = CRYPTO_ALG_TYPE_SCOMPRESS, 349 349 .tfmsize = offsetof(struct crypto_scomp, base), 350 + .algsize = offsetof(struct scomp_alg, base), 350 351 }; 351 352 352 353 static void scomp_prepare_alg(struct scomp_alg *alg)
+1
crypto/shash.c
··· 227 227 .maskset = CRYPTO_ALG_TYPE_MASK, 228 228 .type = CRYPTO_ALG_TYPE_SHASH, 229 229 .tfmsize = offsetof(struct crypto_shash, base), 230 + .algsize = offsetof(struct shash_alg, base), 230 231 }; 231 232 232 233 int crypto_grab_shash(struct crypto_shash_spawn *spawn,
+1
crypto/sig.c
··· 74 74 .maskset = CRYPTO_ALG_TYPE_MASK, 75 75 .type = CRYPTO_ALG_TYPE_SIG, 76 76 .tfmsize = offsetof(struct crypto_sig, base), 77 + .algsize = offsetof(struct sig_alg, base), 77 78 }; 78 79 79 80 struct crypto_sig *crypto_alloc_sig(const char *alg_name, u32 type, u32 mask)
+1
crypto/skcipher.c
··· 620 620 .maskset = CRYPTO_ALG_TYPE_SKCIPHER_MASK, 621 621 .type = CRYPTO_ALG_TYPE_SKCIPHER, 622 622 .tfmsize = offsetof(struct crypto_skcipher, base), 623 + .algsize = offsetof(struct skcipher_alg, base), 623 624 }; 624 625 625 626 int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn,
+9
include/linux/crypto.h
··· 50 50 #define CRYPTO_ALG_NEED_FALLBACK 0x00000100 51 51 52 52 /* 53 + * Set if the algorithm data structure should be duplicated into 54 + * kmalloc memory before registration. This is useful for hardware 55 + * that can be disconnected at will. Do not use this if the data 56 + * structure is embedded into a bigger one. Duplicate the overall 57 + * data structure in the driver in that case. 58 + */ 59 + #define CRYPTO_ALG_DUP_FIRST 0x00000200 60 + 61 + /* 53 62 * Set if the algorithm has passed automated run-time testing. Note that 54 63 * if there is no run-time testing for a given algorithm it is considered 55 64 * to have passed.