如何检查OpenSSL是否支持/使用Intel AES-NI? [英] How can I check if OpenSSL is support/use the Intel AES-NI?
问题描述
请告诉我,如何检查OpenSSL是否受支持/是否使用英特尔AES-NI?
如何检查OpenSSL是否受支持/是否使用英特尔AES-NI?
它不是那么简单,尽管应该如此. OpenSSL用于提供获取ia32处理器检测到的功能的功能,但不再可用.请参见 OPENSSL_ia32cap
手册页中对OPENSSL_ia32cap_loc
的讨论. .另请参见在运行时验证AES-NI使用?在OpenSSL邮件列表中.
如果您要链接到OpenSSL静态库,则可以使用:
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
不会 导出.在这种情况下,您需要编写自己的检测代码.
我什至不理会OpenSSL,因为它仅适用于库的静态链接.我在下面共享了用于检测的代码.我相信我从Intel的Dave Johnston(他设计了RDRAND电路)中删除了很大一部分.
注意 :以下代码可能会错误地拒绝具有AES-NI的AMD处理器.我没有要测试的处理器,所以我无法提供代码.
注意 :下面的代码将无法在Valgrind下正常运行. AES-NI或RDRAND指令没有仿真功能,因此Valgrind从CPUID
返回医生"值,因此它们似乎不可用.请参阅邮件列表上的在Valgrind下运行时,内联汇编的错误结果. /p>
即使AES-NI可用,它也不是 表示您将要使用它.
如果使用诸如AES_*
之类的底层原语,则您将不使用AES-NI,因为它是软件实现.
如果使用的是高级EVP_*
齿轮,则将使用AES-NI(如果可用).该库将自动切换到AES-NI.
如果 AES-NI可用,但您不想使用它,则在启动程序之前执行以下操作:
$ export OPENSSL_ia32cap="~0x200000200000000"
您可以使用以下OpenSSL命令测试速度差异.切换上方的导出以查看差异:
$ 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)
);
}
Tell me please, how can I check if OpenSSL is support/use the Intel AES-NI?
how can I check if OpenSSL is support/use the Intel AES-NI?
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.
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 */
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.
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).
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.
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.
Even though AES-NI is available, it does not mean you are going to use it.
If you use the low level primitives like AES_*
, then you will not use AES-NI because its a software implementation.
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.
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"
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是否支持/使用Intel AES-NI?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!