diff options
Diffstat (limited to 'crypto/shash.c')
| -rw-r--r-- | crypto/shash.c | 84 | 
1 files changed, 78 insertions, 6 deletions
diff --git a/crypto/shash.c b/crypto/shash.c index 22fd9433141..47c713954bf 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -17,6 +17,8 @@  #include <linux/module.h>  #include <linux/slab.h>  #include <linux/seq_file.h> +#include <linux/cryptouser.h> +#include <net/netlink.h>  #include "internal.h" @@ -65,7 +67,8 @@ EXPORT_SYMBOL_GPL(crypto_shash_setkey);  static inline unsigned int shash_align_buffer_size(unsigned len,  						   unsigned long mask)  { -	return len + (mask & ~(__alignof__(u8 __attribute__ ((aligned))) - 1)); +	typedef u8 __attribute__ ((aligned)) u8_aligned; +	return len + (mask & ~(__alignof__(u8_aligned) - 1));  }  static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, @@ -279,10 +282,10 @@ int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc)  	if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) {  		void *data; -		data = crypto_kmap(sg_page(sg), 0); +		data = kmap_atomic(sg_page(sg));  		err = crypto_shash_digest(desc, data + offset, nbytes,  					  req->result); -		crypto_kunmap(data, 0); +		kunmap_atomic(data);  		crypto_yield(desc->flags);  	} else  		err = crypto_shash_init(desc) ?: @@ -310,7 +313,13 @@ static int shash_async_export(struct ahash_request *req, void *out)  static int shash_async_import(struct ahash_request *req, const void *in)  { -	return crypto_shash_import(ahash_request_ctx(req), in); +	struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); +	struct shash_desc *desc = ahash_request_ctx(req); + +	desc->tfm = *ctx; +	desc->flags = req->base.flags; + +	return crypto_shash_import(desc, in);  }  static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) @@ -412,9 +421,9 @@ static int shash_compat_digest(struct hash_desc *hdesc, struct scatterlist *sg,  		desc->flags = hdesc->flags; -		data = crypto_kmap(sg_page(sg), 0); +		data = kmap_atomic(sg_page(sg));  		err = crypto_shash_digest(desc, data + offset, nbytes, out); -		crypto_kunmap(data, 0); +		kunmap_atomic(data);  		crypto_yield(desc->flags);  		goto out;  	} @@ -516,6 +525,32 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg)  	return alg->cra_ctxsize;  } +#ifdef CONFIG_NET +static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) +{ +	struct crypto_report_hash rhash; +	struct shash_alg *salg = __crypto_shash_alg(alg); + +	strncpy(rhash.type, "shash", sizeof(rhash.type)); + +	rhash.blocksize = alg->cra_blocksize; +	rhash.digestsize = salg->digestsize; + +	if (nla_put(skb, CRYPTOCFGA_REPORT_HASH, +		    sizeof(struct crypto_report_hash), &rhash)) +		goto nla_put_failure; +	return 0; + +nla_put_failure: +	return -EMSGSIZE; +} +#else +static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) +{ +	return -ENOSYS; +} +#endif +  static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)  	__attribute__ ((unused));  static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) @@ -535,6 +570,7 @@ static const struct crypto_type crypto_shash_type = {  #ifdef CONFIG_PROC_FS  	.show = crypto_shash_show,  #endif +	.report = crypto_shash_report,  	.maskclear = ~CRYPTO_ALG_TYPE_MASK,  	.maskset = CRYPTO_ALG_TYPE_MASK,  	.type = CRYPTO_ALG_TYPE_SHASH, @@ -595,6 +631,42 @@ int crypto_unregister_shash(struct shash_alg *alg)  }  EXPORT_SYMBOL_GPL(crypto_unregister_shash); +int crypto_register_shashes(struct shash_alg *algs, int count) +{ +	int i, ret; + +	for (i = 0; i < count; i++) { +		ret = crypto_register_shash(&algs[i]); +		if (ret) +			goto err; +	} + +	return 0; + +err: +	for (--i; i >= 0; --i) +		crypto_unregister_shash(&algs[i]); + +	return ret; +} +EXPORT_SYMBOL_GPL(crypto_register_shashes); + +int crypto_unregister_shashes(struct shash_alg *algs, int count) +{ +	int i, ret; + +	for (i = count - 1; i >= 0; --i) { +		ret = crypto_unregister_shash(&algs[i]); +		if (ret) +			pr_err("Failed to unregister %s %s: %d\n", +			       algs[i].base.cra_driver_name, +			       algs[i].base.cra_name, ret); +	} + +	return 0; +} +EXPORT_SYMBOL_GPL(crypto_unregister_shashes); +  int shash_register_instance(struct crypto_template *tmpl,  			    struct shash_instance *inst)  {  | 
