// SPDX-License-Identifier: GPL-2.0-or-later
/* RxRPC key management
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * RxRPC keys should have a description of describing their purpose:
 *	"afs@example.com"
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <crypto/skcipher.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/overflow.h>
#include <linux/skbuff.h>
#include <linux/key-type.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#include <keys/rxrpc-type.h>
#include <keys/user-type.h>
#include "ar-internal.h"

static int rxrpc_preparse(struct key_preparsed_payload *);
static void rxrpc_free_preparse(struct key_preparsed_payload *);
static void rxrpc_destroy(struct key *);
static void rxrpc_describe(const struct key *, struct seq_file *);
static long rxrpc_read(const struct key *, char *, size_t);

/*
 * rxrpc defined keys take an arbitrary string as the description and an
 * arbitrary blob of data as the payload
 */
struct key_type key_type_rxrpc = {
	.name		= "rxrpc",
	.flags		= KEY_TYPE_NET_DOMAIN,
	.preparse	= rxrpc_preparse,
	.free_preparse	= rxrpc_free_preparse,
	.instantiate	= generic_key_instantiate,
	.destroy	= rxrpc_destroy,
	.describe	= rxrpc_describe,
	.read		= rxrpc_read,
};
EXPORT_SYMBOL(key_type_rxrpc);

/*
 * parse an RxKAD type XDR format token
 * - the caller guarantees we have at least 4 words
 */
static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
				    size_t datalen,
				    const __be32 *xdr, unsigned int toklen)
{
	struct rxrpc_key_token *token, **pptoken;
	time64_t expiry;
	size_t plen;
	u32 tktlen;

	_enter(",{%x,%x,%x,%x},%u",
	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
	       toklen);

	if (toklen <= 8 * 4)
		return -EKEYREJECTED;
	tktlen = ntohl(xdr[7]);
	_debug("tktlen: %x", tktlen);
	if (tktlen > AFSTOKEN_RK_TIX_MAX)
		return -EKEYREJECTED;
	if (toklen < 8 * 4 + tktlen)
		return -EKEYREJECTED;

	plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
	prep->quotalen += datalen + plen;

	plen -= sizeof(*token);
	token = kzalloc(sizeof(*token), GFP_KERNEL);
	if (!token)
		return -ENOMEM;

	token->kad = kzalloc(plen, GFP_KERNEL);
	if (!token->kad) {
		kfree(token);
		return -ENOMEM;
	}

	token->security_index	= RXRPC_SECURITY_RXKAD;
	token->kad->ticket_len	= tktlen;
	token->kad->vice_id	= ntohl(xdr[0]);
	token->kad->kvno	= ntohl(xdr[1]);
	token->kad->start	= ntohl(xdr[4]);
	token->kad->expiry	= ntohl(xdr[5]);
	token->kad->primary_flag = ntohl(xdr[6]);
	memcpy(&token->kad->session_key, &xdr[2], 8);
	memcpy(&token->kad->ticket, &xdr[8], tktlen);

	_debug("SCIX: %u", token->security_index);
	_debug("TLEN: %u", token->kad->ticket_len);
	_debug("EXPY: %x", token->kad->expiry);
	_debug("KVNO: %u", token->kad->kvno);
	_debug("PRIM: %u", token->kad->primary_flag);
	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
	       token->kad->session_key[0], token->kad->session_key[1],
	       token->kad->session_key[2], token->kad->session_key[3],
	       token->kad->session_key[4], token->kad->session_key[5],
	       token->kad->session_key[6], token->kad->session_key[7]);
	if (token->kad->ticket_len >= 8)
		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
		       token->kad->ticket[0], token->kad->ticket[1],
		       token->kad->ticket[2], token->kad->ticket[3],
		       token->kad->ticket[4], token->kad->ticket[5],
		       token->kad->ticket[6], token->kad->ticket[7]);

	/* count the number of tokens attached */
	prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);

	/* attach the data */
	for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
	     *pptoken;
	     pptoken = &(*pptoken)->next)
		continue;
	*pptoken = token;
	expiry = rxrpc_u32_to_time64(token->kad->expiry);
	if (expiry < prep->expiry)
		prep->expiry = expiry;

	_leave(" = 0");
	return 0;
}

static u64 xdr_dec64(const __be32 *xdr)
{
	return (u64)ntohl(xdr[0]) << 32 | (u64)ntohl(xdr[1]);
}

