summaryrefslogtreecommitdiffstats
path: root/net/rxrpc/key.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-06-13 07:16:05 -0400
committerDavid Howells <dhowells@redhat.com>2016-06-13 07:16:05 -0400
commit8c3e34a4ff85142ca5dba3f18cbc2061899e2612 (patch)
tree7e8098488c22da71b6a93296b182e29fe797ac3c /net/rxrpc/key.c
parent99860208bc62d8ebd5c57495b84856506fe075bc (diff)
rxrpc: Rename files matching ar-*.c to git rid of the "ar-" prefix
Rename files matching net/rxrpc/ar-*.c to get rid of the "ar-" prefix. This will aid splitting those files by making easier to come up with new names. Note that the not all files are simply renamed from ar-X.c to X.c. The following exceptions are made: (*) ar-call.c -> call_object.c ar-ack.c -> call_event.c call_object.c is going to contain the core of the call object handling. Call event handling is all going to be in call_event.c. (*) ar-accept.c -> call_accept.c Incoming call handling is going to be here. (*) ar-connection.c -> conn_object.c ar-connevent.c -> conn_event.c The former file is going to have the basic connection object handling, but there will likely be some differentiation between client connections and service connections in additional files later. The latter file will have all the connection-level event handling. (*) ar-local.c -> local_object.c This will have the local endpoint object handling code. The local endpoint event handling code will later be split out into local_event.c. (*) ar-peer.c -> peer_object.c This will have the peer endpoint object handling code. Peer event handling code will be placed in peer_event.c (for the moment, there is none). (*) ar-error.c -> peer_event.c This will become the peer event handling code, though for the moment it's actually driven from the local endpoint's perspective. Note that I haven't renamed ar-transport.c to transport_object.c as the intention is to delete it when the rxrpc_transport struct is excised. The only file that actually has its contents changed is net/rxrpc/Makefile. net/rxrpc/ar-internal.h will need its section marker comments updating, but I'll do that in a separate patch to make it easier for git to follow the history across the rename. I may also want to rename ar-internal.h at some point - but that would mean updating all the #includes and I'd rather do that in a separate step. Signed-off-by: David Howells <dhowells@redhat.com.
Diffstat (limited to 'net/rxrpc/key.c')
-rw-r--r--net/rxrpc/key.c1237
1 files changed, 1237 insertions, 0 deletions
diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
new file mode 100644
index 000000000000..4ad56fafe3a7
--- /dev/null
+++ b/net/rxrpc/key.c
@@ -0,0 +1,1237 @@
1/* RxRPC key management
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * RxRPC keys should have a description of describing their purpose:
12 * "afs@CAMBRIDGE.REDHAT.COM>
13 */
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17#include <crypto/skcipher.h>
18#include <linux/module.h>
19#include <linux/net.h>
20#include <linux/skbuff.h>
21#include <linux/key-type.h>
22#include <linux/ctype.h>
23#include <linux/slab.h>
24#include <net/sock.h>
25#include <net/af_rxrpc.h>
26#include <keys/rxrpc-type.h>
27#include <keys/user-type.h>
28#include "ar-internal.h"
29
30static int rxrpc_vet_description_s(const char *);
31static int rxrpc_preparse(struct key_preparsed_payload *);
32static int rxrpc_preparse_s(struct key_preparsed_payload *);
33static void rxrpc_free_preparse(struct key_preparsed_payload *);
34static void rxrpc_free_preparse_s(struct key_preparsed_payload *);
35static void rxrpc_destroy(struct key *);
36static void rxrpc_destroy_s(struct key *);
37static void rxrpc_describe(const struct key *, struct seq_file *);
38static long rxrpc_read(const struct key *, char __user *, size_t);
39
40/*
41 * rxrpc defined keys take an arbitrary string as the description and an
42 * arbitrary blob of data as the payload
43 */
44struct key_type key_type_rxrpc = {
45 .name = "rxrpc",
46 .preparse = rxrpc_preparse,
47 .free_preparse = rxrpc_free_preparse,
48 .instantiate = generic_key_instantiate,
49 .destroy = rxrpc_destroy,
50 .describe = rxrpc_describe,
51 .read = rxrpc_read,
52};
53EXPORT_SYMBOL(key_type_rxrpc);
54
55/*
56 * rxrpc server defined keys take "<serviceId>:<securityIndex>" as the
57 * description and an 8-byte decryption key as the payload
58 */
59struct key_type key_type_rxrpc_s = {
60 .name = "rxrpc_s",
61 .vet_description = rxrpc_vet_description_s,
62 .preparse = rxrpc_preparse_s,
63 .free_preparse = rxrpc_free_preparse_s,
64 .instantiate = generic_key_instantiate,
65 .destroy = rxrpc_destroy_s,
66 .describe = rxrpc_describe,
67};
68
69/*
70 * Vet the description for an RxRPC server key
71 */
72static int rxrpc_vet_description_s(const char *desc)
73{
74 unsigned long num;
75 char *p;
76
77 num = simple_strtoul(desc, &p, 10);
78 if (*p != ':' || num > 65535)
79 return -EINVAL;
80 num = simple_strtoul(p + 1, &p, 10);
81 if (*p || num < 1 || num > 255)
82 return -EINVAL;
83 return 0;
84}
85
86/*
87 * parse an RxKAD type XDR format token
88 * - the caller guarantees we have at least 4 words
89 */
90static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
91 size_t datalen,
92 const __be32 *xdr, unsigned int toklen)
93{
94 struct rxrpc_key_token *token, **pptoken;
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 if (token->kad->expiry < prep->expiry)
162 prep->expiry = token->kad->expiry;
163
164 _leave(" = 0");
165 return 0;
166}
167
168static void rxrpc_free_krb5_principal(struct krb5_principal *princ)
169{
170 int loop;
171
172 if (princ->name_parts) {
173 for (loop = princ->n_name_parts - 1; loop >= 0; loop--)
174 kfree(princ->name_parts[loop]);
175 kfree(princ->name_parts);
176 }
177 kfree(princ->realm);
178}
179
180static void rxrpc_free_krb5_tagged(struct krb5_tagged_data *td)
181{
182 kfree(td->data);
183}
184
185/*
186 * free up an RxK5 token
187 */
188static void rxrpc_rxk5_free(struct rxk5_key *rxk5)
189{
190 int loop;
191
192 rxrpc_free_krb5_principal(&rxk5->client);
193 rxrpc_free_krb5_principal(&rxk5->server);
194 rxrpc_free_krb5_tagged(&rxk5->session);
195
196 if (rxk5->addresses) {
197 for (loop = rxk5->n_addresses - 1; loop >= 0; loop--)
198 rxrpc_free_krb5_tagged(&rxk5->addresses[loop]);
199 kfree(rxk5->addresses);
200 }
201 if (rxk5->authdata) {
202 for (loop = rxk5->n_authdata - 1; loop >= 0; loop--)
203 rxrpc_free_krb5_tagged(&rxk5->authdata[loop]);
204 kfree(rxk5->authdata);
205 }
206
207 kfree(rxk5->ticket);
208 kfree(rxk5->ticket2);
209 kfree(rxk5);
210}
211
212/*
213 * extract a krb5 principal
214 */
215static int rxrpc_krb5_decode_principal(struct krb5_principal *princ,
216 const __be32 **_xdr,
217 unsigned int *_toklen)
218{
219 const __be32 *xdr = *_xdr;
220 unsigned int toklen = *_toklen, n_parts, loop, tmp;
221
222 /* there must be at least one name, and at least #names+1 length
223 * words */
224 if (toklen <= 12)
225 return -EINVAL;
226
227 _enter(",{%x,%x,%x},%u",
228 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), toklen);
229
230 n_parts = ntohl(*xdr++);
231 toklen -= 4;
232 if (n_parts <= 0 || n_parts > AFSTOKEN_K5_COMPONENTS_MAX)
233 return -EINVAL;
234 princ->n_name_parts = n_parts;
235
236 if (toklen <= (n_parts + 1) * 4)
237 return -EINVAL;
238
239 princ->name_parts = kcalloc(n_parts, sizeof(char *), GFP_KERNEL);
240 if (!princ->name_parts)
241 return -ENOMEM;
242
243 for (loop = 0; loop < n_parts; loop++) {
244 if (toklen < 4)
245 return -EINVAL;
246 tmp = ntohl(*xdr++);
247 toklen -= 4;
248 if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX)
249 return -EINVAL;
250 if (tmp > toklen)
251 return -EINVAL;
252 princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL);
253 if (!princ->name_parts[loop])
254 return -ENOMEM;
255 memcpy(princ->name_parts[loop], xdr, tmp);
256 princ->name_parts[loop][tmp] = 0;
257 tmp = (tmp + 3) & ~3;
258 toklen -= tmp;
259 xdr += tmp >> 2;
260 }
261
262 if (toklen < 4)
263 return -EINVAL;
264 tmp = ntohl(*xdr++);
265 toklen -= 4;
266 if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX)
267 return -EINVAL;
268 if (tmp > toklen)
269 return -EINVAL;
270 princ->realm = kmalloc(tmp + 1, GFP_KERNEL);
271 if (!princ->realm)
272 return -ENOMEM;
273 memcpy(princ->realm, xdr, tmp);
274 princ->realm[tmp] = 0;
275 tmp = (tmp + 3) & ~3;
276 toklen -= tmp;
277 xdr += tmp >> 2;
278
279 _debug("%s/...@%s", princ->name_parts[0], princ->realm);
280
281 *_xdr = xdr;
282 *_toklen = toklen;
283 _leave(" = 0 [toklen=%u]", toklen);
284 return 0;
285}
286
287/*
288 * extract a piece of krb5 tagged data
289 */
290static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td,
291 size_t max_data_size,
292 const __be32 **_xdr,
293 unsigned int *_toklen)
294{
295 const __be32 *xdr = *_xdr;
296 unsigned int toklen = *_toklen, len;
297
298 /* there must be at least one tag and one length word */
299 if (toklen <= 8)
300 return -EINVAL;
301
302 _enter(",%zu,{%x,%x},%u",
303 max_data_size, ntohl(xdr[0]), ntohl(xdr[1]), toklen);
304
305 td->tag = ntohl(*xdr++);
306 len = ntohl(*xdr++);
307 toklen -= 8;
308 if (len > max_data_size)
309 return -EINVAL;
310 td->data_len = len;
311
312 if (len > 0) {
313 td->data = kmemdup(xdr, len, GFP_KERNEL);
314 if (!td->data)
315 return -ENOMEM;
316 len = (len + 3) & ~3;
317 toklen -= len;
318 xdr += len >> 2;
319 }
320
321 _debug("tag %x len %x", td->tag, td->data_len);
322
323 *_xdr = xdr;
324 *_toklen = toklen;
325 _leave(" = 0 [toklen=%u]", toklen);
326 return 0;
327}
328
329/*
330 * extract an array of tagged data
331 */
332static int rxrpc_krb5_decode_tagged_array(struct krb5_tagged_data **_td,
333 u8 *_n_elem,
334 u8 max_n_elem,
335 size_t max_elem_size,
336 const __be32 **_xdr,
337 unsigned int *_toklen)
338{
339 struct krb5_tagged_data *td;
340 const __be32 *xdr = *_xdr;
341 unsigned int toklen = *_toklen, n_elem, loop;
342 int ret;
343
344 /* there must be at least one count */
345 if (toklen < 4)
346 return -EINVAL;
347
348 _enter(",,%u,%zu,{%x},%u",
349 max_n_elem, max_elem_size, ntohl(xdr[0]), toklen);
350
351 n_elem = ntohl(*xdr++);
352 toklen -= 4;
353 if (n_elem > max_n_elem)
354 return -EINVAL;
355 *_n_elem = n_elem;
356 if (n_elem > 0) {
357 if (toklen <= (n_elem + 1) * 4)
358 return -EINVAL;
359
360 _debug("n_elem %d", n_elem);
361
362 td = kcalloc(n_elem, sizeof(struct krb5_tagged_data),
363 GFP_KERNEL);
364 if (!td)
365 return -ENOMEM;
366 *_td = td;
367
368 for (loop = 0; loop < n_elem; loop++) {
369 ret = rxrpc_krb5_decode_tagged_data(&td[loop],
370 max_elem_size,
371 &xdr, &toklen);
372 if (ret < 0)
373 return ret;
374 }
375 }
376
377 *_xdr = xdr;
378 *_toklen = toklen;
379 _leave(" = 0 [toklen=%u]", toklen);
380 return 0;
381}
382
383/*
384 * extract a krb5 ticket
385 */
386static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen,
387 const __be32 **_xdr, unsigned int *_toklen)
388{
389 const __be32 *xdr = *_xdr;
390 unsigned int toklen = *_toklen, len;
391
392 /* there must be at least one length word */
393 if (toklen <= 4)
394 return -EINVAL;
395
396 _enter(",{%x},%u", ntohl(xdr[0]), toklen);
397
398 len = ntohl(*xdr++);
399 toklen -= 4;
400 if (len > AFSTOKEN_K5_TIX_MAX)
401 return -EINVAL;
402 *_tktlen = len;
403
404 _debug("ticket len %u", len);
405
406 if (len > 0) {
407 *_ticket = kmemdup(xdr, len, GFP_KERNEL);
408 if (!*_ticket)
409 return -ENOMEM;
410 len = (len + 3) & ~3;
411 toklen -= len;
412 xdr += len >> 2;
413 }
414
415 *_xdr = xdr;
416 *_toklen = toklen;
417 _leave(" = 0 [toklen=%u]", toklen);
418 return 0;
419}
420
421/*
422 * parse an RxK5 type XDR format token
423 * - the caller guarantees we have at least 4 words
424 */
425static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
426 size_t datalen,
427 const __be32 *xdr, unsigned int toklen)
428{
429 struct rxrpc_key_token *token, **pptoken;
430 struct rxk5_key *rxk5;
431 const __be32 *end_xdr = xdr + (toklen >> 2);
432 int ret;
433
434 _enter(",{%x,%x,%x,%x},%u",
435 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
436 toklen);
437
438 /* reserve some payload space for this subkey - the length of the token
439 * is a reasonable approximation */
440 prep->quotalen = datalen + toklen;
441
442 token = kzalloc(sizeof(*token), GFP_KERNEL);
443 if (!token)
444 return -ENOMEM;
445
446 rxk5 = kzalloc(sizeof(*rxk5), GFP_KERNEL);
447 if (!rxk5) {
448 kfree(token);
449 return -ENOMEM;
450 }
451
452 token->security_index = RXRPC_SECURITY_RXK5;
453 token->k5 = rxk5;
454
455 /* extract the principals */
456 ret = rxrpc_krb5_decode_principal(&rxk5->client, &xdr, &toklen);
457 if (ret < 0)
458 goto error;
459 ret = rxrpc_krb5_decode_principal(&rxk5->server, &xdr, &toklen);
460 if (ret < 0)
461 goto error;
462
463 /* extract the session key and the encoding type (the tag field ->
464 * ENCTYPE_xxx) */
465 ret = rxrpc_krb5_decode_tagged_data(&rxk5->session, AFSTOKEN_DATA_MAX,
466 &xdr, &toklen);
467 if (ret < 0)
468 goto error;
469
470 if (toklen < 4 * 8 + 2 * 4)
471 goto inval;
472 rxk5->authtime = be64_to_cpup((const __be64 *) xdr);
473 xdr += 2;
474 rxk5->starttime = be64_to_cpup((const __be64 *) xdr);
475 xdr += 2;
476 rxk5->endtime = be64_to_cpup((const __be64 *) xdr);
477 xdr += 2;
478 rxk5->renew_till = be64_to_cpup((const __be64 *) xdr);
479 xdr += 2;
480 rxk5->is_skey = ntohl(*xdr++);
481 rxk5->flags = ntohl(*xdr++);
482 toklen -= 4 * 8 + 2 * 4;
483
484 _debug("times: a=%llx s=%llx e=%llx rt=%llx",
485 rxk5->authtime, rxk5->starttime, rxk5->endtime,
486 rxk5->renew_till);
487 _debug("is_skey=%x flags=%x", rxk5->is_skey, rxk5->flags);
488
489 /* extract the permitted client addresses */
490 ret = rxrpc_krb5_decode_tagged_array(&rxk5->addresses,
491 &rxk5->n_addresses,
492 AFSTOKEN_K5_ADDRESSES_MAX,
493 AFSTOKEN_DATA_MAX,
494 &xdr, &toklen);
495 if (ret < 0)
496 goto error;
497
498 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
499
500 /* extract the tickets */
501 ret = rxrpc_krb5_decode_ticket(&rxk5->ticket, &rxk5->ticket_len,
502 &xdr, &toklen);
503 if (ret < 0)
504 goto error;
505 ret = rxrpc_krb5_decode_ticket(&rxk5->ticket2, &rxk5->ticket2_len,
506 &xdr, &toklen);
507 if (ret < 0)
508 goto error;
509
510 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
511
512 /* extract the typed auth data */
513 ret = rxrpc_krb5_decode_tagged_array(&rxk5->authdata,
514 &rxk5->n_authdata,
515 AFSTOKEN_K5_AUTHDATA_MAX,
516 AFSTOKEN_BDATALN_MAX,
517 &xdr, &toklen);
518 if (ret < 0)
519 goto error;
520
521 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen);
522
523 if (toklen != 0)
524 goto inval;
525
526 /* attach the payload */
527 for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
528 *pptoken;
529 pptoken = &(*pptoken)->next)
530 continue;
531 *pptoken = token;
532 if (token->kad->expiry < prep->expiry)
533 prep->expiry = token->kad->expiry;
534
535 _leave(" = 0");
536 return 0;
537
538inval:
539 ret = -EINVAL;
540error:
541 rxrpc_rxk5_free(rxk5);
542 kfree(token);
543 _leave(" = %d", ret);
544 return ret;
545}
546
547/*
548 * attempt to parse the data as the XDR format
549 * - the caller guarantees we have more than 7 words
550 */
551static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
552{
553 const __be32 *xdr = prep->data, *token;
554 const char *cp;
555 unsigned int len, tmp, loop, ntoken, toklen, sec_ix;
556 size_t datalen = prep->datalen;
557 int ret;
558
559 _enter(",{%x,%x,%x,%x},%zu",
560 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
561 prep->datalen);
562
563 if (datalen > AFSTOKEN_LENGTH_MAX)
564 goto not_xdr;
565
566 /* XDR is an array of __be32's */
567 if (datalen & 3)
568 goto not_xdr;
569
570 /* the flags should be 0 (the setpag bit must be handled by
571 * userspace) */
572 if (ntohl(*xdr++) != 0)
573 goto not_xdr;
574 datalen -= 4;
575
576 /* check the cell name */
577 len = ntohl(*xdr++);
578 if (len < 1 || len > AFSTOKEN_CELL_MAX)
579 goto not_xdr;
580 datalen -= 4;
581 tmp = (len + 3) & ~3;
582 if (tmp > datalen)
583 goto not_xdr;
584
585 cp = (const char *) xdr;
586 for (loop = 0; loop < len; loop++)
587 if (!isprint(cp[loop]))
588 goto not_xdr;
589 if (len < tmp)
590 for (; loop < tmp; loop++)
591 if (cp[loop])
592 goto not_xdr;
593 _debug("cellname: [%u/%u] '%*.*s'",
594 len, tmp, len, len, (const char *) xdr);
595 datalen -= tmp;
596 xdr += tmp >> 2;
597
598 /* get the token count */
599 if (datalen < 12)
600 goto not_xdr;
601 ntoken = ntohl(*xdr++);
602 datalen -= 4;
603 _debug("ntoken: %x", ntoken);
604 if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
605 goto not_xdr;
606
607 /* check each token wrapper */
608 token = xdr;
609 loop = ntoken;
610 do {
611 if (datalen < 8)
612 goto not_xdr;
613 toklen = ntohl(*xdr++);
614 sec_ix = ntohl(*xdr);
615 datalen -= 4;
616 _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
617 if (toklen < 20 || toklen > datalen)
618 goto not_xdr;
619 datalen -= (toklen + 3) & ~3;
620 xdr += (toklen + 3) >> 2;
621
622 } while (--loop > 0);
623
624 _debug("remainder: %zu", datalen);
625 if (datalen != 0)
626 goto not_xdr;
627
628 /* okay: we're going to assume it's valid XDR format
629 * - we ignore the cellname, relying on the key to be correctly named
630 */
631 do {
632 xdr = token;
633 toklen = ntohl(*xdr++);
634 token = xdr + ((toklen + 3) >> 2);
635 sec_ix = ntohl(*xdr++);
636 toklen -= 4;
637
638 _debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token);
639
640 switch (sec_ix) {
641 case RXRPC_SECURITY_RXKAD:
642 ret = rxrpc_preparse_xdr_rxkad(prep, datalen, xdr, toklen);
643 if (ret != 0)
644 goto error;
645 break;
646
647 case RXRPC_SECURITY_RXK5:
648 ret = rxrpc_preparse_xdr_rxk5(prep, datalen, xdr, toklen);
649 if (ret != 0)
650 goto error;
651 break;
652
653 default:
654 ret = -EPROTONOSUPPORT;
655 goto error;
656 }
657
658 } while (--ntoken > 0);
659
660 _leave(" = 0");
661 return 0;
662
663not_xdr:
664 _leave(" = -EPROTO");
665 return -EPROTO;
666error:
667 _leave(" = %d", ret);
668 return ret;
669}
670
671/*
672 * Preparse an rxrpc defined key.
673 *
674 * Data should be of the form:
675 * OFFSET LEN CONTENT
676 * 0 4 key interface version number
677 * 4 2 security index (type)
678 * 6 2 ticket length
679 * 8 4 key expiry time (time_t)
680 * 12 4 kvno
681 * 16 8 session key
682 * 24 [len] ticket
683 *
684 * if no data is provided, then a no-security key is made
685 */
686static int rxrpc_preparse(struct key_preparsed_payload *prep)
687{
688 const struct rxrpc_key_data_v1 *v1;
689 struct rxrpc_key_token *token, **pp;
690 size_t plen;
691 u32 kver;
692 int ret;
693
694 _enter("%zu", prep->datalen);
695
696 /* handle a no-security key */
697 if (!prep->data && prep->datalen == 0)
698 return 0;
699
700 /* determine if the XDR payload format is being used */
701 if (prep->datalen > 7 * 4) {
702 ret = rxrpc_preparse_xdr(prep);
703 if (ret != -EPROTO)
704 return ret;
705 }
706
707 /* get the key interface version number */
708 ret = -EINVAL;
709 if (prep->datalen <= 4 || !prep->data)
710 goto error;
711 memcpy(&kver, prep->data, sizeof(kver));
712 prep->data += sizeof(kver);
713 prep->datalen -= sizeof(kver);
714
715 _debug("KEY I/F VERSION: %u", kver);
716
717 ret = -EKEYREJECTED;
718 if (kver != 1)
719 goto error;
720
721 /* deal with a version 1 key */
722 ret = -EINVAL;
723 if (prep->datalen < sizeof(*v1))
724 goto error;
725
726 v1 = prep->data;
727 if (prep->datalen != sizeof(*v1) + v1->ticket_length)
728 goto error;
729
730 _debug("SCIX: %u", v1->security_index);
731 _debug("TLEN: %u", v1->ticket_length);
732 _debug("EXPY: %x", v1->expiry);
733 _debug("KVNO: %u", v1->kvno);
734 _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
735 v1->session_key[0], v1->session_key[1],
736 v1->session_key[2], v1->session_key[3],
737 v1->session_key[4], v1->session_key[5],
738 v1->session_key[6], v1->session_key[7]);
739 if (v1->ticket_length >= 8)
740 _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
741 v1->ticket[0], v1->ticket[1],
742 v1->ticket[2], v1->ticket[3],
743 v1->ticket[4], v1->ticket[5],
744 v1->ticket[6], v1->ticket[7]);
745
746 ret = -EPROTONOSUPPORT;
747 if (v1->security_index != RXRPC_SECURITY_RXKAD)
748 goto error;
749
750 plen = sizeof(*token->kad) + v1->ticket_length;
751 prep->quotalen = plen + sizeof(*token);
752
753 ret = -ENOMEM;
754 token = kzalloc(sizeof(*token), GFP_KERNEL);
755 if (!token)
756 goto error;
757 token->kad = kzalloc(plen, GFP_KERNEL);
758 if (!token->kad)
759 goto error_free;
760
761 token->security_index = RXRPC_SECURITY_RXKAD;
762 token->kad->ticket_len = v1->ticket_length;
763 token->kad->expiry = v1->expiry;
764 token->kad->kvno = v1->kvno;
765 memcpy(&token->kad->session_key, &v1->session_key, 8);
766 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
767
768 /* count the number of tokens attached */
769 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
770
771 /* attach the data */
772 pp = (struct rxrpc_key_token **)&prep->payload.data[0];
773 while (*pp)
774 pp = &(*pp)->next;
775 *pp = token;
776 if (token->kad->expiry < prep->expiry)
777 prep->expiry = token->kad->expiry;
778 token = NULL;
779 ret = 0;
780
781error_free:
782 kfree(token);
783error:
784 return ret;
785}
786
787/*
788 * Free token list.
789 */
790static void rxrpc_free_token_list(struct rxrpc_key_token *token)
791{
792 struct rxrpc_key_token *next;
793
794 for (; token; token = next) {
795 next = token->next;
796 switch (token->security_index) {
797 case RXRPC_SECURITY_RXKAD:
798 kfree(token->kad);
799 break;
800 case RXRPC_SECURITY_RXK5:
801 if (token->k5)
802 rxrpc_rxk5_free(token->k5);
803 break;
804 default:
805 pr_err("Unknown token type %x on rxrpc key\n",
806 token->security_index);
807 BUG();
808 }
809
810 kfree(token);
811 }
812}
813
814/*
815 * Clean up preparse data.
816 */
817static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
818{
819 rxrpc_free_token_list(prep->payload.data[0]);
820}
821
822/*
823 * Preparse a server secret key.
824 *
825 * The data should be the 8-byte secret key.
826 */
827static int rxrpc_preparse_s(struct key_preparsed_payload *prep)
828{
829 struct crypto_skcipher *ci;
830
831 _enter("%zu", prep->datalen);
832
833 if (prep->datalen != 8)
834 return -EINVAL;
835
836 memcpy(&prep->payload.data[2], prep->data, 8);
837
838 ci = crypto_alloc_skcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC);
839 if (IS_ERR(ci)) {
840 _leave(" = %ld", PTR_ERR(ci));
841 return PTR_ERR(ci);
842 }
843
844 if (crypto_skcipher_setkey(ci, prep->data, 8) < 0)
845 BUG();
846
847 prep->payload.data[0] = ci;
848 _leave(" = 0");
849 return 0;
850}
851
852/*
853 * Clean up preparse data.
854 */
855static void rxrpc_free_preparse_s(struct key_preparsed_payload *prep)
856{
857 if (prep->payload.data[0])
858 crypto_free_skcipher(prep->payload.data[0]);
859}
860
861/*
862 * dispose of the data dangling from the corpse of a rxrpc key
863 */
864static void rxrpc_destroy(struct key *key)
865{
866 rxrpc_free_token_list(key->payload.data[0]);
867}
868
869/*
870 * dispose of the data dangling from the corpse of a rxrpc key
871 */
872static void rxrpc_destroy_s(struct key *key)
873{
874 if (key->payload.data[0]) {
875 crypto_free_skcipher(key->payload.data[0]);
876 key->payload.data[0] = NULL;
877 }
878}
879
880/*
881 * describe the rxrpc key
882 */
883static void rxrpc_describe(const struct key *key, struct seq_file *m)
884{
885 seq_puts(m, key->description);
886}
887
888/*
889 * grab the security key for a socket
890 */
891int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
892{
893 struct key *key;
894 char *description;
895
896 _enter("");
897
898 if (optlen <= 0 || optlen > PAGE_SIZE - 1)
899 return -EINVAL;
900
901 description = memdup_user_nul(optval, optlen);
902 if (IS_ERR(description))
903 return PTR_ERR(description);
904
905 key = request_key(&key_type_rxrpc, description, NULL);
906 if (IS_ERR(key)) {
907 kfree(description);
908 _leave(" = %ld", PTR_ERR(key));
909 return PTR_ERR(key);
910 }
911
912 rx->key = key;
913 kfree(description);
914 _leave(" = 0 [key %x]", key->serial);
915 return 0;
916}
917
918/*
919 * grab the security keyring for a server socket
920 */
921int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
922 int optlen)
923{
924 struct key *key;
925 char *description;
926
927 _enter("");
928
929 if (optlen <= 0 || optlen > PAGE_SIZE - 1)
930 return -EINVAL;
931
932 description = memdup_user_nul(optval, optlen);
933 if (IS_ERR(description))
934 return PTR_ERR(description);
935
936 key = request_key(&key_type_keyring, description, NULL);
937 if (IS_ERR(key)) {
938 kfree(description);
939 _leave(" = %ld", PTR_ERR(key));
940 return PTR_ERR(key);
941 }
942
943 rx->securities = key;
944 kfree(description);
945 _leave(" = 0 [key %x]", key->serial);
946 return 0;
947}
948
949/*
950 * generate a server data key
951 */
952int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
953 const void *session_key,
954 time_t expiry,
955 u32 kvno)
956{
957 const struct cred *cred = current_cred();
958 struct key *key;
959 int ret;
960
961 struct {
962 u32 kver;
963 struct rxrpc_key_data_v1 v1;
964 } data;
965
966 _enter("");
967
968 key = key_alloc(&key_type_rxrpc, "x",
969 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
970 KEY_ALLOC_NOT_IN_QUOTA, NULL);
971 if (IS_ERR(key)) {
972 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
973 return -ENOMEM;
974 }
975
976 _debug("key %d", key_serial(key));
977
978 data.kver = 1;
979 data.v1.security_index = RXRPC_SECURITY_RXKAD;
980 data.v1.ticket_length = 0;
981 data.v1.expiry = expiry;
982 data.v1.kvno = 0;
983
984 memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
985
986 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
987 if (ret < 0)
988 goto error;
989
990 conn->key = key;
991 _leave(" = 0 [%d]", key_serial(key));
992 return 0;
993
994error:
995 key_revoke(key);
996 key_put(key);
997 _leave(" = -ENOMEM [ins %d]", ret);
998 return -ENOMEM;
999}
1000EXPORT_SYMBOL(rxrpc_get_server_data_key);
1001
1002/**
1003 * rxrpc_get_null_key - Generate a null RxRPC key
1004 * @keyname: The name to give the key.
1005 *
1006 * Generate a null RxRPC key that can be used to indicate anonymous security is
1007 * required for a particular domain.
1008 */
1009struct key *rxrpc_get_null_key(const char *keyname)
1010{
1011 const struct cred *cred = current_cred();
1012 struct key *key;
1013 int ret;
1014
1015 key = key_alloc(&key_type_rxrpc, keyname,
1016 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
1017 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
1018 if (IS_ERR(key))
1019 return key;
1020
1021 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
1022 if (ret < 0) {
1023 key_revoke(key);
1024 key_put(key);
1025 return ERR_PTR(ret);
1026 }
1027
1028 return key;
1029}
1030EXPORT_SYMBOL(rxrpc_get_null_key);
1031
1032/*
1033 * read the contents of an rxrpc key
1034 * - this returns the result in XDR form
1035 */
1036static long rxrpc_read(const struct key *key,
1037 char __user *buffer, size_t buflen)
1038{
1039 const struct rxrpc_key_token *token;
1040 const struct krb5_principal *princ;
1041 size_t size;
1042 __be32 __user *xdr, *oldxdr;
1043 u32 cnlen, toksize, ntoks, tok, zero;
1044 u16 toksizes[AFSTOKEN_MAX];
1045 int loop;
1046
1047 _enter("");
1048
1049 /* we don't know what form we should return non-AFS keys in */
1050 if (memcmp(key->description, "afs@", 4) != 0)
1051 return -EOPNOTSUPP;
1052 cnlen = strlen(key->description + 4);
1053
1054#define RND(X) (((X) + 3) & ~3)
1055
1056 /* AFS keys we return in XDR form, so we need to work out the size of
1057 * the XDR */
1058 size = 2 * 4; /* flags, cellname len */
1059 size += RND(cnlen); /* cellname */
1060 size += 1 * 4; /* token count */
1061
1062 ntoks = 0;
1063 for (token = key->payload.data[0]; token; token = token->next) {
1064 toksize = 4; /* sec index */
1065
1066 switch (token->security_index) {
1067 case RXRPC_SECURITY_RXKAD:
1068 toksize += 8 * 4; /* viceid, kvno, key*2, begin,
1069 * end, primary, tktlen */
1070 toksize += RND(token->kad->ticket_len);
1071 break;
1072
1073 case RXRPC_SECURITY_RXK5:
1074 princ = &token->k5->client;
1075 toksize += 4 + princ->n_name_parts * 4;
1076 for (loop = 0; loop < princ->n_name_parts; loop++)
1077 toksize += RND(strlen(princ->name_parts[loop]));
1078 toksize += 4 + RND(strlen(princ->realm));
1079
1080 princ = &token->k5->server;
1081 toksize += 4 + princ->n_name_parts * 4;
1082 for (loop = 0; loop < princ->n_name_parts; loop++)
1083 toksize += RND(strlen(princ->name_parts[loop]));
1084 toksize += 4 + RND(strlen(princ->realm));
1085
1086 toksize += 8 + RND(token->k5->session.data_len);
1087
1088 toksize += 4 * 8 + 2 * 4;
1089
1090 toksize += 4 + token->k5->n_addresses * 8;
1091 for (loop = 0; loop < token->k5->n_addresses; loop++)
1092 toksize += RND(token->k5->addresses[loop].data_len);
1093
1094 toksize += 4 + RND(token->k5->ticket_len);
1095 toksize += 4 + RND(token->k5->ticket2_len);
1096
1097 toksize += 4 + token->k5->n_authdata * 8;
1098 for (loop = 0; loop < token->k5->n_authdata; loop++)
1099 toksize += RND(token->k5->authdata[loop].data_len);
1100 break;
1101
1102 default: /* we have a ticket we can't encode */
1103 BUG();
1104 continue;
1105 }
1106
1107 _debug("token[%u]: toksize=%u", ntoks, toksize);
1108 ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
1109
1110 toksizes[ntoks++] = toksize;
1111 size += toksize + 4; /* each token has a length word */
1112 }
1113
1114#undef RND
1115
1116 if (!buffer || buflen < size)
1117 return size;
1118
1119 xdr = (__be32 __user *) buffer;
1120 zero = 0;
1121#define ENCODE(x) \
1122 do { \
1123 __be32 y = htonl(x); \
1124 if (put_user(y, xdr++) < 0) \
1125 goto fault; \
1126 } while(0)
1127#define ENCODE_DATA(l, s) \
1128 do { \
1129 u32 _l = (l); \
1130 ENCODE(l); \
1131 if (copy_to_user(xdr, (s), _l) != 0) \
1132 goto fault; \
1133 if (_l & 3 && \
1134 copy_to_user((u8 __user *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \
1135 goto fault; \
1136 xdr += (_l + 3) >> 2; \
1137 } while(0)
1138#define ENCODE64(x) \
1139 do { \
1140 __be64 y = cpu_to_be64(x); \
1141 if (copy_to_user(xdr, &y, 8) != 0) \
1142 goto fault; \
1143 xdr += 8 >> 2; \
1144 } while(0)
1145#define ENCODE_STR(s) \
1146 do { \
1147 const char *_s = (s); \
1148 ENCODE_DATA(strlen(_s), _s); \
1149 } while(0)
1150
1151 ENCODE(0); /* flags */
1152 ENCODE_DATA(cnlen, key->description + 4); /* cellname */
1153 ENCODE(ntoks);
1154
1155 tok = 0;
1156 for (token = key->payload.data[0]; token; token = token->next) {
1157 toksize = toksizes[tok++];
1158 ENCODE(toksize);
1159 oldxdr = xdr;
1160 ENCODE(token->security_index);
1161
1162 switch (token->security_index) {
1163 case RXRPC_SECURITY_RXKAD:
1164 ENCODE(token->kad->vice_id);
1165 ENCODE(token->kad->kvno);
1166 ENCODE_DATA(8, token->kad->session_key);
1167 ENCODE(token->kad->start);
1168 ENCODE(token->kad->expiry);
1169 ENCODE(token->kad->primary_flag);
1170 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
1171 break;
1172
1173 case RXRPC_SECURITY_RXK5:
1174 princ = &token->k5->client;
1175 ENCODE(princ->n_name_parts);
1176 for (loop = 0; loop < princ->n_name_parts; loop++)
1177 ENCODE_STR(princ->name_parts[loop]);
1178 ENCODE_STR(princ->realm);
1179
1180 princ = &token->k5->server;
1181 ENCODE(princ->n_name_parts);
1182 for (loop = 0; loop < princ->n_name_parts; loop++)
1183 ENCODE_STR(princ->name_parts[loop]);
1184 ENCODE_STR(princ->realm);
1185
1186 ENCODE(token->k5->session.tag);
1187 ENCODE_DATA(token->k5->session.data_len,
1188 token->k5->session.data);
1189
1190 ENCODE64(token->k5->authtime);
1191 ENCODE64(token->k5->starttime);
1192 ENCODE64(token->k5->endtime);
1193 ENCODE64(token->k5->renew_till);
1194 ENCODE(token->k5->is_skey);
1195 ENCODE(token->k5->flags);
1196
1197 ENCODE(token->k5->n_addresses);
1198 for (loop = 0; loop < token->k5->n_addresses; loop++) {
1199 ENCODE(token->k5->addresses[loop].tag);
1200 ENCODE_DATA(token->k5->addresses[loop].data_len,
1201 token->k5->addresses[loop].data);
1202 }
1203
1204 ENCODE_DATA(token->k5->ticket_len, token->k5->ticket);
1205 ENCODE_DATA(token->k5->ticket2_len, token->k5->ticket2);
1206
1207 ENCODE(token->k5->n_authdata);
1208 for (loop = 0; loop < token->k5->n_authdata; loop++) {
1209 ENCODE(token->k5->authdata[loop].tag);
1210 ENCODE_DATA(token->k5->authdata[loop].data_len,
1211 token->k5->authdata[loop].data);
1212 }
1213 break;
1214
1215 default:
1216 BUG();
1217 break;
1218 }
1219
1220 ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
1221 toksize);
1222 }
1223
1224#undef ENCODE_STR
1225#undef ENCODE_DATA
1226#undef ENCODE64
1227#undef ENCODE
1228
1229 ASSERTCMP(tok, ==, ntoks);
1230 ASSERTCMP((char __user *) xdr - buffer, ==, size);
1231 _leave(" = %zu", size);
1232 return size;
1233
1234fault:
1235 _leave(" = -EFAULT");
1236 return -EFAULT;
1237}