ike_sign_generate.c
Go to the documentation of this file.
1 /**
2  * @file ike_sign_generate.c
3  * @brief RSA/DSA/ECDSA/EdDSA signature generation
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_generate.h"
38 #include "pkix/pem_import.h"
39 #include "pkix/x509_sign_format.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 Signature generation
48  * @param[in] sa Pointer to the IKE SA
49  * @param[in] id Pointer to the identification data
50  * @param[in] idLen Length of the identification data, in bytes
51  * @param[out] authMethod Authentication method
52  * @param[out] signature Output stream where to write the signature
53  * @param[out] signatureLen Total number of bytes that have been written
54  * @return Error code
55  **/
56 
57 error_t ikeGenerateSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen,
58  uint8_t *authMethod, uint8_t *signature, size_t *signatureLen)
59 {
60  error_t error;
61  IkeContext *context;
62 
63  //Point to the IKE context
64  context = sa->context;
65 
66 #if (IKE_SIGN_HASH_ALGOS_SUPPORT == ENABLED)
67  //Digital signature method?
68  if(sa->signHashAlgos != 0)
69  {
70  //The peer is only allowed to use the "Digital Signature" authentication
71  //method if the Notify payload of type SIGNATURE_HASH_ALGORITHMS has been
72  //sent and received by each peer (refer to RFC 7427, section 3)
74 
75  //The new digital signature method is flexible enough to include all
76  //current signature methods (RSA, RSA-PSS, DSA, ECDSA and EdDSA) and add
77  //new methods in the future
78  error = ikeGenerateDigitalSignature(sa, id, idLen,
79  (IkeAuthData *) signature, signatureLen);
80  }
81  else
82 #endif
83 #if (IKE_RSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
84  //RSA signature algorithm?
85  if(context->certType == IKE_CERT_TYPE_RSA)
86  {
87  //Set authentication method
89 
90  //Generate an RSA signature using the entity's private key
91  error = ikeGenerateRsaSignature(sa, id, idLen, SHA1_HASH_ALGO, signature,
92  signatureLen);
93  }
94  else
95 #endif
96 #if (IKE_DSA_SIGN_SUPPORT == ENABLED && IKE_SHA1_SUPPORT == ENABLED)
97  //DSA signature method?
98  if(context->certType == IKE_CERT_TYPE_DSA)
99  {
100  //Set authentication method
102 
103  //Generate an DSA signature using the entity's private key
104  error = ikeGenerateDsaSignature(sa, id, idLen, SHA1_HASH_ALGO, signature,
105  signatureLen, IKE_SIGN_FORMAT_RAW);
106  }
107  else
108 #endif
109 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_256_SUPPORT == ENABLED && \
110  IKE_SHA256_SUPPORT == ENABLED)
111  //ECDSA with NIST P-256 signature method?
112  if(context->certType == IKE_CERT_TYPE_ECDSA_P256)
113  {
114  //Set authentication method
116 
117  //Generate an ECDSA signature using the entity's private key
118  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP256R1_CURVE,
119  SHA256_HASH_ALGO, signature, signatureLen, IKE_SIGN_FORMAT_RAW);
120  }
121  else
122 #endif
123 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_384_SUPPORT == ENABLED && \
124  IKE_SHA384_SUPPORT == ENABLED)
125  //ECDSA with NIST P-384 signature method?
126  if(context->certType == IKE_CERT_TYPE_ECDSA_P384)
127  {
128  //Set authentication method
130 
131  //Generate an ECDSA signature using the entity's private key
132  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP384R1_CURVE,
133  SHA384_HASH_ALGO, signature, signatureLen, IKE_SIGN_FORMAT_RAW);
134  }
135  else
136 #endif
137 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_521_SUPPORT == ENABLED && \
138  IKE_SHA512_SUPPORT == ENABLED)
139  //ECDSA with NIST P-521 signature method?
140  if(context->certType == IKE_CERT_TYPE_ECDSA_P521)
141  {
142  //Set authentication method
144 
145  //Generate an ECDSA signature using the entity's private key
146  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP521R1_CURVE,
147  SHA512_HASH_ALGO, signature, signatureLen, IKE_SIGN_FORMAT_RAW);
148  }
149  else
150 #endif
151  //Invalid signature method?
152  {
153  //Report an error
155  }
156 
157  //Return status code
158  return error;
159 }
160 
161 
162 /**
163  * @brief Digital signature generation
164  * @param[in] sa Pointer to the IKE SA
165  * @param[in] id Pointer to the identification data
166  * @param[in] idLen Length of the identification data, in bytes
167  * @param[out] authData Output stream where to write the authentication data
168  * @param[out] authDataLen Total number of bytes that have been written
169  * @return Error code
170  **/
171 
173  size_t idLen, IkeAuthData *authData, size_t *authDataLen)
174 {
175  error_t error;
176  size_t n;
177  uint8_t *signature;
178  const HashAlgo *hashAlgo;
179  IkeContext *context;
180  X509SignAlgoId signAlgoId;
181 
182  //Point to the IKE context
183  context = sa->context;
184 
185  //When calculating the digital signature, a peer must pick one algorithm
186  //sent by the other peer (refer to RFC 7427, section 4)
187  if(context->certType == IKE_CERT_TYPE_RSA ||
188  context->certType == IKE_CERT_TYPE_RSA_PSS ||
189  context->certType == IKE_CERT_TYPE_DSA ||
190  context->certType == IKE_CERT_TYPE_ECDSA_P256 ||
191  context->certType == IKE_CERT_TYPE_ECDSA_BRAINPOOLP256R1)
192  {
193  //The preferred signature hash algorithm is SHA-256
195  }
196  else if(context->certType == IKE_CERT_TYPE_ECDSA_P384 ||
197  context->certType == IKE_CERT_TYPE_ECDSA_BRAINPOOLP384R1)
198  {
199  //The preferred signature hash algorithm is SHA-384
201  }
202  else if(context->certType == IKE_CERT_TYPE_ECDSA_P521 ||
203  context->certType == IKE_CERT_TYPE_ECDSA_BRAINPOOLP512R1)
204  {
205  //The preferred signature hash algorithm is SHA-512
207  }
208  else
209  {
210  hashAlgo = NULL;
211  }
212 
213  //Select the algorithm identifier that matches the specified certificate
214  //type and hash algorithms
215  error = ikeSelectSignAlgoId(context->certType, hashAlgo, &signAlgoId);
216 
217  //Check status code
218  if(!error)
219  {
220  //The signature value is prefixed with an ASN.1 object indicating the
221  //algorithm used to generate the signature (refer to RFC 7427, section 3)
222  error = x509FormatSignatureAlgo(&signAlgoId, authData->algoId, &n);
223  }
224 
225  //Check status code
226  if(!error)
227  {
228  //Set the length of the ASN.1 object
229  authData->algoIdLen = (uint8_t) n;
230 
231  //There is no padding between the ASN.1 object and the signature value
232  signature = authData->algoId + authData->algoIdLen;
233 
234 #if (IKE_RSA_SIGN_SUPPORT == ENABLED)
235  //RSA signature algorithm?
236  if(context->certType == IKE_CERT_TYPE_RSA)
237  {
238  //Generate an RSA signature using the entity's private key
239  error = ikeGenerateRsaSignature(sa, id, idLen, hashAlgo, signature,
240  &n);
241  }
242  else
243 #endif
244 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
245  //RSA-PSS signature algorithm?
246  if(context->certType == IKE_CERT_TYPE_RSA_PSS)
247  {
248  //Generate an RSA-PSS signature using the entity's private key
249  error = ikeGenerateRsaPssSignature(sa, id, idLen, hashAlgo,
250  signAlgoId.rsaPssParams.saltLen, signature, &n);
251  }
252  else
253 #endif
254 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
255  //DSA signature method?
256  if(context->certType == IKE_CERT_TYPE_DSA)
257  {
258  //Generate an DSA signature using the entity's private key
259  error = ikeGenerateDsaSignature(sa, id, idLen, hashAlgo, signature,
261  }
262  else
263 #endif
264 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_256_SUPPORT == ENABLED)
265  //ECDSA with NIST P-256 signature method?
266  if(context->certType == IKE_CERT_TYPE_ECDSA_P256)
267  {
268  //Generate an ECDSA signature using the entity's private key
269  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP256R1_CURVE,
270  hashAlgo, signature, &n, IKE_SIGN_FORMAT_ASN1);
271  }
272  else
273 #endif
274 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_384_SUPPORT == ENABLED)
275  //ECDSA with NIST P-384 signature method?
276  if(context->certType == IKE_CERT_TYPE_ECDSA_P384)
277  {
278  //Generate an ECDSA signature using the entity's private key
279  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP384R1_CURVE,
280  hashAlgo, signature, &n, IKE_SIGN_FORMAT_ASN1);
281  }
282  else
283 #endif
284 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED && IKE_ECP_521_SUPPORT == ENABLED)
285  //ECDSA with NIST P-521 signature method?
286  if(context->certType == IKE_CERT_TYPE_ECDSA_P521)
287  {
288  //Generate an ECDSA signature using the entity's private key
289  error = ikeGenerateEcdsaSignature(sa, id, idLen, SECP521R1_CURVE,
290  hashAlgo, signature, &n, IKE_SIGN_FORMAT_ASN1);
291  }
292  else
293 #endif
294 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
295  //Ed25519 signature method?
296  if(context->certType == IKE_CERT_TYPE_ED25519)
297  {
298  //Generate an Ed25519 signature using the entity's private key
299  error = ikeGenerateEd25519Signature(sa, id, idLen, signature, &n);
300  }
301  else
302 #endif
303 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
304  //Ed448 signature method?
305  if(context->certType == IKE_CERT_TYPE_ED448)
306  {
307  //Generate an Ed448 signature using the entity's private key
308  error = ikeGenerateEd448Signature(sa, id, idLen, signature, &n);
309  }
310  else
311 #endif
312  //Invalid signature method?
313  {
314  //Report an error
316  }
317  }
318 
319  //Check status code
320  if(!error)
321  {
322  //Total length of the authentication data
323  *authDataLen = sizeof(IkeAuthData) + authData->algoIdLen + n;
324  }
325 
326  //Return status code
327  return error;
328 }
329 
330 
331 /**
332  * @brief RSA signature generation
333  * @param[in] sa Pointer to the IKE SA
334  * @param[in] id Pointer to the identification data
335  * @param[in] idLen Length of the identification data, in bytes
336  * @param[in] hashAlgo Hash algorithm
337  * @param[out] signature Output stream where to write the signature
338  * @param[out] signatureLen Total number of bytes that have been written
339  * @return Error code
340  **/
341 
343  size_t idLen, const HashAlgo *hashAlgo, uint8_t *signature,
344  size_t *signatureLen)
345 {
346 #if (IKE_RSA_SIGN_SUPPORT == ENABLED)
347  error_t error;
348  IkeContext *context;
349  RsaPrivateKey rsaPrivateKey;
350  uint8_t digest[MAX_HASH_DIGEST_SIZE];
351 
352  //Point to the IKE context
353  context = sa->context;
354 
355  //Initialize RSA private key
356  rsaInitPrivateKey(&rsaPrivateKey);
357 
358  //Digest signed octets
359  error = ikeDigestSignedOctets(sa, hashAlgo, id, idLen, digest,
360  sa->originalInitiator);
361 
362  //Check status code
363  if(!error)
364  {
365  //Import RSA private key
366  error = pemImportRsaPrivateKey(context->privateKey,
367  context->privateKeyLen, context->password, &rsaPrivateKey);
368  }
369 
370  //Check status code
371  if(!error)
372  {
373  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
374  error = rsassaPkcs1v15Sign(&rsaPrivateKey, hashAlgo, digest, signature,
375  signatureLen);
376  }
377 
378  //Free previously allocated memory
379  rsaFreePrivateKey(&rsaPrivateKey);
380 
381  //Return status code
382  return error;
383 #else
384  //Not implemented
385  return ERROR_NOT_IMPLEMENTED;
386 #endif
387 }
388 
389 
390 /**
391  * @brief RSA-PSS signature generation
392  * @param[in] sa Pointer to the IKE SA
393  * @param[in] id Pointer to the identification data
394  * @param[in] idLen Length of the identification data, in bytes
395  * @param[in] hashAlgo Hash algorithm
396  * @param[in] saltLen Length of the salt, in bytes
397  * @param[out] signature Output stream where to write the signature
398  * @param[out] signatureLen Total number of bytes that have been written
399  * @return Error code
400  **/
401 
403  size_t idLen, const HashAlgo *hashAlgo, size_t saltLen, uint8_t *signature,
404  size_t *signatureLen)
405 {
406 #if (IKE_RSA_PSS_SIGN_SUPPORT == ENABLED)
407  error_t error;
408  IkeContext *context;
409  RsaPrivateKey rsaPrivateKey;
410  uint8_t digest[MAX_HASH_DIGEST_SIZE];
411 
412  //Point to the IKE context
413  context = sa->context;
414 
415  //Initialize RSA private key
416  rsaInitPrivateKey(&rsaPrivateKey);
417 
418  //Digest signed octets
419  error = ikeDigestSignedOctets(sa, hashAlgo, id, idLen, digest,
420  sa->originalInitiator);
421 
422  //Check status code
423  if(!error)
424  {
425  //Import RSA private key
426  error = pemImportRsaPrivateKey(context->privateKey,
427  context->privateKeyLen, context->password, &rsaPrivateKey);
428  }
429 
430  //Check status code
431  if(!error)
432  {
433  //Generate RSA signature (RSASSA-PSS signature scheme)
434  error = rsassaPssSign(context->prngAlgo, context->prngContext,
435  &rsaPrivateKey, hashAlgo, saltLen, digest, signature, signatureLen);
436  }
437 
438  //Free previously allocated memory
439  rsaFreePrivateKey(&rsaPrivateKey);
440 
441  //Return status code
442  return error;
443 #else
444  //Not implemented
445  return ERROR_NOT_IMPLEMENTED;
446 #endif
447 }
448 
449 
450 /**
451  * @brief DSA signature generation
452  * @param[in] sa Pointer to the IKE SA
453  * @param[in] id Pointer to the identification data
454  * @param[in] idLen Length of the identification data, in bytes
455  * @param[in] hashAlgo Hash algorithm
456  * @param[out] signature Output stream where to write the signature
457  * @param[out] signatureLen Total number of bytes that have been written
458  * @param[in] format Signature format (raw or ASN.1)
459  * @return Error code
460  **/
461 
463  size_t idLen, const HashAlgo *hashAlgo, uint8_t *signature,
464  size_t *signatureLen, IkeSignFormat format)
465 {
466 #if (IKE_DSA_SIGN_SUPPORT == ENABLED)
467  error_t error;
468  IkeContext *context;
469  DsaPrivateKey dsaPrivateKey;
470  DsaSignature dsaSignature;
471  uint8_t digest[MAX_HASH_DIGEST_SIZE];
472 
473  //Point to the IKE context
474  context = sa->context;
475 
476  //Initialize DSA private key
477  dsaInitPrivateKey(&dsaPrivateKey);
478  //Initialize DSA signature
479  dsaInitSignature(&dsaSignature);
480 
481  //Digest signed octets
482  error = ikeDigestSignedOctets(sa, hashAlgo, id, idLen, digest,
483  sa->originalInitiator);
484 
485  //Check status code
486  if(!error)
487  {
488  //Import DSA private key
489  error = pemImportDsaPrivateKey(context->privateKey,
490  context->privateKeyLen, context->password, &dsaPrivateKey);
491  }
492 
493  //Check status code
494  if(!error)
495  {
496  //Generate DSA signature
497  error = dsaGenerateSignature(context->prngAlgo, context->prngContext,
498  &dsaPrivateKey, digest, hashAlgo->digestSize, &dsaSignature);
499  }
500 
501  //Check status code
502  if(!error)
503  {
504  //Encode (R, S) integer pair
505  error = ikeFormatDsaSignature(&dsaSignature, signature, signatureLen,
506  format);
507  }
508 
509  //Free previously allocated memory
510  dsaFreePrivateKey(&dsaPrivateKey);
511  dsaFreeSignature(&dsaSignature);
512 
513  //Return status code
514  return error;
515 #else
516  //Not implemented
517  return ERROR_NOT_IMPLEMENTED;
518 #endif
519 }
520 
521 
522 /**
523  * @brief ECDSA signature generation
524  * @param[in] sa Pointer to the IKE SA
525  * @param[in] id Pointer to the identification data
526  * @param[in] idLen Length of the identification data, in bytes
527  * @param[in] curveInfo Elliptic curve parameters
528  * @param[in] hashAlgo Hash algorithm
529  * @param[out] signature Output stream where to write the signature
530  * @param[out] signatureLen Total number of bytes that have been written
531  * @param[in] format Signature format (raw or ASN.1)
532  * @return Error code
533  **/
534 
536  size_t idLen, const EcCurveInfo *curveInfo, const HashAlgo *hashAlgo,
537  uint8_t *signature, size_t *signatureLen, IkeSignFormat format)
538 {
539 #if (IKE_ECDSA_SIGN_SUPPORT == ENABLED)
540  error_t error;
541  IkeContext *context;
542  EcDomainParameters ecParams;
543  EcPrivateKey ecPrivateKey;
544  EcdsaSignature ecdsaSignature;
545  uint8_t digest[MAX_HASH_DIGEST_SIZE];
546 
547  //Point to the IKE context
548  context = sa->context;
549 
550  //Initialize EC domain parameters
551  ecInitDomainParameters(&ecParams);
552  //Initialize EC private key
553  ecInitPrivateKey(&ecPrivateKey);
554  //Initialize ECDSA signature
555  ecdsaInitSignature(&ecdsaSignature);
556 
557  //Digest signed octets
558  error = ikeDigestSignedOctets(sa, hashAlgo, id, idLen, digest,
559  sa->originalInitiator);
560 
561  //Check status code
562  if(!error)
563  {
564  //Load EC domain parameters
565  error = ecLoadDomainParameters(&ecParams, curveInfo);
566  }
567 
568  //Check status code
569  if(!error)
570  {
571  //Import EC private key
572  error = pemImportEcPrivateKey(context->privateKey,
573  context->privateKeyLen, context->password, &ecPrivateKey);
574  }
575 
576  //Check status code
577  if(!error)
578  {
579  //Generate ECDSA signature
580  error = ecdsaGenerateSignature(context->prngAlgo, context->prngContext,
581  &ecParams, &ecPrivateKey, digest, hashAlgo->digestSize,
582  &ecdsaSignature);
583  }
584 
585  //Check status code
586  if(!error)
587  {
588  //Encode (R, S) integer pair
589  error = ikeFormatEcdsaSignature(&ecParams, &ecdsaSignature, signature,
590  signatureLen, format);
591  }
592 
593  //Free previously allocated memory
594  ecFreeDomainParameters(&ecParams);
595  ecFreePrivateKey(&ecPrivateKey);
596  ecdsaFreeSignature(&ecdsaSignature);
597 
598  //Return status code
599  return error;
600 #else
601  //Not implemented
602  return ERROR_NOT_IMPLEMENTED;
603 #endif
604 }
605 
606 
607 /**
608  * @brief Ed25519 signature generation
609  * @param[in] sa Pointer to the IKE SA
610  * @param[in] id Pointer to the identification data
611  * @param[in] idLen Length of the identification data, in bytes
612  * @param[out] signature Output stream where to write the signature
613  * @param[out] signatureLen Total number of bytes that have been written
614  * @return Error code
615  **/
616 
618  size_t idLen, uint8_t *signature, size_t *signatureLen)
619 {
620 #if (IKE_ED25519_SIGN_SUPPORT == ENABLED)
621  error_t error;
622  IkeContext *context;
623  EddsaPrivateKey ed25519PrivateKey;
624  EddsaMessageChunk messageChunks[4];
625  uint8_t macId[MAX_HASH_DIGEST_SIZE];
626  uint8_t d[ED25519_PRIVATE_KEY_LEN];
627 
628  //Point to the IKE context
629  context = sa->context;
630 
631  //Initialize Ed25519 private key
632  eddsaInitPrivateKey(&ed25519PrivateKey);
633 
634  //Data to be signed is run through the EdDSA algorithm without pre-hashing
635  error = ikeGetSignedOctets(sa, id, idLen, macId, messageChunks,
636  sa->originalInitiator);
637 
638  //Check status code
639  if(!error)
640  {
641  //Import Ed25519 private key
642  error = pemImportEddsaPrivateKey(context->privateKey,
643  context->privateKeyLen, context->password, &ed25519PrivateKey);
644  }
645 
646  //Check status code
647  if(!error)
648  {
649  //Retrieve raw private key
650  error = mpiExport(&ed25519PrivateKey.d, d, ED25519_PRIVATE_KEY_LEN,
652  }
653 
654  //Check status code
655  if(!error)
656  {
657  //Generate Ed25519 signature
658  error = ed25519GenerateSignatureEx(d, NULL, messageChunks, NULL, 0, 0,
659  signature);
660  }
661 
662  //Check status code
663  if(!error)
664  {
665  //The Ed25519 signature consists of 32 octets
666  *signatureLen = ED25519_SIGNATURE_LEN;
667  }
668 
669  //Free previously allocated memory
670  eddsaFreePrivateKey(&ed25519PrivateKey);
671 
672  //Return status code
673  return error;
674 #else
675  //Not implemented
676  return ERROR_NOT_IMPLEMENTED;
677 #endif
678 }
679 
680 
681 /**
682  * @brief Ed448 signature generation
683  * @param[in] sa Pointer to the IKE SA
684  * @param[in] id Pointer to the identification data
685  * @param[in] idLen Length of the identification data, in bytes
686  * @param[out] signature Output stream where to write the signature
687  * @param[out] signatureLen Total number of bytes that have been written
688  * @return Error code
689  **/
690 
692  size_t idLen, uint8_t *signature, size_t *signatureLen)
693 {
694 #if (IKE_ED448_SIGN_SUPPORT == ENABLED)
695  error_t error;
696  IkeContext *context;
697  EddsaPrivateKey ed448PrivateKey;
698  EddsaMessageChunk messageChunks[4];
699  uint8_t macId[MAX_HASH_DIGEST_SIZE];
700  uint8_t d[ED448_PRIVATE_KEY_LEN];
701 
702  //Point to the IKE context
703  context = sa->context;
704 
705  //Initialize Ed448 private key
706  eddsaInitPrivateKey(&ed448PrivateKey);
707 
708  //Data to be signed is run through the EdDSA algorithm without pre-hashing
709  error = ikeGetSignedOctets(sa, id, idLen, macId, messageChunks,
710  sa->originalInitiator);
711 
712  //Check status code
713  if(!error)
714  {
715  //Import Ed448 private key
716  error = pemImportEddsaPrivateKey(context->privateKey,
717  context->privateKeyLen, context->password, &ed448PrivateKey);
718  }
719 
720  //Check status code
721  if(!error)
722  {
723  //Retrieve raw private key
724  error = mpiExport(&ed448PrivateKey.d, d, ED448_PRIVATE_KEY_LEN,
726  }
727 
728  //Check status code
729  if(!error)
730  {
731  //Generate Ed448 signature
732  error = ed448GenerateSignatureEx(d, NULL, messageChunks, NULL, 0, 0,
733  signature);
734  }
735 
736  //Check status code
737  if(!error)
738  {
739  //The Ed448 signature consists of 32 octets
740  *signatureLen = ED448_SIGNATURE_LEN;
741  }
742 
743  //Free previously allocated memory
744  eddsaFreePrivateKey(&ed448PrivateKey);
745 
746  //Return status code
747  return error;
748 #else
749  //Not implemented
750  return ERROR_NOT_IMPLEMENTED;
751 #endif
752 }
753 
754 #endif
Debugging facilities.
uint8_t n
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:150
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:164
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:177
error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen, DsaSignature *signature)
DSA signature generation.
Definition: dsa.c:484
void dsaInitPrivateKey(DsaPrivateKey *key)
Initialize a DSA private key.
Definition: dsa.c:133
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
void ecFreePrivateKey(EcPrivateKey *key)
Release an EdDSA private key.
Definition: ec.c:192
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
void ecInitPrivateKey(EcPrivateKey *key)
Initialize an EC private key.
Definition: ec.c:177
#define SECP521R1_CURVE
Definition: ec_curves.h:242
#define SECP256R1_CURVE
Definition: ec_curves.h:240
#define SECP384R1_CURVE
Definition: ec_curves.h:241
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:397
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
error_t ed25519GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:271
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
error_t ed448GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:258
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
void eddsaFreePrivateKey(EddsaPrivateKey *key)
Release an EdDSA private key.
Definition: eddsa.c:89
void eddsaInitPrivateKey(EddsaPrivateKey *key)
Initialize an EdDSA private key.
Definition: eddsa.c:73
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define MAX_HASH_DIGEST_SIZE
IKEv2 (Internet Key Exchange Protocol)
@ IKE_AUTH_METHOD_DSS
DSS Digital Signature.
Definition: ike.h:989
@ IKE_AUTH_METHOD_ECDSA_P256_SHA256
ECDSA with SHA-256 on the P-256 curve.
Definition: ike.h:990
@ IKE_AUTH_METHOD_DIGITAL_SIGN
Digital Signature.
Definition: ike.h:995
@ IKE_AUTH_METHOD_ECDSA_P384_SHA384
ECDSA with SHA-384 on the P-384 curve.
Definition: ike.h:991
@ IKE_AUTH_METHOD_RSA
RSA Digital Signature.
Definition: ike.h:987
@ IKE_AUTH_METHOD_ECDSA_P521_SHA512
ECDSA with SHA-512 on the P-521 curve.
Definition: ike.h:992
#define IkeContext
Definition: ike.h:678
@ 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_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
IkeAuthData
Definition: ike.h:1414
uint8_t authMethod
Definition: ike.h:1400
IKEv2 algorithm negotiation.
error_t ikeGenerateSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, uint8_t *authMethod, uint8_t *signature, size_t *signatureLen)
Signature generation.
error_t ikeGenerateEd448Signature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, uint8_t *signature, size_t *signatureLen)
Ed448 signature generation.
error_t ikeGenerateDigitalSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, IkeAuthData *authData, size_t *authDataLen)
Digital signature generation.
error_t ikeGenerateDsaSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, const HashAlgo *hashAlgo, uint8_t *signature, size_t *signatureLen, IkeSignFormat format)
DSA signature generation.
error_t ikeGenerateRsaSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, const HashAlgo *hashAlgo, uint8_t *signature, size_t *signatureLen)
RSA signature generation.
error_t ikeGenerateEd25519Signature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, uint8_t *signature, size_t *signatureLen)
Ed25519 signature generation.
error_t ikeGenerateEcdsaSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, const EcCurveInfo *curveInfo, const HashAlgo *hashAlgo, uint8_t *signature, size_t *signatureLen, IkeSignFormat format)
ECDSA signature generation.
error_t ikeGenerateRsaPssSignature(IkeSaEntry *sa, const uint8_t *id, size_t idLen, const HashAlgo *hashAlgo, size_t saltLen, uint8_t *signature, size_t *signatureLen)
RSA-PSS signature generation.
RSA/DSA/ECDSA/EdDSA signature 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.
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.
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
uint8_t authData[]
Definition: ipv6.h:344
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_LITTLE_ENDIAN
Definition: mpi.h:70
error_t pemImportEcPrivateKey(const char_t *input, size_t length, const char_t *password, EcPrivateKey *privateKey)
Decode a PEM file containing an EC private key.
Definition: pem_import.c:1163
error_t pemImportEddsaPrivateKey(const char_t *input, size_t length, const char_t *password, EddsaPrivateKey *privateKey)
Decode a PEM file containing a EdDSA private key.
Definition: pem_import.c:1450
error_t pemImportDsaPrivateKey(const char_t *input, size_t length, const char_t *password, DsaPrivateKey *privateKey)
Decode a PEM file containing a DSA private key.
Definition: pem_import.c:676
error_t pemImportRsaPrivateKey(const char_t *input, size_t length, const char_t *password, RsaPrivateKey *privateKey)
Decode a PEM file containing an RSA private key.
Definition: pem_import.c:389
PEM file import functions.
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:153
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
Definition: rsa.c:959
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PKCS1-v1_5 signature generation operation.
Definition: rsa.c:705
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize an RSA private key.
Definition: rsa.c:131
#define SHA1_HASH_ALGO
Definition: sha1.h:49
#define SHA256_HASH_ALGO
Definition: sha256.h:49
#define SHA384_HASH_ALGO
Definition: sha384.h:45
#define SHA512_HASH_ALGO
Definition: sha512.h:49
DSA private key.
Definition: dsa.h:72
DSA signature.
Definition: dsa.h:84
Elliptic curve parameters.
Definition: ec_curves.h:295
EC domain parameters.
Definition: ec.h:76
EC private key.
Definition: ec.h:104
ECDSA signature.
Definition: ecdsa.h:49
Message chunk descriptor.
Definition: eddsa.h:71
EdDSA private key.
Definition: eddsa.h:59
Mpi d
Private key.
Definition: eddsa.h:60
Common interface for hash algorithms.
Definition: crypto.h:1014
size_t digestSize
Definition: crypto.h:1020
RSA private key.
Definition: rsa.h:68
Signature algorithm identifier.
Definition: x509_common.h:1033
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:1036
error_t x509FormatSignatureAlgo(const X509SignAlgoId *signatureAlgo, uint8_t *output, size_t *written)
Format SignatureAlgorithm structure.