static time64_t rxrpc_s64_to_time64(s64 time_in_100ns)
{
	bool neg = false;
	u64 tmp = time_in_100ns;

	if (time_in_100ns < 0) {
		tmp = -time_in_100ns;
		neg = true;
	}
	do_div(tmp, 10000000);
	return neg ? -tmp : tmp;
}

/*
 * Parse a YFS-RxGK type XDR format token
 * - the caller guarantees we have at least 4 words
 *
 * struct token_rxgk {
 *	opr_time begintime;
 *	opr_time endtime;
 *	afs_int64 level;
 *	afs_int64 lifetime;
 *	afs_int64 bytelife;
 *	afs_int64 enctype;
 *	opaque key<>;
 *	opaque ticket<>;
 * };
 */
static int rxrpc_preparse_xdr_yfs_rxgk(struct key_preparsed_payload *prep,
				       size_t datalen,
				       const __be32 *xdr, unsigned int toklen)
{
	struct rxrpc_key_token *token, **pptoken;
	time64_t expiry;
	size_t plen;
	const __be32 *ticket, *key;
	s64 tmp;
	size_t raw_keylen, raw_tktlen, keylen, tktlen;

	_enter(",{%x,%x,%x,%x},%x",
	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
	       toklen);

	if (6 * 2 + 2 > toklen / 4)
		goto reject;

	key = xdr + (6 * 2 + 1);
	raw_keylen = ntohl(key[-1]);
	_debug("keylen: %zx", raw_keylen);
	if (raw_keylen > AFSTOKEN_GK_KEY_MAX)
		goto reject;
	keylen = round_up(raw_keylen, 4);
	if ((6 * 2 + 2) * 4 + keylen > toklen)
		goto reject;

	ticket = xdr + (6 * 2 + 1 + (keylen / 4) + 1);
	raw_tktlen = ntohl(ticket[-1]);
	_debug("tktlen: %zx", raw_tktlen);
	if (raw_tktlen > AFSTOKEN_GK_TOKEN_MAX)
		goto reject;
	tktlen = round_up(raw_tktlen, 4);
	if ((6 * 2 + 2) * 4 + keylen + tktlen != toklen) {
		kleave(" = -EKEYREJECTED [%zx!=%x, %zx,%zx]",
		       (6 * 2 + 2) * 4 + keylen + tktlen, toklen,
		       keylen, tktlen);
		goto reject;
	}

	plen = sizeof(*token) + sizeof(*token->rxgk) + tktlen + keylen;
	prep->quotalen += datalen + plen;

	plen -= sizeof(*token);
	token = kzalloc(sizeof(*token), GFP_KERNEL);
	if (!token)
		goto nomem;

	token->rxgk = kzalloc(struct_size_t(struct rxgk_key, _key, raw_keylen), GFP_KERNEL);
	if (!token->rxgk)
		goto nomem_token;

	token->security_index	= RXRPC_SECURITY_YFS_RXGK;
	token->rxgk->begintime	= xdr_dec64(xdr + 0 * 2);
	token->rxgk->endtime	= xdr_dec64(xdr + 1 * 2);
	token->rxgk->level	= tmp = xdr_dec64(xdr + 2 * 2);
	if (tmp < -1LL || tmp > RXRPC_SECURITY_ENCRYPT)
		goto reject_token;
	token->rxgk->lifetime	= xdr_dec64(xdr + 3 * 2);
	token->rxgk->bytelife	= xdr_dec64(xdr + 4 * 2);
	token->rxgk->enctype	= tmp = xdr_dec64(xdr + 5 * 2);
	if (tmp < 0 || tmp > UINT_MAX)
		goto reject_token;
	token->rxgk->key.len	= raw_keylen;
	token->rxgk->key.data	= token->rxgk->_key;
	token->rxgk->ticket.len = raw_tktlen;

	if (token->rxgk->endtime != 0) {
		expiry = rxrpc_s64_to_time64(token->rxgk->endtime);
		if (expiry < 0)
			goto expired;
		if (expiry < prep->expiry)
			prep->expiry = expiry;
	}

	memcpy(token->rxgk->key.data, key, token->rxgk->key.len);

	/* Pad the ticket so that we can use it directly in XDR */
	token->rxgk->ticket.data = kzalloc(tktlen, GFP_KERNEL);
	if (!token->rxgk->ticket.data)
		goto nomem_yrxgk;
	memcpy(token->rxgk->ticket.data, ticket, token->rxgk->ticket.len);

	_debug("SCIX: %u",	token->security_index);
	_debug("EXPY: %llx",	token->rxgk->endtime);
	_debug("LIFE: %llx",	token->rxgk->lifetime);
	_debug("BYTE: %llx",	token->rxgk->bytelife);
	_debug("ENC : %u",	token->rxgk->enctype);
	_debug("LEVL: %u",	token->rxgk->level);
	_debug("KLEN: %u",	token->rxgk->key.len);
	_debug("TLEN: %u",	token->rxgk->ticket.len);
	_debug("KEY0: %*phN",	token->rxgk->key.len, token->rxgk->key.data);
	_debug("TICK: %*phN",
	       min_t(u32, token->rxgk->ticket.len, 32), token->rxgk->ticket.data);

	/* count the number of tokens attached */
	prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);

	/* attach the data */
	for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
	     *pptoken;
	     pptoken = &(*pptoken)->next)
		continue;
	*pptoken = token;

	_leave(" = 0");
	return 0;

