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