diff -Nru nss-3.28.4/debian/changelog nss-3.28.4/debian/changelog --- nss-3.28.4/debian/changelog 2019-12-05 16:26:06.000000000 +0000 +++ nss-3.28.4/debian/changelog 2020-01-07 17:42:27.000000000 +0000 @@ -1,3 +1,15 @@ +nss (2:3.28.4-0ubuntu0.16.04.10) xenial-security; urgency=medium + + * SECURITY UPDATE: Possible wrong length for cryptographic primitives input + - debian/patches/CVE-2019-17006.patch: adds checks for length of crypto + primitives in nss/lib/freebl/chacha20poly1305.c, + nss/lib/freebl/ctr.c, nss/lib/freebl/gcm.c, + nss/lib/freebl/intel-gcm-wrap.c, + nss/lib/freebl/rsapkcs.c. + - CVE-2019-17006 + + -- Leonidas S. Barbosa Tue, 07 Jan 2020 14:42:06 -0300 + nss (2:3.28.4-0ubuntu0.16.04.9) xenial-security; urgency=medium * SECURITY UPDATE: Denial of service diff -Nru nss-3.28.4/debian/patches/CVE-2019-17006.patch nss-3.28.4/debian/patches/CVE-2019-17006.patch --- nss-3.28.4/debian/patches/CVE-2019-17006.patch 1970-01-01 00:00:00.000000000 +0000 +++ nss-3.28.4/debian/patches/CVE-2019-17006.patch 2020-01-07 17:42:00.000000000 +0000 @@ -0,0 +1,201 @@ +Backported of: + + +# HG changeset patch +# User Kevin Jacobs +# Date 1565796935 0 +# Node ID 9d1f5e71773d4e3146524096d74cb96c8df51abe +# Parent dfd6996fe7425eb0437346d11a01082f16fcfe34 +Bug 1539788 - UBSAN fixup for 128b counter. r=mt,jcj + +Differential Revision: https://phabricator.services.mozilla.com/D41884 + +Backported of: + + +# HG changeset patch +# User Kevin Jacobs +# Date 1565711935 0 +# Node ID dfd6996fe7425eb0437346d11a01082f16fcfe34 +# Parent 9bc47e69613e9ee9c8aaaf555150f815fc8161d9 +Bug 1539788 - Add length checks for cryptographic primitives r=mt,jcj + +This patch adds additional length checks around cryptographic primitives. + +Differential Revision: https://phabricator.services.mozilla.com/D36079 +diff --git a/nss/lib/freebl/chacha20poly1305.c b/nss/lib/freebl/chacha20poly1305.c +index cd265e1..4ff9387 100644 +--- a/nss/lib/freebl/chacha20poly1305.c ++++ b/nss/lib/freebl/chacha20poly1305.c +@@ -181,6 +181,12 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx, unsigned char *output, + 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 + // key. The remainder of the block is discarded. +diff --git a/nss/lib/freebl/ctr.c b/nss/lib/freebl/ctr.c +index d5715a5..ef10e03 100644 +--- a/nss/lib/freebl/ctr.c ++++ b/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/nss/lib/freebl/gcm.c b/nss/lib/freebl/gcm.c +index 2212100..a490006 100644 +--- a/nss/lib/freebl/gcm.c ++++ b/nss/lib/freebl/gcm.c +@@ -577,6 +577,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/nss/lib/freebl/intel-gcm-wrap.c b/nss/lib/freebl/intel-gcm-wrap.c +index 8c5eaf0..f4c69b7 100644 +--- a/nss/lib/freebl/intel-gcm-wrap.c ++++ b/nss/lib/freebl/intel-gcm-wrap.c +@@ -63,6 +63,12 @@ intel_AES_GCM_CreateContext(void *context, + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + 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) { +@@ -161,6 +167,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); +@@ -218,6 +232,15 @@ 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/nss/lib/freebl/rsapkcs.c b/nss/lib/freebl/rsapkcs.c +index 577fe1f..19c96c9 100644 +--- a/nss/lib/freebl/rsapkcs.c ++++ b/nss/lib/freebl/rsapkcs.c +@@ -96,7 +96,7 @@ rsa_FormatOneBlock(unsigned modulusLen, + { + unsigned char *block; + unsigned char *bp; +- int padLen; ++ unsigned int padLen; + int i, j; + SECStatus rv; + +@@ -116,14 +116,15 @@ 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 ++ * padLen must be at least RSA_BLOCK_MIN_PAD_LEN (8) bytes. ++ * 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) { +@@ -143,7 +144,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. +@@ -152,6 +153,7 @@ rsa_FormatOneBlock(unsigned modulusLen, + * If we need more than that, refill the bytes after Pad with + * new random bytes as necessary. + */ ++ + padLen = modulusLen - (data->len + 3); + PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN); + if (padLen < RSA_BLOCK_MIN_PAD_LEN) { +@@ -217,8 +219,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) { + result->len = 0; diff -Nru nss-3.28.4/debian/patches/series nss-3.28.4/debian/patches/series --- nss-3.28.4/debian/patches/series 2019-12-05 16:25:41.000000000 +0000 +++ nss-3.28.4/debian/patches/series 2020-01-07 17:42:00.000000000 +0000 @@ -15,3 +15,4 @@ CVE-2019-11729-1.patch CVE-2019-11745.patch CVE-2019-17007.patch +CVE-2019-17006.patch