5.6.0 - Can't link Rijndael encryption code on Mac OS X

63 views
Skip to first unread message

Mouse

unread,
Apr 4, 2009, 10:10:00 PM4/4/09
to Crypto++ Users
Any code I tried that uses AES encryption, fails to link (but the code
that uses decryption is fine - go figure). Other primitives don't seem
to cause problems. Code stopped linking with the move from 5.5.2 to
5.6.0. It applies only to the code that uses AES encryption (CBC in my
case), AES decryption does not seem to be affected. Replacing AES with
e.g. MARS also cures the problem - the issue is definitely with the
new code for AES/Rijndael in 5.6.0.

Mac OS X 10.5.6 Leopard, gcc-4.2.1 (tried with 4.0.1 with the same
result). Everything works fine with 5.5.2.

Here's the command line and the error messages:

$ g++ -I/usr/include/cryptopp -o t1 t1.cpp -lcryptopp -lstdc++
Undefined symbols:
"CryptoPP::Rijndael::Enc::AdvancedProcessBlocks(unsigned char
const*, unsigned char const*, unsigned char*, unsigned long, unsigned
int) const", referenced from:
vtable for CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0,
CryptoPP::Rijndael::Enc>in ccYwjfFL.o
vtable for CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<
(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>,
CryptoPP::Rijndael::Enc>in ccYwjfFL.o
"non-virtual thunk to CryptoPP::Rijndael::Enc::AdvancedProcessBlocks
(unsigned char const*, unsigned char const*, unsigned char*, unsigned
long, unsigned int) const", referenced from:
vtable for CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0,
CryptoPP::Rijndael::Enc>in ccYwjfFL.o
vtable for CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<
(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>,
CryptoPP::Rijndael::Enc>in ccYwjfFL.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


Here's the actual code taken from the FAQ Web page <http://
www.cryptopp.com/fom-serve/cache/79.html> (lest people think that it's
my code that's at fault :-):

#include <iostream>
#include <iomanip>

#include "modes.h"
#include "aes.h"
#include "filters.h"

int main(int argc, char* argv[]) {

//
// Key and IV setup
//
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv
[ CryptoPP::AES::BLOCKSIZE ];
memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );

//
// String and Sink setup
//
std::string plaintext = "Now is the time for all good men to come
to the aide...";
std::string ciphertext;
std::string decryptedtext;

//
// Dump Plain Text
//
std::cout << "Plain Text (" << plaintext.size() << " bytes)" <<
std::endl;
std::cout << plaintext;
std::cout << std::endl << std::endl;

//
// Create Cipher Text
//
CryptoPP::AES::Encryption aesEncryption(key,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption
( aesEncryption, iv );

CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption,
new CryptoPP::StringSink( ciphertext ) );
stfEncryptor.Put( reinterpret_cast<const unsigned char*>
( plaintext.c_str() ), plaintext.length() + 1 );
stfEncryptor.MessageEnd();

//
// Dump Cipher Text
//
std::cout << "Cipher Text (" << ciphertext.size() << " bytes)" <<
std::endl;

for( int i = 0; i < ciphertext.size(); i++ ) {

std::cout << "0x" << std::hex << (0xFF & static_cast<byte>
(ciphertext[i])) << " ";
}

std::cout << std::endl << std::endl;

//
// Decrypt
//
CryptoPP::AES::Decryption aesDecryption(key,
CryptoPP::AES::DEFAULT_KEYLENGTH);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption
( aesDecryption, iv );

CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption,
new CryptoPP::StringSink( decryptedtext ) );
stfDecryptor.Put( reinterpret_cast<const unsigned char*>
( ciphertext.c_str() ), ciphertext.size() );
stfDecryptor.MessageEnd();

//
// Dump Decrypted Text
//
std::cout << "Decrypted Text: " << std::endl;
std::cout << decryptedtext;
std::cout << std::endl << std::endl;

return 0;
}

Mouse

unread,
Apr 4, 2009, 10:38:47 PM4/4/09
to Crypto++ Users
Problem appears related to -DCRYPTOPP_DISABLE_ASM flag that does not
get stored in the config.h file.

GNUmakefile ensures that on Mac OS X (where gas is v1.38) library is
compiled with -DCRYPTOPP_DISABLE_ASM. I omitted this flag when
compiling my code, and until 5.6.0 all was well. In 5.6.0 rijndael.h
got dependency on assembly code (extra function AdvancedProcessBlock,
unless CRYPTOPP_DISABLE_ASM is specified). The library (compiled with
DISABLE_ASM) obviously doesn't have that reference.

Solutions are:

- Ensure that I compile my code with the same flags as GNUmakefile
sets. It would work, but it's ugly.
- Manually stick #define CRYPTOPP_DISABLE_ASM in config.h. It would
work, that's what I'll do on my machine.
- Somehow make sure that rijndael.h (or config,.h or cryptlib.h) file
(s) figure out the situation. I'd like it, but I don't hold my
breath. :-)
> Here's the actual code taken from the FAQ Web page <http://www.cryptopp.com/fom-serve/cache/79.html> (lest people think that it's

Wei Dai

unread,
Apr 5, 2009, 3:59:27 PM4/5/09
to Mouse, Crypto++ Users
Thanks for reporting this. I've fixed this in SVN r463.

--------------------------------------------------
From: "Mouse" <mous...@gmail.com>
Sent: Saturday, April 04, 2009 7:38 PM
To: "Crypto++ Users" <cryptop...@googlegroups.com>
Subject: Re: 5.6.0 - Can't link Rijndael encryption code on Mac OS X
Reply all
Reply to author
Forward
0 new messages