Index: nss/lib/freebl/intel-gcm-wrap.c |
diff --git a/nss/lib/freebl/intel-gcm-wrap.c b/nss/lib/freebl/intel-gcm-wrap.c |
index afd3029383739922578f305f487b5bb4a14d0c79..9b0a542d07ac4a9367f45f9ffc1a12ea49b903dc 100644 |
--- a/nss/lib/freebl/intel-gcm-wrap.c |
+++ b/nss/lib/freebl/intel-gcm-wrap.c |
@@ -39,21 +39,21 @@ struct intel_AES_GCMContextStr{ |
unsigned long Mlen; |
}; |
-intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, |
+intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, |
freeblCipherFunc cipher, |
- const unsigned char *params, |
+ const unsigned char *params, |
unsigned int blocksize) |
{ |
intel_AES_GCMContext *gcm = NULL; |
AESContext *aes = (AESContext*)context; |
const CK_GCM_PARAMS *gcmParams = (const CK_GCM_PARAMS *)params; |
unsigned char buff[AES_BLOCK_SIZE]; /* aux buffer */ |
- |
- int IV_whole_len = gcmParams->ulIvLen&(~0xf); |
- int IV_remainder_len = gcmParams->ulIvLen&0xf; |
- int AAD_whole_len = gcmParams->ulAADLen&(~0xf); |
- int AAD_remainder_len = gcmParams->ulAADLen&0xf; |
- |
+ |
+ unsigned long IV_whole_len = gcmParams->ulIvLen & (~0xful); |
+ unsigned int IV_remainder_len = gcmParams->ulIvLen & 0xful; |
+ unsigned long AAD_whole_len = gcmParams->ulAADLen & (~0xful); |
+ unsigned int AAD_remainder_len = gcmParams->ulAADLen & 0xful; |
+ |
__m128i BSWAP_MASK = _mm_setr_epi8(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0); |
__m128i ONE = _mm_set_epi32(0,0,0,1); |
unsigned int j; |
@@ -64,66 +64,80 @@ intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, |
return NULL; |
} |
gcm = PORT_ZNew(intel_AES_GCMContext); |
- |
+ |
if (gcm == NULL) { |
return NULL; |
} |
+ |
/* initialize context fields */ |
gcm->aes_context = aes; |
gcm->tagBits = gcmParams->ulTagBits; |
gcm->Alen = 0; |
gcm->Mlen = 0; |
+ |
/* first prepare H and its derivatives for ghash */ |
intel_aes_gcmINIT(gcm->Htbl, (unsigned char*)aes->expandedKey, aes->Nr); |
- /* Initial TAG value is zero*/ |
+ |
+ /* Initial TAG value is zero */ |
_mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128()); |
_mm_storeu_si128((__m128i*)gcm->X0, _mm_setzero_si128()); |
+ |
/* Init the counter */ |
- if(gcmParams->ulIvLen == 12) { |
- _mm_storeu_si128((__m128i*)gcm->CTR, _mm_setr_epi32(((unsigned int*)gcmParams->pIv)[0], ((unsigned int*)gcmParams->pIv)[1], ((unsigned int*)gcmParams->pIv)[2], 0x01000000)); |
+ if (gcmParams->ulIvLen == 12) { |
+ _mm_storeu_si128((__m128i*)gcm->CTR, |
+ _mm_setr_epi32(((unsigned int*)gcmParams->pIv)[0], |
+ ((unsigned int*)gcmParams->pIv)[1], |
+ ((unsigned int*)gcmParams->pIv)[2], |
+ 0x01000000)); |
} else { |
- /* If IV size is not 96 bits, then the initial counter value is GHASH of the IV */ |
+ /* If IV size is not 96 bits, then the initial counter value is GHASH |
+ * of the IV */ |
intel_aes_gcmAAD(gcm->Htbl, gcmParams->pIv, IV_whole_len, gcm->T); |
+ |
/* Partial block */ |
- if(IV_remainder_len) { |
+ if (IV_remainder_len) { |
PORT_Memset(buff, 0, AES_BLOCK_SIZE); |
PORT_Memcpy(buff, gcmParams->pIv + IV_whole_len, IV_remainder_len); |
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T); |
- } |
- |
- intel_aes_gcmTAG |
- ( |
+ } |
+ |
+ intel_aes_gcmTAG( |
gcm->Htbl, |
gcm->T, |
gcmParams->ulIvLen, |
0, |
gcm->X0, |
- gcm->CTR |
- ); |
+ gcm->CTR); |
+ |
/* TAG should be zero again */ |
_mm_storeu_si128((__m128i*)gcm->T, _mm_setzero_si128()); |
} |
- /* Encrypt the initial counter, will be used to encrypt the GHASH value, in the end */ |
- rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR, AES_BLOCK_SIZE, AES_BLOCK_SIZE); |
+ |
+ /* Encrypt the initial counter, will be used to encrypt the GHASH value, |
+ * in the end */ |
+ rv = (*cipher)(context, gcm->X0, &j, AES_BLOCK_SIZE, gcm->CTR, |
+ AES_BLOCK_SIZE, AES_BLOCK_SIZE); |
if (rv != SECSuccess) { |
goto loser; |
} |
+ |
/* Promote the counter by 1 */ |
_mm_storeu_si128((__m128i*)gcm->CTR, _mm_shuffle_epi8(_mm_add_epi32(ONE, _mm_shuffle_epi8(_mm_loadu_si128((__m128i*)gcm->CTR), BSWAP_MASK)), BSWAP_MASK)); |
-/* Now hash AAD - it would actually make sense to seperate the context creation from the AAD, |
- * because that would allow to reuse the H, which only changes when the AES key changes, |
- * and not every package, like the IV and AAD */ |
+ /* Now hash AAD - it would actually make sense to seperate the context |
+ * creation from the AAD, because that would allow to reuse the H, which |
+ * only changes when the AES key changes, and not every package, like the |
+ * IV and AAD */ |
intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T); |
- if(AAD_remainder_len) { |
+ if (AAD_remainder_len) { |
PORT_Memset(buff, 0, AES_BLOCK_SIZE); |
PORT_Memcpy(buff, gcmParams->pAAD + AAD_whole_len, AAD_remainder_len); |
intel_aes_gcmAAD(gcm->Htbl, buff, AES_BLOCK_SIZE, gcm->T); |
} |
gcm->Alen += gcmParams->ulAADLen; |
return gcm; |
- |
- loser: |
+ |
+loser: |
if (gcm) { |
PORT_Free(gcm); |
} |
@@ -137,7 +151,7 @@ void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit) |
} |
} |
-SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, |
+SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, |
unsigned char *outbuf, |
unsigned int *outlen, unsigned int maxout, |
const unsigned char *inbuf, unsigned int inlen, |
@@ -145,9 +159,9 @@ SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, |
{ |
unsigned int tagBytes; |
unsigned char T[AES_BLOCK_SIZE]; |
- int j; |
+ unsigned int j; |
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE; |
+ tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; |
if (UINT_MAX - inlen < tagBytes) { |
PORT_SetError(SEC_ERROR_INPUT_LEN); |
return SECFailure; |
@@ -165,7 +179,7 @@ SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, |
inlen); |
gcm->Mlen += inlen; |
- |
+ |
intel_aes_gcmTAG( |
gcm->Htbl, |
gcm->T, |
@@ -176,14 +190,13 @@ SECStatus intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, |
*outlen = inlen + tagBytes; |
- for(j=0; j<tagBytes; j++) |
- { |
- outbuf[inlen+j] = T[j]; |
+ for (j = 0; j < tagBytes; j++) { |
+ outbuf[inlen + j] = T[j]; |
} |
return SECSuccess; |
} |
-SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, |
+SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, |
unsigned char *outbuf, |
unsigned int *outlen, unsigned int maxout, |
const unsigned char *inbuf, unsigned int inlen, |
@@ -193,8 +206,8 @@ SECStatus intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm, |
unsigned char T[AES_BLOCK_SIZE]; |
const unsigned char *intag; |
- tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE-1)) / PR_BITS_PER_BYTE; |
- |
+ tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE; |
+ |
/* get the authentication block */ |
if (inlen < tagBytes) { |
PORT_SetError(SEC_ERROR_INPUT_LEN); |