ike_response_format.c
Go to the documentation of this file.
1 /**
2  * @file ike_response_format.c
3  * @brief IKE response formatting
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IKE_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ike/ike.h"
36 #include "ike/ike_fsm.h"
39 #include "ike/ike_payload_format.h"
40 #include "ike/ike_key_exchange.h"
41 #include "ike/ike_key_material.h"
42 #include "ike/ike_misc.h"
43 #include "ike/ike_debug.h"
44 #include "debug.h"
45 
46 //Check IKEv2 library configuration
47 #if (IKE_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Send IKE response
52  * @param[in] context Pointer to the IKE context
53  * @param[in] message Pointer to the IKE message
54  * @param[in] length Length of the IKE message, in bytes
55  * @return Error code
56  **/
57 
58 error_t ikeSendResponse(IkeContext *context, const uint8_t *message,
59  size_t length)
60 {
61  error_t error;
62  SocketMsg msg;
63 
64  //Debug message
65  TRACE_INFO("Sending IKE message (%" PRIuSIZE " bytes)...\r\n", length);
66  //Dump IKE message for debugging purpose
68 
69  //An implementation must specify the address and port at which the request
70  //was received as the source address and port in the response (refer to
71  //RFC 7296, section 2.11)
72  msg = SOCKET_DEFAULT_MSG;
73  msg.interface = context->localInterface;
74  msg.srcIpAddr = context->localIpAddr;
75  msg.destIpAddr = context->remoteIpAddr;
76  msg.destPort = context->remotePort;
77 
78 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
79  //IKE packets must be sent from UDP port 500 or 4500
80  if(context->localPort == IPSEC_NAT_PORT)
81  {
82  //The UDP payload of all packets containing IKE messages sent on port 4500
83  //must begin with the prefix of four zeros (refer to RFC 7296, section 2)
84  msg.data = (uint8_t *) message - IKE_PREFIX_SIZE;
86 
87  //Send IKE message from UDP port 4500
88  error = socketSendMsg(context->altSocket, &msg, 0);
89  }
90  else
91 #endif
92  {
93  //Point to the IKE message to be transmitted
94  msg.data = (uint8_t *) message;
95  msg.length = length;
96 
97  //Send IKE message from UDP port 500
98  error = socketSendMsg(context->socket, &msg, 0);
99  }
100 
101  //Return status code
102  return error;
103 }
104 
105 
106 /**
107  * @brief Send IKE_SA_INIT response
108  * @param[in] sa Pointer to the IKE SA
109  * @return Error code
110  **/
111 
113 {
114  error_t error;
115  IkeContext *context;
116 
117  //Initialize status code
118  error = NO_ERROR;
119 
120  //Point to the IKE context
121  context = sa->context;
122 
123  //Successful IKE SA creation?
124  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE)
125  {
126  //Save the first message (IKE_SA_INIT request), starting with the first
127  //octet of the first SPI in the header and ending with the last octet of
128  //the last payload
129  osMemcpy(sa->request, sa->initiatorSaInit, sa->initiatorSaInitLen);
130  sa->initiatorSaInit = sa->request;
131 
132  //Each endpoint chooses one of the two SPIs and must choose them so as to
133  //be unique identifiers of an IKE SA (refer to RFC 7296, section 2.6)
134  error = ikeGenerateSaSpi(sa, sa->responderSpi);
135 
136  //Check status code
137  if(!error)
138  {
139  //Nonces used in IKEv2 must be randomly chosen and must be at least
140  //128 bits in size (refer to RFC 7296, section 2.10)
141  error = ikeGenerateNonce(context, sa->responderNonce,
142  &sa->responderNonceLen);
143  }
144 
145  //Check status code
146  if(!error)
147  {
148  //Generate an ephemeral key pair
149  error = ikeGenerateKeyPair(&sa->keContext, context->prngAlgo,
150  context->prngContext);
151  }
152 
153  //Check status code
154  if(!error)
155  {
156  //Let g^ir be the Diffie-Hellman shared secret
157  error = ikeComputeSharedSecret(&sa->keContext, sa->sharedSecret,
158  &sa->sharedSecretLen);
159  }
160 
161  //Check status code
162  if(!error)
163  {
164  //At this point in the negotiation, each party can generate a quantity
165  //called SKEYSEED, from which all keys are derived for that IKE SA
166  //(refer to RFC 7296, section 1.2)
167  error = ikeGenerateSaKeyMaterial(sa, NULL);
168  }
169  }
170  else
171  {
172  //When the IKE_SA_INIT exchange does not result in the creation of an
173  //IKE SA due to INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN, or COOKIE, the
174  //responder's SPI will be zero also in the response message (refer to
175  //RFC 7296, section 2.6)
176  osMemset(sa->responderSpi, 0, IKE_SPI_SIZE);
177  }
178 
179  //Check status code
180  if(!error)
181  {
182  //Four octets of zero are prepended to the IKE header
183  STORE32BE(IKE_PREFIX_VALUE, sa->response);
184 
185  //Format IKE_SA_INIT response
186  error = ikeFormatIkeSaInitResponse(sa, sa->response + IKE_PREFIX_SIZE,
187  &sa->responseLen);
188  }
189 
190  //Check status code
191  if(!error)
192  {
193  //An implementation must respond to the address and port from which the
194  //request was received (refer to RFC 7296, section 2.11)
195  ikeSendResponse(context, sa->response + IKE_PREFIX_SIZE, sa->responseLen);
196 
197  //In an IKE_SA_INIT exchange, any error notification causes the exchange
198  //to fail (refer to RFC 7296, section 2.21.1)
199  if(sa->notifyMsgType != IKE_NOTIFY_MSG_TYPE_NONE)
200  {
201  error = ERROR_UNEXPECTED_STATUS;
202  }
203  }
204 
205  //Check status code
206  if(!error)
207  {
208  //Wait for the IKE_AUTH request from the initiator
210  }
211  else
212  {
213  //The IKE_SA_INIT exchange has failed
214  ikeDeleteSaEntry(sa);
215  }
216 
217  //Return status code
218  return error;
219 }
220 
221 
222 /**
223  * @brief Send IKE_AUTH response
224  * @param[in] sa Pointer to the IKE SA
225  * @return Error code
226  **/
227 
229 {
230  error_t error;
231  IkeContext *context;
232  IkeChildSaEntry *childSa;
233 
234  //Initialize status code
235  error = NO_ERROR;
236 
237  //Point to the IKE context
238  context = sa->context;
239  //Point to the Child SA
240  childSa = sa->childSa2;
241 
242  //Save the second message (IKE_SA_INIT response), starting with the first
243  //octet of the first SPI in the header and ending with the last octet of
244  //the last payload
245  osMemcpy(context->message, sa->responderSaInit, sa->responderSaInitLen);
246  sa->responderSaInit = context->message;
247 
248  //Successful Child SA creation?
249  if(childSa != NULL)
250  {
251  //For the first Child SA created, Ni and Nr are the nonces from the
252  //IKE_SA_INIT exchange (refer to RFC 7296, section 2.17)
253  osMemcpy(childSa->initiatorNonce, sa->initiatorNonce,
254  sa->initiatorNonceLen);
255 
256  osMemcpy(childSa->responderNonce, sa->responderNonce,
257  sa->responderNonceLen);
258 
259  //Save the length of Ni and Nr nonces
260  childSa->initiatorNonceLen = sa->initiatorNonceLen;
261  childSa->responderNonceLen = sa->responderNonceLen;
262 
263  //A single Child SA is created by the IKE_AUTH exchange. Keying
264  //material for the Child SA must be taken from the expanded KEYMAT
265  //(refer to RFC 7296, section 2.17)
266  error = ikeGenerateChildSaKeyMaterial(childSa);
267  }
268 
269  //Check status code
270  if(!error)
271  {
272  //Four octets of zero are prepended to the IKE header
273  STORE32BE(IKE_PREFIX_VALUE, sa->response);
274 
275  //Format IKE_AUTH response
276  error = ikeFormatIkeAuthResponse(sa, sa->response + IKE_PREFIX_SIZE,
277  &sa->responseLen);
278  }
279 
280  //Check status code
281  if(!error)
282  {
283  //All messages following the initial exchange are cryptographically
284  //protected using the cryptographic algorithms and keys negotiated in
285  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
286  error = ikeEncryptMessage(sa, sa->response + IKE_PREFIX_SIZE,
287  &sa->responseLen);
288  }
289 
290  //Check status code
291  if(!error)
292  {
293  //An implementation must respond to the address and port from which the
294  //request was received (refer to RFC 7296, section 2.11)
295  ikeSendResponse(context, sa->response + IKE_PREFIX_SIZE, sa->responseLen);
296 
297  //If creating the Child SA during the IKE_AUTH exchange fails for some
298  //reason, the IKE SA is still created as usual (refer to RFC 7296,
299  //section 1.2)
300  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE ||
301  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN ||
302  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE ||
303  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED ||
304  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE ||
305  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED)
306  {
307  //The responder has sent the IKE_AUTH response
309 
310  //Successful Child SA creation?
311  if(childSa != NULL)
312  {
313  //Update the state of the Child SA
315 
316  //ESP and AH SAs exist in pairs (one in each direction), so two SAs
317  //are created in a single Child SA negotiation for them
318  ikeCreateIpsecSaPair(childSa);
319 
320  //Detach the newly created Child SA
321  sa->childSa2 = NULL;
322  }
323 
324 #if (IKE_INITIAL_CONTACT_SUPPORT == ENABLED)
325  //The INITIAL_CONTACT notification asserts that this IKE SA is the only
326  //IKE SA currently active between the authenticated identities
327  if(sa->initialContact)
328  {
329  //It may be sent when an IKE SA is established after a crash, and the
330  //recipient may use this information to delete any other IKE SAs it
331  //has to the same authenticated identity without waiting for a timeout
333 
334  //Reset flag
335  sa->initialContact = FALSE;
336  }
337 #endif
338  }
339  else if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD)
340  {
341  //An unsupported critical payload was included in the IKE_AUTH request
342  }
343  else
344  {
345  //Only authentication failures (AUTHENTICATION_FAILED) and malformed
346  //messages (INVALID_SYNTAX) lead to a deletion of the IKE SA without
347  //requiring an explicit INFORMATIONAL exchange carrying a Delete
348  //payload
350  }
351  }
352 
353  //Check status code
354  if(error)
355  {
356  //The IKE_AUTH exchange has failed
357  ikeDeleteSaEntry(sa);
358  }
359 
360  //Return status code
361  return error;
362 }
363 
364 
365 /**
366  * @brief Send CREATE_CHILD_SA response
367  * @param[in] sa Pointer to the IKE SA
368  * @return Error code
369  **/
370 
372 {
373  error_t error;
374  IkeContext *context;
375 
376  //Point to the IKE context
377  context = sa->context;
378 
379  //Four octets of zero are prepended to the IKE header
380  STORE32BE(IKE_PREFIX_VALUE, sa->response);
381 
382  //Format CREATE_CHILD_SA response
383  error = ikeFormatCreateChildSaResponse(sa, sa->response + IKE_PREFIX_SIZE,
384  &sa->responseLen);
385 
386  //Check status code
387  if(!error)
388  {
389  //All messages following the initial exchange are cryptographically
390  //protected using the cryptographic algorithms and keys negotiated in
391  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
392  error = ikeEncryptMessage(sa, sa->response + IKE_PREFIX_SIZE,
393  &sa->responseLen);
394  }
395 
396  //Check status code
397  if(!error)
398  {
399  //An implementation must respond to the address and port from which the
400  //request was received (refer to RFC 7296, section 2.11)
401  ikeSendResponse(context, sa->response + IKE_PREFIX_SIZE, sa->responseLen);
402  }
403 
404  //Return status code
405  return error;
406 }
407 
408 
409 /**
410  * @brief Send INFORMATIONAL response
411  * @param[in] sa Pointer to the IKE SA
412  * @return Error code
413  **/
414 
416 {
417  error_t error;
418  uint_t i;
419  IkeContext *context;
420  IkeChildSaEntry *childSa;
421 
422  //Point to the IKE context
423  context = sa->context;
424 
425  //Four octets of zero are prepended to the IKE header
426  STORE32BE(IKE_PREFIX_VALUE, sa->response);
427 
428  //Format INFORMATIONAL response
429  error = ikeFormatInfoResponse(sa, sa->response + IKE_PREFIX_SIZE,
430  &sa->responseLen);
431 
432  //Check status code
433  if(!error)
434  {
435  //All messages following the initial exchange are cryptographically
436  //protected using the cryptographic algorithms and keys negotiated in
437  //the IKE_SA_INIT exchange (refer to RFC 7296, section 1.2)
438  error = ikeEncryptMessage(sa, sa->response + IKE_PREFIX_SIZE,
439  &sa->responseLen);
440  }
441 
442  //Check status code
443  if(!error)
444  {
445  //An implementation must respond to the address and port from which the
446  //request was received (refer to RFC 7296, section 2.11)
447  ikeSendResponse(context, sa->response + IKE_PREFIX_SIZE, sa->responseLen);
448  }
449 
450  //Check whether the IKE SA should be closed
451  if(sa->deleteReceived)
452  {
453  //Delete the IKE SA
454  ikeDeleteSaEntry(sa);
455  }
456 
457  //Loop through Child SA entries
458  for(i = 0; i < context->numChildSaEntries; i++)
459  {
460  //Point to the current Child SA
461  childSa = &context->childSa[i];
462 
463  //Check whether the Child SA should be closed
464  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
465  childSa->deleteReceived)
466  {
467  //Delete the Child SA
468  ikeDeleteChildSaEntry(childSa);
469  }
470  }
471 
472  //Return status code
473  return error;
474 }
475 
476 
477 /**
478  * @brief Send INFORMATIONAL response (outside of an IKE SA)
479  * @param[in] context Pointer to the IKE context
480  * @param[in] message Pointer to the received IKE message
481  * @param[in] length Length of the IKE message, in bytes
482  * @return Error code
483  **/
484 
486  size_t length)
487 {
488  error_t error;
489  IkeHeader ikeHeader;
490 
491  //Check the length of the IKE message
492  if(length >= sizeof(IkeHeader))
493  {
494  //Copy the IKE header
495  osMemcpy(&ikeHeader, message, sizeof(IkeHeader));
496 
497  //Four octets of zero are prepended to the IKE header
498  STORE32BE(IKE_PREFIX_VALUE, context->message);
499 
500  //Format INFORMATIONAL response
501  error = ikeFormatErrorResponse(&ikeHeader, context->message +
502  IKE_PREFIX_SIZE, &context->messageLen);
503 
504  //Check status code
505  if(!error)
506  {
507  //The message is always sent without cryptographic protection. The
508  //message is a response message, and thus it is sent to the IP address
509  //and port from whence it came (refer to RFC 7296, section 1.5)
510  ikeSendResponse(context, context->message + IKE_PREFIX_SIZE,
511  context->messageLen);
512  }
513  }
514  else
515  {
516  //The length of the received IKE message is not valid
517  error = ERROR_INVALID_LENGTH;
518  }
519 
520  //Return status code
521  return error;
522 }
523 
524 
525 /**
526  * @brief Format IKE_SA_INIT response
527  * @param[in] sa Pointer to the IKE SA
528  * @param[out] p Buffer where to format the message
529  * @param[out] length Length of the resulting message, in bytes
530  * @return Error code
531  **/
532 
534 {
535  error_t error;
536  size_t n;
537  uint8_t *nextPayload;
538  IkeHeader *ikeHeader;
539 
540  //Total length of the message
541  *length = 0;
542 
543  //Each message begins with the IKE header
544  ikeHeader = (IkeHeader *) p;
545 
546  //Format IKE header
547  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
548  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
549  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
550  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
551  ikeHeader->minorVersion = IKE_MINOR_VERSION;
552  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_SA_INIT;
553  ikeHeader->flags = IKE_FLAGS_R;
554  ikeHeader->messageId = htonl(sa->rxMessageId);
555 
556  //Keep track of the Next Payload field
557  nextPayload = &ikeHeader->nextPayload;
558 
559  //Point to the first IKE payload
560  p += sizeof(IkeHeader);
561  *length += sizeof(IkeHeader);
562 
563  //Successful IKE SA creation?
564  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE)
565  {
566  //The responder chooses a cryptographic suite from the initiator's offered
567  //choices and expresses that choice in the SAr payload
568  error = ikeFormatSaPayload(sa, NULL, p, &n, &nextPayload);
569  //Any error to report?
570  if(error)
571  return error;
572 
573  //Point to the next payload
574  p += n;
575  *length += n;
576 
577  //The responder completes the Diffie-Hellman exchange with the KEr payload
578  error = ikeFormatKePayload(&sa->keContext, p, &n, &nextPayload);
579  //Any error to report?
580  if(error)
581  return error;
582 
583  //Point to the next payload
584  p += n;
585  *length += n;
586 
587  //The ephemeral private key must be destroyed as soon as possible (refer
588  //to RFC 9206, section 10)
589  ikeFreeKeContext(&sa->keContext);
590  ikeInitKeContext(&sa->keContext);
591 
592  //The responder sends its nonce in the Nr payload
593  error = ikeFormatNoncePayload(sa, NULL, p, &n, &nextPayload);
594  //Any error to report?
595  if(error)
596  return error;
597 
598  //Point to the next payload
599  p += n;
600  *length += n;
601 
602  //A CERTREQ payload can optionally be included
603  error = ikeFormatCertReqPayload(sa, p, &n, &nextPayload);
604  //Any error to report?
605  if(error)
606  return error;
607 
608  //Point to the next payload
609  p += n;
610  *length += n;
611 
612 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
613  //Check whether the initiator has included Notify payloads of type
614  //NAT_DETECTION_SOURCE_IP and NAT_DETECTION_DESTINATION_IP in its
615  //IKE_SA_INIT request
616  if(sa->natDetectSrcIp && sa->natDetectDestIp)
617  {
618  //There MAY be multiple NAT_DETECTION_SOURCE_IP payloads in a message
619  //if the sender does not know which of several network attachments will
620  //be used to send the packet (refer to RFC 7296, section 2.23)
621  error = ikeFormatNotifyPayload(sa, NULL,
623  //Any error to report?
624  if(error)
625  return error;
626 
627  //Point to the next payload
628  p += n;
629  *length += n;
630 
631  //The NAT_DETECTION_DESTINATION_IP payloads can be used to detect if
632  //there is NAT between the hosts
633  error = ikeFormatNotifyPayload(sa, NULL,
635  &nextPayload);
636  //Any error to report?
637  if(error)
638  return error;
639 
640  //Point to the next payload
641  p += n;
642  *length += n;
643  }
644 #endif
645 
646 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
647  //The hash algorithms that can be used for the signature algorithms
648  //are indicated with a Notify payload of type SIGNATURE_HASH_ALGORITHMS
649  //sent inside the IKE_SA_INIT exchange (refer to RFC 7427, section 4)
650  error = ikeFormatNotifyPayload(sa, NULL,
652  //Any error to report?
653  if(error)
654  return error;
655 
656  //Total length of the message
657  *length += n;
658 #endif
659  }
660  else
661  {
662  //In an IKE_SA_INIT exchange, any error notification causes the
663  //exchange to fail. Note that some error notifications such as COOKIE,
664  //INVALID_KE_PAYLOAD or INVALID_MAJOR_VERSION may lead to a subsequent
665  //successful exchange (refer to RFC 7296, section 2.21.1)
666  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
667  &nextPayload);
668 
669  //Total length of the message
670  *length += n;
671  }
672 
673  //The Length field indicates the total length of the IKE message in octets
674  ikeHeader->length = htonl(*length);
675 
676  //Save the second message (IKE_SA_INIT response), starting with the first
677  //octet of the first SPI in the header and ending with the last octet of
678  //the last payload
679  sa->responderSaInit = sa->response + IKE_PREFIX_SIZE;
680  sa->responderSaInitLen = *length;
681 
682  //Successful processing
683  return NO_ERROR;
684 }
685 
686 
687 /**
688  * @brief Format IKE_AUTH response
689  * @param[in] sa Pointer to the IKE SA
690  * @param[out] p Buffer where to format the message
691  * @param[out] length Length of the resulting message, in bytes
692  * @return Error code
693  **/
694 
696 {
697  error_t error;
698  size_t n;
699  uint8_t *nextPayload;
700  IkeHeader *ikeHeader;
701  IkeIdPayload *idPayload;
702 
703  //Total length of the message
704  *length = 0;
705 
706  //Each message begins with the IKE header
707  ikeHeader = (IkeHeader *) p;
708 
709  //Format IKE header
710  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
711  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
712  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
713  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
714  ikeHeader->minorVersion = IKE_MINOR_VERSION;
715  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_IKE_AUTH;
716  ikeHeader->flags = IKE_FLAGS_R;
717  ikeHeader->messageId = htonl(sa->rxMessageId);
718 
719  //Keep track of the Next Payload field
720  nextPayload = &ikeHeader->nextPayload;
721 
722  //Point to the first IKE payload
723  p += sizeof(IkeHeader);
724  *length += sizeof(IkeHeader);
725 
726  //If creating the Child SA during the IKE_AUTH exchange fails for some
727  //reason, the IKE SA is still created as usual (refer to RFC 7296,
728  //section 1.2)
729  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE ||
730  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN ||
731  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE ||
732  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED ||
733  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE ||
734  sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED)
735  {
736  //The responder asserts its identity with the IDr payload (refer to
737  //RFC 7296, section 1.2)
738  error = ikeFormatIdPayload(sa, p, &n, &nextPayload);
739  //Any error to report?
740  if(error)
741  return error;
742 
743  //Point to the Identification payload
744  idPayload = (IkeIdPayload *) p;
745 
746  //Point to the next payload
747  p += n;
748  *length += n;
749 
750  //The responder optionally sends one or more certificates
751  error = ikeFormatCertPayloads(sa, p, &n, &nextPayload);
752  //Any error to report?
753  if(error)
754  return error;
755 
756  //Point to the next payload
757  p += n;
758  *length += n;
759 
760  //The responder authenticates its identity and protects the integrity
761  //of the second message with the AUTH payload
762  error = ikeFormatAuthPayload(sa, idPayload, p, &n, &nextPayload);
763  //Any error to report?
764  if(error)
765  return error;
766 
767  //Point to the next payload
768  p += n;
769  *length += n;
770 
771  //The responder completes negotiation of a Child SA with additional fields
772  if(sa->childSa2 != NULL)
773  {
774  //Piggyback setup of the Child SA
776  //Any error to report?
777  if(error)
778  return error;
779 
780  //Total length of the message
781  *length += n;
782  }
783  else
784  {
785  //Failed to create Child SA?
786  if(sa->notifyMsgType != IKE_NOTIFY_MSG_TYPE_NONE)
787  {
788  //The Notify payload is used to transmit informational data, such
789  //as error conditions
790  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
791  &nextPayload);
792 
793  //Total length of the message
794  *length += n;
795  }
796  }
797  }
798  else
799  {
800  //If the failure is related to creating the IKE SA (for example, an
801  //AUTHENTICATION_FAILED Notify error message is returned), the IKE SA
802  //is not created
803  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
804  &nextPayload);
805 
806  //Total length of the message
807  *length += n;
808  }
809 
810  //The Length field indicates the total length of the IKE message in octets
811  ikeHeader->length = htonl(*length);
812 
813  //Successful processing
814  return NO_ERROR;
815 }
816 
817 
818 /**
819  * @brief Format CREATE_CHILD_SA response
820  * @param[in] sa Pointer to the IKE SA
821  * @param[out] p Buffer where to format the message
822  * @param[out] length Length of the resulting message, in bytes
823  * @return Error code
824  **/
825 
827  size_t *length)
828 {
829  error_t error;
830  size_t n;
831  uint8_t *nextPayload;
832  IkeHeader *ikeHeader;
833 
834  //Total length of the message
835  *length = 0;
836 
837  //Each message begins with the IKE header
838  ikeHeader = (IkeHeader *) p;
839 
840  //Format IKE header
841  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
842  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
843  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
844  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
845  ikeHeader->minorVersion = IKE_MINOR_VERSION;
846  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_CREATE_CHILD_SA;
847  ikeHeader->messageId = htonl(sa->rxMessageId);
848 
849  //This I bit must be set in messages sent by the original initiator of the
850  //IKE SA and must be cleared in messages sent by the original responder
851  if(sa->originalInitiator)
852  {
853  ikeHeader->flags = IKE_FLAGS_R | IKE_FLAGS_I;
854  }
855  else
856  {
857  ikeHeader->flags = IKE_FLAGS_R;
858  }
859 
860  //Keep track of the Next Payload field
861  nextPayload = &ikeHeader->nextPayload;
862 
863  //Point to the first IKE payload
864  p += sizeof(IkeHeader);
865  *length += sizeof(IkeHeader);
866 
867 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
868  //Successful Child SA creation?
869  if(sa->notifyMsgType == IKE_NOTIFY_MSG_TYPE_NONE)
870  {
871  //The CREATE_CHILD_SA exchange is used to create new Child SAs and to
872  //rekey both IKE SAs and Child SAs (refer to RFC 7296, section 1.3)
873  if(sa->childSa2 != NULL)
874  {
875  //Child SA creation/rekeying
877 
878  //Simultaneous rekeying?
879  if(sa->childSa1 != NULL)
880  {
881  //The peer will close the redundant SAs later based on the nonces
882  }
883  else
884  {
885  //Detach the newly created Child SA
886  sa->childSa2 = NULL;
887  }
888  }
889  else if(sa->newSa2 != NULL)
890  {
891  //IKE SA rekeying
892  error = ikeFormatIkeSaRekeyResponse(sa, p, &n, &nextPayload);
893 
894  //Simultaneous rekeying?
895  if(sa->newSa1 != NULL)
896  {
897  //The peer will close the redundant SAs later based on the nonces
898  }
899  else
900  {
901  //Detach the newly created IKE SA
902  sa->newSa2 = NULL;
903  }
904  }
905  else
906  {
907  //Report an error
908  error = ERROR_FAILURE;
909  }
910  }
911  else
912  {
913  //The Notify payload is used to transmit informational data, such
914  //as error conditions
915  error = ikeFormatNotifyPayload(sa, NULL, sa->notifyMsgType, p, &n,
916  &nextPayload);
917  }
918 #else
919  //A minimal implementation may support the CREATE_CHILD_SA exchange only in
920  //so far as to recognize requests and reject them with a Notify payload of
921  //type NO_ADDITIONAL_SAS (refer to RFC 7296, section 4)
922  error = ikeFormatNotifyPayload(sa, NULL,
924 #endif
925 
926  //Check status code
927  if(!error)
928  {
929  //Total length of the message
930  *length += n;
931 
932  //The Length field indicates the total length of the IKE message in octets
933  ikeHeader->length = htonl(*length);
934  }
935 
936  //Return status code
937  return error;
938 }
939 
940 
941 /**
942  * @brief Format INFORMATIONAL response
943  * @param[in] sa Pointer to the IKE SA
944  * @param[out] p Buffer where to format the message
945  * @param[out] length Length of the resulting message, in bytes
946  * @return Error code
947  **/
948 
950  size_t *length)
951 {
952  uint_t i;
953  size_t n;
954  uint8_t *nextPayload;
955  IkeContext *context;
956  IkeChildSaEntry *childSa;
957  IkeHeader *ikeHeader;
958  IkeDeletePayload *deletePayload;
959 
960  //Point to the IKE context
961  context = sa->context;
962 
963  //Total length of the message
964  *length = 0;
965 
966  //Each message begins with the IKE header
967  ikeHeader = (IkeHeader *) p;
968 
969  //Format IKE header
970  osMemcpy(ikeHeader->initiatorSpi, sa->initiatorSpi, IKE_SPI_SIZE);
971  osMemcpy(ikeHeader->responderSpi, sa->responderSpi, IKE_SPI_SIZE);
972  ikeHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
973  ikeHeader->majorVersion = IKE_MAJOR_VERSION;
974  ikeHeader->minorVersion = IKE_MINOR_VERSION;
975  ikeHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
976  ikeHeader->messageId = htonl(sa->rxMessageId);
977 
978  //This I bit must be set in messages sent by the original initiator of the
979  //IKE SA and must be cleared in messages sent by the original responder
980  if(sa->originalInitiator)
981  {
982  ikeHeader->flags = IKE_FLAGS_R | IKE_FLAGS_I;
983  }
984  else
985  {
986  ikeHeader->flags = IKE_FLAGS_R;
987  }
988 
989  //Keep track of the Next Payload field
990  nextPayload = &ikeHeader->nextPayload;
991 
992  //Point to the first IKE payload
993  p += sizeof(IkeHeader);
994  *length += sizeof(IkeHeader);
995 
996  //Point to the Delete payload header
997  deletePayload = (IkeDeletePayload *) p;
998 
999  //Format Delete payload header
1000  deletePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1001  deletePayload->header.critical = FALSE;
1002  deletePayload->header.reserved = 0;
1003  deletePayload->protocolId = IKE_PROTOCOL_ID_AH;
1004  deletePayload->spiSize = IPSEC_SPI_SIZE;
1005  deletePayload->numSpi = 0;
1006 
1007  //Length of the SPI list
1008  n = 0;
1009 
1010  //Loop through Child SA entries
1011  for(i = 0; i < context->numChildSaEntries; i++)
1012  {
1013  //Point to the current Child SA
1014  childSa = &context->childSa[i];
1015 
1016  //Check the state of the Child SA
1017  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
1018  childSa->protocol == IPSEC_PROTOCOL_AH &&
1019  childSa->deleteReceived)
1020  {
1021  //The SPI is the SPI the sending endpoint would expect in inbound ESP
1022  //or AH packets
1023  osMemcpy(deletePayload->spi + n, childSa->localSpi, IPSEC_SPI_SIZE);
1024  n += IPSEC_SPI_SIZE;
1025 
1026  //Increment the number of SPIs
1027  deletePayload->numSpi++;
1028  }
1029  }
1030 
1031  //Any SPI included in the Delete payload?
1032  if(n > 0)
1033  {
1034  //Calculate the length of the Delete payload
1035  n += sizeof(IkeDeletePayload);
1036 
1037  //Fix the Next Payload field of the previous payload
1039 
1040  //Fix the Payload Length field of the payload header
1041  deletePayload->header.payloadLength = htons(n);
1042  //Convert the number of SPIs to network byte order
1043  deletePayload->numSpi = htons(deletePayload->numSpi);
1044 
1045  //Keep track of the Next Payload field
1046  nextPayload = &deletePayload->header.nextPayload;
1047 
1048  //Point to the next payload
1049  p += n;
1050  *length += n;
1051  }
1052 
1053  //Point to the Delete payload header
1054  deletePayload = (IkeDeletePayload *) p;
1055 
1056  //Format Delete payload header
1057  deletePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1058  deletePayload->header.critical = FALSE;
1059  deletePayload->header.reserved = 0;
1060  deletePayload->protocolId = IKE_PROTOCOL_ID_ESP;
1061  deletePayload->spiSize = IPSEC_SPI_SIZE;
1062  deletePayload->numSpi = 0;
1063 
1064  //Length of the SPI list
1065  n = 0;
1066 
1067  //Loop through Child SA entries
1068  for(i = 0; i < context->numChildSaEntries; i++)
1069  {
1070  //Point to the current Child SA
1071  childSa = &context->childSa[i];
1072 
1073  //Check the state of the Child SA
1074  if(childSa->state != IKE_CHILD_SA_STATE_CLOSED &&
1075  childSa->protocol == IPSEC_PROTOCOL_ESP &&
1076  childSa->deleteReceived)
1077  {
1078  //The SPI is the SPI the sending endpoint would expect in inbound ESP
1079  //or AH packets
1080  osMemcpy(deletePayload->spi + n, childSa->localSpi, IPSEC_SPI_SIZE);
1081  n += IPSEC_SPI_SIZE;
1082 
1083  //Increment the number of SPIs
1084  deletePayload->numSpi++;
1085  }
1086  }
1087 
1088  //Any SPI included in the Delete payload?
1089  if(n > 0)
1090  {
1091  //Calculate the length of the Delete payload
1092  n += sizeof(IkeDeletePayload);
1093 
1094  //Fix the Next Payload field of the previous payload
1096 
1097  //Fix the Payload Length field of the payload header
1098  deletePayload->header.payloadLength = htons(n);
1099  //Convert the number of SPIs to network byte order
1100  deletePayload->numSpi = htons(deletePayload->numSpi);
1101 
1102  //Keep track of the Next Payload field
1103  nextPayload = &deletePayload->header.nextPayload;
1104 
1105  //Point to the next payload
1106  p += n;
1107  *length += n;
1108  }
1109 
1110  //The Length field indicates the total length of the IKE message in octets
1111  ikeHeader->length = htonl(*length);
1112 
1113  //Successful processing
1114  return NO_ERROR;
1115 }
1116 
1117 
1118 /**
1119  * @brief Format INFORMATIONAL response (outside of an IKE SA)
1120  * @param[in] requestHeader Pointer to the IKE header of the request
1121  * @param[out] p Buffer where to format the message
1122  * @param[out] length Length of the resulting message, in bytes
1123  * @return Error code
1124  **/
1125 
1126 error_t ikeFormatErrorResponse(IkeHeader *requestHeader, uint8_t *p,
1127  size_t *length)
1128 {
1129  error_t error;
1130  size_t n;
1132  uint8_t *nextPayload;
1133  IkeHeader *responseHeader;
1134 
1135  //Total length of the message
1136  *length = 0;
1137 
1138  //Each message begins with the IKE header
1139  responseHeader = (IkeHeader *) p;
1140 
1141  //The IKE SPIs are copied from the request
1142  osMemcpy(responseHeader->initiatorSpi, requestHeader->initiatorSpi,
1143  IKE_SPI_SIZE);
1144 
1145  osMemcpy(responseHeader->responderSpi, requestHeader->responderSpi,
1146  IKE_SPI_SIZE);
1147 
1148  //The Response flag is set to 1, and the version flags are set in the
1149  //normal fashion (refer to RFC 7296, section 1.5)
1150  responseHeader->nextPayload = IKE_PAYLOAD_TYPE_LAST;
1151  responseHeader->majorVersion = IKE_MAJOR_VERSION;
1152  responseHeader->minorVersion = IKE_MINOR_VERSION;
1153  responseHeader->exchangeType = IKE_EXCHANGE_TYPE_INFORMATIONAL;
1154  responseHeader->flags = IKE_FLAGS_R;
1155  responseHeader->messageId = requestHeader->messageId;
1156 
1157  //Keep track of the Next Payload field
1158  nextPayload = &responseHeader->nextPayload;
1159 
1160  //Point to the first IKE payload
1161  p += sizeof(IkeHeader);
1162  *length += sizeof(IkeHeader);
1163 
1164  //The message includes either an INVALID_IKE_SPI or an INVALID_MAJOR_VERSION
1165  //notification (with no notification data)
1166  if(requestHeader->majorVersion > IKE_MAJOR_VERSION)
1167  {
1169  }
1170  else
1171  {
1173  }
1174 
1175  //Format Notify payload
1176  error = ikeFormatNotifyPayload(NULL, NULL, notifyMsgType, p, &n,
1177  &nextPayload);
1178  //Any error to report?
1179  if(error)
1180  return error;
1181 
1182  //Total length of the message
1183  *length += n;
1184 
1185  //The Length field indicates the total length of the IKE message in octets
1186  responseHeader->length = htonl(*length);
1187 
1188  //Successful processing
1189  return NO_ERROR;
1190 }
1191 
1192 
1193 /**
1194  * @brief Format Child SA creation/rekeying response
1195  * @param[in] sa Pointer to the IKE SA
1196  * @param[out] p Buffer where to format the payloads
1197  * @param[out] length Length of the resulting payloads, in bytes
1198  * @param[in,out] nextPayload Pointer to the Next Payload field
1199  * @return Error code
1200  **/
1201 
1203  size_t *length, uint8_t **nextPayload)
1204 {
1205  error_t error;
1206  size_t n;
1207  IkeChildSaEntry *childSa;
1208 
1209  //Point to the Child SA
1210  childSa = sa->childSa2;
1211 
1212  //Total length of the payloads
1213  *length = 0;
1214 
1215  //The initiator can request that the Child SA use transport mode rather than
1216  //tunnel mode for the SA created
1217  if(childSa->mode == IPSEC_MODE_TRANSPORT)
1218  {
1219  //If the request is accepted, the response must also include a
1220  //notification of type USE_TRANSPORT_MODE
1221  error = ikeFormatNotifyPayload(sa, childSa,
1223  //Any error to report?
1224  if(error)
1225  return error;
1226 
1227  //Point to the next payload
1228  p += n;
1229  *length += n;
1230  }
1231 
1232  //The responder chooses a cryptographic suite from the initiator's offered
1233  //choices and expresses that choice in the SAr payload
1234  error = ikeFormatChildSaPayload(childSa, p, &n, nextPayload);
1235  //Any error to report?
1236  if(error)
1237  return error;
1238 
1239  //Point to the next payload
1240  p += n;
1241  *length += n;
1242 
1243  //Child SA creation/rekeying?
1244  if(sa->state >= IKE_SA_STATE_OPEN)
1245  {
1246  //The responder sends its nonce in the Nr payload
1247  error = ikeFormatNoncePayload(sa, childSa, p, &n, nextPayload);
1248  //Any error to report?
1249  if(error)
1250  return error;
1251 
1252  //Point to the next payload
1253  p += n;
1254  *length += n;
1255  }
1256 
1257 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
1258  //Perfect forward secrecy?
1259  if(childSa->pfs)
1260  {
1261  //The responder replies with a Diffie-Hellman value in the KEr payload if
1262  //KEi was included in the request and the selected cryptographic suite
1263  //includes that group (refer to RFC 7296, section 1.3.1)
1264  error = ikeFormatKePayload(&childSa->keContext, p, &n, nextPayload);
1265  //Any error to report?
1266  if(error)
1267  return error;
1268 
1269  //Point to the next payload
1270  p += n;
1271  *length += n;
1272 
1273  //The ephemeral private key must be destroyed as soon as possible (refer
1274  //to RFC 9206, section 10)
1275  ikeFreeKeContext(&childSa->keContext);
1276  ikeInitKeContext(&childSa->keContext);
1277  }
1278 #endif
1279 
1280  //TSi specifies the source address of traffic forwarded from (or the
1281  //destination address of traffic forwarded to) the initiator of the
1282  //Child SA pair
1283  error = ikeFormatTsiPayload(childSa, p, &n, nextPayload);
1284  //Any error to report?
1285  if(error)
1286  return error;
1287 
1288  //Point to the next payload
1289  p += n;
1290  *length += n;
1291 
1292  //TSr specifies the destination address of the traffic forwarded to (or
1293  //the source address of the traffic forwarded from) the responder of the
1294  //Child SA pair
1295  error = ikeFormatTsrPayload(childSa, p, &n, nextPayload);
1296  //Any error to report?
1297  if(error)
1298  return error;
1299 
1300  //Total length of the payloads
1301  *length += n;
1302 
1303  //Successful processing
1304  return NO_ERROR;
1305 }
1306 
1307 
1308 /**
1309  * @brief Format IKE SA rekeying response
1310  * @param[in] sa Pointer to the IKE SA
1311  * @param[out] p Buffer where to format the payloads
1312  * @param[out] length Length of the resulting payloads, in bytes
1313  * @param[in,out] nextPayload Pointer to the Next Payload field
1314  * @return Error code
1315  **/
1316 
1318  uint8_t **nextPayload)
1319 {
1320 #if (IKE_CREATE_CHILD_SA_SUPPORT == ENABLED)
1321  error_t error;
1322  size_t n;
1323  IkeSaEntry *newSa;
1324 
1325  //Point to the new IKE SA
1326  newSa = sa->newSa2;
1327 
1328  //Total length of the message
1329  *length = 0;
1330 
1331  //A new responder SPI is supplied in the SPI field of the SA payload (refer
1332  //to 7296, section 1.3.2)
1333  error = ikeFormatSaPayload(newSa, newSa->responderSpi, p, &n, nextPayload);
1334  //Any error to report?
1335  if(error)
1336  return error;
1337 
1338  //Point to the next payload
1339  p += n;
1340  *length += n;
1341 
1342  //The responder sends its nonce in the Nr payload
1343  error = ikeFormatNoncePayload(newSa, NULL, p, &n, nextPayload);
1344  //Any error to report?
1345  if(error)
1346  return error;
1347 
1348  //Point to the next payload
1349  p += n;
1350  *length += n;
1351 
1352  //The responder completes the Diffie-Hellman exchange with the KEr payload
1353  error = ikeFormatKePayload(&newSa->keContext, p, &n, nextPayload);
1354  //Any error to report?
1355  if(error)
1356  return error;
1357 
1358  //Total length of the payloads
1359  *length += n;
1360 
1361  //The ephemeral private key must be destroyed as soon as possible (refer to
1362  //RFC 9206, section 10)
1363  ikeFreeKeContext(&newSa->keContext);
1364  ikeInitKeContext(&newSa->keContext);
1365 
1366  //Successful processing
1367  return NO_ERROR;
1368 #else
1369  //Minimal implementations are not required to support the CREATE_CHILD_SA
1370  //exchange (refer to RFC 7296, section 4)
1371  return ERROR_NOT_IMPLEMENTED;
1372 #endif
1373 }
1374 
1375 #endif
#define IKE_PREFIX_SIZE
Definition: ike.h:816
#define htons(value)
Definition: cpu_endian.h:413
#define IPSEC_SPI_SIZE
Definition: ipsec.h:145
void ikeFreeKeContext(IkeKeContext *keContext)
Release key exchange context.
Diffie-Hellman key exchange.
error_t ikeSendErrorResponse(IkeContext *context, uint8_t *message, size_t length)
Send INFORMATIONAL response (outside of an IKE SA)
void ikeInitKeContext(IkeKeContext *keContext)
Initialize key exchange context.
error_t ikeFormatNoncePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Nonce payload.
Helper functions for IKEv2.
error_t ikeComputeSharedSecret(IkeKeContext *keContext, uint8_t *output, size_t *outputLen)
Compute shared secret.
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:199
IKE payload formatting.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ IKE_NOTIFY_MSG_TYPE_NO_PROPOSAL_CHOSEN
Definition: ike.h:1189
error_t ikeFormatCreateChildSaResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format CREATE_CHILD_SA response.
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:632
IKE message encryption.
Message and ancillary data.
Definition: socket.h:241
@ IKE_PROTOCOL_ID_AH
AH.
Definition: ike.h:931
error_t ikeSendInfoResponse(IkeSaEntry *sa)
Send INFORMATIONAL response.
void * data
Pointer to the payload.
Definition: socket.h:242
error_t ikeFormatChildSaPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Security Association payload (AH or ESP protocol)
error_t ikeFormatAuthPayload(IkeSaEntry *sa, const IkeIdPayload *idPayload, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Authentication payload.
IKEv2 finite state machine.
@ IKE_NOTIFY_MSG_TYPE_SIGNATURE_HASH_ALGORITHMS
Definition: ike.h:1255
#define IPSEC_NAT_PORT
Definition: ipsec.h:142
@ IKE_NOTIFY_MSG_TYPE_NAT_DETECTION_SOURCE_IP
Definition: ike.h:1212
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:200
@ IKE_NOTIFY_MSG_TYPE_TS_UNACCEPTABLE
Definition: ike.h:1196
error_t ikeFormatSaPayload(IkeSaEntry *sa, const uint8_t *spi, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Security Association payload (IKE protocol)
@ IKE_NOTIFY_MSG_TYPE_NAT_DETECTION_DESTINATION_IP
Definition: ike.h:1213
void ikeChangeSaState(IkeSaEntry *sa, IkeSaState newState)
Update IKE SA state.
Definition: ike_fsm.c:53
uint16_t destPort
Destination port.
Definition: socket.h:252
#define IkeContext
Definition: ike.h:832
@ IKE_NOTIFY_MSG_TYPE_FAILED_CP_REQUIRED
Definition: ike.h:1195
@ IKE_EXCHANGE_TYPE_IKE_AUTH
IKE_AUTH.
Definition: ike.h:855
error_t socketSendMsg(Socket *socket, const SocketMsg *message, uint_t flags)
Send a message to a connectionless socket.
Definition: socket.c:1664
NetInterface * interface
Underlying network interface.
Definition: socket.h:248
#define FALSE
Definition: os_port.h:46
const SocketMsg SOCKET_DEFAULT_MSG
Definition: socket.c:49
size_t length
Actual length of the payload, in bytes.
Definition: socket.h:244
#define htonl(value)
Definition: cpu_endian.h:414
uint16_t notifyMsgType
Definition: ike.h:1630
@ ERROR_UNEXPECTED_STATUS
Definition: error.h:284
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
Data logging functions for debugging purpose (IKEv2)
error_t ikeSendIkeAuthResponse(IkeSaEntry *sa)
Send IKE_AUTH response.
@ IPSEC_MODE_TRANSPORT
Definition: ipsec.h:212
@ IKE_FLAGS_I
Initiator flag.
Definition: ike.h:876
@ IKE_SA_STATE_OPEN
Definition: ike.h:1360
error_t
Error codes.
Definition: error.h:43
error_t ikeFormatInfoResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format INFORMATIONAL response.
IkeIdPayload
Definition: ike.h:1559
#define IKE_MINOR_VERSION
Definition: ike.h:810
error_t ikeFormatIkeSaInitResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_SA_INIT response.
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t ikeFormatIkeAuthResponse(IkeSaEntry *sa, uint8_t *p, size_t *length)
Format IKE_AUTH response.
Key material generation.
#define IKE_SPI_SIZE
Definition: ike.h:826
#define IKE_MAJOR_VERSION
Definition: ike.h:808
@ IKE_SA_STATE_AUTH_REQ
Definition: ike.h:1358
@ IKE_PROTOCOL_ID_ESP
ESP.
Definition: ike.h:932
#define IKE_PREFIX_VALUE
Definition: ike.h:818
IpAddr srcIpAddr
Source IP address.
Definition: socket.h:249
@ 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:347
IKE response formatting.
void ikeDeleteDuplicateSaEntries(IkeSaEntry *sa)
Delete an duplicate IKE Security Associations.
Definition: ike_misc.c:408
error_t ikeFormatKePayload(IkeKeContext *keContext, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Key Exchange payload.
error_t ikeSendCreateChildSaResponse(IkeSaEntry *sa)
Send CREATE_CHILD_SA response.
error_t ikeFormatTsiPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (initiator)
void ikeDeleteChildSaEntry(IkeChildSaEntry *childSa)
Delete a Child Security Association.
Definition: ike_misc.c:560
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
error_t ikeSendIkeSaInitResponse(IkeSaEntry *sa)
Send IKE_SA_INIT response.
IkeHeader
Definition: ike.h:1459
@ IKE_EXCHANGE_TYPE_CREATE_CHILD_SA
CREATE_CHILD_SA.
Definition: ike.h:856
error_t ikeFormatIdPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Identification payload.
error_t ikeFormatCertPayloads(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate payloads.
void ikeChangeChildSaState(IkeChildSaEntry *childSa, IkeChildSaState newState)
Update Child SA state.
Definition: ike_fsm.c:110
@ IKE_CHILD_SA_STATE_CLOSED
Definition: ike.h:1384
IkeDeletePayload
Definition: ike.h:1646
IKEv2 (Internet Key Exchange Protocol)
error_t ikeCreateIpsecSaPair(IkeChildSaEntry *childSa)
Create AH or ESP SA pair.
Definition: ike_misc.c:1467
IpAddr destIpAddr
Destination IP address.
Definition: socket.h:251
@ IKE_EXCHANGE_TYPE_IKE_SA_INIT
IKE_SA_INIT.
Definition: ike.h:854
error_t ikeGenerateKeyPair(IkeKeContext *keContext, const PrngAlgo *prngAlgo, void *prngContext)
Key pair generation.
#define IkeSaEntry
Definition: ike.h:836
@ IKE_NOTIFY_MSG_TYPE_NO_ADDITIONAL_SAS
Definition: ike.h:1193
@ IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD
Definition: ike.h:1183
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.
error_t ikeFormatIkeSaRekeyResponse(IkeSaEntry *sa, uint8_t *p, size_t *length, uint8_t **nextPayload)
Format IKE SA rekeying response.
error_t ikeFormatChildSaCreateResponse(IkeSaEntry *sa, uint8_t *p, size_t *length, uint8_t **nextPayload)
Format Child SA creation/rekeying response.
uint8_t n
@ IKE_NOTIFY_MSG_TYPE_NONE
Definition: ike.h:1182
error_t ikeFormatErrorResponse(IkeHeader *requestHeader, uint8_t *p, size_t *length)
Format INFORMATIONAL response (outside of an IKE SA)
error_t ikeGenerateSaKeyMaterial(IkeSaEntry *sa, IkeSaEntry *oldSa)
Generate keying material for the IKE SA.
@ ERROR_AUTHENTICATION_FAILED
Definition: error.h:69
@ IKE_EXCHANGE_TYPE_INFORMATIONAL
INFORMATIONAL.
Definition: ike.h:857
@ IKE_PAYLOAD_TYPE_LAST
No Next Payload.
Definition: ike.h:886
IkeNotifyMsgType
Notify message types.
Definition: ike.h:1181
@ IKE_NOTIFY_MSG_TYPE_INTERNAL_ADDRESS_FAILURE
Definition: ike.h:1194
uint8_t nextPayload
Definition: ike.h:1447
@ IKE_FLAGS_R
Response flag.
Definition: ike.h:874
@ IKE_NOTIFY_MSG_TYPE_USE_TRANSPORT_MODE
Definition: ike.h:1215
error_t ikeGenerateNonce(IkeContext *context, uint8_t *nonce, size_t *length)
Generate a new nonce.
Definition: ike_misc.c:792
@ IKE_NOTIFY_MSG_TYPE_SINGLE_PAIR_REQUIRED
Definition: ike.h:1192
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:57
@ IKE_PAYLOAD_TYPE_D
Delete.
Definition: ike.h:896
#define osMemset(p, value, length)
Definition: os_port.h:141
@ IKE_NOTIFY_MSG_TYPE_INVALID_MAJOR_VERSION
Definition: ike.h:1185
void ikeDumpMessage(const uint8_t *message, size_t length)
Dump IKE message.
Definition: ike_debug.c:425
@ IKE_NOTIFY_MSG_TYPE_INVALID_IKE_SPI
Definition: ike.h:1184
error_t ikeSendResponse(IkeContext *context, const uint8_t *message, size_t length)
Send IKE response.
error_t ikeFormatCertReqPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate Request payload.
#define IkeChildSaEntry
Definition: ike.h:840
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
@ NO_ERROR
Success.
Definition: error.h:44
error_t ikeFormatTsrPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (responder)
Debugging facilities.
@ IKE_CHILD_SA_STATE_OPEN
Definition: ike.h:1387