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