Search code examples
c++aescrypto++

Crypto++ AES does not match standard fips197


I'm writing a class which based on crypto++ library. This class a simple way for the encode and decode data using AES algorithm. Here my code:

class AESEncryption
{
public:
    static std::string decrypt(const std::string& data, const std::string& password);
    static std::string encrypt(const std::string& data, const std::string& password);
};
std::string AESEncryption::encrypt(const std::string& data, const std::string& password)
{
    std::vector<CryptoPP::byte> key(password.begin(), password.end());
    std::string result;
    CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption encryption;
    encryption.SetKey(key.data(), key.size());
    CryptoPP::StringSource(data, true, new CryptoPP::StreamTransformationFilter(encryption, new CryptoPP::StringSink(result)));

    return result;
}

std::string AESEncryption::decrypt(const std::string& data, const std::string& password)
{
    std::vector<CryptoPP::byte> key(password.begin(), password.end());
    std::string result;
    CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption decryption;
    decryption.SetKey(key.data(), key.size());
    CryptoPP::StringSource(data, true, new CryptoPP::StreamTransformationFilter(decryption, new CryptoPP::StringSink(result)));
    return result;
}

I began testing my class using samples from standard fips197 (page 46)

Here my test code:

namespace
{
    QByteArray key(QByteArray::fromHex("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"));
    QByteArray plainText(QByteArray::fromHex("00112233445566778899AABBCCDDEEFF"));
    QByteArray result(QByteArray::fromHex("8EA2B7CA516745BFEAFC49904B496089"));
}

TEST(AESEncrypt, Valid)
{
    std::string key_str(key.begin(), key.end());
    std::string paintText_str(plainText.begin(), plainText.end());
    std::string expected_result(result.begin(), result.end());
    auto result = AESEncryption::encrypt(paintText_str, key_str);
    EXPECT_EQ(result, expected_result);
    auto decrypt = AESEncryption::decrypt(result, key_str);
    EXPECT_EQ(decrypt, paintText_str);
}

And I got the next result:

Expected equality of these values:
  result
    Which is: "\x8E\xA2\xB7\xCAQgE\xBF\xEA\xFCI\x90KI`\x89\x9F;u\x4\x92o\x8B\xD3n1\x18\xE9\x3\xA4\xCDJ"
  expected_result
    Which is: "\x8E\xA2\xB7\xCAQgE\xBF\xEA\xFCI\x90KI`\x89"

I got useless data:

\x9F;u\x4\x92o\x8B\xD3n1\x18\xE9\x3\xA4\xCDJ

How to fix it? What can I do which it encryption matches standard?


Solution

  • Expected equality of these values:
      result
        Which is: "\x8E\xA2\xB7\xCAQgE\xBF\xEA\xFCI\x90KI`\x89\x9F;u\x4\x92o\x8B\xD3n1\x18\xE9\x3\xA4\xCDJ"
      expected_result
        Which is: "\x8E\xA2\xB7\xCAQgE\xBF\xEA\xFCI\x90KI`\x89"
    

    How to fix it? What can I do which it encryption matches standard?

    The FIPS 197 ECB mode tests are provided without padding. However, the code below uses PKCS padding which will add an additional 16-bytes due to the padding:

    StringSource(data, true, new StreamTransformationFilter(encryption, new StringSink(result)));
    

    More correctly, ECB mode uses DEFAULT_PADDING by default, which is PKCS_PADDING for ECB mode and CBC mode. I think you should use NO_PADDING instead:

    StringSource(data, true, new StreamTransformationFilter(encryption, new StringSink(result), NO_PADDING));
    

    Also see the docs for StreamTransformationFilter. This is what is happening with the filter you are using:

    StreamTransformationFilter (
        StreamTransformation &c,
        BufferedTransformation *attachment=NULL,
        BlockPaddingScheme padding=DEFAULT_PADDING)
    

    Regarding "Crypto++ AES does not match standard fips197", you can use the following to test the library with the FIPS 197 test vectors (in addition to SP800-38):

    $ ./cryptest.exe tv aes
    Using seed: 1544068124
    
    Testing SymmetricCipher algorithm AES/ECB.
    ....
    Testing SymmetricCipher algorithm AES/CBC.
    ........
    Testing SymmetricCipher algorithm AES/CFB.
    .......
    Testing SymmetricCipher algorithm AES/OFB.
    ....
    Testing SymmetricCipher algorithm AES/CTR.
    .............