ike.c
Go to the documentation of this file.
1 /**
2  * @file ike.c
3  * @brief IKEv2 (Internet Key Exchange Protocol)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2026 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.6.6
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_certificate.h"
41 #include "ike/ike_misc.h"
42 #include "ike/ike_debug.h"
43 #include "pkix/pem_import.h"
44 #include "pkix/x509_cert_parse.h"
45 #include "debug.h"
46 
47 //Check IKEv2 library configuration
48 #if (IKE_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief Initialize settings with default values
53  * @param[out] settings Structure that contains IKE settings
54  **/
55 
57 {
58  //Default task parameters
59  settings->task = OS_TASK_DEFAULT_PARAMS;
60  settings->task.stackSize = IKE_STACK_SIZE;
61  settings->task.priority = IKE_PRIORITY;
62 
63  //TCP/IP stack context
64  settings->netContext = NULL;
65  //Underlying network interface
66  settings->interface = NULL;
67 
68  //Pseudo-random number generator
69  settings->prngAlgo = NULL;
70  settings->prngContext = NULL;
71 
72  //IKE SA entries
73  settings->saEntries = NULL;
74  settings->numSaEntries = 0;
75 
76  //Child SA entries
77  settings->childSaEntries = NULL;
78  settings->numChildSaEntries = 0;
79 
80  //Lifetime of IKE SAs
82  //Lifetime of Child SAs
84 
85 #if (IKE_REAUTH_SUPPORT == ENABLED)
86  //Reauthentication period
87  settings->reauthPeriod = 0;
88 #endif
89 
90 #if (IKE_DPD_SUPPORT == ENABLED)
91  //Dead peer detection period
92  settings->dpdPeriod = 0;
93 #endif
94 
95 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
96  //NAT keepalive interval
98 #endif
99 
100 #if (IKE_COOKIE_SUPPORT == ENABLED)
101  //Cookie generation callback function
102  settings->cookieGenerateCallback = NULL;
103  //Cookie verification callback function
104  settings->cookieVerifyCallback = NULL;
105 #endif
106 
107 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
108  //Certificate verification callback function
109  settings->certVerifyCallback = NULL;
110 #endif
111 }
112 
113 
114 /**
115  * @brief IKE service initialization
116  * @param[in] context Pointer to the IKE context
117  * @param[in] settings IKE specific settings
118  * @return Error code
119  **/
120 
121 error_t ikeInit(IkeContext *context, const IkeSettings *settings)
122 {
123  error_t error;
124 
125  //Debug message
126  TRACE_INFO("Initializing IKE...\r\n");
127 
128  //Ensure the parameters are valid
129  if(context == NULL || settings == NULL)
131 
132  if(settings->prngAlgo == NULL || settings->prngContext == NULL)
134 
135  if(settings->saEntries == NULL || settings->numSaEntries == 0)
137 
138  if(settings->childSaEntries == NULL || settings->numChildSaEntries == 0)
140 
141  //Clear the IKE context
142  osMemset(context, 0, sizeof(IkeContext));
143 
144  //Initialize task parameters
145  context->taskParams = settings->task;
146  context->taskId = OS_INVALID_TASK_ID;
147 
148  //Attach TCP/IP stack context
149  if(settings->netContext != NULL)
150  {
151  context->netContext = settings->netContext;
152  }
153  else if(settings->interface != NULL)
154  {
155  context->netContext = settings->interface->netContext;
156  }
157  else
158  {
159  context->netContext = netGetDefaultContext();
160  }
161 
162  //Underlying network interface
163  context->interface = settings->interface;
164 
165  //Pseudo-random number generator
166  context->prngAlgo = settings->prngAlgo;
167  context->prngContext = settings->prngContext;
168 
169  //IKE SA entries
170  context->sa = settings->saEntries;
171  context->numSaEntries = settings->numSaEntries;
172 
173  //Child SA entries
174  context->childSa = settings->childSaEntries;
175  context->numChildSaEntries = settings->numChildSaEntries;
176 
177  //Lifetime of IKE SAs
178  context->saLifetime = settings->saLifetime;
179  //Lifetime of Child SAs
180  context->childSaLifetime = settings->childSaLifetime;
181 
182 #if (IKE_REAUTH_SUPPORT == ENABLED)
183  //Reauthentication period
184  context->reauthPeriod = settings->reauthPeriod;
185 #endif
186 
187 #if (IKE_DPD_SUPPORT == ENABLED)
188  //Dead peer detection period
189  context->dpdPeriod = settings->dpdPeriod;
190 #endif
191 
192 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
193  //NAT keepalive interval
194  context->natKeepaliveInterval = settings->natKeepaliveInterval;
195 #endif
196 
197 #if (IKE_COOKIE_SUPPORT == ENABLED)
198  //Cookie generation callback function
199  context->cookieGenerateCallback = settings->cookieGenerateCallback;
200  //Cookie verification callback function
201  context->cookieVerifyCallback = settings->cookieVerifyCallback;
202 #endif
203 
204 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
205  //Certificate verification callback function
206  context->certVerifyCallback = settings->certVerifyCallback;
207 #endif
208 
209  //Save the preferred key exchange method
210  context->preferredGroupNum = ikeSelectDefaultGroup();
211 
212  //Get exclusive access
213  netLock(context->netContext);
214  //Attach IKE context
215  context->netContext->ikeContext = context;
216  //Release exclusive access
217  netUnlock(context->netContext);
218 
219  //Initialize status code
220  error = NO_ERROR;
221 
222  //Create an event object to poll the state of the UDP socket
223  if(!osCreateEvent(&context->event))
224  {
225  //Failed to create event
226  error = ERROR_OUT_OF_RESOURCES;
227  }
228 
229  //Check status code
230  if(error)
231  {
232  //Clean up side effects
233  ikeDeinit(context);
234  }
235 
236  //Return status code
237  return error;
238 }
239 
240 
241 /**
242  * @brief Start IKE service
243  * @param[in] context Pointer to the IKE context
244  * @return Error code
245  **/
246 
248 {
249  error_t error;
250 
251  //Make sure the IKE context is valid
252  if(context == NULL)
254 
255  //Debug message
256  TRACE_INFO("Starting IKE...\r\n");
257 
258  //Make sure the IKE service is not already running
259  if(context->running)
260  return ERROR_ALREADY_RUNNING;
261 
262  //Start of exception handling block
263  do
264  {
265  //Open a UDP socket
266  context->socket = socketOpenEx(context->netContext, SOCKET_TYPE_DGRAM,
268  //Failed to open socket?
269  if(context->socket == NULL)
270  {
271  //Report an error
272  error = ERROR_OPEN_FAILED;
273  break;
274  }
275 
276  //Associate the socket with the relevant interface
277  error = socketBindToInterface(context->socket, context->interface);
278  //Unable to bind the socket to the desired interface?
279  if(error)
280  break;
281 
282  //IKE normally listens and sends on UDP port 500 (refer to RFC 7296,
283  //section 2);
284  error = socketBind(context->socket, &IP_ADDR_ANY, IKE_PORT);
285  //Unable to bind the socket to the desired port?
286  if(error)
287  break;
288 
289 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
290  //Open an alternate UDP socket
291  context->altSocket = socketOpenEx(context->netContext, SOCKET_TYPE_DGRAM,
293  //Failed to open socket?
294  if(context->altSocket == NULL)
295  {
296  //Report an error
297  error = ERROR_OPEN_FAILED;
298  break;
299  }
300 
301  //Associate the socket with the relevant interface
302  error = socketBindToInterface(context->altSocket, context->interface);
303  //Unable to bind the socket to the desired interface?
304  if(error)
305  break;
306 
307  //Port 4500 is reserved for UDP-encapsulated ESP and IKE (refer to
308  //RFC 7296, section 2.23);
309  error = socketBind(context->altSocket, &IP_ADDR_ANY, IPSEC_NAT_PORT);
310  //Unable to bind the socket to the desired port?
311  if(error)
312  break;
313 #endif
314 
315  //Start the IKE service
316  context->stop = FALSE;
317  context->running = TRUE;
318 
319  //Create a task
320  context->taskId = osCreateTask("IKE", (OsTaskCode) ikeTask, context,
321  &context->taskParams);
322 
323  //Failed to create task?
324  if(context->taskId == OS_INVALID_TASK_ID)
325  {
326  //Report an error
327  error = ERROR_OUT_OF_RESOURCES;
328  break;
329  }
330 
331  //End of exception handling block
332  } while(0);
333 
334  //Any error to report?
335  if(error)
336  {
337  //Clean up side effects
338  context->running = FALSE;
339 
340  //Close UDP socket
341  if(context->socket != NULL)
342  {
343  socketClose(context->socket);
344  context->socket = NULL;
345  }
346 
347 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
348  //Close alternate UDP socket
349  if(context->altSocket != NULL)
350  {
351  socketClose(context->altSocket);
352  context->altSocket = NULL;
353  }
354 #endif
355  }
356 
357  //Return status code
358  return error;
359 }
360 
361 
362 /**
363  * @brief Stop IKE service
364  * @param[in] context Pointer to the IKE context
365  * @return Error code
366  **/
367 
369 {
370  //Make sure the IKE context is valid
371  if(context == NULL)
373 
374  //Debug message
375  TRACE_INFO("Stopping IKE...\r\n");
376 
377  //Check whether the IKE service is running
378  if(context->running)
379  {
380 #if (NET_RTOS_SUPPORT == ENABLED)
381  //Stop the IKE service
382  context->stop = TRUE;
383  //Send a signal to the task to abort any blocking operation
384  osSetEvent(&context->event);
385 
386  //Wait for the task to terminate
387  while(context->running)
388  {
389  osDelayTask(1);
390  }
391 #endif
392 
393  //Close the UDP socket
394  if(context->socket != NULL)
395  {
396  socketClose(context->socket);
397  context->socket = NULL;
398  }
399 
400 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
401  //Close alternate UDP socket
402  if(context->altSocket != NULL)
403  {
404  socketClose(context->altSocket);
405  context->altSocket = NULL;
406  }
407 #endif
408  }
409 
410  //Successful processing
411  return NO_ERROR;
412 }
413 
414 
415 /**
416  * @brief Specify the preferred key exchange method
417  * @param[in] context Pointer to the IKE context
418  * @param[in] groupNum Preferred group number
419  * @return Error code
420  **/
421 
422 error_t ikeSetPreferredGroup(IkeContext *context, uint16_t groupNum)
423 {
424  //Make sure the IKE context is valid
425  if(context == NULL)
427 
428  //Ensure the specified key exchange method is supported
429  if(!ikeIsGroupSupported(groupNum))
430  return ERROR_INVALID_GROUP;
431 
432  //Save the preferred key exchange method
433  context->preferredGroupNum = groupNum;
434 
435  //Successful processing
436  return NO_ERROR;
437 }
438 
439 
440 /**
441  * @brief Set entity's ID
442  * @param[in] context Pointer to the IKE context
443  * @param[in] idType ID type
444  * @param[in] id Pointer to the identification data
445  * @param[in] idLen Length of the identification data, in bytes
446  * @return Error code
447  **/
448 
449 error_t ikeSetId(IkeContext *context, IkeIdType idType, const void *id,
450  size_t idLen)
451 {
452  //Check parameters
453  if(context == NULL || id == NULL)
455 
456  //Check the length of the identification data
457  if(idLen > IKE_MAX_ID_LEN)
458  return ERROR_INVALID_LENGTH;
459 
460  //Save identification data
461  context->idType = idType;
462  osMemcpy(context->id, id, idLen);
463  context->idLen = idLen;
464 
465  //Successful processing
466  return NO_ERROR;
467 }
468 
469 
470 /**
471  * @brief Set entity's pre-shared key
472  * @param[in] context Pointer to the IKE context
473  * @param[in] psk Pointer to the pre-shared key
474  * @param[in] pskLen Length of the pre-shared key, in bytes
475  * @return Error code
476  **/
477 
478 error_t ikeSetPsk(IkeContext *context, const uint8_t *psk, size_t pskLen)
479 {
480 #if (IKE_PSK_AUTH_SUPPORT == ENABLED)
481  //Check parameters
482  if(context == NULL || psk == NULL)
484 
485  //Check the length of the pre-shared key
486  if(pskLen > IKE_MAX_PSK_LEN)
487  return ERROR_INVALID_LENGTH;
488 
489  //Save pre-shared key
490  osMemcpy(context->psk, psk, pskLen);
491  context->pskLen = pskLen;
492 
493  //Successful processing
494  return NO_ERROR;
495 #else
496  //Pre-shared key authentication is not supported
497  return ERROR_NOT_IMPLEMENTED;
498 #endif
499 }
500 
501 
502 /**
503  * @brief Load entity's certificate
504  * @param[in] context Pointer to the IKE context
505  * @param[in] certChain Certificate chain (PEM format). This parameter is
506  * taken as reference
507  * @param[in] certChainLen Length of the certificate chain
508  * @param[in] privateKey Private key (PEM format). This parameter is taken
509  * as reference
510  * @param[in] privateKeyLen Length of the private key
511  * @param[in] password NULL-terminated string containing the password. This
512  * parameter is required if the private key is encrypted
513  * @return Error code
514  **/
515 
516 error_t ikeSetCertificate(IkeContext *context, const char_t *certChain,
517  size_t certChainLen, const char_t *privateKey, size_t privateKeyLen,
518  const char_t *password)
519 {
520 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
521  error_t error;
522  uint8_t *derCert;
523  size_t derCertLen;
524  IkeCertType certType;
525  X509CertInfo *certInfo;
526 
527  //Check parameters
528  if(context == NULL || certChain == NULL || certChainLen == 0)
530 
531  //The private key is optional
532  if(privateKey == NULL && privateKeyLen != 0)
534 
535  //The password if required only for encrypted private keys
536  if(password != NULL && osStrlen(password) > IKE_MAX_PASSWORD_LEN)
537  return ERROR_INVALID_PASSWORD;
538 
539  //The first pass calculates the length of the DER-encoded certificate
540  error = pemImportCertificate(certChain, certChainLen, NULL, &derCertLen,
541  NULL);
542 
543  //Check status code
544  if(!error)
545  {
546  //Allocate a memory buffer to hold the DER-encoded certificate
547  derCert = ikeAllocMem(derCertLen);
548 
549  //Successful memory allocation?
550  if(derCert != NULL)
551  {
552  //The second pass decodes the PEM certificate
553  error = pemImportCertificate(certChain, certChainLen, derCert,
554  &derCertLen, NULL);
555 
556  //Check status code
557  if(!error)
558  {
559  //Allocate a memory buffer to store X.509 certificate info
560  certInfo = ikeAllocMem(sizeof(X509CertInfo));
561 
562  //Successful memory allocation?
563  if(certInfo != NULL)
564  {
566 
567  //Additional certificate parsing options
569  options.ignoreUnknownExtensions = TRUE;
570 
571  //Parse X.509 certificate
572  error = x509ParseCertificateEx(derCert, derCertLen, certInfo,
573  &options);
574 
575  //Check status code
576  if(!error)
577  {
578  //Retrieve certificate type
579  error = ikeGetCertificateType(certInfo, &certType);
580  }
581 
582  //Release previously allocated memory
583  ikeFreeMem(certInfo);
584  }
585  else
586  {
587  //Failed to allocate memory
588  error = ERROR_OUT_OF_MEMORY;
589  }
590  }
591 
592  //Release previously allocated memory
593  ikeFreeMem(derCert);
594  }
595  else
596  {
597  //Failed to allocate memory
598  error = ERROR_OUT_OF_MEMORY;
599  }
600  }
601 
602  //Check status code
603  if(!error)
604  {
605  //Save the certificate chain and the corresponding private key
606  context->certType = certType;
607  context->certChain = certChain;
608  context->certChainLen = certChainLen;
609  context->privateKey = privateKey;
610  context->privateKeyLen = privateKeyLen;
611 
612  //The password if required only for encrypted private keys
613  if(password != NULL)
614  {
615  osStrcpy(context->password, password);
616  }
617  else
618  {
619  osStrcpy(context->password, "");
620  }
621  }
622 
623  //Return status code
624  return error;
625 #else
626  //Certificate authentication is not supported
627  return ERROR_NOT_IMPLEMENTED;
628 #endif
629 }
630 
631 
632 /**
633  * @brief Create a new IKE SA
634  * @param[in] context Pointer to the IKE context
635  * @param[in] remoteIpAddr IP address of the peer
636  * @return Error code
637  **/
638 
639 error_t ikeCreateSa(IkeContext *context, const IpAddr *remoteIpAddr)
640 {
641  uint_t i;
642  IkeSaEntry *sa;
643 
644  //Check parameters
645  if(context == NULL || remoteIpAddr == NULL)
647 
648  //Debug message
649  TRACE_INFO("Creating IKE SA...\r\n");
650 
651  //Loop through IKE SA entries
652  for(i = 0; i < context->numSaEntries; i++)
653  {
654  //Point to the current IKE SA
655  sa = &context->sa[i];
656 
657  //Check whether the current IKE SA matches the peer's IP address
658  if(sa->state != IKE_SA_STATE_CLOSED &&
659  ipCompAddr(&sa->remoteIpAddr, remoteIpAddr))
660  {
661  break;
662  }
663  }
664 
665  //A new IKE SA should only be created if there is no existing entry
666  if(i >= context->numSaEntries)
667  {
668  //Create a new IKE SA
669  sa = ikeCreateSaEntry(context);
670  //Failed to create IKE SA?
671  if(sa == NULL)
672  return ERROR_OUT_OF_RESOURCES;
673 
674  //Initialize IKE SA
675  sa->remoteIpAddr = *remoteIpAddr;
676 
677  //The original initiator always refers to the party who initiated the
678  //exchange (refer to RFC 7296, section 2.2)
679  sa->originalInitiator = TRUE;
680 
681  //Select the preferred key exchange method
682  sa->keContext.groupNum = context->preferredGroupNum;
683 
684  //Request the creation of the IKE SA
686  //Notify the IKE context that the IKE SA should be created
687  osSetEvent(&context->event);
688  }
689 
690  //Successful processing
691  return NO_ERROR;
692 }
693 
694 
695 /**
696  * @brief Rekey an IKE SA
697  * @param[in] sa Pointer to the IKE SA to rekey
698  * @return Error code
699  **/
700 
702 {
703 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
704  IkeContext *context;
705 
706  //Make sure the IKE SA is valid
707  if(sa == NULL)
709 
710  //Debug message
711  TRACE_INFO("Rekeying IKE SA...\r\n");
712 
713  //Check the state of the IKE SA
714  if(sa->state != IKE_SA_STATE_CLOSED)
715  {
716  //Point to the IKE context
717  context = sa->context;
718 
719  //Request rekeying of the IKE SA
720  sa->rekeyRequest = TRUE;
721  //Notify the IKE context that the IKE SA should be rekeyed
722  osSetEvent(&context->event);
723  }
724 
725  //Successful processing
726  return NO_ERROR;
727 #else
728  //Minimal implementations are not required to support the CREATE_CHILD_SA
729  //exchange (refer to RFC 7296, section 4)
730  return ERROR_NOT_IMPLEMENTED;
731 #endif
732 }
733 
734 
735 /**
736  * @brief Delete an IKE SA
737  * @param[in] sa Pointer to the IKE SA to delete
738  * @return Error code
739  **/
740 
742 {
743  IkeContext *context;
744 
745  //Make sure the IKE SA is valid
746  if(sa == NULL)
748 
749  //Debug message
750  TRACE_INFO("Deleting IKE SA...\r\n");
751 
752  //Check the state of the IKE SA
753  if(sa->state != IKE_SA_STATE_CLOSED)
754  {
755  //Point to the IKE context
756  context = sa->context;
757 
758  //Request closure of the IKE SA
759  sa->deleteRequest = TRUE;
760  //Notify the IKE context that the IKE SA should be closed
761  osSetEvent(&context->event);
762  }
763 
764  //Successful processing
765  return NO_ERROR;
766 }
767 
768 
769 /**
770  * @brief Create a new Child SA
771  * @param[in] context Pointer to the IKE context
772  * @param[in] packet Triggering packet
773  * @return Error code
774  **/
775 
777 {
778  error_t error;
779  IpAddr remoteIpAddr;
780  IkeChildSaEntry *childSa;
781  IpsecContext *ipsecContext;
782  IpsecSpdEntry *spdEntry;
783  IpsecSelector selector;
784 
785  //Check parameters
786  if(context == NULL || packet == NULL)
788 
789  //Debug message
790  TRACE_INFO("Creating Child SA...\r\n");
791 
792  //Point to the IPsec context
793  ipsecContext = context->netContext->ipsecContext;
794  //Sanity check
795  if(ipsecContext == NULL)
796  return ERROR_FAILURE;
797 
798  //The selectors are used to define the granularity of the SAs that are
799  //created in response to the triggering packet
800  selector.localIpAddr.start = packet->localIpAddr;
801  selector.localIpAddr.end = packet->localIpAddr;
802  selector.remoteIpAddr.start = packet->remoteIpAddr;
803  selector.remoteIpAddr.end = packet->remoteIpAddr;
804  selector.nextProtocol = packet->nextProtocol;
805  selector.localPort.start = packet->localPort;
806  selector.localPort.end = packet->localPort;
807 
808  //Set selector for the remote port
809  if(packet->nextProtocol == IPV4_PROTOCOL_ICMP)
810  {
813  }
814  else
815  {
816  selector.remotePort.start = packet->remotePort;
817  selector.remotePort.end = packet->remotePort;
818  }
819 
820  //Search the SPD for a matching entry
821  spdEntry = ipsecFindSpdEntry(ipsecContext, IPSEC_POLICY_ACTION_PROTECT,
822  &selector, TRUE);
823 
824  //Every SPD should have a nominal, final entry that matches anything that is
825  //otherwise unmatched, and discards it (refer to RFC 4301, section 4.4.1)
826  if(spdEntry == NULL)
827  return ERROR_NOT_FOUND;
828 
829  //End-to-end security?
830  if(spdEntry->mode == IPSEC_MODE_TRANSPORT)
831  {
832  remoteIpAddr = packet->remoteIpAddr;
833  }
834  else
835  {
836  remoteIpAddr = spdEntry->remoteTunnelAddr;
837  }
838 
839  //For each selector in an SPD entry, the entry specifies how to derive the
840  //corresponding values for a new SAD entry from those in the SPD and the
841  //packet (refer to RFC 4301, section 4.4.1)
842  error = ipsecDeriveSelector(spdEntry, packet, &selector);
843  //Any error to report?
844  if(error)
845  return error;
846 
847  //Create a new Child SA
848  childSa = ikeCreateChildSaEntry(context);
849  //Failed to create Child SA?
850  if(childSa == NULL)
851  return ERROR_OUT_OF_RESOURCES;
852 
853  //Initialize Child SA
854  childSa->remoteIpAddr = remoteIpAddr;
855  childSa->mode = spdEntry->mode;
856  childSa->protocol = spdEntry->protocol;
857 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
858  childSa->pfs = spdEntry->pfs;
859 #endif
860  childSa->initiator = TRUE;
861  childSa->packetInfo = *packet;
862  childSa->selector = selector;
863 
864  //Initialize outbound SAD entry
865  ipsecContext->sad[childSa->outboundSa].direction = IPSEC_DIR_OUTBOUND;
866  ipsecContext->sad[childSa->outboundSa].selector = selector;
867 
868  //Request the creation of the Child SA
870  //Notify the IKE context that the Child SA should be created
871  osSetEvent(&context->event);
872 
873  //Successful processing
874  return NO_ERROR;
875 }
876 
877 
878 /**
879  * @brief Rekey a Child SA
880  * @param[in] childSa Pointer to the Child SA to rekey
881  * @return Error code
882  **/
883 
885 {
886 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
887  IkeContext *context;
888 
889  //Make sure the Child SA is valid
890  if(childSa == NULL)
892 
893  //Debug message
894  TRACE_INFO("Rekeying Child SA...\r\n");
895 
896  //Check the state of the Child SA
897  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED)
898  {
899  //Point to the IKE context
900  context = childSa->context;
901 
902  //Request rekeying of the Child SA
903  childSa->rekeyRequest = TRUE;
904  //Notify the IKE context that the Child SA should be rekeyed
905  osSetEvent(&context->event);
906  }
907 
908  //Successful processing
909  return NO_ERROR;
910 #else
911  //Minimal implementations are not required to support the CREATE_CHILD_SA
912  //exchange (refer to RFC 7296, section 4)
913  return ERROR_NOT_IMPLEMENTED;
914 #endif
915 }
916 
917 
918 /**
919  * @brief Delete a Child SA
920  * @param[in] childSa Pointer to the Child SA to delete
921  * @return Error code
922  **/
923 
925 {
926  IkeContext *context;
927 
928  //Make sure the Child SA is valid
929  if(childSa == NULL)
931 
932  //Debug message
933  TRACE_INFO("Deleting Child SA...\r\n");
934 
935  //Check the state of the Child SA
936  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED)
937  {
938  //Point to the IKE context
939  context = childSa->context;
940 
941  //Request closure of the Child SA
942  childSa->deleteRequest = TRUE;
943  //Notify the IKE context that the Child SA should be closed
944  osSetEvent(&context->event);
945  }
946 
947  //Successful processing
948  return NO_ERROR;
949 }
950 
951 
952 /**
953  * @brief IKE task
954  * @param[in] context Pointer to the IKE context
955  **/
956 
957 void ikeTask(IkeContext *context)
958 {
959  error_t error;
960  uint_t n;
961  Socket *socket;
962  SocketMsg msg;
963  SocketEventDesc eventDesc[2];
964 
965 #if (NET_RTOS_SUPPORT == ENABLED)
966  //Task prologue
967  osEnterTask();
968 
969  //Main loop
970  while(1)
971  {
972 #endif
973  //Number of entries in the descriptor set
974  n = 0;
975 
976  //IKE normally listens on UDP port 500
977  eventDesc[n].socket = context->socket;
978  eventDesc[n].eventMask = SOCKET_EVENT_RX_READY;
979  eventDesc[n++].eventFlags = 0;
980 
981 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
982  //IKE messages may also be received on UDP port 4500 with a slightly
983  //different format (refer to RFC 7296, section 2)
984  eventDesc[n].socket = context->altSocket;
985  eventDesc[n].eventMask = SOCKET_EVENT_RX_READY;
986  eventDesc[n++].eventFlags = 0;
987 #endif
988 
989  //Wait for an event
990  socketPoll(eventDesc, n, &context->event, IKE_TICK_INTERVAL);
991 
992  //Stop request?
993  if(context->stop)
994  {
995  //Stop IKE service
996  context->running = FALSE;
997  //Task epilogue
998  osExitTask();
999  //Kill ourselves
1001  }
1002 
1003 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
1004  //IKE runs over UDP ports 500 and 4500
1005  if(n > 0 && eventDesc[0].eventFlags != 0)
1006  {
1007  socket = context->socket;
1008  }
1009  else if(n > 1 && eventDesc[1].eventFlags != 0)
1010  {
1011  socket = context->altSocket;
1012  }
1013  else
1014  {
1015  socket = NULL;
1016  }
1017 #else
1018  //IKE runs over UDP port 500
1019  if(n > 0 && eventDesc[0].eventFlags != 0)
1020  {
1021  socket = context->socket;
1022  }
1023  else
1024  {
1025  socket = NULL;
1026  }
1027 #endif
1028 
1029  //Any datagram received?
1030  if(socket != NULL)
1031  {
1032  //Point to the receive buffer
1033  msg = SOCKET_DEFAULT_MSG;
1034  msg.data = context->message;
1035  msg.size = IKE_MAX_MSG_SIZE;
1036 
1037  //Receive incoming datagram
1038  error = socketReceiveMsg(socket, &msg, 0);
1039 
1040  //Check status code
1041  if(!error)
1042  {
1043  //Retrieve the length of the datagram
1044  context->messageLen = msg.length;
1045 
1046  //An implementation must accept incoming requests even if the source
1047  //port is not 500 or 4500 (refer to RFC 7296, section 2.11)
1048  context->localInterface = msg.interface;
1049  context->localIpAddr = msg.destIpAddr;
1050  context->localPort = msg.destPort;
1051  context->remoteIpAddr = msg.srcIpAddr;
1052  context->remotePort = msg.srcPort;
1053 
1054  //Process the received IKE message
1055  ikeDispatchMessage(context, context->message, context->messageLen);
1056  }
1057  }
1058 
1059  //Handle IKE events
1060  ikeProcessEvents(context);
1061 
1062 #if (NET_RTOS_SUPPORT == ENABLED)
1063  }
1064 #endif
1065 }
1066 
1067 
1068 /**
1069  * @brief Release IKE context
1070  * @param[in] context Pointer to the IKE context
1071  **/
1072 
1073 void ikeDeinit(IkeContext *context)
1074 {
1075  NetContext *netContext;
1076 
1077  //Make sure the IKE context is valid
1078  if(context != NULL)
1079  {
1080  //Point to the TCP/IP stack context
1081  netContext = context->netContext;
1082 
1083  //Get exclusive access
1084  netLock(netContext);
1085  //Detach the IKE context
1086  netContext->ikeContext = NULL;
1087  //Release exclusive access
1088  netUnlock(netContext);
1089 
1090  //Free previously allocated resources
1091  osDeleteEvent(&context->event);
1092 
1093  //Clear IKE context
1094  osMemset(context, 0, sizeof(IkeContext));
1095  }
1096 }
1097 
1098 #endif
error_t ikeSetPsk(IkeContext *context, const uint8_t *psk, size_t pskLen)
Set entity's pre-shared key.
Definition: ike.c:478
IkeCertType
Certificate types.
Definition: ike.h:1414
OsTaskId osCreateTask(const char_t *name, OsTaskCode taskCode, void *arg, const OsTaskParameters *params)
Create a task.
@ SOCKET_IP_PROTO_UDP
Definition: socket.h:108
X.509 certificate parsing.
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:1341
void netUnlock(NetContext *context)
Release exclusive access to the core of the TCP/IP stack.
Definition: net.c:319
#define IKE_MAX_MSG_SIZE
Definition: ike.h:201
#define NetContext
Definition: net.h:36
@ ERROR_NOT_FOUND
Definition: error.h:148
Helper functions for IKEv2.
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:276
uint16_t end
Definition: ipsec.h:300
error_t ikeSetCertificate(IkeContext *context, const char_t *certChain, size_t certChainLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load entity's certificate.
Definition: ike.c:516
error_t ikeCreateChildSa(IkeContext *context, const IpsecPacketInfo *packet)
Create a new Child SA.
Definition: ike.c:776
#define osExitTask()
error_t ikeRekeySa(IkeSaEntry *sa)
Rekey an IKE SA.
Definition: ike.c:701
IPsec selector.
Definition: ipsec.h:309
IP network address.
Definition: ip.h:94
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define IPSEC_PORT_START_OPAQUE
Definition: ipsec.h:155
#define TRUE
Definition: os_port.h:50
IpAddr remoteIpAddr
Remote IP address.
Definition: ipsec.h:325
Message and ancillary data.
Definition: socket.h:241
#define OS_INVALID_TASK_ID
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:2057
#define IKE_DEFAULT_SA_LIFETIME
Definition: ike.h:68
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
uint_t numChildSaEntries
Number of Child SA entries.
Definition: ike.h:2033
void ikeGetDefaultSettings(IkeSettings *settings)
Initialize settings with default values.
Definition: ike.c:56
error_t ikeDispatchMessage(IkeContext *context, uint8_t *message, size_t length)
Dispatch incoming IKE message.
IpAddr end
Definition: ipsec.h:289
@ SOCKET_TYPE_DGRAM
Definition: socket.h:93
IkeChildSaEntry * ikeCreateChildSaEntry(IkeContext *context)
Create a new Child Security Association.
Definition: ike_misc.c:451
void * data
Pointer to the payload.
Definition: socket.h:242
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t ikeGetCertificateType(const X509CertInfo *certInfo, IkeCertType *certType)
Retrieve the certificate type.
IkeIdType
ID types.
Definition: ike.h:1121
#define osStrlen(s)
Definition: os_port.h:171
IKEv2 finite state machine.
IKE message dispatching.
#define OS_SELF_TASK_ID
Structure describing socket events.
Definition: socket.h:433
@ IKE_SA_STATE_CLOSED
Definition: ike.h:1354
#define IPSEC_NAT_PORT
Definition: ipsec.h:142
@ IPSEC_POLICY_ACTION_PROTECT
Definition: ipsec.h:240
Certificate parsing options.
Definition: x509_common.h:1409
IkeCertVerifyCallback certVerifyCallback
Certificate verification callback function.
Definition: ike.h:2050
@ IPSEC_DIR_OUTBOUND
Definition: ipsec.h:175
@ ERROR_OPEN_FAILED
Definition: error.h:75
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
uint16_t destPort
Destination port.
Definition: socket.h:252
#define IkeContext
Definition: ike.h:832
uint16_t remotePort
Remote port.
Definition: ipsec.h:328
uint_t numSaEntries
Number of IKE SA entries.
Definition: ike.h:2031
const IpAddr IP_ADDR_ANY
Definition: ip.c:53
error_t ikeRekeyChildSa(IkeChildSaEntry *childSa)
Rekey a Child SA.
Definition: ike.c:884
@ ERROR_INVALID_GROUP
Definition: error.h:276
uint16_t ikeSelectDefaultGroup(void)
Get the default key exchange method.
void osDeleteTask(OsTaskId taskId)
Delete a task.
NetInterface * interface
Underlying network interface.
Definition: socket.h:248
#define FALSE
Definition: os_port.h:46
const SocketMsg SOCKET_DEFAULT_MSG
Definition: socket.c:49
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:55
size_t length
Actual length of the payload, in bytes.
Definition: socket.h:244
#define IKE_STACK_SIZE
Definition: ike.h:49
PEM file import functions.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:326
IkeSaEntry * ikeCreateSaEntry(IkeContext *context)
Create a new IKE Security Association.
Definition: ike_misc.c:185
Data logging functions for debugging purpose (IKEv2)
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:312
uint16_t localPort
Local port.
Definition: ipsec.h:327
const X509Options X509_DEFAULT_OPTIONS
Definition: x509_common.c:173
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:212
X.509 certificate.
Definition: x509_common.h:1194
systime_t dpdPeriod
Dead peer detection period.
Definition: ike.h:2040
error_t
Error codes.
Definition: error.h:43
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:318
error_t ikeDeleteChildSa(IkeChildSaEntry *childSa)
Delete a Child SA.
Definition: ike.c:924
void(* OsTaskCode)(void *arg)
Task routine.
error_t x509ParseCertificateEx(const uint8_t *data, size_t length, X509CertInfo *certInfo, const X509Options *options)
Parse a X.509 certificate.
IpsecPortRange remotePort
Remote port range.
Definition: ipsec.h:314
bool_t ikeIsGroupSupported(uint16_t groupNum)
Check whether a given key exchange method is supported.
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:65
error_t ikeStop(IkeContext *context)
Stop IKE service.
Definition: ike.c:368
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
systime_t natKeepaliveInterval
NAT keepalive interval.
Definition: ike.h:2043
NetInterface * interface
Underlying network interface.
Definition: ike.h:2027
Helper routines for IPsec.
@ IKE_SA_STATE_INIT_REQ
Definition: ike.h:1356
const PrngAlgo * prngAlgo
Pseudo-random number generator to be used.
Definition: ike.h:2028
IpsecProtocol protocol
Security protocol (AH or ESP)
Definition: ipsec.h:356
void osDeleteEvent(OsEvent *event)
Delete an event object.
#define IKE_MAX_PASSWORD_LEN
Definition: ike.h:257
IpAddr srcIpAddr
Source IP address.
Definition: socket.h:249
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define IKE_MAX_ID_LEN
Definition: ike.h:243
error_t socketReceiveMsg(Socket *socket, SocketMsg *message, uint_t flags)
Receive a message from a connectionless socket.
Definition: socket.c:1889
NetContext * netGetDefaultContext(void)
Get default TCP/IP stack context.
Definition: net.c:527
const OsTaskParameters OS_TASK_DEFAULT_PARAMS
#define IKE_MAX_PSK_LEN
Definition: ike.h:250
@ IKE_CHILD_SA_STATE_INIT
Definition: ike.h:1386
IkeCookieGenerateCallback cookieGenerateCallback
Cookie generation callback function.
Definition: ike.h:2046
uint8_t idType
Definition: ike.h:1556
error_t ikeDeleteSa(IkeSaEntry *sa)
Delete an IKE SA.
Definition: ike.c:741
void * prngContext
Pseudo-random number generator context.
Definition: ike.h:2029
#define TRACE_INFO(...)
Definition: debug.h:105
bool_t pfs
Perfect forward secrecy.
Definition: ipsec.h:358
IpsecMode mode
IPsec mode (tunnel or transport)
Definition: ipsec.h:355
#define osEnterTask()
uint_t eventFlags
Returned events.
Definition: socket.h:436
IpsecSpdEntry * ipsecFindSpdEntry(IpsecContext *context, IpsecPolicyAction policyAction, const IpsecSelector *selector, bool_t subset)
Search the SPD database for a matching entry.
Definition: ipsec_misc.c:52
void ikeChangeChildSaState(IkeChildSaEntry *childSa, IkeChildSaState newState)
Update Child SA state.
Definition: ike_fsm.c:110
@ IKE_CHILD_SA_STATE_CLOSED
Definition: ike.h:1384
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout)
Wait for one of a set of sockets to become ready to perform I/O.
Definition: socket.c:2145
#define socketBindToInterface
Definition: net_legacy.h:193
NetContext * netContext
TCP/IP stack context.
Definition: ike.h:2026
IpAddr start
Definition: ipsec.h:288
uint16_t start
Definition: ipsec.h:299
IKEv2 (Internet Key Exchange Protocol)
#define IKE_TICK_INTERVAL
Definition: ike.h:61
IpAddr destIpAddr
Destination IP address.
Definition: socket.h:251
error_t ikeSetPreferredGroup(IkeContext *context, uint16_t groupNum)
Specify the preferred key exchange method.
Definition: ike.c:422
char char_t
Definition: compiler_port.h:55
#define IKE_PRIORITY
Definition: ike.h:56
#define IPSEC_PORT_END_OPAQUE
Definition: ipsec.h:156
IKE settings.
Definition: ike.h:2024
#define IkeSaEntry
Definition: ike.h:836
@ SOCKET_EVENT_RX_READY
Definition: socket.h:179
systime_t childSaLifetime
Lifetime of Child SAs.
Definition: ike.h:2035
uint8_t n
#define IKE_PORT
Definition: ike.h:813
#define ikeFreeMem(p)
Definition: ike.h:759
IkeChildSaEntry * childSaEntries
Child SA entries.
Definition: ike.h:2032
IP packet information.
Definition: ipsec.h:323
Socket * socketOpenEx(NetContext *context, uint_t type, uint_t protocol)
Create a socket.
Definition: socket.c:143
IpsecAddrRange localIpAddr
Local IP address range.
Definition: ipsec.h:310
OsTaskParameters task
Task parameters.
Definition: ike.h:2025
void ikeDeinit(IkeContext *context)
Release IKE context.
Definition: ike.c:1073
IpAddr localIpAddr
Local IP address.
Definition: ipsec.h:324
#define Socket
Definition: socket.h:36
IpAddr remoteTunnelAddr
Remote tunnel IP address.
Definition: ipsec.h:360
error_t ikeInit(IkeContext *context, const IkeSettings *settings)
IKE service initialization.
Definition: ike.c:121
bool_t osCreateEvent(OsEvent *event)
Create an event object.
error_t ikeSetId(IkeContext *context, IkeIdType idType, const void *id, size_t idLen)
Set entity's ID.
Definition: ike.c:449
X.509 certificate handling.
systime_t saLifetime
Lifetime of IKE SAs.
Definition: ike.h:2034
#define IpsecContext
Definition: ipsec.h:40
#define IKE_DEFAULT_NAT_KEEPALIVE_INTERVAL
Definition: ike.h:152
size_t size
Size of the payload, in bytes.
Definition: socket.h:243
IkeCookieVerifyCallback cookieVerifyCallback
Cookie verification callback function.
Definition: ike.h:2047
uint8_t options[]
Definition: tcp.h:364
systime_t reauthPeriod
Reauthentication period.
Definition: ike.h:2037
void netLock(NetContext *context)
Get exclusive access to the core of the TCP/IP stack.
Definition: net.c:307
void osDelayTask(systime_t delay)
Delay routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
@ ERROR_INVALID_PASSWORD
Definition: error.h:281
void ikeTask(IkeContext *context)
IKE task.
Definition: ike.c:957
void ikeProcessEvents(IkeContext *context)
IKE event processing.
Definition: ike_fsm.c:131
error_t ipsecDeriveSelector(const IpsecSpdEntry *spdEntry, const IpsecPacketInfo *packet, IpsecSelector *selector)
Derive SAD selector from SPD entry and triggering packet.
Definition: ipsec_misc.c:946
error_t ikeStart(IkeContext *context)
Start IKE service.
Definition: ike.c:247
Security Policy Database (SPD) entry.
Definition: ipsec.h:351
Socket * socket
Handle to a socket to monitor.
Definition: socket.h:434
unsigned int uint_t
Definition: compiler_port.h:57
#define osMemset(p, value, length)
Definition: os_port.h:141
IkeSaEntry * saEntries
IKE SA entries.
Definition: ike.h:2030
error_t ikeCreateSa(IkeContext *context, const IpAddr *remoteIpAddr)
Create a new IKE SA.
Definition: ike.c:639
#define osStrcpy(s1, s2)
Definition: os_port.h:213
uint16_t srcPort
Source port.
Definition: socket.h:250
#define IkeChildSaEntry
Definition: ike.h:840
IpsecPortRange localPort
Local port range.
Definition: ipsec.h:313
uint_t eventMask
Requested events.
Definition: socket.h:435
IKEv2 algorithm negotiation.
IpsecAddrRange remoteIpAddr
Remote IP address range.
Definition: ipsec.h:311
@ ERROR_ALREADY_RUNNING
Definition: error.h:294
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define ikeAllocMem(size)
Definition: ike.h:754
#define IKE_DEFAULT_CHILD_SA_LIFETIME
Definition: ike.h:75