Undefined reference to CryptoPP::AlignedAllocate when linking

3k views Asked by At

I am getting the below errors compiling the cryptopp project in Windows.

C:\Users\Sajith\AppData\Local\Temp\ccxq8O8x.o:aescbc.cpp:(.text$_ZN8CryptoPP20AllocatorWithCleanupIhLb1EE8allocateEjPKv[
__ZN8CryptoPP20AllocatorWithCleanupIhLb1EE8allocateEjPKv]+0x2e): undefined reference to `CryptoPP::AlignedAllocate(unsig
ned int)'
C:\Users\Sajith\AppData\Local\Temp\ccxq8O8x.o:aescbc.cpp:(.text$_ZN8CryptoPP20AllocatorWithCleanupIhLb1EE10deallocateEPv
j[__ZN8CryptoPP20AllocatorWithCleanupIhLb1EE10deallocateEPvj]+0x28): undefined reference to `CryptoPP::AlignedDeallocate
(void*)'
collect2.exe: error: ld returned 1 exit status


Below is my compilation command :

mingw32-g++.exe -o .\aestest2.exe .\aescbc.cpp   -I "C:\cryptopp\Include" -L "C:\cryptopp\Lib" -lcryptopp


My libcryptopp.a is located at C:\cryptopp\Lib
I tried to find out where AlignedDeallocate is declared but I couldn't.

The part of the program that threw this error is below :

try
    {
        cout << "plain text: " << plain << endl;

        CBC_Mode< AES >::Encryption e;
        e.SetKeyWithIV(key, sizeof(key), iv);

        // The StreamTransformationFilter removes
        //  padding as required.
        StringSource s(plain, true, 
            new StreamTransformationFilter(e,
                new StringSink(cipher)
            ) // StreamTransformationFilter
        ); // StringSource

#if 0
        StreamTransformationFilter filter(e);
        filter.Put((const byte*)plain.data(), plain.size());
        filter.MessageEnd();

        const size_t ret = filter.MaxRetrievable();
        cipher.resize(ret);
        filter.Get((byte*)cipher.data(), cipher.size());
#endif
    }
    catch(const CryptoPP::Exception& e)
    {
        cerr << e.what() << endl;
        exit(1);
    }


Suggestions appreciated !

3

There are 3 answers

10
jww On

AlignedAllocate is in misc.h:

$ grep -I AlignedAllocate *
misc.cpp:void * AlignedAllocate(size_t size)
misc.h:CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size);
secblock.h:                     return (pointer)AlignedAllocate(n*sizeof(T));

And:

$ grep -R AlignedDeallocate *
misc.cpp:void AlignedDeallocate(void *p)
misc.h:CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p);
secblock.h:                     return AlignedDeallocate(p);

However, they are guarded with:

#if CRYPTOPP_BOOL_ALIGN16_ENABLED
CRYPTOPP_DLL void * CRYPTOPP_API AlignedAllocate(size_t size);
CRYPTOPP_DLL void CRYPTOPP_API AlignedDeallocate(void *p);
#endif

CRYPTOPP_BOOL_ALIGN16_ENABLED is set in config.h:

#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)
    #define CRYPTOPP_BOOL_ALIGN16_ENABLED 1
#else
    #define CRYPTOPP_BOOL_ALIGN16_ENABLED 0
#endif

You might consider adding the following to config.h after Crypto++ makes its choice internally:

#undef CRYPTOPP_BOOL_ALIGN16_ENABLED
#define CRYPTOPP_BOOL_ALIGN16_ENABLED 1

Then, rebuild the library and your program.


Something else that may be happening is: MinGW is building the library on a machine with MMX/SSE/SSE2 disabled. Or perhaps they are using g++ -mno-sse -mno-sse2 ....

Then, you come a long with a shiny new Intel or AMD, and based on what g++ enables and the defines in config.h, your program expects AlignedAllocate and AlignedDeallocate because your configuration includes MMX/SSE/SSE2...

This situations is discussed at config.h | Recommendations on the Crypto++ wiki. Its why we tell distros to enable and disable things in config.h, rather than from the command line. Modifying config.h ensures the distro and user programs mostly use the same settings.

If this is the case, then you might try:

export CXXFLAGS="-DNDEBUG -g2 -O2 -mno-sse -mno-sse2"
mingw32-g++.exe $CXXFLAGS -o .\aestest2.exe .\aescbc.cpp \
  -I "C:\cryptopp\Include" -L "C:\cryptopp\Lib" -lcryptopp

There's a slew of defines that cascade based on MMX/SSE/SSE2; see config.h | Assembly Defines on the wiki. Because MMX/SSE/SSE2 is disabled, you will get a software-only implementation of AES. It won't perform as well as it could.

5
Zireael On

I've been experiencing the same thing with MSYS2's version of MinGW64

The solution was to add -static before -lcryptopp. Hope this works for you!

Edit: nevermind my first answer, actually. MSYS2 might have a corrupted version of a shared lib in their repos, but I guess you compiled it yourself.

I'll instead provide a way how to compile Crypto++ with MinGW. You'll need Qt's qmake to generate a Makefile instead of using the one included.

First, open GNUMakefile and look for TESTOBJS, as of 5.6.2 it's bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o. You need to remove .cpps with the same names, so you don't build a bloated lib.

Then open cmd.exe (with PATH containing MinGW's /bin and a directory where your qmake.exe is), navigate to the directory containing the sources and use these:

erase /f GNUmakefile
qmake -project

It'll create a file with the name of the current folder and extension ".pro". Open it with a text editor, change

TEMPLATE = app
TARGET = cryptopp562
INCLUDEPATH += .

to

TEMPLATE = lib
TARGET = cryptopp
INCLUDEPATH += .
CONFIG -= qt
CONFIG += static
LIBS += -lws2_32
QMAKE_CXXFLAGS_RELEASE += -DNDEBUG

Replace every OutputDebugString with OutputDebugStringA in fipstest.cpp.

Now you can type qmake to generate a new Makefile and use mingw32-make. There'll be a ton of warnings, mostly about unused parameters. Nevertheless, nothing serious enough to cancel compilation. libcryptopp.a will be in ./release/.

The example in the question compiles and works perfectly fine with a library compiled this way, tested with MinGW 4.9.2 bundled with Qt and with a standalone MingGW-w64 5.2.0.

The basic idea is taken from here, I merely improved it.

0
BattleTested_закалённый в бою On

if you use of Crypto++ in your program, so attention :

this solution is for linux and if you doing bellow commands, your problem 100 percentage will solved!!!

if you want to linking your .so files and conclusively compiling your program , first you must install all Crypto++ libraries from Synaptic tool in ubuntu or another distribution (debian base linux).

after that you most add -lcryptopp or/and -lcrypto++ to your .pro file in qt creator like this :

LIBS += -lcryptopp
LIBS += -lcrypto++

i had this problem , but my problem solved...

and my code haven't any mistakes

if you want, test that in window and add two top statements in your qt creator in windows.