- Remove upstreamed bmo-1400603.patch

- Added nss-bmo1930797.patch to fix failing tests in testsuite 

- update to NSS 3.106
  * bmo#1925975 - NSS 3.106 should be distributed with NSPR 4.36.
  * bmo#1923767 - pk12util: improve error handling in p12U_ReadPKCS12File.
  * bmo#1899402 - Correctly destroy bulkkey in error scenario.
  * bmo#1919997 - PKCS7 fuzz target, r=djackson,nss-reviewers.
  * bmo#1923002 - Extract certificates with handshake collection script.
  * bmo#1923006 - Specify len_control for fuzz targets.
  * bmo#1923280 - Fix memory leak in dumpCertificatePEM.
  * bmo#1102981 - Fix UBSan errors for SECU_PrintCertificate and
                  SECU_PrintCertificateBasicInfo.
  * bmo#1921528 - add new error codes to mozilla::pkix for Firefox to use.
  * bmo#1921768 - allow null phKey in NSC_DeriveKey.
  * bmo#1921801 - Only create seed corpus zip from existing corpus.
  * bmo#1826035 - Use explicit allowlist for for KDF PRFS.
  * bmo#1920138 - Increase optimization level for fuzz builds.
  * bmo#1920470 - Remove incorrect assert.
  * bmo#1914870 - Use libFuzzer options from fuzz/options/\*.options in CI.
  * bmo#1920945 - Polish corpus collection for automation.
  * bmo#1917572 - Detect new and unfuzzed SSL options.
  * bmo#1804646 - PKCS12 fuzzing target.
- requires NSPR 4.36

OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/mozilla-nss?expand=0&rev=465
This commit is contained in:
Wolfgang Rosenauer 2024-11-26 15:24:39 +00:00 committed by Git OBS Bridge
commit 13053eadb0
60 changed files with 12475 additions and 0 deletions

26
.gitattributes vendored Normal file
View File

@ -0,0 +1,26 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
## Specific LFS patterns
cert9.db filter=lfs diff=lfs merge=lfs -text
key4.db filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.osc

11
_constraints Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<constraints>
<hardware>
<disk>
<size unit="G">5</size>
</disk>
<memory>
<size unit="G">6</size>
</memory>
</hardware>
</constraints>

View File

@ -0,0 +1,17 @@
Index: nss/coreconf/Linux.mk
===================================================================
--- nss.orig/coreconf/Linux.mk
+++ nss/coreconf/Linux.mk
@@ -184,6 +184,12 @@ endif
endif
endif
+# harden DSOs/executables a bit against exploits
+ifeq (2.6,$(firstword $(sort 2.6 $(OS_RELEASE))))
+DSO_LDOPTS+=-Wl,-z,relro
+LDFLAGS += -Wl,-z,relro
+endif
+
USE_SYSTEM_ZLIB = 1
ZLIB_LIBS = -lz

18
baselibs.conf Normal file
View File

@ -0,0 +1,18 @@
mozilla-nss
requires "mozilla-nspr-<targettype> >= 4.36"
requires "libfreebl3-<targettype>"
requires "libsoftokn3-<targettype>"
requires "libnssckbi.so"
libsoftokn3
requires "libfreebl3-<targettype> = <version>"
provides "libsoftokn3-hmac-<targettype> = <version>-%release"
obsoletes "libsoftokn3-hmac-<targettype> < <version>-%release"
+/usr/lib/libsoftokn3.chk
+/usr/lib/libnssdbm3.chk
libfreebl3
provides "libfreebl3-hmac-<targettype> = <version>-%release"
obsoletes "libfreebl3-hmac-<targettype> < <version>-%release"
+/lib/libfreebl3.chk
+/lib/libfreeblpriv3.chk
mozilla-nss-sysinit
mozilla-nss-certs

337
bmo-1400603.patch Normal file
View File

@ -0,0 +1,337 @@
From b2f3a6407d2d6ec89522410d7ac4c56d310c92b1 Mon Sep 17 00:00:00 2001
From: Daiki Ueno <dueno@redhat.com>
Date: Mon, 18 Sep 2017 11:24:00 +0200
Subject: [PATCH] freebl: Reorganize AES-GCM source code based on hw/sw
implementation
diff --git a/lib/freebl/gcm-hw.c b/lib/freebl/gcm-hw.c
new file mode 100644
--- /dev/null
+++ b/lib/freebl/gcm-hw.c
@@ -0,0 +1,151 @@
+/* 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/. */
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+#include "gcm.h"
+#include "secerr.h"
+
+#ifdef NSS_X86_OR_X64
+#include <wmmintrin.h> /* clmul */
+#endif
+
+#define WRITE64(x, bytes) \
+ (bytes)[0] = (x) >> 56; \
+ (bytes)[1] = (x) >> 48; \
+ (bytes)[2] = (x) >> 40; \
+ (bytes)[3] = (x) >> 32; \
+ (bytes)[4] = (x) >> 24; \
+ (bytes)[5] = (x) >> 16; \
+ (bytes)[6] = (x) >> 8; \
+ (bytes)[7] = (x);
+
+SECStatus
+gcm_HashWrite_hw(gcmHashContext *ghash, unsigned char *outbuf,
+ unsigned int maxout)
+{
+#ifdef NSS_X86_OR_X64
+ uint64_t tmp_out[2];
+ _mm_storeu_si128((__m128i *)tmp_out, ghash->x);
+ PORT_Assert(maxout >= 16);
+ WRITE64(tmp_out[0], outbuf + 8);
+ WRITE64(tmp_out[1], outbuf);
+ return SECSuccess;
+#else
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+#endif /* NSS_X86_OR_X64 */
+}
+
+SECStatus
+gcm_HashMult_hw(gcmHashContext *ghash, const unsigned char *buf,
+ unsigned int count)
+{
+#ifdef NSS_X86_OR_X64
+ size_t i;
+ pre_align __m128i z_high post_align;
+ pre_align __m128i z_low post_align;
+ pre_align __m128i C post_align;
+ pre_align __m128i D post_align;
+ pre_align __m128i E post_align;
+ pre_align __m128i F post_align;
+ pre_align __m128i bin post_align;
+ pre_align __m128i Ci post_align;
+ pre_align __m128i tmp post_align;
+
+ for (i = 0; i < count; i++, buf += 16) {
+ bin = _mm_set_epi16(((uint16_t)buf[0] << 8) | buf[1],
+ ((uint16_t)buf[2] << 8) | buf[3],
+ ((uint16_t)buf[4] << 8) | buf[5],
+ ((uint16_t)buf[6] << 8) | buf[7],
+ ((uint16_t)buf[8] << 8) | buf[9],
+ ((uint16_t)buf[10] << 8) | buf[11],
+ ((uint16_t)buf[12] << 8) | buf[13],
+ ((uint16_t)buf[14] << 8) | buf[15]);
+ Ci = _mm_xor_si128(bin, ghash->x);
+
+ /* Do binary mult ghash->X = Ci * ghash->H. */
+ C = _mm_clmulepi64_si128(Ci, ghash->h, 0x00);
+ D = _mm_clmulepi64_si128(Ci, ghash->h, 0x11);
+ E = _mm_clmulepi64_si128(Ci, ghash->h, 0x01);
+ F = _mm_clmulepi64_si128(Ci, ghash->h, 0x10);
+ tmp = _mm_xor_si128(E, F);
+ z_high = _mm_xor_si128(tmp, _mm_slli_si128(D, 8));
+ z_high = _mm_unpackhi_epi64(z_high, D);
+ z_low = _mm_xor_si128(_mm_slli_si128(tmp, 8), C);
+ z_low = _mm_unpackhi_epi64(_mm_slli_si128(C, 8), z_low);
+
+ /* Shift one to the left (multiply by x) as gcm spec is stupid. */
+ C = _mm_slli_si128(z_low, 8);
+ E = _mm_srli_epi64(C, 63);
+ D = _mm_slli_si128(z_high, 8);
+ F = _mm_srli_epi64(D, 63);
+ /* Carry over */
+ C = _mm_srli_si128(z_low, 8);
+ D = _mm_srli_epi64(C, 63);
+ z_low = _mm_or_si128(_mm_slli_epi64(z_low, 1), E);
+ z_high = _mm_or_si128(_mm_or_si128(_mm_slli_epi64(z_high, 1), F), D);
+
+ /* Reduce */
+ C = _mm_slli_si128(z_low, 8);
+ /* D = z_low << 127 */
+ D = _mm_slli_epi64(C, 63);
+ /* E = z_low << 126 */
+ E = _mm_slli_epi64(C, 62);
+ /* F = z_low << 121 */
+ F = _mm_slli_epi64(C, 57);
+ /* z_low ^= (z_low << 127) ^ (z_low << 126) ^ (z_low << 121); */
+ z_low = _mm_xor_si128(_mm_xor_si128(_mm_xor_si128(z_low, D), E), F);
+ C = _mm_srli_si128(z_low, 8);
+ /* D = z_low >> 1 */
+ D = _mm_slli_epi64(C, 63);
+ D = _mm_or_si128(_mm_srli_epi64(z_low, 1), D);
+ /* E = z_low >> 2 */
+ E = _mm_slli_epi64(C, 62);
+ E = _mm_or_si128(_mm_srli_epi64(z_low, 2), E);
+ /* F = z_low >> 7 */
+ F = _mm_slli_epi64(C, 57);
+ F = _mm_or_si128(_mm_srli_epi64(z_low, 7), F);
+ /* ghash->x ^= z_low ^ (z_low >> 1) ^ (z_low >> 2) ^ (z_low >> 7); */
+ ghash->x = _mm_xor_si128(_mm_xor_si128(
+ _mm_xor_si128(_mm_xor_si128(z_high, z_low), D), E),
+ F);
+ }
+ return SECSuccess;
+#else
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+#endif /* NSS_X86_OR_X64 */
+}
+
+SECStatus
+gcm_HashInit_hw(gcmHashContext *ghash)
+{
+#ifdef NSS_X86_OR_X64
+ ghash->ghash_mul = gcm_HashMult_hw;
+ ghash->x = _mm_setzero_si128();
+ /* MSVC requires __m64 to load epi64. */
+ ghash->h = _mm_set_epi32(ghash->h_high >> 32, (uint32_t)ghash->h_high,
+ ghash->h_low >> 32, (uint32_t)ghash->h_low);
+ ghash->hw = PR_TRUE;
+ return SECSuccess;
+#else
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+#endif /* NSS_X86_OR_X64 */
+}
+
+SECStatus
+gcm_HashZeroX_hw(gcmHashContext *ghash)
+{
+#ifdef NSS_X86_OR_X64
+ ghash->x = _mm_setzero_si128();
+ return SECSuccess;
+#else
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+#endif /* NSS_X86_OR_X64 */
+}
+
diff --git a/lib/freebl/rijndael-hw.c b/lib/freebl/rijndael-hw.c
new file mode 100644
--- /dev/null
+++ b/lib/freebl/rijndael-hw.c
@@ -0,0 +1,170 @@
+/* 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/. */
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+#include "rijndael.h"
+#include "secerr.h"
+
+#ifdef NSS_X86_OR_X64
+#include <wmmintrin.h> /* aes-ni */
+#endif
+
+#if defined(NSS_X86_OR_X64)
+#define EXPAND_KEY128(k, rcon, res) \
+ tmp_key = _mm_aeskeygenassist_si128(k, rcon); \
+ tmp_key = _mm_shuffle_epi32(tmp_key, 0xFF); \
+ tmp = _mm_xor_si128(k, _mm_slli_si128(k, 4)); \
+ tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \
+ tmp = _mm_xor_si128(tmp, _mm_slli_si128(tmp, 4)); \
+ res = _mm_xor_si128(tmp, tmp_key)
+
+static void
+native_key_expansion128(AESContext *cx, const unsigned char *key)
+{
+ __m128i *keySchedule = cx->keySchedule;
+ pre_align __m128i tmp_key post_align;
+ pre_align __m128i tmp post_align;
+ keySchedule[0] = _mm_loadu_si128((__m128i *)key);
+ EXPAND_KEY128(keySchedule[0], 0x01, keySchedule[1]);
+ EXPAND_KEY128(keySchedule[1], 0x02, keySchedule[2]);
+ EXPAND_KEY128(keySchedule[2], 0x04, keySchedule[3]);
+ EXPAND_KEY128(keySchedule[3], 0x08, keySchedule[4]);
+ EXPAND_KEY128(keySchedule[4], 0x10, keySchedule[5]);
+ EXPAND_KEY128(keySchedule[5], 0x20, keySchedule[6]);
+ EXPAND_KEY128(keySchedule[6], 0x40, keySchedule[7]);
+ EXPAND_KEY128(keySchedule[7], 0x80, keySchedule[8]);
+ EXPAND_KEY128(keySchedule[8], 0x1B, keySchedule[9]);
+ EXPAND_KEY128(keySchedule[9], 0x36, keySchedule[10]);
+}
+
+#define EXPAND_KEY192_PART1(res, k0, kt, rcon) \
+ tmp2 = _mm_slli_si128(k0, 4); \
+ tmp1 = _mm_xor_si128(k0, tmp2); \
+ tmp2 = _mm_slli_si128(tmp2, 4); \
+ tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \
+ tmp2 = _mm_aeskeygenassist_si128(kt, rcon); \
+ res = _mm_xor_si128(tmp1, _mm_shuffle_epi32(tmp2, 0x55))
+
+#define EXPAND_KEY192_PART2(res, k1, k2) \
+ tmp2 = _mm_xor_si128(k1, _mm_slli_si128(k1, 4)); \
+ res = _mm_xor_si128(tmp2, _mm_shuffle_epi32(k2, 0xFF))
+
+#define EXPAND_KEY192(k0, res1, res2, res3, carry, rcon1, rcon2) \
+ EXPAND_KEY192_PART1(tmp3, k0, res1, rcon1); \
+ EXPAND_KEY192_PART2(carry, res1, tmp3); \
+ res1 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(res1), \
+ _mm_castsi128_pd(tmp3), 0)); \
+ res2 = _mm_castpd_si128(_mm_shuffle_pd(_mm_castsi128_pd(tmp3), \
+ _mm_castsi128_pd(carry), 1)); \
+ EXPAND_KEY192_PART1(res3, tmp3, carry, rcon2)
+
+static void
+native_key_expansion192(AESContext *cx, const unsigned char *key)
+{
+ __m128i *keySchedule = cx->keySchedule;
+ pre_align __m128i tmp1 post_align;
+ pre_align __m128i tmp2 post_align;
+ pre_align __m128i tmp3 post_align;
+ pre_align __m128i carry post_align;
+ keySchedule[0] = _mm_loadu_si128((__m128i *)key);
+ keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16));
+ EXPAND_KEY192(keySchedule[0], keySchedule[1], keySchedule[2],
+ keySchedule[3], carry, 0x1, 0x2);
+ EXPAND_KEY192_PART2(keySchedule[4], carry, keySchedule[3]);
+ EXPAND_KEY192(keySchedule[3], keySchedule[4], keySchedule[5],
+ keySchedule[6], carry, 0x4, 0x8);
+ EXPAND_KEY192_PART2(keySchedule[7], carry, keySchedule[6]);
+ EXPAND_KEY192(keySchedule[6], keySchedule[7], keySchedule[8],
+ keySchedule[9], carry, 0x10, 0x20);
+ EXPAND_KEY192_PART2(keySchedule[10], carry, keySchedule[9]);
+ EXPAND_KEY192(keySchedule[9], keySchedule[10], keySchedule[11],
+ keySchedule[12], carry, 0x40, 0x80);
+}
+
+#define EXPAND_KEY256_PART(res, rconx, k1x, k2x, X) \
+ tmp_key = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(k2x, rconx), X); \
+ tmp2 = _mm_slli_si128(k1x, 4); \
+ tmp1 = _mm_xor_si128(k1x, tmp2); \
+ tmp2 = _mm_slli_si128(tmp2, 4); \
+ tmp1 = _mm_xor_si128(_mm_xor_si128(tmp1, tmp2), _mm_slli_si128(tmp2, 4)); \
+ res = _mm_xor_si128(tmp1, tmp_key);
+
+#define EXPAND_KEY256(res1, res2, k1, k2, rcon) \
+ EXPAND_KEY256_PART(res1, rcon, k1, k2, 0xFF); \
+ EXPAND_KEY256_PART(res2, 0x00, k2, res1, 0xAA)
+
+static void
+native_key_expansion256(AESContext *cx, const unsigned char *key)
+{
+ __m128i *keySchedule = cx->keySchedule;
+ pre_align __m128i tmp_key post_align;
+ pre_align __m128i tmp1 post_align;
+ pre_align __m128i tmp2 post_align;
+ keySchedule[0] = _mm_loadu_si128((__m128i *)key);
+ keySchedule[1] = _mm_loadu_si128((__m128i *)(key + 16));
+ EXPAND_KEY256(keySchedule[2], keySchedule[3], keySchedule[0],
+ keySchedule[1], 0x01);
+ EXPAND_KEY256(keySchedule[4], keySchedule[5], keySchedule[2],
+ keySchedule[3], 0x02);
+ EXPAND_KEY256(keySchedule[6], keySchedule[7], keySchedule[4],
+ keySchedule[5], 0x04);
+ EXPAND_KEY256(keySchedule[8], keySchedule[9], keySchedule[6],
+ keySchedule[7], 0x08);
+ EXPAND_KEY256(keySchedule[10], keySchedule[11], keySchedule[8],
+ keySchedule[9], 0x10);
+ EXPAND_KEY256(keySchedule[12], keySchedule[13], keySchedule[10],
+ keySchedule[11], 0x20);
+ EXPAND_KEY256_PART(keySchedule[14], 0x40, keySchedule[12],
+ keySchedule[13], 0xFF);
+}
+
+#endif /* NSS_X86_OR_X64 */
+
+/*
+ * AES key expansion using aes-ni instructions.
+ */
+void
+rijndael_native_key_expansion(AESContext *cx, const unsigned char *key,
+ unsigned int Nk)
+{
+#ifdef NSS_X86_OR_X64
+ switch (Nk) {
+ case 4:
+ native_key_expansion128(cx, key);
+ return;
+ case 6:
+ native_key_expansion192(cx, key);
+ return;
+ case 8:
+ native_key_expansion256(cx, key);
+ return;
+ default:
+ /* This shouldn't happen. */
+ PORT_Assert(0);
+ }
+#else
+ PORT_Assert(0);
+#endif /* NSS_X86_OR_X64 */
+}
+
+void
+rijndael_native_encryptBlock(AESContext *cx,
+ unsigned char *output,
+ const unsigned char *input)
+{
+#ifdef NSS_X86_OR_X64
+ int i;
+ pre_align __m128i m post_align = _mm_loadu_si128((__m128i *)input);
+ m = _mm_xor_si128(m, cx->keySchedule[0]);
+ for (i = 1; i < cx->Nr; ++i) {
+ m = _mm_aesenc_si128(m, cx->keySchedule[i]);
+ }
+ m = _mm_aesenclast_si128(m, cx->keySchedule[cx->Nr]);
+ _mm_storeu_si128((__m128i *)output, m);
+#else
+ PORT_Assert(0);
+#endif /* NSS_X86_OR_X64 */
+}

3
cert9.db Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6bda6ce59a46dea427681cc8a76295e34c7c2f17f4a2f265b39cfe258ab65ded
size 9216

3
key4.db Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:51ca7b19639cde32fb555b0d10a3b6a1fec0b2ab002062fd611cdc7ad73c2268
size 11264

12
malloc.patch Normal file
View File

@ -0,0 +1,12 @@
Index: nss/tests/ssl/ssl.sh
===================================================================
--- nss.orig/tests/ssl/ssl.sh
+++ nss/tests/ssl/ssl.sh
@@ -1661,6 +1661,7 @@ ssl_run_tests()
################################# main #################################
+unset MALLOC_CHECK_
ssl_init
ssl_run_tests
ssl_cleanup

5
mozilla-nss-rpmlintrc Normal file
View File

@ -0,0 +1,5 @@
addFilter("shlib-policy-name-error")
addFilter("shlib-policy-missing-lib")
addFilter("shlib-policy-missing-suffix")
addFilter("shlib-unversioned-lib")
addFilter("shlib-fixed-dependency")

4149
mozilla-nss.changes Normal file

File diff suppressed because it is too large Load Diff

541
mozilla-nss.spec Normal file
View File

