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