net/sunrpc/auth_gss/gss_krb5_seal.c

Source file repositories/reference/linux-study-clean/net/sunrpc/auth_gss/gss_krb5_seal.c

File Facts

System
Linux kernel
Corpus path
net/sunrpc/auth_gss/gss_krb5_seal.c
Extension
.c
Size
5025 bytes
Lines
153
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/types.h>
#include <linux/jiffies.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/atomic.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>

#include "gss_krb5_internal.h"

#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
# define RPCDBG_FACILITY        RPCDBG_AUTH
#endif

static void *
setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token)
{
	u16 *ptr;
	void *krb5_hdr;
	u8 *p, flags = 0x00;

	if (!ctx->initiate)
		flags |= KG2_TOKEN_FLAG_SENTBYACCEPTOR;
	if (ctx->flags & KRB5_CTX_FLAG_ACCEPTOR_SUBKEY)
		flags |= KG2_TOKEN_FLAG_ACCEPTORSUBKEY;

	/* Per rfc 4121, sec 4.2.6.1, there is no header,
	 * just start the token.
	 */
	krb5_hdr = (u16 *)token->data;
	ptr = krb5_hdr;

	*ptr++ = KG2_TOK_MIC;
	p = (u8 *)ptr;
	*p++ = flags;
	*p++ = 0xff;
	ptr = (u16 *)p;
	*ptr++ = 0xffff;
	*ptr = 0xffff;

	token->len = GSS_KRB5_TOK_HDR_LEN + ctx->krb5e->cksum_len;
	return krb5_hdr;
}

u32
gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
		    struct xdr_netobj *token)
{
	const struct krb5_enctype *krb5 = ctx->krb5e;
	struct crypto_shash *shash = ctx->initiate ?
		ctx->initiator_sign_shash : ctx->acceptor_sign_shash;
	unsigned int cksum_len = krb5->cksum_len;
	struct scatterlist sg_head[XDR_BUF_TO_SG_NENTS];
	struct scatterlist *sg_overflow;
	__be64 seq_send_be64;
	void *krb5_hdr;
	time64_t now;
	ssize_t ret;
	int nsg;

	dprintk("RPC:       %s\n", __func__);

	krb5_hdr = setup_token_v2(ctx, token);

	/* Set up the sequence number. Now 64-bits in clear
	 * text and w/o direction indicator */
	seq_send_be64 = cpu_to_be64(atomic64_fetch_inc(&ctx->seq_send64));
	memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);

	/*
	 * The checksum is written directly into the token buffer.
	 * This is safe: crypto_krb5_get_mic uses shash (software
	 * hash), so the scatterlist is never DMA-mapped.
	 */
	nsg = gss_krb5_mic_build_sg(text,
				    krb5_hdr + GSS_KRB5_TOK_HDR_LEN,
				    cksum_len, krb5_hdr,
				    sg_head, &sg_overflow);
	if (nsg < 0)
		return GSS_S_FAILURE;

	ret = crypto_krb5_get_mic(krb5, shash, NULL, sg_head, nsg,
				  cksum_len + text->len +
					GSS_KRB5_TOK_HDR_LEN,
				  cksum_len,
				  text->len + GSS_KRB5_TOK_HDR_LEN);
	kfree(sg_overflow);
	if (ret < 0)
		return GSS_S_FAILURE;

	now = ktime_get_real_seconds();

Annotation

Implementation Notes