mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 14:24:11 +08:00
crypto: shash - eliminate indirect call for default import and export
Most shash algorithms don't have custom ->import and ->export functions, resulting in the memcpy() based default being used. Yet, crypto_shash_import() and crypto_shash_export() still make an indirect call, which is expensive. Therefore, change how the default import and export are called to make it so that crypto_shash_import() and crypto_shash_export() don't do an indirect call in this case. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
a411f6debe
commit
08debaa5cb
@ -277,17 +277,34 @@ int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(crypto_shash_tfm_digest);
|
EXPORT_SYMBOL_GPL(crypto_shash_tfm_digest);
|
||||||
|
|
||||||
static int shash_default_export(struct shash_desc *desc, void *out)
|
int crypto_shash_export(struct shash_desc *desc, void *out)
|
||||||
{
|
{
|
||||||
memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
|
struct crypto_shash *tfm = desc->tfm;
|
||||||
return 0;
|
struct shash_alg *shash = crypto_shash_alg(tfm);
|
||||||
}
|
|
||||||
|
|
||||||
static int shash_default_import(struct shash_desc *desc, const void *in)
|
if (shash->export)
|
||||||
{
|
return shash->export(desc, out);
|
||||||
memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm));
|
|
||||||
|
memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(tfm));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_shash_export);
|
||||||
|
|
||||||
|
int crypto_shash_import(struct shash_desc *desc, const void *in)
|
||||||
|
{
|
||||||
|
struct crypto_shash *tfm = desc->tfm;
|
||||||
|
struct shash_alg *shash = crypto_shash_alg(tfm);
|
||||||
|
|
||||||
|
if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
|
||||||
|
return -ENOKEY;
|
||||||
|
|
||||||
|
if (shash->import)
|
||||||
|
return shash->import(desc, in);
|
||||||
|
|
||||||
|
memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(tfm));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(crypto_shash_import);
|
||||||
|
|
||||||
static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
|
static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
|
||||||
unsigned int keylen)
|
unsigned int keylen)
|
||||||
@ -666,15 +683,23 @@ static int shash_prepare_alg(struct shash_alg *alg)
|
|||||||
base->cra_type = &crypto_shash_type;
|
base->cra_type = &crypto_shash_type;
|
||||||
base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
|
base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle missing optional functions. For each one we can either
|
||||||
|
* install a default here, or we can leave the pointer as NULL and check
|
||||||
|
* the pointer for NULL in crypto_shash_*(), avoiding an indirect call
|
||||||
|
* when the default behavior is desired. For ->finup and ->digest we
|
||||||
|
* install defaults, since for optimal performance algorithms should
|
||||||
|
* implement these anyway. On the other hand, for ->import and
|
||||||
|
* ->export the common case and best performance comes from the simple
|
||||||
|
* memcpy of the shash_desc_ctx, so when those pointers are NULL we
|
||||||
|
* leave them NULL and provide the memcpy with no indirect call.
|
||||||
|
*/
|
||||||
if (!alg->finup)
|
if (!alg->finup)
|
||||||
alg->finup = shash_default_finup;
|
alg->finup = shash_default_finup;
|
||||||
if (!alg->digest)
|
if (!alg->digest)
|
||||||
alg->digest = shash_default_digest;
|
alg->digest = shash_default_digest;
|
||||||
if (!alg->export) {
|
if (!alg->export)
|
||||||
alg->export = shash_default_export;
|
|
||||||
alg->import = shash_default_import;
|
|
||||||
alg->halg.statesize = alg->descsize;
|
alg->halg.statesize = alg->descsize;
|
||||||
}
|
|
||||||
if (!alg->setkey)
|
if (!alg->setkey)
|
||||||
alg->setkey = shash_no_setkey;
|
alg->setkey = shash_no_setkey;
|
||||||
|
|
||||||
|
@ -952,10 +952,7 @@ int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
|
|||||||
* Context: Any context.
|
* Context: Any context.
|
||||||
* Return: 0 if the export creation was successful; < 0 if an error occurred
|
* Return: 0 if the export creation was successful; < 0 if an error occurred
|
||||||
*/
|
*/
|
||||||
static inline int crypto_shash_export(struct shash_desc *desc, void *out)
|
int crypto_shash_export(struct shash_desc *desc, void *out);
|
||||||
{
|
|
||||||
return crypto_shash_alg(desc->tfm)->export(desc, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_shash_import() - import operational state
|
* crypto_shash_import() - import operational state
|
||||||
@ -969,15 +966,7 @@ static inline int crypto_shash_export(struct shash_desc *desc, void *out)
|
|||||||
* Context: Any context.
|
* Context: Any context.
|
||||||
* Return: 0 if the import was successful; < 0 if an error occurred
|
* Return: 0 if the import was successful; < 0 if an error occurred
|
||||||
*/
|
*/
|
||||||
static inline int crypto_shash_import(struct shash_desc *desc, const void *in)
|
int crypto_shash_import(struct shash_desc *desc, const void *in);
|
||||||
{
|
|
||||||
struct crypto_shash *tfm = desc->tfm;
|
|
||||||
|
|
||||||
if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
|
|
||||||
return -ENOKEY;
|
|
||||||
|
|
||||||
return crypto_shash_alg(tfm)->import(desc, in);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* crypto_shash_init() - (re)initialize message digest
|
* crypto_shash_init() - (re)initialize message digest
|
||||||
|
Loading…
Reference in New Issue
Block a user