AES/CCM Encryption and Plaintext Length Exceeds Maximum Message Length - c++

I am trying to perform an encryption and decryption in Crypto++ library using AES128 cipher with CCM mode of operation. I have a problem when I try to encrypt string longer than 16777215 bytes.
My code:
const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;
e.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
e.SpecifyDataLengths( 0, plain.size(), 0 );
//Encryption
StringSource ss1(
plain,
true,
new AuthenticatedEncryptionFilter(
e,
new StringSink(cipher)
)
);
d.SetKeyWithIV( key, sizeof(key), iv, sizeof(iv) );
d.SpecifyDataLengths( 0, plain.size(), 0 );
//Decryption
AuthenticatedDecryptionFilter df( d,
new StringSink(recovered)
);
StringSource ss2(
cipher,
true,
new Redirector(df)
);
When I try to encrypt/decrypt a plaintext which is size of a CD (737280000), I get the following error:
"terminate called after throwing an instance of 'CryptoPP::InvalidArgument'
what(): AES/CCM: message length 737280000 exceeds the maximum of 16777215"
My question is, how do I encrypt/decrypt a plaintext which is longer than 16777215 bytes?

My question is, how do I encrypt/decrypt a plaintext which is longer than 16777215 bytes?
CCM mode is specified in NIST SP800-38c. Section A.1, Length Requirements, discusses maximum plain text under a security context. A security context is the {key, iv} combination (with some hand waiving).
I believe you have three choices. First, you can increase the length of the IV. The larger the iv, the more plain text you can encrypt. The max iv length is 13 so it does not scale up forever.
Second, you have to re-key or change the iv before you hit the maximum plain text under the context. You can find the maximum plain text length using MaxMessageLength(). Crypto++ tracks the number of bytes processed via m_totalMessageLength, but it is not exposed to user programs. You will have to track it yourself.
Third, you can change algorithms. An algorithm like ChaCha20Poly1305 allows you to encrypt 2^38-1 64-byte blocks. That is just under 2^44 bytes or about 256 GB. You should be safe with ChaCha20Poly1305.
Crypto++ tells you the maximum number of bytes via MaxMessageLength(). In the case of CCM it is based on the iv length, and tracked through m_L in the code below.
lword MaxMessageLength() const
{return m_L<8 ? (W64LIT(1)<<(8*m_L))-1 : W64LIT(0)-1;}
MaxMessageLength() is used in authenc.cpp. ProcessData() throws an exception when the limit is hit:
if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength)
throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
m_totalMessageLength += length;
const int TAG_SIZE = 8;
CCM< AES, TAG_SIZE >::Encryption e;
CCM< AES, TAG_SIZE >::Decryption d;
Your tag size is a tad bit on the small side. You might want to use the maximum size, if your protocol allows it.
I recommend you switch algorithms. CCM is a bastard mode that got standardized in the early 2000's through some Wireless Working Group. Then, NIST adopted it because it was already standardized.
At the time CCM was standardized there were better Authenticated Encryption modes available, like CWC, OCB, EAX and GCM. Unfortunately the damage was done. And now you have algorithms like Bernstein's ChaChaPoly1305.
You might also want to checkout AEAD Comparison on the Crypto++ wiki. The comparison shows CCM is about the worst of the authenticated encryption modes.

Related

OpenSSL AES_CBC-256 decrypting without original text length in C++

