Index: patches/nss-intel-aes-windows.patch |
diff --git a/patches/nss-intel-aes-windows.patch b/patches/nss-intel-aes-windows.patch |
new file mode 100644 |
index 0000000000000000000000000000000000000000..73205a13214fd794039211164406fef18b5d1fb7 |
--- /dev/null |
+++ b/patches/nss-intel-aes-windows.patch |
@@ -0,0 +1,188 @@ |
+diff --git a/nss/lib/freebl/ctr.c b/nss/lib/freebl/ctr.c |
+index 3a2f1a6..7807585 100644 |
+--- a/nss/lib/freebl/ctr.c |
++++ b/nss/lib/freebl/ctr.c |
+@@ -12,6 +12,11 @@ |
+ #include "pkcs11t.h" |
+ #include "secerr.h" |
+ |
++#ifdef USE_HW_AES |
++#include "intel-aes.h" |
++#include "rijndael.h" |
++#endif |
++ |
+ SECStatus |
+ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher, |
+ const unsigned char *param, unsigned int blocksize) |
+@@ -165,3 +170,56 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf, |
+ *outlen += inlen; |
+ return SECSuccess; |
+ } |
++ |
++#if defined(USE_HW_AES) && defined(_MSC_VER) |
++SECStatus |
++CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf, |
++ unsigned int *outlen, unsigned int maxout, |
++ const unsigned char *inbuf, unsigned int inlen, |
++ unsigned int blocksize) |
++{ |
++ unsigned int tmp; |
++ SECStatus rv; |
++ |
++ if (maxout < inlen) { |
++ *outlen = inlen; |
++ PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
++ return SECFailure; |
++ } |
++ *outlen = 0; |
++ if (ctr->bufPtr != blocksize) { |
++ unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen); |
++ ctr_xor(outbuf, inbuf, ctr->buffer+ctr->bufPtr, needed); |
++ ctr->bufPtr += needed; |
++ outbuf += needed; |
++ inbuf += needed; |
++ *outlen += needed; |
++ inlen -= needed; |
++ if (inlen == 0) { |
++ return SECSuccess; |
++ } |
++ PORT_Assert(ctr->bufPtr == blocksize); |
++ } |
++ |
++ intel_aes_ctr_worker(((AESContext*)(ctr->context))->Nr)( |
++ ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize); |
++ *outlen += inlen & (-16); |
++ outbuf += inlen & (-16); |
++ inbuf += inlen & (-16); |
++ inlen &= 16 - 1; |
++ |
++ if (inlen == 0) { |
++ return SECSuccess; |
++ } |
++ rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, |
++ ctr->counter, blocksize, blocksize); |
++ ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); |
++ if (rv != SECSuccess) { |
++ return SECFailure; |
++ } |
++ ctr_xor(outbuf, inbuf, ctr->buffer, inlen); |
++ ctr->bufPtr = inlen; |
++ *outlen += inlen; |
++ return SECSuccess; |
++} |
++#endif |
+diff --git a/nss/lib/freebl/ctr.h b/nss/lib/freebl/ctr.h |
+index 69ef150..e7645a2 100644 |
+--- a/nss/lib/freebl/ctr.h |
++++ b/nss/lib/freebl/ctr.h |
+@@ -41,4 +41,11 @@ SECStatus CTR_Update(CTRContext *ctr, unsigned char *outbuf, |
+ const unsigned char *inbuf, unsigned int inlen, |
+ unsigned int blocksize); |
+ |
++#ifdef USE_HW_AES |
++SECStatus CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf, |
++ unsigned int *outlen, unsigned int maxout, |
++ const unsigned char *inbuf, unsigned int inlen, |
++ unsigned int blocksize); |
++#endif |
++ |
+ #endif |
+diff --git a/nss/lib/freebl/intel-aes.h b/nss/lib/freebl/intel-aes.h |
+index 1e18007..3b71e5f 100644 |
+--- a/nss/lib/freebl/intel-aes.h |
++++ b/nss/lib/freebl/intel-aes.h |
+@@ -33,6 +33,12 @@ SECStatus intel_aes_decrypt_cbc_128(AESContext *cx, unsigned char *output, |
+ const unsigned char *input, |
+ unsigned int inputLen, |
+ unsigned int blocksize); |
++SECStatus intel_aes_encrypt_ctr_128(CTRContext *cx, unsigned char *output, |
++ unsigned int *outputLen, |
++ unsigned int maxOutputLen, |
++ const unsigned char *input, |
++ unsigned int inputLen, |
++ unsigned int blocksize); |
+ SECStatus intel_aes_encrypt_ecb_192(AESContext *cx, unsigned char *output, |
+ unsigned int *outputLen, |
+ unsigned int maxOutputLen, |
+@@ -57,6 +63,12 @@ SECStatus intel_aes_decrypt_cbc_192(AESContext *cx, unsigned char *output, |
+ const unsigned char *input, |
+ unsigned int inputLen, |
+ unsigned int blocksize); |
++SECStatus intel_aes_encrypt_ctr_192(CTRContext *cx, unsigned char *output, |
++ unsigned int *outputLen, |
++ unsigned int maxOutputLen, |
++ const unsigned char *input, |
++ unsigned int inputLen, |
++ unsigned int blocksize); |
+ SECStatus intel_aes_encrypt_ecb_256(AESContext *cx, unsigned char *output, |
+ unsigned int *outputLen, |
+ unsigned int maxOutputLen, |
+@@ -81,6 +93,12 @@ SECStatus intel_aes_decrypt_cbc_256(AESContext *cx, unsigned char *output, |
+ const unsigned char *input, |
+ unsigned int inputLen, |
+ unsigned int blocksize); |
++SECStatus intel_aes_encrypt_ctr_256(CTRContext *cx, unsigned char *output, |
++ unsigned int *outputLen, |
++ unsigned int maxOutputLen, |
++ const unsigned char *input, |
++ unsigned int inputLen, |
++ unsigned int blocksize); |
+ |
+ |
+ #define intel_aes_ecb_worker(encrypt, keysize) \ |
+@@ -102,6 +120,11 @@ SECStatus intel_aes_decrypt_cbc_256(AESContext *cx, unsigned char *output, |
+ (keysize) == 24 ? intel_aes_decrypt_cbc_192 : \ |
+ intel_aes_decrypt_cbc_256)) |
+ |
++#define intel_aes_ctr_worker(nr) \ |
++ ((nr) == 10 ? intel_aes_encrypt_ctr_128 : \ |
++ (nr) == 12 ? intel_aes_encrypt_ctr_192 : \ |
++ intel_aes_encrypt_ctr_256) |
++ |
+ |
+ #define intel_aes_init(encrypt, keysize) \ |
+ do { \ |
+diff --git a/nss/lib/freebl/intel-gcm-wrap.c b/nss/lib/freebl/intel-gcm-wrap.c |
+index b2f6f5e..d49592f 100644 |
+--- a/nss/lib/freebl/intel-gcm-wrap.c |
++++ b/nss/lib/freebl/intel-gcm-wrap.c |
+@@ -3,7 +3,7 @@ |
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
+ /* Copyright(c) 2013, Intel Corp. */ |
+ |
+-/* Wrapper funcions for Intel optimized implementation of AES-GCM */ |
++/* Wrapper functions for Intel optimized implementation of AES-GCM */ |
+ |
+ #ifdef USE_HW_AES |
+ |
+@@ -24,12 +24,8 @@ |
+ #include "intel-gcm.h" |
+ #include "rijndael.h" |
+ |
+-#if defined(__INTEL_COMPILER) |
+-#include <ia32intrin.h> |
+-#elif defined(__GNUC__) |
+ #include <emmintrin.h> |
+ #include <tmmintrin.h> |
+-#endif |
+ |
+ |
+ struct intel_AES_GCMContextStr{ |
+diff --git a/nss/lib/freebl/rijndael.c b/nss/lib/freebl/rijndael.c |
+index 8bb8905..88f231e 100644 |
+--- a/nss/lib/freebl/rijndael.c |
++++ b/nss/lib/freebl/rijndael.c |
+@@ -1171,7 +1171,12 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize, |
+ break; |
+ case NSS_AES_CTR: |
+ cx->worker_cx = CTR_CreateContext(cx, cx->worker, iv, blocksize); |
+- cx->worker = (freeblCipherFunc) CTR_Update ; |
++#if defined(USE_HW_AES) && defined(_MSC_VER) |
++ if (use_hw_aes) |
++ cx->worker = (freeblCipherFunc) CTR_Update_HW_AES; |
++ else |
++#endif |
++ cx->worker = (freeblCipherFunc) CTR_Update; |
+ cx->destroy = (freeblDestroyFunc) CTR_DestroyContext; |
+ cx->isBlock = PR_FALSE; |
+ break; |