@ -0,0 +1,541 @@
#
# spec file for package mozilla-nss
#
# Copyright (c) 2024 SUSE LLC
# Copyright (c) 2006-2024 Wolfgang Rosenauer
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%global nss_softokn_fips_version 3.106
%define NSPR_min_version 4.36
%define nspr_ver %(rpm -q --queryformat '%%{VERSION}' mozilla-nspr)
%define nssdbdir %{_sysconfdir}/pki/nssdb
%global crypto_policies_version 20210218
Name: mozilla-nss
Version: 3.106
Release: 0
%define underscore_version 3_106
Summary: Network Security Services
License: MPL-2.0
Group: System/Libraries
URL: https://www.mozilla.org/projects/security/pki/nss/
Source: https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_%{underscore_version}_RTM/src/nss-%{version}.tar.gz
# hg clone https://hg.mozilla.org/projects/nss nss-%%{version}/nss ; cd nss-%%{version}/nss ; hg up NSS_%%{underscore_version}_RTM
#Source: nss-%%{version}.tar.gz
Source1: nss.pc.in
Source3: nss-config.in
Source4: %{name}-rpmlintrc
Source5: baselibs.conf
Source6: setup-nsssysinit.sh
Source7: cert9.db
Source8: key4.db
Source9: pkcs11.txt
#Source10: PayPalEE.cert
Source11: nss-util.pc.in
Source13: nss-util-config.in
Source99: %{name}.changes
Patch1: nss-opt.patch
Patch2: system-nspr.patch
Patch3: nss-no-rpath.patch
Patch4: add-relro-linker-option.patch
Patch5: malloc.patch
Patch7: nss-sqlitename.patch
Patch8: nss-bmo1930797.patch
Patch9: nss-fips-use-getrandom.patch
Patch10: nss-fips-dsa-kat.patch
Patch11: nss-fips-pairwise-consistency-check.patch
Patch12: nss-fips-rsa-keygen-strictness.patch
Patch13: nss-fips-cavs-keywrap.patch
Patch14: nss-fips-cavs-kas-ffc.patch
Patch15: nss-fips-cavs-kas-ecc.patch
Patch16: nss-fips-gcm-ctr.patch
Patch17: nss-fips-constructor-self-tests.patch
Patch18: nss-fips-cavs-general.patch
Patch19: nss-fips-cavs-dsa-fixes.patch
Patch20: nss-fips-cavs-rsa-fixes.patch
Patch21: nss-fips-approved-crypto-non-ec.patch
Patch22: nss-fips-zeroization.patch
Patch24: nss-fips-use-strong-random-pool.patch
Patch25: nss-fips-detect-fips-mode-fixes.patch
Patch26: nss-fips-combined-hash-sign-dsa-ecdsa.patch
Patch27: nss-fips-aes-keywrap-post.patch
Patch37: nss-fips-fix-missing-nspr.patch
Patch38: nss-fips-stricter-dh.patch
Patch40: nss-fips-180-3-csp-clearing.patch
Patch41: nss-fips-pbkdf-kat-compliance.patch
Patch44: nss-fips-tests-enable-fips.patch
Patch45: nss-fips-drbg-libjitter.patch
Patch46: nss-allow-slow-tests.patch
Patch47: nss-fips-pct-pubkeys.patch
Patch48: nss-fips-test.patch
Patch49: nss-allow-slow-tests-s390x.patch
Patch50: nss-fips-bsc1223724.patch
Patch51: nss-fips-aes-gcm-restrict.patch
Patch52: nss-fips-safe-memset.patch
%if 0%{?sle_version} >= 120000 && 0%{?sle_version} < 150000
# aarch64 + gcc4.8 fails to build on SLE-12 due to undefined references
BuildRequires: gcc9-c++
%else
BuildRequires: gcc-c++
%endif
BuildRequires: pkgconfig
BuildRequires: pkgconfig(nspr) >= %{NSPR_min_version}
BuildRequires: pkgconfig(sqlite3)
BuildRequires: pkgconfig(zlib)
%if 0%{?sle_version} >= 150400
BuildRequires: jitterentropy-devel
# Libjitter needs to be present before AND after the install
Requires(pre): libjitterentropy3
Requires: libjitterentropy3
%endif
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
Requires: crypto-policies >= %{crypto_policies_version}
%endif
Requires: libfreebl3 >= %{nss_softokn_fips_version}
Requires: libsoftokn3 >= %{nss_softokn_fips_version}
Requires: mozilla-nspr >= %{NSPR_min_version}
%if "%{_lib}" == "lib64"
Requires: libnssckbi.so()(64bit)
%else
Requires: libnssckbi.so
%endif
Provides: nss = %{version}
%ifnarch %sparc
%if ! 0%{?qemu_user_space_build}
%define run_testsuite 1
%endif
%endif
%description
Network Security Services (NSS) is a set of libraries designed to
support cross-platform development of security-enabled server
applications. Applications built with NSS can support SSL v3,
TLS v1.0, v1.1, v1.2, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3
certificates, and other security standards.
%package devel
Summary: Network (Netscape) Security Services development files
Group: Development/Libraries/C and C++
Requires: libfreebl3
Requires: libsoftokn3
Requires: mozilla-nss = %{version}-%{release}
Requires: pkgconfig(nspr) >= %{NSPR_min_version}
%description devel
Network Security Services (NSS) is a set of libraries designed to
support cross-platform development of security-enabled server
applications. Applications built with NSS can support SSL v3,
TLS v1.0, v1.1, v1.2, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3
certificates, and other security standards.
%package tools
Summary: Tools for developing, debugging, and managing applications that use NSS
Group: System/Management
Requires(pre): mozilla-nss >= %{version}
%description tools
The NSS Security Tools allow developers to test, debug, and manage
applications that use NSS.
%package sysinit
Summary: System NSS Initialization
Group: System/Management
Requires: mozilla-nss >= %{version}
Requires(post): sed
Requires(post): coreutils
%description sysinit
Default Operation System module that manages applications loading
NSS globally on the system. This module loads the system defined
PKCS #11 modules for NSS and chains with other NSS modules to load
any system or user configured modules.
%package -n libfreebl3
Summary: Freebl library for the Network Security Services
Group: System/Libraries
Provides: libfreebl3-hmac = %{version}-%{release}
Obsoletes: libfreebl3-hmac < %{version}-%{release}
%description -n libfreebl3
Network Security Services (NSS) is a set of libraries designed to
support cross-platform development of security-enabled server
applications. Applications built with NSS can support SSL v3,
TLS v1.0, v1.1, v1.2, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3
certificates, and other security standards.
This package installs the freebl library from NSS.
%package -n libsoftokn3
Summary: Network Security Services Softoken Module
Group: System/Libraries
Requires: libfreebl3 = %{version}-%{release}
Provides: libsoftokn3-hmac = %{version}-%{release}
Obsoletes: libsoftokn3-hmac < %{version}-%{release}
%description -n libsoftokn3
Network Security Services (NSS) is a set of libraries designed to
support cross-platform development of security-enabled server
applications. Applications built with NSS can support SSL v3,
TLS v1.0, v1.1, v1.2, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3
certificates, and other security standards.
Network Security Services Softoken Cryptographic Module
%package certs
Summary: CA certificates for NSS
Group: Productivity/Networking/Security
%description certs
This package contains the integrated CA root certificates from the
Mozilla project.
%prep
%setup -q -n nss-%{version}
cd nss
%patch -P 1 -p1
%patch -P 2 -p1
%patch -P 3 -p1
%patch -P 4 -p1
%if 0%{?suse_version} > 1110
%patch -P 5 -p1
%endif
%patch -P 7 -p1
%patch -P 8 -p1
# FIPS patches
%patch -P 9 -p1
%patch -P 10 -p1
%patch -P 11 -p1
%patch -P 12 -p1
%patch -P 13 -p1
%patch -P 14 -p1
%patch -P 15 -p1
%patch -P 16 -p1
%patch -P 17 -p1
%patch -P 18 -p1
%patch -P 19 -p1
%patch -P 20 -p1
%patch -P 21 -p1
%patch -P 22 -p1
%patch -P 24 -p1
%patch -P 25 -p1
%patch -P 26 -p1
%patch -P 27 -p1
%patch -P 37 -p1
%patch -P 38 -p1
%patch -P 40 -p1
%patch -P 41 -p1
%patch -P 44 -p1
# Libjitter only for SLE15 SP4+
%if 0%{?sle_version} >= 150400
%patch -P 45 -p1
%endif
%patch -P 46 -p1
%patch -P 47 -p1
%patch -P 48 -p1
%ifarch s390x
# slow test on s390x, permit more time
%patch -P 49 -p1
%endif
%patch -P 50 -p1
%patch -P 51 -p1
%if 0%{?sle_version} >= 150000
# glibc on SLE-12 is too old and doesn't have explicit_bzero yet.
%patch -P 52 -p1
%endif
# additional CA certificates
#cd security/nss/lib/ckfw/builtins
#cat %{SOURCE2} >> certdata.txt
#make generate
%build
%ifarch %arm
# LTO fails on neon errors
%global _lto_cflags %{nil}
%else
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects
%endif
cd nss
cat > ../obsenv.sh <<EOF
%if 0%{?sle_version} >= 120000 && 0%{?sle_version} < 150000
export CC=gcc-9
# Yes, they use both...
export CXX=g++-9
export CCC=g++-9
%endif
export NSS_ALLOW_SSLKEYLOGFILE=1
export NSS_ENABLE_WERROR=0
export NSS_NO_PKCS11_BYPASS=1
export FREEBL_NO_DEPEND=1
export FREEBL_LOWHASH=1
export NSPR_INCLUDE_DIR=`nspr-config --includedir`
export NSPR_LIB_DIR=`nspr-config --libdir`
export OPT_FLAGS="%{optflags} -fno-strict-aliasing -fPIE -pie"
export LIBDIR=%{_libdir}
%ifarch x86_64 s390x ppc64 ppc64le ia64 aarch64 riscv64
export USE_64=1
%endif
export NSS_DISABLE_GTESTS=1
export NSS_USE_SYSTEM_SQLITE=1
export NSS_ENABLE_FIPS_INDICATORS=1
export NSS_FIPS_MODULE_ID="\"SUSE Linux Enterprise NSS %{version}-%{release}\""
#export SQLITE_LIB_NAME=nsssqlite3
export MAKE_FLAGS="BUILD_OPT=1"
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
# Set the policy file location
# if set NSS will always check for the policy file and load if it exists
#export POLICY_FILE="nss.config"
# location of the policy file
#export POLICY_PATH="/etc/crypto-policies/back-ends"
%endif
EOF
source ../obsenv.sh
modified="$(sed -n '/^----/n;s/ - .*$//;p;q' "%{SOURCE99}")"
DATE="\"$(date -d "${modified}" "+%%b %%e %%Y")\""
TIME="\"$(date -d "${modified}" "+%%R")\""
find . -name '*.[ch]' -print -exec sed -i "s/__DATE__/${DATE}/g;s/__TIME__/${TIME}/g" {} +
make %{?_smp_mflags} nss_build_all $MAKE_FLAGS
%check
cd nss
# run testsuite
%if 0%{?run_testsuite}
cat > ../obstestenv.sh <<EOF
export BUILD_OPT=1
export HOST="localhost"
export DOMSUF="localdomain"
export USE_IP=TRUE
export IP_ADDRESS="127.0.0.1"
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
# This is necessary because the test suite tests algorithms that are
# disabled by the system policy.
export NSS_IGNORE_SYSTEM_POLICY=1
%endif
EOF
source ../obsenv.sh
source ../obstestenv.sh
cd tests
./all.sh
if grep "FAILED" ../../../tests_results/security/localhost.1/output.log ; then
echo "Testsuite FAILED"
exit 1
fi
%endif
%install
cd nss
mkdir -p %{buildroot}%{_libdir}
mkdir -p %{buildroot}%{_libexecdir}/nss
mkdir -p %{buildroot}%{_includedir}/nss3
mkdir -p %{buildroot}%{_bindir}
mkdir -p %{buildroot}%{_sbindir}
mkdir -p %{buildroot}%{nssdbdir}
pushd ../dist/Linux*
# copy headers
cp -rL ../public/nss/*.h %{buildroot}%{_includedir}/nss3
# copy some freebl include files we also want
for file in blapi.h alghmac.h cmac.h
do
cp -L ../private/nss/$file %{buildroot}/%{_includedir}/nss3
done
# copy dynamic libs
cp -L lib/libnss3.so \
lib/libnssdbm3.so \
lib/libnssdbm3.chk \
lib/libnssutil3.so \
lib/libnssckbi.so \
lib/libnsssysinit.so \
lib/libsmime3.so \
lib/libsoftokn3.so \
lib/libsoftokn3.chk \
lib/libssl3.so \
%{buildroot}%{_libdir}
cp -L lib/libfreebl3.so \
lib/libfreebl3.chk \
lib/libfreeblpriv3.so \
lib/libfreeblpriv3.chk \
%{buildroot}/%{_libdir}
#cp -L lib/libnsssqlite3.so \
# %{buildroot}%{_libdir}
# copy static libs
cp -L lib/libcrmf.a \
lib/libfreebl.a \
lib/libnssb.a \
lib/libnssckfw.a \
%{buildroot}%{_libdir}
# copy tools
cp -L bin/certutil \
bin/cmsutil \
bin/crlutil \
bin/nss-policy-check \
bin/modutil \
bin/pk12util \
bin/signtool \
bin/signver \
bin/ssltap \
%{buildroot}%{_bindir}
# copy man-pages
mkdir -p %{buildroot}%{_mandir}/man1/
cp -L %{_builddir}/nss-%{version}/nss/doc/nroff/* %{buildroot}%{_mandir}/man1/
# Fix conflict with perl-PAR-Packer which has a pp-exe in _bindir
mkdir -p %{buildroot}%{_mandir}/man7/
mv %{buildroot}%{_mandir}/man1/pp.1 %{buildroot}%{_mandir}/man7/pp.7
# copy unsupported tools
cp -L bin/atob \
bin/btoa \
bin/derdump \
bin/ocspclnt \
bin/pp \
bin/selfserv \
bin/shlibsign \
bin/strsclnt \
bin/symkeyutil \
bin/tstclnt \
bin/vfyserv \
bin/vfychain \
%{buildroot}%{_libexecdir}/nss
# prepare pkgconfig file
mkdir -p %{buildroot}%{_libdir}/pkgconfig/
sed "s:%%LIBDIR%%:%{_libdir}:g
s:%%VERSION%%:%{version}:g
s:%%NSPR_VERSION%%:%{nspr_ver}:g" \
%{SOURCE1} > %{buildroot}%{_libdir}/pkgconfig/nss.pc
sed "s:%%LIBDIR%%:%{_libdir}:g
s:%%VERSION%%:%{version}:g
s:%%NSPR_VERSION%%:%{nspr_ver}:g" \
%{SOURCE11} > %{buildroot}%{_libdir}/pkgconfig/nss-util.pc
# prepare nss-config file
popd
NSS_VMAJOR=`cat lib/nss/nss.h | grep "#define.*NSS_VMAJOR" | gawk '{print $3}'`
NSS_VMINOR=`cat lib/nss/nss.h | grep "#define.*NSS_VMINOR" | gawk '{print $3}'`
NSS_VPATCH=`cat lib/nss/nss.h | grep "#define.*NSS_VPATCH" | gawk '{print $3}'`
cat %{SOURCE3} | sed -e "s,@libdir@,%{_libdir},g" \
-e "s,@prefix@,%{_prefix},g" \
-e "s,@exec_prefix@,%{_prefix},g" \
-e "s,@includedir@,%{_includedir}/nss3,g" \
-e "s,@MOD_MAJOR_VERSION@,$NSS_VMAJOR,g" \
-e "s,@MOD_MINOR_VERSION@,$NSS_VMINOR,g" \
-e "s,@MOD_PATCH_VERSION@,$NSS_VPATCH,g" \
> %{buildroot}/%{_bindir}/nss-config
chmod 755 %{buildroot}/%{_bindir}/nss-config
NSSUTIL_VMAJOR=`cat lib/util/nssutil.h | grep "#define.*NSSUTIL_VMAJOR" | awk '{print $3}'`
NSSUTIL_VMINOR=`cat lib/util/nssutil.h | grep "#define.*NSSUTIL_VMINOR" | awk '{print $3}'`
NSSUTIL_VPATCH=`cat lib/util/nssutil.h | grep "#define.*NSSUTIL_VPATCH" | awk '{print $3}'`
cat %{SOURCE13} | sed -e "s,@libdir@,%{_libdir},g" \
-e "s,@prefix@,%{_prefix},g" \
-e "s,@exec_prefix@,%{_prefix},g" \
-e "s,@includedir@,%{_includedir}/nss3,g" \
-e "s,@MOD_MAJOR_VERSION@,$NSSUTIL_VMAJOR,g" \
-e "s,@MOD_MINOR_VERSION@,$NSSUTIL_VMINOR,g" \
-e "s,@MOD_PATCH_VERSION@,$NSSUTIL_VPATCH,g" \
> %{buildroot}/%{_bindir}/nss-util-config
chmod 755 %{buildroot}/%{_bindir}/nss-util-config
# setup-nsssysinfo.sh
install -m 744 %{SOURCE6} %{buildroot}%{_sbindir}/
# create empty NSS database
#LD_LIBRARY_PATH=%{buildroot}/%{_lib}:%{buildroot}%{_libdir} %{buildroot}%{_bindir}/modutil -force -dbdir "sql:%{buildroot}%{nssdbdir}" -create
#LD_LIBRARY_PATH=%{buildroot}/%{_lib}:%{buildroot}%{_libdir} %{buildroot}%{_bindir}/certutil -N -d "sql:%{buildroot}%{nssdbdir}" -f /dev/null 2>&1 > /dev/null
#chmod 644 "%{buildroot}%{nssdbdir}"/*
#sed "s:%{buildroot}::g
#s/^library=$/library=libnsssysinit.so/
#/^NSS/s/\(Flags=internal\)\(,[^m]\)/\1,moduleDBOnly\2/" \
# %{buildroot}%{nssdbdir}/pkcs11.txt > %{buildroot}%{nssdbdir}/pkcs11.txt.sed
# mv %{buildroot}%{nssdbdir}/pkcs11.txt{.sed,}
# copy empty NSS database
install -m 644 %{SOURCE7} %{buildroot}%{nssdbdir}
install -m 644 %{SOURCE8} %{buildroot}%{nssdbdir}
install -m 644 %{SOURCE9} %{buildroot}%{nssdbdir}
# create shlib sigs after extracting debuginfo with a hard-coded key to produce reproducible checksums, using the same key that openssl uses.
%define __spec_install_post \
%{?__debug_package:%{__debug_install_post}} \
%{__arch_install_post} \
%__os_install_post \
LD_LIBRARY_PATH=:%{buildroot}%{_libdir} %{buildroot}%{_libexecdir}/nss/shlibsign -K f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 -i %{buildroot}%{_libdir}/libsoftokn3.so \
LD_LIBRARY_PATH=:%{buildroot}%{_libdir} %{buildroot}%{_libexecdir}/nss/shlibsign -K f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 -i %{buildroot}%{_libdir}/libnssdbm3.so \
LD_LIBRARY_PATH=:%{buildroot}%{_libdir} %{buildroot}%{_libexecdir}/nss/shlibsign -K f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 -i %{buildroot}/%{_libdir}/libfreebl3.so \
LD_LIBRARY_PATH=:%{buildroot}%{_libdir} %{buildroot}%{_libexecdir}/nss/shlibsign -K f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 -i %{buildroot}/%{_libdir}/libfreeblpriv3.so \
%{nil}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%post -n libfreebl3 -p /sbin/ldconfig
%postun -n libfreebl3 -p /sbin/ldconfig
%post -n libsoftokn3 -p /sbin/ldconfig
%postun -n libsoftokn3 -p /sbin/ldconfig
%post sysinit
/sbin/ldconfig
# make sure the current config is enabled
%{_sbindir}/setup-nsssysinit.sh on
%preun sysinit
if [ $1 = 0 ]; then
%{_sbindir}/setup-nsssysinit.sh off
fi
%postun sysinit -p /sbin/ldconfig
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
%posttrans
update-crypto-policies &> /dev/null || :
%endif
%files
%{_libdir}/libnss3.so
%{_libdir}/libnssutil3.so
%{_libdir}/libsmime3.so
%{_libdir}/libssl3.so
%files devel
%defattr(644, root, root, 755)
%{_includedir}/nss3/
%{_libdir}/*.a
%{_libdir}/pkgconfig/*
%attr(755,root,root) %{_bindir}/nss-config
%attr(755,root,root) %{_bindir}/nss-util-config
%files tools
%{_bindir}/*
%exclude %{_sbindir}/setup-nsssysinit.sh
%{_libexecdir}/nss/
%{_mandir}/*/*
%exclude %{_bindir}/nss-config
%exclude %{_bindir}/nss-util-config
%files sysinit
%dir %{_sysconfdir}/pki
%dir %{_sysconfdir}/pki/nssdb
%config(noreplace) %{_sysconfdir}/pki/nssdb/*
%{_libdir}/libnsssysinit.so
%{_sbindir}/setup-nsssysinit.sh
%files -n libfreebl3
%{_libdir}/libfreebl3.so
%{_libdir}/libfreeblpriv3.so
%{_libdir}/libfreebl3.chk
%{_libdir}/libfreeblpriv3.chk
%files -n libsoftokn3
%{_libdir}/libsoftokn3.so
%{_libdir}/libnssdbm3.so
%{_libdir}/libsoftokn3.chk
%{_libdir}/libnssdbm3.chk
%files certs
%{_libdir}/libnssckbi.so
%changelog

3
nss-3.100.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1e35373ce9cb5b776f678bb341b0625c437520d09ebd91d1abd622e072e38d88
size 76746058

3
nss-3.101.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f20e8c5daafd89419d229ec8c54100a5c320dce1467377c9dfcd5e4d8446b468
size 76462490

3
nss-3.102.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:54982d3587e41579c94f2036ba084438b073f8456bbd873b7a942c057e9737cc
size 76460182

3
nss-3.103.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b4ab657f772dc7520c46e8d481940b292dcfc6a4c90150a7c26672384cee962
size 76470174

3
nss-3.105.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8e8e4c8c88ca5c828b207cfaf66c6188e7f96c97cc18946d3db7da4c0d395619
size 76620664

3
nss-3.106.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:026b744e1e0784b890c3846ac9506472a92138c1f4d41dec581949574c585c38
size 76621626

View File

@ -0,0 +1,13 @@
On s390x, this test takes more than 6 seconds (build log says 12 seconds)
--- nss/tests/dbtests/dbtests.sh.orig 2023-12-26 16:48:17.186506407 +0100
+++ nss/tests/dbtests/dbtests.sh 2023-12-26 16:49:13.323116874 +0100
@@ -367,7 +367,7 @@ dbtest_main()
TIMEARRAY=(${RARRAY[1]//./ })
echo "${TIMEARRAY[0]} seconds"
# Was 5, but that is too small for OBS-workers.
- test ${TIMEARRAY[0]} -lt 6
+ test ${TIMEARRAY[0]} -lt 15
ret=$?
html_msg ${ret} 0 "certutil dump keys with explicit default trust flags"
fi

View File

@ -0,0 +1,28 @@
Index: nss/tests/sdr/sdr.sh
===================================================================
--- nss.orig/tests/sdr/sdr.sh
+++ nss/tests/sdr/sdr.sh
@@ -146,7 +146,8 @@ sdr_main()
RARRAY=($dtime)
TIMEARRAY=(${RARRAY[1]//./ })
echo "${TIMEARRAY[0]} seconds"
- html_msg ${TIMEARRAY[0]} 0 "pwdecrypt no time regression"
+ # Suse 2022-10-04: Need more time for slow build servers
+ html_msg $(( ${TIMEARRAY[0]} >= 5 )) 0 "pwdecrypt no time regression"
export NSS_MAX_MP_PBE_ITERATION_COUNT=$OLD_MAX_PBE_ITERATIONS
}
Index: nss/tests/dbtests/dbtests.sh
===================================================================
--- nss.orig/tests/dbtests/dbtests.sh
+++ nss/tests/dbtests/dbtests.sh
@@ -366,7 +366,8 @@ dbtest_main()
RARRAY=($dtime)
TIMEARRAY=(${RARRAY[1]//./ })
echo "${TIMEARRAY[0]} seconds"
- test ${TIMEARRAY[0]} -lt 5
+ # Was 5, but that is too small for OBS-workers.
+ test ${TIMEARRAY[0]} -lt 6
ret=$?
html_msg ${ret} 0 "certutil dump keys with explicit default trust flags"
fi

341
nss-bmo1930797.patch Normal file
View File

@ -0,0 +1,341 @@
# HG changeset patch
# User Robert Relyea <rrelyea@redhat.com>
# Date 1731716524 28800
# Node ID 03e207e378dd37a87e172febb58012472611a78f
# Parent fe06bec77d445965548ee6f9d803bf8d035863c7
Bug 1930797 pkcs12 fixes from RHEL need to be picked up.
1. add ignore integrity option to pk12util
2. update pk12util manpage
a. with new ignore integrity option.
b. with the correct current defaults for pk12util.
3. don't include a fake iv in the param portion of the pbmac1.
4. restore the ability to decode md5 mac'ed pkcs12 files.
5. restore tests for bad pkcs12 encodings
Differential Revision: https://phabricator.services.mozilla.com/D229394
Index: nss/cmd/pk12util/pk12util.c
===================================================================
--- nss.orig/cmd/pk12util/pk12util.c
+++ nss/cmd/pk12util/pk12util.c
@@ -32,12 +32,12 @@ static void
Usage()
{
#define FPS PR_fprintf(PR_STDERR,
- FPS "Usage: %s -i importfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
+ FPS "Usage: %s -i importfile [-I] [-d certdir] [-P dbprefix] [-h tokenname]\n",
progName);
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
FPS "\t\t [-v]\n");
- FPS "Usage: %s -l listfile [-d certdir] [-P dbprefix] [-h tokenname]\n",
+ FPS "Usage: %s -l listfile [-I] [-d certdir] [-P dbprefix] [-h tokenname]\n",
progName);
FPS "\t\t [-k slotpwfile | -K slotpw] [-w p12filepwfile | -W p12filepw]\n");
FPS "\t\t [-v]\n");
@@ -351,7 +351,8 @@ P12U_InitSlot(PK11SlotInfo *slot, secuPW
*/
SEC_PKCS12DecoderContext *
p12U_ReadPKCS12File(SECItem *uniPwp, char *in_file, PK11SlotInfo *slot,
- secuPWData *slotPw, secuPWData *p12FilePw)
+ secuPWData *slotPw, secuPWData *p12FilePw,
+ PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
p12uContext *p12cxt = NULL;
@@ -458,7 +459,10 @@ p12U_ReadPKCS12File(SECItem *uniPwp, cha
/* rv has been set at this point */
done:
- if (rv != SECSuccess) {
+ /* if we are ignoring Integrity and we failed because we couldn't
+ * verify the integrity code, go ahead and succeed */
+ if (rv != SECSuccess && !(ignoreIntegrity &&
+ (pk12uErrno == PK12UERR_DECODEVERIFY))) {
if (p12dcx != NULL) {
SEC_PKCS12DecoderFinish(p12dcx);
p12dcx = NULL;
@@ -490,7 +494,8 @@ done:
*/
PRIntn
P12U_ImportPKCS12Object(char *in_file, PK11SlotInfo *slot,
- secuPWData *slotPw, secuPWData *p12FilePw)
+ secuPWData *slotPw, secuPWData *p12FilePw,
+ PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
SECItem uniPwitem = { 0 };
@@ -509,7 +514,8 @@ P12U_ImportPKCS12Object(char *in_file, P
do {
trypw = PR_FALSE; /* normally we do this once */
rv = SECFailure;
- p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
+ p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw,
+ p12FilePw, ignoreIntegrity);
if (p12dcx == NULL) {
goto loser;
@@ -777,14 +783,16 @@ loser:
PRIntn
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
- secuPWData *slotPw, secuPWData *p12FilePw)
+ secuPWData *slotPw, secuPWData *p12FilePw,
+ PRBool ignoreIntegrity)
{
SEC_PKCS12DecoderContext *p12dcx = NULL;
SECItem uniPwitem = { 0 };
SECStatus rv = SECFailure;
const SEC_PKCS12DecoderItem *dip;
- p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw);
+ p12dcx = p12U_ReadPKCS12File(&uniPwitem, in_file, slot, slotPw, p12FilePw,
+ ignoreIntegrity);
/* did the blob authenticate properly? */
if (p12dcx == NULL) {
SECU_PrintError(progName, "PKCS12 decode not verified");
@@ -997,7 +1005,8 @@ enum {
opt_CertCipher,
opt_KeyLength,
opt_CertKeyLength,
- opt_Mac
+ opt_Mac,
+ opt_IgnoreIntegrity
};
static secuCommandFlag pk12util_options[] = {
@@ -1018,7 +1027,8 @@ static secuCommandFlag pk12util_options[
{ /* opt_CertCipher */ 'C', PR_TRUE, 0, PR_FALSE },
{ /* opt_KeyLength */ 'm', PR_TRUE, 0, PR_FALSE, "key_len" },
{ /* opt_CertKeyLength */ 0, PR_TRUE, 0, PR_FALSE, "cert_key_len" },
- { /* opt_Mac */ 'M', PR_TRUE, 0, PR_FALSE, PR_FALSE }
+ { /* opt_Mac */ 'M', PR_TRUE, 0, PR_FALSE },
+ { /* opt_IgnoreIntegrity */ 'I', PR_FALSE, 0, PR_FALSE }
};
int
@@ -1039,6 +1049,7 @@ main(int argc, char **argv)
int certKeyLen = 0;
secuCommand pk12util;
PRInt32 forceUnicode;
+ PRBool ignoreIntegrity = PR_FALSE;
#ifdef _CRTDBG_MAP_ALLOC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
@@ -1113,6 +1124,9 @@ main(int argc, char **argv)
if (pk12util.options[opt_Raw].activated) {
dumpRawFile = PR_TRUE;
}
+ if (pk12util.options[opt_IgnoreIntegrity].activated) {
+ ignoreIntegrity = PR_TRUE;
+ }
if (pk12util.options[opt_KeyLength].activated) {
keyLen = atoi(pk12util.options[opt_KeyLength].arg);
}
@@ -1183,7 +1197,8 @@ main(int argc, char **argv)
}
if (pk12util.options[opt_Import].activated) {
- P12U_ImportPKCS12Object(import_file, slot, &slotPw, &p12FilePw);
+ P12U_ImportPKCS12Object(import_file, slot, &slotPw, &p12FilePw,
+ ignoreIntegrity);
} else if (pk12util.options[opt_Export].activated) {
P12U_ExportPKCS12Object(pk12util.options[opt_Nickname].arg,
@@ -1191,7 +1206,8 @@ main(int argc, char **argv)
hash, &slotPw, &p12FilePw);
} else if (pk12util.options[opt_List].activated) {
- P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw);
+ P12U_ListPKCS12File(import_file, slot, &slotPw, &p12FilePw,
+ ignoreIntegrity);
} else {
Usage();
Index: nss/doc/pk12util.xml
===================================================================
--- nss.orig/doc/pk12util.xml
+++ nss/doc/pk12util.xml
@@ -38,6 +38,7 @@
<arg>-P dbprefix</arg>
<arg>-r</arg>
<arg>-v</arg>
+ <arg>-I</arg>
<arg>--cert-key-len certKeyLength</arg>
<arg>-k slotPasswordFile|-K slotPassword</arg>
<arg>-w p12filePasswordFile|-W p12filePassword</arg>
@@ -147,6 +148,11 @@
</varlistentry>
<varlistentry>
+ <term>-I </term>
+ <listitem><para>Ignore integrity check results on importing and listing.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>-w p12filePasswordFile</term>
<listitem><para>Specify the text file containing the pkcs #12 file password.</para></listitem>
</varlistentry>
@@ -317,7 +323,7 @@ Certificate Friendly Name: Thawte Fre
<refsection id="encryption">
<title>Password Encryption</title>
- <para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using PKCS #12 SHA-1 and 3-key triple DES for private key encryption. When not in FIPS mode, PKCS #12 SHA-1 and 40-bit RC4 is used for certificate encryption. When in FIPS mode, there is no certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
+ <para>PKCS #12 provides for not only the protection of the private keys but also the certificate and meta-data associated with the keys. Password-based encryption is used to protect private keys on export to a PKCS #12 file and, optionally, the associated certificates. If no algorithm is specified, the tool defaults to using AES-256-CBC for private key encryption and AES-128-CBC for certificate encryption. If certificate encryption is not wanted, specify <userinput>"NONE"</userinput> as the argument of the <option>-C</option> option.</para>
<para>The private key is always protected with strong encryption by default.</para>
<para>Several types of ciphers are supported.</para>
<variablelist>
@@ -327,6 +333,7 @@ Certificate Friendly Name: Thawte Fre
<listitem>
<itemizedlist>
<listitem><para>PBES2 with AES-CBC-Pad as underlying encryption scheme (<userinput>"AES-128-CBC"</userinput>, <userinput>"AES-192-CBC"</userinput>, and <userinput>"AES-256-CBC"</userinput>)</para></listitem>
+ <listitem><para>PBES2 with CAMELLIA-CBC-Pad as underlying encryption scheme (<userinput>"CAMELLIA-128-CBC"</userinput>, <userinput>"CAMELLIA-192-CBC"</userinput>, and <userinput>"CAMELLIA-256-CBC"</userinput>)</para></listitem>
</itemizedlist>
</listitem>
</varlistentry>
Index: nss/lib/pk11wrap/pk11mech.c
===================================================================
--- nss.orig/lib/pk11wrap/pk11mech.c
+++ nss/lib/pk11wrap/pk11mech.c
@@ -1719,10 +1719,19 @@ PK11_ParamToAlgid(SECOidTag algTag, SECI
case CKM_JUNIPER_CBC128:
case CKM_JUNIPER_COUNTER:
case CKM_JUNIPER_SHUFFLE:
- newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
- SEC_ASN1_GET(SEC_OctetStringTemplate));
- if (newParams == NULL)
- break;
+ if (param && param->len > 0) {
+ newParams = SEC_ASN1EncodeItem(NULL, NULL, param,
+ SEC_ASN1_GET(SEC_OctetStringTemplate));
+ if (newParams == NULL)
+ break;
+ } else {
+ /* if no parameters have been supplied, then use NULL params
+ * The SECOID_SetAlgorithmID encoder will encode that as no
+ * params (since params are optional) or with an explicit NULL
+ * (for some historical cases where explicit NULL is expected).
+ */
+ newParams = NULL;
+ }
rv = SECSuccess;
break;
}
Index: nss/lib/pk11wrap/pk11pbe.c
===================================================================
--- nss.orig/lib/pk11wrap/pk11pbe.c
+++ nss/lib/pk11wrap/pk11pbe.c
@@ -770,9 +770,10 @@ sec_pkcs5CreateAlgorithmID(SECOidTag alg
algorithm = sec_pkcs5v2_get_pbe(cipherAlgorithm);
}
+ SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
+
/* set the PKCS5v2 specific parameters */
if (keyLength == 0) {
- SECOidTag hashAlg = HASH_GetHashOidTagByHMACOidTag(cipherAlgorithm);
if (hashAlg != SEC_OID_UNKNOWN) {
keyLength = HASH_ResultLenByOidTag(hashAlg);
} else {
@@ -787,18 +788,25 @@ sec_pkcs5CreateAlgorithmID(SECOidTag alg
prfAlg = SEC_OID_HMAC_SHA1;
}
- /* build the PKCS5v2 cipher algorithm id */
- cipherParams = pk11_GenerateNewParamWithKeyLen(
- PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
- if (!cipherParams) {
- goto loser;
+ /* build the PKCS5v2 cipher algorithm id, if cipher
+ * is an HMAC, the cipherParams should be NULL */
+ if (hashAlg == SEC_OID_UNKNOWN) {
+ cipherParams = pk11_GenerateNewParamWithKeyLen(
+ PK11_AlgtagToMechanism(cipherAlgorithm), keyLength);
+ if (!cipherParams) {
+ goto loser;
+ }
+ } else {
+ cipherParams = NULL;
}
PORT_Memset(&pbeV2_param, 0, sizeof(pbeV2_param));
rv = PK11_ParamToAlgid(cipherAlgorithm, cipherParams,
poolp, &pbeV2_param.cipherAlgId);
- SECITEM_FreeItem(cipherParams, PR_TRUE);
+ if (cipherParams) {
+ SECITEM_FreeItem(cipherParams, PR_TRUE);
+ }
if (rv != SECSuccess) {
goto loser;
}
Index: nss/lib/pkcs12/p12local.c
===================================================================
--- nss.orig/lib/pkcs12/p12local.c
+++ nss/lib/pkcs12/p12local.c
@@ -102,7 +102,7 @@ sec_pkcs12_integrity_key(PK11SlotInfo *s
*hmacMech = PK11_AlgtagToMechanism(hmacAlg);
/* pkcs12v2 hmac uses UTF8 rather than unicode */
if (!sec_pkcs12_convert_item_to_unicode(NULL, &utf8Pw, pwitem,
- PR_TRUE, PR_FALSE, PR_FALSE)) {
+ PR_FALSE, PR_FALSE, PR_FALSE)) {
return NULL;
}
symKey = PK11_PBEKeyGen(slot, prfAlgid, &utf8Pw, PR_FALSE, pwarg);
Index: nss/lib/util/nsshash.c
===================================================================
--- nss.orig/lib/util/nsshash.c
+++ nss/lib/util/nsshash.c
@@ -107,6 +107,9 @@ HASH_GetHashOidTagByHMACOidTag(SECOidTag
switch (hmacOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
+ case SEC_OID_HMAC_MD5:
+ hashOid = SEC_OID_MD5;
+ break;
case SEC_OID_HMAC_SHA1:
hashOid = SEC_OID_SHA1;
break;
@@ -150,6 +153,9 @@ HASH_GetHMACOidTagByHashOidTag(SECOidTag
switch (hashOid) {
/* no oid exists for HMAC_MD2 */
/* NSS does not define a oid for HMAC_MD4 */
+ case SEC_OID_MD5:
+ hmacOid = SEC_OID_HMAC_MD5;
+ break;
case SEC_OID_SHA1:
hmacOid = SEC_OID_HMAC_SHA1;
break;
Index: nss/tests/tools/tools.sh
===================================================================
--- nss.orig/tests/tools/tools.sh
+++ nss/tests/tools/tools.sh
@@ -541,21 +541,21 @@ tools_p12_import_pbmac1_samples()
html_msg $ret 0 "Importing private key pbmac1 hmac-sha-512 from PKCS#12 file"
check_tmpfile
- echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
- ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
+ echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I"
+ ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-iter.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
html_msg $ret 19 "Fail to list private key with bad iterator"
check_tmpfile
- echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
- ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
+ echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I"
+ ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-bad-salt.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
echo "Fail to list private key with bad salt val=$ret"
html_msg $ret 19 "Fail to import private key with bad salt"
check_tmpfile
- echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234'"
- ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' 2>&1
+ echo "${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I"
+ ${BINDIR}/pk12util -l ${TOOLSDIR}/data/pbmac1-invalid-no-length.p12 -d ${P_R_COPYDIR} -k ${R_PWFILE} -W '1234' -I 2>&1
ret=$?
echo "Fail to import private key with no length val=$ret"
html_msg $ret 19 "Fail to import private key with no length"

144
nss-config.in Normal file
View File

@ -0,0 +1,144 @@
#!/bin/sh
prefix=@prefix@
major_version=@MOD_MAJOR_VERSION@
minor_version=@MOD_MINOR_VERSION@
patch_version=@MOD_PATCH_VERSION@
usage()
{
cat <<EOF
Usage: nss-config [OPTIONS] [LIBRARIES]
Options:
[--prefix[=DIR]]
[--exec-prefix[=DIR]]
[--includedir[=DIR]]
[--libdir[=DIR]]
[--version]
[--libs]
[--cflags]
Dynamic Libraries:
nss
ssl
smime
EOF
exit $1
}
if test $# -eq 0; then
usage 1 1>&2
fi
lib_ssl=yes
lib_smime=yes
lib_nss=yes
lib_nssutil=yes
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
;;
--prefix)
echo_prefix=yes
;;
--exec-prefix=*)
exec_prefix=$optarg
;;
--exec-prefix)
echo_exec_prefix=yes
;;
--includedir=*)
includedir=$optarg
;;
--includedir)
echo_includedir=yes
;;
--libdir=*)
libdir=$optarg
;;
--libdir)
echo_libdir=yes
;;
--version)
echo ${major_version}.${minor_version}.${patch_version}
;;
--cflags)
echo_cflags=yes
;;
--libs)
echo_libs=yes
;;
ssl)
lib_ssl=yes
;;
smime)
lib_smime=yes
;;
nss)
lib_nss=yes
;;
nssutil)
lib_nssutil=yes
;;
*)
usage 1 1>&2
;;
esac
shift
done
# Set variables that may be dependent upon other variables
if test -z "$exec_prefix"; then
exec_prefix=@exec_prefix@
fi
if test -z "$includedir"; then
includedir=@includedir@
fi
if test -z "$libdir"; then
libdir=@libdir@
fi
if test "$echo_prefix" = "yes"; then
echo $prefix
fi
if test "$echo_exec_prefix" = "yes"; then
echo $exec_prefix
fi
if test "$echo_includedir" = "yes"; then
echo $includedir
fi
if test "$echo_libdir" = "yes"; then
echo $libdir
fi
if test "$echo_cflags" = "yes"; then
echo -I$includedir
fi
if test "$echo_libs" = "yes"; then
libdirs="-Wl,-rpath-link,$libdir -L$libdir"
if test -n "$lib_ssl"; then
libdirs="$libdirs -lssl${major_version}"
fi
if test -n "$lib_smime"; then
libdirs="$libdirs -lsmime${major_version}"
fi
if test -n "$lib_nss"; then
libdirs="$libdirs -lnss${major_version}"
fi
if test -n "$lib_nssutil"; then
libdirs="$libdirs -lnssutil${major_version}"
fi
echo $libdirs
fi

