20 #include "netif/ppp/ppp_opts.h" 21 #if PPP_SUPPORT && MPPE_SUPPORT 27 #include "netif/ppp/ppp_impl.h" 28 #include "netif/ppp/ccp.h" 29 #include "netif/ppp/mppe.h" 30 #include "netif/ppp/pppdebug.h" 31 #include "netif/ppp/pppcrypt.h" 33 #define SHA1_SIGNATURE_SIZE 20 36 #define MPPE_BIT_A 0x80 37 #define MPPE_BIT_B 0x40 38 #define MPPE_BIT_C 0x20 39 #define MPPE_BIT_D 0x10 41 #define MPPE_BIT_FLUSHED MPPE_BIT_A 42 #define MPPE_BIT_ENCRYPTED MPPE_BIT_D 44 #define MPPE_BITS(p) ((p)[0] & 0xf0) 45 #define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1]) 46 #define MPPE_CCOUNT_SPACE 0x1000 49 #define SANITY_MAX 1600 55 static void mppe_rekey(ppp_mppe_state * state,
int initial_key)
57 lwip_sha1_context sha1_ctx;
58 u8_t sha1_digest[SHA1_SIGNATURE_SIZE];
64 lwip_sha1_init(&sha1_ctx);
65 lwip_sha1_starts(&sha1_ctx);
66 lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen);
67 lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE);
68 lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen);
69 lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE);
70 lwip_sha1_finish(&sha1_ctx, sha1_digest);
71 lwip_sha1_free(&sha1_ctx);
72 MEMCPY(state->session_key, sha1_digest, state->keylen);
75 lwip_arc4_init(&state->arc4);
76 lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen);
77 lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen);
78 lwip_arc4_free(&state->arc4);
80 if (state->keylen == 8) {
82 state->session_key[0] = 0xd1;
83 state->session_key[1] = 0x26;
84 state->session_key[2] = 0x9e;
86 lwip_arc4_init(&state->arc4);
87 lwip_arc4_setup(&state->arc4, state->session_key, state->keylen);
94 void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) {
96 MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN);
103 mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options)
106 const u8_t *debugstr = (
const u8_t*)
"mppe_comp_init";
107 if (&pcb->mppe_decomp == state) {
108 debugstr = (
const u8_t*)
"mppe_decomp_init";
113 MEMCPY(state->session_key, state->master_key,
sizeof(state->master_key));
115 if (options & MPPE_OPT_128)
117 else if (options & MPPE_OPT_40)
120 PPPDEBUG(LOG_DEBUG, (
"%s[%d]: unknown key length\n", debugstr,
122 lcp_close(pcb,
"MPPE required but peer negotiation failed");
125 if (options & MPPE_OPT_STATEFUL)
129 mppe_rekey(state, 1);
134 char mkey[
sizeof(state->master_key) * 2 + 1];
135 char skey[
sizeof(state->session_key) * 2 + 1];
137 PPPDEBUG(LOG_DEBUG, (
"%s[%d]: initialized with %d-bit %s mode\n",
138 debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40,
139 (state->stateful) ?
"stateful" :
"stateless"));
141 for (i = 0; i < (int)
sizeof(state->master_key); i++)
142 sprintf(mkey + i * 2,
"%02x", state->master_key[i]);
143 for (i = 0; i < (int)
sizeof(state->session_key); i++)
144 sprintf(skey + i * 2,
"%02x", state->session_key[i]);
146 (
"%s[%d]: keys: master: %s initial session: %s\n",
147 debugstr, pcb->netif->num, mkey, skey));
157 state->ccount = MPPE_CCOUNT_SPACE - 1;
163 state->bits = MPPE_BIT_ENCRYPTED;
175 void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
178 state->bits |= MPPE_BIT_FLUSHED;
187 mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state,
struct pbuf **pb, u16_t protocol)
204 pbuf_header(np, -(s16_t)(MPPE_OVHD +
sizeof(protocol)));
212 pbuf_header(np, (s16_t)(MPPE_OVHD +
sizeof(protocol)));
217 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
218 PPPDEBUG(LOG_DEBUG, (
"mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount));
220 pl[0] = state->ccount>>8;
221 pl[1] = state->ccount;
223 if (!state->stateful ||
224 ((state->ccount & 0xff) == 0xff) ||
225 (state->bits & MPPE_BIT_FLUSHED)) {
227 if (state->stateful) {
228 PPPDEBUG(LOG_DEBUG, (
"mppe_compress[%d]: rekeying\n", pcb->netif->num));
230 mppe_rekey(state, 0);
231 state->bits |= MPPE_BIT_FLUSHED;
233 pl[0] |= state->bits;
234 state->bits &= ~MPPE_BIT_FLUSHED;
239 pl[0] = protocol >> 8;
246 for (n = np; n != NULL; n = n->
next) {
247 lwip_arc4_crypt(&state->arc4, (u8_t*)n->
payload, n->
len);
262 void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
273 mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state,
struct pbuf **pb)
275 struct pbuf *n0 = *pb, *n;
281 if (n0->
len < MPPE_OVHD) {
283 (
"mppe_decompress[%d]: short pkt (%d)\n",
284 pcb->netif->num, n0->
len));
285 state->sanity_errors += 100;
290 flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED;
291 ccount = MPPE_CCOUNT(pl);
292 PPPDEBUG(LOG_DEBUG, (
"mppe_decompress[%d]: ccount %d\n",
293 pcb->netif->num, ccount));
296 if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) {
298 (
"mppe_decompress[%d]: ENCRYPTED bit not set!\n",
300 state->sanity_errors += 100;
303 if (!state->stateful && !flushed) {
304 PPPDEBUG(LOG_DEBUG, (
"mppe_decompress[%d]: FLUSHED bit not set in " 305 "stateless mode!\n", pcb->netif->num));
306 state->sanity_errors += 100;
309 if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
310 PPPDEBUG(LOG_DEBUG, (
"mppe_decompress[%d]: FLUSHED bit not set on " 311 "flag packet!\n", pcb->netif->num));
312 state->sanity_errors += 100;
320 if (!state->stateful) {
322 if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) {
323 state->sanity_errors++;
328 while (state->ccount != ccount) {
329 mppe_rekey(state, 0);
330 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
334 if (!state->discard) {
336 state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
337 if (ccount != state->ccount) {
344 ccp_resetrequest(pcb);
354 while ((ccount & ~0xff) !=
355 (state->ccount & ~0xff)) {
356 mppe_rekey(state, 0);
359 256) % MPPE_CCOUNT_SPACE;
364 state->ccount = ccount;
375 mppe_rekey(state, 0);
382 for (n = n0; n != NULL; n = n->next) {
383 lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
384 if (n->tot_len == n->len) {
390 state->sanity_errors >>= 1;
395 if (state->sanity_errors >= SANITY_MAX) {
401 lcp_close(pcb,
"Too many MPPE errors");
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define LWIP_UNUSED_ARG(x)
u8_t pbuf_free(struct pbuf *p)