I have this code that I found on SO and it works. My problem is that encryption and decryption are in the same file. Naturally, I want to separate them into two functions. The problem is the decoder needs the original input length. Isn't it a security vulnerability? How can I decrpyt without knowing the original length of the input?
/* computes the ciphertext from plaintext and key using AES256-CBC algorithm */
string cipher_AES(string key, string message)
{
size_t inputslength = message.length();
unsigned char aes_input[inputslength];
unsigned char aes_key[AES_KEYLENGTH];
memset(aes_input, 0, inputslength/8);
memset(aes_key, 0, AES_KEYLENGTH/8);
strcpy((char*) aes_input, message.c_str());
strcpy((char*) aes_key, key.c_str());
/* init vector */
unsigned char iv[AES_BLOCK_SIZE];
memset(iv, 0x00, AES_BLOCK_SIZE);
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, AES_KEYLENGTH, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, AES_KEYLENGTH, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);
stringstream ss;
for(int i = 0; i < encslength; i++)
{
ss << enc_out[i];
}
return ss.str(););
}
First of all, AES encryption takes place 1-to-1 in blocks of 128 bits, so you already know the message size with a 16-byte accuracy by just looking at the ciphertext.
Then, for the last block you just need to determine where the message ends. The standard solution for that is to use padding (e.g. PKCS#7). Or just store the message length at the beginning and encrypt it together with the message.
You can of course continue using OpenSSL AES API, and implement padding or some other mechanism yourself. But OpenSSL already has higher-level API (EVP), which does AES, CBC and PKCS padding automatically.
See EVP Symmetric Encryption and Decryption official OpenSSL wiki page for an example of using the EVP API.
Unrelated notes:
a fixed IV (especially zero IV) is insecure. Consider generating a random IV and storing it together with the ciphertext (e.g. using RAND_bytes).
check out also AES GCM mode for authenticated encryption (encryption + secure checksum), this way the encrypted message additionally becomes tamper-proof. See this example.

Crypto++ extra block at the end of encrypted stream in AES-128 CBC mode

I'm trying to encrypt 320 bytes of binary data using AES-128 in CBC mode and store the cipher into a file. The output file should have been of 320 bytes, but I got 336 bytes. Here is my code:
#include <iostream>
#include <fstream>
#include <crypto++/aes.h>
#include <crypto++/modes.h>
#include <crypto++/base64.h>
#include <crypto++/sha.h>
#include <cryptopp/osrng.h>
#include <crypto++/filters.h>
#include <crypto++/files.h>
namespace CryptoPP
{
using byte = unsigned char;
}
void myAESTest()
{
std::string password = "testPassWord";
// hash the password string
// -------------------------------
CryptoPP::byte key[CryptoPP::AES::DEFAULT_KEYLENGTH], iv[CryptoPP::AES::BLOCKSIZE];
CryptoPP::byte passHash[CryptoPP::SHA256::DIGESTSIZE];
CryptoPP::SHA256().CalculateDigest(passHash, (CryptoPP::byte*) password.data(), password.size());
std::memcpy(key, passHash, CryptoPP::AES::DEFAULT_KEYLENGTH);
std::memcpy(iv, passHash+CryptoPP::AES::DEFAULT_KEYLENGTH, CryptoPP::AES::BLOCKSIZE);
// encrypt
// ---------------------------------
int chunkSize = 20*CryptoPP::AES::BLOCKSIZE;
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor;
encryptor.SetKeyWithIV(key, sizeof(key), iv);
std::ofstream testOut("./test.enc", std::ios::binary);
CryptoPP::FileSink outSink(testOut);
CryptoPP::byte message[chunkSize];
CryptoPP::StreamTransformationFilter stfenc(encryptor, new CryptoPP::Redirector(outSink));
for(int i = 0; i < chunkSize; i ++)
{
message[i] = (CryptoPP::byte)i;
}
stfenc.Put(message, chunkSize);
stfenc.MessageEnd();
testOut.close();
// decrypt
// ------------------------------------
// Because of some unknown reason increase chuksize by 1 block
// chunkSize+=16;
CryptoPP::byte cipher[chunkSize], decrypted[chunkSize];
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decryptor;
decryptor.SetKeyWithIV(key, sizeof(key), iv);
std::ifstream inFile("./test.enc", std::ios::binary);
inFile.read((char *)cipher, chunkSize);
CryptoPP::ArraySink decSink(decrypted, chunkSize);
CryptoPP::StreamTransformationFilter stfdec(decryptor, new CryptoPP::Redirector(decSink));
stfdec.Put(cipher, chunkSize);
stfdec.MessageEnd();
inFile.close();
for(int i = 0; i < chunkSize; i++)
{
std::cout << (int)decrypted[i] << ' ';
}
std::cout << std::endl;
}
int main(int argc, char* argv[])
{
myAESTest();
return 0;
}
I'm not able to understand how the last 16 bytes are generated. If I choose to ignore the last 16 bytes in the decryption, CryptoPP throws CryptoPP::InvalidCiphertext error:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
I'm not able to understand how the last 16 bytes are generated. If I choose to ignore the last 16 bytes in the decryption, Crypto++ throws InvalidCiphertext error
The last 16 bytes are padding. Padding is added by the StreamTransformationFilter filter; see StreamTransformationFilter Class Reference in the manual. Though not obvious, DEFAULT_PADDING is PKCS_PADDING for ECB_Mode and CBC_Mode. It is NO_PADDING for other modes like OFB_Mode and CTR_Mode.
You only need to specify NO_PADDING for both the encryption and decryption filters. However, you have to ensure the plaintext and ciphertext are a multiple of the blocksize, which is 16 for AES.
You can sidestep the blocksize restriction by switching to another mode like CTR_Mode. But then you have to be very careful of key or IV reuse, which may be difficult due to the password derivation scheme you are using.
So instead of:
CBC_Mode<AES>::Encryption encryptor;
...
StreamTransformationFilter stfenc(encryptor, new Redirector(outSink));
Use:
CBC_Mode<AES>::Encryption encryptor;
...
StreamTransformationFilter stfenc(encryptor, new Redirector(outSink), NO_PADDING);
Also see CBC_Mode on the Crypto++ wiki. You might also be interested in Authenticated Encryption on the wiki.
For this, you can also:
#ifndef CRYPTOPP_NO_GLOBAL_BYTE
namespace CryptoPP
{
using byte = unsigned char;
}
#endif
CRYPTOPP_NO_GLOBAL_BYTE is defined after the C++17 std::byte fixes. If CRYPTOPP_NO_GLOBAL_BYTE is not defined, then byte is in the global namespace (Crypto++ 5.6.5 and earlier). If CRYPTOPP_NO_GLOBAL_BYTE is defined, then byte is in the CryptoPP namespace (Crypto++ 6.0 and later).
For this:
std::ofstream testOut("./test.enc", std::ios::binary);
FileSink outSink(testOut);
You can also do:
FileSink outSink("./test.enc");
For this:
SHA256().CalculateDigest(passHash, (byte*) password.data(), password.size());
std::memcpy(key, passHash, AES::DEFAULT_KEYLENGTH);
std::memcpy(iv, passHash+AES::DEFAULT_KEYLENGTH, AES::BLOCKSIZE);
You might consider using HKDF as a derivation function. Use the one password but two different labels to ensure independent derivation. One label might be the string "AES key derivation version 1" and the other label might be "AES iv derivation version 1".
The label would be used as the info parameter for DeriveKey. You just need to call it twice, once for the key and once for the iv.
unsigned int DeriveKey (byte *derived, size_t derivedLen,
const byte *secret, size_t secretLen,
const byte *salt, size_t saltLen,
const byte *info, size_t infoLen) const
secret is the password. If you have salt then use it. Otherwise HKDF uses a default salt.
Also see HKDF on the Crypto++ wiki.
Finally, regarding this:
You can sidestep the blocksize restriction by switching to another mode like CTR_Mode. But then you have to be very careful of key or IV reuse, which may be difficult due to the password derivation scheme you are using.
You might also consider an Integrated Encryption Scheme, like Elliptic Curve Integrated Encryption Scheme. It is IND-CCA2, which is a strong notion of security. Everything you need is packaged into the encryption scheme.
Under ECIES each user gets a public/private keypair. Then, a large random secret is used as a seed for the AES key, iv and mac key. The the plaintext is encrypted and authenticated. Finally, the seed is encrypted under the user's public key. The password is still used, but it is used to decrypt the private key.

Why does Crypto++ think my messages are larger than they are?

I'm using the Crypto++ library for C++ to encrypt 128-bit messages with their public key and my private key from disk. However, when I call my function the program terminates with the error message:
terminate called after throwing an instance of
'CryptoPP::InvalidArgument' what(): RSA/OAEP-MGF1(SHA-1): message
length of 256 exceeds the maximum of 214 for this public key
I'm not sure why it thinks my messages are 256-bit when they are clearly 128-bit. Below is my code:
std::string encryptWithBothKeys(std::string key_name1, std::string key_name2, std::string plain){
std::string cipher1, cipher2;
AutoSeededRandomPool rng;
RSA::PublicKey pub_key;
RSA::PrivateKey priv_key;
loadPublicKey(key_name1, pub_key);
loadPrivateKey(key_name2, priv_key);
RSAES_OAEP_SHA_Encryptor e_pub(pub_key);
RSAES_OAEP_SHA_Encryptor e_priv(priv_key);
StringSource ss1(plain, true,
new PK_EncryptorFilter(rng, e_pub,
new StringSink(cipher1)
)
);
StringSource ss2(cipher1, true,
new PK_EncryptorFilter(rng, e_priv,
new StringSink(cipher2)
)
);
return cipher2;
}
void load(const std::string& filename, BufferedTransformation& bt){
FileSource file(filename.c_str(), true /*pumpAll*/);
file.TransferTo(bt);
bt.MessageEnd();
}
void loadPrivateKey(const std::string& filename, PrivateKey& key){
ByteQueue queue;
load(filename, queue);
key.Load(queue);
}
void loadPublicKey(const std::string& filename, PublicKey& key){
ByteQueue queue;
load(filename, queue);
key.Load(queue);
}
And in the main function I call it like this:
std::string encrypted_msg = encryptWithBothKeys("their.pub", "my.key", "0123456789ABCDEF");
Any suggestions?
EDIT: Turns out the ciphertext after the first encryption is size 256. I guess I need to figure out why it's increasing the size.
I'm not sure why it thinks my messages are 256-bit when they are clearly 128-bit. Below is my code:
Those are bytes, not bits.
What size RSA modulus are you using? I'm guessing its a 2048-bit key, which is 256 bytes, which leaves ≈214 bytes due to OAEP padding.
So the question becomes, what is the size of plain and cipher1 during this:
StringSource ss1(plain, true,
new PK_EncryptorFilter(rng, e_pub,
new StringSink(cipher1)
)
);
My guess is plain1 is small enough. However, when its padded and encrypted, it expands to 256 bytes as cipher1. So the message cipher1 is too large when this is executed:
StringSource ss2(cipher1, true,
new PK_EncryptorFilter(rng, e_priv,
new StringSink(cipher2)
)
);
Also, should the above be using PK_DecryptorFilter? Are you certain you want to encrypt again? If so, then why are you using e_priv?
Encrypting with the private key is not a valid cryptographic operation. If you want the "encrypt with the private key" thing, it usually means you want a Probabilistic Signature Scheme with Recovery (PSSR). Crypto++ supplies a couple of them.

InvalidCiphertext exception when decrypting ciphertext

I'm working in a new protocol for secure communication and I'm having problems to decrypt the ciphertext.
The data packet is saved in a uint8_t* variable and encrypted. Until this part is all going well. But when I try to decrypt I got the followings problems:
1) If I send the vector and the size (it's really 20 but I just want to decrypt the last 16 bytes):
CBC_Mode< AES >::Decryption decryptor;
decryptor.SetKeyWithIV( key, CryptoPP::AES::DEFAULT_KEYLENGTH, iv );
CryptoPP::StringSource ss( vector+4, 16 , true,
new CryptoPP::StreamTransformationFilter( decryptor,
new CryptoPP::StringSink( decryptedtext ) ) );
I get this:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
2) If I just send the vector without size:
CryptoPP::StringSource ss( vector+4, true,
new CryptoPP::StreamTransformationFilter( decryptor,
new CryptoPP::StringSink( decryptedtext ) ) );
The programs runs but I just get all 00:
Text Encrypted (20 bytes)
8c 97 b7 d8 74 80 3d 9f 9f 62 2e 93 38 c7 d1 b de a4 21 80
Text Decrypted (16 bytes)
0 0 0 0 0 0 0 0 68 0 0 0 0 0 0 0 0 0 0 0
I read that it could be that the key is not generated correctly, but I'm working with a size of 16 and here is how I do it:
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];
memset( key, 0x00, CryptoPP::AES::DEFAULT_KEYLENGTH );
memset( iv, 0x00, CryptoPP::AES::BLOCKSIZE );
3) I also tried to cast the vector to char and send it like an string:
CryptoPP::StringSource ss( reinterpret_cast<const unsigned char*>( (vector + 4) ), 16, true,
new CryptoPP::StreamTransformationFilter( decryptor,
new CryptoPP::StringSink( decryptedtext ) ) );
But again I get the same thing:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
Please help, I have tried for days to figure out what's wrong. This is taking me too long and I can't find the solutions.
Does anyone have any idea on what might be happening?
Let me know if you need further details, code or anything.
Edit:
4) One more thing that I tried was (another way to construct the decrypter):
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*>( (vector + 4) ), 16 );
stfDecryptor.MessageEnd();
But I get the same:
terminate called after throwing an instance of 'CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
Edit2:
The vector is created with this line (the way the vector is fulled is a quite complicated to put it here because I am using a platform for network encoding) :
uint8_t* vector;
Edit3:
This is how I encrypt the vector.
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*>( (vector + 4) ), 16 );
stfEncryptor.MessageEnd();
And after that I put the ciphertext again in the vector:
std::cout << std::endl << std::endl;
for(int i=0;i < 16; i++){
*(vector+ i + 4) = (ciphertext[i]) ;
}
terminate called after throwing an instance of CryptoPP::InvalidCiphertext'
what(): StreamTransformationFilter: invalid PKCS #7 block padding found
This is easy enough to fix. Catch a Crypto++ InvalidCiphertext exception. See the InvalidCiphertext Class Reference.
-----
If I just send the vector without size:
CryptoPP::StringSource ss( vector+4, true, ...
I think this might be matching the following StringSource constructor, which means the length is true, which probable means 1. To add insult to injury the attached StreamTransformationFilter is being coerced into the bool pumpAll:
StringSource (const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment=NULL)
You should probably enable warnings to catch these sorts of things. -Wall -Wextra are good choices. (Nothing will help the coercion of the pointer to the bool, though. See, for example, No pointer conversion warning for "bool" in C/C++ on the GCC mailing list).
-----
If I send the vector and the size (it's really 20 but I
just want to decrypt the last 16 bytes):
...
CryptoPP::StringSource ss( vector+4, 16 , true, ...
I don't think this is going to work as expected. CBC mode is not a random access mode (but I may not be parsing things correctly):
CBC_Mode< AES >::Encryption enc;
cout << "Random access: " << enc.IsRandomAccess() << endl;
Results in:
Random access: 0
I'm fairly certain its not going to work at byte sizes. You might be able to do it by adding a layer above the decryptor, but you will have to manage the initialization vector, then decrypt a block, and finally return the offest into the block.
-----
You should probably do something like the following. Its not efficient because it copes a string to a vector, but I wanted to try an use vectors since you seem to be using them.
encrypted.CopyTo(f2) is where you put your socket code. Your code will not need encrypted.CopyTo(f2).
// Creates the memory block and zero's it.
SecByteBlock key(AES::DEFAULT_KEYLENGTH), iv(AES::BLOCKSIZE);
/////////////////////////////////////////////////////////////
string m1;
vector<char> v1;
m1 = "Now is the time for all good men to come to the aide of their country";
copy(m1.begin(), m1.end(), back_inserter(v1));
CBC_Mode< AES >::Encryption enc;
enc.SetKeyWithIV(key, key.size(), iv, iv.size());
ByteQueue encrypted;
StreamTransformationFilter f1(enc, new Redirector(encrypted));
f1.PutWord32((uint32_t)v1.size(), BIG_ENDIAN_ORDER);
f1.Put((const unsigned char *) &v1[0], v1.size());
f1.MessageEnd();
/////////////////////////////////////////////////////////////
string m2;
vector<char> v2;
CBC_Mode< AES >::Decryption dec;
dec.SetKeyWithIV(key, key.size(), iv, iv.size());
ByteQueue decrypted;
StreamTransformationFilter f2(dec, new Redirector(decrypted));
encrypted.CopyTo(f2);
f2.MessageEnd();
uint32_t len;
decrypted.GetWord32(len, BIG_ENDIAN_ORDER);
v2.resize(len);
decrypted.Get((unsigned char *) &v2[0], v2.size());
copy(v2.begin(), v2.end(), back_inserter(m2));
/////////////////////////////////////////////////////////////
cout << "Message: " << m1 << endl;
cout << "Decrypted: " << m2 << endl;
It produces the expected results:
$ ./cryptopp-test.exe
Message: Now is the time for all good men to come to the aide of their country
Decrypted: Now is the time for all good men to come to the aide of their country
-----
Regarding your use of vector + 4: once the cipher text is decrypted, you can seek in it, and do things like read a length from it. That's what this does:
// Ciphertext is already decrypted
uint32_t len;
decrypted.GetWord32(len, BIG_ENDIAN_ORDER);
If you just want to discard the value, then try:
decrypted.Skip(4);
But then you'll have to figure out how to size your vector.
-----
I'm working in a new protocol for secure communication
Secure communications usually provides both confidentiality and authenticity assurances. You seem to be missing the latter since CBC mode only provides confidentiality.
It might be a good idea to use something that already exists, like IPSec (preferred) or TLS (will do in a pinch). Also, key agreement is going to be a pain point. Its another reason to consider using something like IPSec or TLS.
If you can't use something already available, then you should use an Authenticated Encryption mode so you get confidentiality and authenticity combined into a single mode. Try EAX, GCM or CCM mode.
If you do, then then change is fairly trivial:
EAX< AES >::Encryption enc;
enc.SetKeyWithIV(key, key.size(), iv, iv.size());
ByteQueue encrypted;
AuthenticatedEncryptionFilter f1(enc, new Redirector(encrypted));
And:
EAX< AES >::Decryption dec;
dec.SetKeyWithIV(key, key.size(), iv, iv.size());
ByteQueue decrypted;
AuthenticatedDecryptionFilter f2(dec, new Redirector(decrypted));
-----
You can print the cipher text by copying it to an encoder. Copying is non-destructive (unlike moving it with TransferTo):
string encoded;
HexEncoder encoder(new StringSink(encoded));
encrypted.CopyTo(encoder);
encoder.MessageEnd();
Fox CBC mode (less secure):
Encrypted: 7F9FFCAB00704EC79BB5F19C48FE7C668033B16F52E7E00671A38A06F4A7426E7FE31
95CA6A83C7414A76C250B42E63143C93E7A6B97B6304C5782DE3E62BD545706A9F62CD7AD57BC374
19B7510EBED
For EAX mode (more secure):
Encrypted: B75347EB75DF8E1F0424979E91CEECD455F5727B506A8AA932AF07E1DF6A7B037A245
FEC7A2270BFAB8110226769E1C0A12E95C455E9C714AF28DA330A2B01B3F2D541D4E68276193C018
7BA0246166AD26624E848EC8330D3
The extra bytes in EAX mode are the authentication tag. Its used to detect accidental and malicious tampering.
The problem was that I was encoding with padding and trying to decrypt it without. So I add not only in the encryption but in the descryption that it should work without padding.
Creation of the Key and IV:
CBC_Mode< AES >::Encryption encryptor;
encryptor.SetKeyWithIV( key, CryptoPP::AES::DEFAULT_KEYLENGTH, iv );
Encryption:
CryptoPP::StringSource ss( vector + 4 , 16, true,
new CryptoPP::StreamTransformationFilter( encryptor,
new CryptoPP::StringSink( ciphertext ),
CryptoPP::StreamTransformationFilter::NO_PADDING
) // StreamTransformationFilter
); // StringSource
Decryption:
CBC_Mode< AES >::Decryption decryptor;
decryptor.SetKeyWithIV( key, CryptoPP::AES::DEFAULT_KEYLENGTH, iv );
CryptoPP::StringSource ss( reinterpret_cast<const unsigned char*>( (vector + 4) ), 16, true,
new CryptoPP::StreamTransformationFilter( decryptor,
new CryptoPP::StringSink( decryptedtext ), CryptoPP::StreamTransformationFilter::NO_PADDING) );
I did this because I don't want to work with padding anymore.

256-bit Rijndael blocksize?

I am trying to port a decryption routine from C# program to C++ using cryptopp, but I have a problem. In the C# program, the key and IV are both 256 bits. So I tried to do something like this:
char *hash1 = "......";
std::string hash2;
CryptoPP::StringSource(hash1, true,new CryptoPP::Base64Decoder(new CryptoPP::StringSink(hash2)));
CryptoPP::Rijndael::Decryption decryptor(key, 32);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( decryptor, iv);
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, (new CryptoPP::StringSink( decryptedData ) ));
stfDecryptor.Put( reinterpret_cast<const unsigned char*>( hash2.c_str() ), hash2.size() );
stfDecryptor.MessageEnd();
and I am getting
StreamTransformationFilter: ciphertext length is not a multiple of block size.
I tried to pass IV size like this:
CryptoPP::CBC_Mode<CryptoPP::Rijndael >::Decryption decr;
decr.SetKeyWithIV(key, 32, iv, 32);
But then I get:
IV length 32 exceeds the maximum of 16.
So, how can I decrypt data, when it was encrypted by IV with length = 32?
Looking at the implementation, the current iterations of crypto++ only support Rijndael with a block size of 16 bytes. As the IV has to be precisely a single block for CBC mode, Rijndael with a 256 bit block size does not seem to be possible.