include/linux/ceph/messenger.h | 4 +- net/ceph/Kconfig | 3 +- net/ceph/messenger_v2.c | 77 ++++++++++------------------------ 3 files changed, 26 insertions(+), 58 deletions(-)
Use the HMAC-SHA256 library functions instead of crypto_shash. This is
simpler and faster.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
include/linux/ceph/messenger.h | 4 +-
net/ceph/Kconfig | 3 +-
net/ceph/messenger_v2.c | 77 ++++++++++------------------------
3 files changed, 26 insertions(+), 58 deletions(-)
diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h
index 1717cc57cdacd..4b49592a738fc 100644
--- a/include/linux/ceph/messenger.h
+++ b/include/linux/ceph/messenger.h
@@ -1,9 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __FS_CEPH_MESSENGER_H
#define __FS_CEPH_MESSENGER_H
+#include <crypto/sha2.h>
#include <linux/bvec.h>
#include <linux/crypto.h>
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/net.h>
@@ -410,11 +411,12 @@ struct ceph_connection_v2_info {
struct ceph_frame_desc in_desc;
struct ceph_msg_data_cursor in_cursor;
struct ceph_msg_data_cursor out_cursor;
- struct crypto_shash *hmac_tfm; /* post-auth signature */
+ struct hmac_sha256_key hmac_key; /* post-auth signature */
+ bool hmac_key_set;
struct crypto_aead *gcm_tfm; /* on-wire encryption */
struct aead_request *gcm_req;
struct crypto_wait gcm_wait;
struct ceph_gcm_nonce in_gcm_nonce;
struct ceph_gcm_nonce out_gcm_nonce;
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index 0aa21fcbf6ece..ea60e3ef08343 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -4,12 +4,11 @@ config CEPH_LIB
depends on INET
select CRC32
select CRYPTO_AES
select CRYPTO_CBC
select CRYPTO_GCM
- select CRYPTO_HMAC
- select CRYPTO_SHA256
+ select CRYPTO_LIB_SHA256
select CRYPTO
select KEYS
default n
help
Choose Y or M here to include cephlib, which provides the
diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c
index 5483b4eed94e1..c54c8b5a65261 100644
--- a/net/ceph/messenger_v2.c
+++ b/net/ceph/messenger_v2.c
@@ -707,11 +707,11 @@ static int setup_crypto(struct ceph_connection *con,
unsigned int noio_flag;
int ret;
dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n",
__func__, con, con->v2.con_mode, session_key_len, con_secret_len);
- WARN_ON(con->v2.hmac_tfm || con->v2.gcm_tfm || con->v2.gcm_req);
+ WARN_ON(con->v2.hmac_key_set || con->v2.gcm_tfm || con->v2.gcm_req);
if (con->v2.con_mode != CEPH_CON_MODE_CRC &&
con->v2.con_mode != CEPH_CON_MODE_SECURE) {
pr_err("bad con_mode %d\n", con->v2.con_mode);
return -EINVAL;
@@ -721,26 +721,12 @@ static int setup_crypto(struct ceph_connection *con,
WARN_ON(con->v2.con_mode != CEPH_CON_MODE_CRC);
WARN_ON(con_secret_len);
return 0; /* auth_none */
}
- noio_flag = memalloc_noio_save();
- con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
- memalloc_noio_restore(noio_flag);
- if (IS_ERR(con->v2.hmac_tfm)) {
- ret = PTR_ERR(con->v2.hmac_tfm);
- con->v2.hmac_tfm = NULL;
- pr_err("failed to allocate hmac tfm context: %d\n", ret);
- return ret;
- }
-
- ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key,
- session_key_len);
- if (ret) {
- pr_err("failed to set hmac key: %d\n", ret);
- return ret;
- }
+ hmac_sha256_preparekey(&con->v2.hmac_key, session_key, session_key_len);
+ con->v2.hmac_key_set = true;
if (con->v2.con_mode == CEPH_CON_MODE_CRC) {
WARN_ON(con_secret_len);
return 0; /* auth_x, plain mode */
}
@@ -791,42 +777,30 @@ static int setup_crypto(struct ceph_connection *con,
con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN,
CEPH_GCM_IV_LEN);
return 0; /* auth_x, secure mode */
}
-static int ceph_hmac_sha256(struct ceph_connection *con,
- const struct kvec *kvecs, int kvec_cnt, u8 *hmac)
+static void ceph_hmac_sha256(struct ceph_connection *con,
+ const struct kvec *kvecs, int kvec_cnt,
+ u8 hmac[SHA256_DIGEST_SIZE])
{
- SHASH_DESC_ON_STACK(desc, con->v2.hmac_tfm); /* tfm arg is ignored */
- int ret;
+ struct hmac_sha256_ctx ctx;
int i;
- dout("%s con %p hmac_tfm %p kvec_cnt %d\n", __func__, con,
- con->v2.hmac_tfm, kvec_cnt);
+ dout("%s con %p hmac_key_set %d kvec_cnt %d\n", __func__, con,
+ con->v2.hmac_key_set, kvec_cnt);
- if (!con->v2.hmac_tfm) {
+ if (!con->v2.hmac_key_set) {
memset(hmac, 0, SHA256_DIGEST_SIZE);
- return 0; /* auth_none */
+ return; /* auth_none */
}
- desc->tfm = con->v2.hmac_tfm;
- ret = crypto_shash_init(desc);
- if (ret)
- goto out;
-
- for (i = 0; i < kvec_cnt; i++) {
- ret = crypto_shash_update(desc, kvecs[i].iov_base,
- kvecs[i].iov_len);
- if (ret)
- goto out;
- }
-
- ret = crypto_shash_final(desc, hmac);
-
-out:
- shash_desc_zero(desc);
- return ret; /* auth_x, both plain and secure modes */
+ /* auth_x, both plain and secure modes */
+ hmac_sha256_init(&ctx, &con->v2.hmac_key);
+ for (i = 0; i < kvec_cnt; i++)
+ hmac_sha256_update(&ctx, kvecs[i].iov_base, kvecs[i].iov_len);
+ hmac_sha256_final(&ctx, hmac);
}
static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce)
{
u64 counter;
@@ -1453,21 +1427,18 @@ static int prepare_auth_request_more(struct ceph_connection *con,
}
static int prepare_auth_signature(struct ceph_connection *con)
{
void *buf;
- int ret;
buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE,
con_secure(con)));
if (!buf)
return -ENOMEM;
- ret = ceph_hmac_sha256(con, con->v2.in_sign_kvecs,
- con->v2.in_sign_kvec_cnt, CTRL_BODY(buf));
- if (ret)
- return ret;
+ ceph_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt,
+ CTRL_BODY(buf));
return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf,
SHA256_DIGEST_SIZE);
}
@@ -2458,14 +2429,12 @@ static int process_auth_signature(struct ceph_connection *con,
if (con->state != CEPH_CON_S_V2_AUTH_SIGNATURE) {
con->error_msg = "protocol error, unexpected auth_signature";
return -EINVAL;
}
- ret = ceph_hmac_sha256(con, con->v2.out_sign_kvecs,
- con->v2.out_sign_kvec_cnt, hmac);
- if (ret)
- return ret;
+ ceph_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt,
+ hmac);
ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad);
if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) {
con->error_msg = "integrity error, bad auth signature";
return -EBADMSG;
@@ -3812,14 +3781,12 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con)
con->v2.con_mode = CEPH_CON_MODE_UNKNOWN;
memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN);
memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN);
- if (con->v2.hmac_tfm) {
- crypto_free_shash(con->v2.hmac_tfm);
- con->v2.hmac_tfm = NULL;
- }
+ memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key));
+ con->v2.hmac_key_set = false;
if (con->v2.gcm_req) {
aead_request_free(con->v2.gcm_req);
con->v2.gcm_req = NULL;
}
if (con->v2.gcm_tfm) {
base-commit: d6084bb815c453de27af8071a23163a711586a6c
--
2.50.1
On Thu, Jul 31, 2025 at 9:03 PM Eric Biggers <ebiggers@kernel.org> wrote: > > Use the HMAC-SHA256 library functions instead of crypto_shash. This is > simpler and faster. > > Signed-off-by: Eric Biggers <ebiggers@kernel.org> > --- > include/linux/ceph/messenger.h | 4 +- > net/ceph/Kconfig | 3 +- > net/ceph/messenger_v2.c | 77 ++++++++++------------------------ > 3 files changed, 26 insertions(+), 58 deletions(-) > > diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h > index 1717cc57cdacd..4b49592a738fc 100644 > --- a/include/linux/ceph/messenger.h > +++ b/include/linux/ceph/messenger.h > @@ -1,9 +1,10 @@ > /* SPDX-License-Identifier: GPL-2.0 */ > #ifndef __FS_CEPH_MESSENGER_H > #define __FS_CEPH_MESSENGER_H > > +#include <crypto/sha2.h> > #include <linux/bvec.h> > #include <linux/crypto.h> > #include <linux/kref.h> > #include <linux/mutex.h> > #include <linux/net.h> > @@ -410,11 +411,12 @@ struct ceph_connection_v2_info { > > struct ceph_frame_desc in_desc; > struct ceph_msg_data_cursor in_cursor; > struct ceph_msg_data_cursor out_cursor; > > - struct crypto_shash *hmac_tfm; /* post-auth signature */ > + struct hmac_sha256_key hmac_key; /* post-auth signature */ > + bool hmac_key_set; > struct crypto_aead *gcm_tfm; /* on-wire encryption */ > struct aead_request *gcm_req; > struct crypto_wait gcm_wait; > struct ceph_gcm_nonce in_gcm_nonce; > struct ceph_gcm_nonce out_gcm_nonce; > diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig > index 0aa21fcbf6ece..ea60e3ef08343 100644 > --- a/net/ceph/Kconfig > +++ b/net/ceph/Kconfig > @@ -4,12 +4,11 @@ config CEPH_LIB > depends on INET > select CRC32 > select CRYPTO_AES > select CRYPTO_CBC > select CRYPTO_GCM > - select CRYPTO_HMAC > - select CRYPTO_SHA256 > + select CRYPTO_LIB_SHA256 > select CRYPTO > select KEYS > default n > help > Choose Y or M here to include cephlib, which provides the > diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c > index 5483b4eed94e1..c54c8b5a65261 100644 > --- a/net/ceph/messenger_v2.c > +++ b/net/ceph/messenger_v2.c > @@ -707,11 +707,11 @@ static int setup_crypto(struct ceph_connection *con, > unsigned int noio_flag; > int ret; > > dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n", > __func__, con, con->v2.con_mode, session_key_len, con_secret_len); > - WARN_ON(con->v2.hmac_tfm || con->v2.gcm_tfm || con->v2.gcm_req); > + WARN_ON(con->v2.hmac_key_set || con->v2.gcm_tfm || con->v2.gcm_req); > > if (con->v2.con_mode != CEPH_CON_MODE_CRC && > con->v2.con_mode != CEPH_CON_MODE_SECURE) { > pr_err("bad con_mode %d\n", con->v2.con_mode); > return -EINVAL; > @@ -721,26 +721,12 @@ static int setup_crypto(struct ceph_connection *con, > WARN_ON(con->v2.con_mode != CEPH_CON_MODE_CRC); > WARN_ON(con_secret_len); > return 0; /* auth_none */ > } > > - noio_flag = memalloc_noio_save(); > - con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); > - memalloc_noio_restore(noio_flag); > - if (IS_ERR(con->v2.hmac_tfm)) { > - ret = PTR_ERR(con->v2.hmac_tfm); > - con->v2.hmac_tfm = NULL; > - pr_err("failed to allocate hmac tfm context: %d\n", ret); > - return ret; > - } > - > - ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key, > - session_key_len); > - if (ret) { > - pr_err("failed to set hmac key: %d\n", ret); > - return ret; > - } > + hmac_sha256_preparekey(&con->v2.hmac_key, session_key, session_key_len); > + con->v2.hmac_key_set = true; > > if (con->v2.con_mode == CEPH_CON_MODE_CRC) { > WARN_ON(con_secret_len); > return 0; /* auth_x, plain mode */ > } > @@ -791,42 +777,30 @@ static int setup_crypto(struct ceph_connection *con, > con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN, > CEPH_GCM_IV_LEN); > return 0; /* auth_x, secure mode */ > } > > -static int ceph_hmac_sha256(struct ceph_connection *con, > - const struct kvec *kvecs, int kvec_cnt, u8 *hmac) > +static void ceph_hmac_sha256(struct ceph_connection *con, > + const struct kvec *kvecs, int kvec_cnt, > + u8 hmac[SHA256_DIGEST_SIZE]) > { > - SHASH_DESC_ON_STACK(desc, con->v2.hmac_tfm); /* tfm arg is ignored */ > - int ret; > + struct hmac_sha256_ctx ctx; > int i; > > - dout("%s con %p hmac_tfm %p kvec_cnt %d\n", __func__, con, > - con->v2.hmac_tfm, kvec_cnt); > + dout("%s con %p hmac_key_set %d kvec_cnt %d\n", __func__, con, > + con->v2.hmac_key_set, kvec_cnt); > > - if (!con->v2.hmac_tfm) { > + if (!con->v2.hmac_key_set) { > memset(hmac, 0, SHA256_DIGEST_SIZE); > - return 0; /* auth_none */ > + return; /* auth_none */ > } > > - desc->tfm = con->v2.hmac_tfm; > - ret = crypto_shash_init(desc); > - if (ret) > - goto out; > - > - for (i = 0; i < kvec_cnt; i++) { > - ret = crypto_shash_update(desc, kvecs[i].iov_base, > - kvecs[i].iov_len); > - if (ret) > - goto out; > - } > - > - ret = crypto_shash_final(desc, hmac); > - > -out: > - shash_desc_zero(desc); > - return ret; /* auth_x, both plain and secure modes */ > + /* auth_x, both plain and secure modes */ > + hmac_sha256_init(&ctx, &con->v2.hmac_key); > + for (i = 0; i < kvec_cnt; i++) > + hmac_sha256_update(&ctx, kvecs[i].iov_base, kvecs[i].iov_len); > + hmac_sha256_final(&ctx, hmac); > } > > static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce) > { > u64 counter; > @@ -1453,21 +1427,18 @@ static int prepare_auth_request_more(struct ceph_connection *con, > } > > static int prepare_auth_signature(struct ceph_connection *con) > { > void *buf; > - int ret; > > buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE, > con_secure(con))); > if (!buf) > return -ENOMEM; > > - ret = ceph_hmac_sha256(con, con->v2.in_sign_kvecs, > - con->v2.in_sign_kvec_cnt, CTRL_BODY(buf)); > - if (ret) > - return ret; > + ceph_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt, > + CTRL_BODY(buf)); > > return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf, > SHA256_DIGEST_SIZE); > } > > @@ -2458,14 +2429,12 @@ static int process_auth_signature(struct ceph_connection *con, > if (con->state != CEPH_CON_S_V2_AUTH_SIGNATURE) { > con->error_msg = "protocol error, unexpected auth_signature"; > return -EINVAL; > } > > - ret = ceph_hmac_sha256(con, con->v2.out_sign_kvecs, > - con->v2.out_sign_kvec_cnt, hmac); > - if (ret) > - return ret; > + ceph_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt, > + hmac); > > ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad); > if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) { > con->error_msg = "integrity error, bad auth signature"; > return -EBADMSG; > @@ -3812,14 +3781,12 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con) > > con->v2.con_mode = CEPH_CON_MODE_UNKNOWN; > memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN); > memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN); > > - if (con->v2.hmac_tfm) { > - crypto_free_shash(con->v2.hmac_tfm); > - con->v2.hmac_tfm = NULL; > - } > + memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key)); > + con->v2.hmac_key_set = false; Hi Eric, Since we have hmac_key_set anyway, could the call to memzero_explicit() be conditioned on it? Thanks, Ilya
On Thu, Sep 04, 2025 at 12:24:08PM +0200, Ilya Dryomov wrote: > > - if (con->v2.hmac_tfm) { > > - crypto_free_shash(con->v2.hmac_tfm); > > - con->v2.hmac_tfm = NULL; > > - } > > + memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key)); > > + con->v2.hmac_key_set = false; > > Hi Eric, > > Since we have hmac_key_set anyway, could the call to memzero_explicit() > be conditioned on it? If you want. It's less code to just do it unconditionally. - Eric
On Thu, Sep 4, 2025 at 7:26 PM Eric Biggers <ebiggers@kernel.org> wrote: > > On Thu, Sep 04, 2025 at 12:24:08PM +0200, Ilya Dryomov wrote: > > > - if (con->v2.hmac_tfm) { > > > - crypto_free_shash(con->v2.hmac_tfm); > > > - con->v2.hmac_tfm = NULL; > > > - } > > > + memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key)); > > > + con->v2.hmac_key_set = false; > > > > Hi Eric, > > > > Since we have hmac_key_set anyway, could the call to memzero_explicit() > > be conditioned on it? > > If you want. It's less code to just do it unconditionally. Double checking the surrounding code, the only case where hmac_key_set would remain false is auth_none protocol (i.e. no authentication at the Ceph level at all). This is extremely rare, so I'm leaving the patch as is. Thanks, Ilya
On Thu, Jul 31, 2025 at 12:02:27PM -0700, Eric Biggers wrote: > Use the HMAC-SHA256 library functions instead of crypto_shash. This is > simpler and faster. > > Signed-off-by: Eric Biggers <ebiggers@kernel.org> > --- > include/linux/ceph/messenger.h | 4 +- > net/ceph/Kconfig | 3 +- > net/ceph/messenger_v2.c | 77 ++++++++++------------------------ > 3 files changed, 26 insertions(+), 58 deletions(-) Looks like this patch hasn't been applied yet. Can it be taken through the ceph tree? Thanks, - Eric
On Thu, Sep 4, 2025 at 4:32 AM Eric Biggers <ebiggers@kernel.org> wrote: > > On Thu, Jul 31, 2025 at 12:02:27PM -0700, Eric Biggers wrote: > > Use the HMAC-SHA256 library functions instead of crypto_shash. This is > > simpler and faster. > > > > Signed-off-by: Eric Biggers <ebiggers@kernel.org> > > --- > > include/linux/ceph/messenger.h | 4 +- > > net/ceph/Kconfig | 3 +- > > net/ceph/messenger_v2.c | 77 ++++++++++------------------------ > > 3 files changed, 26 insertions(+), 58 deletions(-) > > Looks like this patch hasn't been applied yet. Can it be taken through > the ceph tree? Thanks, Hi Eric, I have just posted a small nit/question on the patch itself. If you agree, I can make the edit and stage the patch later today. Thanks, Ilya
On Thu, 2025-07-31 at 12:02 -0700, Eric Biggers wrote: > Use the HMAC-SHA256 library functions instead of crypto_shash. This is > simpler and faster. > Looks good and much cleaner. Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Thanks, Slava. > Signed-off-by: Eric Biggers <ebiggers@kernel.org> > --- > include/linux/ceph/messenger.h | 4 +- > net/ceph/Kconfig | 3 +- > net/ceph/messenger_v2.c | 77 ++++++++++------------------------ > 3 files changed, 26 insertions(+), 58 deletions(-) > > diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h > index 1717cc57cdacd..4b49592a738fc 100644 > --- a/include/linux/ceph/messenger.h > +++ b/include/linux/ceph/messenger.h > @@ -1,9 +1,10 @@ > /* SPDX-License-Identifier: GPL-2.0 */ > #ifndef __FS_CEPH_MESSENGER_H > #define __FS_CEPH_MESSENGER_H > > +#include <crypto/sha2.h> > #include <linux/bvec.h> > #include <linux/crypto.h> > #include <linux/kref.h> > #include <linux/mutex.h> > #include <linux/net.h> > @@ -410,11 +411,12 @@ struct ceph_connection_v2_info { > > struct ceph_frame_desc in_desc; > struct ceph_msg_data_cursor in_cursor; > struct ceph_msg_data_cursor out_cursor; > > - struct crypto_shash *hmac_tfm; /* post-auth signature */ > + struct hmac_sha256_key hmac_key; /* post-auth signature */ > + bool hmac_key_set; > struct crypto_aead *gcm_tfm; /* on-wire encryption */ > struct aead_request *gcm_req; > struct crypto_wait gcm_wait; > struct ceph_gcm_nonce in_gcm_nonce; > struct ceph_gcm_nonce out_gcm_nonce; > diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig > index 0aa21fcbf6ece..ea60e3ef08343 100644 > --- a/net/ceph/Kconfig > +++ b/net/ceph/Kconfig > @@ -4,12 +4,11 @@ config CEPH_LIB > depends on INET > select CRC32 > select CRYPTO_AES > select CRYPTO_CBC > select CRYPTO_GCM > - select CRYPTO_HMAC > - select CRYPTO_SHA256 > + select CRYPTO_LIB_SHA256 > select CRYPTO > select KEYS > default n > help > Choose Y or M here to include cephlib, which provides the > diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c > index 5483b4eed94e1..c54c8b5a65261 100644 > --- a/net/ceph/messenger_v2.c > +++ b/net/ceph/messenger_v2.c > @@ -707,11 +707,11 @@ static int setup_crypto(struct ceph_connection *con, > unsigned int noio_flag; > int ret; > > dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n", > __func__, con, con->v2.con_mode, session_key_len, con_secret_len); > - WARN_ON(con->v2.hmac_tfm || con->v2.gcm_tfm || con->v2.gcm_req); > + WARN_ON(con->v2.hmac_key_set || con->v2.gcm_tfm || con->v2.gcm_req); > > if (con->v2.con_mode != CEPH_CON_MODE_CRC && > con->v2.con_mode != CEPH_CON_MODE_SECURE) { > pr_err("bad con_mode %d\n", con->v2.con_mode); > return -EINVAL; > @@ -721,26 +721,12 @@ static int setup_crypto(struct ceph_connection *con, > WARN_ON(con->v2.con_mode != CEPH_CON_MODE_CRC); > WARN_ON(con_secret_len); > return 0; /* auth_none */ > } > > - noio_flag = memalloc_noio_save(); > - con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); > - memalloc_noio_restore(noio_flag); > - if (IS_ERR(con->v2.hmac_tfm)) { > - ret = PTR_ERR(con->v2.hmac_tfm); > - con->v2.hmac_tfm = NULL; > - pr_err("failed to allocate hmac tfm context: %d\n", ret); > - return ret; > - } > - > - ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key, > - session_key_len); > - if (ret) { > - pr_err("failed to set hmac key: %d\n", ret); > - return ret; > - } > + hmac_sha256_preparekey(&con->v2.hmac_key, session_key, session_key_len); > + con->v2.hmac_key_set = true; > > if (con->v2.con_mode == CEPH_CON_MODE_CRC) { > WARN_ON(con_secret_len); > return 0; /* auth_x, plain mode */ > } > @@ -791,42 +777,30 @@ static int setup_crypto(struct ceph_connection *con, > con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN, > CEPH_GCM_IV_LEN); > return 0; /* auth_x, secure mode */ > } > > -static int ceph_hmac_sha256(struct ceph_connection *con, > - const struct kvec *kvecs, int kvec_cnt, u8 *hmac) > +static void ceph_hmac_sha256(struct ceph_connection *con, > + const struct kvec *kvecs, int kvec_cnt, > + u8 hmac[SHA256_DIGEST_SIZE]) > { > - SHASH_DESC_ON_STACK(desc, con->v2.hmac_tfm); /* tfm arg is ignored */ > - int ret; > + struct hmac_sha256_ctx ctx; > int i; > > - dout("%s con %p hmac_tfm %p kvec_cnt %d\n", __func__, con, > - con->v2.hmac_tfm, kvec_cnt); > + dout("%s con %p hmac_key_set %d kvec_cnt %d\n", __func__, con, > + con->v2.hmac_key_set, kvec_cnt); > > - if (!con->v2.hmac_tfm) { > + if (!con->v2.hmac_key_set) { > memset(hmac, 0, SHA256_DIGEST_SIZE); > - return 0; /* auth_none */ > + return; /* auth_none */ > } > > - desc->tfm = con->v2.hmac_tfm; > - ret = crypto_shash_init(desc); > - if (ret) > - goto out; > - > - for (i = 0; i < kvec_cnt; i++) { > - ret = crypto_shash_update(desc, kvecs[i].iov_base, > - kvecs[i].iov_len); > - if (ret) > - goto out; > - } > - > - ret = crypto_shash_final(desc, hmac); > - > -out: > - shash_desc_zero(desc); > - return ret; /* auth_x, both plain and secure modes */ > + /* auth_x, both plain and secure modes */ > + hmac_sha256_init(&ctx, &con->v2.hmac_key); > + for (i = 0; i < kvec_cnt; i++) > + hmac_sha256_update(&ctx, kvecs[i].iov_base, kvecs[i].iov_len); > + hmac_sha256_final(&ctx, hmac); > } > > static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce) > { > u64 counter; > @@ -1453,21 +1427,18 @@ static int prepare_auth_request_more(struct ceph_connection *con, > } > > static int prepare_auth_signature(struct ceph_connection *con) > { > void *buf; > - int ret; > > buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE, > con_secure(con))); > if (!buf) > return -ENOMEM; > > - ret = ceph_hmac_sha256(con, con->v2.in_sign_kvecs, > - con->v2.in_sign_kvec_cnt, CTRL_BODY(buf)); > - if (ret) > - return ret; > + ceph_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt, > + CTRL_BODY(buf)); > > return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf, > SHA256_DIGEST_SIZE); > } > > @@ -2458,14 +2429,12 @@ static int process_auth_signature(struct ceph_connection *con, > if (con->state != CEPH_CON_S_V2_AUTH_SIGNATURE) { > con->error_msg = "protocol error, unexpected auth_signature"; > return -EINVAL; > } > > - ret = ceph_hmac_sha256(con, con->v2.out_sign_kvecs, > - con->v2.out_sign_kvec_cnt, hmac); > - if (ret) > - return ret; > + ceph_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt, > + hmac); > > ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad); > if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) { > con->error_msg = "integrity error, bad auth signature"; > return -EBADMSG; > @@ -3812,14 +3781,12 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con) > > con->v2.con_mode = CEPH_CON_MODE_UNKNOWN; > memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN); > memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN); > > - if (con->v2.hmac_tfm) { > - crypto_free_shash(con->v2.hmac_tfm); > - con->v2.hmac_tfm = NULL; > - } > + memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key)); > + con->v2.hmac_key_set = false; > if (con->v2.gcm_req) { > aead_request_free(con->v2.gcm_req); > con->v2.gcm_req = NULL; > } > if (con->v2.gcm_tfm) { > > base-commit: d6084bb815c453de27af8071a23163a711586a6c
© 2016 - 2025 Red Hat, Inc.