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-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 "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  //Encoded the DSA signature using ASN.1
86  error = dsaWriteSignature(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] params EC domain parameters
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  const EcdsaSignature *signature, uint8_t *data, size_t *length,
115  IkeSignFormat format)
116 {
117 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
118  error_t error;
119 
120  //Check signature format
121  if(format == IKE_SIGN_FORMAT_RAW)
122  {
123  size_t n;
124 
125  //The signature payload shall contain an encoding of the computed
126  //signature consisting of the concatenation of a pair of integers R
127  //and S (refer to RFC 4754, section 7)
128  n = mpiGetByteLength(&params->p);
129 
130  //Encode integer R
131  error = mpiExport(&signature->r, data, n, MPI_FORMAT_BIG_ENDIAN);
132 
133  //Check status code
134  if(!error)
135  {
136  //Encode integer S
137  error = mpiExport(&signature->s, data + n, n, MPI_FORMAT_BIG_ENDIAN);
138  }
139 
140  //Check status code
141  if(!error)
142  {
143  //Return the length of the signature
144  *length = 2 * n;
145  }
146  }
147  else if(format == IKE_SIGN_FORMAT_ASN1)
148  {
149  //Encoded the ECDSA signature using ASN.1
150  error = ecdsaWriteSignature(signature, data, length);
151  }
152  else
153  {
154  //Invalid format
155  error = ERROR_INVALID_TYPE;
156  }
157 
158  //Return status code
159  return error;
160 #else
161  //Not implemented
162  return ERROR_NOT_IMPLEMENTED;
163 #endif
164 }
165 
166 
167 /**
168  * @brief DSA signature parsing
169  * @param[in] data Pointer to the encoded signature
170  * @param[in] length Length of the encoded signature, in bytes
171  * @param[out] signature (R, S) integer pair
172  * @param[in] format Signature format (raw or ASN.1)
173  * @return Error code
174  **/
175 
176 error_t ikeParseDsaSignature(const uint8_t *data, size_t length,
177  DsaSignature *signature, IkeSignFormat format)
178 {
179 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
180  error_t error;
181 
182  //Check signature format
183  if(format == IKE_SIGN_FORMAT_RAW)
184  {
185  //DSS is only defined with SHA-1
186  if(length == (2 * IKE_SHA1_DIGEST_SIZE))
187  {
188  //Import integer R
189  error = mpiImport(&signature->r, data, IKE_SHA1_DIGEST_SIZE,
191 
192  //Check status code
193  if(!error)
194  {
195  //Import integer S
196  error = mpiImport(&signature->s, data + IKE_SHA1_DIGEST_SIZE,
198  }
199  }
200  else
201  {
202  //The length of the signature is not acceptable
203  error = ERROR_INVALID_SIGNATURE;
204  }
205  }
206  else if(format == IKE_SIGN_FORMAT_ASN1)
207  {
208  //Read the ASN.1 encoded signature
209  error = dsaReadSignature(data, length, signature);
210  }
211  else
212  {
213  //Invalid format
214  error = ERROR_INVALID_TYPE;
215  }
216 
217  //Return status code
218  return error;
219 #else
220  //Not implemented
221  return ERROR_NOT_IMPLEMENTED;
222 #endif
223 }
224 
225 
226 /**
227  * @brief ECDSA signature parsing
228  * @param[in] params EC domain parameters
229  * @param[in] data Pointer to the encoded signature
230  * @param[in] length Length of the encoded signature, in bytes
231  * @param[out] signature (R, S) integer pair
232  * @param[in] format Signature format (raw or ASN.1)
233  * @return Error code
234  **/
235 
237  size_t length, EcdsaSignature *signature, IkeSignFormat format)
238 {
239 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
240  error_t error;
241  size_t modLen;
242 
243  //Check signature format
244  if(format == IKE_SIGN_FORMAT_RAW)
245  {
246  //Retrieve the length of the modulus
247  modLen = mpiGetByteLength(&params->p);
248 
249  //The signature payload shall contain an encoding of the computed
250  //signature consisting of the concatenation of a pair of integers
251  //R and S (refer to RFC 4754, section 7)
252  if(length == (2 * modLen))
253  {
254  //Import integer R
255  error = mpiImport(&signature->r, data, modLen, MPI_FORMAT_BIG_ENDIAN);
256 
257  //Check status code
258  if(!error)
259  {
260  //Import integer S
261  error = mpiImport(&signature->s, data + modLen, modLen,
263  }
264  }
265  else
266  {
267  //The length of the signature is not acceptable
268  error = ERROR_INVALID_SIGNATURE;
269  }
270  }
271  else if(format == IKE_SIGN_FORMAT_ASN1)
272  {
273  //Read the ASN.1 encoded signature
274  error = ecdsaReadSignature(data, length, signature);
275  }
276  else
277  {
278  //Invalid format
279  error = ERROR_INVALID_TYPE;
280  }
281 
282  //Return status code
283  return error;
284 #else
285  //Not implemented
286  return ERROR_NOT_IMPLEMENTED;
287 #endif
288 }
289 
290 
291 /**
292  * @brief Select the algorithm identifier that matches the specified
293  * certificate type and hash algorithms
294  * @param[in] certType Certificate type
295  * @param[in] hashAlgo Hash algorithm
296  * @param[out] signAlgoId Signature algorithm identifier
297  * @return Error code
298  **/
299 
301  X509SignAlgoId *signAlgoId)
302 {
303  error_t error;
304 
305  //Initialize status code
306  error = NO_ERROR;
307 
308 #if (IKE_RSA_SIGN_SUPPORT == ENABLED)
309  //RSA signature algorithm?
310  if(certType == IKE_CERT_TYPE_RSA)
311  {
312 #if (IKE_SHA1_SUPPORT == ENABLED)
313  //SHA-1 hash algorithm?
314  if(hashAlgo == SHA1_HASH_ALGO)
315  {
316  //RSA with SHA-1 signature algorithm
317  signAlgoId->oid.value = SHA1_WITH_RSA_ENCRYPTION_OID;
318  signAlgoId->oid.length = sizeof(SHA1_WITH_RSA_ENCRYPTION_OID);
319  }
320  else
321 #endif
322 #if (IKE_SHA256_SUPPORT == ENABLED)
323  //SHA-256 hash algorithm?
324  if(hashAlgo == SHA256_HASH_ALGO)
325  {
326  //RSA with SHA-256 signature algorithm
328  signAlgoId->oid.length = sizeof(SHA256_WITH_RSA_ENCRYPTION_OID);
329  }
330  else
331 #endif
332 #if (IKE_SHA384_SUPPORT == ENABLED)
333  //SHA-384 hash algorithm?
334  if(hashAlgo == SHA384_HASH_ALGO)
335  {
336  //RSA with SHA-384 signature algorithm
338  signAlgoId->oid.length = sizeof(SHA384_WITH_RSA_ENCRYPTION_OID);
339  }
340  else
341 #endif
342 #if (IKE_SHA512_SUPPORT == ENABLED)
343  //SHA-512 hash algorithm?
344  if(hashAlgo == SHA512_HASH_ALGO)
345  {
346  //RSA with SHA-512 signature algorithm
348  signAlgoId->oid.length = sizeof(SHA512_WITH_RSA_ENCRYPTION_OID);
349  }
350  else
351 #endif
352  //Invalid hash algorithm?
353  {
354  //Report an error
356  }
357  }
358  else
359 #endif
360 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
361  //RSA-PSS signature algorithm?
362  if(certType == IKE_CERT_TYPE_RSA_PSS)
363  {
364  //Valid hash algorithm?
365  if(hashAlgo != NULL)
366  {
367  //Set the OID of the signature algorithm
368  signAlgoId->oid.value = RSASSA_PSS_OID;
369  signAlgoId->oid.length = sizeof(RSASSA_PSS_OID);
370 
371  //Set the OID of the hash algorithm
372  signAlgoId->rsaPssParams.hashAlgo.value = hashAlgo->oid;
373  signAlgoId->rsaPssParams.hashAlgo.length = hashAlgo->oidSize;
374 
375  //Set RSASSA-PSS parameters
376  signAlgoId->rsaPssParams.maskGenAlgo.value = MGF1_OID;
377  signAlgoId->rsaPssParams.maskGenAlgo.length = sizeof(MGF1_OID);
378  signAlgoId->rsaPssParams.maskGenHashAlgo.value = hashAlgo->oid;
379  signAlgoId->rsaPssParams.maskGenHashAlgo.length = hashAlgo->oidSize;
380  signAlgoId->rsaPssParams.saltLen = hashAlgo->digestSize;
381  }
382  else
383  {
384  //Report an error
386  }
387  }
388  else
389 #endif
390 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
391  //DSA signature algorithm?
392  if(certType == IKE_CERT_TYPE_DSA)
393  {
394 #if (IKE_SHA1_SUPPORT == ENABLED)
395  //SHA-1 hash algorithm?
396  if(hashAlgo == SHA1_HASH_ALGO)
397  {
398  //DSA with SHA-1 signature algorithm
399  signAlgoId->oid.value = DSA_WITH_SHA1_OID;
400  signAlgoId->oid.length = sizeof(DSA_WITH_SHA1_OID);
401  }
402  else
403 #endif
404 #if (IKE_SHA256_SUPPORT == ENABLED)
405  //SHA-256 hash algorithm?
406  if(hashAlgo == SHA256_HASH_ALGO)
407  {
408  //DSA with SHA-256 signature algorithm
409  signAlgoId->oid.value = DSA_WITH_SHA256_OID;
410  signAlgoId->oid.length = sizeof(DSA_WITH_SHA256_OID);
411  }
412  else
413 #endif
414 #if (IKE_SHA384_SUPPORT == ENABLED)
415  //SHA-384 hash algorithm?
416  if(hashAlgo == SHA384_HASH_ALGO)
417  {
418  //DSA with SHA-384 signature algorithm
419  signAlgoId->oid.value = DSA_WITH_SHA384_OID;
420  signAlgoId->oid.length = sizeof(DSA_WITH_SHA384_OID);
421  }
422  else
423 #endif
424 #if (IKE_SHA512_SUPPORT == ENABLED)
425  //SHA-512 hash algorithm?
426  if(hashAlgo == SHA512_HASH_ALGO)
427  {
428  //DSA with SHA-512 signature algorithm
429  signAlgoId->oid.value = DSA_WITH_SHA512_OID;
430  signAlgoId->oid.length = sizeof(DSA_WITH_SHA512_OID);
431  }
432  else
433 #endif
434  //Invalid hash algorithm?
435  {
436  //Report an error
438  }
439  }
440  else
441 #endif
442 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
443  //ECDSA signature algorithm?
444  if(certType == IKE_CERT_TYPE_ECDSA_P256 ||
445  certType == IKE_CERT_TYPE_ECDSA_P384 ||
446  certType == IKE_CERT_TYPE_ECDSA_P521 ||
450  {
451 #if (IKE_SHA1_SUPPORT == ENABLED)
452  //SHA-1 hash algorithm?
453  if(hashAlgo == SHA1_HASH_ALGO)
454  {
455  //ECDSA with SHA-1 signature algorithm
456  signAlgoId->oid.value = ECDSA_WITH_SHA1_OID;
457  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA1_OID);
458  }
459  else
460 #endif
461 #if (IKE_SHA256_SUPPORT == ENABLED)
462  //SHA-256 hash algorithm?
463  if(hashAlgo == SHA256_HASH_ALGO)
464  {
465  //ECDSA with SHA-256 signature algorithm
466  signAlgoId->oid.value = ECDSA_WITH_SHA256_OID;
467  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA256_OID);
468  }
469  else
470 #endif
471 #if (IKE_SHA384_SUPPORT == ENABLED)
472  //SHA-384 hash algorithm?
473  if(hashAlgo == SHA384_HASH_ALGO)
474  {
475  //ECDSA with SHA-384 signature algorithm
476  signAlgoId->oid.value = ECDSA_WITH_SHA384_OID;
477  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA384_OID);
478  }
479  else
480 #endif
481 #if (IKE_SHA512_SUPPORT == ENABLED)
482  //SHA-512 hash algorithm?
483  if(hashAlgo == SHA512_HASH_ALGO)
484  {
485  //ECDSA with SHA-512 signature algorithm
486  signAlgoId->oid.value = ECDSA_WITH_SHA512_OID;
487  signAlgoId->oid.length = sizeof(ECDSA_WITH_SHA512_OID);
488  }
489  else
490 #endif
491  //Invalid hash algorithm?
492  {
493  //Report an error
495  }
496  }
497  else
498 #endif
499 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
500  //Ed25519 signature algorithm?
501  if(certType == IKE_CERT_TYPE_ED25519)
502  {
503  //Set the OID of the signature algorithm
504  signAlgoId->oid.value = ED25519_OID;
505  signAlgoId->oid.length = sizeof(ED25519_OID);
506  }
507  else
508 #endif
509 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
510  //Ed448 signature algorithm?
511  if(certType == IKE_CERT_TYPE_ED448)
512  {
513  //Set the OID of the signature algorithm
514  signAlgoId->oid.value = ED448_OID;
515  signAlgoId->oid.length = sizeof(ED448_OID);
516  }
517  else
518 #endif
519  //Invalid signature algorithm?
520  {
521  //Report an error
523  }
524 
525  //Return status code
526  return error;
527 }
528 
529 
530 /**
531  * @brief Select the signature and hash algorithms that match the specified
532  * identifier
533  * @param[in] signAlgoId Signature algorithm identifier
534  * @param[out] signAlgo Signature algorithm
535  * @param[out] hashAlgo Hash algorithm
536  * @return Error code
537  **/
538 
540  IkeSignAlgo *signAlgo, const HashAlgo **hashAlgo)
541 {
542  error_t error;
543  size_t oidLen;
544  const uint8_t *oid;
545 
546  //Initialize status code
547  error = NO_ERROR;
548 
549  //Point to the object identifier
550  oid = signAlgoId->oid.value;
551  oidLen = signAlgoId->oid.length;
552 
553 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
554  //RSA with SHA-1 signature algorithm?
557  {
558  *signAlgo = IKE_SIGN_ALGO_RSA;
559  *hashAlgo = SHA1_HASH_ALGO;
560  }
561  else
562 #endif
563 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
564  //RSA with SHA-256 signature algorithm?
567  {
568  *signAlgo = IKE_SIGN_ALGO_RSA;
569  *hashAlgo = SHA256_HASH_ALGO;
570  }
571  else
572 #endif
573 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
574  //RSA with SHA-384 signature algorithm?
577  {
578  *signAlgo = IKE_SIGN_ALGO_RSA;
579  *hashAlgo = SHA384_HASH_ALGO;
580  }
581  else
582 #endif
583 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
584  //RSA with SHA-512 signature algorithm?
587  {
588  *signAlgo = IKE_SIGN_ALGO_RSA;
589  *hashAlgo = SHA512_HASH_ALGO;
590  }
591  else
592 #endif
593 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
594  //RSA-PSS signature algorithm
596  sizeof(RSASSA_PSS_OID)))
597  {
598  //Get the OID of the hash algorithm
599  oid = signAlgoId->rsaPssParams.hashAlgo.value;
600  oidLen = signAlgoId->rsaPssParams.hashAlgo.length;
601 
602 #if (IKE_SHA1_SUPPORT == ENABLED)
603  //SHA-1 hash algorithm identifier?
604  if(!oidComp(oid, oidLen, SHA1_OID, sizeof(SHA1_OID)))
605  {
606  //RSA-PSS with SHA-1 signature algorithm
607  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
608  *hashAlgo = SHA1_HASH_ALGO;
609  }
610  else
611 #endif
612 #if (IKE_SHA256_SUPPORT == ENABLED)
613  //SHA-256 hash algorithm identifier?
614  if(!oidComp(oid, oidLen, SHA256_OID, sizeof(SHA256_OID)))
615  {
616  //RSA-PSS with SHA-256 signature algorithm
617  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
618  *hashAlgo = SHA256_HASH_ALGO;
619  }
620  else
621 #endif
622 #if (IKE_SHA384_SUPPORT == ENABLED)
623  //SHA-384 hash algorithm identifier?
624  if(!oidComp(oid, oidLen, SHA384_OID, sizeof(SHA384_OID)))
625  {
626  //RSA-PSS with SHA-384 signature algorithm
627  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
628  *hashAlgo = SHA384_HASH_ALGO;
629  }
630  else
631 #endif
632 #if (IKE_SHA512_SUPPORT == ENABLED)
633  //SHA-512 hash algorithm identifier?
634  if(!oidComp(oid, oidLen, SHA512_OID, sizeof(SHA512_OID)))
635  {
636  //RSA-PSS with SHA-512 signature algorithm
637  *signAlgo = IKE_SIGN_ALGO_RSA_PSS;
638  *hashAlgo = SHA512_HASH_ALGO;
639  }
640  else
641 #endif
642  //Unknown hash algorithm identifier?
643  {
644  //The specified signature algorithm is not supported
646  }
647  }
648  else
649 #endif
650 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
651  //DSA with SHA-1 signature algorithm?
653  sizeof(DSA_WITH_SHA1_OID)))
654  {
655  *signAlgo = IKE_SIGN_ALGO_DSA;
656  *hashAlgo = SHA1_HASH_ALGO;
657  }
658  else
659 #endif
660 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
661  //DSA with SHA-256 signature algorithm?
663  sizeof(DSA_WITH_SHA256_OID)))
664  {
665  *signAlgo = IKE_SIGN_ALGO_DSA;
666  *hashAlgo = SHA256_HASH_ALGO;
667  }
668  else
669 #endif
670 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
671  //DSA with SHA-384 signature algorithm?
673  sizeof(DSA_WITH_SHA384_OID)))
674  {
675  *signAlgo = IKE_SIGN_ALGO_DSA;
676  *hashAlgo = SHA384_HASH_ALGO;
677  }
678  else
679 #endif
680 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
681  //DSA with SHA-512 signature algorithm?
683  sizeof(DSA_WITH_SHA512_OID)))
684  {
685  *signAlgo = IKE_SIGN_ALGO_DSA;
686  *hashAlgo = SHA512_HASH_ALGO;
687  }
688  else
689 #endif
690 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
691  //ECDSA with SHA-1 signature algorithm?
693  sizeof(ECDSA_WITH_SHA1_OID)))
694  {
695  *signAlgo = IKE_SIGN_ALGO_ECDSA;
696  *hashAlgo = SHA1_HASH_ALGO;
697  }
698  else
699 #endif
700 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA256_SUPPORT == ENABLED)
701  //ECDSA with SHA-256 signature algorithm?
703  sizeof(ECDSA_WITH_SHA256_OID)))
704  {
705  *signAlgo = IKE_SIGN_ALGO_ECDSA;
706  *hashAlgo = SHA256_HASH_ALGO;
707  }
708  else
709 #endif
710 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA384_SUPPORT == ENABLED)
711  //ECDSA with SHA-384 signature algorithm?
713  sizeof(ECDSA_WITH_SHA384_OID)))
714  {
715  *signAlgo = IKE_SIGN_ALGO_ECDSA;
716  *hashAlgo = SHA384_HASH_ALGO;
717  }
718  else
719 #endif
720 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_SHA512_SUPPORT == ENABLED)
721  //ECDSA with SHA-512 signature algorithm?
723  sizeof(ECDSA_WITH_SHA512_OID)))
724  {
725  *signAlgo = IKE_SIGN_ALGO_ECDSA;
726  *hashAlgo = SHA512_HASH_ALGO;
727  }
728  else
729 #endif
730 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
731  //Ed25519 signature algorithm?
732  if(!oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
733  {
734  *signAlgo = IKE_SIGN_ALGO_ED25519;
735  *hashAlgo = NULL;
736  }
737  else
738 #endif
739 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
740  //Ed448 signature algorithm?
741  if(!oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
742  {
743  *signAlgo = IKE_SIGN_ALGO_ED448;
744  *hashAlgo = NULL;
745  }
746  else
747 #endif
748  //Unknown signature algorithm?
749  {
751  }
752 
753  //Return status code
754  return error;
755 }
756 
757 
758 /**
759  * @brief Select the hash algorithm to be used for signing
760  * @param[in] sa Pointer to the IKE SA
761  * @param[in] preferredHashAlgoId Preferred hash algorithm (provided as a hint)
762  * @return Signature hash algorithm
763  **/
764 
766  uint16_t preferredHashAlgoId)
767 {
768 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
769  uint16_t n;
770  uint16_t hashAlgoId;
771  const HashAlgo *hashAlgo;
772 
773  //Clear hash algorithm identifier
774  hashAlgoId = 0;
775 
776  //If the preferred hash algorithm is not supported by the peer, then select
777  //a stronger hash algorithm
778  for(n = preferredHashAlgoId; n <= IKE_HASH_ALGO_SHA512; n++)
779  {
780  //Check whether the current hash algorithm is supported by the peer
781  if((sa->signHashAlgos & (1U << n)) != 0)
782  {
783  hashAlgoId = n;
784  break;
785  }
786  }
787 
788  //If no stronger hash algorithm is not supported by the peer, then select
789  //a weaker hash algorithm
790  if(hashAlgoId == 0)
791  {
792  //Loop through the list of signature hash algorithms
793  for(n = preferredHashAlgoId; n >= IKE_HASH_ALGO_SHA1; n--)
794  {
795  //Check whether the current hash algorithm is supported by the peer
796  if((sa->signHashAlgos & (1U << n)) != 0)
797  {
798  hashAlgoId = n;
799  break;
800  }
801  }
802  }
803 
804 #if (IKE_SHA1_SUPPORT == ENABLED)
805  //SHA-1 hash algorithm?
806  if(hashAlgoId == IKE_HASH_ALGO_SHA1)
807  {
808  hashAlgo = SHA1_HASH_ALGO;
809  }
810  else
811 #endif
812 #if (IKE_SHA256_SUPPORT == ENABLED)
813  //SHA-256 hash algorithm?
814  if(hashAlgoId == IKE_HASH_ALGO_SHA256)
815  {
816  hashAlgo = SHA256_HASH_ALGO;
817  }
818  else
819 #endif
820 #if (IKE_SHA384_SUPPORT == ENABLED)
821  //SHA-384 hash algorithm?
822  if(hashAlgoId == IKE_HASH_ALGO_SHA384)
823  {
824  hashAlgo = SHA384_HASH_ALGO;
825  }
826  else
827 #endif
828 #if (IKE_SHA512_SUPPORT == ENABLED)
829  //SHA-512 hash algorithm?
830  if(hashAlgoId == IKE_HASH_ALGO_SHA512)
831  {
832  hashAlgo = SHA512_HASH_ALGO;
833  }
834  else
835 #endif
836  //Unknown hash algorithm?
837  {
838  hashAlgo = NULL;
839  }
840 
841  //Return the hash algorithm to be used for signing
842  return hashAlgo;
843 #else
844  //The digital signature method is not supported
845  return NULL;
846 #endif
847 }
848 
849 
850 /**
851  * @brief Retrieve the octets to be signed using EdDSA
852  * @param[in] sa Pointer to the IKE SA
853  * @param[in] id MAC authentication data
854  * @param[in] idLen MAC authentication data
855  * @param[out] macId Temporary buffer needed to calculate MACedID
856  * @param[out] messageChunks Collection of chunks representing the message to
857  * be signed
858  * @param[in] initiator Specifies whether the digest is performed at initiator
859  * or responder side
860  * @return Error code
861  **/
862 
863 error_t ikeGetSignedOctets(IkeSaEntry *sa, const uint8_t *id, size_t idLen,
864  uint8_t *macId, EddsaMessageChunk *messageChunks, bool_t initiator)
865 {
866  error_t error;
867 
868  //Check whether the calculation is performed at initiator side
869  if(initiator)
870  {
871  //Compute prf(SK_pi, IDi')
872  error = ikeComputePrf(sa, sa->skpi, sa->prfKeyLen, id, idLen,
873  macId);
874 
875  //Check status code
876  if(!error)
877  {
878  //The initiator signs the first message (IKE_SA_INIT request),
879  //starting with the first octet of the first SPI in the header
880  //and ending with the last octet of the last payload
881  messageChunks[0].buffer = sa->initiatorSaInit;
882  messageChunks[0].length = sa->initiatorSaInitLen;
883 
884  //Appended to this (for purposes of computing the signature)
885  //are the responder's nonce Nr, and the value prf(SK_pi, IDi')
886  messageChunks[1].buffer = sa->responderNonce;
887  messageChunks[1].length = sa->responderNonceLen;
888  messageChunks[2].buffer = macId;
889  messageChunks[2].length = sa->prfKeyLen;
890  messageChunks[3].buffer = NULL;
891  messageChunks[3].length = 0;
892  }
893  }
894  else
895  {
896  //Compute prf(SK_pr, IDr')
897  error = ikeComputePrf(sa, sa->skpr, sa->prfKeyLen, id, idLen, macId);
898 
899  //Check status code
900  if(!error)
901  {
902  //For the responder, the octets to be signed start with the
903  //first octet of the first SPI in the header of the second
904  //message (IKE_SA_INIT response) and end with the last octet
905  //of the last payload in the second message
906  messageChunks[0].buffer = sa->responderSaInit;
907  messageChunks[0].length = sa->responderSaInitLen;
908 
909  //Appended to this (for purposes of computing the signature)
910  //are the initiator's nonce Ni, and the value prf(SK_pr, IDr')
911  messageChunks[1].buffer = sa->initiatorNonce;
912  messageChunks[1].length = sa->initiatorNonceLen;
913  messageChunks[2].buffer = macId;
914  messageChunks[2].length = sa->prfKeyLen;
915  messageChunks[3].buffer = NULL;
916  messageChunks[3].length = 0;
917  }
918  }
919 
920  //Successful processing
921  return NO_ERROR;
922 }
923 
924 
925 /**
926  * @brief Digest signed octets
927  * @param[in] sa Pointer to the IKE SA
928  * @param[in] hashAlgo Underlying hash function
929  * @param[in] id MAC authentication data
930  * @param[in] idLen MAC authentication data
931  * @param[out] digest Calculated digest
932  * @param[in] initiator Specifies whether the digest is performed at initiator
933  * or responder side
934  * @return Error code
935  **/
936 
938  const uint8_t *id, size_t idLen, uint8_t *digest, bool_t initiator)
939 {
940  error_t error;
941  HashContext hashContext;
942  uint8_t macId[MAX_HASH_DIGEST_SIZE];
943 
944  //Check whether the calculation is performed at initiator side
945  if(initiator)
946  {
947  //Compute prf(SK_pi, IDi')
948  error = ikeComputePrf(sa, sa->skpi, sa->prfKeyLen, id, idLen, macId);
949 
950  //Check status code
951  if(!error)
952  {
953  //The initiator signs the first message (IKE_SA_INIT request), starting
954  //with the first octet of the first SPI in the header and ending with
955  //the last octet of the last payload
956  hashAlgo->init(&hashContext);
957  hashAlgo->update(&hashContext, sa->initiatorSaInit, sa->initiatorSaInitLen);
958 
959  //Appended to this (for purposes of computing the signature) are the
960  //responder's nonce Nr, and the value prf(SK_pi, IDi')
961  hashAlgo->update(&hashContext, sa->responderNonce, sa->responderNonceLen);
962  hashAlgo->update(&hashContext, macId, sa->prfKeyLen);
963  hashAlgo->final(&hashContext, digest);
964  }
965  }
966  else
967  {
968  //Compute prf(SK_pr, IDr')
969  error = ikeComputePrf(sa, sa->skpr, sa->prfKeyLen, id, idLen, macId);
970 
971  //Check status code
972  if(!error)
973  {
974  //For the responder, the octets to be signed start with the first octet
975  //of the first SPI in the header of the second message (IKE_SA_INIT
976  //response) and end with the last octet of the last payload in the
977  //second message
978  hashAlgo->init(&hashContext);
979  hashAlgo->update(&hashContext, sa->responderSaInit, sa->responderSaInitLen);
980 
981  //Appended to this (for purposes of computing the signature) are the
982  //initiator's nonce Ni, and the value prf(SK_pr, IDr')
983  hashAlgo->update(&hashContext, sa->initiatorNonce, sa->initiatorNonceLen);
984  hashAlgo->update(&hashContext, macId, sa->prfKeyLen);
985  hashAlgo->final(&hashContext, digest);
986  }
987  }
988 
989  //Return status code
990  return error;
991 }
992 
993 #endif
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
uint8_t n
error_t dsaReadSignature(const uint8_t *data, size_t length, DsaSignature *signature)
Read an ASN.1 encoded DSA signature.
Definition: dsa.c:349
const uint8_t DSA_WITH_SHA384_OID[9]
Definition: dsa.c:59
const uint8_t DSA_WITH_SHA512_OID[9]
Definition: dsa.c:61
const uint8_t DSA_WITH_SHA1_OID[7]
Definition: dsa.c:53
error_t dsaWriteSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Encode DSA signature using ASN.1.
Definition: dsa.c:193
const uint8_t DSA_WITH_SHA256_OID[9]
Definition: dsa.c:57
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:98
const uint8_t ED448_OID[3]
Definition: ec_curves.c:100
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
error_t ecdsaReadSignature(const uint8_t *data, size_t length, EcdsaSignature *signature)
Read an ASN.1 encoded ECDSA signature.
Definition: ecdsa.c:260
const uint8_t ECDSA_WITH_SHA256_OID[8]
Definition: ecdsa.c:49
const uint8_t ECDSA_WITH_SHA384_OID[8]
Definition: ecdsa.c:51
const uint8_t ECDSA_WITH_SHA512_OID[8]
Definition: ecdsa.c:53
const uint8_t ECDSA_WITH_SHA1_OID[7]
Definition: ecdsa.c:45
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_TYPE
Definition: error.h:115
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_INVALID_SIGNATURE_ALGO
Definition: error.h:134
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t data[]
Definition: ethernet.h:222
#define MAX_HASH_DIGEST_SIZE
IKEv2 (Internet Key Exchange Protocol)
@ 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
IkeCertType
Certificate types.
Definition: ike.h:1222
@ IKE_CERT_TYPE_ECDSA_P384
Definition: ike.h:1228
@ IKE_CERT_TYPE_ECDSA_P521
Definition: ike.h:1229
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP256R1
Definition: ike.h:1230
@ IKE_CERT_TYPE_RSA_PSS
Definition: ike.h:1225
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP512R1
Definition: ike.h:1232
@ IKE_CERT_TYPE_RSA
Definition: ike.h:1224
@ IKE_CERT_TYPE_DSA
Definition: ike.h:1226
@ IKE_CERT_TYPE_ED25519
Definition: ike.h:1233
@ IKE_CERT_TYPE_ED448
Definition: ike.h:1234
@ IKE_CERT_TYPE_ECDSA_P256
Definition: ike.h:1227
@ IKE_CERT_TYPE_ECDSA_BRAINPOOLP384R1
Definition: ike.h:1231
#define IkeSaEntry
Definition: ike.h:682
#define IKE_SHA1_DIGEST_SIZE
Definition: ike.h:674
IKEv2 algorithm negotiation.
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)
Key material generation.
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 ikeGetSignedOctets(IkeSaEntry *sa, const uint8_t *id, size_t idLen, uint8_t *macId, EddsaMessageChunk *messageChunks, bool_t initiator)
Retrieve the octets to be signed using EdDSA.
error_t ikeDigestSignedOctets(IkeSaEntry *sa, const HashAlgo *hashAlgo, const uint8_t *id, size_t idLen, uint8_t *digest, bool_t initiator)
Digest signed octets.
error_t ikeParseEcdsaSignature(EcDomainParameters *params, const uint8_t *data, size_t length, EcdsaSignature *signature, IkeSignFormat format)
ECDSA signature parsing.
error_t ikeParseDsaSignature(const uint8_t *data, size_t length, DsaSignature *signature, IkeSignFormat format)
DSA signature parsing.
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
error_t ikeFormatEcdsaSignature(EcDomainParameters *params, const EcdsaSignature *signature, uint8_t *data, size_t *length, IkeSignFormat format)
ECDSA signature formatting.
error_t ikeSelectSignAlgo(const X509SignAlgoId *signAlgoId, IkeSignAlgo *signAlgo, const HashAlgo **hashAlgo)
Select the signature and hash algorithms that match the specified identifier.
Helper functions for signature generation and verification.
IkeSignFormat
Signature format.
Definition: ike_sign_misc.h:48
@ IKE_SIGN_FORMAT_RAW
Definition: ike_sign_misc.h:49
@ IKE_SIGN_FORMAT_ASN1
Definition: ike_sign_misc.h:50
IkeSignAlgo
Signature algorithms.
Definition: ike_sign_misc.h:59
@ IKE_SIGN_ALGO_ECDSA
Definition: ike_sign_misc.h:64
@ IKE_SIGN_ALGO_RSA
Definition: ike_sign_misc.h:61
@ IKE_SIGN_ALGO_DSA
Definition: ike_sign_misc.h:63
@ IKE_SIGN_ALGO_ED25519
Definition: ike_sign_misc.h:65
@ IKE_SIGN_ALGO_RSA_PSS
Definition: ike_sign_misc.h:62
@ IKE_SIGN_ALGO_ED448
Definition: ike_sign_misc.h:66
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
const uint8_t MGF1_OID[9]
Definition: rsa.c:91
const uint8_t SHA384_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:70
const uint8_t SHA256_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:68
const uint8_t SHA1_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:64
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
const uint8_t SHA512_WITH_RSA_ENCRYPTION_OID[9]
Definition: rsa.c:72
const uint8_t SHA1_OID[5]
Definition: sha1.c:73
#define SHA1_HASH_ALGO
Definition: sha1.h:49
const uint8_t SHA256_OID[9]
Definition: sha256.c:80
#define SHA256_HASH_ALGO
Definition: sha256.h:49
const uint8_t SHA384_OID[9]
Definition: sha384.c:47
#define SHA384_HASH_ALGO
Definition: sha384.h:45
const uint8_t SHA512_OID[9]
Definition: sha512.c:97
#define SHA512_HASH_ALGO
Definition: sha512.h:49
DSA signature.
Definition: dsa.h:84
Mpi s
Definition: dsa.h:86
Mpi r
Definition: dsa.h:85
EC domain parameters.
Definition: ec.h:76
Mpi p
Prime.
Definition: ec.h:79
ECDSA signature.
Definition: ecdsa.h:49
Message chunk descriptor.
Definition: eddsa.h:71
const void * buffer
Definition: eddsa.h:72
size_t length
Definition: eddsa.h:73
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoFinal final
Definition: crypto.h:1026
HashAlgoUpdate update
Definition: crypto.h:1025
size_t oidSize
Definition: crypto.h:1017
size_t digestSize
Definition: crypto.h:1020
HashAlgoInit init
Definition: crypto.h:1024
const uint8_t * oid
Definition: crypto.h:1016
const uint8_t * value
Definition: x509_common.h:647
X509OctetString maskGenHashAlgo
Definition: x509_common.h:1023
X509OctetString hashAlgo
Definition: x509_common.h:1021
X509OctetString maskGenAlgo
Definition: x509_common.h:1022
Signature algorithm identifier.
Definition: x509_common.h:1033
X509OctetString oid
Definition: x509_common.h:1034
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:1036
uint8_t length
Definition: tcp.h:368
Generic hash algorithm context.