2

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 !

jww
  • 97,681
  • 90
  • 411
  • 885
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • For what its worth, the sample above should work. The code looks good, and the command to compile it looks well formed. – jww Jun 23 '15 at 19:56

3 Answers3

5

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.

jww
  • 97,681
  • 90
  • 411
  • 885
  • Just for curiosity I have already printed the value of `CRYPTOPP_BOOL_ALIGN16_ENABLED` before posting this question and it shows 1. – sjsam Jun 23 '15 at 18:48
  • @sjsam - its defined in `misc.cpp`; see the grep above. – jww Jun 23 '15 at 19:48
  • 1
    @sjsam - can you verify the symbol is exported from the library? There could be a bad interaction between `CRYPTOPP_DLL` (effectively, the way to mark things exported), Windows and the Linux on Windows tools. – jww Jun 23 '15 at 19:55
  • Thankyou Jeff, I will check this one out. :-) – sjsam Jun 24 '15 at 01:35
  • @sjsam - How did you make out? I can set up a test environment and test it with you, if needed. – jww Jun 25 '15 at 20:40
  • 1
    Nice of you Jeff !! Compiling CryptoPP with mingw gave me nothing but grief. As i am nearing the deadline I made a decision to switch my design platform from CodeBlocks to VisualStudio as I had issues with other libraries like mysql as well . I recompiled the CryptoPP with VisualStudio and it works like a charm. I was not able to narrow down the issue but I strongly believe that the problem is what you pointed out. When I get back to mingw I will get back to you. :) – sjsam Jun 26 '15 at 04:09
  • 1
    @sjsam - ***if*** you are building the library under CodeBlocks, then I think you need to define `CRYPTOPP_EXPORTS`. When you consume the library, you omit/don't use `CRYPTOPP_EXPORTS`. ***Compiling Crypto++ with mingw gave me nothing but grief....*** - yeah, I avoid Cygwin, MinGW and WINE like the plague. I use the native platform's tools (when in Rome, do as the Romans do...). – jww Jun 30 '15 at 21:32
  • @jww: I have same problem on Linux. And in my case, it is secblock.h that produces 'undefined reference...' error. I tried undefining and defining CRYPTOPP_BOOL_ALIGN16_ENABLED solution but no success. How to do it now? I use Qt 5 and Fedora 32 bit. – Jatin Mar 29 '16 at 05:56
  • @jww: It builds successfully defining CRYPTOPP_BOOL_ALIGN16_ENABLED = 0 for Linux. But problem now arises at runtime. The program crashes stating: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t): Assertion `dest != __null' failed. For encryption I used sorush-r's code, here (http://stackoverflow.com/questions/21885140/aes-256-encryption-in-c-and-qt-5). Any suggestions please. – Jatin Mar 29 '16 at 06:48
  • @Jatin - I added additional information about potential MinGW causes. In the end, you should probably avoid MinGW since it appears to be abandoned. I'm pretty sure its no longer being maintained because I filed some bugs against it that were neither acknowledged or fixed. I took MinGW out of my testing rotation because it was more frustrating than fruitful. Try Cygwin or use native Windows tools, like Visual Studio, if possible. – jww Mar 29 '16 at 08:24
1

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.

Zireael
  • 11
  • 2
  • This is in fact unrelated. jww's answer is correct. – Alexander Shishenko Oct 27 '15 at 14:25
  • @AlexanderShishenko, well, jww's answer says to define `CRYPTOPP_BOOL_ALIGN16_ENABLED` and the OP replied that he'd already checked that it was defined. Unless I'm missing something? – Zireael Oct 27 '15 at 17:08
  • @AlexanderShishenko, but you're right. Not entirely unrelated, because MSYS2, as of now, does in fact have a corrupted shared version of the library in their repository, but the chance that the OP's using MSYS2 **and** the library from the repository is extremely slim. I've edited the answer to instead explain how to compile Crypto++ with MinGW and avoid linking issues. – Zireael Oct 27 '15 at 17:09
  • @Zireael - good to see you here. Thanks again for the help with [Issue 46](http://github.com/weidai11/cryptopp/issues/45). I see you mentioned ***Qt*** and ***`qmake.exe`***. You will definitely want to visit [Visual Studio](https://cryptopp.com/wiki/Visual_Studio) on the Crypto++ wiki. It provides pre-converted Visual Studio 2010 project files (`vs2010.zip`); and pre-converted Visual Studio 2010 project files using dynamic linking compatible with MFC, Qt, etc (`vs2010-dynamic.zip`). – jww Oct 28 '15 at 09:43
  • *"First, open GNUMakefile... You need to remove .cpps with the same names, so you don't build a bloated lib"* - You can now do a ***`make sources`*** and get a list of files you should build for the library and test program. Its now as easy as copy/paste to get your file list. – jww Mar 29 '16 at 08:28
0

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.