update NSS as-of pm27 rev 7606140ee

This commit is contained in:
Roy Tam 2020-09-04 22:55:34 +08:00
commit 8015bb7004
24 changed files with 1005 additions and 1400 deletions

View file

@ -155,3 +155,30 @@ rijndael_native_encryptBlock(AESContext *cx,
m = _mm_aesenclast_si128(m, cx->k.keySchedule[cx->Nr]);
_mm_storeu_si128((__m128i *)output, m);
}
void
rijndael_native_decryptBlock(AESContext *cx,
unsigned char *output,
const unsigned char *input)
{
int i;
pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input);
m = _mm_xor_si128(m, cx->k.keySchedule[cx->Nr]);
for (i = cx->Nr - 1; i > 0; --i) {
m = _mm_aesdec_si128(m, cx->k.keySchedule[i]);
}
m = _mm_aesdeclast_si128(m, cx->k.keySchedule[0]);
_mm_storeu_si128((__m128i *)output, m);
}
// out = a ^ b
void
native_xorBlock(unsigned char *out,
const unsigned char *a,
const unsigned char *b)
{
pre_align __m128i post_align in1 = _mm_loadu_si128((__m128i *)(a));
pre_align __m128i post_align in2 = _mm_loadu_si128((__m128i *)(b));
in1 = _mm_xor_si128(in1, in2);
_mm_storeu_si128((__m128i *)(out), in1);
}

View file

