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