}
EXPORT_SYMBOL_GPL(crypto_shash_digest);
-static int shash_no_export(struct shash_desc *desc, void *out)
+static int shash_default_export(struct shash_desc *desc, void *out)
{
- return -ENOSYS;
+ memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
+ return 0;
}
-static int shash_no_import(struct shash_desc *desc, const void *in)
+static int shash_default_import(struct shash_desc *desc, const void *in)
{
- return -ENOSYS;
+ memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm));
+ return 0;
}
static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
struct crypto_hash_walk walk;
int nbytes;
- for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
- nbytes = crypto_hash_walk_done(&walk, nbytes))
+ nbytes = crypto_hash_walk_first(req, &walk);
+ if (!nbytes)
+ return crypto_shash_final(desc, req->result);
+
+ do {
nbytes = crypto_hash_walk_last(&walk) ?
crypto_shash_finup(desc, walk.data, nbytes,
req->result) :
crypto_shash_update(desc, walk.data, nbytes);
+ nbytes = crypto_hash_walk_done(&walk, nbytes);
+ } while (nbytes > 0);
return nbytes;
}
crt->setkey = shash_async_setkey;
if (alg->export)
crt->export = shash_async_export;
- if (alg->setkey)
+ if (alg->import)
crt->import = shash_async_import;
crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
alg->finup = shash_finup_unaligned;
if (!alg->digest)
alg->digest = shash_digest_unaligned;
- if (!alg->import)
- alg->import = shash_no_import;
- if (!alg->export)
- alg->export = shash_no_export;
+ if (!alg->export) {
+ alg->export = shash_default_export;
+ alg->import = shash_default_import;
+ alg->statesize = alg->descsize;
+ }
if (!alg->setkey)
alg->setkey = shash_no_setkey;