BA
/
BaBoRo1
Embed:
(wiki syntax)
Show/hide line numbers
lwip_mppe.c
00001 /* 00002 * mppe.c - interface MPPE to the PPP code. 00003 * 00004 * By Frank Cusack <fcusack@fcusack.com>. 00005 * Copyright (c) 2002,2003,2004 Google, Inc. 00006 * All rights reserved. 00007 * 00008 * License: 00009 * Permission to use, copy, modify, and distribute this software and its 00010 * documentation is hereby granted, provided that the above copyright 00011 * notice appears in all copies. This software is provided without any 00012 * warranty, express or implied. 00013 * 00014 * Changelog: 00015 * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com> 00016 * Only need extra skb padding on transmit, not receive. 00017 * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru> 00018 * Use Linux kernel 2.6 arc4 and sha1 routines rather than 00019 * providing our own. 00020 * 2/15/04 - TS: added #include <version.h> and testing for Kernel 00021 * version before using 00022 * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are 00023 * deprecated in 2.6 00024 */ 00025 00026 #include "netif/ppp/ppp_opts.h" 00027 #if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ 00028 00029 #include <string.h> 00030 00031 #include "lwip/err.h" 00032 00033 #include "netif/ppp/ppp_impl.h" 00034 #include "netif/ppp/ccp.h" 00035 #include "netif/ppp/mppe.h" 00036 #include "netif/ppp/pppdebug.h" 00037 #include "netif/ppp/pppcrypt.h" 00038 00039 #define SHA1_SIGNATURE_SIZE 20 00040 00041 /* ppp_mppe_state.bits definitions */ 00042 #define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */ 00043 #define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */ 00044 #define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */ 00045 #define MPPE_BIT_D 0x10 /* This is an encrypted frame */ 00046 00047 #define MPPE_BIT_FLUSHED MPPE_BIT_A 00048 #define MPPE_BIT_ENCRYPTED MPPE_BIT_D 00049 00050 #define MPPE_BITS(p) ((p)[0] & 0xf0) 00051 #define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1]) 00052 #define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */ 00053 00054 #define MPPE_OVHD 2 /* MPPE overhead/packet */ 00055 #define SANITY_MAX 1600 /* Max bogon factor we will tolerate */ 00056 00057 /* 00058 * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3. 00059 * Well, not what's written there, but rather what they meant. 00060 */ 00061 static void mppe_rekey(ppp_mppe_state * state, int initial_key) 00062 { 00063 lwip_sha1_context sha1_ctx; 00064 u8_t sha1_digest[SHA1_SIGNATURE_SIZE]; 00065 00066 /* 00067 * Key Derivation, from RFC 3078, RFC 3079. 00068 * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. 00069 */ 00070 lwip_sha1_init(&sha1_ctx); 00071 lwip_sha1_starts(&sha1_ctx); 00072 lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen); 00073 lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE); 00074 lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen); 00075 lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE); 00076 lwip_sha1_finish(&sha1_ctx, sha1_digest); 00077 lwip_sha1_free(&sha1_ctx); 00078 MEMCPY(state->session_key, sha1_digest, state->keylen); 00079 00080 if (!initial_key) { 00081 lwip_arc4_init(&state->arc4); 00082 lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen); 00083 lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen); 00084 lwip_arc4_free(&state->arc4); 00085 } 00086 if (state->keylen == 8) { 00087 /* See RFC 3078 */ 00088 state->session_key[0] = 0xd1; 00089 state->session_key[1] = 0x26; 00090 state->session_key[2] = 0x9e; 00091 } 00092 lwip_arc4_init(&state->arc4); 00093 lwip_arc4_setup(&state->arc4, state->session_key, state->keylen); 00094 } 00095 00096 /* 00097 * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we 00098 * don't have to keep multiple copies of keys. 00099 */ 00100 void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) { 00101 LWIP_UNUSED_ARG(pcb); 00102 MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN); 00103 } 00104 00105 /* 00106 * Initialize (de)compressor state. 00107 */ 00108 void 00109 mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options) 00110 { 00111 #if PPP_DEBUG 00112 const u8_t *debugstr = (const u8_t*)"mppe_comp_init"; 00113 if (&pcb->mppe_decomp == state) { 00114 debugstr = (const u8_t*)"mppe_decomp_init"; 00115 } 00116 #endif /* PPP_DEBUG */ 00117 00118 /* Save keys. */ 00119 MEMCPY(state->session_key, state->master_key, sizeof(state->master_key)); 00120 00121 if (options & MPPE_OPT_128) 00122 state->keylen = 16; 00123 else if (options & MPPE_OPT_40) 00124 state->keylen = 8; 00125 else { 00126 PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr, 00127 pcb->netif->num)); 00128 lcp_close(pcb, "MPPE required but peer negotiation failed"); 00129 return; 00130 } 00131 if (options & MPPE_OPT_STATEFUL) 00132 state->stateful = 1; 00133 00134 /* Generate the initial session key. */ 00135 mppe_rekey(state, 1); 00136 00137 #if PPP_DEBUG 00138 { 00139 int i; 00140 char mkey[sizeof(state->master_key) * 2 + 1]; 00141 char skey[sizeof(state->session_key) * 2 + 1]; 00142 00143 PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n", 00144 debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40, 00145 (state->stateful) ? "stateful" : "stateless")); 00146 00147 for (i = 0; i < (int)sizeof(state->master_key); i++) 00148 sprintf(mkey + i * 2, "%02x", state->master_key[i]); 00149 for (i = 0; i < (int)sizeof(state->session_key); i++) 00150 sprintf(skey + i * 2, "%02x", state->session_key[i]); 00151 PPPDEBUG(LOG_DEBUG, 00152 ("%s[%d]: keys: master: %s initial session: %s\n", 00153 debugstr, pcb->netif->num, mkey, skey)); 00154 } 00155 #endif /* PPP_DEBUG */ 00156 00157 /* 00158 * Initialize the coherency count. The initial value is not specified 00159 * in RFC 3078, but we can make a reasonable assumption that it will 00160 * start at 0. Setting it to the max here makes the comp/decomp code 00161 * do the right thing (determined through experiment). 00162 */ 00163 state->ccount = MPPE_CCOUNT_SPACE - 1; 00164 00165 /* 00166 * Note that even though we have initialized the key table, we don't 00167 * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1. 00168 */ 00169 state->bits = MPPE_BIT_ENCRYPTED; 00170 } 00171 00172 /* 00173 * We received a CCP Reset-Request (actually, we are sending a Reset-Ack), 00174 * tell the compressor to rekey. Note that we MUST NOT rekey for 00175 * every CCP Reset-Request; we only rekey on the next xmit packet. 00176 * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost. 00177 * So, rekeying for every CCP Reset-Request is broken as the peer will not 00178 * know how many times we've rekeyed. (If we rekey and THEN get another 00179 * CCP Reset-Request, we must rekey again.) 00180 */ 00181 void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state) 00182 { 00183 LWIP_UNUSED_ARG(pcb); 00184 state->bits |= MPPE_BIT_FLUSHED; 00185 } 00186 00187 /* 00188 * Compress (encrypt) a packet. 00189 * It's strange to call this a compressor, since the output is always 00190 * MPPE_OVHD + 2 bytes larger than the input. 00191 */ 00192 err_t 00193 mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol) 00194 { 00195 struct pbuf *n, *np; 00196 u8_t *pl; 00197 err_t err; 00198 00199 LWIP_UNUSED_ARG(pcb); 00200 00201 /* TCP stack requires that we don't change the packet payload, therefore we copy 00202 * the whole packet before encryption. 00203 */ 00204 np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_POOL); 00205 if (!np) { 00206 return ERR_MEM; 00207 } 00208 00209 /* Hide MPPE header + protocol */ 00210 pbuf_header(np, -(s16_t)(MPPE_OVHD + sizeof(protocol))); 00211 00212 if ((err = pbuf_copy(np, *pb)) != ERR_OK) { 00213 pbuf_free(np); 00214 return err; 00215 } 00216 00217 /* Reveal MPPE header + protocol */ 00218 pbuf_header(np, (s16_t)(MPPE_OVHD + sizeof(protocol))); 00219 00220 *pb = np; 00221 pl = (u8_t*)np->payload; 00222 00223 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; 00224 PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount)); 00225 /* FIXME: use PUT* macros */ 00226 pl[0] = state->ccount>>8; 00227 pl[1] = state->ccount; 00228 00229 if (!state->stateful || /* stateless mode */ 00230 ((state->ccount & 0xff) == 0xff) || /* "flag" packet */ 00231 (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */ 00232 /* We must rekey */ 00233 if (state->stateful) { 00234 PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num)); 00235 } 00236 mppe_rekey(state, 0); 00237 state->bits |= MPPE_BIT_FLUSHED; 00238 } 00239 pl[0] |= state->bits; 00240 state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */ 00241 pl += MPPE_OVHD; 00242 00243 /* Add protocol */ 00244 /* FIXME: add PFC support */ 00245 pl[0] = protocol >> 8; 00246 pl[1] = protocol; 00247 00248 /* Hide MPPE header */ 00249 pbuf_header(np, -(s16_t)MPPE_OVHD); 00250 00251 /* Encrypt packet */ 00252 for (n = np; n != NULL; n = n->next) { 00253 lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); 00254 if (n->tot_len == n->len) { 00255 break; 00256 } 00257 } 00258 00259 /* Reveal MPPE header */ 00260 pbuf_header(np, (s16_t)MPPE_OVHD); 00261 00262 return ERR_OK; 00263 } 00264 00265 /* 00266 * We received a CCP Reset-Ack. Just ignore it. 00267 */ 00268 void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state) 00269 { 00270 LWIP_UNUSED_ARG(pcb); 00271 LWIP_UNUSED_ARG(state); 00272 return; 00273 } 00274 00275 /* 00276 * Decompress (decrypt) an MPPE packet. 00277 */ 00278 err_t 00279 mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb) 00280 { 00281 struct pbuf *n0 = *pb, *n; 00282 u8_t *pl; 00283 u16_t ccount; 00284 u8_t flushed; 00285 00286 /* MPPE Header */ 00287 if (n0->len < MPPE_OVHD) { 00288 PPPDEBUG(LOG_DEBUG, 00289 ("mppe_decompress[%d]: short pkt (%d)\n", 00290 pcb->netif->num, n0->len)); 00291 state->sanity_errors += 100; 00292 goto sanity_error; 00293 } 00294 00295 pl = (u8_t*)n0->payload; 00296 flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED; 00297 ccount = MPPE_CCOUNT(pl); 00298 PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n", 00299 pcb->netif->num, ccount)); 00300 00301 /* sanity checks -- terminate with extreme prejudice */ 00302 if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) { 00303 PPPDEBUG(LOG_DEBUG, 00304 ("mppe_decompress[%d]: ENCRYPTED bit not set!\n", 00305 pcb->netif->num)); 00306 state->sanity_errors += 100; 00307 goto sanity_error; 00308 } 00309 if (!state->stateful && !flushed) { 00310 PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in " 00311 "stateless mode!\n", pcb->netif->num)); 00312 state->sanity_errors += 100; 00313 goto sanity_error; 00314 } 00315 if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) { 00316 PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on " 00317 "flag packet!\n", pcb->netif->num)); 00318 state->sanity_errors += 100; 00319 goto sanity_error; 00320 } 00321 00322 /* 00323 * Check the coherency count. 00324 */ 00325 00326 if (!state->stateful) { 00327 /* Discard late packet */ 00328 if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) { 00329 state->sanity_errors++; 00330 goto sanity_error; 00331 } 00332 00333 /* RFC 3078, sec 8.1. Rekey for every packet. */ 00334 while (state->ccount != ccount) { 00335 mppe_rekey(state, 0); 00336 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; 00337 } 00338 } else { 00339 /* RFC 3078, sec 8.2. */ 00340 if (!state->discard) { 00341 /* normal state */ 00342 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; 00343 if (ccount != state->ccount) { 00344 /* 00345 * (ccount > state->ccount) 00346 * Packet loss detected, enter the discard state. 00347 * Signal the peer to rekey (by sending a CCP Reset-Request). 00348 */ 00349 state->discard = 1; 00350 ccp_resetrequest(pcb); 00351 return ERR_BUF; 00352 } 00353 } else { 00354 /* discard state */ 00355 if (!flushed) { 00356 /* ccp.c will be silent (no additional CCP Reset-Requests). */ 00357 return ERR_BUF; 00358 } else { 00359 /* Rekey for every missed "flag" packet. */ 00360 while ((ccount & ~0xff) != 00361 (state->ccount & ~0xff)) { 00362 mppe_rekey(state, 0); 00363 state->ccount = 00364 (state->ccount + 00365 256) % MPPE_CCOUNT_SPACE; 00366 } 00367 00368 /* reset */ 00369 state->discard = 0; 00370 state->ccount = ccount; 00371 /* 00372 * Another problem with RFC 3078 here. It implies that the 00373 * peer need not send a Reset-Ack packet. But RFC 1962 00374 * requires it. Hopefully, M$ does send a Reset-Ack; even 00375 * though it isn't required for MPPE synchronization, it is 00376 * required to reset CCP state. 00377 */ 00378 } 00379 } 00380 if (flushed) 00381 mppe_rekey(state, 0); 00382 } 00383 00384 /* Hide MPPE header */ 00385 pbuf_header(n0, -(s16_t)(MPPE_OVHD)); 00386 00387 /* Decrypt the packet. */ 00388 for (n = n0; n != NULL; n = n->next) { 00389 lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); 00390 if (n->tot_len == n->len) { 00391 break; 00392 } 00393 } 00394 00395 /* good packet credit */ 00396 state->sanity_errors >>= 1; 00397 00398 return ERR_OK; 00399 00400 sanity_error: 00401 if (state->sanity_errors >= SANITY_MAX) { 00402 /* 00403 * Take LCP down if the peer is sending too many bogons. 00404 * We don't want to do this for a single or just a few 00405 * instances since it could just be due to packet corruption. 00406 */ 00407 lcp_close(pcb, "Too many MPPE errors"); 00408 } 00409 return ERR_BUF; 00410 } 00411 00412 #endif /* PPP_SUPPORT && MPPE_SUPPORT */
Generated on Tue Jul 12 2022 12:22:01 by
