我想知道是否有办法在C#.NET的主机系统CPU中测试AES-NI 的存在.
让我先说这个问题不是询问如何使用 .NET中的AES-NI.事实证明,只要AESCryptoServiceProvider使用AES-NI就可以使用它.这个结果基于独立的基准测试,我比较了AESCryptoServiceProviderTrueCrypt提供的基准测试的性能,确实支持AES-NI.在使用和不使用AES-NI的两台机器上,结果令人惊讶地相似.
我希望能够测试它的原因是能够向用户表明他们的计算机支持AES-NI.这将是相关的,因为它将减少涉及诸如"但我的朋友也有Core i5但是他的速度快得多的问题"的支持事件.如果程序的用户界面可以向用户指示他们的系统支持或不支持AES-NI,则还可以指示"由于该系统不支持AES-NI,因此性能较低是正常的".
(我们可以感谢英特尔对不同处理器步进的所有困惑!:-))
有没有办法通过WMI检测这些信息?
似乎 SO: Inline Assembly Code to Get CPU ID上也有类似的问题,答案很好。
但这个答案需要一些调整才能满足您的需要。
首先,据我了解,AES-NI 只能存在于 64 位处理器上,对吧?那么您可以忽略上面答案中的所有 32 位代码。
其次,您需要 ECX 寄存器或更确切地说它的第 25 位,因此您必须稍微更改代码:
private static bool IsAESNIPresent()
{
byte[] sn = new byte[16]; // !!! Here were 8 bytes
if (!ExecuteCode(ref sn))
return false;
var ecx = BitConverter.ToUInt32(sn, 8);
return (ecx & (1 << 25)) != 0;
}
Run Code Online (Sandbox Code Playgroud)
最后,您需要将 ECX 寄存器存储在数组中:
byte[] code_x64 = new byte[] {
0x53, /* push rbx */
0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, /* mov rax, 0x1 */
0x0f, 0xa2, /* cpuid */
0x41, 0x89, 0x00, /* mov [r8], eax */
0x41, 0x89, 0x50, 0x04, /* mov [r8+0x4], ebx !!! changed */
0x41, 0x89, 0x50, 0x08, /* mov [r8+0x8], ecx !!! added */
0x41, 0x89, 0x50, 0x0C, /* mov [r8+0xC], edx !!! added*/
0x5b, /* pop rbx */
0xc3, /* ret */
};
Run Code Online (Sandbox Code Playgroud)
据我所知,这就是所有的变化。