Source: nss Version: 2:3.26-1 X-Debbugs-CC: [email protected] [email protected] Severity: important Tags: security patch upstream Control: fixed -1 2:3.30-1
Hi, the following vulnerabilities were published for nss. CVE-2017-5461[0]: | Mozilla Network Security Services (NSS) before 3.21.4, 3.22.x through | 3.28.x before 3.28.4, 3.29.x before 3.29.5, and 3.30.x before 3.30.1 | allows remote attackers to cause a denial of service (out-of-bounds | write) or possibly have unspecified other impact by leveraging | incorrect base64 operations. CVE-2017-5462[1]: | A flaw in DRBG number generation within the Network Security Services | (NSS) library where the internal state V does not correctly carry bits | over. The NSS library has been updated to fix this issue to address this | issue and Firefox 53 has been updated with NSS version 3.29.5. If you fix the vulnerabilities please also make sure to include the CVE (Common Vulnerabilities & Exposures) ids in your changelog entry. For further information see: [0] https://security-tracker.debian.org/tracker/CVE-2017-5461 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5461 [1] https://security-tracker.debian.org/tracker/CVE-2017-5462 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5462 Please adjust the affected versions in the BTS as needed. While those issues are fixed in experimental, they still need to be fixed in unstable and stretch. I'm attaching the patches I prepared/backported as part of my LTS work. Cheers, -- Raphaël Hertzog ◈ Debian Developer Support Debian LTS: https://www.freexian.com/services/debian-lts.html Learn to master Debian: https://debian-handbook.info/get/
# HG changeset patch # User Franziskus Kiefer <[email protected]> # Date 1489748381 -3600 # Node ID 77a5bb81dbaac5b03266a64ff981c156b61c8931 # Parent da15c12097edbe876620ed5da8378ee3269caea8 Bug 1344380 - gtests for b64 bug and some fixes, r=ttaubert Differential Revision: https://nss-review.dev.mozaws.net/D256#inline-2146 Origin: backport, https://hg.mozilla.org/projects/nss/rev/77a5bb81dbaa --- a/nss/external_tests/util_gtest/manifest.mn +++ b/nss/external_tests/util_gtest/manifest.mn @@ -8,6 +8,7 @@ MODULE = nss CPPSRCS = \ util_utf8_unittest.cc \ + util_b64_unittest.cc \ $(NULL) INCLUDES += \ --- /dev/null +++ b/nss/external_tests/util_gtest/util_b64_unittest.cc @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include <climits> +#include <memory> +#include "nssb64.h" + +#include "gtest/gtest.h" +#include "scoped_ptrs.h" + +namespace nss_test { + +class B64EncodeDecodeTest : public ::testing::Test { + public: + void TestDecodeStr(const std::string &str) { + ScopedSECItem tmp( + NSSBase64_DecodeBuffer(nullptr, nullptr, str.c_str(), str.size())); + ASSERT_TRUE(tmp); + char *out = NSSBase64_EncodeItem(nullptr, nullptr, 0, tmp.get()); + ASSERT_TRUE(out); + ASSERT_EQ(std::string(out), str); + PORT_Free(out); + } + bool TestEncodeItem(SECItem *item) { + bool rv = true; + char *out = NSSBase64_EncodeItem(nullptr, nullptr, 0, item); + rv = !!out; + if (out) { + ScopedSECItem tmp( + NSSBase64_DecodeBuffer(nullptr, nullptr, out, strlen(out))); + EXPECT_TRUE(tmp); + EXPECT_EQ(SECEqual, SECITEM_CompareItem(item, tmp.get())); + PORT_Free(out); + } + return rv; + } + bool TestFakeDecode(size_t str_len) { + std::string str(str_len, 'A'); + ScopedSECItem tmp( + NSSBase64_DecodeBuffer(nullptr, nullptr, str.c_str(), str.size())); + return !!tmp; + } + bool TestFakeEncode(size_t len) { + std::vector<uint8_t> data(len, 0x30); + SECItem tmp = {siBuffer, data.data(), + static_cast<unsigned int>(data.size())}; + return TestEncodeItem(&tmp); + } + + protected: +}; + +TEST_F(B64EncodeDecodeTest, DecEncTest) { TestDecodeStr("VGhpcyBpcyBOU1Mh"); } + +TEST_F(B64EncodeDecodeTest, EncDecTest) { + uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}; + SECItem tmp = {siBuffer, data, sizeof(data)}; + TestEncodeItem(&tmp); +} + +TEST_F(B64EncodeDecodeTest, FakeDecTest) { EXPECT_TRUE(TestFakeDecode(100)); } + +TEST_F(B64EncodeDecodeTest, FakeEncDecTest) { + EXPECT_TRUE(TestFakeEncode(100)); +} + +// These takes a while ... +TEST_F(B64EncodeDecodeTest, LongFakeDecTest1) { + EXPECT_TRUE(TestFakeDecode(0x66666666)); +} +TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest1) { TestFakeEncode(0x3fffffff); } +TEST_F(B64EncodeDecodeTest, LongFakeEncDecTest2) { + EXPECT_FALSE(TestFakeEncode(0x40000000)); +} + +} // namespace nss_test --- nss-3.26.orig/nss/lib/util/nssb64d.c +++ nss-3.26/nss/lib/util/nssb64d.c @@ -373,7 +373,7 @@ pl_base64_decode_flush (PLBase64Decoder static PRUint32 PL_Base64MaxDecodedLength (PRUint32 size) { - return ((size * 3) / 4); + return size * 0.75; } --- a/nss/lib/util/nssb64e.c +++ b/nss/lib/util/nssb64e.c @@ -285,20 +285,29 @@ PL_Base64MaxEncodedLength (PRUint32 size { PRUint32 tokens, tokens_per_line, full_lines, line_break_chars, remainder; + /* This is the maximum length we support. */ + if (size > 0x3fffffff) { + return 0; + } + + tokens = (size + 2) / 3; - if (line_length == 0) + if (line_length == 0) { return tokens * 4; + } - if (line_length < 4) /* too small! */ + if (line_length < 4) { /* too small! */ line_length = 4; + } tokens_per_line = line_length / 4; full_lines = tokens / tokens_per_line; remainder = (tokens - (full_lines * tokens_per_line)) * 4; line_break_chars = full_lines * 2; - if (remainder == 0) + if (remainder == 0) { line_break_chars -= 2; + } return (full_lines * tokens_per_line * 4) + line_break_chars + remainder; } @@ -454,13 +463,18 @@ PL_Base64EncodeBuffer (const unsigned ch PRStatus status; PR_ASSERT(srclen > 0); - if (srclen == 0) + if (srclen == 0) { return dest; + } /* * How much space could we possibly need for encoding this input? */ need_length = PL_Base64MaxEncodedLength (srclen, line_length); + if (need_length == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } /* * Make sure we have at least that much, if output buffer provided. @@ -643,6 +657,10 @@ NSSBase64_EncodeItem (PLArenaPool *arena } max_out_len = PL_Base64MaxEncodedLength (inItem->len, 64); + if (max_out_len == 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } if (arenaOpt != NULL) mark = PORT_ArenaMark (arenaOpt);
# HG changeset patch # User Franziskus Kiefer <[email protected]> # Date 1491394302 -7200 # Node ID 7248d38b76e569d2f89b20598fcdca595c3a2e6a # Parent 6eb39ead39e0b3f6269fd9660a4426187f5302a8 Bug 1345089 - add prng kat tests, r=ttaubert Origin: backport, https://hg.mozilla.org/projects/nss/rev/7248d38b76e5 --- a/nss/lib/freebl/blapi.h +++ b/nss/lib/freebl/blapi.h @@ -1473,6 +1473,12 @@ FIPS186Change_ReduceModQForDSA(const uns const unsigned char *q, unsigned char *xj); +/* To allow NIST KAT tests */ +extern SECStatus +PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len); + /* * The following functions are for FIPS poweron self test and FIPS algorithm * testing. --- a/nss/lib/freebl/drbg.c +++ b/nss/lib/freebl/drbg.c @@ -96,7 +96,8 @@ struct RNGContextStr { * RNG_RandomUpdate. */ PRUint8 additionalDataCache[PRNG_ADDITONAL_DATA_CACHE_SIZE]; PRUint32 additionalAvail; - PRBool isValid; /* false if RNG reaches an invalid state */ + PRBool isValid; /* false if RNG reaches an invalid state */ + PRBool isKatTest; /* true if running NIST PRNG KAT tests */ }; typedef struct RNGContextStr RNGContext; @@ -149,7 +150,7 @@ prng_Hash_df(PRUint8 *requested_bytes, u /* - * Hash_DRBG Instantiate NIST SP 800-80 10.1.1.2 + * Hash_DRBG Instantiate NIST SP 800-90 10.1.1.2 * * NOTE: bytes & len are entropy || nonce || personalization_string. In * normal operation, NSS calculates them all together in a single call. @@ -157,9 +158,11 @@ prng_Hash_df(PRUint8 *requested_bytes, u static SECStatus prng_instantiate(RNGContext *rng, const PRUint8 *bytes, unsigned int len) { - if (len < PRNG_SEEDLEN) { - /* if the seedlen is to small, it's probably because we failed to get - * enough random data */ + if (!rng->isKatTest && len < PRNG_SEEDLEN) { + /* If the seedlen is too small, it's probably because we failed to get + * enough random data. + * This is stricter than NIST SP800-90A requires. Don't enforce it for + * tests. */ PORT_SetError(SEC_ERROR_NEED_RANDOM); return SECFailure; } @@ -272,7 +275,7 @@ prng_reseed_test(RNGContext *rng, const #define PRNG_ADD_BITS_AND_CARRY(dest, dest_len, add, len, carry) \ PRNG_ADD_BITS(dest, dest_len, add, len, carry) \ - PRNG_ADD_CARRY_ONLY(dest, dest_len - len, carry) + PRNG_ADD_CARRY_ONLY(dest, dest_len - len - 1, carry) /* * This function expands the internal state of the prng to fulfill any number @@ -440,6 +443,7 @@ static PRStatus rng_init(void) } /* the RNG is in a valid state */ globalrng->isValid = PR_TRUE; + globalrng->isKatTest = PR_FALSE; /* fetch one random value so that we can populate rng->oldV for our * continous random number test. */ @@ -684,6 +688,17 @@ RNG_RNGShutdown(void) * entropy we may have previously collected. */ RNGContext testContext; +SECStatus +PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len, + const PRUint8 *nonce, unsigned int nonce_len, + const PRUint8 *personal_string, unsigned int ps_len) +{ + testContext.isKatTest = PR_TRUE; + return PRNGTEST_Instantiate(entropy, entropy_len, + nonce, nonce_len, + personal_string, ps_len); +} + /* * Test vector API. Use NIST SP 800-90 general interface so one of the * other NIST SP 800-90 algorithms may be used in the future.
_______________________________________________ Secure-testing-team mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/secure-testing-team

