From f48e3627be16fdd82b63a95b81226edb52186344 Mon Sep 17 00:00:00 2001 From: yixiangzhike Date: Wed, 17 Mar 2021 18:17:53 +0800 Subject: [PATCH] Fix CVE-2020-12403 --- backport-0001-CVE-2020-12403.patch | 96 ++++++++++++++++++++++++++++++ backport-0002-CVE-2020-12403.patch | 74 +++++++++++++++++++++++ nss.spec | 11 +++- 3 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 backport-0001-CVE-2020-12403.patch create mode 100644 backport-0002-CVE-2020-12403.patch diff --git a/backport-0001-CVE-2020-12403.patch b/backport-0001-CVE-2020-12403.patch new file mode 100644 index 0000000..efe6e77 --- /dev/null +++ b/backport-0001-CVE-2020-12403.patch @@ -0,0 +1,96 @@ + +# HG changeset patch +# User Benjamin Beurdouche +# Date 1595031194 0 +# Node ID f282556e6cc7715f5754aeaadda6f902590e7e38 +# Parent 89733253df83ef7fe8dd0d49f6370b857e93d325 +Bug 1636771 - Disable PKCS11 incremental mode for ChaCha20. r=kjacobs,rrelyea + +Depends on D74801 + +Differential Revision: https://phabricator.services.mozilla.com/D83994 + +diff --git a/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc b/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc +--- a/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc ++++ b/nss/gtests/pk11_gtest/pk11_cipherop_unittest.cc +@@ -72,9 +72,58 @@ TEST(Pkcs11CipherOp, SingleCtxMultipleUn + ASSERT_EQ(GetBytes(ctx, outbuf, 17), SECSuccess); + + PK11_FreeSymKey(key); + PK11_FreeSlot(slot); + PK11_DestroyContext(ctx, PR_TRUE); + NSS_ShutdownContext(globalctx); + } + ++TEST(Pkcs11CipherOp, SingleCtxMultipleUnalignedCipherOpsChaCha20) { ++ PK11SlotInfo* slot; ++ PK11SymKey* key; ++ PK11Context* ctx; ++ ++ NSSInitContext* globalctx = ++ NSS_InitContext("", "", "", "", NULL, ++ NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | ++ NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT); ++ ++ const CK_MECHANISM_TYPE cipher = CKM_NSS_CHACHA20_CTR; ++ ++ slot = PK11_GetInternalSlot(); ++ ASSERT_TRUE(slot); ++ ++ // Use arbitrary bytes for the ChaCha20 key and IV ++ uint8_t key_bytes[32]; ++ for (size_t i = 0; i < 32; i++) { ++ key_bytes[i] = i; ++ } ++ SECItem keyItem = {siBuffer, key_bytes, 32}; ++ ++ uint8_t iv_bytes[16]; ++ for (size_t i = 0; i < 16; i++) { ++ key_bytes[i] = i; ++ } ++ SECItem ivItem = {siBuffer, iv_bytes, 16}; ++ ++ SECItem* param = PK11_ParamFromIV(cipher, &ivItem); ++ ++ key = PK11_ImportSymKey(slot, cipher, PK11_OriginUnwrap, CKA_ENCRYPT, ++ &keyItem, NULL); ++ ctx = PK11_CreateContextBySymKey(cipher, CKA_ENCRYPT, key, param); ++ ASSERT_TRUE(key); ++ ASSERT_TRUE(ctx); ++ ++ uint8_t outbuf[128]; ++ // This is supposed to fail for Chacha20. This is because the underlying ++ // PK11_CipherOp operation is calling the C_EncryptUpdate function for ++ // which multi-part is disabled for ChaCha20 in counter mode. ++ ASSERT_EQ(GetBytes(ctx, outbuf, 7), SECFailure); ++ ++ PK11_FreeSymKey(key); ++ PK11_FreeSlot(slot); ++ SECITEM_FreeItem(param, PR_TRUE); ++ PK11_DestroyContext(ctx, PR_TRUE); ++ NSS_ShutdownContext(globalctx); ++} ++ + } // namespace nss_test +diff --git a/nss/lib/softoken/pkcs11c.c b/nss/lib/softoken/pkcs11c.c +--- a/nss/lib/softoken/pkcs11c.c ++++ b/nss/lib/softoken/pkcs11c.c +@@ -1251,16 +1251,17 @@ sftk_CryptInit(CK_SESSION_HANDLE hSessio + + case CKM_NSS_CHACHA20_CTR: /* old NSS private version */ + case CKM_CHACHA20: /* PKCS #11 v3 version */ + { + unsigned char *counter; + unsigned char *nonce; + unsigned long counter_len; + unsigned long nonce_len; ++ context->multi = PR_FALSE; + if (pMechanism->mechanism == CKM_NSS_CHACHA20_CTR) { + if (key_type != CKK_NSS_CHACHA20) { + crv = CKR_KEY_TYPE_INCONSISTENT; + break; + } + if (pMechanism->pParameter == NULL || pMechanism->ulParameterLen != 16) { + crv = CKR_MECHANISM_PARAM_INVALID; + break; + diff --git a/backport-0002-CVE-2020-12403.patch b/backport-0002-CVE-2020-12403.patch new file mode 100644 index 0000000..a56ab51 --- /dev/null +++ b/backport-0002-CVE-2020-12403.patch @@ -0,0 +1,74 @@ + +# HG changeset patch +# User Benjamin Beurdouche +# Date 1595031218 0 +# Node ID c25adfdfab34ddb08d3262aac3242e3399de1095 +# Parent f282556e6cc7715f5754aeaadda6f902590e7e38 +Bug 1636771 - Fix incorrect call to Chacha20Poly1305 by PKCS11. r=jcj,kjacobs,rrelyea + +Differential Revision: https://phabricator.services.mozilla.com/D74801 + +diff --git a/nss/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc b/nss/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc +--- a/nss/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc ++++ b/nss/gtests/pk11_gtest/pk11_chacha20poly1305_unittest.cc +@@ -40,28 +40,35 @@ class Pkcs11ChaCha20Poly1305Test + aead_params.ulNonceLen = iv_len; + aead_params.pAAD = toUcharPtr(aad); + aead_params.ulAADLen = aad_len; + aead_params.ulTagLen = 16; + + SECItem params = {siBuffer, reinterpret_cast(&aead_params), + sizeof(aead_params)}; + +- // Encrypt with bad parameters. ++ // Encrypt with bad parameters (TagLen is too long). + unsigned int encrypted_len = 0; + std::vector encrypted(data_len + aead_params.ulTagLen); + aead_params.ulTagLen = 158072; + SECStatus rv = + PK11_Encrypt(key.get(), kMech, ¶ms, encrypted.data(), + &encrypted_len, encrypted.size(), data, data_len); + EXPECT_EQ(SECFailure, rv); + EXPECT_EQ(0U, encrypted_len); +- aead_params.ulTagLen = 16; ++ ++ // Encrypt with bad parameters (TagLen is too short). ++ aead_params.ulTagLen = 2; ++ rv = PK11_Encrypt(key.get(), kMech, ¶ms, encrypted.data(), ++ &encrypted_len, encrypted.size(), data, data_len); ++ EXPECT_EQ(SECFailure, rv); ++ EXPECT_EQ(0U, encrypted_len); + + // Encrypt. ++ aead_params.ulTagLen = 16; + rv = PK11_Encrypt(key.get(), kMech, ¶ms, encrypted.data(), + &encrypted_len, encrypted.size(), data, data_len); + + // Return if encryption failure was expected due to invalid IV. + // Without valid ciphertext, all further tests can be skipped. + if (invalid_iv) { + EXPECT_EQ(rv, SECFailure); + EXPECT_EQ(0U, encrypted_len) +diff --git a/nss/lib/freebl/chacha20poly1305.c b/nss/lib/freebl/chacha20poly1305.c +--- a/nss/lib/freebl/chacha20poly1305.c ++++ b/nss/lib/freebl/chacha20poly1305.c +@@ -76,17 +76,17 @@ ChaCha20Poly1305_InitContext(ChaCha20Pol + { + #ifdef NSS_DISABLE_CHACHAPOLY + return SECFailure; + #else + if (keyLen != 32) { + PORT_SetError(SEC_ERROR_BAD_KEY); + return SECFailure; + } +- if (tagLen == 0 || tagLen > 16) { ++ if (tagLen != 16) { + PORT_SetError(SEC_ERROR_INPUT_LEN); + return SECFailure; + } + + PORT_Memcpy(ctx->key, key, sizeof(ctx->key)); + ctx->tagLen = tagLen; + + return SECSuccess; + diff --git a/nss.spec b/nss.spec index 66a82dc..d6f913b 100644 --- a/nss.spec +++ b/nss.spec @@ -14,7 +14,7 @@ Summary: Network Security Services Name: nss Version: %{nss_version} -Release: 7 +Release: 8 License: MPLv2.0 URL: http://www.mozilla.org/projects/security/pki/nss/ Provides: nss-system-init @@ -44,6 +44,8 @@ Patch1: 0001-CVE-2020-6829-and-CVE-2020-12400.patch Patch2: 0002-CVE-2020-6829-and-CVE-2020-12400.patch Patch3: CVE-2020-12401.patch Patch4: backport-CVE-2020-25648-tighten-CSS-handling-in-compatibility-mode.patch +Patch5: backport-0001-CVE-2020-12403.patch +Patch6: backport-0002-CVE-2020-12403.patch %description Network Security Services (NSS) is a set of libraries designed to @@ -131,6 +133,8 @@ Help document for NSS %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 %build @@ -184,7 +188,7 @@ export POLICY_FILE="nss.config" # location of the policy file export POLICY_PATH="/etc/crypto-policies/back-ends" -make -j16 -C ./nss all +make %{?_smp_mflags} -C ./nss all make -C ./nss latest # build the man pages clean @@ -552,6 +556,9 @@ update-crypto-policies &>/dev/null||: %doc %{_mandir}/man* %changelog +* Wed Mar 17 2021 yixiangzhike - 3.54-8 +- fix CVE-2020-12403 + * Tue Mar 16 2021 yixiangzhike - 3.54-7 - optimize compilation time -- Gitee