@ -147,9 +147,8 @@ static SECStatus
blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key,
size_t keylen)
{
PORT_Assert(ctx != NULL);
if (!ctx) {
goto failure;
goto failure_noclean;
}
if (outlen == 0 || outlen > BLAKE2B512_LENGTH) {
goto failure;
@ -181,6 +180,7 @@ blake2b_Begin(BLAKE2BContext* ctx, uint8_t outlen, const uint8_t* key,
failure:
PORT_Memset(ctx, 0, sizeof(*ctx));
failure_noclean:
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
@ -218,17 +218,11 @@ SECStatus
BLAKE2B_Update(BLAKE2BContext* ctx, const unsigned char* in,
unsigned int inlen)
{
size_t left = ctx->buflen;
size_t fill = BLAKE2B_BLOCK_LENGTH - left;
/* Nothing to do if there's nothing. */
if (inlen == 0) {
return SECSuccess;
}
PORT_Assert(ctx != NULL);
PORT_Assert(in != NULL);
PORT_Assert(left <= BLAKE2B_BLOCK_LENGTH);
if (!ctx || !in) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
@ -240,6 +234,10 @@ BLAKE2B_Update(BLAKE2BContext* ctx, const unsigned char* in,
return SECFailure;
}
size_t left = ctx->buflen;
PORT_Assert(left <= BLAKE2B_BLOCK_LENGTH);
size_t fill = BLAKE2B_BLOCK_LENGTH - left;
if (inlen > fill) {
if (ctx->buflen) {
/* There's some remaining data in ctx->buf that we have to prepend

View file

@ -22,7 +22,7 @@ struct CMACContextStr {
* add a new Context pointer to the cipher union with the correct type. */
CMACCipher cipherType;
union {
AESContext aes;
AESContext *aes;
} cipher;
int blockSize;
@ -62,7 +62,7 @@ cmac_Encrypt(CMACContext *ctx, unsigned char *output,
{
if (ctx->cipherType == CMAC_AES) {
unsigned int tmpOutputLen;
SECStatus rv = AES_Encrypt(&ctx->cipher.aes, output, &tmpOutputLen,
SECStatus rv = AES_Encrypt(ctx->cipher.aes, output, &tmpOutputLen,
ctx->blockSize, input, inputLen);
/* Assumption: AES_Encrypt (when in ECB mode) always returns an
@ -156,8 +156,9 @@ CMAC_Init(CMACContext *ctx, CMACCipher type,
ctx->blockSize = AES_BLOCK_SIZE;
ctx->cipherType = CMAC_AES;
if (AES_InitContext(&ctx->cipher.aes, key, key_len, NULL, NSS_AES, 1,
ctx->blockSize) != SECSuccess) {
ctx->cipher.aes = AES_CreateContext(key, NULL, NSS_AES, 1, key_len,
ctx->blockSize);
if (ctx->cipher.aes == NULL) {
return SECFailure;
}
@ -308,8 +309,8 @@ CMAC_Destroy(CMACContext *ctx, PRBool free_it)
return;
}
if (ctx->cipherType == CMAC_AES) {
AES_DestroyContext(&ctx->cipher.aes, PR_FALSE);
if (ctx->cipherType == CMAC_AES && ctx->cipher.aes != NULL) {
AES_DestroyContext(ctx->cipher.aes, PR_TRUE);
}
/* Destroy everything in the context. This includes sensitive data in

View file

@ -37,12 +37,24 @@
#include "intel-gcm.h"
#endif /* INTEL_GCM */
#ifdef _MSC_VER
#if _MSC_VER < 1900
#define inline
#endif
#endif
/* Forward declarations */
void rijndael_native_key_expansion(AESContext *cx, const unsigned char *key,
unsigned int Nk);
void rijndael_native_encryptBlock(AESContext *cx,
unsigned char *output,
const unsigned char *input);
void rijndael_native_decryptBlock(AESContext *cx,
unsigned char *output,
const unsigned char *input);
void native_xorBlock(unsigned char *out,
const unsigned char *a,
const unsigned char *b);
/* Stub definitions for the above rijndael_native_* functions, which
* shouldn't be used unless NSS_X86_OR_X64 is defined */
@ -63,6 +75,23 @@ rijndael_native_encryptBlock(AESContext *cx,
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0);
}
void
rijndael_native_decryptBlock(AESContext *cx,
unsigned char *output,
const unsigned char *input)
{
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0);
}
void
native_xorBlock(unsigned char *out, const unsigned char *a,
const unsigned char *b)
{
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0);
}
#endif /* NSS_X86_OR_X64 */
/*
@ -510,6 +539,15 @@ typedef union {
#define STATE_BYTE(i) state.b[i]
// out = a ^ b
inline static void
xorBlock(unsigned char *out, const unsigned char *a, const unsigned char *b)
{
for (unsigned int j = 0; j < AES_BLOCK_SIZE; ++j) {
(out)[j] = (a)[j] ^ (b)[j];
}
}
static void NO_SANITIZE_ALIGNMENT
rijndael_encryptBlock128(AESContext *cx,
unsigned char *output,
@ -605,7 +643,7 @@ rijndael_encryptBlock128(AESContext *cx,
#endif
}
static SECStatus NO_SANITIZE_ALIGNMENT
static void NO_SANITIZE_ALIGNMENT
rijndael_decryptBlock128(AESContext *cx,
unsigned char *output,
const unsigned char *input)
@ -694,7 +732,6 @@ rijndael_decryptBlock128(AESContext *cx,
memcpy(output, outBuf, sizeof outBuf);
}
#endif
return SECSuccess;
}
/**************************************************************************
@ -708,16 +745,13 @@ rijndael_encryptECB(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
AESBlockFunc *encryptor;
if (aesni_support()) {
/* Use hardware acceleration for normal AES parameters. */
encryptor = &rijndael_native_encryptBlock;
} else {
encryptor = &rijndael_encryptBlock128;
}
PRBool aesni = aesni_support();
while (inputLen > 0) {
(*encryptor)(cx, output, input);
if (aesni) {
rijndael_native_encryptBlock(cx, output, input);
} else {
rijndael_encryptBlock128(cx, output, input);
}
output += AES_BLOCK_SIZE;
input += AES_BLOCK_SIZE;
inputLen -= AES_BLOCK_SIZE;
@ -730,20 +764,23 @@ rijndael_encryptCBC(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
unsigned int j;
unsigned char *lastblock;
unsigned char *lastblock = cx->iv;
unsigned char inblock[AES_BLOCK_SIZE * 8];
PRBool aesni = aesni_support();
if (!inputLen)
return SECSuccess;
lastblock = cx->iv;
while (inputLen > 0) {
/* XOR with the last block (IV if first block) */
for (j = 0; j < AES_BLOCK_SIZE; ++j) {
inblock[j] = input[j] ^ lastblock[j];
if (aesni) {
/* XOR with the last block (IV if first block) */
native_xorBlock(inblock, input, lastblock);
/* encrypt */
rijndael_native_encryptBlock(cx, output, inblock);
} else {
xorBlock(inblock, input, lastblock);
rijndael_encryptBlock128(cx, output, inblock);
}
/* encrypt */
rijndael_encryptBlock128(cx, output, inblock);
/* move to the next block */
lastblock = output;
output += AES_BLOCK_SIZE;
@ -759,9 +796,12 @@ rijndael_decryptECB(AESContext *cx, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen)
{
PRBool aesni = aesni_support();
while (inputLen > 0) {
if (rijndael_decryptBlock128(cx, output, input) != SECSuccess) {
return SECFailure;
if (aesni) {
rijndael_native_decryptBlock(cx, output, input);
} else {
rijndael_decryptBlock128(cx, output, input);
}
output += AES_BLOCK_SIZE;
input += AES_BLOCK_SIZE;
@ -777,8 +817,8 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output,
{
const unsigned char *in;
unsigned char *out;
unsigned int j;
unsigned char newIV[AES_BLOCK_SIZE];
PRBool aesni = aesni_support();
if (!inputLen)
return SECSuccess;
@ -787,21 +827,26 @@ rijndael_decryptCBC(AESContext *cx, unsigned char *output,
memcpy(newIV, in, AES_BLOCK_SIZE);
out = output + (inputLen - AES_BLOCK_SIZE);
while (inputLen > AES_BLOCK_SIZE) {
if (rijndael_decryptBlock128(cx, out, in) != SECSuccess) {
return SECFailure;
if (aesni) {
// Use hardware acceleration for normal AES parameters.
rijndael_native_decryptBlock(cx, out, in);
native_xorBlock(out, out, &in[-AES_BLOCK_SIZE]);
} else {
rijndael_decryptBlock128(cx, out, in);
xorBlock(out, out, &in[-AES_BLOCK_SIZE]);
}
for (j = 0; j < AES_BLOCK_SIZE; ++j)
out[j] ^= in[(int)(j - AES_BLOCK_SIZE)];
out -= AES_BLOCK_SIZE;
in -= AES_BLOCK_SIZE;
inputLen -= AES_BLOCK_SIZE;
}
if (in == input) {
if (rijndael_decryptBlock128(cx, out, in) != SECSuccess) {
return SECFailure;
if (aesni) {
rijndael_native_decryptBlock(cx, out, in);
native_xorBlock(out, out, cx->iv);
} else {
rijndael_decryptBlock128(cx, out, in);
xorBlock(out, out, cx->iv);
}
for (j = 0; j < AES_BLOCK_SIZE; ++j)
out[j] ^= cx->iv[j];
}
memcpy(cx->iv, newIV, AES_BLOCK_SIZE);
return SECSuccess;

View file

@ -26,10 +26,6 @@
#endif /* NSS_DISABLE_SSE2 */
#endif
typedef void AESBlockFunc(AESContext *cx,
unsigned char *output,
const unsigned char *input);
/* RIJNDAEL_NUM_ROUNDS
*
* Number of rounds per execution