Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.33-rc4 1200 lines 29 kB view raw
1/* RxRPC key management 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 * 11 * RxRPC keys should have a description of describing their purpose: 12 * "afs@CAMBRIDGE.REDHAT.COM> 13 */ 14 15#include <linux/module.h> 16#include <linux/net.h> 17#include <linux/skbuff.h> 18#include <linux/key-type.h> 19#include <linux/crypto.h> 20#include <linux/ctype.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 27static int rxrpc_instantiate(struct key *, const void *, size_t); 28static int rxrpc_instantiate_s(struct key *, const void *, size_t); 29static void rxrpc_destroy(struct key *); 30static void rxrpc_destroy_s(struct key *); 31static void rxrpc_describe(const struct key *, struct seq_file *); 32static long rxrpc_read(const struct key *, char __user *, size_t); 33 34/* 35 * rxrpc defined keys take an arbitrary string as the description and an 36 * arbitrary blob of data as the payload 37 */ 38struct key_type key_type_rxrpc = { 39 .name = "rxrpc", 40 .instantiate = rxrpc_instantiate, 41 .match = user_match, 42 .destroy = rxrpc_destroy, 43 .describe = rxrpc_describe, 44 .read = rxrpc_read, 45}; 46EXPORT_SYMBOL(key_type_rxrpc); 47 48/* 49 * rxrpc server defined keys take "<serviceId>:<securityIndex>" as the 50 * description and an 8-byte decryption key as the payload 51 */ 52struct key_type key_type_rxrpc_s = { 53 .name = "rxrpc_s", 54 .instantiate = rxrpc_instantiate_s, 55 .match = user_match, 56 .destroy = rxrpc_destroy_s, 57 .describe = rxrpc_describe, 58}; 59 60/* 61 * parse an RxKAD type XDR format token 62 * - the caller guarantees we have at least 4 words 63 */ 64static int rxrpc_instantiate_xdr_rxkad(struct key *key, const __be32 *xdr, 65 unsigned toklen) 66{ 67 struct rxrpc_key_token *token, **pptoken; 68 size_t plen; 69 u32 tktlen; 70 int ret; 71 72 _enter(",{%x,%x,%x,%x},%u", 73 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 74 toklen); 75 76 if (toklen <= 8 * 4) 77 return -EKEYREJECTED; 78 tktlen = ntohl(xdr[7]); 79 _debug("tktlen: %x", tktlen); 80 if (tktlen > AFSTOKEN_RK_TIX_MAX) 81 return -EKEYREJECTED; 82 if (8 * 4 + tktlen != toklen) 83 return -EKEYREJECTED; 84 85 plen = sizeof(*token) + sizeof(*token->kad) + tktlen; 86 ret = key_payload_reserve(key, key->datalen + plen); 87 if (ret < 0) 88 return ret; 89 90 plen -= sizeof(*token); 91 token = kmalloc(sizeof(*token), GFP_KERNEL); 92 if (!token) 93 return -ENOMEM; 94 95 token->kad = kmalloc(plen, GFP_KERNEL); 96 if (!token->kad) { 97 kfree(token); 98 return -ENOMEM; 99 } 100 101 token->security_index = RXRPC_SECURITY_RXKAD; 102 token->kad->ticket_len = tktlen; 103 token->kad->vice_id = ntohl(xdr[0]); 104 token->kad->kvno = ntohl(xdr[1]); 105 token->kad->start = ntohl(xdr[4]); 106 token->kad->expiry = ntohl(xdr[5]); 107 token->kad->primary_flag = ntohl(xdr[6]); 108 memcpy(&token->kad->session_key, &xdr[2], 8); 109 memcpy(&token->kad->ticket, &xdr[8], tktlen); 110 111 _debug("SCIX: %u", token->security_index); 112 _debug("TLEN: %u", token->kad->ticket_len); 113 _debug("EXPY: %x", token->kad->expiry); 114 _debug("KVNO: %u", token->kad->kvno); 115 _debug("PRIM: %u", token->kad->primary_flag); 116 _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", 117 token->kad->session_key[0], token->kad->session_key[1], 118 token->kad->session_key[2], token->kad->session_key[3], 119 token->kad->session_key[4], token->kad->session_key[5], 120 token->kad->session_key[6], token->kad->session_key[7]); 121 if (token->kad->ticket_len >= 8) 122 _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", 123 token->kad->ticket[0], token->kad->ticket[1], 124 token->kad->ticket[2], token->kad->ticket[3], 125 token->kad->ticket[4], token->kad->ticket[5], 126 token->kad->ticket[6], token->kad->ticket[7]); 127 128 /* count the number of tokens attached */ 129 key->type_data.x[0]++; 130 131 /* attach the data */ 132 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 133 *pptoken; 134 pptoken = &(*pptoken)->next) 135 continue; 136 *pptoken = token; 137 if (token->kad->expiry < key->expiry) 138 key->expiry = token->kad->expiry; 139 140 _leave(" = 0"); 141 return 0; 142} 143 144static void rxrpc_free_krb5_principal(struct krb5_principal *princ) 145{ 146 int loop; 147 148 if (princ->name_parts) { 149 for (loop = princ->n_name_parts - 1; loop >= 0; loop--) 150 kfree(princ->name_parts[loop]); 151 kfree(princ->name_parts); 152 } 153 kfree(princ->realm); 154} 155 156static void rxrpc_free_krb5_tagged(struct krb5_tagged_data *td) 157{ 158 kfree(td->data); 159} 160 161/* 162 * free up an RxK5 token 163 */ 164static void rxrpc_rxk5_free(struct rxk5_key *rxk5) 165{ 166 int loop; 167 168 rxrpc_free_krb5_principal(&rxk5->client); 169 rxrpc_free_krb5_principal(&rxk5->server); 170 rxrpc_free_krb5_tagged(&rxk5->session); 171 172 if (rxk5->addresses) { 173 for (loop = rxk5->n_addresses - 1; loop >= 0; loop--) 174 rxrpc_free_krb5_tagged(&rxk5->addresses[loop]); 175 kfree(rxk5->addresses); 176 } 177 if (rxk5->authdata) { 178 for (loop = rxk5->n_authdata - 1; loop >= 0; loop--) 179 rxrpc_free_krb5_tagged(&rxk5->authdata[loop]); 180 kfree(rxk5->authdata); 181 } 182 183 kfree(rxk5->ticket); 184 kfree(rxk5->ticket2); 185 kfree(rxk5); 186} 187 188/* 189 * extract a krb5 principal 190 */ 191static int rxrpc_krb5_decode_principal(struct krb5_principal *princ, 192 const __be32 **_xdr, 193 unsigned *_toklen) 194{ 195 const __be32 *xdr = *_xdr; 196 unsigned toklen = *_toklen, n_parts, loop, tmp; 197 198 /* there must be at least one name, and at least #names+1 length 199 * words */ 200 if (toklen <= 12) 201 return -EINVAL; 202 203 _enter(",{%x,%x,%x},%u", 204 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), toklen); 205 206 n_parts = ntohl(*xdr++); 207 toklen -= 4; 208 if (n_parts <= 0 || n_parts > AFSTOKEN_K5_COMPONENTS_MAX) 209 return -EINVAL; 210 princ->n_name_parts = n_parts; 211 212 if (toklen <= (n_parts + 1) * 4) 213 return -EINVAL; 214 215 princ->name_parts = kcalloc(sizeof(char *), n_parts, GFP_KERNEL); 216 if (!princ->name_parts) 217 return -ENOMEM; 218 219 for (loop = 0; loop < n_parts; loop++) { 220 if (toklen < 4) 221 return -EINVAL; 222 tmp = ntohl(*xdr++); 223 toklen -= 4; 224 if (tmp <= 0 || tmp > AFSTOKEN_STRING_MAX) 225 return -EINVAL; 226 if (tmp > toklen) 227 return -EINVAL; 228 princ->name_parts[loop] = kmalloc(tmp + 1, GFP_KERNEL); 229 if (!princ->name_parts[loop]) 230 return -ENOMEM; 231 memcpy(princ->name_parts[loop], xdr, tmp); 232 princ->name_parts[loop][tmp] = 0; 233 tmp = (tmp + 3) & ~3; 234 toklen -= tmp; 235 xdr += tmp >> 2; 236 } 237 238 if (toklen < 4) 239 return -EINVAL; 240 tmp = ntohl(*xdr++); 241 toklen -= 4; 242 if (tmp <= 0 || tmp > AFSTOKEN_K5_REALM_MAX) 243 return -EINVAL; 244 if (tmp > toklen) 245 return -EINVAL; 246 princ->realm = kmalloc(tmp + 1, GFP_KERNEL); 247 if (!princ->realm) 248 return -ENOMEM; 249 memcpy(princ->realm, xdr, tmp); 250 princ->realm[tmp] = 0; 251 tmp = (tmp + 3) & ~3; 252 toklen -= tmp; 253 xdr += tmp >> 2; 254 255 _debug("%s/...@%s", princ->name_parts[0], princ->realm); 256 257 *_xdr = xdr; 258 *_toklen = toklen; 259 _leave(" = 0 [toklen=%u]", toklen); 260 return 0; 261} 262 263/* 264 * extract a piece of krb5 tagged data 265 */ 266static int rxrpc_krb5_decode_tagged_data(struct krb5_tagged_data *td, 267 size_t max_data_size, 268 const __be32 **_xdr, 269 unsigned *_toklen) 270{ 271 const __be32 *xdr = *_xdr; 272 unsigned toklen = *_toklen, len; 273 274 /* there must be at least one tag and one length word */ 275 if (toklen <= 8) 276 return -EINVAL; 277 278 _enter(",%zu,{%x,%x},%u", 279 max_data_size, ntohl(xdr[0]), ntohl(xdr[1]), toklen); 280 281 td->tag = ntohl(*xdr++); 282 len = ntohl(*xdr++); 283 toklen -= 8; 284 if (len > max_data_size) 285 return -EINVAL; 286 td->data_len = len; 287 288 if (len > 0) { 289 td->data = kmalloc(len, GFP_KERNEL); 290 if (!td->data) 291 return -ENOMEM; 292 memcpy(td->data, xdr, len); 293 len = (len + 3) & ~3; 294 toklen -= len; 295 xdr += len >> 2; 296 } 297 298 _debug("tag %x len %x", td->tag, td->data_len); 299 300 *_xdr = xdr; 301 *_toklen = toklen; 302 _leave(" = 0 [toklen=%u]", toklen); 303 return 0; 304} 305 306/* 307 * extract an array of tagged data 308 */ 309static int rxrpc_krb5_decode_tagged_array(struct krb5_tagged_data **_td, 310 u8 *_n_elem, 311 u8 max_n_elem, 312 size_t max_elem_size, 313 const __be32 **_xdr, 314 unsigned *_toklen) 315{ 316 struct krb5_tagged_data *td; 317 const __be32 *xdr = *_xdr; 318 unsigned toklen = *_toklen, n_elem, loop; 319 int ret; 320 321 /* there must be at least one count */ 322 if (toklen < 4) 323 return -EINVAL; 324 325 _enter(",,%u,%zu,{%x},%u", 326 max_n_elem, max_elem_size, ntohl(xdr[0]), toklen); 327 328 n_elem = ntohl(*xdr++); 329 toklen -= 4; 330 if (n_elem < 0 || n_elem > max_n_elem) 331 return -EINVAL; 332 *_n_elem = n_elem; 333 if (n_elem > 0) { 334 if (toklen <= (n_elem + 1) * 4) 335 return -EINVAL; 336 337 _debug("n_elem %d", n_elem); 338 339 td = kcalloc(sizeof(struct krb5_tagged_data), n_elem, 340 GFP_KERNEL); 341 if (!td) 342 return -ENOMEM; 343 *_td = td; 344 345 for (loop = 0; loop < n_elem; loop++) { 346 ret = rxrpc_krb5_decode_tagged_data(&td[loop], 347 max_elem_size, 348 &xdr, &toklen); 349 if (ret < 0) 350 return ret; 351 } 352 } 353 354 *_xdr = xdr; 355 *_toklen = toklen; 356 _leave(" = 0 [toklen=%u]", toklen); 357 return 0; 358} 359 360/* 361 * extract a krb5 ticket 362 */ 363static int rxrpc_krb5_decode_ticket(u8 **_ticket, u16 *_tktlen, 364 const __be32 **_xdr, unsigned *_toklen) 365{ 366 const __be32 *xdr = *_xdr; 367 unsigned toklen = *_toklen, len; 368 369 /* there must be at least one length word */ 370 if (toklen <= 4) 371 return -EINVAL; 372 373 _enter(",{%x},%u", ntohl(xdr[0]), toklen); 374 375 len = ntohl(*xdr++); 376 toklen -= 4; 377 if (len > AFSTOKEN_K5_TIX_MAX) 378 return -EINVAL; 379 *_tktlen = len; 380 381 _debug("ticket len %u", len); 382 383 if (len > 0) { 384 *_ticket = kmalloc(len, GFP_KERNEL); 385 if (!*_ticket) 386 return -ENOMEM; 387 memcpy(*_ticket, xdr, len); 388 len = (len + 3) & ~3; 389 toklen -= len; 390 xdr += len >> 2; 391 } 392 393 *_xdr = xdr; 394 *_toklen = toklen; 395 _leave(" = 0 [toklen=%u]", toklen); 396 return 0; 397} 398 399/* 400 * parse an RxK5 type XDR format token 401 * - the caller guarantees we have at least 4 words 402 */ 403static int rxrpc_instantiate_xdr_rxk5(struct key *key, const __be32 *xdr, 404 unsigned toklen) 405{ 406 struct rxrpc_key_token *token, **pptoken; 407 struct rxk5_key *rxk5; 408 const __be32 *end_xdr = xdr + (toklen >> 2); 409 int ret; 410 411 _enter(",{%x,%x,%x,%x},%u", 412 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 413 toklen); 414 415 /* reserve some payload space for this subkey - the length of the token 416 * is a reasonable approximation */ 417 ret = key_payload_reserve(key, key->datalen + toklen); 418 if (ret < 0) 419 return ret; 420 421 token = kzalloc(sizeof(*token), GFP_KERNEL); 422 if (!token) 423 return -ENOMEM; 424 425 rxk5 = kzalloc(sizeof(*rxk5), GFP_KERNEL); 426 if (!rxk5) { 427 kfree(token); 428 return -ENOMEM; 429 } 430 431 token->security_index = RXRPC_SECURITY_RXK5; 432 token->k5 = rxk5; 433 434 /* extract the principals */ 435 ret = rxrpc_krb5_decode_principal(&rxk5->client, &xdr, &toklen); 436 if (ret < 0) 437 goto error; 438 ret = rxrpc_krb5_decode_principal(&rxk5->server, &xdr, &toklen); 439 if (ret < 0) 440 goto error; 441 442 /* extract the session key and the encoding type (the tag field -> 443 * ENCTYPE_xxx) */ 444 ret = rxrpc_krb5_decode_tagged_data(&rxk5->session, AFSTOKEN_DATA_MAX, 445 &xdr, &toklen); 446 if (ret < 0) 447 goto error; 448 449 if (toklen < 4 * 8 + 2 * 4) 450 goto inval; 451 rxk5->authtime = be64_to_cpup((const __be64 *) xdr); 452 xdr += 2; 453 rxk5->starttime = be64_to_cpup((const __be64 *) xdr); 454 xdr += 2; 455 rxk5->endtime = be64_to_cpup((const __be64 *) xdr); 456 xdr += 2; 457 rxk5->renew_till = be64_to_cpup((const __be64 *) xdr); 458 xdr += 2; 459 rxk5->is_skey = ntohl(*xdr++); 460 rxk5->flags = ntohl(*xdr++); 461 toklen -= 4 * 8 + 2 * 4; 462 463 _debug("times: a=%llx s=%llx e=%llx rt=%llx", 464 rxk5->authtime, rxk5->starttime, rxk5->endtime, 465 rxk5->renew_till); 466 _debug("is_skey=%x flags=%x", rxk5->is_skey, rxk5->flags); 467 468 /* extract the permitted client addresses */ 469 ret = rxrpc_krb5_decode_tagged_array(&rxk5->addresses, 470 &rxk5->n_addresses, 471 AFSTOKEN_K5_ADDRESSES_MAX, 472 AFSTOKEN_DATA_MAX, 473 &xdr, &toklen); 474 if (ret < 0) 475 goto error; 476 477 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); 478 479 /* extract the tickets */ 480 ret = rxrpc_krb5_decode_ticket(&rxk5->ticket, &rxk5->ticket_len, 481 &xdr, &toklen); 482 if (ret < 0) 483 goto error; 484 ret = rxrpc_krb5_decode_ticket(&rxk5->ticket2, &rxk5->ticket2_len, 485 &xdr, &toklen); 486 if (ret < 0) 487 goto error; 488 489 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); 490 491 /* extract the typed auth data */ 492 ret = rxrpc_krb5_decode_tagged_array(&rxk5->authdata, 493 &rxk5->n_authdata, 494 AFSTOKEN_K5_AUTHDATA_MAX, 495 AFSTOKEN_BDATALN_MAX, 496 &xdr, &toklen); 497 if (ret < 0) 498 goto error; 499 500 ASSERTCMP((end_xdr - xdr) << 2, ==, toklen); 501 502 if (toklen != 0) 503 goto inval; 504 505 /* attach the payload to the key */ 506 for (pptoken = (struct rxrpc_key_token **)&key->payload.data; 507 *pptoken; 508 pptoken = &(*pptoken)->next) 509 continue; 510 *pptoken = token; 511 if (token->kad->expiry < key->expiry) 512 key->expiry = token->kad->expiry; 513 514 _leave(" = 0"); 515 return 0; 516 517inval: 518 ret = -EINVAL; 519error: 520 rxrpc_rxk5_free(rxk5); 521 kfree(token); 522 _leave(" = %d", ret); 523 return ret; 524} 525 526/* 527 * attempt to parse the data as the XDR format 528 * - the caller guarantees we have more than 7 words 529 */ 530static int rxrpc_instantiate_xdr(struct key *key, const void *data, size_t datalen) 531{ 532 const __be32 *xdr = data, *token; 533 const char *cp; 534 unsigned len, tmp, loop, ntoken, toklen, sec_ix; 535 int ret; 536 537 _enter(",{%x,%x,%x,%x},%zu", 538 ntohl(xdr[0]), ntohl(xdr[1]), ntohl(xdr[2]), ntohl(xdr[3]), 539 datalen); 540 541 if (datalen > AFSTOKEN_LENGTH_MAX) 542 goto not_xdr; 543 544 /* XDR is an array of __be32's */ 545 if (datalen & 3) 546 goto not_xdr; 547 548 /* the flags should be 0 (the setpag bit must be handled by 549 * userspace) */ 550 if (ntohl(*xdr++) != 0) 551 goto not_xdr; 552 datalen -= 4; 553 554 /* check the cell name */ 555 len = ntohl(*xdr++); 556 if (len < 1 || len > AFSTOKEN_CELL_MAX) 557 goto not_xdr; 558 datalen -= 4; 559 tmp = (len + 3) & ~3; 560 if (tmp > datalen) 561 goto not_xdr; 562 563 cp = (const char *) xdr; 564 for (loop = 0; loop < len; loop++) 565 if (!isprint(cp[loop])) 566 goto not_xdr; 567 if (len < tmp) 568 for (; loop < tmp; loop++) 569 if (cp[loop]) 570 goto not_xdr; 571 _debug("cellname: [%u/%u] '%*.*s'", 572 len, tmp, len, len, (const char *) xdr); 573 datalen -= tmp; 574 xdr += tmp >> 2; 575 576 /* get the token count */ 577 if (datalen < 12) 578 goto not_xdr; 579 ntoken = ntohl(*xdr++); 580 datalen -= 4; 581 _debug("ntoken: %x", ntoken); 582 if (ntoken < 1 || ntoken > AFSTOKEN_MAX) 583 goto not_xdr; 584 585 /* check each token wrapper */ 586 token = xdr; 587 loop = ntoken; 588 do { 589 if (datalen < 8) 590 goto not_xdr; 591 toklen = ntohl(*xdr++); 592 sec_ix = ntohl(*xdr); 593 datalen -= 4; 594 _debug("token: [%x/%zx] %x", toklen, datalen, sec_ix); 595 if (toklen < 20 || toklen > datalen) 596 goto not_xdr; 597 datalen -= (toklen + 3) & ~3; 598 xdr += (toklen + 3) >> 2; 599 600 } while (--loop > 0); 601 602 _debug("remainder: %zu", datalen); 603 if (datalen != 0) 604 goto not_xdr; 605 606 /* okay: we're going to assume it's valid XDR format 607 * - we ignore the cellname, relying on the key to be correctly named 608 */ 609 do { 610 xdr = token; 611 toklen = ntohl(*xdr++); 612 token = xdr + ((toklen + 3) >> 2); 613 sec_ix = ntohl(*xdr++); 614 toklen -= 4; 615 616 _debug("TOKEN type=%u [%p-%p]", sec_ix, xdr, token); 617 618 switch (sec_ix) { 619 case RXRPC_SECURITY_RXKAD: 620 ret = rxrpc_instantiate_xdr_rxkad(key, xdr, toklen); 621 if (ret != 0) 622 goto error; 623 break; 624 625 case RXRPC_SECURITY_RXK5: 626 ret = rxrpc_instantiate_xdr_rxk5(key, xdr, toklen); 627 if (ret != 0) 628 goto error; 629 break; 630 631 default: 632 ret = -EPROTONOSUPPORT; 633 goto error; 634 } 635 636 } while (--ntoken > 0); 637 638 _leave(" = 0"); 639 return 0; 640 641not_xdr: 642 _leave(" = -EPROTO"); 643 return -EPROTO; 644error: 645 _leave(" = %d", ret); 646 return ret; 647} 648 649/* 650 * instantiate an rxrpc defined key 651 * data should be of the form: 652 * OFFSET LEN CONTENT 653 * 0 4 key interface version number 654 * 4 2 security index (type) 655 * 6 2 ticket length 656 * 8 4 key expiry time (time_t) 657 * 12 4 kvno 658 * 16 8 session key 659 * 24 [len] ticket 660 * 661 * if no data is provided, then a no-security key is made 662 */ 663static int rxrpc_instantiate(struct key *key, const void *data, size_t datalen) 664{ 665 const struct rxrpc_key_data_v1 *v1; 666 struct rxrpc_key_token *token, **pp; 667 size_t plen; 668 u32 kver; 669 int ret; 670 671 _enter("{%x},,%zu", key_serial(key), datalen); 672 673 /* handle a no-security key */ 674 if (!data && datalen == 0) 675 return 0; 676 677 /* determine if the XDR payload format is being used */ 678 if (datalen > 7 * 4) { 679 ret = rxrpc_instantiate_xdr(key, data, datalen); 680 if (ret != -EPROTO) 681 return ret; 682 } 683 684 /* get the key interface version number */ 685 ret = -EINVAL; 686 if (datalen <= 4 || !data) 687 goto error; 688 memcpy(&kver, data, sizeof(kver)); 689 data += sizeof(kver); 690 datalen -= sizeof(kver); 691 692 _debug("KEY I/F VERSION: %u", kver); 693 694 ret = -EKEYREJECTED; 695 if (kver != 1) 696 goto error; 697 698 /* deal with a version 1 key */ 699 ret = -EINVAL; 700 if (datalen < sizeof(*v1)) 701 goto error; 702 703 v1 = data; 704 if (datalen != sizeof(*v1) + v1->ticket_length) 705 goto error; 706 707 _debug("SCIX: %u", v1->security_index); 708 _debug("TLEN: %u", v1->ticket_length); 709 _debug("EXPY: %x", v1->expiry); 710 _debug("KVNO: %u", v1->kvno); 711 _debug("SKEY: %02x%02x%02x%02x%02x%02x%02x%02x", 712 v1->session_key[0], v1->session_key[1], 713 v1->session_key[2], v1->session_key[3], 714 v1->session_key[4], v1->session_key[5], 715 v1->session_key[6], v1->session_key[7]); 716 if (v1->ticket_length >= 8) 717 _debug("TCKT: %02x%02x%02x%02x%02x%02x%02x%02x", 718 v1->ticket[0], v1->ticket[1], 719 v1->ticket[2], v1->ticket[3], 720 v1->ticket[4], v1->ticket[5], 721 v1->ticket[6], v1->ticket[7]); 722 723 ret = -EPROTONOSUPPORT; 724 if (v1->security_index != RXRPC_SECURITY_RXKAD) 725 goto error; 726 727 plen = sizeof(*token->kad) + v1->ticket_length; 728 ret = key_payload_reserve(key, plen + sizeof(*token)); 729 if (ret < 0) 730 goto error; 731 732 ret = -ENOMEM; 733 token = kmalloc(sizeof(*token), GFP_KERNEL); 734 if (!token) 735 goto error; 736 token->kad = kmalloc(plen, GFP_KERNEL); 737 if (!token->kad) 738 goto error_free; 739 740 token->security_index = RXRPC_SECURITY_RXKAD; 741 token->kad->ticket_len = v1->ticket_length; 742 token->kad->expiry = v1->expiry; 743 token->kad->kvno = v1->kvno; 744 memcpy(&token->kad->session_key, &v1->session_key, 8); 745 memcpy(&token->kad->ticket, v1->ticket, v1->ticket_length); 746 747 /* attach the data */ 748 key->type_data.x[0]++; 749 750 pp = (struct rxrpc_key_token **)&key->payload.data; 751 while (*pp) 752 pp = &(*pp)->next; 753 *pp = token; 754 if (token->kad->expiry < key->expiry) 755 key->expiry = token->kad->expiry; 756 token = NULL; 757 ret = 0; 758 759error_free: 760 kfree(token); 761error: 762 return ret; 763} 764 765/* 766 * instantiate a server secret key 767 * data should be a pointer to the 8-byte secret key 768 */ 769static int rxrpc_instantiate_s(struct key *key, const void *data, 770 size_t datalen) 771{ 772 struct crypto_blkcipher *ci; 773 774 _enter("{%x},,%zu", key_serial(key), datalen); 775 776 if (datalen != 8) 777 return -EINVAL; 778 779 memcpy(&key->type_data, data, 8); 780 781 ci = crypto_alloc_blkcipher("pcbc(des)", 0, CRYPTO_ALG_ASYNC); 782 if (IS_ERR(ci)) { 783 _leave(" = %ld", PTR_ERR(ci)); 784 return PTR_ERR(ci); 785 } 786 787 if (crypto_blkcipher_setkey(ci, data, 8) < 0) 788 BUG(); 789 790 key->payload.data = ci; 791 _leave(" = 0"); 792 return 0; 793} 794 795/* 796 * dispose of the data dangling from the corpse of a rxrpc key 797 */ 798static void rxrpc_destroy(struct key *key) 799{ 800 struct rxrpc_key_token *token; 801 802 while ((token = key->payload.data)) { 803 key->payload.data = token->next; 804 switch (token->security_index) { 805 case RXRPC_SECURITY_RXKAD: 806 kfree(token->kad); 807 break; 808 case RXRPC_SECURITY_RXK5: 809 if (token->k5) 810 rxrpc_rxk5_free(token->k5); 811 break; 812 default: 813 printk(KERN_ERR "Unknown token type %x on rxrpc key\n", 814 token->security_index); 815 BUG(); 816 } 817 818 kfree(token); 819 } 820} 821 822/* 823 * dispose of the data dangling from the corpse of a rxrpc key 824 */ 825static void rxrpc_destroy_s(struct key *key) 826{ 827 if (key->payload.data) { 828 crypto_free_blkcipher(key->payload.data); 829 key->payload.data = NULL; 830 } 831} 832 833/* 834 * describe the rxrpc key 835 */ 836static void rxrpc_describe(const struct key *key, struct seq_file *m) 837{ 838 seq_puts(m, key->description); 839} 840 841/* 842 * grab the security key for a socket 843 */ 844int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen) 845{ 846 struct key *key; 847 char *description; 848 849 _enter(""); 850 851 if (optlen <= 0 || optlen > PAGE_SIZE - 1) 852 return -EINVAL; 853 854 description = kmalloc(optlen + 1, GFP_KERNEL); 855 if (!description) 856 return -ENOMEM; 857 858 if (copy_from_user(description, optval, optlen)) { 859 kfree(description); 860 return -EFAULT; 861 } 862 description[optlen] = 0; 863 864 key = request_key(&key_type_rxrpc, description, NULL); 865 if (IS_ERR(key)) { 866 kfree(description); 867 _leave(" = %ld", PTR_ERR(key)); 868 return PTR_ERR(key); 869 } 870 871 rx->key = key; 872 kfree(description); 873 _leave(" = 0 [key %x]", key->serial); 874 return 0; 875} 876 877/* 878 * grab the security keyring for a server socket 879 */ 880int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval, 881 int optlen) 882{ 883 struct key *key; 884 char *description; 885 886 _enter(""); 887 888 if (optlen <= 0 || optlen > PAGE_SIZE - 1) 889 return -EINVAL; 890 891 description = kmalloc(optlen + 1, GFP_KERNEL); 892 if (!description) 893 return -ENOMEM; 894 895 if (copy_from_user(description, optval, optlen)) { 896 kfree(description); 897 return -EFAULT; 898 } 899 description[optlen] = 0; 900 901 key = request_key(&key_type_keyring, description, NULL); 902 if (IS_ERR(key)) { 903 kfree(description); 904 _leave(" = %ld", PTR_ERR(key)); 905 return PTR_ERR(key); 906 } 907 908 rx->securities = key; 909 kfree(description); 910 _leave(" = 0 [key %x]", key->serial); 911 return 0; 912} 913 914/* 915 * generate a server data key 916 */ 917int rxrpc_get_server_data_key(struct rxrpc_connection *conn, 918 const void *session_key, 919 time_t expiry, 920 u32 kvno) 921{ 922 const struct cred *cred = current_cred(); 923 struct key *key; 924 int ret; 925 926 struct { 927 u32 kver; 928 struct rxrpc_key_data_v1 v1; 929 } data; 930 931 _enter(""); 932 933 key = key_alloc(&key_type_rxrpc, "x", 0, 0, cred, 0, 934 KEY_ALLOC_NOT_IN_QUOTA); 935 if (IS_ERR(key)) { 936 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 937 return -ENOMEM; 938 } 939 940 _debug("key %d", key_serial(key)); 941 942 data.kver = 1; 943 data.v1.security_index = RXRPC_SECURITY_RXKAD; 944 data.v1.ticket_length = 0; 945 data.v1.expiry = expiry; 946 data.v1.kvno = 0; 947 948 memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key)); 949 950 ret = key_instantiate_and_link(key, &data, sizeof(data), NULL, NULL); 951 if (ret < 0) 952 goto error; 953 954 conn->key = key; 955 _leave(" = 0 [%d]", key_serial(key)); 956 return 0; 957 958error: 959 key_revoke(key); 960 key_put(key); 961 _leave(" = -ENOMEM [ins %d]", ret); 962 return -ENOMEM; 963} 964EXPORT_SYMBOL(rxrpc_get_server_data_key); 965 966/** 967 * rxrpc_get_null_key - Generate a null RxRPC key 968 * @keyname: The name to give the key. 969 * 970 * Generate a null RxRPC key that can be used to indicate anonymous security is 971 * required for a particular domain. 972 */ 973struct key *rxrpc_get_null_key(const char *keyname) 974{ 975 const struct cred *cred = current_cred(); 976 struct key *key; 977 int ret; 978 979 key = key_alloc(&key_type_rxrpc, keyname, 0, 0, cred, 980 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 981 if (IS_ERR(key)) 982 return key; 983 984 ret = key_instantiate_and_link(key, NULL, 0, NULL, NULL); 985 if (ret < 0) { 986 key_revoke(key); 987 key_put(key); 988 return ERR_PTR(ret); 989 } 990 991 return key; 992} 993EXPORT_SYMBOL(rxrpc_get_null_key); 994 995/* 996 * read the contents of an rxrpc key 997 * - this returns the result in XDR form 998 */ 999static long rxrpc_read(const struct key *key, 1000 char __user *buffer, size_t buflen) 1001{ 1002 const struct rxrpc_key_token *token; 1003 const struct krb5_principal *princ; 1004 size_t size; 1005 __be32 __user *xdr, *oldxdr; 1006 u32 cnlen, toksize, ntoks, tok, zero; 1007 u16 toksizes[AFSTOKEN_MAX]; 1008 int loop; 1009 1010 _enter(""); 1011 1012 /* we don't know what form we should return non-AFS keys in */ 1013 if (memcmp(key->description, "afs@", 4) != 0) 1014 return -EOPNOTSUPP; 1015 cnlen = strlen(key->description + 4); 1016 1017#define RND(X) (((X) + 3) & ~3) 1018 1019 /* AFS keys we return in XDR form, so we need to work out the size of 1020 * the XDR */ 1021 size = 2 * 4; /* flags, cellname len */ 1022 size += RND(cnlen); /* cellname */ 1023 size += 1 * 4; /* token count */ 1024 1025 ntoks = 0; 1026 for (token = key->payload.data; token; token = token->next) { 1027 toksize = 4; /* sec index */ 1028 1029 switch (token->security_index) { 1030 case RXRPC_SECURITY_RXKAD: 1031 toksize += 8 * 4; /* viceid, kvno, key*2, begin, 1032 * end, primary, tktlen */ 1033 toksize += RND(token->kad->ticket_len); 1034 break; 1035 1036 case RXRPC_SECURITY_RXK5: 1037 princ = &token->k5->client; 1038 toksize += 4 + princ->n_name_parts * 4; 1039 for (loop = 0; loop < princ->n_name_parts; loop++) 1040 toksize += RND(strlen(princ->name_parts[loop])); 1041 toksize += 4 + RND(strlen(princ->realm)); 1042 1043 princ = &token->k5->server; 1044 toksize += 4 + princ->n_name_parts * 4; 1045 for (loop = 0; loop < princ->n_name_parts; loop++) 1046 toksize += RND(strlen(princ->name_parts[loop])); 1047 toksize += 4 + RND(strlen(princ->realm)); 1048 1049 toksize += 8 + RND(token->k5->session.data_len); 1050 1051 toksize += 4 * 8 + 2 * 4; 1052 1053 toksize += 4 + token->k5->n_addresses * 8; 1054 for (loop = 0; loop < token->k5->n_addresses; loop++) 1055 toksize += RND(token->k5->addresses[loop].data_len); 1056 1057 toksize += 4 + RND(token->k5->ticket_len); 1058 toksize += 4 + RND(token->k5->ticket2_len); 1059 1060 toksize += 4 + token->k5->n_authdata * 8; 1061 for (loop = 0; loop < token->k5->n_authdata; loop++) 1062 toksize += RND(token->k5->authdata[loop].data_len); 1063 break; 1064 1065 default: /* we have a ticket we can't encode */ 1066 BUG(); 1067 continue; 1068 } 1069 1070 _debug("token[%u]: toksize=%u", ntoks, toksize); 1071 ASSERTCMP(toksize, <=, AFSTOKEN_LENGTH_MAX); 1072 1073 toksizes[ntoks++] = toksize; 1074 size += toksize + 4; /* each token has a length word */ 1075 } 1076 1077#undef RND 1078 1079 if (!buffer || buflen < size) 1080 return size; 1081 1082 xdr = (__be32 __user *) buffer; 1083 zero = 0; 1084#define ENCODE(x) \ 1085 do { \ 1086 __be32 y = htonl(x); \ 1087 if (put_user(y, xdr++) < 0) \ 1088 goto fault; \ 1089 } while(0) 1090#define ENCODE_DATA(l, s) \ 1091 do { \ 1092 u32 _l = (l); \ 1093 ENCODE(l); \ 1094 if (copy_to_user(xdr, (s), _l) != 0) \ 1095 goto fault; \ 1096 if (_l & 3 && \ 1097 copy_to_user((u8 *)xdr + _l, &zero, 4 - (_l & 3)) != 0) \ 1098 goto fault; \ 1099 xdr += (_l + 3) >> 2; \ 1100 } while(0) 1101#define ENCODE64(x) \ 1102 do { \ 1103 __be64 y = cpu_to_be64(x); \ 1104 if (copy_to_user(xdr, &y, 8) != 0) \ 1105 goto fault; \ 1106 xdr += 8 >> 2; \ 1107 } while(0) 1108#define ENCODE_STR(s) \ 1109 do { \ 1110 const char *_s = (s); \ 1111 ENCODE_DATA(strlen(_s), _s); \ 1112 } while(0) 1113 1114 ENCODE(0); /* flags */ 1115 ENCODE_DATA(cnlen, key->description + 4); /* cellname */ 1116 ENCODE(ntoks); 1117 1118 tok = 0; 1119 for (token = key->payload.data; token; token = token->next) { 1120 toksize = toksizes[tok++]; 1121 ENCODE(toksize); 1122 oldxdr = xdr; 1123 ENCODE(token->security_index); 1124 1125 switch (token->security_index) { 1126 case RXRPC_SECURITY_RXKAD: 1127 ENCODE(token->kad->vice_id); 1128 ENCODE(token->kad->kvno); 1129 ENCODE_DATA(8, token->kad->session_key); 1130 ENCODE(token->kad->start); 1131 ENCODE(token->kad->expiry); 1132 ENCODE(token->kad->primary_flag); 1133 ENCODE_DATA(token->kad->ticket_len, token->kad->ticket); 1134 break; 1135 1136 case RXRPC_SECURITY_RXK5: 1137 princ = &token->k5->client; 1138 ENCODE(princ->n_name_parts); 1139 for (loop = 0; loop < princ->n_name_parts; loop++) 1140 ENCODE_STR(princ->name_parts[loop]); 1141 ENCODE_STR(princ->realm); 1142 1143 princ = &token->k5->server; 1144 ENCODE(princ->n_name_parts); 1145 for (loop = 0; loop < princ->n_name_parts; loop++) 1146 ENCODE_STR(princ->name_parts[loop]); 1147 ENCODE_STR(princ->realm); 1148 1149 ENCODE(token->k5->session.tag); 1150 ENCODE_DATA(token->k5->session.data_len, 1151 token->k5->session.data); 1152 1153 ENCODE64(token->k5->authtime); 1154 ENCODE64(token->k5->starttime); 1155 ENCODE64(token->k5->endtime); 1156 ENCODE64(token->k5->renew_till); 1157 ENCODE(token->k5->is_skey); 1158 ENCODE(token->k5->flags); 1159 1160 ENCODE(token->k5->n_addresses); 1161 for (loop = 0; loop < token->k5->n_addresses; loop++) { 1162 ENCODE(token->k5->addresses[loop].tag); 1163 ENCODE_DATA(token->k5->addresses[loop].data_len, 1164 token->k5->addresses[loop].data); 1165 } 1166 1167 ENCODE_DATA(token->k5->ticket_len, token->k5->ticket); 1168 ENCODE_DATA(token->k5->ticket2_len, token->k5->ticket2); 1169 1170 ENCODE(token->k5->n_authdata); 1171 for (loop = 0; loop < token->k5->n_authdata; loop++) { 1172 ENCODE(token->k5->authdata[loop].tag); 1173 ENCODE_DATA(token->k5->authdata[loop].data_len, 1174 token->k5->authdata[loop].data); 1175 } 1176 break; 1177 1178 default: 1179 BUG(); 1180 break; 1181 } 1182 1183 ASSERTCMP((unsigned long)xdr - (unsigned long)oldxdr, ==, 1184 toksize); 1185 } 1186 1187#undef ENCODE_STR 1188#undef ENCODE_DATA 1189#undef ENCODE64 1190#undef ENCODE 1191 1192 ASSERTCMP(tok, ==, ntoks); 1193 ASSERTCMP((char __user *) xdr - buffer, ==, size); 1194 _leave(" = %zu", size); 1195 return size; 1196 1197fault: 1198 _leave(" = -EFAULT"); 1199 return -EFAULT; 1200}