1
0
Fork 0

staging: lustre: Use ahash

This patch replaces uses of the long obsolete hash interface with
ahash.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
hifive-unleashed-5.1
Herbert Xu 2016-02-01 21:36:53 +08:00
parent d12481bc58
commit 6dae10001e
1 changed files with 52 additions and 40 deletions

View File

@ -27,7 +27,7 @@
* Copyright (c) 2012, Intel Corporation. * Copyright (c) 2012, Intel Corporation.
*/ */
#include <linux/crypto.h> #include <crypto/hash.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include "../../../include/linux/libcfs/libcfs.h" #include "../../../include/linux/libcfs/libcfs.h"
#include "linux-crypto.h" #include "linux-crypto.h"
@ -38,9 +38,11 @@ static int cfs_crypto_hash_speeds[CFS_HASH_ALG_MAX];
static int cfs_crypto_hash_alloc(unsigned char alg_id, static int cfs_crypto_hash_alloc(unsigned char alg_id,
const struct cfs_crypto_hash_type **type, const struct cfs_crypto_hash_type **type,
struct hash_desc *desc, unsigned char *key, struct ahash_request **req,
unsigned char *key,
unsigned int key_len) unsigned int key_len)
{ {
struct crypto_ahash *tfm;
int err = 0; int err = 0;
*type = cfs_crypto_hash_type(alg_id); *type = cfs_crypto_hash_type(alg_id);
@ -50,18 +52,23 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id,
alg_id, CFS_HASH_ALG_MAX); alg_id, CFS_HASH_ALG_MAX);
return -EINVAL; return -EINVAL;
} }
desc->tfm = crypto_alloc_hash((*type)->cht_name, 0, 0); tfm = crypto_alloc_ahash((*type)->cht_name, 0, CRYPTO_ALG_ASYNC);
if (desc->tfm == NULL) if (IS_ERR(tfm)) {
return -EINVAL;
if (IS_ERR(desc->tfm)) {
CDEBUG(D_INFO, "Failed to alloc crypto hash %s\n", CDEBUG(D_INFO, "Failed to alloc crypto hash %s\n",
(*type)->cht_name); (*type)->cht_name);
return PTR_ERR(desc->tfm); return PTR_ERR(tfm);
} }
desc->flags = 0; *req = ahash_request_alloc(tfm, GFP_KERNEL);
if (!*req) {
CDEBUG(D_INFO, "Failed to alloc ahash_request for %s\n",
(*type)->cht_name);
crypto_free_ahash(tfm);
return -ENOMEM;
}
ahash_request_set_callback(*req, 0, NULL, NULL);
/** Shash have different logic for initialization then digest /** Shash have different logic for initialization then digest
* shash: crypto_hash_setkey, crypto_hash_init * shash: crypto_hash_setkey, crypto_hash_init
@ -70,23 +77,27 @@ static int cfs_crypto_hash_alloc(unsigned char alg_id,
* cfs_crypto_hash_alloc. * cfs_crypto_hash_alloc.
*/ */
if (key != NULL) if (key != NULL)
err = crypto_hash_setkey(desc->tfm, key, key_len); err = crypto_ahash_setkey(tfm, key, key_len);
else if ((*type)->cht_key != 0) else if ((*type)->cht_key != 0)
err = crypto_hash_setkey(desc->tfm, err = crypto_ahash_setkey(tfm,
(unsigned char *)&((*type)->cht_key), (unsigned char *)&((*type)->cht_key),
(*type)->cht_size); (*type)->cht_size);
if (err != 0) { if (err != 0) {
crypto_free_hash(desc->tfm); crypto_free_ahash(tfm);
return err; return err;
} }
CDEBUG(D_INFO, "Using crypto hash: %s (%s) speed %d MB/s\n", CDEBUG(D_INFO, "Using crypto hash: %s (%s) speed %d MB/s\n",
(crypto_hash_tfm(desc->tfm))->__crt_alg->cra_name, crypto_ahash_alg_name(tfm), crypto_ahash_driver_name(tfm),
(crypto_hash_tfm(desc->tfm))->__crt_alg->cra_driver_name,
cfs_crypto_hash_speeds[alg_id]); cfs_crypto_hash_speeds[alg_id]);
return crypto_hash_init(desc); err = crypto_ahash_init(*req);
if (err) {
ahash_request_free(*req);
crypto_free_ahash(tfm);
}
return err;
} }
int cfs_crypto_hash_digest(unsigned char alg_id, int cfs_crypto_hash_digest(unsigned char alg_id,
@ -95,27 +106,29 @@ int cfs_crypto_hash_digest(unsigned char alg_id,
unsigned char *hash, unsigned int *hash_len) unsigned char *hash, unsigned int *hash_len)
{ {
struct scatterlist sl; struct scatterlist sl;
struct hash_desc hdesc; struct ahash_request *req;
int err; int err;
const struct cfs_crypto_hash_type *type; const struct cfs_crypto_hash_type *type;
if (buf == NULL || buf_len == 0 || hash_len == NULL) if (buf == NULL || buf_len == 0 || hash_len == NULL)
return -EINVAL; return -EINVAL;
err = cfs_crypto_hash_alloc(alg_id, &type, &hdesc, key, key_len); err = cfs_crypto_hash_alloc(alg_id, &type, &req, key, key_len);
if (err != 0) if (err != 0)
return err; return err;
if (hash == NULL || *hash_len < type->cht_size) { if (hash == NULL || *hash_len < type->cht_size) {
*hash_len = type->cht_size; *hash_len = type->cht_size;
crypto_free_hash(hdesc.tfm); crypto_free_ahash(crypto_ahash_reqtfm(req));
ahash_request_free(req);
return -ENOSPC; return -ENOSPC;
} }
sg_init_one(&sl, buf, buf_len); sg_init_one(&sl, buf, buf_len);
hdesc.flags = 0; ahash_request_set_crypt(req, &sl, hash, sl.length);
err = crypto_hash_digest(&hdesc, &sl, sl.length, hash); err = crypto_ahash_digest(req);
crypto_free_hash(hdesc.tfm); crypto_free_ahash(crypto_ahash_reqtfm(req));
ahash_request_free(req);
return err; return err;
} }
@ -125,22 +138,15 @@ struct cfs_crypto_hash_desc *
cfs_crypto_hash_init(unsigned char alg_id, cfs_crypto_hash_init(unsigned char alg_id,
unsigned char *key, unsigned int key_len) unsigned char *key, unsigned int key_len)
{ {
struct ahash_request *req;
struct hash_desc *hdesc;
int err; int err;
const struct cfs_crypto_hash_type *type; const struct cfs_crypto_hash_type *type;
hdesc = kmalloc(sizeof(*hdesc), 0); err = cfs_crypto_hash_alloc(alg_id, &type, &req, key, key_len);
if (hdesc == NULL)
return ERR_PTR(-ENOMEM);
err = cfs_crypto_hash_alloc(alg_id, &type, hdesc, key, key_len); if (err)
if (err) {
kfree(hdesc);
return ERR_PTR(err); return ERR_PTR(err);
} return (struct cfs_crypto_hash_desc *)req;
return (struct cfs_crypto_hash_desc *)hdesc;
} }
EXPORT_SYMBOL(cfs_crypto_hash_init); EXPORT_SYMBOL(cfs_crypto_hash_init);
@ -148,23 +154,27 @@ int cfs_crypto_hash_update_page(struct cfs_crypto_hash_desc *hdesc,
struct page *page, unsigned int offset, struct page *page, unsigned int offset,
unsigned int len) unsigned int len)
{ {
struct ahash_request *req = (void *)hdesc;
struct scatterlist sl; struct scatterlist sl;
sg_init_table(&sl, 1); sg_init_table(&sl, 1);
sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK); sg_set_page(&sl, page, len, offset & ~CFS_PAGE_MASK);
return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); ahash_request_set_crypt(req, &sl, NULL, sl.length);
return crypto_ahash_update(req);
} }
EXPORT_SYMBOL(cfs_crypto_hash_update_page); EXPORT_SYMBOL(cfs_crypto_hash_update_page);
int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc, int cfs_crypto_hash_update(struct cfs_crypto_hash_desc *hdesc,
const void *buf, unsigned int buf_len) const void *buf, unsigned int buf_len)
{ {
struct ahash_request *req = (void *)hdesc;
struct scatterlist sl; struct scatterlist sl;
sg_init_one(&sl, buf, buf_len); sg_init_one(&sl, buf, buf_len);
return crypto_hash_update((struct hash_desc *)hdesc, &sl, sl.length); ahash_request_set_crypt(req, &sl, NULL, sl.length);
return crypto_ahash_update(req);
} }
EXPORT_SYMBOL(cfs_crypto_hash_update); EXPORT_SYMBOL(cfs_crypto_hash_update);
@ -173,25 +183,27 @@ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc,
unsigned char *hash, unsigned int *hash_len) unsigned char *hash, unsigned int *hash_len)
{ {
int err; int err;
int size = crypto_hash_digestsize(((struct hash_desc *)hdesc)->tfm); struct ahash_request *req = (void *)hdesc;
int size = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
if (hash_len == NULL) { if (hash_len == NULL) {
crypto_free_hash(((struct hash_desc *)hdesc)->tfm); crypto_free_ahash(crypto_ahash_reqtfm(req));
kfree(hdesc); ahash_request_free(req);
return 0; return 0;
} }
if (hash == NULL || *hash_len < size) { if (hash == NULL || *hash_len < size) {
*hash_len = size; *hash_len = size;
return -ENOSPC; return -ENOSPC;
} }
err = crypto_hash_final((struct hash_desc *) hdesc, hash); ahash_request_set_crypt(req, NULL, hash, 0);
err = crypto_ahash_final(req);
if (err < 0) { if (err < 0) {
/* May be caller can fix error */ /* May be caller can fix error */
return err; return err;
} }
crypto_free_hash(((struct hash_desc *)hdesc)->tfm); crypto_free_ahash(crypto_ahash_reqtfm(req));
kfree(hdesc); ahash_request_free(req);
return err; return err;
} }
EXPORT_SYMBOL(cfs_crypto_hash_final); EXPORT_SYMBOL(cfs_crypto_hash_final);