From 53e967746f37d5f0322bfc984af3ce1c9517079b Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 30 Nov 2017 11:06:42 -0500 Subject: [PATCH] LU-8602 libcfs: call proper crypto algo when keys are passed in In most cases keys are not passed to cfs_crypto_hash_alloc() but if they are then crypto_ahash_setkey() will fail. Keys are only handled by the hmac version of the algorithm requested. If a key is passed into cfs_crypto_hash_alloc() then we should request the hmac version of the algorithm when calling crypto_alloc_ahash(). Change-Id: I080d89bc864b236524ef11f50df41b750ecab9fe Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/25199 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Sebastien Buisson Reviewed-by: Alexandr Boyko Reviewed-by: Oleg Drokin --- libcfs/libcfs/linux/linux-crypto.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/libcfs/libcfs/linux/linux-crypto.c b/libcfs/libcfs/linux/linux-crypto.c index 1991a86..ab80142 100644 --- a/libcfs/libcfs/linux/linux-crypto.c +++ b/libcfs/libcfs/linux/linux-crypto.c @@ -77,13 +77,27 @@ static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg, int err = 0; *type = cfs_crypto_hash_type(hash_alg); - - if (*type == NULL) { + if (!*type) { CWARN("Unsupported hash algorithm id = %d, max id is %d\n", hash_alg, CFS_HASH_ALG_MAX); return -EINVAL; } - tfm = crypto_alloc_ahash((*type)->cht_name, 0, CRYPTO_ALG_ASYNC); + + /* Keys are only supported for the hmac version */ + if (key && key_len > 0) { + char *algo_name; + + algo_name = kasprintf(GFP_KERNEL, "hmac(%s)", + (*type)->cht_name); + if (!algo_name) + return -ENOMEM; + + tfm = crypto_alloc_ahash(algo_name, 0, CRYPTO_ALG_ASYNC); + kfree(algo_name); + } else { + tfm = crypto_alloc_ahash((*type)->cht_name, 0, + CRYPTO_ALG_ASYNC); + } if (IS_ERR(tfm)) { CDEBUG(D_INFO, "Failed to alloc crypto hash %s\n", (*type)->cht_name); @@ -94,8 +108,7 @@ static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg, if (!*req) { CDEBUG(D_INFO, "Failed to alloc ahash_request for %s\n", (*type)->cht_name); - crypto_free_ahash(tfm); - return -ENOMEM; + GOTO(out_free_tfm, err = -ENOMEM); } ahash_request_set_callback(*req, 0, NULL, NULL); @@ -106,12 +119,8 @@ static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg, err = crypto_ahash_setkey(tfm, (unsigned char *)&((*type)->cht_key), (*type)->cht_size); - - if (err != 0) { - ahash_request_free(*req); - crypto_free_ahash(tfm); - return err; - } + if (err) + GOTO(out_free_req, err); CDEBUG(D_INFO, "Using crypto hash: %s (%s) speed %d MB/s\n", crypto_ahash_alg_name(tfm), crypto_ahash_driver_name(tfm), @@ -119,7 +128,9 @@ static int cfs_crypto_hash_alloc(enum cfs_crypto_hash_alg hash_alg, err = crypto_ahash_init(*req); if (err) { +out_free_req: ahash_request_free(*req); +out_free_tfm: crypto_free_ahash(tfm); } return err; -- 1.8.3.1