如何检查OpenSSL是否支持/使用Intel AES-NI?

如何检查OpenSSL是否支持/使用Intel AES-NI?,openssl,aes,Openssl,Aes,请告诉我,我如何检查OpenSSL是否支持/使用Intel AES-NI 如何检查OpenSSL是否支持/使用Intel AES-NI 虽然应该如此,但它并没有那么简单。OpenSSL用于提供一个函数来获取ia32处理器检测到的功能,但它不再可用。请参阅中关于OPENSSL\u ia32cap\u loc的讨论。另请参见OpenSSL邮件列表中的 如果要链接到OpenSSL静态库,则可以使用: extern unsigned int OPENSSL_ia32cap_P[]; # define A

请告诉我,我如何检查OpenSSL是否支持/使用Intel AES-NI

如何检查OpenSSL是否支持/使用Intel AES-NI

虽然应该如此,但它并没有那么简单。OpenSSL用于提供一个函数来获取ia32处理器检测到的功能,但它不再可用。请参阅中关于
OPENSSL\u ia32cap\u loc
的讨论。另请参见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 speed -elapsed -evp aes-128-ecb

struct CPUIDinfo{
无符号整数EAX;
无符号整数EBX;
无符号整数ECX;
无符号整数EDX;
};
int HasIntelCpu();
int HasAESNI();
int HasRDRAND();
无效cpuid_info(CPUIDinfo*info,常量unsigned int func,
常量无符号整数子函数);
int HasIntelCpu(){
CPUIDinfo信息;
cpuid_info(&info,0,0);
如果(memcmp((char*)(&info.EBX),“Genu”,4)=0
&&memcmp((char*)(&info.EDX),“ineI”,4)=0
&&memcmp((char*)(&info.ECX),“ntel”,4)=0){
返回1;
}
返回0;
}
int HasAESNI(){
如果(!haintelcpu())
返回0;
CPUIDinfo信息;
cpuid_信息(&info,1,0);
静态常量无符号整数AESNI_标志=(1 EBX),“=c”(信息->ECX),“=d”(信息->EDX)
:“a”(职能),“c”(子职能)
);
}

根据以下提供的信息构建的两个快速一行程序:

openssl速度-运行时间-evp aes-128-cbc ... OPENSSL_ia32cap=“~0x2000000000”OPENSSL速度-运行时间-evp aes-128-cbc ...
第一行的输出速度应明显快于第二行。在我的i5测试机器上,几乎是两倍。

如何撤消导出?@user124384 Call
取消设置OPENSSL\u ia32cap
。OPENSSL\u ia32cap的链接已断开。看起来这就是当前的来源:它不应该是4倍或8倍的速度,而不是两倍的速度吗?对于16个大小的块,我得到了两倍的性能,但是对于8192个大小的块,性能接近14倍。
$ 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 speed -elapsed -evp aes-128-cbc ... OPENSSL_ia32cap="~0x200000200000000" openssl speed -elapsed -evp aes-128-cbc ...