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 |
deleted file mode 100644 |
index 9b0a542d07ac4a9367f45f9ffc1a12ea49b903dc..0000000000000000000000000000000000000000 |
--- a/nss/lib/freebl/intel-gcm-wrap.c |
+++ /dev/null |
@@ -1,253 +0,0 @@ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
-/* Copyright(c) 2013, Intel Corp. */ |
- |
-/* Wrapper functions for Intel optimized implementation of AES-GCM */ |
- |
-#ifdef USE_HW_AES |
- |
-#ifdef FREEBL_NO_DEPEND |
-#include "stubs.h" |
-#endif |
- |
-#include "blapii.h" |
-#include "blapit.h" |
-#include "gcm.h" |
-#include "ctr.h" |
-#include "secerr.h" |
-#include "prtypes.h" |
-#include "pkcs11t.h" |
- |
-#include <limits.h> |
- |
-#include "intel-gcm.h" |
-#include "rijndael.h" |
- |
-#include <emmintrin.h> |
-#include <tmmintrin.h> |
- |
- |
-struct intel_AES_GCMContextStr{ |
- unsigned char Htbl[16*AES_BLOCK_SIZE]; |
- unsigned char X0[AES_BLOCK_SIZE]; |
- unsigned char T[AES_BLOCK_SIZE]; |
- unsigned char CTR[AES_BLOCK_SIZE]; |
- AESContext *aes_context; |
- unsigned long tagBits; |
- unsigned long Alen; |
- unsigned long Mlen; |
-}; |
- |
-intel_AES_GCMContext *intel_AES_GCM_CreateContext(void *context, |
- freeblCipherFunc cipher, |
- 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 */ |
- |
- 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; |
- SECStatus rv; |
- |
- if (blocksize != AES_BLOCK_SIZE) { |
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
- 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 */ |
- _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)); |
- } else { |
- /* 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) { |
- 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( |
- gcm->Htbl, |
- gcm->T, |
- gcmParams->ulIvLen, |
- 0, |
- gcm->X0, |
- 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); |
- 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 */ |
- intel_aes_gcmAAD(gcm->Htbl, gcmParams->pAAD, AAD_whole_len, gcm->T); |
- 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: |
- if (gcm) { |
- PORT_Free(gcm); |
- } |
- return NULL; |
-} |
- |
-void intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit) |
-{ |
- if (freeit) { |
- PORT_Free(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, |
- unsigned int blocksize) |
-{ |
- unsigned int tagBytes; |
- unsigned char T[AES_BLOCK_SIZE]; |
- unsigned int j; |
- |
- 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; |
- } |
- if (maxout < inlen + tagBytes) { |
- *outlen = inlen + tagBytes; |
- PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
- return SECFailure; |
- } |
- |
- intel_aes_gcmENC( |
- inbuf, |
- outbuf, |
- gcm, |
- inlen); |
- |
- gcm->Mlen += inlen; |
- |
- intel_aes_gcmTAG( |
- gcm->Htbl, |
- gcm->T, |
- gcm->Mlen, |
- gcm->Alen, |
- gcm->X0, |
- T); |
- |
- *outlen = inlen + tagBytes; |
- |
- for (j = 0; j < tagBytes; j++) { |
- outbuf[inlen + j] = T[j]; |
- } |
- return SECSuccess; |
-} |
- |
-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, |
- unsigned int blocksize) |
-{ |
- unsigned int tagBytes; |
- unsigned char T[AES_BLOCK_SIZE]; |
- const unsigned char *intag; |
- |
- 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); |
- return SECFailure; |
- } |
- |
- inlen -= tagBytes; |
- intag = inbuf + inlen; |
- |
- if (maxout < inlen) { |
- *outlen = inlen; |
- PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
- return SECFailure; |
- } |
- |
- intel_aes_gcmDEC( |
- inbuf, |
- outbuf, |
- gcm, |
- inlen); |
- |
- gcm->Mlen += inlen; |
- intel_aes_gcmTAG( |
- gcm->Htbl, |
- gcm->T, |
- gcm->Mlen, |
- gcm->Alen, |
- gcm->X0, |
- T); |
- |
- if (NSS_SecureMemcmp(T, intag, tagBytes) != 0) { |
- memset(outbuf, 0, inlen); |
- *outlen = 0; |
- /* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */ |
- PORT_SetError(SEC_ERROR_BAD_DATA); |
- return SECFailure; |
- } |
- *outlen = inlen; |
- |
- return SECSuccess; |
-} |
- |
-#endif |