linux/net/rxrpc/key.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* RxRPC key management
   3 *
   4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 *
   7 * RxRPC keys should have a description of describing their purpose:
   8 *      "afs@example.com"
   9 */
  10
  11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12
  13#include <crypto/skcipher.h>
  14#include <linux/module.h>
  15#include <linux/net.h>
  16#include <linux/skbuff.h>
  17#include <linux/key-type.h>
  18#include <linux/ctype.h>
  19#include <linux/slab.h>
  20#include <net/sock.h>
  21#include <net/af_rxrpc.h>
  22#include <keys/rxrpc-type.h>
  23#include <keys/user-type.h>
  24#include "ar-internal.h"
  25
  26static int rxrpc_preparse(struct key_preparsed_payload *);
  27static void rxrpc_free_preparse(struct key_preparsed_payload *);
  28static void rxrpc_destroy(struct key *);
  29static void rxrpc_describe(const struct key *, struct seq_file *);
  30static long rxrpc_read(const struct key *, char *, size_t);
  31
  32/*
  33 * rxrpc defined keys take an arbitrary string as the description and an
  34 * arbitrary blob of data as the payload
  35 */
  36struct key_type key_type_rxrpc = {
  37        .name           = "rxrpc",
  38        .flags          = KEY_TYPE_NET_DOMAIN,
  39        .preparse       = rxrpc_preparse,
  40        .free_preparse  = rxrpc_free_preparse,
  41        .instantiate    = generic_key_instantiate,
  42        .destroy        = rxrpc_destroy,
  43        .describe       = rxrpc_describe,
  44        .read           = rxrpc_read,
  45};
  46EXPORT_SYMBOL(key_type_rxrpc);
  47
  48/*
  49 * parse an RxKAD type XDR format token
  50 * - the caller guarantees we have at least 4 words
  51 */
  52static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
  53                                    size_t datalen,
  54                                    const __be32 *xdr, unsigned int toklen)
  55{
  56        struct rxrpc_key_token *token, **pptoken;
  57        time64_t expiry;
  58        size_t plen;
  59        u32 tktlen;
  60
  61        _enter(",{%x,%x,%x,%x},%u",
  62               ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
  63               toklen);
  64
  65        if (toklen <= 8 * 4)
  66                return -EKEYREJECTED;
  67        tktlen = ntohl(xdr[7]);
  68        _debug("tktlen: %x", tktlen);
  69        if (tktlen > AFSTOKEN_RK_TIX_MAX)
  70                return -EKEYREJECTED;
  71        if (toklen < 8 * 4 + tktlen)
  72                return -EKEYREJECTED;
  73
  74        plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
  75        prep->quotalen = datalen + plen;
  76
  77        plen -= sizeof(*token);
  78        token = kzalloc(sizeof(*token), GFP_KERNEL);
  79        if (!token)
  80                return -ENOMEM;
  81
  82        token->kad = kzalloc(plen, GFP_KERNEL);
  83        if (!token->kad) {
  84                kfree(token);
  85                return -ENOMEM;
  86        }
  87
  88        token->security_index   = RXRPC_SECURITY_RXKAD;
  89        token->kad->ticket_len  = tktlen;
  90        token->kad->vice_id     = ntohl(xdr[0]);
  91        token->kad->kvno        = ntohl(xdr[1]);
  92        token->kad->start       = ntohl(xdr[4]);
  93        token->kad->expiry      = ntohl(xdr[5]);
  94        token->kad->primary_flag = ntohl(xdr[6]);
  95        memcpy(&token->kad->session_key, &xdr[2], 8);
  96        memcpy(&token->kad->ticket, &xdr[8], tktlen);
  97
  98        _debug("SCIX: %u", token->security_index);
  99        _debug("TLEN: %u", token->kad->ticket_len);
 100        _debug("EXPY: %x", token->kad->expiry);
 101        _debug("KVNO: %u", token->kad->kvno);
 102        _debug("PRIM: %u", token->kad->primary_flag);
 103        _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
 104               token->kad->session_key[0], token->kad->session_key[1],
 105               token->kad->session_key[2], token->kad->session_key[3],
 106               token->kad->session_key[4], token->kad->session_key[5],
 107               token->kad->session_key[6], token->kad->session_key[7]);
 108        if (token->kad->ticket_len >= 8)
 109                _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
 110                       token->kad->ticket[0], token->kad->ticket[1],
 111                       token->kad->ticket[2], token->kad->ticket[3],
 112                       token->kad->ticket[4], token->kad->ticket[5],
 113                       token->kad->ticket[6], token->kad->ticket[7]);
 114
 115        /* count the number of tokens attached */
 116        prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
 117
 118        /* attach the data */
 119        for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
 120             *pptoken;
 121             pptoken = &(*pptoken)->next)
 122                continue;
 123        *pptoken = token;
 124        expiry = rxrpc_u32_to_time64(token->kad->expiry);
 125        if (expiry < prep->expiry)
 126                prep->expiry = expiry;
 127
 128        _leave(" = 0");
 129        return 0;
 130}
 131
 132/*
 133 * attempt to parse the data as the XDR format
 134 * - the caller guarantees we have more than 7 words
 135 */
 136static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
 137{
 138        const __be32 *xdr = prep->data, *token, *p;
 139        const char *cp;
 140        unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
 141        size_t datalen = prep->datalen;
 142        int ret, ret2;
 143
 144        _enter(",{%x,%x,%x,%x},%zu",
 145               ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
 146               prep->datalen);
 147
 148        if (datalen > AFSTOKEN_LENGTH_MAX)
 149                goto not_xdr;
 150
 151        /* XDR is an array of __be32's */
 152        if (datalen & 3)
 153                goto not_xdr;
 154
 155        /* the flags should be 0 (the setpag bit must be handled by
 156         * userspace) */
 157        if (ntohl(*xdr++) != 0)
 158                goto not_xdr;
 159        datalen -= 4;
 160
 161        /* check the cell name */
 162        len = ntohl(*xdr++);
 163        if (len < 1 || len > AFSTOKEN_CELL_MAX)
 164                goto not_xdr;
 165        datalen -= 4;
 166        paddedlen = (len + 3) & ~3;
 167        if (paddedlen > datalen)
 168                goto not_xdr;
 169
 170        cp = (const char *) xdr;
 171        for (loop = 0; loop < len; loop++)
 172                if (!isprint(cp[loop]))
 173                        goto not_xdr;
 174        for (; loop < paddedlen; loop++)
 175                if (cp[loop])
 176                        goto not_xdr;
 177        _debug("cellname: [%u/%u] '%*.*s'",
 178               len, paddedlen, len, len, (const char *) xdr);
 179        datalen -= paddedlen;
 180        xdr += paddedlen >> 2;
 181
 182        /* get the token count */
 183        if (datalen < 12)
 184                goto not_xdr;
 185        ntoken = ntohl(*xdr++);
 186        datalen -= 4;
 187        _debug("ntoken: %x", ntoken);
 188        if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
 189                goto not_xdr;
 190
 191        /* check each token wrapper */
 192        p = xdr;
 193        loop = ntoken;
 194        do {
 195                if (datalen < 8)
 196                        goto not_xdr;
 197                toklen = ntohl(*p++);
 198                sec_ix = ntohl(*p);
 199                datalen -= 4;
 200                _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
 201                paddedlen = (toklen + 3) & ~3;
 202                if (toklen < 20 || toklen > datalen || paddedlen > datalen)
 203                        goto not_xdr;
 204                datalen -= paddedlen;
 205                p += paddedlen >> 2;
 206
 207        } while (--loop > 0);
 208
 209        _debug("remainder: %zu", datalen);
 210        if (datalen != 0)
 211                goto not_xdr;
 212
 213        /* okay: we're going to assume it's valid XDR format
 214         * - we ignore the cellname, relying on the key to be correctly named
 215         */
 216        ret = -EPROTONOSUPPORT;
 217        do {
 218                toklen = ntohl(*xdr++);
 219                token = xdr;
 220                xdr += (toklen + 3) / 4;
 221
 222                sec_ix = ntohl(*token++);
 223                toklen -= 4;
 224
 225                _debug("TOKEN type=%x len=%x", sec_ix, toklen);
 226
 227                switch (sec_ix) {
 228                case RXRPC_SECURITY_RXKAD:
 229                        ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen);
 230                        break;
 231                default:
 232                        ret2 = -EPROTONOSUPPORT;
 233                        break;
 234                }
 235
 236                switch (ret2) {
 237                case 0:
 238                        ret = 0;
 239                        break;
 240                case -EPROTONOSUPPORT:
 241                        break;
 242                case -ENOPKG:
 243                        if (ret != 0)
 244                                ret = -ENOPKG;
 245                        break;
 246                default:
 247                        ret = ret2;
 248                        goto error;
 249                }
 250
 251        } while (--ntoken > 0);
 252
 253error:
 254        _leave(" = %d", ret);
 255        return ret;
 256
 257not_xdr:
 258        _leave(" = -EPROTO");
 259        return -EPROTO;
 260}
 261
 262/*
 263 * Preparse an rxrpc defined key.
 264 *
 265 * Data should be of the form:
 266 *      OFFSET  LEN     CONTENT
 267 *      0       4       key interface version number
 268 *      4       2       security index (type)
 269 *      6       2       ticket length
 270 *      8       4       key expiry time (time_t)
 271 *      12      4       kvno
 272 *      16      8       session key
 273 *      24      [len]   ticket
 274 *
 275 * if no data is provided, then a no-security key is made
 276 */
 277static int rxrpc_preparse(struct key_preparsed_payload *prep)
 278{
 279        const struct rxrpc_key_data_v1 *v1;
 280        struct rxrpc_key_token *token, **pp;
 281        time64_t expiry;
 282        size_t plen;
 283        u32 kver;
 284        int ret;
 285
 286        _enter("%zu", prep->datalen);
 287
 288        /* handle a no-security key */
 289        if (!prep->data && prep->datalen == 0)
 290                return 0;
 291
 292        /* determine if the XDR payload format is being used */
 293        if (prep->datalen > 7 * 4) {
 294                ret = rxrpc_preparse_xdr(prep);
 295                if (ret != -EPROTO)
 296                        return ret;
 297        }
 298
 299        /* get the key interface version number */
 300        ret = -EINVAL;
 301        if (prep->datalen <= 4 || !prep->data)
 302                goto error;
 303        memcpy(&kver, prep->data, sizeof(kver));
 304        prep->data += sizeof(kver);
 305        prep->datalen -= sizeof(kver);
 306
 307        _debug("KEY I/F VERSION: %u", kver);
 308
 309        ret = -EKEYREJECTED;
 310        if (kver != 1)
 311                goto error;
 312
 313        /* deal with a version 1 key */
 314        ret = -EINVAL;
 315        if (prep->datalen < sizeof(*v1))
 316                goto error;
 317
 318        v1 = prep->data;
 319        if (prep->datalen != sizeof(*v1) + v1->ticket_length)
 320                goto error;
 321
 322        _debug("SCIX: %u", v1->security_index);
 323        _debug("TLEN: %u", v1->ticket_length);
 324        _debug("EXPY: %x", v1->expiry);
 325        _debug("KVNO: %u", v1->kvno);
 326        _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
 327               v1->session_key[0], v1->session_key[1],
 328               v1->session_key[2], v1->session_key[3],
 329               v1->session_key[4], v1->session_key[5],
 330               v1->session_key[6], v1->session_key[7]);
 331        if (v1->ticket_length >= 8)
 332                _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
 333                       v1->ticket[0], v1->ticket[1],
 334                       v1->ticket[2], v1->ticket[3],
 335                       v1->ticket[4], v1->ticket[5],
 336                       v1->ticket[6], v1->ticket[7]);
 337
 338        ret = -EPROTONOSUPPORT;
 339        if (v1->security_index != RXRPC_SECURITY_RXKAD)
 340                goto error;
 341
 342        plen = sizeof(*token->kad) + v1->ticket_length;
 343        prep->quotalen = plen + sizeof(*token);
 344
 345        ret = -ENOMEM;
 346        token = kzalloc(sizeof(*token), GFP_KERNEL);
 347        if (!token)
 348                goto error;
 349        token->kad = kzalloc(plen, GFP_KERNEL);
 350        if (!token->kad)
 351                goto error_free;
 352
 353        token->security_index           = RXRPC_SECURITY_RXKAD;
 354        token->kad->ticket_len          = v1->ticket_length;
 355        token->kad->expiry              = v1->expiry;
 356        token->kad->kvno                = v1->kvno;
 357        memcpy(&token->kad->session_key, &v1->session_key, 8);
 358        memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
 359
 360        /* count the number of tokens attached */
 361        prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
 362
 363        /* attach the data */
 364        pp = (struct rxrpc_key_token **)&prep->payload.data[0];
 365        while (*pp)
 366                pp = &(*pp)->next;
 367        *pp = token;
 368        expiry = rxrpc_u32_to_time64(token->kad->expiry);
 369        if (expiry < prep->expiry)
 370                prep->expiry = expiry;
 371        token = NULL;
 372        ret = 0;
 373
 374error_free:
 375        kfree(token);
 376error:
 377        return ret;
 378}
 379
 380/*
 381 * Free token list.
 382 */
 383static void rxrpc_free_token_list(struct rxrpc_key_token *token)
 384{
 385        struct rxrpc_key_token *next;
 386
 387        for (; token; token = next) {
 388                next = token->next;
 389                switch (token->security_index) {
 390                case RXRPC_SECURITY_RXKAD:
 391                        kfree(token->kad);
 392                        break;
 393                default:
 394                        pr_err("Unknown token type %x on rxrpc key\n",
 395                               token->security_index);
 396                        BUG();
 397                }
 398
 399                kfree(token);
 400        }
 401}
 402
 403/*
 404 * Clean up preparse data.
 405 */
 406static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
 407{
 408        rxrpc_free_token_list(prep->payload.data[0]);
 409}
 410
 411/*
 412 * dispose of the data dangling from the corpse of a rxrpc key
 413 */
 414static void rxrpc_destroy(struct key *key)
 415{
 416        rxrpc_free_token_list(key->payload.data[0]);
 417}
 418
 419/*
 420 * describe the rxrpc key
 421 */
 422static void rxrpc_describe(const struct key *key, struct seq_file *m)
 423{
 424        const struct rxrpc_key_token *token;
 425        const char *sep = ": ";
 426
 427        seq_puts(m, key->description);
 428
 429        for (token = key->payload.data[0]; token; token = token->next) {
 430                seq_puts(m, sep);
 431
 432                switch (token->security_index) {
 433                case RXRPC_SECURITY_RXKAD:
 434                        seq_puts(m, "ka");
 435                        break;
 436                default: /* we have a ticket we can't encode */
 437                        seq_printf(m, "%u", token->security_index);
 438                        break;
 439                }
 440
 441                sep = " ";
 442        }
 443}
 444
 445/*
 446 * grab the security key for a socket
 447 */
 448int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
 449{
 450        struct key *key;
 451        char *description;
 452
 453        _enter("");
 454
 455        if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities)
 456                return -EINVAL;
 457
 458        description = memdup_sockptr_nul(optval, optlen);
 459        if (IS_ERR(description))
 460                return PTR_ERR(description);
 461
 462        key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
 463        if (IS_ERR(key)) {
 464                kfree(description);
 465                _leave(" = %ld", PTR_ERR(key));
 466                return PTR_ERR(key);
 467        }
 468
 469        rx->key = key;
 470        kfree(description);
 471        _leave(" = 0 [key %x]", key->serial);
 472        return 0;
 473}
 474
 475/*
 476 * generate a server data key
 477 */
 478int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
 479                              const void *session_key,
 480                              time64_t expiry,
 481                              u32 kvno)
 482{
 483        const struct cred *cred = current_cred();
 484        struct key *key;
 485        int ret;
 486
 487        struct {
 488                u32 kver;
 489                struct rxrpc_key_data_v1 v1;
 490        } data;
 491
 492        _enter("");
 493
 494        key = key_alloc(&key_type_rxrpc, "x",
 495                        GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
 496                        KEY_ALLOC_NOT_IN_QUOTA, NULL);
 497        if (IS_ERR(key)) {
 498                _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
 499                return -ENOMEM;
 500        }
 501
 502        _debug("key %d", key_serial(key));
 503
 504        data.kver = 1;
 505        data.v1.security_index = RXRPC_SECURITY_RXKAD;
 506        data.v1.ticket_length = 0;
 507        data.v1.expiry = rxrpc_time64_to_u32(expiry);
 508        data.v1.kvno = 0;
 509
 510        memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
 511
 512        ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
 513        if (ret < 0)
 514                goto error;
 515
 516        conn->params.key = key;
 517        _leave(" = 0 [%d]", key_serial(key));
 518        return 0;
 519
 520error:
 521        key_revoke(key);
 522        key_put(key);
 523        _leave(" = -ENOMEM [ins %d]", ret);
 524        return -ENOMEM;
 525}
 526EXPORT_SYMBOL(rxrpc_get_server_data_key);
 527
 528/**
 529 * rxrpc_get_null_key - Generate a null RxRPC key
 530 * @keyname: The name to give the key.
 531 *
 532 * Generate a null RxRPC key that can be used to indicate anonymous security is
 533 * required for a particular domain.
 534 */
 535struct key *rxrpc_get_null_key(const char *keyname)
 536{
 537        const struct cred *cred = current_cred();
 538        struct key *key;
 539        int ret;
 540
 541        key = key_alloc(&key_type_rxrpc, keyname,
 542                        GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
 543                        KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
 544        if (IS_ERR(key))
 545                return key;
 546
 547        ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
 548        if (ret < 0) {
 549                key_revoke(key);
 550                key_put(key);
 551                return ERR_PTR(ret);
 552        }
 553
 554        return key;
 555}
 556EXPORT_SYMBOL(rxrpc_get_null_key);
 557
 558/*
 559 * read the contents of an rxrpc key
 560 * - this returns the result in XDR form
 561 */
 562static long rxrpc_read(const struct key *key,
 563                       char *buffer, size_t buflen)
 564{
 565        const struct rxrpc_key_token *token;
 566        size_t size;
 567        __be32 *xdr, *oldxdr;
 568        u32 cnlen, toksize, ntoks, tok, zero;
 569        u16 toksizes[AFSTOKEN_MAX];
 570
 571        _enter("");
 572
 573        /* we don't know what form we should return non-AFS keys in */
 574        if (memcmp(key->description, "afs@", 4) != 0)
 575                return -EOPNOTSUPP;
 576        cnlen = strlen(key->description + 4);
 577
 578#define RND(X) (((X) + 3) & ~3)
 579
 580        /* AFS keys we return in XDR form, so we need to work out the size of
 581         * the XDR */
 582        size = 2 * 4;   /* flags, cellname len */
 583        size += RND(cnlen);     /* cellname */
 584        size += 1 * 4;  /* token count */
 585
 586        ntoks = 0;
 587        for (token = key->payload.data[0]; token; token = token->next) {
 588                toksize = 4;    /* sec index */
 589
 590                switch (token->security_index) {
 591                case RXRPC_SECURITY_RXKAD:
 592                        toksize += 8 * 4;       /* viceid, kvno, key*2, begin,
 593                                                 * end, primary, tktlen */
 594                        if (!token->no_leak_key)
 595                                toksize += RND(token->kad->ticket_len);
 596                        break;
 597
 598                default: /* we have a ticket we can't encode */
 599                        pr_err("Unsupported key token type (%u)\n",
 600                               token->security_index);
 601                        return -ENOPKG;
 602                }
 603
 604                _debug("token[%u]: toksize=%u", ntoks, toksize);
 605                ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
 606
 607                toksizes[ntoks++] = toksize;
 608                size += toksize + 4; /* each token has a length word */
 609        }
 610
 611#undef RND
 612
 613        if (!buffer || buflen < size)
 614                return size;
 615
 616        xdr = (__be32 *)buffer;
 617        zero = 0;
 618#define ENCODE(x)                               \
 619        do {                                    \
 620                *xdr++ = htonl(x);              \
 621        } while(0)
 622#define ENCODE_DATA(l, s)                                               \
 623        do {                                                            \
 624                u32 _l = (l);                                           \
 625                ENCODE(l);                                              \
 626                memcpy(xdr, (s), _l);                                   \
 627                if (_l & 3)                                             \
 628                        memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
 629                xdr += (_l + 3) >> 2;                                   \
 630        } while(0)
 631#define ENCODE_BYTES(l, s)                                              \
 632        do {                                                            \
 633                u32 _l = (l);                                           \
 634                memcpy(xdr, (s), _l);                                   \
 635                if (_l & 3)                                             \
 636                        memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
 637                xdr += (_l + 3) >> 2;                                   \
 638        } while(0)
 639#define ENCODE64(x)                                     \
 640        do {                                            \
 641                __be64 y = cpu_to_be64(x);              \
 642                memcpy(xdr, &y, 8);                     \
 643                xdr += 8 >> 2;                          \
 644        } while(0)
 645#define ENCODE_STR(s)                           \
 646        do {                                    \
 647                const char *_s = (s);           \
 648                ENCODE_DATA(strlen(_s), _s);    \
 649        } while(0)
 650
 651        ENCODE(0);                                      /* flags */
 652        ENCODE_DATA(cnlen, key->description + 4);       /* cellname */
 653        ENCODE(ntoks);
 654
 655        tok = 0;
 656        for (token = key->payload.data[0]; token; token = token->next) {
 657                toksize = toksizes[tok++];
 658                ENCODE(toksize);
 659                oldxdr = xdr;
 660                ENCODE(token->security_index);
 661
 662                switch (token->security_index) {
 663                case RXRPC_SECURITY_RXKAD:
 664                        ENCODE(token->kad->vice_id);
 665                        ENCODE(token->kad->kvno);
 666                        ENCODE_BYTES(8, token->kad->session_key);
 667                        ENCODE(token->kad->start);
 668                        ENCODE(token->kad->expiry);
 669                        ENCODE(token->kad->primary_flag);
 670                        if (token->no_leak_key)
 671                                ENCODE(0);
 672                        else
 673                                ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
 674                        break;
 675
 676                default:
 677                        pr_err("Unsupported key token type (%u)\n",
 678                               token->security_index);
 679                        return -ENOPKG;
 680                }
 681
 682                ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
 683                          toksize);
 684        }
 685
 686#undef ENCODE_STR
 687#undef ENCODE_DATA
 688#undef ENCODE64
 689#undef ENCODE
 690
 691        ASSERTCMP(tok, ==, ntoks);
 692        ASSERTCMP((char __user *) xdr - buffer, ==, size);
 693        _leave(" = %zu", size);
 694        return size;
 695}
 696