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