Сбой Crypto ++ AES в режиме релиза с использованием VS2017 - PullRequest
0 голосов
/ 29 октября 2018

У меня есть следующий код. Очень простой пример шифрования и дешифрования строки «abcd». Я пробовал это с примером из Crypto ++ (https://www.cryptopp.com/wiki/CBC_mode), и он выдает то же исключение.

AutoSeededRandomPool rand;

SecByteBlock key(nullptr, AES::MAX_KEYLENGTH);
rand.GenerateBlock(key, key.size());

byte iv[AES::BLOCKSIZE];
rand.GenerateBlock(iv, AES::BLOCKSIZE);

std::string encryptedData;
CBC_Mode<AES>::Encryption cbcEncryption(key, key.size(), iv);

StringSource ss("abcd", true,
    new StreamTransformationFilter(cbcEncryption,
        new StringSink(encryptedData)
    )
);

std::string decryptedData;

CBC_Mode<AES>::Decryption cbcDecryption(key, key.size(), iv);

StringSource ss2(encryptedData, true,
    new StreamTransformationFilter(cbcDecryption,
        new StringSink(decryptedData)
    )
);

Проблема заключается в том, что когда я строю в режиме отладки, он работает нормально, но когда я делаю это в режиме релиза, я получаю исключение из кода Crypto ++ («StreamTransformationFilter: недопустимое заполнение блока PKCS # 7 найдено»)

Exception

1 Ответ

0 голосов
/ 06 ноября 2018

Проблема заключается в том, что когда я строю в режиме отладки, он работает нормально, но когда я делаю это в режиме релиза, я получаю исключение из кода Crypto ++ («StreamTransformationFilter: найден неверный отступ блока PKCS # 7») ...

Похоже, это проблема компилятора, связанная с глобальной оптимизацией. Наш обходной путь - отключить глобальные оптимизации для исходного файла rijndael.cpp.

В rijndael.cpp вы можете добавить следующее в верхней части файла, чтобы избежать проблемы:

#if defined(_MSC_VER) && (_MSC_VER >= 1910)
# pragma optimize("", off)
# pragma optimize("ts", on)
#endif

Вы можете воспроизвести проблему следующим образом в rijndael.cpp:

#if defined(_MSC_VER) && (_MSC_VER >= 1910)
# pragma optimize("", off)
# pragma optimize("g", on)
#endif

Также см. Фиксация f57df06c5e6d и pragma optimize в MSDN.


Если на вашем компьютере установлен AES-NI, но вы хотите воспроизвести проблему, закомментируйте код, который присваивает g_hasAESNI в cpu.cpp. g_hasAESNI сохранит значение по умолчанию false.

--- a/cpu.cpp
+++ b/cpu.cpp
@@ -242,7 +242,7 @@ void DetectX86Features()
        g_hasSSSE3 = g_hasSSE2 && ((cpuid1[2] & (1<< 9)) != 0);
        g_hasSSE41 = g_hasSSE2 && ((cpuid1[2] & (1<<19)) != 0);
        g_hasSSE42 = g_hasSSE2 && ((cpuid1[2] & (1<<20)) != 0);
-       g_hasAESNI = g_hasSSE2 && ((cpuid1[2] & (1<<25)) != 0);
+       //g_hasAESNI = g_hasSSE2 && ((cpuid1[2] & (1<<25)) != 0);
        g_hasCLMUL = g_hasSSE2 && ((cpuid1[2] & (1<< 1)) != 0);
...