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