View File

@ -0,0 +1,40 @@
Index: nss/lib/freebl/pqg.c
===================================================================
--- nss.orig/lib/freebl/pqg.c
+++ nss/lib/freebl/pqg.c
@@ -1232,6 +1232,9 @@ cleanup:
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
+ if (rv != SECSuccess) {
+ mp_zero(G);
+ }
return rv;
}
Index: nss/lib/softoken/sftkdb.c
===================================================================
--- nss.orig/lib/softoken/sftkdb.c
+++ nss/lib/softoken/sftkdb.c
@@ -1538,7 +1538,7 @@ loser:
PORT_ZFree(data, dataSize);
}
if (arena) {
- PORT_FreeArena(arena, PR_FALSE);
+ PORT_FreeArena(arena, PR_TRUE);
}
return crv;
}
Index: nss/lib/softoken/sftkpwd.c
===================================================================
--- nss.orig/lib/softoken/sftkpwd.c
+++ nss/lib/softoken/sftkpwd.c
@@ -1459,7 +1459,7 @@ loser:
PORT_ZFree(newKey.data, newKey.len);
}
if (result) {
- SECITEM_FreeItem(result, PR_TRUE);
+ SECITEM_ZfreeItem(result, PR_TRUE);
}
if (rv != SECSuccess) {
(*keydb->db->sdb_Abort)(keydb->db);

View File

@ -0,0 +1,42 @@
Index: nss/lib/softoken/sftkmessage.c
===================================================================
--- nss.orig/lib/softoken/sftkmessage.c
+++ nss/lib/softoken/sftkmessage.c
@@ -183,6 +183,37 @@ sftk_CryptMessage(CK_SESSION_HANDLE hSes
if (crv != CKR_OK)
return crv;
+ if (context->isFIPS && (contextType == SFTK_MESSAGE_ENCRYPT)) {
+ if ((pParameter == NULL) || (ulParameterLen != sizeof(CK_GCM_MESSAGE_PARAMS))) {
+ context->isFIPS = PR_FALSE;
+ } else {
+ CK_GCM_MESSAGE_PARAMS *p = (CK_GCM_MESSAGE_PARAMS *)pParameter;
+ switch (p->ivGenerator) {
+ default:
+ case CKG_NO_GENERATE:
+ context->isFIPS = PR_FALSE;
+ break;
+ case CKG_GENERATE_RANDOM:
+ if ((p->ulIvLen < 96 / PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 0)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ case CKG_GENERATE_COUNTER_XOR:
+ if ((p->ulIvLen != 96 / PR_BITS_PER_BYTE) ||
+ (p->ulIvFixedBits != 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ break;
+ case CKG_GENERATE_COUNTER:
+ if ((p->ulIvFixedBits < 32) ||
+ ((p->ulIvLen * PR_BITS_PER_BYTE - p->ulIvFixedBits) < 32)) {
+ context->isFIPS = PR_FALSE;
+ }
+ }
+ }
+ }
+
if (!pOuttext) {
*pulOuttextLen = ulIntextLen;
return CKR_OK;

View File

@ -0,0 +1,130 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1589854460 -7200
# Tue May 19 04:14:20 2020 +0200
# Node ID ce99bba6375432c55a73c1367f619dfef7c7e9fc
# Parent 2c820431829b3e5c7e161bd0bf73b48def9d3822
commit e78f5a6a2124ce88002796d6aaefc6232f132526
Author: Hans Petter Jansson <hpj@cl.no>
AES Keywrap POST.
Index: nss/lib/freebl/fipsfreebl.c
===================================================================
--- nss.orig/lib/freebl/fipsfreebl.c
+++ nss/lib/freebl/fipsfreebl.c
@@ -113,6 +113,9 @@ DllMain(
#define FIPS_AES_192_KEY_SIZE 24 /* 192-bits */
#define FIPS_AES_256_KEY_SIZE 32 /* 256-bits */
+/* FIPS preprocessor directives for AES Keywrap */
+#define FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE 24 /* 192-bits */
+
/* FIPS preprocessor directives for message digests */
#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
@@ -292,6 +295,9 @@ freebl_fips_AES_PowerUpSelfTest(int aes_
static const PRUint8 aes_gcm_known_aad[] = { "MozillaallizoM" };
+ /* AES Keywrap Known Initialization Vector (64 bits) */
+ static const PRUint8 aes_key_wrap_iv[] = { "WrapparW" };
+
/* AES Known Ciphertext (128-bit key). */
static const PRUint8 aes_ecb128_known_ciphertext[] = {
0x3c, 0xa5, 0x96, 0xf3, 0x34, 0x6a, 0x96, 0xc1,
@@ -362,6 +368,25 @@ freebl_fips_AES_PowerUpSelfTest(int aes_
};
+ /* AES Keywrap Known Ciphertexts. */
+ static const PRUint8 aes_kw128_known_ciphertext[] = {
+ 0xd7, 0xec, 0x33, 0x3a, 0x35, 0x50, 0x91, 0x4d,
+ 0x04, 0x69, 0x1f, 0xbc, 0x9b, 0x3a, 0x51, 0x9d,
+ 0xf3, 0x45, 0x01, 0xec, 0xaa, 0x43, 0x33, 0x42
+ };
+
+ static const PRUint8 aes_kw192_known_ciphertext[] = {
+ 0x18, 0x44, 0xab, 0x72, 0xbd, 0x35, 0x6c, 0x8f,
+ 0x34, 0x34, 0x2e, 0x0b, 0xb0, 0x19, 0xd3, 0x46,
+ 0x3e, 0x53, 0x4f, 0x2f, 0x43, 0xcc, 0xf5, 0x8c
+ };
+
+ static const PRUint8 aes_kw256_known_ciphertext[] = {
+ 0x3e, 0xaf, 0xf3, 0x36, 0xaf, 0xc3, 0x68, 0xab,
+ 0x5a, 0x07, 0xed, 0x64, 0x5b, 0xf8, 0x81, 0x0d,
+ 0x9e, 0x67, 0x75, 0xbd, 0x66, 0xe1, 0x52, 0xdc
+ };
+
const PRUint8 *aes_ecb_known_ciphertext =
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_ecb128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_ecb192_known_ciphertext
: aes_ecb256_known_ciphertext;
@@ -378,11 +403,15 @@ freebl_fips_AES_PowerUpSelfTest(int aes_
(aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cmac128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cmac192_known_ciphertext
: aes_cmac256_known_ciphertext;
+ const PRUint8 *aes_keywrap_known_ciphertext =
+ (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_kw128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_kw192_known_ciphertext : aes_kw256_known_ciphertext;
+
/* AES variables. */
PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2];
PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2];
AESContext *aes_context;
CMACContext *cmac_context;
+ AESKeyWrapContext *aes_keywrap_context;
unsigned int aes_bytes_encrypted;
unsigned int aes_bytes_decrypted;
CK_NSS_GCM_PARAMS gcmParams;
@@ -608,6 +637,52 @@ freebl_fips_AES_PowerUpSelfTest(int aes_
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return (SECFailure);
}
+
+ /********************************/
+ /* AES Keywrap En/Decrypt Test. */
+ /********************************/
+
+ /* Create encryption context */
+ aes_keywrap_context = AESKeyWrap_CreateContext(aes_known_key, aes_key_wrap_iv, PR_TRUE,
+ aes_key_size);
+ if (aes_keywrap_context == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return (SECFailure);
+ }
+
+ aes_status = AESKeyWrap_Encrypt(aes_keywrap_context,
+ aes_computed_ciphertext, &aes_bytes_encrypted,
+ FIPS_AES_ENCRYPT_LENGTH * 2,
+ aes_known_plaintext, FIPS_AES_ENCRYPT_LENGTH);
+
+ AESKeyWrap_DestroyContext(aes_keywrap_context, PR_TRUE);
+
+ if ((aes_status != SECSuccess) ||
+ (aes_bytes_encrypted != FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE) ||
+ (PORT_Memcmp (aes_computed_ciphertext, aes_keywrap_known_ciphertext,
+ FIPS_AES_KEYWRAP_KNOWN_CIPHERTEXT_SIZE) != 0)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
+
+ /* Create decryption context */
+ aes_keywrap_context = AESKeyWrap_CreateContext(aes_known_key, aes_key_wrap_iv, PR_FALSE,
+ aes_key_size);
+
+ aes_status = AESKeyWrap_Decrypt(aes_keywrap_context,
+ aes_computed_plaintext, &aes_bytes_decrypted,
+ FIPS_AES_ENCRYPT_LENGTH,
+ aes_computed_ciphertext, aes_bytes_encrypted);
+
+ AESKeyWrap_DestroyContext(aes_keywrap_context, PR_TRUE);
+
+ if ((aes_status != SECSuccess) ||
+ (aes_bytes_decrypted != FIPS_AES_ENCRYPT_LENGTH) ||
+ (PORT_Memcmp (aes_computed_plaintext, aes_known_plaintext,
+ FIPS_AES_ENCRYPT_LENGTH) != 0)) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return (SECFailure);
+ }
return (SECSuccess);
}

File diff suppressed because it is too large Load Diff

19
nss-fips-bsc1223724.patch Normal file
View File

@ -0,0 +1,19 @@
Index: nss/lib/pk11wrap/pk11skey.c
===================================================================
--- nss.orig/lib/pk11wrap/pk11skey.c
+++ nss/lib/pk11wrap/pk11skey.c
@@ -521,6 +521,14 @@ PK11_ImportDataKey(PK11SlotInfo *slot, C
CK_OBJECT_HANDLE handle;
PK11GenericObject *genObject;
+ // Using HTTP3, Firefox runs via neqo that doesn't log in before calling into
+ // this function. So we try to log in here (and ignore failures) in case of FIPS.
+ // Also, no need to also load certificates, we only create a new object and we
+ // have to be logged in for that.
+ if (PK11_IsFIPS()) {
+ PK11_Authenticate(slot, PR_FALSE, wincx);
+ }
+
genObject = PK11_CreateGenericObject(slot, template, PR_ARRAY_SIZE(template), PR_FALSE);
if (genObject == NULL) {
return NULL;

View File

@ -0,0 +1,206 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574237264 -3600
# Wed Nov 20 09:07:44 2019 +0100
# Node ID 0e904e6179d1db21965df2c405c80c3fc0258658
# Parent 969310ea4c573aac64bf08846b8938b8fa783870
[PATCH] 24
From ef2620b770082c77dbbbccae2e773157897b005d Mon Sep 17 00:00:00 2001
---
nss/cmd/fipstest/fipstest.c | 112 ++++++++++++++++++++++++++++++++----
1 file changed, 101 insertions(+), 11 deletions(-)
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -5575,7 +5575,7 @@ loser:
void
dsa_pqggen_test(char *reqfn)
{
- char buf[800]; /* holds one line from the input REQUEST file
+ char buf[2048]; /* holds one line from the input REQUEST file
* or to the output RESPONSE file.
* 800 to hold seed = (384 public key (x2 for HEX)
*/
@@ -5591,6 +5591,13 @@ dsa_pqggen_test(char *reqfn)
PQGVerify *vfy = NULL;
unsigned int keySizeIndex = 0;
dsa_pqg_type type = FIPS186_1;
+ SECItem P = { 0, 0, 0 };
+ SECItem Q = { 0, 0, 0 };
+ SECItem firstseed = { 0, 0, 0 };
+ SECItem pseed = { 0, 0, 0 };
+ SECItem qseed = { 0, 0, 0 };
+ SECItem index = { 0, 0, 0 };
+ HASH_HashType hashtype = HASH_AlgNULL;
dsareq = fopen(reqfn, "r");
dsaresp = stdout;
@@ -5611,8 +5618,8 @@ dsa_pqggen_test(char *reqfn)
output_g = 1;
exit(1);
} else if (strncmp(&buf[1], "A.2.3", 5) == 0) {
- fprintf(stderr, "NSS only Generates G with P&Q\n");
- exit(1);
+ type = A_2_3;
+ output_g = 1;
} else if (strncmp(&buf[1], "A.1.2.1", 7) == 0) {
type = A_1_2_1;
output_g = 0;
@@ -5626,14 +5633,17 @@ dsa_pqggen_test(char *reqfn)
/* [Mod = ... ] */
if (buf[0] == '[') {
+ int hashbits;
if (type == FIPS186_1) {
N = 160;
if (sscanf(buf, "[mod = %d]", &L) != 1) {
goto loser;
}
- } else if (sscanf(buf, "[mod = L=%d, N=%d", &L, &N) != 2) {
+ } else if (sscanf(buf, "[mod = L=%d, N=%d, SHA-%d", &L, &N, &hashbits) != 3) {
goto loser;
+ } else {
+ hashtype = sha_get_hashType (hashbits);
}
fputs(buf, dsaresp);
@@ -5655,7 +5665,7 @@ dsa_pqggen_test(char *reqfn)
continue;
}
/* N = ... */
- if (buf[0] == 'N') {
+ if (buf[0] == 'N' && type != A_2_3) {
if (strncmp(buf, "Num", 3) == 0) {
if (sscanf(buf, "Num = %d", &count) != 1) {
goto loser;
@@ -5670,7 +5680,10 @@ dsa_pqggen_test(char *reqfn)
rv = PQG_ParamGenSeedLen(keySizeIndex, PQG_TEST_SEED_BYTES,
&pqg, &vfy);
} else {
- rv = PQG_ParamGenV2(L, N, N, &pqg, &vfy);
+ if (firstseed.data)
+ SECITEM_ZfreeItem(&firstseed, PR_FALSE);
+
+ rv = FREEBL_Test_PQG_ParamGenV2_p(L, N, 0, &pqg, &vfy, &firstseed, hashtype);
}
if (rv != SECSuccess) {
fprintf(dsaresp,
@@ -5681,6 +5694,10 @@ dsa_pqggen_test(char *reqfn)
fprintf(dsaresp, "P = %s\n", buf);
to_hex_str(buf, pqg->subPrime.data, pqg->subPrime.len);
fprintf(dsaresp, "Q = %s\n", buf);
+ if (firstseed.data) {
+ to_hex_str(buf, firstseed.data, firstseed.len);
+ fprintf(dsaresp, "firstseed = %s\n", buf);
+ }
if (output_g) {
to_hex_str(buf, pqg->base.data, pqg->base.len);
fprintf(dsaresp, "G = %s\n", buf);
@@ -5696,13 +5713,13 @@ dsa_pqggen_test(char *reqfn)
}
fprintf(dsaresp, "%s\n", buf);
} else {
- unsigned int seedlen = vfy->seed.len / 2;
- unsigned int pgen_counter = vfy->counter >> 16;
- unsigned int qgen_counter = vfy->counter & 0xffff;
+ unsigned int seedlen = (vfy->seed.len - firstseed.len) / 2;
+ unsigned int pgen_counter = vfy->counter & 0xffff;
+ unsigned int qgen_counter = vfy->counter >> 16;
/*fprintf(dsaresp, "index = %02x\n", vfy->h.data[0]); */
- to_hex_str(buf, vfy->seed.data, seedlen);
+ to_hex_str(buf, vfy->seed.data + firstseed.len, seedlen);
fprintf(dsaresp, "pseed = %s\n", buf);
- to_hex_str(buf, vfy->seed.data + seedlen, seedlen);
+ to_hex_str(buf, vfy->seed.data + firstseed.len + seedlen, seedlen);
fprintf(dsaresp, "qseed = %s\n", buf);
fprintf(dsaresp, "pgen_counter = %d\n", pgen_counter);
fprintf(dsaresp, "qgen_counter = %d\n", qgen_counter);
@@ -5722,12 +5739,85 @@ dsa_pqggen_test(char *reqfn)
vfy = NULL;
}
}
+ continue;
+ }
+
+ if (parse_secitem ("P", buf, &P)) {
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (parse_secitem ("Q", buf, &Q)) {
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (parse_secitem ("firstseed", buf, &firstseed)) {
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (parse_secitem ("pseed", buf, &pseed)) {
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (parse_secitem ("qseed", buf, &qseed)) {
+ fputs(buf, dsaresp);
+ continue;
+ }
+ if (parse_secitem ("index", buf, &index) && type == A_2_3) {
+ SECStatus rv;
+ PLArenaPool *arena;
+
+ fputs(buf, dsaresp);
+
+ arena = PORT_NewArena (NSS_FREEBL_DEFAULT_CHUNKSIZE);
+ pqg = (PQGParams *)PORT_ArenaZAlloc(arena, sizeof(PQGParams));
+ pqg->arena = arena;
+
+ arena = PORT_NewArena (NSS_FREEBL_DEFAULT_CHUNKSIZE);
+ vfy = (PQGVerify *)PORT_ArenaZAlloc(arena, sizeof(PQGVerify));
+ vfy->arena = arena;
+
+ SECITEM_CopyItem(pqg->arena, &pqg->prime, &P);
+ SECITEM_CopyItem(pqg->arena, &pqg->subPrime, &Q);
+
+ SECITEM_AllocItem(vfy->arena, &vfy->seed, firstseed.len + pseed.len + qseed.len);
+ memcpy (vfy->seed.data, firstseed.data, firstseed.len);
+ memcpy (vfy->seed.data + firstseed.len, pseed.data, pseed.len);
+ memcpy (vfy->seed.data + firstseed.len + pseed.len, qseed.data, qseed.len);
+
+ SECITEM_AllocItem(vfy->arena, &vfy->h, 1);
+ vfy->h.data [0] = index.data [0];
+
+ rv = FREEBL_Test_PQG_ParamGenV2_p(L, N, 0, &pqg, &vfy, &firstseed, hashtype);
+ if (rv != SECSuccess) {
+ fprintf(dsaresp,
+ "ERROR: Unable to verify PQG parameters");
+ goto loser;
+ }
+
+ to_hex_str(buf, pqg->base.data, pqg->base.len);
+ fprintf(dsaresp, "G = %s\n\n", buf);
+ PQG_DestroyParams(pqg);
+ pqg = NULL;
+ PQG_DestroyVerify(vfy);
+ vfy = NULL;
continue;
}
}
loser:
fclose(dsareq);
+ if (P.data)
+ SECITEM_ZfreeItem(&P, PR_FALSE);
+ if (Q.data)
+ SECITEM_ZfreeItem(&Q, PR_FALSE);
+ if (firstseed.data)
+ SECITEM_ZfreeItem(&firstseed, PR_FALSE);
+ if (pseed.data)
+ SECITEM_ZfreeItem(&pseed, PR_FALSE);
+ if (qseed.data)
+ SECITEM_ZfreeItem(&qseed, PR_FALSE);
+ if (index.data)
+ SECITEM_ZfreeItem(&index, PR_FALSE);
if (pqg != NULL) {
PQG_DestroyParams(pqg);
}

316
nss-fips-cavs-general.patch Normal file
View File

@ -0,0 +1,316 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1590413427 -7200
# Mon May 25 15:30:27 2020 +0200
# Node ID 969310ea4c573aac64bf08846b8938b8fa783870
# Parent 60c5e5d73ce1177fa66d8fd6cf49d9b371ca9be4
imported patch nss-fips-cavs-general.patch
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
+#include <dlfcn.h>
#include "secitem.h"
#include "blapi.h"
@@ -18,6 +19,9 @@
#include "lowkeyi.h"
#include "softoken.h"
#include "pkcs11t.h"
+
+#include "../../lib/freebl/fips.h"
+
#define __PASTE(x, y) x##y
#undef CK_PKCS11_FUNCTION_INFO
#undef CK_NEED_ARG_LIST
@@ -55,6 +59,10 @@ EC_CopyParams(PLArenaPool *arena, ECPara
#define RSA_MAX_TEST_EXPONENT_BYTES 8
#define PQG_TEST_SEED_BYTES 20
+SECStatus (*FREEBL_Test_PQG_ParamGenV2_p) (unsigned int L, unsigned int N, unsigned int seedBytes,
+ PQGParams **pParams, PQGVerify **pVfy,
+ SECItem *firstseed, HASH_HashType hashtype);
+
SECStatus
hex_to_byteval(const char *c2, unsigned char *byteval)
{
@@ -168,6 +176,62 @@ from_hex_str(unsigned char *buf, unsigne
return PR_TRUE;
}
+#if 0
+
+static void
+dump_secitem (FILE *out, SECItem *secitem)
+{
+ char buf [4096];
+
+ to_hex_str(buf, secitem->data, secitem->len);
+ fputs (buf, out);
+}
+
+static void
+dump_labeled_secitem (FILE *out, const char *name, SECItem *secitem)
+{
+ fprintf (out, "%s = ", name);
+ dump_secitem (out, secitem);
+ fputs ("\n", out);
+}
+
+#endif
+
+static int
+parse_secitem (const char *name, const char *buf, SECItem *secitem)
+{
+ if (!strncmp (buf, name, strlen (name))) {
+ int i, j, len;
+
+ i = strlen (name);
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ len = strspn (&buf[i], "0123456789abcdefABCDEF");
+ if (!len)
+ return 0;
+
+ if (secitem->data) {
+ SECITEM_ZfreeItem(secitem, PR_FALSE);
+ secitem->data = NULL;
+ }
+
+ len = (len + 1) / 2;
+ SECITEM_AllocItem(NULL, secitem, len);
+ secitem->len = len;
+
+ memset(secitem->data, 0, secitem->len);
+ for (j = 0; j < secitem->len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &secitem->data[j]);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
SECStatus
tdea_encrypt_buf(
int mode,
@@ -8915,41 +8979,6 @@ out:
}
}
-static int
-parse_secitem (const char *name, const char *buf, SECItem *secitem)
-{
- if (!strncmp (buf, name, strlen (name))) {
- int i, j, len;
-
- i = strlen (name);
- while (isspace(buf[i]) || buf[i] == '=') {
- i++;
- }
-
- len = strspn (&buf[i], "0123456789abcdefABCDEF");
- if (!len)
- return 0;
-
- if (secitem->data) {
- SECITEM_ZfreeItem(secitem, PR_FALSE);
- secitem->data = NULL;
- }
-
- len = (len + 1) / 2;
- SECITEM_AllocItem(NULL, secitem, len);
- secitem->len = len;
-
- memset(secitem->data, 0, secitem->len);
- for (j = 0; j < secitem->len; i += 2, j++) {
- hex_to_byteval(&buf[i], &secitem->data[j]);
- }
-
- return 1;
- }
-
- return 0;
-}
-
void
kas_ffc_test(char *reqfn, int do_validity)
{
@@ -9372,12 +9401,34 @@ out:
free_param_specs (pspecs);
}
+static void
+init_functions (void)
+{
+ void *freebl_so;
+
+ freebl_so = dlopen ("libfreeblpriv3.so", RTLD_LAZY);
+ if (freebl_so == NULL)
+ {
+ fprintf (stderr, "Failed to load libfreeblpriv3.so.");
+ exit (1);
+ }
+
+ FREEBL_Test_PQG_ParamGenV2_p = dlsym (freebl_so, "FREEBL_Test_PQG_ParamGenV2");
+
+ if (FREEBL_Test_PQG_ParamGenV2_p == NULL)
+ {
+ fprintf (stderr, "Failed to bind FREEBL_TEST_PQG_ParamGenV2.");
+ exit (1);
+ }
+}
+
int
main(int argc, char **argv)
{
if (argc < 2)
exit(-1);
+ init_functions();
RNG_RNGInit();
SECOID_Init();
Index: nss/lib/freebl/freebl.def
===================================================================
--- nss.orig/lib/freebl/freebl.def
+++ nss/lib/freebl/freebl.def
@@ -21,6 +21,7 @@
LIBRARY freebl3 ;-
EXPORTS ;-
FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
;+ local:
;+ *;
;+};
Index: nss/lib/freebl/freebl_hash.def
===================================================================
--- nss.orig/lib/freebl/freebl_hash.def
+++ nss/lib/freebl/freebl_hash.def
@@ -21,6 +21,7 @@
LIBRARY freebl3 ;-
EXPORTS ;-
FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
;+ local:
;+ *;
;+};
Index: nss/lib/freebl/freebl_hash_vector.def
===================================================================
--- nss.orig/lib/freebl/freebl_hash_vector.def
+++ nss/lib/freebl/freebl_hash_vector.def
@@ -21,6 +21,7 @@
LIBRARY freebl3 ;-
EXPORTS ;-
FREEBL_GetVector;
+FREEBL_Test_PQG_ParamGenV2;
;+ local:
;+ *;
;+};
Index: nss/lib/freebl/pqg.c
===================================================================
--- nss.orig/lib/freebl/pqg.c
+++ nss/lib/freebl/pqg.c
@@ -1242,7 +1242,8 @@ cleanup:
**/
static SECStatus
pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
- unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy)
+ unsigned int seedBytes, PQGParams **pParams, PQGVerify **pVfy,
+ SECItem *firstseed_out, HASH_HashType hashtype)
{
unsigned int n; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
unsigned int seedlen; /* Per FIPS 186-3 app A.1.1.2 (was 'g' 186-1)*/
@@ -1250,7 +1251,6 @@ pqg_ParamGen(unsigned int L, unsigned in
unsigned int offset; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
unsigned int outlen; /* Per FIPS 186-3, appendix A.1.1.2. */
unsigned int maxCount;
- HASH_HashType hashtype = HASH_AlgNULL;
SECItem *seed; /* Per FIPS 186, app 2.2. 186-3 app A.1.1.2 */
PLArenaPool *arena = NULL;
PQGParams *params = NULL;
@@ -1301,7 +1301,8 @@ pqg_ParamGen(unsigned int L, unsigned in
/* fill in P Q, */
SECITEM_TO_MPINT((*pParams)->prime, &P);
SECITEM_TO_MPINT((*pParams)->subPrime, &Q);
- hashtype = getFirstHash(L, N);
+ if (hashtype == HASH_AlgNULL)
+ hashtype = getFirstHash(L, N);
CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &(*pVfy)->seed,
(*pVfy)->h.data[0], &G));
MPINT_TO_SECITEM(&G, &(*pParams)->base, (*pParams)->arena);
@@ -1341,7 +1342,8 @@ pqg_ParamGen(unsigned int L, unsigned in
/* Select Hash and Compute lengths. */
/* getFirstHash gives us the smallest acceptable hash for this key
* strength */
- hashtype = getFirstHash(L, N);
+ if (hashtype == HASH_AlgNULL)
+ hashtype = getFirstHash(L, N);
outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE;
/* Step 3: n = Ceil(L/outlen)-1; (same as n = Floor((L-1)/outlen)) */
@@ -1543,6 +1545,10 @@ generate_G:
verify->counter = counter;
*pParams = params;
*pVfy = verify;
+
+ if (firstseed_out)
+ SECITEM_CopyItem (NULL, firstseed_out, &firstseed);
+
cleanup:
if (pseed.data) {
SECITEM_ZfreeItem(&pseed, PR_FALSE);
@@ -1587,7 +1593,7 @@ PQG_ParamGen(unsigned int j, PQGParams *
L = 512 + (j * 64); /* bits in P */
seedBytes = L / 8;
return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
- pParams, pVfy);
+ pParams, pVfy, NULL, HASH_AlgNULL);
}
SECStatus
@@ -1602,7 +1608,7 @@ PQG_ParamGenSeedLen(unsigned int j, unsi
}
L = 512 + (j * 64); /* bits in P */
return pqg_ParamGen(L, DSA1_Q_BITS, FIPS186_1_TYPE, seedBytes,
- pParams, pVfy);
+ pParams, pVfy, NULL, HASH_AlgNULL);
}
SECStatus
@@ -1620,7 +1626,26 @@ PQG_ParamGenV2(unsigned int L, unsigned
/* error code already set */
return SECFailure;
}
- return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy);
+ return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy, NULL, HASH_AlgNULL);
+}
+
+SECStatus
+FREEBL_Test_PQG_ParamGenV2 (unsigned int L, unsigned int N, unsigned int seedBytes,
+ PQGParams **pParams, PQGVerify **pVfy, SECItem *firstseed_out,
+ HASH_HashType hashtype)
+{
+ if (N == 0) {
+ N = pqg_get_default_N(L);
+ }
+ if (seedBytes == 0) {
+ /* seedBytes == L/8 for probable primes, N/8 for Shawe-Taylor Primes */
+ seedBytes = N / 8;
+ }
+ if (pqg_validate_dsa2(L, N) != SECSuccess) {
+ /* error code already set */
+ return SECFailure;
+ }
+ return pqg_ParamGen(L, N, FIPS186_3_ST_TYPE, seedBytes, pParams, pVfy, firstseed_out, hashtype);
}
/*

372
nss-fips-cavs-kas-ecc.patch Normal file
View File

@ -0,0 +1,372 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574234615 -3600
# Wed Nov 20 08:23:35 2019 +0100
# Node ID f5cf5d16deb68e65b5dd4e799d9e8e3098400d62
# Parent af7d3ee4e96cf685be0b95dff7aa5a1d3ab64a89
[PATCH] 21
From 4c27df62aa425745620f45710465b0264acacbb0 Mon Sep 17 00:00:00 2001
---
nss/cmd/fipstest/fipstest.c | 304 ++++++++++++++++++++++++++++++++++++
nss/cmd/fipstest/kas.sh | 22 +++
2 files changed, 326 insertions(+)
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -9077,6 +9077,301 @@ out:
}
}
+typedef struct
+{
+ char param_name [2];
+ ECParams *ecparams;
+ int hash_len;
+ HASH_HashType hash_type;
+}
+ParamSpec;
+
+#define PARAM_SPECS_MAX 12
+
+static int
+find_free_param_spec (const ParamSpec *pspecs)
+{
+ int i;
+
+ for (i = 0; i < PARAM_SPECS_MAX; i++)
+ {
+ if (pspecs [i].param_name [0] == 0
+ && pspecs [i].param_name [1] == 0)
+ return i;
+ }
+
+ return 0;
+}
+
+static int
+find_param_spec (const ParamSpec *pspecs, char *name)
+{
+ int i;
+
+ for (i = 0; i < PARAM_SPECS_MAX; i++)
+ {
+ if (pspecs [i].param_name [0] == name [0]
+ && pspecs [i].param_name [1] == name [1])
+ return i;
+ }
+
+ return 0;
+}
+
+static void
+free_param_specs (ParamSpec *pspecs)
+{
+ int i;
+
+ for (i = 0; i < PARAM_SPECS_MAX; i++)
+ {
+ if (pspecs [i].ecparams)
+ PORT_FreeArena(pspecs [i].ecparams->arena, PR_FALSE);
+ }
+}
+
+#define CURVE_NAME_MAX 64
+
+static ECParams *
+get_and_decode_nistp_params (int n)
+{
+ char curve_name [CURVE_NAME_MAX];
+ SECItem *encodedparams;
+ ECParams *ecparams = NULL;
+
+ snprintf (curve_name, CURVE_NAME_MAX, "nistp%d", n);
+
+ encodedparams = getECParams (curve_name);
+ if (!encodedparams)
+ return NULL;
+
+ EC_DecodeParams (encodedparams, &ecparams);
+ SECITEM_FreeItem(encodedparams, PR_TRUE);
+ return ecparams;
+}
+
+void
+kas_ecc_test(char *reqfn, int do_validity)
+{
+ char buf[2048];
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ ParamSpec pspecs [PARAM_SPECS_MAX];
+ SECItem x_ephem_cavs;
+ SECItem y_ephem_cavs;
+ SECItem x_ephem_iut;
+ SECItem y_ephem_iut;
+ SECItem d_ephem_iut;
+ SECItem cavs_hash_zz;
+ SECItem publicValue;
+ int current_pspec_def = -1;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ memset(&pspecs, 0, sizeof (pspecs));
+ memset(&x_ephem_cavs, 0, sizeof(x_ephem_cavs));
+ memset(&y_ephem_cavs, 0, sizeof(y_ephem_cavs));
+ memset(&x_ephem_iut, 0, sizeof(x_ephem_iut));
+ memset(&y_ephem_iut, 0, sizeof(y_ephem_iut));
+ memset(&d_ephem_iut, 0, sizeof(d_ephem_iut));
+ memset(&cavs_hash_zz, 0, sizeof(cavs_hash_zz));
+ memset(&publicValue, 0, sizeof(publicValue));
+
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* [xx] or
+ * [xx - SHAxxx] or
+ * [SHA(s) supported (Used for hashing Z): SHAxxx] */
+ if (buf[0] == '[') {
+ char tbuf [2];
+ int num;
+
+ if (strlen (buf) >= 4 && buf [3] == ']'
+ && sscanf(buf, "[%c%c]", &tbuf [0], &tbuf [1]) == 2) {
+ int i = current_pspec_def = find_free_param_spec (pspecs);
+ if (i < 0)
+ goto out;
+
+ pspecs [i].param_name [0] = tbuf [0];
+ pspecs [i].param_name [1] = tbuf [1];
+
+ fputs(buf, resp);
+ continue;
+ }
+
+ if (strlen (buf) >= 6 && buf [3] == ' ' && buf [4] == '-'
+ && sscanf(buf, "[%c%c - ", &tbuf [0], &tbuf [1]) == 2) {
+ current_pspec_def = find_param_spec (pspecs, tbuf);
+ if (current_pspec_def < 0)
+ goto out;
+
+ fputs(buf, resp);
+ continue;
+ }
+
+ if (!strncmp(buf, "[Curve selected:", strlen ("[Curve selected:"))) {
+ char *p = buf + strlen ("[Curve selected:");
+ p += strcspn (p, "0123456789");
+ if (!*p)
+ goto out;
+ if (sscanf(p, "%d", &num) != 1)
+ goto out;
+
+ if (current_pspec_def < 0)
+ goto out;
+
+ pspecs [current_pspec_def].ecparams = get_and_decode_nistp_params (num);
+ if (!pspecs [current_pspec_def].ecparams)
+ goto out;
+
+ fputs(buf, resp);
+ continue;
+ }
+
+ if (sscanf(buf, "[SHA(s) supported (Used for hashing Z): SHA%d", &num) == 1) {
+ if (current_pspec_def < 0)
+ goto out;
+
+ pspecs [current_pspec_def].hash_len = num;
+ pspecs [current_pspec_def].hash_type = sha_get_hashType(num);
+ fputs(buf, resp);
+ continue;
+ }
+
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("QeCAVSx", buf, &x_ephem_cavs)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("QeCAVSy", buf, &y_ephem_cavs)) {
+ fputs(buf, resp);
+
+ if (!do_validity) {
+ SECItem ZZ;
+ unsigned char ZZ_hash_buf [1024];
+ int field_len;
+ int len;
+ ECPrivateKey *privKey;
+
+ field_len = (pspecs [current_pspec_def].ecparams->fieldID.size + 7) >> 3;
+
+ if (EC_NewKey(pspecs [current_pspec_def].ecparams, &privKey) != SECSuccess)
+ goto out;
+
+ len = privKey->publicValue.len;
+ if (len % 2 == 0) {
+ goto out;
+ }
+ len = (len - 1) / 2;
+ if (privKey->publicValue.data[0] !=
+ EC_POINT_FORM_UNCOMPRESSED) {
+ goto out;
+ }
+
+ to_hex_str(buf, &privKey->publicValue.data[1], len);
+ fprintf (resp, "QeIUTx = %s\n", buf);
+ to_hex_str(buf, &privKey->publicValue.data[1 + len], len);
+ fprintf (resp, "QeIUTy = %s\n", buf);
+
+ SECITEM_AllocItem(NULL, &publicValue, 1 + 2 * field_len);
+ publicValue.len = 1 + 2 * field_len;
+ publicValue.data [0] = EC_POINT_FORM_UNCOMPRESSED;
+ memcpy (&publicValue.data [1], x_ephem_cavs.data + x_ephem_cavs.len - field_len, field_len);
+ memcpy (&publicValue.data [1 + field_len], y_ephem_cavs.data + y_ephem_cavs.len - field_len, field_len);
+
+ if (ECDH_Derive (&publicValue, pspecs [current_pspec_def].ecparams, &privKey->privateValue, PR_TRUE, &ZZ) != SECSuccess) {
+ goto out;
+ }
+
+ SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+ publicValue.data = NULL;
+
+ fips_hashBuf_zeropad(pspecs [current_pspec_def].hash_type, ZZ_hash_buf, ZZ.data, ZZ.len, len);
+
+ to_hex_str(buf, ZZ_hash_buf, pspecs [current_pspec_def].hash_len / 8);
+ fprintf (resp, "HashZZ = %s\n", buf);
+
+ PORT_FreeArena(privKey->ecParams.arena, PR_TRUE);
+ }
+
+ continue;
+ } else if (parse_secitem ("deIUT", buf, &d_ephem_iut)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("QeIUTx", buf, &x_ephem_iut)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("QeIUTy", buf, &y_ephem_iut)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("CAVSHashZZ", buf, &cavs_hash_zz)) {
+ if (do_validity) {
+ SECItem ZZ;
+ unsigned char ZZ_hash_buf [1024];
+ char Z_buf [1024];
+ int field_len;
+
+ field_len = (pspecs [current_pspec_def].ecparams->fieldID.size + 7) >> 3;
+
+ SECITEM_AllocItem(NULL, &publicValue, 1 + 2 * field_len);
+ publicValue.len = 1 + 2 * field_len;
+ publicValue.data [0] = EC_POINT_FORM_UNCOMPRESSED;
+ memcpy (&publicValue.data [1], x_ephem_cavs.data + x_ephem_cavs.len - field_len, field_len);
+ memcpy (&publicValue.data [1 + field_len], y_ephem_cavs.data + y_ephem_cavs.len - field_len, field_len);
+
+ if (ECDH_Derive (&publicValue, pspecs [current_pspec_def].ecparams, &d_ephem_iut, PR_TRUE, &ZZ) != SECSuccess) {
+ goto out;
+ }
+
+ SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+ publicValue.data = NULL;
+
+ fputs(buf, resp);
+
+ fips_hashBuf_zeropad(pspecs [current_pspec_def].hash_type, ZZ_hash_buf, ZZ.data, ZZ.len, field_len);
+ to_hex_str(Z_buf, ZZ_hash_buf, pspecs [current_pspec_def].hash_len / 8);
+ fprintf(resp, "IUTHashZZ = %s\n", Z_buf);
+
+ fprintf(resp, "Result = %s\n",
+ (cavs_hash_zz.len == pspecs [current_pspec_def].hash_len / 8
+ && memcmp (cavs_hash_zz.data, ZZ_hash_buf, pspecs [current_pspec_def].hash_len / 8) == 0) ? "P" : "F");
+ } else {
+ fputs(buf, resp);
+ }
+ continue;
+ } else {
+ /* Comments, blank lines, ... */
+ fputs(buf, resp);
+ }
+ }
+
+out:
+ fclose(req);
+
+ if (d_ephem_iut.data) {
+ SECITEM_ZfreeItem(&d_ephem_iut, PR_FALSE);
+ }
+ if (x_ephem_iut.data) {
+ SECITEM_ZfreeItem(&x_ephem_iut, PR_FALSE);
+ }
+ if (y_ephem_iut.data) {
+ SECITEM_ZfreeItem(&y_ephem_iut, PR_FALSE);
+ }
+ if (x_ephem_cavs.data) {
+ SECITEM_ZfreeItem(&x_ephem_cavs, PR_FALSE);
+ }
+ if (y_ephem_cavs.data) {
+ SECITEM_ZfreeItem(&y_ephem_cavs, PR_FALSE);
+ }
+ if (cavs_hash_zz.data) {
+ SECITEM_ZfreeItem(&cavs_hash_zz, PR_FALSE);
+ }
+ if (publicValue.data) {
+ SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+ }
+
+ free_param_specs (pspecs);
+}
+
int
main(int argc, char **argv)
{
@@ -9272,6 +9567,15 @@ main(int argc, char **argv)
} else {
kas_ffc_test(argv[3], PR_FALSE);
}
+ } else if (strcmp(argv[1], "kasecc") == 0) {
+ /***************/
+ /* KAS ECC */
+ /***************/
+ if (strcmp(argv[2], "validity") == 0) {
+ kas_ecc_test(argv[3], PR_TRUE);
+ } else {
+ kas_ecc_test(argv[3], PR_FALSE);
+ }
}
return 0;
}
Index: nss/cmd/fipstest/kas.sh
===================================================================
--- nss.orig/cmd/fipstest/kas.sh
+++ nss/cmd/fipstest/kas.sh
@@ -27,6 +27,16 @@ KASValidityTest_FFCEphem_NOKC_ZZOnly_ini
KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
"
+kas_requests_ecc_function="
+KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
+KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
+"
+
+kas_requests_ecc_validity="
+KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req
+KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req
+"
+
if [ ${COMMAND} = "verify" ]; then
for request in $kas_requests; do
sh ./validate1.sh ${TESTDIR} $request
@@ -45,3 +55,15 @@ for request in $kas_requests_ffc_validit
echo $request $response
fipstest kasffc validity ${REQDIR}/$request > ${RSPDIR}/$response
done
+
+for request in $kas_requests_ecc_function; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest kasecc function ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
+for request in $kas_requests_ecc_validity; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest kasecc validity ${REQDIR}/$request > ${RSPDIR}/$response
+done

285
nss-fips-cavs-kas-ffc.patch Normal file
View File

@ -0,0 +1,285 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574234297 -3600
# Wed Nov 20 08:18:17 2019 +0100
# Node ID af7d3ee4e96cf685be0b95dff7aa5a1d3ab64a89
# Parent 5d6e015d1af40b5f5b990d0cf4d97932774c2a61
[PATCH] 20
From ac98082c3bc0c9f85213078b730980483062f25c Mon Sep 17 00:00:00 2001
---
nss/cmd/fipstest/fipstest.c | 194 ++++++++++++++++++++++++++++++++++++
nss/cmd/fipstest/kas.sh | 47 +++++++++
2 files changed, 241 insertions(+)
create mode 100644 nss/cmd/fipstest/kas.sh
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -2257,6 +2257,29 @@ fips_hashBuf(HASH_HashType type, unsigne
return rv;
}
+SECStatus
+fips_hashBuf_zeropad(HASH_HashType type, unsigned char *hashBuf,
+ unsigned char *msg, int len, int pad_to_len)
+{
+ unsigned char buf [8192];
+
+ if (pad_to_len > 8192)
+ {
+ fprintf (stderr, "Internal buffer too small.\n");
+ exit (1);
+ }
+
+ if (len > pad_to_len)
+ {
+ fprintf (stderr, "Value to hash exceeds maximum length.\n");
+ exit (1);
+ }
+
+ memset (buf, 0, pad_to_len - len);
+ memcpy (buf + (pad_to_len - len), msg, len);
+ return fips_hashBuf (type, hashBuf, buf, pad_to_len);
+}
+
int
fips_hashLen(HASH_HashType type)
{
@@ -8892,6 +8915,168 @@ out:
}
}
+static int
+parse_secitem (const char *name, const char *buf, SECItem *secitem)
+{
+ if (!strncmp (buf, name, strlen (name))) {
+ int i, j, len;
+
+ i = strlen (name);
+ while (isspace(buf[i]) || buf[i] == '=') {
+ i++;
+ }
+
+ len = strspn (&buf[i], "0123456789abcdefABCDEF");
+ if (!len)
+ return 0;
+
+ if (secitem->data) {
+ SECITEM_ZfreeItem(secitem, PR_FALSE);
+ secitem->data = NULL;
+ }
+
+ len = (len + 1) / 2;
+ SECITEM_AllocItem(NULL, secitem, len);
+ secitem->len = len;
+
+ memset(secitem->data, 0, secitem->len);
+ for (j = 0; j < secitem->len; i += 2, j++) {
+ hex_to_byteval(&buf[i], &secitem->data[j]);
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+kas_ffc_test(char *reqfn, int do_validity)
+{
+ char buf[1024];
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ PQGParams keyParams;
+ HASH_HashType hashType = HASH_AlgNULL;
+ int hashNum = 0;
+ SECItem y_ephem_cavs;
+ SECItem x_ephem_iut;
+ SECItem y_ephem_iut;
+ SECItem cavs_hash_zz;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+ memset(&keyParams, 0, sizeof(keyParams));
+ memset(&y_ephem_cavs, 0, sizeof(y_ephem_cavs));
+ memset(&x_ephem_iut, 0, sizeof(x_ephem_iut));
+ memset(&y_ephem_iut, 0, sizeof(y_ephem_iut));
+ memset(&cavs_hash_zz, 0, sizeof(cavs_hash_zz));
+
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* [xx] or
+ * [xx - SHAxxx] or
+ * [SHA(s) supported (Used for hashing Z): SHAxxx] */
+ if (buf[0] == '[') {
+ unsigned char tbuf [2];
+
+ if (sscanf(buf, "[%c%c - SHA%d]", &tbuf [0], &tbuf [1],
+ &hashNum) != 3) {
+ fputs(buf, resp);
+ continue;
+ }
+
+ fputs(buf, resp);
+
+ hashType = sha_get_hashType(hashNum);
+ if (hashType == HASH_AlgNULL) {
+ fprintf(resp, "ERROR: invalid hash (SHA-%d)", hashNum);
+ goto out;
+ }
+
+ continue;
+ } else if (parse_secitem ("YephemCAVS", buf, &y_ephem_cavs)) {
+ fputs(buf, resp);
+
+ if (!do_validity) {
+ SECItem ZZ;
+ unsigned char ZZ_hash_buf [1024];
+ DHParams dh_params;
+ DHPrivateKey *dh_privKey;
+
+ dh_params.prime = keyParams.prime;
+ dh_params.base = keyParams.base;
+
+ DH_NewKey (&dh_params, &dh_privKey);
+ DH_Derive(&y_ephem_cavs, &keyParams.prime, &dh_privKey->privateValue, &ZZ, 0);
+
+ fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, keyParams.prime.len);
+
+ to_hex_str(buf, dh_privKey->publicValue.data, dh_privKey->publicValue.len);
+ fprintf(resp, "YephemIUT = %s\n", buf);
+
+ to_hex_str(buf, ZZ_hash_buf, hashNum / 8);
+ fprintf(resp, "HashZZ = %s\n", buf);
+
+ PORT_FreeArena(dh_privKey->arena, PR_TRUE);
+ }
+
+ continue;
+ } else if (parse_secitem ("XephemIUT", buf, &x_ephem_iut)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("YephemIUT", buf, &y_ephem_iut)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("CAVSHashZZ", buf, &cavs_hash_zz)) {
+ if (do_validity) {
+ SECItem ZZ;
+ unsigned char ZZ_hash_buf [1024];
+ char Z_buf [1024];
+
+ DH_Derive(&y_ephem_cavs, &keyParams.prime, &x_ephem_iut, &ZZ, 0);
+
+ fputs(buf, resp);
+
+ to_hex_str(Z_buf, ZZ.data, ZZ.len);
+
+ fips_hashBuf_zeropad(hashType, ZZ_hash_buf, ZZ.data, ZZ.len, keyParams.prime.len);
+ to_hex_str(Z_buf, ZZ_hash_buf, hashNum / 8);
+ fprintf(resp, "IUTHashZZ = %s\n", Z_buf);
+
+ fprintf(resp, "Result = %s\n",
+ (cavs_hash_zz.len == hashNum / 8 && memcmp (cavs_hash_zz.data, ZZ_hash_buf, hashNum / 8) == 0) ? "P" : "F");
+ } else {
+ fputs(buf, resp);
+ }
+ continue;
+ } else if (parse_secitem ("P", buf, &keyParams.prime)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("Q", buf, &keyParams.subPrime)) {
+ fputs(buf, resp);
+ continue;
+ } else if (parse_secitem ("G", buf, &keyParams.base)) {
+ fputs(buf, resp);
+ continue;
+ } else {
+ /* Comments, blank lines, ... */
+ fputs(buf, resp);
+ }
+ }
+
+out:
+ fclose(req);
+ if (keyParams.prime.data) { /* P */
+ SECITEM_ZfreeItem(&keyParams.prime, PR_FALSE);
+ }
+ if (keyParams.subPrime.data) { /* Q */
+ SECITEM_ZfreeItem(&keyParams.subPrime, PR_FALSE);
+ }
+ if (keyParams.base.data) { /* G */
+ SECITEM_ZfreeItem(&keyParams.base, PR_FALSE);
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -9078,6 +9263,15 @@ main(int argc, char **argv)
/* AES Keywrap */
/***************/
keywrap(argv[2]);
+ } else if (strcmp(argv[1], "kasffc") == 0) {
+ /***************/
+ /* KAS FFC */
+ /***************/
+ if (strcmp(argv[2], "validity") == 0) {
+ kas_ffc_test(argv[3], PR_TRUE);
+ } else {
+ kas_ffc_test(argv[3], PR_FALSE);
+ }
}
return 0;
}
Index: nss/cmd/fipstest/kas.sh
===================================================================
--- /dev/null
+++ nss/cmd/fipstest/kas.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+#
+# 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/.
+#
+# A Bourne shell script for running the NIST RNG Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KAS
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+kas_requests_ffc_function="
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req
+KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req
+"
+
+kas_requests_ffc_validity="
+KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req
+KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $kas_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+
+for request in $kas_requests_ffc_function; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest kasffc function ${REQDIR}/$request > ${RSPDIR}/$response
+done
+
+for request in $kas_requests_ffc_validity; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest kasffc validity ${REQDIR}/$request > ${RSPDIR}/$response
+done

237
nss-fips-cavs-keywrap.patch Normal file
View File

@ -0,0 +1,237 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574234023 -3600
# Wed Nov 20 08:13:43 2019 +0100
# Node ID 5d6e015d1af40b5f5b990d0cf4d97932774c2a61
# Parent 2f570c6952d8edfc1ad9061cd3830f202eec1960
[PATCH 1/2] 19
From f4cbaf95fcf2519029bb3c4407b2f15aa27c94c1 Mon Sep 17 00:00:00 2001
---
nss/cmd/fipstest/fipstest.c | 160 ++++++++++++++++++++++++++++++++++++
nss/cmd/fipstest/keywrap.sh | 40 +++++++++
2 files changed, 200 insertions(+)
create mode 100644 nss/cmd/fipstest/keywrap.sh
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -8737,6 +8737,161 @@ done:
return;
}
+void
+keywrap (char *reqfn)
+{
+ char buf[1024];
+ FILE *req; /* input stream from the REQUEST file */
+ FILE *resp; /* output stream to the RESPONSE file */
+ int i, j;
+ AESKeyWrapContext *ctx = NULL;
+ unsigned char key_data [1024];
+ int key_data_len = 0;
+
+ req = fopen(reqfn, "r");
+ resp = stdout;
+
+ while (fgets(buf, sizeof buf, req) != NULL) {
+ /* K = ... */
+ if (buf[0] == 'K') {
+ /* Skip to value */
+ for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+ ;
+
+ if (i == 1) {
+ /* Unknown variable starting with 'K' */
+ fputs(buf, resp);
+ continue;
+ }
+
+ for (j = 0; isxdigit(buf[i]) && j < sizeof key_data; i += 2, j++) {
+ hex_to_byteval(&buf[i], &key_data[j]);
+ }
+
+ key_data_len = j;
+
+ fputs(buf, resp);
+ continue;
+ }
+ /* C = ... */
+ /* This means we're doing decryption */
+ /* Make sure we don't pick up COUNT = ... here */
+ else if (buf[0] == 'C' && (isspace (buf[1]) || buf[1] == '=')) {
+ unsigned char data_in [1024];
+ unsigned char data_out [1024];
+ unsigned int data_in_len, data_out_len;
+
+ if (key_data_len <= 0) {
+ fprintf(resp, "ERROR: No key specified\n");
+ goto out;
+ }
+
+ /* Skip to value */
+ for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+ ;
+
+ if (i == 1) {
+ /* Unknown variable starting with 'C' */
+ fputs(buf, resp);
+ continue;
+ }
+
+ fputs(buf, resp);
+
+ for (j = 0; isxdigit(buf[i]) && j < sizeof data_in; i += 2, j++) {
+ hex_to_byteval(&buf[i], &data_in[j]);
+ }
+
+ data_in_len = j;
+
+ if (ctx) {
+ AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+ ctx = NULL;
+ }
+
+ ctx = AESKeyWrap_CreateContext(key_data, NULL, PR_FALSE, key_data_len);
+ if (!ctx) {
+ fprintf(resp, "ERROR: Unable to create context\n");
+ goto out;
+ }
+
+ if (AESKeyWrap_Decrypt(ctx, data_out, &data_out_len, 1024, data_in, data_in_len)
+ != SECSuccess) {
+ fprintf(resp, "FAIL\n");
+ continue;
+ }
+
+ fputs("P = ", resp);
+ to_hex_str(buf, data_out, data_out_len);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+ /* P = ... */
+ /* This means we're doing encryption */
+ else if (buf[0] == 'P') {
+ unsigned char data_in [1024];
+ unsigned char data_out [1024];
+ unsigned int data_in_len, data_out_len;
+
+ if (key_data_len <= 0) {
+ fprintf(resp, "ERROR: No key specified\n");
+ goto out;
+ }
+
+ /* Skip to value */
+ for (i = 1; isspace(buf[i]) || buf[i] == '='; i++)
+ ;
+
+ if (i == 1) {
+ /* Unknown variable starting with 'P' */
+ fputs(buf, resp);
+ continue;
+ }
+
+ fputs(buf, resp);
+
+ for (j = 0; isxdigit(buf[i]) && j < sizeof data_in; i += 2, j++) {
+ hex_to_byteval(&buf[i], &data_in[j]);
+ }
+
+ data_in_len = j;
+
+ if (ctx) {
+ AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+ ctx = NULL;
+ }
+
+ ctx = AESKeyWrap_CreateContext(key_data, NULL, PR_TRUE, key_data_len);
+ if (!ctx) {
+ fprintf(resp, "ERROR: Unable to create context\n");
+ goto out;
+ }
+
+ if (AESKeyWrap_Encrypt(ctx, data_out, &data_out_len, 1024, data_in, data_in_len)
+ != SECSuccess) {
+ fprintf(resp, "FAIL\n");
+ continue;
+ }
+
+ fputs("C = ", resp);
+ to_hex_str(buf, data_out, data_out_len);
+ fputs(buf, resp);
+ fputc('\n', resp);
+ }
+ /* Comments, blank lines, ... */
+ else {
+ fputs(buf, resp);
+ continue;
+ }
+ }
+
+out:
+ fclose(req);
+ if (ctx) {
+ AESKeyWrap_DestroyContext (ctx, PR_TRUE);
+ }
+}
+
int
main(int argc, char **argv)
{
@@ -8918,6 +9073,11 @@ main(int argc, char **argv)
ikev2(argv[2]);
} else if (strcmp(argv[1], "kbkdf") == 0) {
kbkdf(argv[2]);
+ } else if (strcmp(argv[1], "keywrap") == 0) {
+ /***************/
+ /* AES Keywrap */
+ /***************/
+ keywrap(argv[2]);
}
return 0;
}
Index: nss/cmd/fipstest/keywrap.sh
===================================================================
--- /dev/null
+++ nss/cmd/fipstest/keywrap.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# 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/.
+#
+# A Bourne shell script for running the NIST AES keywrap Algorithm Validation Suite
+#
+# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
+# variables appropriately so that the fipstest command and the NSPR and NSS
+# shared libraries/DLLs are on the search path. Then run this script in the
+# directory where the REQUEST (.req) files reside. The script generates the
+# RESPONSE (.rsp) files in the same directory.
+BASEDIR=${1-.}
+TESTDIR=${BASEDIR}/KeyWrap38F
+COMMAND=${2-run}
+REQDIR=${TESTDIR}/req
+RSPDIR=${TESTDIR}/resp
+
+keywrap_requests="
+KW_AD_128.req
+KW_AD_192.req
+KW_AD_256.req
+KW_AE_128.req
+KW_AE_192.req
+KW_AE_256.req
+"
+
+if [ ${COMMAND} = "verify" ]; then
+ for request in $keywrap_requests; do
+ sh ./validate1.sh ${TESTDIR} $request
+ done
+ exit 0
+fi
+
+for request in $keywrap_requests; do
+ response=`echo $request | sed -e "s/req/rsp/"`
+ echo $request $response
+ fipstest keywrap ${REQDIR}/$request > ${RSPDIR}/$response
+done

View File

@ -0,0 +1,33 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574237297 -3600
# Wed Nov 20 09:08:17 2019 +0100
# Node ID 3f4d682c9a1e8b3d939c744ee249e23179db5191
# Parent 0e904e6179d1db21965df2c405c80c3fc0258658
[PATCH] 25
From 9b4636ad75add2ac09ce1844b3071785d563c275 Mon Sep 17 00:00:00 2001
---
nss/cmd/fipstest/fipstest.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: nss/cmd/fipstest/fipstest.c
===================================================================
--- nss.orig/cmd/fipstest/fipstest.c
+++ nss/cmd/fipstest/fipstest.c
@@ -6535,7 +6535,7 @@ rsa_siggen_test(char *reqfn)
/* Output the signature */
fputs(buf, rsaresp);
to_hex_str(buf, rsa_computed_signature, rsa_bytes_signed);
- fprintf(rsaresp, "S = %s\n", buf);
+ fprintf(rsaresp, "S = %s\n\n", buf);
/* Perform RSA verification with the RSA public key. */
rv = RSA_HashCheckSign(shaOid,
@@ -9521,6 +9521,7 @@ main(int argc, char **argv)
init_functions();
RNG_RNGInit();
SECOID_Init();
+ BL_Init();
/*************/
/* TDEA */

View File

@ -0,0 +1,328 @@
From 7f3606a84f6c62b002246ee73121279e59f83437 Mon Sep 17 00:00:00 2001
From: Hans Petter Jansson <hpj@cl.no>
Date: Thu, 28 May 2020 22:44:22 +0200
Subject: [PATCH] CKM_(EC)DSA_SHAxxx mechs: Add some missing pieces.
This includes pairwise consistency checks and entry points for
power-on self tests.
---
cmd/lib/pk11table.c | 8 ++
lib/pk11wrap/pk11mech.c | 8 ++
lib/softoken/pkcs11c.c | 213 +++++++++++++++++++++++++++-------------
lib/softoken/softoken.h | 10 ++
4 files changed, 169 insertions(+), 70 deletions(-)
Index: nss/cmd/lib/pk11table.c
===================================================================
--- nss.orig/cmd/lib/pk11table.c
+++ nss/cmd/lib/pk11table.c
@@ -274,6 +274,10 @@ const Constant _consts[] = {
mkEntry(CKM_DSA_KEY_PAIR_GEN, Mechanism),
mkEntry(CKM_DSA, Mechanism),
mkEntry(CKM_DSA_SHA1, Mechanism),
+ mkEntry(CKM_DSA_SHA224, Mechanism),
+ mkEntry(CKM_DSA_SHA256, Mechanism),
+ mkEntry(CKM_DSA_SHA384, Mechanism),
+ mkEntry(CKM_DSA_SHA512, Mechanism),
mkEntry(CKM_DH_PKCS_KEY_PAIR_GEN, Mechanism),
mkEntry(CKM_DH_PKCS_DERIVE, Mechanism),
mkEntry(CKM_X9_42_DH_DERIVE, Mechanism),
@@ -439,6 +443,10 @@ const Constant _consts[] = {
mkEntry(CKM_EC_KEY_PAIR_GEN, Mechanism),
mkEntry(CKM_ECDSA, Mechanism),
mkEntry(CKM_ECDSA_SHA1, Mechanism),
+ mkEntry(CKM_ECDSA_SHA224, Mechanism),
+ mkEntry(CKM_ECDSA_SHA256, Mechanism),
+ mkEntry(CKM_ECDSA_SHA384, Mechanism),
+ mkEntry(CKM_ECDSA_SHA512, Mechanism),
mkEntry(CKM_ECDH1_DERIVE, Mechanism),
mkEntry(CKM_ECDH1_COFACTOR_DERIVE, Mechanism),
mkEntry(CKM_EC_EDWARDS_KEY_PAIR_GEN, Mechanism),
Index: nss/lib/pk11wrap/pk11mech.c
===================================================================
--- nss.orig/lib/pk11wrap/pk11mech.c
+++ nss/lib/pk11wrap/pk11mech.c
@@ -377,6 +377,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,
return CKK_RSA;
case CKM_DSA:
case CKM_DSA_SHA1:
+ case CKM_DSA_SHA224:
+ case CKM_DSA_SHA256:
+ case CKM_DSA_SHA384:
+ case CKM_DSA_SHA512:
case CKM_DSA_KEY_PAIR_GEN:
return CKK_DSA;
case CKM_DH_PKCS_DERIVE:
@@ -387,6 +391,10 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type,
return CKK_KEA;
case CKM_ECDSA:
case CKM_ECDSA_SHA1:
+ case CKM_ECDSA_SHA224:
+ case CKM_ECDSA_SHA256:
+ case CKM_ECDSA_SHA384:
+ case CKM_ECDSA_SHA512:
case CKM_EC_KEY_PAIR_GEN: /* aka CKM_ECDSA_KEY_PAIR_GEN */
case CKM_ECDH1_DERIVE:
return CKK_EC; /* CKK_ECDSA is deprecated */
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -2848,6 +2848,38 @@ nsc_EDDSASignStub(void *ctx, unsigned ch
return rv;
}
+SECStatus
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+ const unsigned char *hash, unsigned int hashLen)
+{
+ SECStatus rv;
+
+ rv = nsc_DSA_Sign_Stub(key, sig, sigLen, maxLen, hash, hashLen);
+
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+
+ return rv;
+}
+
+SECStatus
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+ const unsigned char *hash, unsigned int hashLen)
+{
+ SECStatus rv;
+
+ rv = nsc_ECDSASignStub(key, sig, sigLen, maxLen, hash, hashLen);
+
+ if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+ sftk_fatalError = PR_TRUE;
+ }
+
+ return rv;
+}
+
/* NSC_SignInit setups up the signing operations. There are three basic
* types of signing:
* (1) the tradition single part, where "Raw RSA" or "Raw DSA" is applied
@@ -3755,6 +3787,22 @@ NSC_VerifyInit(CK_SESSION_HANDLE hSessio
info->hashOid = SEC_OID_##mmm; \
goto finish_rsa;
+#define INIT_DSA_VFY_MECH(mmm) \
+ case CKM_DSA_##mmm: \
+ context->multi = PR_TRUE; \
+ crv = sftk_doSub##mmm(context); \
+ if (crv != CKR_OK) \
+ break; \
+ goto finish_dsa;
+
+#define INIT_ECDSA_VFY_MECH(mmm) \
+ case CKM_ECDSA_##mmm: \
+ context->multi = PR_TRUE; \
+ crv = sftk_doSub##mmm(context); \
+ if (crv != CKR_OK) \
+ break; \
+ goto finish_ecdsa;
+
switch (pMechanism->mechanism) {
INIT_RSA_VFY_MECH(MD5)
INIT_RSA_VFY_MECH(MD2)
@@ -5017,6 +5065,73 @@ loser:
#define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
+static CK_RV
+pairwise_signverify_mech (CK_SESSION_HANDLE hSession,
+ SFTKObject *publicKey, SFTKObject *privateKey,
+ CK_MECHANISM mech,
+ CK_ULONG signature_length,
+ CK_ULONG pairwise_digest_length)
+{
+ /* Variables used for Signature/Verification functions. */
+ /* Must be at least 256 bits for DSA2 digest */
+ unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World through NSS!";
+ unsigned char *signature;
+ CK_RV crv;
+
+ /* Allocate space for signature data. */
+ signature = (unsigned char *)PORT_ZAlloc(signature_length);
+ if (signature == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ /* Sign the known hash using the private key. */
+ crv = NSC_SignInit(hSession, &mech, privateKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ crv = NSC_Sign(hSession,
+ known_digest,
+ pairwise_digest_length,
+ signature,
+ &signature_length);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ /* detect trivial signing transforms */
+ if ((signature_length >= pairwise_digest_length) &&
+ (PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
+ PORT_Free(signature);
+ return CKR_DEVICE_ERROR;
+ }
+
+ /* Verify the known hash using the public key. */
+ crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
+ if (crv != CKR_OK) {
+ PORT_Free(signature);
+ return crv;
+ }
+
+ crv = NSC_Verify(hSession,
+ known_digest,
+ pairwise_digest_length,
+ signature,
+ signature_length);
+
+ /* Free signature data. */
+ PORT_Free(signature);
+
+ if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
+ (crv == CKR_SIGNATURE_INVALID)) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ return crv;
+}
+
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
*
@@ -5071,8 +5186,6 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
/* Variables used for Signature/Verification functions. */
/* Must be at least 256 bits for DSA2 digest */
- unsigned char *known_digest = (unsigned char *)"Mozilla Rules the World through NSS!";
- unsigned char *signature;
CK_ULONG signature_length;
if (keyType == CKK_RSA) {
@@ -5226,80 +5339,36 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
}
}
+#define SIGNVERIFY_CHECK_MECH(vfymech) \
+ mech.mechanism = vfymech; \
+ crv = pairwise_signverify_mech (hSession, publicKey, privateKey, \
+ mech, signature_length, pairwise_digest_length); \
+ if (crv != CKR_OK) \
+ return crv;
+
if (canSignVerify) {
- /* Determine length of signature. */
switch (keyType) {
case CKK_RSA:
signature_length = modulusLen;
- mech.mechanism = CKM_RSA_PKCS;
+ SIGNVERIFY_CHECK_MECH(CKM_SHA224_RSA_PKCS)
break;
case CKK_DSA:
signature_length = DSA_MAX_SIGNATURE_LEN;
pairwise_digest_length = subPrimeLen;
- mech.mechanism = CKM_DSA;
+ SIGNVERIFY_CHECK_MECH(CKM_DSA_SHA224)
break;
case CKK_EC:
signature_length = MAX_ECKEY_LEN * 2;
- mech.mechanism = CKM_ECDSA;
+ SIGNVERIFY_CHECK_MECH(CKM_ECDSA_SHA224)
break;
case CKK_EC_EDWARDS:
signature_length = ED25519_SIGN_LEN;
- mech.mechanism = CKM_EDDSA;
+ SIGNVERIFY_CHECK_MECH(CKM_EDDSA)
break;
default:
return CKR_DEVICE_ERROR;
}
- /* Allocate space for signature data. */
- signature = (unsigned char *)PORT_ZAlloc(signature_length);
- if (signature == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* Sign the known hash using the private key. */
- crv = NSC_SignInit(hSession, &mech, privateKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- crv = NSC_Sign(hSession,
- known_digest,
- pairwise_digest_length,
- signature,
- &signature_length);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- /* detect trivial signing transforms */
- if ((signature_length >= pairwise_digest_length) &&
- (PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
- PORT_Free(signature);
- return CKR_DEVICE_ERROR;
- }
-
- /* Verify the known hash using the public key. */
- crv = NSC_VerifyInit(hSession, &mech, publicKey->handle);
- if (crv != CKR_OK) {
- PORT_Free(signature);
- return crv;
- }
-
- crv = NSC_Verify(hSession,
- known_digest,
- pairwise_digest_length,
- signature,
- signature_length);
-
- /* Free signature data. */
- PORT_Free(signature);
-
- if ((crv == CKR_SIGNATURE_LEN_RANGE) ||
- (crv == CKR_SIGNATURE_INVALID)) {
- return CKR_GENERAL_ERROR;
- }
if (crv != CKR_OK) {
return crv;
}
Index: nss/lib/softoken/softoken.h
===================================================================
--- nss.orig/lib/softoken/softoken.h
+++ nss/lib/softoken/softoken.h
@@ -35,6 +35,16 @@ RSA_HashCheckSign(SECOidTag hashOid, NSS
const unsigned char *sig, unsigned int sigLen,
const unsigned char *hash, unsigned int hashLen);
+extern SECStatus
+DSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+ const unsigned char *hash, unsigned int hashLen);
+
+extern SECStatus
+ECDSA_HashSign(SECOidTag hashOid, NSSLOWKEYPrivateKey *key,
+ unsigned char *sig, unsigned int *sigLen, unsigned int maxLen,
+ const unsigned char *hash, unsigned int hashLen);
+
/*
** Prepare a buffer for padded CBC encryption, growing to the appropriate
** boundary, filling with the appropriate padding.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1584305671 -3600
# Sun Mar 15 21:54:31 2020 +0100
# Node ID 715834d4a258c535f3abbf116d69d5e77392593b
# Parent 4ddd7d49eeed4ea32850daf41a472ccb50dee45e
commit facacdb9078693d7a4219e84f73ea7b8f977ddc2
Author: Hans Petter Jansson <hpj@cl.no>
Patch 32: nss-fips-detect-fips-mode-fixes.patch
Index: nss/lib/freebl/nsslowhash.c
===================================================================
--- nss.orig/lib/freebl/nsslowhash.c
+++ nss/lib/freebl/nsslowhash.c
@@ -2,9 +2,13 @@
* 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/. */
+#define _GNU_SOURCE 1
+#include <stdlib.h>
+
#ifdef FREEBL_NO_DEPEND
#include "stubs.h"
#endif
+
#include "prtypes.h"
#include "prenv.h"
#include "secerr.h"
@@ -27,6 +31,22 @@ struct NSSLOWHASHContextStr {
static NSSLOWInitContext dummyContext = { 0 };
static PRBool post_failed = PR_TRUE;
+static PRBool
+getFIPSEnv(void)
+{
+ char *fipsEnv = secure_getenv("NSS_FIPS");
+ if (!fipsEnv) {
+ return PR_FALSE;
+ }
+ if ((strcasecmp(fipsEnv, "fips") == 0) ||
+ (strcasecmp(fipsEnv, "true") == 0) ||
+ (strcasecmp(fipsEnv, "on") == 0) ||
+ (strcasecmp(fipsEnv, "1") == 0)) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
NSSLOWInitContext *
NSSLOW_Init(void)
{
@@ -37,7 +57,7 @@ NSSLOW_Init(void)
#ifndef NSS_FIPS_DISABLED
/* make sure the FIPS product is installed if we are trying to
* go into FIPS mode */
- if (NSS_GetSystemFIPSEnabled()) {
+ if (NSS_GetSystemFIPSEnabled() || getFIPSEnv()) {
if (BL_FIPSEntryOK(PR_TRUE, PR_FALSE) != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
post_failed = PR_TRUE;
Index: nss/lib/sysinit/nsssysinit.c
===================================================================
--- nss.orig/lib/sysinit/nsssysinit.c
+++ nss/lib/sysinit/nsssysinit.c
@@ -185,9 +185,9 @@ getFIPSMode(void)
size = fread(&d, 1, 1, f);
fclose(f);
if (size != 1)
- return PR_FALSE;
+ return getFIPSEnv();
if (d != '1')
- return PR_FALSE;
+ return getFIPSEnv();
return PR_TRUE;
#else
return PR_FALSE;

View File

@ -0,0 +1,111 @@
Index: nss/coreconf/Linux.mk
===================================================================
--- nss.orig/coreconf/Linux.mk
+++ nss/coreconf/Linux.mk
@@ -136,7 +136,7 @@ OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLA
ifeq ($(KERNEL),Linux)
OS_CFLAGS += -DLINUX -Dlinux
endif
-OS_LIBS = $(OS_PTHREAD) -ldl -lc
+OS_LIBS = $(OS_PTHREAD) -ldl -lc -ljitterentropy
ifeq ($(OS_TARGET),Android)
OS_LIBS += -llog
Index: nss/lib/freebl/drbg.c
===================================================================
--- nss.orig/lib/freebl/drbg.c
+++ nss/lib/freebl/drbg.c
@@ -6,6 +6,8 @@
#include "stubs.h"
#endif
+#include <jitterentropy.h>
+
#include <unistd.h>
#include "prerror.h"
@@ -107,6 +109,45 @@ typedef struct RNGContextStr RNGContext;
static RNGContext *globalrng = NULL;
static RNGContext theGlobalRng;
+/* Jitterentropy */
+#define JITTER_FLAGS JENT_FORCE_FIPS
+static struct rand_data *jitter;
+
+static ssize_t
+FIPS_jent_get_entropy (void *dest, ssize_t len)
+{
+ int result = -1;
+
+ /* Ensure that the jitterentropy generator is initialized */
+
+ if (!jitter)
+ {
+ if (jent_entropy_init_ex (1, JITTER_FLAGS))
+ goto out;
+
+ jitter = jent_entropy_collector_alloc (1, JITTER_FLAGS);
+ if (!jitter)
+ goto out;
+ }
+
+ /* Get some entropy */
+
+ result = jent_read_entropy_safe (&jitter, dest, len);
+
+out:
+ return result;
+}
+
+static void
+FIPS_jent_deinit (void)
+{
+ if (jitter)
+ {
+ jent_entropy_collector_free (jitter);
+ jitter = NULL;
+ }
+}
+
/*
* The next several functions are derived from the NIST SP 800-90
* spec. In these functions, an attempt was made to use names consistent
@@ -180,7 +221,7 @@ static PRCallOnceType coRNGInitEntropy;
static PRStatus
prng_initEntropy(void)
{
- size_t length;
+ ssize_t length;
PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE];
SHA256Context ctx;
@@ -203,8 +244,8 @@ prng_initEntropy(void)
/* For FIPS 140-2 4.9.2 continuous random number generator test,
* fetch the initial entropy from the system RNG and keep it for
* later comparison. */
- length = RNG_SystemRNG(block, sizeof(block));
- if (length == 0) {
+ length = FIPS_jent_get_entropy(block, sizeof(block));
+ if (length < 1) {
coRNGInitEntropy.status = PR_FAILURE;
__sync_synchronize ();
coRNGInitEntropy.initialized = 1;
@@ -244,8 +285,8 @@ prng_getEntropy(PRUint8 *buffer, size_t
* iteratively fetch fixed sized blocks from the system and
* compare consecutive blocks. */
while (total < requestLength) {
- size_t length = RNG_SystemRNG(block, sizeof(block));
- if (length == 0) {
+ ssize_t length = FIPS_jent_get_entropy(block, sizeof(block));
+ if (length < 1) {
rv = SECFailure; /* error is already set */
goto out;
}
@@ -792,6 +833,7 @@ RNG_RNGShutdown(void)
/* clear */
prng_freeRNGContext(globalrng);
globalrng = NULL;
+ FIPS_jent_deinit ();
/* reset the callonce struct to allow a new call to RNG_RNGInit() */
coRNGInit = pristineCallOnce;
}

26
nss-fips-dsa-kat.patch Normal file
View File

@ -0,0 +1,26 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@suse.com>
# Date 1505605677 -7200
# Sun Sep 17 01:47:57 2017 +0200
# Node ID 4ae6bed68a83c01f6d2ce7a37bdb0bdb0556416f
# Parent 5e191a391c38967e49a1d005800713ccd1010b09
[PATCH 2/6] Make DSA KAT FIPS compliant (1024 -> 2048 bit key).
From b88701933a284ba8640df66b954c04d36ee592c9 Mon Sep 17 00:00:00 2001
---
nss/lib/freebl/dsa.c | 2 +-
nss/lib/freebl/fipsfreebl.c | 143 +++++++++++++++++++++++++++-----------------
2 files changed, 90 insertions(+), 55 deletions(-)
Index: nss/lib/freebl/dsa.c
===================================================================
--- nss.orig/lib/freebl/dsa.c
+++ nss/lib/freebl/dsa.c
@@ -536,7 +536,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECIt
return rv;
}
-/* For FIPS compliance testing. Seed must be exactly 20 bytes. */
+/* For FIPS compliance testing. Seed must be the same size as subprime. */
SECStatus
DSA_SignDigestWithSeed(DSAPrivateKey *key,
SECItem *signature,

View File

@ -0,0 +1,123 @@
diff --git a/lib/freebl/drbg.c b/lib/freebl/drbg.c
index 3ed1751..56a1a58 100644
--- a/lib/freebl/drbg.c
+++ b/lib/freebl/drbg.c
@@ -6,6 +6,8 @@
#include "stubs.h"
#endif
+#include <unistd.h>
+
#include "prerror.h"
#include "secerr.h"
@@ -182,11 +184,30 @@ prng_initEntropy(void)
PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE];
SHA256Context ctx;
+ /* Don't have NSPR, so can't use the real PR_CallOnce. Implement a stripped
+ * down version. This is similar to freebl_RunLoaderOnce(). */
+ if (coRNGInitEntropy.initialized) {
+ return coRNGInitEntropy.status;
+ }
+ if (__sync_lock_test_and_set(&coRNGInitEntropy.inProgress, 1) != 0) {
+ /* Shouldn't have a lot of takers here, which is good
+ * since we don't have condition variables yet.
+ * 'initialized' only ever gets set (not cleared) so we don't
+ * need the traditional locks. */
+ while (!coRNGInitEntropy.initialized) {
+ sleep(1); /* don't have condition variables, just give up the CPU */
+ }
+ return coRNGInitEntropy.status;
+ }
+
/* For FIPS 140-2 4.9.2 continuous random number generator test,
* fetch the initial entropy from the system RNG and keep it for
* later comparison. */
length = RNG_SystemRNG(block, sizeof(block));
if (length == 0) {
+ coRNGInitEntropy.status = PR_FAILURE;
+ __sync_synchronize ();
+ coRNGInitEntropy.initialized = 1;
return PR_FAILURE; /* error is already set */
}
PORT_Assert(length == sizeof(block));
@@ -199,6 +220,9 @@ prng_initEntropy(void)
sizeof(globalrng->previousEntropyHash));
PORT_Memset(block, 0, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
+ coRNGInitEntropy.status = PR_SUCCESS;
+ __sync_synchronize ();
+ coRNGInitEntropy.initialized = 1;
return PR_SUCCESS;
}
@@ -211,7 +235,7 @@ prng_getEntropy(PRUint8 *buffer, size_t requestLength)
SHA256Context ctx;
SECStatus rv = SECSuccess;
- if (PR_CallOnce(&coRNGInitEntropy, prng_initEntropy) != PR_SUCCESS) {
+ if (prng_initEntropy () != PR_SUCCESS) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
@@ -564,10 +588,34 @@ prng_freeRNGContext(RNGContext *rng)
SECStatus
RNG_RNGInit(void)
{
+ /* Don't have NSPR, so can't use the real PR_CallOnce. Implement a stripped
+ * down version. This is similar to freebl_RunLoaderOnce(). */
+ if (coRNGInit.initialized) {
+ return coRNGInit.status;
+ }
+ if (__sync_lock_test_and_set(&coRNGInit.inProgress, 1) != 0) {
+ /* Shouldn't have a lot of takers here, which is good
+ * since we don't have condition variables yet.
+ * 'initialized' only ever gets set (not cleared) so we don't
+ * need the traditional locks. */
+ while (!coRNGInit.initialized) {
+ sleep(1); /* don't have condition variables, just give up the CPU */
+ }
+ return coRNGInit.status;
+ }
+
/* Allow only one call to initialize the context */
- PR_CallOnce(&coRNGInit, rng_init);
+ coRNGInit.status = rng_init ();
+ __sync_synchronize ();
+ coRNGInit.initialized = 1;
+ if (coRNGInit.status != PR_SUCCESS)
+ return SECFailure;
+
/* Make sure there is a context */
- return (globalrng != NULL) ? SECSuccess : SECFailure;
+ coRNGInit.status = (globalrng != NULL) ? SECSuccess : SECFailure;
+ __sync_synchronize ();
+ coRNGInit.initialized = 1;
+ return coRNGInit.status;
}
/*
@@ -842,7 +890,21 @@ PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
}
/* replicate reseed test from prng_GenerateGlobalRandomBytes */
if (testContext.reseed_counter[0] >= RESEED_VALUE) {
- rv = prng_reseed(&testContext, NULL, 0, NULL, 0);
+ /* We need to supply the entropy so as to avoid use of global RNG */
+ static const PRUint8 reseed_entropy[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ };
+ static const PRUint8 additional_input[] = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ };
+ rv = prng_reseed(&testContext, reseed_entropy, sizeof reseed_entropy,
+ additional_input, sizeof additional_input);
if (rv != SECSuccess) {
return rv;
}

62
nss-fips-gcm-ctr.patch Normal file
View File

@ -0,0 +1,62 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574234739 -3600
# Wed Nov 20 08:25:39 2019 +0100
# Node ID 5396ffb26887cc0cd42b9f12cc6c8e3dfdaf194b
# Parent f5cf5d16deb68e65b5dd4e799d9e8e3098400d62
[PATCH] 22
From 41dd171b242b0cb550d12760da110db7e2c21daf Mon Sep 17 00:00:00 2001
---
nss/lib/freebl/gcm.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
Index: nss/lib/freebl/gcm.c
===================================================================
--- nss.orig/lib/freebl/gcm.c
+++ nss/lib/freebl/gcm.c
@@ -535,8 +535,14 @@ struct GCMContextStr {
unsigned char tagKey[MAX_BLOCK_SIZE];
PRBool ctr_context_init;
gcmIVContext gcm_iv;
+ unsigned long long gcm_iv_bytes;
};
+/* NIST SP-800-38D limits the use of GCM with a single IV to 2^39 - 256
+ * bits which translates to 2^32 - 2 128bit blocks or 2^36 - 32 bytes
+ */
+#define MAX_GCM_BYTES_PER_IV ((1ULL << 36) - 32)
+
SECStatus gcm_InitCounter(GCMContext *gcm, const unsigned char *iv,
unsigned int ivLen, unsigned int tagBits,
const unsigned char *aad, unsigned int aadLen);
@@ -676,6 +682,8 @@ gcm_InitCounter(GCMContext *gcm, const u
goto loser;
}
+ gcm->gcm_iv_bytes = MAX_GCM_BYTES_PER_IV;
+
/* finally mix in the AAD data */
rv = gcmHash_Reset(ghash, aad, aadLen);
if (rv != SECSuccess) {
@@ -777,6 +785,13 @@ GCM_EncryptUpdate(GCMContext *gcm, unsig
return SECFailure;
}
+ /* bail out if this invocation requests processing more than what is
+ * considered to be a safe limit */
+ if (gcm->gcm_iv_bytes < (unsigned long long)inlen) {
+ 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);
@@ -805,6 +820,7 @@ GCM_EncryptUpdate(GCMContext *gcm, unsig
*outlen = 0;
return SECFailure;
};
+ gcm->gcm_iv_bytes -= inlen;
*outlen += len;
return SECSuccess;
}

View File

@ -0,0 +1,35 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574138371 -3600
# Tue Nov 19 05:39:31 2019 +0100
# Node ID 557f9009507c9e70941dbe39965028049e1ef5a2
# Parent 4ae6bed68a83c01f6d2ce7a37bdb0bdb0556416f
[PATCH 07/22] 15
From 2a162c34b7aad7399f33069cd9930fd92714861c Mon Sep 17 00:00:00 2001
---
nss/lib/softoken/pkcs11c.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -5009,8 +5009,8 @@ loser:
return crv;
}
-#define PAIRWISE_DIGEST_LENGTH SHA1_LENGTH /* 160-bits */
-#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
+#define PAIRWISE_DIGEST_LENGTH SHA224_LENGTH /* 224-bits */
+#define PAIRWISE_MESSAGE_LENGTH 20 /* 160-bits */
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
@@ -6077,6 +6077,7 @@ NSC_GenerateKeyPair(CK_SESSION_HANDLE hS
(PRUint32)crv);
sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
}
+ sftk_fatalError = PR_TRUE;
}
}

View File

@ -0,0 +1,59 @@
Index: nss/lib/softoken/lowpbe.c
===================================================================
--- nss.orig/lib/softoken/lowpbe.c
+++ nss/lib/softoken/lowpbe.c
@@ -1755,7 +1755,7 @@ loser:
return ret_algid;
}
-#define TEST_KEY "pbkdf test key"
+#define TEST_KEY "qrfhfgkeWKZsYyLfUddaKQKLGhwqjQhNCiAdfweKEPaRf"
SECStatus
sftk_fips_pbkdf_PowerUpSelfTests(void)
{
@@ -1765,16 +1765,22 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
unsigned char iteration_count = 5;
unsigned char keyLen = 64;
char *inKeyData = TEST_KEY;
- static const unsigned char saltData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+ static const unsigned char saltData[] = {
+ 0x11, 0x39, 0x93, 0x54, 0x1C, 0xDD, 0xD7, 0x18,
+ 0x2F, 0x4A, 0xC1, 0x14, 0x03, 0x7A, 0x0B, 0x64,
+ 0x48, 0x99, 0xF4, 0x6D, 0xB7, 0x48, 0xE3, 0x3B,
+ 0x91, 0xBF, 0x65, 0xA9, 0x26, 0x83, 0xE8, 0x22
+ };
+
static const unsigned char pbkdf_known_answer[] = {
- 0x31, 0xf0, 0xe5, 0x39, 0x9f, 0x39, 0xb9, 0x29,
- 0x68, 0xac, 0xf2, 0xe9, 0x53, 0x9b, 0xb4, 0x9c,
- 0x28, 0x59, 0x8b, 0x5c, 0xd8, 0xd4, 0x02, 0x37,
- 0x18, 0x22, 0xc1, 0x92, 0xd0, 0xfa, 0x72, 0x90,
- 0x2c, 0x8d, 0x19, 0xd4, 0x56, 0xfb, 0x16, 0xfa,
- 0x8d, 0x5c, 0x06, 0x33, 0xd1, 0x5f, 0x17, 0xb1,
- 0x22, 0xd9, 0x9c, 0xaf, 0x5e, 0x3f, 0xf3, 0x66,
- 0xc6, 0x14, 0xfe, 0x83, 0xfa, 0x1a, 0x2a, 0xc5
+ 0x44, 0xd2, 0xae, 0x2d, 0x45, 0xb9, 0x42, 0x70,
+ 0xcb, 0x3e, 0x40, 0xc5, 0xcf, 0x36, 0x9b, 0x5f,
+ 0xfc, 0x64, 0xb1, 0x10, 0x18, 0x4d, 0xd8, 0xb6,
+ 0x71, 0xa3, 0xc4, 0x4f, 0x1d, 0xa7, 0x8f, 0xa5,
+ 0x0c, 0x4b, 0x13, 0xce, 0x2f, 0x2b, 0x48, 0xe0,
+ 0xfc, 0x10, 0x6d, 0xf4, 0xfb, 0x71, 0x1b, 0x0e,
+ 0x33, 0x2c, 0x43, 0x43, 0xe1, 0x77, 0x16, 0xf5,
+ 0x1e, 0x96, 0xcd, 0x93, 0x21, 0xb8, 0x78, 0x32
};
sftk_PBELockInit();
@@ -1803,11 +1809,12 @@ sftk_fips_pbkdf_PowerUpSelfTests(void)
* for NSSPKCS5_PBKDF2 */
pbe_params.iter = iteration_count;
pbe_params.keyLen = keyLen;
- pbe_params.hashType = HASH_AlgSHA256;
+ pbe_params.hashType = HASH_AlgSHA384;
pbe_params.pbeType = NSSPKCS5_PBKDF2;
pbe_params.is2KeyDES = PR_FALSE;
result = nsspkcs5_ComputeKeyAndIV(&pbe_params, &inKey, NULL, PR_FALSE);
+
if ((result == NULL) || (result->len != sizeof(pbkdf_known_answer)) ||
(PORT_Memcmp(result->data, pbkdf_known_answer, sizeof(pbkdf_known_answer)) != 0)) {
SECITEM_FreeItem(result, PR_TRUE);

127
nss-fips-pct-pubkeys.patch Normal file
View File

@ -0,0 +1,127 @@
# HG changeset patch
# Parent 5786c2bb5c229b530e95e435ee0cf51314359e7b
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -5132,6 +5132,88 @@ pairwise_signverify_mech (CK_SESSION_HAN
return crv;
}
+/* This function regenerates a public key from a private key
+ * (not simply returning the saved public key) and compares it
+ * to the given publicKey
+ */
+static CK_RV
+regeneratePublicKeyFromPrivateKeyAndCompare(NSSLOWKEYPrivateKey *currPrivKey,
+ NSSLOWKEYPublicKey *currPubKey)
+{
+ NSSLOWKEYPublicKey *pubk;
+ SECItem publicValue;
+ PLArenaPool *arena;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (arena == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return CKR_HOST_MEMORY;
+ }
+
+ switch (currPrivKey->keyType) {
+ case NSSLOWKEYDHKey:
+ pubk = (NSSLOWKEYPublicKey *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPublicKey));
+ if (pubk != NULL) {
+ SECStatus rv;
+
+ pubk->arena = arena;
+ pubk->keyType = currPrivKey->keyType;
+
+ // Regenerate the publicValue
+ rv = DH_Derive(&currPrivKey->u.dh.base, &currPrivKey->u.dh.prime,
+ &currPrivKey->u.dh.privateValue, &publicValue, 0);
+ if (rv != SECSuccess) {
+ break;
+ }
+ rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue,
+ &publicValue);
+ SECITEM_ZfreeItem(&publicValue, PR_FALSE);
+ if (rv != SECSuccess) {
+ break;
+ }
+
+ if (SECITEM_CompareItem(&pubk->u.dh.publicValue, &currPubKey->u.dh.publicValue) != SECEqual) {
+ nsslowkey_DestroyPublicKey(pubk);
+ return CKR_GENERAL_ERROR;
+ }
+ nsslowkey_DestroyPublicKey(pubk);
+ return CKR_OK;
+ }
+ break;
+ case NSSLOWKEYECKey:
+ {
+ ECPrivateKey *privk = NULL;
+ SECStatus rv;
+
+ /* The "seed" is an octet stream corresponding to our private key.
+ * The new public key is derived from this + the parameters and
+ * stored in the new private key's publicValue. */
+ rv = EC_NewKeyFromSeed (&currPrivKey->u.ec.ecParams,
+ &privk,
+ currPrivKey->u.ec.privateValue.data,
+ currPrivKey->u.ec.privateValue.len);
+ if (rv != SECSuccess)
+ break;
+
+ /* Verify that the passed-in public value is equal to the one derived */
+ if (SECITEM_CompareItem (&privk->publicValue, &currPubKey->u.ec.publicValue) != SECEqual) {
+ PORT_FreeArena (privk->ecParams.arena, PR_TRUE);
+ return CKR_GENERAL_ERROR;
+ }
+
+ PORT_FreeArena (privk->ecParams.arena, PR_TRUE);
+ return CKR_OK;
+ }
+ break;
+ default:
+ break;
+ }
+
+ PORT_FreeArena(arena, PR_TRUE);
+ return CKR_GENERAL_ERROR;
+}
+
/*
* FIPS 140-2 pairwise consistency check utilized to validate key pair.
*
@@ -5484,6 +5566,30 @@ sftk_PairwiseConsistencyCheck(CK_SESSION
}
}
+ // Regenerate the publicKey from the privateKey and compare it to the
+ // original publicKey
+ if (keyType == CKK_DH || keyType == CKK_EC) {
+ NSSLOWKEYPrivateKey *currPrivKey = sftk_GetPrivKey(privateKey, CKK_DH, &crv);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ if (!currPrivKey) {
+ return CKR_DEVICE_ERROR;
+ }
+
+ NSSLOWKEYPublicKey *currPubKey = sftk_GetPubKey(publicKey, CKK_DH, &crv);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ if (!currPubKey) {
+ return CKR_DEVICE_ERROR;
+ }
+
+ crv = regeneratePublicKeyFromPrivateKeyAndCompare(currPrivKey, currPubKey);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ }
return CKR_OK;
}

View File

@ -0,0 +1,244 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1584305670 -3600
# Sun Mar 15 21:54:30 2020 +0100
# Node ID 2f570c6952d8edfc1ad9061cd3830f202eec1960
# Parent 557f9009507c9e70941dbe39965028049e1ef5a2
commit 4b8c0eac6b092717157b4141c82b4d76ccdc91b3
Author: Hans Petter Jansson <hpj@cl.no>
Patch 16: nss-fips-rsa-keygen-strictness.patch
Index: nss/lib/freebl/mpi/mpprime.c
===================================================================
--- nss.orig/lib/freebl/mpi/mpprime.c
+++ nss/lib/freebl/mpi/mpprime.c
@@ -14,6 +14,8 @@
#include <stdlib.h>
#include <string.h>
+#include "../fips.h"
+
#define SMALL_TABLE 0 /* determines size of hard-wired prime table */
#define RANDOM() rand()
@@ -465,6 +467,25 @@ mpp_make_prime_ext_random(mp_int *start,
} else
num_tests = 50;
+ /* FIPS 186-4 mandates more M-R tests for probable primes generation - make
+ * sure the minimums are observed (see Appendix C, tables C.1 and C.2).
+ * For DSA this is handled in pqg_ParamGen() through the use of
+ * prime_testcount_p() and prime_testcount_q() respectively.
+ * For RSA this unfortunately seems to be the right place to prevent larger
+ * code changes. On the other hand, it seems to generally speed things up,
+ * since there are measurably less errors while calculating inverse modulo in
+ * rsa_build_from_primes().
+ */
+ if (FIPS_mode()) {
+ if (nBits >= 1536)
+ i = 4;
+ else
+ i = 5;
+ if (i > num_tests)
+ num_tests = i;
+ i = 0;
+ }
+
if (strong)
--nBits;
MP_CHECKOK(mpl_set_bit(start, nBits - 1, 1));
Index: nss/lib/freebl/rsa.c
===================================================================
--- nss.orig/lib/freebl/rsa.c
+++ nss/lib/freebl/rsa.c
@@ -16,11 +16,13 @@
#include "prinit.h"
#include "blapi.h"
#include "mpi.h"
+#include "mpi-priv.h"
#include "mpprime.h"
#include "mplogic.h"
#include "secmpi.h"
#include "secitem.h"
#include "blapii.h"
+#include "fips.h"
/* The minimal required randomness is 64 bits */
/* EXP_BLINDING_RANDOMNESS_LEN is the length of the randomness in mp_digits */
@@ -151,11 +153,24 @@ rsa_build_from_primes(const mp_int *p, c
err = mp_invmod(d, &phi, e);
} else {
err = mp_invmod(e, &phi, d);
- }
+ /* FIPS 186-4 (B.3.1.3.a) places additional requirements on the
+ * private exponent d:
+ * 2^(n/2) < d < lcm(p-1, q-1) = phi
+ */
+ if (FIPS_mode() && (MP_OKAY == err)) {
+ CHECK_MPI_OK( mp_2expt(&tmp, keySizeInBits / 2) );
+ if ((mp_cmp(d, &tmp) <= 0) || (mp_cmp(d, &phi) >= 0)) {
+ /* new set of p, q is needed for another calculation of d */
+ err = MP_UNDEF;
+ }
+ }
+ }
} else {
err = MP_OKAY;
}
- /* Verify that phi(n) and e have no common divisors */
+ /* Verify that phi(n) and e have no common divisors
+ * This is also the coprimality constraint from FIPS 186-4 (B.3.1.2.a)
+ */
if (err != MP_OKAY) {
if (err == MP_UNDEF) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
@@ -288,10 +303,12 @@ RSA_NewKey(int keySizeInBits, SECItem *p
mp_int q = { 0, 0, 0, NULL };
mp_int e = { 0, 0, 0, NULL };
mp_int d = { 0, 0, 0, NULL };
+ mp_int u = { 0, 0, 0, NULL };
+ mp_int v = { 0, 0, 0, NULL };
int kiter;
int max_attempts;
mp_err err = MP_OKAY;
- SECStatus rv = SECSuccess;
+ SECStatus rv = SECFailure;
int prerr = 0;
RSAPrivateKey *key = NULL;
PLArenaPool *arena = NULL;
@@ -309,11 +326,40 @@ RSA_NewKey(int keySizeInBits, SECItem *p
PORT_SetError(SEC_ERROR_INVALID_ARGS);
goto cleanup;
}
+
+ MP_DIGITS(&p) = 0;
+ MP_DIGITS(&q) = 0;
+ MP_DIGITS(&d) = 0;
+ MP_DIGITS(&u) = 0;
+ MP_DIGITS(&v) = 0;
+ CHECK_MPI_OK(mp_init(&p));
+ CHECK_MPI_OK(mp_init(&q));
+ CHECK_MPI_OK(mp_init(&d));
+ CHECK_MPI_OK(mp_init(&u));
+ CHECK_MPI_OK(mp_init(&v));
+
#ifndef NSS_FIPS_DISABLED
- /* Check that the exponent is not smaller than 65537 */
- if (mp_cmp_d(&e, 0x10001) < 0) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- goto cleanup;
+ if (FIPS_mode()) {
+ /* Check that the exponent is not smaller than 65537 */
+ if (mp_cmp_d(&e, 0x10001) < 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto cleanup;
+ }
+
+ /* FIPS 186-4 requires 2^16 < e < 2^256 (B.3.1.1.b) */
+ CHECK_MPI_OK( mp_2expt(&v, 256) );
+ if (!(mp_cmp(&e, &v) < 0 )) {
+ err = MP_BADARG;
+ goto cleanup;
+ }
+
+ /* FIPS 186-4 mandates keys to be either 2048, 3072 or 4096 bits long.
+ * We also allow a key length of 4096, since this is needed in order to
+ * pass the CAVS RSA SigGen test. */
+ if (keySizeInBits < 2048) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ goto cleanup;
+ }
}
#endif
@@ -331,12 +377,7 @@ RSA_NewKey(int keySizeInBits, SECItem *p
key->arena = arena;
/* length of primes p and q (in bytes) */
primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE);
- MP_DIGITS(&p) = 0;
- MP_DIGITS(&q) = 0;
- MP_DIGITS(&d) = 0;
- CHECK_MPI_OK(mp_init(&p));
- CHECK_MPI_OK(mp_init(&q));
- CHECK_MPI_OK(mp_init(&d));
+
/* 3. Set the version number (PKCS1 v1.5 says it should be zero) */
SECITEM_AllocItem(arena, &key->version, 1);
key->version.data[0] = 0;
@@ -347,13 +388,64 @@ RSA_NewKey(int keySizeInBits, SECItem *p
PORT_SetError(0);
CHECK_SEC_OK(generate_prime(&p, primeLen));
CHECK_SEC_OK(generate_prime(&q, primeLen));
- /* Assure p > q */
+ /* Assure p >= q */
/* NOTE: PKCS #1 does not require p > q, and NSS doesn't use any
* implementation optimization that requires p > q. We can remove
* this code in the future.
*/
if (mp_cmp(&p, &q) < 0)
mp_exch(&p, &q);
+
+ /* FIPS 186-4 puts additional requirements on the primes (B.3.1.2.a-d)
+ * (n = key bit length):
+ * 1) both (p-1) and (q-1) are coprime to e (B.3.1.2.a), i.e.:
+ * gcd(p-1,e) = 1, gcd(q-1,e) = 1
+ * this is ensured in rsa_build_from_primes(), where
+ * phi = lcm(p-1)(q-1) is tested for coprimality to e
+ * 2) magnitude constraint (B.3.1.2.b and B.3.1.2.c):
+ * both p and q are from open the interval
+ * I = ( sqrt(2) * 2^(n/2 - 1) , 2^(n/2 - 1) )
+ * 3) minimum distance (B.3.1.2.d): abs(p-q) > 2 ^ (n/2 - 100)
+ */
+ if (FIPS_mode()) {
+ /* 2 */
+ /* in order not to constrain the selection too much,
+ * expand the inequality:
+ * x > 2^(1/2) * 2^(n/2 - 1)
+ * = 2^(1/2 + k) * 2^(n/2 - k - 1)
+ * = y(k) * r(k)
+ * for z(k) >= y(k) it clearly holds:
+ * x > z(k) * r(k)
+ * one suitable z(k) such that z(k)/y(k) - 1 = o(1) is
+ * ceil(y(k)) for big-enough k
+ * ceil(y(30))/y(30) - 1 < 10^-10, so lets use that
+ * 2^30.5 = 1518500249.98802484622388101120...
+ * the magic constant is thus z(30) = 1518500250 < 2^31
+ *
+ * Additionally, since p >= q is required above, the
+ * condtitions can be shortened to:
+ * 1518500250 * 2^(n/2 - 31) = v < q
+ * p < u = 2^(n/2 - 1)
+ */
+ CHECK_MPI_OK( mp_2expt(&u, keySizeInBits / 2 - 31) );
+ CHECK_MPI_OK( mp_mul_d(&u, 1518500250, &v) );
+ CHECK_MPI_OK( mp_2expt(&u, keySizeInBits / 2) );
+ if ((mp_cmp(&q, &v) <= 0) || (mp_cmp(&p, &u) >= 0)) {
+ prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
+ kiter++;
+ continue;
+ }
+ /* 3 */
+ CHECK_MPI_OK( mp_sub(&p, &q, &u) );
+ CHECK_MPI_OK( mp_abs(&u, &u) );
+ CHECK_MPI_OK( mp_2expt(&v, keySizeInBits / 2 - 100) );
+ if (mp_cmp(&u, &v) < 0) {
+ prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
+ kiter++;
+ continue;
+ }
+ }
+
/* Attempt to use these primes to generate a key */
rv = rsa_build_from_primes(&p, &q,
&e, PR_FALSE, /* needPublicExponent=false */
@@ -376,7 +468,9 @@ cleanup:
mp_clear(&q);
mp_clear(&e);
mp_clear(&d);
- if (err) {
+ mp_clear(&u);
+ mp_clear(&v);
+ if (err != MP_OKAY) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}

510
nss-fips-safe-memset.patch Normal file
View File

@ -0,0 +1,510 @@
Index: nss/lib/freebl/aeskeywrap.c
===================================================================
--- nss.orig/lib/freebl/aeskeywrap.c
+++ nss/lib/freebl/aeskeywrap.c
@@ -513,7 +513,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
PORT_Memcpy(iv + AES_KEY_WRAP_BLOCK_SIZE, input, inputLen);
rv = AES_Encrypt(&cx->aescx, output, pOutputLen, maxOutputLen, iv,
outLen);
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -529,7 +529,7 @@ AESKeyWrap_EncryptKWP(AESKeyWrapContext
PORT_ZFree(newBuf, paddedInputLen);
/* a little overkill, we only need to clear out the length, but this
* is easier to verify we got it all */
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
@@ -632,12 +632,12 @@ AESKeyWrap_DecryptKWP(AESKeyWrapContext
loser:
/* if we failed, make sure we don't return any data to the user */
if ((rv != SECSuccess) && (output == newBuf)) {
- PORT_Memset(newBuf, 0, paddedLen);
+ PORT_SafeZero(newBuf, paddedLen);
}
/* clear out CSP sensitive data from the heap and stack */
if (allocBuf) {
PORT_ZFree(allocBuf, paddedLen);
}
- PORT_Memset(iv, 0, sizeof(iv));
+ PORT_SafeZero(iv, sizeof(iv));
return rv;
}
Index: nss/lib/freebl/blapii.h
===================================================================
--- nss.orig/lib/freebl/blapii.h
+++ nss/lib/freebl/blapii.h
@@ -113,10 +113,10 @@ PRBool ppc_crypto_support();
#ifdef NSS_FIPS_DISABLED
#define BLAPI_CLEAR_STACK(stack_size)
#else
-#define BLAPI_CLEAR_STACK(stack_size) \
- { \
- volatile char _stkclr[stack_size]; \
- PORT_Memset((void *)&_stkclr[0], 0, stack_size); \
+#define BLAPI_CLEAR_STACK(stack_size) \
+ { \
+ volatile char _stkclr[stack_size]; \
+ PORT_SafeZero((void *)&_stkclr[0], stack_size); \
}
#endif
Index: nss/lib/freebl/drbg.c
===================================================================
--- nss.orig/lib/freebl/drbg.c
+++ nss/lib/freebl/drbg.c
@@ -218,7 +218,7 @@ prng_initEntropy(void)
SHA256_Update(&ctx, block, sizeof(block));
SHA256_End(&ctx, globalrng->previousEntropyHash, NULL,
sizeof(globalrng->previousEntropyHash));
- PORT_Memset(block, 0, sizeof(block));
+ PORT_SafeZero(block, sizeof(block));
SHA256_DestroyContext(&ctx, PR_FALSE);
coRNGInitEntropy.status = PR_SUCCESS;
__sync_synchronize ();
@@ -270,8 +270,8 @@ prng_getEntropy(PRUint8 *buffer, size_t
}
out:
- PORT_Memset(hash, 0, sizeof hash);
- PORT_Memset(block, 0, sizeof block);
+ PORT_SafeZero(hash, sizeof hash);
+ PORT_SafeZero(block, sizeof block);
return rv;
}
@@ -417,8 +417,8 @@ prng_Hashgen(RNGContext *rng, PRUint8 *r
PRNG_ADD_CARRY_ONLY(data, (sizeof data) - 1, carry);
SHA256_DestroyContext(&ctx, PR_FALSE);
}
- PORT_Memset(data, 0, sizeof data);
- PORT_Memset(thisHash, 0, sizeof thisHash);
+ PORT_SafeZero(data, sizeof data);
+ PORT_SafeZero(thisHash, sizeof thisHash);
}
/*
@@ -479,7 +479,7 @@ prng_generateNewBytes(RNGContext *rng,
PRNG_ADD_CARRY_ONLY(rng->reseed_counter, (sizeof rng->reseed_counter) - 1, carry);
/* if the prng failed, don't return any output, signal softoken */
- PORT_Memset(H, 0, sizeof H);
+ PORT_SafeZero(H, sizeof H);
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
Index: nss/lib/freebl/dsa.c
===================================================================
--- nss.orig/lib/freebl/dsa.c
+++ nss/lib/freebl/dsa.c
@@ -471,7 +471,7 @@ dsa_SignDigest(DSAPrivateKey *key, SECIt
err = MP_OKAY;
signature->len = dsa_signature_len;
cleanup:
- PORT_Memset(localDigestData, 0, DSA_MAX_SUBPRIME_LEN);
+ PORT_SafeZero(localDigestData, DSA_MAX_SUBPRIME_LEN);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
@@ -532,7 +532,7 @@ DSA_SignDigest(DSAPrivateKey *key, SECIt
rv = dsa_SignDigest(key, signature, digest, kSeed);
} while (rv != SECSuccess && PORT_GetError() == SEC_ERROR_NEED_RANDOM &&
--retries > 0);
- PORT_Memset(kSeed, 0, sizeof kSeed);
+ PORT_SafeZero(kSeed, sizeof kSeed);
return rv;
}
@@ -673,7 +673,7 @@ DSA_VerifyDigest(DSAPublicKey *key, cons
verified = SECSuccess; /* Signature verified. */
}
cleanup:
- PORT_Memset(localDigestData, 0, sizeof localDigestData);
+ PORT_SafeZero(localDigestData, sizeof localDigestData);
mp_clear(&p);
mp_clear(&q);
mp_clear(&g);
Index: nss/lib/freebl/gcm.c
===================================================================
--- nss.orig/lib/freebl/gcm.c
+++ nss/lib/freebl/gcm.c
@@ -507,7 +507,7 @@ gcmHash_Final(gcmHashContext *ghash, uns
rv = SECSuccess;
cleanup:
- PORT_Memset(T, 0, sizeof(T));
+ PORT_SafeZero(T, sizeof(T));
return rv;
}
@@ -629,15 +629,15 @@ GCM_CreateContext(void *context, freeblC
if (rv != SECSuccess) {
goto loser;
}
- PORT_Memset(H, 0, AES_BLOCK_SIZE);
+ PORT_SafeZero(H, AES_BLOCK_SIZE);
gcm->ctr_context_init = PR_TRUE;
return gcm;
loser:
- PORT_Memset(H, 0, AES_BLOCK_SIZE);
+ PORT_SafeZero(H, AES_BLOCK_SIZE);
if (ghash && ghash->mem) {
void *mem = ghash->mem;
- PORT_Memset(ghash, 0, sizeof(gcmHashContext));
+ PORT_SafeZero(ghash, sizeof(gcmHashContext));
PORT_Free(mem);
}
if (gcm) {
@@ -717,11 +717,11 @@ gcm_InitCounter(GCMContext *gcm, const u
goto loser;
}
- PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+ PORT_SafeZero(&ctrParams, sizeof ctrParams);
return SECSuccess;
loser:
- PORT_Memset(&ctrParams, 0, sizeof ctrParams);
+ PORT_SafeZero(&ctrParams, sizeof ctrParams);
if (freeCtr) {
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
}
@@ -1212,10 +1212,10 @@ GCM_DecryptAEAD(GCMContext *gcm, unsigne
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
PORT_SetError(SEC_ERROR_BAD_DATA);
- PORT_Memset(tag, 0, sizeof(tag));
+ PORT_SafeZero(tag, sizeof(tag));
return SECFailure;
}
- PORT_Memset(tag, 0, sizeof(tag));
+ PORT_SafeZero(tag, sizeof(tag));
/* finish the decryption */
rv = CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);
Index: nss/lib/freebl/hmacct.c
===================================================================
--- nss.orig/lib/freebl/hmacct.c
+++ nss/lib/freebl/hmacct.c
@@ -274,10 +274,10 @@ MAC(unsigned char *mdOut,
hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
hashObj->destroy(mdState, PR_TRUE);
- PORT_Memset(lengthBytes, 0, sizeof lengthBytes);
- PORT_Memset(hmacPad, 0, sizeof hmacPad);
- PORT_Memset(firstBlock, 0, sizeof firstBlock);
- PORT_Memset(macOut, 0, sizeof macOut);
+ PORT_SafeZero(lengthBytes, sizeof lengthBytes);
+ PORT_SafeZero(hmacPad, sizeof hmacPad);
+ PORT_SafeZero(firstBlock, sizeof firstBlock);
+ PORT_SafeZero(macOut, sizeof macOut);
return SECSuccess;
}
Index: nss/lib/freebl/intel-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/intel-gcm-wrap.c
+++ nss/lib/freebl/intel-gcm-wrap.c
@@ -195,7 +195,7 @@ intel_aes_gcmInitCounter(intel_AES_GCMCo
void
intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit)
{
- PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext));
+ PORT_SafeZero(gcm, sizeof(intel_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}
Index: nss/lib/freebl/ppc-gcm-wrap.c
===================================================================
--- nss.orig/lib/freebl/ppc-gcm-wrap.c
+++ nss/lib/freebl/ppc-gcm-wrap.c
@@ -169,7 +169,7 @@ ppc_aes_gcmInitCounter(ppc_AES_GCMContex
void
ppc_AES_GCM_DestroyContext(ppc_AES_GCMContext *gcm, PRBool freeit)
{
- PORT_Memset(gcm, 0, sizeof(ppc_AES_GCMContext));
+ PORT_SafeZero(gcm, sizeof(ppc_AES_GCMContext));
if (freeit) {
PORT_Free(gcm);
}
Index: nss/lib/freebl/pqg.c
===================================================================
--- nss.orig/lib/freebl/pqg.c
+++ nss/lib/freebl/pqg.c
@@ -703,7 +703,7 @@ cleanup:
mp_clear(&a);
mp_clear(&z);
mp_clear(&two_length_minus_1);
- PORT_Memset(x, 0, sizeof(x));
+ PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -859,7 +859,7 @@ cleanup:
mp_clear(&c);
mp_clear(&c0);
mp_clear(&one);
- PORT_Memset(x, 0, sizeof(x));
+ PORT_SafeZero(x, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@@ -1072,7 +1072,7 @@ makePfromQandSeed(
CHECK_MPI_OK(mp_sub_d(&c, 1, &c)); /* c -= 1 */
CHECK_MPI_OK(mp_sub(&X, &c, P)); /* P = X - c */
cleanup:
- PORT_Memset(V_j, 0, sizeof V_j);
+ PORT_SafeZero(V_j, sizeof V_j);
mp_clear(&W);
mp_clear(&X);
mp_clear(&c);
@@ -1221,7 +1221,7 @@ makeGfromIndex(HASH_HashType hashtype,
/* step 11.
* return valid G */
cleanup:
- PORT_Memset(data, 0, sizeof(data));
+ PORT_SafeZero(data, sizeof(data));
if (hashcx) {
hashobj->destroy(hashcx, PR_TRUE);
}
Index: nss/lib/freebl/rijndael.c
===================================================================
--- nss.orig/lib/freebl/rijndael.c
+++ nss/lib/freebl/rijndael.c
@@ -1251,7 +1251,7 @@ AES_DestroyContext(AESContext *cx, PRBoo
cx->worker_cx = NULL;
cx->destroy = NULL;
}
- PORT_Memset(cx, 0, sizeof(AESContext));
+ PORT_SafeZero(cx, sizeof(AESContext));
if (freeit) {
PORT_Free(mem);
} else {
Index: nss/lib/freebl/rsa.c
===================================================================
--- nss.orig/lib/freebl/rsa.c
+++ nss/lib/freebl/rsa.c
@@ -145,8 +145,8 @@ rsa_build_from_primes(const mp_int *p, c
/* 2. Compute phi = (p-1)*(q-1) */
CHECK_MPI_OK(mp_sub_d(p, 1, &psub1));
CHECK_MPI_OK(mp_sub_d(q, 1, &qsub1));
+ CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
if (needPublicExponent || needPrivateExponent) {
- CHECK_MPI_OK(mp_lcm(&psub1, &qsub1, &phi));
/* 3. Compute d = e**-1 mod(phi) */
/* or e = d**-1 mod(phi) as necessary */
if (needPublicExponent) {
@@ -180,6 +180,15 @@ rsa_build_from_primes(const mp_int *p, c
goto cleanup;
}
+ /* make sure we weren't passed in a d or e = 1 mod phi */
+ /* just need to check d, because if one is = 1 mod phi, they both are */
+ CHECK_MPI_OK(mp_mod(d, &phi, &tmp));
+ if (mp_cmp_d(&tmp, 2) <= 0) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ rv = SECFailure;
+ goto cleanup;
+ }
+
/* 4. Compute exponent1 = d mod (p-1) */
CHECK_MPI_OK(mp_mod(d, &psub1, &tmp));
MPINT_TO_SECITEM(&tmp, &key->exponent1, key->arena);
@@ -1251,6 +1260,8 @@ rsa_PrivateKeyOpCRTCheckedPubKey(RSAPriv
/* Perform a public key operation v = m ** e mod n */
CHECK_MPI_OK(mp_exptmod(m, &e, &n, &v));
if (mp_cmp(&v, c) != 0) {
+ /* this error triggers a fips fatal error lock */
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
rv = SECFailure;
}
cleanup:
Index: nss/lib/freebl/rsapkcs.c
===================================================================
--- nss.orig/lib/freebl/rsapkcs.c
+++ nss/lib/freebl/rsapkcs.c
@@ -978,14 +978,14 @@ rsa_GetHMACContext(const SECHashObject *
/* now create the hmac key */
hmac = HMAC_Create(hash, keyHash, keyLen, PR_TRUE);
if (hmac == NULL) {
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
return NULL;
}
HMAC_Begin(hmac);
HMAC_Update(hmac, input, inputLen);
rv = HMAC_Finish(hmac, keyHash, &keyLen, sizeof(keyHash));
if (rv != SECSuccess) {
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
}
@@ -993,7 +993,7 @@ rsa_GetHMACContext(const SECHashObject *
* reuse the original context allocated above so we don't
* need to allocate and free another one */
rv = HMAC_ReInit(hmac, hash, keyHash, keyLen, PR_TRUE);
- PORT_Memset(keyHash, 0, sizeof(keyHash));
+ PORT_SafeZero(keyHash, sizeof(keyHash));
if (rv != SECSuccess) {
HMAC_Destroy(hmac, PR_TRUE);
return NULL;
@@ -1043,7 +1043,7 @@ rsa_HMACPrf(HMACContext *hmac, const cha
return rv;
}
PORT_Memcpy(output, hmacLast, left);
- PORT_Memset(hmacLast, 0, sizeof(hmacLast));
+ PORT_SafeZero(hmacLast, sizeof(hmacLast));
}
return rv;
}
@@ -1088,7 +1088,7 @@ rsa_GetErrorLength(HMACContext *hmac, in
outLength = PORT_CT_SEL(PORT_CT_LT(candidate, maxLegalLen),
candidate, outLength);
}
- PORT_Memset(out, 0, sizeof(out));
+ PORT_SafeZero(out, sizeof(out));
return outLength;
}
Index: nss/lib/freebl/shvfy.c
===================================================================
--- nss.orig/lib/freebl/shvfy.c
+++ nss/lib/freebl/shvfy.c
@@ -365,7 +365,7 @@ blapi_SHVerifyDSACheck(PRFileDesc *shFD,
/* verify the hash against the check file */
rv = DSA_VerifyDigest(key, signature, &hash);
- PORT_Memset(hashBuf, 0, sizeof hashBuf);
+ PORT_SafeZero(hashBuf, sizeof hashBuf);
return (rv == SECSuccess) ? PR_TRUE : PR_FALSE;
}
#endif
@@ -427,7 +427,7 @@ blapi_SHVerifyHMACCheck(PRFileDesc *shFD
if (rv == SECSuccess) {
result = SECITEM_ItemsAreEqual(signature, &hash);
}
- PORT_Memset(hashBuf, 0, sizeof hashBuf);
+ PORT_SafeZero(hashBuf, sizeof hashBuf);
return result;
}
@@ -451,7 +451,7 @@ blapi_SHVerifyFile(const char *shName, P
#ifndef NSS_STRICT_INTEGRITY
DSAPublicKey key;
- PORT_Memset(&key, 0, sizeof(key));
+ PORT_SafeZero(&key, sizeof(key));
#endif
/* If our integrity check was never ran or failed, fail any other
@@ -600,7 +600,7 @@ blapi_SHVerifyFile(const char *shName, P
shFD = NULL;
loser:
- PORT_Memset(&header, 0, sizeof header);
+ PORT_SafeZero(&header, sizeof header);
if (checkName != NULL) {
PORT_Free(checkName);
}
Index: nss/lib/freebl/tlsprfalg.c
===================================================================
--- nss.orig/lib/freebl/tlsprfalg.c
+++ nss/lib/freebl/tlsprfalg.c
@@ -82,8 +82,8 @@ loser:
/* clear out state so it's not left on the stack */
if (cx)
HMAC_Destroy(cx, PR_TRUE);
- PORT_Memset(state, 0, sizeof(state));
- PORT_Memset(outbuf, 0, sizeof(outbuf));
+ PORT_SafeZero(state, sizeof(state));
+ PORT_SafeZero(outbuf, sizeof(outbuf));
return rv;
}
Index: nss/lib/freebl/unix_urandom.c
===================================================================
--- nss.orig/lib/freebl/unix_urandom.c
+++ nss/lib/freebl/unix_urandom.c
@@ -22,7 +22,7 @@ RNG_SystemInfoForRNG(void)
return;
}
RNG_RandomUpdate(bytes, numBytes);
- PORT_Memset(bytes, 0, sizeof bytes);
+ PORT_SafeZero(bytes, sizeof bytes);
}
size_t
Index: nss/lib/softoken/pkcs11c.c
===================================================================
--- nss.orig/lib/softoken/pkcs11c.c
+++ nss/lib/softoken/pkcs11c.c
@@ -5105,7 +5105,7 @@ pairwise_signverify_mech (CK_SESSION_HAN
if ((signature_length >= pairwise_digest_length) &&
(PORT_Memcmp(known_digest, signature + (signature_length - pairwise_digest_length), pairwise_digest_length) == 0)) {
PORT_Free(signature);
- return CKR_DEVICE_ERROR;
+ return CKR_GENERAL_ERROR;
}
/* Verify the known hash using the public key. */
Index: nss/lib/util/secport.h
===================================================================
--- nss.orig/lib/util/secport.h
+++ nss/lib/util/secport.h
@@ -36,6 +36,9 @@
#include <sys/types.h>
#include <ctype.h>
+/* ask for Annex K for memset_s. will set the appropriate #define
+ * if Annex K is supported */
+#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
@@ -178,6 +181,39 @@ SEC_END_PROTOS
#define PORT_Memmove memmove
#define PORT_Memset memset
+/* there are cases where the compiler optimizes away our attempt to clear
+ * out our stack variables. There are multiple solutions for this problem,
+ * but they aren't universally accepted on all platforms. This attempts
+ * to select the best solution available given our os, compilier, and libc */
+#ifdef __STDC_LIB_EXT1__
+/* if the os implements C11 annex K, use memset_s */
+#define PORT_SafeZero(p, n) memset_s(p, n, 0, n)
+#else
+#ifdef XP_WIN
+/* windows has a secure zero funtion */
+#define PORT_SafeZero(p, n) SecureZeroMemory(p, n)
+#else
+/* _DEFAULT_SORUCE == BSD source in GCC based environments
+ * if other environmens support explicit_bzero, their defines
+ * should be added here */
+#if defined(_DEFAULT_SOURCE) || defined(_BSD_SOURCE)
+#define PORT_SafeZero(p, n) explicit_bzero(p, n)
+#else
+/* if the os doesn't support one of the above, but does support
+ * memset_explicit, you can add the definition for memset with the
+ * appropriate define check here */
+/* define an explicitly implementated Safe zero if the OS
+ * doesn't provide one */
+#define PORT_SafeZero(p, n) \
+ if (p != NULL) { \
+ volatile unsigned char *__vl = (unsigned char *)p; \
+ size_t __nl = n; \
+ while (__nl--) *__vl++ = 0; \
+ }
+#endif /* no explicit_bzero */
+#endif /* no windows SecureZeroMemory */
+#endif /* no memset_s */
+
#define PORT_Strcasecmp PL_strcasecmp
#define PORT_Strcat strcat
#define PORT_Strchr strchr

View File

@ -0,0 +1,52 @@
commit 3ab80b72e85583bd727730bc5b57f91e07b89710
Author: Hans Petter Jansson <hpj@cl.no>
Date: Fri Sep 4 13:41:34 2020 +0200
Patch 38: nss-fips-stricter-dh.patch
Index: nss/lib/freebl/dh.c
===================================================================
--- nss.orig/lib/freebl/dh.c
+++ nss/lib/freebl/dh.c
@@ -449,7 +449,7 @@ cleanup:
PRBool
KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime)
{
- mp_int p, q, y, r;
+ mp_int p, q, y, r, psub1;
mp_err err;
int cmp = 1; /* default is false */
if (!Y || !prime || !subPrime) {
@@ -460,13 +460,24 @@ KEA_Verify(SECItem *Y, SECItem *prime, S
MP_DIGITS(&q) = 0;
MP_DIGITS(&y) = 0;
MP_DIGITS(&r) = 0;
+ MP_DIGITS(&psub1) = 0;
CHECK_MPI_OK(mp_init(&p));
CHECK_MPI_OK(mp_init(&q));
CHECK_MPI_OK(mp_init(&y));
CHECK_MPI_OK(mp_init(&r));
+ CHECK_MPI_OK(mp_init(&psub1));
SECITEM_TO_MPINT(*prime, &p);
SECITEM_TO_MPINT(*subPrime, &q);
SECITEM_TO_MPINT(*Y, &y);
+
+ CHECK_MPI_OK(mp_sub_d(&p, 1, &psub1));
+
+ if (mp_cmp_d(&y, 1) <= 0 ||
+ mp_cmp(&y, &psub1) >= 0) {
+ err = MP_BADARG;
+ goto cleanup;
+ }
+
/* compute r = y**q mod p */
CHECK_MPI_OK(mp_exptmod(&y, &q, &p, &r));
/* compare to 1 */
@@ -476,6 +487,7 @@ cleanup:
mp_clear(&q);
mp_clear(&y);
mp_clear(&r);
+ mp_clear(&psub1);
if (err) {
MP_TO_SEC_ERROR(err);
return PR_FALSE;

15
nss-fips-test.patch Normal file
View File

@ -0,0 +1,15 @@
Index: nss/tests/cert/cert.sh
===================================================================
--- nss.orig/tests/cert/cert.sh
+++ nss/tests/cert/cert.sh
@@ -1367,8 +1367,8 @@ cert_fips()
echo "$SCRIPTNAME: Enable FIPS mode on database -----------------------"
CU_ACTION="Enable FIPS mode on database for ${CERTNAME}"
- echo "modutil -dbdir ${PROFILEDIR} -fips true "
- ${BINDIR}/modutil -dbdir ${PROFILEDIR} -fips true 2>&1 <<MODSCRIPT
+ echo "modutil -dbdir ${PROFILEDIR} -chkfips true "
+ ${BINDIR}/modutil -dbdir ${PROFILEDIR} -chkfips true 2>&1 <<MODSCRIPT
y
MODSCRIPT
RET=$?

View File

@ -0,0 +1,25 @@
Index: nss/tests/cert/cert.sh
===================================================================
--- nss.orig/tests/cert/cert.sh
+++ nss/tests/cert/cert.sh
@@ -1350,6 +1350,11 @@ cert_stresscerts()
##############################################################################
cert_fips()
{
+ OLD_FIPS_MODE=`echo ${NSS_FIPS}`
+ OLD_CHECKSUMS_MODE=`echo ${NSS_IGNORE_CHECKSUMS}`
+ export NSS_FIPS=1
+ export NSS_IGNORE_CHECKSUMS=1
+
CERTFAILED=0
echo "$SCRIPTNAME: Creating FIPS 140 DSA Certificates =============="
cert_init_cert "${FIPSDIR}" "FIPS PUB 140 Test Certificate" 1000 "${D_FIPS}"
@@ -1390,6 +1395,8 @@ MODSCRIPT
cert_log "SUCCESS: FIPS passed"
fi
+ export NSS_FIPS=${OLD_FIPS_MODE}
+ export NSS_IGNORE_CHECKSUMS=${OLD_CHECKSUMS_MODE}
}
########################## cert_rsa_exponent #################################

View File

@ -0,0 +1,125 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1574137588 -3600
# Tue Nov 19 05:26:28 2019 +0100
# Node ID 5e191a391c38967e49a1d005800713ccd1010b09
# Parent 92da25f8ea7d41e938858872e2b6a2fb1aa53bb2
commit c2a88344b616c75b1873fb163491d7362a4c3e5b
Author: Hans Petter Jansson <hpj@cl.no>
11
Index: nss/coreconf/Linux.mk
===================================================================
--- nss.orig/coreconf/Linux.mk
+++ nss/coreconf/Linux.mk
@@ -190,6 +190,18 @@ DSO_LDOPTS+=-Wl,-z,relro
LDFLAGS += -Wl,-z,relro
endif
+#
+# On Linux 3.17 or later, use getrandom() to obtain entropy where possible.
+# Set NSS_USE_GETRANDOM to 0 in the environment to override this.
+#
+ifneq ($(OS_TARGET),Android)
+ifeq (3.17,$(firstword $(sort 3.17 $(OS_RELEASE))))
+ifneq ($(NSS_USE_GETRANDOM),0)
+ DEFINES += -DNSS_USE_GETRANDOM
+endif
+endif
+endif
+
USE_SYSTEM_ZLIB = 1
ZLIB_LIBS = -lz
Index: nss/lib/freebl/unix_rand.c
===================================================================
--- nss.orig/lib/freebl/unix_rand.c
+++ nss/lib/freebl/unix_rand.c
@@ -13,6 +13,10 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef NSS_USE_GETRANDOM
+# include <sys/syscall.h>
+# include <linux/random.h>
+#endif
#include <dirent.h>
#include "secrng.h"
#include "secerr.h"
@@ -21,6 +25,43 @@
#include "prprf.h"
#include "prenv.h"
+#ifdef NSS_USE_GETRANDOM
+# ifndef __NR_getrandom
+# if defined __x86_64__
+# define __NR_getrandom 318
+# elif defined(__i386__)
+# define __NR_getrandom 355
+# elif defined(__arm__)
+# define __NR_getrandom 384
+# elif defined(__aarch64__)
+# define __NR_getrandom 278
+# elif defined(__ia64__)
+# define __NR_getrandom 1339
+# elif defined(__m68k__)
+# define __NR_getrandom 352
+# elif defined(__s390x__)
+# define __NR_getrandom 349
+# elif defined(__powerpc__)
+# define __NR_getrandom 359
+# elif defined _MIPS_SIM
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define __NR_getrandom 4353
+# endif
+# if _MIPS_SIM == _MIPS_SIM_NABI32
+# define __NR_getrandom 6317
+# endif
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR_getrandom 5313
+# endif
+# else
+# warning "__NR_getrandom unknown for your architecture"
+# endif
+# endif
+# ifndef GRND_RANDOM
+# define GRND_RANDOM 0x02
+# endif
+#endif
+
size_t RNG_FileUpdate(const char *fileName, size_t limit);
/*
@@ -775,6 +816,26 @@ ReadFileOK(char *dir, char *file)
size_t
RNG_SystemRNG(void *dest, size_t maxLen)
{
+#ifdef NSS_USE_GETRANDOM
+ unsigned char *buf = dest;
+ size_t inBytes = 0;
+ int ret;
+
+ do {
+ ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes, 0);
+
+ if (0 < ret)
+ inBytes += ret;
+ } while ((0 < ret || EINTR == errno || ERESTART == errno)
+ && inBytes < maxLen);
+
+ if (inBytes != maxLen) {
+ PORT_SetError(SEC_ERROR_NEED_RANDOM); /* system RNG failed */
+ inBytes = 0;
+ }
+
+ return inBytes;
+#else
FILE *file;
int fd;
int bytes;
@@ -808,4 +869,5 @@ RNG_SystemRNG(void *dest, size_t maxLen)
fileBytes = 0;
}
return fileBytes;
+#endif
}

View File

@ -0,0 +1,52 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574240799 -3600
# Wed Nov 20 10:06:39 2019 +0100
# Node ID 4ddd7d49eeed4ea32850daf41a472ccb50dee45e
# Parent 0efca22bbafd7575b20461f255c46157c9321822
[PATCH] 31
From a7cbf64ba8ac07a4a1fdea91f39da56d86af03bf Mon Sep 17 00:00:00 2001
---
nss/lib/freebl/unix_rand.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
Index: nss/lib/freebl/unix_rand.c
===================================================================
--- nss.orig/lib/freebl/unix_rand.c
+++ nss/lib/freebl/unix_rand.c
@@ -24,6 +24,7 @@
#include "prthread.h"
#include "prprf.h"
#include "prenv.h"
+#include "fips.h"
#ifdef NSS_USE_GETRANDOM
# ifndef __NR_getrandom
@@ -692,7 +693,7 @@ RNG_SystemInfoForRNG(void)
}
/* grab some data from system's PRNG before any other files. */
- bytes = RNG_FileUpdate("/dev/urandom", SYSTEM_RNG_SEED_COUNT);
+ bytes = RNG_FileUpdate(FIPS_mode() ? "/dev/random" : "/dev/urandom", SYSTEM_RNG_SEED_COUNT);
if (!bytes) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
}
@@ -822,7 +823,8 @@ RNG_SystemRNG(void *dest, size_t maxLen)
int ret;
do {
- ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes, 0);
+ ret = syscall(__NR_getrandom, buf + inBytes, maxLen - inBytes,
+ FIPS_mode () ? GRND_RANDOM : 0);
if (0 < ret)
inBytes += ret;
@@ -842,7 +844,7 @@ RNG_SystemRNG(void *dest, size_t maxLen)
size_t fileBytes = 0;
unsigned char *buffer = dest;
- file = fopen("/dev/urandom", "r");
+ file = fopen(FIPS_mode() ? "/dev/random" : "/dev/urandom", "r");
if (file == NULL) {
PORT_SetError(SEC_ERROR_NEED_RANDOM);
return 0;

201
nss-fips-zeroization.patch Normal file
View File

@ -0,0 +1,201 @@
# HG changeset patch
# User Hans Petter Jansson <hpj@cl.no>
# Date 1574240665 -3600
# Wed Nov 20 10:04:25 2019 +0100
# Node ID 3a2cb65dc157344cdad19e8e16e9c33e36f82d96
# Parent 2d4483f4a1259f965f32ff4c65436e92aef83be7
[PATCH 07/10] 29
From 76da775313bd40a1353a9d2f6cc43ebe1a287574 Mon Sep 17 00:00:00 2001
---
nss/lib/freebl/aeskeywrap.c | 1 +
nss/lib/freebl/cts.c | 18 +++++++++------
nss/lib/freebl/dh.c | 4 ++++
nss/lib/freebl/ec.c | 2 +-
nss/lib/freebl/gcm.c | 45 +++++++++++++++++++++++++++++++++----
5 files changed, 58 insertions(+), 12 deletions(-)
Index: nss/lib/freebl/aeskeywrap.c
===================================================================
--- nss.orig/lib/freebl/aeskeywrap.c
+++ nss/lib/freebl/aeskeywrap.c
@@ -102,6 +102,7 @@ AESKeyWrap_DestroyContext(AESKeyWrapCont
{
if (cx) {
AES_DestroyContext(&cx->aescx, PR_FALSE);
+ memset(cx->iv, 0, sizeof (cx->iv));
/* memset(cx, 0, sizeof *cx); */
if (freeit) {
PORT_Free(cx->mem);
Index: nss/lib/freebl/cts.c
===================================================================
--- nss.orig/lib/freebl/cts.c
+++ nss/lib/freebl/cts.c
@@ -37,6 +37,7 @@ CTS_CreateContext(void *context, freeblC
void
CTS_DestroyContext(CTSContext *cts, PRBool freeit)
{
+ PORT_Memset(cts, 0, sizeof(CTSContext));
if (freeit) {
PORT_Free(cts);
}
@@ -135,7 +136,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsig
PORT_Memset(lastBlock + inlen, 0, blocksize - inlen);
rv = (*cts->cipher)(cts->context, outbuf, &tmp, maxout, lastBlock,
blocksize, blocksize);
- PORT_Memset(lastBlock, 0, blocksize);
+ PORT_Memset(lastBlock, 0, MAX_BLOCK_SIZE);
if (rv == SECSuccess) {
*outlen = written + blocksize;
} else {
@@ -230,13 +231,15 @@ CTS_DecryptUpdate(CTSContext *cts, unsig
rv = (*cts->cipher)(cts->context, outbuf, outlen, maxout, inbuf,
fullblocks, blocksize);
if (rv != SECSuccess) {
- return SECFailure;
+ rv = SECFailure;
+ goto cleanup;
}
*outlen = fullblocks; /* AES low level doesn't set outlen */
inbuf += fullblocks;
inlen -= fullblocks;
if (inlen == 0) {
- return SECSuccess;
+ rv = SECSuccess;
+ goto cleanup;
}
outbuf += fullblocks;
@@ -280,9 +283,9 @@ CTS_DecryptUpdate(CTSContext *cts, unsig
rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
blocksize, blocksize);
if (rv != SECSuccess) {
- PORT_Memset(lastBlock, 0, blocksize);
PORT_Memset(saveout, 0, *outlen);
- return SECFailure;
+ rv = SECFailure;
+ goto cleanup;
}
/* make up for the out of order CBC decryption */
XOR_BLOCK(Pn, Cn_2, blocksize);
@@ -297,7 +300,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsig
/* clear last block. At this point last block contains Pn xor Cn_1 xor
* Cn_2, both of with an attacker would know, so we need to clear this
* buffer out */
- PORT_Memset(lastBlock, 0, blocksize);
+cleanup:
+ PORT_Memset(lastBlock, 0, MAX_BLOCK_SIZE);
/* Cn, Cn_1, and Cn_2 have encrypted data, so no need to clear them */
- return SECSuccess;
+ return rv;
}
Index: nss/lib/freebl/dh.c
===================================================================
--- nss.orig/lib/freebl/dh.c
+++ nss/lib/freebl/dh.c
@@ -192,6 +192,10 @@ cleanup:
rv = SECFailure;
}
if (rv) {
+ SECITEM_ZfreeItem(&key->prime, PR_FALSE);
+ SECITEM_ZfreeItem(&key->base, PR_FALSE);
+ SECITEM_ZfreeItem(&key->publicValue, PR_FALSE);
+ SECITEM_ZfreeItem(&key->privateValue, PR_FALSE);
*privKey = NULL;
PORT_FreeArena(arena, PR_TRUE);
}
Index: nss/lib/freebl/gcm.c
===================================================================
--- nss.orig/lib/freebl/gcm.c
+++ nss/lib/freebl/gcm.c
@@ -162,6 +162,9 @@ bmul(uint64_t x, uint64_t y, uint64_t *r
*r_high = (uint64_t)(r >> 64);
*r_low = (uint64_t)r;
+
+ /* Zeroization */
+ x1 = x2 = x3 = x4 = x5 = y1 = y2 = y3 = y4 = y5 = r = z = 0;
}
SECStatus
@@ -200,6 +203,12 @@ gcm_HashMult_sftw(gcmHashContext *ghash,
}
ghash->x_low = ci_low;
ghash->x_high = ci_high;
+
+ /* Zeroization */
+ ci_low = ci_high = z2_low = z2_high = z0_low = z0_high = z1a_low = z1a_high = 0;
+ z_low = z_high = 0;
+ i = 0;
+
return SECSuccess;
}
#else
@@ -239,6 +248,10 @@ bmul32(uint32_t x, uint32_t y, uint32_t
z = z0 | z1 | z2 | z3;
*r_high = (uint32_t)(z >> 32);
*r_low = (uint32_t)z;
+
+ /* Zeroization */
+ x0 = x1 = x2 = x3 = y0 = y1 = y2 = y3 = 0;
+ z0 = z1 = z2 = z3 = z = 0;
}
SECStatus
@@ -324,6 +337,20 @@ gcm_HashMult_sftw32(gcmHashContext *ghas
ghash->x_high = z_high_h;
ghash->x_low = z_high_l;
}
+
+ /* Zeroization */
+ ci_low = ci_high = z_high_h = z_high_l = z_low_h = z_low_l = 0;
+
+ ci_high_h = ci_high_l = ci_low_h = ci_low_l
+ = b_a_h = b_a_l = a_a_h = a_a_l = b_b_h = b_b_l
+ = a_b_h = a_b_l = b_c_h = b_c_l = a_c_h = a_c_l = c_c_h = c_c_l
+ = ci_highXlow_h = ci_highXlow_l = c_a_h = c_a_l = c_b_h = c_b_l
+ = h_high_h = h_high_l = h_low_h = h_low_l = h_highXlow_h = h_highXlow_l
+ = h_highX_xored
+ = 0;
+
+ i = 0;
+
return SECSuccess;
}
#endif /* HAVE_INT128_SUPPORT */
@@ -870,11 +897,13 @@ GCM_DecryptUpdate(GCMContext *gcm, unsig
/* verify the block */
rv = gcmHash_Update(gcm->ghash_context, inbuf, inlen);
if (rv != SECSuccess) {
- return SECFailure;
+ rv = SECFailure;
+ goto cleanup;
}
rv = gcm_GetTag(gcm, tag, &len, AES_BLOCK_SIZE);
if (rv != SECSuccess) {
- return SECFailure;
+ rv = SECFailure;
+ goto cleanup;
}
/* Don't decrypt if we can't authenticate the encrypted data!
* This assumes that if tagBits is not a multiple of 8, intag will
@@ -882,10 +911,18 @@ GCM_DecryptUpdate(GCMContext *gcm, unsig
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
PORT_SetError(SEC_ERROR_BAD_DATA);
- PORT_Memset(tag, 0, sizeof(tag));
- return SECFailure;
+ rv = SECFailure;
+ goto cleanup;
}
+cleanup:
+ tagBytes = 0;
PORT_Memset(tag, 0, sizeof(tag));
+ intag = NULL;
+ len = 0;
+ if (rv != SECSuccess) {
+ return rv;
+ }
+
/* finish the decryption */
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, AES_BLOCK_SIZE);

32
nss-no-rpath.patch Normal file
View File

@ -0,0 +1,32 @@
# HG changeset patch
# Parent 796f0564feb6df3081b8ff7cb3a0d354053b3d2c
Index: security/nss/cmd/platlibs.mk
===================================================================
RCS file: /cvsroot/mozilla/security/nss/cmd/platlibs.mk,v
retrieving revision 1.71
diff --git a/cmd/platlibs.mk b/cmd/platlibs.mk
--- a/cmd/platlibs.mk
+++ b/cmd/platlibs.mk
@@ -13,19 +13,19 @@ ifeq ($(USE_64), 1)
EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1/64:/usr/lib/mps/64'
else
EXTRA_SHARED_LIBS += -R '$$ORIGIN/../lib:/usr/lib/mps/secv1:/usr/lib/mps'
endif
endif
ifeq ($(OS_ARCH), Linux)
ifeq ($(USE_64), 1)
-EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:/opt/sun/private/lib64:$$ORIGIN/../lib'
+#EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib64:/opt/sun/private/lib64:$$ORIGIN/../lib'
else
-EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib:/opt/sun/private/lib'
+#EXTRA_SHARED_LIBS += -Wl,-rpath,'$$ORIGIN/../lib:/opt/sun/private/lib'
endif
endif
endif # BUILD_SUN_PKG
ifdef NSS_DISABLE_DBM
DBMLIB = $(NULL)
else

17
nss-opt.patch Normal file
View File

@ -0,0 +1,17 @@
Index: nss/coreconf/Linux.mk
===================================================================
--- nss.orig/coreconf/Linux.mk
+++ nss/coreconf/Linux.mk
@@ -114,11 +114,7 @@ LIBC_TAG = _glibc
endif
ifdef BUILD_OPT
-ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE))
- OPTIMIZER = -Os
-else
- OPTIMIZER = -O2
-endif
+ OPTIMIZER = $(OPT_FLAGS)
ifdef MOZ_DEBUG_SYMBOLS
ifdef MOZ_DEBUG_FLAGS
OPTIMIZER += $(MOZ_DEBUG_FLAGS)

29
nss-sqlitename.patch Normal file
View File

@ -0,0 +1,29 @@
# HG changeset patch
# User M. Sirringhaus <msirringhaus@suse.de>
# Date 1590407652 -7200
# Mon May 25 13:54:12 2020 +0200
# Node ID b1d7045b31cf4090c0b78003c77a2eb6c8c57436
# Parent e3d3ed5e142b172289d9d4a1c7fc63dfd4359410
Index: security/nss/lib/sqlite/manifest.mn
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/sqlite/manifest.mn,v
retrieving revision 1.5
diff -r e3d3ed5e142b -r b1d7045b31cf lib/sqlite/manifest.mn
--- a/lib/sqlite/manifest.mn Mon Sep 18 11:24:00 2017 +0200
+++ b/lib/sqlite/manifest.mn Mon May 25 13:54:12 2020 +0200
@@ -6,11 +6,11 @@
MODULE = nss
-LIBRARY_NAME = sqlite
+LIBRARY_NAME = nsssqlite
LIBRARY_VERSION = 3
-MAPFILE = $(OBJDIR)/$(LIBRARY_NAME).def
+MAPFILE = $(OBJDIR)/sqlite.def
RES = $(NULL)
-
+MAPFILE_SOURCE = sqlite.def
DEFINES += -DSQLITE_THREADSAFE=1
PRIVATE_EXPORTS = \

118
nss-util-config.in Normal file
View File

@ -0,0 +1,118 @@
#!/bin/sh
prefix=@prefix@
major_version=@MOD_MAJOR_VERSION@
minor_version=@MOD_MINOR_VERSION@
patch_version=@MOD_PATCH_VERSION@
usage()
{
cat <<EOF
Usage: nss-util-config [OPTIONS] [LIBRARIES]
Options:
[--prefix[=DIR]]
[--exec-prefix[=DIR]]
[--includedir[=DIR]]
[--libdir[=DIR]]
[--version]
[--libs]
[--cflags]
Dynamic Libraries:
nssutil
EOF
exit $1
}
if test $# -eq 0; then
usage 1 1>&2
fi
lib_nssutil=yes
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
;;
--prefix)
echo_prefix=yes
;;
--exec-prefix=*)
exec_prefix=$optarg
;;
--exec-prefix)
echo_exec_prefix=yes
;;
--includedir=*)
includedir=$optarg
;;
--includedir)
echo_includedir=yes
;;
--libdir=*)
libdir=$optarg
;;
--libdir)
echo_libdir=yes
;;
--version)
echo ${major_version}.${minor_version}.${patch_version}
;;
--cflags)
echo_cflags=yes
;;
--libs)
echo_libs=yes
;;
*)
usage 1 1>&2
;;
esac
shift
done
# Set variables that may be dependent upon other variables
if test -z "$exec_prefix"; then
exec_prefix=@exec_prefix@
fi
if test -z "$includedir"; then
includedir=@includedir@
fi
if test -z "$libdir"; then
libdir=@libdir@
fi
if test "$echo_prefix" = "yes"; then
echo $prefix
fi
if test "$echo_exec_prefix" = "yes"; then
echo $exec_prefix
fi
if test "$echo_includedir" = "yes"; then
echo $includedir
fi
if test "$echo_libdir" = "yes"; then
echo $libdir
fi
if test "$echo_cflags" = "yes"; then
echo -I$includedir
fi
if test "$echo_libs" = "yes"; then
libdirs="-Wl,-rpath-link,$libdir -L$libdir"
if test -n "$lib_nssutil"; then
libdirs="$libdirs -lnssutil${major_version}"
fi
echo $libdirs
fi

11
nss-util.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=/usr
exec_prefix=${prefix}
libdir=%LIBDIR%
includedir=${prefix}/include/nss3
Name: NSS-UTIL
Description: Network Security Services Utility Library
Version: %VERSION%
Requires: nspr >= %NSPR_VERSION%
Libs: -lnssutil3
Cflags: -I${includedir}

11
nss.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=/usr
exec_prefix=${prefix}
libdir=%LIBDIR%
includedir=${prefix}/include/nss3
Name: NSS
Description: Network Security Services
Version: %VERSION%
Requires: nspr >= %NSPR_VERSION%, nss-util >= %VERSION%
Libs: -lssl3 -lsmime3 -lnss3
Cflags: -I${includedir}

5
pkcs11.txt Normal file
View File

@ -0,0 +1,5 @@
library=libnsssysinit.so
name=NSS Internal PKCS #11 Module
parameters=configdir='sql:/etc/pki/nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''
NSS=Flags=internal,moduleDBOnly,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})

55
setup-nsssysinit.sh Normal file
View File

@ -0,0 +1,55 @@
#!/bin/sh
#
# Turns on or off the nss-sysinit module db by editing the
# global PKCS #11 congiguration file.
#
# This script can be invoked by the user as super user.
# It is invoked at nss-sysinit post install time with argument on
# and at nss-sysinit pre uninstall with argument off.
#
usage()
{
cat <<EOF
Usage: setup-nsssysinit [on|off]
on - turns on nsssysinit
off - turns off nsssysinit
EOF
exit $1
}
# validate
if test $# -eq 0; then
usage 1 1>&2
fi
# the system-wide configuration file
p11conf="/etc/pki/nssdb/pkcs11.txt"
# must exist, otherwise report it and exit with failure
if [ ! -f $p11conf ]; then
echo "Could not find ${p11conf}"
exit 1
fi
on="1"
case "$1" in
on | ON )
cat ${p11conf} | \
sed -e 's/^library=$/library=libnsssysinit.so/' \
-e '/^NSS/s/\(Flags=internal\)\(,[^m]\)/\1,moduleDBOnly\2/' > \
${p11conf}.on
mv ${p11conf}.on ${p11conf}
;;
off | OFF )
if [ ! `grep "^library=libnsssysinit" ${p11conf}` ]; then
exit 0
fi
cat ${p11conf} | \
sed -e 's/^library=libnsssysinit.so/library=/' \
-e '/^NSS/s/Flags=internal,moduleDBOnly/Flags=internal/' > \
${p11conf}.off
mv ${p11conf}.off ${p11conf}
;;
* )
usage 1 1>&2
;;
esac

17
system-nspr.patch Normal file
View File

@ -0,0 +1,17 @@
diff --git a/Makefile b/Makefile
index eb4ed1a..de9c13d 100644
--- a/Makefile
+++ b/Makefile
@@ -48,12 +48,10 @@ include $(CORE_DEPTH)/coreconf/rules.mk
#######################################################################
nss_build_all:
- $(MAKE) build_nspr
$(MAKE) all
$(MAKE) latest
nss_clean_all:
- $(MAKE) clobber_nspr
$(MAKE) clobber
NSPR_CONFIG_STATUS = $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)/config.status