nomem_yrxgk:
	kfree(token->rxgk);
nomem_token:
	kfree(token);
nomem:
	return -ENOMEM;
reject_token:
	kfree(token->rxgk);
	kfree(token);
reject:
	return -EKEYREJECTED;
expired:
	kfree(token->rxgk);
	kfree(token);
	return -EKEYEXPIRED;
}

/*
 * attempt to parse the data as the XDR format
 * - the caller guarantees we have more than 7 words
 */
static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
{
	const __be32 *xdr = prep->data, *token, *p;
	const char *cp;
	unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
	size_t datalen = prep->datalen;
	int ret, ret2;

	_enter(",{%x,%x,%x,%x},%zu",
	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
	       prep->datalen);

	if (datalen > AFSTOKEN_LENGTH_MAX)
		goto not_xdr;

	/* XDR is an array of __be32's */
	if (datalen & 3)
		goto not_xdr;

	/* the flags should be 0 (the setpag bit must be handled by
	 * userspace) */
	if (ntohl(*xdr++) != 0)
		goto not_xdr;
	datalen -= 4;

	/* check the cell name */
	len = ntohl(*xdr++);
	if (len < 1 || len > AFSTOKEN_CELL_MAX)
		goto not_xdr;
	datalen -= 4;
	paddedlen = (len + 3) & ~3;
	if (paddedlen > datalen)
		goto not_xdr;

	cp = (const char *) xdr;
	for (loop = 0; loop < len; loop++)
		if (!isprint(cp[loop]))
			goto not_xdr;
	for (; loop < paddedlen; loop++)
		if (cp[loop])
			goto not_xdr;
	_debug("cellname: [%u/%u] '%*.*s'",
	       len, paddedlen, len, len, (const char *) xdr);
	datalen -= paddedlen;
	xdr += paddedlen >> 2;

	/* get the token count */
	if (datalen < 12)
		goto not_xdr;
	ntoken = ntohl(*xdr++);
	datalen -= 4;
	_debug("ntoken: %x", ntoken);
	if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
		goto not_xdr;

	/* check each token wrapper */
	p = xdr;
	loop = ntoken;
	do {
		if (datalen < 8)
			goto not_xdr;
		toklen = ntohl(*p++);
		sec_ix = ntohl(*p);
		datalen -= 4;
		_debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
		paddedlen = (toklen + 3) & ~3;
		if (toklen < 20 || toklen > datalen || paddedlen > datalen)
			goto not_xdr;
		datalen -= paddedlen;
		p += paddedlen >> 2;

	} while (--loop > 0);

	_debug("remainder: %zu", datalen);
	if (datalen != 0)
		goto not_xdr;

	/* okay: we're going to assume it's valid XDR format
	 * - we ignore the cellname, relying on the key to be correctly named
	 */
	ret = -EPROTONOSUPPORT;
	do {
		toklen = ntohl(*xdr++);
		token = xdr;
		xdr += (toklen + 3) / 4;

		sec_ix = ntohl(*token++);
		toklen -= 4;

		_debug("TOKEN type=%x len=%x", sec_ix, toklen);

		switch (sec_ix) {
		case RXRPC_SECURITY_RXKAD:
			ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen);
			break;
		case RXRPC_SECURITY_YFS_RXGK:
			ret2 = rxrpc_preparse_xdr_yfs_rxgk(prep, datalen, token, toklen);
			break;
		default:
			ret2 = -EPROTONOSUPPORT;
			break;
		}

		switch (ret2) {
		case 0:
			ret = 0;
			break;
		case -EPROTONOSUPPORT:
			break;
		case -ENOPKG:
			if (ret != 0)
				ret = -ENOPKG;
			break;
		default:
			ret = ret2;
			goto error;
		}

	} while (--ntoken > 0);

