xref: /openbmc/linux/net/rxrpc/key.c (revision 0727d3ec)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* RxRPC key management
3  *
4  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  *
7  * RxRPC keys should have a description of describing their purpose:
8  *	"afs@CAMBRIDGE.REDHAT.COM>
9  */
10 
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 
13 #include <crypto/skcipher.h>
14 #include <linux/module.h>
15 #include <linux/net.h>
16 #include <linux/skbuff.h>
17 #include <linux/key-type.h>
18 #include <linux/ctype.h>
19 #include <linux/slab.h>
20 #include <net/sock.h>
21 #include <net/af_rxrpc.h>
22 #include <keys/rxrpc-type.h>
23 #include <keys/user-type.h>
24 #include "ar-internal.h"
25 
26 static int rxrpc_vet_description_s(const char *);
27 static int rxrpc_preparse(struct key_preparsed_payload *);
28 static int rxrpc_preparse_s(struct key_preparsed_payload *);
29 static void rxrpc_free_preparse(struct key_preparsed_payload *);
30 static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
31 static void rxrpc_destroy(struct key *);
32 static void rxrpc_destroy_s(struct key *);
33 static void rxrpc_describe(const struct key *, struct seq_file *);
34 static void rxrpc_describe_s(const struct key *, struct seq_file *);
35 static long rxrpc_read(const struct key *, char *, size_t);
36 
37 /*
38  * rxrpc defined keys take an arbitrary string as the description and an
39  * arbitrary blob of data as the payload
40  */
41 struct key_type key_type_rxrpc = {
42 	.name		= "rxrpc",
43 	.flags		= KEY_TYPE_NET_DOMAIN,
44 	.preparse	= rxrpc_preparse,
45 	.free_preparse	= rxrpc_free_preparse,
46 	.instantiate	= generic_key_instantiate,
47 	.destroy	= rxrpc_destroy,
48 	.describe	= rxrpc_describe,
49 	.read		= rxrpc_read,
50 };
51 EXPORT_SYMBOL(key_type_rxrpc);
52 
53 /*
54  * rxrpc server defined keys take "<serviceId>:<securityIndex>" as the
55  * description and an 8-byte decryption key as the payload
56  */
57 struct key_type key_type_rxrpc_s = {
58 	.name		= "rxrpc_s",
59 	.flags		= KEY_TYPE_NET_DOMAIN,
60 	.vet_description = rxrpc_vet_description_s,
61 	.preparse	= rxrpc_preparse_s,
62 	.free_preparse	= rxrpc_free_preparse_s,
63 	.instantiate	= generic_key_instantiate,
64 	.destroy	= rxrpc_destroy_s,
65 	.describe	= rxrpc_describe_s,
66 };
67 
68 /*
69  * Vet the description for an RxRPC server key
70  */
71 static int rxrpc_vet_description_s(const char *desc)
72 {
73 	unsigned long num;
74 	char *p;
75 
76 	num = simple_strtoul(desc, &p, 10);
77 	if (*p != ':' || num > 65535)
78 		return -EINVAL;
79 	num = simple_strtoul(p + 1, &p, 10);
80 	if (*p || num < 1 || num > 255)
81 		return -EINVAL;
82 	return 0;
83 }
84 
85 /*
86  * parse an RxKAD type XDR format token
87  * - the caller guarantees we have at least 4 words
88  */
89 static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
90 				    size_t datalen,
91 				    const __be32 *xdr, unsigned int toklen)
92 {
93 	struct rxrpc_key_token *token, **pptoken;
94 	time64_t expiry;
95 	size_t plen;
96 	u32 tktlen;
97 
98 	_enter(",{%x,%x,%x,%x},%u",
99 	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
100 	       toklen);
101 
102 	if (toklen <= 8 * 4)
103 		return -EKEYREJECTED;
104 	tktlen = ntohl(xdr[7]);
105 	_debug("tktlen: %x", tktlen);
106 	if (tktlen > AFSTOKEN_RK_TIX_MAX)
107 		return -EKEYREJECTED;
108 	if (toklen < 8 * 4 + tktlen)
109 		return -EKEYREJECTED;
110 
111 	plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
112 	prep->quotalen = datalen + plen;
113 
114 	plen -= sizeof(*token);
115 	token = kzalloc(sizeof(*token), GFP_KERNEL);
116 	if (!token)
117 		return -ENOMEM;
118 
119 	token->kad = kzalloc(plen, GFP_KERNEL);
120 	if (!token->kad) {
121 		kfree(token);
122 		return -ENOMEM;
123 	}
124 
125 	token->security_index	= RXRPC_SECURITY_RXKAD;
126 	token->kad->ticket_len	= tktlen;
127 	token->kad->vice_id	= ntohl(xdr[0]);
128 	token->kad->kvno	= ntohl(xdr[1]);
129 	token->kad->start	= ntohl(xdr[4]);
130 	token->kad->expiry	= ntohl(xdr[5]);
131 	token->kad->primary_flag = ntohl(xdr[6]);
132 	memcpy(&token->kad->session_key, &xdr[2], 8);
133 	memcpy(&token->kad->ticket, &xdr[8], tktlen);
134 
135 	_debug("SCIX: %u", token->security_index);
136 	_debug("TLEN: %u", token->kad->ticket_len);
137 	_debug("EXPY: %x", token->kad->expiry);
138 	_debug("KVNO: %u", token->kad->kvno);
139 	_debug("PRIM: %u", token->kad->primary_flag);
140 	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
141 	       token->kad->session_key[0], token->kad->session_key[1],
142 	       token->kad->session_key[2], token->kad->session_key[3],
143 	       token->kad->session_key[4], token->kad->session_key[5],
144 	       token->kad->session_key[6], token->kad->session_key[7]);
145 	if (token->kad->ticket_len >= 8)
146 		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
147 		       token->kad->ticket[0], token->kad->ticket[1],
148 		       token->kad->ticket[2], token->kad->ticket[3],
149 		       token->kad->ticket[4], token->kad->ticket[5],
150 		       token->kad->ticket[6], token->kad->ticket[7]);
151 
152 	/* count the number of tokens attached */
153 	prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
154 
155 	/* attach the data */
156 	for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
157 	     *pptoken;
158 	     pptoken = &(*pptoken)->next)
159 		continue;
160 	*pptoken = token;
161 	expiry = rxrpc_u32_to_time64(token->kad->expiry);
162 	if (expiry < prep->expiry)
163 		prep->expiry = expiry;
164 
165 	_leave(" = 0");
166 	return 0;
167 }
168 
169 /*
170  * attempt to parse the data as the XDR format
171  * - the caller guarantees we have more than 7 words
172  */
173 static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
174 {
175 	const __be32 *xdr = prep->data, *token;
176 	const char *cp;
177 	unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
178 	size_t datalen = prep->datalen;
179 	int ret;
180 
181 	_enter(",{%x,%x,%x,%x},%zu",
182 	       ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
183 	       prep->datalen);
184 
185 	if (datalen > AFSTOKEN_LENGTH_MAX)
186 		goto not_xdr;
187 
188 	/* XDR is an array of __be32's */
189 	if (datalen & 3)
190 		goto not_xdr;
191 
192 	/* the flags should be 0 (the setpag bit must be handled by
193 	 * userspace) */
194 	if (ntohl(*xdr++) != 0)
195 		goto not_xdr;
196 	datalen -= 4;
197 
198 	/* check the cell name */
199 	len = ntohl(*xdr++);
200 	if (len < 1 || len > AFSTOKEN_CELL_MAX)
201 		goto not_xdr;
202 	datalen -= 4;
203 	paddedlen = (len + 3) & ~3;
204 	if (paddedlen > datalen)
205 		goto not_xdr;
206 
207 	cp = (const char *) xdr;
208 	for (loop = 0; loop < len; loop++)
209 		if (!isprint(cp[loop]))
210 			goto not_xdr;
211 	for (; loop < paddedlen; loop++)
212 		if (cp[loop])
213 			goto not_xdr;
214 	_debug("cellname: [%u/%u] '%*.*s'",
215 	       len, paddedlen, len, len, (const char *) xdr);
216 	datalen -= paddedlen;
217 	xdr += paddedlen >> 2;
218 
219 	/* get the token count */
220 	if (datalen < 12)
221 		goto not_xdr;
222 	ntoken = ntohl(*xdr++);
223 	datalen -= 4;
224 	_debug("ntoken: %x", ntoken);
225 	if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
226 		goto not_xdr;
227 
228 	/* check each token wrapper */
229 	token = xdr;
230 	loop = ntoken;
231 	do {
232 		if (datalen < 8)
233 			goto not_xdr;
234 		toklen = ntohl(*xdr++);
235 		sec_ix = ntohl(*xdr);
236 		datalen -= 4;
237 		_debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
238 		paddedlen = (toklen + 3) & ~3;
239 		if (toklen < 20 || toklen > datalen || paddedlen > datalen)
240 			goto not_xdr;
241 		datalen -= paddedlen;
242 		xdr += paddedlen >> 2;
243 
244 	} while (--loop > 0);
245 
246 	_debug("remainder: %zu", datalen);
247 	if (datalen != 0)
248 		goto not_xdr;
249 
250 	/* okay: we're going to assume it's valid XDR format
251 	 * - we ignore the cellname, relying on the key to be correctly named
252 	 */
253 	do {
254 		xdr = token;
255 		toklen = ntohl(*xdr++);
256 		token = xdr + ((toklen + 3) >> 2);
257 		sec_ix = ntohl(*xdr++);
258 		toklen -= 4;
259 
260 		_debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token);
261 
262 		switch (sec_ix) {
263 		case RXRPC_SECURITY_RXKAD:
264 			ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen);
265 			if (ret != 0)
266 				goto error;
267 			break;
268 
269 		default:
270 			ret = -EPROTONOSUPPORT;
271 			goto error;
272 		}
273 
274 	} while (--ntoken > 0);
275 
276 	_leave(" = 0");
277 	return 0;
278 
279 not_xdr:
280 	_leave(" = -EPROTO");
281 	return -EPROTO;
282 error:
283 	_leave(" = %d", ret);
284 	return ret;
285 }
286 
287 /*
288  * Preparse an rxrpc defined key.
289  *
290  * Data should be of the form:
291  *	OFFSET	LEN	CONTENT
292  *	0	4	key interface version number
293  *	4	2	security index (type)
294  *	6	2	ticket length
295  *	8	4	key expiry time (time_t)
296  *	12	4	kvno
297  *	16	8	session key
298  *	24	[len]	ticket
299  *
300  * if no data is provided, then a no-security key is made
301  */
302 static int rxrpc_preparse(struct key_preparsed_payload *prep)
303 {
304 	const struct rxrpc_key_data_v1 *v1;
305 	struct rxrpc_key_token *token, **pp;
306 	time64_t expiry;
307 	size_t plen;
308 	u32 kver;
309 	int ret;
310 
311 	_enter("%zu", prep->datalen);
312 
313 	/* handle a no-security key */
314 	if (!prep->data && prep->datalen == 0)
315 		return 0;
316 
317 	/* determine if the XDR payload format is being used */
318 	if (prep->datalen > 7 * 4) {
319 		ret = rxrpc_preparse_xdr(prep);
320 		if (ret != -EPROTO)
321 			return ret;
322 	}
323 
324 	/* get the key interface version number */
325 	ret = -EINVAL;
326 	if (prep->datalen <= 4 || !prep->data)
327 		goto error;
328 	memcpy(&kver, prep->data, sizeof(kver));
329 	prep->data += sizeof(kver);
330 	prep->datalen -= sizeof(kver);
331 
332 	_debug("KEY I/F VERSION: %u", kver);
333 
334 	ret = -EKEYREJECTED;
335 	if (kver != 1)
336 		goto error;
337 
338 	/* deal with a version 1 key */
339 	ret = -EINVAL;
340 	if (prep->datalen < sizeof(*v1))
341 		goto error;
342 
343 	v1 = prep->data;
344 	if (prep->datalen != sizeof(*v1) + v1->ticket_length)
345 		goto error;
346 
347 	_debug("SCIX: %u", v1->security_index);
348 	_debug("TLEN: %u", v1->ticket_length);
349 	_debug("EXPY: %x", v1->expiry);
350 	_debug("KVNO: %u", v1->kvno);
351 	_debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
352 	       v1->session_key[0], v1->session_key[1],
353 	       v1->session_key[2], v1->session_key[3],
354 	       v1->session_key[4], v1->session_key[5],
355 	       v1->session_key[6], v1->session_key[7]);
356 	if (v1->ticket_length >= 8)
357 		_debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
358 		       v1->ticket[0], v1->ticket[1],
359 		       v1->ticket[2], v1->ticket[3],
360 		       v1->ticket[4], v1->ticket[5],
361 		       v1->ticket[6], v1->ticket[7]);
362 
363 	ret = -EPROTONOSUPPORT;
364 	if (v1->security_index != RXRPC_SECURITY_RXKAD)
365 		goto error;
366 
367 	plen = sizeof(*token->kad) + v1->ticket_length;
368 	prep->quotalen = plen + sizeof(*token);
369 
370 	ret = -ENOMEM;
371 	token = kzalloc(sizeof(*token), GFP_KERNEL);
372 	if (!token)
373 		goto error;
374 	token->kad = kzalloc(plen, GFP_KERNEL);
375 	if (!token->kad)
376 		goto error_free;
377 
378 	token->security_index		= RXRPC_SECURITY_RXKAD;
379 	token->kad->ticket_len		= v1->ticket_length;
380 	token->kad->expiry		= v1->expiry;
381 	token->kad->kvno		= v1->kvno;
382 	memcpy(&token->kad->session_key, &v1->session_key, 8);
383 	memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
384 
385 	/* count the number of tokens attached */
386 	prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
387 
388 	/* attach the data */
389 	pp = (struct rxrpc_key_token **)&prep->payload.data[0];
390 	while (*pp)
391 		pp = &(*pp)->next;
392 	*pp = token;
393 	expiry = rxrpc_u32_to_time64(token->kad->expiry);
394 	if (expiry < prep->expiry)
395 		prep->expiry = expiry;
396 	token = NULL;
397 	ret = 0;
398 
399 error_free:
400 	kfree(token);
401 error:
402 	return ret;
403 }
404 
405 /*
406  * Free token list.
407  */
408 static void rxrpc_free_token_list(struct rxrpc_key_token *token)
409 {
410 	struct rxrpc_key_token *next;
411 
412 	for (; token; token = next) {
413 		next = token->next;
414 		switch (token->security_index) {
415 		case RXRPC_SECURITY_RXKAD:
416 			kfree(token->kad);
417 			break;
418 		default:
419 			pr_err("Unknown token type %x on rxrpc key\n",
420 			       token->security_index);
421 			BUG();
422 		}
423 
424 		kfree(token);
425 	}
426 }
427 
428 /*
429  * Clean up preparse data.
430  */
431 static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
432 {
433 	rxrpc_free_token_list(prep->payload.data[0]);
434 }
435 
436 /*
437  * Preparse a server secret key.
438  *
439  * The data should be the 8-byte secret key.
440  */
441 static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
442 {
443 	struct crypto_skcipher *ci;
444 
445 	_enter("%zu", prep->datalen);
446 
447 	if (prep->datalen != 8)
448 		return -EINVAL;
449 
450 	memcpy(&prep->payload.data[2], prep->data, 8);
451 
452 	ci = crypto_alloc_skcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
453 	if (IS_ERR(ci)) {
454 		_leave(" = %ld", PTR_ERR(ci));
455 		return PTR_ERR(ci);
456 	}
457 
458 	if (crypto_skcipher_setkey(ci, prep->data, 8) < 0)
459 		BUG();
460 
461 	prep->payload.data[0] = ci;
462 	_leave(" = 0");
463 	return 0;
464 }
465 
466 /*
467  * Clean up preparse data.
468  */
469 static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
470 {
471 	if (prep->payload.data[0])
472 		crypto_free_skcipher(prep->payload.data[0]);
473 }
474 
475 /*
476  * dispose of the data dangling from the corpse of a rxrpc key
477  */
478 static void rxrpc_destroy(struct key *key)
479 {
480 	rxrpc_free_token_list(key->payload.data[0]);
481 }
482 
483 /*
484  * dispose of the data dangling from the corpse of a rxrpc key
485  */
486 static void rxrpc_destroy_s(struct key *key)
487 {
488 	if (key->payload.data[0]) {
489 		crypto_free_skcipher(key->payload.data[0]);
490 		key->payload.data[0] = NULL;
491 	}
492 }
493 
494 /*
495  * describe the rxrpc key
496  */
497 static void rxrpc_describe(const struct key *key, struct seq_file *m)
498 {
499 	const struct rxrpc_key_token *token;
500 	const char *sep = ": ";
501 
502 	seq_puts(m, key->description);
503 
504 	for (token = key->payload.data[0]; token; token = token->next) {
505 		seq_puts(m, sep);
506 
507 		switch (token->security_index) {
508 		case RXRPC_SECURITY_RXKAD:
509 			seq_puts(m, "ka");
510 			break;
511 		default: /* we have a ticket we can't encode */
512 			seq_printf(m, "%u", token->security_index);
513 			break;
514 		}
515 
516 		sep = " ";
517 	}
518 }
519 
520 /*
521  * describe the rxrpc server key
522  */
523 static void rxrpc_describe_s(const struct key *key, struct seq_file *m)
524 {
525 	seq_puts(m, key->description);
526 }
527 
528 /*
529  * grab the security key for a socket
530  */
531 int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
532 {
533 	struct key *key;
534 	char *description;
535 
536 	_enter("");
537 
538 	if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities)
539 		return -EINVAL;
540 
541 	description = memdup_sockptr_nul(optval, optlen);
542 	if (IS_ERR(description))
543 		return PTR_ERR(description);
544 
545 	key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
546 	if (IS_ERR(key)) {
547 		kfree(description);
548 		_leave(" = %ld", PTR_ERR(key));
549 		return PTR_ERR(key);
550 	}
551 
552 	rx->key = key;
553 	kfree(description);
554 	_leave(" = 0 [key %x]", key->serial);
555 	return 0;
556 }
557 
558 /*
559  * grab the security keyring for a server socket
560  */
561 int rxrpc_server_keyring(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
562 {
563 	struct key *key;
564 	char *description;
565 
566 	_enter("");
567 
568 	if (optlen <= 0 || optlen > PAGE_SIZE - 1)
569 		return -EINVAL;
570 
571 	description = memdup_sockptr_nul(optval, optlen);
572 	if (IS_ERR(description))
573 		return PTR_ERR(description);
574 
575 	key = request_key(&key_type_keyring, description, NULL);
576 	if (IS_ERR(key)) {
577 		kfree(description);
578 		_leave(" = %ld", PTR_ERR(key));
579 		return PTR_ERR(key);
580 	}
581 
582 	rx->securities = key;
583 	kfree(description);
584 	_leave(" = 0 [key %x]", key->serial);
585 	return 0;
586 }
587 
588 /*
589  * generate a server data key
590  */
591 int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
592 			      const void *session_key,
593 			      time64_t expiry,
594 			      u32 kvno)
595 {
596 	const struct cred *cred = current_cred();
597 	struct key *key;
598 	int ret;
599 
600 	struct {
601 		u32 kver;
602 		struct rxrpc_key_data_v1 v1;
603 	} data;
604 
605 	_enter("");
606 
607 	key = key_alloc(&key_type_rxrpc, "x",
608 			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
609 			KEY_ALLOC_NOT_IN_QUOTA, NULL);
610 	if (IS_ERR(key)) {
611 		_leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
612 		return -ENOMEM;
613 	}
614 
615 	_debug("key %d", key_serial(key));
616 
617 	data.kver = 1;
618 	data.v1.security_index = RXRPC_SECURITY_RXKAD;
619 	data.v1.ticket_length = 0;
620 	data.v1.expiry = rxrpc_time64_to_u32(expiry);
621 	data.v1.kvno = 0;
622 
623 	memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
624 
625 	ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
626 	if (ret < 0)
627 		goto error;
628 
629 	conn->params.key = key;
630 	_leave(" = 0 [%d]", key_serial(key));
631 	return 0;
632 
633 error:
634 	key_revoke(key);
635 	key_put(key);
636 	_leave(" = -ENOMEM [ins %d]", ret);
637 	return -ENOMEM;
638 }
639 EXPORT_SYMBOL(rxrpc_get_server_data_key);
640 
641 /**
642  * rxrpc_get_null_key - Generate a null RxRPC key
643  * @keyname: The name to give the key.
644  *
645  * Generate a null RxRPC key that can be used to indicate anonymous security is
646  * required for a particular domain.
647  */
648 struct key *rxrpc_get_null_key(const char *keyname)
649 {
650 	const struct cred *cred = current_cred();
651 	struct key *key;
652 	int ret;
653 
654 	key = key_alloc(&key_type_rxrpc, keyname,
655 			GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
656 			KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
657 	if (IS_ERR(key))
658 		return key;
659 
660 	ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
661 	if (ret < 0) {
662 		key_revoke(key);
663 		key_put(key);
664 		return ERR_PTR(ret);
665 	}
666 
667 	return key;
668 }
669 EXPORT_SYMBOL(rxrpc_get_null_key);
670 
671 /*
672  * read the contents of an rxrpc key
673  * - this returns the result in XDR form
674  */
675 static long rxrpc_read(const struct key *key,
676 		       char *buffer, size_t buflen)
677 {
678 	const struct rxrpc_key_token *token;
679 	size_t size;
680 	__be32 *xdr, *oldxdr;
681 	u32 cnlen, toksize, ntoks, tok, zero;
682 	u16 toksizes[AFSTOKEN_MAX];
683 
684 	_enter("");
685 
686 	/* we don't know what form we should return non-AFS keys in */
687 	if (memcmp(key->description, "afs@", 4) != 0)
688 		return -EOPNOTSUPP;
689 	cnlen = strlen(key->description + 4);
690 
691 #define RND(X) (((X) + 3) & ~3)
692 
693 	/* AFS keys we return in XDR form, so we need to work out the size of
694 	 * the XDR */
695 	size = 2 * 4;	/* flags, cellname len */
696 	size += RND(cnlen);	/* cellname */
697 	size += 1 * 4;	/* token count */
698 
699 	ntoks = 0;
700 	for (token = key->payload.data[0]; token; token = token->next) {
701 		toksize = 4;	/* sec index */
702 
703 		switch (token->security_index) {
704 		case RXRPC_SECURITY_RXKAD:
705 			toksize += 8 * 4;	/* viceid, kvno, key*2, begin,
706 						 * end, primary, tktlen */
707 			toksize += RND(token->kad->ticket_len);
708 			break;
709 
710 		default: /* we have a ticket we can't encode */
711 			pr_err("Unsupported key token type (%u)\n",
712 			       token->security_index);
713 			continue;
714 		}
715 
716 		_debug("token[%u]: toksize=%u", ntoks, toksize);
717 		ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
718 
719 		toksizes[ntoks++] = toksize;
720 		size += toksize + 4; /* each token has a length word */
721 	}
722 
723 #undef RND
724 
725 	if (!buffer || buflen < size)
726 		return size;
727 
728 	xdr = (__be32 *)buffer;
729 	zero = 0;
730 #define ENCODE(x)				\
731 	do {					\
732 		*xdr++ = htonl(x);		\
733 	} while(0)
734 #define ENCODE_DATA(l, s)						\
735 	do {								\
736 		u32 _l = (l);						\
737 		ENCODE(l);						\
738 		memcpy(xdr, (s), _l);					\
739 		if (_l & 3)						\
740 			memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));	\
741 		xdr += (_l + 3) >> 2;					\
742 	} while(0)
743 #define ENCODE_BYTES(l, s)						\
744 	do {								\
745 		u32 _l = (l);						\
746 		memcpy(xdr, (s), _l);					\
747 		if (_l & 3)						\
748 			memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));	\
749 		xdr += (_l + 3) >> 2;					\
750 	} while(0)
751 #define ENCODE64(x)					\
752 	do {						\
753 		__be64 y = cpu_to_be64(x);		\
754 		memcpy(xdr, &y, 8);			\
755 		xdr += 8 >> 2;				\
756 	} while(0)
757 #define ENCODE_STR(s)				\
758 	do {					\
759 		const char *_s = (s);		\
760 		ENCODE_DATA(strlen(_s), _s);	\
761 	} while(0)
762 
763 	ENCODE(0);					/* flags */
764 	ENCODE_DATA(cnlen, key->description + 4);	/* cellname */
765 	ENCODE(ntoks);
766 
767 	tok = 0;
768 	for (token = key->payload.data[0]; token; token = token->next) {
769 		toksize = toksizes[tok++];
770 		ENCODE(toksize);
771 		oldxdr = xdr;
772 		ENCODE(token->security_index);
773 
774 		switch (token->security_index) {
775 		case RXRPC_SECURITY_RXKAD:
776 			ENCODE(token->kad->vice_id);
777 			ENCODE(token->kad->kvno);
778 			ENCODE_BYTES(8, token->kad->session_key);
779 			ENCODE(token->kad->start);
780 			ENCODE(token->kad->expiry);
781 			ENCODE(token->kad->primary_flag);
782 			ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
783 			break;
784 
785 		default:
786 			break;
787 		}
788 
789 		ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
790 			  toksize);
791 	}
792 
793 #undef ENCODE_STR
794 #undef ENCODE_DATA
795 #undef ENCODE64
796 #undef ENCODE
797 
798 	ASSERTCMP(tok, ==, ntoks);
799 	ASSERTCMP((char __user *) xdr - buffer, ==, size);
800 	_leave(" = %zu", size);
801 	return size;
802 }
803