mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
crypto: skcipher - Make use of internal state
This patch adds code to the skcipher/lskcipher API to make use of the internal state if present. In particular, the skcipher lskcipher wrapper will allocate a buffer for the IV/state and feed that to the underlying lskcipher algorithm. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
@@ -698,6 +698,64 @@ int crypto_skcipher_decrypt(struct skcipher_request *req)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_skcipher_decrypt);
|
||||
|
||||
static int crypto_lskcipher_export(struct skcipher_request *req, void *out)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
u8 *ivs = skcipher_request_ctx(req);
|
||||
|
||||
ivs = PTR_ALIGN(ivs, crypto_skcipher_alignmask(tfm) + 1);
|
||||
|
||||
memcpy(out, ivs + crypto_skcipher_ivsize(tfm),
|
||||
crypto_skcipher_statesize(tfm));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_lskcipher_import(struct skcipher_request *req, const void *in)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
u8 *ivs = skcipher_request_ctx(req);
|
||||
|
||||
ivs = PTR_ALIGN(ivs, crypto_skcipher_alignmask(tfm) + 1);
|
||||
|
||||
memcpy(ivs + crypto_skcipher_ivsize(tfm), in,
|
||||
crypto_skcipher_statesize(tfm));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_noexport(struct skcipher_request *req, void *out)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_noimport(struct skcipher_request *req, const void *in)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_skcipher_export(struct skcipher_request *req, void *out)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
|
||||
|
||||
if (alg->co.base.cra_type != &crypto_skcipher_type)
|
||||
return crypto_lskcipher_export(req, out);
|
||||
return alg->export(req, out);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_skcipher_export);
|
||||
|
||||
int crypto_skcipher_import(struct skcipher_request *req, const void *in)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
|
||||
|
||||
if (alg->co.base.cra_type != &crypto_skcipher_type)
|
||||
return crypto_lskcipher_import(req, in);
|
||||
return alg->import(req, in);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_skcipher_import);
|
||||
|
||||
static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
@@ -713,8 +771,17 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
|
||||
|
||||
skcipher_set_needkey(skcipher);
|
||||
|
||||
if (tfm->__crt_alg->cra_type != &crypto_skcipher_type)
|
||||
if (tfm->__crt_alg->cra_type != &crypto_skcipher_type) {
|
||||
unsigned am = crypto_skcipher_alignmask(skcipher);
|
||||
unsigned reqsize;
|
||||
|
||||
reqsize = am & ~(crypto_tfm_ctx_alignment() - 1);
|
||||
reqsize += crypto_skcipher_ivsize(skcipher);
|
||||
reqsize += crypto_skcipher_statesize(skcipher);
|
||||
crypto_skcipher_set_reqsize(skcipher, reqsize);
|
||||
|
||||
return crypto_init_lskcipher_ops_sg(tfm);
|
||||
}
|
||||
|
||||
if (alg->exit)
|
||||
skcipher->base.exit = crypto_skcipher_exit_tfm;
|
||||
@@ -756,6 +823,7 @@ static void crypto_skcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
seq_printf(m, "ivsize : %u\n", skcipher->ivsize);
|
||||
seq_printf(m, "chunksize : %u\n", skcipher->chunksize);
|
||||
seq_printf(m, "walksize : %u\n", skcipher->walksize);
|
||||
seq_printf(m, "statesize : %u\n", skcipher->statesize);
|
||||
}
|
||||
|
||||
static int __maybe_unused crypto_skcipher_report(
|
||||
@@ -870,7 +938,9 @@ int skcipher_prepare_alg_common(struct skcipher_alg_common *alg)
|
||||
struct crypto_istat_cipher *istat = skcipher_get_stat_common(alg);
|
||||
struct crypto_alg *base = &alg->base;
|
||||
|
||||
if (alg->ivsize > PAGE_SIZE / 8 || alg->chunksize > PAGE_SIZE / 8)
|
||||
if (alg->ivsize > PAGE_SIZE / 8 || alg->chunksize > PAGE_SIZE / 8 ||
|
||||
alg->statesize > PAGE_SIZE / 2 ||
|
||||
(alg->ivsize + alg->statesize) > PAGE_SIZE / 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (!alg->chunksize)
|
||||
@@ -899,6 +969,12 @@ static int skcipher_prepare_alg(struct skcipher_alg *alg)
|
||||
if (!alg->walksize)
|
||||
alg->walksize = alg->chunksize;
|
||||
|
||||
if (!alg->statesize) {
|
||||
alg->import = skcipher_noimport;
|
||||
alg->export = skcipher_noexport;
|
||||
} else if (!(alg->import && alg->export))
|
||||
return -EINVAL;
|
||||
|
||||
base->cra_type = &crypto_skcipher_type;
|
||||
base->cra_flags |= CRYPTO_ALG_TYPE_SKCIPHER;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user