[PATCH 05/18] SUNRPC: Prepare crypto/krb5 encryption and checksum handles

From: Chuck Lever

Date: Mon Apr 27 2026 - 09:55:59 EST


From: Chuck Lever <chuck.lever@xxxxxxxxxx>

Allocate crypto_aead handles for encryption (one per direction)
and crypto_shash handles for checksumming (one per direction)
using the crypto/krb5 library's key preparation functions.

These four handles derive their subkeys from the session key
and the RFC 4121 usage numbers and are ready for use in
encrypt, decrypt, get_mic, and verify_mic operations.

The existing crypto_sync_skcipher and crypto_ahash handles
remain in place for now; subsequent patches switch the
per-message operations to the new handles and then remove
the old ones.

Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---
net/sunrpc/auth_gss/gss_krb5_internal.h | 4 +++
net/sunrpc/auth_gss/gss_krb5_mech.c | 45 +++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)

diff --git a/net/sunrpc/auth_gss/gss_krb5_internal.h b/net/sunrpc/auth_gss/gss_krb5_internal.h
index a3fe4be3b9ae..33d41d972bd1 100644
--- a/net/sunrpc/auth_gss/gss_krb5_internal.h
+++ b/net/sunrpc/auth_gss/gss_krb5_internal.h
@@ -65,6 +65,10 @@ struct krb5_ctx {
u32 flags;
const struct gss_krb5_enctype *gk5e; /* enctype-specific info */
const struct krb5_enctype *krb5e; /* crypto/krb5 enctype */
+ struct crypto_aead *initiator_enc_aead;
+ struct crypto_aead *acceptor_enc_aead;
+ struct crypto_shash *initiator_sign_shash;
+ struct crypto_shash *acceptor_sign_shash;
struct crypto_sync_skcipher *enc;
struct crypto_sync_skcipher *seq;
struct crypto_sync_skcipher *acceptor_enc;
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 7606bbd7b8c4..35189c57fd0c 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -300,6 +300,10 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
.len = ctx->gk5e->keylength,
.data = ctx->Ksess,
};
+ struct krb5_buffer TK = {
+ .len = ctx->gk5e->keylength,
+ .data = ctx->Ksess,
+ };
struct xdr_netobj keyout;
int ret = -EINVAL;

@@ -374,12 +378,49 @@ gss_krb5_import_ctx_v2(struct krb5_ctx *ctx, gfp_t gfp_mask)
if (ctx->acceptor_integ == NULL)
goto out_free;

+ ctx->initiator_enc_aead =
+ crypto_krb5_prepare_encryption(ctx->krb5e, &TK,
+ KG_USAGE_INITIATOR_SEAL,
+ gfp_mask);
+ if (IS_ERR(ctx->initiator_enc_aead)) {
+ ret = PTR_ERR(ctx->initiator_enc_aead);
+ goto out_free;
+ }
+ ctx->acceptor_enc_aead =
+ crypto_krb5_prepare_encryption(ctx->krb5e, &TK,
+ KG_USAGE_ACCEPTOR_SEAL,
+ gfp_mask);
+ if (IS_ERR(ctx->acceptor_enc_aead)) {
+ ret = PTR_ERR(ctx->acceptor_enc_aead);
+ goto out_free;
+ }
+ ctx->initiator_sign_shash =
+ crypto_krb5_prepare_checksum(ctx->krb5e, &TK,
+ KG_USAGE_INITIATOR_SIGN,
+ gfp_mask);
+ if (IS_ERR(ctx->initiator_sign_shash)) {
+ ret = PTR_ERR(ctx->initiator_sign_shash);
+ goto out_free;
+ }
+ ctx->acceptor_sign_shash =
+ crypto_krb5_prepare_checksum(ctx->krb5e, &TK,
+ KG_USAGE_ACCEPTOR_SIGN,
+ gfp_mask);
+ if (IS_ERR(ctx->acceptor_sign_shash)) {
+ ret = PTR_ERR(ctx->acceptor_sign_shash);
+ goto out_free;
+ }
+
ret = 0;
out:
kfree_sensitive(keyout.data);
return ret;

out_free:
+ crypto_free_shash(ctx->acceptor_sign_shash);
+ crypto_free_shash(ctx->initiator_sign_shash);
+ crypto_free_aead(ctx->acceptor_enc_aead);
+ crypto_free_aead(ctx->initiator_enc_aead);
crypto_free_ahash(ctx->acceptor_integ);
crypto_free_ahash(ctx->initiator_integ);
crypto_free_ahash(ctx->acceptor_sign);
@@ -502,6 +543,10 @@ gss_krb5_delete_sec_context(void *internal_ctx)
{
struct krb5_ctx *kctx = internal_ctx;

+ crypto_free_shash(kctx->acceptor_sign_shash);
+ crypto_free_shash(kctx->initiator_sign_shash);
+ crypto_free_aead(kctx->acceptor_enc_aead);
+ crypto_free_aead(kctx->initiator_enc_aead);
crypto_free_sync_skcipher(kctx->seq);
crypto_free_sync_skcipher(kctx->enc);
crypto_free_sync_skcipher(kctx->acceptor_enc);

--
2.53.0