ike_message_format.c
Go to the documentation of this file.
1 /**
2  * @file ike_message_format.c
3  * @brief IKE message formatting
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.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IKE_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ipsec/ipsec_misc.h"
36 #include "ike/ike.h"
37 #include "ike/ike_fsm.h"
38 #include "ike/ike_algorithms.h"
39 #include "ike/ike_message_format.h"
41 #include "ike/ike_payload_format.h"
42 #include "ike/ike_auth.h"
43 #include "ike/ike_key_exchange.h"
44 #include "ike/ike_key_material.h"
45 #include "ike/ike_dh_groups.h"
46 #include "ike/ike_misc.h"
47 #include "ike/ike_debug.h"
48 #include "ah/ah_algorithms.h"
49 #include "debug.h"
50 
51 //Check IKEv2 library configuration
52 #if (IKE_SUPPORT == ENABLED)
53 
54 
55 /**
56  * @brief Send IKE_SA_INIT request
57  * @param[in] sa Pointer to the IKE SA
58  * @return Error code
59  **/
60 
62 {
63  error_t error;
64  IkeContext *context;
65 
66  //Initialize status code
67  error = NO_ERROR;
68 
69  //Point to the IKE context
70  context = sa->context;
71 
72  //The Message ID is a 32-bit quantity, which is zero for the IKE_SA_INIT
73  //messages (including retries of the message due to responses such as
74  //COOKIE and INVALID_KE_PAYLOAD)
75  sa->txMessageId = 0;
76 
77  //Format IKE_SA_INIT request
78  error = ikeFormatIkeSaInitRequest(sa, sa->request, &sa->requestLen);
79 
80  //Check status code
81  if(!error)
82  {
83  //Debug message
84  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->requestLen);
85  //Dump IKE message for debugging purpose
86  ikeDumpMessage(sa->request, sa->requestLen);
87 
88  //Send IKE request
89  socketSendTo(context->socket, &sa->remoteIpAddr, sa->remotePort,
90  sa->request, sa->requestLen, NULL, 0);
91 
92  //Wait for the IKE_SA_INIT response from the responder
94  }
95 
96  //Return status code
97  return error;
98 }
99 
100 
101 /**
102  * @brief Send IKE_SA_INIT response
103  * @param[in] sa Pointer to the IKE SA
104  * @return Error code
105  **/
106 
108 {
109  error_t error;
110  IkeContext *context;
111 
112  //Initialize status code
113  error = NO_ERROR;
114 
115  //Point to the IKE context
116  context = sa->context;
117 
118  //Successful IKE SA creation?
119  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE)
120  {
121  //Save the first message (IKE_SA_INIT request), starting with the first
122  //octet of the first SPI in the header and ending with the last octet of
123  //the last payload
124  osMemcpy(sa->request, context->message, sa->initiatorSaInitLen);
125  sa->initiatorSaInit = sa->request;
126 
127  //Each endpoint chooses one of the two SPIs and must choose them so as to
128  //be unique identifiers of an IKE SA (refer to RFC 7296, section 2.6)
129  error = ikeGenerateSaSpi(sa, sa->responderSpi);
130 
131  //Check status code
132  if(!error)
133  {
134  //Nonces used in IKEv2 must be randomly chosen and must be at least
135  //128 bits in size (refer to RFC 7296, section 2.10)
136  error = ikeGenerateNonce(context, sa->responderNonce,
137  &sa->responderNonceLen);
138  }
139 
140  //Check status code
141  if(!error)
142  {
143  //Generate an ephemeral key pair
144  error = ikeGenerateDhKeyPair(sa);
145  }
146 
147  //Check status code
148  if(!error)
149  {
150  //Let g^ir be the Diffie-Hellman shared secret
151  error = ikeComputeDhSharedSecret(sa);
152  }
153 
154  //Check status code
155  if(!error)
156  {
157  //At this point in the negotiation, each party can generate a quantity
158  //called SKEYSEED, from which all keys are derived for that IKE SA
159  //(refer to RFC 7296, section 1.2)
160  error = ikeGenerateSaKeyMaterial(sa, NULL);
161  }
162  }
163  else
164  {
165  //When the IKE_SA_INIT exchange does not result in the creation of an
166  //IKE SA due to INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN, or COOKIE, the
167  //responder's SPI will be zero also in the response message (refer to
168  //RFC 7296, section 2.6)
169  osMemset(sa->responderSpi, 0, IKE_SPI_SIZE);
170  }
171 
172  //Check status code
173  if(!error)
174  {
175  //Format IKE_SA_INIT response
176  error = ikeFormatIkeSaInitResponse(sa, sa->response, &sa->responseLen);
177  }
178 
179  //Check status code
180  if(!error)
181  {
182  //Debug message
183  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->responseLen);
184  //Dump IKE message for debugging purpose
185  ikeDumpMessage(sa->response, sa->responseLen);
186 
187  //An implementation must respond to the address and port from which the
188  //request was received (refer to RFC 7296, section 2.11)
189  socketSendTo(context->socket, &context->remoteIpAddr, context->remotePort,
190  sa->response, sa->responseLen, NULL, 0);
191 
192  //In an IKE_SA_INIT exchange, any error notification causes the exchange
193  //to fail (refer to RFC 7296, section 2.21.1)
194  if(sa->notifyMsgType != IKE_NOTIFY_MSG_TYPE_NONE)
195  {
196  error = ERROR_UNEXPECTED_STATUS;
197  }
198  }
199 
200  //Check status code
201  if(!error)
202  {
203  //Wait for the IKE_AUTH request from the initiator
205  }
206  else
207  {
208  //The IKE_SA_INIT exchange has failed
209  ikeDeleteSaEntry(sa);
210  }
211 
212  //Return status code
213  return error;
214 }
215 
216 
217 /**
218  * @brief Send IKE_AUTH request
219  * @param[in] sa Pointer to the IKE SA
220  * @return Error code
221  **/
222 
224 {
225  error_t error;
226  IkeContext *context;
227 
228  //Point to the IKE context
229  context = sa->context;
230 
231  //Save the second message (IKE_SA_INIT response), starting with the first
232  //octet of the first SPI in the header and ending with the last octet of
233  //the last payload
234  osMemcpy(sa->response, context->message, sa->responderSaInitLen);
235  sa->responderSaInit = sa->response;
236 
237  //Save the first message (IKE_SA_INIT request), starting with the first
238  //octet of the first SPI in the header and ending with the last octet of
239  //the last payload
240  osMemcpy(context->message, sa->request, sa->initiatorSaInitLen);
241  sa->initiatorSaInit = context->message;
242 
243  //Let g^ir be the Diffie-Hellman shared secret
244  error = ikeComputeDhSharedSecret(sa);
245 
246  //Check status code
247  if(!error)
248  {
249  //At this point in the negotiation, each party can generate a quantity
250  //called SKEYSEED, from which all keys are derived for that IKE SA (refer
251  //to RFC 7296, section 1.2)
252  error = ikeGenerateSaKeyMaterial(sa, NULL);
253  }
254 
255  //Check status code
256  if(!error)
257  {
258  //Valid Child SA?
259  if(sa->childSa != NULL)
260  {
261  //Generate a new SPI for the Child SA
262  error = ikeGenerateChildSaSpi(sa->childSa, sa->childSa->localSpi);
263  }
264  }
265 
266  //Check status code
267  if(!error)
268  {
269  //The message ID is incremented for each subsequent exchange
270  sa->txMessageId++;
271 
272  //Format IKE_AUTH request
273  error = ikeFormatIkeAuthRequest(sa, sa->request, &sa->requestLen);
274  }
275 
276  //Check status code
277  if(!error)
278  {
279  //All messages following the initial exchange are cryptographically
280  //protected using the cryptographic algorithms and keys negotiated in
281  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
282  error = ikeEncryptMessage(sa, sa->request, &sa->requestLen);
283  }
284 
285  //Check status code
286  if(!error)
287  {
288  //Debug message
289  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->requestLen);
290  //Dump IKE message for debugging purpose
291  ikeDumpMessage(sa->request, sa->requestLen);
292 
293  //Send IKE request
294  socketSendTo(context->socket, &sa->remoteIpAddr, sa->remotePort,
295  sa->request, sa->requestLen, NULL, 0);
296 
297  //Wait for the IKE_AUTH response from the responder
299  }
300 
301  //Return status code
302  return error;
303 }
304 
305 
306 /**
307  * @brief Send IKE_AUTH response
308  * @param[in] sa Pointer to the IKE SA
309  * @return Error code
310  **/
311 
313 {
314  error_t error;
315  IkeContext *context;
316  IkeChildSaEntry *childSa;
317 
318  //Initialize status code
319  error = NO_ERROR;
320 
321  //Point to the IKE context
322  context = sa->context;
323  //Point to the Child SA
324  childSa = sa->childSa;
325 
326  //Save the second message (IKE_SA_INIT response), starting with the first
327  //octet of the first SPI in the header and ending with the last octet of
328  //the last payload
329  osMemcpy(context->message, sa->response, sa->responderSaInitLen);
330  sa->responderSaInit = context->message;
331 
332  //Successful Child SA creation?
333  if(childSa != NULL)
334  {
335  //For the first Child SA created, Ni and Nr are the nonces from the
336  //IKE_SA_INIT exchange (refer to RFC 7296, section 2.17)
337  osMemcpy(childSa->initiatorNonce, sa->initiatorNonce,
338  sa->initiatorNonceLen);
339  osMemcpy(childSa->responderNonce, sa->responderNonce,
340  sa->responderNonceLen);
341 
342  //Save the length of Ni and Nr nonces
343  childSa->initiatorNonceLen = sa->initiatorNonceLen;
344  childSa->responderNonceLen = sa->responderNonceLen;
345 
346  //A single Child SA is created by the IKE_AUTH exchange. Keying
347  //material for the Child SA must be taken from the expanded KEYMAT
348  //(refer to RFC 7296, section 2.17)
349  error = ikeGenerateChildSaKeyMaterial(childSa);
350  }
351 
352  //Check status code
353  if(!error)
354  {
355  //Format IKE_AUTH response
356  error = ikeFormatIkeAuthResponse(sa, sa->response, &sa->responseLen);
357  }
358 
359  //Check status code
360  if(!error)
361  {
362  //All messages following the initial exchange are cryptographically
363  //protected using the cryptographic algorithms and keys negotiated in
364  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
365  error = ikeEncryptMessage(sa, sa->response, &sa->responseLen);
366  }
367 
368  //Check status code
369  if(!error)
370  {
371  //Debug message
372  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->responseLen);
373  //Dump IKE message for debugging purpose
374  ikeDumpMessage(sa->response, sa->responseLen);
375 
376  //An implementation must respond to the address and port from which the
377  //request was received (refer to RFC 7296, section 2.11)
378  socketSendTo(context->socket, &context->remoteIpAddr, context->remotePort,
379  sa->response, sa->responseLen, NULL, 0);
380 
381  //If creating the Child SA during the IKE_AUTH exchange fails for some
382  //reason, the IKE SA is still created as usual (refer to RFC 7296,
383  //section 1.2)
384  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE ||
385  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN ||
386  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE ||
387  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED ||
388  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE ||
389  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED)
390  {
391  //The responder has sent the IKE_AUTH response
393 
394  //Successful Child SA creation?
395  if(childSa != NULL)
396  {
397  //Update the state of the Child SA
399 
400  //ESP and AH SAs exist in pairs (one in each direction), so two SAs
401  //are created in a single Child SA negotiation for them
402  ikeCreateIpsecSaPair(childSa);
403  }
404 
405 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
406  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
407  //IKE SA currently active between the authenticated identities
408  if(sa->initialContact)
409  {
410  //It may be sent when an IKE SA is established after a crash, and the
411  //recipient may use this information to delete any other IKE SAs it
412  //has to the same authenticated identity without waiting for a timeout
414 
415  //Reset flag
416  sa->initialContact = FALSE;
417  }
418 #endif
419  }
420  else if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD)
421  {
422  //An unsupported critical payload was included in the IKE_AUTH request
423  }
424  else
425  {
426  //Only authentication failures (AUTHENTICATION_FAILED) and malformed
427  //messages (INVALID_SYNTAX) lead to a deletion of the IKE SA without
428  //requiring an explicit INFORMATIONAL exchange carrying a Delete
429  //payload
431  }
432  }
433 
434  //Check status code
435  if(error)
436  {
437  //The IKE_AUTH exchange has failed
438  ikeDeleteSaEntry(sa);
439  }
440 
441  //Return status code
442  return error;
443 }
444 
445 
446 /**
447  * @brief Send CREATE_CHILD_SA request
448  * @param[in] sa Pointer to the IKE SA
449  * @param[in] childSa Pointer to the Child SA
450  * @return Error code
451  **/
452 
454 {
455  //Minimal implementations are not required to support the CREATE_CHILD_SA
456  //exchange (refer to RFC 7296, section 4)
457  return ERROR_NOT_IMPLEMENTED;
458 }
459 
460 
461 /**
462  * @brief Send CREATE_CHILD_SA response
463  * @param[in] sa Pointer to the IKE SA
464  * @param[in] childSa Pointer to the Child SA
465  * @return Error code
466  **/
467 
469 {
470  error_t error;
471  IkeContext *context;
472 
473  //Point to the IKE context
474  context = sa->context;
475 
476  //Format CREATE_CHILD_SA response
477  error = ikeFormatCreateChildSaResponse(sa, childSa, sa->response,
478  &sa->responseLen);
479 
480  //Check status code
481  if(!error)
482  {
483  //All messages following the initial exchange are cryptographically
484  //protected using the cryptographic algorithms and keys negotiated in
485  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
486  error = ikeEncryptMessage(sa, sa->response, &sa->responseLen);
487  }
488 
489  //Check status code
490  if(!error)
491  {
492  //Debug message
493  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->responseLen);
494  //Dump IKE message for debugging purpose
495  ikeDumpMessage(sa->response, sa->responseLen);
496 
497  //An implementation must respond to the address and port from which the
498  //request was received (refer to RFC 7296, section 2.11)
499  socketSendTo(context->socket, &context->remoteIpAddr, context->remotePort,
500  sa->response, sa->responseLen, NULL, 0);
501  }
502 
503  //Return status code
504  return error;
505 }
506 
507 
508 /**
509  * @brief Send INFORMATIONAL request
510  * @param[in] sa Pointer to the IKE SA
511  * @return Error code
512  **/
513 
515 {
516  error_t error;
517  IkeContext *context;
518 
519  //Point to the IKE context
520  context = sa->context;
521 
522  //The message ID is incremented for each subsequent exchange
523  sa->txMessageId++;
524 
525  //Format INFORMATIONAL request
526  error = ikeFormatInfoRequest(sa, sa->request, &sa->requestLen);
527 
528  //Check status code
529  if(!error)
530  {
531  //All messages following the initial exchange are cryptographically
532  //protected using the cryptographic algorithms and keys negotiated in
533  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
534  error = ikeEncryptMessage(sa, sa->request, &sa->requestLen);
535  }
536 
537  //Check status code
538  if(!error)
539  {
540  //Debug message
541  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->requestLen);
542  //Dump IKE message for debugging purpose
543  ikeDumpMessage(sa->request, sa->requestLen);
544 
545  //Send IKE request
546  socketSendTo(context->socket, &sa->remoteIpAddr, sa->remotePort,
547  sa->request, sa->requestLen, NULL, 0);
548 
549  //Wait for the INFORMATIONAL response
550  if(sa->state == IKE_SA_STATE_DPD_REQ)
551  {
553  }
554  else if(sa->state == IKE_SA_STATE_DELETE_REQ)
555  {
557  }
558  else if(sa->state == IKE_SA_STATE_DELETE_CHILD_REQ)
559  {
561  }
562  else if(sa->state == IKE_SA_STATE_AUTH_FAILURE_REQ)
563  {
565  }
566  else
567  {
568  //Just for sanity
569  }
570  }
571 
572  //Return status code
573  return error;
574 }
575 
576 
577 /**
578  * @brief Send INFORMATIONAL response
579  * @param[in] sa Pointer to the IKE SA
580  * @return Error code
581  **/
582 
584 {
585  error_t error;
586  uint_t i;
587  IkeContext *context;
588  IkeChildSaEntry *childSa;
589 
590  //Point to the IKE context
591  context = sa->context;
592 
593  //Format INFORMATIONAL response
594  error = ikeFormatInfoResponse(sa, sa->response, &sa->responseLen);
595 
596  //Check status code
597  if(!error)
598  {
599  //All messages following the initial exchange are cryptographically
600  //protected using the cryptographic algorithms and keys negotiated in
601  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
602  error = ikeEncryptMessage(sa, sa->response, &sa->responseLen);
603  }
604 
605  //Check status code
606  if(!error)
607  {
608  //Debug message
609  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", sa->responseLen);
610  //Dump IKE message for debugging purpose
611  ikeDumpMessage(sa->response, sa->responseLen);
612 
613  //An implementation must respond to the address and port from which the
614  //request was received (refer to RFC 7296, section 2.11)
615  socketSendTo(context->socket, &context->remoteIpAddr, context->remotePort,
616  sa->response, sa->responseLen, NULL, 0);
617  }
618 
619  //Check whether the IKE SA should be closed
620  if(sa->deleteReceived)
621  {
622  //Delete the IKE SA
623  ikeDeleteSaEntry(sa);
624  }
625 
626  //Loop through Child SA entries
627  for(i = 0; i < context->numChildSaEntries; i++)
628  {
629  //Point to the current Child SA
630  childSa = &context->childSa[i];
631 
632  //Check whether the Child SA should be closed
633  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
634  childSa->deleteReceived)
635  {
636  //Delete the Child SA
637  ikeDeleteChildSaEntry(childSa);
638  }
639  }
640 
641  //Return status code
642  return error;
643 }
644 
645 
646 /**
647  * @brief Send INFORMATIONAL response (outside of an IKE SA)
648  * @param[in] context Pointer to the IKE context
649  * @param[in] message Pointer to the received IKE message
650  * @param[in] length Length of the IKE message, in bytes
651  * @return Error code
652  **/
653 
655  size_t length)
656 {
657  error_t error;
658  IkeHeader ikeHeader;
659 
660  //Check the length of the IKE message
661  if(length >= sizeof(IkeHeader))
662  {
663  //Copy the IKE header
664  osMemcpy(&ikeHeader, message, sizeof(IkeHeader));
665 
666  //Format INFORMATIONAL response
667  error = ikeFormatErrorResponse(&ikeHeader, context->message,
668  &context->messageLen);
669 
670  //Check status code
671  if(!error)
672  {
673  //Debug message
674  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", context->messageLen);
675  //Dump IKE message for debugging purpose
676  ikeDumpMessage(context->message, context->messageLen);
677 
678  //The message is always sent without cryptographic protection. The message
679  //is a response message, and thus it is sent to the IP address and port
680  //from whence it came (refer to RFC 7296, section 1.5)
681  error = socketSendTo(context->socket, &context->remoteIpAddr,
682  context->remotePort, context->message, context->messageLen, NULL, 0);
683  }
684  }
685  else
686  {
687  //The length of the received IKE message is not valid
688  error = ERROR_INVALID_LENGTH;
689  }
690 
691  //Return status code
692  return error;
693 }
694 
695 
696 /**
697  * @brief Format IKE_SA_INIT request
698  * @param[in] sa Pointer to the IKE SA
699  * @param[out] p Buffer where to format the message
700  * @param[out] length Length of the resulting message, in bytes
701  * @return Error code
702  **/
703 
705 {
706  error_t error;
707  size_t n;
708  uint8_t *nextPayload;
709  IkeHeader *ikeHeader;
710 
711  //Total length of the message
712  *length = 0;
713 
714  //Each message begins with the IKE header
715  ikeHeader = (IkeHeader *) p;
716 
717  //In the first message of an initial IKE exchange, the initiator will not
718  //know the responder's SPI value and will therefore set that field to zero
719  //(refer to RFC 7296, section 2.6)
720  osMemset(sa->responderSpi, 0, IKE_SPI_SIZE);
721 
722  //Format IKE header
723  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
724  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
725  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
726  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
727  ikeHeader->minorVersion = IKE_MINOR_VERSION;
728  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_SA_INIT;
729  ikeHeader->flags = IKE_FLAGS_I;
730  ikeHeader->messageId = htonl(sa->txMessageId);
731 
732  //Keep track of the Next Payload field
733  nextPayload = &ikeHeader->nextPayload;
734 
735  //Point to the first IKE payload
736  p += sizeof(IkeHeader);
737  *length += sizeof(IkeHeader);
738 
739  //If the IKE_SA_INIT response includes the COOKIE notification, the
740  //initiator must then retry the IKE_SA_INIT request (refer to RFC 7296,
741  //section 2.6)
742  if(sa->cookieLen > 0)
743  {
744  //The initiator must include the COOKIE notification containing the
745  //received data as the first payload, and all other payloads unchanged
747  p, &n, &nextPayload);
748  //Any error to report?
749  if(error)
750  return error;
751 
752  //Point to the next payload
753  p += n;
754  *length += n;
755  }
756 
757  //The SAi payload states the cryptographic algorithms the initiator supports
758  //for the IKE SA (refer to RFC 7296, section 1.2)
759  error = ikeFormatSaPayload(sa, NULL, p, &n, &nextPayload);
760  //Any error to report?
761  if(error)
762  return error;
763 
764  //Point to the next payload
765  p += n;
766  *length += n;
767 
768  //The KEi payload sends the initiator's Diffie-Hellman value
769  error = ikeFormatKePayload(sa, p, &n, &nextPayload);
770  //Any error to report?
771  if(error)
772  return error;
773 
774  //Point to the next payload
775  p += n;
776  *length += n;
777 
778  //The initiator sends its nonce in the Ni payload
779  error = ikeFormatNoncePayload(sa, NULL, p, &n, &nextPayload);
780  //Any error to report?
781  if(error)
782  return error;
783 
784  //Point to the next payload
785  p += n;
786  *length += n;
787 
788 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
789  //The supported hash algorithms that can be used for the signature algorithms
790  //are indicated with a Notify payload of type SIGNATURE_HASH_ALGORITHMS sent
791  //inside the IKE_SA_INIT exchange (refer to RFC 7427, section 4)
792  error = ikeFormatNotifyPayload(sa, NULL,
794  //Any error to report?
795  if(error)
796  return error;
797 
798  //Total length of the message
799  *length += n;
800 #endif
801 
802  //The Length field indicates the total length of the IKE message in octets
803  ikeHeader->length = htonl(*length);
804 
805  //Save the length of the first message (IKE_SA_INIT request)
806  sa->initiatorSaInitLen = *length;
807 
808  //Successful processing
809  return NO_ERROR;
810 }
811 
812 
813 /**
814  * @brief Format IKE_SA_INIT response
815  * @param[in] sa Pointer to the IKE SA
816  * @param[out] p Buffer where to format the message
817  * @param[out] length Length of the resulting message, in bytes
818  * @return Error code
819  **/
820 
822 {
823  error_t error;
824  size_t n;
825  uint8_t *nextPayload;
826  IkeHeader *ikeHeader;
827 
828  //Total length of the message
829  *length = 0;
830 
831  //Each message begins with the IKE header
832  ikeHeader = (IkeHeader *) p;
833 
834  //Format IKE header
835  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
836  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
837  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
838  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
839  ikeHeader->minorVersion = IKE_MINOR_VERSION;
840  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_SA_INIT;
841  ikeHeader->flags = IKE_FLAGS_R;
842  ikeHeader->messageId = htonl(sa->rxMessageId);
843 
844  //Keep track of the Next Payload field
845  nextPayload = &ikeHeader->nextPayload;
846 
847  //Point to the first IKE payload
848  p += sizeof(IkeHeader);
849  *length += sizeof(IkeHeader);
850 
851  //Successful IKE SA creation?
852  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE)
853  {
854  //The responder chooses a cryptographic suite from the initiator's offered
855  //choices and expresses that choice in the SAr payload
856  error = ikeFormatSaPayload(sa, NULL, p, &n, &nextPayload);
857  //Any error to report?
858  if(error)
859  return error;
860 
861  //Point to the next payload
862  p += n;
863  *length += n;
864 
865  //The responder completes the Diffie-Hellman exchange with the KEr payload
866  error = ikeFormatKePayload(sa, p, &n, &nextPayload);
867  //Any error to report?
868  if(error)
869  return error;
870 
871  //Point to the next payload
872  p += n;
873  *length += n;
874 
875  //The responder sends its nonce in the Nr payload
876  error = ikeFormatNoncePayload(sa, NULL, p, &n, &nextPayload);
877  //Any error to report?
878  if(error)
879  return error;
880 
881  //Point to the next payload
882  p += n;
883  *length += n;
884 
885  //A CERTREQ payload can optionally be included
886  error = ikeFormatCertReqPayload(sa, p, &n, &nextPayload);
887  //Any error to report?
888  if(error)
889  return error;
890 
891  //Point to the next payload
892  p += n;
893  *length += n;
894 
895 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
896  //The hash algorithms that can be used for the signature algorithms
897  //are indicated with a Notify payload of type SIGNATURE_HASH_ALGORITHMS
898  //sent inside the IKE_SA_INIT exchange (refer to RFC 7427, section 4)
899  error = ikeFormatNotifyPayload(sa, NULL,
901  //Any error to report?
902  if(error)
903  return error;
904 
905  //Total length of the message
906  *length += n;
907 #endif
908  }
909  else
910  {
911  //In an IKE_SA_INIT exchange, any error notification causes the
912  //exchange to fail. Note that some error notifications such as COOKIE,
913  //INVALID_KE_PAYLOAD or INVALID_MAJOR_VERSION may lead to a subsequent
914  //successful exchange (refer to RFC 7296, section 2.21.1)
915  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
916  &nextPayload);
917 
918  //Total length of the message
919  *length += n;
920  }
921 
922  //The Length field indicates the total length of the IKE message in octets
923  ikeHeader->length = htonl(*length);
924 
925  //Save the length of the second message (IKE_SA_INIT response)
926  sa->responderSaInitLen = *length;
927 
928  //Successful processing
929  return NO_ERROR;
930 }
931 
932 
933 /**
934  * @brief Format IKE_AUTH request
935  * @param[in] sa Pointer to the IKE SA
936  * @param[out] p Buffer where to format the message
937  * @param[out] length Length of the resulting message, in bytes
938  * @return Error code
939  **/
940 
942 {
943  error_t error;
944  size_t n;
945  uint8_t *nextPayload;
946  IkeChildSaEntry *childSa;
947  IkeHeader *ikeHeader;
948  IkeIdPayload *idPayload;
949 
950  //Point to the Child SA
951  childSa = sa->childSa;
952 
953  //Total length of the message
954  *length = 0;
955 
956  //Each message begins with the IKE header
957  ikeHeader = (IkeHeader *) p;
958 
959  //Format IKE header
960  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
961  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
962  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
963  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
964  ikeHeader->minorVersion = IKE_MINOR_VERSION;
965  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_AUTH;
966  ikeHeader->flags = IKE_FLAGS_I;
967  ikeHeader->messageId = htonl(sa->txMessageId);
968 
969  //Keep track of the Next Payload field
970  nextPayload = &ikeHeader->nextPayload;
971 
972  //Point to the first IKE payload
973  p += sizeof(IkeHeader);
974  *length += sizeof(IkeHeader);
975 
976  //The initiator asserts its identity with the IDi payload (refer to RFC 7296,
977  //section 1.2)
978  error = ikeFormatIdPayload(sa, p, &n, &nextPayload);
979  //Any error to report?
980  if(error)
981  return error;
982 
983  //Point to the Identification payload
984  idPayload = (IkeIdPayload *) p;
985 
986  //Point to the next payload
987  p += n;
988  *length += n;
989 
990  //The initiator might send its certificate(s) in CERT payload(s)
991  error = ikeFormatCertPayloads(sa, p, &n, &nextPayload);
992  //Any error to report?
993  if(error)
994  return error;
995 
996  //Point to the next payload
997  p += n;
998  *length += n;
999 
1000 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
1001  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
1002  //IKE SA currently active between the authenticated identities
1003  if(ikeIsInitialContact(sa))
1004  {
1005  //It may be sent when an IKE SA is established after a crash, and the
1006  //recipient may use this information to delete any other IKE SAs it
1007  //has to the same authenticated identity without waiting for a timeout
1009  p, &n, &nextPayload);
1010  //Any error to report?
1011  if(error)
1012  return error;
1013 
1014  //Point to the next payload
1015  p += n;
1016  *length += n;
1017  }
1018 #endif
1019 
1020  //The initiator might also send list of its trust anchors in CERTREQ
1021  //payload(s)
1022  error = ikeFormatCertReqPayload(sa, p, &n, &nextPayload);
1023  //Any error to report?
1024  if(error)
1025  return error;
1026 
1027  //Point to the next payload
1028  p += n;
1029  *length += n;
1030 
1031  //The initiator proves knowledge of the secret corresponding to IDi and
1032  //integrity protects the contents of the first message using the AUTH payload
1033  error = ikeFormatAuthPayload(sa, idPayload, p, &n, &nextPayload);
1034  //Any error to report?
1035  if(error)
1036  return error;
1037 
1038  //Point to the next payload
1039  p += n;
1040  *length += n;
1041 
1042  //Child SAs can be created either by being piggybacked on the IKE_AUTH
1043  //exchange, or using a separate CREATE_CHILD_SA exchange
1044  if(childSa != NULL)
1045  {
1046  //The USE_TRANSPORT_MODE notification may be included in a request
1047  //message that also includes an SA payload requesting a Child SA. It
1048  //requests that the Child SA use transport mode rather than tunnel
1049  //mode for the SA created (refer to RFC 7296, section 1.3.1)
1050  if(childSa->mode == IPSEC_MODE_TRANSPORT)
1051  {
1052  //Include a notification of type USE_TRANSPORT_MODE
1053  error = ikeFormatNotifyPayload(sa, childSa,
1055  //Any error to report?
1056  if(error)
1057  return error;
1058 
1059  //Point to the next payload
1060  p += n;
1061  *length += n;
1062  }
1063 
1064  //The initiator begins negotiation of a Child SA using the SAi payload
1065  error = ikeFormatSaPayload(sa, childSa, p, &n, &nextPayload);
1066  //Any error to report?
1067  if(error)
1068  return error;
1069 
1070  //Point to the next payload
1071  p += n;
1072  *length += n;
1073 
1074  //TSi specifies the source address of traffic forwarded from (or the
1075  //destination address of traffic forwarded to) the initiator of the
1076  //Child SA pair
1077  error = ikeFormatTsiPayload(childSa, p, &n, &nextPayload);
1078  //Any error to report?
1079  if(error)
1080  return error;
1081 
1082  //Point to the next payload
1083  p += n;
1084  *length += n;
1085 
1086  //TSr specifies the destination address of the traffic forwarded to (or
1087  //the source address of the traffic forwarded from) the responder of the
1088  //Child SA pair
1089  error = ikeFormatTsrPayload(childSa, p, &n, &nextPayload);
1090  //Any error to report?
1091  if(error)
1092  return error;
1093 
1094  //Total length of the message
1095  *length += n;
1096  }
1097 
1098  //The Length field indicates the total length of the IKE message in octets
1099  ikeHeader->length = htonl(*length);
1100 
1101  //Successful processing
1102  return NO_ERROR;
1103 }
1104 
1105 
1106 /**
1107  * @brief Format IKE_AUTH response
1108  * @param[in] sa Pointer to the IKE SA
1109  * @param[out] p Buffer where to format the message
1110  * @param[out] length Length of the resulting message, in bytes
1111  * @return Error code
1112  **/
1113 
1115 {
1116  error_t error;
1117  size_t n;
1118  uint8_t *nextPayload;
1119  IkeChildSaEntry *childSa;
1120  IkeHeader *ikeHeader;
1121  IkeIdPayload *idPayload;
1122 
1123  //Point to the Child SA
1124  childSa = sa->childSa;
1125 
1126  //Total length of the message
1127  *length = 0;
1128 
1129  //Each message begins with the IKE header
1130  ikeHeader = (IkeHeader *) p;
1131 
1132  //Format IKE header
1133  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
1134  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
1135  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1136  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
1137  ikeHeader->minorVersion = IKE_MINOR_VERSION;
1138  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_AUTH;
1139  ikeHeader->flags = IKE_FLAGS_R;
1140  ikeHeader->messageId = htonl(sa->rxMessageId);
1141 
1142  //Keep track of the Next Payload field
1143  nextPayload = &ikeHeader->nextPayload;
1144 
1145  //Point to the first IKE payload
1146  p += sizeof(IkeHeader);
1147  *length += sizeof(IkeHeader);
1148 
1149  //If creating the Child SA during the IKE_AUTH exchange fails for some
1150  //reason, the IKE SA is still created as usual (refer to RFC 7296,
1151  //section 1.2)
1152  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE ||
1153  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN ||
1154  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE ||
1155  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED ||
1156  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE ||
1157  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED)
1158  {
1159  //The responder asserts its identity with the IDr payload (refer to
1160  //RFC 7296, section 1.2)
1161  error = ikeFormatIdPayload(sa, p, &n, &nextPayload);
1162  //Any error to report?
1163  if(error)
1164  return error;
1165 
1166  //Point to the Identification payload
1167  idPayload = (IkeIdPayload *) p;
1168 
1169  //Point to the next payload
1170  p += n;
1171  *length += n;
1172 
1173  //The responder optionally sends one or more certificates
1174  error = ikeFormatCertPayloads(sa, p, &n, &nextPayload);
1175  //Any error to report?
1176  if(error)
1177  return error;
1178 
1179  //Point to the next payload
1180  p += n;
1181  *length += n;
1182 
1183  //The responder authenticates its identity and protects the integrity
1184  //of the second message with the AUTH payload
1185  error = ikeFormatAuthPayload(sa, idPayload, p, &n, &nextPayload);
1186  //Any error to report?
1187  if(error)
1188  return error;
1189 
1190  //Point to the next payload
1191  p += n;
1192  *length += n;
1193 
1194  //The responder completes negotiation of a Child SA with additional fields
1195  if(childSa != NULL)
1196  {
1197  //The initiator can request that the Child SA use transport mode rather
1198  //than tunnel mode for the SA created
1199  if(childSa->mode == IPSEC_MODE_TRANSPORT)
1200  {
1201  //If the request is accepted, the response must also include a
1202  //notification of type USE_TRANSPORT_MODE
1203  error = ikeFormatNotifyPayload(sa, childSa,
1205  //Any error to report?
1206  if(error)
1207  return error;
1208 
1209  //Point to the next payload
1210  p += n;
1211  *length += n;
1212  }
1213 
1214  //The responder chooses a cryptographic suite from the initiator's
1215  //offered choices and expresses that choice in the SAr payload
1216  error = ikeFormatSaPayload(sa, sa->childSa, p, &n, &nextPayload);
1217  //Any error to report?
1218  if(error)
1219  return error;
1220 
1221  //Point to the next payload
1222  p += n;
1223  *length += n;
1224 
1225  //TSi specifies the source address of traffic forwarded from (or the
1226  //destination address of traffic forwarded to) the initiator of the
1227  //Child SA pair
1228  error = ikeFormatTsiPayload(childSa, p, &n, &nextPayload);
1229  //Any error to report?
1230  if(error)
1231  return error;
1232 
1233  //Point to the next payload
1234  p += n;
1235  *length += n;
1236 
1237  //TSr specifies the destination address of the traffic forwarded to (or
1238  //the source address of the traffic forwarded from) the responder of the
1239  //Child SA pair
1240  error = ikeFormatTsrPayload(childSa, p, &n, &nextPayload);
1241  //Any error to report?
1242  if(error)
1243  return error;
1244 
1245  //Total length of the message
1246  *length += n;
1247  }
1248  else
1249  {
1250  //Check whether the Child SA creation has failed
1251  if(sa->notifyMsgType != IKE_NOTIFY_MSG_TYPE_NONE)
1252  {
1253  //Format Notify payload
1254  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
1255  &nextPayload);
1256 
1257  //Total length of the message
1258  *length += n;
1259  }
1260  }
1261  }
1262  else
1263  {
1264  //If the failure is related to creating the IKE SA (for example, an
1265  //AUTHENTICATION_FAILED Notify error message is returned), the IKE SA
1266  //is not created
1267  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
1268  &nextPayload);
1269 
1270  //Total length of the message
1271  *length += n;
1272  }
1273 
1274  //The Length field indicates the total length of the IKE message in octets
1275  ikeHeader->length = htonl(*length);
1276 
1277  //Successful processing
1278  return NO_ERROR;
1279 }
1280 
1281 
1282 /**
1283  * @brief Format CREATE_CHILD_SA request
1284  * @param[in] sa Pointer to the IKE SA
1285  * @param[in] childSa Pointer to the Child SA
1286  * @param[out] p Buffer where to format the message
1287  * @param[out] length Length of the resulting message, in bytes
1288  * @return Error code
1289  **/
1290 
1292  uint8_t *p, size_t *length)
1293 {
1294  //Minimal implementations are not required to support the CREATE_CHILD_SA
1295  //exchange (refer to RFC 7296, section 4)
1296  return ERROR_NOT_IMPLEMENTED;
1297 }
1298 
1299 
1300 /**
1301  * @brief Format CREATE_CHILD_SA response
1302  * @param[in] sa Pointer to the IKE SA
1303  * @param[in] childSa Pointer to the Child SA
1304  * @param[out] p Buffer where to format the message
1305  * @param[out] length Length of the resulting message, in bytes
1306  * @return Error code
1307  **/
1308 
1310  uint8_t *p, size_t *length)
1311 {
1312  error_t error;
1313  size_t n;
1314  uint8_t *nextPayload;
1315  IkeHeader *ikeHeader;
1316 
1317  //Total length of the message
1318  *length = 0;
1319 
1320  //Each message begins with the IKE header
1321  ikeHeader = (IkeHeader *) p;
1322 
1323  //Format IKE header
1324  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
1325  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
1326  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1327  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
1328  ikeHeader->minorVersion = IKE_MINOR_VERSION;
1329  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_CREATE_CHILD_SA;
1330  ikeHeader->messageId = htonl(sa->rxMessageId);
1331 
1332  //This I bit must be set in messages sent by the original initiator of the
1333  //IKE SA and must be cleared in messages sent by the original responder
1334  if(sa->originalInitiator)
1335  {
1336  ikeHeader->flags = IKE_FLAGS_R | IKE_FLAGS_I;
1337  }
1338  else
1339  {
1340  ikeHeader->flags = IKE_FLAGS_R;
1341  }
1342 
1343  //Keep track of the Next Payload field
1344  nextPayload = &ikeHeader->nextPayload;
1345 
1346  //Point to the first IKE payload
1347  p += sizeof(IkeHeader);
1348  *length += sizeof(IkeHeader);
1349 
1350  //A minimal implementation may support the CREATE_CHILD_SA exchange only in
1351  //so far as to recognize requests and reject them with a Notify payload of
1352  //type NO_ADDITIONAL_SAS (refer to RFC 7296, section 4)
1354  p, &n, &nextPayload);
1355  //Any error to report?
1356  if(error)
1357  return error;
1358 
1359  //Total length of the message
1360  *length += n;
1361 
1362  //The Length field indicates the total length of the IKE message in octets
1363  ikeHeader->length = htonl(*length);
1364 
1365  //Successful processing
1366  return NO_ERROR;
1367 }
1368 
1369 
1370 /**
1371  * @brief Format INFORMATIONAL request
1372  * @param[in] sa Pointer to the IKE SA
1373  * @param[out] p Buffer where to format the message
1374  * @param[out] length Length of the resulting message, in bytes
1375  * @return Error code
1376  **/
1377 
1379  size_t *length)
1380 {
1381  error_t error;
1382  size_t n;
1383  uint8_t *nextPayload;
1384  IkeHeader *ikeHeader;
1385 
1386  //Total length of the message
1387  *length = 0;
1388 
1389  //Each message begins with the IKE header
1390  ikeHeader = (IkeHeader *) p;
1391 
1392  //Format IKE header
1393  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
1394  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
1395  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1396  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
1397  ikeHeader->minorVersion = IKE_MINOR_VERSION;
1398  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
1399  ikeHeader->messageId = htonl(sa->txMessageId);
1400 
1401  //This I bit must be set in messages sent by the original initiator of the
1402  //IKE SA and must be cleared in messages sent by the original responder
1403  if(sa->originalInitiator)
1404  {
1405  ikeHeader->flags = IKE_FLAGS_I;
1406  }
1407  else
1408  {
1409  ikeHeader->flags = 0;
1410  }
1411 
1412  //Keep track of the Next Payload field
1413  nextPayload = &ikeHeader->nextPayload;
1414 
1415  //Point to the first IKE payload
1416  p += sizeof(IkeHeader);
1417  *length += sizeof(IkeHeader);
1418 
1419  //Check the state of the IKE SA
1420  if(sa->state == IKE_SA_STATE_DPD_REQ)
1421  {
1422  //An INFORMATIONAL request with no payloads is commonly used as a check
1423  //for liveness (refer to RFC 7296, section 1)
1424  }
1425  else if(sa->state == IKE_SA_STATE_DELETE_REQ ||
1426  sa->state == IKE_SA_STATE_DELETE_CHILD_REQ)
1427  {
1428  //To delete an SA, an INFORMATIONAL exchange with one or more Delete
1429  //payloads is sent listing the SPIs (as they would be expected in the
1430  //headers of inbound packets) of the SAs to be deleted
1431  error = ikeFormatDeletePayload(sa, sa->childSa, p, &n, &nextPayload);
1432  //Any error to report?
1433  if(error)
1434  return error;
1435 
1436  //Total length of the message
1437  *length += n;
1438  }
1439  else if(sa->state == IKE_SA_STATE_AUTH_FAILURE_REQ)
1440  {
1441  //All errors causing the authentication to fail for whatever reason
1442  //(invalid shared secret, invalid ID, untrusted certificate issuer,
1443  //revoked or expired certificate, etc.) should result in an
1444  //AUTHENTICATION_FAILED notification
1446  p, &n, &nextPayload);
1447  //Any error to report?
1448  if(error)
1449  return error;
1450 
1451  //Total length of the message
1452  *length += n;
1453  }
1454  else
1455  {
1456  //Just for sanity
1457  }
1458 
1459  //The Length field indicates the total length of the IKE message in octets
1460  ikeHeader->length = htonl(*length);
1461 
1462  //Successful processing
1463  return NO_ERROR;
1464 }
1465 
1466 
1467 /**
1468  * @brief Format INFORMATIONAL response
1469  * @param[in] sa Pointer to the IKE SA
1470  * @param[out] p Buffer where to format the message
1471  * @param[out] length Length of the resulting message, in bytes
1472  * @return Error code
1473  **/
1474 
1476  size_t *length)
1477 {
1478  uint_t i;
1479  size_t n;
1480  uint8_t *nextPayload;
1481  IkeContext *context;
1482  IkeChildSaEntry *childSa;
1483  IkeHeader *ikeHeader;
1484  IkeDeletePayload *deletePayload;
1485 
1486  //Point to the IKE context
1487  context = sa->context;
1488 
1489  //Total length of the message
1490  *length = 0;
1491 
1492  //Each message begins with the IKE header
1493  ikeHeader = (IkeHeader *) p;
1494 
1495  //Format IKE header
1496  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
1497  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
1498  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1499  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
1500  ikeHeader->minorVersion = IKE_MINOR_VERSION;
1501  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
1502  ikeHeader->messageId = htonl(sa->rxMessageId);
1503 
1504  //This I bit must be set in messages sent by the original initiator of the
1505  //IKE SA and must be cleared in messages sent by the original responder
1506  if(sa->originalInitiator)
1507  {
1508  ikeHeader->flags = IKE_FLAGS_R | IKE_FLAGS_I;
1509  }
1510  else
1511  {
1512  ikeHeader->flags = IKE_FLAGS_R;
1513  }
1514 
1515  //Keep track of the Next Payload field
1516  nextPayload = &ikeHeader->nextPayload;
1517 
1518  //Point to the first IKE payload
1519  p += sizeof(IkeHeader);
1520  *length += sizeof(IkeHeader);
1521 
1522  //Point to the Delete payload header
1523  deletePayload = (IkeDeletePayload *) p;
1524 
1525  //Format Delete payload header
1526  deletePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1527  deletePayload->header.critical = FALSE;
1528  deletePayload->header.reserved = 0;
1529  deletePayload->protocolId = IKE_PROTOCOL_ID_AH;
1530  deletePayload->spiSize = IPSEC_SPI_SIZE;
1531  deletePayload->numSpi = 0;
1532 
1533  //Length of the SPI list
1534  n = 0;
1535 
1536  //Loop through Child SA entries
1537  for(i = 0; i < context->numChildSaEntries; i++)
1538  {
1539  //Point to the current Child SA
1540  childSa = &context->childSa[i];
1541 
1542  //Check the state of the Child SA
1543  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
1544  childSa->protocol == IPSEC_PROTOCOL_AH &&
1545  childSa->deleteReceived)
1546  {
1547  //The SPI is the SPI the sending endpoint would expect in inbound ESP
1548  //or AH packets
1549  osMemcpy(deletePayload->spi + n, childSa->localSpi, IPSEC_SPI_SIZE);
1550  n += IPSEC_SPI_SIZE;
1551 
1552  //Increment the number of SPIs
1553  deletePayload->numSpi++;
1554  }
1555  }
1556 
1557  //Any SPI included in the Delete payload?
1558  if(n > 0)
1559  {
1560  //Calculate the length of the Delete payload
1561  n += sizeof(IkeDeletePayload);
1562 
1563  //Fix the Next Payload field of the previous payload
1565 
1566  //Fix the Payload Length field of the payload header
1567  deletePayload->header.payloadLength = htons(n);
1568  //Convert the number of SPIs to network byte order
1569  deletePayload->numSpi = htons(deletePayload->numSpi);
1570 
1571  //Keep track of the Next Payload field
1572  nextPayload = &deletePayload->header.nextPayload;
1573 
1574  //Point to the next payload
1575  p += n;
1576  *length += n;
1577  }
1578 
1579  //Point to the Delete payload header
1580  deletePayload = (IkeDeletePayload *) p;
1581 
1582  //Format Delete payload header
1583  deletePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1584  deletePayload->header.critical = FALSE;
1585  deletePayload->header.reserved = 0;
1586  deletePayload->protocolId = IKE_PROTOCOL_ID_ESP;
1587  deletePayload->spiSize = IPSEC_SPI_SIZE;
1588  deletePayload->numSpi = 0;
1589 
1590  //Length of the SPI list
1591  n = 0;
1592 
1593  //Loop through Child SA entries
1594  for(i = 0; i < context->numChildSaEntries; i++)
1595  {
1596  //Point to the current Child SA
1597  childSa = &context->childSa[i];
1598 
1599  //Check the state of the Child SA
1600  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
1601  childSa->protocol == IPSEC_PROTOCOL_ESP &&
1602  childSa->deleteReceived)
1603  {
1604  //The SPI is the SPI the sending endpoint would expect in inbound ESP
1605  //or AH packets
1606  osMemcpy(deletePayload->spi + n, childSa->localSpi, IPSEC_SPI_SIZE);
1607  n += IPSEC_SPI_SIZE;
1608 
1609  //Increment the number of SPIs
1610  deletePayload->numSpi++;
1611  }
1612  }
1613 
1614  //Any SPI included in the Delete payload?
1615  if(n > 0)
1616  {
1617  //Calculate the length of the Delete payload
1618  n += sizeof(IkeDeletePayload);
1619 
1620  //Fix the Next Payload field of the previous payload
1622 
1623  //Fix the Payload Length field of the payload header
1624  deletePayload->header.payloadLength = htons(n);
1625  //Convert the number of SPIs to network byte order
1626  deletePayload->numSpi = htons(deletePayload->numSpi);
1627 
1628  //Keep track of the Next Payload field
1629  nextPayload = &deletePayload->header.nextPayload;
1630 
1631  //Point to the next payload
1632  p += n;
1633  *length += n;
1634  }
1635 
1636  //The Length field indicates the total length of the IKE message in octets
1637  ikeHeader->length = htonl(*length);
1638 
1639  //Successful processing
1640  return NO_ERROR;
1641 }
1642 
1643 
1644 /**
1645  * @brief Format INFORMATIONAL response (outside of an IKE SA)
1646  * @param[in] requestHeader Pointer to the IKE header of the request
1647  * @param[out] p Buffer where to format the message
1648  * @param[out] length Length of the resulting message, in bytes
1649  * @return Error code
1650  **/
1651 
1652 error_t ikeFormatErrorResponse(IkeHeader *requestHeader, uint8_t *p,
1653  size_t *length)
1654 {
1655  error_t error;
1656  size_t n;
1658  uint8_t *nextPayload;
1659  IkeHeader *responseHeader;
1660 
1661  //Total length of the message
1662  *length = 0;
1663 
1664  //Each message begins with the IKE header
1665  responseHeader = (IkeHeader *) p;
1666 
1667  //The IKE SPIs are copied from the request
1668  osMemcpy(responseHeader->initiatorSpi, requestHeader->initiatorSpi,
1669  IKE_SPI_SIZE);
1670  osMemcpy(responseHeader->responderSpi, requestHeader->responderSpi,
1671  IKE_SPI_SIZE);
1672 
1673  //The Response flag is set to 1, and the version flags are set in the
1674  //normal fashion (refer to RFC 7296, section 1.5)
1675  responseHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1676  responseHeader->majorVersion = IKE_MAJOR_VERSION;
1677  responseHeader->minorVersion = IKE_MINOR_VERSION;
1678  responseHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
1679  responseHeader->flags = IKE_FLAGS_R;
1680  responseHeader->messageId = requestHeader->messageId;
1681 
1682  //Keep track of the Next Payload field
1683  nextPayload = &responseHeader->nextPayload;
1684 
1685  //Point to the first IKE payload
1686  p += sizeof(IkeHeader);
1687  *length += sizeof(IkeHeader);
1688 
1689  //The message includes either an INVALID_IKE_SPI or an INVALID_MAJOR_VERSION
1690  //notification (with no notification data)
1691  if(requestHeader->majorVersion > IKE_MAJOR_VERSION)
1692  {
1694  }
1695  else
1696  {
1698  }
1699 
1700  //Format Notify payload
1701  error = ikeFormatNotifyPayload(NULL, NULL, notifyMsgType, p, &n,
1702  &nextPayload);
1703  //Any error to report?
1704  if(error)
1705  return error;
1706 
1707  //Total length of the message
1708  *length += n;
1709 
1710  //The Length field indicates the total length of the IKE message in octets
1711  responseHeader->length = htonl(*length);
1712 
1713  //Successful processing
1714  return NO_ERROR;
1715 }
1716 
1717 #endif
AH algorithm negotiation.
#define htons(value)
Definition: cpu_endian.h:413
#define IPSEC_SPI_SIZE
Definition: ipsec.h:138
Diffie-Hellman key exchange.
error_t ikeFormatNoncePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Nonce payload.
Authentication of the IKE SA.
Helper functions for IKEv2.
IKE message formatting.
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:192
IKE payload formatting.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN
Definition: ike.h:1133
uint8_t p
Definition: ndp.h:300
uint8_t message[]
Definition: chap.h:154
error_t ikeGenerateSaSpi(IkeSaEntry *sa, uint8_t *spi)
Generate a new IKE SA SPI.
Definition: ike_misc.c:530
IKE message encryption.
@ IKE_SA_STATE_DELETE_REQ
Definition: ike.h:1296
error_t ikeSendCreateChildSaResponse(IkeSaEntry *sa, IkeChildSaEntry *childSa)
Send CREATE_CHILD_SA response.
error_t ikeFormatIkeAuthResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_AUTH response.
@ IKE_PROTOCOL_ID_AH
AH protocol.
Definition: ike.h:887
error_t ikeFormatSaPayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Security Association payload.
error_t ikeFormatInfoRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format INFORMATIONAL request.
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:1197
error_t ikeFormatIkeSaInitRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_SA_INIT request.
error_t ikeFormatDeletePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Delete payload.
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:193
error_t ikeFormatInfoResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format INFORMATIONAL response.
@ IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE
Definition: ike.h:1140
error_t ikeSendIkeAuthRequest(IkeSaEntry *sa)
Send IKE_AUTH request.
error_t ikeFormatIkeSaInitResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_SA_INIT response.
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
#define IkeContext
Definition: ike.h:796
@ IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED
Definition: ike.h:1139
@ IKE_EXCHANGE_TYPE_IKE_AUTH
IKE_AUTH.
Definition: ike.h:819
@ IKE_SA_STATE_DELETE_CHILD_RESP
Definition: ike.h:1303
error_t ikeFormatCreateChildSaRequest(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *length)
Format CREATE_CHILD_SA request.
#define FALSE
Definition: os_port.h:46
#define htonl(value)
Definition: cpu_endian.h:414
uint16_t notifyMsgType
Definition: ike.h:1561
@ ERROR_UNEXPECTED_STATUS
Definition: error.h:284
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t ikeComputeDhSharedSecret(IkeSaEntry *sa)
Compute Diffie-Hellman shared secret.
Data logging functions for debugging purpose (IKEv2)
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:205
error_t ikeSendIkeSaInitResponse(IkeSaEntry *sa)
Send IKE_SA_INIT response.
@ IKE_FLAGS_I
Initiator flag.
Definition: ike.h:835
@ IKE_SA_STATE_OPEN
Definition: ike.h:1291
error_t
Error codes.
Definition: error.h:43
IkeIdPayload
Definition: ike.h:1490
@ IKE_SA_STATE_AUTH_FAILURE_RESP
Definition: ike.h:1305
#define IKE_MINOR_VERSION
Definition: ike.h:782
error_t ikeFormatCreateChildSaResponse(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *length)
Format CREATE_CHILD_SA response.
Key material generation.
#define IKE_SPI_SIZE
Definition: ike.h:790
error_t ikeSendErrorResponse(IkeContext *context, uint8_t *message, size_t length)
Send INFORMATIONAL response (outside of an IKE SA)
Helper routines for IPsec.
#define IKE_MAJOR_VERSION
Definition: ike.h:780
error_t ikeSendInfoRequest(IkeSaEntry *sa)
Send INFORMATIONAL request.
@ IKE_SA_STATE_AUTH_REQ
Definition: ike.h:1289
@ IKE_PROTOCOL_ID_ESP
ESP protocol.
Definition: ike.h:888
@ ERROR_INVALID_LENGTH
Definition: error.h:111
error_t ikeFormatNotifyPayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, IkeNotifyMsgType notifyMsgType, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Notify payload.
void ikeDeleteSaEntry(IkeSaEntry *sa)
Delete an IKE Security Association.
Definition: ike_misc.c:298
void ikeDeleteDuplicateSaEntries(IkeSaEntry *sa)
Delete an duplicate IKE Security Associations.
Definition: ike_misc.c:353
error_t ikeFormatTsiPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (initiator)
error_t ikeSendIkeAuthResponse(IkeSaEntry *sa)
Send IKE_AUTH response.
void ikeDeleteChildSaEntry(IkeChildSaEntry *childSa)
Delete a Child Security Association.
Definition: ike_misc.c:501
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
IkeHeader
Definition: ike.h:1390
@ IKE_EXCHANGE_TYPE_CREATE_CHILD_SA
CREATE_CHILD_SA.
Definition: ike.h:820
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.
void ikeChangeChildSaState(IkeChildSaEntry *childSa, IkeChildSaState newState)
Update Child SA state.
Definition: ike_fsm.c:108
@ IKE_CHILD_SA_STATE_CLOSED
Definition: ike.h:1315
error_t ikeGenerateDhKeyPair(IkeSaEntry *sa)
Diffie-Hellman key pair generation.
IkeDeletePayload
Definition: ike.h:1577
IKEv2 (Internet Key Exchange Protocol)
error_t ikeFormatErrorResponse(IkeHeader *requestHeader, uint8_t *p, size_t *length)
Format INFORMATIONAL response (outside of an IKE SA)
error_t ikeCreateIpsecSaPair(IkeChildSaEntry *childSa)
Create AH or ESP SA pair.
Definition: ike_misc.c:1026
@ IKE_EXCHANGE_TYPE_IKE_SA_INIT
IKE_SA_INIT.
Definition: ike.h:818
#define IkeSaEntry
Definition: ike.h:800
@ IKE_NOTIFY_MSG_TYPE_NO_ADDITIONAL_SAS
Definition: ike.h:1137
@ IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD
Definition: ike.h:1127
error_t ikeGenerateChildSaKeyMaterial(IkeChildSaEntry *childSa)
Generate keying material for the Child SA.
error_t ikeEncryptMessage(IkeSaEntry *sa, uint8_t *message, size_t *messageLen)
Encrypt an outgoing IKE message.
uint8_t n
@ IKE_NOTIFY_MSG_TYPE_NONE
Definition: ike.h:1126
error_t ikeFormatKePayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Key Exchange payload.
error_t ikeSendIkeSaInitRequest(IkeSaEntry *sa)
Send IKE_SA_INIT request.
error_t ikeGenerateSaKeyMaterial(IkeSaEntry *sa, IkeSaEntry *oldSa)
Generate keying material for the IKE SA.
@ ERROR_AUTHENTICATION_FAILED
Definition: error.h:69
error_t ikeGenerateChildSaSpi(IkeChildSaEntry *childSa, uint8_t *spi)
Generate a new Child SA SPI.
Definition: ike_misc.c:615
error_t ikeFormatIkeAuthRequest(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_AUTH request.
@ IKE_SA_STATE_DPD_REQ
Definition: ike.h:1292
@ IKE_SA_STATE_DELETE_RESP
Definition: ike.h:1297
@ IKE_NOTIFY_MSG_TYPE_AUTH_FAILED
Definition: ike.h:1135
@ IKE_SA_STATE_AUTH_RESP
Definition: ike.h:1290
@ IKE_EXCHANGE_TYPE_INFORMATIONAL
INFORMATIONAL.
Definition: ike.h:821
@ IKE_PAYLOAD_TYPE_LAST
No Next Payload.
Definition: ike.h:845
IkeNotifyMsgType
Notify message types.
Definition: ike.h:1125
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1288
@ IKE_NOTIFY_MSG_TYPE_INITIAL_CONTACT
Definition: ike.h:1150
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:1512
@ IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE
Definition: ike.h:1138
@ IKE_SA_STATE_AUTH_FAILURE_REQ
Definition: ike.h:1304
bool_t ikeIsInitialContact(IkeSaEntry *sa)
Test if the IKE SA is the only currently active with a given peer.
Definition: ike_misc.c:1152
uint8_t nextPayload
Definition: ike.h:1378
@ IKE_NOTIFY_MSG_TYPE_COOKIE
Definition: ike.h:1156
@ IKE_FLAGS_R
Response flag.
Definition: ike.h:833
@ IKE_NOTIFY_MSG_TYPE_USE_TRANSPORT_MODE
Definition: ike.h:1157
error_t ikeGenerateNonce(IkeContext *context, uint8_t *nonce, size_t *length)
Generate a new nonce.
Definition: ike_misc.c:689
@ IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED
Definition: ike.h:1136
@ IKE_SA_STATE_DPD_RESP
Definition: ike.h:1293
error_t ikeSendInfoResponse(IkeSaEntry *sa)
Send INFORMATIONAL response.
Diffie-Hellman groups.
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:57
@ IKE_PAYLOAD_TYPE_D
Delete.
Definition: ike.h:855
#define osMemset(p, value, length)
Definition: os_port.h:138
@ IKE_NOTIFY_MSG_TYPE_INVALID_MAJOR_VERSION
Definition: ike.h:1129
void ikeDumpMessage(const uint8_t *message, size_t length)
Dump IKE message.
Definition: ike_debug.c:385
@ IKE_NOTIFY_MSG_TYPE_INVALID_IKE_SPI
Definition: ike.h:1128
error_t ikeFormatCertReqPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate Request payload.
#define IkeChildSaEntry
Definition: ike.h:804
IKEv2 algorithm negotiation.
@ 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:1302
@ IKE_CHILD_SA_STATE_OPEN
Definition: ike.h:1318
error_t ikeSendCreateChildSaRequest(IkeSaEntry *sa, IkeChildSaEntry *childSa)
Send CREATE_CHILD_SA request.