summaryrefslogtreecommitdiffstats
path: root/security/nss
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss')
-rw-r--r--security/nss/coreconf/coreconf.dep1
-rw-r--r--security/nss/lib/freebl/chacha20poly1305.c5
-rw-r--r--security/nss/lib/freebl/ctr.c12
-rw-r--r--security/nss/lib/freebl/gcm.c6
-rw-r--r--security/nss/lib/freebl/intel-gcm-wrap.c22
-rw-r--r--security/nss/lib/freebl/rsapkcs.c20
-rw-r--r--security/nss/lib/nss/nss.h4
-rw-r--r--security/nss/lib/softoken/pkcs11c.c33
-rw-r--r--security/nss/lib/softoken/softkver.h4
-rw-r--r--security/nss/lib/util/nssutil.h4
10 files changed, 88 insertions, 23 deletions
diff --git a/security/nss/coreconf/coreconf.dep b/security/nss/coreconf/coreconf.dep
index 5182f7555..590d1bfae 100644
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -10,3 +10,4 @@
*/
#error "Do not include this header file."
+
diff --git a/security/nss/lib/freebl/chacha20poly1305.c b/security/nss/lib/freebl/chacha20poly1305.c
index 302f0db9e..8fdaf3fec 100644
--- a/security/nss/lib/freebl/chacha20poly1305.c
+++ b/security/nss/lib/freebl/chacha20poly1305.c
@@ -234,6 +234,11 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output,
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
+ // ChaCha has a 64 octet block, with a 32-bit block counter.
+ if (inputLen >= (1ULL << (6 + 32)) + ctx->tagLen) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
PORT_Memset(block, 0, sizeof(block));
// Generate a block of keystream. The first 32 bytes will be the poly1305
diff --git a/security/nss/lib/freebl/ctr.c b/security/nss/lib/freebl/ctr.c
index d7652c060..4d26a5b06 100644
--- a/security/nss/lib/freebl/ctr.c
+++ b/security/nss/lib/freebl/ctr.c
@@ -128,6 +128,12 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
unsigned int tmp;
SECStatus rv;
+ // Limit block count to 2^counterBits - 2
+ if (ctr->counterBits < (sizeof(unsigned int) * 8) &&
+ inlen > ((1 << ctr->counterBits) - 2) * AES_BLOCK_SIZE) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
if (maxout < inlen) {
*outlen = inlen;
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
@@ -199,6 +205,12 @@ CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
unsigned int tmp;
SECStatus rv;
+ // Limit block count to 2^counterBits - 2
+ if (ctr->counterBits < (sizeof(unsigned int) * 8) &&
+ inlen > ((1 << ctr->counterBits) - 2) * AES_BLOCK_SIZE) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
if (maxout < inlen) {
*outlen = inlen;
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
diff --git a/security/nss/lib/freebl/gcm.c b/security/nss/lib/freebl/gcm.c
index f1e16da78..e93970b88 100644
--- a/security/nss/lib/freebl/gcm.c
+++ b/security/nss/lib/freebl/gcm.c
@@ -469,6 +469,12 @@ gcmHash_Reset(gcmHashContext *ghash, const unsigned char *AAD,
{
SECStatus rv;
+ // Limit AADLen in accordance with SP800-38D
+ if (sizeof(AADLen) >= 8 && AADLen > (1ULL << 61) - 1) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+
ghash->cLen = 0;
PORT_Memset(ghash->counterBuf, 0, GCM_HASH_LEN_LEN * 2);
ghash->bufLen = 0;
diff --git a/security/nss/lib/freebl/intel-gcm-wrap.c b/security/nss/lib/freebl/intel-gcm-wrap.c
index 37a1af765..f69bc7c7a 100644
--- a/security/nss/lib/freebl/intel-gcm-wrap.c
+++ b/security/nss/lib/freebl/intel-gcm-wrap.c
@@ -62,6 +62,12 @@ intel_AES_GCM_CreateContext(void *context,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
+ // Limit AADLen in accordance with SP800-38D
+ if (sizeof(AAD_whole_len) >= 8 && AAD_whole_len > (1ULL << 61) - 1) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return NULL;
+ }
+
gcm = PORT_ZNew(intel_AES_GCMContext);
if (gcm == NULL) {
return NULL;
@@ -159,6 +165,14 @@ intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm,
unsigned char T[AES_BLOCK_SIZE];
unsigned int j;
+ // GCM has a 16 octet block, with a 32-bit block counter
+ // Limit in accordance with SP800-38D
+ if (sizeof(inlen) > 4 &&
+ inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+
tagBytes = (gcm->tagBits + (PR_BITS_PER_BYTE - 1)) / PR_BITS_PER_BYTE;
if (UINT_MAX - inlen < tagBytes) {
PORT_SetError(SEC_ERROR_INPUT_LEN);
@@ -216,6 +230,14 @@ intel_AES_GCM_DecryptUpdate(intel_AES_GCMContext *gcm,
inlen -= tagBytes;
intag = inbuf + inlen;
+ // GCM has a 16 octet block, with a 32-bit block counter
+ // Limit in accordance with SP800-38D
+ if (sizeof(inlen) > 4 &&
+ inlen >= ((1ULL << 32) - 2) * AES_BLOCK_SIZE) {
+ PORT_SetError(SEC_ERROR_INPUT_LEN);
+ return SECFailure;
+ }
+
if (maxout < inlen) {
*outlen = inlen;
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
diff --git a/security/nss/lib/freebl/rsapkcs.c b/security/nss/lib/freebl/rsapkcs.c
index 875e4e28d..6f94770ad 100644
--- a/security/nss/lib/freebl/rsapkcs.c
+++ b/security/nss/lib/freebl/rsapkcs.c
@@ -115,7 +115,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
{
unsigned char *block;
unsigned char *bp;
- int padLen;
+ unsigned int padLen;
int i, j;
SECStatus rv;
@@ -135,14 +135,14 @@ rsa_FormatOneBlock(unsigned modulusLen,
switch (blockType) {
/*
- * Blocks intended for private-key operation.
- */
+ * Blocks intended for private-key operation.
+ */
case RSA_BlockPrivate: /* preferred method */
/*
- * 0x00 || BT || Pad || 0x00 || ActualData
- * 1 1 padLen 1 data->len
- * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
- */
+ * 0x00 || BT || Pad || 0x00 || ActualData
+ * 1 1 padLen 1 data->len
+ * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
+ */
padLen = modulusLen - data->len - 3;
PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN);
if (padLen < RSA_BLOCK_MIN_PAD_LEN) {
@@ -162,7 +162,7 @@ rsa_FormatOneBlock(unsigned modulusLen,
/*
* 0x00 || BT || Pad || 0x00 || ActualData
* 1 1 padLen 1 data->len
- * Pad is all non-zero random bytes.
+ * Pad is 8 or more non-zero random bytes.
*
* Build the block left to right.
* Fill the entire block from Pad to the end with random bytes.
@@ -236,7 +236,9 @@ rsa_FormatBlock(SECItem *result,
* The "3" below is the first octet + the second octet + the 0x00
* octet that always comes just before the ActualData.
*/
- PORT_Assert(data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
+ if (data->len > (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN))) {
+ return SECFailure;
+ }
result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
if (result->data == NULL) {
diff --git a/security/nss/lib/nss/nss.h b/security/nss/lib/nss/nss.h
index ea54ce0cd..f6b83a01c 100644
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -22,10 +22,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define NSS_VERSION "3.41.2" _NSS_CUSTOMIZED
+#define NSS_VERSION "3.41.3" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
#define NSS_VMINOR 41
-#define NSS_VPATCH 2
+#define NSS_VPATCH 3
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index 884702cc1..327a67d5c 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -7668,9 +7668,11 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
const SECHashObject *rawHash;
unsigned hashLen;
CK_BYTE hashbuf[HASH_LENGTH_MAX];
- CK_BYTE *prk; /* psuedo-random key */
+ CK_BYTE *prk; /* psuedo-random key */
CK_ULONG prkLen;
- CK_BYTE *okm; /* output keying material */
+ CK_BYTE *okm; /* output keying material */
+ unsigned allocated_space = 0; /* If we need more work space, track it */
+ unsigned char *key_buf = &key_block[0];
rawHash = HASH_GetRawHashObject(hashType);
if (rawHash == NULL || rawHash->length > sizeof(hashbuf)) {
@@ -7686,7 +7688,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
crv = CKR_MECHANISM_PARAM_INVALID;
break;
}
- if (keySize == 0 || keySize > sizeof key_block ||
+ if (keySize == 0 ||
(!params->bExpand && keySize > hashLen) ||
(params->bExpand && keySize > 255 * hashLen)) {
crv = CKR_TEMPLATE_INCONSISTENT;
@@ -7736,34 +7738,49 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession,
/* T(1) = HMAC-Hash(prk, "" | info | 0x01)
* T(n) = HMAC-Hash(prk, T(n-1) | info | n
* key material = T(1) | ... | T(n)
+ *
+ * If the requested output length does not fit
+ * within |key_block|, allocate space for expansion.
*/
HMACContext *hmac;
CK_BYTE bi;
- unsigned iterations = PR_ROUNDUP(keySize, hashLen) / hashLen;
+ unsigned n_bytes = PR_ROUNDUP(keySize, hashLen);
+ unsigned iterations = n_bytes / hashLen;
hmac = HMAC_Create(rawHash, prk, prkLen, isFIPS);
if (hmac == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- for (bi = 1; bi <= iterations; ++bi) {
+ if (n_bytes > sizeof(key_block)) {
+ key_buf = PORT_Alloc(n_bytes);
+ if (key_buf == NULL) {
+ crv = CKR_HOST_MEMORY;
+ break;
+ }
+ allocated_space = n_bytes;
+ }
+ for (bi = 1; bi <= iterations && bi > 0; ++bi) {
unsigned len;
HMAC_Begin(hmac);
if (bi > 1) {
- HMAC_Update(hmac, key_block + ((bi - 2) * hashLen), hashLen);
+ HMAC_Update(hmac, key_buf + ((bi - 2) * hashLen), hashLen);
}
if (params->ulInfoLen != 0) {
HMAC_Update(hmac, params->pInfo, params->ulInfoLen);
}
HMAC_Update(hmac, &bi, 1);
- HMAC_Finish(hmac, key_block + ((bi - 1) * hashLen), &len,
+ HMAC_Finish(hmac, key_buf + ((bi - 1) * hashLen), &len,
hashLen);
PORT_Assert(len == hashLen);
}
HMAC_Destroy(hmac, PR_TRUE);
- okm = key_block;
+ okm = key_buf;
}
/* key material = prk */
crv = sftk_forceAttribute(key, CKA_VALUE, okm, keySize);
+ if (allocated_space) {
+ PORT_ZFree(key_buf, allocated_space);
+ }
break;
} /* end of CKM_NSS_HKDF_* */
diff --git a/security/nss/lib/softoken/softkver.h b/security/nss/lib/softoken/softkver.h
index 73a38b010..ab2e91018 100644
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -17,10 +17,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
-#define SOFTOKEN_VERSION "3.41.2" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION "3.41.3" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 41
-#define SOFTOKEN_VPATCH 2
+#define SOFTOKEN_VPATCH 3
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
diff --git a/security/nss/lib/util/nssutil.h b/security/nss/lib/util/nssutil.h
index a2be260b0..f880fb55e 100644
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -19,10 +19,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
-#define NSSUTIL_VERSION "3.41.2"
+#define NSSUTIL_VERSION "3.41.3"
#define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 41
-#define NSSUTIL_VPATCH 2
+#define NSSUTIL_VPATCH 3
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE