xref: /linux/crypto/shash.c (revision f4d663ce6357e533f107ce3789bd8848c94bea81)
17b5a080bSHerbert Xu /*
27b5a080bSHerbert Xu  * Synchronous Cryptographic Hash operations.
37b5a080bSHerbert Xu  *
47b5a080bSHerbert Xu  * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
57b5a080bSHerbert Xu  *
67b5a080bSHerbert Xu  * This program is free software; you can redistribute it and/or modify it
77b5a080bSHerbert Xu  * under the terms of the GNU General Public License as published by the Free
87b5a080bSHerbert Xu  * Software Foundation; either version 2 of the License, or (at your option)
97b5a080bSHerbert Xu  * any later version.
107b5a080bSHerbert Xu  *
117b5a080bSHerbert Xu  */
127b5a080bSHerbert Xu 
133b2f6df0SHerbert Xu #include <crypto/scatterwalk.h>
147b5a080bSHerbert Xu #include <crypto/internal/hash.h>
157b5a080bSHerbert Xu #include <linux/err.h>
167b5a080bSHerbert Xu #include <linux/kernel.h>
177b5a080bSHerbert Xu #include <linux/module.h>
187b5a080bSHerbert Xu #include <linux/slab.h>
197b5a080bSHerbert Xu #include <linux/seq_file.h>
20*f4d663ceSSteffen Klassert #include <linux/cryptouser.h>
21*f4d663ceSSteffen Klassert #include <net/netlink.h>
227b5a080bSHerbert Xu 
233b2f6df0SHerbert Xu #include "internal.h"
243b2f6df0SHerbert Xu 
253f683d61SHerbert Xu static const struct crypto_type crypto_shash_type;
263f683d61SHerbert Xu 
2757cfe44bSHerbert Xu static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
2857cfe44bSHerbert Xu 			   unsigned int keylen)
2957cfe44bSHerbert Xu {
3057cfe44bSHerbert Xu 	return -ENOSYS;
3157cfe44bSHerbert Xu }
3257cfe44bSHerbert Xu 
337b5a080bSHerbert Xu static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
347b5a080bSHerbert Xu 				  unsigned int keylen)
357b5a080bSHerbert Xu {
367b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
377b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
387b5a080bSHerbert Xu 	unsigned long absize;
397b5a080bSHerbert Xu 	u8 *buffer, *alignbuffer;
407b5a080bSHerbert Xu 	int err;
417b5a080bSHerbert Xu 
4218eb8ea6SHerbert Xu 	absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1));
437b5a080bSHerbert Xu 	buffer = kmalloc(absize, GFP_KERNEL);
447b5a080bSHerbert Xu 	if (!buffer)
457b5a080bSHerbert Xu 		return -ENOMEM;
467b5a080bSHerbert Xu 
477b5a080bSHerbert Xu 	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
487b5a080bSHerbert Xu 	memcpy(alignbuffer, key, keylen);
497b5a080bSHerbert Xu 	err = shash->setkey(tfm, alignbuffer, keylen);
508c32c516SHerbert Xu 	kzfree(buffer);
517b5a080bSHerbert Xu 	return err;
527b5a080bSHerbert Xu }
537b5a080bSHerbert Xu 
547b5a080bSHerbert Xu int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key,
557b5a080bSHerbert Xu 			unsigned int keylen)
567b5a080bSHerbert Xu {
577b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
587b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
597b5a080bSHerbert Xu 
607b5a080bSHerbert Xu 	if ((unsigned long)key & alignmask)
617b5a080bSHerbert Xu 		return shash_setkey_unaligned(tfm, key, keylen);
627b5a080bSHerbert Xu 
637b5a080bSHerbert Xu 	return shash->setkey(tfm, key, keylen);
647b5a080bSHerbert Xu }
657b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_setkey);
667b5a080bSHerbert Xu 
677b5a080bSHerbert Xu static inline unsigned int shash_align_buffer_size(unsigned len,
687b5a080bSHerbert Xu 						   unsigned long mask)
697b5a080bSHerbert Xu {
707b5a080bSHerbert Xu 	return len + (mask & ~(__alignof__(u8 __attribute__ ((aligned))) - 1));
717b5a080bSHerbert Xu }
727b5a080bSHerbert Xu 
737b5a080bSHerbert Xu static int shash_update_unaligned(struct shash_desc *desc, const u8 *data,
747b5a080bSHerbert Xu 				  unsigned int len)
757b5a080bSHerbert Xu {
767b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
777b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
787b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
797b5a080bSHerbert Xu 	unsigned int unaligned_len = alignmask + 1 -
807b5a080bSHerbert Xu 				     ((unsigned long)data & alignmask);
810e2d3a12SHerbert Xu 	u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)]
827b5a080bSHerbert Xu 		__attribute__ ((aligned));
830e2d3a12SHerbert Xu 	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
848c32c516SHerbert Xu 	int err;
857b5a080bSHerbert Xu 
86f4f68993SYehuda Sadeh 	if (unaligned_len > len)
87f4f68993SYehuda Sadeh 		unaligned_len = len;
88f4f68993SYehuda Sadeh 
897b5a080bSHerbert Xu 	memcpy(buf, data, unaligned_len);
908c32c516SHerbert Xu 	err = shash->update(desc, buf, unaligned_len);
918c32c516SHerbert Xu 	memset(buf, 0, unaligned_len);
927b5a080bSHerbert Xu 
938c32c516SHerbert Xu 	return err ?:
947b5a080bSHerbert Xu 	       shash->update(desc, data + unaligned_len, len - unaligned_len);
957b5a080bSHerbert Xu }
967b5a080bSHerbert Xu 
977b5a080bSHerbert Xu int crypto_shash_update(struct shash_desc *desc, const u8 *data,
987b5a080bSHerbert Xu 			unsigned int len)
997b5a080bSHerbert Xu {
1007b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1017b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1027b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1037b5a080bSHerbert Xu 
1047b5a080bSHerbert Xu 	if ((unsigned long)data & alignmask)
1057b5a080bSHerbert Xu 		return shash_update_unaligned(desc, data, len);
1067b5a080bSHerbert Xu 
1077b5a080bSHerbert Xu 	return shash->update(desc, data, len);
1087b5a080bSHerbert Xu }
1097b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_update);
1107b5a080bSHerbert Xu 
1117b5a080bSHerbert Xu static int shash_final_unaligned(struct shash_desc *desc, u8 *out)
1127b5a080bSHerbert Xu {
1137b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1147b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1157b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1167b5a080bSHerbert Xu 	unsigned int ds = crypto_shash_digestsize(tfm);
1170e2d3a12SHerbert Xu 	u8 ubuf[shash_align_buffer_size(ds, alignmask)]
1187b5a080bSHerbert Xu 		__attribute__ ((aligned));
1190e2d3a12SHerbert Xu 	u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1);
1207b5a080bSHerbert Xu 	int err;
1217b5a080bSHerbert Xu 
1227b5a080bSHerbert Xu 	err = shash->final(desc, buf);
1238c32c516SHerbert Xu 	if (err)
1248c32c516SHerbert Xu 		goto out;
1258c32c516SHerbert Xu 
1267b5a080bSHerbert Xu 	memcpy(out, buf, ds);
1278c32c516SHerbert Xu 
1288c32c516SHerbert Xu out:
1298c32c516SHerbert Xu 	memset(buf, 0, ds);
1307b5a080bSHerbert Xu 	return err;
1317b5a080bSHerbert Xu }
1327b5a080bSHerbert Xu 
1337b5a080bSHerbert Xu int crypto_shash_final(struct shash_desc *desc, u8 *out)
1347b5a080bSHerbert Xu {
1357b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1367b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1377b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1387b5a080bSHerbert Xu 
1397b5a080bSHerbert Xu 	if ((unsigned long)out & alignmask)
1407b5a080bSHerbert Xu 		return shash_final_unaligned(desc, out);
1417b5a080bSHerbert Xu 
1427b5a080bSHerbert Xu 	return shash->final(desc, out);
1437b5a080bSHerbert Xu }
1447b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_final);
1457b5a080bSHerbert Xu 
1467b5a080bSHerbert Xu static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data,
1477b5a080bSHerbert Xu 				 unsigned int len, u8 *out)
1487b5a080bSHerbert Xu {
1497b5a080bSHerbert Xu 	return crypto_shash_update(desc, data, len) ?:
1507b5a080bSHerbert Xu 	       crypto_shash_final(desc, out);
1517b5a080bSHerbert Xu }
1527b5a080bSHerbert Xu 
1537b5a080bSHerbert Xu int crypto_shash_finup(struct shash_desc *desc, const u8 *data,
1547b5a080bSHerbert Xu 		       unsigned int len, u8 *out)
1557b5a080bSHerbert Xu {
1567b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1577b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1587b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1597b5a080bSHerbert Xu 
1608267adabSHerbert Xu 	if (((unsigned long)data | (unsigned long)out) & alignmask)
1617b5a080bSHerbert Xu 		return shash_finup_unaligned(desc, data, len, out);
1627b5a080bSHerbert Xu 
1637b5a080bSHerbert Xu 	return shash->finup(desc, data, len, out);
1647b5a080bSHerbert Xu }
1657b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_finup);
1667b5a080bSHerbert Xu 
1677b5a080bSHerbert Xu static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data,
1687b5a080bSHerbert Xu 				  unsigned int len, u8 *out)
1697b5a080bSHerbert Xu {
1707b5a080bSHerbert Xu 	return crypto_shash_init(desc) ?:
171f88ad8deSHerbert Xu 	       crypto_shash_finup(desc, data, len, out);
1727b5a080bSHerbert Xu }
1737b5a080bSHerbert Xu 
1747b5a080bSHerbert Xu int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
1757b5a080bSHerbert Xu 			unsigned int len, u8 *out)
1767b5a080bSHerbert Xu {
1777b5a080bSHerbert Xu 	struct crypto_shash *tfm = desc->tfm;
1787b5a080bSHerbert Xu 	struct shash_alg *shash = crypto_shash_alg(tfm);
1797b5a080bSHerbert Xu 	unsigned long alignmask = crypto_shash_alignmask(tfm);
1807b5a080bSHerbert Xu 
1818267adabSHerbert Xu 	if (((unsigned long)data | (unsigned long)out) & alignmask)
1827b5a080bSHerbert Xu 		return shash_digest_unaligned(desc, data, len, out);
1837b5a080bSHerbert Xu 
1847b5a080bSHerbert Xu 	return shash->digest(desc, data, len, out);
1857b5a080bSHerbert Xu }
1867b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_shash_digest);
1877b5a080bSHerbert Xu 
188f592682fSHerbert Xu static int shash_default_export(struct shash_desc *desc, void *out)
189dec8b786SHerbert Xu {
190f592682fSHerbert Xu 	memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
191f592682fSHerbert Xu 	return 0;
192dec8b786SHerbert Xu }
19399d27e1cSHerbert Xu 
194f592682fSHerbert Xu static int shash_default_import(struct shash_desc *desc, const void *in)
19599d27e1cSHerbert Xu {
196f592682fSHerbert Xu 	memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm));
197f592682fSHerbert Xu 	return 0;
19899d27e1cSHerbert Xu }
199dec8b786SHerbert Xu 
2003b2f6df0SHerbert Xu static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
2013b2f6df0SHerbert Xu 			      unsigned int keylen)
2023b2f6df0SHerbert Xu {
2033b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(tfm);
2043b2f6df0SHerbert Xu 
2053b2f6df0SHerbert Xu 	return crypto_shash_setkey(*ctx, key, keylen);
2063b2f6df0SHerbert Xu }
2073b2f6df0SHerbert Xu 
2083b2f6df0SHerbert Xu static int shash_async_init(struct ahash_request *req)
2093b2f6df0SHerbert Xu {
2103b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
2113b2f6df0SHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
2123b2f6df0SHerbert Xu 
2133b2f6df0SHerbert Xu 	desc->tfm = *ctx;
2143b2f6df0SHerbert Xu 	desc->flags = req->base.flags;
2153b2f6df0SHerbert Xu 
2163b2f6df0SHerbert Xu 	return crypto_shash_init(desc);
2173b2f6df0SHerbert Xu }
2183b2f6df0SHerbert Xu 
2197eddf95eSHerbert Xu int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc)
2203b2f6df0SHerbert Xu {
2213b2f6df0SHerbert Xu 	struct crypto_hash_walk walk;
2223b2f6df0SHerbert Xu 	int nbytes;
2233b2f6df0SHerbert Xu 
2243b2f6df0SHerbert Xu 	for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0;
2253b2f6df0SHerbert Xu 	     nbytes = crypto_hash_walk_done(&walk, nbytes))
2263b2f6df0SHerbert Xu 		nbytes = crypto_shash_update(desc, walk.data, nbytes);
2273b2f6df0SHerbert Xu 
2283b2f6df0SHerbert Xu 	return nbytes;
2293b2f6df0SHerbert Xu }
2307eddf95eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_update);
2317eddf95eSHerbert Xu 
2327eddf95eSHerbert Xu static int shash_async_update(struct ahash_request *req)
2337eddf95eSHerbert Xu {
2347eddf95eSHerbert Xu 	return shash_ahash_update(req, ahash_request_ctx(req));
2357eddf95eSHerbert Xu }
2363b2f6df0SHerbert Xu 
2373b2f6df0SHerbert Xu static int shash_async_final(struct ahash_request *req)
2383b2f6df0SHerbert Xu {
2393b2f6df0SHerbert Xu 	return crypto_shash_final(ahash_request_ctx(req), req->result);
2403b2f6df0SHerbert Xu }
2413b2f6df0SHerbert Xu 
24266f6ce5eSHerbert Xu int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc)
24366f6ce5eSHerbert Xu {
24466f6ce5eSHerbert Xu 	struct crypto_hash_walk walk;
24566f6ce5eSHerbert Xu 	int nbytes;
24666f6ce5eSHerbert Xu 
247cbc86b91SHerbert Xu 	nbytes = crypto_hash_walk_first(req, &walk);
248cbc86b91SHerbert Xu 	if (!nbytes)
249cbc86b91SHerbert Xu 		return crypto_shash_final(desc, req->result);
250cbc86b91SHerbert Xu 
251cbc86b91SHerbert Xu 	do {
25266f6ce5eSHerbert Xu 		nbytes = crypto_hash_walk_last(&walk) ?
25366f6ce5eSHerbert Xu 			 crypto_shash_finup(desc, walk.data, nbytes,
25466f6ce5eSHerbert Xu 					    req->result) :
25566f6ce5eSHerbert Xu 			 crypto_shash_update(desc, walk.data, nbytes);
256cbc86b91SHerbert Xu 		nbytes = crypto_hash_walk_done(&walk, nbytes);
257cbc86b91SHerbert Xu 	} while (nbytes > 0);
25866f6ce5eSHerbert Xu 
25966f6ce5eSHerbert Xu 	return nbytes;
26066f6ce5eSHerbert Xu }
26166f6ce5eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_finup);
26266f6ce5eSHerbert Xu 
26366f6ce5eSHerbert Xu static int shash_async_finup(struct ahash_request *req)
26466f6ce5eSHerbert Xu {
26566f6ce5eSHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
26666f6ce5eSHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
26766f6ce5eSHerbert Xu 
26866f6ce5eSHerbert Xu 	desc->tfm = *ctx;
26966f6ce5eSHerbert Xu 	desc->flags = req->base.flags;
27066f6ce5eSHerbert Xu 
27166f6ce5eSHerbert Xu 	return shash_ahash_finup(req, desc);
27266f6ce5eSHerbert Xu }
27366f6ce5eSHerbert Xu 
2747eddf95eSHerbert Xu int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)
2753b2f6df0SHerbert Xu {
2763b2f6df0SHerbert Xu 	struct scatterlist *sg = req->src;
2773b2f6df0SHerbert Xu 	unsigned int offset = sg->offset;
2783b2f6df0SHerbert Xu 	unsigned int nbytes = req->nbytes;
2793b2f6df0SHerbert Xu 	int err;
2803b2f6df0SHerbert Xu 
2813b2f6df0SHerbert Xu 	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
2823b2f6df0SHerbert Xu 		void *data;
2833b2f6df0SHerbert Xu 
2843b2f6df0SHerbert Xu 		data = crypto_kmap(sg_page(sg), 0);
2853b2f6df0SHerbert Xu 		err = crypto_shash_digest(desc, data + offset, nbytes,
2863b2f6df0SHerbert Xu 					  req->result);
2873b2f6df0SHerbert Xu 		crypto_kunmap(data, 0);
2883b2f6df0SHerbert Xu 		crypto_yield(desc->flags);
2897eddf95eSHerbert Xu 	} else
2907eddf95eSHerbert Xu 		err = crypto_shash_init(desc) ?:
29166f6ce5eSHerbert Xu 		      shash_ahash_finup(req, desc);
2923b2f6df0SHerbert Xu 
2933b2f6df0SHerbert Xu 	return err;
2943b2f6df0SHerbert Xu }
2957eddf95eSHerbert Xu EXPORT_SYMBOL_GPL(shash_ahash_digest);
2967eddf95eSHerbert Xu 
2977eddf95eSHerbert Xu static int shash_async_digest(struct ahash_request *req)
2987eddf95eSHerbert Xu {
2997eddf95eSHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
3007eddf95eSHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
3017eddf95eSHerbert Xu 
3027eddf95eSHerbert Xu 	desc->tfm = *ctx;
3037eddf95eSHerbert Xu 	desc->flags = req->base.flags;
3047eddf95eSHerbert Xu 
3057eddf95eSHerbert Xu 	return shash_ahash_digest(req, desc);
3067eddf95eSHerbert Xu }
3073b2f6df0SHerbert Xu 
30866f6ce5eSHerbert Xu static int shash_async_export(struct ahash_request *req, void *out)
30966f6ce5eSHerbert Xu {
31066f6ce5eSHerbert Xu 	return crypto_shash_export(ahash_request_ctx(req), out);
31166f6ce5eSHerbert Xu }
31266f6ce5eSHerbert Xu 
31366f6ce5eSHerbert Xu static int shash_async_import(struct ahash_request *req, const void *in)
31466f6ce5eSHerbert Xu {
31590246e79SHerbert Xu 	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req));
31690246e79SHerbert Xu 	struct shash_desc *desc = ahash_request_ctx(req);
31790246e79SHerbert Xu 
31890246e79SHerbert Xu 	desc->tfm = *ctx;
31990246e79SHerbert Xu 	desc->flags = req->base.flags;
32090246e79SHerbert Xu 
32190246e79SHerbert Xu 	return crypto_shash_import(desc, in);
32266f6ce5eSHerbert Xu }
32366f6ce5eSHerbert Xu 
3243b2f6df0SHerbert Xu static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
3253b2f6df0SHerbert Xu {
3263b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
3273b2f6df0SHerbert Xu 
3283b2f6df0SHerbert Xu 	crypto_free_shash(*ctx);
3293b2f6df0SHerbert Xu }
3303b2f6df0SHerbert Xu 
33188056ec3SHerbert Xu int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
3323b2f6df0SHerbert Xu {
3333b2f6df0SHerbert Xu 	struct crypto_alg *calg = tfm->__crt_alg;
33466f6ce5eSHerbert Xu 	struct shash_alg *alg = __crypto_shash_alg(calg);
33588056ec3SHerbert Xu 	struct crypto_ahash *crt = __crypto_ahash_cast(tfm);
3363b2f6df0SHerbert Xu 	struct crypto_shash **ctx = crypto_tfm_ctx(tfm);
3373b2f6df0SHerbert Xu 	struct crypto_shash *shash;
3383b2f6df0SHerbert Xu 
3393b2f6df0SHerbert Xu 	if (!crypto_mod_get(calg))
3403b2f6df0SHerbert Xu 		return -EAGAIN;
3413b2f6df0SHerbert Xu 
3423f683d61SHerbert Xu 	shash = crypto_create_tfm(calg, &crypto_shash_type);
3433b2f6df0SHerbert Xu 	if (IS_ERR(shash)) {
3443b2f6df0SHerbert Xu 		crypto_mod_put(calg);
3453b2f6df0SHerbert Xu 		return PTR_ERR(shash);
3463b2f6df0SHerbert Xu 	}
3473b2f6df0SHerbert Xu 
3483b2f6df0SHerbert Xu 	*ctx = shash;
3493b2f6df0SHerbert Xu 	tfm->exit = crypto_exit_shash_ops_async;
3503b2f6df0SHerbert Xu 
3513b2f6df0SHerbert Xu 	crt->init = shash_async_init;
3523b2f6df0SHerbert Xu 	crt->update = shash_async_update;
3533b2f6df0SHerbert Xu 	crt->final = shash_async_final;
35466f6ce5eSHerbert Xu 	crt->finup = shash_async_finup;
3553b2f6df0SHerbert Xu 	crt->digest = shash_async_digest;
35666f6ce5eSHerbert Xu 
35766f6ce5eSHerbert Xu 	if (alg->setkey)
3583b2f6df0SHerbert Xu 		crt->setkey = shash_async_setkey;
35966f6ce5eSHerbert Xu 	if (alg->export)
36066f6ce5eSHerbert Xu 		crt->export = shash_async_export;
3610044f3edSSteffen Klassert 	if (alg->import)
36266f6ce5eSHerbert Xu 		crt->import = shash_async_import;
3633b2f6df0SHerbert Xu 
3643b2f6df0SHerbert Xu 	crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
3653b2f6df0SHerbert Xu 
3663b2f6df0SHerbert Xu 	return 0;
3673b2f6df0SHerbert Xu }
3683b2f6df0SHerbert Xu 
3695f7082edSHerbert Xu static int shash_compat_setkey(struct crypto_hash *tfm, const u8 *key,
3705f7082edSHerbert Xu 			       unsigned int keylen)
3715f7082edSHerbert Xu {
372113adefcSHerbert Xu 	struct shash_desc **descp = crypto_hash_ctx(tfm);
373113adefcSHerbert Xu 	struct shash_desc *desc = *descp;
3745f7082edSHerbert Xu 
3755f7082edSHerbert Xu 	return crypto_shash_setkey(desc->tfm, key, keylen);
3765f7082edSHerbert Xu }
3775f7082edSHerbert Xu 
3785f7082edSHerbert Xu static int shash_compat_init(struct hash_desc *hdesc)
3795f7082edSHerbert Xu {
380113adefcSHerbert Xu 	struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
381113adefcSHerbert Xu 	struct shash_desc *desc = *descp;
3825f7082edSHerbert Xu 
3835f7082edSHerbert Xu 	desc->flags = hdesc->flags;
3845f7082edSHerbert Xu 
3855f7082edSHerbert Xu 	return crypto_shash_init(desc);
3865f7082edSHerbert Xu }
3875f7082edSHerbert Xu 
3885f7082edSHerbert Xu static int shash_compat_update(struct hash_desc *hdesc, struct scatterlist *sg,
3895f7082edSHerbert Xu 			       unsigned int len)
3905f7082edSHerbert Xu {
391113adefcSHerbert Xu 	struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
392113adefcSHerbert Xu 	struct shash_desc *desc = *descp;
3935f7082edSHerbert Xu 	struct crypto_hash_walk walk;
3945f7082edSHerbert Xu 	int nbytes;
3955f7082edSHerbert Xu 
3965f7082edSHerbert Xu 	for (nbytes = crypto_hash_walk_first_compat(hdesc, &walk, sg, len);
3975f7082edSHerbert Xu 	     nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes))
3985f7082edSHerbert Xu 		nbytes = crypto_shash_update(desc, walk.data, nbytes);
3995f7082edSHerbert Xu 
4005f7082edSHerbert Xu 	return nbytes;
4015f7082edSHerbert Xu }
4025f7082edSHerbert Xu 
4035f7082edSHerbert Xu static int shash_compat_final(struct hash_desc *hdesc, u8 *out)
4045f7082edSHerbert Xu {
405113adefcSHerbert Xu 	struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
406113adefcSHerbert Xu 
407113adefcSHerbert Xu 	return crypto_shash_final(*descp, out);
4085f7082edSHerbert Xu }
4095f7082edSHerbert Xu 
4105f7082edSHerbert Xu static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg,
4115f7082edSHerbert Xu 			       unsigned int nbytes, u8 *out)
4125f7082edSHerbert Xu {
4135f7082edSHerbert Xu 	unsigned int offset = sg->offset;
4145f7082edSHerbert Xu 	int err;
4155f7082edSHerbert Xu 
4165f7082edSHerbert Xu 	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {
417113adefcSHerbert Xu 		struct shash_desc **descp = crypto_hash_ctx(hdesc->tfm);
418113adefcSHerbert Xu 		struct shash_desc *desc = *descp;
4195f7082edSHerbert Xu 		void *data;
4205f7082edSHerbert Xu 
4215f7082edSHerbert Xu 		desc->flags = hdesc->flags;
4225f7082edSHerbert Xu 
4235f7082edSHerbert Xu 		data = crypto_kmap(sg_page(sg), 0);
4245f7082edSHerbert Xu 		err = crypto_shash_digest(desc, data + offset, nbytes, out);
4255f7082edSHerbert Xu 		crypto_kunmap(data, 0);
4265f7082edSHerbert Xu 		crypto_yield(desc->flags);
4275f7082edSHerbert Xu 		goto out;
4285f7082edSHerbert Xu 	}
4295f7082edSHerbert Xu 
4305f7082edSHerbert Xu 	err = shash_compat_init(hdesc);
4315f7082edSHerbert Xu 	if (err)
4325f7082edSHerbert Xu 		goto out;
4335f7082edSHerbert Xu 
4345f7082edSHerbert Xu 	err = shash_compat_update(hdesc, sg, nbytes);
4355f7082edSHerbert Xu 	if (err)
4365f7082edSHerbert Xu 		goto out;
4375f7082edSHerbert Xu 
4385f7082edSHerbert Xu 	err = shash_compat_final(hdesc, out);
4395f7082edSHerbert Xu 
4405f7082edSHerbert Xu out:
4415f7082edSHerbert Xu 	return err;
4425f7082edSHerbert Xu }
4435f7082edSHerbert Xu 
4445f7082edSHerbert Xu static void crypto_exit_shash_ops_compat(struct crypto_tfm *tfm)
4455f7082edSHerbert Xu {
446113adefcSHerbert Xu 	struct shash_desc **descp = crypto_tfm_ctx(tfm);
447113adefcSHerbert Xu 	struct shash_desc *desc = *descp;
4485f7082edSHerbert Xu 
4495f7082edSHerbert Xu 	crypto_free_shash(desc->tfm);
450113adefcSHerbert Xu 	kzfree(desc);
4515f7082edSHerbert Xu }
4525f7082edSHerbert Xu 
4535f7082edSHerbert Xu static int crypto_init_shash_ops_compat(struct crypto_tfm *tfm)
4545f7082edSHerbert Xu {
4555f7082edSHerbert Xu 	struct hash_tfm *crt = &tfm->crt_hash;
4565f7082edSHerbert Xu 	struct crypto_alg *calg = tfm->__crt_alg;
4575f7082edSHerbert Xu 	struct shash_alg *alg = __crypto_shash_alg(calg);
458113adefcSHerbert Xu 	struct shash_desc **descp = crypto_tfm_ctx(tfm);
4595f7082edSHerbert Xu 	struct crypto_shash *shash;
460113adefcSHerbert Xu 	struct shash_desc *desc;
4615f7082edSHerbert Xu 
4624abfd73eSAdrian-Ken Rueegsegger 	if (!crypto_mod_get(calg))
4634abfd73eSAdrian-Ken Rueegsegger 		return -EAGAIN;
4644abfd73eSAdrian-Ken Rueegsegger 
4653f683d61SHerbert Xu 	shash = crypto_create_tfm(calg, &crypto_shash_type);
4664abfd73eSAdrian-Ken Rueegsegger 	if (IS_ERR(shash)) {
4674abfd73eSAdrian-Ken Rueegsegger 		crypto_mod_put(calg);
4685f7082edSHerbert Xu 		return PTR_ERR(shash);
4694abfd73eSAdrian-Ken Rueegsegger 	}
4705f7082edSHerbert Xu 
471113adefcSHerbert Xu 	desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(shash),
472113adefcSHerbert Xu 		       GFP_KERNEL);
473113adefcSHerbert Xu 	if (!desc) {
474113adefcSHerbert Xu 		crypto_free_shash(shash);
475113adefcSHerbert Xu 		return -ENOMEM;
476113adefcSHerbert Xu 	}
477113adefcSHerbert Xu 
478113adefcSHerbert Xu 	*descp = desc;
4795f7082edSHerbert Xu 	desc->tfm = shash;
4805f7082edSHerbert Xu 	tfm->exit = crypto_exit_shash_ops_compat;
4815f7082edSHerbert Xu 
4825f7082edSHerbert Xu 	crt->init = shash_compat_init;
4835f7082edSHerbert Xu 	crt->update = shash_compat_update;
4845f7082edSHerbert Xu 	crt->final  = shash_compat_final;
4855f7082edSHerbert Xu 	crt->digest = shash_compat_digest;
4865f7082edSHerbert Xu 	crt->setkey = shash_compat_setkey;
4875f7082edSHerbert Xu 
4885f7082edSHerbert Xu 	crt->digestsize = alg->digestsize;
4895f7082edSHerbert Xu 
4905f7082edSHerbert Xu 	return 0;
4915f7082edSHerbert Xu }
4925f7082edSHerbert Xu 
4933b2f6df0SHerbert Xu static int crypto_init_shash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
4943b2f6df0SHerbert Xu {
4953b2f6df0SHerbert Xu 	switch (mask & CRYPTO_ALG_TYPE_MASK) {
4965f7082edSHerbert Xu 	case CRYPTO_ALG_TYPE_HASH_MASK:
4975f7082edSHerbert Xu 		return crypto_init_shash_ops_compat(tfm);
4983b2f6df0SHerbert Xu 	}
4993b2f6df0SHerbert Xu 
5003b2f6df0SHerbert Xu 	return -EINVAL;
5013b2f6df0SHerbert Xu }
5023b2f6df0SHerbert Xu 
5033b2f6df0SHerbert Xu static unsigned int crypto_shash_ctxsize(struct crypto_alg *alg, u32 type,
5043b2f6df0SHerbert Xu 					 u32 mask)
5053b2f6df0SHerbert Xu {
5063b2f6df0SHerbert Xu 	switch (mask & CRYPTO_ALG_TYPE_MASK) {
5075f7082edSHerbert Xu 	case CRYPTO_ALG_TYPE_HASH_MASK:
508113adefcSHerbert Xu 		return sizeof(struct shash_desc *);
5093b2f6df0SHerbert Xu 	}
5103b2f6df0SHerbert Xu 
5113b2f6df0SHerbert Xu 	return 0;
5123b2f6df0SHerbert Xu }
5133b2f6df0SHerbert Xu 
5142ca33da1SHerbert Xu static int crypto_shash_init_tfm(struct crypto_tfm *tfm)
5157b5a080bSHerbert Xu {
516113adefcSHerbert Xu 	struct crypto_shash *hash = __crypto_shash_cast(tfm);
517113adefcSHerbert Xu 
518113adefcSHerbert Xu 	hash->descsize = crypto_shash_alg(hash)->descsize;
5197b5a080bSHerbert Xu 	return 0;
5207b5a080bSHerbert Xu }
5217b5a080bSHerbert Xu 
5222ca33da1SHerbert Xu static unsigned int crypto_shash_extsize(struct crypto_alg *alg)
5237b5a080bSHerbert Xu {
5247b5a080bSHerbert Xu 	return alg->cra_ctxsize;
5257b5a080bSHerbert Xu }
5267b5a080bSHerbert Xu 
527*f4d663ceSSteffen Klassert static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
528*f4d663ceSSteffen Klassert {
529*f4d663ceSSteffen Klassert 	struct crypto_report_hash rhash;
530*f4d663ceSSteffen Klassert 	struct shash_alg *salg = __crypto_shash_alg(alg);
531*f4d663ceSSteffen Klassert 
532*f4d663ceSSteffen Klassert 	snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
533*f4d663ceSSteffen Klassert 	rhash.blocksize = alg->cra_blocksize;
534*f4d663ceSSteffen Klassert 	rhash.digestsize = salg->digestsize;
535*f4d663ceSSteffen Klassert 
536*f4d663ceSSteffen Klassert 	NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH,
537*f4d663ceSSteffen Klassert 		sizeof(struct crypto_report_hash), &rhash);
538*f4d663ceSSteffen Klassert 
539*f4d663ceSSteffen Klassert 	return 0;
540*f4d663ceSSteffen Klassert 
541*f4d663ceSSteffen Klassert nla_put_failure:
542*f4d663ceSSteffen Klassert 	return -EMSGSIZE;
543*f4d663ceSSteffen Klassert }
544*f4d663ceSSteffen Klassert 
5457b5a080bSHerbert Xu static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
5467b5a080bSHerbert Xu 	__attribute__ ((unused));
5477b5a080bSHerbert Xu static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
5487b5a080bSHerbert Xu {
5497b5a080bSHerbert Xu 	struct shash_alg *salg = __crypto_shash_alg(alg);
5507b5a080bSHerbert Xu 
5517b5a080bSHerbert Xu 	seq_printf(m, "type         : shash\n");
5527b5a080bSHerbert Xu 	seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
5537b5a080bSHerbert Xu 	seq_printf(m, "digestsize   : %u\n", salg->digestsize);
5547b5a080bSHerbert Xu }
5557b5a080bSHerbert Xu 
5567b5a080bSHerbert Xu static const struct crypto_type crypto_shash_type = {
5573b2f6df0SHerbert Xu 	.ctxsize = crypto_shash_ctxsize,
5587b5a080bSHerbert Xu 	.extsize = crypto_shash_extsize,
5593b2f6df0SHerbert Xu 	.init = crypto_init_shash_ops,
5607b5a080bSHerbert Xu 	.init_tfm = crypto_shash_init_tfm,
5617b5a080bSHerbert Xu #ifdef CONFIG_PROC_FS
5627b5a080bSHerbert Xu 	.show = crypto_shash_show,
5637b5a080bSHerbert Xu #endif
564*f4d663ceSSteffen Klassert 	.report = crypto_shash_report,
5657b5a080bSHerbert Xu 	.maskclear = ~CRYPTO_ALG_TYPE_MASK,
5667b5a080bSHerbert Xu 	.maskset = CRYPTO_ALG_TYPE_MASK,
5677b5a080bSHerbert Xu 	.type = CRYPTO_ALG_TYPE_SHASH,
5687b5a080bSHerbert Xu 	.tfmsize = offsetof(struct crypto_shash, base),
5697b5a080bSHerbert Xu };
5707b5a080bSHerbert Xu 
5717b5a080bSHerbert Xu struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
5727b5a080bSHerbert Xu 					u32 mask)
5737b5a080bSHerbert Xu {
5743f683d61SHerbert Xu 	return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask);
5757b5a080bSHerbert Xu }
5767b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_alloc_shash);
5777b5a080bSHerbert Xu 
578619a6ebdSHerbert Xu static int shash_prepare_alg(struct shash_alg *alg)
5797b5a080bSHerbert Xu {
5807b5a080bSHerbert Xu 	struct crypto_alg *base = &alg->base;
5817b5a080bSHerbert Xu 
5827b5a080bSHerbert Xu 	if (alg->digestsize > PAGE_SIZE / 8 ||
58399d27e1cSHerbert Xu 	    alg->descsize > PAGE_SIZE / 8 ||
58499d27e1cSHerbert Xu 	    alg->statesize > PAGE_SIZE / 8)
5857b5a080bSHerbert Xu 		return -EINVAL;
5867b5a080bSHerbert Xu 
5877b5a080bSHerbert Xu 	base->cra_type = &crypto_shash_type;
5887b5a080bSHerbert Xu 	base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
5897b5a080bSHerbert Xu 	base->cra_flags |= CRYPTO_ALG_TYPE_SHASH;
59099d27e1cSHerbert Xu 
5918267adabSHerbert Xu 	if (!alg->finup)
5928267adabSHerbert Xu 		alg->finup = shash_finup_unaligned;
5938267adabSHerbert Xu 	if (!alg->digest)
5948267adabSHerbert Xu 		alg->digest = shash_digest_unaligned;
595f592682fSHerbert Xu 	if (!alg->export) {
596f592682fSHerbert Xu 		alg->export = shash_default_export;
597f592682fSHerbert Xu 		alg->import = shash_default_import;
598f592682fSHerbert Xu 		alg->statesize = alg->descsize;
599f592682fSHerbert Xu 	}
60057cfe44bSHerbert Xu 	if (!alg->setkey)
60157cfe44bSHerbert Xu 		alg->setkey = shash_no_setkey;
60299d27e1cSHerbert Xu 
603619a6ebdSHerbert Xu 	return 0;
604619a6ebdSHerbert Xu }
605619a6ebdSHerbert Xu 
606619a6ebdSHerbert Xu int crypto_register_shash(struct shash_alg *alg)
607619a6ebdSHerbert Xu {
608619a6ebdSHerbert Xu 	struct crypto_alg *base = &alg->base;
609619a6ebdSHerbert Xu 	int err;
610619a6ebdSHerbert Xu 
611619a6ebdSHerbert Xu 	err = shash_prepare_alg(alg);
612619a6ebdSHerbert Xu 	if (err)
613619a6ebdSHerbert Xu 		return err;
6147b5a080bSHerbert Xu 
6157b5a080bSHerbert Xu 	return crypto_register_alg(base);
6167b5a080bSHerbert Xu }
6177b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_register_shash);
6187b5a080bSHerbert Xu 
6197b5a080bSHerbert Xu int crypto_unregister_shash(struct shash_alg *alg)
6207b5a080bSHerbert Xu {
6217b5a080bSHerbert Xu 	return crypto_unregister_alg(&alg->base);
6227b5a080bSHerbert Xu }
6237b5a080bSHerbert Xu EXPORT_SYMBOL_GPL(crypto_unregister_shash);
6247b5a080bSHerbert Xu 
625619a6ebdSHerbert Xu int shash_register_instance(struct crypto_template *tmpl,
626619a6ebdSHerbert Xu 			    struct shash_instance *inst)
627619a6ebdSHerbert Xu {
628619a6ebdSHerbert Xu 	int err;
629619a6ebdSHerbert Xu 
630619a6ebdSHerbert Xu 	err = shash_prepare_alg(&inst->alg);
631619a6ebdSHerbert Xu 	if (err)
632619a6ebdSHerbert Xu 		return err;
633619a6ebdSHerbert Xu 
634619a6ebdSHerbert Xu 	return crypto_register_instance(tmpl, shash_crypto_instance(inst));
635619a6ebdSHerbert Xu }
636619a6ebdSHerbert Xu EXPORT_SYMBOL_GPL(shash_register_instance);
637619a6ebdSHerbert Xu 
6382e4fddd8SHerbert Xu void shash_free_instance(struct crypto_instance *inst)
6392e4fddd8SHerbert Xu {
6402e4fddd8SHerbert Xu 	crypto_drop_spawn(crypto_instance_ctx(inst));
6412e4fddd8SHerbert Xu 	kfree(shash_instance(inst));
6422e4fddd8SHerbert Xu }
6432e4fddd8SHerbert Xu EXPORT_SYMBOL_GPL(shash_free_instance);
6442e4fddd8SHerbert Xu 
64594296999SHerbert Xu int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn,
64694296999SHerbert Xu 			    struct shash_alg *alg,
64794296999SHerbert Xu 			    struct crypto_instance *inst)
64894296999SHerbert Xu {
64994296999SHerbert Xu 	return crypto_init_spawn2(&spawn->base, &alg->base, inst,
65094296999SHerbert Xu 				  &crypto_shash_type);
65194296999SHerbert Xu }
65294296999SHerbert Xu EXPORT_SYMBOL_GPL(crypto_init_shash_spawn);
65394296999SHerbert Xu 
6547d6f5640SHerbert Xu struct shash_alg *shash_attr_alg(struct rtattr *rta, u32 type, u32 mask)
6557d6f5640SHerbert Xu {
6567d6f5640SHerbert Xu 	struct crypto_alg *alg;
6577d6f5640SHerbert Xu 
6587d6f5640SHerbert Xu 	alg = crypto_attr_alg2(rta, &crypto_shash_type, type, mask);
6597d6f5640SHerbert Xu 	return IS_ERR(alg) ? ERR_CAST(alg) :
6607d6f5640SHerbert Xu 	       container_of(alg, struct shash_alg, base);
6617d6f5640SHerbert Xu }
6627d6f5640SHerbert Xu EXPORT_SYMBOL_GPL(shash_attr_alg);
6637d6f5640SHerbert Xu 
6647b5a080bSHerbert Xu MODULE_LICENSE("GPL");
6657b5a080bSHerbert Xu MODULE_DESCRIPTION("Synchronous cryptographic hash type");
666