使用 VS2017 在发布模式下 Crypto++ AES 崩溃
Crypto++ AES crashing in release mode using VS2017
我有以下代码。一个非常简单的字符串"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: invalid PKCS #7 block padding found")
The problem is when I build in debug mode, it works fine but when I do it in release mode I get an exception from Crypto++ code ("StreamTransformationFilter: invalid PKCS #7 block padding found") ...
这似乎是与全局优化相关的编译器问题。我们的解决方法是禁用源文件 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
另请参阅 MSDN 上的 Commit f57df06c5e6d and pragma optimize
。
如果您的机器有 AES-NI 但您想重现该问题,请注释掉 cpu.cpp
中分配 g_hasAESNI
的代码。 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);
我有以下代码。一个非常简单的字符串"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: invalid PKCS #7 block padding found")
The problem is when I build in debug mode, it works fine but when I do it in release mode I get an exception from Crypto++ code ("StreamTransformationFilter: invalid PKCS #7 block padding found") ...
这似乎是与全局优化相关的编译器问题。我们的解决方法是禁用源文件 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
另请参阅 MSDN 上的 Commit f57df06c5e6d and pragma optimize
。
如果您的机器有 AES-NI 但您想重现该问题,请注释掉 cpu.cpp
中分配 g_hasAESNI
的代码。 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);