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-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.2
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 algorithms
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->authHashAlgo = NULL;
952  sa->authCipherAlgo = AES_CIPHER_ALGO;
953  sa->authKeyLen = 16;
954  sa->icvLen = 12;
955  }
956  else
957 #endif
958 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
959  //HMAC-MD5-96 authentication algorithm?
960  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96)
961  {
962  sa->authHashAlgo = MD5_HASH_ALGO;
963  sa->authCipherAlgo = NULL;
964  sa->authKeyLen = MD5_DIGEST_SIZE;
965  sa->icvLen = 12;
966  }
967  else
968 #endif
969 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
970  //HMAC-SHA1-96 authentication algorithm?
971  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96)
972  {
973  sa->authHashAlgo = SHA1_HASH_ALGO;
974  sa->authCipherAlgo = NULL;
975  sa->authKeyLen = SHA1_DIGEST_SIZE;
976  sa->icvLen = 12;
977  }
978  else
979 #endif
980 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
981  //HMAC-SHA256-128 authentication algorithm?
983  {
984  sa->authHashAlgo = SHA256_HASH_ALGO;
985  sa->authCipherAlgo = NULL;
986  sa->authKeyLen = SHA256_DIGEST_SIZE;
987  sa->icvLen = 16;
988  }
989  else
990 #endif
991 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
992  //HMAC-SHA384-192 authentication algorithm?
994  {
995  sa->authHashAlgo = SHA384_HASH_ALGO;
996  sa->authCipherAlgo = NULL;
997  sa->authKeyLen = SHA384_DIGEST_SIZE;
998  sa->icvLen = 24;
999  }
1000  else
1001 #endif
1002 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
1003  //HMAC-SHA512-256 authentication algorithm?
1004  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_512_256)
1005  {
1006  sa->authHashAlgo = SHA512_HASH_ALGO;
1007  sa->authCipherAlgo = NULL;
1008  sa->authKeyLen = SHA512_DIGEST_SIZE;
1009  sa->icvLen = 32;
1010  }
1011  else
1012 #endif
1013 #if (IKE_XCBC_MAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1014  //AES-XCBC-MAC-96 authentication algorithm?
1015  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_AES_XCBC_96)
1016  {
1017  sa->authHashAlgo = NULL;
1018  sa->authCipherAlgo = AES_CIPHER_ALGO;
1019  sa->authKeyLen = 16;
1020  sa->icvLen = 12;
1021  }
1022  else
1023 #endif
1024  //Unknown authentication algorithm?
1025  {
1026  //Report an error
1027  error = ERROR_UNSUPPORTED_ALGO;
1028  }
1029 
1030  //Return status code
1031  return error;
1032 }
1033 
1034 
1035 /**
1036  * @brief Select the relevant PRF algorithm
1037  * @param[in] sa Pointer to the IKE SA
1038  * @param[in] prfAlgoId PRF algorithm identifier
1039  * @return Error code
1040  **/
1041 
1042 error_t ikeSelectPrfAlgo(IkeSaEntry *sa, uint16_t prfAlgoId)
1043 {
1044  error_t error;
1045 
1046  //Initialize status code
1047  error = NO_ERROR;
1048 
1049 #if (IKE_CMAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1050  //AES-CMAC PRF algorithm?
1051  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_AES128_CMAC)
1052  {
1053  sa->prfHashAlgo = NULL;
1054  sa->prfCipherAlgo = AES_CIPHER_ALGO;
1055  sa->prfKeyLen = 16;
1056  }
1057  else
1058 #endif
1059 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
1060  //HMAC-MD5 PRF algorithm?
1061  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_MD5)
1062  {
1063  sa->prfHashAlgo = MD5_HASH_ALGO;
1064  sa->prfCipherAlgo = NULL;
1065  sa->prfKeyLen = MD5_DIGEST_SIZE;
1066  }
1067  else
1068 #endif
1069 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
1070  //HMAC-SHA1 PRF algorithm?
1071  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA1)
1072  {
1073  sa->prfHashAlgo = SHA1_HASH_ALGO;
1074  sa->prfCipherAlgo = NULL;
1075  sa->prfKeyLen = SHA1_DIGEST_SIZE;
1076  }
1077  else
1078 #endif
1079 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
1080  //HMAC-SHA256 PRF algorithm?
1081  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256)
1082  {
1083  sa->prfHashAlgo = SHA256_HASH_ALGO;
1084  sa->prfCipherAlgo = NULL;
1085  sa->prfKeyLen = SHA256_DIGEST_SIZE;
1086  }
1087  else
1088 #endif
1089 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
1090  //HMAC-SHA384 PRF algorithm?
1091  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384)
1092  {
1093  sa->prfHashAlgo = SHA384_HASH_ALGO;
1094  sa->prfCipherAlgo = NULL;
1095  sa->prfKeyLen = SHA384_DIGEST_SIZE;
1096  }
1097  else
1098 #endif
1099 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
1100  //HMAC-SHA512 PRF algorithm?
1101  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512)
1102  {
1103  sa->prfHashAlgo = SHA512_HASH_ALGO;
1104  sa->prfCipherAlgo = NULL;
1105  sa->prfKeyLen = SHA512_DIGEST_SIZE;
1106  }
1107  else
1108 #endif
1109 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_TIGER_SUPPORT == ENABLED)
1110  //HMAC-Tiger PRF algorithm?
1111  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_TIGER)
1112  {
1113  sa->prfHashAlgo = TIGER_HASH_ALGO;
1114  sa->prfCipherAlgo = NULL;
1115  sa->prfKeyLen = TIGER_DIGEST_SIZE;
1116  }
1117  else
1118 #endif
1119 #if (IKE_XCBC_MAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1120  //AES-XCBC-MAC PRF algorithm?
1121  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_AES128_XCBC)
1122  {
1123  sa->prfHashAlgo = NULL;
1124  sa->prfCipherAlgo = AES_CIPHER_ALGO;
1125  sa->prfKeyLen = 16;
1126  }
1127  else
1128 #endif
1129  //Unknown PRF algorithm?
1130  {
1131  //Report an error
1132  error = ERROR_UNSUPPORTED_ALGO;
1133  }
1134 
1135  //Return status code
1136  return error;
1137 }
1138 
1139 
1140 /**
1141  * @brief Add the supported transforms to the proposal
1142  * @param[in] transformType Transform type
1143  * @param[in] transformId Transform identifier
1144  * @param[in] keyLen Key length attribute (for encryption algorithms with
1145  * variable-length keys)
1146  * @param[in,out] proposal Pointer to the Proposal substructure
1147  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1148  * @return Error code
1149  **/
1150 
1152  uint16_t keyLen, IkeProposal *proposal, uint8_t **lastSubstruc)
1153 {
1154  size_t n;
1155  size_t length;
1156  uint8_t *p;
1157  IkeTransform *transform;
1158  IkeTransformAttr *attr;
1159 
1160  //Get the length of the Proposal substructure
1161  length = ntohs(proposal->proposalLength);
1162  //Point to the buffer where to format the Transform substructure
1163  p = (uint8_t *) proposal + length;
1164 
1165  //The Last Substruc field has a value of 2 if there are more Transform
1166  //substructures
1167  if(*lastSubstruc != NULL)
1168  {
1169  **lastSubstruc = IKE_LAST_SUBSTRUC_MORE_TRANSFORMS;
1170  }
1171 
1172  //Point to the Transform substructure
1173  transform = (IkeTransform *) p;
1174 
1175  //Format Transform substructure
1176  transform->lastSubstruc = IKE_LAST_SUBSTRUC_LAST;
1177  transform->reserved1 = 0;
1178  transform->transformType = transformType;
1179  transform->reserved2 = 0;
1180  transform->transformId = htons(transformId);
1181 
1182  //Length of the Transform substructure
1183  n = sizeof(IkeTransform);
1184 
1185  //Encryption algorithm with variable-length keys?
1188  {
1189  //The Key Length attribute is used by certain encryption transforms
1190  //with variable-length keys (refer to RFC 7296, section 3.3.2)
1191  attr = (IkeTransformAttr *) transform->transformAttr;
1192 
1193  //The Key Length attribute uses Type/value format
1194  attr->type = HTONS((uint16_t) IKE_ATTR_FORMAT_TV |
1195  (uint16_t) IKE_TRANSFORM_ATTR_TYPE_KEY_LEN);
1196 
1197  //The value of the attribute specifies the length of the key, in bits
1198  attr->length = htons(keyLen * 8);
1199 
1200  //Adjust the length of the Transform substructure
1201  n += sizeof(IkeTransformAttr);
1202  }
1203 
1204  //The Transform Length field indicates the length of the Transform
1205  //substructure including header and attributes
1206  transform->transformLength = htons(n);
1207 
1208  //Keep track of the Last Substruc field
1209  *lastSubstruc = &transform->lastSubstruc;
1210 
1211  //Increment the number of transforms
1212  proposal->numTransforms++;
1213 
1214  //Adjust the length of the Proposal substructure
1215  length += n;
1216  //Save the actual length of the Proposal substructure
1217  proposal->proposalLength = htons(length);
1218 
1219  //Successful processing
1220  return NO_ERROR;
1221 }
1222 
1223 
1224 /**
1225  * @brief Add the supported IKE transforms to the proposal
1226  * @param[in] context Pointer to the IKE context
1227  * @param[in,out] proposal Pointer to the Proposal substructure
1228  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1229  * @return Error code
1230  **/
1231 
1233  uint8_t **lastSubstruc)
1234 {
1235  error_t error;
1236 
1237  //Add supported encryption transforms
1238  error = ikeAddSupportedEncTransforms(context, proposal, lastSubstruc);
1239 
1240  //Check status code
1241  if(!error)
1242  {
1243  //Add supported PRF transforms
1244  error = ikeAddSupportedPrfTransforms(context, proposal, lastSubstruc);
1245  }
1246 
1247  //Check status code
1248  if(!error)
1249  {
1250  //Add supported integrity transforms
1251  error = ikeAddSupportedAuthTransforms(context, proposal, lastSubstruc);
1252  }
1253 
1254  //Check status code
1255  if(!error)
1256  {
1257  //Add supported key exchange transforms
1258  error = ikeAddSupportedKeTransforms(context, proposal, lastSubstruc);
1259  }
1260 
1261  //Return status code
1262  return error;
1263 }
1264 
1265 
1266 /**
1267  * @brief Add the supported key exchange transforms to the proposal
1268  * @param[in] context Pointer to the IKE context
1269  * @param[in,out] proposal Pointer to the Proposal substructure
1270  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1271  * @return Error code
1272  **/
1273 
1275  IkeProposal *proposal, uint8_t **lastSubstruc)
1276 {
1277  error_t error;
1278  uint_t i;
1279 
1280  //Initialize status code
1281  error = NO_ERROR;
1282 
1283  //Loop through the list of supported key exchange transforms
1284  for(i = 0; i < arraysize(ikeSupportedKeAlgos) && !error; i++)
1285  {
1286  //Add a new transform to the proposal
1288  ikeSupportedKeAlgos[i], 0, proposal, lastSubstruc);
1289  }
1290 
1291  //Return status code
1292  return error;
1293 }
1294 
1295 
1296 /**
1297  * @brief Add the supported encryption transforms to the proposal
1298  * @param[in] context Pointer to the IKE context
1299  * @param[in,out] proposal Pointer to the Proposal substructure
1300  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1301  * @return Error code
1302  **/
1303 
1305  IkeProposal *proposal, uint8_t **lastSubstruc)
1306 {
1307  error_t error;
1308  uint_t i;
1309 
1310  //Initialize status code
1311  error = NO_ERROR;
1312 
1313  //Loop through the list of supported encryption transforms
1314  for(i = 0; i < arraysize(ikeSupportedEncAlgos) && !error; i++)
1315  {
1316  //Add a new transform to the proposal
1318  ikeSupportedEncAlgos[i].id, ikeSupportedEncAlgos[i].keyLen,
1319  proposal, lastSubstruc);
1320  }
1321 
1322  //Return status code
1323  return error;
1324 }
1325 
1326 
1327 /**
1328  * @brief Add the supported integrity transforms to the proposal
1329  * @param[in] context Pointer to the IKE context
1330  * @param[in,out] proposal Pointer to the Proposal substructure
1331  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1332  * @return Error code
1333  **/
1334 
1336  IkeProposal *proposal, uint8_t **lastSubstruc)
1337 {
1338  error_t error;
1339  uint_t i;
1340 
1341  //Initialize status code
1342  error = NO_ERROR;
1343 
1344  //Loop through the list of supported integrity transforms
1345  for(i = 0; i < (arraysize(ikeSupportedAuthAlgos) - 1) && !error; i++)
1346  {
1347  //Add a new transform to the proposal
1349  ikeSupportedAuthAlgos[i], 0, proposal, lastSubstruc);
1350  }
1351 
1352  //Return status code
1353  return error;
1354 }
1355 
1356 
1357 /**
1358  * @brief Add the supported PRF transforms to the proposal
1359  * @param[in] context Pointer to the IKE context
1360  * @param[in,out] proposal Pointer to the Proposal substructure
1361  * @param[in,out] lastSubstruc Pointer to the Last Substruc field
1362  * @return Error code
1363  **/
1364 
1366  IkeProposal *proposal, uint8_t **lastSubstruc)
1367 {
1368  error_t error;
1369  uint_t i;
1370 
1371  //Initialize status code
1372  error = NO_ERROR;
1373 
1374  //Loop through the list of supported PRF transforms
1375  for(i = 0; i < arraysize(ikeSupportedPrfAlgos) && !error; i++)
1376  {
1377  //Add a new transform to the proposal
1379  ikeSupportedPrfAlgos[i], 0, proposal, lastSubstruc);
1380  }
1381 
1382  //Return status code
1383  return error;
1384 }
1385 
1386 
1387 /**
1388  * @brief Get the number of transforms that match a given transform type
1389  * @param[in] transformType Transform type
1390  * @param[in] proposal Pointer to the Proposal substructure
1391  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1392  * @return Number of transforms
1393  **/
1394 
1396  const IkeProposal *proposal, size_t proposalLen)
1397 {
1398  uint_t i;
1399  size_t n;
1400  size_t length;
1402  const uint8_t *p;
1403  IkeTransform *transform;
1404 
1405  //Number of transforms
1406  numTransforms = 0;
1407 
1408  //Check the length of the Proposal substructure
1409  if(proposalLen >= sizeof(IkeProposal) &&
1410  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1411  {
1412  //Get the length of the Proposal substructure
1413  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1414  //Point to the first Transform substructure
1415  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1416 
1417  //Loop through the list of algorithms supported by the peer
1418  for(i = 0; i < proposal->numTransforms; i++)
1419  {
1420  //Malformed substructure?
1421  if(length < sizeof(IkeTransform))
1422  break;
1423 
1424  //Point to the Transform substructure
1425  transform = (IkeTransform *) p;
1426 
1427  //The Transform Length field indicates the length of the Transform
1428  //substructure including header and attributes
1429  n = ntohs(transform->transformLength);
1430 
1431  //Check the length of the transform
1432  if(n < sizeof(IkeTransform) || n > length)
1433  break;
1434 
1435  //Check transform type
1436  if(transform->transformType == transformType)
1437  {
1438  numTransforms++;
1439  }
1440 
1441  //The Last Substruc field has a value of 0 if this was the last
1442  //Transform Substructure
1443  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1444  break;
1445 
1446  //Jump to the next Transform substructure
1447  p += n;
1448  length -= n;
1449  }
1450  }
1451 
1452  //Return the number of transforms
1453  return numTransforms;
1454 }
1455 
1456 
1457 /**
1458  * @brief Transform negotiation
1459  * @param[in] transformType Transform type
1460  * @param[in] algoList List of algorithms
1461  * @param[in] algoListLen Number of items in the list
1462  * @param[in] proposal Pointer to the Proposal substructure
1463  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1464  * @return Selected transform, if any
1465  **/
1466 
1468  const uint16_t *algoList, uint_t algoListLen, const IkeProposal *proposal,
1469  size_t proposalLen)
1470 {
1471  uint_t i;
1472  uint_t j;
1473  size_t n;
1474  size_t length;
1475  bool_t found;
1476  const uint8_t *p;
1477  uint16_t selectedAlgo;
1478  IkeTransform *transform;
1479 
1480  //Initialize flag
1481  found = FALSE;
1482 
1483  //Key exchange transform negotiation?
1485  {
1486  selectedAlgo = IKE_TRANSFORM_ID_DH_GROUP_NONE;
1487  }
1488  else
1489  {
1490  selectedAlgo = IKE_TRANSFORM_ID_INVALID;
1491  }
1492 
1493  //Check the length of the Proposal substructure
1494  if(proposalLen >= sizeof(IkeProposal) &&
1495  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1496  {
1497  //Loop through the list of algorithms supported by the entity
1498  for(i = 0; i < algoListLen && !found; i++)
1499  {
1500  //Get the length of the Proposal substructure
1501  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1502  //Point to the first Transform substructure
1503  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1504 
1505  //Loop through the list of algorithms supported by the peer
1506  for(j = 0; j < proposal->numTransforms && !found; j++)
1507  {
1508  //Malformed substructure?
1509  if(length < sizeof(IkeTransform))
1510  break;
1511 
1512  //Point to the Transform substructure
1513  transform = (IkeTransform *) p;
1514 
1515  //The Transform Length field indicates the length of the Transform
1516  //substructure including header and attributes
1517  n = ntohs(transform->transformLength);
1518 
1519  //Check the length of the transform
1520  if(n < sizeof(IkeTransform) || n > length)
1521  break;
1522 
1523  //Check transform type
1524  if(transform->transformType == transformType)
1525  {
1526  //Check transform identifier
1527  if(ntohs(transform->transformId) == algoList[i])
1528  {
1529  selectedAlgo = algoList[i];
1530  found = TRUE;
1531  }
1532  }
1533 
1534  //The Last Substruc field has a value of 0 if this was the last
1535  //Transform Substructure
1536  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1537  break;
1538 
1539  //Jump to the next Transform substructure
1540  p += n;
1541  length -= n;
1542  }
1543  }
1544  }
1545 
1546  //Return the chosen algorithm, if any
1547  return selectedAlgo;
1548 }
1549 
1550 
1551 /**
1552  * @brief Key exchange transform negotiation
1553  * @param[in] context Pointer to the IKE context
1554  * @param[in] proposal Pointer to the Proposal substructure
1555  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1556  * @return Selected key exchange transform, if any
1557  **/
1558 
1559 uint16_t ikeSelectKeTransform(IkeContext *context, const IkeProposal *proposal,
1560  size_t proposalLen)
1561 {
1562  //Select the key exchange transform to use
1563  return ikeSelectTransform(IKE_TRANSFORM_TYPE_DH, ikeSupportedKeAlgos,
1564  arraysize(ikeSupportedKeAlgos), proposal, proposalLen);
1565 }
1566 
1567 
1568 /**
1569  * @brief Encryption transform negotiation
1570  * @param[in] context Pointer to the IKE context
1571  * @param[in] proposal Pointer to the Proposal substructure
1572  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1573  * @return Selected encryption transform, if any
1574  **/
1575 
1577  const IkeProposal *proposal, size_t proposalLen)
1578 {
1579  uint_t i;
1580  uint_t j;
1581  size_t n;
1582  size_t length;
1583  uint8_t *p;
1584  uint16_t transformId;
1585  const IkeEncAlgo *selectedAlgo;
1586  const IkeTransform *transform;
1587  const IkeTransformAttr *attr;
1588 
1589  //Chosen algorithm
1590  selectedAlgo = NULL;
1591 
1592  //Check the length of the Proposal substructure
1593  if(proposalLen >= sizeof(IkeProposal) &&
1594  proposalLen >= (sizeof(IkeProposal) + proposal->spiSize))
1595  {
1596  //Loop through the list of algorithms supported by the entity
1597  for(i = 0; i < arraysize(ikeSupportedEncAlgos) && selectedAlgo == NULL; i++)
1598  {
1599  //Get the length of the Proposal substructure
1600  length = proposalLen - sizeof(IkeProposal) - proposal->spiSize;
1601  //Point to the first Transform substructure
1602  p = (uint8_t *) proposal + sizeof(IkeProposal) + proposal->spiSize;
1603 
1604  //Loop through the list of algorithms supported by the peer
1605  for(j = 0; j < proposal->numTransforms && selectedAlgo == NULL; j++)
1606  {
1607  //Malformed substructure?
1608  if(length < sizeof(IkeTransform))
1609  break;
1610 
1611  //Point to the Transform substructure
1612  transform = (IkeTransform *) p;
1613 
1614  //The Transform Length field indicates the length of the Transform
1615  //substructure including header and attributes
1616  n = ntohs(transform->transformLength);
1617 
1618  //Check the length of the transform
1619  if(n < sizeof(IkeTransform) || n > length)
1620  break;
1621 
1622  //Check transform type
1623  if(transform->transformType == IKE_TRANSFORM_TYPE_ENCR)
1624  {
1625  //Convert the Transform ID field to host byte order
1626  transformId = ntohs(transform->transformId);
1627 
1628  //Variable-length key encryption algorithm?
1630  {
1631  //For algorithms that accept a variable-length key, a fixed
1632  //key size must be specified as part of the cryptographic
1633  //transform negotiated (refer to RFC 7296, section 2.13)
1634  if(n == (sizeof(IkeTransform) + sizeof(IkeTransformAttr)))
1635  {
1636  //Point to the transform attribute
1637  attr = (IkeTransformAttr *) transform->transformAttr;
1638 
1639  //Check attribute format and type
1640  if(ntohs(attr->type) == ((uint16_t) IKE_ATTR_FORMAT_TV |
1641  (uint16_t) IKE_TRANSFORM_ATTR_TYPE_KEY_LEN))
1642  {
1643  //Check transform identifier and key length
1644  if(transformId == ikeSupportedEncAlgos[i].id &&
1645  ntohs(attr->length) == (ikeSupportedEncAlgos[i].keyLen * 8))
1646  {
1647  selectedAlgo = &ikeSupportedEncAlgos[i];
1648  }
1649  }
1650  }
1651  }
1652  else
1653  {
1654  //The Key Length attribute must not be used with transforms
1655  //that use a fixed-length key (refer to RFC 7296, section 3.3.5)
1656  if(n == sizeof(IkeTransform))
1657  {
1658  //Check transform identifier
1659  if(transformId == ikeSupportedEncAlgos[i].id)
1660  {
1661  selectedAlgo = &ikeSupportedEncAlgos[i];
1662  }
1663  }
1664  }
1665  }
1666 
1667  //The Last Substruc field has a value of 0 if this was the last
1668  //Transform Substructure
1669  if(transform->lastSubstruc == IKE_LAST_SUBSTRUC_LAST)
1670  break;
1671 
1672  //Jump to the next Transform substructure
1673  p += n;
1674  length -= n;
1675  }
1676  }
1677  }
1678 
1679  //Return the chosen algorithm, if any
1680  return selectedAlgo;
1681 }
1682 
1683 
1684 /**
1685  * @brief Integrity transform negotiation
1686  * @param[in] context Pointer to the IKE context
1687  * @param[in] proposal Pointer to the Proposal substructure
1688  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1689  * @return Selected integrity transform, if any
1690  **/
1691 
1692 uint16_t ikeSelectAuthTransform(IkeContext *context, const IkeProposal *proposal,
1693  size_t proposalLen)
1694 {
1695  //Select the integrity transform to use
1696  return ikeSelectTransform(IKE_TRANSFORM_TYPE_INTEG, ikeSupportedAuthAlgos,
1697  arraysize(ikeSupportedAuthAlgos) - 1, proposal, proposalLen);
1698 }
1699 
1700 
1701 /**
1702  * @brief PRF transform negotiation
1703  * @param[in] context Pointer to the IKE context
1704  * @param[in] proposal Pointer to the Proposal substructure
1705  * @param[in] proposalLen Length of the Proposal substructure, in bytes
1706  * @return Selected PRF transform, if any
1707  **/
1708 
1709 uint16_t ikeSelectPrfTransform(IkeContext *context, const IkeProposal *proposal,
1710  size_t proposalLen)
1711 {
1712  //Select the key exchange transform to use
1713  return ikeSelectTransform(IKE_TRANSFORM_TYPE_PRF, ikeSupportedPrfAlgos,
1714  arraysize(ikeSupportedPrfAlgos), proposal, proposalLen);
1715 }
1716 
1717 
1718 /**
1719  * @brief Select a single proposal (IKE protocol)
1720  * @param[in] sa Pointer to the IKE SA
1721  * @param[in] payload Pointer to the Security Association payload
1722  * @param[in] spiSize Expected SPI size, in bytes
1723  * @return Error code
1724  **/
1725 
1727  size_t spiSize)
1728 {
1729  error_t error;
1730  size_t n;
1731  size_t length;
1732  const uint8_t *p;
1733  const IkeProposal *proposal;
1734  const IkeEncAlgo *encAlgo;
1735 
1736  //Clear the set of parameters
1737  sa->dhGroupNum = IKE_TRANSFORM_ID_DH_GROUP_NONE;
1738  sa->prfAlgoId = IKE_TRANSFORM_ID_INVALID;
1739  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1740  sa->encKeyLen = 0;
1741  sa->authAlgoId = IKE_TRANSFORM_ID_INVALID;
1742 
1743  //Retrieve the length of the SA payload
1744  length = ntohs(payload->header.payloadLength);
1745 
1746  //Malformed payload?
1747  if(length < sizeof(IkeSaPayload))
1748  return ERROR_INVALID_MESSAGE;
1749 
1750  //Point to the first byte of the Proposals field
1751  p = payload->proposals;
1752  //Determine the length of the Proposals field
1753  length -= sizeof(IkeSaPayload);
1754 
1755  //Initialize status code
1756  error = ERROR_INVALID_PROPOSAL;
1757 
1758  //The Security Association payload contains one or more Proposal
1759  //substructures
1760  while(1)
1761  {
1762  //Malformed payload?
1763  if(length < sizeof(IkeProposal))
1764  {
1765  //Report an error
1766  error = ERROR_INVALID_MESSAGE;
1767  break;
1768  }
1769 
1770  //Point to the Proposal substructure
1771  proposal = (IkeProposal *) p;
1772 
1773  //The Proposal Length field indicates the length of this proposal,
1774  //including all transforms and attributes that follow
1775  n = ntohs(proposal->proposalLength);
1776 
1777  //Check the length of the proposal
1778  if(n < sizeof(IkeProposal) || n > length)
1779  {
1780  //Report an error
1781  error = ERROR_INVALID_MESSAGE;
1782  break;
1783  }
1784 
1785  //Check protocol identifier
1786  if(proposal->protocolId == IKE_PROTOCOL_ID_IKE &&
1787  proposal->spiSize == spiSize)
1788  {
1789  //Key exchange transform negotiation
1790  sa->dhGroupNum = ikeSelectKeTransform(sa->context, proposal, n);
1791  //PRF transform negotiation
1792  sa->prfAlgoId = ikeSelectPrfTransform(sa->context, proposal, n);
1793  //Encryption transform negotiation
1794  encAlgo = ikeSelectEncTransform(sa->context, proposal, n);
1795 
1796  //Valid encryption transform?
1797  if(encAlgo != NULL)
1798  {
1799  sa->encAlgoId = encAlgo->id;
1800  sa->encKeyLen = encAlgo->keyLen;
1801  }
1802  else
1803  {
1804  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1805  sa->encKeyLen = 0;
1806  }
1807 
1808  //AEAD algorithm?
1809  if(ikeIsAeadEncAlgo(sa->encAlgoId))
1810  {
1811  //When an authenticated encryption algorithm is selected as the
1812  //encryption algorithm for any SA, an integrity algorithm must not
1813  //be selected for that SA (refer to RFC 5282, section 8)
1814  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
1815  }
1816  else
1817  {
1818  //Integrity transform negotiation
1819  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
1820  }
1821 
1822  //Valid proposal?
1823  if(sa->dhGroupNum != IKE_TRANSFORM_ID_DH_GROUP_NONE &&
1824  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
1825  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
1826  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
1827  {
1828  //Save the number of the proposal that was accepted
1829  sa->acceptedProposalNum = proposal->proposalNum;
1830 
1831  //A new initiator SPI is supplied in the SPI field of the SA
1832  //payload (refer to RFC 7296, section 1.3.2)
1833  if(spiSize != 0)
1834  {
1835  osMemcpy(sa->initiatorSpi, proposal->spi, IKE_SPI_SIZE);
1836  }
1837 
1838  //Successful negotiation
1839  error = NO_ERROR;
1840  break;
1841  }
1842  }
1843 
1844  //Jump to the next proposal
1845  p += n;
1846  length -= n;
1847  }
1848 
1849  //Return status code
1850  return error;
1851 }
1852 
1853 
1854 /**
1855  * @brief Select a single proposal (AH or ESP protocol)
1856  * @param[in] childSa Pointer to the Child SA
1857  * @param[in] payload Pointer to the Security Association payload
1858  * @return Error code
1859  **/
1860 
1861 
1863  const IkeSaPayload *payload)
1864 {
1865  error_t error;
1866 
1867 #if (AH_SUPPORT == ENABLED)
1868  //AH protocol identifier?
1869  if(childSa->protocol == IPSEC_PROTOCOL_AH)
1870  {
1871  error = ahSelectSaProposal(childSa, payload);
1872  }
1873  else
1874 #endif
1875 #if (ESP_SUPPORT == ENABLED)
1876  //ESP protocol identifier?
1877  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
1878  {
1879  error = espSelectSaProposal(childSa, payload);
1880  }
1881  else
1882 #endif
1883  //Unknown protocol identifier?
1884  {
1885  error = ERROR_INVALID_PROTOCOL;
1886  }
1887 
1888  //Return status code
1889  return error;
1890 }
1891 
1892 
1893 /**
1894  * @brief Check whether the selected proposal is acceptable (IKE protocol)
1895  * @param[in] sa Pointer to the IKE SA
1896  * @param[in] payload Pointer to the Security Association payload
1897  * @return Error code
1898  **/
1899 
1901 {
1902  size_t n;
1903  size_t length;
1904  const uint8_t *p;
1905  const IkeProposal *proposal;
1906  const IkeEncAlgo *encAlgo;
1907 
1908  //Clear the set of parameters
1909  sa->prfAlgoId = IKE_TRANSFORM_ID_INVALID;
1910  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1911  sa->encKeyLen = 0;
1912  sa->authAlgoId = IKE_TRANSFORM_ID_INVALID;
1913 
1914  //Retrieve the length of the SA payload
1915  length = ntohs(payload->header.payloadLength);
1916 
1917  //Malformed payload?
1918  if(length < sizeof(IkeSaPayload))
1919  return ERROR_INVALID_MESSAGE;
1920 
1921  //Point to the first byte of the Proposals field
1922  p = payload->proposals;
1923  //Determine the length of the Proposals field
1924  length -= sizeof(IkeSaPayload);
1925 
1926  //Malformed payload?
1927  if(length < sizeof(IkeProposal))
1928  return ERROR_INVALID_MESSAGE;
1929 
1930  //Point to the Proposal substructure
1931  proposal = (IkeProposal *) p;
1932 
1933  //The Proposal Length field indicates the length of this proposal,
1934  //including all transforms and attributes that follow
1935  n = ntohs(proposal->proposalLength);
1936 
1937  //The responder must accept a single proposal (refer to RFC 7296,
1938  //section 2.7)
1939  if(n != length)
1940  return ERROR_INVALID_MESSAGE;
1941 
1942  //Check protocol identifier
1943  if(proposal->protocolId != IKE_PROTOCOL_ID_IKE)
1944  return ERROR_INVALID_MESSAGE;
1945 
1946  //Initial IKE SA negotiation?
1947  if(sa->state == IKE_SA_STATE_INIT_RESP)
1948  {
1949  //For an initial IKE SA negotiation, the SPI Size field must be zero
1950  if(proposal->spiSize != 0)
1951  return ERROR_INVALID_MESSAGE;
1952  }
1953  else
1954  {
1955  //During subsequent negotiations, it is equal to the size, in octets,
1956  //of the SPI of the corresponding protocol (8 for IKE)
1957  if(proposal->spiSize != IKE_SPI_SIZE)
1958  return ERROR_INVALID_MESSAGE;
1959 
1960  //A new responder SPI is supplied in the SPI field of the SA payload
1961  //(refer to RFC 7296, section 1.3.2)
1962  osMemcpy(sa->responderSpi, proposal->spi, IKE_SPI_SIZE);
1963  }
1964 
1965  //The accepted cryptographic suite must contain exactly one transform of
1966  //each type included in the proposal (refer to RFC 7296, section 2.7)
1967  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_DH, proposal, n) != 1 ||
1968  ikeGetNumTransforms(IKE_TRANSFORM_TYPE_PRF, proposal, n) != 1 ||
1970  {
1971  return ERROR_INVALID_PROPOSAL;
1972  }
1973 
1974  //Make sure the selected Diffie-Hellman group is acceptable
1975  if(ikeSelectKeTransform(sa->context, proposal, n) != sa->dhGroupNum)
1976  return ERROR_INVALID_PROPOSAL;
1977 
1978  //Get the selected PRF transform
1979  sa->prfAlgoId = ikeSelectPrfTransform(sa->context, proposal, n);
1980  //Get the selected encryption transform
1981  encAlgo = ikeSelectEncTransform(sa->context, proposal, n);
1982 
1983  //Valid encryption transform?
1984  if(encAlgo != NULL)
1985  {
1986  sa->encAlgoId = encAlgo->id;
1987  sa->encKeyLen = encAlgo->keyLen;
1988  }
1989 
1990  //AEAD algorithm?
1991  if(ikeIsAeadEncAlgo(sa->encAlgoId))
1992  {
1993  //When an authenticated encryption algorithm is selected as the encryption
1994  //algorithm for any SA, an integrity algorithm must not be selected for
1995  //that SA (refer to RFC 5282, section 8)
1996  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 0)
1997  return ERROR_INVALID_PROPOSAL;
1998 
1999  //AEAD algorithms combine encryption and integrity into a single operation
2000  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
2001  }
2002  else
2003  {
2004  //Exactly one integrity transform must be included in the proposal
2005  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 1)
2006  return ERROR_INVALID_PROPOSAL;
2007 
2008  //Get the selected integrity transform
2009  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
2010  }
2011 
2012  //The initiator of an exchange must check that the accepted offer is
2013  //consistent with one of its proposals, and if not must terminate the
2014  //exchange (refer to RFC 7296, section 3.3.6)
2015  if(sa->dhGroupNum != IKE_TRANSFORM_ID_DH_GROUP_NONE &&
2016  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
2017  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
2018  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
2019  {
2020  return NO_ERROR;
2021  }
2022  else
2023  {
2024  return ERROR_INVALID_PROPOSAL;
2025  }
2026 }
2027 
2028 
2029 /**
2030  * @brief Check whether the selected proposal is acceptable (AH or ESP protocol)
2031  * @param[in] childSa Pointer to the Child SA
2032  * @param[in] payload Pointer to the Security Association payload
2033  * @return Error code
2034  **/
2035 
2037  const IkeSaPayload *payload)
2038 {
2039  error_t error;
2040 
2041 #if (AH_SUPPORT == ENABLED)
2042  //AH protocol identifier?
2043  if(childSa->protocol == IPSEC_PROTOCOL_AH)
2044  {
2045  error = ahCheckSaProposal(childSa, payload);
2046  }
2047  else
2048 #endif
2049 #if (ESP_SUPPORT == ENABLED)
2050  //ESP protocol identifier?
2051  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
2052  {
2053  error = espCheckSaProposal(childSa, payload);
2054  }
2055  else
2056 #endif
2057  //Unknown protocol identifier?
2058  {
2059  error = ERROR_INVALID_PROTOCOL;
2060  }
2061 
2062  //Return status code
2063  return error;
2064 }
2065 
2066 
2067 /**
2068  * @brief Test if the transform ID identifies an AEAD encryption algorithm
2069  * @param[in] encAlgoId Encryption algorithm identifier
2070  * @return TRUE if AEAD encryption algorithm, else FALSE
2071  **/
2072 
2073 bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
2074 {
2075  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2076  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2077  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2078  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2079  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2080  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2081  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2085  {
2086  return TRUE;
2087  }
2088  else
2089  {
2090  return FALSE;
2091  }
2092 }
2093 
2094 
2095 /**
2096  * @brief Test if the transform ID identifies a variable-length key encryption algorithm
2097  * @param[in] encAlgoId Encryption algorithm identifier
2098  * @return TRUE if variable-length key encryption algorithm, else FALSE
2099  **/
2100 
2102 {
2103  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC ||
2104  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR ||
2105  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2106  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2107  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2108  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2109  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2110  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2111  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC ||
2112  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR ||
2113  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2116  {
2117  return TRUE;
2118  }
2119  else
2120  {
2121  return FALSE;
2122  }
2123 }
2124 
2125 
2126 /**
2127  * @brief Test if the group number identifies a DH key exchange algorithm
2128  * @param[in] groupNum Group number
2129  * @return TRUE if DH key exchange algorithm, else FALSE
2130  **/
2131 
2132 bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
2133 {
2134  //Diffie-Hellman key exchange?
2135  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_MODP_768 ||
2146  {
2147  return TRUE;
2148  }
2149  else
2150  {
2151  return FALSE;
2152  }
2153 }
2154 
2155 
2156 /**
2157  * @brief Test if the group number identifies an ECDH key exchange algorithm
2158  * @param[in] groupNum Group number
2159  * @return TRUE if ECDH key exchange algorithm, else FALSE
2160  **/
2161 
2163 {
2164  //ECDH key exchange?
2165  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_192 ||
2166  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_224 ||
2167  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_256 ||
2168  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_384 ||
2169  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_521 ||
2176  {
2177  return TRUE;
2178  }
2179  else
2180  {
2181  return FALSE;
2182  }
2183 }
2184 
2185 
2186 /**
2187  * @brief Test if the group number identifies an ML-KEM key exchange algorithm
2188  * @param[in] groupNum Group number
2189  * @return TRUE if ML-KEM key exchange algorithm, else FALSE
2190  **/
2191 
2193 {
2194  //ML-KEM key exchange?
2195  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ML_KEM_512 ||
2198  {
2199  return TRUE;
2200  }
2201  else
2202  {
2203  return FALSE;
2204  }
2205 }
2206 
2207 
2208 /**
2209  * @brief Get the elliptic curve that matches the specified group number
2210  * @param[in] groupNum Group number
2211  * @return Elliptic curve parameters
2212  **/
2213 
2214 const EcCurve *ikeGetEcdhCurve(uint16_t groupNum)
2215 {
2216  const EcCurve *curve;
2217 
2218 #if (IKE_ECDH_KE_SUPPORT == ENABLED)
2219 #if (IKE_ECP_192_SUPPORT == ENABLED)
2220  //NIST P-192 elliptic curve?
2221  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_192)
2222  {
2223  curve = SECP192R1_CURVE;
2224  }
2225  else
2226 #endif
2227 #if (IKE_ECP_224_SUPPORT == ENABLED)
2228  //NIST P-224 elliptic curve?
2229  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_224)
2230  {
2231  curve = SECP224R1_CURVE;
2232  }
2233  else
2234 #endif
2235 #if (IKE_ECP_256_SUPPORT == ENABLED)
2236  //NIST P-256 elliptic curve?
2237  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_256)
2238  {
2239  curve = SECP256R1_CURVE;
2240  }
2241  else
2242 #endif
2243 #if (IKE_ECP_384_SUPPORT == ENABLED)
2244  //NIST P-384 elliptic curve?
2245  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_384)
2246  {
2247  curve = SECP384R1_CURVE;
2248  }
2249  else
2250 #endif
2251 #if (IKE_ECP_521_SUPPORT == ENABLED)
2252  //NIST P-521 elliptic curve?
2253  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_521)
2254  {
2255  curve = SECP521R1_CURVE;
2256  }
2257  else
2258 #endif
2259 #if (IKE_BRAINPOOLP224R1_SUPPORT == ENABLED)
2260  //brainpoolP224r1 elliptic curve?
2262  {
2263  curve = BRAINPOOLP224R1_CURVE;
2264  }
2265  else
2266 #endif
2267 #if (IKE_BRAINPOOLP256R1_SUPPORT == ENABLED)
2268  //brainpoolP256r1 elliptic curve?
2270  {
2271  curve = BRAINPOOLP256R1_CURVE;
2272  }
2273  else
2274 #endif
2275 #if (IKE_BRAINPOOLP384R1_SUPPORT == ENABLED)
2276  //brainpoolP384r1 elliptic curve?
2278  {
2279  curve = BRAINPOOLP384R1_CURVE;
2280  }
2281  else
2282 #endif
2283 #if (IKE_BRAINPOOLP512R1_SUPPORT == ENABLED)
2284  //brainpoolP512r1 elliptic curve?
2286  {
2287  curve = BRAINPOOLP512R1_CURVE;
2288  }
2289  else
2290 #endif
2291 #if (IKE_CURVE25519_SUPPORT == ENABLED)
2292  //Curve25519 elliptic curve?
2293  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_CURVE25519)
2294  {
2295  curve = X25519_CURVE;
2296  }
2297  else
2298 #endif
2299 #if (IKE_CURVE448_SUPPORT == ENABLED)
2300  //Curve448 elliptic curve?
2301  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_CURVE448)
2302  {
2303  curve = X448_CURVE;
2304  }
2305  else
2306 #endif
2307 #endif
2308  //Unknown elliptic curve?
2309  {
2310  curve = NULL;
2311  }
2312 
2313  //Return the elliptic curve parameters, if any
2314  return curve;
2315 }
2316 
2317 
2318 /**
2319  * @brief Get the default Diffie-Hellman group number
2320  * @return Default Diffie-Hellman group number
2321  **/
2322 
2324 {
2325  return ikeSupportedKeAlgos[0];
2326 }
2327 
2328 
2329 /**
2330  * @brief Check whether a given Diffie-Hellman group is supported
2331  * @param[in] groupNum Diffie-Hellman group number
2332  * @return TRUE is the Diffie-Hellman group is supported, else FALSE
2333  **/
2334 
2335 bool_t ikeIsDhGroupSupported(uint16_t groupNum)
2336 {
2337  uint_t i;
2338  bool_t acceptable;
2339 
2340  //Initialize flag
2341  acceptable = FALSE;
2342 
2343  //Loop through the list of Diffie-Hellman groups supported by the entity
2344  for(i = 0; i < arraysize(ikeSupportedKeAlgos); i++)
2345  {
2346  //Compare Diffie-Hellman groups
2347  if(ikeSupportedKeAlgos[i] == groupNum)
2348  {
2349  acceptable = TRUE;
2350  break;
2351  }
2352  }
2353 
2354  //Return TRUE is the Diffie-Hellman group is supported
2355  return acceptable;
2356 }
2357 
2358 
2359 /**
2360  * @brief Check whether a given signature hash algorithm is supported
2361  * @param[in] hashAlgoId Signature hash algorithm identifier
2362  * @return TRUE is the signature hash algorithm is supported, else FALSE
2363  **/
2364 
2365 bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
2366 {
2367  bool_t acceptable;
2368 
2369 #if (IKE_SHA1_SUPPORT == ENABLED)
2370  //SHA-1 hash algorithm identifier?
2371  if(hashAlgoId == IKE_HASH_ALGO_SHA1)
2372  {
2373  acceptable = TRUE;
2374  }
2375  else
2376 #endif
2377 #if (IKE_SHA256_SUPPORT == ENABLED)
2378  //SHA-256 hash algorithm identifier?
2379  if(hashAlgoId == IKE_HASH_ALGO_SHA256)
2380  {
2381  acceptable = TRUE;
2382  }
2383  else
2384 #endif
2385 #if (IKE_SHA384_SUPPORT == ENABLED)
2386  //SHA-384 hash algorithm identifier?
2387  if(hashAlgoId == IKE_HASH_ALGO_SHA384)
2388  {
2389  acceptable = TRUE;
2390  }
2391  else
2392 #endif
2393 #if (IKE_SHA512_SUPPORT == ENABLED)
2394  //SHA-512 hash algorithm identifier?
2395  if(hashAlgoId == IKE_HASH_ALGO_SHA512)
2396  {
2397  acceptable = TRUE;
2398  }
2399  else
2400 #endif
2401 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED || IKE_ED448_SIGN_SUPPORT == ENABLED)
2402  //"Identity" hash algorithm identifier?
2403  if(hashAlgoId == IKE_HASH_ALGO_IDENTITY)
2404  {
2405  acceptable = TRUE;
2406  }
2407  else
2408 #endif
2409  //Unknown hash algorithm identifier?
2410  {
2411  acceptable = FALSE;
2412  }
2413 
2414  //Return TRUE is the signature hash is supported
2415  return acceptable;
2416 }
2417 
2418 #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:928
@ IKE_TRANSFORM_ID_AUTH_AES_CMAC_96
Definition: ike.h:981
AH algorithm negotiation.
@ IKE_TRANSFORM_ID_DH_GROUP_CURVE448
curve448
Definition: ike.h:1019
#define htons(value)
Definition: cpu_endian.h:413
error_t ikeSelectEncAlgo(IkeSaEntry *sa, uint16_t encAlgoId, size_t encKeyLen)
Select the relevant encryption algorithm.
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:986
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_1024
1024-bit MODP Group
Definition: ike.h:999
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_192
192-bit Random ECP Group
Definition: ike.h:1012
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96
Definition: ike.h:975
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:61
@ IKE_TRANSFORM_ID_PRF_AES128_CMAC
Definition: ike.h:962
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_16
Definition: ike.h:927
#define SHA1_HASH_ALGO
Definition: sha1.h:49
@ IKE_TRANSFORM_ID_ENCR_AES_CTR
Definition: ike.h:924
@ IKE_TRANSFORM_ID_DH_GROUP_NONE
None.
Definition: ike.h:997
#define SECP521R1_CURVE
Definition: ec_curves.h:53
@ CIPHER_MODE_CBC
Definition: crypto.h:1008
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:192
@ IKE_HASH_ALGO_SHA256
Definition: ike.h:1331
#define SHA512_HASH_ALGO
Definition: sha512.h:49
@ IKE_HASH_ALGO_SHA1
Definition: ike.h:1330
#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:932
uint8_t p
Definition: ndp.h:300
@ CIPHER_MODE_GCM
Definition: crypto.h:1013
@ IKE_TRANSFORM_ID_ENCR_IDEA
Definition: ike.h:917
@ IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96
Definition: ike.h:974
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_4096
4096-bit MODP Group
Definition: ike.h:1003
Encryption algorithm.
@ IKE_LAST_SUBSTRUC_MORE_TRANSFORMS
More transform substructures.
Definition: ike.h:876
#define TRUE
Definition: os_port.h:50
#define SECP256R1_CURVE
Definition: ec_curves.h:51
Collection of AEAD algorithms.
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048
2048-bit MODP Group
Definition: ike.h:1001
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_DH_GROUP_MODP_8192
8192-bit MODP Group
Definition: ike.h:1005
@ IKE_TRANSFORM_TYPE_DH
Diffie-Hellman Group.
Definition: ike.h:901
uint8_t numTransforms
Definition: ike.h:1434
ESP algorithm negotiation.
#define IDEA_CIPHER_ALGO
Definition: idea.h:40
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8
Definition: ike.h:934
@ IKE_LAST_SUBSTRUC_LAST
Last proposal/transform substructure.
Definition: ike.h:874
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:936
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
bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
Check whether a given signature hash algorithm is supported.
IkeTransform
Definition: ike.h:1452
@ IKE_TRANSFORM_ID_DH_GROUP_CURVE25519
curve25519
Definition: ike.h:1018
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP224R1
224-bit Brainpool ECP Group
Definition: ike.h:1014
uint16_t ikeSelectTransform(IkeTransformType transformType, const uint16_t *algoList, uint_t algoListLen, const IkeProposal *proposal, size_t proposalLen)
Transform negotiation.
@ CIPHER_MODE_CTR
Definition: crypto.h:1011
@ IKE_TRANSFORM_ID_ENCR_CHACHA20_POLY1305
Definition: ike.h:937
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:1046
@ IKE_TRANSFORM_ID_AUTH_AES_XCBC_96
Definition: ike.h:978
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384
Definition: ike.h:960
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:193
#define IKE_TRANSFORM_ID_INVALID
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_224
224-bit Random ECP Group
Definition: ike.h:1013
#define AES_BLOCK_SIZE
Definition: aes.h:43
@ IKE_TRANSFORM_ID_ENCR_AES_CBC
Definition: ike.h:923
#define BRAINPOOLP512R1_CURVE
Definition: ec_curves.h:66
@ IKE_TRANSFORM_ATTR_TYPE_KEY_LEN
Key Length (in bits)
Definition: ike.h:1056
#define IkeContext
Definition: ike.h:796
#define BRAINPOOLP384R1_CURVE
Definition: ec_curves.h:64
#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.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_INVALID_PROPOSAL
Definition: error.h:301
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
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_768
768-bit MODP Group
Definition: ike.h:998
bool_t ikeIsDhGroupSupported(uint16_t groupNum)
Check whether a given Diffie-Hellman group is supported.
@ ERROR_UNSUPPORTED_ALGO
Definition: error.h:126
uint8_t spiSize
Definition: ike.h:1433
@ IKE_HASH_ALGO_SHA512
Definition: ike.h:1333
#define IKE_SPI_SIZE
Definition: ike.h:790
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:955
bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies a DH key exchange algorithm.
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP512R1
512-bit Brainpool ECP Group
Definition: ike.h:1017
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA1
Definition: ike.h:956
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_12
Definition: ike.h:929
#define CAMELLIA_CIPHER_ALGO
Definition: camellia.h:40
IkeTransformAttr
Definition: ike.h:1464
uint8_t transformType
Definition: ike.h:1448
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_ID_DH_GROUP_MODP_1536
1536-bit MODP Group
Definition: ike.h:1000
@ IKE_TRANSFORM_TYPE_ENCR
Encryption Algorithm.
Definition: ike.h:898
uint8_t length
Definition: tcp.h:375
@ IKE_TRANSFORM_ID_PRF_AES128_XCBC
Definition: ike.h:958
@ IKE_TRANSFORM_ID_DH_GROUP_ML_KEM_768
ML-KEM-768.
Definition: ike.h:1023
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048_224
2048-bit MODP Group with 224-bit Prime Order Subgroup
Definition: ike.h:1010
@ 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:897
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_384
384-bit Random ECP Group
Definition: ike.h:1007
#define MD5_DIGEST_SIZE
Definition: md5.h:45
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256
Definition: ike.h:959
#define TIGER_HASH_ALGO
Definition: tiger.h:44
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_256_128
Definition: ike.h:985
@ IKE_TRANSFORM_ID_ENCR_DES
Definition: ike.h:914
Collection of hash algorithms.
IKEv2 (Internet Key Exchange Protocol)
#define ntohs(value)
Definition: cpu_endian.h:421
#define SHA384_HASH_ALGO
Definition: sha384.h:45
uint16_t ikeSelectDefaultDhGroup(void)
Get the default Diffie-Hellman group number.
IkeProposal
Definition: ike.h:1436
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
@ CIPHER_MODE_CCM
Definition: crypto.h:1012
#define IkeSaEntry
Definition: ike.h:800
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_1024_160
1024-bit MODP Group with 160-bit Prime Order Subgroup
Definition: ike.h:1009
@ IKE_TRANSFORM_ID_ENCR_3DES
Definition: ike.h:915
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_16
Definition: ike.h:930
#define HTONS(value)
Definition: cpu_endian.h:410
uint8_t n
@ IKE_TRANSFORM_ID_PRF_HMAC_TIGER
Definition: ike.h:957
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_3072
3072-bit MODP Group
Definition: ike.h:1002
@ IKE_TRANSFORM_ID_DH_GROUP_ML_KEM_1024
ML-KEM-1024.
Definition: ike.h:1024
uint8_t payload[]
Definition: ipv6.h:286
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:926
@ IKE_TRANSFORM_TYPE_PRF
Pseudorandom Function.
Definition: ike.h:899
#define DES_BLOCK_SIZE
Definition: des.h:43
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR
Definition: ike.h:933
uint16_t transformId
Definition: ike.h:1450
@ IKE_PROTOCOL_ID_IKE
IKE protocol.
Definition: ike.h:886
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1288
#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.
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048_256
2048-bit MODP Group with 256-bit Prime Order Subgroup
Definition: ike.h:1011
#define EcCurve
Definition: ec.h:346
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_256
256-bit Random ECP Group
Definition: ike.h:1006
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1015
error_t ahCheckSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable.
#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:987
@ IKE_TRANSFORM_ID_DH_GROUP_ML_KEM_512
ML-KEM-512.
Definition: ike.h:1022
unsigned int uint_t
Definition: compiler_port.h:57
@ IKE_TRANSFORM_ID_AUTH_NONE
Definition: ike.h:973
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP384R1
384-bit Brainpool ECP Group
Definition: ike.h:1016
uint16_t id
error_t ikeCheckChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (AH or ESP protocol)
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_521
521-bit Random ECP Group
Definition: ike.h:1008
#define IkeChildSaEntry
Definition: ike.h:804
@ IKE_HASH_ALGO_SHA384
Definition: ike.h:1332
@ IKE_HASH_ALGO_IDENTITY
Definition: ike.h:1334
#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_DH_GROUP_BRAINPOOLP256R1
256-bit Brainpool ECP Group
Definition: ike.h:1015
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512
Definition: ike.h:961
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_6144
6144-bit MODP Group
Definition: ike.h:1004
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
IkeSaPayload
Definition: ike.h:1419
#define arraysize(a)
Definition: os_port.h:71
#define X25519_CURVE
Definition: ec_curves.h:70
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12
Definition: ike.h:935
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_8
Definition: ike.h:925
@ IKE_TRANSFORM_TYPE_INTEG
Integrity Algorithm.
Definition: ike.h:900