Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Bug 1357670 - AES-NI for all platforms that support it, r=ttaubert,mt
With this patch we use AES-NI whenever possible. The compile time flag USE_HW_AES
does NOT disable this new code. NSS_DISABLE_HW_AES can be used as runtime
flag to disable AES-NI and fall back to the software implementation.

Differential Revision: https://nss-review.dev.mozaws.net/D323

--HG--
extra : rebase_source : 40035bcd45711652feeef0b75b7326b8a371da80
extra : histedit_source : 552b54f8bf0bc5eb94092294313422a484490b52%2Cb18d7d5fd2c1b22e15e4ed5b57387a9d7780ccf0
  • Loading branch information
franziskuskiefer committed Apr 25, 2017
1 parent 521fc92 commit 0d75de7
Show file tree
Hide file tree
Showing 20 changed files with 431 additions and 441 deletions.
7 changes: 3 additions & 4 deletions gtests/freebl_gtest/ghash_unittest.cc
Expand Up @@ -137,16 +137,15 @@ class GHashTest : public ::testing::TestWithParam<ghash_kat_value> {
// Hash additional_data, cipher_text.
gcmHash_Reset(&ghashCtx,
const_cast<const unsigned char *>(additional_data.data()),
additional_data.size(), 16);
additional_data.size());
gcmHash_Update(&ghashCtx,
const_cast<const unsigned char *>(cipher_text.data()),
cipher_text.size(), 16);
cipher_text.size());

// Finalise (hash in the length).
uint8_t result_bytes[16];
unsigned int out_len;
ASSERT_EQ(SECSuccess,
gcmHash_Final(&ghashCtx, result_bytes, &out_len, 16, 16));
ASSERT_EQ(SECSuccess, gcmHash_Final(&ghashCtx, result_bytes, &out_len, 16));
ASSERT_EQ(16U, out_len);
EXPECT_EQ(expected, std::vector<uint8_t>(result_bytes, result_bytes + 16));
}
Expand Down
20 changes: 14 additions & 6 deletions lib/freebl/aeskeywrap.c
Expand Up @@ -22,8 +22,9 @@
#include "rijndael.h"

struct AESKeyWrapContextStr {
unsigned char iv[AES_KEY_WRAP_IV_BYTES];
AESContext aescx;
unsigned char iv[AES_KEY_WRAP_IV_BYTES];
void *mem; /* Pointer to beginning of allocated memory. */
};

