xref: /openbmc/linux/crypto/shash.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27b5a080bSHerbert Xu /*
37b5a080bSHerbert Xu  * Synchronous Cryptographic Hash operations.
47b5a080bSHerbert Xu  *
57b5a080bSHerbert Xu  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
67b5a080bSHerbert Xu  */
77b5a080bSHerbert Xu 
83b2f6df0SHerbert Xu #include <crypto/scatterwalk.h>
942808e5dSHerbert Xu #include <linux/cryptouser.h>
107b5a080bSHerbert Xu #include <linux/err.h>
117b5a080bSHerbert Xu #include <linux/kernel.h>
127b5a080bSHerbert Xu #include <linux/module.h>
137b5a080bSHerbert Xu #include <linux/slab.h>
147b5a080bSHerbert Xu #include <linux/seq_file.h>
1542808e5dSHerbert Xu #include <linux/string.h>
16f4d663ceSSteffen Klassert #include <net/netlink.h>
177b5a080bSHerbert Xu 
1842808e5dSHerbert Xu #include "hash.h"
193b2f6df0SHerbert Xu 
201c799571SHerbert Xu #define MAX_SHASH_ALIGNMASK 63
211c799571SHerbert Xu 
223f683d61SHerbert Xu static const struct crypto_type crypto_shash_type;
233f683d61SHerbert Xu 
shash_get_stat(struct shash_alg * alg)2442808e5dSHerbert Xu static inline struct crypto_istat_hash *shash_get_stat(struct shash_alg *alg)
2542808e5dSHerbert Xu {
2642808e5dSHerbert Xu 	return hash_get_stat(&alg->halg);
2742808e5dSHerbert Xu }
2842808e5dSHerbert Xu 
crypto_shash_errstat(struct shash_alg * alg,int err)2942808e5dSHerbert Xu static inline int crypto_shash_errstat(struct shash_alg *alg, int err)
3042808e5dSHerbert Xu {
3142808e5dSHerbert Xu 	return crypto_hash_errstat(&alg->halg, err);
3242808e5dSHerbert Xu }
3342808e5dSHerbert Xu 
shash_no_setkey(struct crypto_shash * tfm,const u8 * key,unsigned int keylen)34c060e16dSEric Biggers int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
3557cfe44bSHerbert Xu 		    unsigned int keylen)
3657cfe44bSHerbert Xu {
3757cfe44bSHerbert Xu 	return -ENOSYS;
3857cfe44bSHerbert Xu }
39c060e16dSEric Biggers EXPORT_SYMBOL_GPL(shash_no_setkey);
4057cfe44bSHerbert Xu 
shash_setkey_unaligned(struct crypto_shash * tfm,const u8 * key,unsigned int keylen)417b5a080bSHerbert Xu static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
427b5a080bSHerbert Xu 				  unsigned int keylen)
437b5a080bSHerbert Xu {
447b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
457b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
467b5a080bSHerbert Xu 	unsigned long absize;
477b5a080bSHerbert Xu 	u8 *buffer, *alignbuffer;
487b5a080bSHerbert Xu 	int err;
497b5a080bSHerbert Xu 
5018eb8ea6SHerbert Xu 	absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
519039f3efSJia-Ju Bai 	buffer = kmalloc(absize, GFP_ATOMIC);
527b5a080bSHerbert Xu 	if (!buffer)
537b5a080bSHerbert Xu 		return -ENOMEM;
547b5a080bSHerbert Xu 
557b5a080bSHerbert Xu 	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
567b5a080bSHerbert Xu 	memcpy(alignbuffer, key, keylen);
577b5a080bSHerbert Xu 	err = shash->setkey(tfm, alignbuffer, keylen);
58453431a5SWaiman Long 	kfree_sensitive(buffer);
597b5a080bSHerbert Xu 	return err;
607b5a080bSHerbert Xu }
617b5a080bSHerbert Xu 
shash_set_needkey(struct crypto_shash * tfm,struct shash_alg * alg)62ba7d7433SEric Biggers static void shash_set_needkey(struct crypto_shash *tfm, struct shash_alg *alg)
63ba7d7433SEric Biggers {
64c2881789SEric Biggers 	if (crypto_shash_alg_needs_key(alg))
65ba7d7433SEric Biggers 		crypto_shash_set_flags(tfm, CRYPTO_TFM_NEED_KEY);
66ba7d7433SEric Biggers }
67ba7d7433SEric Biggers 
crypto_shash_setkey(struct crypto_shash * tfm,const u8 * key,unsigned int keylen)687b5a080bSHerbert Xu int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
697b5a080bSHerbert Xu 			unsigned int keylen)
707b5a080bSHerbert Xu {
717b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
727b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
739fa68f62SEric Biggers 	int err;
747b5a080bSHerbert Xu 
757b5a080bSHerbert Xu 	if ((unsigned long)key & alignmask)
769fa68f62SEric Biggers 		err = shash_setkey_unaligned(tfm, key, keylen);
779fa68f62SEric Biggers 	else
789fa68f62SEric Biggers 		err = shash->setkey(tfm, key, keylen);
797b5a080bSHerbert Xu 
80ba7d7433SEric Biggers 	if (unlikely(err)) {
81ba7d7433SEric Biggers 		shash_set_needkey(tfm, shash);
829fa68f62SEric Biggers 		return err;
83ba7d7433SEric Biggers 	}
849fa68f62SEric Biggers 
859fa68f62SEric Biggers 	crypto_shash_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
869fa68f62SEric Biggers 	return 0;
877b5a080bSHerbert Xu }
887b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_setkey);
897b5a080bSHerbert Xu 
shash_update_unaligned(struct shash_desc * desc,const u8 * data,unsigned int len)907b5a080bSHerbert Xu static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
917b5a080bSHerbert Xu 				  unsigned int len)
927b5a080bSHerbert Xu {
937b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
947b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
957b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
967b5a080bSHerbert Xu 	unsigned int unaligned_len = alignmask + 1 -
977b5a080bSHerbert Xu 				     ((unsigned long)data & alignmask);
98f3569fd6SKees Cook 	/*
99f3569fd6SKees Cook 	 * We cannot count on __aligned() working for large values:
100f3569fd6SKees Cook 	 * https://patchwork.kernel.org/patch/9507697/
101f3569fd6SKees Cook 	 */
1021c799571SHerbert Xu 	u8 ubuf[MAX_SHASH_ALIGNMASK * 2];
1030e2d3a12SHerbert Xu 	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
1048c32c516SHerbert Xu 	int err;
1057b5a080bSHerbert Xu 
106f3569fd6SKees Cook 	if (WARN_ON(buf + unaligned_len > ubuf + sizeof(ubuf)))
107f3569fd6SKees Cook 		return -EINVAL;
108f3569fd6SKees Cook 
109f4f68993SYehuda Sadeh 	if (unaligned_len > len)
110f4f68993SYehuda Sadeh 		unaligned_len = len;
111f4f68993SYehuda Sadeh 
1127b5a080bSHerbert Xu 	memcpy(buf, data, unaligned_len);
1138c32c516SHerbert Xu 	err = shash->update(desc, buf, unaligned_len);
1148c32c516SHerbert Xu 	memset(buf, 0, unaligned_len);
1157b5a080bSHerbert Xu 
1168c32c516SHerbert Xu 	return err ?:
1177b5a080bSHerbert Xu 	       shash->update(desc, data + unaligned_len, len - unaligned_len);
1187b5a080bSHerbert Xu }
1197b5a080bSHerbert Xu 
crypto_shash_update(struct shash_desc * desc,const u8 * data,unsigned int len)1207b5a080bSHerbert Xu int crypto_shash_update(struct shash_desc *desc, const u8 *data,
1217b5a080bSHerbert Xu 			unsigned int len)
1227b5a080bSHerbert Xu {
1237b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1247b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1257b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
12642808e5dSHerbert Xu 	int err;
12742808e5dSHerbert Xu 
12842808e5dSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
12942808e5dSHerbert Xu 		atomic64_add(len, &shash_get_stat(shash)->hash_tlen);
1307b5a080bSHerbert Xu 
1317b5a080bSHerbert Xu 	if ((unsigned long)data & alignmask)
13242808e5dSHerbert Xu 		err = shash_update_unaligned(desc, data, len);
13342808e5dSHerbert Xu 	else
13442808e5dSHerbert Xu 		err = shash->update(desc, data, len);
1357b5a080bSHerbert Xu 
13642808e5dSHerbert Xu 	return crypto_shash_errstat(shash, err);
1377b5a080bSHerbert Xu }
1387b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_update);
1397b5a080bSHerbert Xu 
shash_final_unaligned(struct shash_desc * desc,u8 * out)1407b5a080bSHerbert Xu static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
1417b5a080bSHerbert Xu {
1427b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1437b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1447b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1457b5a080bSHerbert Xu 	unsigned int ds = crypto_shash_digestsize(tfm);
146f3569fd6SKees Cook 	/*
147f3569fd6SKees Cook 	 * We cannot count on __aligned() working for large values:
148f3569fd6SKees Cook 	 * https://patchwork.kernel.org/patch/9507697/
149f3569fd6SKees Cook 	 */
1501c799571SHerbert Xu 	u8 ubuf[MAX_SHASH_ALIGNMASK + HASH_MAX_DIGESTSIZE];
1510e2d3a12SHerbert Xu 	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
1527b5a080bSHerbert Xu 	int err;
1537b5a080bSHerbert Xu 
154f3569fd6SKees Cook 	if (WARN_ON(buf + ds > ubuf + sizeof(ubuf)))
155f3569fd6SKees Cook 		return -EINVAL;
156f3569fd6SKees Cook 
1577b5a080bSHerbert Xu 	err = shash->final(desc, buf);
1588c32c516SHerbert Xu 	if (err)
1598c32c516SHerbert Xu 		goto out;
1608c32c516SHerbert Xu 
1617b5a080bSHerbert Xu 	memcpy(out, buf, ds);
1628c32c516SHerbert Xu 
1638c32c516SHerbert Xu out:
1648c32c516SHerbert Xu 	memset(buf, 0, ds);
1657b5a080bSHerbert Xu 	return err;
1667b5a080bSHerbert Xu }
1677b5a080bSHerbert Xu 
crypto_shash_final(struct shash_desc * desc,u8 * out)1687b5a080bSHerbert Xu int crypto_shash_final(struct shash_desc *desc, u8 *out)
1697b5a080bSHerbert Xu {
1707b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1717b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1727b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
17342808e5dSHerbert Xu 	int err;
17442808e5dSHerbert Xu 
17542808e5dSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
17642808e5dSHerbert Xu 		atomic64_inc(&shash_get_stat(shash)->hash_cnt);
1777b5a080bSHerbert Xu 
1787b5a080bSHerbert Xu 	if ((unsigned long)out & alignmask)
17942808e5dSHerbert Xu 		err = shash_final_unaligned(desc, out);
18042808e5dSHerbert Xu 	else
18142808e5dSHerbert Xu 		err = shash->final(desc, out);
1827b5a080bSHerbert Xu 
18342808e5dSHerbert Xu 	return crypto_shash_errstat(shash, err);
1847b5a080bSHerbert Xu }
1857b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_final);
1867b5a080bSHerbert Xu 
shash_finup_unaligned(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)1877b5a080bSHerbert Xu static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
1887b5a080bSHerbert Xu 				 unsigned int len, u8 *out)
1897b5a080bSHerbert Xu {
19042808e5dSHerbert Xu 	return shash_update_unaligned(desc, data, len) ?:
19142808e5dSHerbert Xu 	       shash_final_unaligned(desc, out);
1927b5a080bSHerbert Xu }
1937b5a080bSHerbert Xu 
crypto_shash_finup(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)1947b5a080bSHerbert Xu int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
1957b5a080bSHerbert Xu 		       unsigned int len, u8 *out)
1967b5a080bSHerbert Xu {
1977b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1987b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1997b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
20042808e5dSHerbert Xu 	int err;
20142808e5dSHerbert Xu 
20242808e5dSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
20342808e5dSHerbert Xu 		struct crypto_istat_hash *istat = shash_get_stat(shash);
20442808e5dSHerbert Xu 
20542808e5dSHerbert Xu 		atomic64_inc(&istat->hash_cnt);
20642808e5dSHerbert Xu 		atomic64_add(len, &istat->hash_tlen);
20742808e5dSHerbert Xu 	}
2087b5a080bSHerbert Xu 
2098267adabSHerbert Xu 	if (((unsigned long)data | (unsigned long)out) & alignmask)
21042808e5dSHerbert Xu 		err = shash_finup_unaligned(desc, data, len, out);
21142808e5dSHerbert Xu 	else
21242808e5dSHerbert Xu 		err = shash->finup(desc, data, len, out);
2137b5a080bSHerbert Xu 
21442808e5dSHerbert Xu 
21542808e5dSHerbert Xu 	return crypto_shash_errstat(shash, err);
2167b5a080bSHerbert Xu }
2177b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_finup);
2187b5a080bSHerbert Xu 
shash_digest_unaligned(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)2197b5a080bSHerbert Xu static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data,
2207b5a080bSHerbert Xu 				  unsigned int len, u8 *out)
2217b5a080bSHerbert Xu {
2227b5a080bSHerbert Xu 	return crypto_shash_init(desc) ?:
22342808e5dSHerbert Xu 	       shash_update_unaligned(desc, data, len) ?:
22442808e5dSHerbert Xu 	       shash_final_unaligned(desc, out);
2257b5a080bSHerbert Xu }
2267b5a080bSHerbert Xu 
crypto_shash_digest(struct shash_desc * desc,const u8 * data,unsigned int len,u8 * out)2277b5a080bSHerbert Xu int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
2287b5a080bSHerbert Xu 			unsigned int len, u8 *out)
2297b5a080bSHerbert Xu {
2307b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
2317b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
2327b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
23342808e5dSHerbert Xu 	int err;
23442808e5dSHerbert Xu 
23542808e5dSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS)) {
23642808e5dSHerbert Xu 		struct crypto_istat_hash *istat = shash_get_stat(shash);
23742808e5dSHerbert Xu 
23842808e5dSHerbert Xu 		atomic64_inc(&istat->hash_cnt);
23942808e5dSHerbert Xu 		atomic64_add(len, &istat->hash_tlen);
24042808e5dSHerbert Xu 	}
2417b5a080bSHerbert Xu 
2429fa68f62SEric Biggers 	if (crypto_shash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
24342808e5dSHerbert Xu 		err = -ENOKEY;
24442808e5dSHerbert Xu 	else if (((unsigned long)data | (unsigned long)out) & alignmask)
24542808e5dSHerbert Xu 		err = shash_digest_unaligned(desc, data, len, out);
24642808e5dSHerbert Xu 	else
24742808e5dSHerbert Xu 		err = shash->digest(desc, data, len, out);
2489fa68f62SEric Biggers 
24942808e5dSHerbert Xu 	return crypto_shash_errstat(shash, err);
2507b5a080bSHerbert Xu }
2517b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_digest);
2527b5a080bSHerbert Xu 
crypto_shash_tfm_digest(struct crypto_shash * tfm,const u8 * data,unsigned int len,u8 * out)253822a98b8SEric Biggers int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
254822a98b8SEric Biggers 			    unsigned int len, u8 *out)
255822a98b8SEric Biggers {
256822a98b8SEric Biggers 	SHASH_DESC_ON_STACK(desc, tfm);
257822a98b8SEric Biggers 	int err;
258822a98b8SEric Biggers 
259822a98b8SEric Biggers 	desc->tfm = tfm;
260822a98b8SEric Biggers 
261822a98b8SEric Biggers 	err = crypto_shash_digest(desc, data, len, out);
262822a98b8SEric Biggers 
263822a98b8SEric Biggers 	shash_desc_zero(desc);
264822a98b8SEric Biggers 
265822a98b8SEric Biggers 	return err;
266822a98b8SEric Biggers }
267822a98b8SEric Biggers EXPORT_SYMBOL_GPL(crypto_shash_tfm_digest);
268822a98b8SEric Biggers 
shash_default_export(struct shash_desc * desc,void * out)269f592682fSHerbert Xu static int shash_default_export(struct shash_desc *desc, void *out)
270dec8b786SHerbert Xu {
271f592682fSHerbert Xu 	memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
272f592682fSHerbert Xu 	return 0;
273dec8b786SHerbert Xu }
27499d27e1cSHerbert Xu 
shash_default_import(struct shash_desc * desc,const void * in)275f592682fSHerbert Xu static int shash_default_import(struct shash_desc *desc, const void *in)
27699d27e1cSHerbert Xu {
277f592682fSHerbert Xu 	memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm));
278f592682fSHerbert Xu 	return 0;
27999d27e1cSHerbert Xu }
280dec8b786SHerbert Xu 
shash_async_setkey(struct crypto_ahash * tfm,const u8 * key,unsigned int keylen)2813b2f6df0SHerbert Xu static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
2823b2f6df0SHerbert Xu 			      unsigned int keylen)
2833b2f6df0SHerbert Xu {
2843b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(tfm);
2853b2f6df0SHerbert Xu 
2863b2f6df0SHerbert Xu 	return crypto_shash_setkey(*ctx, key, keylen);
2873b2f6df0SHerbert Xu }
2883b2f6df0SHerbert Xu 
shash_async_init(struct ahash_request * req)2893b2f6df0SHerbert Xu static int shash_async_init(struct ahash_request *req)
2903b2f6df0SHerbert Xu {
2913b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
2923b2f6df0SHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
2933b2f6df0SHerbert Xu 
2943b2f6df0SHerbert Xu 	desc->tfm = *ctx;
2953b2f6df0SHerbert Xu 
2963b2f6df0SHerbert Xu 	return crypto_shash_init(desc);
2973b2f6df0SHerbert Xu }
2983b2f6df0SHerbert Xu 
shash_ahash_update(struct ahash_request * req,struct shash_desc * desc)2997eddf95eSHerbert Xu int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc)
3003b2f6df0SHerbert Xu {
3013b2f6df0SHerbert Xu 	struct crypto_hash_walk walk;
3023b2f6df0SHerbert Xu 	int nbytes;
3033b2f6df0SHerbert Xu 
3043b2f6df0SHerbert Xu 	for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
3053b2f6df0SHerbert Xu 	     nbytes = crypto_hash_walk_done(&walk, nbytes))
3063b2f6df0SHerbert Xu 		nbytes = crypto_shash_update(desc, walk.data, nbytes);
3073b2f6df0SHerbert Xu 
3083b2f6df0SHerbert Xu 	return nbytes;
3093b2f6df0SHerbert Xu }
3107eddf95eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_update);
3117eddf95eSHerbert Xu 
shash_async_update(struct ahash_request * req)3127eddf95eSHerbert Xu static int shash_async_update(struct ahash_request *req)
3137eddf95eSHerbert Xu {
3147eddf95eSHerbert Xu 	return shash_ahash_update(req, ahash_request_ctx(req));
3157eddf95eSHerbert Xu }
3163b2f6df0SHerbert Xu 
shash_async_final(struct ahash_request * req)3173b2f6df0SHerbert Xu static int shash_async_final(struct ahash_request *req)
3183b2f6df0SHerbert Xu {
3193b2f6df0SHerbert Xu 	return crypto_shash_final(ahash_request_ctx(req), req->result);
3203b2f6df0SHerbert Xu }
3213b2f6df0SHerbert Xu 
shash_ahash_finup(struct ahash_request * req,struct shash_desc * desc)32266f6ce5eSHerbert Xu int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc)
32366f6ce5eSHerbert Xu {
32466f6ce5eSHerbert Xu 	struct crypto_hash_walk walk;
32566f6ce5eSHerbert Xu 	int nbytes;
32666f6ce5eSHerbert Xu 
327cbc86b91SHerbert Xu 	nbytes = crypto_hash_walk_first(req, &walk);
328cbc86b91SHerbert Xu 	if (!nbytes)
329cbc86b91SHerbert Xu 		return crypto_shash_final(desc, req->result);
330cbc86b91SHerbert Xu 
331cbc86b91SHerbert Xu 	do {
33266f6ce5eSHerbert Xu 		nbytes = crypto_hash_walk_last(&walk) ?
33366f6ce5eSHerbert Xu 			 crypto_shash_finup(desc, walk.data, nbytes,
33466f6ce5eSHerbert Xu 					    req->result) :
33566f6ce5eSHerbert Xu 			 crypto_shash_update(desc, walk.data, nbytes);
336cbc86b91SHerbert Xu 		nbytes = crypto_hash_walk_done(&walk, nbytes);
337cbc86b91SHerbert Xu 	} while (nbytes > 0);
33866f6ce5eSHerbert Xu 
33966f6ce5eSHerbert Xu 	return nbytes;
34066f6ce5eSHerbert Xu }
34166f6ce5eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_finup);
34266f6ce5eSHerbert Xu 
shash_async_finup(struct ahash_request * req)34366f6ce5eSHerbert Xu static int shash_async_finup(struct ahash_request *req)
34466f6ce5eSHerbert Xu {
34566f6ce5eSHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
34666f6ce5eSHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
34766f6ce5eSHerbert Xu 
34866f6ce5eSHerbert Xu 	desc->tfm = *ctx;
34966f6ce5eSHerbert Xu 
35066f6ce5eSHerbert Xu 	return shash_ahash_finup(req, desc);
35166f6ce5eSHerbert Xu }
35266f6ce5eSHerbert Xu 
shash_ahash_digest(struct ahash_request * req,struct shash_desc * desc)3537eddf95eSHerbert Xu int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
3543b2f6df0SHerbert Xu {
3553b2f6df0SHerbert Xu 	unsigned int nbytes = req->nbytes;
356b61907bbSHerbert Xu 	struct scatterlist *sg;
357b61907bbSHerbert Xu 	unsigned int offset;
3583b2f6df0SHerbert Xu 	int err;
3593b2f6df0SHerbert Xu 
360b61907bbSHerbert Xu 	if (nbytes &&
361b61907bbSHerbert Xu 	    (sg = req->src, offset = sg->offset,
36267cb60e4SEric Biggers 	     nbytes <= min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset))) {
3633b2f6df0SHerbert Xu 		void *data;
3643b2f6df0SHerbert Xu 
365aa969515SArd Biesheuvel 		data = kmap_local_page(sg_page(sg));
3663b2f6df0SHerbert Xu 		err = crypto_shash_digest(desc, data + offset, nbytes,
3673b2f6df0SHerbert Xu 					  req->result);
368aa969515SArd Biesheuvel 		kunmap_local(data);
3697eddf95eSHerbert Xu 	} else
3707eddf95eSHerbert Xu 		err = crypto_shash_init(desc) ?:
37166f6ce5eSHerbert Xu 		      shash_ahash_finup(req, desc);
3723b2f6df0SHerbert Xu 
3733b2f6df0SHerbert Xu 	return err;
3743b2f6df0SHerbert Xu }
3757eddf95eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_digest);
3767eddf95eSHerbert Xu 
shash_async_digest(struct ahash_request * req)3777eddf95eSHerbert Xu static int shash_async_digest(struct ahash_request *req)
3787eddf95eSHerbert Xu {
3797eddf95eSHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
3807eddf95eSHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
3817eddf95eSHerbert Xu 
3827eddf95eSHerbert Xu 	desc->tfm = *ctx;
3837eddf95eSHerbert Xu 
3847eddf95eSHerbert Xu 	return shash_ahash_digest(req, desc);
3857eddf95eSHerbert Xu }
3863b2f6df0SHerbert Xu 
shash_async_export(struct ahash_request * req,void * out)38766f6ce5eSHerbert Xu static int shash_async_export(struct ahash_request *req, void *out)
38866f6ce5eSHerbert Xu {
38966f6ce5eSHerbert Xu 	return crypto_shash_export(ahash_request_ctx(req), out);
39066f6ce5eSHerbert Xu }
39166f6ce5eSHerbert Xu 
shash_async_import(struct ahash_request * req,const void * in)39266f6ce5eSHerbert Xu static int shash_async_import(struct ahash_request *req, const void *in)
39366f6ce5eSHerbert Xu {
39490246e79SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
39590246e79SHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
39690246e79SHerbert Xu 
39790246e79SHerbert Xu 	desc->tfm = *ctx;
39890246e79SHerbert Xu 
39990246e79SHerbert Xu 	return crypto_shash_import(desc, in);
40066f6ce5eSHerbert Xu }
40166f6ce5eSHerbert Xu 
crypto_exit_shash_ops_async(struct crypto_tfm * tfm)4023b2f6df0SHerbert Xu static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
4033b2f6df0SHerbert Xu {
4043b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
4053b2f6df0SHerbert Xu 
4063b2f6df0SHerbert Xu 	crypto_free_shash(*ctx);
4073b2f6df0SHerbert Xu }
4083b2f6df0SHerbert Xu 
crypto_init_shash_ops_async(struct crypto_tfm * tfm)40988056ec3SHerbert Xu int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
4103b2f6df0SHerbert Xu {
4113b2f6df0SHerbert Xu 	struct crypto_alg *calg = tfm->__crt_alg;
41266f6ce5eSHerbert Xu 	struct shash_alg *alg = __crypto_shash_alg(calg);
41388056ec3SHerbert Xu 	struct crypto_ahash *crt = __crypto_ahash_cast(tfm);
4143b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
4153b2f6df0SHerbert Xu 	struct crypto_shash *shash;
4163b2f6df0SHerbert Xu 
4173b2f6df0SHerbert Xu 	if (!crypto_mod_get(calg))
4183b2f6df0SHerbert Xu 		return -EAGAIN;
4193b2f6df0SHerbert Xu 
4203f683d61SHerbert Xu 	shash = crypto_create_tfm(calg, &crypto_shash_type);
4213b2f6df0SHerbert Xu 	if (IS_ERR(shash)) {
4223b2f6df0SHerbert Xu 		crypto_mod_put(calg);
4233b2f6df0SHerbert Xu 		return PTR_ERR(shash);
4243b2f6df0SHerbert Xu 	}
4253b2f6df0SHerbert Xu 
4263b2f6df0SHerbert Xu 	*ctx = shash;
4273b2f6df0SHerbert Xu 	tfm->exit = crypto_exit_shash_ops_async;
4283b2f6df0SHerbert Xu 
4293b2f6df0SHerbert Xu 	crt->init = shash_async_init;
4303b2f6df0SHerbert Xu 	crt->update = shash_async_update;
4313b2f6df0SHerbert Xu 	crt->final = shash_async_final;
43266f6ce5eSHerbert Xu 	crt->finup = shash_async_finup;
4333b2f6df0SHerbert Xu 	crt->digest = shash_async_digest;
434ba7d7433SEric Biggers 	if (crypto_shash_alg_has_setkey(alg))
4353b2f6df0SHerbert Xu 		crt->setkey = shash_async_setkey;
43600420a65SHerbert Xu 
4379fa68f62SEric Biggers 	crypto_ahash_set_flags(crt, crypto_shash_get_flags(shash) &
4389fa68f62SEric Biggers 				    CRYPTO_TFM_NEED_KEY);
43900420a65SHerbert Xu 
44066f6ce5eSHerbert Xu 	crt->export = shash_async_export;
44166f6ce5eSHerbert Xu 	crt->import = shash_async_import;
4423b2f6df0SHerbert Xu 
4433b2f6df0SHerbert Xu 	crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
4443b2f6df0SHerbert Xu 
4453b2f6df0SHerbert Xu 	return 0;
4463b2f6df0SHerbert Xu }
4473b2f6df0SHerbert Xu 
crypto_clone_shash_ops_async(struct crypto_ahash * nhash,struct crypto_ahash * hash)448ed3630b8SHerbert Xu struct crypto_ahash *crypto_clone_shash_ops_async(struct crypto_ahash *nhash,
449ed3630b8SHerbert Xu 						  struct crypto_ahash *hash)
450ed3630b8SHerbert Xu {
451ed3630b8SHerbert Xu 	struct crypto_shash **nctx = crypto_ahash_ctx(nhash);
452ed3630b8SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(hash);
453ed3630b8SHerbert Xu 	struct crypto_shash *shash;
454ed3630b8SHerbert Xu 
455ed3630b8SHerbert Xu 	shash = crypto_clone_shash(*ctx);
456ed3630b8SHerbert Xu 	if (IS_ERR(shash)) {
457ed3630b8SHerbert Xu 		crypto_free_ahash(nhash);
458ed3630b8SHerbert Xu 		return ERR_CAST(shash);
459ed3630b8SHerbert Xu 	}
460ed3630b8SHerbert Xu 
461ed3630b8SHerbert Xu 	*nctx = shash;
462ed3630b8SHerbert Xu 
463ed3630b8SHerbert Xu 	return nhash;
464ed3630b8SHerbert Xu }
465ed3630b8SHerbert Xu 
crypto_shash_exit_tfm(struct crypto_tfm * tfm)466fbce6be5SHerbert Xu static void crypto_shash_exit_tfm(struct crypto_tfm *tfm)
4677b5a080bSHerbert Xu {
468113adefcSHerbert Xu 	struct crypto_shash *hash = __crypto_shash_cast(tfm);
4699fa68f62SEric Biggers 	struct shash_alg *alg = crypto_shash_alg(hash);
470113adefcSHerbert Xu 
471fbce6be5SHerbert Xu 	alg->exit_tfm(hash);
472fbce6be5SHerbert Xu }
473fbce6be5SHerbert Xu 
crypto_shash_init_tfm(struct crypto_tfm * tfm)474fbce6be5SHerbert Xu static int crypto_shash_init_tfm(struct crypto_tfm *tfm)
475fbce6be5SHerbert Xu {
476fbce6be5SHerbert Xu 	struct crypto_shash *hash = __crypto_shash_cast(tfm);
477fbce6be5SHerbert Xu 	struct shash_alg *alg = crypto_shash_alg(hash);
478fbce6be5SHerbert Xu 	int err;
479fbce6be5SHerbert Xu 
4809fa68f62SEric Biggers 	hash->descsize = alg->descsize;
4819fa68f62SEric Biggers 
482ba7d7433SEric Biggers 	shash_set_needkey(hash, alg);
4839fa68f62SEric Biggers 
484fbce6be5SHerbert Xu 	if (alg->exit_tfm)
485fbce6be5SHerbert Xu 		tfm->exit = crypto_shash_exit_tfm;
486fbce6be5SHerbert Xu 
487fbce6be5SHerbert Xu 	if (!alg->init_tfm)
488fbce6be5SHerbert Xu 		return 0;
489fbce6be5SHerbert Xu 
490fbce6be5SHerbert Xu 	err = alg->init_tfm(hash);
491fbce6be5SHerbert Xu 	if (err)
492fbce6be5SHerbert Xu 		return err;
493fbce6be5SHerbert Xu 
494fbce6be5SHerbert Xu 	/* ->init_tfm() may have increased the descsize. */
495fbce6be5SHerbert Xu 	if (WARN_ON_ONCE(hash->descsize > HASH_MAX_DESCSIZE)) {
496fbce6be5SHerbert Xu 		if (alg->exit_tfm)
497fbce6be5SHerbert Xu 			alg->exit_tfm(hash);
498fbce6be5SHerbert Xu 		return -EINVAL;
499fbce6be5SHerbert Xu 	}
500fbce6be5SHerbert Xu 
5017b5a080bSHerbert Xu 	return 0;
5027b5a080bSHerbert Xu }
5037b5a080bSHerbert Xu 
crypto_shash_free_instance(struct crypto_instance * inst)50448fb3e57SEric Biggers static void crypto_shash_free_instance(struct crypto_instance *inst)
50548fb3e57SEric Biggers {
50648fb3e57SEric Biggers 	struct shash_instance *shash = shash_instance(inst);
50748fb3e57SEric Biggers 
50848fb3e57SEric Biggers 	shash->free(shash);
50948fb3e57SEric Biggers }
51048fb3e57SEric Biggers 
crypto_shash_report(struct sk_buff * skb,struct crypto_alg * alg)511c0f9e01dSHerbert Xu static int __maybe_unused crypto_shash_report(
512c0f9e01dSHerbert Xu 	struct sk_buff *skb, struct crypto_alg *alg)
513f4d663ceSSteffen Klassert {
514f4d663ceSSteffen Klassert 	struct crypto_report_hash rhash;
515f4d663ceSSteffen Klassert 	struct shash_alg *salg = __crypto_shash_alg(alg);
516f4d663ceSSteffen Klassert 
51737db69e0SEric Biggers 	memset(&rhash, 0, sizeof(rhash));
51837db69e0SEric Biggers 
51937db69e0SEric Biggers 	strscpy(rhash.type, "shash", sizeof(rhash.type));
5209a5467bfSMathias Krause 
521f4d663ceSSteffen Klassert 	rhash.blocksize = alg->cra_blocksize;
522f4d663ceSSteffen Klassert 	rhash.digestsize = salg->digestsize;
523f4d663ceSSteffen Klassert 
52437db69e0SEric Biggers 	return nla_put(skb, CRYPTOCFGA_REPORT_HASH, sizeof(rhash), &rhash);
525f4d663ceSSteffen Klassert }
526f4d663ceSSteffen Klassert 
5277b5a080bSHerbert Xu static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
528d8c34b94SGideon Israel Dsouza 	__maybe_unused;
crypto_shash_show(struct seq_file * m,struct crypto_alg * alg)5297b5a080bSHerbert Xu static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
5307b5a080bSHerbert Xu {
5317b5a080bSHerbert Xu 	struct shash_alg *salg = __crypto_shash_alg(alg);
5327b5a080bSHerbert Xu 
5337b5a080bSHerbert Xu 	seq_printf(m, "type         : shash\n");
5347b5a080bSHerbert Xu 	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
5357b5a080bSHerbert Xu 	seq_printf(m, "digestsize   : %u\n", salg->digestsize);
5367b5a080bSHerbert Xu }
5377b5a080bSHerbert Xu 
crypto_shash_report_stat(struct sk_buff * skb,struct crypto_alg * alg)53842808e5dSHerbert Xu static int __maybe_unused crypto_shash_report_stat(
53942808e5dSHerbert Xu 	struct sk_buff *skb, struct crypto_alg *alg)
54042808e5dSHerbert Xu {
54142808e5dSHerbert Xu 	return crypto_hash_report_stat(skb, alg, "shash");
54242808e5dSHerbert Xu }
54342808e5dSHerbert Xu 
5447b5a080bSHerbert Xu static const struct crypto_type crypto_shash_type = {
545ac611680SHerbert Xu 	.extsize = crypto_alg_extsize,
5467b5a080bSHerbert Xu 	.init_tfm = crypto_shash_init_tfm,
54748fb3e57SEric Biggers 	.free = crypto_shash_free_instance,
5487b5a080bSHerbert Xu #ifdef CONFIG_PROC_FS
5497b5a080bSHerbert Xu 	.show = crypto_shash_show,
5507b5a080bSHerbert Xu #endif
551*b8969a1bSOndrej Mosnacek #if IS_ENABLED(CONFIG_CRYPTO_USER)
552f4d663ceSSteffen Klassert 	.report = crypto_shash_report,
553c0f9e01dSHerbert Xu #endif
55442808e5dSHerbert Xu #ifdef CONFIG_CRYPTO_STATS
55542808e5dSHerbert Xu 	.report_stat = crypto_shash_report_stat,
55642808e5dSHerbert Xu #endif
5577b5a080bSHerbert Xu 	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
5587b5a080bSHerbert Xu 	.maskset = CRYPTO_ALG_TYPE_MASK,
5597b5a080bSHerbert Xu 	.type = CRYPTO_ALG_TYPE_SHASH,
5607b5a080bSHerbert Xu 	.tfmsize = offsetof(struct crypto_shash, base),
5617b5a080bSHerbert Xu };
5627b5a080bSHerbert Xu 
crypto_grab_shash(struct crypto_shash_spawn * spawn,struct crypto_instance * inst,const char * name,u32 type,u32 mask)563fdfad1ffSEric Biggers int crypto_grab_shash(struct crypto_shash_spawn *spawn,
564fdfad1ffSEric Biggers 		      struct crypto_instance *inst,
565fdfad1ffSEric Biggers 		      const char *name, u32 type, u32 mask)
566fdfad1ffSEric Biggers {
567fdfad1ffSEric Biggers 	spawn->base.frontend = &crypto_shash_type;
568fdfad1ffSEric Biggers 	return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
569fdfad1ffSEric Biggers }
570fdfad1ffSEric Biggers EXPORT_SYMBOL_GPL(crypto_grab_shash);
571fdfad1ffSEric Biggers 
crypto_alloc_shash(const char * alg_name,u32 type,u32 mask)5727b5a080bSHerbert Xu struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
5737b5a080bSHerbert Xu 					u32 mask)
5747b5a080bSHerbert Xu {
5753f683d61SHerbert Xu 	return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
5767b5a080bSHerbert Xu }
5777b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_alloc_shash);
5787b5a080bSHerbert Xu 
crypto_has_shash(const char * alg_name,u32 type,u32 mask)57985cc4243SHannes Reinecke int crypto_has_shash(const char *alg_name, u32 type, u32 mask)
58085cc4243SHannes Reinecke {
58185cc4243SHannes Reinecke 	return crypto_type_has_alg(alg_name, &crypto_shash_type, type, mask);
58285cc4243SHannes Reinecke }
58385cc4243SHannes Reinecke EXPORT_SYMBOL_GPL(crypto_has_shash);
58485cc4243SHannes Reinecke 
crypto_clone_shash(struct crypto_shash * hash)585ed3630b8SHerbert Xu struct crypto_shash *crypto_clone_shash(struct crypto_shash *hash)
586ed3630b8SHerbert Xu {
587ed3630b8SHerbert Xu 	struct crypto_tfm *tfm = crypto_shash_tfm(hash);
588ed3630b8SHerbert Xu 	struct shash_alg *alg = crypto_shash_alg(hash);
589ed3630b8SHerbert Xu 	struct crypto_shash *nhash;
590ed3630b8SHerbert Xu 	int err;
591ed3630b8SHerbert Xu 
592ed3630b8SHerbert Xu 	if (!crypto_shash_alg_has_setkey(alg)) {
593ed3630b8SHerbert Xu 		tfm = crypto_tfm_get(tfm);
594ed3630b8SHerbert Xu 		if (IS_ERR(tfm))
595ed3630b8SHerbert Xu 			return ERR_CAST(tfm);
596ed3630b8SHerbert Xu 
597ed3630b8SHerbert Xu 		return hash;
598ed3630b8SHerbert Xu 	}
599ed3630b8SHerbert Xu 
600ed3630b8SHerbert Xu 	if (!alg->clone_tfm && (alg->init_tfm || alg->base.cra_init))
601ed3630b8SHerbert Xu 		return ERR_PTR(-ENOSYS);
602ed3630b8SHerbert Xu 
603ed3630b8SHerbert Xu 	nhash = crypto_clone_tfm(&crypto_shash_type, tfm);
604ed3630b8SHerbert Xu 	if (IS_ERR(nhash))
605ed3630b8SHerbert Xu 		return nhash;
606ed3630b8SHerbert Xu 
607ed3630b8SHerbert Xu 	nhash->descsize = hash->descsize;
608ed3630b8SHerbert Xu 
609ed3630b8SHerbert Xu 	if (alg->clone_tfm) {
610ed3630b8SHerbert Xu 		err = alg->clone_tfm(nhash, hash);
611ed3630b8SHerbert Xu 		if (err) {
612ed3630b8SHerbert Xu 			crypto_free_shash(nhash);
613ed3630b8SHerbert Xu 			return ERR_PTR(err);
614ed3630b8SHerbert Xu 		}
615ed3630b8SHerbert Xu 	}
616ed3630b8SHerbert Xu 
617ed3630b8SHerbert Xu 	return nhash;
618ed3630b8SHerbert Xu }
61942808e5dSHerbert Xu EXPORT_SYMBOL_GPL(crypto_clone_shash);
6207b5a080bSHerbert Xu 
hash_prepare_alg(struct hash_alg_common * alg)62142808e5dSHerbert Xu int hash_prepare_alg(struct hash_alg_common *alg)
6227b5a080bSHerbert Xu {
6237b5a080bSHerbert Xu 	struct crypto_istat_hash *istat = hash_get_stat(alg);
6249697b328SHerbert Xu 	struct crypto_alg *base = &alg->base;
6257b5a080bSHerbert Xu 
6267b5a080bSHerbert Xu 	if (alg->digestsize > HASH_MAX_DIGESTSIZE)
62742808e5dSHerbert Xu 		return -EINVAL;
62842808e5dSHerbert Xu 
62942808e5dSHerbert Xu 	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
63042808e5dSHerbert Xu 
63142808e5dSHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_STATS))
63242808e5dSHerbert Xu 		memset(istat, 0, sizeof(*istat));
63342808e5dSHerbert Xu 
63442808e5dSHerbert Xu 	return 0;
63542808e5dSHerbert Xu }
63642808e5dSHerbert Xu 
shash_prepare_alg(struct shash_alg * alg)63742808e5dSHerbert Xu static int shash_prepare_alg(struct shash_alg *alg)
63842808e5dSHerbert Xu {
63942808e5dSHerbert Xu 	struct crypto_alg *base = &alg->halg.base;
64042808e5dSHerbert Xu 	int err;
64142808e5dSHerbert Xu 
64242808e5dSHerbert Xu 	if (alg->descsize > HASH_MAX_DESCSIZE)
6431c799571SHerbert Xu 		return -EINVAL;
6441c799571SHerbert Xu 
6451c799571SHerbert Xu 	if (base->cra_alignmask > MAX_SHASH_ALIGNMASK)
64641a2e94fSEric Biggers 		return -EINVAL;
64741a2e94fSEric Biggers 
64841a2e94fSEric Biggers 	if ((alg->export && !alg->import) || (alg->import && !alg->export))
64942808e5dSHerbert Xu 		return -EINVAL;
65042808e5dSHerbert Xu 
65142808e5dSHerbert Xu 	err = hash_prepare_alg(&alg->halg);
65242808e5dSHerbert Xu 	if (err)
6537b5a080bSHerbert Xu 		return err;
6547b5a080bSHerbert Xu 
65599d27e1cSHerbert Xu 	base->cra_type = &crypto_shash_type;
6568267adabSHerbert Xu 	base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
6578267adabSHerbert Xu 
6588267adabSHerbert Xu 	if (!alg->finup)
6598267adabSHerbert Xu 		alg->finup = shash_finup_unaligned;
660f592682fSHerbert Xu 	if (!alg->digest)
661f592682fSHerbert Xu 		alg->digest = shash_digest_unaligned;
662f592682fSHerbert Xu 	if (!alg->export) {
66342808e5dSHerbert Xu 		alg->export = shash_default_export;
664f592682fSHerbert Xu 		alg->import = shash_default_import;
66557cfe44bSHerbert Xu 		alg->halg.statesize = alg->descsize;
66657cfe44bSHerbert Xu 	}
66799d27e1cSHerbert Xu 	if (!alg->setkey)
668619a6ebdSHerbert Xu 		alg->setkey = shash_no_setkey;
669619a6ebdSHerbert Xu 
670619a6ebdSHerbert Xu 	return 0;
671619a6ebdSHerbert Xu }
672619a6ebdSHerbert Xu 
crypto_register_shash(struct shash_alg * alg)673619a6ebdSHerbert Xu int crypto_register_shash(struct shash_alg *alg)
674619a6ebdSHerbert Xu {
675619a6ebdSHerbert Xu 	struct crypto_alg *base = &alg->base;
676619a6ebdSHerbert Xu 	int err;
677619a6ebdSHerbert Xu 
678619a6ebdSHerbert Xu 	err = shash_prepare_alg(alg);
6797b5a080bSHerbert Xu 	if (err)
6807b5a080bSHerbert Xu 		return err;
6817b5a080bSHerbert Xu 
6827b5a080bSHerbert Xu 	return crypto_register_alg(base);
6837b5a080bSHerbert Xu }
684c6d633a9SEric Biggers EXPORT_SYMBOL_GPL(crypto_register_shash);
6857b5a080bSHerbert Xu 
crypto_unregister_shash(struct shash_alg * alg)686c6d633a9SEric Biggers void crypto_unregister_shash(struct shash_alg *alg)
6877b5a080bSHerbert Xu {
6887b5a080bSHerbert Xu 	crypto_unregister_alg(&alg->base);
6897b5a080bSHerbert Xu }
69050fc3e8dSJussi Kivilinna EXPORT_SYMBOL_GPL(crypto_unregister_shash);
69150fc3e8dSJussi Kivilinna 
crypto_register_shashes(struct shash_alg * algs,int count)69250fc3e8dSJussi Kivilinna int crypto_register_shashes(struct shash_alg *algs, int count)
69350fc3e8dSJussi Kivilinna {
69450fc3e8dSJussi Kivilinna 	int i, ret;
69550fc3e8dSJussi Kivilinna 
69650fc3e8dSJussi Kivilinna 	for (i = 0; i < count; i++) {
69750fc3e8dSJussi Kivilinna 		ret = crypto_register_shash(&algs[i]);
69850fc3e8dSJussi Kivilinna 		if (ret)
69950fc3e8dSJussi Kivilinna 			goto err;
70050fc3e8dSJussi Kivilinna 	}
70150fc3e8dSJussi Kivilinna 
70250fc3e8dSJussi Kivilinna 	return 0;
70350fc3e8dSJussi Kivilinna 
70450fc3e8dSJussi Kivilinna err:
70550fc3e8dSJussi Kivilinna 	for (--i; i >= 0; --i)
70650fc3e8dSJussi Kivilinna 		crypto_unregister_shash(&algs[i]);
70750fc3e8dSJussi Kivilinna 
70850fc3e8dSJussi Kivilinna 	return ret;
70950fc3e8dSJussi Kivilinna }
710c6d633a9SEric Biggers EXPORT_SYMBOL_GPL(crypto_register_shashes);
71150fc3e8dSJussi Kivilinna 
crypto_unregister_shashes(struct shash_alg * algs,int count)712c6d633a9SEric Biggers void crypto_unregister_shashes(struct shash_alg *algs, int count)
71350fc3e8dSJussi Kivilinna {
714c6d633a9SEric Biggers 	int i;
715c6d633a9SEric Biggers 
71650fc3e8dSJussi Kivilinna 	for (i = count - 1; i >= 0; --i)
71750fc3e8dSJussi Kivilinna 		crypto_unregister_shash(&algs[i]);
71850fc3e8dSJussi Kivilinna }
719619a6ebdSHerbert Xu EXPORT_SYMBOL_GPL(crypto_unregister_shashes);
720619a6ebdSHerbert Xu 
shash_register_instance(struct crypto_template * tmpl,struct shash_instance * inst)721619a6ebdSHerbert Xu int shash_register_instance(struct crypto_template *tmpl,
722619a6ebdSHerbert Xu 			    struct shash_instance *inst)
723619a6ebdSHerbert Xu {
724d4fdc2dfSEric Biggers 	int err;
725d4fdc2dfSEric Biggers 
726d4fdc2dfSEric Biggers 	if (WARN_ON(!inst->free))
727619a6ebdSHerbert Xu 		return -EINVAL;
728619a6ebdSHerbert Xu 
729619a6ebdSHerbert Xu 	err = shash_prepare_alg(&inst->alg);
730619a6ebdSHerbert Xu 	if (err)
731619a6ebdSHerbert Xu 		return err;
732619a6ebdSHerbert Xu 
733619a6ebdSHerbert Xu 	return crypto_register_instance(tmpl, shash_crypto_instance(inst));
734619a6ebdSHerbert Xu }
735a39c66ccSEric Biggers EXPORT_SYMBOL_GPL(shash_register_instance);
7362e4fddd8SHerbert Xu 
shash_free_singlespawn_instance(struct shash_instance * inst)737a39c66ccSEric Biggers void shash_free_singlespawn_instance(struct shash_instance *inst)
738a39c66ccSEric Biggers {
7392e4fddd8SHerbert Xu 	crypto_drop_spawn(shash_instance_ctx(inst));
740a39c66ccSEric Biggers 	kfree(inst);
7412e4fddd8SHerbert Xu }
7427b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(shash_free_singlespawn_instance);
7437b5a080bSHerbert Xu 
744 MODULE_LICENSE("GPL");
745 MODULE_DESCRIPTION("Synchronous cryptographic hash type");
746