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 fsm_opt *o) 368 { 369 static char buf[70]; 370 u_int32_t val; 371 char ch; 372 int len, n; 373 374 ua_ntohl(o->data, &val); 375 len = 0; 376 if ((n = snprintf(buf, sizeof buf, "value 0x%08x ", (unsigned)val)) > 0) 377 len += n; 378 if (!(val & MPPE_OPT_BITMASK)) { 379 if ((n = snprintf(buf + len, sizeof buf - len, "(0")) > 0) 380 len += n; 381 } else { 382 ch = '('; 383 if (val & MPPE_OPT_128BIT) { 384 if ((n = snprintf(buf + len, sizeof buf - len, "%c128", ch)) > 0) 385 len += n; 386 ch = '/'; 387 } 388 if (val & MPPE_OPT_56BIT) { 389 if ((n = snprintf(buf + len, sizeof buf - len, "%c56", ch)) > 0) 390 len += n; 391 ch = '/'; 392 } 393 if (val & MPPE_OPT_40BIT) { 394 if ((n = snprintf(buf + len, sizeof buf - len, "%c40", ch)) > 0) 395 len += n; 396 ch = '/'; 397 } 398 } 399 400 if ((n = snprintf(buf + len, sizeof buf - len, " bits, state%s", 401 (val & MPPE_OPT_STATELESS) ? "less" : "ful")) > 0) 402 len += n; 403 404 if (val & MPPE_OPT_COMPRESSED) { 405 if ((n = snprintf(buf + len, sizeof buf - len, ", compressed")) > 0) 406 len += n; 407 } 408 409 snprintf(buf + len, sizeof buf - len, ")"); 410 411 return buf; 412 } 413 414 static int 415 MPPEUsable(struct fsm *fp) 416 { 417 struct lcp *lcp; 418 int ok; 419 420 lcp = &fp->link->lcp; 421 ok = (lcp->want_auth == PROTO_CHAP && lcp->want_authtype == 0x81) || 422 (lcp->his_auth == PROTO_CHAP && lcp->his_authtype == 0x81); 423 if (!ok) 424 log_Printf(LogCCP, "MPPE: Not usable without CHAP81\n"); 425 426 return ok; 427 } 428 429 static int 430 MPPERequired(struct fsm *fp) 431 { 432 return fp->link->ccp.cfg.mppe.required; 433 } 434 435 static u_int32_t 436 MPPE_ConfigVal(const struct ccp_config *cfg) 437 { 438 u_int32_t val; 439 440 val = cfg->mppe.state == MPPE_STATELESS ? MPPE_OPT_STATELESS : 0; 441 switch(cfg->mppe.keybits) { 442 case 128: 443 val |= MPPE_OPT_128BIT; 444 break; 445 case 56: 446 val |= MPPE_OPT_56BIT; 447 break; 448 case 40: 449 val |= MPPE_OPT_40BIT; 450 break; 451 case 0: 452 val |= MPPE_OPT_128BIT | MPPE_OPT_56BIT | MPPE_OPT_40BIT; 453 break; 454 } 455 456 return val; 457 } 458 459 /* 460 * What options should we use for our first configure request 461 */ 462 static void 463 MPPEInitOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) 464 { 465 u_int32_t mval; 466 467 o->hdr.len = 6; 468 469 if (!MPPE_MasterKeyValid) { 470 log_Printf(LogCCP, "MPPE: MasterKey is invalid," 471 " MPPE is available only with CHAP81 authentication\n"); 472 ua_htonl(0x0, o->data); 473 return; 474 } 475 476 mval = MPPE_ConfigVal(cfg); 477 ua_htonl(&mval, o->data); 478 } 479 480 /* 481 * Our CCP request was NAK'd with the given options 482 */ 483 static int 484 MPPESetOptsOutput(struct fsm_opt *o, const struct ccp_config *cfg) 485 { 486 u_int32_t mval, peer; 487 488 ua_ntohl(o->data, &peer); 489 490 if (!MPPE_MasterKeyValid) 491 /* Treat their NAK as a REJ */ 492 return MODE_NAK; 493 494 mval = MPPE_ConfigVal(cfg); 495 496 /* 497 * If we haven't been configured with a specific number of keybits, allow 498 * whatever the peer asks for. 499 */ 500 if (!cfg->mppe.keybits) { 501 mval &= ~MPPE_OPT_BITMASK; 502 mval |= (peer & MPPE_OPT_BITMASK); 503 if (!(mval & MPPE_OPT_BITMASK)) 504 mval |= MPPE_OPT_128BIT; 505 } 506 507 /* Adjust our statelessness */ 508 if (cfg->mppe.state == MPPE_ANYSTATE) { 509 mval &= ~MPPE_OPT_STATELESS; 510 mval |= (peer & MPPE_OPT_STATELESS); 511 } 512 513 ua_htonl(&mval, o->data); 514 515 return MODE_ACK; 516 } 517 518 /* 519 * The peer has requested the given options 520 */ 521 static int 522 MPPESetOptsInput(struct fsm_opt *o, const struct ccp_config *cfg) 523 { 524 u_int32_t mval, peer; 525 int res = MODE_ACK; 526 527 ua_ntohl(o->data, &peer); 528 if (!MPPE_MasterKeyValid) { 529 if (peer != 0) { 530 peer = 0; 531 ua_htonl(&peer, o->data); 532 return MODE_NAK; 533 } else 534 return MODE_ACK; 535 } 536 537 mval = MPPE_ConfigVal(cfg); 538 539 if (peer & ~MPPE_OPT_MASK) 540 /* He's asking for bits we don't know about */ 541 res = MODE_NAK; 542 543 if (peer & MPPE_OPT_STATELESS) { 544 if (cfg->mppe.state == MPPE_STATEFUL) 545 /* Peer can't have stateless */ 546 res = MODE_NAK; 547 else 548 /* Peer wants stateless, that's ok */ 549 mval |= MPPE_OPT_STATELESS; 550 } else { 551 if (cfg->mppe.state == MPPE_STATELESS) 552 /* Peer must have stateless */ 553 res = MODE_NAK; 554 else 555 /* Peer doesn't want stateless, that's ok */ 556 mval &= ~MPPE_OPT_STATELESS; 557 } 558 559 /* If we've got a configured number of keybits - the peer must use that */ 560 if (cfg->mppe.keybits) { 561 ua_htonl(&mval, o->data); 562 return peer == mval ? res : MODE_NAK; 563 } 564 565 /* If a specific number of bits hasn't been requested, we'll need to NAK */ 566 switch (peer & MPPE_OPT_BITMASK) { 567 case MPPE_OPT_128BIT: 568 case MPPE_OPT_56BIT: 569 case MPPE_OPT_40BIT: 570 break; 571 default: 572 res = MODE_NAK; 573 } 574 575 /* Suggest the best number of bits */ 576 mval &= ~MPPE_OPT_BITMASK; 577 if (peer & MPPE_OPT_128BIT) 578 mval |= MPPE_OPT_128BIT; 579 else if (peer & MPPE_OPT_56BIT) 580 mval |= MPPE_OPT_56BIT; 581 else if (peer & MPPE_OPT_40BIT) 582 mval |= MPPE_OPT_40BIT; 583 else 584 mval |= MPPE_OPT_128BIT; 585 ua_htonl(&mval, o->data); 586 587 return res; 588 } 589 590 static struct mppe_state * 591 MPPE_InitState(struct fsm_opt *o) 592 { 593 struct mppe_state *mp; 594 u_int32_t val; 595 596 if ((mp = calloc(1, sizeof *mp)) != NULL) { 597 ua_ntohl(o->data, &val); 598 599 switch (val & MPPE_OPT_BITMASK) { 600 case MPPE_OPT_128BIT: 601 mp->keylen = 16; 602 mp->keybits = 128; 603 break; 604 case MPPE_OPT_56BIT: 605 mp->keylen = 8; 606 mp->keybits = 56; 607 break; 608 case MPPE_OPT_40BIT: 609 mp->keylen = 8; 610 mp->keybits = 40; 611 break; 612 default: 613 log_Printf(LogWARN, "Unexpected MPPE options 0x%08x\n", val); 614 free(mp); 615 return NULL; 616 } 617 618 mp->stateless = !!(val & MPPE_OPT_STATELESS); 619 } 620 621 return mp; 622 } 623 624 static void * 625 MPPEInitInput(struct fsm_opt *o) 626 { 627 struct mppe_state *mip; 628 629 if (!MPPE_MasterKeyValid) { 630 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 631 return NULL; 632 } 633 634 if ((mip = MPPE_InitState(o)) == NULL) { 635 log_Printf(LogWARN, "MPPEInput: Cannot initialise - unexpected options\n"); 636 return NULL; 637 } 638 639 log_Printf(LogDEBUG, "MPPE: InitInput: %d-bits\n", mip->keybits); 640 641 GetAsymetricStartKey(MPPE_MasterKey, mip->mastkey, mip->keylen, 0, 642 MPPE_IsServer); 643 GetNewKeyFromSHA(mip->mastkey, mip->mastkey, mip->keylen, mip->sesskey); 644 645 MPPEReduceSessionKey(mip); 646 647 log_Printf(LogCCP, "MPPE: Input channel initiated\n"); 648 649 if (!mip->stateless) { 650 /* 651 * We need to initialise our dictionary here as the first packet we 652 * receive is unlikely to have the FLUSHED bit set. 653 */ 654 log_Printf(LogDEBUG, "MPPEInitInput: Dictionary initialised [%d]\n", 655 mip->cohnum); 656 RC4_set_key(&mip->rc4key, mip->keylen, mip->sesskey); 657 } else { 658 /* 659 * We do the first key change here as the first packet is expected 660 * to have a sequence number of 0 and we'll therefore not expect 661 * to have to change the key at that point. 662 */ 663 log_Printf(LogDEBUG, "MPPEInitInput: Key changed [%d]\n", mip->cohnum); 664 MPPEKeyChange(mip); 665 } 666 667 return mip; 668 } 669 670 static void * 671 MPPEInitOutput(struct fsm_opt *o) 672 { 673 struct mppe_state *mop; 674 675 if (!MPPE_MasterKeyValid) { 676 log_Printf(LogWARN, "MPPE: Cannot initialise without CHAP81\n"); 677 return NULL; 678 } 679 680 if ((mop = MPPE_InitState(o)) == NULL) { 681 log_Printf(LogWARN, "MPPEOutput: Cannot initialise - unexpected options\n"); 682 return NULL; 683 } 684 685 log_Printf(LogDEBUG, "MPPE: InitOutput: %d-bits\n", mop->keybits); 686 687 GetAsymetricStartKey(MPPE_MasterKey, mop->mastkey, mop->keylen, 1, 688 MPPE_IsServer); 689 GetNewKeyFromSHA(mop->mastkey, mop->mastkey, mop->keylen, mop->sesskey); 690 691 MPPEReduceSessionKey(mop); 692 693 log_Printf(LogCCP, "MPPE: Output channel initiated\n"); 694 695 if (!mop->stateless) { 696 /* 697 * We need to initialise our dictionary now as the first packet we 698 * send won't have the FLUSHED bit set. 699 */ 700 log_Printf(LogDEBUG, "MPPEInitOutput: Dictionary initialised [%d]\n", 701 mop->cohnum); 702 RC4_set_key(&mop->rc4key, mop->keylen, mop->sesskey); 703 } 704 705 return mop; 706 } 707 708 static void 709 MPPETermInput(void *v) 710 { 711 free(v); 712 } 713 714 static void 715 MPPETermOutput(void *v) 716 { 717 free(v); 718 } 719 720 const struct ccp_algorithm MPPEAlgorithm = { 721 TY_MPPE, 722 CCP_NEG_MPPE, 723 MPPEDispOpts, 724 MPPEUsable, 725 MPPERequired, 726 { 727 MPPESetOptsInput, 728 MPPEInitInput, 729 MPPETermInput, 730 MPPEResetInput, 731 MPPEInput, 732 MPPEDictSetup 733 }, 734 { 735 2, 736 MPPEInitOptsOutput, 737 MPPESetOptsOutput, 738 MPPEInitOutput, 739 MPPETermOutput, 740 MPPEResetOutput, 741 MPPEOutput 742 }, 743 }; 744