error:
	_leave(" = %d", ret);
	return ret;

not_xdr:
	_leave(" = -EPROTO");
	return -EPROTO;
}

/*
 * Preparse an rxrpc defined key.
 *
 * Data should be of the form:
 *	OFFSET	LEN	CONTENT
 *	0	4	key interface version number
 *	4	2	security index (type)
 *	6	2	ticket length
 *	8	4	key expiry time (time_t)
 *	12	4	kvno
 *	16	8	session key
 *	24	[len]	ticket
 *
 * if no data is provided, then a no-security key is made
 */
static int rxrpc_preparse(struct key_preparsed_payload *prep)
{
	const struct rxrpc_key_data_v1 *v1;
	struct rxrpc_key_token *token, **pp;
	time64_t expiry;
	size_t plen;
	u32 kver;
	int ret;

	_enter("%zu", prep->datalen);

	/* handle a no-security key */
	if (!prep->data && prep->datalen == 0)
		return 0;

	/* determine if the XDR payload format is being used */
	if (prep->datalen > 7 * 4) {
		ret = rxrpc_preparse_xdr(prep);
		if (ret != -EPROTO)
			return ret;
	}

	/* get the key interface version number */
	ret = -EINVAL;
	if (prep->datalen <= 4 || !prep->data)
		goto error;
	memcpy(&kver, prep->data, sizeof(kver));
	prep->data += sizeof(kver);
	prep->datalen -= sizeof(kver);
	prep->quotalen = 0;

	_debug("KEY I/F VERSION: %u", kver);

	ret = -EKEYREJECTED;
	if (kver != 1)
		goto error;

	/* deal with a version 1 key */
	ret = -EINVAL;
	if (prep->datalen < sizeof(*v1))
		goto error;

	v1 = prep->data;
	if (prep->datalen != sizeof(*v1) + v1->ticket_length)
		goto error;

	_debug("SCIX: %u", v1->security_index);
	_debug("TLEN: %u", v1->ticket_length);
	_debug("EXPY: %x", v1->expiry);
	_debug("KVNO: %u", v1->kvno);
	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
	       v1->session_key[0], v1->session_key[1],
	       v1->session_key[2], v1->session_key[3],
	       v1->session_key[4], v1->session_key[5],
	       v1->session_key[6], v1->session_key[7]);
	if (v1->ticket_length >= 8)
		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
		       v1->ticket[0], v1->ticket[1],
		       v1->ticket[2], v1->ticket[3],
		       v1->ticket[4], v1->ticket[5],
		       v1->ticket[6], v1->ticket[7]);

	ret = -EPROTONOSUPPORT;
	if (v1->security_index != RXRPC_SECURITY_RXKAD)
		goto error;

	ret = -EKEYREJECTED;
	if (v1->ticket_length > AFSTOKEN_RK_TIX_MAX)
		goto error;

	plen = sizeof(*token->kad) + v1->ticket_length;
	prep->quotalen += plen + sizeof(*token);

	ret = -ENOMEM;
	token = kzalloc(sizeof(*token), GFP_KERNEL);
	if (!token)
		goto error;
	token->kad = kzalloc(plen, GFP_KERNEL);
	if (!token->kad)
		goto error_free;

	token->security_index		= RXRPC_SECURITY_RXKAD;
	token->kad->ticket_len		= v1->ticket_length;
	token->kad->expiry		= v1->expiry;
	token->kad->kvno		= v1->kvno;
	memcpy(&token->kad->session_key, &v1->session_key, 8);
	memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);

	/* count the number of tokens attached */
	prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);

	/* attach the data */
	pp = (struct rxrpc_key_token **)&prep->payload.data[0];
	while (*pp)
		pp = &(*pp)->next;
	*pp = token;
	expiry = rxrpc_u32_to_time64(token->kad->expiry);
	if (expiry < prep->expiry)
		prep->expiry = expiry;
	token = NULL;
	ret = 0;

error_free:
	kfree(token);
error:
	return ret;
}

/*
 * Free token list.
 */
static void rxrpc_free_token_list(struct rxrpc_key_token *token)
{
	struct rxrpc_key_token *next;

	for (; token; token = next) {
		next = token->next;
		switch (token->security_index) {
		case RXRPC_SECURITY_RXKAD:
			kfree(token->kad);
			break;
		case RXRPC_SECURITY_YFS_RXGK:
			kfree(token->rxgk->ticket.data);
			kfree(token->rxgk);
			break;
		default:
			pr_err("Unknown token type %x on rxrpc key\n",
			       token->security_index);
			BUG();
		}

		kfree(token);
	}
}

