1 /*- 2 * Copyright (c) 2000 Semen Ustimenko <semenu@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/types.h> 30 31 #include <arpa/inet.h> 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <termios.h> 37 #ifdef __FreeBSD__ 38 #include <sha.h> 39 #else 40 #include <openssl/sha.h> 41 #endif 42 #include <openssl/rc4.h> 43 44 #include "defs.h" 45 #include "mbuf.h" 46 #include "log.h" 47 #include "timer.h" 48 #include "fsm.h" 49 #include "lqr.h" 50 #include "hdlc.h" 51 #include "lcp.h" 52 #include "ccp.h" 53 #include "throughput.h" 54 #include "layer.h" 55 #include "link.h" 56 #include "chap_ms.h" 57 #include "proto.h" 58 #include "mppe.h" 59 #include "ua.h" 60 61 /* 62 * Documentation: 63 * 64 * draft-ietf-pppext-mppe-04.txt 65 * draft-ietf-pppext-mppe-keys-02.txt 66 */ 67 68 #define MPPE_OPT_STATELESS 0x1000000 69 #define MPPE_OPT_COMPRESSED 0x01 70 #define MPPE_OPT_40BIT 0x20 71 #define MPPE_OPT_56BIT 0x80 72 #define MPPE_OPT_128BIT 0x40 73 #define MPPE_OPT_BITMASK 0xe0 74 #define MPPE_OPT_MASK (MPPE_OPT_STATELESS | MPPE_OPT_BITMASK) 75 76 #define MPPE_FLUSHED 0x8000 77 #define MPPE_ENCRYPTED 0x1000 78 #define MPPE_HEADER_BITMASK 0xf000 79 #define MPPE_HEADER_FLAG 0x00ff 80 #define MPPE_HEADER_FLAGMASK 0x00ff 81 #define MPPE_HEADER_FLAGSHIFT 8 82 #define MPPE_HEADER_STATEFUL_KEYCHANGES 16 83 84 struct mppe_state { 85 unsigned stateless : 1; 86 unsigned flushnext : 1; 87 unsigned flushrequired : 1; 88 int cohnum; 89 int keylen; /* 8 or 16 bytes */ 90 int keybits; /* 40, 56 or 128 bits */ 91 char sesskey[MPPE_KEY_LEN]; 92 char mastkey[MPPE_KEY_LEN]; 93 RC4_KEY rc4key; 94 }; 95 96 int MPPE_MasterKeyValid = 0; 97 int MPPE_IsServer = 0; 98 char MPPE_MasterKey[MPPE_KEY_LEN]; 99 100 /* 101 * The peer has missed a packet. Mark the next output frame to be FLUSHED 102 */ 103 static int 104 MPPEResetOutput(void *v) 105 { 106 struct mppe_state *mop = (struct mppe_state *)v; 107 108 if (mop->stateless) 109 log_Printf(LogCCP, "MPPE: Unexpected output channel reset\n"); 110 else { 111 log_Printf(LogCCP, "MPPE: Output channel reset\n"); 112 mop->flushnext = 1; 113 } 114 115 return 0; /* Ask FSM not to ACK */ 116 } 117 118 static void 119 MPPEReduceSessionKey(struct mppe_state *mp) 120 { 121 switch(mp->keybits) { 122 case 40: 123 mp->sesskey[2] = 0x9e; 124 mp->sesskey[1] = 0x26; 125 case 56: 126 mp->sesskey[0] = 0xd1; 127 case 128: 128 } 129 } 130 131 static void 132 MPPEKeyChange(struct mppe_state *mp) 133 { 134 char InterimKey[MPPE_KEY_LEN]; 135 RC4_KEY RC4Key; 136 137 GetNewKeyFromSHA(mp->mastkey, mp->sesskey, mp->keylen, InterimKey); 138 RC4_set_key(&RC4Key, mp->keylen, InterimKey); 139 RC4(&RC4Key, mp->keylen, InterimKey, mp->sesskey); 140 141 MPPEReduceSessionKey(mp); 142 } 143 144 static struct mbuf * 145 MPPEOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short *proto, 146 struct mbuf *mp) 147 { 148 struct mppe_state *mop = (struct mppe_state *)v; 149 struct mbuf *mo; 150 u_short nproto, prefix; 151 int dictinit, ilen, len; 152 char *rp; 153 154 ilen = m_length(mp); 155 dictinit = 0; 156 157 log_Printf(LogDEBUG, "MPPE: Output: Proto %02x (%d bytes)\n", *proto, ilen); 158 if (*proto < 0x21 && *proto > 0xFA) { 159 log_Printf(LogDEBUG, "MPPE: Output: Not encrypting\n"); 160 ccp->compout += ilen; 161 ccp->uncompout += ilen; 162 return mp; 163 } 164 165 log_DumpBp(LogDEBUG, "MPPE: Output: Encrypt packet:", mp); 166 167 /* Get mbuf for prefixes */ 168 mo = m_get(4, MB_CCPOUT); 169 mo->m_next = mp; 170 171 rp = MBUF_CTOP(mo); 172 prefix = MPPE_ENCRYPTED | mop->cohnum; 173 174 if (mop->stateless || 175 (mop->cohnum & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) { 176 /* Change our key */ 177 log_Printf(LogDEBUG, "MPPEOutput: Key changed [%d]\n", mop->cohnum); 178 MPPEKeyChange(mop); 179 dictinit = 1; 180 } 181 182 if (mop->stateless || mop->flushnext) { 183 prefix |= MPPE_FLUSHED; 184 dictinit = 1; 185 mop->flushnext = 0; 186 } 187 188 if (dictinit) { 189 /* Initialise our dictionary */ 190 log_Printf(LogDEBUG, "MPPEOutput: Dictionary initialised [%d]\n", 191 mop->cohnum); 192 RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey); 193 } 194 195 /* Set MPPE packet prefix */ 196 ua_htons(&prefix, rp); 197 198 /* Save encrypted protocol number */ 199 nproto = htons(*proto); 200 RC4(&mop->rc4key, 2, (char *)&nproto, rp + 2); 201 202 /* Encrypt main packet */ 203 rp = MBUF_CTOP(mp); 204 RC4(&mop->rc4key, ilen, rp, rp); 205 206 mop->cohnum++; 207 mop->cohnum &= ~MPPE_HEADER_BITMASK; 208 209 /* Set the protocol number */ 210 *proto = ccp_Proto(ccp); 211 len = m_length(mo); 212 ccp->uncompout += ilen; 213 ccp->compout += len; 214 215 log_Printf(LogDEBUG, "MPPE: Output: Encrypted: Proto %02x (%d bytes)\n", 216 *proto, len); 217 218 return mo; 219 } 220 221 static void 222 MPPEResetInput(void *v) 223 { 224 log_Printf(LogCCP, "MPPE: Unexpected input channel ack\n"); 225 } 226 227 static struct mbuf * 228 MPPEInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mp) 229 { 230 struct mppe_state *mip = (struct mppe_state *)v; 231 u_short prefix; 232 char *rp; 233 int dictinit, flushed, ilen, len, n; 234 235 ilen = m_length(mp); 236 dictinit = 0; 237 ccp->compin += ilen; 238 239 log_Printf(LogDEBUG, "MPPE: Input: Proto %02x (%d bytes)\n", *proto, ilen); 240 log_DumpBp(LogDEBUG, "MPPE: Input: Packet:", mp); 241 242 mp = mbuf_Read(mp, &prefix, 2); 243 prefix = ntohs(prefix); 244 flushed = prefix & MPPE_FLUSHED; 245 prefix &= ~flushed; 246 if ((prefix & MPPE_HEADER_BITMASK) != MPPE_ENCRYPTED) { 247 log_Printf(LogERROR, "MPPE: Input: Invalid packet (flags = 0x%x)\n", 248 (prefix & MPPE_HEADER_BITMASK) | flushed); 249 m_freem(mp); 250 return NULL; 251 } 252 253 prefix &= ~MPPE_HEADER_BITMASK; 254 255 if (!flushed && mip->stateless) { 256 log_Printf(LogCCP, "MPPEInput: Packet without MPPE_FLUSHED set" 257 " in stateless mode\n"); 258 flushed = MPPE_FLUSHED; 259 /* Should we really continue ? */ 260 } 261 262 if (mip->stateless) { 263 /* Change our key for each missed packet in stateless mode */ 264 while (prefix != mip->cohnum) { 265 log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix); 266 MPPEKeyChange(mip); 267 /* 268 * mip->cohnum contains what we received last time in stateless 269 * mode. 270 */ 271 mip->cohnum++; 272 mip->cohnum &= ~MPPE_HEADER_BITMASK; 273 } 274 dictinit = 1; 275 } else { 276 if (flushed) { 277 /* 278 * We can always process a flushed packet. 279 * Catch up on any outstanding key changes. 280 */ 281 n = (prefix >> MPPE_HEADER_FLAGSHIFT) - 282 (mip->cohnum >> MPPE_HEADER_FLAGSHIFT); 283 if (n < 0) 284 n += MPPE_HEADER_STATEFUL_KEYCHANGES; 285 while (n--) { 286 log_Printf(LogDEBUG, "MPPEInput: Key changed during catchup [%u]\n", 287 prefix); 288 MPPEKeyChange(mip); 289 } 290 mip->flushrequired = 0; 291 mip->cohnum = prefix; 292 dictinit = 1; 293 } 294 295 if (mip->flushrequired) { 296 /* 297 * Perhaps we should be lenient if 298 * (prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG 299 * The spec says that we shouldn't be though.... 300 */ 301 log_Printf(LogDEBUG, "MPPE: Not flushed - discarded\n"); 302 fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0, 303 MB_CCPOUT); 304 m_freem(mp); 305 return NULL; 306 } 307 308 if (prefix != mip->cohnum) { 309 /* 310 * We're in stateful mode and didn't receive the expected 311 * packet. Send a reset request, but don't tell the CCP layer 312 * about it as we don't expect to receive a Reset ACK ! 313 * Guess what... M$ invented this ! 314 */ 315 log_Printf(LogCCP, "MPPE: Input: Got seq %u, not %u\n", 316 prefix, mip->cohnum); 317 fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->fsm.reqid++, NULL, 0, 318 MB_CCPOUT); 319 mip->flushrequired = 1; 320 m_freem(mp); 321 return NULL; 322 } 323 324 if ((prefix & MPPE_HEADER_FLAGMASK) == MPPE_HEADER_FLAG) { 325 log_Printf(LogDEBUG, "MPPEInput: Key changed [%u]\n", prefix); 326 MPPEKeyChange(mip); 327 dictinit = 1; 328 } else if (flushed) 329 dictinit = 1; 330 331 /* 332 * mip->cohnum contains what we expect to receive next time in stateful 333 * mode. 334 */ 335 mip->cohnum++; 336 mip->cohnum &= ~MPPE_HEADER_BITMASK; 337 } 338 339 if (dictinit) { 340 log_Printf(LogDEBUG, "MPPEInput: Dictionary initialised [%u]\n", prefix); 341 RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey); 342 } 343 344 mp = mbuf_Read(mp, proto, 2); 345 RC4(&mip->rc4key, 2, (char *)proto, (char *)proto); 346 *proto = ntohs(*proto); 347 348 rp = MBUF_CTOP(mp); 349 len = m_length(mp); 350 RC4(&mip->rc4key, len, rp, rp); 351 352 log_Printf(LogDEBUG, "MPPEInput: Decrypted: Proto %02x (%d bytes)\n", 353 *proto, len); 354 log_DumpBp(LogDEBUG, "MPPEInput: Decrypted: Packet:", mp); 355 356 ccp->uncompin += len; 357 358 return mp; 359 } 360 361 static void 362 MPPEDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi) 363 { 364 } 365 366 static const char * 367 MPPEDispOpts(struct lcp_opt *o) 368 { 369 static char buf[70]; 370 u_int32_t val; 371 char ch; 372 int len; 373 374 ua_ntohl(o->data, &val); 375 snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val); 376 len = strlen(buf); 377 if (!(val & MPPE_OPT_BITMASK)) { 378 snprintf(buf + len, sizeof buf - len, "(0"); 379 len++; 380 } else { 381 ch = '('; 382 if (val & MPPE_OPT_128BIT) { 383 snprintf(buf + len, sizeof buf - len, "%c128", ch); 384 len += strlen(buf + len); 385 ch = '/'; 386 } 387 if (val & MPPE_OPT_56BIT) { 388 snprintf(buf + len, sizeof buf - len, "%c56", ch); 389 len += strlen(buf + len); 390 ch = '/'; 391 } 392 if (val & MPPE_OPT_40BIT) { 393 snprintf(buf + len, sizeof buf - len, "%c40", ch); 394 len += strlen(buf + len); 395 ch = '/'; 396 } 397 } 398 399 snprintf(buf + len, sizeof buf - len, " bits, state%s", 400 (val & MPPE_OPT_STATELESS) ? "less" : "ful"); 401 len += strlen(buf + len); 402 403 if (val & MPPE_OPT_COMPRESSED) { 404 snprintf(buf + len, sizeof buf - len, ", compressed"); 405 len += strlen(buf + len); 406 } 407 408 snprintf(buf + len, sizeof buf - len, ")"); 409 410 return buf; 411 } 412 413 static int 414 MPPEUsable(struct fsm *fp) 415 { 416 struct lcp *lcp; 417 int ok; 418 419 lcp = &fp->link->lcp; 420 ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) || 421 (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81); 422 if (!ok) 423 log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n"); 424 425 return ok; 426 } 427 428 static int 429 MPPERequired(struct fsm *fp) 430 { 431 return fp->link->ccp.cfg.mppe.required; 432 } 433 434 static u_int32_t 435 MPPE_ConfigVal(const struct ccp_config *cfg) 436 { 437 u_int32_t val; 438 439 val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0; 440 switch(cfg->mppe.keybits) { 441 case 128: 442 val |= MPPE_OPT_128BIT; 443 break; 444 case 56: 445 val |= MPPE_OPT_56BIT; 446 break; 447 case 40: 448 val |= MPPE_OPT_40BIT; 449 break; 450 case 0: 451 val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT; 452 break; 453 } 454 455 return val; 456 } 457 458 /* 459 * What options should we use for our first configure request 460 */ 461 static void 462 MPPEInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) 463 { 464 u_int32_t mval; 465 466 o->len = 6; 467 468 if (!MPPE_MasterKeyValid) { 469 log_Printf(LogCCP, "MPPE: MasterKey is invalid," 470 " MPPE is available only with CHAP81 authentication\n"); 471 ua_htonl(0x0, o->data); 472 return; 473 } 474 475 mval = MPPE_ConfigVal(cfg); 476 ua_htonl(&mval, o->data); 477 } 478 479 /* 480 * Our CCP request was NAK'd with the given options 481 */ 482 static int 483 MPPESetOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg) 484 { 485 u_int32_t mval, peer; 486 487 ua_ntohl(o->data, &peer); 488 489 if (!MPPE_MasterKeyValid) 490 /* Treat their NAK as a REJ */ 491 return MODE_NAK; 492 493 mval = MPPE_ConfigVal(cfg); 494 495 /* 496 * If we haven't been configured with a specific number of keybits, allow 497 * whatever the peer asks for. 498 */ 499 if (!cfg->mppe.keybits) { 500 mval &= ~MPPE_OPT_BITMASK; 501 mval |= (peer & MPPE_OPT_BITMASK); 502 if (!(mval & MPPE_OPT_BITMASK)) 503 mval |= MPPE_OPT_128BIT; 504 } 505 506 /* Adjust our statelessness */ 507 if (cfg->mppe.state == MPPE_ANYSTATE) { 508 mval &= ~MPPE_OPT_STATELESS; 509 mval |= (peer & MPPE_OPT_STATELESS); 510 } 511 512 ua_htonl(&mval, o->data); 513 514 return MODE_ACK; 515 } 516 517 /* 518 * The peer has requested the given options 519 */ 520 static int 521 MPPESetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg) 522 { 523 u_int32_t mval, peer; 524 int res = MODE_ACK; 525 526 ua_ntohl(o->data, &peer); 527 if (!MPPE_MasterKeyValid) { 528 if (peer != 0) { 529 peer = 0; 530 ua_htonl(&peer, o->data); 531 return MODE_NAK; 532 } else 533 return MODE_ACK; 534 } 535 536 mval = MPPE_ConfigVal(cfg); 537 538 if (peer & ~MPPE_OPT_MASK) 539 /* He's asking for bits we don't know about */ 540 res = MODE_NAK; 541 542 if (peer & MPPE_OPT_STATELESS) { 543 if (cfg->mppe.state == MPPE_STATEFUL) 544 /* Peer can't have stateless */ 545 res = MODE_NAK; 546 else 547 /* Peer wants stateless, that's ok */ 548 mval |= MPPE_OPT_STATELESS; 549 } else { 550 if (cfg->mppe.state == MPPE_STATELESS) 551 /* Peer must have stateless */ 552 res = MODE_NAK; 553 else 554 /* Peer doesn't want stateless, that's ok */ 555 mval &= ~MPPE_OPT_STATELESS; 556 } 557 558 /* If we've got a configured number of keybits - the peer must use that */ 559 if (cfg->mppe.keybits) { 560 ua_htonl(&mval, o->data); 561 return peer == mval ? res : MODE_NAK; 562 } 563 564 /* If a specific number of bits hasn't been requested, we'll need to NAK */ 565 switch (peer & MPPE_OPT_BITMASK) { 566 case MPPE_OPT_128BIT: 567 case MPPE_OPT_56BIT: 568 case MPPE_OPT_40BIT: 569 break; 570 default: 571 res = MODE_NAK; 572 } 573 574 /* Suggest the best number of bits */ 575 mval &= ~MPPE_OPT_BITMASK; 576 if (peer & MPPE_OPT_128BIT) 577 mval |= MPPE_OPT_128BIT; 578 else if (peer & MPPE_OPT_56BIT) 579 mval |= MPPE_OPT_56BIT; 580 else if (peer & MPPE_OPT_40BIT) 581 mval |= MPPE_OPT_40BIT; 582 else 583 mval |= MPPE_OPT_128BIT; 584 ua_htonl(&mval, o->data); 585 586 return res; 587 } 588 589 static struct mppe_state * 590 MPPE_InitState(struct lcp_opt *o) 591 { 592 struct mppe_state *mp; 593 u_int32_t val; 594 595 if ((mp = calloc(1, sizeof *mp)) != NULL) { 596 ua_ntohl(o->data, &val); 597 598 switch (val & MPPE_OPT_BITMASK) { 599 case MPPE_OPT_128BIT: 600 mp->keylen = 16; 601 mp->keybits = 128; 602 break; 603 case MPPE_OPT_56BIT: 604 mp->keylen = 8; 605 mp->keybits = 56; 606 break; 607 case MPPE_OPT_40BIT: 608 mp->keylen = 8; 609 mp->keybits = 40; 610 break; 611 default: 612 log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val); 613 free(mp); 614 return NULL; 615 } 616 617 mp->stateless = !!(val & MPPE_OPT_STATELESS); 618 } 619 620 return mp; 621 } 622 623 static void * 624 MPPEInitInput(struct lcp_opt *o) 625 { 626 struct mppe_state *mip; 627 628 if (!MPPE_MasterKeyValid) { 629 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 630 return NULL; 631 } 632 633 if ((mip = MPPE_InitState(o)) == NULL) { 634 log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n"); 635 return NULL; 636 } 637 638 log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits); 639 640 GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0, 641 MPPE_IsServer); 642 GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey); 643 644 MPPEReduceSessionKey(mip); 645 646 log_Printf(LogCCP, "MPPE: Input channel initiated\n"); 647 648 if (!mip->stateless) { 649 /* 650 * We need to initialise our dictionary here as the first packet we 651 * receive is unlikely to have the FLUSHED bit set. 652 */ 653 log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n", 654 mip->cohnum); 655 RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey); 656 } else { 657 /* 658 * We do the first key change here as the first packet is expected 659 * to have a sequence number of 0 and we'll therefore not expect 660 * to have to change the key at that point. 661 */ 662 log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum); 663 MPPEKeyChange(mip); 664 } 665 666 return mip; 667 } 668 669 static void * 670 MPPEInitOutput(struct lcp_opt *o) 671 { 672 struct mppe_state *mop; 673 674 if (!MPPE_MasterKeyValid) { 675 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 676 return NULL; 677 } 678 679 if ((mop = MPPE_InitState(o)) == NULL) { 680 log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n"); 681 return NULL; 682 } 683 684 log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits); 685 686 GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1, 687 MPPE_IsServer); 688 GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey); 689 690 MPPEReduceSessionKey(mop); 691 692 log_Printf(LogCCP, "MPPE: Output channel initiated\n"); 693 694 if (!mop->stateless) { 695 /* 696 * We need to initialise our dictionary now as the first packet we 697 * send won't have the FLUSHED bit set. 698 */ 699 log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n", 700 mop->cohnum); 701 RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey); 702 } 703 704 return mop; 705 } 706 707 static void 708 MPPETermInput(void *v) 709 { 710 free(v); 711 } 712 713 static void 714 MPPETermOutput(void *v) 715 { 716 free(v); 717 } 718 719 const struct ccp_algorithm MPPEAlgorithm = { 720 TY_MPPE, 721 CCP_NEG_MPPE, 722 MPPEDispOpts, 723 MPPEUsable, 724 MPPERequired, 725 { 726 MPPESetOptsInput, 727 MPPEInitInput, 728 MPPETermInput, 729 MPPEResetInput, 730 MPPEInput, 731 MPPEDictSetup 732 }, 733 { 734 2, 735 MPPEInitOptsOutput, 736 MPPESetOptsOutput, 737 MPPEInitOutput, 738 MPPETermOutput, 739 MPPEResetOutput, 740 MPPEOutput 741 }, 742 }; 743