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-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
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_HMAC_AUTH_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
948  //HMAC-MD5-96 authentication algorithm?
949  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96)
950  {
951  sa->authHashAlgo = MD5_HASH_ALGO;
952  sa->authCipherAlgo = NULL;
953  sa->authKeyLen = MD5_DIGEST_SIZE;
954  sa->icvLen = 12;
955  }
956  else
957 #endif
958 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
959  //HMAC-SHA1-96 authentication algorithm?
960  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96)
961  {
962  sa->authHashAlgo = SHA1_HASH_ALGO;
963  sa->authCipherAlgo = NULL;
964  sa->authKeyLen = SHA1_DIGEST_SIZE;
965  sa->icvLen = 12;
966  }
967  else
968 #endif
969 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
970  //HMAC-SHA256-128 authentication algorithm?
972  {
973  sa->authHashAlgo = SHA256_HASH_ALGO;
974  sa->authCipherAlgo = NULL;
975  sa->authKeyLen = SHA256_DIGEST_SIZE;
976  sa->icvLen = 16;
977  }
978  else
979 #endif
980 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
981  //HMAC-SHA384-192 authentication algorithm?
983  {
984  sa->authHashAlgo = SHA384_HASH_ALGO;
985  sa->authCipherAlgo = NULL;
986  sa->authKeyLen = SHA384_DIGEST_SIZE;
987  sa->icvLen = 24;
988  }
989  else
990 #endif
991 #if (IKE_HMAC_AUTH_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
992  //HMAC-SHA512-256 authentication algorithm?
994  {
995  sa->authHashAlgo = SHA512_HASH_ALGO;
996  sa->authCipherAlgo = NULL;
997  sa->authKeyLen = SHA512_DIGEST_SIZE;
998  sa->icvLen = 32;
999  }
1000  else
1001 #endif
1002 #if (IKE_CMAC_AUTH_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1003  //AES-CMAC-96 authentication algorithm?
1004  if(authAlgoId == IKE_TRANSFORM_ID_AUTH_AES_CMAC_96)
1005  {
1006  sa->authHashAlgo = NULL;
1007  sa->authCipherAlgo = AES_CIPHER_ALGO;
1008  sa->authKeyLen = 16;
1009  sa->icvLen = 12;
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_HMAC_PRF_SUPPORT == ENABLED && IKE_MD5_SUPPORT == ENABLED)
1050  //HMAC-MD5 PRF algorithm?
1051  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_MD5)
1052  {
1053  sa->prfHashAlgo = MD5_HASH_ALGO;
1054  sa->prfCipherAlgo = NULL;
1055  sa->prfKeyLen = MD5_DIGEST_SIZE;
1056  }
1057  else
1058 #endif
1059 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
1060  //HMAC-SHA1 PRF algorithm?
1061  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA1)
1062  {
1063  sa->prfHashAlgo = SHA1_HASH_ALGO;
1064  sa->prfCipherAlgo = NULL;
1065  sa->prfKeyLen = SHA1_DIGEST_SIZE;
1066  }
1067  else
1068 #endif
1069 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
1070  //HMAC-SHA256 PRF algorithm?
1071  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256)
1072  {
1073  sa->prfHashAlgo = SHA256_HASH_ALGO;
1074  sa->prfCipherAlgo = NULL;
1075  sa->prfKeyLen = SHA256_DIGEST_SIZE;
1076  }
1077  else
1078 #endif
1079 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
1080  //HMAC-SHA384 PRF algorithm?
1081  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384)
1082  {
1083  sa->prfHashAlgo = SHA384_HASH_ALGO;
1084  sa->prfCipherAlgo = NULL;
1085  sa->prfKeyLen = SHA384_DIGEST_SIZE;
1086  }
1087  else
1088 #endif
1089 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
1090  //HMAC-SHA512 PRF algorithm?
1091  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512)
1092  {
1093  sa->prfHashAlgo = SHA512_HASH_ALGO;
1094  sa->prfCipherAlgo = NULL;
1095  sa->prfKeyLen = SHA512_DIGEST_SIZE;
1096  }
1097  else
1098 #endif
1099 #if (IKE_HMAC_PRF_SUPPORT == ENABLED && IKE_TIGER_SUPPORT == ENABLED)
1100  //HMAC-Tiger PRF algorithm?
1101  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_HMAC_TIGER)
1102  {
1103  sa->prfHashAlgo = TIGER_HASH_ALGO;
1104  sa->prfCipherAlgo = NULL;
1105  sa->prfKeyLen = TIGER_DIGEST_SIZE;
1106  }
1107  else
1108 #endif
1109 #if (IKE_CMAC_PRF_SUPPORT == ENABLED && IKE_AES_128_SUPPORT == ENABLED)
1110  //AES-CMAC PRF algorithm?
1111  if(prfAlgoId == IKE_TRANSFORM_ID_PRF_AES128_CMAC)
1112  {
1113  sa->prfHashAlgo = NULL;
1114  sa->prfCipherAlgo = AES_CIPHER_ALGO;
1115  sa->prfKeyLen = 16;
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 
1803  //AEAD algorithm?
1804  if(ikeIsAeadEncAlgo(sa->encAlgoId))
1805  {
1806  //When an authenticated encryption algorithm is selected as the
1807  //encryption algorithm for any SA, an integrity algorithm must not
1808  //be selected for that SA (refer to RFC 5282, section 8)
1809  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
1810  }
1811  else
1812  {
1813  //Integrity transform negotiation
1814  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
1815  }
1816 
1817  //Valid proposal?
1818  if(sa->dhGroupNum != IKE_TRANSFORM_ID_DH_GROUP_NONE &&
1819  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
1820  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
1821  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
1822  {
1823  //A new initiator SPI is supplied in the SPI field of the SA
1824  //payload (refer to RFC 7296, section 1.3.2)
1825  if(spiSize != 0)
1826  {
1827  osMemcpy(sa->initiatorSpi, proposal->spi, IKE_SPI_SIZE);
1828  }
1829 
1830  //Successful negotiation
1831  error = NO_ERROR;
1832  break;
1833  }
1834  }
1835 
1836  //Jump to the next proposal
1837  p += n;
1838  length -= n;
1839  }
1840 
1841  //Return status code
1842  return error;
1843 }
1844 
1845 
1846 /**
1847  * @brief Select a single proposal (AH or ESP protocol)
1848  * @param[in] childSa Pointer to the Child SA
1849  * @param[in] payload Pointer to the Security Association payload
1850  * @return Error code
1851  **/
1852 
1853 
1855  const IkeSaPayload *payload)
1856 {
1857  error_t error;
1858 
1859 #if (AH_SUPPORT == ENABLED)
1860  //AH protocol identifier?
1861  if(childSa->protocol == IPSEC_PROTOCOL_AH)
1862  {
1863  error = ahSelectSaProposal(childSa, payload);
1864  }
1865  else
1866 #endif
1867 #if (ESP_SUPPORT == ENABLED)
1868  //ESP protocol identifier?
1869  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
1870  {
1871  error = espSelectSaProposal(childSa, payload);
1872  }
1873  else
1874 #endif
1875  //Unknown protocol identifier?
1876  {
1877  error = ERROR_INVALID_PROTOCOL;
1878  }
1879 
1880  //Return status code
1881  return error;
1882 }
1883 
1884 
1885 /**
1886  * @brief Check whether the selected proposal is acceptable (IKE protocol)
1887  * @param[in] sa Pointer to the IKE SA
1888  * @param[in] payload Pointer to the Security Association payload
1889  * @return Error code
1890  **/
1891 
1893 {
1894  size_t n;
1895  size_t length;
1896  const uint8_t *p;
1897  const IkeProposal *proposal;
1898  const IkeEncAlgo *encAlgo;
1899 
1900  //Clear the set of parameters
1901  sa->prfAlgoId = IKE_TRANSFORM_ID_INVALID;
1902  sa->encAlgoId = IKE_TRANSFORM_ID_INVALID;
1903  sa->encKeyLen = 0;
1904  sa->authAlgoId = IKE_TRANSFORM_ID_INVALID;
1905 
1906  //Retrieve the length of the SA payload
1907  length = ntohs(payload->header.payloadLength);
1908 
1909  //Malformed payload?
1910  if(length < sizeof(IkeSaPayload))
1911  return ERROR_INVALID_MESSAGE;
1912 
1913  //Point to the first byte of the Proposals field
1914  p = payload->proposals;
1915  //Determine the length of the Proposals field
1916  length -= sizeof(IkeSaPayload);
1917 
1918  //Malformed payload?
1919  if(length < sizeof(IkeProposal))
1920  return ERROR_INVALID_MESSAGE;
1921 
1922  //Point to the Proposal substructure
1923  proposal = (IkeProposal *) p;
1924 
1925  //The Proposal Length field indicates the length of this proposal,
1926  //including all transforms and attributes that follow
1927  n = ntohs(proposal->proposalLength);
1928 
1929  //The responder must accept a single proposal (refer to RFC 7296,
1930  //section 2.7)
1931  if(n != length)
1932  return ERROR_INVALID_MESSAGE;
1933 
1934  //Check protocol identifier
1935  if(proposal->protocolId != IKE_PROTOCOL_ID_IKE)
1936  return ERROR_INVALID_MESSAGE;
1937 
1938  //Initial IKE SA negotiation?
1939  if(sa->state == IKE_SA_STATE_INIT_RESP)
1940  {
1941  //For an initial IKE SA negotiation, the SPI Size field must be zero
1942  if(proposal->spiSize != 0)
1943  return ERROR_INVALID_MESSAGE;
1944  }
1945  else
1946  {
1947  //During subsequent negotiations, it is equal to the size, in octets,
1948  //of the SPI of the corresponding protocol (8 for IKE)
1949  if(proposal->spiSize != IKE_SPI_SIZE)
1950  return ERROR_INVALID_MESSAGE;
1951 
1952  //A new responder SPI is supplied in the SPI field of the SA payload
1953  //(refer to RFC 7296, section 1.3.2)
1954  osMemcpy(sa->responderSpi, proposal->spi, IKE_SPI_SIZE);
1955  }
1956 
1957  //The accepted cryptographic suite must contain exactly one transform of
1958  //each type included in the proposal (refer to RFC 7296, section 2.7)
1959  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_DH, proposal, n) != 1 ||
1960  ikeGetNumTransforms(IKE_TRANSFORM_TYPE_PRF, proposal, n) != 1 ||
1962  {
1963  return ERROR_INVALID_PROPOSAL;
1964  }
1965 
1966  //Make sure the selected Diffie-Hellman group is acceptable
1967  if(ikeSelectKeTransform(sa->context, proposal, n) != sa->dhGroupNum)
1968  return ERROR_INVALID_PROPOSAL;
1969 
1970  //Get the selected PRF transform
1971  sa->prfAlgoId = ikeSelectPrfTransform(sa->context, proposal, n);
1972  //Get the selected encryption transform
1973  encAlgo = ikeSelectEncTransform(sa->context, proposal, n);
1974 
1975  //Valid encryption transform?
1976  if(encAlgo != NULL)
1977  {
1978  sa->encAlgoId = encAlgo->id;
1979  sa->encKeyLen = encAlgo->keyLen;
1980  }
1981 
1982  //AEAD algorithm?
1983  if(ikeIsAeadEncAlgo(sa->encAlgoId))
1984  {
1985  //When an authenticated encryption algorithm is selected as the encryption
1986  //algorithm for any SA, an integrity algorithm must not be selected for
1987  //that SA (refer to RFC 5282, section 8)
1988  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 0)
1989  return ERROR_INVALID_PROPOSAL;
1990 
1991  //AEAD algorithms combine encryption and integrity into a single operation
1992  sa->authAlgoId = IKE_TRANSFORM_ID_AUTH_NONE;
1993  }
1994  else
1995  {
1996  //Exactly one integrity transform must be included in the proposal
1997  if(ikeGetNumTransforms(IKE_TRANSFORM_TYPE_INTEG, proposal, n) != 1)
1998  return ERROR_INVALID_PROPOSAL;
1999 
2000  //Get the selected integrity transform
2001  sa->authAlgoId = ikeSelectAuthTransform(sa->context, proposal, n);
2002  }
2003 
2004  //The initiator of an exchange must check that the accepted offer is
2005  //consistent with one of its proposals, and if not must terminate the
2006  //exchange (refer to RFC 7296, section 3.3.6)
2007  if(sa->dhGroupNum != IKE_TRANSFORM_ID_DH_GROUP_NONE &&
2008  sa->prfAlgoId != IKE_TRANSFORM_ID_INVALID &&
2009  sa->encAlgoId != IKE_TRANSFORM_ID_INVALID &&
2010  sa->authAlgoId != IKE_TRANSFORM_ID_INVALID)
2011  {
2012  return NO_ERROR;
2013  }
2014  else
2015  {
2016  return ERROR_INVALID_PROPOSAL;
2017  }
2018 }
2019 
2020 
2021 /**
2022  * @brief Check whether the selected proposal is acceptable (AH or ESP protocol)
2023  * @param[in] childSa Pointer to the Child SA
2024  * @param[in] payload Pointer to the Security Association payload
2025  * @return Error code
2026  **/
2027 
2029  const IkeSaPayload *payload)
2030 {
2031  error_t error;
2032 
2033 #if (AH_SUPPORT == ENABLED)
2034  //AH protocol identifier?
2035  if(childSa->protocol == IPSEC_PROTOCOL_AH)
2036  {
2037  error = ahCheckSaProposal(childSa, payload);
2038  }
2039  else
2040 #endif
2041 #if (ESP_SUPPORT == ENABLED)
2042  //ESP protocol identifier?
2043  if(childSa->protocol == IPSEC_PROTOCOL_ESP)
2044  {
2045  error = espCheckSaProposal(childSa, payload);
2046  }
2047  else
2048 #endif
2049  //Unknown protocol identifier?
2050  {
2051  error = ERROR_INVALID_PROTOCOL;
2052  }
2053 
2054  //Return status code
2055  return error;
2056 }
2057 
2058 
2059 /**
2060  * @brief Test if the transform ID identifies an AEAD encryption algorithm
2061  * @param[in] encAlgoId Encryption algorithm identifier
2062  * @return TRUE if AEAD encryption algorithm, else FALSE
2063  **/
2064 
2065 bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
2066 {
2067  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2068  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2069  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2070  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2071  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2072  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2073  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2077  {
2078  return TRUE;
2079  }
2080  else
2081  {
2082  return FALSE;
2083  }
2084 }
2085 
2086 
2087 /**
2088  * @brief Test if the transform ID identifies a variable-length key encryption algorithm
2089  * @param[in] encAlgoId Encryption algorithm identifier
2090  * @return TRUE if variable-length key encryption algorithm, else FALSE
2091  **/
2092 
2094 {
2095  if(encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CBC ||
2096  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CTR ||
2097  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_8 ||
2098  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_12 ||
2099  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_CCM_16 ||
2100  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_8 ||
2101  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_12 ||
2102  encAlgoId == IKE_TRANSFORM_ID_ENCR_AES_GCM_16 ||
2103  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC ||
2104  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR ||
2105  encAlgoId == IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8 ||
2108  {
2109  return TRUE;
2110  }
2111  else
2112  {
2113  return FALSE;
2114  }
2115 }
2116 
2117 
2118 /**
2119  * @brief Test if the group number identifies a DH key exchange algorithm
2120  * @param[in] groupNum Group number
2121  * @return TRUE if DH key exchange algorithm, else FALSE
2122  **/
2123 
2124 bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
2125 {
2126  //Diffie-Hellman key exchange?
2127  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_MODP_768 ||
2138  {
2139  return TRUE;
2140  }
2141  else
2142  {
2143  return FALSE;
2144  }
2145 }
2146 
2147 
2148 /**
2149  * @brief Test if the group number identifies an ECDH key exchange algorithm
2150  * @param[in] groupNum Group number
2151  * @return TRUE if ECDH key exchange algorithm, else FALSE
2152  **/
2153 
2155 {
2156  //ECDH key exchange?
2157  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_192 ||
2158  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_224 ||
2159  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_256 ||
2160  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_384 ||
2161  groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_521 ||
2168  {
2169  return TRUE;
2170  }
2171  else
2172  {
2173  return FALSE;
2174  }
2175 }
2176 
2177 
2178 /**
2179  * @brief Get the elliptic curve that matches the specified group number
2180  * @param[in] groupNum Group number
2181  * @return Elliptic curve domain parameters
2182  **/
2183 
2184 const EcCurveInfo *ikeGetEcdhCurveInfo(uint16_t groupNum)
2185 {
2186  const EcCurveInfo *curveInfo;
2187 
2188 #if (IKE_ECDH_KE_SUPPORT == ENABLED)
2189 #if (IKE_ECP_192_SUPPORT == ENABLED)
2190  //NIST P-192 elliptic curve?
2191  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_192)
2192  {
2193  curveInfo = SECP192R1_CURVE;
2194  }
2195  else
2196 #endif
2197 #if (IKE_ECP_224_SUPPORT == ENABLED)
2198  //NIST P-224 elliptic curve?
2199  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_224)
2200  {
2201  curveInfo = SECP224R1_CURVE;
2202  }
2203  else
2204 #endif
2205 #if (IKE_ECP_256_SUPPORT == ENABLED)
2206  //NIST P-256 elliptic curve?
2207  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_256)
2208  {
2209  curveInfo = SECP256R1_CURVE;
2210  }
2211  else
2212 #endif
2213 #if (IKE_ECP_384_SUPPORT == ENABLED)
2214  //NIST P-384 elliptic curve?
2215  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_384)
2216  {
2217  curveInfo = SECP384R1_CURVE;
2218  }
2219  else
2220 #endif
2221 #if (IKE_ECP_521_SUPPORT == ENABLED)
2222  //NIST P-521 elliptic curve?
2223  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_ECP_521)
2224  {
2225  curveInfo = SECP521R1_CURVE;
2226  }
2227  else
2228 #endif
2229 #if (IKE_BRAINPOOLP224R1_SUPPORT == ENABLED)
2230  //brainpoolP224r1 elliptic curve?
2232  {
2233  curveInfo = BRAINPOOLP224R1_CURVE;
2234  }
2235  else
2236 #endif
2237 #if (IKE_BRAINPOOLP256R1_SUPPORT == ENABLED)
2238  //brainpoolP256r1 elliptic curve?
2240  {
2241  curveInfo = BRAINPOOLP256R1_CURVE;
2242  }
2243  else
2244 #endif
2245 #if (IKE_BRAINPOOLP384R1_SUPPORT == ENABLED)
2246  //brainpoolP384r1 elliptic curve?
2248  {
2249  curveInfo = BRAINPOOLP384R1_CURVE;
2250  }
2251  else
2252 #endif
2253 #if (IKE_BRAINPOOLP512R1_SUPPORT == ENABLED)
2254  //brainpoolP512r1 elliptic curve?
2256  {
2257  curveInfo = BRAINPOOLP512R1_CURVE;
2258  }
2259  else
2260 #endif
2261 #if (IKE_CURVE25519_SUPPORT == ENABLED)
2262  //Curve25519 elliptic curve?
2263  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_CURVE25519)
2264  {
2265  curveInfo = X25519_CURVE;
2266  }
2267  else
2268 #endif
2269 #if (IKE_CURVE448_SUPPORT == ENABLED)
2270  //Curve448 elliptic curve?
2271  if(groupNum == IKE_TRANSFORM_ID_DH_GROUP_CURVE448)
2272  {
2273  curveInfo = X448_CURVE;
2274  }
2275  else
2276 #endif
2277 #endif
2278  //Unknown elliptic curve?
2279  {
2280  curveInfo = NULL;
2281  }
2282 
2283  //Return the elliptic curve domain parameters, if any
2284  return curveInfo;
2285 }
2286 
2287 
2288 /**
2289  * @brief Load the EC parameters that match the specified group number
2290  * @param[in,out] params Elliptic curve domain parameters
2291  * @param[in] groupNum Group number
2292  * @return Error code
2293  **/
2294 
2295 error_t ikeLoadEcdhParams(EcDomainParameters *params, uint16_t groupNum)
2296 {
2297  error_t error;
2298  const EcCurveInfo *curveInfo;
2299 
2300  //Get the elliptic curve that matches the specified group number
2301  curveInfo = ikeGetEcdhCurveInfo(groupNum);
2302 
2303  //Make sure the group number is acceptable
2304  if(curveInfo != NULL)
2305  {
2306  //Load EC domain parameters
2307  error = ecLoadDomainParameters(params, curveInfo);
2308  }
2309  else
2310  {
2311  //Report an error
2312  error = ERROR_UNSUPPORTED_TYPE;
2313  }
2314 
2315  //Return status code
2316  return error;
2317 }
2318 
2319 
2320 /**
2321  * @brief Get the default Diffie-Hellman group number
2322  * @return Default Diffie-Hellman group number
2323  **/
2324 
2326 {
2327  return ikeSupportedKeAlgos[0];
2328 }
2329 
2330 
2331 /**
2332  * @brief Check whether a given Diffie-Hellman group is supported
2333  * @param[in] groupNum Diffie-Hellman group number
2334  * @return TRUE is the Diffie-Hellman group is supported, else FALSE
2335  **/
2336 
2337 bool_t ikeIsDhGroupSupported(uint16_t groupNum)
2338 {
2339  uint_t i;
2340  bool_t acceptable;
2341 
2342  //Initialize flag
2343  acceptable = FALSE;
2344 
2345  //Loop through the list of Diffie-Hellman groups supported by the entity
2346  for(i = 0; i < arraysize(ikeSupportedKeAlgos); i++)
2347  {
2348  //Compare Diffie-Hellman groups
2349  if(ikeSupportedKeAlgos[i] == groupNum)
2350  {
2351  acceptable = TRUE;
2352  break;
2353  }
2354  }
2355 
2356  //Return TRUE is the Diffie-Hellman group is supported
2357  return acceptable;
2358 }
2359 
2360 
2361 /**
2362  * @brief Check whether a given signature hash algorithm is supported
2363  * @param[in] hashAlgoId Signature hash algorithm identifier
2364  * @return TRUE is the signature hash algorithm is supported, else FALSE
2365  **/
2366 
2367 bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
2368 {
2369  bool_t acceptable;
2370 
2371 #if (IKE_SHA1_SUPPORT == ENABLED)
2372  //SHA-1 hash algorithm identifier?
2373  if(hashAlgoId == IKE_HASH_ALGO_SHA1)
2374  {
2375  acceptable = TRUE;
2376  }
2377  else
2378 #endif
2379 #if (IKE_SHA256_SUPPORT == ENABLED)
2380  //SHA-256 hash algorithm identifier?
2381  if(hashAlgoId == IKE_HASH_ALGO_SHA256)
2382  {
2383  acceptable = TRUE;
2384  }
2385  else
2386 #endif
2387 #if (IKE_SHA384_SUPPORT == ENABLED)
2388  //SHA-384 hash algorithm identifier?
2389  if(hashAlgoId == IKE_HASH_ALGO_SHA384)
2390  {
2391  acceptable = TRUE;
2392  }
2393  else
2394 #endif
2395 #if (IKE_SHA512_SUPPORT == ENABLED)
2396  //SHA-512 hash algorithm identifier?
2397  if(hashAlgoId == IKE_HASH_ALGO_SHA512)
2398  {
2399  acceptable = TRUE;
2400  }
2401  else
2402 #endif
2403 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED || IKE_ED448_SIGN_SUPPORT == ENABLED)
2404  //"Identity" hash algorithm identifier?
2405  if(hashAlgoId == IKE_HASH_ALGO_IDENTITY)
2406  {
2407  acceptable = TRUE;
2408  }
2409  else
2410 #endif
2411  //Unknown hash algorithm identifier?
2412  {
2413  acceptable = FALSE;
2414  }
2415 
2416  //Return TRUE is the signature hash is supported
2417  return acceptable;
2418 }
2419 
2420 #endif
#define AES_CIPHER_ALGO
Definition: aes.h:45
#define AES_BLOCK_SIZE
Definition: aes.h:43
error_t ahCheckSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable.
error_t ahSelectSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal.
AH algorithm negotiation.
#define CAMELLIA_BLOCK_SIZE
Definition: camellia.h:38
#define CAMELLIA_CIPHER_ALGO
Definition: camellia.h:40
Collection of AEAD algorithms.
Block cipher modes of operation.
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
#define HTONS(value)
Definition: cpu_endian.h:410
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:951
@ CIPHER_MODE_CCM
Definition: crypto.h:949
@ CIPHER_MODE_CBC
Definition: crypto.h:945
@ CIPHER_MODE_CTR
Definition: crypto.h:948
@ CIPHER_MODE_GCM
Definition: crypto.h:950
Debugging facilities.
#define DES3_CIPHER_ALGO
Definition: des3.h:46
#define DES3_BLOCK_SIZE
Definition: des3.h:44
#define DES_BLOCK_SIZE
Definition: des.h:43
#define DES_CIPHER_ALGO
Definition: des.h:45
uint8_t n
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
#define BRAINPOOLP256R1_CURVE
Definition: ec_curves.h:246
#define X448_CURVE
Definition: ec_curves.h:252
#define X25519_CURVE
Definition: ec_curves.h:251
#define SECP521R1_CURVE
Definition: ec_curves.h:242
#define BRAINPOOLP384R1_CURVE
Definition: ec_curves.h:248
#define SECP256R1_CURVE
Definition: ec_curves.h:240
#define SECP224R1_CURVE
Definition: ec_curves.h:238
#define SECP384R1_CURVE
Definition: ec_curves.h:241
#define BRAINPOOLP224R1_CURVE
Definition: ec_curves.h:245
#define SECP192R1_CURVE
Definition: ec_curves.h:236
#define BRAINPOOLP512R1_CURVE
Definition: ec_curves.h:249
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_TYPE
Definition: error.h:125
@ ERROR_INVALID_PROTOCOL
Definition: error.h:101
@ ERROR_INVALID_MESSAGE
Definition: error.h:105
@ ERROR_INVALID_PROPOSAL
Definition: error.h:299
@ ERROR_UNSUPPORTED_ALGO
Definition: error.h:126
@ NO_ERROR
Success.
Definition: error.h:44
error_t espCheckSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable.
error_t espSelectSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal.
ESP algorithm negotiation.
Collection of hash algorithms.
#define IDEA_BLOCK_SIZE
Definition: idea.h:38
#define IDEA_CIPHER_ALGO
Definition: idea.h:40
IKEv2 (Internet Key Exchange Protocol)
uint16_t transformId
Definition: ike.h:1326
IkeProposal
Definition: ike.h:1312
@ IKE_LAST_SUBSTRUC_LAST
Last proposal/transform substructure.
Definition: ike.h:756
@ IKE_LAST_SUBSTRUC_MORE_TRANSFORMS
More transform substructures.
Definition: ike.h:758
IkeSaPayload
Definition: ike.h:1295
uint8_t numTransforms
Definition: ike.h:1310
#define IkeChildSaEntry
Definition: ike.h:686
@ IKE_TRANSFORM_ID_AUTH_AES_CMAC_96
Definition: ike.h:863
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA1_96
Definition: ike.h:857
@ IKE_TRANSFORM_ID_AUTH_NONE
Definition: ike.h:855
@ IKE_TRANSFORM_ID_AUTH_HMAC_MD5_96
Definition: ike.h:856
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_512_256
Definition: ike.h:869
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_384_192
Definition: ike.h:868
@ IKE_TRANSFORM_ID_AUTH_HMAC_SHA2_256_128
Definition: ike.h:867
@ IKE_TRANSFORM_ID_AUTH_AES_XCBC_96
Definition: ike.h:860
#define IkeContext
Definition: ike.h:678
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_3072
3072-bit MODP Group
Definition: ike.h:884
@ IKE_TRANSFORM_ID_DH_GROUP_CURVE25519
Curve25519.
Definition: ike.h:900
@ IKE_TRANSFORM_ID_DH_GROUP_CURVE448
Curve448.
Definition: ike.h:901
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_1536
1536-bit MODP Group
Definition: ike.h:882
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_384
384-bit Random ECP Group
Definition: ike.h:889
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048_224
2048-bit MODP Group with 224-bit Prime Order Subgroup
Definition: ike.h:892
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP384R1
384-bit Brainpool ECP Group
Definition: ike.h:898
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_768
768-bit MODP Group
Definition: ike.h:880
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP224R1
224-bit Brainpool ECP Group
Definition: ike.h:896
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_1024
1024-bit MODP Group
Definition: ike.h:881
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_192
192-bit Random ECP Group
Definition: ike.h:894
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048_256
2048-bit MODP Group with 256-bit Prime Order Subgroup
Definition: ike.h:893
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_8192
8192-bit MODP Group
Definition: ike.h:887
@ IKE_TRANSFORM_ID_DH_GROUP_NONE
None.
Definition: ike.h:879
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_6144
6144-bit MODP Group
Definition: ike.h:886
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_4096
4096-bit MODP Group
Definition: ike.h:885
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_1024_160
1024-bit MODP Group with 160-bit Prime Order Subgroup
Definition: ike.h:891
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP512R1
512-bit Brainpool ECP Group
Definition: ike.h:899
@ IKE_TRANSFORM_ID_DH_GROUP_MODP_2048
2048-bit MODP Group
Definition: ike.h:883
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_256
256-bit Random ECP Group
Definition: ike.h:888
@ IKE_TRANSFORM_ID_DH_GROUP_BRAINPOOLP256R1
256-bit Brainpool ECP Group
Definition: ike.h:897
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_224
224-bit Random ECP Group
Definition: ike.h:895
@ IKE_TRANSFORM_ID_DH_GROUP_ECP_521
521-bit Random ECP Group
Definition: ike.h:890
@ IKE_HASH_ALGO_IDENTITY
Definition: ike.h:1213
@ IKE_HASH_ALGO_SHA512
Definition: ike.h:1212
@ IKE_HASH_ALGO_SHA256
Definition: ike.h:1210
@ IKE_HASH_ALGO_SHA384
Definition: ike.h:1211
@ IKE_HASH_ALGO_SHA1
Definition: ike.h:1209
uint8_t transformType
Definition: ike.h:1324
@ IKE_PROTOCOL_ID_IKE
IKE protocol.
Definition: ike.h:768
@ IKE_SA_STATE_INIT_RESP
Definition: ike.h:1167
uint8_t spiSize
Definition: ike.h:1309
IkeTransformType
Transform types.
Definition: ike.h:779
@ IKE_TRANSFORM_TYPE_INTEG
Integrity Algorithm.
Definition: ike.h:782
@ IKE_TRANSFORM_TYPE_PRF
Pseudorandom Function.
Definition: ike.h:781
@ IKE_TRANSFORM_TYPE_ENCR
Encryption Algorithm.
Definition: ike.h:780
@ IKE_TRANSFORM_TYPE_DH
Diffie-Hellman Group.
Definition: ike.h:783
@ IKE_ATTR_FORMAT_TV
shortened Type/Value format
Definition: ike.h:925
#define IkeSaEntry
Definition: ike.h:682
#define IKE_SPI_SIZE
Definition: ike.h:672
IkeTransformAttr
Definition: ike.h:1340
@ IKE_TRANSFORM_ID_PRF_AES128_CMAC
Definition: ike.h:844
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_256
Definition: ike.h:841
@ IKE_TRANSFORM_ID_PRF_AES128_XCBC
Definition: ike.h:840
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_512
Definition: ike.h:843
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA1
Definition: ike.h:838
@ IKE_TRANSFORM_ID_PRF_HMAC_MD5
Definition: ike.h:837
@ IKE_TRANSFORM_ID_PRF_HMAC_SHA2_384
Definition: ike.h:842
@ IKE_TRANSFORM_ID_PRF_HMAC_TIGER
Definition: ike.h:839
IkeTransform
Definition: ike.h:1328
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_8
Definition: ike.h:807
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_12
Definition: ike.h:817
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_16
Definition: ike.h:812
@ IKE_TRANSFORM_ID_ENCR_DES
Definition: ike.h:796
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_12
Definition: ike.h:808
@ IKE_TRANSFORM_ID_ENCR_AES_CBC
Definition: ike.h:805
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_8
Definition: ike.h:810
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_8
Definition: ike.h:816
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CBC
Definition: ike.h:814
@ IKE_TRANSFORM_ID_ENCR_AES_CTR
Definition: ike.h:806
@ IKE_TRANSFORM_ID_ENCR_AES_GCM_12
Definition: ike.h:811
@ IKE_TRANSFORM_ID_ENCR_AES_CCM_16
Definition: ike.h:809
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CCM_16
Definition: ike.h:818
@ IKE_TRANSFORM_ID_ENCR_CHACHA20_POLY1305
Definition: ike.h:819
@ IKE_TRANSFORM_ID_ENCR_3DES
Definition: ike.h:797
@ IKE_TRANSFORM_ID_ENCR_IDEA
Definition: ike.h:799
@ IKE_TRANSFORM_ID_ENCR_CAMELLIA_CTR
Definition: ike.h:815
@ IKE_TRANSFORM_ATTR_TYPE_KEY_LEN
Key Length (in bits)
Definition: ike.h:935
bool_t ikeIsEcdhKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies an ECDH key exchange algorithm.
uint16_t ikeSelectTransform(IkeTransformType transformType, const uint16_t *algoList, uint_t algoListLen, const IkeProposal *proposal, size_t proposalLen)
Transform negotiation.
uint_t ikeGetNumTransforms(IkeTransformType transformType, const IkeProposal *proposal, size_t proposalLen)
Get the number of transforms that match a given transform type.
const IkeEncAlgo * ikeSelectEncTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Encryption transform negotiation.
error_t ikeAddSupportedKeTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported key exchange transforms to the proposal.
error_t ikeSelectChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Select a single proposal (AH or ESP protocol)
bool_t ikeIsAeadEncAlgo(uint16_t encAlgoId)
Test if the transform ID identifies an AEAD encryption algorithm.
error_t ikeSelectAuthAlgo(IkeSaEntry *sa, uint16_t authAlgoId)
Select the relevant MAC algorithm.
error_t ikeSelectEncAlgo(IkeSaEntry *sa, uint16_t encAlgoId, size_t encKeyLen)
Select the relevant encryption algorithm.
error_t ikeCheckSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (IKE protocol)
error_t ikeAddSupportedEncTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported encryption transforms to the proposal.
bool_t ikeIsDhKeyExchangeAlgo(uint16_t groupNum)
Test if the group number identifies a DH key exchange algorithm.
const EcCurveInfo * ikeGetEcdhCurveInfo(uint16_t groupNum)
Get the elliptic curve that matches the specified group number.
uint16_t ikeSelectKeTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Key exchange transform negotiation.
error_t ikeSelectSaProposal(IkeSaEntry *sa, const IkeSaPayload *payload, size_t spiSize)
Select a single proposal (IKE protocol)
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 ikeCheckChildSaProposal(IkeChildSaEntry *childSa, const IkeSaPayload *payload)
Check whether the selected proposal is acceptable (AH or ESP protocol)
error_t ikeLoadEcdhParams(EcDomainParameters *params, uint16_t groupNum)
Load the EC parameters that match the specified group number.
bool_t ikeIsHashAlgoSupported(uint16_t hashAlgoId)
Check whether a given signature hash algorithm is supported.
error_t ikeAddSupportedPrfTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported PRF transforms to the proposal.
uint16_t ikeSelectDefaultDhGroup(void)
Get the default Diffie-Hellman group number.
error_t ikeAddSupportedAuthTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported integrity transforms to the proposal.
bool_t ikeIsVariableLengthKeyEncAlgo(uint16_t encAlgoId)
Test if the transform ID identifies a variable-length key encryption algorithm.
uint16_t ikeSelectAuthTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
Integrity transform negotiation.
uint16_t ikeSelectPrfTransform(IkeContext *context, const IkeProposal *proposal, size_t proposalLen)
PRF transform negotiation.
error_t ikeAddSupportedTransforms(IkeContext *context, IkeProposal *proposal, uint8_t **lastSubstruc)
Add the supported IKE transforms to the proposal.
error_t ikeSelectPrfAlgo(IkeSaEntry *sa, uint16_t prfAlgoId)
Select the relevant PRF algorithm.
bool_t ikeIsDhGroupSupported(uint16_t groupNum)
Check whether a given Diffie-Hellman group is supported.
IKEv2 algorithm negotiation.
#define IKE_TRANSFORM_ID_INVALID
@ IPSEC_PROTOCOL_ESP
Definition: ipsec.h:193
@ IPSEC_PROTOCOL_AH
Definition: ipsec.h:192
uint8_t payload[]
Definition: ipv6.h:277
#define MD5_DIGEST_SIZE
Definition: md5.h:45
#define MD5_HASH_ALGO
Definition: md5.h:49
uint8_t p
Definition: ndp.h:300
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define arraysize(a)
Definition: os_port.h:71
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define SHA1_HASH_ALGO
Definition: sha1.h:49
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define SHA256_DIGEST_SIZE
Definition: sha256.h:45
#define SHA256_HASH_ALGO
Definition: sha256.h:49
#define SHA384_HASH_ALGO
Definition: sha384.h:45
#define SHA384_DIGEST_SIZE
Definition: sha384.h:41
#define SHA512_HASH_ALGO
Definition: sha512.h:49
#define SHA512_DIGEST_SIZE
Definition: sha512.h:45
Elliptic curve parameters.
Definition: ec_curves.h:295
EC domain parameters.
Definition: ec.h:76
Encryption algorithm.
uint16_t keyLen
uint16_t id
uint8_t length
Definition: tcp.h:368
#define TIGER_DIGEST_SIZE
Definition: tiger.h:40
#define TIGER_HASH_ALGO
Definition: tiger.h:44