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