ike_algorithms.c
Go to the documentation of this file.
1 /**
2  * @file ike_algorithms.c
3  * @brief IKEv2 algorithm negotiation
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 "ah/ah_algorithms.h"
38 #include "esp/esp_algorithms.h"
41 #include "hash/hash_algorithms.h"
42 #include "debug.h"
43 
44 //Check IKEv2 library configuration
45 #if (IKE_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief List of supported key exchange methods
50  **/
51 
52 static const uint16_t ikeSupportedKeAlgos[] =
53 {
54 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_CURVE25519_SUPPORT == ENABLED)
55  //Curve25519 elliptic curve
57 #endif
58 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_CURVE448_SUPPORT == ENABLED)
59  //Curve448 elliptic curve
61 #endif
62 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_ECP_256_SUPPORT == ENABLED)
63  //NIST P-256 elliptic curve
65 #endif
66 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_ECP_384_SUPPORT == ENABLED)
67  //NIST P-384 elliptic curve
69 #endif
70 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_ECP_521_SUPPORT == ENABLED)
71  //NIST P-521 elliptic curve
73 #endif
74 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_ECP_224_SUPPORT == ENABLED)
75  //NIST P-224 elliptic curve
77 #endif
78 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_ECP_192_SUPPORT == ENABLED)
79  //NIST P-192 elliptic curve
81 #endif
82 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_BRAINPOOLP256R1_SUPPORT == ENABLED)
83  //brainpoolP256r1 elliptic curve
85 #endif
86 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_BRAINPOOLP384R1_SUPPORT == ENABLED)
87  //brainpoolP384r1 elliptic curve
89 #endif
90 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_BRAINPOOLP512R1_SUPPORT == ENABLED)
91  //brainpoolP512r1 elliptic curve
93 #endif
94 #if (IKE_ECDH_KE_SUPPORT == ENABLED && IKE_BRAINPOOLP224R1_SUPPORT == ENABLED)
95  //brainpoolP224r1 elliptic curve
97 #endif
98 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 2048 && \
99  IKE_MIN_DH_MODULUS_SIZE <= 2048)
100  //Diffie-Hellman group 14
102 #endif
103 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 3072 && \
104  IKE_MIN_DH_MODULUS_SIZE <= 3072)
105  //Diffie-Hellman group 15
107 #endif
108 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 4096 && \
109  IKE_MIN_DH_MODULUS_SIZE <= 4096)
110  //Diffie-Hellman group 16
112 #endif
113 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 6144 && \
114  IKE_MIN_DH_MODULUS_SIZE <= 6144)
115  //Diffie-Hellman group 17
117 #endif
118 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 8192 && \
119  IKE_MIN_DH_MODULUS_SIZE <= 8192)
120  //Diffie-Hellman group 18
122 #endif
123 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 1536 && \
124  IKE_MIN_DH_MODULUS_SIZE <= 1536)
125  //Diffie-Hellman group 5
127 #endif
128 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 1024 && \
129  IKE_MIN_DH_MODULUS_SIZE <= 1024)
130  //Diffie-Hellman group 2
132 #endif
133 #if (IKE_DH_KE_SUPPORT == ENABLED && IKE_MAX_DH_MODULUS_SIZE >= 768 && \
134  IKE_MIN_DH_MODULUS_SIZE <= 768)
135  //Diffie-Hellman group 1
137 #endif
138 };
139 
140 
141 /**
142  * @brief List of supported encryption algorithms
143  **/
144 
145 static const IkeEncAlgo ikeSupportedEncAlgos[] =
146 {
147 #if (IKE_CHACHA20_POLY1305_SUPPORT == ENABLED)
149 #endif
150 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
152 #endif
153 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
155 #endif
156 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
158 #endif
159 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
161 #endif
162 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
164 #endif
165 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
167 #endif
168 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
170 #endif
171 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
173 #endif
174 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
176 #endif
177 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
179 #endif
180 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
182 #endif
183 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
185 #endif
186 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
188 #endif
189 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
191 #endif
192 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
194 #endif
195 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
197 #endif
198 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
200 #endif
201 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
203 #endif
204 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
206 #endif
207 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
209 #endif
210 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
212 #endif
213 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
215 #endif
216 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
218 #endif
219 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
221 #endif
222 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
224 #endif
225 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
227 #endif
228 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
230 #endif
231 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
233 #endif
234 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
236 #endif
237 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
239 #endif
240 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
242 #endif
243 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
245 #endif
246 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
248 #endif
249 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
251 #endif
252 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
254 #endif
255 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
257 #endif
258 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
260 #endif
261 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
263 #endif
264 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
266 #endif
267 #if (IKE_3DES_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
269 #endif
270 #if (IKE_DES_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
272 #endif
273 #if (IKE_IDEA_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
275 #endif
276 };
277 
278 
279 /**
280  * @brief List of supported integrity algorithms
281  **/
282 
283 static const uint16_t ikeSupportedAuthAlgos[] =
284 {
285 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
287 #endif
288 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
290 #endif
291 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
293 #endif
294 #if (IKE_CMAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
296 #endif
297 #if (IKE_XCBC_MAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
299 #endif
300 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
302 #endif
303 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
305 #endif
306  0
307 };
308 
309 
310 /**
311  * @brief List of supported pseudorandom functions
312  **/
313 
314 static const uint16_t ikeSupportedPrfAlgos[] =
315 {
316 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
318 #endif
319 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
321 #endif
322 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
324 #endif
325 #if (IKE_CMAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
327 #endif
328 #if (IKE_XCBC_MAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
330 #endif
331 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_TIGER_SUPPORT == ENABLED)
333 #endif
334 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
336 #endif
337 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
339 #endif
340 };
341 
342 
343 /**
344  * @brief Select the relevant encryption algorithm
345  * @param[in] sa Pointer to the IKE SA
346  * @param[in] encAlgoId Encryption algorithm identifier
347  * @param[in] encKeyLen Length of the encryption key, in bytes
348  * @return Error code
349  **/
350 
351 error_t ikeSelectEncAlgo(IkeSaEntry *sa, uint16_t encAlgoId,
352  size_t encKeyLen)
353 {
354  error_t error;
355 
356  //Initialize status code
357  error = NO_ERROR;
358 
359 #if (IKE_IDEA_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
360  //IDEA-CBC encryption algorithm?
361  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_IDEA)
362  {
363  sa->cipherMode = CIPHER_MODE_CBC;
364  sa->cipherAlgo = IDEA_CIPHER_ALGO;
365  sa->encKeyLen = 16;
366  sa->ivLen = IDEA_BLOCK_SIZE;
367  }
368  else
369 #endif
370 #if (IKE_DES_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
371  //DES-CBC encryption algorithm?
372  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_DES)
373  {
374  sa->cipherMode = CIPHER_MODE_CBC;
375  sa->cipherAlgo = DES_CIPHER_ALGO;
376  sa->encKeyLen = 8;
377  sa->ivLen = DES_BLOCK_SIZE;
378  }
379  else
380 #endif
381 #if (IKE_3DES_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
382  //3DES-CBC encryption algorithm?
383  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_3DES)
384  {
385  sa->cipherMode = CIPHER_MODE_CBC;
386  sa->cipherAlgo = DES3_CIPHER_ALGO;
387  sa->encKeyLen = 24;
388  sa->ivLen = DES3_BLOCK_SIZE;
389  }
390  else
391 #endif
392 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
393  //AES-CBC with 128-bit key encryption algorithm?
394  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC && encKeyLen == 16)
395  {
396  sa->cipherMode = CIPHER_MODE_CBC;
397  sa->cipherAlgo = AES_CIPHER_ALGO;
398  sa->encKeyLen = 16;
399  sa->ivLen = AES_BLOCK_SIZE;
400  }
401  else
402 #endif
403 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
404  //AES-CBC with 192-bit key encryption algorithm?
405  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC && encKeyLen == 24)
406  {
407  sa->cipherMode = CIPHER_MODE_CBC;
408  sa->cipherAlgo = AES_CIPHER_ALGO;
409  sa->encKeyLen = 24;
410  sa->ivLen = AES_BLOCK_SIZE;
411  }
412  else
413 #endif
414 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
415  //AES-CBC with 256-bit key encryption algorithm?
416  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC && encKeyLen == 32)
417  {
418  sa->cipherMode = CIPHER_MODE_CBC;
419  sa->cipherAlgo = AES_CIPHER_ALGO;
420  sa->encKeyLen = 32;
421  sa->ivLen = AES_BLOCK_SIZE;
422  }
423  else
424 #endif
425 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
426  //AES-CTR with 128-bit key encryption algorithm?
427  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR && encKeyLen == 16)
428  {
429  sa->cipherMode = CIPHER_MODE_CTR;
430  sa->cipherAlgo = AES_CIPHER_ALGO;
431  sa->encKeyLen = 16;
432  sa->saltLen = 4;
433  sa->ivLen = 8;
434  }
435  else
436 #endif
437 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
438  //AES-CTR with 192-bit key encryption algorithm?
439  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR && encKeyLen == 24)
440  {
441  sa->cipherMode = CIPHER_MODE_CTR;
442  sa->cipherAlgo = AES_CIPHER_ALGO;
443  sa->encKeyLen = 24;
444  sa->saltLen = 4;
445  sa->ivLen = 8;
446  }
447  else
448 #endif
449 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
450  //AES-CTR with 256-bit key encryption algorithm?
451  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR && encKeyLen == 32)
452  {
453  sa->cipherMode = CIPHER_MODE_CTR;
454  sa->cipherAlgo = AES_CIPHER_ALGO;
455  sa->encKeyLen = 32;
456  sa->saltLen = 4;
457  sa->ivLen = 8;
458  }
459  else
460 #endif
461 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
462  //AES-CCM with 128-bit key and 8-octet ICV encryption algorithm?
463  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 && encKeyLen == 16)
464  {
465  sa->cipherMode = CIPHER_MODE_CCM;
466  sa->cipherAlgo = AES_CIPHER_ALGO;
467  sa->encKeyLen = 16;
468  sa->authKeyLen = 0;
469  sa->saltLen = 3;
470  sa->ivLen = 8;
471  sa->icvLen = 8;
472  }
473  else
474 #endif
475 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
476  //AES-CCM with 192-bit key and 8-octet ICV encryption algorithm?
477  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 && encKeyLen == 24)
478  {
479  sa->cipherMode = CIPHER_MODE_CCM;
480  sa->cipherAlgo = AES_CIPHER_ALGO;
481  sa->encKeyLen = 24;
482  sa->authKeyLen = 0;
483  sa->saltLen = 3;
484  sa->ivLen = 8;
485  sa->icvLen = 8;
486  }
487  else
488 #endif
489 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
490  //AES-CCM with 256-bit key and 8-octet ICV encryption algorithm?
491  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 && encKeyLen == 32)
492  {
493  sa->cipherMode = CIPHER_MODE_CCM;
494  sa->cipherAlgo = AES_CIPHER_ALGO;
495  sa->encKeyLen = 32;
496  sa->authKeyLen = 0;
497  sa->saltLen = 3;
498  sa->ivLen = 8;
499  sa->icvLen = 8;
500  }
501  else
502 #endif
503 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
504  //AES-CCM with 128-bit key and 12-octet ICV encryption algorithm?
505  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 && encKeyLen == 16)
506  {
507  sa->cipherMode = CIPHER_MODE_CCM;
508  sa->cipherAlgo = AES_CIPHER_ALGO;
509  sa->encKeyLen = 16;
510  sa->authKeyLen = 0;
511  sa->saltLen = 3;
512  sa->ivLen = 8;
513  sa->icvLen = 12;
514  }
515  else
516 #endif
517 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
518  //AES-CCM with 192-bit key and 12-octet ICV encryption algorithm?
519  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 && encKeyLen == 24)
520  {
521  sa->cipherMode = CIPHER_MODE_CCM;
522  sa->cipherAlgo = AES_CIPHER_ALGO;
523  sa->encKeyLen = 24;
524  sa->authKeyLen = 0;
525  sa->saltLen = 3;
526  sa->ivLen = 8;
527  sa->icvLen = 12;
528  }
529  else
530 #endif
531 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
532  //AES-CCM with 256-bit key and 12-octet ICV encryption algorithm?
533  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 && encKeyLen == 32)
534  {
535  sa->cipherMode = CIPHER_MODE_CCM;
536  sa->cipherAlgo = AES_CIPHER_ALGO;
537  sa->encKeyLen = 32;
538  sa->authKeyLen = 0;
539  sa->saltLen = 3;
540  sa->ivLen = 8;
541  sa->icvLen = 12;
542  }
543  else
544 #endif
545 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
546  //AES-CCM with 128-bit key and 16-octet ICV encryption algorithm?
547  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 && encKeyLen == 16)
548  {
549  sa->cipherMode = CIPHER_MODE_CCM;
550  sa->cipherAlgo = AES_CIPHER_ALGO;
551  sa->encKeyLen = 16;
552  sa->authKeyLen = 0;
553  sa->saltLen = 3;
554  sa->ivLen = 8;
555  sa->icvLen = 16;
556  }
557  else
558 #endif
559 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
560  //AES-CCM with 192-bit key and 16-octet ICV encryption algorithm?
561  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 && encKeyLen == 24)
562  {
563  sa->cipherMode = CIPHER_MODE_CCM;
564  sa->cipherAlgo = AES_CIPHER_ALGO;
565  sa->encKeyLen = 24;
566  sa->authKeyLen = 0;
567  sa->saltLen = 3;
568  sa->ivLen = 8;
569  sa->icvLen = 16;
570  }
571  else
572 #endif
573 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
574  //AES-CCM with 256-bit key and 16-octet ICV encryption algorithm?
575  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 && encKeyLen == 32)
576  {
577  sa->cipherMode = CIPHER_MODE_CCM;
578  sa->cipherAlgo = AES_CIPHER_ALGO;
579  sa->encKeyLen = 32;
580  sa->authKeyLen = 0;
581  sa->saltLen = 3;
582  sa->ivLen = 8;
583  sa->icvLen = 16;
584  }
585  else
586 #endif
587 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
588  //AES-GCM with 128-bit key and 8-octet ICV encryption algorithm?
589  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 && encKeyLen == 16)
590  {
591  sa->cipherMode = CIPHER_MODE_GCM;
592  sa->cipherAlgo = AES_CIPHER_ALGO;
593  sa->encKeyLen = 16;
594  sa->authKeyLen = 0;
595  sa->saltLen = 4;
596  sa->ivLen = 8;
597  sa->icvLen = 8;
598  }
599  else
600 #endif
601 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
602  //AES-GCM with 192-bit key and 8-octet ICV encryption algorithm?
603  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 && encKeyLen == 24)
604  {
605  sa->cipherMode = CIPHER_MODE_GCM;
606  sa->cipherAlgo = AES_CIPHER_ALGO;
607  sa->encKeyLen = 24;
608  sa->authKeyLen = 0;
609  sa->saltLen = 4;
610  sa->ivLen = 8;
611  sa->icvLen = 8;
612  }
613  else
614 #endif
615 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_8_SUPPORT == ENABLED)
616  //AES-GCM with 256-bit key and 8-octet ICV encryption algorithm?
617  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 && encKeyLen == 32)
618  {
619  sa->cipherMode = CIPHER_MODE_GCM;
620  sa->cipherAlgo = AES_CIPHER_ALGO;
621  sa->encKeyLen = 32;
622  sa->authKeyLen = 0;
623  sa->saltLen = 4;
624  sa->ivLen = 8;
625  sa->icvLen = 8;
626  }
627  else
628 #endif
629 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
630  //AES-GCM with 128-bit key and 12-octet ICV encryption algorithm?
631  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 && encKeyLen == 16)
632  {
633  sa->cipherMode = CIPHER_MODE_GCM;
634  sa->cipherAlgo = AES_CIPHER_ALGO;
635  sa->encKeyLen = 16;
636  sa->authKeyLen = 0;
637  sa->saltLen = 4;
638  sa->ivLen = 8;
639  sa->icvLen = 12;
640  }
641  else
642 #endif
643 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
644  //AES-GCM with 192-bit key and 12-octet ICV encryption algorithm?
645  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 && encKeyLen == 24)
646  {
647  sa->cipherMode = CIPHER_MODE_GCM;
648  sa->cipherAlgo = AES_CIPHER_ALGO;
649  sa->encKeyLen = 24;
650  sa->authKeyLen = 0;
651  sa->saltLen = 4;
652  sa->ivLen = 8;
653  sa->icvLen = 12;
654  }
655  else
656 #endif
657 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_12_SUPPORT == ENABLED)
658  //AES-GCM with 256-bit key and 12-octet ICV encryption algorithm?
659  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 && encKeyLen == 32)
660  {
661  sa->cipherMode = CIPHER_MODE_GCM;
662  sa->cipherAlgo = AES_CIPHER_ALGO;
663  sa->encKeyLen = 32;
664  sa->authKeyLen = 0;
665  sa->saltLen = 4;
666  sa->ivLen = 8;
667  sa->icvLen = 12;
668  }
669  else
670 #endif
671 #if (IKE_AES_128_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
672  //AES-GCM with 128-bit key and 16-octet ICV encryption algorithm?
673  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 && encKeyLen == 16)
674  {
675  sa->cipherMode = CIPHER_MODE_GCM;
676  sa->cipherAlgo = AES_CIPHER_ALGO;
677  sa->encKeyLen = 16;
678  sa->authKeyLen = 0;
679  sa->saltLen = 4;
680  sa->ivLen = 8;
681  sa->icvLen = 16;
682  }
683  else
684 #endif
685 #if (IKE_AES_192_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
686  //AES-GCM with 192-bit key and 16-octet ICV encryption algorithm?
687  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 && encKeyLen == 24)
688  {
689  sa->cipherMode = CIPHER_MODE_GCM;
690  sa->cipherAlgo = AES_CIPHER_ALGO;
691  sa->encKeyLen = 24;
692  sa->authKeyLen = 0;
693  sa->saltLen = 4;
694  sa->ivLen = 8;
695  sa->icvLen = 16;
696  }
697  else
698 #endif
699 #if (IKE_AES_256_SUPPORT == ENABLED && IKE_GCM_16_SUPPORT == ENABLED)
700  //AES-GCM with 256-bit key and 16-octet ICV encryption algorithm?
701  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 && encKeyLen == 32)
702  {
703  sa->cipherMode = CIPHER_MODE_GCM;
704  sa->cipherAlgo = AES_CIPHER_ALGO;
705  sa->encKeyLen = 32;
706  sa->authKeyLen = 0;
707  sa->saltLen = 4;
708  sa->ivLen = 8;
709  sa->icvLen = 16;
710  }
711  else
712 #endif
713 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
714  //Camellia-CBC with 128-bit key encryption algorithm?
715  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC && encKeyLen == 16)
716  {
717  sa->cipherMode = CIPHER_MODE_CBC;
718  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
719  sa->encKeyLen = 16;
720  sa->ivLen = CAMELLIA_BLOCK_SIZE;
721  }
722  else
723 #endif
724 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
725  //Camellia-CBC with 192-bit key encryption algorithm?
726  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC && encKeyLen == 24)
727  {
728  sa->cipherMode = CIPHER_MODE_CBC;
729  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
730  sa->encKeyLen = 24;
731  sa->ivLen = CAMELLIA_BLOCK_SIZE;
732  }
733  else
734 #endif
735 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CBC_SUPPORT == ENABLED)
736  //Camellia-CBC with 256-bit key encryption algorithm?
737  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC && encKeyLen == 32)
738  {
739  sa->cipherMode = CIPHER_MODE_CBC;
740  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
741  sa->encKeyLen = 32;
742  sa->ivLen = CAMELLIA_BLOCK_SIZE;
743  }
744  else
745 #endif
746 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
747  //Camellia-CTR with 128-bit key encryption algorithm?
748  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR && encKeyLen == 16)
749  {
750  sa->cipherMode = CIPHER_MODE_CTR;
751  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
752  sa->encKeyLen = 16;
753  sa->saltLen = 4;
754  sa->ivLen = 8;
755  }
756  else
757 #endif
758 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
759  //Camellia-CTR with 192-bit key encryption algorithm?
760  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR && encKeyLen == 24)
761  {
762  sa->cipherMode = CIPHER_MODE_CTR;
763  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
764  sa->encKeyLen = 24;
765  sa->saltLen = 4;
766  sa->ivLen = 8;
767  }
768  else
769 #endif
770 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CTR_SUPPORT == ENABLED)
771  //Camellia-CTR with 256-bit key encryption algorithm?
772  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR && encKeyLen == 32)
773  {
774  sa->cipherMode = CIPHER_MODE_CTR;
775  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
776  sa->encKeyLen = 32;
777  sa->saltLen = 4;
778  sa->ivLen = 8;
779  }
780  else
781 #endif
782 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
783  //Camellia-CCM with 128-bit key and 8-octet ICV encryption algorithm?
784  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 && encKeyLen == 16)
785  {
786  sa->cipherMode = CIPHER_MODE_CCM;
787  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
788  sa->encKeyLen = 16;
789  sa->authKeyLen = 0;
790  sa->saltLen = 3;
791  sa->ivLen = 8;
792  sa->icvLen = 8;
793  }
794  else
795 #endif
796 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
797  //Camellia-CCM with 192-bit key and 8-octet ICV encryption algorithm?
798  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 && encKeyLen == 24)
799  {
800  sa->cipherMode = CIPHER_MODE_CCM;
801  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
802  sa->encKeyLen = 24;
803  sa->authKeyLen = 0;
804  sa->saltLen = 3;
805  sa->ivLen = 8;
806  sa->icvLen = 8;
807  }
808  else
809 #endif
810 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_8_SUPPORT == ENABLED)
811  //Camellia-CCM with 256-bit key and 8-octet ICV encryption algorithm?
812  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 && encKeyLen == 32)
813  {
814  sa->cipherMode = CIPHER_MODE_CCM;
815  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
816  sa->encKeyLen = 32;
817  sa->authKeyLen = 0;
818  sa->saltLen = 3;
819  sa->ivLen = 8;
820  sa->icvLen = 8;
821  }
822  else
823 #endif
824 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
825  //Camellia-CCM with 128-bit key and 12-octet ICV encryption algorithm?
826  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12 && encKeyLen == 16)
827  {
828  sa->cipherMode = CIPHER_MODE_CCM;
829  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
830  sa->encKeyLen = 16;
831  sa->authKeyLen = 0;
832  sa->saltLen = 3;
833  sa->ivLen = 8;
834  sa->icvLen = 12;
835  }
836  else
837 #endif
838 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
839  //Camellia-CCM with 192-bit key and 12-octet ICV encryption algorithm?
840  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12 && encKeyLen == 24)
841  {
842  sa->cipherMode = CIPHER_MODE_CCM;
843  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
844  sa->encKeyLen = 24;
845  sa->authKeyLen = 0;
846  sa->saltLen = 3;
847  sa->ivLen = 8;
848  sa->icvLen = 12;
849  }
850  else
851 #endif
852 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_12_SUPPORT == ENABLED)
853  //Camellia-CCM with 256-bit key and 12-octet ICV encryption algorithm?
854  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12 && encKeyLen == 32)
855  {
856  sa->cipherMode = CIPHER_MODE_CCM;
857  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
858  sa->encKeyLen = 32;
859  sa->authKeyLen = 0;
860  sa->saltLen = 3;
861  sa->ivLen = 8;
862  sa->icvLen = 12;
863  }
864  else
865 #endif
866 #if (IKE_CAMELLIA_128_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
867  //Camellia-CCM with 128-bit key and 16-octet ICV encryption algorithm?
868  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_16 && encKeyLen == 16)
869  {
870  sa->cipherMode = CIPHER_MODE_CCM;
871  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
872  sa->encKeyLen = 16;
873  sa->authKeyLen = 0;
874  sa->saltLen = 3;
875  sa->ivLen = 8;
876  sa->icvLen = 16;
877  }
878  else
879 #endif
880 #if (IKE_CAMELLIA_192_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
881  //Camellia-CCM with 192-bit key and 16-octet ICV encryption algorithm?
882  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_16 && encKeyLen == 24)
883  {
884  sa->cipherMode = CIPHER_MODE_CCM;
885  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
886  sa->encKeyLen = 24;
887  sa->authKeyLen = 0;
888  sa->saltLen = 3;
889  sa->ivLen = 8;
890  sa->icvLen = 16;
891  }
892  else
893 #endif
894 #if (IKE_CAMELLIA_256_SUPPORT == ENABLED && IKE_CCM_16_SUPPORT == ENABLED)
895  //Camellia-CCM with 256-bit key and 16-octet ICV encryption algorithm?
896  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_16 && encKeyLen == 32)
897  {
898  sa->cipherMode = CIPHER_MODE_CCM;
899  sa->cipherAlgo = CAMELLIA_CIPHER_ALGO;
900  sa->encKeyLen = 32;
901  sa->authKeyLen = 0;
902  sa->saltLen = 3;
903  sa->ivLen = 8;
904  sa->icvLen = 16;
905  }
906  else
907 #endif
908 #if (IKE_CHACHA20_POLY1305_SUPPORT == ENABLED)
909  //ChaCha20Poly1305 encryption algorithm?
911  {
912  sa->cipherMode = CIPHER_MODE_CHACHA20_POLY1305;
913  sa->cipherAlgo = NULL;
914  sa->encKeyLen = 32;
915  sa->authKeyLen = 0;
916  sa->saltLen = 4;
917  sa->ivLen = 8;
918  sa->icvLen = 16;
919  }
920  else
921 #endif
922  //Unknown encryption algorithm?
923  {
924  //Report an error
925  error = ERROR_UNSUPPORTED_ALGO;
926  }
927 
928  //Return status code
929  return error;
930 }
931 
932 
933 /**
934  * @brief Select the relevant MAC algorithm
935  * @param[in] sa Pointer to the IKE SA
936  * @param[in] authAlgoId Authentication algorithm identifier
937  * @return Error code
938  **/
939 
940 error_t ikeSelectAuthAlgo(IkeSaEntry *sa, uint16_t authAlgoId)
941 {
942  error_t error;
943 
944  //Initialize status code
945  error = NO_ERROR;
946 
947 #if (IKE_CMAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
948  //AES-CMAC-96 authentication algorithm?
949  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_AES_CMAC_96)
950  {
951  sa->authMacAlgo = MAC_ALGO_CMAC;
952  sa->authHashAlgo = NULL;
953  sa->authCipherAlgo = AES_CIPHER_ALGO;
954  sa->authKeyLen = 16;
955  sa->icvLen = 12;
956  }
957  else
958 #endif
959 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
960  //HMAC-MD5-96 authentication algorithm?
961  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96)
962  {
963  sa->authMacAlgo = MAC_ALGO_HMAC;
964  sa->authHashAlgo = MD5_HASH_ALGO;
965  sa->authCipherAlgo = NULL;
966  sa->authKeyLen = MD5_DIGEST_SIZE;
967  sa->icvLen = 12;
968  }
969  else
970 #endif
971 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
972  //HMAC-SHA1-96 authentication algorithm?
973  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96)
974  {
975  sa->authMacAlgo = MAC_ALGO_HMAC;
976  sa->authHashAlgo = SHA1_HASH_ALGO;
977  sa->authCipherAlgo = NULL;
978  sa->authKeyLen = SHA1_DIGEST_SIZE;
979  sa->icvLen = 12;
980  }
981  else
982 #endif
983 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
984  //HMAC-SHA256-128 authentication algorithm?
986  {
987  sa->authMacAlgo = MAC_ALGO_HMAC;
988  sa->authHashAlgo = SHA256_HASH_ALGO;
989  sa->authCipherAlgo = NULL;
990  sa->authKeyLen = SHA256_DIGEST_SIZE;
991  sa->icvLen = 16;
992  }
993  else
994 #endif
995 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
996  //HMAC-SHA384-192 authentication algorithm?
998  {
999  sa->authMacAlgo = MAC_ALGO_HMAC;
1000  sa->authHashAlgo = SHA384_HASH_ALGO;
1001  sa->authCipherAlgo = NULL;
1002  sa->authKeyLen = SHA384_DIGEST_SIZE;
1003  sa->icvLen = 24;
1004  }
1005  else
1006 #endif
1007 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
1008  //HMAC-SHA512-256 authentication algorithm?
1009  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_512_256)
1010  {
1011  sa->authMacAlgo = MAC_ALGO_HMAC;
1012  sa->authHashAlgo = SHA512_HASH_ALGO;
1013  sa->authCipherAlgo = NULL;
1014  sa->authKeyLen = SHA512_DIGEST_SIZE;
1015  sa->icvLen = 32;
1016  }
1017  else
1018 #endif
1019 #if (IKE_XCBC_MAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1020  //AES-XCBC-MAC-96 authentication algorithm?
1021  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_AES_XCBC_96)
1022  {
1023  sa->authMacAlgo = MAC_ALGO_XCBC_MAC;
1024  sa->authHashAlgo = NULL;
1025  sa->authCipherAlgo = AES_CIPHER_ALGO;
1026  sa->authKeyLen = 16;
1027  sa->icvLen = 12;
1028  }
1029  else
1030 #endif
1031  //Unknown authentication algorithm?
1032  {
1033  //Report an error
1034  error = ERROR_UNSUPPORTED_ALGO;
1035  }
1036 
1037  //Return status code
1038  return error;
1039 }
1040 
1041 
1042 /**
1043  * @brief Select the relevant PRF algorithm
1044  * @param[in] sa Pointer to the IKE SA
1045  * @param[in] prfAlgoId PRF algorithm identifier
1046  * @return Error code
1047  **/
1048 
1049 error_t ikeSelectPrfAlgo(IkeSaEntry *sa, uint16_t prfAlgoId)
1050 {
1051  error_t error;
1052 
1053  //Initialize status code
1054  error = NO_ERROR;
1055 
1056 #if (IKE_CMAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1057  //AES-CMAC PRF algorithm?
1058  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_AES128_CMAC)
1059  {
1060  sa->prfMacAlgo = MAC_ALGO_CMAC;
1061  sa->prfHashAlgo = NULL;
1062  sa->prfCipherAlgo = AES_CIPHER_ALGO;
1063  sa->prfKeyLen = 16;
1064  }
1065  else
1066 #endif
1067 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
1068  //HMAC-MD5 PRF algorithm?
1069  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_MD5)
1070  {
1071  sa->prfMacAlgo = MAC_ALGO_HMAC;
1072  sa->prfHashAlgo = MD5_HASH_ALGO;
1073  sa->prfCipherAlgo = NULL;
1074  sa->prfKeyLen = MD5_DIGEST_SIZE;
1075  }
1076  else
1077 #endif
1078 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
1079  //HMAC-SHA1 PRF algorithm?
1080  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA1)
1081  {
1082  sa->prfMacAlgo = MAC_ALGO_HMAC;
1083  sa->prfHashAlgo = SHA1_HASH_ALGO;
1084  sa->prfCipherAlgo = NULL;
1085  sa->prfKeyLen = SHA1_DIGEST_SIZE;
1086  }
1087  else
1088 #endif
1089 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
1090  //HMAC-SHA256 PRF algorithm?
1091  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256)
1092  {
1093  sa->prfMacAlgo = MAC_ALGO_HMAC;
1094  sa->prfHashAlgo = SHA256_HASH_ALGO;
1095  sa->prfCipherAlgo = NULL;
1096  sa->prfKeyLen = SHA256_DIGEST_SIZE;
1097  }
1098  else
1099 #endif
1100 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
1101  //HMAC-SHA384 PRF algorithm?
1102  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384)
1103  {
1104  sa->prfMacAlgo = MAC_ALGO_HMAC;
1105  sa->prfHashAlgo = SHA384_HASH_ALGO;
1106  sa->prfCipherAlgo = NULL;
1107  sa->prfKeyLen = SHA384_DIGEST_SIZE;
1108  }
1109  else
1110 #endif
1111 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
1112  //HMAC-SHA512 PRF algorithm?
1113  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512)
1114  {
1115  sa->prfMacAlgo = MAC_ALGO_HMAC;
1116  sa->prfHashAlgo = SHA512_HASH_ALGO;
1117  sa->prfCipherAlgo = NULL;
1118  sa->prfKeyLen = SHA512_DIGEST_SIZE;
1119  }
1120  else
1121 #endif
1122 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_TIGER_SUPPORT == ENABLED)
1123  //HMAC-Tiger PRF algorithm?
1124  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_TIGER)
1125  {
1126  sa->prfMacAlgo = MAC_ALGO_HMAC;
1127  sa->prfHashAlgo = TIGER_HASH_ALGO;
1128  sa->prfCipherAlgo = NULL;
1129  sa->prfKeyLen = TIGER_DIGEST_SIZE;
1130  }
1131  else
1132 #endif
1133 #if (IKE_XCBC_MAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1134  //AES-XCBC-MAC PRF algorithm?
1135  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_AES128_XCBC)
1136  {
1137  sa->prfMacAlgo = MAC_ALGO_XCBC_MAC;
1138  sa->prfHashAlgo = NULL;
1139  sa->prfCipherAlgo = AES_CIPHER_ALGO;
1140  sa->prfKeyLen = 16;
1141  }
1142  else
1143 #endif
1144  //Unknown PRF algorithm?
1145  {
1146  //Report an error
1147  error = ERROR_UNSUPPORTED_ALGO;
1148  }
1149 
1150  //Return status code
1151  return error;
1152 }
1153 
1154 
1155 /**
1156  * @brief Add the supported transforms to the proposal
1157  * @param[in] transformType Transform type
1158  * @param[in] transformId Transform identifier
1159  * @param[in] keyLen Key length attribute (for encryption algorithms with
1160  * variable-length keys)
1161  * @param[in,out] proposal Pointer to the Proposal substructure
1162  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1163  * @return Error code
1164  **/
1165 
1167  uint16_t keyLen, IkeProposal *proposal, uint8_t **lastSubstruc)
1168 {
1169  size_t n;
1170  size_t length;
1171  uint8_t *p;
1172  IkeTransform *transform;
1173  IkeTransformAttr *attr;
1174 
1175  //Get the length of the Proposal substructure
1176  length = ntohs(proposal->proposalLength);
1177  //Point to the buffer where to format the Transform substructure
1178  p = (uint8_t *) proposal + length;
1179 
1180  //The Last Substruc field has a value of 2 if there are more Transform
1181  //substructures
1182  if(*lastSubstruc != NULL)
1183  {
1184  **lastSubstruc = IKE_LAST_SUBSTRUC_MORE_TRANSFORMS;
1185  }
1186 
1187  //Point to the Transform substructure
1188  transform = (IkeTransform *) p;
1189 
1190  //Format Transform substructure
1191  transform->lastSubstruc = IKE_LAST_SUBSTRUC_LAST;
1192  transform->reserved1 = 0;
1193  transform->transformType = transformType;
1194  transform->reserved2 = 0;
1195  transform->transformId = htons(transformId);
1196 
1197  //Length of the Transform substructure
1198  n = sizeof(IkeTransform);
1199 
1200  //Encryption algorithm with variable-length keys?
1203  {
1204  //The Key Length attribute is used by certain encryption transforms
1205  //with variable-length keys (refer to RFC 7296, section 3.3.2)
1206  attr = (IkeTransformAttr *) transform->transformAttr;
1207 
1208  //The Key Length attribute uses Type/value format
1209  attr->type = HTONS((uint16_t) IKE_ATTR_FORMAT_TV |
1210  (uint16_t) IKE_TRANSFORM_ATTR_TYPE_KEY_LEN);
1211 
1212  //The value of the attribute specifies the length of the key, in bits
1213  attr->length = htons(keyLen * 8);
1214 
1215  //Adjust the length of the Transform substructure
1216  n += sizeof(IkeTransformAttr);
1217  }
1218 
1219  //The Transform Length field indicates the length of the Transform
1220  //substructure including header and attributes
1221  transform->transformLength = htons(n);
1222 
1223  //Keep track of the Last Substruc field
1224  *lastSubstruc = &transform->lastSubstruc;
1225 
1226  //Increment the number of transforms
1227  proposal->numTransforms++;
1228 
1229  //Adjust the length of the Proposal substructure
1230  length += n;
1231  //Save the actual length of the Proposal substructure
1232  proposal->proposalLength = htons(length);
1233 
1234  //Successful processing
1235  return NO_ERROR;
1236 }
1237 
1238 
1239 /**
1240  * @brief Add the supported IKE transforms to the proposal
1241  * @param[in] context Pointer to the IKE context
1242  * @param[in,out] proposal Pointer to the Proposal substructure
1243  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1244  * @return Error code
1245  **/
1246 
1248  uint8_t **lastSubstruc)
1249 {
1250  error_t error;
1251 
1252  //Add supported encryption transforms
1253  error = ikeAddSupportedEncTransforms(context, proposal, lastSubstruc);
1254 
1255  //Check status code
1256  if(!error)
1257  {
1258  //Add supported PRF transforms
1259  error = ikeAddSupportedPrfTransforms(context, proposal, lastSubstruc);
1260  }
1261 
1262  //Check status code
1263  if(!error)
1264  {
1265  //Add supported integrity transforms
1266  error = ikeAddSupportedAuthTransforms(context, proposal, lastSubstruc);
1267  }
1268 
1269  //Check status code
1270  if(!error)
1271  {
1272  //Add supported key exchange transforms
1273  error = ikeAddSupportedKeTransforms(context, proposal, lastSubstruc);
1274  }
1275 
1276  //Return status code
1277  return error;
1278 }
1279 
1280 
1281 /**
1282  * @brief Add the supported key exchange transforms to the proposal
1283  * @param[in] context Pointer to the IKE context
1284  * @param[in,out] proposal Pointer to the Proposal substructure
1285  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1286  * @return Error code
1287  **/
1288 
1290  IkeProposal *proposal, uint8_t **lastSubstruc)
1291 {
1292  error_t error;
1293  uint_t i;
1294 
1295  //Initialize status code
1296  error = NO_ERROR;
1297 
1298  //Loop through the list of supported key exchange transforms
1299  for(i = 0; i < arraysize(ikeSupportedKeAlgos) && !error; i++)
1300  {
1301  //Add a new transform to the proposal
1303  ikeSupportedKeAlgos[i], 0, proposal, lastSubstruc);
1304  }
1305 
1306  //Return status code
1307  return error;
1308 }
1309 
1310 
1311 /**
1312  * @brief Add the supported encryption transforms to the proposal
1313  * @param[in] context Pointer to the IKE context
1314  * @param[in,out] proposal Pointer to the Proposal substructure
1315  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1316  * @return Error code
1317  **/
1318 
1320  IkeProposal *proposal, uint8_t **lastSubstruc)
1321 {
1322  error_t error;
1323  uint_t i;
1324 
1325  //Initialize status code
1326  error = NO_ERROR;
1327 
1328  //Loop through the list of supported encryption transforms
1329  for(i = 0; i < arraysize(ikeSupportedEncAlgos) && !error; i++)
1330  {
1331  //Add a new transform to the proposal
1333  ikeSupportedEncAlgos[i].id, ikeSupportedEncAlgos[i].keyLen,
1334  proposal, lastSubstruc);
1335  }
1336 
1337  //Return status code
1338  return error;
1339 }
1340 
1341 
1342 /**
1343  * @brief Add the supported integrity transforms to the proposal
1344  * @param[in] context Pointer to the IKE context
1345  * @param[in,out] proposal Pointer to the Proposal substructure
1346  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1347  * @return Error code
1348  **/
1349 
1351  IkeProposal *proposal, uint8_t **lastSubstruc)
1352 {
1353  error_t error;
1354  uint_t i;
1355 
1356  //Initialize status code
1357  error = NO_ERROR;
1358 
1359  //Loop through the list of supported integrity transforms
1360  for(i = 0; i < (arraysize(ikeSupportedAuthAlgos) - 1) && !error; i++)
1361  {
1362  //Add a new transform to the proposal
1364  ikeSupportedAuthAlgos[i], 0, proposal, lastSubstruc);
1365  }
1366 
1367  //Return status code
1368  return error;
1369 }
1370 
1371 
1372 /**
1373  * @brief Add the supported PRF transforms to the proposal
1374  * @param[in] context Pointer to the IKE context
1375  * @param[in,out] proposal Pointer to the Proposal substructure
1376  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1377  * @return Error code
1378  **/
1379 
1381  IkeProposal *proposal, uint8_t **lastSubstruc)
1382 {
1383  error_t error;
1384  uint_t i;
1385 
1386  //Initialize status code
1387  error = NO_ERROR;
1388 
1389  //Loop through the list of supported PRF transforms
1390  for(i = 0; i < arraysize(ikeSupportedPrfAlgos) && !error; i++)
1391  {
1392  //Add a new transform to the proposal
1394  ikeSupportedPrfAlgos[i], 0, proposal, lastSubstruc);
1395  }
1396 
1397  //Return status code
1398  return error;
1399 }
1400 
1401 
1402 /**
1403  * @brief Get the number of transforms that match a given transform type
1404  * @param[in] transformType Transform type
1405  * @param[in] proposal Pointer to the Proposal substructure
1406  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1407  * @return Number of transforms
1408  **/
1409 
1411  const IkeProposal *proposal, size_t proposalLen)
1412 {
1413  uint_t i;
1414  size_t n;
1415  size_t length;
1417  const uint8_t *p;
1418  IkeTransform *transform;
1419 
1420  //Number of transforms
1421  numTransforms = 0;
1422 
1423  //Check the length of the Proposal substructure
1424  if(proposalLen >= sizeof(IkeProposal) &&
1425  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1426  {
1427  //Get the length of the Proposal substructure
1428  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1429  //Point to the first Transform substructure
1430  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1431 
1432  //Loop through the list of algorithms supported by the peer
1433  for(i = 0; i < proposal->numTransforms; i++)
1434  {
1435  //Malformed substructure?
1436  if(length < sizeof(IkeTransform))
1437  break;
1438 
1439  //Point to the Transform substructure
1440  transform = (IkeTransform *) p;
1441 
1442  //The Transform Length field indicates the length of the Transform
1443  //substructure including header and attributes
1444  n = ntohs(transform->transformLength);
1445 
1446  //Check the length of the transform
1447  if(n < sizeof(IkeTransform) || n > length)
1448  break;
1449 
1450  //Check transform type
1451  if(transform->transformType == transformType)
1452  {
1453  numTransforms++;
1454  }
1455 
1456  //The Last Substruc field has a value of 0 if this was the last
1457  //Transform Substructure
1458  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1459  break;
1460 
1461  //Jump to the next Transform substructure
1462  p += n;
1463  length -= n;
1464  }
1465  }
1466 
1467  //Return the number of transforms
1468  return numTransforms;
1469 }
1470 
1471 
1472 /**
1473  * @brief Transform negotiation
1474  * @param[in] transformType Transform type
1475  * @param[in] algoList List of algorithms
1476  * @param[in] algoListLen Number of items in the list
1477  * @param[in] proposal Pointer to the Proposal substructure
1478  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1479  * @return Selected transform, if any
1480  **/
1481 
1483  const uint16_t *algoList, uint_t algoListLen, const IkeProposal *proposal,
1484  size_t proposalLen)
1485 {
1486  uint_t i;
1487  uint_t j;
1488  size_t n;
1489  size_t length;
1490  bool_t found;
1491  const uint8_t *p;
1492  uint16_t selectedAlgo;
1493  IkeTransform *transform;
1494 
1495  //Initialize flag
1496  found = FALSE;
1497 
1498  //Key exchange transform negotiation?
1500  {
1501  selectedAlgo = IKE_TRANSFORM_ID_KE_NONE;
1502  }
1503  else
1504  {
1505  selectedAlgo = IKE_TRANSFORM_ID_INVALID;
1506  }
1507 
1508  //Check the length of the Proposal substructure
1509  if(proposalLen >= sizeof(IkeProposal) &&
1510  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1511  {
1512  //Loop through the list of algorithms supported by the entity
1513  for(i = 0; i < algoListLen && !found; i++)
1514  {
1515  //Get the length of the Proposal substructure
1516  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1517  //Point to the first Transform substructure
1518  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1519 
1520  //Loop through the list of algorithms supported by the peer
1521  for(j = 0; j < proposal->numTransforms && !found; j++)
1522  {
1523  //Malformed substructure?
1524  if(length < sizeof(IkeTransform))
1525  break;
1526 
1527  //Point to the Transform substructure
1528  transform = (IkeTransform *) p;
1529 
1530  //The Transform Length field indicates the length of the Transform
1531  //substructure including header and attributes
1532  n = ntohs(transform->transformLength);
1533 
1534  //Check the length of the transform
1535  if(n < sizeof(IkeTransform) || n > length)
1536  break;
1537 
1538  //Check transform type
1539  if(transform->transformType == transformType)
1540  {
1541  //Check transform identifier
1542  if(ntohs(transform->transformId) == algoList[i])
1543  {
1544  selectedAlgo = algoList[i];
1545  found = TRUE;
1546  }
1547  }
1548 
1549  //The Last Substruc field has a value of 0 if this was the last
1550  //Transform Substructure
1551  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1552  break;
1553 
1554  //Jump to the next Transform substructure
1555  p += n;
1556  length -= n;
1557  }
1558  }
1559  }
1560 
1561  //Return the chosen algorithm, if any
1562  return selectedAlgo;
1563 }
1564 
1565 
1566 /**
1567  * @brief Key exchange transform negotiation
1568  * @param[in] context Pointer to the IKE context
1569  * @param[in] proposal Pointer to the Proposal substructure
1570  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1571  * @return Selected key exchange transform, if any
1572  **/
1573 
1574 uint16_t ikeSelectKeTransform(IkeContext *context, const IkeProposal *proposal,
1575  size_t proposalLen)
1576 {
1577  //Select the key exchange transform to use
1578  return ikeSelectTransform(IKE_TRANSFORM_TYPE_KE, ikeSupportedKeAlgos,
1579  arraysize(ikeSupportedKeAlgos), proposal, proposalLen);
1580 }
1581 
1582 
1583 /**
1584  * @brief Encryption transform negotiation
1585  * @param[in] context Pointer to the IKE context
1586  * @param[in] proposal Pointer to the Proposal substructure
1587  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1588  * @return Selected encryption transform, if any
1589  **/
1590 
1592  const IkeProposal *proposal, size_t proposalLen)
1593 {
1594  uint_t i;
1595  uint_t j;
1596  size_t n;
1597  size_t length;
1598  uint8_t *p;
1599  uint16_t transformId;
1600  const IkeEncAlgo *selectedAlgo;
1601  const IkeTransform *transform;
1602  const IkeTransformAttr *attr;
1603 
1604  //Chosen algorithm
1605  selectedAlgo = NULL;
1606 
1607  //Check the length of the Proposal substructure
1608  if(proposalLen >= sizeof(IkeProposal) &&
1609  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1610  {
1611  //Loop through the list of algorithms supported by the entity
1612  for(i = 0; i < arraysize(ikeSupportedEncAlgos) && selectedAlgo == NULL; i++)
1613  {
1614  //Get the length of the Proposal substructure
1615  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1616  //Point to the first Transform substructure
1617  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1618 
1619  //Loop through the list of algorithms supported by the peer
1620  for(j = 0; j < proposal->numTransforms && selectedAlgo == NULL; j++)
1621  {
1622  //Malformed substructure?
1623  if(length < sizeof(IkeTransform))
1624  break;
1625 
1626  //Point to the Transform substructure
1627  transform = (IkeTransform *) p;
1628 
1629  //The Transform Length field indicates the length of the Transform
1630  //substructure including header and attributes
1631  n = ntohs(transform->transformLength);
1632 
1633  //Check the length of the transform
1634  if(n < sizeof(IkeTransform) || n > length)
1635  break;
1636 
1637  //Check transform type
1638  if(transform->transformType == IKE_TRANSFORM_TYPE_ENCR)
1639  {
1640  //Convert the Transform ID field to host byte order
1641  transformId = ntohs(transform->transformId);
1642 
1643  //Variable-length key encryption algorithm?
1645  {
1646  //For algorithms that accept a variable-length key, a fixed
1647  //key size must be specified as part of the cryptographic
1648  //transform negotiated (refer to RFC 7296, section 2.13)
1649  if(n == (sizeof(IkeTransform) + sizeof(IkeTransformAttr)))
1650  {
1651  //Point to the transform attribute
1652  attr = (IkeTransformAttr *) transform->transformAttr;
1653 
1654  //Check attribute format and type
1655  if(ntohs(attr->type) == ((uint16_t) IKE_ATTR_FORMAT_TV |
1656  (uint16_t) IKE_TRANSFORM_ATTR_TYPE_KEY_LEN))
1657  {
1658  //Check transform identifier and key length
1659  if(transformId == ikeSupportedEncAlgos[i].id &&
1660  ntohs(attr->length) == (ikeSupportedEncAlgos[i].keyLen * 8))
1661  {
1662  selectedAlgo = &ikeSupportedEncAlgos[i];
1663  }
1664  }
1665  }
1666  }
1667  else
1668  {
1669  //The Key Length attribute must not be used with transforms
1670  //that use a fixed-length key (refer to RFC 7296, section 3.3.5)
1671  if(n == sizeof(IkeTransform))
1672  {
1673  //Check transform identifier
1674  if(transformId == ikeSupportedEncAlgos[i].id)
1675  {
1676  selectedAlgo = &ikeSupportedEncAlgos[i];
1677  }
1678  }
1679  }
1680  }
1681 
1682  //The Last Substruc field has a value of 0 if this was the last
1683  //Transform Substructure
1684  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1685  break;
1686 
1687  //Jump to the next Transform substructure
1688  p += n;
1689  length -= n;
1690  }
1691  }
1692  }
1693 
1694  //Return the chosen algorithm, if any
1695  return selectedAlgo;
1696 }
1697 
1698 
1699 /**
1700  * @brief Integrity transform negotiation
1701  * @param[in] context Pointer to the IKE context
1702  * @param[in] proposal Pointer to the Proposal substructure
1703  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1704  * @return Selected integrity transform, if any
1705  **/
1706 
1707 uint16_t ikeSelectAuthTransform(IkeContext *context, const IkeProposal *proposal,
1708  size_t proposalLen)
1709 {
1710  //Select the integrity transform to use
1711  return ikeSelectTransform(IKE_TRANSFORM_TYPE_INTEG, ikeSupportedAuthAlgos,
1712  arraysize(ikeSupportedAuthAlgos) - 1, proposal, proposalLen);
1713 }
1714 
1715 
1716 /**
1717  * @brief PRF transform negotiation
1718  * @param[in] context Pointer to the IKE context
1719  * @param[in] proposal Pointer to the Proposal substructure
1720  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1721  * @return Selected PRF transform, if any
1722  **/
1723 
1724 uint16_t ikeSelectPrfTransform(IkeContext *context, const IkeProposal *proposal,
1725  size_t proposalLen)
1726 {
1727  //Select the key exchange transform to use
1728  return ikeSelectTransform(IKE_TRANSFORM_TYPE_PRF, ikeSupportedPrfAlgos,
1729  arraysize(ikeSupportedPrfAlgos), proposal, proposalLen);
1730 }
1731 
1732 
1733 /**
1734  * @brief Select a single proposal (IKE protocol)
1735  * @param[in] sa Pointer to the IKE SA
1736  * @param[in] payload Pointer to the Security Association payload
1737  * @param[in] spiSize Expected SPI size, in bytes
1738  * @return Error code
1739  **/
1740 
1742  size_t spiSize)
1743 {
1744  error_t error;
1745  size_t n;
1746  size_t length;
1747  const uint8_t *p;
1748  const IkeProposal *proposal;
1749  const IkeEncAlgo *encAlgo;
1750 
1751  //Clear the set of parameters
1752  sa->keContext.groupNum = IKE_TRANSFORM_ID_KE_NONE;
1753  sa->prfAlgoId = IKE_TRANSFORM_ID_INVALID;
1754  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1755  sa->encKeyLen = 0;
1756  sa->authAlgoId = IKE_TRANSFORM_ID_INVALID;
1757 
1758  //Retrieve the length of the SA payload
1759  length = ntohs(payload->header.payloadLength);
1760 
1761  //Malformed payload?
1762  if(length < sizeof(IkeSaPayload))
1763  return ERROR_INVALID_MESSAGE;
1764 
1765  //Point to the first byte of the Proposals field
1766  p = payload->proposals;
1767  //Determine the length of the Proposals field
1768  length -= sizeof(IkeSaPayload);
1769 
1770  //Initialize status code
1771  error = ERROR_INVALID_PROPOSAL;
1772 
1773  //The Security Association payload contains one or more Proposal
1774  //substructures
1775  while(1)
1776  {
1777  //Malformed payload?
1778  if(length < sizeof(IkeProposal))
1779  {
1780  //Report an error
1781  error = ERROR_INVALID_MESSAGE;
1782  break;
1783  }
1784 
1785  //Point to the Proposal substructure
1786  proposal = (IkeProposal *) p;
1787 
1788  //The Proposal Length field indicates the length of this proposal,
1789  //including all transforms and attributes that follow
1790  n = ntohs(proposal->proposalLength);
1791 
1792  //Check the length of the proposal
1793  if(n < sizeof(IkeProposal) || n > length)
1794  {
1795  //Report an error
1796  error = ERROR_INVALID_MESSAGE;
1797  break;
1798  }
1799 
1800  //Check protocol identifier
1801  if(proposal->protocolId == IKE_PROTOCOL_ID_IKE &&
1802  proposal->spiSize == spiSize)
1803  {
1804  //Key exchange transform negotiation
1805  sa->keContext.groupNum = ikeSelectKeTransform(sa->context, proposal, n);
1806  //PRF transform negotiation
1807  sa->prfAlgoId = ikeSelectPrfTransform(sa->context, proposal, n);
1808  //Encryption transform negotiation
1809  encAlgo = ikeSelectEncTransform(sa->context, proposal, n);
1810 
1811  //Valid encryption transform?
1812  if(encAlgo != NULL)
1813  {
1814  sa->encAlgoId = encAlgo->id;
1815  sa->encKeyLen = encAlgo->keyLen;
1816  }
1817  else
1818  {
1819  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1820  sa->encKeyLen = 0;
1821  }
1822 
1823  //AEAD algorithm?
1824  if(ikeIsAeadEncAlgo(sa->encAlgoId))
1825  {
1826  //When an authenticated encryption algorithm is selected as the
1827  //encryption algorithm for any SA, an integrity algorithm must not
1828  //be selected for that SA (refer to RFC 5282, section 8)
1829  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
1830  }
1831  else
1832  {
1833  //Integrity transform negotiation
1834  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
1835  }
1836 
1837  //Valid proposal?
1838  if(sa->keContext.groupNum != IKE_TRANSFORM_ID_KE_NONE &&
1839  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
1840  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
1841  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
1842  {
1843  //Save the number of the proposal that was accepted
1844  sa->acceptedProposalNum = proposal->proposalNum;
1845 
1846  //A new initiator SPI is supplied in the SPI field of the SA
1847  //payload (refer to RFC 7296, section 1.3.2)
1848  if(spiSize != 0)
1849  {
1850  osMemcpy(sa->initiatorSpi, proposal->spi, IKE_SPI_SIZE);
1851  }
1852 
1853  //Successful negotiation
1854  error = NO_ERROR;
1855  break;
1856  }
1857  }
1858 
1859  //Jump to the next proposal
1860  p += n;
1861  length -= n;
1862  }
1863 
1864  //Return status code
1865  return error;
1866 }
1867 
1868 
1869 /**
1870  * @brief Select a single proposal (AH or ESP protocol)
1871  * @param[in] childSa Pointer to the Child SA
1872  * @param[in] payload Pointer to the Security Association payload
1873  * @return Error code
1874  **/
1875 
1876 
1878  const IkeSaPayload *payload)
1879 {
1880  error_t error;
1881 
1882 #if (AH_SUPPORT == ENABLED)
1883  //AH protocol identifier?
1884  if(childSa->protocol == IPSEC_PROTOCOL_AH)
1885  {
1886  error = ahSelectSaProposal(childSa, payload);
1887  }
1888  else
1889 #endif
1890 #if (ESP_SUPPORT == ENABLED)
1891  //ESP protocol identifier?
1892  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
1893  {
1894  error = espSelectSaProposal(childSa, payload);
1895  }
1896  else
1897 #endif
1898  //Unknown protocol identifier?
1899  {
1900  error = ERROR_INVALID_PROTOCOL;
1901  }
1902 
1903  //Return status code
1904  return error;
1905 }
1906 
1907 
1908 /**
1909  * @brief Check whether the selected proposal is acceptable (IKE protocol)
1910  * @param[in] sa Pointer to the IKE SA
1911  * @param[in] payload Pointer to the Security Association payload
1912  * @return Error code
1913  **/
1914 
1916 {
1917  size_t n;
1918  size_t length;
1919  const uint8_t *p;
1920  const IkeProposal *proposal;
1921  const IkeEncAlgo *encAlgo;
1922 
1923  //Clear the set of parameters
1924  sa->prfAlgoId = IKE_TRANSFORM_ID_INVALID;
1925  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1926  sa->encKeyLen = 0;
1927  sa->authAlgoId = IKE_TRANSFORM_ID_INVALID;
1928 
1929  //Retrieve the length of the SA payload
1930  length = ntohs(payload->header.payloadLength);
1931 
1932  //Malformed payload?
1933  if(length < sizeof(IkeSaPayload))
1934  return ERROR_INVALID_MESSAGE;
1935 
1936  //Point to the first byte of the Proposals field
1937  p = payload->proposals;
1938  //Determine the length of the Proposals field
1939  length -= sizeof(IkeSaPayload);
1940 
1941  //Malformed payload?
1942  if(length < sizeof(IkeProposal))
1943  return ERROR_INVALID_MESSAGE;
1944 
1945  //Point to the Proposal substructure
1946  proposal = (IkeProposal *) p;
1947 
1948  //The Proposal Length field indicates the length of this proposal,
1949  //including all transforms and attributes that follow
1950  n = ntohs(proposal->proposalLength);
1951 
1952  //The responder must accept a single proposal (refer to RFC 7296,
1953  //section 2.7)
1954  if(n != length)
1955  return ERROR_INVALID_MESSAGE;
1956 
1957  //Check protocol identifier
1958  if(proposal->protocolId != IKE_PROTOCOL_ID_IKE)
1959  return ERROR_INVALID_MESSAGE;
1960 
1961  //Initial IKE SA negotiation?
1962  if(sa->state == IKE_SA_STATE_INIT_RESP)
1963  {
1964  //For an initial IKE SA negotiation, the SPI Size field must be zero
1965  if(proposal->spiSize != 0)
1966  return ERROR_INVALID_MESSAGE;
1967  }
1968  else
1969  {
1970  //During subsequent negotiations, it is equal to the size, in octets,
1971  //of the SPI of the corresponding protocol (8 for IKE)
1972  if(proposal->spiSize != IKE_SPI_SIZE)
1973  return ERROR_INVALID_MESSAGE;
1974 
1975  //A new responder SPI is supplied in the SPI field of the SA payload
1976  //(refer to RFC 7296, section 1.3.2)
1977  osMemcpy(sa->responderSpi, proposal->spi, IKE_SPI_SIZE);
1978  }
1979 
1980  //The accepted cryptographic suite must contain exactly one transform of
1981  //each type included in the proposal (refer to RFC 7296, section 2.7)
1982  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_KE, proposal, n) != 1 ||
1983  ikeGetNumTransforms(IKE_TRANSFORM_TYPE_PRF, proposal, n) != 1 ||
1985  {
1986  return ERROR_INVALID_PROPOSAL;
1987  }
1988 
1989  //Make sure the selected key exchange method is acceptable
1990  if(ikeSelectKeTransform(sa->context, proposal, n) != sa->keContext.groupNum)
1991  return ERROR_INVALID_PROPOSAL;
1992 
1993  //Get the selected PRF transform
1994  sa->prfAlgoId = ikeSelectPrfTransform(sa->context, proposal, n);
1995  //Get the selected encryption transform
1996  encAlgo = ikeSelectEncTransform(sa->context, proposal, n);
1997 
1998  //Valid encryption transform?
1999  if(encAlgo != NULL)
2000  {
2001  sa->encAlgoId = encAlgo->id;
2002  sa->encKeyLen = encAlgo->keyLen;
2003  }
2004 
2005  //AEAD algorithm?
2006  if(ikeIsAeadEncAlgo(sa->encAlgoId))
2007  {
2008  //When an authenticated encryption algorithm is selected as the encryption
2009  //algorithm for any SA, an integrity algorithm must not be selected for
2010  //that SA (refer to RFC 5282, section 8)
2011  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 0)
2012  return ERROR_INVALID_PROPOSAL;
2013 
2014  //AEAD algorithms combine encryption and integrity into a single operation
2015  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
2016  }
2017  else
2018  {
2019  //Exactly one integrity transform must be included in the proposal
2020  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 1)
2021  return ERROR_INVALID_PROPOSAL;
2022 
2023  //Get the selected integrity transform
2024  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
2025  }
2026 
2027  //The initiator of an exchange must check that the accepted offer is
2028  //consistent with one of its proposals, and if not must terminate the
2029  //exchange (refer to RFC 7296, section 3.3.6)
2030  if(sa->keContext.groupNum != IKE_TRANSFORM_ID_KE_NONE &&
2031  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
2032  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
2033  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
2034  {
2035  return NO_ERROR;
2036  }
2037  else
2038  {
2039  return ERROR_INVALID_PROPOSAL;
2040  }
2041 }
2042 
2043 
2044 /**
2045  * @brief Check whether the selected proposal is acceptable (AH or ESP protocol)
2046  * @param[in] childSa Pointer to the Child SA
2047  * @param[in] payload Pointer to the Security Association payload
2048  * @return Error code
2049  **/
2050 
2052  const IkeSaPayload *payload)
2053 {
2054  error_t error;
2055 
2056 #if (AH_SUPPORT == ENABLED)
2057  //AH protocol identifier?
2058  if(childSa->protocol == IPSEC_PROTOCOL_AH)
2059  {
2060  error = ahCheckSaProposal(childSa, payload);
2061  }
2062  else
2063 #endif
2064 #if (ESP_SUPPORT == ENABLED)
2065  //ESP protocol identifier?
2066  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
2067  {
2068  error = espCheckSaProposal(childSa, payload);
2069  }
2070  else
2071 #endif
2072  //Unknown protocol identifier?
2073  {
2074  error = ERROR_INVALID_PROTOCOL;
2075  }
2076 
2077  //Return status code
2078  return error;
2079 }
2080 
2081 
2082 /**
2083  * @brief Test if the transform ID identifies an AEAD encryption algorithm
2084  * @param[in] encAlgoId Encryption algorithm identifier
2085  * @return TRUE if AEAD encryption algorithm, else FALSE
2086  **/
2087 
2088 bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
2089 {
2090  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2091  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2092  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2093  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2094  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2095  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2096  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2101  {
2102  return TRUE;
2103  }
2104  else
2105  {
2106  return FALSE;
2107  }
2108 }
2109 
2110 
2111 /**
2112  * @brief Test if the transform ID identifies a variable-length key encryption algorithm
2113  * @param[in] encAlgoId Encryption algorithm identifier
2114  * @return TRUE if variable-length key encryption algorithm, else FALSE
2115  **/
2116 
2118 {
2119  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC ||
2120  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR ||
2121  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2122  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2123  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2124  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2125  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2126  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2127  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC ||
2128  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR ||
2129  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2133  {
2134  return TRUE;
2135  }
2136  else
2137  {
2138  return FALSE;
2139  }
2140 }
2141 
2142 
2143 /**
2144  * @brief Test if the group number identifies a DH key exchange algorithm
2145  * @param[in] groupNum Group number
2146  * @return TRUE if DH key exchange algorithm, else FALSE
2147  **/
2148 
2149 bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
2150 {
2151  //Diffie-Hellman key exchange?
2152  if(groupNum == IKE_TRANSFORM_ID_KE_MODP_768 ||
2153  groupNum == IKE_TRANSFORM_ID_KE_MODP_1024 ||
2154  groupNum == IKE_TRANSFORM_ID_KE_MODP_1536 ||
2155  groupNum == IKE_TRANSFORM_ID_KE_MODP_2048 ||
2156  groupNum == IKE_TRANSFORM_ID_KE_MODP_3072 ||
2157  groupNum == IKE_TRANSFORM_ID_KE_MODP_4096 ||
2158  groupNum == IKE_TRANSFORM_ID_KE_MODP_6144 ||
2159  groupNum == IKE_TRANSFORM_ID_KE_MODP_8192 ||
2160  groupNum == IKE_TRANSFORM_ID_KE_MODP_1024_160 ||
2161  groupNum == IKE_TRANSFORM_ID_KE_MODP_2048_224 ||
2163  {
2164  return TRUE;
2165  }
2166  else
2167  {
2168  return FALSE;
2169  }
2170 }
2171 
2172 
2173 /**
2174  * @brief Test if the group number identifies an ECDH key exchange algorithm
2175  * @param[in] groupNum Group number
2176  * @return TRUE if ECDH key exchange algorithm, else FALSE
2177  **/
2178 
2180 {
2181  //ECDH key exchange?
2182  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_192 ||
2183  groupNum == IKE_TRANSFORM_ID_KE_ECP_224 ||
2184  groupNum == IKE_TRANSFORM_ID_KE_ECP_256 ||
2185  groupNum == IKE_TRANSFORM_ID_KE_ECP_384 ||
2186  groupNum == IKE_TRANSFORM_ID_KE_ECP_521 ||
2191  groupNum == IKE_TRANSFORM_ID_KE_CURVE25519 ||
2192  groupNum == IKE_TRANSFORM_ID_KE_CURVE448)
2193  {
2194  return TRUE;
2195  }
2196  else
2197  {
2198  return FALSE;
2199  }
2200 }
2201 
2202 
2203 /**
2204  * @brief Test if the group number identifies an ML-KEM key exchange algorithm
2205  * @param[in] groupNum Group number
2206  * @return TRUE if ML-KEM key exchange algorithm, else FALSE
2207  **/
2208 
2210 {
2211  //ML-KEM key exchange?
2212  if(groupNum == IKE_TRANSFORM_ID_KE_ML_KEM_512 ||
2213  groupNum == IKE_TRANSFORM_ID_KE_ML_KEM_768 ||
2214  groupNum == IKE_TRANSFORM_ID_KE_ML_KEM_1024)
2215  {
2216  return TRUE;
2217  }
2218  else
2219  {
2220  return FALSE;
2221  }
2222 }
2223 
2224 
2225 /**
2226  * @brief Get the elliptic curve that matches the specified group number
2227  * @param[in] groupNum Group number
2228  * @return Elliptic curve parameters
2229  **/
2230 
2231 const EcCurve *ikeGetEcdhCurve(uint16_t groupNum)
2232 {
2233  const EcCurve *curve;
2234 
2235 #if (IKE_ECDH_KE_SUPPORT == ENABLED)
2236 #if (IKE_ECP_192_SUPPORT == ENABLED)
2237  //NIST P-192 elliptic curve?
2238  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_192)
2239  {
2240  curve = SECP192R1_CURVE;
2241  }
2242  else
2243 #endif
2244 #if (IKE_ECP_224_SUPPORT == ENABLED)
2245  //NIST P-224 elliptic curve?
2246  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_224)
2247  {
2248  curve = SECP224R1_CURVE;
2249  }
2250  else
2251 #endif
2252 #if (IKE_ECP_256_SUPPORT == ENABLED)
2253  //NIST P-256 elliptic curve?
2254  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_256)
2255  {
2256  curve = SECP256R1_CURVE;
2257  }
2258  else
2259 #endif
2260 #if (IKE_ECP_384_SUPPORT == ENABLED)
2261  //NIST P-384 elliptic curve?
2262  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_384)
2263  {
2264  curve = SECP384R1_CURVE;
2265  }
2266  else
2267 #endif
2268 #if (IKE_ECP_521_SUPPORT == ENABLED)
2269  //NIST P-521 elliptic curve?
2270  if(groupNum == IKE_TRANSFORM_ID_KE_ECP_521)
2271  {
2272  curve = SECP521R1_CURVE;
2273  }
2274  else
2275 #endif
2276 #if (IKE_BRAINPOOLP224R1_SUPPORT == ENABLED)
2277  //brainpoolP224r1 elliptic curve?
2278  if(groupNum == IKE_TRANSFORM_ID_KE_BRAINPOOLP224R1)
2279  {
2280  curve = BRAINPOOLP224R1_CURVE;
2281  }
2282  else
2283 #endif
2284 #if (IKE_BRAINPOOLP256R1_SUPPORT == ENABLED)
2285  //brainpoolP256r1 elliptic curve?
2286  if(groupNum == IKE_TRANSFORM_ID_KE_BRAINPOOLP256R1)
2287  {
2288  curve = BRAINPOOLP256R1_CURVE;
2289  }
2290  else
2291 #endif
2292 #if (IKE_BRAINPOOLP384R1_SUPPORT == ENABLED)
2293  //brainpoolP384r1 elliptic curve?
2294  if(groupNum == IKE_TRANSFORM_ID_KE_BRAINPOOLP384R1)
2295  {
2296  curve = BRAINPOOLP384R1_CURVE;
2297  }
2298  else
2299 #endif
2300 #if (IKE_BRAINPOOLP512R1_SUPPORT == ENABLED)
2301  //brainpoolP512r1 elliptic curve?
2302  if(groupNum == IKE_TRANSFORM_ID_KE_BRAINPOOLP512R1)
2303  {
2304  curve = BRAINPOOLP512R1_CURVE;
2305  }
2306  else
2307 #endif
2308 #if (IKE_CURVE25519_SUPPORT == ENABLED)
2309  //Curve25519 elliptic curve?
2310  if(groupNum == IKE_TRANSFORM_ID_KE_CURVE25519)
2311  {
2312  curve = X25519_CURVE;
2313  }
2314  else
2315 #endif
2316 #if (IKE_CURVE448_SUPPORT == ENABLED)
2317  //Curve448 elliptic curve?
2318  if(groupNum == IKE_TRANSFORM_ID_KE_CURVE448)
2319  {
2320  curve = X448_CURVE;
2321  }
2322  else
2323 #endif
2324 #endif
2325  //Unknown elliptic curve?
2326  {
2327  curve = NULL;
2328  }
2329 
2330  //Return the elliptic curve parameters, if any
2331  return curve;
2332 }
2333 
2334 
2335 /**
2336  * @brief Get the default key exchange method
2337  * @return Default group number
2338  **/
2339 
2341 {
2342  return ikeSupportedKeAlgos[0];
2343 }
2344 
2345 
2346 /**
2347  * @brief Check whether a given key exchange method is supported
2348  * @param[in] groupNum Group number
2349  * @return TRUE is the key exchange method is supported, else FALSE
2350  **/
2351 
2352 bool_t ikeIsGroupSupported(uint16_t groupNum)
2353 {
2354  uint_t i;
2355  bool_t acceptable;
2356 
2357  //Initialize flag
2358  acceptable = FALSE;
2359 
2360  //Loop through the list of key exchange methods supported by the entity
2361  for(i = 0; i < arraysize(ikeSupportedKeAlgos); i++)
2362  {
2363  //Compare group numbers
2364  if(ikeSupportedKeAlgos[i] == groupNum)
2365  {
2366  acceptable = TRUE;
2367  break;
2368  }
2369  }
2370 
2371  //Return TRUE is the key exchange method is supported
2372  return acceptable;
2373 }
2374 
2375 
2376 /**
2377  * @brief Check whether a given signature hash algorithm is supported
2378  * @param[in] hashAlgoId Signature hash algorithm identifier
2379  * @return TRUE is the signature hash algorithm is supported, else FALSE
2380  **/
2381 
2382 bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
2383 {
2384  bool_t acceptable;
2385 
2386 #if (IKE_SHA1_SUPPORT == ENABLED)
2387  //SHA-1 hash algorithm identifier?
2388  if(hashAlgoId == IKE_HASH_ALGO_SHA1)
2389  {
2390  acceptable = TRUE;
2391  }
2392  else
2393 #endif
2394 #if (IKE_SHA256_SUPPORT == ENABLED)
2395  //SHA-256 hash algorithm identifier?
2396  if(hashAlgoId == IKE_HASH_ALGO_SHA256)
2397  {
2398  acceptable = TRUE;
2399  }
2400  else
2401 #endif
2402 #if (IKE_SHA384_SUPPORT == ENABLED)
2403  //SHA-384 hash algorithm identifier?
2404  if(hashAlgoId == IKE_HASH_ALGO_SHA384)
2405  {
2406  acceptable = TRUE;
2407  }
2408  else
2409 #endif
2410 #if (IKE_SHA512_SUPPORT == ENABLED)
2411  //SHA-512 hash algorithm identifier?
2412  if(hashAlgoId == IKE_HASH_ALGO_SHA512)
2413  {
2414  acceptable = TRUE;
2415  }
2416  else
2417 #endif
2418 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED || IKE_ED448_SIGN_SUPPORT == ENABLED)
2419  //"Identity" hash algorithm identifier?
2420  if(hashAlgoId == IKE_HASH_ALGO_IDENTITY)
2421  {
2422  acceptable = TRUE;
2423  }
2424  else
2425 #endif
2426  //Unknown hash algorithm identifier?
2427  {
2428  acceptable = FALSE;
2429  }
2430 
2431  //Return TRUE is the signature hash is supported
2432  return acceptable;
2433 }
2434 
2435 #endif
error_t ikeAddSupportedAuthTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported integrity transforms to the proposal.
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_8
Definition: ike.h:984
@ IKE_TRANSFORM_ID_AUTH_AES_CMAC_96
Definition: ike.h:1037
AH algorithm negotiation.
@ MAC_ALGO_CMAC
@ CIPHER_MODE_CBC
Definition: cipher_modes.h:82
#define htons(value)
Definition: cpu_endian.h:413
error_t ikeSelectEncAlgo(IkeSaEntry *sa, uint16_t encAlgoId, size_t encKeyLen)
Select the relevant encryption algorithm.
@ IKE_TRANSFORM_ID_KE_MODP_1024
1024-bit MODP Group
Definition: ike.h:1055
uint_t ikeGetNumTransforms(IkeTransformType transformType, const IkeProposal *proposal, size_t proposalLen)
Get the number of transforms that match a given transform type.
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_384_192
Definition: ike.h:1042
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96
Definition: ike.h:1031
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:63
@ IKE_TRANSFORM_ID_PRF_AES128_CMAC
Definition: ike.h:1018
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_16
Definition: ike.h:983
@ IKE_TRANSFORM_ID_KE_ML_KEM_1024
ML-KEM-1024.
Definition: ike.h:1080
#define SHA1_HASH_ALGO
Definition: sha1.h:49
@ IKE_TRANSFORM_ID_ENCR_AES_CTR
Definition: ike.h:980
#define SECP521R1_CURVE
Definition: ec_curves.h:53
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:199
@ IKE_HASH_ALGO_SHA256
Definition: ike.h:1400
#define SHA512_HASH_ALGO
Definition: sha512.h:49
@ IKE_HASH_ALGO_SHA1
Definition: ike.h:1399
#define IDEA_BLOCK_SIZE
Definition: idea.h:38
#define SECP384R1_CURVE
Definition: ec_curves.h:52
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC
Definition: ike.h:988
uint8_t p
Definition: ndp.h:300
@ IKE_TRANSFORM_ID_ENCR_IDEA
Definition: ike.h:973
@ IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96
Definition: ike.h:1030
Encryption algorithm.
@ IKE_LAST_SUBSTRUC_MORE_TRANSFORMS
More transform substructures.
Definition: ike.h:920
#define TRUE
Definition: os_port.h:50
#define SECP256R1_CURVE
Definition: ec_curves.h:51
Collection of cipher algorithms.
error_t ikeAddTransform(IkeTransformType transformType, uint16_t transformId, uint16_t keyLen, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported transforms to the proposal.
error_t ikeCheckSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (IKE protocol)
@ IKE_TRANSFORM_ID_KE_MODP_2048_224
2048-bit MODP Group with 224-bit Prime Order Subgroup
Definition: ike.h:1066
uint8_t numTransforms
Definition: ike.h:1503
ESP algorithm negotiation.
@ IKE_TRANSFORM_ID_KE_ML_KEM_512
ML-KEM-512.
Definition: ike.h:1078
@ CIPHER_MODE_CTR
Definition: cipher_modes.h:85
@ IKE_TRANSFORM_ID_KE_BRAINPOOLP256R1
256-bit Brainpool ECP Group
Definition: ike.h:1071
#define IDEA_CIPHER_ALGO
Definition: idea.h:40
@ IKE_TRANSFORM_ID_KE_ECP_192
192-bit Random ECP Group
Definition: ike.h:1068
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8
Definition: ike.h:990
@ IKE_LAST_SUBSTRUC_LAST
Last proposal/transform substructure.
Definition: ike.h:918
@ IKE_TRANSFORM_ID_KE_MODP_768
768-bit MODP Group
Definition: ike.h:1054
error_t ikeSelectChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal (AH or ESP protocol)
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_16
Definition: ike.h:992
error_t ikeSelectPrfAlgo(IkeSaEntry *sa, uint16_t prfAlgoId)
Select the relevant PRF algorithm.
const IkeEncAlgo * ikeSelectEncTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Encryption transform negotiation.
error_t ikeAddSupportedPrfTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported PRF transforms to the proposal.
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
@ IKE_TRANSFORM_ID_KE_MODP_2048_256
2048-bit MODP Group with 256-bit Prime Order Subgroup
Definition: ike.h:1067
bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
Check whether a given signature hash algorithm is supported.
@ IKE_TRANSFORM_ID_KE_ECP_224
224-bit Random ECP Group
Definition: ike.h:1069
IkeTransform
Definition: ike.h:1521
uint16_t ikeSelectTransform(IkeTransformType transformType, const uint16_t *algoList, uint_t algoListLen, const IkeProposal *proposal, size_t proposalLen)
Transform negotiation.
@ IKE_TRANSFORM_ID_ENCR_CHACHA20_POLY1305
Definition: ike.h:993
@ IKE_TRANSFORM_ID_KE_ECP_384
384-bit Random ECP Group
Definition: ike.h:1063
uint16_t ikeSelectPrfTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
PRF transform negotiation.
@ IKE_ATTR_FORMAT_TV
shortened Type/Value format
Definition: ike.h:1102
@ IKE_TRANSFORM_ID_AUTH_AES_XCBC_96
Definition: ike.h:1034
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384
Definition: ike.h:1016
error_t espSelectSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal.
#define DES3_BLOCK_SIZE
Definition: des3.h:44
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:200
@ IKE_TRANSFORM_ID_KE_MODP_3072
3072-bit MODP Group
Definition: ike.h:1058
#define IKE_TRANSFORM_ID_INVALID
#define AES_BLOCK_SIZE
Definition: aes.h:43
@ IKE_TRANSFORM_ID_ENCR_AES_CBC
Definition: ike.h:979
#define BRAINPOOLP512R1_CURVE
Definition: ec_curves.h:66
@ IKE_TRANSFORM_ATTR_TYPE_KEY_LEN
Key Length (in bits)
Definition: ike.h:1112
#define IkeContext
Definition: ike.h:832
#define BRAINPOOLP384R1_CURVE
Definition: ec_curves.h:64
uint16_t ikeSelectDefaultGroup(void)
Get the default key exchange method.
#define BRAINPOOLP224R1_CURVE
Definition: ec_curves.h:58
#define FALSE
Definition: os_port.h:46
error_t ikeSelectAuthAlgo(IkeSaEntry *sa, uint16_t authAlgoId)
Select the relevant MAC algorithm.
@ IKE_TRANSFORM_ID_KE_BRAINPOOLP224R1
224-bit Brainpool ECP Group
Definition: ike.h:1070
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: cipher_modes.h:91
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
@ IKE_TRANSFORM_ID_KE_MODP_6144
6144-bit MODP Group
Definition: ike.h:1060
@ ERROR_INVALID_PROPOSAL
Definition: error.h:301
@ IKE_TRANSFORM_ID_KE_BRAINPOOLP384R1
384-bit Brainpool ECP Group
Definition: ike.h:1072
error_t ahSelectSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal.
error_t ikeAddSupportedKeTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported key exchange transforms to the proposal.
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_ALGO
Definition: error.h:126
uint8_t spiSize
Definition: ike.h:1502
bool_t ikeIsGroupSupported(uint16_t groupNum)
Check whether a given key exchange method is supported.
@ IKE_TRANSFORM_ID_KE_MODP_1536
1536-bit MODP Group
Definition: ike.h:1056
@ IKE_TRANSFORM_ID_KE_MODP_4096
4096-bit MODP Group
Definition: ike.h:1059
@ CIPHER_MODE_GCM
Definition: cipher_modes.h:87
@ IKE_HASH_ALGO_SHA512
Definition: ike.h:1402
#define IKE_SPI_SIZE
Definition: ike.h:826
bool_t ikeIsMlkemKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies an ML-KEM key exchange algorithm.
#define MD5_HASH_ALGO
Definition: md5.h:49
@ IKE_TRANSFORM_ID_PRF_HMAC_MD5
Definition: ike.h:1011
@ IKE_TRANSFORM_ID_KE_ECP_256
256-bit Random ECP Group
Definition: ike.h:1062
bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies a DH key exchange algorithm.
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA1
Definition: ike.h:1012
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_12
Definition: ike.h:985
#define CAMELLIA_CIPHER_ALGO
Definition: camellia.h:40
IkeTransformAttr
Definition: ike.h:1533
uint8_t transformType
Definition: ike.h:1517
uint16_t keyLen
Block cipher modes of operation.
#define DES_CIPHER_ALGO
Definition: des.h:45
uint16_t ikeSelectAuthTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Integrity transform negotiation.
error_t espCheckSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable.
@ IKE_TRANSFORM_TYPE_ENCR
Encryption Algorithm.
Definition: ike.h:945
uint8_t length
Definition: tcp.h:375
@ IKE_TRANSFORM_ID_KE_MODP_1024_160
1024-bit MODP Group with 160-bit Prime Order Subgroup
Definition: ike.h:1065
@ IKE_TRANSFORM_ID_PRF_AES128_XCBC
Definition: ike.h:1014
@ ERROR_INVALID_PROTOCOL
Definition: error.h:101
bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
Test if the transform ID identifies an AEAD encryption algorithm.
IkeTransformType
Transform types.
Definition: ike.h:944
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
#define MD5_DIGEST_SIZE
Definition: md5.h:45
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256
Definition: ike.h:1015
#define TIGER_HASH_ALGO
Definition: tiger.h:44
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_256_128
Definition: ike.h:1041
@ IKE_TRANSFORM_ID_ENCR_DES
Definition: ike.h:970
Collection of hash algorithms.
IKEv2 (Internet Key Exchange Protocol)
#define ntohs(value)
Definition: cpu_endian.h:421
@ IKE_TRANSFORM_ID_KE_NONE
None.
Definition: ike.h:1053
#define SHA384_HASH_ALGO
Definition: sha384.h:45
@ IKE_TRANSFORM_ID_ENCR_NULL_AUTH_AES_GMAC
Definition: ike.h:987
@ IKE_TRANSFORM_ID_KE_MODP_2048
2048-bit MODP Group
Definition: ike.h:1057
@ IKE_TRANSFORM_ID_KE_ECP_521
521-bit Random ECP Group
Definition: ike.h:1064
IkeProposal
Definition: ike.h:1505
@ IKE_TRANSFORM_TYPE_KE
Key Exchange Method.
Definition: ike.h:948
error_t ikeSelectSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload, size_t spiSize)
Select a single proposal (IKE protocol)
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define IkeSaEntry
Definition: ike.h:836
@ IKE_TRANSFORM_ID_ENCR_3DES
Definition: ike.h:971
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_16
Definition: ike.h:986
@ CIPHER_MODE_CCM
Definition: cipher_modes.h:86
@ IKE_TRANSFORM_ID_KE_CURVE25519
curve25519
Definition: ike.h:1074
#define HTONS(value)
Definition: cpu_endian.h:410
uint8_t n
@ IKE_TRANSFORM_ID_PRF_HMAC_TIGER
Definition: ike.h:1013
@ IKE_TRANSFORM_ID_KE_ML_KEM_768
ML-KEM-768.
Definition: ike.h:1079
uint8_t payload[]
Definition: ipv6.h:308
error_t ikeAddSupportedTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported IKE transforms to the proposal.
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_12
Definition: ike.h:982
@ IKE_TRANSFORM_TYPE_PRF
Pseudorandom Function.
Definition: ike.h:946
#define DES_BLOCK_SIZE
Definition: des.h:43
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR
Definition: ike.h:989
uint16_t transformId
Definition: ike.h:1519
@ IKE_PROTOCOL_ID_IKE
IKE.
Definition: ike.h:930
@ MAC_ALGO_HMAC
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1357
#define CAMELLIA_BLOCK_SIZE
Definition: camellia.h:38
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define BRAINPOOLP256R1_CURVE
Definition: ec_curves.h:60
const EcCurve * ikeGetEcdhCurve(uint16_t groupNum)
Get the elliptic curve that matches the specified group number.
#define X448_CURVE
Definition: ec_curves.h:71
#define TIGER_DIGEST_SIZE
Definition: tiger.h:40
#define SECP224R1_CURVE
Definition: ec_curves.h:49
bool_t ikeIsVariableLengthKeyEncAlgo(uint16_t encAlgoId)
Test if the transform ID identifies a variable-length key encryption algorithm.
#define EcCurve
Definition: ec.h:346
@ IKE_TRANSFORM_ID_KE_MODP_8192
8192-bit MODP Group
Definition: ike.h:1061
error_t ahCheckSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable.
@ IKE_TRANSFORM_ID_KE_BRAINPOOLP512R1
512-bit Brainpool ECP Group
Definition: ike.h:1073
#define DES3_CIPHER_ALGO
Definition: des3.h:46
bool_t ikeIsEcdhKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies an ECDH key exchange algorithm.
error_t ikeAddSupportedEncTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported encryption transforms to the proposal.
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_512_256
Definition: ike.h:1043
unsigned int uint_t
Definition: compiler_port.h:57
@ IKE_TRANSFORM_ID_AUTH_NONE
Definition: ike.h:1029
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
uint16_t id
error_t ikeCheckChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (AH or ESP protocol)
#define IkeChildSaEntry
Definition: ike.h:840
@ IKE_HASH_ALGO_SHA384
Definition: ike.h:1401
@ IKE_HASH_ALGO_IDENTITY
Definition: ike.h:1403
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
#define SECP192R1_CURVE
Definition: ec_curves.h:47
IKEv2 algorithm negotiation.
uint16_t ikeSelectKeTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Key exchange transform negotiation.
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512
Definition: ike.h:1017
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ MAC_ALGO_XCBC_MAC
IkeSaPayload
Definition: ike.h:1488
#define arraysize(a)
Definition: os_port.h:71
@ IKE_TRANSFORM_ID_KE_CURVE448
curve448
Definition: ike.h:1075
#define X25519_CURVE
Definition: ec_curves.h:70
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12
Definition: ike.h:991
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_8
Definition: ike.h:981
@ IKE_TRANSFORM_TYPE_INTEG
Integrity Algorithm.
Definition: ike.h:947