Delay-load crypto++ cryptopp.dll

547 views Asked by At

The Crypto++ library supports late binding by compiling against cryptlib.lib and cryptopp.lib. This requires to use the cryptopp.dll. When trying to delay-load this dll by /DELAYLOAD:cryptopp.dll this causes a link error that it could not be delay loaded because of required imports.

As example see the following code:

#include <Crypto++/dll.h>
#include <crypto++/base64.h>

bool HexDecode(const std::string& strHex, std::string& strData)
{
    try
    {
        CryptoPP::StringSource(strHex, true,
            new CryptoPP::Base64Decoder(
                new CryptoPP::StringSink(strData)));
    }

    catch(...)
    {
        return false;
    }

    return true;
}

This causes the following link error:

LINK : fatal error LNK1194: Delay loading "cryptopp.dll" not possible because of import of data symbol ""__declspec(dllimport) bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" (__imp_?g_pAssignIntToInteger@CryptoPP@@3P6A_NABVtype_info@@PAXPBX@ZA)". Link without /DELAYLOAD:cryptopp.dll

Did anyone already managed to delay load cryptopp.dll successfully?

1

There are 1 answers

0
jww On

The Crypto++ library supports late binding by compiling against cryptlib.lib and cryptopp.lib...

The DLL is a FIPS DLL. The actual purpose of splitting functionality into two separate libraries is to provide the logical module boundary required by FIPS 140-2. The FIPS module boundary is cryptopp.dll.

The FIPS DLL only includes the FIPS algorithms, like AES and RSA. I recommend you avoid the FIPS DLL at all costs. Its a pain to work with. Also see FIPS DLL on the Crypto++ wiki.

If you want a DLL, then write your own wrapper DLL with your own API, and then link to the Crypto++ static library.

In the wrapper DLL case (and since you seem experienced), I highly encourage you to use cryptest.nmake as a starting point. If you are familiar with makefiles (I think you are), then you will find it much easier to work with than the Visual Studio project files.


LINK : fatal error LNK1194: Delay loading "cryptopp.dll" not possible because of import of data symbol ""__declspec(dllimport) bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" (__imp_?g_pAssignIntToInteger@CryptoPP@@3P6A_NABVtype_info@@PAXPBX@ZA)". Link without /DELAYLOAD:cryptopp.dll

This is an interesting question because you have two libraries, and its not clear to me which library the symbol is in. The first library is the FIPS DLL (cryptopp.dll), and it includes AES, RSA, etc. The second library is the Static Lib (cryptlib.lib), and it includes HexEncoder, FileSource, and the other supporting stuff.

I believe g_pAssignIntToInteger should be in the Static Lib (cryptlib.lib) because it was part of AlgorithmParamters. See, for example, Commit 5efb019d8bdc593b. However, from the error above, it appears to be residing in the FIPS DLL because of the symbol name __imp_?g_pAssignIntToInteger ....

Now the added wrinkle is, g_pAssignIntToInteger is a function pointer, and compilers won't optimize them away. So the linker never discards Integer related symbols, which is the point of the decoupling.

At Commit 0e55f5ac7d98f3c8 we removed g_pAssignIntToInteger and added a define CRYPTOPP_NO_ASSIGN_TO_INTEGER to accomplish the task. The define ensures the symbol and unwanted code like Integer code can be discarded.