Index: nss/lib/freebl/ctr.c |
diff --git a/nss/lib/freebl/ctr.c b/nss/lib/freebl/ctr.c |
index 3a2f1a6b82b7818e6052e400a387ac76ec57848e..78075853376adf8a8c6f95dad9cc48bfe4307e9d 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) |
Ryan Sleevi
2014/04/23 19:53:34
Alignment?
wtc
2014/04/24 01:04:10
Done. I will also align the parameters of the othe
|
+{ |
+ 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); |
Ryan Sleevi
2014/04/23 19:53:34
spaces here between ctr->buffer and ctr->bufPtr?
wtc
2014/04/24 01:04:10
I will fix this in the NSS upstream.
|
+ 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; |
Ryan Sleevi
2014/04/23 19:53:34
This style surprises me, if only because it seems
wtc
2014/04/24 01:04:10
Done. This code also assumes |blocksize| is 16. I
|
+ |
+ if (inlen == 0) { |
+ return SECSuccess; |
+ } |
+ rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize, |
Ryan Sleevi
2014/04/23 19:53:34
Should we add a PORT_Assert that tmp == blocksize?
wtc
2014/04/24 01:04:10
Done.
|
+ ctr->counter, blocksize, blocksize); |
+ ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize); |
Ryan Sleevi
2014/04/23 19:53:34
Why does this happen before the rv check?
wtc
2014/04/24 01:04:10
I don't really know. Perhaps the author wanted to
|
+ if (rv != SECSuccess) { |
+ return SECFailure; |
+ } |
+ ctr_xor(outbuf, inbuf, ctr->buffer, inlen); |
+ ctr->bufPtr = inlen; |
+ *outlen += inlen; |
+ return SECSuccess; |
+} |
+#endif |