}
EXPORT_SYMBOL_GPL(crypto_hash_alg_has_setkey);
-struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *hash)
-{
- struct hash_alg_common *halg = crypto_hash_alg_common(hash);
- struct crypto_tfm *tfm = crypto_ahash_tfm(hash);
- struct crypto_ahash *fb = NULL;
- struct crypto_ahash *nhash;
- struct ahash_alg *alg;
- int err;
-
- if (!crypto_hash_alg_has_setkey(halg)) {
- tfm = crypto_tfm_get(tfm);
- if (IS_ERR(tfm))
- return ERR_CAST(tfm);
-
- return hash;
- }
-
- nhash = crypto_clone_tfm(&crypto_ahash_type, tfm);
-
- if (IS_ERR(nhash))
- return nhash;
-
- nhash->reqsize = hash->reqsize;
- nhash->statesize = hash->statesize;
-
- if (likely(hash->using_shash)) {
- struct crypto_shash **nctx = crypto_ahash_ctx(nhash);
- struct crypto_shash *shash;
-
- shash = crypto_clone_shash(ahash_to_shash(hash));
- if (IS_ERR(shash)) {
- err = PTR_ERR(shash);
- goto out_free_nhash;
- }
- crypto_ahash_tfm(nhash)->exit = crypto_exit_ahash_using_shash;
- nhash->using_shash = true;
- *nctx = shash;
- return nhash;
- }
-
- if (crypto_ahash_need_fallback(hash)) {
- fb = crypto_clone_ahash(crypto_ahash_fb(hash));
- err = PTR_ERR(fb);
- if (IS_ERR(fb))
- goto out_free_nhash;
-
- crypto_ahash_tfm(nhash)->fb = crypto_ahash_tfm(fb);
- }
-
- err = -ENOSYS;
- alg = crypto_ahash_alg(hash);
- if (!alg->clone_tfm)
- goto out_free_fb;
-
- err = alg->clone_tfm(nhash, hash);
- if (err)
- goto out_free_fb;
-
- crypto_ahash_tfm(nhash)->exit = crypto_ahash_exit_tfm;
-
- return nhash;
-
-out_free_fb:
- crypto_free_ahash(fb);
-out_free_nhash:
- crypto_free_ahash(nhash);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL_GPL(crypto_clone_ahash);
-
static int ahash_default_export_core(struct ahash_request *req, void *out)
{
return -ENOSYS;
return 0;
}
-static int cmac_clone_tfm(struct crypto_shash *tfm, struct crypto_shash *otfm)
-{
- struct cmac_tfm_ctx *octx = crypto_shash_ctx(otfm);
- struct cmac_tfm_ctx *ctx = crypto_shash_ctx(tfm);
- struct crypto_cipher *cipher;
-
- cipher = crypto_clone_cipher(octx->child);
- if (IS_ERR(cipher))
- return PTR_ERR(cipher);
-
- ctx->child = cipher;
-
- return 0;
-}
-
static void cmac_exit_tfm(struct crypto_shash *tfm)
{
struct cmac_tfm_ctx *ctx = crypto_shash_ctx(tfm);
inst->alg.finup = crypto_cmac_digest_finup;
inst->alg.setkey = crypto_cmac_digest_setkey;
inst->alg.init_tfm = cmac_init_tfm;
- inst->alg.clone_tfm = cmac_clone_tfm;
inst->alg.exit_tfm = cmac_exit_tfm;
inst->free = shash_free_singlespawn_instance;
return 0;
}
-static int cryptd_hash_clone_tfm(struct crypto_ahash *ntfm,
- struct crypto_ahash *tfm)
-{
- struct cryptd_hash_ctx *nctx = crypto_ahash_ctx(ntfm);
- struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm);
- struct crypto_shash *hash;
-
- hash = crypto_clone_shash(ctx->child);
- if (IS_ERR(hash))
- return PTR_ERR(hash);
-
- nctx->child = hash;
- return 0;
-}
-
static void cryptd_hash_exit_tfm(struct crypto_ahash *tfm)
{
struct cryptd_hash_ctx *ctx = crypto_ahash_ctx(tfm);
inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx);
inst->alg.init_tfm = cryptd_hash_init_tfm;
- inst->alg.clone_tfm = cryptd_hash_clone_tfm;
inst->alg.exit_tfm = cryptd_hash_exit_tfm;
inst->alg.init = cryptd_hash_init_enqueue;
return 0;
}
-static int hmac_clone_tfm(struct crypto_shash *dst, struct crypto_shash *src)
-{
- struct hmac_ctx *sctx = crypto_shash_ctx(src);
- struct hmac_ctx *dctx = crypto_shash_ctx(dst);
- struct crypto_shash *hash;
-
- hash = crypto_clone_shash(sctx->hash);
- if (IS_ERR(hash))
- return PTR_ERR(hash);
-
- dctx->hash = hash;
- return 0;
-}
-
static void hmac_exit_tfm(struct crypto_shash *parent)
{
struct hmac_ctx *tctx = crypto_shash_ctx(parent);
inst->alg.import_core = hmac_import_core;
inst->alg.setkey = hmac_setkey;
inst->alg.init_tfm = hmac_init_tfm;
- inst->alg.clone_tfm = hmac_clone_tfm;
inst->alg.exit_tfm = hmac_exit_tfm;
inst->free = shash_free_singlespawn_instance;
return 0;
}
-static int hmac_clone_ahash_tfm(struct crypto_ahash *dst,
- struct crypto_ahash *src)
-{
- struct ahash_hmac_ctx *sctx = crypto_ahash_ctx(src);
- struct ahash_hmac_ctx *dctx = crypto_ahash_ctx(dst);
- struct crypto_ahash *hash;
-
- hash = crypto_clone_ahash(sctx->hash);
- if (IS_ERR(hash))
- return PTR_ERR(hash);
-
- dctx->hash = hash;
- return 0;
-}
-
static void hmac_exit_ahash_tfm(struct crypto_ahash *parent)
{
struct ahash_hmac_ctx *tctx = crypto_ahash_ctx(parent);
inst->alg.import_core = hmac_import_core_ahash;
inst->alg.setkey = hmac_setkey_ahash;
inst->alg.init_tfm = hmac_init_ahash_tfm;
- inst->alg.clone_tfm = hmac_clone_ahash_tfm;
inst->alg.exit_tfm = hmac_exit_ahash_tfm;
inst->free = ahash_free_singlespawn_instance;
}
EXPORT_SYMBOL_GPL(crypto_has_shash);
-struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
-{
- struct crypto_tfm *tfm = crypto_shash_tfm(hash);
- struct shash_alg *alg = crypto_shash_alg(hash);
- struct crypto_shash *nhash;
- int err;
-
- if (!crypto_shash_alg_has_setkey(alg)) {
- tfm = crypto_tfm_get(tfm);
- if (IS_ERR(tfm))
- return ERR_CAST(tfm);
-
- return hash;
- }
-
- if (!alg->clone_tfm && (alg->init_tfm || alg->base.cra_init))
- return ERR_PTR(-ENOSYS);
-
- nhash = crypto_clone_tfm(&crypto_shash_type, tfm);
- if (IS_ERR(nhash))
- return nhash;
-
- if (alg->clone_tfm) {
- err = alg->clone_tfm(nhash, hash);
- if (err) {
- crypto_free_shash(nhash);
- return ERR_PTR(err);
- }
- }
-
- if (alg->exit_tfm)
- crypto_shash_tfm(nhash)->exit = crypto_shash_exit_tfm;
-
- return nhash;
-}
-EXPORT_SYMBOL_GPL(crypto_clone_shash);
-
int hash_prepare_alg(struct hash_alg_common *alg)
{
struct crypto_alg *base = &alg->base;
* @exit_tfm: Deinitialize the cryptographic transformation object.
* This is a counterpart to @init_tfm, used to remove
* various changes set in @init_tfm.
- * @clone_tfm: Copy transform into new object, may allocate memory.
* @halg: see struct hash_alg_common
*/
struct ahash_alg {
unsigned int keylen);
int (*init_tfm)(struct crypto_ahash *tfm);
void (*exit_tfm)(struct crypto_ahash *tfm);
- int (*clone_tfm)(struct crypto_ahash *dst, struct crypto_ahash *src);
struct hash_alg_common halg;
};
* @exit_tfm: Deinitialize the cryptographic transformation object.
* This is a counterpart to @init_tfm, used to remove
* various changes set in @init_tfm.
- * @clone_tfm: Copy transform into new object, may allocate memory.
* @descsize: Size of the operational state for the message digest. This state
* size is the memory size that needs to be allocated for
* shash_desc.__ctx
unsigned int keylen);
int (*init_tfm)(struct crypto_shash *tfm);
void (*exit_tfm)(struct crypto_shash *tfm);
- int (*clone_tfm)(struct crypto_shash *dst, struct crypto_shash *src);
unsigned int descsize;
struct crypto_ahash *crypto_alloc_ahash(const char *alg_name, u32 type,
u32 mask);
-struct crypto_ahash *crypto_clone_ahash(struct crypto_ahash *tfm);
-
static inline struct crypto_tfm *crypto_ahash_tfm(struct crypto_ahash *tfm)
{
return &tfm->base;
struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
u32 mask);
-struct crypto_shash *crypto_clone_shash(struct crypto_shash *tfm);
-
int crypto_has_shash(const char *alg_name, u32 type, u32 mask);
static inline struct crypto_tfm *crypto_shash_tfm(struct crypto_shash *tfm)