Index: nss/lib/freebl/rijndael.c |
diff --git a/nss/lib/freebl/rijndael.c b/nss/lib/freebl/rijndael.c |
index 970386749b2f4f97dc2f6b30d84fae3736d835fe..4e4be79fdf10696e8b286a31cc06d52d7199d360 100644 |
--- a/nss/lib/freebl/rijndael.c |
+++ b/nss/lib/freebl/rijndael.c |
@@ -18,17 +18,20 @@ |
#include "ctr.h" |
#include "gcm.h" |
-#if USE_HW_AES |
-#include "intel-gcm.h" |
+#ifdef USE_HW_AES |
#include "intel-aes.h" |
#include "mpi.h" |
static int has_intel_aes = 0; |
+static PRBool use_hw_aes = PR_FALSE; |
+ |
+#ifdef INTEL_GCM |
+#include "intel-gcm.h" |
static int has_intel_avx = 0; |
static int has_intel_clmul = 0; |
-static PRBool use_hw_aes = PR_FALSE; |
static PRBool use_hw_gcm = PR_FALSE; |
#endif |
+#endif /* USE_HW_AES */ |
/* |
* There are currently five ways to build this code, varying in performance |
@@ -833,7 +836,6 @@ rijndael_encryptECB(AESContext *cx, unsigned char *output, |
SECStatus rv; |
AESBlockFunc *encryptor; |
- |
encryptor = (blocksize == RIJNDAEL_MIN_BLOCKSIZE) |
? &rijndael_encryptBlock128 |
: &rijndael_encryptBlock; |
@@ -966,17 +968,28 @@ AESContext * AES_AllocateContext(void) |
} |
-#if USE_HW_AES |
+#ifdef INTEL_GCM |
/* |
* Adapted from the example code in "How to detect New Instruction support in |
* the 4th generation Intel Core processor family" by Max Locktyukhin. |
+ * |
+ * XGETBV: |
+ * Reads an extended control register (XCR) specified by ECX into EDX:EAX. |
*/ |
static PRBool |
check_xcr0_ymm() |
{ |
PRUint32 xcr0; |
#if defined(_MSC_VER) |
+#if defined(_M_IX86) |
+ __asm { |
+ mov ecx, 0 |
+ xgetbv |
+ mov xcr0, eax |
+ } |
+#else |
xcr0 = (PRUint32)_xgetbv(0); /* Requires VS2010 SP1 or later. */ |
+#endif |
#else |
__asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx"); |
#endif |
@@ -1022,7 +1035,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
PORT_SetError(SEC_ERROR_INVALID_ARGS); |
return SECFailure; |
} |
-#if USE_HW_AES |
+#ifdef USE_HW_AES |
if (has_intel_aes == 0) { |
unsigned long eax, ebx, ecx, edx; |
char *disable_hw_aes = getenv("NSS_DISABLE_HW_AES"); |
@@ -1030,6 +1043,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
if (disable_hw_aes == NULL) { |
freebl_cpuid(1, &eax, &ebx, &ecx, &edx); |
has_intel_aes = (ecx & (1 << 25)) != 0 ? 1 : -1; |
+#ifdef INTEL_GCM |
has_intel_clmul = (ecx & (1 << 1)) != 0 ? 1 : -1; |
if ((ecx & (1 << 27)) != 0 && (ecx & (1 << 28)) != 0 && |
check_xcr0_ymm()) { |
@@ -1037,17 +1051,22 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
} else { |
has_intel_avx = -1; |
} |
+#endif |
} else { |
has_intel_aes = -1; |
+#ifdef INTEL_GCM |
has_intel_avx = -1; |
has_intel_clmul = -1; |
+#endif |
} |
} |
use_hw_aes = (PRBool) |
(has_intel_aes > 0 && (keysize % 8) == 0 && blocksize == 16); |
+#ifdef INTEL_GCM |
use_hw_gcm = (PRBool) |
(use_hw_aes && has_intel_avx>0 && has_intel_clmul>0); |
#endif |
+#endif /* USE_HW_AES */ |
/* Nb = (block size in bits) / 32 */ |
cx->Nb = blocksize / 4; |
/* Nk = (key size in bits) / 32 */ |
@@ -1057,7 +1076,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
/* copy in the iv, if neccessary */ |
if (mode == NSS_AES_CBC) { |
memcpy(cx->iv, iv, blocksize); |
-#if USE_HW_AES |
+#ifdef USE_HW_AES |
if (use_hw_aes) { |
cx->worker = (freeblCipherFunc) |
intel_aes_cbc_worker(encrypt, keysize); |
@@ -1068,7 +1087,7 @@ aes_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
? &rijndael_encryptCBC : &rijndael_decryptCBC); |
} |
} else { |
-#if USE_HW_AES |
+#ifdef USE_HW_AES |
if (use_hw_aes) { |
cx->worker = (freeblCipherFunc) |
intel_aes_ecb_worker(encrypt, keysize); |
@@ -1156,7 +1175,7 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
cx->isBlock = PR_FALSE; |
break; |
case NSS_AES_GCM: |
-#if USE_HW_AES |
+#ifdef INTEL_GCM |
if(use_hw_gcm) { |
cx->worker_cx = intel_AES_GCM_CreateContext(cx, cx->worker, iv, blocksize); |
cx->worker = (freeblCipherFunc) |