noloader / cryptopp-cmake

CMake files for Crypto++ project

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Import library cryptopp-shared.lib does not appear to be generated or installed on windows

SylvainCorlay opened this issue · comments

I think that it should be in PREFIX/lib/ next to cryptopp-static.lib.

It seems that cryptopp is not exporting any symbol on windows.

Testing on 7.0.0

  • CRYPTOPP_EXPORTS is not defined for the cryptopp-shared target
  • the fact that a common cryptopp-object target is used for both the static and shared libraries prevents different compilation flags to be passed to the two targts.

Working on the top of 8.0.0.

I got the shared library to build locally but I am getting some link issues with the weird template instantiations.

The Windows DLL was a special-purpose shared library for a FIPS-140 validated module. It only included FIPS algorithms like AES and SHA. It has been dead for a couple of years now.

You should build a wrapper shared object around the static library. Also see Wrapper DLL on the Crypto++ wiki.

(I have wanted to delete that damn DLL project for years. It causes nothing but confusion for users. I have not been given the go-ahead).

Still, I should report that using BUILD_SHARED on windows generates a cryptopp-targets that refers to a non-existent cryptopp-shared.lib.

So you can't use the static library if the dynamic library was built, because find_package screams that a file is missing.

So you can't use the static library if the dynamic library was built, because find_package screams that a file is missing.

Ack, thanks. Let's see if @abdes can help.

Sorry about not being more help. I don't know CMake that well. I generally maintain the GNU makefile and Autotools.

I've been testing a Windows DLL using cryptest.nmake. cryptest.nmake is a Windows Nmake makefile. I use it to cut through the cruft of Visual Studio projects, MSBuild and CMake. It does exactly what I want without fighting back.

I added dump2def.cxx. The program allows us to create a DEF file from the static LIB using dumpbin.exe, and then build a DLL and export all the symbols found in the static lib. The linker also creates an import lib cryptopp.lib and export file cryptopp.exp.

With the DLL in hand we still have the problem of programs linking to the library and declspec(dllimport) in headers. Microsoft requires it, and there's no way to side step like we did with dllexport.

At least two problems remain.

First, only some classes use CRYPTOPP_DLL and they are the ones used in the FIPS DLL. That means AES and SHA have it, but helper classes like Base64Encoder does not. It also means non-FIPS ciphers like ChaCha and x25519 are not available.

Second, because the DLL is predicated upon FIPS DLL and the requirement for the "logical module boundary", when CRYPTOPP_IMPORTS is defined some implementations in the library go missing. That's because the implementation is supposed to be available in the FIPS DLL already, so there's no need for the library to provide it again.

You can see it in the guards that are sprinkled throughout the source code:

$ grep CRYPTOPP_IMPORTS *.*
algparam.cpp:#ifndef CRYPTOPP_IMPORTS
asn.cpp:#ifndef CRYPTOPP_IMPORTS
authenc.cpp:#ifndef CRYPTOPP_IMPORTS
basecode.cpp:#ifndef CRYPTOPP_IMPORTS
cbcmac.cpp:#ifndef CRYPTOPP_IMPORTS
ccm.cpp:#ifndef CRYPTOPP_IMPORTS
channels.cpp:#ifndef CRYPTOPP_IMPORTS
cmac.cpp:#ifndef CRYPTOPP_IMPORTS
...

There's a third, minor problem, and that's how to get CMake to build the DLL in a similar fashion to Nmake. I believe that is answered at Export all symbols when creating a DLL on Stack Overflow. But I don't know if our CMakefile is set up to do it.

So I'm not sure what happens next given the two or three issues. I know you will need to add CRYPTOPP_DLL to some classes. I know you will need to compile the client program with CRYPTOPP_IMPORTS. But I am not sure what happens next.


I think the way for you to proceed is gut the DLL code from CMakeList.txt so CMake stops trying to find a DLL. Then, build the Wrapper DLL like discussed earlier.

