Extend RFC-7427 Signature Authentication support to IKEv2 with EDDSA
This project aimed to extend the RFC-7427 Digital signature authentication scheme to support EdDSA as per RFC 8420. Since Libreswan relies on the NSS library for cryptographic operations, modifications in the NSS code were made to add the implementation of EdDSA.The mechanisms for generating Ed25519 keys, generating and verifying Ed25519 signatures were added to the NSS. As per RFC 8420, a new value “Identity” must be sent in the SIGNATURE_HASH_ALGORITHMS notification. Inserting this new value into the notification indicates that the receiver supports at least one signature algorithm that accepts messages of an arbitrary size such as Ed25519 and Ed448. Support for this new value and other code to support EdDSA was added in libreswan.
Implementation of EdDSA required code changes in the NSS crypto library as well as in libreswan itself.
The freebl is the base cryptographic layer where the primitives are implemented. The formally verified implementation (HACL* Library) of Ed25519 was integrated and EDDSA_SignDigest, EDDSA_VerifyDigest, and ED_NewKey were defined in the freebl layer. The Softoken is the PKCS #11 plumbing layer. The current PKCS #11 spec defines CKM_EDDSA mechanism to add support for EdDSA. This mechanism was implemented and the functions EDDSA_SignDigest and EDDSA_VerifyDigest were hooked into NSC_SignInit and NSC_VerifyInit using the stub functions nsc_EDDSASignStub and nsc_EDDSAVerifyStub.
The test suite of the gtests (freebl_gtest and pk11_gtest) was extended and test vectors from RFC 8032 were included. Files Hacl_Ed25519.c, Hacl_Ed25519.h, ed25519_unittest.cc, pk11_eddsa_unittest.cc, pk11_eddsa_vectors.h were added. Also, modifications were made to pk11_signature_test.h as EdDSA do not require to prehash the messages to generate and verify signatures. Other modifications were made in blapi.h, pk11table.c, ec.c, loader.c, loader.h, pk11mech.c, pkcs11c.c.
Changes were made in confread.c to parse the new eddsa option. Policy, ASN.1 Object, and structures for the public and private keys were added to libreswan. Libreswan already supported ECDSA. To avoid too much code duplication, functions were renamed and code was generalized to EC. Major modifications were made in secrets.c to generalize the code. RFC-8420 specifies that EdDSA versions that do not require prehashing of the message SHOULD be used. To signal that no hashing needs to be done, the standard defines a new value “Identity” in the SIGNATURE HASH ALGORITHMS IANA Registry. This new hash algorithm IKEv2_HASH_ALGORITHM_IDENTITY was added and its structure was defined in crypt_hash.c. To generate and verify signatures, ikev2_eddsa.c was added and changes were made to v2_calculate_sighash(), authsig_and_log_using_pubkey(), and code for AUTHBY_EDDSA was added.
To test the new code, dest_certs.py and strongswan-ec-gen.sh were extended to generate Ed25519 certificates and new test cases were added to verify feature functionality and to perform interoperability tests with strongswan to verify proper implementation.
To use EdDSA, the user must set the “authby” value of the connection in the ipsec.conf to EdDSA (authby=eddsa).
Issues encountered and Future Work
Currently, the NSS library supports curve25519 and uses it for Key Exchange but the public keys generated can not be used for the Ed25519 signature scheme even though both of these generate keys using the same curve. This is caused by NSS's public key generation code that currently uses the encoding of the “x” coordinate of a point on the Curve25519 curve. Whereas an Ed25519 public key is encoded using the “x” and “y” coordinates of a point on the Curve25519 curve.
A separate SECOID needs to be added to support Ed25519 x509 certificates. Changes need to be made to secsign.c and secvfy.c to recognize and pass around the new OID value added for Ed25519. The new OID has to be added to nss/lib/util/secoid*. The oid table will link to the CKM_EDDSA mechanism (??). With this functionality in place, kibreswan can use the EDDSA algorithm as specified in RFC 8420.
This project work was sponsored by Google as part of the Google Summer of Code 2021 Program. The implementation for this project is done by Rishabh Kumar (email@example.com) under the mentorship of Paul Wouters and Andrew Cagney.