chap.c
Go to the documentation of this file.
1 /**
2  * @file chap.c
3  * @brief CHAP (Challenge Handshake Authentication Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL PPP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "ppp/ppp_debug.h"
37 #include "ppp/lcp.h"
38 #include "ppp/ipcp.h"
39 #include "ppp/ipv6cp.h"
40 #include "ppp/chap.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (PPP_SUPPORT == ENABLED && CHAP_SUPPORT == ENABLED)
45 
46 //Additional dependencies
47 #include "core/crypto.h"
48 #include "hash/md5.h"
49 
50 
51 /**
52  * @brief Start CHAP authentication
53  * @param[in] context PPP context
54  * @return Error code
55  **/
56 
58 {
59  //Debug message
60  TRACE_INFO("\r\nStarting CHAP authentication...\r\n");
61 
62  //Check whether the other end of the PPP link is being authenticated
63  if(context->localConfig.authProtocol == PPP_PROTOCOL_CHAP)
64  {
65  //Initialize restart counter
66  context->chapFsm.restartCounter = CHAP_MAX_CHALLENGES;
67  //Send a Challenge packet
68  chapSendChallenge(context);
69  //Switch to the Challenge-Sent state
70  context->chapFsm.localState = CHAP_STATE_2_CHALLENGE_SENT;
71  }
72 
73  //Check whether the other end of the PPP link is the authenticator
74  if(context->peerConfig.authProtocol == PPP_PROTOCOL_CHAP)
75  {
76  //Switch to the Started state
77  context->chapFsm.peerState = CHAP_STATE_1_STARTED;
78  }
79 
80  //Successful processing
81  return NO_ERROR;
82 }
83 
84 
85 /**
86  * @brief Abort CHAP authentication
87  * @param[in] context PPP context
88  * @return Error code
89  **/
90 
92 {
93  //Debug message
94  TRACE_INFO("\r\nAborting CHAP authentication...\r\n");
95 
96  //Abort CHAP authentication process
97  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
98  context->chapFsm.peerState = CHAP_STATE_0_INITIAL;
99 
100  //Successful processing
101  return NO_ERROR;
102 }
103 
104 
105 /**
106  * @brief CHAP timer handler
107  * @param[in] context PPP context
108  **/
109 
110 void chapTick(PppContext *context)
111 {
112  //Check whether the restart timer is running
113  if(context->chapFsm.localState == CHAP_STATE_2_CHALLENGE_SENT)
114  {
115  //Get current time
117 
118  //Check restart timer
119  if((time - context->chapFsm.timestamp) >= CHAP_RESTART_TIMER)
120  {
121  //Debug message
122  TRACE_INFO("\r\nCHAP Timeout event\r\n");
123 
124  //Check whether the restart counter is greater than zero
125  if(context->chapFsm.restartCounter > 0)
126  {
127  //Retransmit the Challenge packet
128  chapSendChallenge(context);
129  }
130  else
131  {
132  //Abort CHAP authentication
133  context->chapFsm.localState = CHAP_STATE_0_INITIAL;
134  //Authentication failed
135  lcpClose(context);
136  }
137  }
138  }
139 }
140 
141 
142 /**
143  * @brief Process an incoming CHAP packet
144  * @param[in] context PPP context
145  * @param[in] packet CHAP packet received from the peer
146  * @param[in] length Length of the packet, in bytes
147  **/
148 
150  const PppPacket *packet, size_t length)
151 {
152  //Ensure the length of the incoming CHAP packet is valid
153  if(length < sizeof(PppPacket))
154  return;
155 
156  //Check the length field
157  if(ntohs(packet->length) > length)
158  return;
159  if(ntohs(packet->length) < sizeof(PppPacket))
160  return;
161 
162  //Save the length of the CHAP packet
163  length = ntohs(packet->length);
164 
165  //Debug message
166  TRACE_INFO("CHAP packet received (%" PRIuSIZE " bytes)...\r\n", length);
167  //Dump CHAP packet contents for debugging purpose
169 
170  //CHAP is done at initial link establishment, and could also be
171  //requested after link establishment
172  if(context->pppPhase != PPP_PHASE_AUTHENTICATE &&
173  context->pppPhase != PPP_PHASE_NETWORK)
174  {
175  //Any packets received during any other phase must be silently discarded
176  return;
177  }
178 
179  //Check CHAP code field
180  switch(packet->code)
181  {
182  //Challenge packet?
183  case CHAP_CODE_CHALLENGE:
184  //Process Challenge packet
185  chapProcessChallenge(context, (ChapChallengePacket *) packet, length);
186  break;
187  //Response packet?
188  case CHAP_CODE_RESPONSE:
189  //Process Response packet
190  chapProcessResponse(context, (ChapResponsePacket *) packet, length);
191  break;
192  //Success packet?
193  case CHAP_CODE_SUCCESS:
194  //Process Success packet
195  chapProcessSuccess(context, (ChapSuccessPacket *) packet, length);
196  break;
197  //Failure packet?
198  case CHAP_CODE_FAILURE:
199  //Process Failure packet
200  chapProcessFailure(context, (ChapFailurePacket *) packet, length);
201  break;
202  //Unknown code field
203  default:
204  //Silently drop the incoming packet
205  break;
206  }
207 }
208 
209 
210 /**
211  * @brief Process Challenge packet
212  * @param[in] context PPP context
213  * @param[in] challengePacket Packet received from the peer
214  * @param[in] length Length of the packet, in bytes
215  * @return Error code
216  **/
217 
219  const ChapChallengePacket *challengePacket, size_t length)
220 {
221  size_t n;
222  Md5Context md5Context;
223  uint8_t digest[MD5_DIGEST_SIZE];
224 
225  //Debug message
226  TRACE_INFO("\r\nCHAP Challenge packet received\r\n");
227 
228  //Make sure the Challenge packet is acceptable
229  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
230  return ERROR_FAILURE;
231 
232  //Check the length of the packet
233  if(length < sizeof(ChapChallengePacket))
234  return ERROR_INVALID_LENGTH;
235 
236  //Malformed Challenge packet?
237  if(length < (sizeof(ChapChallengePacket) + challengePacket->valueSize))
238  return ERROR_INVALID_LENGTH;
239 
240  //Save the Identifier field
241  context->chapFsm.peerIdentifier = challengePacket->identifier;
242 
243  //Retrieve the length of the password
244  n = osStrlen(context->password);
245 
246  //The response value is the one-way hash calculated over a stream
247  //of octets consisting of the identifier, followed by the secret,
248  //followed by the challenge value
249  md5Init(&md5Context);
250  md5Update(&md5Context, &challengePacket->identifier, sizeof(uint8_t));
251  md5Update(&md5Context, context->password, n);
252  md5Update(&md5Context, challengePacket->value, challengePacket->valueSize);
253  md5Final(&md5Context, digest);
254 
255  //Whenever a Challenge packet is received, the peer must send a Response packet
256  chapSendResponse(context, digest);
257 
258  //Switch to the Response-Sent state
259  context->chapFsm.peerState = CHAP_STATE_4_RESPONSE_SENT;
260 
261  //Successful processing
262  return NO_ERROR;
263 }
264 
265 
266 /**
267  * @brief Process Response packet
268  * @param[in] context PPP context
269  * @param[in] responsePacket Packet received from the peer
270  * @param[in] length Length of the packet, in bytes
271  * @return Error code
272  **/
273 
275  const ChapResponsePacket *responsePacket, size_t length)
276 {
277  bool_t status;
278  const uint8_t *p;
279 
280  //Debug message
281  TRACE_INFO("\r\nCHAP Response packet received\r\n");
282 
283  //Make sure the Response packet is acceptable
284  if(context->localConfig.authProtocol != PPP_PROTOCOL_CHAP)
285  return ERROR_FAILURE;
286 
287  //Check the length of the packet
288  if(length < sizeof(ChapResponsePacket))
289  return ERROR_INVALID_LENGTH;
290 
291  //When a packet is received with an invalid Identifier field, the
292  //packet is silently discarded without affecting the automaton
293  if(responsePacket->identifier != context->chapFsm.localIdentifier)
294  return ERROR_WRONG_IDENTIFIER;
295 
296  //Malformed Response packet?
297  if(length < (sizeof(ChapResponsePacket) + responsePacket->valueSize))
298  return ERROR_INVALID_LENGTH;
299 
300  //The length of the response value depends upon the hash algorithm used
301  if(responsePacket->valueSize != MD5_DIGEST_SIZE)
302  return ERROR_INVALID_LENGTH;
303 
304  //Retrieve the response value
305  context->chapFsm.response = responsePacket->value;
306 
307  //Point to the Name field
308  p = responsePacket->value + responsePacket->valueSize;
309  //Retrieve the length of the Name field
310  length -= sizeof(ChapResponsePacket) + responsePacket->valueSize;
311 
312  //Limit the length of the string
314  //Copy the name of the peer to be identified
315  osMemcpy(context->peerName, p, length);
316  //Properly terminate the string with a NULL character
317  context->peerName[length] = '\0';
318 
319  //Invoke user-defined callback, if any
320  if(context->settings.authCallback != NULL)
321  {
322  //Perfom username and password verification
323  status = context->settings.authCallback(context->interface,
324  context->peerName);
325  }
326  else
327  {
328  //Unable to perform authentication...
329  status = FALSE;
330  }
331 
332  //Whenever a Response packet is received, the authenticator compares the
333  //Response Value with its own calculation of the expected value. Based on
334  //this comparison, the authenticator must send a Success or Failure packet
335  if(status)
336  {
337  //Send a Success packet
338  chapSendSuccess(context);
339 
340  //Switch to the Success-Sent state
341  context->chapFsm.localState = CHAP_STATE_6_SUCCESS_SENT;
342  //The user has been successfully authenticated
343  context->localAuthDone = TRUE;
344 
345  //Check whether PPP authentication is complete
346  if(context->localAuthDone && context->peerAuthDone)
347  {
348  //Check current PPP phase
349  if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
350  {
351  //Advance to the Network phase
352  context->pppPhase = PPP_PHASE_NETWORK;
353 
354 #if (IPV4_SUPPORT == ENABLED)
355  //IPCP Open event
356  ipcpOpen(context);
357 #endif
358 #if (IPV6_SUPPORT == ENABLED)
359  //IPV6CP Open event
360  ipv6cpOpen(context);
361 #endif
362  }
363  }
364  }
365  else
366  {
367  //Send a Failure packet
368  chapSendFailure(context);
369 
370  //Switch to the Failure-Sent state
371  context->chapFsm.localState = CHAP_STATE_8_FAILURE_SENT;
372  //The authenticator should take action to terminate the link
373  lcpClose(context);
374  }
375 
376  //Successful processing
377  return NO_ERROR;
378 }
379 
380 
381 /**
382  * @brief Process Success packet
383  * @param[in] context PPP context
384  * @param[in] successPacket Packet received from the peer
385  * @param[in] length Length of the packet, in bytes
386  * @return Error code
387  **/
388 
390  const ChapSuccessPacket *successPacket, size_t length)
391 {
392  //Debug message
393  TRACE_INFO("\r\nCHAP Success packet received\r\n");
394 
395  //Make sure the Success packet is acceptable
396  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
397  return ERROR_FAILURE;
398 
399  //Check the length of the packet
400  if(length < sizeof(ChapSuccessPacket))
401  return ERROR_INVALID_LENGTH;
402 
403  //When a packet is received with an invalid Identifier field, the
404  //packet is silently discarded without affecting the automaton
405  if(successPacket->identifier != context->chapFsm.peerIdentifier)
406  return ERROR_WRONG_IDENTIFIER;
407 
408  //Switch to the Success-Rcvd state
409  context->chapFsm.peerState = CHAP_STATE_7_SUCCESS_RCVD;
410  //The user name has been accepted by the authenticator
411  context->peerAuthDone = TRUE;
412 
413  //Check whether PPP authentication is complete
414  if(context->localAuthDone && context->peerAuthDone)
415  {
416  //Check current PPP phase
417  if(context->pppPhase == PPP_PHASE_AUTHENTICATE)
418  {
419  //Advance to the Network phase
420  context->pppPhase = PPP_PHASE_NETWORK;
421 
422 #if (IPV4_SUPPORT == ENABLED)
423  //IPCP Open event
424  ipcpOpen(context);
425 #endif
426 #if (IPV6_SUPPORT == ENABLED)
427  //IPV6CP Open event
428  ipv6cpOpen(context);
429 #endif
430  }
431  }
432 
433  //Successful processing
434  return NO_ERROR;
435 }
436 
437 
438 /**
439  * @brief Process Failure packet
440  * @param[in] context PPP context
441  * @param[in] failurePacket Packet received from the peer
442  * @param[in] length Length of the packet, in bytes
443  * @return Error code
444  **/
445 
447  const ChapFailurePacket *failurePacket, size_t length)
448 {
449  //Debug message
450  TRACE_INFO("\r\nCHAP Failure packet received\r\n");
451 
452  //Make sure the Failure packet is acceptable
453  if(context->peerConfig.authProtocol != PPP_PROTOCOL_CHAP)
454  return ERROR_FAILURE;
455 
456  //Check the length of the packet
457  if(length < sizeof(ChapFailurePacket))
458  return ERROR_INVALID_LENGTH;
459 
460  //When a packet is received with an invalid Identifier field, the
461  //packet is silently discarded without affecting the automaton
462  if(failurePacket->identifier != context->chapFsm.peerIdentifier)
463  return ERROR_WRONG_IDENTIFIER;
464 
465  //Switch to the Failure-Rcvd state
466  context->chapFsm.peerState = CHAP_STATE_9_FAILURE_RCVD;
467  //Authentication failed
468  lcpClose(context);
469 
470  //Successful processing
471  return NO_ERROR;
472 }
473 
474 
475 /**
476  * @brief Send Challenge packet
477  * @param[in] context PPP context
478  * @return Error code
479  **/
480 
482 {
483  error_t error;
484  size_t n;
485  size_t length;
486  size_t offset;
487  NetBuffer *buffer;
488  ChapChallengePacket *challengePacket;
489 
490  //Retrieve the length of the username
491  n = osStrlen(context->username);
492  //Calculate the length of the Challenge packet
494 
495  //Allocate a buffer memory to hold the Challenge packet
496  buffer = pppAllocBuffer(length, &offset);
497  //Failed to allocate memory?
498  if(buffer == NULL)
499  return ERROR_OUT_OF_MEMORY;
500 
501  //Point to the Challenge packet
502  challengePacket = netBufferAt(buffer, offset, 0);
503 
504  //Format packet header
505  challengePacket->code = CHAP_CODE_CHALLENGE;
506  challengePacket->identifier = ++context->chapFsm.localIdentifier;
507  challengePacket->length = htons(length);
508  challengePacket->valueSize = MD5_DIGEST_SIZE;
509 
510  //Make sure that the callback function has been registered
511  if(context->settings.randCallback != NULL)
512  {
513  //Generate a random challenge value
514  error = context->settings.randCallback(
515  context->chapFsm.challenge, MD5_DIGEST_SIZE);
516  }
517  else
518  {
519  //Report an error
520  error = ERROR_FAILURE;
521  }
522 
523  //Check status code
524  if(!error)
525  {
526  //Copy the challenge value
527  osMemcpy(challengePacket->value, context->chapFsm.challenge, MD5_DIGEST_SIZE);
528 
529  //The Name field is one or more octets representing the
530  //identification of the system transmitting the packet
531  osMemcpy(challengePacket->value + MD5_DIGEST_SIZE, context->username, n);
532 
533  //Debug message
534  TRACE_INFO("Sending CHAP Challenge packet (%" PRIuSIZE " bytes)...\r\n", length);
535  //Dump packet contents for debugging purpose
536  pppDumpPacket((PppPacket *) challengePacket, length, PPP_PROTOCOL_CHAP);
537 
538  //Send PPP frame
539  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
540 
541  //The restart counter is decremented each time a Challenge packet is sent
542  if(context->chapFsm.restartCounter > 0)
543  context->chapFsm.restartCounter--;
544 
545  //Save the time at which the packet was sent
546  context->chapFsm.timestamp = osGetSystemTime();
547  }
548 
549  //Free previously allocated memory block
550  netBufferFree(buffer);
551 
552  //Return status code
553  return error;
554 }
555 
556 
557 /**
558  * @brief Send Response packet
559  * @param[in] context PPP context
560  * @param[in] value Response value
561  * @return Error code
562  **/
563 
564 error_t chapSendResponse(PppContext *context, const uint8_t *value)
565 {
566  error_t error;
567  size_t n;
568  size_t length;
569  size_t offset;
570  NetBuffer *buffer;
571  ChapResponsePacket *responsePacket;
572 
573  //Retrieve the length of the username
574  n = osStrlen(context->username);
575  //Calculate the length of the Response packet
577 
578  //Allocate a buffer memory to hold the Response packet
579  buffer = pppAllocBuffer(length, &offset);
580  //Failed to allocate memory?
581  if(buffer == NULL)
582  return ERROR_OUT_OF_MEMORY;
583 
584  //Point to the Response packet
585  responsePacket = netBufferAt(buffer, offset, 0);
586 
587  //Format packet header
588  responsePacket->code = CHAP_CODE_RESPONSE;
589  responsePacket->identifier = context->chapFsm.peerIdentifier;
590  responsePacket->length = htons(length);
591  responsePacket->valueSize = MD5_DIGEST_SIZE;
592 
593  //Copy the Response value
594  osMemcpy(responsePacket->value, value, MD5_DIGEST_SIZE);
595 
596  //The Name field is one or more octets representing the
597  //identification of the system transmitting the packet
598  osMemcpy(responsePacket->value + MD5_DIGEST_SIZE, context->username, n);
599 
600  //Debug message
601  TRACE_INFO("Sending CHAP Response packet (%" PRIuSIZE " bytes)...\r\n", length);
602  //Dump packet contents for debugging purpose
603  pppDumpPacket((PppPacket *) responsePacket, length, PPP_PROTOCOL_CHAP);
604 
605  //Send PPP frame
606  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
607 
608  //Free previously allocated memory block
609  netBufferFree(buffer);
610 
611  //Return status code
612  return error;
613 }
614 
615 
616 /**
617  * @brief Send Success packet
618  * @param[in] context PPP context
619  * @return Error code
620  **/
621 
623 {
624  error_t error;
625  size_t length;
626  size_t offset;
627  NetBuffer *buffer;
628  PppPacket *successPacket;
629 
630  //Retrieve the length of the Success packet
631  length = sizeof(PppPacket);
632 
633  //Allocate a buffer memory to hold the Success packet
634  buffer = pppAllocBuffer(length, &offset);
635  //Failed to allocate memory?
636  if(buffer == NULL)
637  return ERROR_OUT_OF_MEMORY;
638 
639  //Point to the Success packet
640  successPacket = netBufferAt(buffer, offset, 0);
641 
642  //Format packet header
643  successPacket->code = CHAP_CODE_SUCCESS;
644  successPacket->identifier = context->chapFsm.localIdentifier;
645  successPacket->length = htons(length);
646 
647  //Debug message
648  TRACE_INFO("Sending CHAP Success packet (%" PRIuSIZE " bytes)...\r\n", length);
649  //Dump packet contents for debugging purpose
650  pppDumpPacket((PppPacket *) successPacket, length, PPP_PROTOCOL_CHAP);
651 
652  //Send PPP frame
653  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
654 
655  //Free previously allocated memory block
656  netBufferFree(buffer);
657 
658  //Return status code
659  return error;
660 }
661 
662 
663 /**
664  * @brief Send Failure packet
665  * @param[in] context PPP context
666  * @return Error code
667  **/
668 
670 {
671  error_t error;
672  size_t length;
673  size_t offset;
674  NetBuffer *buffer;
675  PppPacket *failurePacket;
676 
677  //Retrieve the length of the Failure packet
678  length = sizeof(PppPacket);
679 
680  //Allocate a buffer memory to hold the Failure packet
681  buffer = pppAllocBuffer(length, &offset);
682  //Failed to allocate memory?
683  if(buffer == NULL)
684  return ERROR_OUT_OF_MEMORY;
685 
686  //Point to the Failure packet
687  failurePacket = netBufferAt(buffer, offset, 0);
688 
689  //Format packet header
690  failurePacket->code = CHAP_CODE_FAILURE;
691  failurePacket->identifier = context->chapFsm.localIdentifier;
692  failurePacket->length = htons(length);
693 
694  //Debug message
695  TRACE_INFO("Sending CHAP Failure packet (%" PRIuSIZE " bytes)...\r\n", length);
696  //Dump packet contents for debugging purpose
697  pppDumpPacket((PppPacket *) failurePacket, length, PPP_PROTOCOL_CHAP);
698 
699  //Send PPP frame
700  error = pppSendFrame(context->interface, buffer, offset, PPP_PROTOCOL_CHAP);
701 
702  //Free previously allocated memory block
703  netBufferFree(buffer);
704 
705  //Return status code
706  return error;
707 }
708 
709 
710 /**
711  * @brief Password verification
712  * @param[in] context PPP context
713  * @param[in] password NULL-terminated string containing the password to be checked
714  * @return TRUE if the password is valid, else FALSE
715  **/
716 
717 bool_t chapCheckPassword(PppContext *context, const char_t *password)
718 {
719  size_t n;
720  Md5Context md5Context;
721  uint8_t digest[MD5_DIGEST_SIZE];
722 
723  //Retrieve the length of the password
724  n = osStrlen(password);
725 
726  //The response value is the one-way hash calculated over a stream
727  //of octets consisting of the identifier, followed by the secret,
728  //followed by the challenge value
729  md5Init(&md5Context);
730  md5Update(&md5Context, &context->chapFsm.localIdentifier, sizeof(uint8_t));
731  md5Update(&md5Context, password, n);
732  md5Update(&md5Context, context->chapFsm.challenge, MD5_DIGEST_SIZE);
733  md5Final(&md5Context, digest);
734 
735  //Check the resulting digest value
736  if(osMemcmp(digest, context->chapFsm.response, MD5_DIGEST_SIZE) == 0)
737  {
738  return TRUE;
739  }
740  else
741  {
742  return FALSE;
743  }
744 }
745 
746 #endif
@ CHAP_STATE_0_INITIAL
Definition: chap.h:71
#define htons(value)
Definition: cpu_endian.h:413
error_t chapProcessSuccess(PppContext *context, const ChapSuccessPacket *successPacket, size_t length)
Process Success packet.
Definition: chap.c:389
Data logging functions for debugging purpose (PPP)
int bool_t
Definition: compiler_port.h:61
#define PppPacket
Definition: ppp.h:37
error_t chapSendResponse(PppContext *context, const uint8_t *value)
Send Response packet.
Definition: chap.c:564
CHAP (Challenge Handshake Authentication Protocol)
@ CHAP_CODE_SUCCESS
Success.
Definition: chap.h:92
#define CHAP_MAX_CHALLENGES
Definition: chap.h:54
void chapProcessPacket(PppContext *context, const PppPacket *packet, size_t length)
Process an incoming CHAP packet.
Definition: chap.c:149
@ PPP_PROTOCOL_CHAP
Challenge Handshake Authentication Protocol.
Definition: ppp.h:206
uint8_t p
Definition: ndp.h:300
@ CHAP_STATE_6_SUCCESS_SENT
Definition: chap.h:77
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define TRUE
Definition: os_port.h:50
IPV6CP (PPP IPv6 Control Protocol)
@ CHAP_STATE_1_STARTED
Definition: chap.h:72
void chapTick(PppContext *context)
CHAP timer handler.
Definition: chap.c:110
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
#define CHAP_RESTART_TIMER
Definition: chap.h:47
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ CHAP_CODE_CHALLENGE
Challenge.
Definition: chap.h:90
@ PPP_PHASE_NETWORK
Network-layer protocol phase.
Definition: ppp.h:169
@ CHAP_STATE_2_CHALLENGE_SENT
Definition: chap.h:73
@ CHAP_CODE_RESPONSE
Response.
Definition: chap.h:91
NetBuffer * pppAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold a PPP frame.
Definition: ppp.c:1305
#define osStrlen(s)
Definition: os_port.h:168
ChapChallengePacket
Definition: chap.h:128
#define PppContext
Definition: ppp.h:38
IPCP (PPP Internet Protocol Control Protocol)
LCP (PPP Link Control Protocol)
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
#define FALSE
Definition: os_port.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
ChapResponsePacket
Definition: chap.h:142
error_t
Error codes.
Definition: error.h:43
@ CHAP_CODE_FAILURE
Failure.
Definition: chap.h:93
error_t chapAbortAuth(PppContext *context)
Abort CHAP authentication.
Definition: chap.c:91
@ PPP_PHASE_AUTHENTICATE
Authentication phase.
Definition: ppp.h:168
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ CHAP_STATE_4_RESPONSE_SENT
Definition: chap.h:75
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
@ CHAP_STATE_7_SUCCESS_RCVD
Definition: chap.h:78
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
ChapSuccessPacket
Definition: chap.h:155
error_t chapSendSuccess(PppContext *context)
Send Success packet.
Definition: chap.c:622
MD5 algorithm context.
Definition: md5.h:62
@ CHAP_STATE_9_FAILURE_RCVD
Definition: chap.h:80
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
error_t chapProcessFailure(PppContext *context, const ChapFailurePacket *failurePacket, size_t length)
Process Failure packet.
Definition: chap.c:446
#define MIN(a, b)
Definition: os_port.h:63
error_t ipcpOpen(PppContext *context)
IPCP Open event.
Definition: ipcp.c:76
#define MD5_DIGEST_SIZE
Definition: md5.h:45
uint32_t systime_t
System time.
#define ntohs(value)
Definition: cpu_endian.h:421
char char_t
Definition: compiler_port.h:55
uint32_t time
error_t pppSendFrame(NetInterface *interface, NetBuffer *buffer, size_t offset, uint16_t protocol)
Send a PPP frame.
Definition: ppp.c:1035
uint8_t n
error_t pppDumpPacket(const PppPacket *packet, size_t length, PppProtocol protocol)
Dump LCP/NCP packet for debugging purpose.
Definition: ppp_debug.c:143
MD5 (Message-Digest Algorithm)
bool_t chapCheckPassword(PppContext *context, const char_t *password)
Password verification.
Definition: chap.c:717
error_t chapSendChallenge(PppContext *context)
Send Challenge packet.
Definition: chap.c:481
error_t chapProcessChallenge(PppContext *context, const ChapChallengePacket *challengePacket, size_t length)
Process Challenge packet.
Definition: chap.c:218
error_t chapProcessResponse(PppContext *context, const ChapResponsePacket *responsePacket, size_t length)
Process Response packet.
Definition: chap.c:274
uint8_t value[]
Definition: tcp.h:376
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
error_t ipv6cpOpen(PppContext *context)
IPV6CP Open event.
Definition: ipv6cp.c:77
error_t chapStartAuth(PppContext *context)
Start CHAP authentication.
Definition: chap.c:57
void * netBufferAt(const NetBuffer *buffer, size_t offset, size_t length)
Returns a pointer to a data segment.
Definition: net_mem.c:418
error_t chapSendFailure(PppContext *context)
Send Failure packet.
Definition: chap.c:669
error_t lcpClose(PppContext *context)
LCP Close event.
Definition: lcp.c:103
#define PRIuSIZE
TCP/IP stack core.
ChapFailurePacket
Definition: chap.h:168
@ CHAP_STATE_8_FAILURE_SENT
Definition: chap.h:79
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
systime_t osGetSystemTime(void)
Retrieve system time.
#define PPP_MAX_USERNAME_LEN
Definition: ppp.h:68