#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_krb5.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include "gss_krb5_internal.h"
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__);
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();