ike_request_format.c
Go to the documentation of this file.
1 /**
2  * @file ike_request_format.c
3  * @brief IKE request formatting
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 "ike/ike.h"
36 #include "ike/ike_fsm.h"
38 #include "ike/ike_request_format.h"
39 #include "ike/ike_payload_format.h"
40 #include "ike/ike_key_exchange.h"
41 #include "ike/ike_key_material.h"
42 #include "ike/ike_misc.h"
43 #include "ike/ike_debug.h"
44 #include "debug.h"
45 
46 //Check IKEv2 library configuration
47 #if (IKE_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Send IKE request message
52  * @param[in] sa Pointer to the IKE SA
53  * @return Error code
54  **/
55 
57 {
58  error_t error;
59  IkeContext *context;
60 
61  //Point to the IKE context
62  context = sa->context;
63 
64  //Debug message
65  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->requestLen);
66  //Dump IKE message for debugging purpose
67  ikeDumpMessage(sa->request + IKE_PREFIX_SIZE, sa->requestLen);
68 
69 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
70  //IKE packets must be sent from UDP port 500 or 4500
71  if(sa->localNat || sa->remoteNat)
72  {
73  //The UDP payload of all packets containing IKE messages sent on port 4500
74  //must begin with the prefix of four zeros (refer to RFC 7296, section 2)
75  error = socketSendTo(context->altSocket, &sa->remoteIpAddr, IPSEC_NAT_PORT,
76  sa->request, sa->requestLen + IKE_PREFIX_SIZE, NULL, 0);
77  }
78  else
79 #endif
80  {
81  //Send the IKE request on port 500
82  error = socketSendTo(context->socket, &sa->remoteIpAddr, IKE_PORT,
83  sa->request + IKE_PREFIX_SIZE, sa->requestLen, NULL, 0);
84  }
85 
86 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
87  //A peer should send a NAT-keepalive packet if no other packet to the peer
88  //has been sent in M seconds (refer to RFC 3948, section 4)
89  sa->natKeepAliveTimestamp = osGetSystemTime();
90 #endif
91 
92  //Return status code
93  return error;
94 }
95 
96 
97 /**
98  * @brief Send IKE_SA_INIT request
99  * @param[in] sa Pointer to the IKE SA
100  * @return Error code
101  **/
102 
104 {
105  error_t error;
106  IkeContext *context;
107 
108  //Initialize status code
109  error = NO_ERROR;
110 
111  //Point to the IKE context
112  context = sa->context;
113 
114  //The Message ID is a 32-bit quantity, which is zero for the IKE_SA_INIT
115  //messages (including retries of the message due to responses such as
116  //COOKIE and INVALID_KE_PAYLOAD)
117  sa->txMessageId = 0;
118 
119  //Four octets of zero are prepended to the IKE header
120  STORE32BE(IKE_PREFIX_VALUE, sa->request);
121 
122  //Format IKE_SA_INIT request
123  error = ikeFormatIkeSaInitRequest(sa, sa->request + IKE_PREFIX_SIZE,
124  &sa->requestLen);
125 
126  //Check status code
127  if(!error)
128  {
129  //Send IKE request
130  ikeSendRequest(sa);
131 
132  //Wait for the IKE_SA_INIT response from the responder
134  }
135 
136  //Return status code
137  return error;
138 }
139 
140 
141 /**
142  * @brief Send IKE_AUTH request
143  * @param[in] sa Pointer to the IKE SA
144  * @return Error code
145  **/
146 
148 {
149  error_t error;
150  IkeContext *context;
151 
152  //Point to the IKE context
153  context = sa->context;
154 
155  //Save the second message (IKE_SA_INIT response), starting with the first
156  //octet of the first SPI in the header and ending with the last octet of
157  //the last payload
158  osMemcpy(sa->response, sa->responderSaInit, sa->responderSaInitLen);
159  sa->responderSaInit = sa->response;
160 
161  //Save the first message (IKE_SA_INIT request), starting with the first
162  //octet of the first SPI in the header and ending with the last octet of
163  //the last payload
164  osMemcpy(context->message, sa->initiatorSaInit, sa->initiatorSaInitLen);
165  sa->initiatorSaInit = context->message;
166 
167  //Let g^ir be the Diffie-Hellman shared secret
168  error = ikeComputeSharedSecret(&sa->keContext, sa->sharedSecret,
169  &sa->sharedSecretLen);
170 
171  //Check status code
172  if(!error)
173  {
174  //The ephemeral private key must be destroyed as soon as possible (refer
175  //to RFC 9206, section 10)
176  ikeFreeKeContext(&sa->keContext);
177  ikeInitKeContext(&sa->keContext);
178 
179  //At this point in the negotiation, each party can generate a quantity
180  //called SKEYSEED, from which all keys are derived for that IKE SA (refer
181  //to RFC 7296, section 1.2)
182  error = ikeGenerateSaKeyMaterial(sa, NULL);
183  }
184 
185  //Check status code
186  if(!error)
187  {
188  //Valid Child SA?
189  if(sa->childSa1 != NULL)
190  {
191  //Generate a new SPI for the Child SA
192  error = ikeGenerateChildSaSpi(sa->childSa1, sa->childSa1->localSpi);
193  }
194  }
195 
196  //Check status code
197  if(!error)
198  {
199  //The message ID is incremented for each subsequent exchange
200  sa->txMessageId++;
201 
202  //Four octets of zero are prepended to the IKE header
203  STORE32BE(IKE_PREFIX_VALUE, sa->request);
204 
205  //Format IKE_AUTH request
206  error = ikeFormatIkeAuthRequest(sa, sa->request + IKE_PREFIX_SIZE,
207  &sa->requestLen);
208  }
209 
210  //Check status code
211  if(!error)
212  {
213  //All messages following the initial exchange are cryptographically
214  //protected using the cryptographic algorithms and keys negotiated in
215  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
216  error = ikeEncryptMessage(sa, sa->request + IKE_PREFIX_SIZE,
217  &sa->requestLen);
218  }
219 
220  //Check status code
221  if(!error)
222  {
223  //Send IKE request
224  ikeSendRequest(sa);
225 
226  //Wait for the IKE_AUTH response from the responder
228  }
229 
230  //Return status code
231  return error;
232 }
233 
234 
235 /**
236  * @brief Send CREATE_CHILD_SA request
237  * @param[in] sa Pointer to the IKE SA
238  * @return Error code
239  **/
240 
242 {
243 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
244  error_t error;
245  IkeContext *context;
246 
247  //Point to the IKE context
248  context = sa->context;
249 
250  //The message ID is incremented for each subsequent exchange
251  sa->txMessageId++;
252 
253  //Four octets of zero are prepended to the IKE header
254  STORE32BE(IKE_PREFIX_VALUE, sa->request);
255 
256  //Format CREATE_CHILD_SA request
257  error = ikeFormatCreateChildSaRequest(sa, sa->request + IKE_PREFIX_SIZE,
258  &sa->requestLen);
259 
260  //Check status code
261  if(!error)
262  {
263  //All messages following the initial exchange are cryptographically
264  //protected using the cryptographic algorithms and keys negotiated in
265  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
266  error = ikeEncryptMessage(sa, sa->request + IKE_PREFIX_SIZE,
267  &sa->requestLen);
268  }
269 
270  //Check status code
271  if(!error)
272  {
273  //Send IKE request
274  ikeSendRequest(sa);
275 
276  //Wait for the CREATE_CHILD_SA response
277  if(sa->state == IKE_SA_STATE_REKEY_REQ)
278  {
280  }
281  else if(sa->state == IKE_SA_STATE_CREATE_CHILD_REQ)
282  {
284  }
285  else if(sa->state == IKE_SA_STATE_REKEY_CHILD_REQ)
286  {
288  }
289  else
290  {
291  //Just for sanity
292  }
293  }
294 
295  //Return status code
296  return error;
297 #else
298  //Minimal implementations are not required to support the CREATE_CHILD_SA
299  //exchange (refer to RFC 7296, section 4)
300  return ERROR_NOT_IMPLEMENTED;
301 #endif
302 }
303 
304 
305 /**
306  * @brief Send INFORMATIONAL request
307  * @param[in] sa Pointer to the IKE SA
308  * @return Error code
309  **/
310 
312 {
313  error_t error;
314  IkeContext *context;
315 
316  //Point to the IKE context
317  context = sa->context;
318 
319  //The message ID is incremented for each subsequent exchange
320  sa->txMessageId++;
321 
322  //Four octets of zero are prepended to the IKE header
323  STORE32BE(IKE_PREFIX_VALUE, sa->request);
324 
325  //Format INFORMATIONAL request
326  error = ikeFormatInfoRequest(sa, sa->request + IKE_PREFIX_SIZE,
327  &sa->requestLen);
328 
329  //Check status code
330  if(!error)
331  {
332  //All messages following the initial exchange are cryptographically
333  //protected using the cryptographic algorithms and keys negotiated in
334  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
335  error = ikeEncryptMessage(sa, sa->request + IKE_PREFIX_SIZE,
336  &sa->requestLen);
337  }
338 
339  //Check status code
340  if(!error)
341  {
342  //Send IKE request
343  ikeSendRequest(sa);
344 
345  //Wait for the INFORMATIONAL response
346  if(sa->state == IKE_SA_STATE_DPD_REQ)
347  {
349  }
350  else if(sa->state == IKE_SA_STATE_DELETE_REQ)
351  {
353  }
354  else if(sa->state == IKE_SA_STATE_DELETE_CHILD_REQ)
355  {
357  }
358  else if(sa->state == IKE_SA_STATE_AUTH_FAILURE_REQ)
359  {
361  }
362  else
363  {
364  //Just for sanity
365  }
366  }
367 
368  //Return status code
369  return error;
370 }
371 
372 
373 /**
374  * @brief Send NAT-keepalive packet
375  * @param[in] sa Pointer to the IKE SA
376  * @return Error code
377  **/
378 
380 {
381 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
382  IkeContext *context;
383 
384  //Point to the IKE context
385  context = sa->context;
386 
387  //The sender must use a one octet long payload with the value 0xFF (refer to
388  //RFC 3948, section 2.3)
389  context->message[0] = IKE_NAT_KEEPALIVE_PACKET_VALUE;
390  context->messageLen = IKE_NAT_KEEPALIVE_PACKET_SIZE;
391 
392  //Debug message
393  TRACE_INFO("Sending NAT keepalive packet (%" PRIuSIZE " bytes)...\r\n",
394  context->messageLen);
395 
396  //The sole purpose of sending NAT-keepalive packets is to keep NAT mappings
397  //alive for the duration of a connection between the peers
398  socketSendTo(context->altSocket, &sa->remoteIpAddr, IPSEC_NAT_PORT,
399  context->message, context->messageLen, NULL, 0);
400 
401  //Save the time at which the NAT-keepalive packet was sent
402  sa->natKeepAliveTimestamp = osGetSystemTime();
403 
404  //Successful processing
405  return NO_ERROR;
406 #else
407  //Minimal implementations are not required to support NAT traversal
408  return ERROR_NOT_IMPLEMENTED;
409 #endif
410 }
411 
412 
413 /**
414  * @brief Format IKE_SA_INIT request
415  * @param[in] sa Pointer to the IKE SA
416  * @param[out] p Buffer where to format the message
417  * @param[out] length Length of the resulting message, in bytes
418  * @return Error code
419  **/
420 
422 {
423  error_t error;
424  size_t n;
425  uint8_t *nextPayload;
426  IkeHeader *ikeHeader;
427 
428  //Total length of the message
429  *length = 0;
430 
431  //Each message begins with the IKE header
432  ikeHeader = (IkeHeader *) p;
433 
434  //In the first message of an initial IKE exchange, the initiator will not
435  //know the responder's SPI value and will therefore set that field to zero
436  //(refer to RFC 7296, section 2.6)
437  osMemset(sa->responderSpi, 0, IKE_SPI_SIZE);
438 
439  //Format IKE header
440  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
441  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
442  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
443  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
444  ikeHeader->minorVersion = IKE_MINOR_VERSION;
445  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_SA_INIT;
446  ikeHeader->flags = IKE_FLAGS_I;
447  ikeHeader->messageId = htonl(sa->txMessageId);
448 
449  //Keep track of the Next Payload field
450  nextPayload = &ikeHeader->nextPayload;
451 
452  //Point to the first IKE payload
453  p += sizeof(IkeHeader);
454  *length += sizeof(IkeHeader);
455 
456  //If the IKE_SA_INIT response includes the COOKIE notification, the
457  //initiator must then retry the IKE_SA_INIT request (refer to RFC 7296,
458  //section 2.6)
459  if(sa->cookieLen > 0)
460  {
461  //The initiator must include the COOKIE notification containing the
462  //received data as the first payload, and all other payloads unchanged
464  p, &n, &nextPayload);
465  //Any error to report?
466  if(error)
467  return error;
468 
469  //Point to the next payload
470  p += n;
471  *length += n;
472  }
473 
474  //The SAi payload states the cryptographic algorithms the initiator supports
475  //for the IKE SA (refer to RFC 7296, section 1.2)
476  error = ikeFormatSaPayload(sa, NULL, p, &n, &nextPayload);
477  //Any error to report?
478  if(error)
479  return error;
480 
481  //Point to the next payload
482  p += n;
483  *length += n;
484 
485  //The KEi payload sends the initiator's Diffie-Hellman value
486  error = ikeFormatKePayload(&sa->keContext, p, &n, &nextPayload);
487  //Any error to report?
488  if(error)
489  return error;
490 
491  //Point to the next payload
492  p += n;
493  *length += n;
494 
495  //The initiator sends its nonce in the Ni payload
496  error = ikeFormatNoncePayload(sa, NULL, p, &n, &nextPayload);
497  //Any error to report?
498  if(error)
499  return error;
500 
501  //Point to the next payload
502  p += n;
503  *length += n;
504 
505 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
506  //There MAY be multiple NAT_DETECTION_SOURCE_IP payloads in a message if the
507  //sender does not know which of several network attachments will be used to
508  //send the packet (refer to RFC 7296, section 2.23)
509  error = ikeFormatNotifyPayload(sa, NULL,
511  //Any error to report?
512  if(error)
513  return error;
514 
515  //Point to the next payload
516  p += n;
517  *length += n;
518 
519  //The NAT_DETECTION_DESTINATION_IP payloads can be used to detect if there is
520  //NAT between the hosts
521  error = ikeFormatNotifyPayload(sa, NULL,
523  //Any error to report?
524  if(error)
525  return error;
526 
527  //Point to the next payload
528  p += n;
529  *length += n;
530 #endif
531 
532 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
533  //The supported hash algorithms that can be used for the signature algorithms
534  //are indicated with a Notify payload of type SIGNATURE_HASH_ALGORITHMS sent
535  //inside the IKE_SA_INIT exchange (refer to RFC 7427, section 4)
536  error = ikeFormatNotifyPayload(sa, NULL,
538  //Any error to report?
539  if(error)
540  return error;
541 
542  //Total length of the message
543  *length += n;
544 #endif
545 
546  //The Length field indicates the total length of the IKE message in octets
547  ikeHeader->length = htonl(*length);
548 
549  //Save the first message (IKE_SA_INIT request), starting with the first
550  //octet of the first SPI in the header and ending with the last octet of
551  //the last payload
552  sa->initiatorSaInit = sa->request + IKE_PREFIX_SIZE;
553  sa->initiatorSaInitLen = *length;
554 
555  //Successful processing
556  return NO_ERROR;
557 }
558 
559 
560 /**
561  * @brief Format IKE_AUTH request
562  * @param[in] sa Pointer to the IKE SA
563  * @param[out] p Buffer where to format the message
564  * @param[out] length Length of the resulting message, in bytes
565  * @return Error code
566  **/
567 
569 {
570  error_t error;
571  size_t n;
572  uint8_t *nextPayload;
573  IkeHeader *ikeHeader;
574  IkeIdPayload *idPayload;
575 
576  //Total length of the message
577  *length = 0;
578 
579  //Each message begins with the IKE header
580  ikeHeader = (IkeHeader *) p;
581 
582  //Format IKE header
583  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
584  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
585  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
586  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
587  ikeHeader->minorVersion = IKE_MINOR_VERSION;
588  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_AUTH;
589  ikeHeader->flags = IKE_FLAGS_I;
590  ikeHeader->messageId = htonl(sa->txMessageId);
591 
592  //Keep track of the Next Payload field
593  nextPayload = &ikeHeader->nextPayload;
594 
595  //Point to the first IKE payload
596  p += sizeof(IkeHeader);
597  *length += sizeof(IkeHeader);
598 
599  //The initiator asserts its identity with the IDi payload (refer to RFC 7296,
600  //section 1.2)
601  error = ikeFormatIdPayload(sa, p, &n, &nextPayload);
602  //Any error to report?
603  if(error)
604  return error;
605 
606  //Point to the Identification payload
607  idPayload = (IkeIdPayload *) p;
608 
609  //Point to the next payload
610  p += n;
611  *length += n;
612 
613  //The initiator might send its certificate(s) in CERT payload(s)
614  error = ikeFormatCertPayloads(sa, p, &n, &nextPayload);
615  //Any error to report?
616  if(error)
617  return error;
618 
619  //Point to the next payload
620  p += n;
621  *length += n;
622 
623 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
624  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
625  //IKE SA currently active between the authenticated identities
626  if(ikeIsInitialContact(sa))
627  {
628  //It may be sent when an IKE SA is established after a crash, and the
629  //recipient may use this information to delete any other IKE SAs it
630  //has to the same authenticated identity without waiting for a timeout
631  error = ikeFormatNotifyPayload(sa, NULL,
633  //Any error to report?
634  if(error)
635  return error;
636 
637  //Point to the next payload
638  p += n;
639  *length += n;
640  }
641 #endif
642 
643  //The initiator might also send list of its trust anchors in CERTREQ
644  //payload(s)
645  error = ikeFormatCertReqPayload(sa, p, &n, &nextPayload);
646  //Any error to report?
647  if(error)
648  return error;
649 
650  //Point to the next payload
651  p += n;
652  *length += n;
653 
654  //The initiator proves knowledge of the secret corresponding to IDi and
655  //integrity protects the contents of the first message using the AUTH payload
656  error = ikeFormatAuthPayload(sa, idPayload, p, &n, &nextPayload);
657  //Any error to report?
658  if(error)
659  return error;
660 
661  //Point to the next payload
662  p += n;
663  *length += n;
664 
665  //Child SAs can be created either by being piggybacked on the IKE_AUTH
666  //exchange, or using a separate CREATE_CHILD_SA exchange
667  if(sa->childSa1 != NULL)
668  {
669  //Piggyback setup of the Child SA
670  error = ikeFormatChildSaCreateRequest(sa, p, &n, &nextPayload);
671  //Any error to report?
672  if(error)
673  return error;
674 
675  //Total length of the message
676  *length += n;
677  }
678 
679  //The Length field indicates the total length of the IKE message in octets
680  ikeHeader->length = htonl(*length);
681 
682  //Successful processing
683  return NO_ERROR;
684 }
685 
686 
687 /**
688  * @brief Format CREATE_CHILD_SA request
689  * @param[in] sa Pointer to the IKE SA
690  * @param[out] p Buffer where to format the message
691  * @param[out] length Length of the resulting message, in bytes
692  * @return Error code
693  **/
694 
696  size_t *length)
697 {
698 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
699  error_t error;
700  size_t n;
701  uint8_t *nextPayload;
702  IkeHeader *ikeHeader;
703 
704  //Total length of the message
705  *length = 0;
706 
707  //Each message begins with the IKE header
708  ikeHeader = (IkeHeader *) p;
709 
710  //Format IKE header
711  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
712  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
713  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
714  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
715  ikeHeader->minorVersion = IKE_MINOR_VERSION;
716  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_CREATE_CHILD_SA;
717  ikeHeader->messageId = htonl(sa->txMessageId);
718 
719  //This I bit must be set in messages sent by the original initiator of the
720  //IKE SA and must be cleared in messages sent by the original responder
721  if(sa->originalInitiator)
722  {
723  ikeHeader->flags = IKE_FLAGS_I;
724  }
725  else
726  {
727  ikeHeader->flags = 0;
728  }
729 
730  //Keep track of the Next Payload field
731  nextPayload = &ikeHeader->nextPayload;
732 
733  //Point to the first IKE payload
734  p += sizeof(IkeHeader);
735  *length += sizeof(IkeHeader);
736 
737  //The CREATE_CHILD_SA exchange is used to create new Child SAs and to rekey
738  //both IKE SAs and Child SAs (refer to RFC 7296, section 1.3)
739  if(sa->state == IKE_SA_STATE_REKEY_REQ)
740  {
741  //IKE SA rekeying
742  error = ikeFormatIkeSaRekeyRequest(sa, p, &n, &nextPayload);
743  }
744  else if(sa->state == IKE_SA_STATE_CREATE_CHILD_REQ ||
745  sa->state == IKE_SA_STATE_REKEY_CHILD_REQ)
746  {
747  //Child SA creation/rekeying
748  error = ikeFormatChildSaCreateRequest(sa, p, &n, &nextPayload);
749  }
750  else
751  {
752  //Report an error
753  error = ERROR_WRONG_STATE;
754  }
755 
756  //Check status code
757  if(!error)
758  {
759  //Total length of the message
760  *length += n;
761 
762  //The Length field indicates the total length of the IKE message in octets
763  ikeHeader->length = htonl(*length);
764  }
765 
766  //Return status code
767  return error;
768 #else
769  //Minimal implementations are not required to support the CREATE_CHILD_SA
770  //exchange (refer to RFC 7296, section 4)
771  return ERROR_NOT_IMPLEMENTED;
772 #endif
773 }
774 
775 
776 /**
777  * @brief Format INFORMATIONAL request
778  * @param[in] sa Pointer to the IKE SA
779  * @param[out] p Buffer where to format the message
780  * @param[out] length Length of the resulting message, in bytes
781  * @return Error code
782  **/
783 
785  size_t *length)
786 {
787  error_t error;
788  size_t n;
789  uint8_t *nextPayload;
790  IkeHeader *ikeHeader;
791 
792  //Total length of the message
793  *length = 0;
794 
795  //Each message begins with the IKE header
796  ikeHeader = (IkeHeader *) p;
797 
798  //Format IKE header
799  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
800  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
801  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
802  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
803  ikeHeader->minorVersion = IKE_MINOR_VERSION;
804  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
805  ikeHeader->messageId = htonl(sa->txMessageId);
806 
807  //This I bit must be set in messages sent by the original initiator of the
808  //IKE SA and must be cleared in messages sent by the original responder
809  if(sa->originalInitiator)
810  {
811  ikeHeader->flags = IKE_FLAGS_I;
812  }
813  else
814  {
815  ikeHeader->flags = 0;
816  }
817 
818  //Keep track of the Next Payload field
819  nextPayload = &ikeHeader->nextPayload;
820 
821  //Point to the first IKE payload
822  p += sizeof(IkeHeader);
823  *length += sizeof(IkeHeader);
824 
825  //Check the state of the IKE SA
826  if(sa->state == IKE_SA_STATE_DPD_REQ)
827  {
828  //An INFORMATIONAL request with no payloads is commonly used as a check
829  //for liveness (refer to RFC 7296, section 1)
830  }
831  else if(sa->state == IKE_SA_STATE_DELETE_REQ ||
832  sa->state == IKE_SA_STATE_DELETE_CHILD_REQ)
833  {
834  //To delete an SA, an INFORMATIONAL exchange with one or more Delete
835  //payloads is sent listing the SPIs (as they would be expected in the
836  //headers of inbound packets) of the SAs to be deleted
837  error = ikeFormatDeletePayload(sa, sa->childSa1, p, &n, &nextPayload);
838  //Any error to report?
839  if(error)
840  return error;
841 
842  //Total length of the message
843  *length += n;
844  }
845  else if(sa->state == IKE_SA_STATE_AUTH_FAILURE_REQ)
846  {
847  //All errors causing the authentication to fail for whatever reason
848  //(invalid shared secret, invalid ID, untrusted certificate issuer,
849  //revoked or expired certificate, etc.) should result in an
850  //AUTHENTICATION_FAILED notification
852  p, &n, &nextPayload);
853  //Any error to report?
854  if(error)
855  return error;
856 
857  //Total length of the message
858  *length += n;
859  }
860  else
861  {
862  //Just for sanity
863  }
864 
865  //The Length field indicates the total length of the IKE message in octets
866  ikeHeader->length = htonl(*length);
867 
868  //Successful processing
869  return NO_ERROR;
870 }
871 
872 
873 /**
874  * @brief Format Child SA creation/rekeying request
875  * @param[in] sa Pointer to the IKE SA
876  * @param[out] p Buffer where to format the payloads
877  * @param[out] length Length of the resulting payloads, in bytes
878  * @param[in,out] nextPayload Pointer to the Next Payload field
879  * @return Error code
880  **/
881 
883  size_t *length, uint8_t **nextPayload)
884 {
885  error_t error;
886  size_t n;
887  IkeChildSaEntry *childSa;
888 
889  //Point to the Child SA
890  childSa = sa->childSa1;
891 
892  //Total length of the payloads
893  *length = 0;
894 
895  //Child SA rekeying?
896  if(sa->state == IKE_SA_STATE_REKEY_CHILD_REQ)
897  {
898  //The REKEY_SA notification must be included in a CREATE_CHILD_SA exchange if
899  //the purpose of the exchange is to replace an existing ESP or AH SA (refer
900  //to RFC 7296, section 1.3.3)
901  error = ikeFormatNotifyPayload(sa, childSa,
903  //Any error to report?
904  if(error)
905  return error;
906 
907  //Point to the next payload
908  p += n;
909  *length += n;
910  }
911 
912  //The USE_TRANSPORT_MODE notification may be included in a request message
913  //that also includes an SA payload requesting a Child SA. It requests that
914  //the Child SA use transport mode rather than tunnel mode for the SA created
915  //(refer to RFC 7296, section 1.3.1)
916  if(childSa->mode == IPSEC_MODE_TRANSPORT)
917  {
918  //Include a notification of type USE_TRANSPORT_MODE
919  error = ikeFormatNotifyPayload(sa, childSa,
921  //Any error to report?
922  if(error)
923  return error;
924 
925  //Point to the next payload
926  p += n;
927  *length += n;
928  }
929 
930  //The initiator sends SA offers in the SAi payload
931  error = ikeFormatChildSaPayload(childSa, p, &n, nextPayload);
932  //Any error to report?
933  if(error)
934  return error;
935 
936  //Point to the next payload
937  p += n;
938  *length += n;
939 
940  //Child SA creation/rekeying?
941  if(sa->state == IKE_SA_STATE_CREATE_CHILD_REQ ||
942  sa->state == IKE_SA_STATE_REKEY_CHILD_REQ)
943  {
944  //The initiator sends a nonce in the Ni payload
945  error = ikeFormatNoncePayload(sa, childSa, p, &n, nextPayload);
946  //Any error to report?
947  if(error)
948  return error;
949 
950  //Point to the next payload
951  p += n;
952  *length += n;
953 
954 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
955  //Perfect forward secrecy?
956  if(childSa->pfs)
957  {
958  //Optionally, the initiator sends a Diffie-Hellman value in the KEi
959  //payload (refer to RFC 7296, section 1.3.1)
960  error = ikeFormatKePayload(&childSa->keContext, p, &n, nextPayload);
961  //Any error to report?
962  if(error)
963  return error;
964 
965  //Point to the next payload
966  p += n;
967  *length += n;
968  }
969 #endif
970  }
971 
972 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
973  //Child SA creation?
974  if(sa->state == IKE_SA_STATE_INIT_RESP ||
975  sa->state == IKE_SA_STATE_CREATE_CHILD_REQ)
976  {
977  //NAT detected?
978  if(sa->localNat || sa->remoteNat)
979  {
980  //Check if the client is proposing transport mode
981  if(childSa->mode == IPSEC_MODE_TRANSPORT)
982  {
983  //The TSi entries must have exactly one IP address, and that must
984  //match the source address of the IKE SA (refer to RFC 7296,
985  //section 2.23.1)
986  childSa->selector.localIpAddr.start = childSa->packetInfo.localIpAddr;
987  childSa->selector.localIpAddr.end = childSa->packetInfo.localIpAddr;
988 
989  //The TSr entries must have exactly one IP address, and that must
990  //match the destination address of the IKE SA
991  childSa->selector.remoteIpAddr.start = childSa->packetInfo.remoteIpAddr;
992  childSa->selector.remoteIpAddr.end = childSa->packetInfo.remoteIpAddr;
993  }
994  }
995  }
996 #endif
997 
998  //TSi specifies the source address of traffic forwarded from (or the
999  //destination address of traffic forwarded to) the initiator of the
1000  //Child SA pair
1001  error = ikeFormatTsiPayload(childSa, p, &n, nextPayload);
1002  //Any error to report?
1003  if(error)
1004  return error;
1005 
1006  //Point to the next payload
1007  p += n;
1008  *length += n;
1009 
1010  //TSr specifies the destination address of the traffic forwarded to (or
1011  //the source address of the traffic forwarded from) the responder of the
1012  //Child SA pair
1013  error = ikeFormatTsrPayload(childSa, p, &n, nextPayload);
1014  //Any error to report?
1015  if(error)
1016  return error;
1017 
1018  //Total length of the payloads
1019  *length += n;
1020 
1021  //Successful processing
1022  return NO_ERROR;
1023 }
1024 
1025 
1026 /**
1027  * @brief Format IKE SA rekeying request
1028  * @param[in] sa Pointer to the IKE SA
1029  * @param[out] p Buffer where to format the payloads
1030  * @param[out] length Length of the resulting payloads, in bytes
1031  * @param[in,out] nextPayload Pointer to the Next Payload field
1032  * @return Error code
1033  **/
1034 
1036  uint8_t **nextPayload)
1037 {
1038 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
1039  error_t error;
1040  size_t n;
1041  IkeSaEntry *newSa;
1042 
1043  //Point to the new IKE SA
1044  newSa = sa->newSa1;
1045 
1046  //Total length of the payloads
1047  *length = 0;
1048 
1049  //A new initiator SPI is supplied in the SPI field of the SA payload
1050  //(refer to 7296, section 1.3.2)
1051  error = ikeFormatSaPayload(newSa, newSa->initiatorSpi, p, &n, nextPayload);
1052  //Any error to report?
1053  if(error)
1054  return error;
1055 
1056  //Point to the next payload
1057  p += n;
1058  *length += n;
1059 
1060  //The initiator sends its nonce in the Ni payload
1061  error = ikeFormatNoncePayload(newSa, NULL, p, &n, nextPayload);
1062  //Any error to report?
1063  if(error)
1064  return error;
1065 
1066  //Point to the next payload
1067  p += n;
1068  *length += n;
1069 
1070  //The KEi payload sends the initiator's Diffie-Hellman value
1071  error = ikeFormatKePayload(&newSa->keContext, p, &n, nextPayload);
1072  //Any error to report?
1073  if(error)
1074  return error;
1075 
1076  //Total length of the payloads
1077  *length += n;
1078 
1079  //Successful processing
1080  return NO_ERROR;
1081 #else
1082  //Minimal implementations are not required to support the CREATE_CHILD_SA
1083  //exchange (refer to RFC 7296, section 4)
1084  return ERROR_NOT_IMPLEMENTED;
1085 #endif
1086 }
1087 
1088 #endif
#define IKE_PREFIX_SIZE
Definition: ike.h:816
error_t ikeSendIkeSaInitRequest(IkeSaEntry *sa)
Send IKE_SA_INIT request.
void ikeFreeKeContext(IkeKeContext *keContext)
Release key exchange context.
error_t ikeFormatCreateChildSaRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format CREATE_CHILD_SA request.
error_t ikeFormatIkeSaRekeyRequest(IkeSaEntry *sa, uint8_t *p, size_t *length, uint8_t **nextPayload)
Format IKE SA rekeying request.
Diffie-Hellman key exchange.
void ikeInitKeContext(IkeKeContext *keContext)
Initialize key exchange context.
error_t ikeFormatNoncePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Nonce payload.
error_t ikeFormatInfoRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format INFORMATIONAL request.
Helper functions for IKEv2.
error_t ikeComputeSharedSecret(IkeKeContext *keContext, uint8_t *output, size_t *outputLen)
Compute shared secret.
IKE payload formatting.
@ IKE_NOTIFY_MSG_TYPE_REKEY_SA
Definition: ike.h:1217
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
uint8_t p
Definition: ndp.h:300
IKE message encryption.
@ IKE_SA_STATE_DELETE_REQ
Definition: ike.h:1365
error_t ikeFormatChildSaPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Security Association payload (AH or ESP protocol)
error_t ikeFormatAuthPayload(IkeSaEntry *sa, const IkeIdPayload *idPayload, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Authentication payload.
IKEv2 finite state machine.
@ IKE_NOTIFY_MSG_TYPE_SIGNATURE_HASH_ALGORITHMS
Definition: ike.h:1255
error_t ikeFormatDeletePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Delete payload.
#define IPSEC_NAT_PORT
Definition: ipsec.h:142
@ IKE_NOTIFY_MSG_TYPE_NAT_DETECTION_SOURCE_IP
Definition: ike.h:1212
@ IKE_SA_STATE_REKEY_REQ
Definition: ike.h:1363
error_t ikeSendNatKeepalive(IkeSaEntry *sa)
Send NAT-keepalive packet.
@ ERROR_WRONG_STATE
Definition: error.h:210
error_t ikeFormatSaPayload(IkeSaEntry *sa, const uint8_t *spi, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Security Association payload (IKE protocol)
error_t ikeFormatIkeSaInitRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_SA_INIT request.
@ IKE_NOTIFY_MSG_TYPE_NAT_DETECTION_DESTINATION_IP
Definition: ike.h:1213
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
#define IkeContext
Definition: ike.h:832
@ IKE_EXCHANGE_TYPE_IKE_AUTH
IKE_AUTH.
Definition: ike.h:855
@ IKE_SA_STATE_DELETE_CHILD_RESP
Definition: ike.h:1372
#define htonl(value)
Definition: cpu_endian.h:414
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
Data logging functions for debugging purpose (IKEv2)
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:212
@ IKE_FLAGS_I
Initiator flag.
Definition: ike.h:876
error_t
Error codes.
Definition: error.h:43
IkeIdPayload
Definition: ike.h:1559
@ IKE_SA_STATE_AUTH_FAILURE_RESP
Definition: ike.h:1374
#define IKE_NAT_KEEPALIVE_PACKET_VALUE
Definition: ike.h:823
@ IKE_SA_STATE_REKEY_CHILD_REQ
Definition: ike.h:1369
#define IKE_MINOR_VERSION
Definition: ike.h:810
Key material generation.
error_t ikeSendInfoRequest(IkeSaEntry *sa)
Send INFORMATIONAL request.
#define IKE_SPI_SIZE
Definition: ike.h:826
#define IKE_MAJOR_VERSION
Definition: ike.h:808
#define IKE_PREFIX_VALUE
Definition: ike.h:818
error_t ikeFormatNotifyPayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, IkeNotifyMsgType notifyMsgType, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Notify payload.
error_t ikeSendIkeAuthRequest(IkeSaEntry *sa)
Send IKE_AUTH request.
error_t ikeFormatKePayload(IkeKeContext *keContext, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Key Exchange payload.
error_t ikeFormatTsiPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (initiator)
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
IkeHeader
Definition: ike.h:1459
@ IKE_EXCHANGE_TYPE_CREATE_CHILD_SA
CREATE_CHILD_SA.
Definition: ike.h:856
error_t ikeFormatIdPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Identification payload.
error_t ikeFormatCertPayloads(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate payloads.
error_t ikeSendCreateChildSaRequest(IkeSaEntry *sa)
Send CREATE_CHILD_SA request.
error_t ikeFormatIkeAuthRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_AUTH request.
IKEv2 (Internet Key Exchange Protocol)
error_t ikeSendRequest(IkeSaEntry *sa)
Send IKE request message.
@ IKE_SA_STATE_CREATE_CHILD_REQ
Definition: ike.h:1367
@ IKE_EXCHANGE_TYPE_IKE_SA_INIT
IKE_SA_INIT.
Definition: ike.h:854
#define IkeSaEntry
Definition: ike.h:836
error_t ikeEncryptMessage(IkeSaEntry *sa, uint8_t *message, size_t *messageLen)
Encrypt an outgoing IKE message.
uint8_t n
#define IKE_PORT
Definition: ike.h:813
@ IKE_SA_STATE_REKEY_CHILD_RESP
Definition: ike.h:1370
error_t ikeGenerateSaKeyMaterial(IkeSaEntry *sa, IkeSaEntry *oldSa)
Generate keying material for the IKE SA.
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_NOTIFY_MSG_TYPE_AUTH_FAILED
Definition: ike.h:1191
@ IKE_SA_STATE_AUTH_RESP
Definition: ike.h:1359
@ IKE_EXCHANGE_TYPE_INFORMATIONAL
INFORMATIONAL.
Definition: ike.h:857
@ IKE_PAYLOAD_TYPE_LAST
No Next Payload.
Definition: ike.h:886
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1357
@ IKE_NOTIFY_MSG_TYPE_INITIAL_CONTACT
Definition: ike.h:1208
error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags)
Send a datagram to a specific destination.
Definition: socket.c:1532
@ IKE_SA_STATE_AUTH_FAILURE_REQ
Definition: ike.h:1373
bool_t ikeIsInitialContact(IkeSaEntry *sa)
Test if the IKE SA is the only currently active with a given peer.
Definition: ike_misc.c:1625
uint8_t nextPayload
Definition: ike.h:1447
@ IKE_NOTIFY_MSG_TYPE_COOKIE
Definition: ike.h:1214
@ IKE_NOTIFY_MSG_TYPE_USE_TRANSPORT_MODE
Definition: ike.h:1215
@ IKE_SA_STATE_REKEY_RESP
Definition: ike.h:1364
@ IKE_SA_STATE_CREATE_CHILD_RESP
Definition: ike.h:1368
@ IKE_SA_STATE_DPD_RESP
Definition: ike.h:1362
error_t ikeFormatChildSaCreateRequest(IkeSaEntry *sa, uint8_t *p, size_t *length, uint8_t **nextPayload)
Format Child SA creation/rekeying request.
#define PRIuSIZE
#define osMemset(p, value, length)
Definition: os_port.h:141
#define IKE_NAT_KEEPALIVE_PACKET_SIZE
Definition: ike.h:821
void ikeDumpMessage(const uint8_t *message, size_t length)
Dump IKE message.
Definition: ike_debug.c:425
error_t ikeFormatCertReqPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate Request payload.
#define IkeChildSaEntry
Definition: ike.h:840
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
@ NO_ERROR
Success.
Definition: error.h:44
error_t ikeFormatTsrPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (responder)
Debugging facilities.
@ IKE_SA_STATE_DELETE_CHILD_REQ
Definition: ike.h:1371
IKE request formatting.
systime_t osGetSystemTime(void)
Retrieve system time.