[Intel CPU中的安全指令集].01.如何检测

Intel CPU中有很多不同的指令集,如:MMX,SSE,SSE2,AVX,AES,VT-x等。而其中有一些与大数计算和密码算法相关的指令集,如AES-NI,SHA,RDRAND等,这些指令集可使得我们的加解密等密码学中的计算更快速并且更安全。

那我们该如何检测CPU中所支持的指令集呢?CPUID指令。
我们使用它来得到CPU的各种信息,并会根据不同的参数把相关信息存到eax,ebx,ecx和edx四个寄存器中。
在Windows中,我们可以直接使用__cpuid()和__cpuidex()函数。


函数: 


    void __cpuid(int CPUInfo[4],   int InfoType);

    void __cpuidex(   int CPUInfo[4],   int InfoType,   int ECXValue);
        
参数
[out] CPUInfo 包含有关支持的功能和 CPU 的集合的信息的四个整数。
[in] InfoType 指示的代码的信息此命令检索。
[in] ECXValue ECX 寄存器值在内部之前的生成 cpuid 命令。
头文件

而在linux上,我们可以用内嵌汇编编写同样的__cpuid()和__cpuidex()函数。代码如下:

#ifndef __linux__

#include
#else

static void __cpuidex(unsigned int where[4], unsigned int leaf, unsigned int ECXValue) {
    asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)), "=c"(*(where+2)),"=d"(*(where+3)):"a"(leaf), "c"(ECXValue));
    return;
}

static void __cpuid(unsigned int where[4], unsigned int leaf) {
    asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)), "=c"(*(where+2)),"=d"(*(where+3)):"a"(leaf));
    return;
}
#endif

在使用CPUID指令时,可设给与下列表格相同的eax和ecx的值,来得到对应的CPU信息:

EAX ECX RETURN
0x00 0 Get vendor ID
0x01 0 Processor Info and Feature Bits
0x02 0 Cache and TLB Descriptor information
0x03 0 Processor Serial Number
0x07 0 Structured Extended Feature Flags Enumeration Leaf (Output depends on ECX input value)

 我们可以使用下列代码,检测CPU是否为INTEL生产:

 unsigned int cpuid_results[4];
 __cpuid(cpuid_results,0);

 if (cpuid_results[0] < 1)
  return 0;
/*
 *      MSB         LSB
 * EBX = 'u' 'n' 'e' 'G'
 * EDX = 'I' 'e' 'n' 'i'
 * ECX = 'l' 'e' 't' 'n'
 */
 /* According to http://en.wikipedia.org/wiki/CPUID */
 
 if (memcmp((unsigned char *)&cpuid_results[1], "Genu", 4) != 0 ||
  memcmp((unsigned char *)&cpuid_results[3], "ineI", 4) != 0 ||
  memcmp((unsigned char *)&cpuid_results[2], "ntel", 4) != 0)
  return 0;

我们所关心的CPU功能信息主要是CPUID.1.0(EAX=1,ECX=0)和CPUID.7.0(EAX=7,ECX=0)这两个分支。
CPUID.1.0(EAX=1,ECX=0)
功能信息主要存于ECX和EDX寄存器中。与安全相关的指令有:

PCLMULQDQ CPUID.1.0.ECX[1]
AES-NI CPUID.1.0.ECX[25]
RDRAND CPUID.1.0.ECX[30]


[Intel CPU中的安全指令集].01.如何检测_第1张图片

检测代码如下:

 __cpuid(cpuid_results,1);
 if ((cpuid_results[2] & (1 << 1)) != 0) {
  // CPUID.1.ECX[1]
        g_cpu_features |= CPU_X86_FEATURE_PCLMULQDQ;
    }
 if ((cpuid_results[2] & (1 << 25)) != 0) {
        g_cpu_features |= CPU_X86_FEATURE_AESNI; // aes-ni
    }
 if ((cpuid_results[2] & (1 << 30)) != 0) {
  //RDRAND is not an AVX instruction. It is a normal instruction.
        g_cpu_features |= CPU_X86_FEATURE_RDRND; // secure key
    }

CPUID.7.0(EAX=7,ECX=0)
功能信息主要存于EBX寄存器中。与安全相关的指令有:

OS Guard(SMEP) CPUID.7.0.EBX[7]
RDSEED CPUID.7.0.EBX[18]
ADX CPUID.7.0.EBX[19]
SHA CPUID.7.0.EBX[29]

 

检测代码如下:

 // Look for CPUID.7.0.EBX
   // EAX = 7, ECX = 0
 __cpuidex(cpuid_results,7,0);
 printf("CPUID.7.0.EBX 0x%08x:\n", cpuid_results[1]);
 if ((cpuid_results[1] & (1 << 7)) != 0) {
  // SMEP is identified by CPUID leaf 7 EBX[7], which is 0 before
  // CPUID.7.0.EBX[7]
        g_cpu_features |= CPU_X86_FEATURE_SMEP;
    }
 if ((cpuid_results[1] & (1 << 18)) != 0) {
  // Intel® RDSEED Extensions
  // CPUID.7.0.EBX[18]
        g_cpu_features |= CPU_X86_FEATURE_RDSEED;
    }
 if ((cpuid_results[1] & (1 << 19)) != 0) {
  // Intel® ADX Extensions
  // CPUID.7.0.EBX[19]
        g_cpu_features |= CPU_X86_FEATURE_ADX;
    }
 if ((cpuid_results[1] & (1 << 29)) != 0) {
  // Intel® SHA Extensions
  // CPUID.7.0.EBX[29]
        g_cpu_features |= CPU_X86_FEATURE_SHA;
    }

相关链接:

[1] CPUID http://en.wikipedia.org/wiki/CPUID

[2] Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 2A 

http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-manual.html

[3] PCLMULQDQ Instruction and Elliptic Curve Cryptography: Paper

http://www.intel.com/content/www/us/en/intelligent-systems/wireless-infrastructure/polynomial-multiplication-instructions-paper.html

[4] Intel® Advanced Encryption Standard Instructions (AES-NI)

http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-instructions-aes-ni/

[5] What is Intel(r) Secure Key Technology?

http://software.intel.com/en-us/blogs/2012/05/14/what-is-intelr-secure-key-technology

[6] New Instructions Supporting Large Integer Arithmetic on Intel® Architecture Processors

http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-large-integer-arithmetic-paper.pdf

[7] Intel? SHA Extensions

http://software.intel.com/en-us/articles/intel-sha-extensions

[8] The Difference Between RDRAND and RDSEED

http://software.intel.com/en-us/blogs/2012/11/17/the-difference-between-rdrand-and-rdseed

[9] INTRODUCTION TO INTEL® AES-NI AND INTEL® SECURE KEY INSTRUCTIONS

http://software.intel.com/en-us/articles/introduction-to-intel-aes-ni-and-intel-secure-key-instructions

 [10] Performance Impact of Intel® Secure Key on OpenSSL

http://software.intel.com/en-us/articles/performance-impact-of-intel-secure-key-on-openssl

[11] SMEP: What is it, and how to beat it on Windows

http://j00ru.vexillium.org/?p=783

[12] Windows Compiler Intrinsics: __cpuid, __cpuidex

http://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.90).aspx

http://bbs.xwh.cn/thread-8285132-1-1.html

你可能感兴趣的:([Intel CPU中的安全指令集].01.如何检测)