ike_payload_format.c
Go to the documentation of this file.
1 /**
2  * @file ike_payload_format.c
3  * @brief IKE payload 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_algorithms.h"
37 #include "ike/ike_payload_format.h"
38 #include "ike/ike_auth.h"
39 #include "ike/ike_certificate.h"
40 #include "ike/ike_key_exchange.h"
41 #include "ike/ike_key_material.h"
42 #include "ah/ah_algorithms.h"
43 #include "esp/esp_algorithms.h"
44 #include "pkix/pem_import.h"
45 #include "debug.h"
46 
47 //Check IKEv2 library configuration
48 #if (IKE_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief Format Security Association payload (IKE protocol)
53  * @param[in] sa Pointer to the IKE SA
54  * @param[in] spi Security parameter index (optional parameter)
55  * @param[out] p Buffer where to format the payload
56  * @param[out] written Length of the resulting payload
57  * @param[in,out] nextPayload Pointer to the Next Payload field
58  * @return Error code
59  **/
60 
61 error_t ikeFormatSaPayload(IkeSaEntry *sa, const uint8_t *spi, uint8_t *p,
62  size_t *written, uint8_t **nextPayload)
63 {
64  error_t error;
65  size_t n;
66  IkeSaPayload *saPayload;
67 
68  //Fix the Next Payload field of the previous payload
70 
71  //Point to the Security Association payload header
72  saPayload = (IkeSaPayload *) p;
73 
74  //Format Security Association payload header
75  saPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
76  saPayload->header.critical = FALSE;
77  saPayload->header.reserved = 0;
78 
79  //Length of the payload header
80  *written = sizeof(IkeSaPayload);
81 
82  //Point to the Proposals field
83  p = saPayload->proposals;
84 
85  //Format Proposal substructure
86  error = ikeFormatSaProposal(sa, spi, p, &n);
87  //Any error to report?
88  if(error)
89  return error;
90 
91  //Total length of the payload
92  *written += n;
93 
94  //Fix the Payload Length field of the payload header
95  saPayload->header.payloadLength = htons(*written);
96 
97  //Keep track of the Next Payload field
98  *nextPayload = &saPayload->header.nextPayload;
99 
100  //Successful processing
101  return NO_ERROR;
102 }
103 
104 
105 /**
106  * @brief Format Proposal substructure (IKE protocol)
107  * @param[in] sa Pointer to the IKE SA
108  * @param[in] spi Security parameter index (optional parameter)
109  * @param[out] p Buffer where to format the Proposal substructure
110  * @param[out] written Length of the resulting Proposal substructure
111  * @return Error code
112  **/
113 
114 error_t ikeFormatSaProposal(IkeSaEntry *sa, const uint8_t *spi, uint8_t *p,
115  size_t *written)
116 {
117  error_t error;
118  size_t n;
119  uint8_t *lastSubstruc;
120  IkeContext *context;
121  IkeProposal *proposal;
122 
123  //Point to the IKE context
124  context = sa->context;
125 
126  //Point to the Proposal substructure
127  proposal = (IkeProposal *) p;
128 
129  //Format Proposal substructure
130  proposal->lastSubstruc = IKE_LAST_SUBSTRUC_LAST;
131  proposal->reserved = 0;
132  proposal->proposalLength = 0;
133  proposal->protocolId = IKE_PROTOCOL_ID_IKE;
134  proposal->spiSize = (spi != NULL) ? IKE_SPI_SIZE : 0;
135  proposal->numTransforms = 0;
136 
137  //Length of the Proposal substructure
138  n = sizeof(IkeProposal);
139 
140  //When the SPI Size field is zero, the SPI field is not present
141  if(spi != NULL)
142  {
143  //Copy the sending entity's SPI
144  osMemcpy(proposal->spi, spi, IKE_SPI_SIZE);
145  //Adjust the length of the Proposal substructure
146  n += IKE_SPI_SIZE;
147  }
148 
149  //The Proposal Length field indicates the length of the proposal, including
150  //all transforms and attributes that follow
151  proposal->proposalLength = htons(n);
152 
153  //The Last Substruc field has a value of 0 if this was the last Transform
154  //Substructure, and a value of 3 if there are more Transform Substructures
155  lastSubstruc = NULL;
156 
157  //Check whether the entity is the original initiator of the IKE SA
158  if(sa->originalInitiator)
159  {
160  //When a proposal is made, the first proposal in an SA payload must be 1,
161  //and subsequent proposals must be one more than the previous proposal
162  //(refer to RFC 7296, section 3.3.1)
163  proposal->proposalNum = 1;
164 
165  //IKE generally has four transforms: a Diffie-Hellman group, an
166  //integrity check algorithm, a PRF algorithm, and an encryption
167  //algorithm
168  error = ikeAddSupportedTransforms(context, proposal, &lastSubstruc);
169  //Any error to report?
170  if(error)
171  return error;
172  }
173  else
174  {
175  //When a proposal is accepted, the proposal number in the SA payload must
176  //match the number on the proposal sent that was accepted (refer to
177  //RFC 7296, section 3.3.1)
178  proposal->proposalNum = sa->acceptedProposalNum;
179 
180  //The accepted cryptographic suite must contain exactly one encryption
181  //transform
182  error = ikeAddTransform(IKE_TRANSFORM_TYPE_ENCR, sa->encAlgoId,
183  sa->encKeyLen, proposal, &lastSubstruc);
184  //Any error to report?
185  if(error)
186  return error;
187 
188  //The accepted cryptographic suite must contain exactly one PRF
189  //transform
190  error = ikeAddTransform(IKE_TRANSFORM_TYPE_PRF, sa->prfAlgoId, 0,
191  proposal, &lastSubstruc);
192  //Any error to report?
193  if(error)
194  return error;
195 
196  //AEAD encryption algorithm?
197  if(ikeIsAeadEncAlgo(sa->encAlgoId))
198  {
199  //If all of the encryption algorithms in any proposal are
200  //authenticated encryption algorithms, then the proposal must not
201  //propose any integrity transforms (refer to RFC 5282, section 8)
202  error = NO_ERROR;
203  }
204  else
205  {
206  //The accepted cryptographic suite must contain exactly one
207  //integrity transform
208  error = ikeAddTransform(IKE_TRANSFORM_TYPE_INTEG, sa->authAlgoId, 0,
209  proposal, &lastSubstruc);
210  }
211 
212  //Any error to report?
213  if(error)
214  return error;
215 
216  //The accepted cryptographic suite must contain exactly one key
217  //exchange transform
218  error = ikeAddTransform(IKE_TRANSFORM_TYPE_KE, sa->keContext.groupNum, 0,
219  proposal, &lastSubstruc);
220  //Any error to report?
221  if(error)
222  return error;
223  }
224 
225  //Total length of the Proposal substructure
226  *written = ntohs(proposal->proposalLength);
227 
228  //Successful processing
229  return NO_ERROR;
230 }
231 
232 
233 /**
234  * @brief Format Security Association payload (AH or ESP protocol)
235  * @param[in] childSa Pointer to the Child SA
236  * @param[out] p Buffer where to format the payload
237  * @param[out] written Length of the resulting payload
238  * @param[in,out] nextPayload Pointer to the Next Payload field
239  * @return Error code
240  **/
241 
243  size_t *written, uint8_t **nextPayload)
244 {
245  error_t error;
246  size_t n;
247  IkeSaPayload *saPayload;
248 
249  //Fix the Next Payload field of the previous payload
251 
252  //Point to the Security Association payload header
253  saPayload = (IkeSaPayload *) p;
254 
255  //Format Security Association payload header
256  saPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
257  saPayload->header.critical = FALSE;
258  saPayload->header.reserved = 0;
259 
260  //Length of the payload header
261  *written = sizeof(IkeSaPayload);
262 
263  //Point to the Proposals field
264  p = saPayload->proposals;
265 
266  //Format Proposal substructure
267  error = ikeFormatChildSaProposal(childSa, p, &n);
268  //Any error to report?
269  if(error)
270  return error;
271 
272  //Total length of the payload
273  *written += n;
274 
275  //Fix the Payload Length field of the payload header
276  saPayload->header.payloadLength = htons(*written);
277 
278  //Keep track of the Next Payload field
279  *nextPayload = &saPayload->header.nextPayload;
280 
281  //Successful processing
282  return NO_ERROR;
283 }
284 
285 
286 /**
287  * @brief Format Proposal substructure (AH or ESP protocol)
288  * @param[in] childSa Pointer to the Child SA
289  * @param[out] p Buffer where to format the Proposal substructure
290  * @param[out] written Length of the resulting Proposal substructure
291  * @return Error code
292  **/
293 
295  size_t *written)
296 {
297  error_t error;
298  size_t n;
299  uint8_t *lastSubstruc;
300  IkeContext *context;
301  IkeProposal *proposal;
302 
303  //Point to the IKE context
304  context = childSa->context;
305 
306  //Point to the Proposal substructure
307  proposal = (IkeProposal *) p;
308 
309  //Format Proposal substructure
310  proposal->lastSubstruc = IKE_LAST_SUBSTRUC_LAST;
311  proposal->reserved = 0;
312  proposal->proposalLength = 0;
313  proposal->protocolId = childSa->protocol;
314  proposal->spiSize = IPSEC_SPI_SIZE;
315  proposal->numTransforms = 0;
316 
317  //Length of the Proposal substructure
318  n = sizeof(IkeProposal);
319 
320  //Copy the sending entity's SPI
321  osMemcpy(proposal->spi, childSa->localSpi, IPSEC_SPI_SIZE);
322  //Adjust the length of the Proposal substructure
323  n += IPSEC_SPI_SIZE;
324 
325  //The Proposal Length field indicates the length of the proposal, including
326  //all transforms and attributes that follow
327  proposal->proposalLength = htons(n);
328 
329  //The Last Substruc field has a value of 0 if this was the last Transform
330  //Substructure, and a value of 3 if there are more Transform Substructures
331  lastSubstruc = NULL;
332 
333  //Check whether the entity is the initiator of the CREATE_CHILD_SA
334  //exchange
335  if(childSa->initiator)
336  {
337  //When a proposal is made, the first proposal in an SA payload must be 1,
338  //and subsequent proposals must be one more than the previous proposal
339  //(refer to RFC 7296, section 3.3.1)
340  proposal->proposalNum = 1;
341 
342 #if (AH_SUPPORT == ENABLED)
343  //AH protocol identifier?
344  if(childSa->protocol == IPSEC_PROTOCOL_AH)
345  {
346  //AH generally has two transforms: ESN and an integrity check
347  //algorithm
348  error = ahAddSupportedTransforms(childSa, proposal, &lastSubstruc);
349  //Any error to report?
350  if(error)
351  return error;
352  }
353  else
354 #endif
355 #if (ESP_SUPPORT == ENABLED)
356  //ESP protocol identifier?
357  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
358  {
359  //ESP generally has three transforms: ESN, an encryption algorithm
360  //and an integrity check algorithm
361  error = espAddSupportedTransforms(childSa, proposal, &lastSubstruc);
362  //Any error to report?
363  if(error)
364  return error;
365  }
366  else
367 #endif
368  //Unknown protocol identifier?
369  {
370  //Report an error
371  return ERROR_FAILURE;
372  }
373  }
374  else
375  {
376  //When a proposal is accepted, the proposal number in the SA payload must
377  //match the number on the proposal sent that was accepted (refer to
378  //RFC 7296, section 3.3.1)
379  proposal->proposalNum = childSa->acceptedProposalNum;
380 
381 #if (AH_SUPPORT == ENABLED)
382  //AH protocol identifier?
383  if(childSa->protocol == IPSEC_PROTOCOL_AH)
384  {
385  //The accepted proposal contains a single integrity transform
387  childSa->authAlgoId, 0, proposal, &lastSubstruc);
388  //Any error to report?
389  if(error)
390  return error;
391 
392 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
393  //Perfect forward secrecy?
394  if(childSa->pfs)
395  {
396  //The accepted proposal contains a single key exchange transform
398  childSa->keContext.groupNum, 0, proposal, &lastSubstruc);
399  //Any error to report?
400  if(error)
401  return error;
402  }
403 #endif
404  //The accepted proposal contains a single ESN transform
405  error = ikeAddTransform(IKE_TRANSFORM_TYPE_ESN, childSa->esn,
406  0, proposal, &lastSubstruc);
407  //Any error to report?
408  if(error)
409  return error;
410  }
411  else
412 #endif
413 #if (ESP_SUPPORT == ENABLED)
414  //ESP protocol identifier?
415  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
416  {
417  //The accepted proposal contains a single encryption transform
418  error = ikeAddTransform(IKE_TRANSFORM_TYPE_ENCR, childSa->encAlgoId,
419  childSa->encKeyLen, proposal, &lastSubstruc);
420  //Any error to report?
421  if(error)
422  return error;
423 
424  //AEAD encryption algorithm?
425  if(ikeIsAeadEncAlgo(childSa->encAlgoId))
426  {
427  //If all of the encryption algorithms in any proposal are
428  //authenticated encryption algorithms, then the proposal must not
429  //propose any integrity transforms (refer to RFC 5282, section 8)
430  error = NO_ERROR;
431  }
432  else
433  {
434  //The accepted proposal contains a single integrity transform
436  childSa->authAlgoId, 0, proposal, &lastSubstruc);
437  }
438 
439  //Any error to report?
440  if(error)
441  return error;
442 
443 #if (IKE_CHILD_SA_PFS_SUPPORT == ENABLED)
444  //Perfect forward secrecy?
445  if(childSa->pfs)
446  {
447  //The accepted proposal contains a single key exchange transform
449  childSa->keContext.groupNum, 0, proposal, &lastSubstruc);
450  //Any error to report?
451  if(error)
452  return error;
453  }
454 #endif
455  //The accepted proposal contains a single ESN transform
456  error = ikeAddTransform(IKE_TRANSFORM_TYPE_ESN, childSa->esn,
457  0, proposal, &lastSubstruc);
458  //Any error to report?
459  if(error)
460  return error;
461  }
462  else
463 #endif
464  //Unknown protocol identifier?
465  {
466  //Report an error
467  return ERROR_FAILURE;
468  }
469  }
470 
471  //Total length of the Proposal substructure
472  *written = ntohs(proposal->proposalLength);
473 
474  //Successful processing
475  return NO_ERROR;
476 }
477 
478 
479 /**
480  * @brief Format Key Exchange payload
481  * @param[in] keContext Pointer to the key exchange context
482  * @param[out] p Buffer where to format the payload
483  * @param[out] written Length of the resulting payload
484  * @param[in,out] nextPayload Pointer to the Next Payload field
485  * @return Error code
486  **/
487 
488 error_t ikeFormatKePayload(IkeKeContext *keContext, uint8_t *p, size_t *written,
489  uint8_t **nextPayload)
490 {
491  error_t error;
492  size_t n;
493  IkeKePayload *kePayload;
494 
495  //Fix the Next Payload field of the previous payload
497 
498  //Point to the Key Exchange payload header
499  kePayload = (IkeKePayload *) p;
500 
501  //Format Key Exchange payload header
502  kePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
503  kePayload->header.critical = FALSE;
504  kePayload->header.reserved = 0;
505 
506  //The Key Exchange Method identifies the Diffie-Hellman group in which the
507  //Key Exchange Data was computed
508  kePayload->keyExchangeMethod = htons(keContext->groupNum);
509 
510  //For forward compatibility, all fields marked RESERVED must be set to
511  //zero (refer to RFC 7296, section 2.5)
512  kePayload->reserved = 0;
513 
514  //A Key Exchange payload is constructed by copying one's Diffie-Hellman
515  //public value into the Key Exchange Data portion of the payload
516  error = ikeFormatPublicKey(keContext, kePayload->keyExchangeData, &n);
517  //Any error to report?
518  if(error)
519  return error;
520 
521  //Total length of payload
522  *written = sizeof(IkeKePayload) + n;
523  //Fix the Payload Length field of the payload header
524  kePayload->header.payloadLength = htons(*written);
525 
526  //Keep track of the Next Payload field
527  *nextPayload = &kePayload->header.nextPayload;
528 
529  //Successful processing
530  return NO_ERROR;
531 }
532 
533 
534 /**
535  * @brief Format Identification payload
536  * @param[in] sa Pointer to the IKE SA
537  * @param[out] p Buffer where to format the payload
538  * @param[out] written Length of the resulting payload
539  * @param[in,out] nextPayload Pointer to the Next Payload field
540  * @return Error code
541  **/
542 
543 error_t ikeFormatIdPayload(IkeSaEntry *sa, uint8_t *p, size_t *written,
544  uint8_t **nextPayload)
545 {
546  error_t error;
547  IkeContext *context;
548  IkeIdPayload *idPayload;
549 
550  //Initialize status code
551  error = NO_ERROR;
552 
553  //Point to the IKE context
554  context = sa->context;
555 
556  //Fix the Next Payload field of the previous payload
557  if(sa->originalInitiator)
558  {
560  }
561  else
562  {
564  }
565 
566  //Point to the Identification payload header
567  idPayload = (IkeIdPayload *) p;
568 
569  //Format Identification payload header
570  idPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
571  idPayload->header.critical = FALSE;
572  idPayload->header.reserved = 0;
573 
574  //For forward compatibility, all fields marked RESERVED must be set to
575  //zero (refer to RFC 7296, section 2.5)
576  osMemset(idPayload->reserved, 0, 3);
577 
578  //Length of the payload header
579  *written = sizeof(IkeIdPayload);
580 
581  //Check the type of identification being used
582  if(context->idType != IKE_ID_TYPE_INVALID)
583  {
584  //Set ID type
585  idPayload->idType = context->idType;
586 
587  //Copy identification data
588  osMemcpy(idPayload->idData, context->id, context->idLen);
589  //Total length of the payload
590  *written += context->idLen;
591  }
592  else
593  {
594 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
595  //Check whether an end-entity's certificate exists
596  if(context->certChain != NULL && context->certChainLen > 0)
597  {
598  size_t n;
599 
600  //Set ID type
601  idPayload->idType = IKE_ID_TYPE_DER_ASN1_DN;
602 
603  //Extract the subject's distinguished name from the certificate
604  error = ikeGetCertSubjectDn(context->certChain, context->certChainLen,
605  idPayload->idData, &n);
606 
607  //Check status code
608  if(!error)
609  {
610  //Total length of the payload
611  *written += n;
612  }
613  }
614  else
615 #endif
616  {
617  //Report an error
618  error = ERROR_INVALID_TYPE;
619  }
620  }
621 
622  //Check status code
623  if(!error)
624  {
625  //Fix the Payload Length field of the payload header
626  idPayload->header.payloadLength = htons(*written);
627 
628  //Keep track of the Next Payload field
629  *nextPayload = &idPayload->header.nextPayload;
630  }
631 
632  //Return status code
633  return error;
634 }
635 
636 
637 /**
638  * @brief Format Certificate payloads
639  * @param[in] sa Pointer to the IKE SA
640  * @param[out] p Buffer where to format the payloads
641  * @param[out] written Length of the resulting payloads
642  * @param[in,out] nextPayload Pointer to the Next Payload field
643  * @return Error code
644  **/
645 
646 error_t ikeFormatCertPayloads(IkeSaEntry *sa, uint8_t *p, size_t *written,
647  uint8_t **nextPayload)
648 {
649 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
650  error_t error;
651  size_t m;
652  size_t n;
653  size_t certChainLen;
654  const char_t *certChain;
655  IkeContext *context;
656 
657  //Initialize status code
658  error = NO_ERROR;
659 
660  //Point to the IKE context
661  context = sa->context;
662 
663  //Total length of the Certificate payloads
664  *written = 0;
665 
666  //Check whether an end-entity's certificate exists
667  if(context->certChain != NULL && context->certChainLen > 0)
668  {
669  //Point to the certificate chain
670  certChain = context->certChain;
671  //Get the total length, in bytes, of the certificate chain
672  certChainLen = context->certChainLen;
673 
674  //If multiple certificates are sent, the first certificate must contain
675  //the public key associated with the private key used to sign the AUTH
676  //payload (refer to RFC 7296, section 3.6)
677  error = ikeFormatCertPayload(certChain, certChainLen, &m, p, &n,
678  nextPayload);
679 
680  //Check status code
681  if(!error)
682  {
683  //Point to the next payload
684  p += n;
685  *written += n;
686 
687  //Move to the next certificate of the chain
688  certChain += m;
689  certChainLen -= m;
690 
691  //If a chain of certificates needs to be sent, multiple Certificate
692  //payloads are used
693  while(certChainLen > 0 && !error)
694  {
695  //Format Certificate payload
696  error = ikeFormatCertPayload(certChain, certChainLen, &m, p, &n,
697  nextPayload);
698 
699  //Check status code
700  if(!error)
701  {
702  //Point to the next payload
703  p += n;
704  *written += n;
705 
706  //Move to the next certificate of the chain
707  certChain += m;
708  certChainLen -= m;
709  }
710  }
711 
712  //The end of the certificate chain has been reached
713  error = NO_ERROR;
714  }
715  }
716 
717  //Return status code
718  return error;
719 #else
720  //Certificate authentication is not supported
721  *written = 0;
722  //Successful processing
723  return NO_ERROR;
724 #endif
725 }
726 
727 
728 /**
729  * @brief Format Certificate payload
730  * @param[in] certChain Pointer to the certificate chain (PEM format)
731  * @param[in] certChainLen Length of the certificate chain, in bytes
732  * @param[out] consumed Total number of characters that have been consumed
733  * @param[out] p Buffer where to format the payload
734  * @param[out] written Length of the resulting payload
735  * @param[in,out] nextPayload Pointer to the Next Payload field
736  * @return Error code
737  **/
738 
739 error_t ikeFormatCertPayload(const char_t *certChain, size_t certChainLen,
740  size_t *consumed, uint8_t *p, size_t *written, uint8_t **nextPayload)
741 {
742 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
743  error_t error;
744  size_t n;
745  IkeCertPayload *certPayload;
746 
747  //Point to the Certificate payload header
748  certPayload = (IkeCertPayload *) p;
749 
750  //The Certificate Data field Extract the DER-encoded certificate
751  error = pemImportCertificate(certChain, certChainLen, certPayload->certData,
752  &n, consumed);
753 
754  //Check status code
755  if(!error)
756  {
757  //Fix the Next Payload field of the previous payload
759 
760  //Format Certificate payload header
761  certPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
762  certPayload->header.critical = FALSE;
763  certPayload->header.reserved = 0;
764  certPayload->certEncoding = IKE_CERT_ENCODING_X509_CERT_SIGN;
765 
766  //Total length of the payload
767  *written = sizeof(IkeCertPayload) + n;
768  //Fix the Payload Length field of the payload header
769  certPayload->header.payloadLength = htons(*written);
770 
771  //Keep track of the Next Payload field
772  *nextPayload = &certPayload->header.nextPayload;
773  }
774  else
775  {
776  //End of file detected
777  *written = 0;
778  }
779 
780  //Return status code
781  return error;
782 #else
783  //Certificate authentication is not supported
784  *written = 0;
785  //Successful processing
786  return NO_ERROR;
787 #endif
788 }
789 
790 
791 /**
792  * @brief Format Certificate Request payload
793  * @param[in] sa Pointer to the IKE SA
794  * @param[out] p Buffer where to format the payload
795  * @param[out] written Length of the resulting payload
796  * @param[in,out] nextPayload Pointer to the Next Payload field
797  * @return Error code
798  **/
799 
800 error_t ikeFormatCertReqPayload(IkeSaEntry *sa, uint8_t *p, size_t *written,
801  uint8_t **nextPayload)
802 {
803 #if (IKE_CERT_AUTH_SUPPORT == ENABLED)
804  error_t error;
805  uint_t i;
806  size_t n;
807  IpsecPadEntry *entry;
808  IpsecContext *ipsecContext;
809  IkeCertReqPayload *certReqPayload;
810 
811  //Initialize status code
812  error = NO_ERROR;
813 
814  //Point to the IPsec context
815  ipsecContext = sa->context->netContext->ipsecContext;
816  //Sanity check
817  if(ipsecContext == NULL)
818  return ERROR_FAILURE;
819 
820  //Point to the Certificate Request payload header
821  certReqPayload = (IkeCertReqPayload *) p;
822 
823  //Length of the Certification Authority field
824  n = 0;
825 
826  //Loop through PAD entries
827  for(i = 0; i < ipsecContext->numPadEntries && !error; i++)
828  {
829  //Point to the current PAD entry
830  entry = &ipsecContext->pad[i];
831 
832  //Valid authentication method?
833  if(entry->authMethod == IPSEC_AUTH_METHOD_IKEV2)
834  {
835  //Valid trusted CA list?
836  if(entry->trustedCaList != NULL && entry->trustedCaListLen > 0)
837  {
838  //The Certification Authority value is a concatenated list of
839  //SHA-1 hashes of the public keys of trusted Certification
840  //Authorities (CAs)
842  entry->trustedCaListLen, certReqPayload->certAuthority, &n);
843  }
844  }
845  }
846 
847  //Check status code
848  if(!error)
849  {
850  //Check the length of the Certification Authority field
851  if(n > 0)
852  {
853  //Fix the Next Payload field of the previous payload
855 
856  //Format Certificate payload header
857  certReqPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
858  certReqPayload->header.critical = FALSE;
859  certReqPayload->header.reserved = 0;
860  certReqPayload->certEncoding = IKE_CERT_ENCODING_X509_CERT_SIGN;
861 
862  //Total length of the payload
863  *written = sizeof(IkeCertReqPayload) + n;
864  //Fix the Payload Length field of the payload header
865  certReqPayload->header.payloadLength = htons(*written);
866 
867  //Keep track of the Next Payload field
868  *nextPayload = &certReqPayload->header.nextPayload;
869  }
870  else
871  {
872  //The Certification Authority field is empty
873  *written = 0;
874  }
875  }
876 
877  //Return status code
878  return error;
879 #else
880  //Certificate authentication is not supported
881  *written = 0;
882  //Successful processing
883  return NO_ERROR;
884 #endif
885 }
886 
887 
888 /**
889  * @brief Format Authentication payload
890  * @param[in] sa Pointer to the IKE SA
891  * @param[in] idPayload Pointer to the Identification payload
892  * @param[out] p Buffer where to format the payload
893  * @param[out] written Length of the resulting payload
894  * @param[in,out] nextPayload Pointer to the Next Payload field
895  * @return Error code
896  **/
897 
899  uint8_t *p, size_t *written, uint8_t **nextPayload)
900 {
901  error_t error;
902  size_t n;
903  IkeAuthPayload *authPayload;
904 
905  //Fix the Next Payload field of the previous payload
907 
908  //Point to the Authentication payload header
909  authPayload = (IkeAuthPayload *) p;
910 
911  //Format Authentication payload header
912  authPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
913  authPayload->header.critical = FALSE;
914  authPayload->header.reserved = 0;
915 
916  //For forward compatibility, all fields marked RESERVED must be set to
917  //zero (refer to RFC 7296, section 2.5)
918  osMemset(authPayload->reserved, 0, 3);
919 
920  //Generate AUTH value
921  error = ikeGenerateAuth(sa, idPayload, &authPayload->authMethod,
922  authPayload->authData, &n);
923 
924  //Check status code
925  if(!error)
926  {
927  //Total length of the payload
928  *written = sizeof(IkeAuthPayload) + n;
929  //Fix the Payload Length field of the payload header
930  authPayload->header.payloadLength = htons(*written);
931 
932  //Keep track of the Next Payload field
933  *nextPayload = &authPayload->header.nextPayload;
934  }
935 
936  //Return status code
937  return error;
938 }
939 
940 
941 /**
942  * @brief Format Nonce payload
943  * @param[in] sa Pointer to the IKE SA
944  * @param[in] childSa Pointer to the Child SA
945  * @param[out] p Buffer where to format the payload
946  * @param[out] written Length of the resulting payload
947  * @param[in,out] nextPayload Pointer to the Next Payload field
948  * @return Error code
949  **/
950 
952  uint8_t *p, size_t *written, uint8_t **nextPayload)
953 {
954  IkeNoncePayload *noncePayload;
955 
956  //Fix the Next Payload field of the previous payload
958 
959  //Point to the Nonce payload header
960  noncePayload = (IkeNoncePayload *) p;
961 
962  //Format Nonce payload header
963  noncePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
964  noncePayload->header.critical = FALSE;
965  noncePayload->header.reserved = 0;
966 
967  //Length of the payload header
968  *written = sizeof(IkeNoncePayload);
969 
970  //Valid Child SA?
971  if(childSa != NULL)
972  {
973  //Check whether the entity is the initiator of the CREATE_CHILD_SA
974  //exchange
975  if(childSa->initiator)
976  {
977  //Copy the initiator's nonce
978  osMemcpy(noncePayload->nonceData, childSa->initiatorNonce,
979  childSa->initiatorNonceLen);
980 
981  //The size of the Nonce Data must be between 16 and 256 octets
982  *written += childSa->initiatorNonceLen;
983  }
984  else
985  {
986  //Copy the responder's nonce
987  osMemcpy(noncePayload->nonceData, childSa->responderNonce,
988  childSa->responderNonceLen);
989 
990  //The size of the Nonce Data must be between 16 and 256 octets
991  *written += childSa->responderNonceLen;
992  }
993  }
994  else
995  {
996  //Check whether the entity is the original initiator of the IKE SA
997  if(sa->originalInitiator)
998  {
999  //Copy the initiator's nonce
1000  osMemcpy(noncePayload->nonceData, sa->initiatorNonce,
1001  sa->initiatorNonceLen);
1002 
1003  //The size of the Nonce Data must be between 16 and 256 octets
1004  *written += sa->initiatorNonceLen;
1005  }
1006  else
1007  {
1008  //Copy the responder's nonce
1009  osMemcpy(noncePayload->nonceData, sa->responderNonce,
1010  sa->responderNonceLen);
1011 
1012  //The size of the Nonce Data must be between 16 and 256 octets
1013  *written += sa->responderNonceLen;
1014  }
1015  }
1016 
1017  //Fix the Payload Length field of the payload header
1018  noncePayload->header.payloadLength = htons(*written);
1019 
1020  //Keep track of the Next Payload field
1021  *nextPayload = &noncePayload->header.nextPayload;
1022 
1023  //Successful processing
1024  return NO_ERROR;
1025 }
1026 
1027 
1028 /**
1029  * @brief Format Notify payload
1030  * @param[in] sa Pointer to the IKE SA
1031  * @param[in] childSa Pointer to the Child SA
1032  * @param[in] notifyMsgType Type of notification
1033  * @param[out] p Buffer where to format the payload
1034  * @param[out] written Length of the resulting payload
1035  * @param[in,out] nextPayload Pointer to the Next Payload field
1036  * @return Error code
1037  **/
1038 
1040  IkeNotifyMsgType notifyMsgType, uint8_t *p, size_t *written,
1041  uint8_t **nextPayload)
1042 {
1043  error_t error;
1044  size_t n;
1045  IkeNotifyPayload *notifyPayload;
1046 
1047  //Initialize status code
1048  error = NO_ERROR;
1049 
1050  //Fix the Next Payload field of the previous payload
1052 
1053  //Point to the Notify payload header
1054  notifyPayload = (IkeNotifyPayload *) p;
1055 
1056  //Format Notify payload header
1057  notifyPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1058  notifyPayload->header.critical = FALSE;
1059  notifyPayload->header.reserved = 0;
1060 
1061  //If the SPI field is empty, the Protocol ID field must be sent as zero and
1062  //must be ignored on receipt (refer to RFC 7296, section 3.10)
1063  notifyPayload->protocolId = 0;
1064  notifyPayload->spiSize = 0;
1065 
1066  //The Notify Message Type field specifies the type of notification message
1067  notifyPayload->notifyMsgType = htons(notifyMsgType);
1068 
1069  //Length of the payload header
1070  *written = sizeof(IkeNotifyPayload);
1071 
1072  //The notification may include additional data
1074  {
1075  //In that Notify payload, the Notification Data contains the one-octet
1076  //payload type (refer to RFC 7296, section 2.5)
1077  notifyPayload->spi[0] = sa->unsupportedCriticalPayload;
1078 
1079  //Total length of the payload
1080  *written += sizeof(uint8_t);
1081  }
1083  {
1084  //The responder indicate its preferred Diffie-Hellman group in the
1085  //INVALID_KE_PAYLOAD Notify payload
1086  STORE16BE(sa->preferredGroupNum, notifyPayload->spi);
1087 
1088  //Total length of the payload
1089  *written += sizeof(uint16_t);
1090  }
1092  {
1093  //The Protocol ID field must contain either 2 to indicate AH or 3 to
1094  //indicate ESP
1095  notifyPayload->protocolId = sa->notifyProtocolId;
1096 
1097  //The SPI Size field specifies the length in octets of the SPI as
1098  //defined by the IPsec protocol ID
1099  notifyPayload->spiSize = IPSEC_SPI_SIZE;
1100 
1101  //The SPI is included only with INVALID_SELECTORS, REKEY_SA, and
1102  //CHILD_SA_NOT_FOUND notifications (refer to RFC 7296, section 3.10)
1103  osMemcpy(notifyPayload->spi, sa->notifySpi, IPSEC_SPI_SIZE);
1104 
1105  //Total length of the payload
1106  *written += notifyPayload->spiSize;
1107  }
1109  {
1110  //The data associated with the NAT_DETECTION_SOURCE_IP notification is a
1111  //SHA-1 digest of the SPIs (in the order they appear in the header), IP
1112  //address, and port from which this packet was sent
1113  error = ikeFormatNatDetectSrcIpNotificationData(sa, notifyPayload->spi,
1114  &n);
1115 
1116  //Check status code
1117  if(!error)
1118  {
1119  //Total length of the payload
1120  *written += n;
1121  }
1122  }
1124  {
1125  //The data associated with the NAT_DETECTION_DESTINATION_IP notification
1126  //is a SHA-1 digest of the SPIs (in the order they appear in the header),
1127  //IP address, and port to which this packet was sent
1128  error = ikeFormatNatDetectDestIpNotificationData(sa, notifyPayload->spi,
1129  &n);
1130 
1131  //Check status code
1132  if(!error)
1133  {
1134  //Total length of the payload
1135  *written += n;
1136  }
1137  }
1139  {
1140  //The data associated with this notification must be between 1 and 64
1141  //octets in length (refer to RFC 7296, section 2.6)
1142  osMemcpy(notifyPayload->spi, sa->cookie, sa->cookieLen);
1143 
1144  //Adjust the length of the Notify payload
1145  *written += sa->cookieLen;
1146  }
1148  {
1149  //The Protocol ID field must contain either 2 to indicate AH or 3 to
1150  //indicate ESP
1151  notifyPayload->protocolId = childSa->protocol;
1152 
1153  //The SPI Size field specifies the length in octets of the SPI as
1154  //defined by the IPsec protocol ID
1155  notifyPayload->spiSize = IPSEC_SPI_SIZE;
1156 
1157  //The SA being rekeyed is identified by the SPI field in the Notify
1158  //payload; this is the SPI the exchange initiator would expect in
1159  //inbound ESP or AH packets. There is no data associated with this
1160  //Notify message type (refer to RFC 7296, section 1.3.3)
1161  osMemcpy(notifyPayload->spi, childSa->oldChildSa->localSpi,
1162  IPSEC_SPI_SIZE);
1163 
1164  //Total length of the payload
1165  *written += notifyPayload->spiSize;
1166  }
1168  {
1169  //The Notification Data field contains the list of 16-bit hash algorithm
1170  //identifiers (refer to RFC 7427, section 4)
1171  error = ikeFormatSignHashAlgosNotificationData(sa, notifyPayload->spi,
1172  &n);
1173 
1174  //Check status code
1175  if(!error)
1176  {
1177  //Total length of the payload
1178  *written += n;
1179  }
1180  }
1181  else
1182  {
1183  //Just for sanity
1184  }
1185 
1186  //Check status code
1187  if(!error)
1188  {
1189  //Fix the Payload Length field of the payload header
1190  notifyPayload->header.payloadLength = htons(*written);
1191 
1192  //Keep track of the Next Payload field
1193  *nextPayload = &notifyPayload->header.nextPayload;
1194  }
1195 
1196  //Return status code
1197  return error;
1198 }
1199 
1200 
1201 /**
1202  * @brief Format NAT_DETECTION_SOURCE_IP notification data
1203  * @param[in] sa Pointer to the IKE SA
1204  * @param[out] p Buffer where to format the notification data
1205  * @param[out] written Length of the notification data, in bytes
1206  * @return Error code
1207  **/
1208 
1210  size_t *written)
1211 {
1212 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
1213  error_t error;
1214  IpAddr localIpAddr;
1215  uint16_t localPort;
1216  NetInterface *interface;
1217  IkeContext *context;
1218  Sha1Context sha1Context;
1219 
1220  //Point to the IKE context
1221  context = sa->context;
1222 
1223  //Check whether the entity is the original initiator of the IKE SA
1224  if(sa->originalInitiator)
1225  {
1226  //Point to the network interface
1227  interface = context->interface;
1228 
1229  //Get exclusive access
1230  netLock(context->netContext);
1231 
1232  //Retrieve the IP address of the host
1233  error = ipSelectSourceAddr(context->netContext, &interface,
1234  &sa->remoteIpAddr, &localIpAddr);
1235 
1236  //Release exclusive access
1237  netUnlock(context->netContext);
1238 
1239  //Any error to report?
1240  if(error)
1241  return error;
1242 
1243  //Convert the source port number to network byte order
1244  if(sa->localNat || sa->remoteNat)
1245  {
1246  localPort = HTONS(IPSEC_NAT_PORT);
1247  }
1248  else
1249  {
1250  localPort = HTONS(IKE_PORT);
1251  }
1252  }
1253  else
1254  {
1255  //Retrieve the IP address of the host
1256  localIpAddr = context->localIpAddr;
1257  //Convert the source port number to network byte order
1258  localPort = htons(context->localPort);
1259  }
1260 
1261  //The data associated with the NAT_DETECTION_SOURCE_IP notification is a
1262  //SHA-1 digest of the SPIs (in the order they appear in the header), IP
1263  //address, and port from which this packet was sent
1264  sha1Init(&sha1Context);
1265  sha1Update(&sha1Context, sa->initiatorSpi, IKE_SPI_SIZE);
1266  sha1Update(&sha1Context, sa->responderSpi, IKE_SPI_SIZE);
1267  sha1Update(&sha1Context, localIpAddr.addr, localIpAddr.length);
1268  sha1Update(&sha1Context, &localPort, sizeof(localPort));
1269  sha1Final(&sha1Context, p);
1270 
1271  //Set the length of the notification data
1272  *written = SHA1_DIGEST_SIZE;
1273 
1274  //Successful processing
1275  return NO_ERROR;
1276 #else
1277  //Minimal implementations are not required to support NAT traversal
1278  return ERROR_NOT_IMPLEMENTED;
1279 #endif
1280 }
1281 
1282 
1283 /**
1284  * @brief Format NAT_DETECTION_DESTINATION_IP notification data
1285  * @param[in] sa Pointer to the IKE SA
1286  * @param[out] p Buffer where to format the notification data
1287  * @param[out] written Length of the notification data, in bytes
1288  * @return Error code
1289  **/
1290 
1292  size_t *written)
1293 {
1294 #if (IKE_NAT_TRAVERSAL_SUPPORT == ENABLED)
1295  IpAddr remoteIpAddr;
1296  uint16_t remotePort;
1297  IkeContext *context;
1298  Sha1Context sha1Context;
1299 
1300  //Point to the IKE context
1301  context = sa->context;
1302 
1303  //Check whether the entity is the original initiator of the IKE SA
1304  if(sa->originalInitiator)
1305  {
1306  //Get the recipient IP address
1307  remoteIpAddr = sa->remoteIpAddr;
1308 
1309  //Convert the destination port number to network byte order
1310  if(sa->localNat || sa->remoteNat)
1311  {
1312  remotePort = HTONS(IPSEC_NAT_PORT);
1313  }
1314  else
1315  {
1316  remotePort = HTONS(IKE_PORT);
1317  }
1318  }
1319  else
1320  {
1321  //Get the recipient IP address and port number
1322  remoteIpAddr = context->remoteIpAddr;
1323  remotePort = htons(context->remotePort);
1324  }
1325 
1326  //The data associated with the NAT_DETECTION_DESTINATION_IP notification is
1327  //a SHA-1 digest of the SPIs (in the order they appear in the header), IP
1328  //address, and port to which this packet was sent
1329  sha1Init(&sha1Context);
1330  sha1Update(&sha1Context, sa->initiatorSpi, IKE_SPI_SIZE);
1331  sha1Update(&sha1Context, sa->responderSpi, IKE_SPI_SIZE);
1332  sha1Update(&sha1Context, remoteIpAddr.addr, remoteIpAddr.length);
1333  sha1Update(&sha1Context, &remotePort, sizeof(remotePort));
1334  sha1Final(&sha1Context, p);
1335 
1336  //Set the length of the notification data
1337  *written = SHA1_DIGEST_SIZE;
1338 
1339  //Successful processing
1340  return NO_ERROR;
1341 #else
1342  //Minimal implementations are not required to support NAT traversal
1343  return ERROR_NOT_IMPLEMENTED;
1344 #endif
1345 }
1346 
1347 
1348 /**
1349  * @brief Format SIGNATURE_HASH_ALGORITHMS notification data
1350  * @param[in] sa Pointer to the IKE SA
1351  * @param[out] p Buffer where to format the notification data
1352  * @param[out] written Length of the notification data, in bytes
1353  * @return Error code
1354  **/
1355 
1357  size_t *written)
1358 {
1359 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
1360  //The Notification Data field contains the list of 16-bit hash algorithm
1361  //identifiers
1362  *written = 0;
1363 
1364 #if (IKE_SHA1_SUPPORT == ENABLED)
1365  //SHA-1 hash algorithm is supported
1367 
1368  //Adjust the length of the notification data
1369  p += sizeof(uint16_t);
1370  *written += sizeof(uint16_t);
1371 #endif
1372 
1373 #if (IKE_SHA256_SUPPORT == ENABLED)
1374  //SHA-256 hash algorithm is supported
1376 
1377  //Adjust the length of the notification data
1378  p += sizeof(uint16_t);
1379  *written += sizeof(uint16_t);
1380 #endif
1381 
1382 #if (IKE_SHA384_SUPPORT == ENABLED)
1383  //SHA-384 hash algorithm is supported
1385 
1386  //Adjust the length of the notification data
1387  p += sizeof(uint16_t);
1388  *written += sizeof(uint16_t);
1389 #endif
1390 
1391 #if (IKE_SHA512_SUPPORT == ENABLED)
1392  //SHA-512 hash algorithm is supported
1394 
1395  //Adjust the length of the notification data
1396  p += sizeof(uint16_t);
1397  *written += sizeof(uint16_t);
1398 #endif
1399 
1400 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED || IKE_ED448_SIGN_SUPPORT == ENABLED)
1401  //Inserting "Identity" hash identifier indicates that the receiver supports
1402  //at least one signature algorithm that accepts messages of arbitrary size
1403  //such as Ed25519 and Ed448 (refer to RFC 8420, section 2)
1405 
1406  //Adjust the length of the notification data
1407  p += sizeof(uint16_t);
1408  *written += sizeof(uint16_t);
1409 #endif
1410 
1411  //Successful processing
1412  return NO_ERROR;
1413 #else
1414  //The SIGNATURE_HASH_ALGORITHMS notification is not supported
1415  return ERROR_NOT_IMPLEMENTED;
1416 #endif
1417 }
1418 
1419 
1420 /**
1421  * @brief Format Delete payload
1422  * @param[in] sa Pointer to the IKE SA
1423  * @param[in] childSa Pointer to the Child SA
1424  * @param[out] p Buffer where to format the payload
1425  * @param[out] written Length of the resulting payload
1426  * @param[in,out] nextPayload Pointer to the Next Payload field
1427  * @return Error code
1428  **/
1429 
1431  uint8_t *p, size_t *written, uint8_t **nextPayload)
1432 {
1433  IkeDeletePayload *deletePayload;
1434 
1435  //Fix the Next Payload field of the previous payload
1437 
1438  //Point to the Delete payload header
1439  deletePayload = (IkeDeletePayload *) p;
1440 
1441  //Format Delete payload header
1442  deletePayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1443  deletePayload->header.critical = FALSE;
1444  deletePayload->header.reserved = 0;
1445 
1446  //Length of the payload header
1447  *written = sizeof(IkeDeletePayload);
1448 
1449  //Valid Child SA?
1450  if(childSa != NULL)
1451  {
1452  deletePayload->protocolId = childSa->protocol;
1453  deletePayload->spiSize = IPSEC_SPI_SIZE;
1454  deletePayload->numSpi = HTONS(1);
1455 
1456  //Deletion of a Child SA, such as ESP or AH, will contain the IPsec
1457  //protocol ID of that protocol (2 for AH, 3 for ESP), and the SPI is the
1458  //SPI the sending endpoint would expect in inbound ESP or AH packets
1459  osMemcpy(deletePayload->spi, childSa->localSpi, IPSEC_SPI_SIZE);
1460 
1461  //Total length of the payload
1462  *written += IPSEC_SPI_SIZE;
1463  }
1464  else
1465  {
1466  //Deletion of the IKE SA is indicated by a protocol ID of 1 (IKE) but
1467  //no SPIs
1468  deletePayload->protocolId = IKE_PROTOCOL_ID_IKE;
1469  deletePayload->spiSize = 0;
1470  deletePayload->numSpi = HTONS(0);
1471  }
1472 
1473  //Fix the Payload Length field of the payload header
1474  deletePayload->header.payloadLength = htons(*written);
1475 
1476  //Keep track of the Next Payload field
1477  *nextPayload = &deletePayload->header.nextPayload;
1478 
1479  //Successful processing
1480  return NO_ERROR;
1481 }
1482 
1483 
1484 /**
1485  * @brief Format Traffic Selector payload (initiator)
1486  * @param[in] childSa Pointer to the Child SA
1487  * @param[out] p Buffer where to format the payload
1488  * @param[out] written Length of the resulting payload
1489  * @param[in,out] nextPayload Pointer to the Next Payload field
1490  * @return Error code
1491  **/
1492 
1494  size_t *written, uint8_t **nextPayload)
1495 {
1496  error_t error;
1497  size_t n;
1498  IkeTsEntry tsEntry;
1499  IkeTsPayload *tsPayload;
1500  IpsecSelector *selector;
1501 
1502  //Get selector parameters
1503  selector = &childSa->selector;
1504 
1505  //Fix the Next Payload field of the previous payload
1507 
1508  //Point to the Traffic Selector payload header
1509  tsPayload = (IkeTsPayload *) p;
1510 
1511  //Format Traffic Selector payload header
1512  tsPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1513  tsPayload->header.critical = FALSE;
1514  tsPayload->header.reserved = 0;
1515  tsPayload->numTs = 0;
1516 
1517  //The reserved field must be sent as zero
1518  osMemset(tsPayload->reserved, 0, 3);
1519 
1520  //Length of the payload header
1521  *written = sizeof(IkeTsPayload);
1522 
1523  //Point to the Traffic Selectors field
1524  p = tsPayload->trafficSelectors;
1525 
1526  //Check whether the entity is the initiator of the exchange
1527  if(childSa->initiator)
1528  {
1529 #if (IKE_SPECIFIC_TS_SUPPORT == ENABLED)
1530  //If the initiator has requested the SA due to a data packet, the
1531  //initiator should include as the first Traffic Selector in each of TSi
1532  //and TSr a very specific Traffic Selector including the addresses in
1533  //the packet triggering the request (refer to RFC 7296, section 2.9)
1534  if(childSa->state == IKE_CHILD_SA_STATE_INIT)
1535  {
1536  //The very specific first Traffic Selector helps the responder to
1537  //select the correct range
1538  tsEntry.startAddr = childSa->packetInfo.localIpAddr;
1539  tsEntry.endAddr = childSa->packetInfo.localIpAddr;
1540  tsEntry.ipProtocolId = childSa->packetInfo.nextProtocol;
1541  tsEntry.startPort = childSa->packetInfo.localPort;
1542  tsEntry.endPort = childSa->packetInfo.localPort;
1543 
1544  //The Traffic Selector payload may contain multiple Traffic Selector
1545  //substructures
1546  if(!ipCompAddr(&selector->localIpAddr.start, &tsEntry.startAddr) ||
1547  !ipCompAddr(&selector->localIpAddr.end, &tsEntry.endAddr) ||
1548  selector->nextProtocol != tsEntry.ipProtocolId ||
1549  selector->localPort.start != tsEntry.startPort ||
1550  selector->localPort.end != tsEntry.endPort)
1551  {
1552  //Format Traffic Selector substructure
1553  error = ikeFormatTsEntry(&tsEntry, p, &n);
1554  //Any error to report?
1555  if(error)
1556  return error;
1557 
1558  //Point to the next substructure
1559  p += n;
1560  *written += n;
1561 
1562  //Adjust the number of Traffic Selector substructures
1563  tsPayload->numTs++;
1564 
1565  //The second traffic selector contains a range of IP addresses
1566  //and ports
1567  tsEntry.startAddr = selector->localIpAddr.start;
1568  tsEntry.endAddr = selector->localIpAddr.end;
1569  tsEntry.ipProtocolId = selector->nextProtocol;
1570  tsEntry.startPort = selector->localPort.start;
1571  tsEntry.endPort = selector->localPort.end;
1572  }
1573  }
1574  else
1575 #endif
1576  {
1577  //TSi specifies the source address of traffic forwarded from (or the
1578  //destination address of traffic forwarded to) the initiator of the
1579  //Child SA pair (refer to RFC 7296, section 2.9)
1580  tsEntry.startAddr = selector->localIpAddr.start;
1581  tsEntry.endAddr = selector->localIpAddr.end;
1582  tsEntry.ipProtocolId = selector->nextProtocol;
1583  tsEntry.startPort = selector->localPort.start;
1584  tsEntry.endPort = selector->localPort.end;
1585  }
1586  }
1587  else
1588  {
1589  //TSi specifies the source address of traffic forwarded from (or the
1590  //destination address of traffic forwarded to) the initiator of the Child
1591  //SA pair (refer to RFC 7296, section 2.9)
1592  tsEntry.startAddr = selector->remoteIpAddr.start;
1593  tsEntry.endAddr = selector->remoteIpAddr.end;
1594  tsEntry.ipProtocolId = selector->nextProtocol;
1595  tsEntry.startPort = selector->remotePort.start;
1596  tsEntry.endPort = selector->remotePort.end;
1597  }
1598 
1599  //Format Traffic Selector substructure
1600  error = ikeFormatTsEntry(&tsEntry, p, &n);
1601  //Any error to report?
1602  if(error)
1603  return error;
1604 
1605  //Total length of the payload
1606  *written += n;
1607 
1608  //Adjust the number of Traffic Selector substructures
1609  tsPayload->numTs++;
1610 
1611  //Fix the Payload Length field of the payload header
1612  tsPayload->header.payloadLength = htons(*written);
1613 
1614  //Keep track of the Next Payload field
1615  *nextPayload = &tsPayload->header.nextPayload;
1616 
1617  //Return status code
1618  return error;
1619 }
1620 
1621 
1622 /**
1623  * @brief Format Traffic Selector payload (responder)
1624  * @param[in] childSa Pointer to the Child SA
1625  * @param[out] p Buffer where to format the payload
1626  * @param[out] written Length of the resulting payload
1627  * @param[in,out] nextPayload Pointer to the Next Payload field
1628  * @return Error code
1629  **/
1630 
1632  size_t *written, uint8_t **nextPayload)
1633 {
1634  error_t error;
1635  size_t n;
1636  IkeTsEntry tsEntry;
1637  IkeTsPayload *tsPayload;
1638  IpsecSelector *selector;
1639 
1640  //Get selector parameters
1641  selector = &childSa->selector;
1642 
1643  //Fix the Next Payload field of the previous payload
1645 
1646  //Point to the Traffic Selector payload header
1647  tsPayload = (IkeTsPayload *) p;
1648 
1649  //Format Traffic Selector payload header
1650  tsPayload->header.nextPayload = IKE_PAYLOAD_TYPE_LAST;
1651  tsPayload->header.critical = FALSE;
1652  tsPayload->header.reserved = 0;
1653  tsPayload->numTs = 0;
1654 
1655  //The reserved field must be sent as zero
1656  osMemset(tsPayload->reserved, 0, 3);
1657 
1658  //Length of the payload header
1659  *written = sizeof(IkeTsPayload);
1660 
1661  //Point to the Traffic Selectors field
1662  p = tsPayload->trafficSelectors;
1663 
1664  //Check whether the entity is the initiator of the exchange
1665  if(childSa->initiator)
1666  {
1667 #if (IKE_SPECIFIC_TS_SUPPORT == ENABLED)
1668  //If the initiator has requested the SA due to a data packet, the
1669  //initiator should include as the first Traffic Selector in each of TSi
1670  //and TSr a very specific Traffic Selector including the addresses in
1671  //the packet triggering the request (refer to RFC 7296, section 2.9)
1672  if(childSa->state == IKE_CHILD_SA_STATE_INIT &&
1673  (childSa->packetInfo.nextProtocol == IPV4_PROTOCOL_UDP ||
1674  childSa->packetInfo.nextProtocol == IPV4_PROTOCOL_TCP))
1675  {
1676  //The very specific first Traffic Selector helps the responder to
1677  //select the correct range
1678  tsEntry.startAddr = childSa->packetInfo.remoteIpAddr;
1679  tsEntry.endAddr = childSa->packetInfo.remoteIpAddr;
1680  tsEntry.ipProtocolId = childSa->packetInfo.nextProtocol;
1681  tsEntry.startPort = childSa->packetInfo.remotePort;
1682  tsEntry.endPort = childSa->packetInfo.remotePort;
1683 
1684  //The Traffic Selector payload may contain multiple Traffic Selector
1685  //substructures
1686  if(!ipCompAddr(&selector->remoteIpAddr.start, &tsEntry.startAddr) ||
1687  !ipCompAddr(&selector->remoteIpAddr.end, &tsEntry.endAddr) ||
1688  selector->nextProtocol != tsEntry.ipProtocolId ||
1689  selector->remotePort.start != tsEntry.startPort ||
1690  selector->remotePort.end != tsEntry.endPort)
1691  {
1692  //Format Traffic Selector substructure
1693  error = ikeFormatTsEntry(&tsEntry, p, &n);
1694  //Any error to report?
1695  if(error)
1696  return error;
1697 
1698  //Point to the next substructure
1699  p += n;
1700  *written += n;
1701 
1702  //Adjust the number of Traffic Selector substructures
1703  tsPayload->numTs++;
1704 
1705  //The second traffic selector contains a range of IP addresses
1706  //and ports
1707  tsEntry.startAddr = selector->remoteIpAddr.start;
1708  tsEntry.endAddr = selector->remoteIpAddr.end;
1709  tsEntry.ipProtocolId = selector->nextProtocol;
1710  tsEntry.startPort = selector->remotePort.start;
1711  tsEntry.endPort = selector->remotePort.end;
1712  }
1713  }
1714  else
1715 #endif
1716  {
1717  //TSr specifies the source address of traffic forwarded from (or the
1718  //destination address of traffic forwarded to) the responder of the
1719  //Child SA pair (refer to RFC 7296, section 2.9)
1720  tsEntry.startAddr = selector->remoteIpAddr.start;
1721  tsEntry.endAddr = selector->remoteIpAddr.end;
1722  tsEntry.ipProtocolId = selector->nextProtocol;
1723  tsEntry.startPort = selector->remotePort.start;
1724  tsEntry.endPort = selector->remotePort.end;
1725  }
1726  }
1727  else
1728  {
1729  //TSr specifies the source address of traffic forwarded from (or the
1730  //destination address of traffic forwarded to) the responder of the Child
1731  //SA pair (refer to RFC 7296, section 2.9)
1732  tsEntry.startAddr = selector->localIpAddr.start;
1733  tsEntry.endAddr = selector->localIpAddr.end;
1734  tsEntry.ipProtocolId = selector->nextProtocol;
1735  tsEntry.startPort = selector->localPort.start;
1736  tsEntry.endPort = selector->localPort.end;
1737  }
1738 
1739  //Format Traffic Selector substructure
1740  error = ikeFormatTsEntry(&tsEntry, p, &n);
1741  //Any error to report?
1742  if(error)
1743  return error;
1744 
1745  //Total length of the payload
1746  *written += n;
1747 
1748  //Adjust the number of Traffic Selector substructures
1749  tsPayload->numTs++;
1750 
1751  //Fix the Payload Length field of the payload header
1752  tsPayload->header.payloadLength = htons(*written);
1753 
1754  //Keep track of the Next Payload field
1755  *nextPayload = &tsPayload->header.nextPayload;
1756 
1757  //Return status code
1758  return error;
1759 }
1760 
1761 
1762 /**
1763  * @brief Format Traffic Selector substructure
1764  * @param[in] tsEntry Traffic selector entry
1765  * @param[out] p Buffer where to format the Traffic Selector substructure
1766  * @param[out] written Length of the resulting Traffic Selector substructure
1767  * @return Error code
1768  **/
1769 
1770 error_t ikeFormatTsEntry(const IkeTsEntry *tsEntry, uint8_t *p,
1771  size_t *written)
1772 {
1773  error_t error;
1774  IkeTs *ts;
1775 
1776  //Initialize status code
1777  error = NO_ERROR;
1778 
1779  //Point to the Traffic Selector substructure
1780  ts = (IkeTs *) p;
1781 
1782  //Format Traffic Selector substructure
1783  ts->ipProtocolId = tsEntry->ipProtocolId;
1784  ts->startPort = htons(tsEntry->startPort);
1785  ts->endPort = htons(tsEntry->endPort);
1786 
1787  //Length of the substructure
1788  *written = sizeof(IkeTs);
1789 
1790 #if (IPV4_SUPPORT == ENABLED)
1791  //IPv4 address range?
1792  if(tsEntry->startAddr.length == sizeof(Ipv4Addr) &&
1793  tsEntry->endAddr.length == sizeof(Ipv4Addr))
1794  {
1795  //Specify the type of Traffic Selector
1796  ts->tsType = IKE_TS_TYPE_IPV4_ADDR_RANGE;
1797 
1798  //A range of IPv4 addresses is represented by two four-octet values
1799  ipv4CopyAddr(ts->startAddr, &tsEntry->startAddr.ipv4Addr);
1800  ipv4CopyAddr(ts->startAddr + sizeof(Ipv4Addr), &tsEntry->endAddr.ipv4Addr);
1801 
1802  //The length of the selector depends on the TS Type field
1803  *written += 2 * sizeof(Ipv4Addr);
1804  }
1805  else
1806 #endif
1807 #if (IPV6_SUPPORT == ENABLED)
1808  //IPv6 address range?
1809  if(tsEntry->startAddr.length == sizeof(Ipv6Addr) &&
1810  tsEntry->endAddr.length == sizeof(Ipv6Addr))
1811  {
1812  //Specify the type of Traffic Selector
1813  ts->tsType = IKE_TS_TYPE_IPV6_ADDR_RANGE;
1814 
1815  //A range of IPv6 addresses is represented by two sixteen-octet values
1816  ipv6CopyAddr(ts->startAddr, &tsEntry->startAddr.ipv6Addr);
1817  ipv6CopyAddr(ts->startAddr + sizeof(Ipv6Addr), &tsEntry->endAddr.ipv6Addr);
1818 
1819  //The length of the selector depends on the TS Type field
1820  *written += 2 * sizeof(Ipv6Addr);
1821  }
1822  else
1823 #endif
1824  //Unknown Traffic Selector type?
1825  {
1826  //Report an error
1827  error = ERROR_INVALID_TYPE;
1828  }
1829 
1830  //Check status code
1831  if(!error)
1832  {
1833  //The Selector Length field specifies the length of this Traffic Selector
1834  //substructure including the header
1835  ts->selectorLength = htons(*written);
1836  }
1837 
1838  //Return status code
1839  return error;
1840 }
1841 
1842 #endif
uint8_t addr[4]
Definition: ip.h:104
AH algorithm negotiation.
#define htons(value)
Definition: cpu_endian.h:413
#define IPSEC_SPI_SIZE
Definition: ipsec.h:145
void netUnlock(NetContext *context)
Release exclusive access to the core of the TCP/IP stack.
Definition: net.c:319
Diffie-Hellman key exchange.
error_t ikeFormatNoncePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Nonce payload.
@ IKE_TS_TYPE_IPV4_ADDR_RANGE
TS_IPV4_ADDR_RANGE.
Definition: ike.h:1280
Authentication of the IKE SA.
uint16_t end
Definition: ipsec.h:300
IkeCertReqPayload
Definition: ike.h:1583
uint16_t endPort
Definition: ike.h:1806
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:199
@ IKE_HASH_ALGO_SHA256
Definition: ike.h:1400
IKE payload formatting.
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
@ IKE_NOTIFY_MSG_TYPE_REKEY_SA
Definition: ike.h:1217
@ IKE_NOTIFY_MSG_TYPE_CHILD_SA_NOT_FOUND
Definition: ike.h:1202
IPsec selector.
Definition: ipsec.h:309
IP network address.
Definition: ip.h:94
uint32_t spi
Definition: ah.h:175
Traffic selector entry.
Definition: ike.h:1801
@ IKE_HASH_ALGO_SHA1
Definition: ike.h:1399
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
IkeKePayload
Definition: ike.h:1546
uint8_t p
Definition: ndp.h:300
@ IKE_ID_TYPE_DER_ASN1_DN
Definition: ike.h:1127
error_t ikeAddTransform(IkeTransformType transformType, uint16_t transformId, uint16_t keyLen, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported transforms to the proposal.
IkeNotifyPayload
Definition: ike.h:1632
ESP algorithm negotiation.
IpAddr end
Definition: ipsec.h:289
Ipv6Addr
Definition: ipv6.h:282
@ IKE_LAST_SUBSTRUC_LAST
Last proposal/transform substructure.
Definition: ike.h:918
@ IKE_PAYLOAD_TYPE_CERTREQ
Certificate Request.
Definition: ike.h:892
error_t ipSelectSourceAddr(NetContext *context, NetInterface **interface, const IpAddr *destAddr, IpAddr *srcAddr)
IP source address selection.
Definition: ip.c:120
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.
error_t ahAddSupportedTransforms(IkeChildSaEntry *childSa, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported AH transforms to the proposal.
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:324
@ IKE_NOTIFY_MSG_TYPE_SIGNATURE_HASH_ALGORITHMS
Definition: ike.h:1255
uint16_t startPort
Definition: ike.h:1805
error_t ikeFormatDeletePayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Delete payload.
#define IPSEC_NAT_PORT
Definition: ipsec.h:142
@ IKE_NOTIFY_MSG_TYPE_NAT_DETECTION_SOURCE_IP
Definition: ike.h:1212
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:200
@ IKE_TRANSFORM_TYPE_ESN
Extended Sequence Numbers.
Definition: ike.h:949
error_t ikeGenerateAuth(IkeSaEntry *sa, const IkeIdPayload *idPayload, uint8_t *authMethod, uint8_t *authData, size_t *authDataLen)
Generate signature or MAC.
Definition: ike_auth.c:60
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
Peer Authorization Database (PAD) entry.
Definition: ipsec.h:412
#define IkeContext
Definition: ike.h:832
IkeAuthPayload
Definition: ike.h:1596
@ IPV4_PROTOCOL_TCP
Definition: ipv4.h:278
error_t ikeFormatCertAuthorities(const char_t *trustedCaList, size_t trustedCaListLen, uint8_t *certAuth, size_t *certAuthLen)
Format list of acceptable certification authorities.
#define FALSE
Definition: os_port.h:46
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:55
error_t ikeFormatNatDetectDestIpNotificationData(IkeSaEntry *sa, uint8_t *p, size_t *written)
Format NAT_DETECTION_DESTINATION_IP notification data.
PEM file import functions.
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
uint16_t notifyMsgType
Definition: ike.h:1630
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
IpsecAuthMethod authMethod
Authentication method (IKEv1, IKEv2, KINK)
Definition: ipsec.h:413
uint8_t nextProtocol
Next layer protocol.
Definition: ipsec.h:312
error_t ikeFormatPublicKey(IkeKeContext *keContext, uint8_t *p, size_t *written)
Format public key.
error_t
Error codes.
Definition: error.h:43
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:318
IkeIdPayload
Definition: ike.h:1559
@ IKE_PAYLOAD_TYPE_AUTH
Authentication.
Definition: ike.h:893
IpsecPortRange remotePort
Remote port range.
Definition: ipsec.h:314
@ IKE_PAYLOAD_TYPE_CERT
Certificate.
Definition: ike.h:891
IkeTsPayload
Definition: ike.h:1670
IpAddr startAddr
Definition: ike.h:1802
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
Key material generation.
@ IKE_HASH_ALGO_SHA512
Definition: ike.h:1402
#define IKE_SPI_SIZE
Definition: ike.h:826
uint8_t ipProtocolId
Definition: ike.h:1804
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define NetInterface
Definition: net.h:40
error_t espAddSupportedTransforms(IkeChildSaEntry *childSa, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported ESP transforms to the proposal.
error_t ikeFormatNotifyPayload(IkeSaEntry *sa, IkeChildSaEntry *childSa, IkeNotifyMsgType notifyMsgType, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Notify payload.
@ IKE_CHILD_SA_STATE_INIT
Definition: ike.h:1386
@ IKE_PAYLOAD_TYPE_IDI
Identification - Initiator.
Definition: ike.h:889
@ IPSEC_AUTH_METHOD_IKEV2
Definition: ipsec.h:187
error_t ikeFormatChildSaProposal(IkeChildSaEntry *childSa, uint8_t *p, size_t *written)
Format Proposal substructure (AH or ESP protocol)
@ ERROR_INVALID_TYPE
Definition: error.h:115
error_t ikeFormatKePayload(IkeKeContext *keContext, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Key Exchange payload.
error_t ikeFormatTsiPayload(IkeChildSaEntry *childSa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Traffic Selector payload (initiator)
@ IKE_TRANSFORM_TYPE_ENCR
Encryption Algorithm.
Definition: ike.h:945
size_t trustedCaListLen
Trusted CA list (PEM format)
Definition: ipsec.h:420
bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
Test if the transform ID identifies an AEAD encryption algorithm.
error_t ikeFormatIdPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Identification payload.
size_t length
Definition: ip.h:95
error_t ikeFormatCertPayloads(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate payloads.
IpAddr start
Definition: ipsec.h:288
IkeDeletePayload
Definition: ike.h:1646
const char_t * trustedCaList
Definition: ipsec.h:419
uint16_t start
Definition: ipsec.h:299
IKEv2 (Internet Key Exchange Protocol)
error_t ikeFormatCertPayload(const char_t *certChain, size_t certChainLen, size_t *consumed, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate payload.
#define ntohs(value)
Definition: cpu_endian.h:421
IkeTs
Definition: ike.h:1685
IkeProposal
Definition: ike.h:1505
char char_t
Definition: compiler_port.h:55
@ IKE_TRANSFORM_TYPE_KE
Key Exchange Method.
Definition: ike.h:948
Ipv4Addr ipv4Addr
Definition: ip.h:99
@ IKE_PAYLOAD_TYPE_NONCE
Nonce.
Definition: ike.h:894
@ IKE_NOTIFY_MSG_TYPE_INVALID_KE_PAYLOAD
Definition: ike.h:1190
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define ipv6CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv6.h:132
#define IkeSaEntry
Definition: ike.h:836
error_t ikeFormatNatDetectSrcIpNotificationData(IkeSaEntry *sa, uint8_t *p, size_t *written)
Format NAT_DETECTION_SOURCE_IP notification data.
error_t ikeGetCertSubjectDn(const char_t *cert, size_t certLen, uint8_t *subjectDn, size_t *subjectDnLen)
Extract subject's DN from certificate.
@ IKE_NOTIFY_MSG_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD
Definition: ike.h:1183
uint8_t m
Definition: ndp.h:304
#define HTONS(value)
Definition: cpu_endian.h:410
uint8_t n
#define IKE_PORT
Definition: ike.h:813
@ IPV4_PROTOCOL_UDP
Definition: ipv4.h:279
IkeCertPayload
Definition: ike.h:1571
error_t ikeAddSupportedTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported IKE transforms to the proposal.
IpsecAddrRange localIpAddr
Local IP address range.
Definition: ipsec.h:310
@ IKE_TRANSFORM_TYPE_PRF
Pseudorandom Function.
Definition: ike.h:946
@ IKE_PROTOCOL_ID_IKE
IKE.
Definition: ike.h:930
@ IKE_ID_TYPE_INVALID
Definition: ike.h:1122
X.509 certificate handling.
#define IpsecContext
Definition: ipsec.h:40
@ IKE_PAYLOAD_TYPE_LAST
No Next Payload.
Definition: ike.h:886
IkeNotifyMsgType
Notify message types.
Definition: ike.h:1181
@ IKE_PAYLOAD_TYPE_KE
Key Exchange.
Definition: ike.h:888
SHA-1 algorithm context.
Definition: sha1.h:62
uint8_t nextPayload
Definition: ike.h:1447
@ IKE_NOTIFY_MSG_TYPE_COOKIE
Definition: ike.h:1214
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:167
@ IKE_PAYLOAD_TYPE_TSI
Traffic Selector - Initiator.
Definition: ike.h:898
void netLock(NetContext *context)
Get exclusive access to the core of the TCP/IP stack.
Definition: net.c:307
@ IKE_CERT_ENCODING_X509_CERT_SIGN
X.509 certificate - signature.
Definition: ike.h:1144
IkeNoncePayload
Definition: ike.h:1618
IpAddr endAddr
Definition: ike.h:1803
uint16_t groupNum
Key exchange method.
Definition: ike.h:1816
@ IKE_PAYLOAD_TYPE_IDR
Identification - Responder.
Definition: ike.h:890
Ipv6Addr ipv6Addr
Definition: ip.h:102
Key exchange context.
Definition: ike.h:1815
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
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
@ IKE_PAYLOAD_TYPE_SA
Security Association.
Definition: ike.h:887
error_t ikeFormatSaProposal(IkeSaEntry *sa, const uint8_t *spi, uint8_t *p, size_t *written)
Format Proposal substructure (IKE protocol)
error_t ikeFormatTsEntry(const IkeTsEntry *tsEntry, uint8_t *p, size_t *written)
Format Traffic Selector substructure.
error_t ikeFormatCertReqPayload(IkeSaEntry *sa, uint8_t *p, size_t *written, uint8_t **nextPayload)
Format Certificate Request payload.
#define IkeChildSaEntry
Definition: ike.h:840
@ IKE_HASH_ALGO_SHA384
Definition: ike.h:1401
@ IKE_HASH_ALGO_IDENTITY
Definition: ike.h:1403
IpsecPortRange localPort
Local port range.
Definition: ipsec.h:313
@ IKE_PAYLOAD_TYPE_N
Notify.
Definition: ike.h:895
IKEv2 algorithm negotiation.
IpsecAddrRange remoteIpAddr
Remote IP address range.
Definition: ipsec.h:311
@ 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)
@ IKE_TS_TYPE_IPV6_ADDR_RANGE
TS_IPV6_ADDR_RANGE.
Definition: ike.h:1281
Debugging facilities.
IkeSaPayload
Definition: ike.h:1488
@ IKE_PAYLOAD_TYPE_TSR
Traffic Selector - Responder.
Definition: ike.h:899
error_t ikeFormatSignHashAlgosNotificationData(IkeSaEntry *sa, uint8_t *p, size_t *written)
Format SIGNATURE_HASH_ALGORITHMS notification data.
@ IKE_TRANSFORM_TYPE_INTEG
Integrity Algorithm.
Definition: ike.h:947