如何检查 OpenSSL 是否支持/使用英特尔 AES-NI? [英] How can I check if OpenSSL is support/use the Intel AES-NI?

查看:17
本文介绍了如何检查 OpenSSL 是否支持/使用英特尔 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中对OPENSSL_ia32cap_loc的讨论 手册页.另请参阅 在运行时验证 AES-NI 的使用? 在 OpenSSL 邮件列表中.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