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