ike_sign_misc.c
Go to the documentation of this file.
1 /**
2  * @file ike_sign_misc.c
3  * @brief Helper functions for signature generation and verification
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2022-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneIPSEC Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL IKE_TRACE_LEVEL
33 
34 //Dependencies
35 #include "ike/ike.h"
36 #include "ike/ike_algorithms.h"
37 #include "ike/ike_sign_misc.h"
38 #include "ike/ike_key_material.h"
39 #include "encoding/oid.h"
40 #include "kdf/ike_kdf.h"
41 #include "debug.h"
42 
43 //Check IKEv2 library configuration
44 #if (IKE_SUPPORT == ENABLED && IKE_CERT_AUTH_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief DSA signature formatting
49  * @param[in] signature (R, S) integer pair
50  * @param[out] data Pointer to the buffer where to store the encoded signature
51  * @param[out] length Length of the encoded signature, in bytes
52  * @param[in] format Signature format (raw or ASN.1)
53  * @return Error code
54  **/
55 
56 error_t ikeFormatDsaSignature(const DsaSignature *signature, uint8_t *data,
57  size_t *length, IkeSignFormat format)
58 {
59 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
60  error_t error;
61 
62  //Check signature format
63  if(format == IKE_SIGN_FORMAT_RAW)
64  {
65  //Encode integer R
66  error = mpiExport(&signature->r, data, IKE_SHA1_DIGEST_SIZE,
68 
69  //Check status code
70  if(!error)
71  {
72  //Encode integer S
73  error = mpiExport(&signature->s, data + IKE_SHA1_DIGEST_SIZE,
75  }
76 
77  //Check status code
78  if(!error)
79  {
80  //Return the length of the signature
82  }
83  }
84  else if(format == IKE_SIGN_FORMAT_ASN1)
85  {
86  //Encode the DSA signature using ASN.1
87  error = dsaExportSignature(signature, data, length);
88  }
89  else
90  {
91  //Invalid format
92  error = ERROR_INVALID_TYPE;
93  }
94 
95  //Return status code
96  return error;
97 #else
98  //Not implemented
99  return ERROR_NOT_IMPLEMENTED;
100 #endif
101 }
102 
103 
104 /**
105  * @brief ECDSA signature formatting
106  * @param[in] signature (R, S) integer pair
107  * @param[out] data Pointer to the buffer where to store the encoded signature
108  * @param[out] length Length of the encoded signature, in bytes
109  * @param[in] format Signature format (raw or ASN.1)
110  * @return Error code
111  **/
112 
114  size_t *length, IkeSignFormat format)
115 {
116 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
117  error_t error;
118 
119  //Check signature format
120  if(format == IKE_SIGN_FORMAT_RAW)
121  {
122  //The signature payload shall contain an encoding of the computed
123  //signature consisting of the concatenation of a pair of integers R
124  //and S (refer to RFC 4754, section 7)
125  error = ecdsaExportSignature(signature, data, length,
127  }
128  else if(format == IKE_SIGN_FORMAT_ASN1)
129  {
130  //Encode the ECDSA signature using ASN.1
131  error = ecdsaExportSignature(signature, data, length,
133  }
134  else
135  {
136  //Invalid format
137  error = ERROR_INVALID_TYPE;
138  }
139 
140  //Return status code
141  return error;
142 #else
143  //Not implemented
144  return ERROR_NOT_IMPLEMENTED;
145 #endif
146 }
147 
148 
149 /**
150  * @brief DSA signature parsing
151  * @param[in] data Pointer to the encoded signature
152  * @param[in] length Length of the encoded signature, in bytes
153  * @param[out] signature (R, S) integer pair
154  * @param[in] format Signature format (raw or ASN.1)
155  * @return Error code
156  **/
157 
158 error_t ikeParseDsaSignature(const uint8_t *data, size_t length,
159  DsaSignature *signature, IkeSignFormat format)
160 {
161 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
162  error_t error;
163 
164  //Check signature format
165  if(format == IKE_SIGN_FORMAT_RAW)
166  {
167  //DSS is only defined with SHA-1
168  if(length == (2 * IKE_SHA1_DIGEST_SIZE))
169  {
170  //Import integer R
171  error = mpiImport(&signature->r, data, IKE_SHA1_DIGEST_SIZE,
173 
174  //Check status code
175  if(!error)
176  {
177  //Import integer S
178  error = mpiImport(&signature->s, data + IKE_SHA1_DIGEST_SIZE,
180  }
181  }
182  else
183  {
184  //The length of the signature is not acceptable
185  error = ERROR_INVALID_SIGNATURE;
186  }
187  }
188  else if(format == IKE_SIGN_FORMAT_ASN1)
189  {
190  //Read the ASN.1 encoded signature
191  error = dsaImportSignature(signature, data, length);
192  }
193  else
194  {
195  //Invalid format
196  error = ERROR_INVALID_TYPE;
197  }
198 
199  //Return status code
200  return error;
201 #else
202  //Not implemented
203  return ERROR_NOT_IMPLEMENTED;
204 #endif
205 }
206 
207 
208 /**
209  * @brief ECDSA signature parsing
210  * @param[in] curve Elliptic curve parameters
211  * @param[in] data Pointer to the encoded signature
212  * @param[in] length Length of the encoded signature, in bytes
213  * @param[out] signature (R, S) integer pair
214  * @param[in] format Signature format (raw or ASN.1)
215  * @return Error code
216  **/
217 
218 error_t ikeParseEcdsaSignature(const EcCurve *curve, const uint8_t *data,
219  size_t length, EcdsaSignature *signature, IkeSignFormat format)
220 {
221 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
222  error_t error;
223 
224  //Check signature format
225  if(format == IKE_SIGN_FORMAT_RAW)
226  {
227  //The signature payload shall contain an encoding of the computed
228  //signature consisting of the concatenation of a pair of integers
229  //R and S (refer to RFC 4754, section 7)
230  error = ecdsaImportSignature(signature, curve, data, length,
232  }
233  else if(format == IKE_SIGN_FORMAT_ASN1)
234  {
235  //Read the ASN.1 encoded signature
236  error = ecdsaImportSignature(signature, curve, data, length,
238  }
239  else
240  {
241  //Invalid format
242  error = ERROR_INVALID_TYPE;
243  }
244 
245  //Return status code
246  return error;
247 #else
248  //Not implemented
249  return ERROR_NOT_IMPLEMENTED;
250 #endif
251 }
252 
253 
254 /**
255  * @brief Select the algorithm identifier that matches the specified
256  * certificate type and hash algorithms
257  * @param[in] certType Certificate type
258  * @param[in] hashAlgo Hash algorithm
259  * @param[out] signAlgoId Signature algorithm identifier
260  * @return Error code
261  **/
262 
264  X509SignAlgoId *signAlgoId)
265 {
266  error_t error;
267 
268  //Initialize status code
269  error = NO_ERROR;
270 
271 #if (IKE_RSA_SIGN_SUPPORT == ENABLED)
272  //RSA signature algorithm?
273  if(certType == IKE_CERT_TYPE_RSA)
274  {
275 #if (IKE_SHA1_SUPPORT == ENABLED)
276  //SHA-1 hash algorithm?
277  if(hashAlgo == SHA1_HASH_ALGO)
278  {
279  //RSA with SHA-1 signature algorithm
280  signAlgoId->oid.value = SHA1_WITH_RSA_ENCRYPTION_OID;
281  signAlgoId->oid.length = sizeof(SHA1_WITH_RSA_ENCRYPTION_OID);
282  }
283  else
284 #endif
285 #if (IKE_SHA256_SUPPORT == ENABLED)
286  //SHA-256 hash algorithm?
287  if(hashAlgo == SHA256_HASH_ALGO)
288  {
289  //RSA with SHA-256 signature algorithm
291  signAlgoId->oid.length = sizeof(SHA256_WITH_RSA_ENCRYPTION_OID);
292  }
293  else
294 #endif
295 #if (IKE_SHA384_SUPPORT == ENABLED)
296  //SHA-384 hash algorithm?
297  if(hashAlgo == SHA384_HASH_ALGO)
298  {
299  //RSA with SHA-384 signature algorithm
301  signAlgoId->oid.length = sizeof(SHA384_WITH_RSA_ENCRYPTION_OID);
302  }
303  else
304 #endif
305 #if (IKE_SHA512_SUPPORT == ENABLED)
306  //SHA-512 hash algorithm?
307  if(hashAlgo == SHA512_HASH_ALGO)
308  {
309  //RSA with SHA-512 signature algorithm
311  signAlgoId->oid.length = sizeof(SHA512_WITH_RSA_ENCRYPTION_OID);
312  }
313  else
314 #endif
315  //Invalid hash algorithm?
316  {
317  //Report an error
319  }
320  }
321  else
322 #endif
323 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
324  //RSA-PSS signature algorithm?
325  if(certType == IKE_CERT_TYPE_RSA_PSS)
326  {
327  //SHA-1, SHA-256, SHA-384 or SHA-512 hash algorithm?
328  if(hashAlgo != NULL)
329  {
330  //Set the OID of the signature algorithm
331  signAlgoId->oid.value = RSASSA_PSS_OID;
332  signAlgoId->oid.length = sizeof(RSASSA_PSS_OID);
333 
334  //Set the OID of the hash algorithm
335  signAlgoId->rsaPssParams.hashAlgo.value = hashAlgo->oid;
336  signAlgoId->rsaPssParams.hashAlgo.length = hashAlgo->oidSize;
337 
338  //Set RSASSA-PSS parameters
339  signAlgoId->rsaPssParams.maskGenAlgo.value = MGF1_OID;
340  signAlgoId->rsaPssParams.maskGenAlgo.length = sizeof(MGF1_OID);
341  signAlgoId->rsaPssParams.maskGenHashAlgo.value = hashAlgo->oid;
342  signAlgoId->rsaPssParams.maskGenHashAlgo.length = hashAlgo->oidSize;
343  signAlgoId->rsaPssParams.saltLen = hashAlgo->digestSize;
344  }
345  else
346  {
347  //Report an error
349  }
350  }
351  else
352 #endif
353 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
354  //DSA signature algorithm?
355  if(certType == IKE_CERT_TYPE_DSA)
356  {
357 #if (IKE_SHA1_SUPPORT == ENABLED)
358  //SHA-1 hash algorithm?
359  if(hashAlgo == SHA1_HASH_ALGO)
360  {
361  //DSA with SHA-1 signature algorithm
362  signAlgoId->oid.value = DSA_WITH_SHA1_OID;
363  signAlgoId->oid.length = sizeof(DSA_WITH_SHA1_OID);
364  }
365  else
366 #endif
367 #if (IKE_SHA256_SUPPORT == ENABLED)
368  //SHA-256 hash algorithm?
369  if(hashAlgo == SHA256_HASH_ALGO)
370  {
371  //DSA with SHA-256 signature algorithm
372  signAlgoId->oid.value = DSA_WITH_SHA256_OID;
373  signAlgoId->oid.length = sizeof(DSA_WITH_SHA256_OID);
374  }
375  else
376 #endif
377 #if (IKE_SHA384_SUPPORT == ENABLED)
378  //SHA-384 hash algorithm?
379  if(hashAlgo == SHA384_HASH_ALGO)
380  {
381  //DSA with SHA-384 signature algorithm
382  signAlgoId->oid.value = DSA_WITH_SHA384_OID;
383  signAlgoId->oid.length = sizeof(DSA_WITH_SHA384_OID);
384  }
385  else
386 #endif
387 #if (IKE_SHA512_SUPPORT == ENABLED)
388  //SHA-512 hash algorithm?
389  if(hashAlgo == SHA512_HASH_ALGO)
390  {
391  //DSA with SHA-512 signature algorithm
392  signAlgoId->oid.value = DSA_WITH_SHA512_OID;
393  signAlgoId->oid.length = sizeof(DSA_WITH_SHA512_OID);
394  }
395  else
396 #endif
397  //Invalid hash algorithm?
398  {
399  //Report an error
401  }
402  }
403  else
404 #endif
405 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
406  //ECDSA signature algorithm?
407  if(certType == IKE_CERT_TYPE_ECDSA_P256 ||
408  certType == IKE_CERT_TYPE_ECDSA_P384 ||
409  certType == IKE_CERT_TYPE_ECDSA_P521 ||
413  {
414 #if (IKE_SHA1_SUPPORT == ENABLED)
415  //SHA-1 hash algorithm?
416  if(hashAlgo == SHA1_HASH_ALGO)
417  {
418  //ECDSA with SHA-1 signature algorithm
419  signAlgoId->oid.value = ECDSA_WITH_SHA1_OID;
420  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA1_OID);
421  }
422  else
423 #endif
424 #if (IKE_SHA256_SUPPORT == ENABLED)
425  //SHA-256 hash algorithm?
426  if(hashAlgo == SHA256_HASH_ALGO)
427  {
428  //ECDSA with SHA-256 signature algorithm
429  signAlgoId->oid.value = ECDSA_WITH_SHA256_OID;
430  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA256_OID);
431  }
432  else
433 #endif
434 #if (IKE_SHA384_SUPPORT == ENABLED)
435  //SHA-384 hash algorithm?
436  if(hashAlgo == SHA384_HASH_ALGO)
437  {
438  //ECDSA with SHA-384 signature algorithm
439  signAlgoId->oid.value = ECDSA_WITH_SHA384_OID;
440  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA384_OID);
441  }
442  else
443 #endif
444 #if (IKE_SHA512_SUPPORT == ENABLED)
445  //SHA-512 hash algorithm?
446  if(hashAlgo == SHA512_HASH_ALGO)
447  {
448  //ECDSA with SHA-512 signature algorithm
449  signAlgoId->oid.value = ECDSA_WITH_SHA512_OID;
450  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA512_OID);
451  }
452  else
453 #endif
454  //Invalid hash algorithm?
455  {
456  //Report an error
458  }
459  }
460  else
461 #endif
462 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
463  //Ed25519 signature algorithm?
464  if(certType == IKE_CERT_TYPE_ED25519)
465  {
466  //Set the OID of the signature algorithm
467  signAlgoId->oid.value = ED25519_OID;
468  signAlgoId->oid.length = sizeof(ED25519_OID);
469  }
470  else
471 #endif
472 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
473  //Ed448 signature algorithm?
474  if(certType == IKE_CERT_TYPE_ED448)
475  {
476  //Set the OID of the signature algorithm
477  signAlgoId->oid.value = ED448_OID;
478  signAlgoId->oid.length = sizeof(ED448_OID);
479  }
480  else
481 #endif
482  //Invalid signature algorithm?
483  {
484  //Report an error
486  }
487 
488  //Return status code
489  return error;
490 }
491 
492 
493 /**
494  * @brief Select the signature and hash algorithms that match the specified
495  * identifier
496  * @param[in] signAlgoId Signature algorithm identifier
497  * @param[out] signAlgo Signature algorithm
498  * @param[out] hashAlgo Hash algorithm
499  * @return Error code
500  **/
501 
503  IkeSignAlgo *signAlgo, const HashAlgo **hashAlgo)
504 {
505  error_t error;
506  size_t oidLen;
507  const uint8_t *oid;
508 
509  //Initialize status code
510  error = NO_ERROR;
511 
512  //Point to the object identifier
513  oid = signAlgoId->oid.value;
514  oidLen = signAlgoId->oid.length;
515 
516 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
517  //RSA with SHA-1 signature algorithm?
519  {
520  *signAlgo = IKE_SIGN_ALGO_RSA;
521  *hashAlgo = SHA1_HASH_ALGO;
522  }
523  else
524 #endif
525 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
526  //RSA with SHA-256 signature algorithm?
528  {
529  *signAlgo = IKE_SIGN_ALGO_RSA;
530  *hashAlgo = SHA256_HASH_ALGO;
531  }
532  else
533 #endif
534 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
535  //RSA with SHA-384 signature algorithm?
537  {
538  *signAlgo = IKE_SIGN_ALGO_RSA;
539  *hashAlgo = SHA384_HASH_ALGO;
540  }
541  else
542 #endif
543 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
544  //RSA with SHA-512 signature algorithm?
546  {
547  *signAlgo = IKE_SIGN_ALGO_RSA;
548  *hashAlgo = SHA512_HASH_ALGO;
549  }
550  else
551 #endif
552 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
553  //RSA-PSS signature algorithm
554  if(OID_COMP(oid, oidLen, RSASSA_PSS_OID) == 0)
555  {
556  //Get the OID of the hash algorithm
557  oid = signAlgoId->rsaPssParams.hashAlgo.value;
558  oidLen = signAlgoId->rsaPssParams.hashAlgo.length;
559 
560 #if (IKE_SHA1_SUPPORT == ENABLED)
561  //SHA-1 hash algorithm identifier?
562  if(OID_COMP(oid, oidLen, SHA1_OID) == 0)
563  {
564  //RSA-PSS with SHA-1 signature algorithm
565  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
566  *hashAlgo = SHA1_HASH_ALGO;
567  }
568  else
569 #endif
570 #if (IKE_SHA256_SUPPORT == ENABLED)
571  //SHA-256 hash algorithm identifier?
572  if(OID_COMP(oid, oidLen, SHA256_OID) == 0)
573  {
574  //RSA-PSS with SHA-256 signature algorithm
575  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
576  *hashAlgo = SHA256_HASH_ALGO;
577  }
578  else
579 #endif
580 #if (IKE_SHA384_SUPPORT == ENABLED)
581  //SHA-384 hash algorithm identifier?
582  if(OID_COMP(oid, oidLen, SHA384_OID) == 0)
583  {
584  //RSA-PSS with SHA-384 signature algorithm
585  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
586  *hashAlgo = SHA384_HASH_ALGO;
587  }
588  else
589 #endif
590 #if (IKE_SHA512_SUPPORT == ENABLED)
591  //SHA-512 hash algorithm identifier?
592  if(OID_COMP(oid, oidLen, SHA512_OID) == 0)
593  {
594  //RSA-PSS with SHA-512 signature algorithm
595  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
596  *hashAlgo = SHA512_HASH_ALGO;
597  }
598  else
599 #endif
600  //Unknown hash algorithm identifier?
601  {
602  //The specified signature algorithm is not supported
604  }
605  }
606  else
607 #endif
608 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
609  //DSA with SHA-1 signature algorithm?
611  {
612  *signAlgo = IKE_SIGN_ALGO_DSA;
613  *hashAlgo = SHA1_HASH_ALGO;
614  }
615  else
616 #endif
617 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
618  //DSA with SHA-256 signature algorithm?
620  {
621  *signAlgo = IKE_SIGN_ALGO_DSA;
622  *hashAlgo = SHA256_HASH_ALGO;
623  }
624  else
625 #endif
626 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
627  //DSA with SHA-384 signature algorithm?
629  {
630  *signAlgo = IKE_SIGN_ALGO_DSA;
631  *hashAlgo = SHA384_HASH_ALGO;
632  }
633  else
634 #endif
635 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
636  //DSA with SHA-512 signature algorithm?
638  {
639  *signAlgo = IKE_SIGN_ALGO_DSA;
640  *hashAlgo = SHA512_HASH_ALGO;
641  }
642  else
643 #endif
644 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
645  //ECDSA with SHA-1 signature algorithm?
647  {
648  *signAlgo = IKE_SIGN_ALGO_ECDSA;
649  *hashAlgo = SHA1_HASH_ALGO;
650  }
651  else
652 #endif
653 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
654  //ECDSA with SHA-256 signature algorithm?
656  {
657  *signAlgo = IKE_SIGN_ALGO_ECDSA;
658  *hashAlgo = SHA256_HASH_ALGO;
659  }
660  else
661 #endif
662 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
663  //ECDSA with SHA-384 signature algorithm?
665  {
666  *signAlgo = IKE_SIGN_ALGO_ECDSA;
667  *hashAlgo = SHA384_HASH_ALGO;
668  }
669  else
670 #endif
671 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
672  //ECDSA with SHA-512 signature algorithm?
674  {
675  *signAlgo = IKE_SIGN_ALGO_ECDSA;
676  *hashAlgo = SHA512_HASH_ALGO;
677  }
678  else
679 #endif
680 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
681  //Ed25519 signature algorithm?
682  if(OID_COMP(oid, oidLen, ED25519_OID) == 0)
683  {
684  *signAlgo = IKE_SIGN_ALGO_ED25519;
685  *hashAlgo = NULL;
686  }
687  else
688 #endif
689 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
690  //Ed448 signature algorithm?
691  if(OID_COMP(oid, oidLen, ED448_OID) == 0)
692  {
693  *signAlgo = IKE_SIGN_ALGO_ED448;
694  *hashAlgo = NULL;
695  }
696  else
697 #endif
698  //Unknown signature algorithm?
699  {
701  }
702 
703  //Return status code
704  return error;
705 }
706 
707 
708 /**
709  * @brief Select the hash algorithm to be used for signing
710  * @param[in] sa Pointer to the IKE SA
711  * @param[in] preferredHashAlgoId Preferred hash algorithm (provided as a hint)
712  * @return Signature hash algorithm
713  **/
714 
716  uint16_t preferredHashAlgoId)
717 {
718 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
719  uint16_t n;
720  uint16_t hashAlgoId;
721  const HashAlgo *hashAlgo;
722 
723  //Clear hash algorithm identifier
724  hashAlgoId = 0;
725 
726  //If the preferred hash algorithm is not supported by the peer, then select
727  //a stronger hash algorithm
728  for(n = preferredHashAlgoId; n <= IKE_HASH_ALGO_SHA512; n++)
729  {
730  //Check whether the current hash algorithm is supported by the peer
731  if((sa->signHashAlgos & (1U << n)) != 0)
732  {
733  hashAlgoId = n;
734  break;
735  }
736  }
737 
738  //If no stronger hash algorithm is not supported by the peer, then select
739  //a weaker hash algorithm
740  if(hashAlgoId == 0)
741  {
742  //Loop through the list of signature hash algorithms
743  for(n = preferredHashAlgoId; n >= IKE_HASH_ALGO_SHA1; n--)
744  {
745  //Check whether the current hash algorithm is supported by the peer
746  if((sa->signHashAlgos & (1U << n)) != 0)
747  {
748  hashAlgoId = n;
749  break;
750  }
751  }
752  }
753 
754 #if (IKE_SHA1_SUPPORT == ENABLED)
755  //SHA-1 hash algorithm?
756  if(hashAlgoId == IKE_HASH_ALGO_SHA1)
757  {
758  hashAlgo = SHA1_HASH_ALGO;
759  }
760  else
761 #endif
762 #if (IKE_SHA256_SUPPORT == ENABLED)
763  //SHA-256 hash algorithm?
764  if(hashAlgoId == IKE_HASH_ALGO_SHA256)
765  {
766  hashAlgo = SHA256_HASH_ALGO;
767  }
768  else
769 #endif
770 #if (IKE_SHA384_SUPPORT == ENABLED)
771  //SHA-384 hash algorithm?
772  if(hashAlgoId == IKE_HASH_ALGO_SHA384)
773  {
774  hashAlgo = SHA384_HASH_ALGO;
775  }
776  else
777 #endif
778 #if (IKE_SHA512_SUPPORT == ENABLED)
779  //SHA-512 hash algorithm?
780  if(hashAlgoId == IKE_HASH_ALGO_SHA512)
781  {
782  hashAlgo = SHA512_HASH_ALGO;
783  }
784  else
785 #endif
786  //Unknown hash algorithm?
787  {
788  hashAlgo = NULL;
789  }
790 
791  //Return the hash algorithm to be used for signing
792  return hashAlgo;
793 #else
794  //The digital signature method is not supported
795  return NULL;
796 #endif
797 }
798 
799 
800 /**
801  * @brief Retrieve the octets to be signed using EdDSA
802  * @param[in] sa Pointer to the IKE SA
803  * @param[in] id MAC authentication data
804  * @param[in] idLen MAC authentication data
805  * @param[out] macId Temporary buffer needed to calculate MACedID
806  * @param[out] messageFrags Array of fragments representing the message to be
807  * signed
808  * @param[in] initiator Specifies whether the digest is performed at initiator
809  * or responder side
810  * @return Error code
811  **/
812 
813 error_t ikeGetSignedOctets(IkeSaEntry *sa, const uint8_t *id, size_t idLen,
814  uint8_t *macId, DataFrag *messageFrags, bool_t initiator)
815 {
816  error_t error;
817 
818  //Check whether the calculation is performed at initiator side
819  if(initiator)
820  {
821  //Compute prf(SK_pi, IDi')
822  error = ikePrf(sa->prfMacAlgo, sa->prfHashAlgo, sa->prfCipherAlgo,
823  sa->skpi, sa->prfKeyLen, id, idLen, macId);
824 
825  //Check status code
826  if(!error)
827  {
828  //The initiator signs the first message (IKE_SA_INIT request), starting
829  //with the first octet of the first SPI in the header and ending with
830  //the last octet of the last payload
831  messageFrags[0].buffer = sa->initiatorSaInit;
832  messageFrags[0].length = sa->initiatorSaInitLen;
833 
834  //Appended to this (for purposes of computing the signature) are the
835  //responder's nonce Nr, and the value prf(SK_pi, IDi')
836  messageFrags[1].buffer = sa->responderNonce;
837  messageFrags[1].length = sa->responderNonceLen;
838  messageFrags[2].buffer = macId;
839  messageFrags[2].length = sa->prfKeyLen;
840  }
841  }
842  else
843  {
844  //Compute prf(SK_pr, IDr')
845  error = ikePrf(sa->prfMacAlgo, sa->prfHashAlgo, sa->prfCipherAlgo,
846  sa->skpr, sa->prfKeyLen, id, idLen, macId);
847 
848  //Check status code
849  if(!error)
850  {
851  //For the responder, the octets to be signed start with the first octet
852  //of the first SPI in the header of the second message (IKE_SA_INIT
853  //response) and end with the last octet of the last payload in the
854  //second message
855  messageFrags[0].buffer = sa->responderSaInit;
856  messageFrags[0].length = sa->responderSaInitLen;
857 
858  //Appended to this (for purposes of computing the signature) are the
859  //initiator's nonce Ni, and the value prf(SK_pr, IDr')
860  messageFrags[1].buffer = sa->initiatorNonce;
861  messageFrags[1].length = sa->initiatorNonceLen;
862  messageFrags[2].buffer = macId;
863  messageFrags[2].length = sa->prfKeyLen;
864  }
865  }
866 
867  //Successful processing
868  return NO_ERROR;
869 }
870 
871 
872 /**
873  * @brief Digest signed octets
874  * @param[in] sa Pointer to the IKE SA
875  * @param[in] hashAlgo Underlying hash function
876  * @param[in] id MAC authentication data
877  * @param[in] idLen MAC authentication data
878  * @param[out] digest Calculated digest
879  * @param[in] initiator Specifies whether the digest is performed at initiator
880  * or responder side
881  * @return Error code
882  **/
883 
885  const uint8_t *id, size_t idLen, uint8_t *digest, bool_t initiator)
886 {
887  error_t error;
888  HashContext hashContext;
889  uint8_t macId[IKE_MAX_DIGEST_SIZE];
890 
891  //Check whether the calculation is performed at initiator side
892  if(initiator)
893  {
894  //Compute prf(SK_pi, IDi')
895  error = ikePrf(sa->prfMacAlgo, sa->prfHashAlgo, sa->prfCipherAlgo,
896  sa->skpi, sa->prfKeyLen, id, idLen, macId);
897 
898  //Check status code
899  if(!error)
900  {
901  //The initiator signs the first message (IKE_SA_INIT request), starting
902  //with the first octet of the first SPI in the header and ending with
903  //the last octet of the last payload
904  hashAlgo->init(&hashContext);
905  hashAlgo->update(&hashContext, sa->initiatorSaInit, sa->initiatorSaInitLen);
906 
907  //Appended to this (for purposes of computing the signature) are the
908  //responder's nonce Nr, and the value prf(SK_pi, IDi')
909  hashAlgo->update(&hashContext, sa->responderNonce, sa->responderNonceLen);
910  hashAlgo->update(&hashContext, macId, sa->prfKeyLen);
911  hashAlgo->final(&hashContext, digest);
912  }
913  }
914  else
915  {
916  //Compute prf(SK_pr, IDr')
917  error = ikePrf(sa->prfMacAlgo, sa->prfHashAlgo, sa->prfCipherAlgo,
918  sa->skpr, sa->prfKeyLen, id, idLen, macId);
919 
920  //Check status code
921  if(!error)
922  {
923  //For the responder, the octets to be signed start with the first octet
924  //of the first SPI in the header of the second message (IKE_SA_INIT
925  //response) and end with the last octet of the last payload in the
926  //second message
927  hashAlgo->init(&hashContext);
928  hashAlgo->update(&hashContext, sa->responderSaInit, sa->responderSaInitLen);
929 
930  //Appended to this (for purposes of computing the signature) are the
931  //initiator's nonce Ni, and the value prf(SK_pr, IDr')
932  hashAlgo->update(&hashContext, sa->initiatorNonce, sa->initiatorNonceLen);
933  hashAlgo->update(&hashContext, macId, sa->prfKeyLen);
934  hashAlgo->final(&hashContext, digest);
935  }
936  }
937 
938  //Return status code
939  return error;
940 }
941 
942 #endif
error_t ecdsaImportSignature(EcdsaSignature *signature, const EcCurve *curve, const uint8_t *input, size_t length, EcdsaSignatureFormat format)
Import an ECDSA signature.
Definition: ecdsa.c:107
@ IKE_SIGN_ALGO_ED448
Definition: ike_sign_misc.h:66
Mpi s
Definition: dsa.h:87
ECDSA signature.
Definition: ecdsa.h:63
IkeCertType
Certificate types.
Definition: ike.h:1414
const void * buffer
Definition: crypto.h:1165
error_t ikePrf(MacAlgo macAlgo, const HashAlgo *hashAlgo, const CipherAlgo *cipherAlgo, const uint8_t *key, size_t keyLen, const uint8_t *data, size_t dataLen, uint8_t *output)
Pseudorandom function (prf function)
Definition: ike_kdf.c:55
HashAlgoInit init
Definition: crypto.h:1253
error_t dsaImportSignature(DsaSignature *signature, const uint8_t *input, size_t length)
Import an ASN.1 encoded DSA signature.
Definition: dsa.c:197
Generic hash algorithm context.
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:63
#define SHA1_HASH_ALGO
Definition: sha1.h:49
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP384R1
Definition: ike.h:1423
@ IKE_HASH_ALGO_SHA256
Definition: ike.h:1400
const uint8_t * oid
Definition: crypto.h:1245
#define SHA512_HASH_ALGO
Definition: sha512.h:49
const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:69
@ IKE_HASH_ALGO_SHA1
Definition: ike.h:1399
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
X509OctetString hashAlgo
Definition: x509_common.h:1151
OID (Object Identifier)
IkeSignAlgo
Signature algorithms.
Definition: ike_sign_misc.h:59
@ IKE_CERT_TYPE_RSA_PSS
Definition: ike.h:1417
uint8_t data[]
Definition: ethernet.h:224
size_t digestSize
Definition: crypto.h:1249
HashAlgoUpdate update
Definition: crypto.h:1254
error_t ikeParseDsaSignature(const uint8_t *data, size_t length, DsaSignature *signature, IkeSignFormat format)
DSA signature parsing.
X509OctetString maskGenHashAlgo
Definition: x509_common.h:1153
error_t ikeDigestSignedOctets(IkeSaEntry *sa, const HashAlgo *hashAlgo, const uint8_t *id, size_t idLen, uint8_t *digest, bool_t initiator)
Digest signed octets.
Mpi r
Definition: dsa.h:86
@ IKE_SIGN_ALGO_RSA
Definition: ike_sign_misc.h:61
error_t ikeParseEcdsaSignature(const EcCurve *curve, const uint8_t *data, size_t length, EcdsaSignature *signature, IkeSignFormat format)
ECDSA signature parsing.
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:85
#define IKE_MAX_DIGEST_SIZE
Definition: ike.h:764
@ IKE_CERT_TYPE_ECDSA_P384
Definition: ike.h:1420
const uint8_t ECDSA_WITH_SHA256_OID[8]
Definition: ecdsa.c:50
uint8_t oid[]
Definition: lldp_tlv.h:300
const uint8_t MGF1_OID[9]
Definition: rsa.c:92
error_t ikeSelectSignAlgoId(IkeCertType certType, const HashAlgo *hashAlgo, X509SignAlgoId *signAlgoId)
Select the algorithm identifier that matches the specified certificate type and hash algorithms.
size_t oidSize
Definition: crypto.h:1246
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP256R1
Definition: ike.h:1422
error_t ecdsaExportSignature(const EcdsaSignature *signature, uint8_t *output, size_t *written, EcdsaSignatureFormat format)
Export an ECDSA signature.
Definition: ecdsa.c:275
const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:67
Helper functions for signature generation and verification.
error_t
Error codes.
Definition: error.h:43
@ IKE_SIGN_ALGO_RSA_PSS
Definition: ike_sign_misc.h:62
const uint8_t DSA_WITH_SHA384_OID[9]
Definition: dsa.c:59
error_t ikeGetSignedOctets(IkeSaEntry *sa, const uint8_t *id, size_t idLen, uint8_t *macId, DataFrag *messageFrags, bool_t initiator)
Retrieve the octets to be signed using EdDSA.
Key material generation.
@ IKE_HASH_ALGO_SHA512
Definition: ike.h:1402
error_t ikeSelectSignAlgo(const X509SignAlgoId *signAlgoId, IkeSignAlgo *signAlgo, const HashAlgo **hashAlgo)
Select the signature and hash algorithms that match the specified identifier.
const uint8_t SHA256_OID[9]
Definition: sha256.c:82
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:714
@ ECDSA_SIGNATURE_FORMAT_RAW
Definition: ecdsa.h:52
Data fragment descriptor.
Definition: crypto.h:1164
const uint8_t ECDSA_WITH_SHA384_OID[8]
Definition: ecdsa.c:52
const uint8_t DSA_WITH_SHA512_OID[9]
Definition: dsa.c:61
@ IKE_SIGN_FORMAT_ASN1
Definition: ike_sign_misc.h:50
@ ERROR_INVALID_TYPE
Definition: error.h:115
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:811
size_t length
Definition: crypto.h:1166
uint8_t length
Definition: tcp.h:375
X509OctetString oid
Definition: x509_common.h:1164
X509OctetString maskGenAlgo
Definition: x509_common.h:1152
const uint8_t ECDSA_WITH_SHA1_OID[7]
Definition: ecdsa.c:46
IKEv2 key derivation functions.
@ IKE_CERT_TYPE_DSA
Definition: ike.h:1418
const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:65
@ IKE_SIGN_ALGO_DSA
Definition: ike_sign_misc.h:63
@ IKE_CERT_TYPE_RSA
Definition: ike.h:1416
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP512R1
Definition: ike.h:1424
const uint8_t ED448_OID[3]
Definition: ec_curves.c:114
const uint8_t ECDSA_WITH_SHA512_OID[8]
Definition: ecdsa.c:54
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:112
@ IKE_CERT_TYPE_ED25519
Definition: ike.h:1426
IKEv2 (Internet Key Exchange Protocol)
@ IKE_CERT_TYPE_ED448
Definition: ike.h:1427
IkeSignFormat
Signature format.
Definition: ike_sign_misc.h:48
HashAlgoFinal final
Definition: crypto.h:1255
#define SHA384_HASH_ALGO
Definition: sha384.h:45
@ ERROR_INVALID_SIGNATURE_ALGO
Definition: error.h:135
error_t dsaExportSignature(const DsaSignature *signature, uint8_t *output, size_t *written)
Export a DSA signature to ASN.1 format.
Definition: dsa.c:334
#define IkeSaEntry
Definition: ike.h:836
@ ECDSA_SIGNATURE_FORMAT_ASN1
Definition: ecdsa.h:51
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
uint8_t n
@ IKE_SIGN_FORMAT_RAW
Definition: ike_sign_misc.h:49
error_t ikeFormatEcdsaSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length, IkeSignFormat format)
ECDSA signature formatting.
#define IKE_SHA1_DIGEST_SIZE
Definition: ike.h:828
@ IKE_SIGN_ALGO_ECDSA
Definition: ike_sign_misc.h:64
const uint8_t DSA_WITH_SHA1_OID[7]
Definition: dsa.c:53
const uint8_t DSA_WITH_SHA256_OID[9]
Definition: dsa.c:57
uint8_t oidLen
Definition: lldp_tlv.h:299
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
const uint8_t SHA512_OID[9]
Definition: sha512.c:99
const uint8_t SHA1_OID[5]
Definition: sha1.c:73
const uint8_t * value
Definition: x509_common.h:762
Common interface for hash algorithms.
Definition: crypto.h:1243
DSA signature.
Definition: dsa.h:85
#define EcCurve
Definition: ec.h:346
@ IKE_CERT_TYPE_ECDSA_P521
Definition: ike.h:1421
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
const uint8_t SHA384_OID[9]
Definition: sha384.c:47
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:1166
@ IKE_HASH_ALGO_SHA384
Definition: ike.h:1401
const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:61
@ IKE_SIGN_ALGO_ED25519
Definition: ike_sign_misc.h:65
IKEv2 algorithm negotiation.
Signature algorithm identifier.
Definition: x509_common.h:1163
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
const HashAlgo * ikeSelectSignHashAlgo(IkeSaEntry *sa, uint16_t preferredHashAlgoId)
Select the hash algorithm to be used for signing.
error_t ikeFormatDsaSignature(const DsaSignature *signature, uint8_t *data, size_t *length, IkeSignFormat format)
DSA signature formatting.
Definition: ike_sign_misc.c:56
@ IKE_CERT_TYPE_ECDSA_P256
Definition: ike.h:1419