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