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 /* 133 * attempt to parse the data as the XDR format 134 * - the caller guarantees we have more than 7 words 135 */ 136 static int rxrpc_preparse_xdr(struct key_preparsed_payload *prep) 137 { 138 const __be32 *xdr = prep->data, *token, *p; 139 const char *cp; 140 unsigned int len, paddedlen, loop, ntoken, toklen, sec_ix; 141 size_t datalen = prep->datalen; 142 int ret, ret2; 143 144 _enter(",{%x,%x,%x,%x},%zu", 145 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 146 prep->datalen); 147 148 if (datalen > AFSTOKEN_LENGTH_MAX) 149 goto not_xdr; 150 151 /* XDR is an array of __be32's */ 152 if (datalen & 3) 153 goto not_xdr; 154 155 /* the flags should be 0 (the setpag bit must be handled by 156 * userspace) */ 157 if (ntohl(*xdr++) != 0) 158 goto not_xdr; 159 datalen -= 4; 160 161 /* check the cell name */ 162 len = ntohl(*xdr++); 163 if (len < 1 || len > AFSTOKEN_CELL_MAX) 164 goto not_xdr; 165 datalen -= 4; 166 paddedlen = (len + 3) & ~3; 167 if (paddedlen > datalen) 168 goto not_xdr; 169 170 cp = (const char *) xdr; 171 for (loop = 0; loop < len; loop++) 172 if (!isprint(cp[loop])) 173 goto not_xdr; 174 for (; loop < paddedlen; loop++) 175 if (cp[loop]) 176 goto not_xdr; 177 _debug("cellname: [%u/%u] '%*.*s'", 178 len, paddedlen, len, len, (const char *) xdr); 179 datalen -= paddedlen; 180 xdr += paddedlen >> 2; 181 182 /* get the token count */ 183 if (datalen < 12) 184 goto not_xdr; 185 ntoken = ntohl(*xdr++); 186 datalen -= 4; 187 _debug("ntoken: %x", ntoken); 188 if (ntoken < 1 || ntoken > AFSTOKEN_MAX) 189 goto not_xdr; 190 191 /* check each token wrapper */ 192 p = xdr; 193 loop = ntoken; 194 do { 195 if (datalen < 8) 196 goto not_xdr; 197 toklen = ntohl(*p++); 198 sec_ix = ntohl(*p); 199 datalen -= 4; 200 _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); 201 paddedlen = (toklen + 3) & ~3; 202 if (toklen < 20 || toklen > datalen || paddedlen > datalen) 203 goto not_xdr; 204 datalen -= paddedlen; 205 p += paddedlen >> 2; 206 207 } while (--loop > 0); 208 209 _debug("remainder: %zu", datalen); 210 if (datalen != 0) 211 goto not_xdr; 212 213 /* okay: we're going to assume it's valid XDR format 214 * - we ignore the cellname, relying on the key to be correctly named 215 */ 216 ret = -EPROTONOSUPPORT; 217 do { 218 toklen = ntohl(*xdr++); 219 token = xdr; 220 xdr += (toklen + 3) / 4; 221 222 sec_ix = ntohl(*token++); 223 toklen -= 4; 224 225 _debug("TOKEN type=%x len=%x", sec_ix, toklen); 226 227 switch (sec_ix) { 228 case RXRPC_SECURITY_RXKAD: 229 ret2 = rxrpc_preparse_xdr_rxkad(prep, datalen, token, toklen); 230 break; 231 default: 232 ret2 = -EPROTONOSUPPORT; 233 break; 234 } 235 236 switch (ret2) { 237 case 0: 238 ret = 0; 239 break; 240 case -EPROTONOSUPPORT: 241 break; 242 case -ENOPKG: 243 if (ret != 0) 244 ret = -ENOPKG; 245 break; 246 default: 247 ret = ret2; 248 goto error; 249 } 250 251 } while (--ntoken > 0); 252 253 error: 254 _leave(" = %d", ret); 255 return ret; 256 257 not_xdr: 258 _leave(" = -EPROTO"); 259 return -EPROTO; 260 } 261 262 /* 263 * Preparse an rxrpc defined key. 264 * 265 * Data should be of the form: 266 * OFFSET LEN CONTENT 267 * 0 4 key interface version number 268 * 4 2 security index (type) 269 * 6 2 ticket length 270 * 8 4 key expiry time (time_t) 271 * 12 4 kvno 272 * 16 8 session key 273 * 24 [len] ticket 274 * 275 * if no data is provided, then a no-security key is made 276 */ 277 static int rxrpc_preparse(struct key_preparsed_payload *prep) 278 { 279 const struct rxrpc_key_data_v1 *v1; 280 struct rxrpc_key_token *token, **pp; 281 time64_t expiry; 282 size_t plen; 283 u32 kver; 284 int ret; 285 286 _enter("%zu", prep->datalen); 287 288 /* handle a no-security key */ 289 if (!prep->data && prep->datalen == 0) 290 return 0; 291 292 /* determine if the XDR payload format is being used */ 293 if (prep->datalen > 7 * 4) { 294 ret = rxrpc_preparse_xdr(prep); 295 if (ret != -EPROTO) 296 return ret; 297 } 298 299 /* get the key interface version number */ 300 ret = -EINVAL; 301 if (prep->datalen <= 4 || !prep->data) 302 goto error; 303 memcpy(&kver, prep->data, sizeof(kver)); 304 prep->data += sizeof(kver); 305 prep->datalen -= sizeof(kver); 306 307 _debug("KEY I/F VERSION: %u", kver); 308 309 ret = -EKEYREJECTED; 310 if (kver != 1) 311 goto error; 312 313 /* deal with a version 1 key */ 314 ret = -EINVAL; 315 if (prep->datalen < sizeof(*v1)) 316 goto error; 317 318 v1 = prep->data; 319 if (prep->datalen != sizeof(*v1) + v1->ticket_length) 320 goto error; 321 322 _debug("SCIX: %u", v1->security_index); 323 _debug("TLEN: %u", v1->ticket_length); 324 _debug("EXPY: %x", v1->expiry); 325 _debug("KVNO: %u", v1->kvno); 326 _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", 327 v1->session_key[0], v1->session_key[1], 328 v1->session_key[2], v1->session_key[3], 329 v1->session_key[4], v1->session_key[5], 330 v1->session_key[6], v1->session_key[7]); 331 if (v1->ticket_length >= 8) 332 _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", 333 v1->ticket[0], v1->ticket[1], 334 v1->ticket[2], v1->ticket[3], 335 v1->ticket[4], v1->ticket[5], 336 v1->ticket[6], v1->ticket[7]); 337 338 ret = -EPROTONOSUPPORT; 339 if (v1->security_index != RXRPC_SECURITY_RXKAD) 340 goto error; 341 342 plen = sizeof(*token->kad) + v1->ticket_length; 343 prep->quotalen = plen + sizeof(*token); 344 345 ret = -ENOMEM; 346 token = kzalloc(sizeof(*token), GFP_KERNEL); 347 if (!token) 348 goto error; 349 token->kad = kzalloc(plen, GFP_KERNEL); 350 if (!token->kad) 351 goto error_free; 352 353 token->security_index = RXRPC_SECURITY_RXKAD; 354 token->kad->ticket_len = v1->ticket_length; 355 token->kad->expiry = v1->expiry; 356 token->kad->kvno = v1->kvno; 357 memcpy(&token->kad->session_key, &v1->session_key, 8); 358 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 359 360 /* count the number of tokens attached */ 361 prep->payload.data[1] = (void *)((unsigned long)prep->payload.data[1] + 1); 362 363 /* attach the data */ 364 pp = (struct rxrpc_key_token **)&prep->payload.data[0]; 365 while (*pp) 366 pp = &(*pp)->next; 367 *pp = token; 368 expiry = rxrpc_u32_to_time64(token->kad->expiry); 369 if (expiry < prep->expiry) 370 prep->expiry = expiry; 371 token = NULL; 372 ret = 0; 373 374 error_free: 375 kfree(token); 376 error: 377 return ret; 378 } 379 380 /* 381 * Free token list. 382 */ 383 static void rxrpc_free_token_list(struct rxrpc_key_token *token) 384 { 385 struct rxrpc_key_token *next; 386 387 for (; token; token = next) { 388 next = token->next; 389 switch (token->security_index) { 390 case RXRPC_SECURITY_RXKAD: 391 kfree(token->kad); 392 break; 393 default: 394 pr_err("Unknown token type %x on rxrpc key\n", 395 token->security_index); 396 BUG(); 397 } 398 399 kfree(token); 400 } 401 } 402 403 /* 404 * Clean up preparse data. 405 */ 406 static void rxrpc_free_preparse(struct key_preparsed_payload *prep) 407 { 408 rxrpc_free_token_list(prep->payload.data[0]); 409 } 410 411 /* 412 * dispose of the data dangling from the corpse of a rxrpc key 413 */ 414 static void rxrpc_destroy(struct key *key) 415 { 416 rxrpc_free_token_list(key->payload.data[0]); 417 } 418 419 /* 420 * describe the rxrpc key 421 */ 422 static void rxrpc_describe(const struct key *key, struct seq_file *m) 423 { 424 const struct rxrpc_key_token *token; 425 const char *sep = ": "; 426 427 seq_puts(m, key->description); 428 429 for (token = key->payload.data[0]; token; token = token->next) { 430 seq_puts(m, sep); 431 432 switch (token->security_index) { 433 case RXRPC_SECURITY_RXKAD: 434 seq_puts(m, "ka"); 435 break; 436 default: /* we have a ticket we can't encode */ 437 seq_printf(m, "%u", token->security_index); 438 break; 439 } 440 441 sep = " "; 442 } 443 } 444 445 /* 446 * grab the security key for a socket 447 */ 448 int rxrpc_request_key(struct rxrpc_sock *rx, sockptr_t optval, int optlen) 449 { 450 struct key *key; 451 char *description; 452 453 _enter(""); 454 455 if (optlen <= 0 || optlen > PAGE_SIZE - 1 || rx->securities) 456 return -EINVAL; 457 458 description = memdup_sockptr_nul(optval, optlen); 459 if (IS_ERR(description)) 460 return PTR_ERR(description); 461 462 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL); 463 if (IS_ERR(key)) { 464 kfree(description); 465 _leave(" = %ld", PTR_ERR(key)); 466 return PTR_ERR(key); 467 } 468 469 rx->key = key; 470 kfree(description); 471 _leave(" = 0 [key %x]", key->serial); 472 return 0; 473 } 474 475 /* 476 * generate a server data key 477 */ 478 int rxrpc_get_server_data_key(struct rxrpc_connection *conn, 479 const void *session_key, 480 time64_t expiry, 481 u32 kvno) 482 { 483 const struct cred *cred = current_cred(); 484 struct key *key; 485 int ret; 486 487 struct { 488 u32 kver; 489 struct rxrpc_key_data_v1 v1; 490 } data; 491 492 _enter(""); 493 494 key = key_alloc(&key_type_rxrpc, "x", 495 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 496 KEY_ALLOC_NOT_IN_QUOTA, NULL); 497 if (IS_ERR(key)) { 498 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 499 return -ENOMEM; 500 } 501 502 _debug("key %d", key_serial(key)); 503 504 data.kver = 1; 505 data.v1.security_index = RXRPC_SECURITY_RXKAD; 506 data.v1.ticket_length = 0; 507 data.v1.expiry = rxrpc_time64_to_u32(expiry); 508 data.v1.kvno = 0; 509 510 memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); 511 512 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); 513 if (ret < 0) 514 goto error; 515 516 conn->key = key; 517 _leave(" = 0 [%d]", key_serial(key)); 518 return 0; 519 520 error: 521 key_revoke(key); 522 key_put(key); 523 _leave(" = -ENOMEM [ins %d]", ret); 524 return -ENOMEM; 525 } 526 EXPORT_SYMBOL(rxrpc_get_server_data_key); 527 528 /** 529 * rxrpc_get_null_key - Generate a null RxRPC key 530 * @keyname: The name to give the key. 531 * 532 * Generate a null RxRPC key that can be used to indicate anonymous security is 533 * required for a particular domain. 534 */ 535 struct key *rxrpc_get_null_key(const char *keyname) 536 { 537 const struct cred *cred = current_cred(); 538 struct key *key; 539 int ret; 540 541 key = key_alloc(&key_type_rxrpc, keyname, 542 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 543 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL); 544 if (IS_ERR(key)) 545 return key; 546 547 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); 548 if (ret < 0) { 549 key_revoke(key); 550 key_put(key); 551 return ERR_PTR(ret); 552 } 553 554 return key; 555 } 556 EXPORT_SYMBOL(rxrpc_get_null_key); 557 558 /* 559 * read the contents of an rxrpc key 560 * - this returns the result in XDR form 561 */ 562 static long rxrpc_read(const struct key *key, 563 char *buffer, size_t buflen) 564 { 565 const struct rxrpc_key_token *token; 566 size_t size; 567 __be32 *xdr, *oldxdr; 568 u32 cnlen, toksize, ntoks, tok, zero; 569 u16 toksizes[AFSTOKEN_MAX]; 570 571 _enter(""); 572 573 /* we don't know what form we should return non-AFS keys in */ 574 if (memcmp(key->description, "afs@", 4) != 0) 575 return -EOPNOTSUPP; 576 cnlen = strlen(key->description + 4); 577 578 #define RND(X) (((X) + 3) & ~3) 579 580 /* AFS keys we return in XDR form, so we need to work out the size of 581 * the XDR */ 582 size = 2 * 4; /* flags, cellname len */ 583 size += RND(cnlen); /* cellname */ 584 size += 1 * 4; /* token count */ 585 586 ntoks = 0; 587 for (token = key->payload.data[0]; token; token = token->next) { 588 toksize = 4; /* sec index */ 589 590 switch (token->security_index) { 591 case RXRPC_SECURITY_RXKAD: 592 toksize += 8 * 4; /* viceid, kvno, key*2, begin, 593 * end, primary, tktlen */ 594 if (!token->no_leak_key) 595 toksize += RND(token->kad->ticket_len); 596 break; 597 598 default: /* we have a ticket we can't encode */ 599 pr_err("Unsupported key token type (%u)\n", 600 token->security_index); 601 return -ENOPKG; 602 } 603 604 _debug("token[%u]: toksize=%u", ntoks, toksize); 605 if (WARN_ON(toksize > AFSTOKEN_LENGTH_MAX)) 606 return -EIO; 607 608 toksizes[ntoks++] = toksize; 609 size += toksize + 4; /* each token has a length word */ 610 } 611 612 #undef RND 613 614 if (!buffer || buflen < size) 615 return size; 616 617 xdr = (__be32 *)buffer; 618 zero = 0; 619 #define ENCODE(x) \ 620 do { \ 621 *xdr++ = htonl(x); \ 622 } while(0) 623 #define ENCODE_DATA(l, s) \ 624 do { \ 625 u32 _l = (l); \ 626 ENCODE(l); \ 627 memcpy(xdr, (s), _l); \ 628 if (_l & 3) \ 629 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 630 xdr += (_l + 3) >> 2; \ 631 } while(0) 632 #define ENCODE_BYTES(l, s) \ 633 do { \ 634 u32 _l = (l); \ 635 memcpy(xdr, (s), _l); \ 636 if (_l & 3) \ 637 memcpy((u8 *)xdr + _l, &zero, 4 - (_l & 3)); \ 638 xdr += (_l + 3) >> 2; \ 639 } while(0) 640 #define ENCODE64(x) \ 641 do { \ 642 __be64 y = cpu_to_be64(x); \ 643 memcpy(xdr, &y, 8); \ 644 xdr += 8 >> 2; \ 645 } while(0) 646 #define ENCODE_STR(s) \ 647 do { \ 648 const char *_s = (s); \ 649 ENCODE_DATA(strlen(_s), _s); \ 650 } while(0) 651 652 ENCODE(0); /* flags */ 653 ENCODE_DATA(cnlen, key->description + 4); /* cellname */ 654 ENCODE(ntoks); 655 656 tok = 0; 657 for (token = key->payload.data[0]; token; token = token->next) { 658 toksize = toksizes[tok++]; 659 ENCODE(toksize); 660 oldxdr = xdr; 661 ENCODE(token->security_index); 662 663 switch (token->security_index) { 664 case RXRPC_SECURITY_RXKAD: 665 ENCODE(token->kad->vice_id); 666 ENCODE(token->kad->kvno); 667 ENCODE_BYTES(8, token->kad->session_key); 668 ENCODE(token->kad->start); 669 ENCODE(token->kad->expiry); 670 ENCODE(token->kad->primary_flag); 671 if (token->no_leak_key) 672 ENCODE(0); 673 else 674 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); 675 break; 676 677 default: 678 pr_err("Unsupported key token type (%u)\n", 679 token->security_index); 680 return -ENOPKG; 681 } 682 683 if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr != 684 toksize)) 685 return -EIO; 686 } 687 688 #undef ENCODE_STR 689 #undef ENCODE_DATA 690 #undef ENCODE64 691 #undef ENCODE 692 693 if (WARN_ON(tok != ntoks)) 694 return -EIO; 695 if (WARN_ON((unsigned long)xdr - (unsigned long)buffer != size)) 696 return -EIO; 697 _leave(" = %zu", size); 698 return size; 699 } 700
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.