STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
mppe.c
Go to the documentation of this file.
1 /*
2  * mppe.c - interface MPPE to the PPP code.
3  *
4  * By Frank Cusack <fcusack@fcusack.com>.
5  * Copyright (c) 2002,2003,2004 Google, Inc.
6  * All rights reserved.
7  *
8  * License:
9  * Permission to use, copy, modify, and distribute this software and its
10  * documentation is hereby granted, provided that the above copyright
11  * notice appears in all copies. This software is provided without any
12  * warranty, express or implied.
13  *
14  * Changelog:
15  * 08/12/05 - Matt Domsch <Matt_Domsch@dell.com>
16  * Only need extra skb padding on transmit, not receive.
17  * 06/18/04 - Matt Domsch <Matt_Domsch@dell.com>, Oleg Makarenko <mole@quadra.ru>
18  * Use Linux kernel 2.6 arc4 and sha1 routines rather than
19  * providing our own.
20  * 2/15/04 - TS: added #include <version.h> and testing for Kernel
21  * version before using
22  * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
23  * deprecated in 2.6
24  */
25 
26 #include "lwip/opt.h"
27 #if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */
28 
29 #include <string.h>
30 
31 #include "lwip/err.h"
32 
33 #include "netif/ppp/ppp_impl.h"
34 #include "netif/ppp/ccp.h"
35 #include "netif/ppp/mppe.h"
36 #include "netif/ppp/pppdebug.h"
37 
38 #if LWIP_INCLUDED_POLARSSL_SHA1
40 #else
41 #include "polarssl/sha1.h"
42 #endif
43 
44 #if LWIP_INCLUDED_POLARSSL_ARC4
46 #else
47 #include "polarssl/arc4.h"
48 #endif
49 
50 #define SHA1_SIGNATURE_SIZE 20
51 
52 /* ppp_mppe_state.bits definitions */
53 #define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
54 #define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
55 #define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
56 #define MPPE_BIT_D 0x10 /* This is an encrypted frame */
57 
58 #define MPPE_BIT_FLUSHED MPPE_BIT_A
59 #define MPPE_BIT_ENCRYPTED MPPE_BIT_D
60 
61 #define MPPE_BITS(p) ((p)[0] & 0xf0)
62 #define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1])
63 #define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
64 
65 #define MPPE_OVHD 2 /* MPPE overhead/packet */
66 #define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
67 
68 /*
69  * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
70  * Well, not what's written there, but rather what they meant.
71  */
72 static void mppe_rekey(ppp_mppe_state * state, int initial_key)
73 {
74  sha1_context sha1_ctx;
75  u8_t sha1_digest[SHA1_SIGNATURE_SIZE];
76 
77  /*
78  * Key Derivation, from RFC 3078, RFC 3079.
79  * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
80  */
81  sha1_starts(&sha1_ctx);
82  sha1_update(&sha1_ctx, state->master_key, state->keylen);
83  sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE);
84  sha1_update(&sha1_ctx, state->session_key, state->keylen);
85  sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE);
86  sha1_finish(&sha1_ctx, sha1_digest);
87  MEMCPY(state->session_key, sha1_digest, state->keylen);
88 
89  if (!initial_key) {
90  arc4_setup(&state->arc4, sha1_digest, state->keylen);
91  arc4_crypt(&state->arc4, state->session_key, state->keylen);
92  }
93  if (state->keylen == 8) {
94  /* See RFC 3078 */
95  state->session_key[0] = 0xd1;
96  state->session_key[1] = 0x26;
97  state->session_key[2] = 0x9e;
98  }
99  arc4_setup(&state->arc4, state->session_key, state->keylen);
100 }
101 
102 /*
103  * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we
104  * don't have to keep multiple copies of keys.
105  */
106 void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) {
107  LWIP_UNUSED_ARG(pcb);
108  MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN);
109 }
110 
111 /*
112  * Initialize (de)compressor state.
113  */
114 void
115 mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options)
116 {
117 #if PPP_DEBUG
118  const u8_t *debugstr = (const u8_t*)"mppe_comp_init";
119  if (&pcb->mppe_decomp == state) {
120  debugstr = (const u8_t*)"mppe_decomp_init";
121  }
122 #endif /* PPP_DEBUG */
123 
124  /* Save keys. */
125  MEMCPY(state->session_key, state->master_key, sizeof(state->master_key));
126 
127  if (options & MPPE_OPT_128)
128  state->keylen = 16;
129  else if (options & MPPE_OPT_40)
130  state->keylen = 8;
131  else {
132  PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr,
133  pcb->netif->num));
134  lcp_close(pcb, "MPPE required but peer negotiation failed");
135  return;
136  }
137  if (options & MPPE_OPT_STATEFUL)
138  state->stateful = 1;
139 
140  /* Generate the initial session key. */
141  mppe_rekey(state, 1);
142 
143 #if PPP_DEBUG
144  {
145  int i;
146  char mkey[sizeof(state->master_key) * 2 + 1];
147  char skey[sizeof(state->session_key) * 2 + 1];
148 
149  PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n",
150  debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40,
151  (state->stateful) ? "stateful" : "stateless"));
152 
153  for (i = 0; i < (int)sizeof(state->master_key); i++)
154  sprintf(mkey + i * 2, "%02x", state->master_key[i]);
155  for (i = 0; i < (int)sizeof(state->session_key); i++)
156  sprintf(skey + i * 2, "%02x", state->session_key[i]);
157  PPPDEBUG(LOG_DEBUG,
158  ("%s[%d]: keys: master: %s initial session: %s\n",
159  debugstr, pcb->netif->num, mkey, skey));
160  }
161 #endif /* PPP_DEBUG */
162 
163  /*
164  * Initialize the coherency count. The initial value is not specified
165  * in RFC 3078, but we can make a reasonable assumption that it will
166  * start at 0. Setting it to the max here makes the comp/decomp code
167  * do the right thing (determined through experiment).
168  */
169  state->ccount = MPPE_CCOUNT_SPACE - 1;
170 
171  /*
172  * Note that even though we have initialized the key table, we don't
173  * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
174  */
175  state->bits = MPPE_BIT_ENCRYPTED;
176 }
177 
178 /*
179  * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
180  * tell the compressor to rekey. Note that we MUST NOT rekey for
181  * every CCP Reset-Request; we only rekey on the next xmit packet.
182  * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
183  * So, rekeying for every CCP Reset-Request is broken as the peer will not
184  * know how many times we've rekeyed. (If we rekey and THEN get another
185  * CCP Reset-Request, we must rekey again.)
186  */
187 void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
188 {
189  LWIP_UNUSED_ARG(pcb);
190  state->bits |= MPPE_BIT_FLUSHED;
191 }
192 
193 /*
194  * Compress (encrypt) a packet.
195  * It's strange to call this a compressor, since the output is always
196  * MPPE_OVHD + 2 bytes larger than the input.
197  */
198 err_t
199 mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol)
200 {
201  struct pbuf *n, *np;
202  u8_t *pl;
203  err_t err;
204 
205  LWIP_UNUSED_ARG(pcb);
206 
207  /* TCP stack requires that we don't change the packet payload, therefore we copy
208  * the whole packet before encryption.
209  */
210  np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_POOL);
211  if (!np) {
212  return ERR_MEM;
213  }
214 
215  /* Hide MPPE header + protocol */
216  pbuf_header(np, -(s16_t)(MPPE_OVHD + sizeof(protocol)));
217 
218  if ((err = pbuf_copy(np, *pb)) != ERR_OK) {
219  pbuf_free(np);
220  return err;
221  }
222 
223  /* Reveal MPPE header + protocol */
224  pbuf_header(np, (s16_t)(MPPE_OVHD + sizeof(protocol)));
225 
226  *pb = np;
227  pl = (u8_t*)np->payload;
228 
229  state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
230  PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount));
231  /* FIXME: use PUT* macros */
232  pl[0] = state->ccount>>8;
233  pl[1] = state->ccount;
234 
235  if (!state->stateful || /* stateless mode */
236  ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
237  (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
238  /* We must rekey */
239  if (state->stateful) {
240  PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num));
241  }
242  mppe_rekey(state, 0);
243  state->bits |= MPPE_BIT_FLUSHED;
244  }
245  pl[0] |= state->bits;
246  state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
247  pl += MPPE_OVHD;
248 
249  /* Add protocol */
250  /* FIXME: add PFC support */
251  pl[0] = protocol >> 8;
252  pl[1] = protocol;
253 
254  /* Hide MPPE header */
255  pbuf_header(np, -(s16_t)MPPE_OVHD);
256 
257  /* Encrypt packet */
258  for (n = np; n != NULL; n = n->next) {
259  arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
260  if (n->tot_len == n->len) {
261  break;
262  }
263  }
264 
265  /* Reveal MPPE header */
266  pbuf_header(np, (s16_t)MPPE_OVHD);
267 
268  return ERR_OK;
269 }
270 
271 /*
272  * We received a CCP Reset-Ack. Just ignore it.
273  */
274 void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state)
275 {
276  LWIP_UNUSED_ARG(pcb);
277  LWIP_UNUSED_ARG(state);
278  return;
279 }
280 
281 /*
282  * Decompress (decrypt) an MPPE packet.
283  */
284 err_t
285 mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb)
286 {
287  struct pbuf *n0 = *pb, *n;
288  u8_t *pl;
289  u16_t ccount;
290  u8_t flushed;
291 
292  /* MPPE Header */
293  if (n0->len < MPPE_OVHD) {
294  PPPDEBUG(LOG_DEBUG,
295  ("mppe_decompress[%d]: short pkt (%d)\n",
296  pcb->netif->num, n0->len));
297  state->sanity_errors += 100;
298  goto sanity_error;
299  }
300 
301  pl = (u8_t*)n0->payload;
302  flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED;
303  ccount = MPPE_CCOUNT(pl);
304  PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n",
305  pcb->netif->num, ccount));
306 
307  /* sanity checks -- terminate with extreme prejudice */
308  if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) {
309  PPPDEBUG(LOG_DEBUG,
310  ("mppe_decompress[%d]: ENCRYPTED bit not set!\n",
311  pcb->netif->num));
312  state->sanity_errors += 100;
313  goto sanity_error;
314  }
315  if (!state->stateful && !flushed) {
316  PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in "
317  "stateless mode!\n", pcb->netif->num));
318  state->sanity_errors += 100;
319  goto sanity_error;
320  }
321  if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
322  PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on "
323  "flag packet!\n", pcb->netif->num));
324  state->sanity_errors += 100;
325  goto sanity_error;
326  }
327 
328  /*
329  * Check the coherency count.
330  */
331 
332  if (!state->stateful) {
333  /* Discard late packet */
334  if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) {
335  state->sanity_errors++;
336  goto sanity_error;
337  }
338 
339  /* RFC 3078, sec 8.1. Rekey for every packet. */
340  while (state->ccount != ccount) {
341  mppe_rekey(state, 0);
342  state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
343  }
344  } else {
345  /* RFC 3078, sec 8.2. */
346  if (!state->discard) {
347  /* normal state */
348  state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
349  if (ccount != state->ccount) {
350  /*
351  * (ccount > state->ccount)
352  * Packet loss detected, enter the discard state.
353  * Signal the peer to rekey (by sending a CCP Reset-Request).
354  */
355  state->discard = 1;
356  ccp_resetrequest(pcb);
357  return ERR_BUF;
358  }
359  } else {
360  /* discard state */
361  if (!flushed) {
362  /* ccp.c will be silent (no additional CCP Reset-Requests). */
363  return ERR_BUF;
364  } else {
365  /* Rekey for every missed "flag" packet. */
366  while ((ccount & ~0xff) !=
367  (state->ccount & ~0xff)) {
368  mppe_rekey(state, 0);
369  state->ccount =
370  (state->ccount +
371  256) % MPPE_CCOUNT_SPACE;
372  }
373 
374  /* reset */
375  state->discard = 0;
376  state->ccount = ccount;
377  /*
378  * Another problem with RFC 3078 here. It implies that the
379  * peer need not send a Reset-Ack packet. But RFC 1962
380  * requires it. Hopefully, M$ does send a Reset-Ack; even
381  * though it isn't required for MPPE synchronization, it is
382  * required to reset CCP state.
383  */
384  }
385  }
386  if (flushed)
387  mppe_rekey(state, 0);
388  }
389 
390  /* Hide MPPE header */
391  pbuf_header(n0, -(s16_t)(MPPE_OVHD));
392 
393  /* Decrypt the packet. */
394  for (n = n0; n != NULL; n = n->next) {
395  arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len);
396  if (n->tot_len == n->len) {
397  break;
398  }
399  }
400 
401  /* good packet credit */
402  state->sanity_errors >>= 1;
403 
404  return ERR_OK;
405 
406 sanity_error:
407  if (state->sanity_errors >= SANITY_MAX) {
408  /*
409  * Take LCP down if the peer is sending too many bogons.
410  * We don't want to do this for a single or just a few
411  * instances since it could just be due to packet corruption.
412  */
413  lcp_close(pcb, "Too many MPPE errors");
414  }
415  return ERR_BUF;
416 }
417 
418 #endif /* PPP_SUPPORT && MPPE_SUPPORT */
419 
signed short s16_t
Definition: cc.h:41
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:603
#define MEMCPY(dst, src, len)
Definition: opt.h:84
u16_t len
Definition: pbuf.h:125
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:199
#define NULL
Definition: usbd_def.h:53
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:652
Definition: pbuf.h:68
err_t pbuf_copy(struct pbuf *p_to, struct pbuf *p_from)
Definition: pbuf.c:886
#define ERR_OK
Definition: err.h:52
u16_t tot_len
Definition: pbuf.h:122
Definition: pbuf.h:108
s8_t err_t
Definition: err.h:47
Definition: pbuf.h:90
struct pbuf * next
Definition: pbuf.h:110
unsigned char u8_t
Definition: cc.h:38
#define ERR_MEM
Definition: err.h:53
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:89
unsigned short u16_t
Definition: cc.h:40
void * payload
Definition: pbuf.h:113
#define ERR_BUF
Definition: err.h:54