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.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_certificate.h"
40 #include "ike/ike_message_parse.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  //Reauthentication period
85  settings->reauthPeriod = 0;
86 
87 #if (IKE_DPD_SUPPORT == ENABLED)
88  //Dead peer detection period
89  settings->dpdPeriod = 0;
90 #endif
91 #if (IKE_COOKIE_SUPPORT == ENABLED)
92  //Cookie generation callback function
93  settings->cookieGenerateCallback = NULL;
94  //Cookie verification callback function
95  settings->cookieVerifyCallback = NULL;
96 #endif
97 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
98  //Certificate verification callback function
99  settings->certVerifyCallback = NULL;
100 #endif
101 }
102 
103 
104 /**
105  * @brief IKE service initialization
106  * @param[in] context Pointer to the IKE context
107  * @param[in] settings IKE specific settings
108  * @return Error code
109  **/
110 
111 error_t ikeInit(IkeContext *context, const IkeSettings *settings)
112 {
113  error_t error;
114 
115  //Debug message
116  TRACE_INFO("Initializing IKE...\r\n");
117 
118  //Ensure the parameters are valid
119  if(context == NULL || settings == NULL)
121 
122  if(settings->prngAlgo == NULL || settings->prngContext == NULL)
124 
125  if(settings->saEntries == NULL || settings->numSaEntries == 0)
127 
128  if(settings->childSaEntries == NULL || settings->numChildSaEntries == 0)
130 
131  //Clear the IKE context
132  osMemset(context, 0, sizeof(IkeContext));
133 
134  //Initialize task parameters
135  context->taskParams = settings->task;
136  context->taskId = OS_INVALID_TASK_ID;
137 
138  //Attach TCP/IP stack context
139  if(settings->netContext != NULL)
140  {
141  context->netContext = settings->netContext;
142  }
143  else if(settings->interface != NULL)
144  {
145  context->netContext = settings->interface->netContext;
146  }
147  else
148  {
149  context->netContext = netGetDefaultContext();
150  }
151 
152  //Underlying network interface
153  context->interface = settings->interface;
154 
155  //Pseudo-random number generator
156  context->prngAlgo = settings->prngAlgo;
157  context->prngContext = settings->prngContext;
158 
159  //IKE SA entries
160  context->sa = settings->saEntries;
161  context->numSaEntries = settings->numSaEntries;
162 
163  //Child SA entries
164  context->childSa = settings->childSaEntries;
165  context->numChildSaEntries = settings->numChildSaEntries;
166 
167  //Lifetime of IKE SAs
168  context->saLifetime = settings->saLifetime;
169  //Lifetime of Child SAs
170  context->childSaLifetime = settings->childSaLifetime;
171  //Reauthentication period
172  context->reauthPeriod = settings->reauthPeriod;
173 
174 #if (IKE_DPD_SUPPORT == ENABLED)
175  //Dead peer detection period
176  context->dpdPeriod = settings->dpdPeriod;
177 #endif
178 #if (IKE_COOKIE_SUPPORT == ENABLED)
179  //Cookie generation callback function
180  context->cookieGenerateCallback = settings->cookieGenerateCallback;
181  //Cookie verification callback function
182  context->cookieVerifyCallback = settings->cookieVerifyCallback;
183 #endif
184 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
185  //Certificate verification callback function
186  context->certVerifyCallback = settings->certVerifyCallback;
187 #endif
188 
189  //Save the preferred key exchange method
190  context->preferredGroupNum = ikeSelectDefaultGroup();
191 
192  //Get exclusive access
193  netLock(context->netContext);
194  //Attach IKE context
195  context->netContext->ikeContext = context;
196  //Release exclusive access
197  netUnlock(context->netContext);
198 
199  //Initialize status code
200  error = NO_ERROR;
201 
202  //Create an event object to poll the state of the UDP socket
203  if(!osCreateEvent(&context->event))
204  {
205  //Failed to create event
206  error = ERROR_OUT_OF_RESOURCES;
207  }
208 
209  //Check status code
210  if(error)
211  {
212  //Clean up side effects
213  ikeDeinit(context);
214  }
215 
216  //Return status code
217  return error;
218 }
219 
220 
221 /**
222  * @brief Start IKE service
223  * @param[in] context Pointer to the IKE context
224  * @return Error code
225  **/
226 
228 {
229  error_t error;
230 
231  //Make sure the IKE context is valid
232  if(context == NULL)
234 
235  //Debug message
236  TRACE_INFO("Starting IKE...\r\n");
237 
238  //Make sure the IKE service is not already running
239  if(context->running)
240  return ERROR_ALREADY_RUNNING;
241 
242  //Start of exception handling block
243  do
244  {
245  //Open a UDP socket
246  context->socket = socketOpenEx(context->netContext, SOCKET_TYPE_DGRAM,
248  //Failed to open socket?
249  if(context->socket == NULL)
250  {
251  //Report an error
252  error = ERROR_OPEN_FAILED;
253  break;
254  }
255 
256  //Associate the socket with the relevant interface
257  error = socketBindToInterface(context->socket, context->interface);
258  //Unable to bind the socket to the desired interface?
259  if(error)
260  break;
261 
262  //IKE normally listens and sends on UDP port 500 (refer to RFC 7296,
263  //section 2);
264  error = socketBind(context->socket, &IP_ADDR_ANY, IKE_PORT);
265  //Unable to bind the socket to the desired port?
266  if(error)
267  break;
268 
269  //Start the IKE service
270  context->stop = FALSE;
271  context->running = TRUE;
272 
273  //Create a task
274  context->taskId = osCreateTask("IKE", (OsTaskCode) ikeTask, context,
275  &context->taskParams);
276 
277  //Failed to create task?
278  if(context->taskId == OS_INVALID_TASK_ID)
279  {
280  //Report an error
281  error = ERROR_OUT_OF_RESOURCES;
282  break;
283  }
284 
285  //End of exception handling block
286  } while(0);
287 
288  //Any error to report?
289  if(error)
290  {
291  //Clean up side effects
292  context->running = FALSE;
293 
294  //Close the UDP socket
295  socketClose(context->socket);
296  context->socket = NULL;
297  }
298 
299  //Return status code
300  return error;
301 }
302 
303 
304 /**
305  * @brief Stop IKE service
306  * @param[in] context Pointer to the IKE context
307  * @return Error code
308  **/
309 
311 {
312  //Make sure the IKE context is valid
313  if(context == NULL)
315 
316  //Debug message
317  TRACE_INFO("Stopping IKE...\r\n");
318 
319  //Check whether the IKE service is running
320  if(context->running)
321  {
322 #if (NET_RTOS_SUPPORT == ENABLED)
323  //Stop the IKE service
324  context->stop = TRUE;
325  //Send a signal to the task to abort any blocking operation
326  osSetEvent(&context->event);
327 
328  //Wait for the task to terminate
329  while(context->running)
330  {
331  osDelayTask(1);
332  }
333 #endif
334 
335  //Close the UDP socket
336  socketClose(context->socket);
337  context->socket = NULL;
338  }
339 
340  //Successful processing
341  return NO_ERROR;
342 }
343 
344 
345 /**
346  * @brief Specify the preferred key exchange method
347  * @param[in] context Pointer to the IKE context
348  * @param[in] groupNum Preferred group number
349  * @return Error code
350  **/
351 
352 error_t ikeSetPreferredGroup(IkeContext *context, uint16_t groupNum)
353 {
354  //Make sure the IKE context is valid
355  if(context == NULL)
357 
358  //Ensure the specified key exchange method is supported
359  if(!ikeIsGroupSupported(groupNum))
360  return ERROR_INVALID_GROUP;
361 
362  //Save the preferred key exchange method
363  context->preferredGroupNum = groupNum;
364 
365  //Successful processing
366  return NO_ERROR;
367 }
368 
369 
370 /**
371  * @brief Set entity's ID
372  * @param[in] context Pointer to the IKE context
373  * @param[in] idType ID type
374  * @param[in] id Pointer to the identification data
375  * @param[in] idLen Length of the identification data, in bytes
376  * @return Error code
377  **/
378 
379 error_t ikeSetId(IkeContext *context, IkeIdType idType, const void *id,
380  size_t idLen)
381 {
382  //Check parameters
383  if(context == NULL || id == NULL)
385 
386  //Check the length of the identification data
387  if(idLen > IKE_MAX_ID_LEN)
388  return ERROR_INVALID_LENGTH;
389 
390  //Save identification data
391  context->idType = idType;
392  osMemcpy(context->id, id, idLen);
393  context->idLen = idLen;
394 
395  //Successful processing
396  return NO_ERROR;
397 }
398 
399 
400 /**
401  * @brief Set entity's pre-shared key
402  * @param[in] context Pointer to the IKE context
403  * @param[in] psk Pointer to the pre-shared key
404  * @param[in] pskLen Length of the pre-shared key, in bytes
405  * @return Error code
406  **/
407 
408 error_t ikeSetPsk(IkeContext *context, const uint8_t *psk, size_t pskLen)
409 {
410 #if (IKE_PSK_AUTH_SUPPORT == ENABLED)
411  //Check parameters
412  if(context == NULL || psk == NULL)
414 
415  //Check the length of the pre-shared key
416  if(pskLen > IKE_MAX_PSK_LEN)
417  return ERROR_INVALID_LENGTH;
418 
419  //Save pre-shared key
420  osMemcpy(context->psk, psk, pskLen);
421  context->pskLen = pskLen;
422 
423  //Successful processing
424  return NO_ERROR;
425 #else
426  //Pre-shared key authentication is not supported
427  return ERROR_NOT_IMPLEMENTED;
428 #endif
429 }
430 
431 
432 /**
433  * @brief Load entity's certificate
434  * @param[in] context Pointer to the IKE context
435  * @param[in] certChain Certificate chain (PEM format). This parameter is
436  * taken as reference
437  * @param[in] certChainLen Length of the certificate chain
438  * @param[in] privateKey Private key (PEM format). This parameter is taken
439  * as reference
440  * @param[in] privateKeyLen Length of the private key
441  * @param[in] password NULL-terminated string containing the password. This
442  * parameter is required if the private key is encrypted
443  * @return Error code
444  **/
445 
446 error_t ikeSetCertificate(IkeContext *context, const char_t *certChain,
447  size_t certChainLen, const char_t *privateKey, size_t privateKeyLen,
448  const char_t *password)
449 {
450 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
451  error_t error;
452  uint8_t *derCert;
453  size_t derCertLen;
454  IkeCertType certType;
455  X509CertInfo *certInfo;
456 
457  //Check parameters
458  if(context == NULL || certChain == NULL || certChainLen == 0)
460 
461  //The private key is optional
462  if(privateKey == NULL && privateKeyLen != 0)
464 
465  //The password if required only for encrypted private keys
466  if(password != NULL && osStrlen(password) > IKE_MAX_PASSWORD_LEN)
467  return ERROR_INVALID_PASSWORD;
468 
469  //The first pass calculates the length of the DER-encoded certificate
470  error = pemImportCertificate(certChain, certChainLen, NULL, &derCertLen,
471  NULL);
472 
473  //Check status code
474  if(!error)
475  {
476  //Allocate a memory buffer to hold the DER-encoded certificate
477  derCert = ikeAllocMem(derCertLen);
478 
479  //Successful memory allocation?
480  if(derCert != NULL)
481  {
482  //The second pass decodes the PEM certificate
483  error = pemImportCertificate(certChain, certChainLen, derCert,
484  &derCertLen, NULL);
485 
486  //Check status code
487  if(!error)
488  {
489  //Allocate a memory buffer to store X.509 certificate info
490  certInfo = ikeAllocMem(sizeof(X509CertInfo));
491 
492  //Successful memory allocation?
493  if(certInfo != NULL)
494  {
496 
497  //Additional certificate parsing options
499  options.ignoreUnknownExtensions = TRUE;
500 
501  //Parse X.509 certificate
502  error = x509ParseCertificateEx(derCert, derCertLen, certInfo,
503  &options);
504 
505  //Check status code
506  if(!error)
507  {
508  //Retrieve certificate type
509  error = ikeGetCertificateType(certInfo, &certType);
510  }
511 
512  //Release previously allocated memory
513  ikeFreeMem(certInfo);
514  }
515  else
516  {
517  //Failed to allocate memory
518  error = ERROR_OUT_OF_MEMORY;
519  }
520  }
521 
522  //Release previously allocated memory
523  ikeFreeMem(derCert);
524  }
525  else
526  {
527  //Failed to allocate memory
528  error = ERROR_OUT_OF_MEMORY;
529  }
530  }
531 
532  //Check status code
533  if(!error)
534  {
535  //Save the certificate chain and the corresponding private key
536  context->certType = certType;
537  context->certChain = certChain;
538  context->certChainLen = certChainLen;
539  context->privateKey = privateKey;
540  context->privateKeyLen = privateKeyLen;
541 
542  //The password if required only for encrypted private keys
543  if(password != NULL)
544  {
545  osStrcpy(context->password, password);
546  }
547  else
548  {
549  osStrcpy(context->password, "");
550  }
551  }
552 
553  //Return status code
554  return error;
555 #else
556  //Certificate authentication is not supported
557  return ERROR_NOT_IMPLEMENTED;
558 #endif
559 }
560 
561 
562 /**
563  * @brief Delete an IKE SA
564  * @param[in] sa Pointer to the IKE SA to delete
565  * @return Error code
566  **/
567 
569 {
570  IkeContext *context;
571 
572  //Make sure the IKE SA is valid
573  if(sa == NULL)
575 
576  //Debug message
577  TRACE_INFO("Deleting IKE SA...\r\n");
578 
579  //Check the state of the IKE SA
580  if(sa->state != IKE_SA_STATE_CLOSED)
581  {
582  //Point to the IKE context
583  context = sa->context;
584 
585  //Request closure of the IKE SA
586  sa->deleteRequest = TRUE;
587  //Notify the IKE context that the IKE SA should be closed
588  osSetEvent(&context->event);
589  }
590 
591  //Successful processing
592  return NO_ERROR;
593 }
594 
595 
596 /**
597  * @brief Create a new Child SA
598  * @param[in] context Pointer to the IKE context
599  * @param[in] packet Triggering packet
600  * @return Error code
601  **/
602 
604 {
605  error_t error;
606  IpAddr remoteIpAddr;
607  IkeChildSaEntry *childSa;
608  IpsecContext *ipsecContext;
609  IpsecSpdEntry *spdEntry;
610  IpsecSelector selector;
611 
612  //Check parameters
613  if(context == NULL || packet == NULL)
615 
616  //Debug message
617  TRACE_INFO("Creating Child SA...\r\n");
618 
619  //Point to the IPsec context
620  ipsecContext = context->netContext->ipsecContext;
621  //Sanity check
622  if(ipsecContext == NULL)
623  return ERROR_FAILURE;
624 
625  //The selectors are used to define the granularity of the SAs that are
626  //created in response to the triggering packet
627  selector.localIpAddr.start = packet->localIpAddr;
628  selector.localIpAddr.end = packet->localIpAddr;
629  selector.remoteIpAddr.start = packet->remoteIpAddr;
630  selector.remoteIpAddr.end = packet->remoteIpAddr;
631  selector.nextProtocol = packet->nextProtocol;
632  selector.localPort.start = packet->localPort;
633  selector.localPort.end = packet->localPort;
634 
635  //Set selector for the remote port
636  if(packet->nextProtocol == IPV4_PROTOCOL_ICMP)
637  {
640  }
641  else
642  {
643  selector.remotePort.start = packet->remotePort;
644  selector.remotePort.end = packet->remotePort;
645  }
646 
647  //Search the SPD for a matching entry
648  spdEntry = ipsecFindSpdEntry(ipsecContext, IPSEC_POLICY_ACTION_PROTECT,
649  &selector);
650 
651  //Every SPD should have a nominal, final entry that matches anything that is
652  //otherwise unmatched, and discards it (refer to RFC 4301, section 4.4.1)
653  if(spdEntry == NULL)
654  return ERROR_NOT_FOUND;
655 
656  //End-to-end security?
657  if(spdEntry->mode == IPSEC_MODE_TRANSPORT)
658  {
659  remoteIpAddr = packet->remoteIpAddr;
660  }
661  else
662  {
663  remoteIpAddr = spdEntry->remoteTunnelAddr;
664  }
665 
666  //For each selector in an SPD entry, the entry specifies how to derive the
667  //corresponding values for a new SAD entry from those in the SPD and the
668  //packet (refer to RFC 4301, section 4.4.1)
669  error = ipsecDeriveSelector(spdEntry, packet, &selector);
670  //Any error to report?
671  if(error)
672  return error;
673 
674  //Create a new Child SA
675  childSa = ikeCreateChildSaEntry(context);
676  //Failed to create Child SA?
677  if(childSa == NULL)
678  return ERROR_OUT_OF_RESOURCES;
679 
680  //Initialize Child SA
681  childSa->remoteIpAddr = remoteIpAddr;
682  childSa->mode = spdEntry->mode;
683  childSa->protocol = spdEntry->protocol;
684  childSa->initiator = TRUE;
685  childSa->packetInfo = *packet;
686  childSa->selector = selector;
687 
688  //Initialize outbound SAD entry
689  ipsecContext->sad[childSa->outboundSa].direction = IPSEC_DIR_OUTBOUND;
690  ipsecContext->sad[childSa->outboundSa].selector = selector;
691 
692  //Request the creation of the Child SA
694  //Notify the IKE context that the Child SA should be created
695  osSetEvent(&context->event);
696 
697  //Successful processing
698  return NO_ERROR;
699 }
700 
701 
702 
703 
704 /**
705  * @brief Delete a Child SA
706  * @param[in] childSa Pointer to the Child SA to delete
707  * @return Error code
708  **/
709 
711 {
712  IkeContext *context;
713 
714  //Make sure the Child SA is valid
715  if(childSa == NULL)
717 
718  //Debug message
719  TRACE_INFO("Deleting Child SA...\r\n");
720 
721  //Check the state of the Child SA
722  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED)
723  {
724  //Point to the IKE context
725  context = childSa->context;
726 
727  //Request closure of the Child SA
728  childSa->deleteRequest = TRUE;
729  //Notify the IKE context that the Child SA should be closed
730  osSetEvent(&context->event);
731  }
732 
733  //Successful processing
734  return NO_ERROR;
735 }
736 
737 
738 /**
739  * @brief IKE task
740  * @param[in] context Pointer to the IKE context
741  **/
742 
743 void ikeTask(IkeContext *context)
744 {
745  error_t error;
746  SocketEventDesc eventDesc;
747 
748 #if (NET_RTOS_SUPPORT == ENABLED)
749  //Task prologue
750  osEnterTask();
751 
752  //Main loop
753  while(1)
754  {
755 #endif
756  //Specify the events the application is interested in
757  eventDesc.socket = context->socket;
758  eventDesc.eventMask = SOCKET_EVENT_RX_READY;
759  eventDesc.eventFlags = 0;
760 
761  //Wait for an event
762  socketPoll(&eventDesc, 1, &context->event, IKE_TICK_INTERVAL);
763 
764  //Stop request?
765  if(context->stop)
766  {
767  //Stop IKE service
768  context->running = FALSE;
769  //Task epilogue
770  osExitTask();
771  //Kill ourselves
773  }
774 
775  //Any datagram received?
776  if(eventDesc.eventFlags != 0)
777  {
778  //An implementation must accept incoming requests even if the source
779  //port is not 500 or 4500 (refer to RFC 7296, section 2.11)
780  error = socketReceiveEx(context->socket, &context->remoteIpAddr,
781  &context->remotePort, &context->localIpAddr, context->message,
782  IKE_MAX_MSG_SIZE, &context->messageLen, 0);
783 
784  //Check status code
785  if(!error)
786  {
787  //Process the received IKE message
788  ikeProcessMessage(context, context->message, context->messageLen);
789  }
790  }
791 
792  //Handle IKE events
793  ikeProcessEvents(context);
794 
795 #if (NET_RTOS_SUPPORT == ENABLED)
796  }
797 #endif
798 }
799 
800 
801 /**
802  * @brief Release IKE context
803  * @param[in] context Pointer to the IKE context
804  **/
805 
806 void ikeDeinit(IkeContext *context)
807 {
808  NetContext *netContext;
809 
810  //Make sure the IKE context is valid
811  if(context != NULL)
812  {
813  //Point to the TCP/IP stack context
814  netContext = context->netContext;
815 
816  //Get exclusive access
817  netLock(netContext);
818  //Detach the IKE context
819  netContext->ikeContext = NULL;
820  //Release exclusive access
821  netUnlock(netContext);
822 
823  //Free previously allocated resources
824  osDeleteEvent(&context->event);
825 
826  //Clear IKE context
827  osMemset(context, 0, sizeof(IkeContext));
828  }
829 }
830 
831 #endif
error_t ikeSetPsk(IkeContext *context, const uint8_t *psk, size_t pskLen)
Set entity's pre-shared key.
Definition: ike.c:408
IkeCertType
Certificate types.
Definition: ike.h:1378
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:1344
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:166
#define NetContext
Definition: net.h:36
@ ERROR_NOT_FOUND
Definition: error.h:148
Helper functions for IKEv2.
@ IPV4_PROTOCOL_ICMP
Definition: ipv4.h:275
uint16_t end
Definition: ipsec.h:297
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:446
error_t ikeCreateChildSa(IkeContext *context, const IpsecPacketInfo *packet)
Create a new Child SA.
Definition: ike.c:603
#define osExitTask()
IPsec selector.
Definition: ipsec.h:306
IP network address.
Definition: ip.h:90
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define IPSEC_PORT_START_OPAQUE
Definition: ipsec.h:152
#define TRUE
Definition: os_port.h:50
IpAddr remoteIpAddr
Remote IP address.
Definition: ipsec.h:322
#define OS_INVALID_TASK_ID
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:2094
#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:1956
void ikeGetDefaultSettings(IkeSettings *settings)
Initialize settings with default values.
Definition: ike.c:56
IpAddr end
Definition: ipsec.h:286
@ SOCKET_TYPE_DGRAM
Definition: socket.h:93
IkeChildSaEntry * ikeCreateChildSaEntry(IkeContext *context)
Create a new Child Security Association.
Definition: ike_misc.c:396
@ 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:1085
#define osStrlen(s)
Definition: os_port.h:168
IKEv2 finite state machine.
#define OS_SELF_TASK_ID
Structure describing socket events.
Definition: socket.h:433
@ IKE_SA_STATE_CLOSED
Definition: ike.h:1318
@ IPSEC_POLICY_ACTION_PROTECT
Definition: ipsec.h:237
Certificate parsing options.
Definition: x509_common.h:1336
IkeCertVerifyCallback certVerifyCallback
Certificate verification callback function.
Definition: ike.h:1968
@ IPSEC_DIR_OUTBOUND
Definition: ipsec.h:172
@ ERROR_OPEN_FAILED
Definition: error.h:75
#define IkeContext
Definition: ike.h:796
uint16_t remotePort
Remote port.
Definition: ipsec.h:325
uint_t numSaEntries
Number of IKE SA entries.
Definition: ike.h:1954
const IpAddr IP_ADDR_ANY
Definition: ip.c:53
@ ERROR_INVALID_GROUP
Definition: error.h:276
uint16_t ikeSelectDefaultGroup(void)
Get the default key exchange method.
void osDeleteTask(OsTaskId taskId)
Delete a task.
#define FALSE
Definition: os_port.h:46
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
#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:144
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:323
Data logging functions for debugging purpose (IKEv2)
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:309
uint16_t localPort
Local port.
Definition: ipsec.h:324
const X509Options X509_DEFAULT_OPTIONS
Definition: x509_common.c:173
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:209
X.509 certificate.
Definition: x509_common.h:1121
systime_t dpdPeriod
Dead peer detection period.
Definition: ike.h:1961
error_t
Error codes.
Definition: error.h:43
error_t ikeDeleteChildSa(IkeChildSaEntry *childSa)
Delete a Child SA.
Definition: ike.c:710
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:311
bool_t ikeIsGroupSupported(uint16_t groupNum)
Check whether a given key exchange method is supported.
error_t ikeStop(IkeContext *context)
Stop IKE service.
Definition: ike.c:310
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
NetInterface * interface
Underlying network interface.
Definition: ike.h:1950
Helper routines for IPsec.
const PrngAlgo * prngAlgo
Pseudo-random number generator to be used.
Definition: ike.h:1951
IpsecProtocol protocol
Security protocol (AH or ESP)
Definition: ipsec.h:353
void osDeleteEvent(OsEvent *event)
Delete an event object.
#define IKE_MAX_PASSWORD_LEN
Definition: ike.h:222
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define IKE_MAX_ID_LEN
Definition: ike.h:208
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:215
@ IKE_CHILD_SA_STATE_INIT
Definition: ike.h:1350
IkeCookieGenerateCallback cookieGenerateCallback
Cookie generation callback function.
Definition: ike.h:1964
uint8_t idType
Definition: ike.h:1520
error_t ikeDeleteSa(IkeSaEntry *sa)
Delete an IKE SA.
Definition: ike.c:568
void * prngContext
Pseudo-random number generator context.
Definition: ike.h:1952
IKE message parsing.
#define TRACE_INFO(...)
Definition: debug.h:105
IpsecMode mode
IPsec mode (tunnel or transport)
Definition: ipsec.h:352
#define osEnterTask()
uint_t eventFlags
Returned events.
Definition: socket.h:436
void ikeChangeChildSaState(IkeChildSaEntry *childSa, IkeChildSaState newState)
Update Child SA state.
Definition: ike_fsm.c:108
@ IKE_CHILD_SA_STATE_CLOSED
Definition: ike.h:1348
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:2182
#define socketBindToInterface
Definition: net_legacy.h:193
NetContext * netContext
TCP/IP stack context.
Definition: ike.h:1949
IpAddr start
Definition: ipsec.h:285
IpsecSpdEntry * ipsecFindSpdEntry(IpsecContext *context, IpsecPolicyAction policyAction, const IpsecSelector *selector)
Search the SPD database for a matching entry.
Definition: ipsec_misc.c:51
uint16_t start
Definition: ipsec.h:296
IKEv2 (Internet Key Exchange Protocol)
#define IKE_TICK_INTERVAL
Definition: ike.h:61
error_t ikeSetPreferredGroup(IkeContext *context, uint16_t groupNum)
Specify the preferred key exchange method.
Definition: ike.c:352
char char_t
Definition: compiler_port.h:55
#define IKE_PRIORITY
Definition: ike.h:56
#define IPSEC_PORT_END_OPAQUE
Definition: ipsec.h:153
IKE settings.
Definition: ike.h:1947
#define IkeSaEntry
Definition: ike.h:800
@ SOCKET_EVENT_RX_READY
Definition: socket.h:179
systime_t childSaLifetime
Lifetime of Child SAs.
Definition: ike.h:1958
#define IKE_PORT
Definition: ike.h:785
#define ikeFreeMem(p)
Definition: ike.h:731
IkeChildSaEntry * childSaEntries
Child SA entries.
Definition: ike.h:1955
IP packet information.
Definition: ipsec.h:320
Socket * socketOpenEx(NetContext *context, uint_t type, uint_t protocol)
Create a socket.
Definition: socket.c:146
IpsecAddrRange localIpAddr
Local IP address range.
Definition: ipsec.h:307
OsTaskParameters task
Task parameters.
Definition: ike.h:1948
void ikeDeinit(IkeContext *context)
Release IKE context.
Definition: ike.c:806
IpAddr localIpAddr
Local IP address.
Definition: ipsec.h:321
IpAddr remoteTunnelAddr
Remote tunnel IP address.
Definition: ipsec.h:356
error_t ikeInit(IkeContext *context, const IkeSettings *settings)
IKE service initialization.
Definition: ike.c:111
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:379
X.509 certificate handling.
systime_t saLifetime
Lifetime of IKE SAs.
Definition: ike.h:1957
#define IpsecContext
Definition: ipsec.h:40
IkeCookieVerifyCallback cookieVerifyCallback
Cookie verification callback function.
Definition: ike.h:1965
uint8_t options[]
Definition: tcp.h:364
systime_t reauthPeriod
Reauthentication period.
Definition: ike.h:1959
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:743
error_t socketReceiveEx(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram.
Definition: socket.c:1768
void ikeProcessEvents(IkeContext *context)
IKE event processing.
Definition: ike_fsm.c:129
error_t ipsecDeriveSelector(const IpsecSpdEntry *spdEntry, const IpsecPacketInfo *packet, IpsecSelector *selector)
Derive SAD selector from SPD entry and triggering packet.
Definition: ipsec_misc.c:802
error_t ikeStart(IkeContext *context)
Start IKE service.
Definition: ike.c:227
Security Policy Database (SPD) entry.
Definition: ipsec.h:348
Socket * socket
Handle to a socket to monitor.
Definition: socket.h:434
#define osMemset(p, value, length)
Definition: os_port.h:138
IkeSaEntry * saEntries
IKE SA entries.
Definition: ike.h:1953
#define osStrcpy(s1, s2)
Definition: os_port.h:210
#define IkeChildSaEntry
Definition: ike.h:804
error_t ikeProcessMessage(IkeContext *context, uint8_t *message, size_t length)
Process incoming IKE message.
IpsecPortRange localPort
Local port range.
Definition: ipsec.h:310
uint_t eventMask
Requested events.
Definition: socket.h:435
IKEv2 algorithm negotiation.
IpsecAddrRange remoteIpAddr
Remote IP address range.
Definition: ipsec.h:308
@ ERROR_ALREADY_RUNNING
Definition: error.h:294
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define ikeAllocMem(size)
Definition: ike.h:726
#define IKE_DEFAULT_CHILD_SA_LIFETIME
Definition: ike.h:75