ike_message_parse.c
Go to the documentation of this file.
1 /**
2  * @file ike_message_parse.c
3  * @brief IKE message parsing
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC 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 IKE_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ipsec/ipsec_misc.h"
36 #include "ike/ike.h"
37 #include "ike/ike_fsm.h"
38 #include "ike/ike_algorithms.h"
39 #include "ike/ike_message_format.h"
40 #include "ike/ike_message_parse.h"
42 #include "ike/ike_payload_parse.h"
43 #include "ike/ike_auth.h"
44 #include "ike/ike_certificate.h"
45 #include "ike/ike_key_exchange.h"
46 #include "ike/ike_key_material.h"
47 #include "ike/ike_dh_groups.h"
48 #include "ike/ike_misc.h"
49 #include "ike/ike_debug.h"
50 #include "ah/ah_algorithms.h"
51 #include "esp/esp_algorithms.h"
52 #include "debug.h"
53 
54 //Check IKEv2 library configuration
55 #if (IKE_SUPPORT == ENABLED)
56 
57 
58 /**
59  * @brief Process incoming IKE message
60  * @param[in] context Pointer to the IKE context
61  * @param[in] message Pointer to the received IKE message
62  * @param[in] length Length of the IKE message, in bytes
63  * @return Error code
64  **/
65 
66 error_t ikeProcessMessage(IkeContext *context, uint8_t *message, size_t length)
67 {
68  error_t error;
69  IkeHeader *ikeHeader;
70 
71  //Malformed IKE message?
72  if(length < sizeof(IkeHeader))
73  return ERROR_INVALID_LENGTH;
74 
75  //Each message begins with the IKE header
76  ikeHeader = (IkeHeader *) message;
77 
78  //Debug message
79  TRACE_INFO("IKE message received (%" PRIuSIZE " bytes)...\r\n", length);
80  //Dump IKE message for debugging purpose
82 
83  //Check the length of the IKE message
84  if(length < ntohl(ikeHeader->length))
85  return ERROR_INVALID_LENGTH;
86 
87  //The Length field indicates the total length of the IKE message in octets
88  length = ntohl(ikeHeader->length);
89 
90  //The R bit indicates whether the message is a request or response
91  if((ikeHeader->flags & IKE_FLAGS_R) == 0)
92  {
93  //Process incoming IKE request
94  error = ikeProcessRequest(context, message, length);
95  }
96  else
97  {
98  //Process incoming IKE response
99  error = ikeProcessResponse(context, message, length);
100  }
101 
102  //Return status code
103  return error;
104 }
105 
106 
107 /**
108  * @brief Process incoming IKE request
109  * @param[in] context Pointer to the IKE context
110  * @param[in] message Pointer to the received IKE message
111  * @param[in] length Length of the IKE message, in bytes
112  * @return Error code
113  **/
114 
115 error_t ikeProcessRequest(IkeContext *context, uint8_t *message, size_t length)
116 {
117  error_t error;
118  uint8_t exchangeType;
119  IkeHeader *ikeHeader;
120  IkeSaEntry *sa;
121 
122  //Each message begins with the IKE header
123  ikeHeader = (IkeHeader *) message;
124  //The Exchange Type field indicates the type of exchange being used
125  exchangeType = ikeHeader->exchangeType;
126 
127  //Check the major version number
128  if(ikeHeader->majorVersion <= IKE_MAJOR_VERSION)
129  {
130  //Initial exchange?
132  {
133  //Process IKE_SA_INIT request
134  error = ikeProcessIkeSaInitRequest(context, message, length);
135  }
136  else
137  {
138  //Perform IKE SA lookup
139  sa = ikeFindSaEntry(context, ikeHeader);
140 
141  //Check whether the receiving node has an active IKE SA
142  if(sa != NULL)
143  {
144  //All messages following the initial exchange are cryptographically
145  //protected using the cryptographic algorithms and keys negotiated
146  //in the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
147  error = ikeDecryptMessage(sa, message, &length);
148 
149  //Check status code
150  if(!error)
151  {
152  //The responder must remember each response until it receives a
153  //request whose sequence number is larger than or equal to the
154  //sequence number in the response plus its window size
155  if(ntohl(ikeHeader->messageId) < sa->rxMessageId &&
156  sa->rxMessageId != UINT32_MAX)
157  {
158  //If the responder receives a retransmitted request for which
159  //it has already forgotten the response, it must ignore the
160  //request
161  }
162  else if(ntohl(ikeHeader->messageId) == sa->rxMessageId &&
163  sa->rxMessageId != UINT32_MAX)
164  {
165  //The responder has received a retransmission of the request
166  error = ikeRetransmitResponse(sa);
167  }
168  else if(ntohl(ikeHeader->messageId) == (sa->rxMessageId + 1))
169  {
170  //The counter increments as requests are received
171  sa->rxMessageId++;
172 
173  //In the unlikely event that Message IDs grow too large to fit
174  //in 32 bits, the IKE SA must be closed or rekeyed (refer to
175  //RFC 7296, section 2.2)
176  if(sa->rxMessageId == UINT32_MAX)
177  {
178  //Delete the IKE SA
179  ikeDeleteSaEntry(sa);
180  }
181  else
182  {
183  //Forget the previous response
184  sa->responseLen = 0;
185  //Clear error notification
186  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_NONE;
187 
188  //Check IKE exchange type
190  {
191  //Process IKE_AUTH request
193  }
195  {
196  //Process CREATE_CHILD_SA request
198  length);
199  }
201  {
202  //Process INFORMATIONAL request
203  error = ikeProcessInfoRequest(sa, message, length);
204  }
205  else
206  {
207  //Unknown exchange type
208  error = ERROR_UNKNOWN_TYPE;
209  }
210 
211  //Only authentication failures (AUTHENTICATION_FAILED) and
212  //malformed messages (INVALID_SYNTAX) lead to a deletion of
213  //the IKE SA without requiring an explicit INFORMATIONAL
214  //exchange carrying a Delete payload
215  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_AUTH_FAILED ||
216  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX)
217  {
218  //This error notification is considered fatal in both peers
219  ikeDeleteSaEntry(sa);
220  }
221  }
222  }
223  else
224  {
225  //Discard the request since the message ID is outside the
226  //supported window
227  }
228  }
229  }
230  else
231  {
232  //If a node receives a message on UDP port 500 or 4500 outside the
233  //context of an IKE SA known to it (and the message is not a request
234  //to start an IKE SA), this may be the result of a recent crash of
235  //the node. If the message is marked as a request, the node can audit
236  //the suspicious event and may send a response
237  error = ikeSendErrorResponse(context, message, length);
238  }
239  }
240  }
241  else
242  {
243  //If an IKE request packet arrives with a higher major version number
244  //than the implementation supports, the node notifies the sender about
245  //this situation (refer to RFC 7296, section 1.5)
246  error = ikeSendErrorResponse(context, message, length);
247  }
248 
249  //Return status code
250  return error;
251 }
252 
253 
254 /**
255  * @brief Process incoming IKE response
256  * @param[in] context Pointer to the IKE context
257  * @param[in] message Pointer to the received IKE message
258  * @param[in] length Length of the IKE message, in bytes
259  * @return Error code
260  **/
261 
263 {
264  error_t error;
265  uint8_t exchangeType;
266  IkeHeader *ikeHeader;
267  IkeSaEntry *sa;
268 
269  //Initialize status code
270  error = NO_ERROR;
271 
272  //Each message begins with the IKE header
273  ikeHeader = (IkeHeader *) message;
274  //The Exchange Type field indicates the type of exchange being used
275  exchangeType = ikeHeader->exchangeType;
276 
277  //Check the major version number
278  if(ikeHeader->majorVersion <= IKE_MAJOR_VERSION)
279  {
280  //Perform IKE SA lookup
281  sa = ikeFindSaEntry(context, ikeHeader);
282 
283  //Check whether the receiving node has an active IKE SA
284  if(sa != NULL)
285  {
286  //Check the state of the IKE SA
287  if(sa->state == IKE_SA_STATE_INIT_RESP ||
288  sa->state == IKE_SA_STATE_AUTH_RESP ||
289  sa->state == IKE_SA_STATE_DPD_RESP ||
290  sa->state == IKE_SA_STATE_REKEY_RESP ||
291  sa->state == IKE_SA_STATE_DELETE_RESP ||
292  sa->state == IKE_SA_STATE_CREATE_CHILD_RESP ||
293  sa->state == IKE_SA_STATE_REKEY_CHILD_RESP ||
294  sa->state == IKE_SA_STATE_DELETE_CHILD_RESP ||
295  sa->state == IKE_SA_STATE_AUTH_FAILURE_RESP)
296  {
297  //The Message ID field is used to match requests and responses
298  if(ntohl(ikeHeader->messageId) == sa->txMessageId)
299  {
300  //All messages following the initial exchange are cryptographically
301  //protected using the cryptographic algorithms and keys negotiated
302  //in the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
304  {
305  //Decrypt IKE message
306  error = ikeDecryptMessage(sa, message, &length);
307  }
308 
309  //Check status code
310  if(!error)
311  {
312  //Check IKE exchange type
314  {
315  //Process IKE_SA_INIT response
317  }
319  {
320  //Process IKE_AUTH response
322  }
324  {
325  //Process CREATE_CHILD_SA response
327  }
329  {
330  //Process INFORMATIONAL response
331  error = ikeProcessInfoResponse(sa, message, length);
332  }
333  else
334  {
335  //Unknown exchange type
336  error = ERROR_UNKNOWN_TYPE;
337  }
338 
339  //Only authentication failures (AUTHENTICATION_FAILED) and
340  //malformed messages (INVALID_SYNTAX) lead to a deletion of
341  //the IKE SA without requiring an explicit INFORMATIONAL
342  //exchange carrying a Delete payload
343  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_AUTH_FAILED ||
344  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX)
345  {
346  //This error notification is considered fatal in both peers
347  ikeDeleteSaEntry(sa);
348  }
349  }
350  }
351  else
352  {
353  //Unexpected Message ID
354  error = ERROR_WRONG_IDENTIFIER;
355  }
356  }
357  else
358  {
359  //Unexpected response
360  error = ERROR_UNEXPECTED_MESSAGE;
361  }
362  }
363  else
364  {
365  //If a node receives a message on UDP port 500 or 4500 outside the
366  //context of an IKE SA known to it, this may be the result of a
367  //recent crash of the node. If the message is marked as a response,
368  //the node can audit the suspicious event but must not respond
369  error = ERROR_INVALID_SPI;
370  }
371  }
372  else
373  {
374  //If an endpoint receives a message with a higher major version number,
375  //it must drop the message
376  error = ERROR_INVALID_VERSION;
377  }
378 
379  //Return status code
380  return error;
381 }
382 
383 
384 /**
385  * @brief Process incoming IKE_SA_INIT request
386  * @param[in] context Pointer to the IKE context
387  * @param[in] message Pointer to the received IKE message
388  * @param[in] length Length of the IKE message, in bytes
389  * @return Error code
390  **/
391 
393  size_t length)
394 {
395  error_t error;
396  IkeSaEntry *sa;
397  const IkeHeader *ikeHeader;
398  const IkeSaPayload *saPayload;
399  const IkeKePayload *kePayload;
400  const IkeNoncePayload *noncePayload;
401 #if (IKE_COOKIE_SUPPORT == ENABLED || IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
402  const IkeNotifyPayload *notifyPayload;
403 #endif
404 
405  //Each message begins with the IKE header
406  ikeHeader = (IkeHeader *) message;
407 
408  //The initiator's SPI must not be zero (refer to RFC 7296, section 3.1)
409  if(osMemcmp(ikeHeader->initiatorSpi, IKE_INVALID_SPI, IKE_SPI_SIZE) == 0)
410  return ERROR_INVALID_MESSAGE;
411 
412  //The responder's SPI must be zero in the first message of an IKE initial
413  //exchange (including repeats of that message including a cookie)
414  if(osMemcmp(ikeHeader->responderSpi, IKE_INVALID_SPI, IKE_SPI_SIZE) != 0)
415  return ERROR_INVALID_MESSAGE;
416 
417  //The Message ID is a 32-bit quantity, which is zero for the IKE_SA_INIT
418  //messages (including retries of the message due to responses such as
419  //COOKIE and INVALID_KE_PAYLOAD)
420  if(ntohl(ikeHeader->messageId) != 0)
421  return ERROR_INVALID_MESSAGE;
422 
423  //The SAi payload states the cryptographic algorithms the initiator supports
424  //for the IKE SA (refer to RFC 7296, section 1.2)
425  saPayload = (IkeSaPayload *) ikeGetPayload(message, length,
427 
428  //The KEi payload sends the initiator's Diffie-Hellman value
429  kePayload = (IkeKePayload *) ikeGetPayload(message, length,
431 
432  //The initiator sends its nonce in the Ni payload
433  noncePayload = (IkeNoncePayload *) ikeGetPayload(message, length,
435 
436  //Mandatory payloads must be included in the received message
437  if(saPayload == NULL || kePayload == NULL || noncePayload == NULL)
438  return ERROR_INVALID_MESSAGE;
439 
440  //When a responder receives an IKE_SA_INIT request, it has to determine
441  //whether the packet is a retransmission belonging to an existing half-open
442  //IKE SA, or a new request, or it belongs to an existing IKE SA where the
443  //IKE_AUTH request has been already received (refer to RFC 7296, section 2.1)
444  sa = ikeFindHalfOpenSaEntry(context, ikeHeader, noncePayload);
445 
446  //Existing IKE SA found?
447  if(sa != NULL)
448  {
449  //Half-open IKE SA?
450  if(sa->state == IKE_SA_STATE_AUTH_REQ)
451  {
452  //If the packet is a retransmission belonging to an existing half-open
453  //IKE SA The responder retransmits the same response
454  return ikeRetransmitResponse(sa);
455  }
456  else
457  {
458  //If the packet belongs to an existing IKE SA where the IKE_AUTH
459  //request has been already received, then the responder ignores it
461  }
462  }
463 
464  //If the packet is a new request, the responder creates a new IKE SA and
465  //sends a fresh response
466  sa = ikeCreateSaEntry(context);
467  //Failed to create IKE SA?
468  if(sa == NULL)
469  return ERROR_OUT_OF_RESOURCES;
470 
471  //Initialize IKE SA
472  sa->remoteIpAddr = context->remoteIpAddr;
473  sa->remotePort = IKE_PORT;
474 
475  //The original initiator always refers to the party who initiated the
476  //exchange (refer to RFC 7296, section 2.2)
477  sa->originalInitiator = FALSE;
478 
479  //The Message ID is zero for the IKE_SA_INIT messages
480  sa->rxMessageId = 0;
481 
482  //Save initiator's IKE SPI
483  osMemcpy(sa->initiatorSpi, ikeHeader->initiatorSpi, IKE_SPI_SIZE);
484 
485  //Save the length of the first message (IKE_SA_INIT request)
486  sa->initiatorSaInitLen = length;
487 
488  //Start of exception handling block
489  do
490  {
491  //Check whether the message contains an unsupported critical payload
493  &sa->unsupportedCriticalPayload);
494 
495  //Valid IKE message?
496  if(error == NO_ERROR)
497  {
498  //The message is valid
499  }
500  else if(error == ERROR_UNSUPPORTED_OPTION)
501  {
502  //Reject the message and send an UNSUPPORTED_CRITICAL_PAYLOAD error
504  break;
505  }
506  else
507  {
508  //Reject the message and send an INVALID_SYNTAX error
509  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
510  break;
511  }
512 
513  //Save initiator's nonce
514  error = ikeParseNoncePayload(noncePayload, sa->initiatorNonce,
515  &sa->initiatorNonceLen);
516 
517  //Malformed nonce?
518  if(error)
519  {
520  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
521  break;
522  }
523 
524 #if (IKE_COOKIE_SUPPORT == ENABLED)
525  //Any registered callbacks?
526  if(context->cookieVerifyCallback != NULL &&
527  context->cookieGenerateCallback != NULL)
528  {
529  //Check whether the response includes a COOKIE notification
530  notifyPayload = ikeGetStatusNotifyPayload(message, length,
532 
533  //COOKIE notification received?
534  if(notifyPayload != NULL)
535  {
536  //Save the received cookie
537  error = ikeParseCookieNotification(sa, notifyPayload);
538 
539  //Malformed notification?
540  if(error)
541  {
542  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
543  break;
544  }
545  }
546  else
547  {
548  //No cookie has been included in the IKE_SA_INIT message
549  sa->cookieLen = 0;
550  }
551 
552  //The cookie can be recomputed when the IKE_SA_INIT arrives the second
553  //time and compared to the cookie in the received message
554  error = context->cookieVerifyCallback(context,
555  &context->remoteIpAddr, sa->initiatorSpi, sa->initiatorNonce,
556  sa->initiatorNonceLen, sa->cookie, sa->cookieLen);
557 
558  //Check status code
559  if(error == NO_ERROR)
560  {
561  //The received cookie is valid
562  }
563  else if(error == ERROR_WRONG_COOKIE)
564  {
565  //When one party receives an IKE_SA_INIT request containing a cookie
566  //whose contents do not match the value expected, that party must
567  //ignore the cookie and process the message as if no cookie had been
568  //included (refer to RFC 7296, section 2.6)
569  error = context->cookieGenerateCallback(context,
570  &context->remoteIpAddr, sa->initiatorSpi, sa->initiatorNonce,
571  sa->initiatorNonceLen, sa->cookie, &sa->cookieLen);
572 
573  //Check status code
574  if(!error)
575  {
576  //Send a response containing a new cookie
577  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_COOKIE;
578  }
579  else
580  {
581  //Send an error response
582  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE;
583  }
584 
585  //Send IKE_SA_INIT response message
586  break;
587  }
588  else
589  {
590  //Send an error response
591  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE;
592  break;
593  }
594  }
595 #endif
596 
597  //Check the syntax of the SAi payload
598  error = ikeParseSaPayload(saPayload);
599 
600  //Malformed SAi payload?
601  if(error)
602  {
603  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
604  break;
605  }
606 
607  //The responder must choose a single suite, which may be any subset of
608  //the SA proposal (refer to RFC 7296, section 2.7)
609  error = ikeSelectSaProposal(sa, saPayload, 0);
610 
611  //The responder must accept a single proposal or reject them all and
612  //return an error. The error is given in a notification of type
613  //NO_PROPOSAL_CHOSEN
614  if(error)
615  {
616  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN;
617  break;
618  }
619 
620  //Nonces used in IKEv2 must be at least half the key size of the
621  //negotiated pseudorandom function (refer to RFC 7296, section 2.10)
622  error = ikeCheckNonceLength(sa, sa->initiatorNonceLen);
623 
624  //Unacceptable nonce length?
625  if(error)
626  {
627  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
628  break;
629  }
630 
631  //The Key Exchange payload is used to exchange Diffie-Hellman public
632  //numbers as part of a Diffie-Hellman key exchange
633  error = ikeParseKePayload(sa, kePayload);
634 
635  //Check status code
636  if(error == NO_ERROR)
637  {
638  //The Key Exchange payload is acceptable
639  }
640  else if(error == ERROR_INVALID_SYNTAX)
641  {
642  //The Key Exchange payload is malformed
643  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
644  break;
645  }
646  else if(error == ERROR_INVALID_GROUP)
647  {
648  //Reject the message with a Notify payload of type INVALID_KE_PAYLOAD
649  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_KE_PAYLOAD;
650  break;
651  }
652  else
653  {
654  //Report an error
655  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE;
656  break;
657  }
658 
659 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
660  //Search the IKE_SA_INIT message for a Notify payload of type
661  //SIGNATURE_HASH_ALGORITHMS
662  notifyPayload = ikeGetStatusNotifyPayload(message, length,
664 
665  //SIGNATURE_HASH_ALGORITHMS notification received?
666  if(notifyPayload != NULL)
667  {
668  //This notification indicates the list of hash functions supported by
669  //the sending peer (refer to RFC 7427, section 4)
670  error = ikeParseSignHashAlgosNotification(sa, notifyPayload);
671 
672  //Malformed notification?
673  if(error)
674  {
675  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
676  break;
677  }
678  }
679  else
680  {
681  //The notification is not present in the IKE_SA_INIT message
682  sa->signHashAlgos = 0;
683  }
684 #endif
685 
686  //End of exception handling block
687  } while(0);
688 
689  //An IKE message flow always consists of a request followed by a response
690  return ikeSendIkeSaInitResponse(sa);
691 }
692 
693 
694 /**
695  * @brief Process incoming IKE_SA_INIT response
696  * @param[in] sa Pointer to the IKE SA
697  * @param[in] message Pointer to the received IKE message
698  * @param[in] length Length of the IKE message, in bytes
699  * @return Error code
700  **/
701 
703  size_t length)
704 {
705  error_t error;
706  uint16_t notifyMsgType;
707  const IkeHeader *ikeHeader;
708  const IkeSaPayload *saPayload;
709  const IkeKePayload *kePayload;
710  const IkeNoncePayload *noncePayload;
711  const IkeCertReqPayload *certReqPayload;
712  const IkeNotifyPayload *notifyPayload;
713 
714  //Each message begins with the IKE header
715  ikeHeader = (IkeHeader *) message;
716 
717  //Check the state of the IKE SA
718  if(sa->state != IKE_SA_STATE_INIT_RESP)
720 
721  //Save the length of the second message (IKE_SA_INIT response)
722  sa->responderSaInitLen = length;
723 
724  //Start of exception handling block
725  do
726  {
727  //Payloads sent in IKE response messages must not have the critical flag
728  //set (refer to RFC 7296, section 2.5)
729  error = ikeCheckCriticalPayloads(message, length, NULL);
730  //Any error to report?
731  if(error)
732  break;
733 
734  //Check whether the response includes a Notify payload indicating an error
735  notifyPayload = ikeGetErrorNotifyPayload(message, length);
736 
737  //Error notification found?
738  if(notifyPayload != NULL)
739  {
740  //Types in the range 0-16383 are intended for reporting errors
741  notifyMsgType = ntohs(notifyPayload->notifyMsgType);
742 
743  //Some error notifications such as INVALID_KE_PAYLOAD may lead to a
744  //subsequent successful exchange
746  {
747  //If the initiator guesses wrong, the responder will respond with a
748  //Notify payload of type INVALID_KE_PAYLOAD indicating the selected
749  //group (refer to RFC 7296, section 1.2)
750  error = ikeParseInvalidKeyPayloadNotification(sa, notifyPayload);
751  //Malformed notification?
752  if(error)
753  break;
754 
755  //Reinitialize Diffie-Hellman context
756  ikeFreeDhContext(sa);
757  ikeInitDhContext(sa);
758 
759  //Generate a new ephemeral key pair
760  error = ikeGenerateDhKeyPair(sa);
761  //Any error to report?
762  if(error)
763  break;
764 
765  //The initiator must retry the IKE_SA_INIT with the corrected
766  //Diffie-Hellman group (refer to RFC 7296, section 1.2)
767  error = ERROR_RETRY;
768  break;
769  }
770  else
771  {
772  //An implementation receiving an error type that it does not
773  //recognize in a response must assume that the corresponding
774  //request has failed entirely (refer to RFC 7296, section 3.10.1)
775  error = ERROR_UNEXPECTED_STATUS;
776  break;
777  }
778  }
779 
780  //Check whether the response includes a COOKIE notification
781  notifyPayload = ikeGetStatusNotifyPayload(message, length,
783 
784  //COOKIE notification received?
785  if(notifyPayload != NULL)
786  {
787  //Save the received cookie
788  error = ikeParseCookieNotification(sa, notifyPayload);
789  //Malformed notification?
790  if(error)
791  break;
792 
793  //If the IKE_SA_INIT response includes the COOKIE notification, the
794  //initiator must then retry the IKE_SA_INIT request
795  error = ERROR_RETRY;
796  break;
797  }
798 
799  //The responder chooses a cryptographic suite from the initiator's offered
800  //choices and expresses that choice in the SAr payload
801  saPayload = (IkeSaPayload *) ikeGetPayload(message, length,
803 
804  //The responder completes the Diffie-Hellman exchange with the KEr payload
805  kePayload = (IkeKePayload *) ikeGetPayload(message, length,
807 
808  //The responder sends its nonce in the Nr payload
809  noncePayload = (IkeNoncePayload *) ikeGetPayload(message, length,
811 
812  //A Certificate Request payload can optionally be included
813  certReqPayload = (IkeCertReqPayload *) ikeGetPayload(message, length,
815 
816  //Mandatory payloads must be included in the received message
817  if(saPayload == NULL || kePayload == NULL || noncePayload == NULL)
818  {
819  error = ERROR_INVALID_MESSAGE;
820  break;
821  }
822 
823  //The responder's SPI must not be zero
824  if(osMemcmp(ikeHeader->responderSpi, IKE_INVALID_SPI, IKE_SPI_SIZE) == 0)
825  {
826  error = ERROR_INVALID_MESSAGE;
827  break;
828  }
829 
830  //Save responder's IKE SPI
831  osMemcpy(sa->responderSpi, ikeHeader->responderSpi, IKE_SPI_SIZE);
832 
833  //Save responder's nonce
834  error = ikeParseNoncePayload(noncePayload, sa->responderNonce,
835  &sa->responderNonceLen);
836  //Malformed nonce?
837  if(error)
838  break;
839 
840  //Check the syntax of the SAr payload
841  error = ikeParseSaPayload(saPayload);
842  //Malformed SAr payload?
843  if(error)
844  break;
845 
846  //The initiator of an exchange must check that the accepted offer is
847  //consistent with one of its proposals, and if not must terminate the
848  //exchange (refer to RFC 7296, section 3.3.6)
849  error = ikeCheckSaProposal(sa, saPayload);
850  //Invalid cryptographic suite?
851  if(error)
852  break;
853 
854  //Nonces used in IKEv2 must be at least half the key size of the
855  //negotiated pseudorandom function (refer to RFC 7296, section 2.10)
856  error = ikeCheckNonceLength(sa, sa->responderNonceLen);
857  //Unacceptable nonce length?
858  if(error)
859  break;
860 
861  //The Key Exchange payload is used to exchange Diffie-Hellman public
862  //numbers as part of a Diffie-Hellman key exchange
863  error = ikeParseKePayload(sa, kePayload);
864  //Any error to report?
865  if(error)
866  break;
867 
868  //The Certificate Request payload is optional
869  if(certReqPayload != NULL)
870  {
871  //The Certificate Request payload provides a means to request preferred
872  //certificates via IKE (refer to RFC 7296, section 3.7)
873  error = ikeParseCertReqPayload(sa, certReqPayload);
874  //Any error to report?
875  if(error)
876  break;
877  }
878 
879 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
880  //Search the IKE_SA_INIT message for a Notify payload of type
881  //SIGNATURE_HASH_ALGORITHMS
882  notifyPayload = ikeGetStatusNotifyPayload(message, length,
884 
885  //SIGNATURE_HASH_ALGORITHMS notification received?
886  if(notifyPayload != NULL)
887  {
888  //This notification indicates the list of hash functions supported by
889  //the sending peer (refer to RFC 7427, section 4)
890  error = ikeParseSignHashAlgosNotification(sa, notifyPayload);
891  //Any error to report?
892  if(error)
893  break;
894  }
895  else
896  {
897  //The notification is not present in the IKE_SA_INIT message
898  sa->signHashAlgos = 0;
899  }
900 #endif
901 
902  //End of exception handling block
903  } while(0);
904 
905  //Check status code
906  if(error == NO_ERROR)
907  {
908  //The second pair of messages (IKE_AUTH) authenticate the previous
909  //messages, exchange identities and certificates, and establish the
910  //first Child SA
911  error = ikeSendIkeAuthRequest(sa);
912  }
913  else if(error == ERROR_RETRY)
914  {
915  //The initiator must then retry the IKE_SA_INIT request
916  error = ikeSendIkeSaInitRequest(sa);
917  }
918  else
919  {
920  //The IKE_SA_INIT response is not valid
921  }
922 
923  //Check whether the IKE_SA_INIT exchange has failed
924  if(error)
925  {
926  ikeDeleteSaEntry(sa);
927  }
928 
929  //Return status code
930  return error;
931 }
932 
933 
934 /**
935  * @brief Process incoming IKE_AUTH request
936  * @param[in] sa Pointer to the IKE SA
937  * @param[in] message Pointer to the received IKE message
938  * @param[in] length Length of the IKE message, in bytes
939  * @return Error code
940  **/
941 
943  size_t length)
944 {
945  error_t error;
946  IkeChildSaEntry *childSa;
947  IpsecPadEntry *padEntry;
948  const IkeIdPayload *idPayload;
949  const IkeCertPayload *certPayload;
950  const IkeCertReqPayload *certReqPayload;
951  const IkeAuthPayload *authPayload;
952  const IkeSaPayload *saPayload;
953  const IkeTsPayload *tsiPayload;
954  const IkeTsPayload *tsrPayload;
955 
956  //Initialize Child SA
957  childSa = NULL;
958 
959  //Check the state of the IKE SA
960  if(sa->state != IKE_SA_STATE_AUTH_REQ)
962 
963  //Start of exception handling block
964  do
965  {
966  //Check whether the message contains an unsupported critical payload
968  &sa->unsupportedCriticalPayload);
969 
970  //Valid IKE message?
971  if(error == NO_ERROR)
972  {
973  //The message is valid
974  }
975  else if(error == ERROR_UNSUPPORTED_OPTION)
976  {
977  //Reject the message and send an UNSUPPORTED_CRITICAL_PAYLOAD error
979  break;
980  }
981  else
982  {
983  //Reject the message and send an INVALID_SYNTAX error
984  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
985  break;
986  }
987 
988  //The initiator asserts its identity with the IDi payload (refer to
989  //RFC 7296, section 1.2)
990  idPayload = (IkeIdPayload *) ikeGetPayload(message, length,
992 
993  //The Certificate payload provides a means to transport certificates or
994  //other authentication-related information via IKE
995  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
997 
998  //A Certificate Request payload can optionally be included
999  certReqPayload = (IkeCertReqPayload *) ikeGetPayload(message, length,
1001 
1002  //The initiator proves knowledge of the secret corresponding to IDi and
1003  //integrity protects the contents of the first message using the AUTH
1004  //payload
1005  authPayload = (IkeAuthPayload *) ikeGetPayload(message, length,
1007 
1008  //Mandatory payloads must be included in the received message
1009  if(idPayload == NULL || authPayload == NULL)
1010  {
1011  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1012  break;
1013  }
1014 
1015  //Parse Identification payload
1016  error = ikeParseIdPayload(sa, idPayload);
1017 
1018  //Malformed Identification payload?
1019  if(error)
1020  {
1021  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1022  break;
1023  }
1024 
1025  //Perform lookup in the PAD database based on the ID
1026  padEntry = ipsecFindPadEntry(netContext.ipsecContext, sa->peerIdType,
1027  sa->peerId, sa->peerIdLen);
1028 
1029  //All errors causing the authentication to fail for whatever reason
1030  //(invalid shared secret, invalid ID, untrusted certificate issuer,
1031  //revoked or expired certificate, etc.) should result in an
1032  //AUTHENTICATION_FAILED notification
1033  if(padEntry == NULL)
1034  {
1035  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_AUTH_FAILED;
1036  break;
1037  }
1038 
1039 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
1040  //Check whether a Certificate payload is included
1041  if(certPayload != NULL)
1042  {
1043  //Parse the certificate chain
1044  error = ikeParseCertificateChain(sa, padEntry, message, length);
1045 
1046  //Failed to validate certificate chain?
1047  if(error)
1048  {
1049  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_AUTH_FAILED;
1050  break;
1051  }
1052  }
1053 #endif
1054 
1055  //The peers are authenticated by having each sign (or MAC using a padded
1056  //shared secret as the key, as described later in this section) a block
1057  //of data (refer to RFC 7296, section 2.15)
1058  error = ikeVerifyAuth(sa, padEntry, idPayload, certPayload, authPayload);
1059 
1060  //Authentication failure?
1061  if(error)
1062  {
1063  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_AUTH_FAILED;
1064  break;
1065  }
1066 
1067  //The Certificate Request payload is optional
1068  if(certReqPayload != NULL)
1069  {
1070  //The Certificate Request payload provides a means to request preferred
1071  //certificates via IKE (refer to RFC 7296, section 3.7)
1072  error = ikeParseCertReqPayload(sa, certReqPayload);
1073 
1074  //Malformed Certificate Request payload?
1075  if(error)
1076  {
1077  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1078  break;
1079  }
1080  }
1081 
1082  //The initiator begins negotiation of a Child SA using the SAi payload
1083  saPayload = (IkeSaPayload *) ikeGetPayload(message, length,
1084  IKE_PAYLOAD_TYPE_SA, 0);
1085 
1086  //TSi specifies the source address of traffic forwarded from (or the
1087  //destination address of traffic forwarded to) the initiator of the
1088  //Child SA pair
1089  tsiPayload = (IkeTsPayload *) ikeGetPayload(message, length,
1091 
1092  //TSr specifies the destination address of the traffic forwarded to (or
1093  //the source address of the traffic forwarded from) the responder of the
1094  //Child SA pair
1095  tsrPayload = (IkeTsPayload *) ikeGetPayload(message, length,
1097 
1098  //Child SAs can be created either by being piggybacked on the IKE_AUTH
1099  //exchange, or using a separate CREATE_CHILD_SA exchange
1100  if(saPayload != NULL && tsiPayload != NULL && tsrPayload != NULL)
1101  {
1102  //Create a new Child SA
1103  childSa = ikeCreateChildSaEntry(sa->context);
1104 
1105  //Failed to create Child SA?
1106  if(childSa == NULL)
1107  {
1108  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE;
1109  break;
1110  }
1111 
1112  //Initialize Child SA
1113  childSa->sa = sa;
1114  childSa->mode = IPSEC_MODE_TUNNEL;
1115  childSa->initiator = FALSE;
1116 
1117  //Generate a new SPI for the Child SA
1118  error = ikeGenerateChildSaSpi(childSa, childSa->localSpi);
1119 
1120  //Any error to report?
1121  if(error)
1122  {
1123  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE;
1124  break;
1125  }
1126 
1127  //IKEv2 allows the responder to choose a subset of the traffic proposed
1128  //by the initiator (refer to RFC 7296, section 2.9)
1129  error = ikeSelectTs(childSa, tsiPayload, tsrPayload);
1130 
1131  //If the responder's policy does not allow it to accept any part of
1132  //the proposed Traffic Selectors, it responds with a TS_UNACCEPTABLE
1133  //Notify message
1134  if(error)
1135  {
1136  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE;
1137  break;
1138  }
1139 
1140  //Check the syntax of the SAi payload
1141  error = ikeParseSaPayload(saPayload);
1142 
1143  //Malformed SAi payload?
1144  if(error)
1145  {
1146  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1147  break;
1148  }
1149 
1150  //The responder must choose a single suite, which may be any subset
1151  //of the SA proposal (refer to RFC 7296, section 2.7)
1152  error = ikeSelectChildSaProposal(childSa, saPayload);
1153 
1154  //The responder must accept a single proposal or reject them all and
1155  //return an error. The error is given in a notification of type
1156  //NO_PROPOSAL_CHOSEN
1157  if(error)
1158  {
1159  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN;
1160  break;
1161  }
1162 
1163  //The USE_TRANSPORT_MODE notification may be included in a request
1164  //message that also includes an SA payload requesting a Child SA
1167  {
1168  //It requests that the Child SA use transport mode rather than
1169  //tunnel mode for the SA created
1170  childSa->mode = IPSEC_MODE_TRANSPORT;
1171  }
1172 
1173  //Attach the newly created Child SA to the IKE SA
1174  sa->childSa = childSa;
1175  }
1176 
1177 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
1178  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
1179  //IKE SA currently active between the authenticated identities
1182  {
1183  //It may be sent when an IKE SA is established after a crash, and the
1184  //recipient may use this information to delete any other IKE SAs it
1185  //has to the same authenticated identity without waiting for a timeout
1186  sa->initialContact = TRUE;
1187  }
1188 #endif
1189 
1190  //End of exception handling block
1191  } while(0);
1192 
1193  //Failed to create Child SA?
1194  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN ||
1195  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE ||
1196  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED ||
1197  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE ||
1198  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED)
1199  {
1200  //If creating the Child SA during the IKE_AUTH exchange fails for some
1201  //reason, the IKE SA is still created as usual (refer to RFC 7296,
1202  //section 1.2)
1203  if(childSa != NULL)
1204  {
1205  ikeDeleteChildSaEntry(childSa);
1206  }
1207  }
1208 
1209  //An IKE message flow always consists of a request followed by a response
1210  return ikeSendIkeAuthResponse(sa);
1211 }
1212 
1213 
1214 /**
1215  * @brief Process incoming IKE_AUTH response
1216  * @param[in] sa Pointer to the IKE SA
1217  * @param[in] message Pointer to the received IKE message
1218  * @param[in] length Length of the IKE message, in bytes
1219  * @return Error code
1220  **/
1221 
1223  size_t length)
1224 {
1225  error_t error;
1226  uint16_t notifyMsgType;
1227  IkeChildSaEntry *childSa;
1228  IpsecPadEntry *padEntry;
1229  const IkeIdPayload *idPayload;
1230  const IkeCertPayload *certPayload;
1231  const IkeAuthPayload *authPayload;
1232  const IkeSaPayload *saPayload;
1233  const IkeNotifyPayload *notifyPayload;
1234  const IkeTsPayload *tsiPayload;
1235  const IkeTsPayload *tsrPayload;
1236 
1237  //Point to the Child SA
1238  childSa = sa->childSa;
1239 
1240  //Start of exception handling block
1241  do
1242  {
1243  //Check the state of the IKE SA
1244  if(sa->state != IKE_SA_STATE_AUTH_RESP)
1245  {
1246  error = ERROR_UNEXPECTED_MESSAGE;
1247  break;
1248  }
1249 
1250  //Payloads sent in IKE response messages must not have the critical flag
1251  //set (refer to RFC 7296, section 2.5)
1252  error = ikeCheckCriticalPayloads(message, length, NULL);
1253  //Any error to report?
1254  if(error)
1255  break;
1256 
1257  //Check whether the response includes a Notify payload indicating an error
1258  notifyPayload = ikeGetErrorNotifyPayload(message, length);
1259 
1260  //Error notification found?
1261  if(notifyPayload != NULL)
1262  {
1263  //Types in the range 0-16383 are intended for reporting errors
1264  notifyMsgType = ntohs(notifyPayload->notifyMsgType);
1265 
1266  //If creating the Child SA during the IKE_AUTH exchange fails for some
1267  //reason, the IKE SA is still created as usual (refer to RFC 7296,
1268  //section 1.2)
1274  {
1275  error = ERROR_UNEXPECTED_STATUS;
1276  break;
1277  }
1278  }
1279 
1280  //The responder asserts its identity with the IDr payload (refer to
1281  //RFC 7296, section 1.2)
1282  idPayload = (IkeIdPayload *) ikeGetPayload(message, length,
1284 
1285  //The Certificate payload provides a means to transport certificates or
1286  //other authentication-related information via IKE
1287  certPayload = (IkeCertPayload *) ikeGetPayload(message, length,
1289 
1290  //The responder authenticates its identity and protects the integrity
1291  //of the second message with the AUTH payload
1292  authPayload = (IkeAuthPayload *) ikeGetPayload(message, length,
1294 
1295  //Mandatory payloads must be included in the received message
1296  if(idPayload == NULL || authPayload == NULL)
1297  {
1299  break;
1300  }
1301 
1302  //Parse Identification payload
1303  error = ikeParseIdPayload(sa, idPayload);
1304  //Malformed Identification payload?
1305  if(error)
1306  {
1308  break;
1309  }
1310 
1311  //Perform lookup in the PAD database based on the ID
1312  padEntry = ipsecFindPadEntry(netContext.ipsecContext, sa->peerIdType,
1313  sa->peerId, sa->peerIdLen);
1314  //Invalid ID?
1315  if(padEntry == NULL)
1316  {
1318  break;
1319  }
1320 
1321 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
1322  //Check whether a Certificate payload is included
1323  if(certPayload != NULL)
1324  {
1325  //Parse the certificate chain
1326  error = ikeParseCertificateChain(sa, padEntry, message, length);
1327  //Failed to validate certificate chain?
1328  if(error)
1329  {
1331  break;
1332  }
1333  }
1334 #endif
1335 
1336  //The peers are authenticated by having each sign (or MAC using a padded
1337  //shared secret as the key, as described later in this section) a block
1338  //of data (refer to RFC 7296, section 2.15)
1339  error = ikeVerifyAuth(sa, padEntry, idPayload, certPayload, authPayload);
1340  //Authentication failure?
1341  if(error)
1342  {
1344  break;
1345  }
1346 
1347  //The responder completes negotiation of a Child SA with additional fields
1348  if(childSa != NULL)
1349  {
1350  //Successful Child SA creation?
1351  if(notifyPayload == NULL)
1352  {
1353  //The responder chooses a cryptographic suite from the initiator's
1354  //offered choices and expresses that choice in the SAr payload
1355  saPayload = (IkeSaPayload *) ikeGetPayload(message, length,
1356  IKE_PAYLOAD_TYPE_SA, 0);
1357 
1358  //TSi specifies the source address of traffic forwarded from (or
1359  //the destination address of traffic forwarded to) the initiator
1360  //of the Child SA pair
1361  tsiPayload = (IkeTsPayload *) ikeGetPayload(message, length,
1363 
1364  //TSr specifies the destination address of the traffic forwarded
1365  //to (or the source address of the traffic forwarded from) the
1366  //responder of the Child SA pair
1367  tsrPayload = (IkeTsPayload *) ikeGetPayload(message, length,
1369 
1370  //Mandatory payloads must be included in the received message
1371  if(saPayload == NULL || tsiPayload == NULL || tsrPayload == NULL)
1372  {
1373  error = ERROR_INVALID_MESSAGE;
1374  break;
1375  }
1376 
1377  //Check the syntax of the SAr payload
1378  error = ikeParseSaPayload(saPayload);
1379  //Malformed SAr payload?
1380  if(error)
1381  break;
1382 
1383  //The initiator of an exchange must check that the accepted offer
1384  //is consistent with one of its proposals, and if not must terminate
1385  //the exchange (refer to RFC 7296, section 3.3.6)
1386  error = ikeCheckChildSaProposal(childSa, saPayload);
1387  //Invalid cryptographic suite?
1388  if(error)
1389  break;
1390 
1391  //When the responder chooses a subset of the traffic proposed by
1392  //the initiator, it narrows the Traffic Selectors to some subset
1393  //of the initiator's proposal (refer to RFC 7296, section 2.9)
1394  error = ikeCheckTs(childSa, tsiPayload, tsrPayload);
1395  //Invalid traffic selector?
1396  if(error)
1397  break;
1398 
1399  //The initiator can request that the Child SA use transport mode rather
1400  //than tunnel mode for the SA created
1401  if(childSa->mode == IPSEC_MODE_TRANSPORT)
1402  {
1403  //If the request is accepted, the response must also include a
1404  //notification of type USE_TRANSPORT_MODE
1407  {
1408  //Use tunnel mode
1409  childSa->mode = IPSEC_MODE_TUNNEL;
1410  }
1411  }
1412 
1413  //For the first Child SA created, Ni and Nr are the nonces from the
1414  //IKE_SA_INIT exchange (refer to RFC 7296, section 2.17)
1415  osMemcpy(childSa->initiatorNonce, sa->initiatorNonce,
1416  sa->initiatorNonceLen);
1417  osMemcpy(childSa->responderNonce, sa->responderNonce,
1418  sa->responderNonceLen);
1419 
1420  //Save the length of Ni and Nr nonces
1421  childSa->initiatorNonceLen = sa->initiatorNonceLen;
1422  childSa->responderNonceLen = sa->responderNonceLen;
1423 
1424  //A single Child SA is created by the IKE_AUTH exchange. Keying
1425  //material for the Child SA must be taken from the expanded KEYMAT
1426  //(refer to RFC 7296, section 2.17)
1427  error = ikeGenerateChildSaKeyMaterial(childSa);
1428  //Any error to report?
1429  if(error)
1430  break;
1431  }
1432  else
1433  {
1434  //The Child SA creation has failed
1435  ikeDeleteChildSaEntry(childSa);
1436  sa->childSa = NULL;
1437  childSa = NULL;
1438 
1439  //Request closure of the IKE SA
1440  sa->deleteRequest = TRUE;
1441  }
1442  }
1443 
1444 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
1445  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
1446  //IKE SA currently active between the authenticated identities
1449  {
1450  //It may be sent when an IKE SA is established after a crash, and the
1451  //recipient may use this information to delete any other IKE SAs it
1452  //has to the same authenticated identity without waiting for a timeout
1454  }
1455 #endif
1456 
1457  //End of exception handling block
1458  } while(0);
1459 
1460  //Check status code
1461  if(error == NO_ERROR)
1462  {
1463  //The initiator has received the IKE_AUTH response
1465 
1466  //Successful Child SA creation?
1467  if(childSa != NULL)
1468  {
1469  //Update the state of the Child SA
1471 
1472  //ESP and AH SAs exist in pairs (one in each direction), so two SAs
1473  //are created in a single Child SA negotiation for them
1474  ikeCreateIpsecSaPair(childSa);
1475  }
1476 
1477  //Check whether reauthentication is on-going
1478  if(sa->oldSa != NULL)
1479  {
1480  //IKEv2 does not have any special support for reauthentication.
1481  //Reauthentication is done by creating a new IKE SA from scratch,
1482  //creating new Child SAs within the new IKE SA, and finally deleting
1483  //the old IKE SA
1484  ikeProcessSaDeleteEvent(sa->oldSa);
1485 
1486  //Detach the old IKE SA
1487  sa->oldSa = NULL;
1488  }
1489  }
1490  else if(error == ERROR_AUTHENTICATION_FAILED)
1491  {
1492  //All errors causing the authentication to fail for whatever reason
1493  //(invalid shared secret, invalid ID, untrusted certificate issuer,
1494  //revoked or expired certificate, etc.) should result in an
1495  //AUTHENTICATION_FAILED notification
1497 
1498  //If the error occurs on the initiator, the notification may be returned
1499  //in a separate INFORMATIONAL exchange, usually with no other payloads.
1500  //This is an exception for the general rule of not starting new exchanges
1501  //based on errors in responses (refer to RFC 7296, section 2.21.2)
1502  ikeSendInfoRequest(sa);
1503  }
1504  else
1505  {
1506  //The IKE_AUTH exchange has failed
1507  ikeDeleteSaEntry(sa);
1508  }
1509 
1510  //Return status code
1511  return error;
1512 }
1513 
1514 
1515 /**
1516  * @brief Process incoming CREATE_CHILD_SA request
1517  * @param[in] sa Pointer to the IKE SA
1518  * @param[in] message Pointer to the received IKE message
1519  * @param[in] length Length of the IKE message, in bytes
1520  * @return Error code
1521  **/
1522 
1524  size_t length)
1525 {
1526  //The CREATE_CHILD_SA exchange may be initiated by either end of the IKE SA
1527  //after the initial exchanges are completed (refer to RFC 7296, section 1.3)
1528  if(sa->state < IKE_SA_STATE_OPEN)
1529  return ERROR_UNEXPECTED_MESSAGE;
1530 
1531  //A minimal implementation may support the CREATE_CHILD_SA exchange only in
1532  //so far as to recognize requests and reject them with a Notify payload of
1533  //type NO_ADDITIONAL_SAS (refer to RFC 7296, section 4)
1534  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_NO_ADDITIONAL_SAS;
1535 
1536  //An IKE message flow always consists of a request followed by a response
1537  return ikeSendCreateChildSaResponse(sa, NULL);
1538 }
1539 
1540 
1541 /**
1542  * @brief Process incoming CREATE_CHILD_SA response
1543  * @param[in] sa Pointer to the IKE SA
1544  * @param[in] message Pointer to the received IKE message
1545  * @param[in] length Length of the IKE message, in bytes
1546  * @return Error code
1547  **/
1548 
1550  size_t length)
1551 {
1552  //Minimal implementations are not required to support the CREATE_CHILD_SA
1553  //exchange (refer to RFC 7296, section 4)
1554  return ERROR_UNEXPECTED_MESSAGE;
1555 }
1556 
1557 
1558 /**
1559  * @brief Process incoming INFORMATIONAL request
1560  * @param[in] sa Pointer to the IKE SA
1561  * @param[in] message Pointer to the received IKE message
1562  * @param[in] length Length of the IKE message, in bytes
1563  * @return Error code
1564  **/
1565 
1567  size_t length)
1568 {
1569  error_t error;
1570  uint_t i;
1571  uint16_t notifyMsgType;
1572  const IkeDeletePayload *deletePayload;
1573  const IkeNotifyPayload *notifyPayload;
1574 
1575  //INFORMATIONAL exchanges must only occur after the initial exchanges
1576  //and are cryptographically protected with the negotiated keys (refer to
1577  //RFC 7296, section 1.4)
1578  if(sa->state < IKE_SA_STATE_OPEN)
1579  return ERROR_UNEXPECTED_MESSAGE;
1580 
1581  //Start of exception handling block
1582  do
1583  {
1584  //Check whether the message contains an unsupported critical payload
1586  &sa->unsupportedCriticalPayload);
1587 
1588  //Valid IKE message?
1589  if(error == NO_ERROR)
1590  {
1591  //The message is valid
1592  }
1593  else if(error == ERROR_UNSUPPORTED_OPTION)
1594  {
1595  //Reject the message and send an UNSUPPORTED_CRITICAL_PAYLOAD error
1597  break;
1598  }
1599  else
1600  {
1601  //Reject the message and send an INVALID_SYNTAX error
1602  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1603  break;
1604  }
1605 
1606  //Check whether the response includes a Notify payload indicating an error
1607  notifyPayload = ikeGetErrorNotifyPayload(message, length);
1608 
1609  //Error notification found?
1610  if(notifyPayload != NULL)
1611  {
1612  //Types in the range 0-16383 are intended for reporting errors
1613  notifyMsgType = ntohs(notifyPayload->notifyMsgType);
1614 
1615  //Check error type
1618  {
1619  //This error notification is considered fatal in both peers
1620  sa->deleteReceived = TRUE;
1621  }
1622  else
1623  {
1624  //Unrecognized error types in a request must be ignored (refer to
1625  //RFC 7296, section 3.10.1)
1626  }
1627  }
1628 
1629  //To delete an SA, an INFORMATIONAL exchange with one or more Delete
1630  //payloads is sent listing the SPIs of the SAs to be deleted (refer to
1631  //RFC 7296, section 1.4.1)
1632  for(i = 0; ; i++)
1633  {
1634  //Extract next Delete payload
1635  deletePayload = (IkeDeletePayload *) ikeGetPayload(message, length,
1636  IKE_PAYLOAD_TYPE_D, i);
1637 
1638  //Delete payload not found?
1639  if(deletePayload == NULL)
1640  break;
1641 
1642  //The Delete payload list the SPIs to be deleted
1643  error = ikeParseDeletePayload(sa, deletePayload, FALSE);
1644 
1645  //Malformed payload?
1646  if(error)
1647  {
1648  sa->notifyMsgType = IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX;
1649  break;
1650  }
1651  }
1652 
1653  //End of exception handling block
1654  } while(0);
1655 
1656  //An IKE message flow always consists of a request followed by a response
1657  return ikeSendInfoResponse(sa);
1658 }
1659 
1660 
1661 /**
1662  * @brief Process incoming INFORMATIONAL response
1663  * @param[in] sa Pointer to the IKE SA
1664  * @param[in] message Pointer to the received IKE message
1665  * @param[in] length Length of the IKE message, in bytes
1666  * @return Error code
1667  **/
1668 
1670  size_t length)
1671 {
1672  error_t error;
1673  uint_t i;
1674  const IkeDeletePayload *deletePayload;
1675  const IkeNotifyPayload *notifyPayload;
1676 
1677  //Start of exception handling block
1678  do
1679  {
1680  //Check the state of the IKE SA
1681  if(sa->state != IKE_SA_STATE_DPD_RESP &&
1682  sa->state != IKE_SA_STATE_DELETE_RESP &&
1683  sa->state != IKE_SA_STATE_DELETE_CHILD_RESP &&
1684  sa->state != IKE_SA_STATE_AUTH_FAILURE_RESP)
1685  {
1686  error = ERROR_UNEXPECTED_MESSAGE;
1687  break;
1688  }
1689 
1690  //Payloads sent in IKE response messages must not have the critical flag
1691  //set (refer to RFC 7296, section 2.5)
1692  error = ikeCheckCriticalPayloads(message, length, NULL);
1693  //Any error to report?
1694  if(error)
1695  break;
1696 
1697  //Check whether the response includes a Notify payload indicating an error
1698  notifyPayload = ikeGetErrorNotifyPayload(message, length);
1699 
1700  //Error notification found?
1701  if(notifyPayload != NULL)
1702  {
1703  //An implementation receiving an error type that it does not recognize
1704  //in a response must assume that the corresponding request has failed
1705  //entirely (refer to RFC 7296, section 3.10.1)
1706  error = ERROR_UNEXPECTED_STATUS;
1707  break;
1708  }
1709 
1710  //The response in the INFORMATIONAL exchange will contain Delete payloads
1711  //for the paired SAs going in the other direction
1712  for(i = 0; ; i++)
1713  {
1714  //Extract next Delete payload
1715  deletePayload = (IkeDeletePayload *) ikeGetPayload(message, length,
1716  IKE_PAYLOAD_TYPE_D, i);
1717  //Delete payload not found?
1718  if(deletePayload == NULL)
1719  break;
1720 
1721  //The Delete payload list the SPIs to be deleted
1722  error = ikeParseDeletePayload(sa, deletePayload, TRUE);
1723  //Malformed payload?
1724  if(error)
1725  break;
1726  }
1727 
1728  //End of exception handling block
1729  } while(0);
1730 
1731  //Check status code
1732  if(error == NO_ERROR)
1733  {
1734  //Check the state of the IKE SA
1735  if(sa->state == IKE_SA_STATE_DPD_RESP)
1736  {
1737  //Receipt of a fresh cryptographically protected message on an IKE SA
1738  //ensures liveness of the IKE SA and all of its Child SAs
1740  }
1741  else if(sa->state == IKE_SA_STATE_DELETE_RESP ||
1742  sa->state == IKE_SA_STATE_AUTH_FAILURE_RESP)
1743  {
1744  //Deleting an IKE SA implicitly closes any remaining Child SAs
1745  //negotiated under it (refer to RFC 7296, section 1.4.1)
1746  ikeDeleteSaEntry(sa);
1747  }
1748  else if(sa->state == IKE_SA_STATE_DELETE_CHILD_RESP)
1749  {
1750  //Update the state of the IKE SA
1752  }
1753  else
1754  {
1755  //Just for sanity
1756  }
1757  }
1758  else
1759  {
1760  //Delete the IKE SA
1761  ikeDeleteSaEntry(sa);
1762  }
1763 
1764  //Return status code
1765  return error;
1766 }
1767 
1768 #endif
AH algorithm negotiation.
error_t ikeParseIdPayload(IkeSaEntry *sa, const IkeIdPayload *idPayload)
Parse Identification payload.
Diffie-Hellman key exchange.
Authentication of the IKE SA.
Helper functions for IKEv2.
IKE message formatting.
IkeCertReqPayload
Definition: ike.h:1514
error_t ikeRetransmitResponse(IkeSaEntry *sa)
Retransmit IKE response message.
Definition: ike_misc.c:98
error_t ikeParseCookieNotification(IkeSaEntry *sa, const IkeNotifyPayload *notifyPayload)
Parse COOKIE notification.
IpsecPadEntry * ipsecFindPadEntry(IpsecContext *context, uint8_t idType, const uint8_t *id, size_t idLen)
Find PAD entry that matches the specified identification data.
Definition: ipsec_misc.c:243
@ IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN
Definition: ike.h:1133
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
IkeKePayload
Definition: ike.h:1477
error_t ikeCheckCriticalPayloads(const uint8_t *message, size_t length, uint8_t *unsupportedCriticalPayload)
Check whether the message contains an unsupported critical payload.
uint8_t message[]
Definition: chap.h:154
error_t ikeProcessIkeSaInitRequest(IkeContext *context, const uint8_t *message, size_t length)
Process incoming IKE_SA_INIT request.
error_t ikeSendCreateChildSaResponse(IkeSaEntry *sa, IkeChildSaEntry *childSa)
Send CREATE_CHILD_SA response.
const IkePayloadHeader * ikeGetPayload(const uint8_t *message, size_t length, uint8_t type, uint_t index)
Search an IKE message for a given payload type.
#define TRUE
Definition: os_port.h:50
error_t ikeParseKePayload(IkeSaEntry *sa, const IkeKePayload *kePayload)
Parse Key Exchange payload.
error_t ikeCheckSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (IKE protocol)
IkeNotifyPayload
Definition: ike.h:1563
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
ESP algorithm negotiation.
error_t ikeParseNoncePayload(const IkeNoncePayload *noncePayload, uint8_t *nonce, size_t *nonceLen)
Parse Nonce payload.
IkeChildSaEntry * ikeCreateChildSaEntry(IkeContext *context)
Create a new Child Security Association.
Definition: ike_misc.c:396
error_t ikeProcessCreateChildSaResponse(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming CREATE_CHILD_SA response.
@ IKE_PAYLOAD_TYPE_CERTREQ
Certificate Request.
Definition: ike.h:851
error_t ikeSelectChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal (AH or ESP protocol)
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
const IkeNotifyPayload * ikeGetErrorNotifyPayload(const uint8_t *message, size_t length)
Search an IKE message for an error Notify payload.
@ ERROR_WRONG_COOKIE
Definition: error.h:92
NetContext netContext
Definition: net.c:75
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
error_t ikeSelectTs(IkeChildSaEntry *childSa, const IkeTsPayload *tsiPayload, const IkeTsPayload *tsrPayload)
Traffic selector selection.
Definition: ike_misc.c:760
IKEv2 finite state machine.
@ ERROR_INVALID_VERSION
Definition: error.h:118
@ IPSEC_MODE_TUNNEL
Definition: ipsec.h:204
error_t ikeParseSignHashAlgosNotification(IkeSaEntry *sa, const IkeNotifyPayload *notifyPayload)
Parse SIGNATURE_HASH_ALGORITHMS notification.
@ IKE_NOTIFY_MSG_TYPE_SIGNATURE_HASH_ALGORITHMS
Definition: ike.h:1197
error_t ikeDecryptMessage(IkeSaEntry *sa, uint8_t *message, size_t *messageLen)
Decrypt an incoming IKE message.
error_t ikeProcessSaDeleteEvent(IkeSaEntry *sa)
Handle IKE SA deletion event.
Definition: ike_fsm.c:692
@ IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE
Definition: ike.h:1140
error_t ikeSendIkeAuthRequest(IkeSaEntry *sa)
Send IKE_AUTH request.
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
const uint8_t IKE_INVALID_SPI[8]
Definition: ike_misc.c:47
Peer Authorization Database (PAD) entry.
Definition: ipsec.h:400
#define IkeContext
Definition: ike.h:796
IkeAuthPayload
Definition: ike.h:1527
@ IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED
Definition: ike.h:1139
@ IKE_EXCHANGE_TYPE_IKE_AUTH
IKE_AUTH.
Definition: ike.h:819
@ ERROR_INVALID_GROUP
Definition: error.h:276
@ IKE_SA_STATE_DELETE_CHILD_RESP
Definition: ike.h:1303
#define FALSE
Definition: os_port.h:46
uint16_t notifyMsgType
Definition: ike.h:1561
@ ERROR_UNEXPECTED_STATUS
Definition: error.h:284
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
IkeSaEntry * ikeCreateSaEntry(IkeContext *context)
Create a new IKE Security Association.
Definition: ike_misc.c:136
Data logging functions for debugging purpose (IKEv2)
error_t ikeProcessIkeAuthResponse(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming IKE_AUTH response.
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:205
void ikeInitDhContext(IkeSaEntry *sa)
Initialize Diffie-Hellman context.
error_t ikeSendIkeSaInitResponse(IkeSaEntry *sa)
Send IKE_SA_INIT response.
@ IKE_SA_STATE_OPEN
Definition: ike.h:1291
error_t
Error codes.
Definition: error.h:43
IkeIdPayload
Definition: ike.h:1490
@ IKE_SA_STATE_AUTH_FAILURE_RESP
Definition: ike.h:1305
@ IKE_PAYLOAD_TYPE_AUTH
Authentication.
Definition: ike.h:852
@ IKE_PAYLOAD_TYPE_CERT
Certificate.
Definition: ike.h:850
IkeTsPayload
Definition: ike.h:1601
@ ERROR_UNSUPPORTED_OPTION
Definition: error.h:297
Key material generation.
#define IKE_SPI_SIZE
Definition: ike.h:790
error_t ikeProcessIkeSaInitResponse(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming IKE_SA_INIT response.
error_t ikeSendErrorResponse(IkeContext *context, uint8_t *message, size_t length)
Send INFORMATIONAL response (outside of an IKE SA)
Helper routines for IPsec.
#define IKE_MAJOR_VERSION
Definition: ike.h:780
error_t ikeParseCertificateChain(IkeSaEntry *sa, IpsecPadEntry *padEntry, const uint8_t *message, size_t length)
Parse certificate chain.
error_t ikeSendInfoRequest(IkeSaEntry *sa)
Send INFORMATIONAL request.
@ IKE_SA_STATE_AUTH_REQ
Definition: ike.h:1289
@ ERROR_RETRY
Definition: error.h:299
const IkeNotifyPayload * ikeGetStatusNotifyPayload(const uint8_t *message, size_t length, uint16_t type)
Search an IKE message for a given status Notify payload.
@ ERROR_INVALID_LENGTH
Definition: error.h:111
uint8_t exchangeType
Definition: ike.h:1386
void ikeDeleteSaEntry(IkeSaEntry *sa)
Delete an IKE Security Association.
Definition: ike_misc.c:298
error_t ikeProcessInfoResponse(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming INFORMATIONAL response.
error_t ikeVerifyAuth(IkeSaEntry *sa, IpsecPadEntry *padEntry, const IkeIdPayload *idPayload, const IkeCertPayload *certPayload, const IkeAuthPayload *authPayload)
Verify signature or MAC.
Definition: ike_auth.c:137
@ ERROR_UNKNOWN_TYPE
Definition: error.h:296
@ IKE_PAYLOAD_TYPE_IDI
Identification - Initiator.
Definition: ike.h:848
void ikeDeleteDuplicateSaEntries(IkeSaEntry *sa)
Delete an duplicate IKE Security Associations.
Definition: ike_misc.c:353
error_t ikeSendIkeAuthResponse(IkeSaEntry *sa)
Send IKE_AUTH response.
IKE message parsing.
void ikeDeleteChildSaEntry(IkeChildSaEntry *childSa)
Delete a Child Security Association.
Definition: ike_misc.c:501
#define TRACE_INFO(...)
Definition: debug.h:105
error_t ikeCheckNonceLength(IkeSaEntry *sa, size_t nonceLen)
Check the length of the nonce.
Definition: ike_misc.c:934
uint8_t length
Definition: tcp.h:375
IkeHeader
Definition: ike.h:1390
@ IKE_EXCHANGE_TYPE_CREATE_CHILD_SA
CREATE_CHILD_SA.
Definition: ike.h:820
error_t ikeCheckTs(IkeChildSaEntry *childSa, const IkeTsPayload *tsiPayload, const IkeTsPayload *tsrPayload)
Check whether the selected traffic selectors are acceptable.
Definition: ike_misc.c:854
void ikeChangeChildSaState(IkeChildSaEntry *childSa, IkeChildSaState newState)
Update Child SA state.
Definition: ike_fsm.c:108
void * ipsecContext
IPsec context.
Definition: net.h:339
error_t ikeParseSaPayload(const IkeSaPayload *saPayload)
Parse Security Association payload.
error_t ikeGenerateDhKeyPair(IkeSaEntry *sa)
Diffie-Hellman key pair generation.
IkeDeletePayload
Definition: ike.h:1577
IKEv2 (Internet Key Exchange Protocol)
error_t ikeCreateIpsecSaPair(IkeChildSaEntry *childSa)
Create AH or ESP SA pair.
Definition: ike_misc.c:1026
#define ntohs(value)
Definition: cpu_endian.h:421
error_t ikeProcessCreateChildSaRequest(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming CREATE_CHILD_SA request.
@ IKE_EXCHANGE_TYPE_IKE_SA_INIT
IKE_SA_INIT.
Definition: ike.h:818
error_t ikeSelectSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload, size_t spiSize)
Select a single proposal (IKE protocol)
@ IKE_PAYLOAD_TYPE_NONCE
Nonce.
Definition: ike.h:853
@ IKE_NOTIFY_MSG_TYPE_INVALID_KE_PAYLOAD
Definition: ike.h:1134
IKE payload parsing.
#define IkeSaEntry
Definition: ike.h:800
@ ERROR_INVALID_SPI
Definition: error.h:298
@ IKE_NOTIFY_MSG_TYPE_NO_ADDITIONAL_SAS
Definition: ike.h:1137
@ IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD
Definition: ike.h:1127
error_t ikeGenerateChildSaKeyMaterial(IkeChildSaEntry *childSa)
Generate keying material for the Child SA.
@ IKE_NOTIFY_MSG_TYPE_NONE
Definition: ike.h:1126
#define IKE_PORT
Definition: ike.h:785
@ IKE_SA_STATE_REKEY_CHILD_RESP
Definition: ike.h:1301
IkeCertPayload
Definition: ike.h:1502
error_t ikeSendIkeSaInitRequest(IkeSaEntry *sa)
Send IKE_SA_INIT request.
IkeSaEntry * ikeFindSaEntry(IkeContext *context, const IkeHeader *ikeHeader)
Find an IKE SA that matches an incoming IKE message.
Definition: ike_misc.c:183
@ ERROR_AUTHENTICATION_FAILED
Definition: error.h:69
error_t ikeGenerateChildSaSpi(IkeChildSaEntry *childSa, uint8_t *spi)
Generate a new Child SA SPI.
Definition: ike_misc.c:615
error_t ikeParseCertReqPayload(IkeSaEntry *sa, const IkeCertReqPayload *certReqPayload)
Parse Certificate Request payload.
error_t ikeProcessResponse(IkeContext *context, uint8_t *message, size_t length)
Process incoming IKE response.
@ IKE_SA_STATE_DELETE_RESP
Definition: ike.h:1297
@ IKE_NOTIFY_MSG_TYPE_AUTH_FAILED
Definition: ike.h:1135
X.509 certificate handling.
@ IKE_NOTIFY_MSG_TYPE_TEMPORARY_FAILURE
Definition: ike.h:1145
@ IKE_SA_STATE_AUTH_RESP
Definition: ike.h:1290
@ IKE_EXCHANGE_TYPE_INFORMATIONAL
INFORMATIONAL.
Definition: ike.h:821
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1288
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ IKE_NOTIFY_MSG_TYPE_INITIAL_CONTACT
Definition: ike.h:1150
@ IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE
Definition: ike.h:1138
@ IKE_PAYLOAD_TYPE_KE
Key Exchange.
Definition: ike.h:847
error_t ikeParseInvalidKeyPayloadNotification(IkeSaEntry *sa, const IkeNotifyPayload *notifyPayload)
Parse INVALID_KE_PAYLOAD notification.
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
@ IKE_SA_STATE_AUTH_FAILURE_REQ
Definition: ike.h:1304
@ IKE_NOTIFY_MSG_TYPE_COOKIE
Definition: ike.h:1156
@ IKE_FLAGS_R
Response flag.
Definition: ike.h:833
@ IKE_PAYLOAD_TYPE_TSI
Traffic Selector - Initiator.
Definition: ike.h:857
@ IKE_NOTIFY_MSG_TYPE_USE_TRANSPORT_MODE
Definition: ike.h:1157
@ IKE_SA_STATE_REKEY_RESP
Definition: ike.h:1295
error_t ikeProcessInfoRequest(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming INFORMATIONAL request.
IkeSaEntry * ikeFindHalfOpenSaEntry(IkeContext *context, const IkeHeader *ikeHeader, const IkeNoncePayload *noncePayload)
Find an half-open IKE SA that matches an incoming IKE_SA_INIT request.
Definition: ike_misc.c:244
IkeNoncePayload
Definition: ike.h:1549
@ IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED
Definition: ike.h:1136
@ IKE_SA_STATE_CREATE_CHILD_RESP
Definition: ike.h:1299
error_t ikeProcessIkeAuthRequest(IkeSaEntry *sa, const uint8_t *message, size_t length)
Process incoming IKE_AUTH request.
@ IKE_SA_STATE_DPD_RESP
Definition: ike.h:1293
error_t ikeParseDeletePayload(IkeSaEntry *sa, const IkeDeletePayload *deletePayload, bool_t response)
Parse Delete payload.
error_t ikeSendInfoResponse(IkeSaEntry *sa)
Send INFORMATIONAL response.
@ IKE_PAYLOAD_TYPE_IDR
Identification - Responder.
Definition: ike.h:849
Diffie-Hellman groups.
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:57
@ IKE_PAYLOAD_TYPE_D
Delete.
Definition: ike.h:855
@ IKE_PAYLOAD_TYPE_SA
Security Association.
Definition: ike.h:846
void ikeDumpMessage(const uint8_t *message, size_t length)
Dump IKE message.
Definition: ike_debug.c:385
error_t ikeCheckChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (AH or ESP protocol)
#define IkeChildSaEntry
Definition: ike.h:804
error_t ikeProcessMessage(IkeContext *context, uint8_t *message, size_t length)
Process incoming IKE message.
error_t ikeProcessRequest(IkeContext *context, uint8_t *message, size_t length)
Process incoming IKE request.
#define ntohl(value)
Definition: cpu_endian.h:422
IKEv2 algorithm negotiation.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
IKE message decryption.
IkeSaPayload
Definition: ike.h:1419
@ IKE_PAYLOAD_TYPE_TSR
Traffic Selector - Responder.
Definition: ike.h:858
@ IKE_NOTIFY_MSG_TYPE_INVALID_SYNTAX
Definition: ike.h:1130
@ IKE_CHILD_SA_STATE_OPEN
Definition: ike.h:1318
void ikeFreeDhContext(IkeSaEntry *sa)
Release Diffie-Hellman context.