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