从C#测试AES-NI指令

fdm*_*ion 6 .net c# aes

我想知道是否有办法在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检测这些信息?

Mar*_*nko 2

似乎 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)

据我所知,这就是所有的变化。