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 26 static int rxrpc_preparse(struct key_preparsed_payload *); 27 static void rxrpc_free_preparse(struct key_preparsed_payload *); 28 static void rxrpc_destroy(struct key *); 29 static void rxrpc_describe(const struct key *, struct seq_file *); 30 static 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 */ 36 struct 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 }; 46 EXPORT_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 */ 52 static 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 static u64 xdr_dec64(const __be32 *xdr) 133 { 134 return (u64)ntohl(xdr[0]) << 32 | (u64)ntohl(xdr[1]); 135 } 136 137 static time64_t rxrpc_s64_to_time64(s64 time_in_100ns) 138 { 139 bool neg = false; 140 u64 tmp = time_in_100ns; 141 142 if (time_in_100ns < 0) { 143 tmp = -time_in_100ns; 144 neg = true; 145 } 146 do_div(tmp, 10000000); 147 return neg ? -tmp : tmp; 148 } 149 150 /* 151 * Parse a YFS-RxGK type XDR format token 152 * - the caller guarantees we have at least 4 words 153 * 154 * struct token_rxgk { 155 * opr_time begintime; 156 * opr_time endtime; 157 * afs_int64 level; 158 * afs_int64 lifetime; 159 * afs_int64 bytelife; 160 * afs_int64 enctype; 161 * opaque key<>; 162 * opaque ticket<>; 163 * }; 164 */ 165 static int rxrpc_preparse_xdr_yfs_rxgk(struct key_preparsed_payload *prep, 166 size_t datalen, 167 const __be32 *xdr, unsigned int toklen) 168 { 169 struct rxrpc_key_token *token, **pptoken; 170 time64_t expiry; 171 size_t plen; 172 const __be32 *ticket, *key; 173 s64 tmp; 174 u32 tktlen, keylen; 175 176 _enter(",{%x,%x,%x,%x},%x", 177 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 178 toklen); 179 180 if (6 * 2 + 2 > toklen / 4) 181 goto reject; 182 183 key = xdr + (6 * 2 + 1); 184 keylen = ntohl(key[-1]); 185 _debug("keylen: %x", keylen); 186 keylen = round_up(keylen, 4); 187 if ((6 * 2 + 2) * 4 + keylen > toklen) 188 goto reject; 189 190 ticket = xdr + (6 * 2 + 1 + (keylen / 4) + 1); 191 tktlen = ntohl(ticket[-1]); 192 _debug("tktlen: %x", tktlen); 193 tktlen = round_up(tktlen, 4); 194 if ((6 * 2 + 2) * 4 + keylen + tktlen != toklen) { 195 kleave(" = -EKEYREJECTED [%x!=%x, %x,%x]", 196 (6 * 2 + 2) * 4 + keylen + tktlen, toklen, 197 keylen, tktlen); 198 goto reject; 199 } 200 201 plen = sizeof(*token) + sizeof(*token->rxgk) + tktlen + keylen; 202 prep->quotalen = datalen + plen; 203 204 plen -= sizeof(*token); 205 token = kzalloc(sizeof(*token), GFP_KERNEL); 206 if (!token) 207 goto nomem; 208 209 token->rxgk = kzalloc(sizeof(*token->rxgk) + keylen, GFP_KERNEL); 210 if (!token->rxgk) 211 goto nomem_token; 212 213 token->security_index = RXRPC_SECURITY_YFS_RXGK; 214 token->rxgk->begintime = xdr_dec64(xdr + 0 * 2); 215 token->rxgk->endtime = xdr_dec64(xdr + 1 * 2); 216 token->rxgk->level = tmp = xdr_dec64(xdr + 2 * 2); 217 if (tmp < -1LL || tmp > RXRPC_SECURITY_ENCRYPT) 218 goto reject_token; 219 token->rxgk->lifetime = xdr_dec64(xdr + 3 * 2); 220 token->rxgk->bytelife = xdr_dec64(xdr + 4 * 2); 221 token->rxgk->enctype = tmp = xdr_dec64(xdr + 5 * 2); 222 if (tmp < 0 || tmp > UINT_MAX) 223 goto reject_token; 224 token->rxgk->key.len = ntohl(key[-1]); 225 token->rxgk->key.data = token->rxgk->_key; 226 token->rxgk->ticket.len = ntohl(ticket[-1]); 227 228 if (token->rxgk->endtime != 0) { 229 expiry = rxrpc_s64_to_time64(token->rxgk->endtime); 230 if (expiry < 0) 231 goto expired; 232 if (expiry < prep->expiry) 233 prep->expiry = expiry; 234 } 235 236 memcpy(token->rxgk->key.data, key, token->rxgk->key.len); 237 238 /* Pad the ticket so that we can use it directly in XDR */ 239 token->rxgk->ticket.data = kzalloc(round_up(token->rxgk->ticket.len, 4), 240 GFP_KERNEL); 241 if (!token->rxgk->ticket.data) 242 goto nomem_yrxgk; 243 memcpy(token->rxgk->ticket.data, ticket, token->rxgk->ticket.len); 244 245 _debug("SCIX: %u", token->security_index); 246 _debug("EXPY: %llx", token->rxgk->endtime); 247 _debug("LIFE: %llx", token->rxgk->lifetime); 248 _debug("BYTE: %llx", token->rxgk->bytelife); 249 _debug("ENC : %u", token->rxgk->enctype); 250 _debug("LEVL: %u", token->rxgk->level); 251 _debug("KLEN: %u", token->rxgk->key.len); 252 _debug("TLEN: %u", token->rxgk->ticket.len); 253 _debug("KEY0: %*phN", token->rxgk->key.len, token->rxgk->key.data); 254 _debug("TICK: %*phN", 255 min_t(u32, token->rxgk->ticket.len, 32), token->rxgk->ticket.data); 256 257 /* count the number of tokens attached */ 258 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); 259 260 /* attach the data */ 261 for (pptoken = (struct rxrpc_key_token **)&prep->payload.data[0]; 262 *pptoken; 263 pptoken = &(*pptoken)->next) 264 continue; 265 *pptoken = token; 266 267 _leave(" = 0"); 268 return 0; 269 270 nomem_yrxgk: 271 kfree(token->rxgk); 272 nomem_token: 273 kfree(token); 274 nomem: 275 return -ENOMEM; 276 reject_token: 277 kfree(token); 278 reject: 279 return -EKEYREJECTED; 280 expired: 281 kfree(token->rxgk); 282 kfree(token); 283 return -EKEYEXPIRED; 284 } 285 286 /* 287 * attempt to parse the data as the XDR format 288 * - the caller guarantees we have more than 7 words 289 */ 290 static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) 291 { 292 const __be32 *xdr = prep->data, *token, *p; 293 const char *cp; 294 unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix; 295 size_t datalen = prep->datalen; 296 int ret, ret2; 297 298 _enter(",{%x,%x,%x,%x},%zu", 299 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 300 prep->datalen); 301 302 if (datalen > AFSTOKEN_LENGTH_MAX) 303 goto not_xdr; 304 305 /* XDR is an array of __be32's */ 306 if (datalen & 3) 307 goto not_xdr; 308 309 /* the flags should be 0 (the setpag bit must be handled by 310 * userspace) */ 311 if (ntohl(*xdr++) != 0) 312 goto not_xdr; 313 datalen -= 4; 314 315 /* check the cell name */ 316 len = ntohl(*xdr++); 317 if (len < 1 || len > AFSTOKEN_CELL_MAX) 318 goto not_xdr; 319 datalen -= 4; 320 paddedlen = (len + 3) & ~3; 321 if (paddedlen > datalen) 322 goto not_xdr; 323 324 cp = (const char *) xdr; 325 for (loop = 0; loop < len; loop++) 326 if (!isprint(cp[loop])) 327 goto not_xdr; 328 for (; loop < paddedlen; loop++) 329 if (cp[loop]) 330 goto not_xdr; 331 _debug("cellname: [%u/%u] '%*.*s'", 332 len, paddedlen, len, len, (const char *) xdr); 333 datalen -= paddedlen; 334 xdr += paddedlen >> 2; 335 336 /* get the token count */ 337 if (datalen < 12) 338 goto not_xdr; 339 ntoken = ntohl(*xdr++); 340 datalen -= 4; 341 _debug("ntoken: %x", ntoken); 342 if (ntoken < 1 || ntoken > AFSTOKEN_MAX) 343 goto not_xdr; 344 345 /* check each token wrapper */ 346 p = xdr; 347 loop = ntoken; 348 do { 349 if (datalen < 8) 350 goto not_xdr; 351 toklen = ntohl(*p++); 352 sec_ix = ntohl(*p); 353 datalen -= 4; 354 _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); 355 paddedlen = (toklen + 3) & ~3; 356 if (toklen < 20 || toklen > datalen || paddedlen > datalen) 357 goto not_xdr; 358 datalen -= paddedlen; 359 p += paddedlen >> 2; 360 361 } while (--loop > 0); 362 363 _debug("remainder: %zu", datalen); 364 if (datalen != 0) 365 goto not_xdr; 366 367 /* okay: we're going to assume it's valid XDR format 368 * - we ignore the cellname, relying on the key to be correctly named 369 */ 370 ret = -EPROTONOSUPPORT; 371 do { 372 toklen = ntohl(*xdr++); 373 token = xdr; 374 xdr += (toklen + 3) / 4; 375 376 sec_ix = ntohl(*token++); 377 toklen -= 4; 378 379 _debug("TOKEN type=%x len=%x", sec_ix, toklen); 380 381 switch (sec_ix) { 382 case RXRPC_SECURITY_RXKAD: 383 ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen); 384 break; 385 case RXRPC_SECURITY_YFS_RXGK: 386 ret2 = rxrpc_preparse_xdr_yfs_rxgk(prep, datalen, token, toklen); 387 break; 388 default: 389 ret2 = -EPROTONOSUPPORT; 390 break; 391 } 392 393 switch (ret2) { 394 case 0: 395 ret = 0; 396 break; 397 case -EPROTONOSUPPORT: 398 break; 399 case -ENOPKG: 400 if (ret != 0) 401 ret = -ENOPKG; 402 break; 403 default: 404 ret = ret2; 405 goto error; 406 } 407 408 } while (--ntoken > 0); 409 410 error: 411 _leave(" = %d", ret); 412 return ret; 413 414 not_xdr: 415 _leave(" = -EPROTO"); 416 return -EPROTO; 417 } 418 419 /* 420 * Preparse an rxrpc defined key. 421 * 422 * Data should be of the form: 423 * OFFSET LEN CONTENT 424 * 0 4 key interface version number 425 * 4 2 security index (type) 426 * 6 2 ticket length 427 * 8 4 key expiry time (time_t) 428 * 12 4 kvno 429 * 16 8 session key 430 * 24 [len] ticket 431 * 432 * if no data is provided, then a no-security key is made 433 */ 434 static int rxrpc_preparse(struct key_preparsed_payload *prep) 435 { 436 const struct rxrpc_key_data_v1 *v1; 437 struct rxrpc_key_token *token, **pp; 438 time64_t expiry; 439 size_t plen; 440 u32 kver; 441 int ret; 442 443 _enter("%zu", prep->datalen); 444 445 /* handle a no-security key */ 446 if (!prep->data && prep->datalen == 0) 447 return 0; 448 449 /* determine if the XDR payload format is being used */ 450 if (prep->datalen > 7 * 4) { 451 ret = rxrpc_preparse_xdr(prep); 452 if (ret != -EPROTO) 453 return ret; 454 } 455 456 /* get the key interface version number */ 457 ret = -EINVAL; 458 if (prep->datalen <= 4 || !prep->data) 459 goto error; 460 memcpy(&kver, prep->data, sizeof(kver)); 461 prep->data += sizeof(kver); 462 prep->datalen -= sizeof(kver); 463 464 _debug("KEY I/F VERSION: %u", kver); 465 466 ret = -EKEYREJECTED; 467 if (kver != 1) 468 goto error; 469 470 /* deal with a version 1 key */ 471 ret = -EINVAL; 472 if (prep->datalen < sizeof(*v1)) 473 goto error; 474 475 v1 = prep->data; 476 if (prep->datalen != sizeof(*v1) + v1->ticket_length) 477 goto error; 478 479 _debug("SCIX: %u", v1->security_index); 480 _debug("TLEN: %u", v1->ticket_length); 481 _debug("EXPY: %x", v1->expiry); 482 _debug("KVNO: %u", v1->kvno); 483 _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", 484 v1->session_key[0], v1->session_key[1], 485 v1->session_key[2], v1->session_key[3], 486 v1->session_key[4], v1->session_key[5], 487 v1->session_key[6], v1->session_key[7]); 488 if (v1->ticket_length >= 8) 489 _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", 490 v1->ticket[0], v1->ticket[1], 491 v1->ticket[2], v1->ticket[3], 492 v1->ticket[4], v1->ticket[5], 493 v1->ticket[6], v1->ticket[7]); 494 495 ret = -EPROTONOSUPPORT; 496 if (v1->security_index != RXRPC_SECURITY_RXKAD) 497 goto error; 498 499 plen = sizeof(*token->kad) + v1->ticket_length; 500 prep->quotalen = plen + sizeof(*token); 501 502 ret = -ENOMEM; 503 token = kzalloc(sizeof(*token), GFP_KERNEL); 504 if (!token) 505 goto error; 506 token->kad = kzalloc(plen, GFP_KERNEL); 507 if (!token->kad) 508 goto error_free; 509 510 token->security_index = RXRPC_SECURITY_RXKAD; 511 token->kad->ticket_len = v1->ticket_length; 512 token->kad->expiry = v1->expiry; 513 token->kad->kvno = v1->kvno; 514 memcpy(&token->kad->session_key, &v1->session_key, 8); 515 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 516 517 /* count the number of tokens attached */ 518 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); 519 520 /* attach the data */ 521 pp = (struct rxrpc_key_token **)&prep->payload.data[0]; 522 while (*pp) 523 pp = &(*pp)->next; 524 *pp = token; 525 expiry = rxrpc_u32_to_time64(token->kad->expiry); 526 if (expiry < prep->expiry) 527 prep->expiry = expiry; 528 token = NULL; 529 ret = 0; 530 531 error_free: 532 kfree(token); 533 error: 534 return ret; 535 } 536 537 /* 538 * Free token list. 539 */ 540 static void rxrpc_free_token_list(struct rxrpc_key_token *token) 541 { 542 struct rxrpc_key_token *next; 543 544 for (; token; token = next) { 545 next = token->next; 546 switch (token->security_index) { 547 case RXRPC_SECURITY_RXKAD: 548 kfree(token->kad); 549 break; 550 case RXRPC_SECURITY_YFS_RXGK: 551 kfree(token->rxgk->ticket.data); 552 kfree(token->rxgk); 553 break; 554 default: 555 pr_err("Unknown token type %x on rxrpc key\n", 556 token->security_index); 557 BUG(); 558 } 559 560 kfree(token); 561 } 562 } 563 564 /* 565 * Clean up preparse data. 566 */ 567 static void rxrpc_free_preparse(struct key_preparsed_payload *prep) 568 { 569 rxrpc_free_token_list(prep->payload.data[0]); 570 } 571 572 /* 573 * dispose of the data dangling from the corpse of a rxrpc key 574 */ 575 static void rxrpc_destroy(struct key *key) 576 { 577 rxrpc_free_token_list(key->payload.data[0]); 578 } 579 580 /* 581 * describe the rxrpc key 582 */ 583 static void rxrpc_describe(const struct key *key, struct seq_file *m) 584 { 585 const struct rxrpc_key_token *token; 586 const char *sep = ": "; 587 588 seq_puts(m, key->description); 589 590 for (token = key->payload.data[0]; token; token = token->next) { 591 seq_puts(m, sep); 592 593 switch (token->security_index) { 594 case RXRPC_SECURITY_RXKAD: 595 seq_puts(m, "ka"); 596 break; 597 case RXRPC_SECURITY_YFS_RXGK: 598 seq_puts(m, "ygk"); 599 break; 600 default: /* we have a ticket we can't encode */ 601 seq_printf(m, "%u", token->security_index); 602 break; 603 } 604 605 sep = " "; 606 } 607 } 608 609 /* 610 * grab the security key for a socket 611 */ 612 int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen) 613 { 614 struct key *key; 615 char *description; 616 617 _enter(""); 618 619 if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities) 620 return -EINVAL; 621 622 description = memdup_sockptr_nul(optval, optlen); 623 if (IS_ERR(description)) 624 return PTR_ERR(description); 625 626 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL); 627 if (IS_ERR(key)) { 628 kfree(description); 629 _leave(" = %ld", PTR_ERR(key)); 630 return PTR_ERR(key); 631 } 632 633 rx->key = key; 634 kfree(description); 635 _leave(" = 0 [key %x]", key->serial); 636 return 0; 637 } 638 639 /* 640 * generate a server data key 641 */ 642 int rxrpc_get_server_data_key(struct rxrpc_connection *conn, 643 const void *session_key, 644 time64_t expiry, 645 u32 kvno) 646 { 647 const struct cred *cred = current_cred(); 648 struct key *key; 649 int ret; 650 651 struct { 652 u32 kver; 653 struct rxrpc_key_data_v1 v1; 654 } data; 655 656 _enter(""); 657 658 key = key_alloc(&key_type_rxrpc, "x", 659 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 660 KEY_ALLOC_NOT_IN_QUOTA, NULL); 661 if (IS_ERR(key)) { 662 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 663 return -ENOMEM; 664 } 665 666 _debug("key %d", key_serial(key)); 667 668 data.kver = 1; 669 data.v1.security_index = RXRPC_SECURITY_RXKAD; 670 data.v1.ticket_length = 0; 671 data.v1.expiry = rxrpc_time64_to_u32(expiry); 672 data.v1.kvno = 0; 673 674 memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); 675 676 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); 677 if (ret < 0) 678 goto error; 679 680 conn->key = key; 681 _leave(" = 0 [%d]", key_serial(key)); 682 return 0; 683 684 error: 685 key_revoke(key); 686 key_put(key); 687 _leave(" = -ENOMEM [ins %d]", ret); 688 return -ENOMEM; 689 } 690 EXPORT_SYMBOL(rxrpc_get_server_data_key); 691 692 /** 693 * rxrpc_get_null_key - Generate a null RxRPC key 694 * @keyname: The name to give the key. 695 * 696 * Generate a null RxRPC key that can be used to indicate anonymous security is 697 * required for a particular domain. 698 * 699 * Return: The new key or a negative error code. 700 */ 701 struct key *rxrpc_get_null_key(const char *keyname) 702 { 703 const struct cred *cred = current_cred(); 704 struct key *key; 705 int ret; 706 707 key = key_alloc(&key_type_rxrpc, keyname, 708 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 709 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL); 710 if (IS_ERR(key)) 711 return key; 712 713 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); 714 if (ret < 0) { 715 key_revoke(key); 716 key_put(key); 717 return ERR_PTR(ret); 718 } 719 720 return key; 721 } 722 EXPORT_SYMBOL(rxrpc_get_null_key); 723 724 /* 725 * read the contents of an rxrpc key 726 * - this returns the result in XDR form 727 */ 728 static long rxrpc_read(const struct key *key, 729 char *buffer, size_t buflen) 730 { 731 const struct rxrpc_key_token *token; 732 size_t size; 733 __be32 *xdr, *oldxdr; 734 u32 cnlen, toksize, ntoks, tok, zero; 735 u16 toksizes[AFSTOKEN_MAX]; 736 737 _enter(""); 738 739 /* we don't know what form we should return non-AFS keys in */ 740 if (memcmp(key->description, "afs@", 4) != 0) 741 return -EOPNOTSUPP; 742 cnlen = strlen(key->description + 4); 743 744 #define RND(X) (((X) + 3) & ~3) 745 746 /* AFS keys we return in XDR form, so we need to work out the size of 747 * the XDR */ 748 size = 2 * 4; /* flags, cellname len */ 749 size += RND(cnlen); /* cellname */ 750 size += 1 * 4; /* token count */ 751 752 ntoks = 0; 753 for (token = key->payload.data[0]; token; token = token->next) { 754 toksize = 4; /* sec index */ 755 756 switch (token->security_index) { 757 case RXRPC_SECURITY_RXKAD: 758 toksize += 8 * 4; /* viceid, kvno, key*2, begin, 759 * end, primary, tktlen */ 760 if (!token->no_leak_key) 761 toksize += RND(token->kad->ticket_len); 762 break; 763 764 case RXRPC_SECURITY_YFS_RXGK: 765 toksize += 6 * 8 + 2 * 4; 766 if (!token->no_leak_key) 767 toksize += RND(token->rxgk->key.len); 768 toksize += RND(token->rxgk->ticket.len); 769 break; 770 771 default: /* we have a ticket we can't encode */ 772 pr_err("Unsupported key token type (%u)\n", 773 token->security_index); 774 return -ENOPKG; 775 } 776 777 _debug("token[%u]: toksize=%u", ntoks, toksize); 778 if (WARN_ON(toksize > AFSTOKEN_LENGTH_MAX)) 779 return -EIO; 780 781 toksizes[ntoks++] = toksize; 782 size += toksize + 4; /* each token has a length word */ 783 } 784 785 #undef RND 786 787 if (!buffer || buflen < size) 788 return size; 789 790 xdr = (__be32 *)buffer; 791 zero = 0; 792 #define ENCODE(x) \ 793 do { \ 794 *xdr++ = htonl(x); \ 795 } while(0) 796 #define ENCODE_DATA(l, s) \ 797 do { \ 798 u32 _l = (l); \ 799 ENCODE(l); \ 800 memcpy(xdr, (s), _l); \ 801 if (_l & 3) \ 802 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 803 xdr += (_l + 3) >> 2; \ 804 } while(0) 805 #define ENCODE_BYTES(l, s) \ 806 do { \ 807 u32 _l = (l); \ 808 memcpy(xdr, (s), _l); \ 809 if (_l & 3) \ 810 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 811 xdr += (_l + 3) >> 2; \ 812 } while(0) 813 #define ENCODE64(x) \ 814 do { \ 815 __be64 y = cpu_to_be64(x); \ 816 memcpy(xdr, &y, 8); \ 817 xdr += 8 >> 2; \ 818 } while(0) 819 #define ENCODE_STR(s) \ 820 do { \ 821 const char *_s = (s); \ 822 ENCODE_DATA(strlen(_s), _s); \ 823 } while(0) 824 825 ENCODE(0); /* flags */ 826 ENCODE_DATA(cnlen, key->description + 4); /* cellname */ 827 ENCODE(ntoks); 828 829 tok = 0; 830 for (token = key->payload.data[0]; token; token = token->next) { 831 toksize = toksizes[tok++]; 832 ENCODE(toksize); 833 oldxdr = xdr; 834 ENCODE(token->security_index); 835 836 switch (token->security_index) { 837 case RXRPC_SECURITY_RXKAD: 838 ENCODE(token->kad->vice_id); 839 ENCODE(token->kad->kvno); 840 ENCODE_BYTES(8, token->kad->session_key); 841 ENCODE(token->kad->start); 842 ENCODE(token->kad->expiry); 843 ENCODE(token->kad->primary_flag); 844 if (token->no_leak_key) 845 ENCODE(0); 846 else 847 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); 848 break; 849 850 case RXRPC_SECURITY_YFS_RXGK: 851 ENCODE64(token->rxgk->begintime); 852 ENCODE64(token->rxgk->endtime); 853 ENCODE64(token->rxgk->level); 854 ENCODE64(token->rxgk->lifetime); 855 ENCODE64(token->rxgk->bytelife); 856 ENCODE64(token->rxgk->enctype); 857 if (token->no_leak_key) 858 ENCODE(0); 859 else 860 ENCODE_DATA(token->rxgk->key.len, token->rxgk->key.data); 861 ENCODE_DATA(token->rxgk->ticket.len, token->rxgk->ticket.data); 862 break; 863 864 default: 865 pr_err("Unsupported key token type (%u)\n", 866 token->security_index); 867 return -ENOPKG; 868 } 869 870 if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr != 871 toksize)) 872 return -EIO; 873 } 874 875 #undef ENCODE_STR 876 #undef ENCODE_DATA 877 #undef ENCODE64 878 #undef ENCODE 879 880 if (WARN_ON(tok != ntoks)) 881 return -EIO; 882 if (WARN_ON((unsigned long)xdr - (unsigned long)buffer != size)) 883 return -EIO; 884 _leave(" = %zu", size); 885 return size; 886 } 887