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