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