diff --git a/libi2pd/Crypto.h b/libi2pd/Crypto.h index 43f1def9..ceaff30b 100644 --- a/libi2pd/Crypto.h +++ b/libi2pd/Crypto.h @@ -266,6 +266,9 @@ namespace crypto # define LEGACY_OPENSSL 1 #else # define LEGACY_OPENSSL 0 +# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 +# define OPENSSL_EDDSA +# endif #endif #if LEGACY_OPENSSL diff --git a/libi2pd/Signature.cpp b/libi2pd/Signature.cpp index baa265bc..f5164e9f 100644 --- a/libi2pd/Signature.cpp +++ b/libi2pd/Signature.cpp @@ -6,6 +6,26 @@ namespace i2p { namespace crypto { +#if OPENSSL_EDDSA + EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) + { + m_Pkey = EVP_PKEY_new_raw_public_key (EVP_PKEY_ED25519, NULL, signingKey, 32); + m_MDCtx = EVP_MD_CTX_create (); + EVP_DigestVerifyInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + } + + EDDSA25519Verifier::~EDDSA25519Verifier () + { + EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); + } + + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const + { + return EVP_DigestVerify (m_MDCtx, signature, 64, buf, len); + } + +#else EDDSA25519Verifier::EDDSA25519Verifier (const uint8_t * signingKey) { memcpy (m_PublicKeyEncoded, signingKey, EDDSA25519_PUBLIC_KEY_LENGTH); @@ -14,6 +34,10 @@ namespace crypto BN_CTX_free (ctx); } + EDDSA25519Verifier::~EDDSA25519Verifier () + { + } + bool EDDSA25519Verifier::Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const { uint8_t digest[64]; @@ -26,7 +50,30 @@ namespace crypto return GetEd25519 ()->Verify (m_PublicKey, digest, signature); } +#endif +#if OPENSSL_EDDSA + EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) + { + m_Pkey = EVP_PKEY_new_raw_private_key (EVP_PKEY_ED25519, NULL, signingPrivateKey, 32); + // TODO: check public key + m_MDCtx = EVP_MD_CTX_create (); + EVP_DigestSignInit (m_MDCtx, NULL, NULL, NULL, m_Pkey); + } + + EDDSA25519Signer::~EDDSA25519Signer () + { + EVP_MD_CTX_destroy (m_MDCtx); + EVP_PKEY_free (m_Pkey); + } + + void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const + { + size_t l = 64; + EVP_DigestSign (m_MDCtx, signature, &l, buf, len); + } + +#else EDDSA25519Signer::EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey) { // expand key @@ -47,10 +94,15 @@ namespace crypto BN_CTX_free (ctx); } + EDDSA25519Signer::~EDDSA25519Signer () + { + } + void EDDSA25519Signer::Sign (const uint8_t * buf, int len, uint8_t * signature) const { GetEd25519 ()->Sign (m_ExpandedPrivateKey, m_PublicKeyEncoded, buf, len, signature); } +#endif } } diff --git a/libi2pd/Signature.h b/libi2pd/Signature.h index 8b30a8e8..6b958107 100644 --- a/libi2pd/Signature.h +++ b/libi2pd/Signature.h @@ -367,6 +367,8 @@ namespace crypto public: EDDSA25519Verifier (const uint8_t * signingKey); + ~EDDSA25519Verifier (); + bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; size_t GetPublicKeyLen () const { return EDDSA25519_PUBLIC_KEY_LENGTH; }; @@ -374,8 +376,13 @@ namespace crypto private: +#if OPENSSL_EDDSA + EVP_PKEY * m_Pkey; + EVP_MD_CTX * m_MDCtx; +#else EDDSAPoint m_PublicKey; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; +#endif }; class EDDSA25519Signer: public Signer @@ -384,20 +391,39 @@ namespace crypto EDDSA25519Signer (const uint8_t * signingPrivateKey, const uint8_t * signingPublicKey = nullptr); // we pass signingPublicKey to check if it matches private key + ~EDDSA25519Signer (); + void Sign (const uint8_t * buf, int len, uint8_t * signature) const; const uint8_t * GetPublicKey () const { return m_PublicKeyEncoded; }; private: - +#if OPENSSL_EDDSA + EVP_PKEY * m_Pkey; + EVP_MD_CTX * m_MDCtx; +#else uint8_t m_ExpandedPrivateKey[64]; uint8_t m_PublicKeyEncoded[EDDSA25519_PUBLIC_KEY_LENGTH]; +#endif }; inline void CreateEDDSA25519RandomKeys (uint8_t * signingPrivateKey, uint8_t * signingPublicKey) { +#if OPENSSL_EDDSA + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_ED25519, NULL); + EVP_PKEY_keygen_init (pctx); + EVP_PKEY_keygen (pctx, &pkey); + EVP_PKEY_CTX_free (pctx); + size_t len = EDDSA25519_PUBLIC_KEY_LENGTH; + EVP_PKEY_get_raw_public_key (pkey, signingPublicKey, &len); + len = EDDSA25519_PRIVATE_KEY_LENGTH; + EVP_PKEY_get_raw_private_key (pkey, signingPrivateKey, &len); + EVP_PKEY_free (pkey); +#else RAND_bytes (signingPrivateKey, EDDSA25519_PRIVATE_KEY_LENGTH); EDDSA25519Signer signer (signingPrivateKey); memcpy (signingPublicKey, signer.GetPublicKey (), EDDSA25519_PUBLIC_KEY_LENGTH); +#endif }