/******************************************/
Expand All @@ -34,8 +35,14 @@ struct AESKeyWrapContextStr {
AESKeyWrapContext *
AESKeyWrap_AllocateContext(void)
{
AESKeyWrapContext *cx = PORT_New(AESKeyWrapContext);
return cx;
/* aligned_alloc is C11 so we have to do it the old way. */
AESKeyWrapContext *ctx = PORT_ZAlloc(sizeof(AESKeyWrapContext) + 15);
if (ctx == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
return NULL;
}
ctx->mem = ctx;
return (AESKeyWrapContext *)(((uintptr_t)ctx + 15) & ~(uintptr_t)0x0F);
}

SECStatus
Expand Down Expand Up @@ -77,7 +84,7 @@ AESKeyWrap_CreateContext(const unsigned char *key, const unsigned char *iv,
return NULL; /* error is already set */
rv = AESKeyWrap_InitContext(cx, key, keylen, iv, 0, encrypt, 0);
if (rv != SECSuccess) {
PORT_Free(cx);
PORT_Free(cx->mem);
cx = NULL; /* error should already be set */
}
return cx;
Expand All @@ -94,8 +101,9 @@ AESKeyWrap_DestroyContext(AESKeyWrapContext *cx, PRBool freeit)
if (cx) {
AES_DestroyContext(&cx->aescx, PR_FALSE);
/* memset(cx, 0, sizeof *cx); */
if (freeit)
PORT_Free(cx);
if (freeit) {
PORT_Free(cx->mem);
}
}
}

Expand Down
3 changes: 1 addition & 2 deletions lib/freebl/blapi.h
Expand Up @@ -801,8 +801,7 @@ SEED_Decrypt(SEEDContext *cx, unsigned char *output,
** Create a new AES context suitable for AES encryption/decryption.
** "key" raw key data
** "keylen" the number of bytes of key data (16, 24, or 32)
** "blocklen" is the blocksize to use (16, 24, or 32)
** XXX currently only blocksize==16 has been tested!
** "blocklen" is the blocksize to use. NOTE: only 16 is supported!
*/
extern AESContext *
AES_CreateContext(const unsigned char *key, const unsigned char *iv,
Expand Down
12 changes: 12 additions & 0 deletions lib/freebl/blapii.h
Expand Up @@ -51,6 +51,18 @@ SEC_END_PROTOS
#define HAVE_NO_SANITIZE_ATTR 0
#endif

/* Alignment helpers. */
#if defined(_WINDOWS) && defined(NSS_X86_OR_X64)
#define pre_align __declspec(align(16))
#define post_align
#elif defined(NSS_X86_OR_X64)
#define pre_align
#define post_align __attribute__((aligned(16)))
#else
#define pre_align
#define post_align
#endif

#if defined(HAVE_UNALIGNED_ACCESS) && HAVE_NO_SANITIZE_ATTR
#define NO_SANITIZE_ALIGNMENT __attribute__((no_sanitize("alignment")))
#else
Expand Down
20 changes: 10 additions & 10 deletions lib/freebl/ctr.c
Expand Up @@ -19,38 +19,38 @@

SECStatus
CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
const unsigned char *param, unsigned int blocksize)
const unsigned char *param)
{
const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param;

if (ctrParams->ulCounterBits == 0 ||
ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) {
ctrParams->ulCounterBits > AES_BLOCK_SIZE * PR_BITS_PER_BYTE) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}

/* Invariant: 0 < ctr->bufPtr <= blocksize */
/* Invariant: 0 < ctr->bufPtr <= AES_BLOCK_SIZE */
ctr->checkWrap = PR_FALSE;
ctr->bufPtr = blocksize; /* no unused data in the buffer */
ctr->bufPtr = AES_BLOCK_SIZE; /* no unused data in the buffer */
ctr->cipher = cipher;
ctr->context = context;
ctr->counterBits = ctrParams->ulCounterBits;
if (blocksize > sizeof(ctr->counter) ||
blocksize > sizeof(ctrParams->cb)) {
if (AES_BLOCK_SIZE > sizeof(ctr->counter) ||
AES_BLOCK_SIZE > sizeof(ctrParams->cb)) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
PORT_Memcpy(ctr->counter, ctrParams->cb, AES_BLOCK_SIZE);
if (ctr->counterBits < 64) {
PORT_Memcpy(ctr->counterFirst, ctr->counter, blocksize);
PORT_Memcpy(ctr->counterFirst, ctr->counter, AES_BLOCK_SIZE);
ctr->checkWrap = PR_TRUE;
}
return SECSuccess;
}

CTRContext *
CTR_CreateContext(void *context, freeblCipherFunc cipher,
const unsigned char *param, unsigned int blocksize)
const unsigned char *param)
{
CTRContext *ctr;
SECStatus rv;
Expand All @@ -60,7 +60,7 @@ CTR_CreateContext(void *context, freeblCipherFunc cipher,
if (ctr == NULL) {
return NULL;
}
rv = CTR_InitContext(ctr, context, cipher, param, blocksize);
rv = CTR_InitContext(ctr, context, cipher, param);
if (rv != SECSuccess) {
CTR_DestroyContext(ctr, PR_TRUE);
ctr = NULL;
Expand Down
5 changes: 2 additions & 3 deletions lib/freebl/ctr.h
Expand Up @@ -23,8 +23,7 @@ struct CTRContextStr {
typedef struct CTRContextStr CTRContext;

SECStatus CTR_InitContext(CTRContext *ctr, void *context,
freeblCipherFunc cipher, const unsigned char *param,
unsigned int blocksize);
freeblCipherFunc cipher, const unsigned char *param);

/*
* The context argument is the inner cipher context to use with cipher. The
Expand All @@ -34,7 +33,7 @@ SECStatus CTR_InitContext(CTRContext *ctr, void *context,
* The cipher argument is a block cipher in the ECB encrypt mode.
*/
CTRContext *CTR_CreateContext(void *context, freeblCipherFunc cipher,
const unsigned char *param, unsigned int blocksize);
const unsigned char *param);

void CTR_DestroyContext(CTRContext *ctr, PRBool freeit);

Expand Down
8 changes: 2 additions & 6 deletions lib/freebl/cts.c
Expand Up @@ -20,19 +20,15 @@ struct CTSContextStr {

CTSContext *
CTS_CreateContext(void *context, freeblCipherFunc cipher,
const unsigned char *iv, unsigned int blocksize)
const unsigned char *iv)
{
CTSContext *cts;

if (blocksize > MAX_BLOCK_SIZE) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return NULL;
}
cts = PORT_ZNew(CTSContext);
if (cts == NULL) {
return NULL;
}
PORT_Memcpy(cts->iv, iv, blocksize);
PORT_Memcpy(cts->iv, iv, MAX_BLOCK_SIZE);
cts->cipher = cipher;
cts->context = context;
return cts;
Expand Down
2 changes: 1 addition & 1 deletion lib/freebl/cts.h
Expand Up @@ -17,7 +17,7 @@ typedef struct CTSContextStr CTSContext;
* The cipher argument is a block cipher in the CBC mode.
*/
CTSContext *CTS_CreateContext(void *context, freeblCipherFunc cipher,
const unsigned char *iv, unsigned int blocksize);
const unsigned char *iv);

void CTS_DestroyContext(CTSContext *cts, PRBool freeit);

Expand Down

0 comments on commit 0d75de7

Please sign in to comment.