From 97ef85c9aa0291cb4b1670ffd29299014b18ffad Mon Sep 17 00:00:00 2001 From: Sylvain Rochet Date: Thu, 27 Aug 2015 01:58:35 +0200 Subject: [PATCH] PPP, MPPE, fixed TCP over MPPE We used to modify in place the packet payload during encryption, it works well for UDP and ICMP but TCP stack requires that we don't change the packet payload, therefore we now copy the whole packet before encryption. --- src/netif/ppp/mppe.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/netif/ppp/mppe.c b/src/netif/ppp/mppe.c index 907c820c..1996f809 100644 --- a/src/netif/ppp/mppe.c +++ b/src/netif/ppp/mppe.c @@ -198,20 +198,31 @@ void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state) err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol) { - struct pbuf *n; + struct pbuf *n, *np; u8_t *pl; + err_t err; - if (pbuf_header(*pb, (s16_t)(MPPE_OVHD + sizeof(protocol))) == 0) { - pbuf_ref(*pb); - } else { - struct pbuf *np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol), PBUF_RAM); - if (!np) { - return ERR_MEM; - } - pbuf_chain(np, *pb); - *pb = np; + /* TCP stack requires that we don't change the packet payload, therefore we copy + * the whole packet before encryption. + */ + np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_POOL); + if (!np) { + return ERR_MEM; } - pl = (u8_t*)(*pb)->payload; + + /* Hide MPPE header + protocol */ + pbuf_header(np, -(s16_t)(MPPE_OVHD + sizeof(protocol))); + + if ((err = pbuf_copy(np, *pb)) != ERR_OK) { + pbuf_free(np); + return err; + } + + /* Reveal MPPE header + protocol */ + pbuf_header(np, (s16_t)(MPPE_OVHD + sizeof(protocol))); + + *pb = np; + pl = (u8_t*)np->payload; state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount)); @@ -239,10 +250,10 @@ mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t proto pl[1] = protocol; /* Hide MPPE header */ - pbuf_header(*pb, -(s16_t)MPPE_OVHD); + pbuf_header(np, -(s16_t)MPPE_OVHD); /* Encrypt packet */ - for (n = *pb; n != NULL; n = n->next) { + for (n = np; n != NULL; n = n->next) { arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); if (n->tot_len == n->len) { break; @@ -250,7 +261,7 @@ mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t proto } /* Reveal MPPE header */ - pbuf_header(*pb, (s16_t)MPPE_OVHD); + pbuf_header(np, (s16_t)MPPE_OVHD); return ERR_OK; }