/*
 * Clean up preparse data.
 */
static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
{
	rxrpc_free_token_list(prep->payload.data[0]);
}

/*
 * dispose of the data dangling from the corpse of a rxrpc key
 */
static void rxrpc_destroy(struct key *key)
{
	rxrpc_free_token_list(key->payload.data[0]);
}

/*
 * describe the rxrpc key
 */
static void rxrpc_describe(const struct key *key, struct seq_file *m)
{
	const struct rxrpc_key_token *token;
	const char *sep = ": ";

	seq_puts(m, key->description);

	for (token = key->payload.data[0]; token; token = token->next) {
		seq_puts(m, sep);

		switch (token->security_index) {
		case RXRPC_SECURITY_RXKAD:
			seq_puts(m, "ka");
			break;
		case RXRPC_SECURITY_YFS_RXGK:
			seq_puts(m, "ygk");
			break;
		default: /* we have a ticket we can't encode */
			seq_printf(m, "%u", token->security_index);
			break;
		}

		sep = " ";
	}
}

/*
 * grab the security key for a socket
 */
int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
{
	struct key *key;
	char *description;

	_enter("");

	if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->key)
		return -EINVAL;

	description = memdup_sockptr_nul(optval, optlen);
	if (IS_ERR(description))
		return PTR_ERR(description);

	key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
	if (IS_ERR(key)) {
		kfree(description);
		_leave(" = %ld", PTR_ERR(key));
		return PTR_ERR(key);
	}

	rx->key = key;
	kfree(description);
	_leave(" = 0 [key %x]", key->serial);
	return 0;
}

/*
 * generate a server data key
 */
int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
			      const void *session_key,
			      time64_t expiry,
			      u32 kvno)
{
	const struct cred *cred = current_cred();
	struct key *key;
	int ret;

	struct {
		u32 kver;
		struct rxrpc_key_data_v1 v1;
	} data;

	_enter("");

	key = key_alloc(&key_type_rxrpc, "x",
			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
			KEY_ALLOC_NOT_IN_QUOTA, NULL);
	if (IS_ERR(key)) {
		_leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
		return -ENOMEM;
	}

	_debug("key %d", key_serial(key));

	data.kver = 1;
	data.v1.security_index = RXRPC_SECURITY_RXKAD;
	data.v1.ticket_length = 0;
	data.v1.expiry = rxrpc_time64_to_u32(expiry);
	data.v1.kvno = 0;

	memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));

	ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
	if (ret < 0)
		goto error;

	conn->key = key;
	_leave(" = 0 [%d]", key_serial(key));
	return 0;

error:
	key_revoke(key);
	key_put(key);
	_leave(" = -ENOMEM [ins %d]", ret);
	return -ENOMEM;
}
EXPORT_SYMBOL(rxrpc_get_server_data_key);

/**
 * rxrpc_get_null_key - Generate a null RxRPC key
 * @keyname: The name to give the key.
 *
 * Generate a null RxRPC key that can be used to indicate anonymous security is
 * required for a particular domain.
 *
 * Return: The new key or a negative error code.
 */
struct key *rxrpc_get_null_key(const char *keyname)
{
	const struct cred *cred = current_cred();
	struct key *key;
	int ret;

