ike_fsm.c
Go to the documentation of this file.
1 /**
2  * @file ike_fsm.c
3  * @brief IKEv2 finite state machine
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_key_exchange.h"
39 #include "ike/ike_request_format.h"
40 #include "ike/ike_misc.h"
41 #include "debug.h"
42 
43 //Check IKEv2 library configuration
44 #if (IKE_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Update IKE SA state
49  * @param[in] sa Pointer to the IKE SA
50  * @param[in] newState New IKE SA state to switch to
51  **/
52 
54 {
55  IkeContext *context;
56 
57  //Point to the IKE context
58  context = sa->context;
59 
60  //Successful IKE SA creation?
61  if(sa->state < IKE_SA_STATE_OPEN &&
62  newState == IKE_SA_STATE_OPEN)
63  {
64  //IKE SA uses secret keys that should be used only for a limited amount
65  //of time (refer to RFC 7296, section 2.8)
66  sa->lifetimeStart = osGetSystemTime();
67 
68  //If the two ends have the same lifetime policies, it is possible that
69  //both will initiate a rekeying at the same time. To reduce the
70  //probability of this happening, the timing of rekeying requests should
71  //be jittered (refer to RFC 7296, section 2.8.1)
72  sa->lifetime = ikeRandomizeDelay(context, context->saLifetime);
73 
74 #if (IKE_REAUTH_SUPPORT == ENABLED)
75  //Reauthentication period
76  sa->reauthPeriod = ikeRandomizeDelay(context, context->reauthPeriod);
77 #endif
78  }
79 
80 #if (IKE_DPD_SUPPORT == ENABLED)
81  //The dead peer detection mechanism is used to perform a liveness check
82  if((sa->state < IKE_SA_STATE_OPEN || sa->state == IKE_SA_STATE_DPD_RESP) &&
83  newState == IKE_SA_STATE_OPEN)
84  {
85  //Get current time
86  sa->dpdTimestamp = osGetSystemTime();
87  //Set dead peer detection period
88  sa->dpdPeriod = ikeRandomizeDelay(context, context->dpdPeriod);
89  }
90 #endif
91 
92  //Set time stamp
93  sa->timestamp = osGetSystemTime();
94  //Set initial retransmission timeout
95  sa->timeout = IKE_INIT_TIMEOUT;
96  //Reset retransmission counter
97  sa->retransmitCount = 0;
98 
99  //Switch to the new state
100  sa->state = newState;
101 }
102 
103 
104 /**
105  * @brief Update Child SA state
106  * @param[in] childSa Pointer to the Child SA
107  * @param[in] newState New Child SA state to switch to
108  **/
109 
111 {
112  //Successful Child SA creation?
113  if(childSa->state < IKE_CHILD_SA_STATE_OPEN &&
114  newState == IKE_CHILD_SA_STATE_OPEN)
115  {
116  //ESP and AH SA use secret keys that should be used only for a limited
117  //amount of time
118  childSa->lifetimeStart = osGetSystemTime();
119  }
120 
121  //Switch to the new state
122  childSa->state = newState;
123 }
124 
125 
126 /**
127  * @brief IKE event processing
128  * @param[in] context Pointer to the IKE context
129  **/
130 
132 {
133  error_t error;
134  uint_t i;
135  systime_t time;
136  IkeSaEntry *sa;
137  IkeChildSaEntry *childSa;
138 
139  //Get current time
140  time = osGetSystemTime();
141 
142  //Loop through IKE SA entries
143  for(i = 0; i < context->numSaEntries; i++)
144  {
145  //Point to the current IKE SA
146  sa = &context->sa[i];
147 
148  //Check the state of the IKE SA
149  if(sa->state == IKE_SA_STATE_INIT_REQ)
150  {
151  //Communication using IKE always begins with IKE_SA_INIT and IKE_AUTH
152  //exchanges. These initial exchanges normally consist of four messages
153  error = ikeProcessSaInitEvent(sa);
154 
155  //Check status code code
156  if(error)
157  {
158  //Delete the IKE SA
159  ikeDeleteSaEntry(sa);
160  }
161  }
162  else if(sa->state == IKE_SA_STATE_AUTH_REQ)
163  {
164  //Delete half-open IKE SAs after timeout
165  if((time - sa->timestamp) >= IKE_HALF_OPEN_TIMEOUT)
166  {
167  //Debug message
168  TRACE_INFO("Deleting half-open IKE SA...\r\n");
169  //Delete the IKE SA
170  ikeDeleteSaEntry(sa);
171  }
172  }
173  else if(sa->state == IKE_SA_STATE_OPEN)
174  {
175  //Process IKE SA events
176  ikeProcessSaEvents(sa);
177  }
178  else if(sa->state == IKE_SA_STATE_INIT_RESP ||
179  sa->state == IKE_SA_STATE_AUTH_RESP ||
180  sa->state == IKE_SA_STATE_DPD_RESP ||
181  sa->state == IKE_SA_STATE_REKEY_RESP ||
182  sa->state == IKE_SA_STATE_DELETE_RESP ||
183  sa->state == IKE_SA_STATE_CREATE_CHILD_RESP ||
184  sa->state == IKE_SA_STATE_REKEY_CHILD_RESP ||
185  sa->state == IKE_SA_STATE_DELETE_CHILD_RESP ||
186  sa->state == IKE_SA_STATE_AUTH_FAILURE_RESP)
187  {
188  //Check current time
189  if((time - sa->timestamp) >= sa->timeout)
190  {
191  //The initiator must retransmit the request until it either receives
192  //a corresponding response or deems the IKE SA to have failed (refer
193  //to RFC 7296, section 2.1)
194  if(sa->retransmitCount < IKE_MAX_RETRIES)
195  {
196  //A retransmission from the initiator must be bitwise identical
197  //to the original request
199  }
200  else
201  {
202  //The initiator discards all state associated with the IKE SA
203  //and any Child SAs that were negotiated using that IKE SA
204  ikeDeleteSaEntry(sa);
205  }
206  }
207  }
208  else
209  {
210  //Just for sanity
211  }
212  }
213 
214  //Loop through Child SA entries
215  for(i = 0; i < context->numChildSaEntries; i++)
216  {
217  //Point to the current Child SA
218  childSa = &context->childSa[i];
219 
220  //Check the Child SA should be created
221  if(childSa->state == IKE_CHILD_SA_STATE_INIT &&
222  childSa->sa == NULL)
223  {
225  }
226  }
227 }
228 
229 
230 /**
231  * @brief IKE SA event processing
232  * @param[in] sa Pointer to the IKE SA
233  * @return Error code
234  **/
235 
237 {
238  error_t error;
239  uint_t i;
240  systime_t time;
241  IkeContext *context;
242  IkeChildSaEntry *childSa;
243 
244  //Initialize status code
245  error = NO_ERROR;
246 
247  //Point to the IKE context
248  context = sa->context;
249 
250  //Get current time
251  time = osGetSystemTime();
252 
253 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
254  //Check the state of the IKE SA
255  if(sa->state == IKE_SA_STATE_OPEN)
256  {
257  //Check whether rekeying is enabled
258  if(sa->lifetime != 0)
259  {
260  //Check whether the lifetime of the IKE SA has expired
261  if((time - sa->lifetimeStart) >= sa->lifetime)
262  {
263  //Reestablishment of Security Associations to take the place of ones
264  //that expire is referred to as rekeying
265  sa->rekeyRequest = TRUE;
266  }
267  }
268 
269  //Check whether the IKE SA should be rekeyed
270  if(sa->rekeyRequest)
271  {
272  //Rekey the specified IKE SA
273  error = ikeProcessSaRekeyEvent(sa);
274  }
275  }
276 #endif
277 
278 #if (IKE_REAUTH_SUPPORT == ENABLED)
279  //Check the state of the IKE SA
280  if(sa->state == IKE_SA_STATE_OPEN && !error)
281  {
282  //Check whether reauthentication is enabled
283  if(sa->reauthPeriod != 0)
284  {
285  //Reauthentication has to be initiated by the same party as the
286  //original IKE SA. IKEv2 does not currently allow the responder to
287  //request reauthentication (refer to RFC 7296, section 2.8.3)
288  if(sa->originalInitiator)
289  {
290  //Check whether the reauthentication period has expired
291  if((time - sa->lifetimeStart) >= sa->reauthPeriod)
292  {
293  //IKEv2 does not have any special support for reauthentication.
294  //Reauthentication is done by creating a new IKE SA from scratch,
295  //creating new Child SAs within the new IKE SA, and finally
296  //deleting the old IKE SA
297  sa->reauthRequest = TRUE;
298  }
299 
300  //Check whether reauthentication should be initiated
301  if(sa->reauthRequest && !sa->reauthPending)
302  {
303  //Initiate reauthentication
304  error = ikeProcessSaReauthEvent(sa);
305  }
306  }
307  }
308  }
309 #endif
310 
311 #if (IKE_DPD_SUPPORT == ENABLED)
312  //Check the state of the IKE SA
313  if(sa->state == IKE_SA_STATE_OPEN && !error)
314  {
315  //Check whether the dead peer detection mechanism is enabled
316  if(sa->dpdPeriod != 0)
317  {
318  //Check whether the DPD period has expired
319  if((time - sa->dpdTimestamp) >= sa->dpdPeriod)
320  {
321  //If no cryptographically protected messages have been received on
322  //an IKE SA or any of its Child SAs recently, the system needs to
323  //perform a liveness check in order to prevent sending messages to
324  //a dead peer liveness of the other endpoint to avoid black holes
325  error = ikeProcessSaDpdEvent(sa);
326  }
327  }
328  }
329 #endif
330 
331 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
332  //Check the state of the IKE SA
333  if(sa->state >= IKE_SA_STATE_INIT_REQ && !error)
334  {
335  //Check whether the NAT keepalive mechanism is enabled
336  if(sa->localNat && context->natKeepaliveInterval != 0)
337  {
338  //A peer should send a NAT-keepalive packet if no other packet to
339  //the peer has been sent in M seconds. M is a locally configurable
340  //parameter with a default value of 20 seconds (refer to RFC 3948,
341  //section 4)
342  if((time - sa->natKeepAliveTimestamp) >= context->natKeepaliveInterval)
343  {
344  //The sole purpose of sending NAT-keepalive packets is to keep NAT
345  //mappings alive for the duration of a connection between the peers
346  error = ikeSendNatKeepalive(sa);
347  }
348  }
349  }
350 #endif
351 
352  //Check the state of the IKE SA
353  if(sa->state == IKE_SA_STATE_OPEN && !error)
354  {
355  //Check whether the IKE SA should be closed
356  if(sa->deleteRequest)
357  {
358  //Close the specified IKE SA
359  error = ikeProcessSaDeleteEvent(sa);
360  }
361  }
362 
363  //Check the state of the IKE SA
364  if(sa->state == IKE_SA_STATE_OPEN && !error)
365  {
366  //Loop through Child SA entries
367  for(i = 0; i < context->numChildSaEntries && !error; i++)
368  {
369  //Point to the current Child SA
370  childSa = &context->childSa[i];
371 
372  //Valid Child SA?
373  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
374  childSa->sa == sa)
375  {
376  //Process Child SA events
377  error = ikeProcessChildSaEvents(childSa);
378  }
379  }
380  }
381 
382  //Return status code
383  return error;
384 }
385 
386 
387 /**
388  * @brief Child SA event processing
389  * @param[in] childSa Pointer to the Child SA
390  * @return Error code
391  **/
392 
394 {
395  error_t error;
396  IkeSaEntry *sa;
397 
398  //Initialize status code
399  error = NO_ERROR;
400 
401  //Point to the IKE SA
402  sa = childSa->sa;
403 
404 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
405  //Check the state of the IKE SA
406  if(sa->state == IKE_SA_STATE_OPEN)
407  {
408  systime_t time;
409  IkeContext *context;
410 
411  //Point to the IKE context
412  context = childSa->context;
413  //Get current time
414  time = osGetSystemTime();
415 
416  //Check whether rekeying is enabled
417  if(context->childSaLifetime != 0)
418  {
419  //Check whether the lifetime of the Child SA has expired
420  if((time - childSa->lifetimeStart) >= context->childSaLifetime)
421  {
422  //Reestablishment of Security Associations to take the place of
423  //ones that expire is referred to as rekeying
424  childSa->rekeyRequest = TRUE;
425  }
426  }
427 
428  //Check whether the Child SA should be rekeyed
429  if(childSa->rekeyRequest)
430  {
431  //Rekey the specified Child SA
432  error = ikeProcessChildSaRekeyEvent(childSa);
433  }
434  }
435 #endif
436 
437  //Check the state of the IKE SA
438  if(sa->state == IKE_SA_STATE_OPEN && !error)
439  {
440  //Check whether the Child SA should be closed
441  if(childSa->deleteRequest)
442  {
443  //Close the specified Child SA
444  error = ikeProcessChildSaDeleteEvent(childSa);
445  }
446  }
447 
448  //Return status code
449  return error;
450 }
451 
452 
453 /**
454  * @brief Handle IKE SA creation event
455  * @param[in] sa Pointer to the IKE SA
456  * @return Error code
457  **/
458 
460 {
461  error_t error;
462  bool_t valid;
463  IkeContext *context;
464 
465  //Point to the IKE context
466  context = sa->context;
467 
468  //Initialize flag
469  valid = FALSE;
470 
471  //Valid entity's ID
472  if(context->idType != IKE_ID_TYPE_INVALID)
473  {
474 #if (IKE_PSK_AUTH_SUPPORT == ENABLED)
475  //Pre-shared key authentication?
476  if(context->pskLen > 0)
477  {
478  valid = TRUE;
479  }
480 #endif
481  }
482  else
483  {
484 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
485  //Certificate authentication?
486  if(context->certChain != NULL && context->certChainLen > 0)
487  {
488  valid = TRUE;
489  }
490 #endif
491  }
492 
493  //Valid credentials?
494  if(valid)
495  {
496  //Each endpoint chooses one of the two SPIs and must choose them so as to
497  //be unique identifiers of an IKE SA (refer to RFC 7296, section 2.6)
498  error = ikeGenerateSaSpi(sa, sa->initiatorSpi);
499 
500  //Check status code
501  if(!error)
502  {
503  //Nonces used in IKEv2 must be randomly chosen and must be at least
504  //128 bits in size (refer to RFC 7296, section 2.10)
505  error = ikeGenerateNonce(context, sa->initiatorNonce,
506  &sa->initiatorNonceLen);
507  }
508 
509  //Check status code
510  if(!error)
511  {
512  //Generate an ephemeral key pair
513  error = ikeGenerateKeyPair(&sa->keContext, context->prngAlgo,
514  context->prngContext);
515  }
516 
517  //Check status code
518  if(!error)
519  {
520  //The first exchange of an IKE session, IKE_SA_INIT, negotiates
521  //security parameters for the IKE SA, sends nonces, and sends
522  //Diffie-Hellman values
523  error = ikeSendIkeSaInitRequest(sa);
524  }
525  }
526  else
527  {
528  //No valid credentials provided
529  error = ERROR_NOT_CONFIGURED;
530  }
531 
532  //Return status code
533  return error;
534 }
535 
536 
537 /**
538  * @brief Handle IKE SA dead peer detection event
539  * @param[in] sa Pointer to the IKE SA
540  * @return Error code
541  **/
542 
544 {
545  //If no cryptographically protected messages have been received on an
546  //IKE SA or any of its Child SAs recently, the system needs to perform
547  //a liveness check in order to prevent sending messages to a dead peer
548  //(refer to RFC 7296, section 2.4)
550 
551  //An INFORMATIONAL request with no payloads is commonly used as a check
552  //for liveness (refer to RFC 7296, section 1)
553  return ikeSendInfoRequest(sa);
554 }
555 
556 
557 /**
558  * @brief Handle IKE SA rekeying event
559  * @param[in] sa Pointer to the IKE SA
560  * @return Error code
561  **/
562 
564 {
565 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
566  error_t error;
567  IkeContext *context;
568  IkeSaEntry *newSa;
569 
570  //Initialize status code
571  error = NO_ERROR;
572 
573  //Point to the IKE context
574  context = sa->context;
575 
576  //Create a new IKE SA
577  newSa = ikeCreateSaEntry(context);
578 
579  //Successful IKE SA creation?
580  if(newSa != NULL)
581  {
582  //Initialize IKE SA
583  newSa->remoteIpAddr = sa->remoteIpAddr;
584 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
585  newSa->localNat = sa->localNat;
586  newSa->remoteNat = sa->remoteNat;
587 #endif
588 
589  //The initiator of the rekey exchange is the new "original initiator"
590  //of the new IKE SA (refer to RFC 7296, section 1.3.2)
591  newSa->originalInitiator = TRUE;
592 
593  //Select the preferred key exchange method
594  newSa->keContext.groupNum = context->preferredGroupNum;
595 
596  //Each endpoint chooses one of the two SPIs and must choose them so as to
597  //be unique identifiers of an IKE SA (refer to RFC 7296, section 2.6)
598  error = ikeGenerateSaSpi(newSa, newSa->initiatorSpi);
599 
600  //Check status code
601  if(!error)
602  {
603  //Nonces used in IKEv2 must be randomly chosen and must be at least
604  //128 bits in size (refer to RFC 7296, section 2.10)
605  error = ikeGenerateNonce(context, newSa->initiatorNonce,
606  &newSa->initiatorNonceLen);
607  }
608 
609  //Check status code
610  if(!error)
611  {
612  //Generate an ephemeral key pair
613  error = ikeGenerateKeyPair(&newSa->keContext, context->prngAlgo,
614  context->prngContext);
615  }
616 
617  //Check status code
618  if(!error)
619  {
620  //Acknowledge request
621  sa->rekeyRequest = FALSE;
622 
623  //Attach the newly created IKE SA
624  sa->newSa1 = newSa;
625  sa->newSa2 = NULL;
626 
627  //Update the state of the IKE SA
629 
630  //To rekey an IKE SA, establish a new equivalent IKE SA with the peer
631  //to whom the old IKE SA is shared using a CREATE_CHILD_SA within the
632  //existing IKE SA (refer to RFC 7296, section 2.8)
634  }
635  else
636  {
637  //Clean up any side effects
638  ikeDeleteSaEntry(newSa);
639  }
640  }
641  else
642  {
643  //Failed to create IKE SA
644  error = ERROR_OUT_OF_RESOURCES;
645  }
646 
647  //Return status code
648  return error;
649 #else
650  //Minimal implementations are not required to support the CREATE_CHILD_SA
651  //exchange (refer to RFC 7296, section 4)
652  return ERROR_NOT_IMPLEMENTED;
653 #endif
654 }
655 
656 
657 /**
658  * @brief Handle IKE SA reauthentication event
659  * @param[in] sa Pointer to the IKE SA
660  * @return Error code
661  **/
662 
664 {
665 #if (IKE_REAUTH_SUPPORT == ENABLED)
666  error_t error;
667  IkeContext *context;
668  IkeSaEntry *newSa;
669  IkeChildSaEntry *childSa;
670  IkeChildSaEntry *newChildSa;
671 
672  //Initialize status code
673  error = NO_ERROR;
674 
675  //Point to the IKE context
676  context = sa->context;
677  //Point to the Child SA
678  childSa = sa->childSa1;
679 
680  //Sanity check
681  if(childSa != NULL)
682  {
683  //Acknowledge request
684  sa->reauthPending = TRUE;
685 
686  //Create a new IKE SA
687  newSa = ikeCreateSaEntry(context);
688 
689  //Successful IKE SA creation?
690  if(newSa != NULL)
691  {
692  //Create a new Child SA
693  newChildSa = ikeCreateChildSaEntry(context);
694 
695  //Successful IKE SA creation?
696  if(newChildSa != NULL)
697  {
698  //Initialize IKE SA
699  newSa->remoteIpAddr = sa->remoteIpAddr;
700 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
701  newSa->localNat = sa->localNat;
702  newSa->remoteNat = sa->remoteNat;
703 #endif
704  newSa->childSa1 = newChildSa;
705  newSa->childSa2 = NULL;
706 
707  //The initiator of the rekey exchange is the new "original initiator"
708  //of the new IKE SA (refer to RFC 7296, section 1.3.2)
709  newSa->originalInitiator = TRUE;
710 
711  //Select the preferred key exchange method
712  newSa->keContext.groupNum = context->preferredGroupNum;
713 
714  //Initialize Child SA
715  newChildSa->sa = newSa;
716  newChildSa->mode = childSa->mode;
717  newChildSa->protocol = childSa->protocol;
718  newChildSa->initiator = TRUE;
719  newChildSa->selector = childSa->selector;
720 
721  //Each endpoint chooses one of the two SPIs and must choose them so as to
722  //be unique identifiers of an IKE SA (refer to RFC 7296, section 2.6)
723  error = ikeGenerateSaSpi(newSa, newSa->initiatorSpi);
724 
725  //Check status code
726  if(!error)
727  {
728  //Nonces used in IKEv2 must be randomly chosen and must be at least
729  //128 bits in size (refer to RFC 7296, section 2.10)
730  error = ikeGenerateNonce(context, newSa->initiatorNonce,
731  &newSa->initiatorNonceLen);
732  }
733 
734  //Check status code
735  if(!error)
736  {
737  //Generate an ephemeral key pair
738  error = ikeGenerateKeyPair(&newSa->keContext, context->prngAlgo,
739  context->prngContext);
740  }
741 
742  //Check status code
743  if(!error)
744  {
745  //The first exchange of an IKE session, IKE_SA_INIT, negotiates
746  //security parameters for the IKE SA, sends nonces, and sends
747  //Diffie-Hellman values
748  error = ikeSendIkeSaInitRequest(newSa);
749  }
750 
751  //Check status code
752  if(!error)
753  {
754  //Attach the old IKE SA
755  newSa->oldSa = sa;
756  }
757  else
758  {
759  //Failed to initiate reauthentication
760  ikeDeleteSaEntry(newSa);
761  }
762  }
763  else
764  {
765  //Clean up any side effects
766  ikeDeleteSaEntry(newSa);
767  //Failed to create Child SA
768  error = ERROR_OUT_OF_RESOURCES;
769  }
770  }
771  else
772  {
773  //Failed to create IKE SA
774  error = ERROR_OUT_OF_RESOURCES;
775  }
776 
777  //Failed to initiate reauthentication?
778  if(error)
779  {
780  //Close the old IKE SA
781  sa->deleteRequest = TRUE;
782  //Notify the IKE context that the IKE SA should be closed
783  osSetEvent(&context->event);
784  }
785  }
786 
787  //Return status code
788  return error;
789 #else
790  //Reauthentication is not implemented
791  return ERROR_NOT_IMPLEMENTED;
792 #endif
793 }
794 
795 
796 /**
797  * @brief Handle IKE SA deletion event
798  * @param[in] sa Pointer to the IKE SA
799  * @return Error code
800  **/
801 
803 {
804  //Acknowledge request
805  sa->deleteRequest = FALSE;
806  sa->childSa1 = NULL;
807  sa->childSa2 = NULL;
808 
809  //Update the state of the IKE SA
811 
812  //To delete an SA, an INFORMATIONAL exchange with one or more Delete
813  //payloads is sent listing the SPIs of the SAs to be deleted
814  return ikeSendInfoRequest(sa);
815 }
816 
817 
818 /**
819  * @brief Handle Child SA creation event
820  * @param[in] childSa Pointer to the Child SA
821  * @return Error code
822  **/
823 
825 {
826  error_t error;
827  IkeContext *context;
828  IkeSaEntry *sa;
829 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
830  uint_t i;
831  IkeSaEntry *bestSa;
832 #endif
833 
834  //Initialize status code
835  error = NO_ERROR;
836 
837  //Point to the IKE context
838  context = childSa->context;
839 
840 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
841  //Loop through IKE SA entries
842  for(bestSa = NULL, i = 0; i < context->numSaEntries; i++)
843  {
844  //Point to the current IKE SA
845  sa = &context->sa[i];
846 
847  //Check whether the current IKE SA matches the peer's IP address
848  if(sa->state != IKE_SA_STATE_CLOSED &&
849  ipCompAddr(&sa->remoteIpAddr, &childSa->remoteIpAddr))
850  {
851  //Prefer an IKE SA that is known to be alive
852  if(bestSa == NULL)
853  {
854  bestSa = sa;
855  }
856  else if(sa->state == IKE_SA_STATE_OPEN &&
857  bestSa->state != IKE_SA_STATE_OPEN)
858  {
859  bestSa = sa;
860  }
861  else
862  {
863  }
864  }
865  }
866 
867  //A minimal implementation need not be able to initiate a CREATE_CHILD_SA
868  //exchange (refer to RFC 7296, section 4)
869  if(bestSa != NULL && !bestSa->noAdditionalSas)
870  {
871  //Check the state of the IKE SA
872  if(bestSa->state == IKE_SA_STATE_OPEN)
873  {
874  //Attach the Child SA to the IKE SA
875  bestSa->childSa1 = childSa;
876  bestSa->childSa2 = NULL;
877  childSa->sa = bestSa;
878 
879  //Generate a new SPI for the Child SA
880  error = ikeGenerateChildSaSpi(childSa, childSa->localSpi);
881 
882  //Check status code
883  if(!error)
884  {
885  //Nonces used in IKEv2 must be randomly chosen and must be at least
886  //128 bits in size (refer to RFC 7296, section 2.10)
887  error = ikeGenerateNonce(context, childSa->initiatorNonce,
888  &childSa->initiatorNonceLen);
889  }
890 
891 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
892  //Check status code
893  if(!error)
894  {
895  //Perfect forward secrecy?
896  if(childSa->pfs)
897  {
898  //Select the preferred key exchange method
899  childSa->keContext.groupNum = context->preferredGroupNum;
900 
901  //Generate an ephemeral key pair
902  error = ikeGenerateKeyPair(&childSa->keContext,
903  context->prngAlgo, context->prngContext);
904  }
905  }
906 #endif
907  //Check status code
908  if(!error)
909  {
910  //Update the state of the IKE SA
912 
913  //The initiator begins negotiation of a Child SA using the
914  //CREATE_CHILD_SA exchange
915  error = ikeSendCreateChildSaRequest(bestSa);
916  }
917  }
918  else
919  {
920  //Wait for the IKE SA negotiation to complete
921  }
922  }
923  else
924 #endif
925  {
926  //Create a new IKE SA
927  sa = ikeCreateSaEntry(context);
928 
929  //Successful IKE SA creation?
930  if(sa != NULL)
931  {
932  //Initialize IKE SA
933  sa->remoteIpAddr = childSa->remoteIpAddr;
934  sa->childSa1 = childSa;
935 
936  //The original initiator always refers to the party who initiated the
937  //exchange (refer to RFC 7296, section 2.2)
938  sa->originalInitiator = TRUE;
939 
940  //Select the preferred key exchange method
941  sa->keContext.groupNum = context->preferredGroupNum;
942 
943  //Attach the newly created IKE SA to the Child SA
944  childSa->sa = sa;
945 
946  //Update the state of the IKE SA
948  //Notify the IKE context that the IKE SA should be created
949  osSetEvent(&context->event);
950  }
951  else
952  {
953  //Failed to create IKE SA
954  error = ERROR_OUT_OF_RESOURCES;
955  }
956  }
957 
958  //Return status code
959  return error;
960 }
961 
962 
963 /**
964  * @brief Handle Child SA rekeying event
965  * @param[in] childSa Pointer to the Child SA
966  * @return Error code
967  **/
968 
970 {
971 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
972  error_t error;
973  IkeSaEntry *sa;
974  IkeContext *context;
975  IkeChildSaEntry *newChildSa;
976 
977  //Initialize status code
978  error = NO_ERROR;
979 
980  //Point to the IKE context
981  context = childSa->context;
982  //Point to the IKE SA
983  sa = childSa->sa;
984 
985  //Create a new Child SA
986  newChildSa = ikeCreateChildSaEntry(context);
987 
988  //Successful Child SA creation?
989  if(newChildSa != NULL)
990  {
991  //Initialize Child SA
992  newChildSa->sa = sa;
993  newChildSa->oldChildSa = childSa;
994  newChildSa->mode = childSa->mode;
995  newChildSa->protocol = childSa->protocol;
996 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
997  newChildSa->pfs = childSa->pfs;
998 #endif
999  newChildSa->initiator = TRUE;
1000 
1001  //When the initiator attempts to rekey the Child SA, the proposed Traffic
1002  //Selectors should be either the same as, or a superset of, the Traffic
1003  //Selectors used in the old Child SA (refer to RFC 7296, section 2.9.2)
1004  newChildSa->selector = childSa->selector;
1005 
1006  //Generate a new SPI for the Child SA
1007  error = ikeGenerateChildSaSpi(newChildSa, newChildSa->localSpi);
1008 
1009  //Check status code
1010  if(!error)
1011  {
1012  //Nonces used in IKEv2 must be randomly chosen and must be at least
1013  //128 bits in size (refer to RFC 7296, section 2.10)
1014  error = ikeGenerateNonce(context, newChildSa->initiatorNonce,
1015  &newChildSa->initiatorNonceLen);
1016  }
1017 
1018 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
1019  //Check status code
1020  if(!error)
1021  {
1022  //Perfect forward secrecy?
1023  if(newChildSa->pfs)
1024  {
1025  //Select the preferred key exchange method
1026  if(childSa->keContext.groupNum != IKE_TRANSFORM_ID_KE_NONE)
1027  {
1028  newChildSa->keContext.groupNum = childSa->keContext.groupNum;
1029  }
1030  else
1031  {
1032  newChildSa->keContext.groupNum = context->preferredGroupNum;
1033  }
1034 
1035  //Generate an ephemeral key pair
1036  error = ikeGenerateKeyPair(&newChildSa->keContext,
1037  context->prngAlgo, context->prngContext);
1038  }
1039  }
1040 #endif
1041 
1042  //Check status code
1043  if(!error)
1044  {
1045  //Acknowledge request
1046  childSa->rekeyRequest = FALSE;
1047 
1048  //Attach the newly created Child SA to the IKE SA
1049  sa->childSa1 = newChildSa;
1050  sa->childSa2 = NULL;
1051 
1052  //Update the state of the IKE SA
1054  //Update the state of the Child SA
1056 
1057  //To rekey a Child SA within an existing IKE SA, create a new
1058  //equivalent SA, and when the new one is established, delete the
1059  //old one
1060  error = ikeSendCreateChildSaRequest(sa);
1061  }
1062  else
1063  {
1064  //Clean up any side effects
1065  ikeDeleteChildSaEntry(newChildSa);
1066  }
1067  }
1068  else
1069  {
1070  //Failed to create Child SA
1071  error = ERROR_OUT_OF_RESOURCES;
1072  }
1073 
1074  //Return status code
1075  return error;
1076 #else
1077  //Minimal implementations are not required to support the CREATE_CHILD_SA
1078  //exchange (refer to RFC 7296, section 4)
1079  return ERROR_NOT_IMPLEMENTED;
1080 #endif
1081 }
1082 
1083 
1084 /**
1085  * @brief Handle Child SA deletion event
1086  * @param[in] childSa Pointer to the Child SA
1087  * @return Error code
1088  **/
1089 
1091 {
1092  IkeSaEntry *sa;
1093 
1094  //Point to the IKE SA
1095  sa = childSa->sa;
1096 
1097  //Acknowledge request
1098  childSa->deleteRequest = FALSE;
1099 
1100  //Attach the Child SA to the IKE SA
1101  sa->childSa1 = childSa;
1102  sa->childSa2 = NULL;
1103 
1104  //Update the state of the IKE SA
1106  //Update the state of the Child SA
1108 
1109  //To delete an SA, an INFORMATIONAL exchange with one or more Delete payloads
1110  //is sent listing the SPIs of the SAs to be deleted
1111  return ikeSendInfoRequest(sa);
1112 }
1113 
1114 #endif
IkeSaState
IKE Security Association state.
Definition: ike.h:1353
@ IKE_CHILD_SA_STATE_DELETE
Definition: ike.h:1389
error_t ikeSendIkeSaInitRequest(IkeSaEntry *sa)
Send IKE_SA_INIT request.
error_t ikeProcessSaReauthEvent(IkeSaEntry *sa)
Handle IKE SA reauthentication event.
Definition: ike_fsm.c:663
Diffie-Hellman key exchange.
int bool_t
Definition: compiler_port.h:63
Helper functions for IKEv2.
error_t ikeProcessSaRekeyEvent(IkeSaEntry *sa)
Handle IKE SA rekeying event.
Definition: ike_fsm.c:563
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
error_t ikeGenerateSaSpi(IkeSaEntry *sa, uint8_t *spi)
Generate a new IKE SA SPI.
Definition: ike_misc.c:632
@ IKE_SA_STATE_DELETE_REQ
Definition: ike.h:1365
#define TRUE
Definition: os_port.h:50
systime_t ikeRandomizeDelay(IkeContext *context, systime_t delay)
Apply random jitter to a time interval.
Definition: ike_misc.c:826
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
IkeChildSaEntry * ikeCreateChildSaEntry(IkeContext *context)
Create a new Child Security Association.
Definition: ike_misc.c:451
@ ERROR_NOT_CONFIGURED
Definition: error.h:218
IKEv2 finite state machine.
@ IKE_SA_STATE_CLOSED
Definition: ike.h:1354
@ IKE_CHILD_SA_STATE_REKEY
Definition: ike.h:1388
error_t ikeProcessSaDeleteEvent(IkeSaEntry *sa)
Handle IKE SA deletion event.
Definition: ike_fsm.c:802
@ IKE_SA_STATE_REKEY_REQ
Definition: ike.h:1363
error_t ikeSendNatKeepalive(IkeSaEntry *sa)
Send NAT-keepalive packet.
error_t ikeProcessSaEvents(IkeSaEntry *sa)
IKE SA event processing.
Definition: ike_fsm.c:236
#define IKE_HALF_OPEN_TIMEOUT
Definition: ike.h:187
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
#define IkeContext
Definition: ike.h:832
@ IKE_SA_STATE_DELETE_CHILD_RESP
Definition: ike.h:1372
#define FALSE
Definition: os_port.h:46
IkeSaEntry * ikeCreateSaEntry(IkeContext *context)
Create a new IKE Security Association.
Definition: ike_misc.c:185
error_t ikeProcessSaInitEvent(IkeSaEntry *sa)
Handle IKE SA creation event.
Definition: ike_fsm.c:459
@ IKE_SA_STATE_OPEN
Definition: ike.h:1360
error_t
Error codes.
Definition: error.h:43
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:318
@ IKE_SA_STATE_AUTH_FAILURE_RESP
Definition: ike.h:1374
@ IKE_SA_STATE_REKEY_CHILD_REQ
Definition: ike.h:1369
error_t ikeRetransmitRequest(IkeSaEntry *sa)
Retransmit IKE request message.
Definition: ike_misc.c:56
error_t ikeSendInfoRequest(IkeSaEntry *sa)
Send INFORMATIONAL request.
IkeChildSaState
Child Security Association state.
Definition: ike.h:1383
Helper routines for IPsec.
@ IKE_SA_STATE_INIT_REQ
Definition: ike.h:1356
@ IKE_SA_STATE_AUTH_REQ
Definition: ike.h:1358
void ikeDeleteSaEntry(IkeSaEntry *sa)
Delete an IKE Security Association.
Definition: ike_misc.c:347
@ IKE_CHILD_SA_STATE_INIT
Definition: ike.h:1386
void ikeDeleteChildSaEntry(IkeChildSaEntry *childSa)
Delete a Child Security Association.
Definition: ike_misc.c:560
#define TRACE_INFO(...)
Definition: debug.h:105
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 ikeSendCreateChildSaRequest(IkeSaEntry *sa)
Send CREATE_CHILD_SA request.
IKEv2 (Internet Key Exchange Protocol)
error_t ikeProcessSaDpdEvent(IkeSaEntry *sa)
Handle IKE SA dead peer detection event.
Definition: ike_fsm.c:543
uint32_t systime_t
System time.
@ IKE_TRANSFORM_ID_KE_NONE
None.
Definition: ike.h:1053
@ IKE_SA_STATE_CREATE_CHILD_REQ
Definition: ike.h:1367
error_t ikeGenerateKeyPair(IkeKeContext *keContext, const PrngAlgo *prngAlgo, void *prngContext)
Key pair generation.
uint32_t time
#define IkeSaEntry
Definition: ike.h:836
@ IKE_SA_STATE_REKEY_CHILD_RESP
Definition: ike.h:1370
error_t ikeGenerateChildSaSpi(IkeChildSaEntry *childSa, uint8_t *spi)
Generate a new Child SA SPI.
Definition: ike_misc.c:718
@ IKE_SA_STATE_DPD_REQ
Definition: ike.h:1361
@ IKE_SA_STATE_DELETE_RESP
Definition: ike.h:1366
@ IKE_ID_TYPE_INVALID
Definition: ike.h:1122
@ IKE_SA_STATE_AUTH_RESP
Definition: ike.h:1359
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1357
#define IKE_INIT_TIMEOUT
Definition: ike.h:173
@ IKE_SA_STATE_REKEY_RESP
Definition: ike.h:1364
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t ikeGenerateNonce(IkeContext *context, uint8_t *nonce, size_t *length)
Generate a new nonce.
Definition: ike_misc.c:792
void ikeProcessEvents(IkeContext *context)
IKE event processing.
Definition: ike_fsm.c:131
@ IKE_SA_STATE_CREATE_CHILD_RESP
Definition: ike.h:1368
#define IKE_MAX_RETRIES
Definition: ike.h:166
@ IKE_SA_STATE_DPD_RESP
Definition: ike.h:1362
unsigned int uint_t
Definition: compiler_port.h:57
error_t ikeProcessChildSaDeleteEvent(IkeChildSaEntry *childSa)
Handle Child SA deletion event.
Definition: ike_fsm.c:1090
#define IkeChildSaEntry
Definition: ike.h:840
error_t ikeProcessChildSaInitEvent(IkeChildSaEntry *childSa)
Handle Child SA creation event.
Definition: ike_fsm.c:824
error_t ikeProcessChildSaEvents(IkeChildSaEntry *childSa)
Child SA event processing.
Definition: ike_fsm.c:393
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ IKE_SA_STATE_DELETE_CHILD_REQ
Definition: ike.h:1371
IKE request formatting.
@ IKE_CHILD_SA_STATE_OPEN
Definition: ike.h:1387
systime_t osGetSystemTime(void)
Retrieve system time.
error_t ikeProcessChildSaRekeyEvent(IkeChildSaEntry *childSa)
Handle Child SA rekeying event.
Definition: ike_fsm.c:969