From: Chuck Lever Date: Mon, 27 Apr 2026 13:50:54 +0000 (-0400) Subject: SUNRPC: Switch MIC token verification to crypto/krb5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4f6bd01c5bf7afbf4a3d07f2229e06c2236e8ed;p=thirdparty%2Fkernel%2Flinux.git SUNRPC: Switch MIC token verification to crypto/krb5 gss_krb5_verify_mic_v2() currently recomputes a checksum using gss_krb5_checksum() and then compares it against the received checksum with memcmp(). Replace this with a call to crypto_krb5_verify_mic(), which performs the hash, comparison, and offset/length adjustment in a single operation through the crypto/krb5 library. The scatterlist layout required by RFC 4121 Section 4.2.4 is constructed via gss_krb5_mic_build_sg(), the shared helper introduced in the preceding commit. The received checksum occupies the first scatterlist entry, pointing directly into the token buffer. The errno result from crypto_krb5_verify_mic() is mapped to a GSS major status code via gss_krb5_errno_to_status(), which returns GSS_S_BAD_SIG for -EBADMSG (checksum mismatch). Assisted-by: Claude:claude-opus-4-6 Reviewed-by: Jeff Layton Acked-by: Anna Schumaker Signed-off-by: Chuck Lever --- diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c index ef0e6af9fc959..b5fb70419faaa 100644 --- a/net/sunrpc/auth_gss/gss_krb5_unseal.c +++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c @@ -60,6 +60,8 @@ #include #include #include +#include +#include #include "gss_krb5_internal.h" @@ -71,18 +73,19 @@ u32 gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, struct xdr_netobj *read_token) { - struct crypto_ahash *tfm = ctx->initiate ? - ctx->acceptor_sign : ctx->initiator_sign; - char cksumdata[GSS_KRB5_MAX_CKSUM_LEN]; - struct xdr_netobj cksumobj = { - .len = ctx->gk5e->cksumlength, - .data = cksumdata, - }; + const struct krb5_enctype *krb5 = ctx->krb5e; + struct crypto_shash *shash = ctx->initiate ? + ctx->acceptor_sign_shash : ctx->initiator_sign_shash; + unsigned int cksum_len = krb5->cksum_len; + struct scatterlist sg_head[XDR_BUF_TO_SG_NENTS]; + struct scatterlist *sg_overflow; + size_t mic_offset, mic_len; u8 *ptr = read_token->data; __be16 be16_ptr; time64_t now; u8 flags; - int i; + int nsg, i; + int ret; dprintk("RPC: %s\n", __func__); @@ -104,13 +107,20 @@ gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, if (ptr[i] != 0xff) return GSS_S_DEFECTIVE_TOKEN; - if (gss_krb5_checksum(tfm, ptr, GSS_KRB5_TOK_HDR_LEN, - message_buffer, 0, &cksumobj)) + nsg = gss_krb5_mic_build_sg(message_buffer, + ptr + GSS_KRB5_TOK_HDR_LEN, + cksum_len, ptr, + sg_head, &sg_overflow); + if (nsg < 0) return GSS_S_FAILURE; - if (memcmp(cksumobj.data, ptr + GSS_KRB5_TOK_HDR_LEN, - ctx->gk5e->cksumlength)) - return GSS_S_BAD_SIG; + mic_offset = 0; + mic_len = cksum_len + message_buffer->len + GSS_KRB5_TOK_HDR_LEN; + ret = crypto_krb5_verify_mic(krb5, shash, NULL, sg_head, nsg, + &mic_offset, &mic_len); + kfree(sg_overflow); + if (ret) + return gss_krb5_errno_to_status(ret); /* it got through unscathed. Make sure the context is unexpired */ now = ktime_get_real_seconds();