	key = key_alloc(&key_type_rxrpc, keyname,
			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
			KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
	if (IS_ERR(key))
		return key;

	ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
	if (ret < 0) {
		key_revoke(key);
		key_put(key);
		return ERR_PTR(ret);
	}

	return key;
}
EXPORT_SYMBOL(rxrpc_get_null_key);

/*
 * read the contents of an rxrpc key
 * - this returns the result in XDR form
 */
static long rxrpc_read(const struct key *key,
		       char *buffer, size_t buflen)
{
	const struct rxrpc_key_token *token;
	size_t size;
	__be32 *xdr, *oldxdr;
	u32 cnlen, toksize, ntoks, tok, zero;
	u16 toksizes[AFSTOKEN_MAX];

	_enter("");

	/* we don't know what form we should return non-AFS keys in */
	if (memcmp(key->description, "afs@", 4) != 0)
		return -EOPNOTSUPP;
	cnlen = strlen(key->description + 4);

#define RND(X) (((X) + 3) & ~3)

	/* AFS keys we return in XDR form, so we need to work out the size of
	 * the XDR */
	size = 2 * 4;	/* flags, cellname len */
	size += RND(cnlen);	/* cellname */
	size += 1 * 4;	/* token count */

	ntoks = 0;
	for (token = key->payload.data[0]; token; token = token->next) {
		toksize = 4;	/* sec index */

		switch (token->security_index) {
		case RXRPC_SECURITY_RXKAD:
			toksize += 8 * 4;	/* viceid, kvno, key*2, begin,
						 * end, primary, tktlen */
			if (!token->no_leak_key)
				toksize += RND(token->kad->ticket_len);
			break;

		case RXRPC_SECURITY_YFS_RXGK:
			toksize += 6 * 8 + 2 * 4;
			if (!token->no_leak_key)
				toksize += RND(token->rxgk->key.len);
			toksize += RND(token->rxgk->ticket.len);
			break;

		default: /* we have a ticket we can't encode */
			pr_err("Unsupported key token type (%u)\n",
			       token->security_index);
			return -ENOPKG;
		}

		_debug("token[%u]: toksize=%u", ntoks, toksize);
		if (WARN_ON(toksize > AFSTOKEN_LENGTH_MAX))
			return -EIO;

		toksizes[ntoks++] = toksize;
		size += toksize + 4; /* each token has a length word */
	}

#undef RND

	if (!buffer || buflen < size)
		return size;

	xdr = (__be32 *)buffer;
	zero = 0;
#define ENCODE(x)				\
	do {					\
		*xdr++ = htonl(x);		\
	} while(0)
#define ENCODE_DATA(l, s)						\
	do {								\
		u32 _l = (l);						\
		ENCODE(l);						\
		memcpy(xdr, (s), _l);					\
		if (_l & 3)						\
			memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));	\
		xdr += (_l + 3) >> 2;					\
	} while(0)
#define ENCODE_BYTES(l, s)						\
	do {								\
		u32 _l = (l);						\
		memcpy(xdr, (s), _l);					\
		if (_l & 3)						\
			memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));	\
		xdr += (_l + 3) >> 2;					\
	} while(0)
#define ENCODE64(x)					\
	do {						\
		__be64 y = cpu_to_be64(x);		\
		memcpy(xdr, &y, 8);			\
		xdr += 8 >> 2;				\
	} while(0)
#define ENCODE_STR(s)				\
	do {					\
		const char *_s = (s);		\
		ENCODE_DATA(strlen(_s), _s);	\
	} while(0)

	ENCODE(0);					/* flags */
	ENCODE_DATA(cnlen, key->description + 4);	/* cellname */
	ENCODE(ntoks);

	tok = 0;
	for (token = key->payload.data[0]; token; token = token->next) {
		toksize = toksizes[tok++];
		ENCODE(toksize);
		oldxdr = xdr;
		ENCODE(token->security_index);

		switch (token->security_index) {
		case RXRPC_SECURITY_RXKAD:
			ENCODE(token->kad->vice_id);
			ENCODE(token->kad->kvno);
			ENCODE_BYTES(8, token->kad->session_key);
			ENCODE(token->kad->start);
			ENCODE(token->kad->expiry);
			ENCODE(token->kad->primary_flag);
			if (token->no_leak_key)
				ENCODE(0);
			else
				ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
			break;

		case RXRPC_SECURITY_YFS_RXGK:
			ENCODE64(token->rxgk->begintime);
			ENCODE64(token->rxgk->endtime);
			ENCODE64(token->rxgk->level);
			ENCODE64(token->rxgk->lifetime);
			ENCODE64(token->rxgk->bytelife);
			ENCODE64(token->rxgk->enctype);
			if (token->no_leak_key)
				ENCODE(0);
			else
				ENCODE_DATA(token->rxgk->key.len, token->rxgk->key.data);
			ENCODE_DATA(token->rxgk->ticket.len, token->rxgk->ticket.data);
			break;

		default:
			pr_err("Unsupported key token type (%u)\n",
			       token->security_index);
			return -ENOPKG;
		}

		if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr !=
			    toksize))
			return -EIO;
	}

#undef ENCODE_STR
#undef ENCODE_DATA
#undef ENCODE64
#undef ENCODE

	if (WARN_ON(tok != ntoks))
		return -EIO;
	if (WARN_ON((unsigned long)xdr - (unsigned long)buffer != size))
		return -EIO;
	_leave(" = %zu", size);
	return size;
}
