Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* RxRPC key management
0003  *
0004  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  *
0007  * RxRPC keys should have a description of describing their purpose:
0008  *  "afs@example.com"
0009  */
0010 
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012 
0013 #include <crypto/skcipher.h>
0014 #include <linux/module.h>
0015 #include <linux/net.h>
0016 #include <linux/skbuff.h>
0017 #include <linux/key-type.h>
0018 #include <linux/ctype.h>
0019 #include <linux/slab.h>
0020 #include <net/sock.h>
0021 #include <net/af_rxrpc.h>
0022 #include <keys/rxrpc-type.h>
0023 #include <keys/user-type.h>
0024 #include "ar-internal.h"
0025 
0026 static int rxrpc_preparse(struct key_preparsed_payload *);
0027 static void rxrpc_free_preparse(struct key_preparsed_payload *);
0028 static void rxrpc_destroy(struct key *);
0029 static void rxrpc_describe(const struct key *, struct seq_file *);
0030 static long rxrpc_read(const struct key *, char *, size_t);
0031 
0032 /*
0033  * rxrpc defined keys take an arbitrary string as the description and an
0034  * arbitrary blob of data as the payload
0035  */
0036 struct key_type key_type_rxrpc = {
0037     .name       = "rxrpc",
0038     .flags      = KEY_TYPE_NET_DOMAIN,
0039     .preparse   = rxrpc_preparse,
0040     .free_preparse  = rxrpc_free_preparse,
0041     .instantiate    = generic_key_instantiate,
0042     .destroy    = rxrpc_destroy,
0043     .describe   = rxrpc_describe,
0044     .read       = rxrpc_read,
0045 };
0046 EXPORT_SYMBOL(key_type_rxrpc);
0047 
0048 /*
0049  * parse an RxKAD type XDR format token
0050  * - the caller guarantees we have at least 4 words
0051  */
0052 static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
0053                     size_t datalen,
0054                     const __be32 *xdr, unsigned int toklen)
0055 {
0056     struct rxrpc_key_token *token, **pptoken;
0057     time64_t expiry;
0058     size_t plen;
0059     u32 tktlen;
0060 
0061     _enter(",{%x,%x,%x,%x},%u",
0062            ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
0063            toklen);
0064 
0065     if (toklen <= 8 * 4)
0066         return -EKEYREJECTED;
0067     tktlen = ntohl(xdr[7]);
0068     _debug("tktlen: %x", tktlen);
0069     if (tktlen > AFSTOKEN_RK_TIX_MAX)
0070         return -EKEYREJECTED;
0071     if (toklen < 8 * 4 + tktlen)
0072         return -EKEYREJECTED;
0073 
0074     plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
0075     prep->quotalen = datalen + plen;
0076 
0077     plen -= sizeof(*token);
0078     token = kzalloc(sizeof(*token), GFP_KERNEL);
0079     if (!token)
0080         return -ENOMEM;
0081 
0082     token->kad = kzalloc(plen, GFP_KERNEL);
0083     if (!token->kad) {
0084         kfree(token);
0085         return -ENOMEM;
0086     }
0087 
0088     token->security_index   = RXRPC_SECURITY_RXKAD;
0089     token->kad->ticket_len  = tktlen;
0090     token->kad->vice_id = ntohl(xdr[0]);
0091     token->kad->kvno    = ntohl(xdr[1]);
0092     token->kad->start   = ntohl(xdr[4]);
0093     token->kad->expiry  = ntohl(xdr[5]);
0094     token->kad->primary_flag = ntohl(xdr[6]);
0095     memcpy(&token->kad->session_key, &xdr[2], 8);
0096     memcpy(&token->kad->ticket, &xdr[8], tktlen);
0097 
0098     _debug("SCIX: %u", token->security_index);
0099     _debug("TLEN: %u", token->kad->ticket_len);
0100     _debug("EXPY: %x", token->kad->expiry);
0101     _debug("KVNO: %u", token->kad->kvno);
0102     _debug("PRIM: %u", token->kad->primary_flag);
0103     _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
0104            token->kad->session_key[0], token->kad->session_key[1],
0105            token->kad->session_key[2], token->kad->session_key[3],
0106            token->kad->session_key[4], token->kad->session_key[5],
0107            token->kad->session_key[6], token->kad->session_key[7]);
0108     if (token->kad->ticket_len >= 8)
0109         _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
0110                token->kad->ticket[0], token->kad->ticket[1],
0111                token->kad->ticket[2], token->kad->ticket[3],
0112                token->kad->ticket[4], token->kad->ticket[5],
0113                token->kad->ticket[6], token->kad->ticket[7]);
0114 
0115     /* count the number of tokens attached */
0116     prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
0117 
0118     /* attach the data */
0119     for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0];
0120          *pptoken;
0121          pptoken = &(*pptoken)->next)
0122         continue;
0123     *pptoken = token;
0124     expiry = rxrpc_u32_to_time64(token->kad->expiry);
0125     if (expiry < prep->expiry)
0126         prep->expiry = expiry;
0127 
0128     _leave(" = 0");
0129     return 0;
0130 }
0131 
0132 /*
0133  * attempt to parse the data as the XDR format
0134  * - the caller guarantees we have more than 7 words
0135  */
0136 static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep)
0137 {
0138     const __be32 *xdr = prep->data, *token, *p;
0139     const char *cp;
0140     unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix;
0141     size_t datalen = prep->datalen;
0142     int ret, ret2;
0143 
0144     _enter(",{%x,%x,%x,%x},%zu",
0145            ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]),
0146            prep->datalen);
0147 
0148     if (datalen > AFSTOKEN_LENGTH_MAX)
0149         goto not_xdr;
0150 
0151     /* XDR is an array of __be32's */
0152     if (datalen & 3)
0153         goto not_xdr;
0154 
0155     /* the flags should be 0 (the setpag bit must be handled by
0156      * userspace) */
0157     if (ntohl(*xdr++) != 0)
0158         goto not_xdr;
0159     datalen -= 4;
0160 
0161     /* check the cell name */
0162     len = ntohl(*xdr++);
0163     if (len < 1 || len > AFSTOKEN_CELL_MAX)
0164         goto not_xdr;
0165     datalen -= 4;
0166     paddedlen = (len + 3) & ~3;
0167     if (paddedlen > datalen)
0168         goto not_xdr;
0169 
0170     cp = (const char *) xdr;
0171     for (loop = 0; loop < len; loop++)
0172         if (!isprint(cp[loop]))
0173             goto not_xdr;
0174     for (; loop < paddedlen; loop++)
0175         if (cp[loop])
0176             goto not_xdr;
0177     _debug("cellname: [%u/%u] '%*.*s'",
0178            len, paddedlen, len, len, (const char *) xdr);
0179     datalen -= paddedlen;
0180     xdr += paddedlen >> 2;
0181 
0182     /* get the token count */
0183     if (datalen < 12)
0184         goto not_xdr;
0185     ntoken = ntohl(*xdr++);
0186     datalen -= 4;
0187     _debug("ntoken: %x", ntoken);
0188     if (ntoken < 1 || ntoken > AFSTOKEN_MAX)
0189         goto not_xdr;
0190 
0191     /* check each token wrapper */
0192     p = xdr;
0193     loop = ntoken;
0194     do {
0195         if (datalen < 8)
0196             goto not_xdr;
0197         toklen = ntohl(*p++);
0198         sec_ix = ntohl(*p);
0199         datalen -= 4;
0200         _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix);
0201         paddedlen = (toklen + 3) & ~3;
0202         if (toklen < 20 || toklen > datalen || paddedlen > datalen)
0203             goto not_xdr;
0204         datalen -= paddedlen;
0205         p += paddedlen >> 2;
0206 
0207     } while (--loop > 0);
0208 
0209     _debug("remainder: %zu", datalen);
0210     if (datalen != 0)
0211         goto not_xdr;
0212 
0213     /* okay: we're going to assume it's valid XDR format
0214      * - we ignore the cellname, relying on the key to be correctly named
0215      */
0216     ret = -EPROTONOSUPPORT;
0217     do {
0218         toklen = ntohl(*xdr++);
0219         token = xdr;
0220         xdr += (toklen + 3) / 4;
0221 
0222         sec_ix = ntohl(*token++);
0223         toklen -= 4;
0224 
0225         _debug("TOKEN type=%x len=%x", sec_ix, toklen);
0226 
0227         switch (sec_ix) {
0228         case RXRPC_SECURITY_RXKAD:
0229             ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen);
0230             break;
0231         default:
0232             ret2 = -EPROTONOSUPPORT;
0233             break;
0234         }
0235 
0236         switch (ret2) {
0237         case 0:
0238             ret = 0;
0239             break;
0240         case -EPROTONOSUPPORT:
0241             break;
0242         case -ENOPKG:
0243             if (ret != 0)
0244                 ret = -ENOPKG;
0245             break;
0246         default:
0247             ret = ret2;
0248             goto error;
0249         }
0250 
0251     } while (--ntoken > 0);
0252 
0253 error:
0254     _leave(" = %d", ret);
0255     return ret;
0256 
0257 not_xdr:
0258     _leave(" = -EPROTO");
0259     return -EPROTO;
0260 }
0261 
0262 /*
0263  * Preparse an rxrpc defined key.
0264  *
0265  * Data should be of the form:
0266  *  OFFSET  LEN CONTENT
0267  *  0   4   key interface version number
0268  *  4   2   security index (type)
0269  *  6   2   ticket length
0270  *  8   4   key expiry time (time_t)
0271  *  12  4   kvno
0272  *  16  8   session key
0273  *  24  [len]   ticket
0274  *
0275  * if no data is provided, then a no-security key is made
0276  */
0277 static int rxrpc_preparse(struct key_preparsed_payload *prep)
0278 {
0279     const struct rxrpc_key_data_v1 *v1;
0280     struct rxrpc_key_token *token, **pp;
0281     time64_t expiry;
0282     size_t plen;
0283     u32 kver;
0284     int ret;
0285 
0286     _enter("%zu", prep->datalen);
0287 
0288     /* handle a no-security key */
0289     if (!prep->data && prep->datalen == 0)
0290         return 0;
0291 
0292     /* determine if the XDR payload format is being used */
0293     if (prep->datalen > 7 * 4) {
0294         ret = rxrpc_preparse_xdr(prep);
0295         if (ret != -EPROTO)
0296             return ret;
0297     }
0298 
0299     /* get the key interface version number */
0300     ret = -EINVAL;
0301     if (prep->datalen <= 4 || !prep->data)
0302         goto error;
0303     memcpy(&kver, prep->data, sizeof(kver));
0304     prep->data += sizeof(kver);
0305     prep->datalen -= sizeof(kver);
0306 
0307     _debug("KEY I/F VERSION: %u", kver);
0308 
0309     ret = -EKEYREJECTED;
0310     if (kver != 1)
0311         goto error;
0312 
0313     /* deal with a version 1 key */
0314     ret = -EINVAL;
0315     if (prep->datalen < sizeof(*v1))
0316         goto error;
0317 
0318     v1 = prep->data;
0319     if (prep->datalen != sizeof(*v1) + v1->ticket_length)
0320         goto error;
0321 
0322     _debug("SCIX: %u", v1->security_index);
0323     _debug("TLEN: %u", v1->ticket_length);
0324     _debug("EXPY: %x", v1->expiry);
0325     _debug("KVNO: %u", v1->kvno);
0326     _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x",
0327            v1->session_key[0], v1->session_key[1],
0328            v1->session_key[2], v1->session_key[3],
0329            v1->session_key[4], v1->session_key[5],
0330            v1->session_key[6], v1->session_key[7]);
0331     if (v1->ticket_length >= 8)
0332         _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x",
0333                v1->ticket[0], v1->ticket[1],
0334                v1->ticket[2], v1->ticket[3],
0335                v1->ticket[4], v1->ticket[5],
0336                v1->ticket[6], v1->ticket[7]);
0337 
0338     ret = -EPROTONOSUPPORT;
0339     if (v1->security_index != RXRPC_SECURITY_RXKAD)
0340         goto error;
0341 
0342     plen = sizeof(*token->kad) + v1->ticket_length;
0343     prep->quotalen = plen + sizeof(*token);
0344 
0345     ret = -ENOMEM;
0346     token = kzalloc(sizeof(*token), GFP_KERNEL);
0347     if (!token)
0348         goto error;
0349     token->kad = kzalloc(plen, GFP_KERNEL);
0350     if (!token->kad)
0351         goto error_free;
0352 
0353     token->security_index       = RXRPC_SECURITY_RXKAD;
0354     token->kad->ticket_len      = v1->ticket_length;
0355     token->kad->expiry      = v1->expiry;
0356     token->kad->kvno        = v1->kvno;
0357     memcpy(&token->kad->session_key, &v1->session_key, 8);
0358     memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length);
0359 
0360     /* count the number of tokens attached */
0361     prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1);
0362 
0363     /* attach the data */
0364     pp = (struct rxrpc_key_token **)&prep->payload.data[0];
0365     while (*pp)
0366         pp = &(*pp)->next;
0367     *pp = token;
0368     expiry = rxrpc_u32_to_time64(token->kad->expiry);
0369     if (expiry < prep->expiry)
0370         prep->expiry = expiry;
0371     token = NULL;
0372     ret = 0;
0373 
0374 error_free:
0375     kfree(token);
0376 error:
0377     return ret;
0378 }
0379 
0380 /*
0381  * Free token list.
0382  */
0383 static void rxrpc_free_token_list(struct rxrpc_key_token *token)
0384 {
0385     struct rxrpc_key_token *next;
0386 
0387     for (; token; token = next) {
0388         next = token->next;
0389         switch (token->security_index) {
0390         case RXRPC_SECURITY_RXKAD:
0391             kfree(token->kad);
0392             break;
0393         default:
0394             pr_err("Unknown token type %x on rxrpc key\n",
0395                    token->security_index);
0396             BUG();
0397         }
0398 
0399         kfree(token);
0400     }
0401 }
0402 
0403 /*
0404  * Clean up preparse data.
0405  */
0406 static void rxrpc_free_preparse(struct key_preparsed_payload *prep)
0407 {
0408     rxrpc_free_token_list(prep->payload.data[0]);
0409 }
0410 
0411 /*
0412  * dispose of the data dangling from the corpse of a rxrpc key
0413  */
0414 static void rxrpc_destroy(struct key *key)
0415 {
0416     rxrpc_free_token_list(key->payload.data[0]);
0417 }
0418 
0419 /*
0420  * describe the rxrpc key
0421  */
0422 static void rxrpc_describe(const struct key *key, struct seq_file *m)
0423 {
0424     const struct rxrpc_key_token *token;
0425     const char *sep = ": ";
0426 
0427     seq_puts(m, key->description);
0428 
0429     for (token = key->payload.data[0]; token; token = token->next) {
0430         seq_puts(m, sep);
0431 
0432         switch (token->security_index) {
0433         case RXRPC_SECURITY_RXKAD:
0434             seq_puts(m, "ka");
0435             break;
0436         default: /* we have a ticket we can't encode */
0437             seq_printf(m, "%u", token->security_index);
0438             break;
0439         }
0440 
0441         sep = " ";
0442     }
0443 }
0444 
0445 /*
0446  * grab the security key for a socket
0447  */
0448 int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen)
0449 {
0450     struct key *key;
0451     char *description;
0452 
0453     _enter("");
0454 
0455     if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities)
0456         return -EINVAL;
0457 
0458     description = memdup_sockptr_nul(optval, optlen);
0459     if (IS_ERR(description))
0460         return PTR_ERR(description);
0461 
0462     key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL);
0463     if (IS_ERR(key)) {
0464         kfree(description);
0465         _leave(" = %ld", PTR_ERR(key));
0466         return PTR_ERR(key);
0467     }
0468 
0469     rx->key = key;
0470     kfree(description);
0471     _leave(" = 0 [key %x]", key->serial);
0472     return 0;
0473 }
0474 
0475 /*
0476  * generate a server data key
0477  */
0478 int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
0479                   const void *session_key,
0480                   time64_t expiry,
0481                   u32 kvno)
0482 {
0483     const struct cred *cred = current_cred();
0484     struct key *key;
0485     int ret;
0486 
0487     struct {
0488         u32 kver;
0489         struct rxrpc_key_data_v1 v1;
0490     } data;
0491 
0492     _enter("");
0493 
0494     key = key_alloc(&key_type_rxrpc, "x",
0495             GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
0496             KEY_ALLOC_NOT_IN_QUOTA, NULL);
0497     if (IS_ERR(key)) {
0498         _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
0499         return -ENOMEM;
0500     }
0501 
0502     _debug("key %d", key_serial(key));
0503 
0504     data.kver = 1;
0505     data.v1.security_index = RXRPC_SECURITY_RXKAD;
0506     data.v1.ticket_length = 0;
0507     data.v1.expiry = rxrpc_time64_to_u32(expiry);
0508     data.v1.kvno = 0;
0509 
0510     memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
0511 
0512     ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL);
0513     if (ret < 0)
0514         goto error;
0515 
0516     conn->params.key = key;
0517     _leave(" = 0 [%d]", key_serial(key));
0518     return 0;
0519 
0520 error:
0521     key_revoke(key);
0522     key_put(key);
0523     _leave(" = -ENOMEM [ins %d]", ret);
0524     return -ENOMEM;
0525 }
0526 EXPORT_SYMBOL(rxrpc_get_server_data_key);
0527 
0528 /**
0529  * rxrpc_get_null_key - Generate a null RxRPC key
0530  * @keyname: The name to give the key.
0531  *
0532  * Generate a null RxRPC key that can be used to indicate anonymous security is
0533  * required for a particular domain.
0534  */
0535 struct key *rxrpc_get_null_key(const char *keyname)
0536 {
0537     const struct cred *cred = current_cred();
0538     struct key *key;
0539     int ret;
0540 
0541     key = key_alloc(&key_type_rxrpc, keyname,
0542             GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
0543             KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
0544     if (IS_ERR(key))
0545         return key;
0546 
0547     ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
0548     if (ret < 0) {
0549         key_revoke(key);
0550         key_put(key);
0551         return ERR_PTR(ret);
0552     }
0553 
0554     return key;
0555 }
0556 EXPORT_SYMBOL(rxrpc_get_null_key);
0557 
0558 /*
0559  * read the contents of an rxrpc key
0560  * - this returns the result in XDR form
0561  */
0562 static long rxrpc_read(const struct key *key,
0563                char *buffer, size_t buflen)
0564 {
0565     const struct rxrpc_key_token *token;
0566     size_t size;
0567     __be32 *xdr, *oldxdr;
0568     u32 cnlen, toksize, ntoks, tok, zero;
0569     u16 toksizes[AFSTOKEN_MAX];
0570 
0571     _enter("");
0572 
0573     /* we don't know what form we should return non-AFS keys in */
0574     if (memcmp(key->description, "afs@", 4) != 0)
0575         return -EOPNOTSUPP;
0576     cnlen = strlen(key->description + 4);
0577 
0578 #define RND(X) (((X) + 3) & ~3)
0579 
0580     /* AFS keys we return in XDR form, so we need to work out the size of
0581      * the XDR */
0582     size = 2 * 4;   /* flags, cellname len */
0583     size += RND(cnlen); /* cellname */
0584     size += 1 * 4;  /* token count */
0585 
0586     ntoks = 0;
0587     for (token = key->payload.data[0]; token; token = token->next) {
0588         toksize = 4;    /* sec index */
0589 
0590         switch (token->security_index) {
0591         case RXRPC_SECURITY_RXKAD:
0592             toksize += 8 * 4;   /* viceid, kvno, key*2, begin,
0593                          * end, primary, tktlen */
0594             if (!token->no_leak_key)
0595                 toksize += RND(token->kad->ticket_len);
0596             break;
0597 
0598         default: /* we have a ticket we can't encode */
0599             pr_err("Unsupported key token type (%u)\n",
0600                    token->security_index);
0601             return -ENOPKG;
0602         }
0603 
0604         _debug("token[%u]: toksize=%u", ntoks, toksize);
0605         ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX);
0606 
0607         toksizes[ntoks++] = toksize;
0608         size += toksize + 4; /* each token has a length word */
0609     }
0610 
0611 #undef RND
0612 
0613     if (!buffer || buflen < size)
0614         return size;
0615 
0616     xdr = (__be32 *)buffer;
0617     zero = 0;
0618 #define ENCODE(x)               \
0619     do {                    \
0620         *xdr++ = htonl(x);      \
0621     } while(0)
0622 #define ENCODE_DATA(l, s)                       \
0623     do {                                \
0624         u32 _l = (l);                       \
0625         ENCODE(l);                      \
0626         memcpy(xdr, (s), _l);                   \
0627         if (_l & 3)                     \
0628             memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
0629         xdr += (_l + 3) >> 2;                   \
0630     } while(0)
0631 #define ENCODE_BYTES(l, s)                      \
0632     do {                                \
0633         u32 _l = (l);                       \
0634         memcpy(xdr, (s), _l);                   \
0635         if (_l & 3)                     \
0636             memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3));    \
0637         xdr += (_l + 3) >> 2;                   \
0638     } while(0)
0639 #define ENCODE64(x)                 \
0640     do {                        \
0641         __be64 y = cpu_to_be64(x);      \
0642         memcpy(xdr, &y, 8);         \
0643         xdr += 8 >> 2;              \
0644     } while(0)
0645 #define ENCODE_STR(s)               \
0646     do {                    \
0647         const char *_s = (s);       \
0648         ENCODE_DATA(strlen(_s), _s);    \
0649     } while(0)
0650 
0651     ENCODE(0);                  /* flags */
0652     ENCODE_DATA(cnlen, key->description + 4);   /* cellname */
0653     ENCODE(ntoks);
0654 
0655     tok = 0;
0656     for (token = key->payload.data[0]; token; token = token->next) {
0657         toksize = toksizes[tok++];
0658         ENCODE(toksize);
0659         oldxdr = xdr;
0660         ENCODE(token->security_index);
0661 
0662         switch (token->security_index) {
0663         case RXRPC_SECURITY_RXKAD:
0664             ENCODE(token->kad->vice_id);
0665             ENCODE(token->kad->kvno);
0666             ENCODE_BYTES(8, token->kad->session_key);
0667             ENCODE(token->kad->start);
0668             ENCODE(token->kad->expiry);
0669             ENCODE(token->kad->primary_flag);
0670             if (token->no_leak_key)
0671                 ENCODE(0);
0672             else
0673                 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket);
0674             break;
0675 
0676         default:
0677             pr_err("Unsupported key token type (%u)\n",
0678                    token->security_index);
0679             return -ENOPKG;
0680         }
0681 
0682         ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==,
0683               toksize);
0684     }
0685 
0686 #undef ENCODE_STR
0687 #undef ENCODE_DATA
0688 #undef ENCODE64
0689 #undef ENCODE
0690 
0691     ASSERTCMP(tok, ==, ntoks);
0692     ASSERTCMP((char __user *) xdr - buffer, ==, size);
0693     _leave(" = %zu", size);
0694     return size;
0695 }