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