Hopefully one of the CMake folks will jump in and provide better advice for this problem.

OK, so I worked on this a little more this morning. I opened cryptest.nmake and make the following change (I swapped-in the DLL):

cryptest.exe: pch.pch cryptopp.dll $(TEST_OBJS)
	$(LD) $(LDFLAGS) $(TEST_OBJS) cryptopp.lib $(LDLIBS) /out:$@

Running .\cryptest.exe v results in:

C:\Test\cryptopp>.\cryptest.exe v
Using seed: 1546886929

Testing Settings...

passed:  Your machine is little endian.
passed:  Aligned data access.
passed:  sizeof(byte) == 1
passed:  sizeof(word16) == 2
passed:  sizeof(word32) == 4
passed:  sizeof(word64) == 8
passed:  sizeof(hword) == 4, sizeof(word) == 8
FAILED:  cacheLineSize == -871684609
hasSSE2 == 1, hasSSSE3 == 255, hasSSE4.1 == 255, hasSSE4.2 == 255, hasAVX == 255
, hasAVX2 == 255, hasAESNI == 255, hasCLMUL == 255, hasRDRAND == 255, hasRDSEED
== 255, hasSHA == 255, isP4 == 255
Some critical setting in config.h is in error.  Please fix it and recompile.

cacheLineSize is in cryptopp.dll. It is declared as:

extern CRYPTOPP_DLL word32 g_cacheLineSize;

So it looks like we have to do the CRYPTOPP_IMPORTS gyrations. Next, add the following to cryptest.nmake:

# For testing cryptopp.dll and CRYPTOPP_IMPORTS
CXXFLAGS_IMPORTS = /wd4275 /DCRYPTOPP_IMPORTS
test.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $*.cpp
*test.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $*.cpp
bench*.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $*.cpp
regtest*.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $*.cpp
validat*.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_IMPORTS) /c $*.cpp

A test compile start off with a slew of warnings:

        cl.exe /nologo /W4 /wd4231 /wd4511 /wd4156 /D_MBCS /Zi /TP /GR /EHsc /DN
DEBUG /D_NDEBUG /Oi /Oy /O2 /MT /FI sdkddkver.h /FI winapifamily.h /wd4275 /DCRY
PTOPP_IMPORTS /c test.cpp
test.cpp
c:\users\jeff\desktop\cryptopp\cryptlib.h(198): warning C4251: 'CryptoPP::Except
ion::m_what': class 'std::basic_string<char,std::char_traits<char>,std::allocato
r<char>>' needs to have dll-interface to be used by clients of class 'CryptoPP::
Exception'
...

And ends with link errors:

...
test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) publ
ic: __cdecl CryptoPP::FileSink::FileSink(char const *,bool)" (__imp_??0FileSink@
CryptoPP@@QEAA@PEBD_N@Z) referenced in function "void __cdecl CryptoPP::Test::AE
S_CTR_Encrypt(char const *,char const *,char const *,char const *)" (?AES_CTR_En
crypt@Test@CryptoPP@@YAXPEBD000@Z)

I also tried adding the following which should be a step in the right direction:

# For testing cryptopp.dll and CRYPTOPP_EXPORTS
CXXFLAGS_EXPORTS = /wd4275 /wd4251 /DCRYPTOPP_DLL_ONLY
.cpp.obj:
	$(CXX) $(CXXFLAGS) $(CXXFLAGS_EXPORTS) /c $<

At this point I don't believe cryptopp.dll is viable on Windows. We should probably pull the DLL project out of CMake until first class DLL support is added (and not the hacked FIPS DLL support).

Crypto++ DLL is probably not going to work. Under Visual Studio it is actually a FIPS DLL and it is a lot of trouble. My advice is, remove anything that has to do with a DLL.

If you want a DLL, then create a Wrapper DLL with the functions you want to use.