如何检查 OpenSSL 是否支持/使用英特尔 AES-NI? [英] How can I check if OpenSSL is support/use the Intel AES-NI?
问题描述
请告诉我,如何检查 OpenSSL 是否支持/使用 Intel AES-NI?
Tell me please, how can I check if OpenSSL is support/use the Intel AES-NI?
推荐答案
如何检查 OpenSSL 是否支持/使用 Intel AES-NI?
how can I check if OpenSSL is support/use the Intel AES-NI?
它不是那么简单,虽然它应该是.OpenSSL 曾经提供一个函数来获取为 ia32 处理器检测到的功能,但它不再可用.请参阅OPENSSL_ia32cap中对
手册页.另请参阅 在运行时验证 AES-NI 的使用? 在 OpenSSL 邮件列表中.OPENSSL_ia32cap_loc
的讨论
Its not that simple, though it should be. OpenSSL used to provide a function to get the capabilities detected for an ia32 processor, but its no longer available. See the discussion of OPENSSL_ia32cap_loc
in the OPENSSL_ia32cap
man page. Also see Verify AES-NI use at runtime? on the OpenSSL mailing list.
如果您要链接到 OpenSSL 静态库,则可以使用:
If you are linking to the OpenSSL static library, then you can use:
extern unsigned int OPENSSL_ia32cap_P[];
# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32)))
if(AESNI_CAPABLE)
/* AES-NI is available */
如果您正在链接到 OpenSSL 共享对象,则OPENSSL_ia32cap_P
符号将不导出.在这种情况下,您需要编写自己的检测代码.
If you are linking to the OpenSSL shared object, then the symbol OPENSSL_ia32cap_P
is not exported. In this case, you need to write your own detection code.
我什至不理会 OpenSSL,因为它只适用于库的静态链接.我在下面分享了我用于检测的代码.我相信我从英特尔的 Dave Johnston(他设计了 RDRAND 电路)那里窃取了其中的很大一部分.
I don't even bother with OpenSSL since it only works with static linking of the library. I shared the code I use for detection below. I believe I ripped a significant portion of it from Dave Johnston of Intel (he designed the RDRAND circuit).
注意:下面的代码可能会错误地拒绝 带有 AES-NI 的 AMD 处理器.我没有要测试的处理器,所以我无法提供代码.
Note: the code below could incorrectly reject an AMD processor with AES-NI. I don't have a processor to test on, so I can't offer the code.
注意:以下代码在 Valgrind 下不会按预期执行.没有针对 AES-NI 或 RDRAND 指令的仿真,因此 Valgrind 从 CPUID
返回一个篡改"值,因此它们似乎不可用.请参阅邮件列表中的在 Valgrind 下运行时内联汇编的错误结果.
Note: the code below will not perform as expected under Valgrind. There's no emulation for the AES-NI or RDRAND instructions, so Valgrind returns a "doctored" value from CPUID
so it appears they are not available. See Incorrect results from inline assembly when running under Valgrind on the mailing list.
尽管 AES-NI 可用,但它不意味着您会使用它.
Even though AES-NI is available, it does not mean you are going to use it.
如果您使用像 AES_*
这样的低级原语,那么您将不使用 AES-NI,因为它是一种软件实现.
If you use the low level primitives like AES_*
, then you will not use AES-NI because its a software implementation.
如果您使用高级EVP_*
设备,那么您将使用AES-NI(如果可用).该库将自动切换到 AES-NI.
If you use the high level EVP_*
gear, then you will use AES-NI if its available. The library will switch to AES-NI automatically.
如果 AES-NI 可用但您不想使用它,请在启动程序之前执行以下操作:
If AES-NI is available but you don't want to use it, then perform the following before launching you program:
$ export OPENSSL_ia32cap="~0x200000200000000"
您可以使用以下 OpenSSL 命令测试速度差异.切换上面的导出以查看差异:
You can test the speed difference with the following OpenSSL command. Toggle the export above to see the differences:
$ openssl speed -elapsed -evp aes-128-ecb
<小时>
struct CPUIDinfo {
unsigned int EAX;
unsigned int EBX;
unsigned int ECX;
unsigned int EDX;
};
int HasIntelCpu();
int HasAESNI();
int HasRDRAND();
void cpuid_info(CPUIDinfo *info, const unsigned int func,
const unsigned int subfunc);
int HasIntelCpu() {
CPUIDinfo info;
cpuid_info(&info, 0, 0);
if (memcmp((char *) (&info.EBX), "Genu", 4) == 0
&& memcmp((char *) (&info.EDX), "ineI", 4) == 0
&& memcmp((char *) (&info.ECX), "ntel", 4) == 0) {
return 1;
}
return 0;
}
int HasAESNI() {
if (!HasIntelCpu())
return 0;
CPUIDinfo info;
cpuid_info(&info, 1, 0);
static const unsigned int AESNI_FLAG = (1 << 25);
if ((info.ECX & AESNI_FLAG) == AESNI_FLAG)
return 1;
return 0;
}
int HasRDRAND() {
if (!HasIntelCpu())
return 0;
CPUIDinfo info;
cpuid_info(&info, 1, 0);
static const unsigned int RDRAND_FLAG = (1 << 30);
if ((info.ECX & RDRAND_FLAG) == RDRAND_FLAG)
return 1;
return 0;
}
void cpuid_info(CPUIDinfo *info, unsigned int func, unsigned int subfunc) {
__asm__ __volatile__ (
"cpuid"
: "=a"(info->EAX), "=b"(info->EBX), "=c"(info->ECX), "=d"(info->EDX)
: "a"(func), "c"(subfunc)
);
}
这篇关于如何检查 OpenSSL 是否支持/使用英特尔 AES-NI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!