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 plen = sizeof(*token->kad) + v1->ticket_length; 506 prep->quotalen += plen + sizeof(*token); 507 508 ret = -ENOMEM; 509 token = kzalloc_obj(*token); 510 if (!token) 511 goto error; 512 token->kad = kzalloc(plen, GFP_KERNEL); 513 if (!token->kad) 514 goto error_free; 515 516 token->security_index = RXRPC_SECURITY_RXKAD; 517 token->kad->ticket_len = v1->ticket_length; 518 token->kad->expiry = v1->expiry; 519 token->kad->kvno = v1->kvno; 520 memcpy(&token->kad->session_key, &v1->session_key, 8); 521 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 522 523 /* count the number of tokens attached */ 524 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); 525 526 /* attach the data */ 527 pp = (struct rxrpc_key_token **)&prep->payload.data[0]; 528 while (*pp) 529 pp = &(*pp)->next; 530 *pp = token; 531 expiry = rxrpc_u32_to_time64(token->kad->expiry); 532 if (expiry < prep->expiry) 533 prep->expiry = expiry; 534 token = NULL; 535 ret = 0; 536 537 error_free: 538 kfree(token); 539 error: 540 return ret; 541 } 542 543 /* 544 * Free token list. 545 */ 546 static void rxrpc_free_token_list(struct rxrpc_key_token *token) 547 { 548 struct rxrpc_key_token *next; 549 550 for (; token; token = next) { 551 next = token->next; 552 switch (token->security_index) { 553 case RXRPC_SECURITY_RXKAD: 554 kfree(token->kad); 555 break; 556 case RXRPC_SECURITY_YFS_RXGK: 557 kfree(token->rxgk->ticket.data); 558 kfree(token->rxgk); 559 break; 560 default: 561 pr_err("Unknown token type %x on rxrpc key\n", 562 token->security_index); 563 BUG(); 564 } 565 566 kfree(token); 567 } 568 } 569 570 /* 571 * Clean up preparse data. 572 */ 573 static void rxrpc_free_preparse(struct key_preparsed_payload *prep) 574 { 575 rxrpc_free_token_list(prep->payload.data[0]); 576 } 577 578 /* 579 * dispose of the data dangling from the corpse of a rxrpc key 580 */ 581 static void rxrpc_destroy(struct key *key) 582 { 583 rxrpc_free_token_list(key->payload.data[0]); 584 } 585 586 /* 587 * describe the rxrpc key 588 */ 589 static void rxrpc_describe(const struct key *key, struct seq_file *m) 590 { 591 const struct rxrpc_key_token *token; 592 const char *sep = ": "; 593 594 seq_puts(m, key->description); 595 596 for (token = key->payload.data[0]; token; token = token->next) { 597 seq_puts(m, sep); 598 599 switch (token->security_index) { 600 case RXRPC_SECURITY_RXKAD: 601 seq_puts(m, "ka"); 602 break; 603 case RXRPC_SECURITY_YFS_RXGK: 604 seq_puts(m, "ygk"); 605 break; 606 default: /* we have a ticket we can't encode */ 607 seq_printf(m, "%u", token->security_index); 608 break; 609 } 610 611 sep = " "; 612 } 613 } 614 615 /* 616 * grab the security key for a socket 617 */ 618 int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen) 619 { 620 struct key *key; 621 char *description; 622 623 _enter(""); 624 625 if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->key) 626 return -EINVAL; 627 628 description = memdup_sockptr_nul(optval, optlen); 629 if (IS_ERR(description)) 630 return PTR_ERR(description); 631 632 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL); 633 if (IS_ERR(key)) { 634 kfree(description); 635 _leave(" = %ld", PTR_ERR(key)); 636 return PTR_ERR(key); 637 } 638 639 rx->key = key; 640 kfree(description); 641 _leave(" = 0 [key %x]", key->serial); 642 return 0; 643 } 644 645 /* 646 * generate a server data key 647 */ 648 int rxrpc_get_server_data_key(struct rxrpc_connection *conn, 649 const void *session_key, 650 time64_t expiry, 651 u32 kvno) 652 { 653 const struct cred *cred = current_cred(); 654 struct key *key; 655 int ret; 656 657 struct { 658 u32 kver; 659 struct rxrpc_key_data_v1 v1; 660 } data; 661 662 _enter(""); 663 664 key = key_alloc(&key_type_rxrpc, "x", 665 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 666 KEY_ALLOC_NOT_IN_QUOTA, NULL); 667 if (IS_ERR(key)) { 668 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 669 return -ENOMEM; 670 } 671 672 _debug("key %d", key_serial(key)); 673 674 data.kver = 1; 675 data.v1.security_index = RXRPC_SECURITY_RXKAD; 676 data.v1.ticket_length = 0; 677 data.v1.expiry = rxrpc_time64_to_u32(expiry); 678 data.v1.kvno = 0; 679 680 memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); 681 682 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); 683 if (ret < 0) 684 goto error; 685 686 conn->key = key; 687 _leave(" = 0 [%d]", key_serial(key)); 688 return 0; 689 690 error: 691 key_revoke(key); 692 key_put(key); 693 _leave(" = -ENOMEM [ins %d]", ret); 694 return -ENOMEM; 695 } 696 EXPORT_SYMBOL(rxrpc_get_server_data_key); 697 698 /** 699 * rxrpc_get_null_key - Generate a null RxRPC key 700 * @keyname: The name to give the key. 701 * 702 * Generate a null RxRPC key that can be used to indicate anonymous security is 703 * required for a particular domain. 704 * 705 * Return: The new key or a negative error code. 706 */ 707 struct key *rxrpc_get_null_key(const char *keyname) 708 { 709 const struct cred *cred = current_cred(); 710 struct key *key; 711 int ret; 712 713 key = key_alloc(&key_type_rxrpc, keyname, 714 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 715 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL); 716 if (IS_ERR(key)) 717 return key; 718 719 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); 720 if (ret < 0) { 721 key_revoke(key); 722 key_put(key); 723 return ERR_PTR(ret); 724 } 725 726 return key; 727 } 728 EXPORT_SYMBOL(rxrpc_get_null_key); 729 730 /* 731 * read the contents of an rxrpc key 732 * - this returns the result in XDR form 733 */ 734 static long rxrpc_read(const struct key *key, 735 char *buffer, size_t buflen) 736 { 737 const struct rxrpc_key_token *token; 738 size_t size; 739 __be32 *xdr, *oldxdr; 740 u32 cnlen, toksize, ntoks, tok, zero; 741 u16 toksizes[AFSTOKEN_MAX]; 742 743 _enter(""); 744 745 /* we don't know what form we should return non-AFS keys in */ 746 if (memcmp(key->description, "afs@", 4) != 0) 747 return -EOPNOTSUPP; 748 cnlen = strlen(key->description + 4); 749 750 #define RND(X) (((X) + 3) & ~3) 751 752 /* AFS keys we return in XDR form, so we need to work out the size of 753 * the XDR */ 754 size = 2 * 4; /* flags, cellname len */ 755 size += RND(cnlen); /* cellname */ 756 size += 1 * 4; /* token count */ 757 758 ntoks = 0; 759 for (token = key->payload.data[0]; token; token = token->next) { 760 toksize = 4; /* sec index */ 761 762 switch (token->security_index) { 763 case RXRPC_SECURITY_RXKAD: 764 toksize += 8 * 4; /* viceid, kvno, key*2, begin, 765 * end, primary, tktlen */ 766 if (!token->no_leak_key) 767 toksize += RND(token->kad->ticket_len); 768 break; 769 770 case RXRPC_SECURITY_YFS_RXGK: 771 toksize += 6 * 8 + 2 * 4; 772 if (!token->no_leak_key) 773 toksize += RND(token->rxgk->key.len); 774 toksize += RND(token->rxgk->ticket.len); 775 break; 776 777 default: /* we have a ticket we can't encode */ 778 pr_err("Unsupported key token type (%u)\n", 779 token->security_index); 780 return -ENOPKG; 781 } 782 783 _debug("token[%u]: toksize=%u", ntoks, toksize); 784 if (WARN_ON(toksize > AFSTOKEN_LENGTH_MAX)) 785 return -EIO; 786 787 toksizes[ntoks++] = toksize; 788 size += toksize + 4; /* each token has a length word */ 789 } 790 791 #undef RND 792 793 if (!buffer || buflen < size) 794 return size; 795 796 xdr = (__be32 *)buffer; 797 zero = 0; 798 #define ENCODE(x) \ 799 do { \ 800 *xdr++ = htonl(x); \ 801 } while(0) 802 #define ENCODE_DATA(l, s) \ 803 do { \ 804 u32 _l = (l); \ 805 ENCODE(l); \ 806 memcpy(xdr, (s), _l); \ 807 if (_l & 3) \ 808 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 809 xdr += (_l + 3) >> 2; \ 810 } while(0) 811 #define ENCODE_BYTES(l, s) \ 812 do { \ 813 u32 _l = (l); \ 814 memcpy(xdr, (s), _l); \ 815 if (_l & 3) \ 816 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 817 xdr += (_l + 3) >> 2; \ 818 } while(0) 819 #define ENCODE64(x) \ 820 do { \ 821 __be64 y = cpu_to_be64(x); \ 822 memcpy(xdr, &y, 8); \ 823 xdr += 8 >> 2; \ 824 } while(0) 825 #define ENCODE_STR(s) \ 826 do { \ 827 const char *_s = (s); \ 828 ENCODE_DATA(strlen(_s), _s); \ 829 } while(0) 830 831 ENCODE(0); /* flags */ 832 ENCODE_DATA(cnlen, key->description + 4); /* cellname */ 833 ENCODE(ntoks); 834 835 tok = 0; 836 for (token = key->payload.data[0]; token; token = token->next) { 837 toksize = toksizes[tok++]; 838 ENCODE(toksize); 839 oldxdr = xdr; 840 ENCODE(token->security_index); 841 842 switch (token->security_index) { 843 case RXRPC_SECURITY_RXKAD: 844 ENCODE(token->kad->vice_id); 845 ENCODE(token->kad->kvno); 846 ENCODE_BYTES(8, token->kad->session_key); 847 ENCODE(token->kad->start); 848 ENCODE(token->kad->expiry); 849 ENCODE(token->kad->primary_flag); 850 if (token->no_leak_key) 851 ENCODE(0); 852 else 853 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); 854 break; 855 856 case RXRPC_SECURITY_YFS_RXGK: 857 ENCODE64(token->rxgk->begintime); 858 ENCODE64(token->rxgk->endtime); 859 ENCODE64(token->rxgk->level); 860 ENCODE64(token->rxgk->lifetime); 861 ENCODE64(token->rxgk->bytelife); 862 ENCODE64(token->rxgk->enctype); 863 if (token->no_leak_key) 864 ENCODE(0); 865 else 866 ENCODE_DATA(token->rxgk->key.len, token->rxgk->key.data); 867 ENCODE_DATA(token->rxgk->ticket.len, token->rxgk->ticket.data); 868 break; 869 870 default: 871 pr_err("Unsupported key token type (%u)\n", 872 token->security_index); 873 return -ENOPKG; 874 } 875 876 if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr != 877 toksize)) 878 return -EIO; 879 } 880 881 #undef ENCODE_STR 882 #undef ENCODE_DATA 883 #undef ENCODE64 884 #undef ENCODE 885 886 if (WARN_ON(tok != ntoks)) 887 return -EIO; 888 if (WARN_ON((unsigned long)xdr - (unsigned long)buffer != size)) 889 return -EIO; 890 _leave(" = %zu", size); 891 return size; 892 } 893