Closed janblome closed 2 years ago
What is the problem you are reporting? You have to use RTTI for Crypto++.
My specific problem is that I'm using CryptoPP in an application that is itself not compiled with RTTI. This application links to a static build of CryptoPP, presumably built with RTTI. This approach seemed to work fine, but now that I'm trying to use the ECDH
class I'm facing what seems to be undefined behavior. I think this is because the DL_SignerBase::SignAndRestart
method is defined in the header, so it doesn't get compiled as part of the static library. Sorry, I missed mentioning that part in the issue.
It is of course valid to say any program using CryptoPP has to also be itself built with RTTI 🙂. In my case I'm hesitant to change that for the application where I'm using CryptoPP, so that's why I patched it on my end.
You should probably use a C-based library, like OpenSSL or Mbed-TLS.
C++ libraries like Botan and Crypto++ need full C++ features. I am not aware of any embedded C++ crypto libraries. Embedded C++ lacks exceptions, RTTI, virtual bases, multiple inheritance, and a lot of the stream stuff with language support via char traits.
Hi, I'm trying to use the elliptic curve Diffie-Hellman class (
ECDH<ECP>
) in a program compiled without RTTI. This results in a compiler warning when using MSVC (full program and output at the end of the issue):I looked into that a bit and saw that in
pubkey.h:1658
theDL_SignerBase::SignAndRestart
method uses adynamic_cast
to crosscast aDL_ElgamalLikeSignatureAlgorithm
pointer to aDeterministicSignatureAlgorithm
pointer. A cast like that is as far as I know not possible at all without RTTI.Is making this work without RTTI something you would consider?
Possible Solution
For my use-case I patched CryptoPP by adding a virtual method to the
DL_ElgamalLikeSignatureAlgorithm
class to return a pointer to itself as aDeterministicSignatureAlgorithm
. It returns anullptr
if the conversion wouldn't be possible. This is also the default, just likeIsDeterministic
returnsfalse
by default:This can then be overridden in
DL_Algorithm_DSA_RFC6979
, which is the only class I found whereIsDeterministic
returnedtrue
:Since the correct pointer is now determined statically this solves my issue. I attached my complete changes as patch, if this approach is something you would be interested in I would also be happy to create a PR for further discussion 🙂.
Full Patch
```diff diff --git a/gfpcrypt.h b/gfpcrypt.h index f8fc3c5e..ee570f62 100644 --- a/gfpcrypt.h +++ b/gfpcrypt.h @@ -354,6 +354,8 @@ public: {return false;} bool IsDeterministic() const {return true;} + const DeterministicSignatureAlgorithm * GetDeterministic() const + {return this;} // Deterministic K Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const diff --git a/pubkey.h b/pubkey.h index efa607b6..09035930 100644 --- a/pubkey.h +++ b/pubkey.h @@ -1399,6 +1399,9 @@ private: templateMinimal Program
I tried this with the Visual Studio 2022 (Compiler Version 19.33) and using CryptoPP 8.7.0 (retrieved via Conan, paths shortened for clarity).
Code
Compiler Invocation
Compiler Output
Full Output
``` cryptopp\8.7.0\include\cryptopp\queue.h(222): error C2220: the following warning is treated as an error cryptopp\8.7.0\include\cryptopp\queue.h(222): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc cryptopp\8.7.0\include\cryptopp\pubkey.h(1658): warning C4541: 'dynamic_cast' used on polymorphic type 'CryptoPP::DL_ElgamalLikeSignatureAlgorithm