commit a09480012ab82a03290f9cf82abba37bd01ae66d Author: CentOS Sources Date: Tue Nov 5 15:19:29 2019 -0500 import nss-3.44.0-8.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a250c86 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +SOURCES/blank-cert8.db +SOURCES/blank-cert9.db +SOURCES/blank-key3.db +SOURCES/blank-key4.db +SOURCES/blank-secmod.db +SOURCES/cert8.db.xml +SOURCES/cert9.db.xml +SOURCES/key3.db.xml +SOURCES/key4.db.xml +SOURCES/nss-3.44.tar.gz +SOURCES/nss-config.xml +SOURCES/nss-softokn-cavs-1.0.tar.gz +SOURCES/secmod.db.xml +SOURCES/setup-nsssysinit.xml diff --git a/.nss.metadata b/.nss.metadata new file mode 100644 index 0000000..bd0ba0b --- /dev/null +++ b/.nss.metadata @@ -0,0 +1,14 @@ +d272a7b58364862613d44261c5744f7a336bf177 SOURCES/blank-cert8.db +b5570125fbf6bfb410705706af48217a0817c03a SOURCES/blank-cert9.db +7f78b5bcecdb5005e7b803604b2ec9d1a9df2fb5 SOURCES/blank-key3.db +f9c9568442386da370193474de1b25c3f68cdaf6 SOURCES/blank-key4.db +bd748cf6e1465a1bbe6e751b72ffc0076aff0b50 SOURCES/blank-secmod.db +6a43a6788fff0f2a967051209adbd354fad4c346 SOURCES/cert8.db.xml +ea6705e15999bdc6365f05b3d66f9c1d49677f84 SOURCES/cert9.db.xml +24c123810543ff0f6848647d6d910744e275fb01 SOURCES/key3.db.xml +af51b16a56fda1f7525a0eed3ecbdcbb4133be0c SOURCES/key4.db.xml +44a83b1bf4efd27605177ecdbf217e579ae8c8ae SOURCES/nss-3.44.tar.gz +2905c9b06e7e686c9e3c0b5736a218766d4ae4c2 SOURCES/nss-config.xml +d8a7f044570732caf4ed06fd44a63b3e86ea2a16 SOURCES/nss-softokn-cavs-1.0.tar.gz +ca9ebf79c1437169a02527c18b1e3909943c4be9 SOURCES/secmod.db.xml +bcbe05281b38d843273f91ae3f9f19f70c7d97b3 SOURCES/setup-nsssysinit.xml diff --git a/SOURCES/iquote.patch b/SOURCES/iquote.patch new file mode 100644 index 0000000..6e4adcd --- /dev/null +++ b/SOURCES/iquote.patch @@ -0,0 +1,13 @@ +diff -up nss/coreconf/location.mk.iquote nss/coreconf/location.mk +--- nss/coreconf/location.mk.iquote 2017-07-27 16:09:32.000000000 +0200 ++++ nss/coreconf/location.mk 2017-09-06 13:23:14.633611555 +0200 +@@ -75,4 +75,9 @@ ifndef SQLITE_LIB_NAME + SQLITE_LIB_NAME = sqlite3 + endif + ++# Prefer in-tree headers over system headers ++ifdef IN_TREE_FREEBL_HEADERS_FIRST ++ INCLUDES += -iquote $(DIST)/../public/nss -iquote $(DIST)/../private/nss ++endif ++ + MK_LOCATION = included diff --git a/SOURCES/nss-3.44-missing-softokn-kdf.patch b/SOURCES/nss-3.44-missing-softokn-kdf.patch new file mode 100644 index 0000000..b285e9e --- /dev/null +++ b/SOURCES/nss-3.44-missing-softokn-kdf.patch @@ -0,0 +1,560 @@ +diff -up ./gtests/pk11_gtest/manifest.mn.missing_kdf ./gtests/pk11_gtest/manifest.mn +--- ./gtests/pk11_gtest/manifest.mn.missing_kdf 2019-08-08 10:22:53.072100034 -0700 ++++ ./gtests/pk11_gtest/manifest.mn 2019-08-08 10:23:33.424061237 -0700 +@@ -14,6 +14,7 @@ CPPSRCS = \ + pk11_encrypt_derive_unittest.cc \ + pk11_export_unittest.cc \ + pk11_import_unittest.cc \ ++ pk11_kdf_unittest.cc \ + pk11_pbkdf2_unittest.cc \ + pk11_prf_unittest.cc \ + pk11_prng_unittest.cc \ +diff -up ./gtests/pk11_gtest/pk11_gtest.gyp.missing_kdf ./gtests/pk11_gtest/pk11_gtest.gyp +--- ./gtests/pk11_gtest/pk11_gtest.gyp.missing_kdf 2019-08-08 10:23:13.298080588 -0700 ++++ ./gtests/pk11_gtest/pk11_gtest.gyp 2019-08-08 10:23:49.728045561 -0700 +@@ -19,6 +19,7 @@ + 'pk11_ecdsa_unittest.cc', + 'pk11_encrypt_derive_unittest.cc', + 'pk11_import_unittest.cc', ++ 'pk11_kdf_unittest.cc', + 'pk11_pbkdf2_unittest.cc', + 'pk11_prf_unittest.cc', + 'pk11_prng_unittest.cc', +diff -up ./gtests/pk11_gtest/pk11_kdf_unittest.cc.missing_kdf ./gtests/pk11_gtest/pk11_kdf_unittest.cc +--- ./gtests/pk11_gtest/pk11_kdf_unittest.cc.missing_kdf 2019-08-07 14:23:28.657960569 -0700 ++++ ./gtests/pk11_gtest/pk11_kdf_unittest.cc 2019-08-08 10:22:38.015114511 -0700 +@@ -0,0 +1,509 @@ ++/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* vim: set ts=2 et sw=2 tw=80: */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this file, ++ * You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include ++#include "nss.h" ++#include "pk11pub.h" ++ ++#include "cpputil.h" ++ ++#include "gtest/gtest.h" ++ ++namespace nss_test { ++ ++const size_t kGxySize = 256; ++const size_t kSeedSize = 8; ++const size_t kKeySize = 64; ++const size_t kLongKeySize = 1056; ++const size_t kAesXcbcLen = 16; ++const size_t kSha1Len = 20; ++const size_t kSha224Len = 28; ++const size_t kSha256Len = 32; ++const size_t kSha384Len = 48; ++const size_t kSha512Len = 64; ++ ++// This is not the right size for anything ++const size_t kIncorrectSize = 17; ++ ++const uint8_t kGxyData[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, ++ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, ++ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, ++ 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, ++ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, ++ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, ++ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, ++ 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, ++ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x21, 0x22, 0x23, ++ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, ++ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, ++ 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, ++ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, ++ 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, ++ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, ++ 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, ++ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, ++ 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, ++ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, ++ 0xfc, 0xfd, 0xfe, 0xff}; ++ ++const uint8_t kKeyData[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, ++ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, ++ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, ++ 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, ++ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, ++ 0x3c, 0x3d, 0x3e, 0x3f}; ++ ++const uint8_t kSeed[] = { ++ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, ++ 0xfc, 0xfd, 0xfe, 0xff, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, ++ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xd0, 0xd1, 0xd2, 0xd3}; ++ ++const uint8_t kExpectedOutputIkeSha256[] = { ++ 0xd3, 0x9d, 0xb2, 0x77, 0x4b, 0x7f, 0xea, 0x81, 0xfc, 0xe5, 0x22, 0xb7, ++ 0xdf, 0xa5, 0x65, 0x15, 0xc9, 0x8f, 0x89, 0x45, 0xda, 0xd9, 0x5d, 0x12, ++ 0xbb, 0x52, 0xb6, 0x3b, 0xf4, 0x4d, 0xaf, 0x16}; ++ ++const uint8_t kExpectedOutputIke1Sha256[] = { ++ 0x25, 0x45, 0x68, 0xd2, 0x98, 0x96, 0xa3, 0xda, 0x89, 0x76, 0x06, 0x01, ++ 0xd0, 0xce, 0xf8, 0x05, 0x26, 0x3f, 0xaf, 0x95, 0x92, 0x48, 0x02, 0x0e, ++ 0x39, 0x75, 0x94, 0x00, 0x22, 0xd8, 0x5a, 0x50}; ++ ++const uint8_t kExpectedOutputIkePlusSha256[] = { ++ 0x03, 0x1e, 0xe7, 0x13, 0x6e, 0x58, 0x11, 0xc4, 0x81, 0x56, 0x42, 0x3c, ++ 0x3c, 0xaa, 0xdb, 0xad, 0x8a, 0x84, 0xdc, 0xa3, 0x0f, 0xe7, 0x67, 0x55, ++ 0x9c, 0x9f, 0xb8, 0x57, 0xa9, 0x5b, 0x41, 0x53, 0x86, 0xe0, 0xb3, 0x21, ++ 0x08, 0x1b, 0x38, 0x24, 0xce, 0xef, 0x7c, 0x89, 0x0d, 0xa7, 0xae, 0x14, ++ 0x58, 0xbd, 0x79, 0x9c, 0x32, 0x25, 0x7f, 0x3e, 0xbd, 0xe1, 0xfb, 0x3a, ++ 0x38, 0x51, 0x05, 0xaa, 0xc8, 0x37, 0x3e, 0x4e, 0x9b, 0x70, 0xb8, 0xe2, ++ 0x21, 0xe7, 0x12, 0xb3, 0xf7, 0x64, 0x21, 0x9d, 0x52, 0x38, 0x41, 0xfb, ++ 0x54, 0xaf, 0x59, 0xc3, 0xab, 0xf3, 0x7f, 0x64, 0xee, 0x17, 0xf5, 0xa8, ++ 0x2b, 0xdf, 0x2d, 0xd3, 0x29, 0x0e, 0x4f, 0x31, 0x54, 0x25, 0x4e, 0x65, ++ 0x52, 0xdf, 0x66, 0xfd, 0x49, 0x85, 0x1f, 0x87, 0x71, 0xa1, 0x5c, 0xfa, ++ 0x99, 0xf5, 0x21, 0x9a, 0xbc, 0x55, 0x5b, 0x1c, 0x19, 0xd9, 0x4b, 0x42, ++ 0xc5, 0xa0, 0xed, 0x1a, 0x1e, 0xf0, 0x04, 0x52, 0xb3, 0xd0, 0x0f, 0x48, ++ 0x45, 0x00, 0xdc, 0x94, 0xae, 0xd8, 0x70, 0x2e, 0xdd, 0x12, 0xe1, 0x66, ++ 0x72, 0xc2, 0x39, 0xd2, 0xc6, 0xfa, 0xdd, 0x8c, 0x11, 0x9c, 0x9d, 0x60, ++ 0xd1, 0x08, 0x79, 0x62, 0xbb, 0x97, 0x45, 0x38, 0x2d, 0x83, 0x9c, 0x2e, ++ 0x8f, 0x88, 0xa3, 0xad, 0x5b, 0x8e, 0x4e, 0x0e, 0xdb, 0xee, 0xaf, 0x1d, ++ 0xf6, 0xe7, 0x7e, 0x28, 0xc5, 0xcf, 0x0c, 0xd9, 0xee, 0xde, 0xc8, 0x87, ++ 0x00, 0xfe, 0x02, 0xd8, 0x30, 0xa6, 0x68, 0xec, 0x51, 0x22, 0xac, 0x4c, ++ 0x38, 0x0f, 0xbb, 0x5c, 0xcb, 0xd5, 0x93, 0xda, 0xea, 0xd0, 0x1b, 0x41, ++ 0x85, 0x8d, 0x12, 0x56, 0xbb, 0x90, 0x62, 0xc9, 0x91, 0x62, 0xf8, 0x29, ++ 0x9a, 0x4f, 0xd8, 0x5e, 0x7d, 0x1f, 0x69, 0xe8, 0x23, 0x53, 0x26, 0x98, ++ 0x98, 0x88, 0xfa, 0x14, 0xdc, 0xa3, 0x0f, 0xc7, 0x58, 0xb2, 0x6d, 0xa5, ++ 0x34, 0x53, 0xb5, 0xc3, 0xcc, 0xbb, 0xd7, 0xd4, 0x80, 0xf3, 0x8c, 0x79, ++ 0xd2, 0xac, 0x12, 0xa5, 0xf9, 0x99, 0xe7, 0x1b, 0x46, 0x16, 0x02, 0x6a, ++ 0xa3, 0xc5, 0x20, 0xb5, 0x5a, 0x55, 0xbd, 0xac, 0x70, 0xf1, 0x5b, 0xe4, ++ 0x45, 0x12, 0x7e, 0xcf, 0x12, 0xbf, 0x53, 0x7e, 0x3d, 0xbe, 0x53, 0x77, ++ 0xc4, 0x2c, 0x17, 0x5f, 0xe5, 0xb9, 0x73, 0x01, 0x5d, 0x9b, 0x34, 0x3c, ++ 0x45, 0xf0, 0xa4, 0x91, 0xaf, 0x34, 0xa2, 0xd6, 0x0a, 0x14, 0x98, 0x2c, ++ 0x91, 0xd5, 0x8f, 0x12, 0xde, 0x7c, 0x61, 0xd8, 0x42, 0x07, 0x42, 0x1a, ++ 0x01, 0x2b, 0xf6, 0x54, 0xd1, 0xde, 0x6d, 0x9c, 0x8b, 0x51, 0x81, 0x3e, ++ 0x01, 0xd1, 0xfb, 0x5a, 0xcd, 0xf0, 0xeb, 0xcc, 0x03, 0xe2, 0xc1, 0x31, ++ 0x92, 0x11, 0x88, 0x1f, 0xec, 0x81, 0x07, 0x78, 0x89, 0x89, 0x29, 0x19, ++ 0x3f, 0x75, 0x01, 0x0e, 0x73, 0xbc, 0x1e, 0x76, 0x23, 0x80, 0x36, 0xaa, ++ 0x2a, 0xd0, 0x77, 0x57, 0x6a, 0xea, 0xe2, 0xdb, 0xed, 0x17, 0x79, 0x3d, ++ 0x8b, 0x8a, 0xbe, 0x32, 0x90, 0x2e, 0x1c, 0x00, 0xc2, 0x27, 0xb5, 0x64, ++ 0x7c, 0xc3, 0xca, 0xb8, 0xaf, 0xcb, 0x17, 0x29, 0xec, 0x00, 0x5b, 0x83, ++ 0x9f, 0xfe, 0x8b, 0xb6, 0x6f, 0x01, 0x23, 0x6b, 0xb3, 0xaa, 0x34, 0x3f, ++ 0x5c, 0x66, 0x7c, 0xec, 0x15, 0x5a, 0xa9, 0x3c, 0xe2, 0xef, 0xcb, 0xe5, ++ 0x79, 0xfa, 0xf2, 0x7c, 0x4e, 0x0f, 0x70, 0x41, 0xa4, 0x09, 0x07, 0x30, ++ 0xbd, 0x28, 0x3f, 0x30, 0xd3, 0xc2, 0xbd, 0x06, 0x5e, 0x21, 0xbd, 0x20, ++ 0xae, 0xa4, 0xa9, 0x7d, 0x91, 0xe8, 0x9d, 0x0a, 0x81, 0x02, 0xf7, 0xd6, ++ 0x7c, 0x1f, 0xb6, 0xa5, 0x40, 0xb6, 0x25, 0xac, 0xce, 0x77, 0x20, 0xfa, ++ 0x71, 0x79, 0x21, 0x94, 0xcd, 0x63, 0xcf, 0x62, 0xd4, 0xda, 0xc6, 0xe8, ++ 0x3c, 0xdb, 0x86, 0x1e, 0x8d, 0x2d, 0x12, 0xf6, 0xea, 0xb0, 0xed, 0xf8, ++ 0xfa, 0xc6, 0x37, 0xee, 0xca, 0x11, 0x1a, 0xac, 0x95, 0xf6, 0xe3, 0x02, ++ 0x97, 0xba, 0xb2, 0xb2, 0x02, 0x82, 0xbe, 0x32, 0xa3, 0xe8, 0xf4, 0xae, ++ 0x4e, 0xaf, 0x47, 0xb9, 0xe7, 0x91, 0x18, 0x90, 0xd8, 0xcb, 0x59, 0xed, ++ 0xc2, 0x47, 0x6d, 0xe1, 0x9d, 0x74, 0xe6, 0xc7, 0xc0, 0xdc, 0x82, 0x5b, ++ 0x6a, 0x7d, 0x1c, 0x58, 0xc8, 0x3d, 0x7d, 0xed, 0xdd, 0x60, 0x91, 0x9e, ++ 0x68, 0x6e, 0x56, 0x33, 0x8b, 0xca, 0x35, 0xf8, 0x96, 0x67, 0x22, 0x3a, ++ 0xb9, 0x02, 0xe9, 0x7c, 0xb1, 0xca, 0x25, 0xc2, 0xc8, 0xc7, 0xd8, 0x71, ++ 0xfa, 0xfa, 0x76, 0xeb, 0x1d, 0x52, 0x75, 0xc6, 0x56, 0xf3, 0x1a, 0xd3, ++ 0xda, 0xe4, 0x49, 0x7b, 0xd0, 0x77, 0x72, 0x06, 0xe7, 0xb9, 0xd9, 0x06, ++ 0x87, 0x43, 0x6a, 0x52, 0xee, 0x3a, 0x71, 0x6e, 0x51, 0x8d, 0x55, 0x7a, ++ 0xb1, 0x62, 0x75, 0xac, 0xa9, 0x89, 0x77, 0x93, 0x40, 0xef, 0x66, 0x44, ++ 0x08, 0x49, 0xbb, 0xdb, 0x85, 0x0b, 0xd3, 0xfa, 0x37, 0x27, 0x41, 0xd1, ++ 0x57, 0xc3, 0x95, 0xaa, 0x85, 0x5a, 0x43, 0x74, 0x39, 0x72, 0x08, 0xdf, ++ 0x58, 0xe1, 0xf7, 0x95, 0x6c, 0xc1, 0xb1, 0x9b, 0x21, 0x53, 0xc1, 0xf9, ++ 0xcc, 0x74, 0xf9, 0x62, 0xa4, 0xa0, 0x34, 0x22, 0xaa, 0x84, 0x78, 0x49, ++ 0x50, 0xa9, 0x8e, 0x7b, 0xfa, 0xaa, 0xc2, 0xe8, 0xae, 0x34, 0x3d, 0xa7, ++ 0xe1, 0x5a, 0x14, 0xa6, 0xd7, 0x6c, 0x67, 0xc7, 0x5e, 0xda, 0x79, 0x36, ++ 0x57, 0x85, 0x5e, 0x09, 0xa2, 0x1f, 0x96, 0x5a, 0x71, 0xc2, 0xfe, 0x57, ++ 0x5c, 0x4c, 0xe8, 0xbf, 0x9b, 0x5c, 0xd7, 0x06, 0x09, 0xb5, 0x63, 0x93, ++ 0x7e, 0xee, 0x65, 0xef, 0x88, 0xe1, 0x60, 0x3e, 0x50, 0x84, 0x39, 0xb9, ++ 0xae, 0xab, 0xad, 0xee, 0x31, 0x04, 0x7f, 0xed, 0x78, 0x35, 0xc0, 0x14, ++ 0xa6, 0xc3, 0xeb, 0x3c, 0xd7, 0xc3, 0xb3, 0x6b, 0x58, 0x63, 0x7e, 0xa8, ++ 0xc9, 0xb9, 0x23, 0xd3, 0xe5, 0xe7, 0xcc, 0x84, 0x63, 0xc8, 0xbd, 0x31, ++ 0x9f, 0x02, 0x4e, 0x74, 0x98, 0xba, 0x8a, 0x0c, 0x80, 0xab, 0x10, 0xc4, ++ 0xb2, 0x61, 0xad, 0x3d, 0x93, 0x9d, 0xdc, 0x76, 0xe5, 0x0e, 0x2e, 0x4b, ++ 0x81, 0x3b, 0x1f, 0xd3, 0x54, 0xc0, 0x2a, 0xde, 0x0e, 0x1d, 0x59, 0x31, ++ 0x5c, 0x28, 0xf8, 0x75, 0xfc, 0x71, 0x2e, 0xc1, 0x85, 0x90, 0x23, 0xfd, ++ 0x2e, 0x8b, 0xb9, 0x52, 0x1a, 0xdf, 0x61, 0x54, 0x9b, 0x43, 0xa6, 0x8d, ++ 0x5f, 0xd0, 0x52, 0x0b, 0x66, 0xbc, 0xf5, 0x1a, 0xce, 0x58, 0xef, 0xb3, ++ 0x1d, 0x8d, 0x4b, 0x1b, 0xf3, 0x8e, 0xe6, 0x68, 0xc3, 0xd5, 0x95, 0x42, ++ 0xf5, 0xb0, 0x73, 0x2c, 0x31, 0x71, 0x20, 0xf5, 0xdc, 0xbf, 0x56, 0x72, ++ 0x53, 0xf9, 0xfe, 0xfa, 0x19, 0xdc, 0x46, 0xd1, 0x2b, 0xe3, 0xdb, 0x50, ++ 0xec, 0x14, 0xee, 0x70, 0xcc, 0xe6, 0x11, 0x75, 0xb4, 0x63, 0xfc, 0xd1, ++ 0x8f, 0x54, 0xfa, 0xcc, 0x99, 0xcc, 0xb8, 0x61, 0xa7, 0x33, 0x18, 0xa2, ++ 0x17, 0xee, 0xb1, 0x82, 0x3d, 0x6a, 0x8d, 0x63, 0xe0, 0x15, 0x1b, 0x5c, ++ 0x20, 0x53, 0x33, 0xa7, 0x85, 0x17, 0x81, 0xba, 0x18, 0x2a, 0x73, 0x00, ++ 0x1e, 0x3e, 0x2c, 0xb5, 0x5f, 0x4e, 0x82, 0xa8, 0x09, 0xa0, 0x22, 0xdc, ++ 0xc4, 0x76, 0x7c, 0x66, 0xf4, 0x78, 0xa1, 0x0a, 0xf7, 0x39, 0x06, 0x0a, ++ 0xd7, 0x43, 0x72, 0x12, 0x3b, 0x8e, 0x7e, 0x62, 0x4f, 0x5a, 0x03, 0xe5, ++ 0x22, 0x97, 0xdc, 0xbb, 0xaa, 0xa2, 0xc0, 0x03, 0x8e, 0x60, 0xd1, 0x61, ++ 0xc7, 0xef, 0x0f, 0x54, 0x43, 0x4e, 0x38, 0xda, 0xb6, 0xe2, 0x5b, 0x0e, ++ 0x45, 0xae, 0x39, 0x86, 0x85, 0x25, 0x30, 0xb1, 0x9d, 0xda, 0xdb, 0x70, ++ 0xa7, 0xe5, 0x77, 0xb8, 0x47, 0xaa, 0xe7, 0x3e, 0xe8, 0x5a, 0x96, 0xc6, ++ 0x0a, 0x0b, 0x07, 0x8d, 0x6d, 0xeb, 0x80, 0x0c, 0xd9, 0x80, 0x2d, 0x4d}; ++ ++const uint8_t kExpectedOutputIkeAppBSha256[] = { ++ 0xe7, 0x11, 0x54, 0x6e, 0x3f, 0xaa, 0xd4, 0xc7, 0xc4, 0xaa, 0x75, 0x6b, ++ 0xc2, 0x6c, 0xad, 0x6a, 0xbe, 0xa8, 0x24, 0x19, 0x84, 0xa0, 0xf6, 0xb0, ++ 0x83, 0x9c, 0x70, 0xca, 0x61, 0xc4, 0xef, 0x88, 0xd7, 0xd5, 0xb7, 0x2e, ++ 0x45, 0x32, 0xe1, 0x1d, 0x12, 0x38, 0xfb, 0xcb, 0x08, 0x54, 0xc7, 0xdb, ++ 0xc4, 0x80, 0x2d, 0xd4, 0xf3, 0xbf, 0x51, 0x80, 0xf3, 0xa6, 0xdf, 0x77, ++ 0x51, 0x61, 0xd8, 0xdb, 0x98, 0x2c, 0xc2, 0xe6, 0x72, 0x36, 0x90, 0xf9, ++ 0xd2, 0x2a, 0x6d, 0x6c, 0xeb, 0x10, 0x3f, 0xa0, 0xa3, 0xff, 0xe4, 0x8b, ++ 0x5a, 0x4a, 0x1b, 0xec, 0xb0, 0x48, 0xb0, 0xed, 0x16, 0x8a, 0x89, 0x31, ++ 0x96, 0x5e, 0xa9, 0x11, 0x1f, 0x28, 0x68, 0x07, 0xf1, 0xa3, 0x2b, 0x01, ++ 0x4f, 0x0b, 0x73, 0x78, 0x3b, 0xca, 0x4f, 0x8f, 0x34, 0xc0, 0x21, 0x14, ++ 0xe3, 0xdf, 0xa1, 0xf7, 0x05, 0x63, 0xcb, 0x74, 0x7a, 0x90, 0x59, 0x19, ++ 0xc9, 0xa9, 0x47, 0xcf, 0xe7, 0xbe, 0x04, 0xa7, 0x0c, 0x32, 0xdd, 0x34, ++ 0x07, 0x8f, 0x4f, 0xb5, 0x75, 0xfb, 0xb9, 0x06, 0xd2, 0x55, 0x08, 0xce, ++ 0x0a, 0x47, 0xc2, 0x64, 0x5f, 0xd5, 0xab, 0x55, 0x2a, 0x1a, 0x7e, 0xbd, ++ 0xd5, 0x6d, 0x43, 0x89, 0x3c, 0x53, 0xde, 0x01, 0xfe, 0x19, 0x19, 0xc3, ++ 0xaf, 0xa0, 0x64, 0x2d, 0x7e, 0xe1, 0x7e, 0x31, 0x61, 0xf9, 0xe6, 0x4f, ++ 0x56, 0xc3, 0xc9, 0x7e, 0x92, 0xd7, 0x88, 0x58, 0x1a, 0x7f, 0x3c, 0x3e, ++ 0xae, 0x3f, 0x86, 0xec, 0xb2, 0xaa, 0x8b, 0xaf, 0x22, 0x49, 0xa5, 0x3d, ++ 0xc2, 0xb1, 0x94, 0x0f, 0x5b, 0x08, 0x49, 0xac, 0x23, 0xa4, 0x79, 0x33, ++ 0xde, 0xfb, 0x8b, 0xd3, 0xe6, 0x6c, 0x83, 0xce, 0x01, 0xc7, 0xb4, 0x23, ++ 0x5c, 0x6d, 0x81, 0xda, 0x70, 0x71, 0x43, 0x9c, 0x94, 0x6a, 0x9e, 0x03, ++ 0x6d, 0xc3, 0x71, 0x69, 0x53, 0x83, 0x89, 0x08, 0x1b, 0x2b, 0x4b, 0xa8, ++ 0x4a, 0x2a, 0xdf, 0x26, 0xaf, 0xc3, 0x8e, 0x59, 0x15, 0xa7, 0x24, 0x8f, ++ 0x3c, 0xad, 0x08, 0xf2, 0x12, 0xe1, 0x42, 0x41, 0x0c, 0xcb, 0x3e, 0xf4, ++ 0x71, 0xab, 0xb1, 0x16, 0x2c, 0xb7, 0xe1, 0x3f, 0x94, 0x03, 0x01, 0x78, ++ 0xd7, 0x84, 0x1d, 0x63, 0x03, 0xfe, 0x4b, 0x3f, 0x40, 0xce, 0x30, 0x75, ++ 0x10, 0xd1, 0xa4, 0xd3, 0x3c, 0x68, 0x9b, 0xc0, 0x6b, 0xdc, 0xe1, 0xda, ++ 0x06, 0x41, 0x71, 0x20, 0x88, 0x82, 0x60, 0x2e, 0x48, 0x93, 0x78, 0x30, ++ 0xb4, 0xb9, 0xe3, 0x88, 0x79, 0xf7, 0x0d, 0x0b, 0xa4, 0xae, 0x2e, 0x7b, ++ 0x00, 0x82, 0x49, 0xbf, 0xe8, 0x07, 0xb4, 0x51, 0xd9, 0xa0, 0xf7, 0x8f, ++ 0xe6, 0x24, 0x17, 0xd0, 0xa5, 0x58, 0xcc, 0x37, 0xf2, 0x86, 0x6e, 0xc2, ++ 0xf0, 0xf0, 0x87, 0x64, 0xfa, 0x6e, 0x94, 0x99, 0x1a, 0xbc, 0xd9, 0xea, ++ 0x48, 0x07, 0x38, 0x2e, 0x79, 0x61, 0x82, 0x69, 0x09, 0x6f, 0xbc, 0x8e, ++ 0x44, 0x38, 0x0e, 0xc9, 0x6f, 0xcd, 0xb7, 0x39, 0x92, 0x02, 0x27, 0x23, ++ 0x35, 0xcf, 0x4f, 0xf7, 0x52, 0x7b, 0x33, 0x93, 0xbd, 0x6c, 0x7c, 0xef, ++ 0x39, 0x4b, 0x1a, 0x9f, 0xdf, 0x8f, 0x5c, 0x5b, 0x7b, 0xdb, 0x6b, 0xfd, ++ 0x72, 0xe0, 0xb0, 0xc5, 0x97, 0x5b, 0x08, 0x6b, 0x17, 0x2f, 0x38, 0xd7, ++ 0xbe, 0xf8, 0xd7, 0x20, 0xf5, 0x33, 0x68, 0x69, 0x16, 0xe5, 0x08, 0x05, ++ 0x6c, 0x1b, 0xfa, 0xa8, 0x63, 0x55, 0xb4, 0x03, 0xb9, 0x89, 0xd7, 0x61, ++ 0xf3, 0x9a, 0xf6, 0x45, 0xb4, 0xb2, 0x16, 0x5d, 0xf3, 0x09, 0x7b, 0x09, ++ 0x09, 0x75, 0x0a, 0xbd, 0xdf, 0x7d, 0xe6, 0x1e, 0x07, 0xec, 0x7c, 0x14, ++ 0xac, 0x4b, 0x68, 0xa8, 0x44, 0x5f, 0x77, 0x36, 0xb8, 0x1d, 0x7c, 0x73, ++ 0x82, 0x80, 0xc2, 0x52, 0x55, 0x2c, 0x5d, 0xba, 0x53, 0x79, 0x45, 0xad, ++ 0x51, 0x98, 0xbb, 0x8a, 0xea, 0x4f, 0x19, 0x22, 0x22, 0x69, 0xd3, 0x3a, ++ 0x72, 0xd8, 0xe3, 0x37, 0xf4, 0x3b, 0xf3, 0xf1, 0x52, 0x48, 0x4d, 0xbf, ++ 0xa5, 0x7a, 0xef, 0x44, 0x53, 0x7b, 0x6e, 0x6c, 0xb7, 0x1a, 0xa8, 0x75, ++ 0xaf, 0xdb, 0x15, 0x05, 0x53, 0xc8, 0xb9, 0x9c, 0xea, 0x1a, 0xf7, 0x9d, ++ 0x9b, 0xb6, 0xa6, 0x5e, 0x0f, 0xf7, 0x49, 0x7e, 0xc9, 0x12, 0x38, 0x3d, ++ 0x78, 0xaf, 0x80, 0x3d, 0x76, 0x6d, 0x96, 0x4f, 0x06, 0xff, 0xdf, 0xc5, ++ 0x9c, 0x47, 0xbe, 0x3e, 0x3d, 0xc2, 0x2a, 0x41, 0x15, 0x7e, 0xbd, 0xab, ++ 0x12, 0x02, 0xfe, 0xa5, 0x4f, 0xb4, 0x1a, 0xf5, 0x6a, 0xed, 0xff, 0x50, ++ 0x5a, 0x56, 0x7b, 0x2f, 0xff, 0xff, 0x29, 0xb5, 0x77, 0xf4, 0x38, 0xb3, ++ 0x40, 0xd9, 0x17, 0x89, 0x43, 0x3f, 0x86, 0x29, 0x50, 0xce, 0x72, 0xde, ++ 0x55, 0x63, 0x06, 0x14, 0x50, 0xae, 0xc1, 0x49, 0x10, 0x55, 0x21, 0xeb, ++ 0x68, 0xe7, 0xfc, 0xc7, 0xf5, 0x92, 0xc5, 0xf2, 0xe2, 0xc9, 0xdb, 0x42, ++ 0x59, 0x44, 0x0e, 0xda, 0x23, 0x50, 0x62, 0xef, 0x6e, 0xae, 0x1c, 0x0e, ++ 0x93, 0x74, 0xa6, 0xdb, 0x4c, 0xc7, 0x4b, 0xa6, 0xe2, 0x3a, 0xe3, 0x03, ++ 0x22, 0xd1, 0xe4, 0x21, 0x13, 0x98, 0x6a, 0xeb, 0x43, 0xbf, 0xe6, 0x8a, ++ 0xfb, 0x28, 0x15, 0x47, 0x7e, 0xaa, 0x12, 0x60, 0x08, 0x23, 0xc6, 0x59, ++ 0xeb, 0xc1, 0x71, 0x18, 0x03, 0x16, 0x7f, 0x75, 0x5f, 0x65, 0x8a, 0x7f, ++ 0x1d, 0xae, 0x98, 0x94, 0xa4, 0xb1, 0xf5, 0xcc, 0x0a, 0x6f, 0x62, 0x79, ++ 0x27, 0x38, 0x32, 0x73, 0x90, 0xc8, 0x3f, 0x70, 0xf7, 0x44, 0xcf, 0xfd, ++ 0xc8, 0xfa, 0xcb, 0x3e, 0x73, 0x5f, 0x1d, 0xde, 0xb5, 0x73, 0x4d, 0x00, ++ 0x2a, 0xce, 0x77, 0x92, 0x17, 0x0f, 0xcf, 0xbf, 0x87, 0x78, 0xdc, 0xbc, ++ 0x83, 0xb3, 0x86, 0xd5, 0x32, 0xf5, 0x17, 0x73, 0xba, 0x90, 0xae, 0xc4, ++ 0x40, 0x25, 0x26, 0xde, 0x8c, 0x5e, 0xbb, 0x83, 0x0e, 0x27, 0xd5, 0x0a, ++ 0x4d, 0x89, 0xf0, 0xf3, 0x0f, 0xb5, 0x7d, 0xe3, 0x04, 0x6b, 0x5a, 0x59, ++ 0xf4, 0x0a, 0x23, 0xc9, 0xe9, 0xe5, 0x1c, 0x20, 0x43, 0xac, 0xe2, 0x61, ++ 0x10, 0x8d, 0x20, 0x83, 0xe7, 0x60, 0x28, 0x32, 0xd0, 0x15, 0x67, 0xf1, ++ 0xaf, 0xd4, 0xcb, 0x2a, 0xec, 0xc5, 0xe2, 0xe7, 0xa2, 0x57, 0x18, 0x3d, ++ 0x5e, 0xdd, 0x14, 0x88, 0x39, 0x59, 0x10, 0x9c, 0xa9, 0xf9, 0xd9, 0xb9, ++ 0xdd, 0x09, 0xb0, 0x2f, 0x5a, 0x30, 0x0f, 0xbf, 0x34, 0x8a, 0xf1, 0x62, ++ 0x40, 0x15, 0x4e, 0xe9, 0x69, 0x2f, 0x94, 0x87, 0x07, 0xf0, 0x01, 0xa2, ++ 0x8f, 0x11, 0xb9, 0x31, 0x4c, 0x2b, 0x7d, 0x7f, 0x6c, 0x04, 0xd6, 0x91, ++ 0x4d, 0x71, 0x6b, 0x8c, 0xa7, 0x47, 0xb1, 0x34, 0x34, 0x08, 0xda, 0x5b, ++ 0xcb, 0x82, 0xbb, 0x5b, 0x14, 0x27, 0x2a, 0x20, 0x25, 0xda, 0xbe, 0x1d, ++ 0x21, 0xa8, 0x68, 0x77, 0xf4, 0x17, 0xaf, 0x7f, 0x22, 0xda, 0xd4, 0xc6, ++ 0x38, 0x0c, 0xbe, 0xf1, 0xa5, 0x0b, 0x17, 0x83, 0x22, 0xb3, 0x5b, 0x12, ++ 0x1f, 0x0a, 0x18, 0x14, 0x46, 0xbf, 0x9b, 0xc0, 0x53, 0x7a, 0x83, 0x40, ++ 0xde, 0x1a, 0x9d, 0xf0, 0x3b, 0x66, 0x74, 0x01, 0xa1, 0xfc, 0x29, 0xde, ++ 0x08, 0x66, 0x85, 0x56, 0x2c, 0xc8, 0x30, 0xb7, 0x42, 0x1f, 0xa2, 0x32, ++ 0x28, 0xc4, 0xc5, 0xfe, 0xea, 0xb0, 0x4e, 0x81, 0x59, 0x74, 0x90, 0x93, ++ 0xb1, 0x1c, 0x5c, 0x4f, 0x54, 0x5e, 0xcc, 0xd7, 0x1d, 0x75, 0xd2, 0x3d, ++ 0x77, 0xff, 0x72, 0xa8, 0x74, 0x31, 0xec, 0x74, 0xe8, 0xcc, 0x69, 0xce, ++ 0xde, 0xe5, 0x05, 0x1e, 0xc2, 0x99, 0x90, 0x22, 0xe5, 0x10, 0xd4, 0xaf, ++ 0x52, 0xe3, 0x47, 0xf4, 0x38, 0xeb, 0xa3, 0xd2, 0x72, 0x64, 0xb2, 0xd3, ++ 0x0c, 0x0c, 0xaa, 0xae, 0x29, 0xb5, 0x38, 0xd4, 0x52, 0xfa, 0x96, 0x17, ++ 0x7a, 0x18, 0xe8, 0x89, 0xd2, 0xd5, 0xd9, 0xae, 0x5a, 0x0e, 0x25, 0x8d}; ++ ++class IkeKdfTest : public ::testing::Test { ++ public: ++ IkeKdfTest() ++ : params_({siBuffer, nullptr, 0}), ++ gxy_item_({siBuffer, toUcharPtr(kGxyData), kGxySize}), ++ skey_item_({siBuffer, toUcharPtr(kKeyData), kKeySize}), ++ key_mech_(0), ++ slot_(nullptr), ++ gxy_(nullptr), ++ skey_(nullptr), ++ okey_(nullptr) {} ++ ++ ~IkeKdfTest() { ++ if (slot_) { ++ PK11_FreeSlot(slot_); ++ } ++ if (gxy_) { ++ PK11_FreeSymKey(gxy_); ++ } ++ ClearTempVars(); ++ } ++ ++ void ClearTempVars() { ++ if (skey_) { ++ PK11_FreeSymKey(skey_); ++ skey_ = nullptr; ++ } ++ if (okey_) { ++ PK11_FreeSymKey(okey_); ++ okey_ = nullptr; ++ } ++ } ++ ++ void Init() { ++ params_.type = siBuffer; ++ ++ gxy_item_.type = siBuffer; ++ gxy_item_.data = ++ const_cast(static_cast(kGxyData)); ++ gxy_item_.len = sizeof(kGxyData); ++ skey_item_.type = siBuffer; ++ skey_item_.data = ++ const_cast(static_cast(kKeyData)); ++ ++ slot_ = PK11_GetInternalSlot(); ++ ASSERT_NE(nullptr, slot_); ++ gxy_ = PK11_ImportSymKey(slot_, CKM_NSS_IKE_PRF_DERIVE, PK11_OriginUnwrap, ++ CKA_DERIVE, &gxy_item_, NULL); ++ ASSERT_NE(nullptr, gxy_); ++ } ++ ++ void ComputeAndVerifyKey(CK_MECHANISM_TYPE derive_mech, ++ CK_MECHANISM_TYPE hash_mech, const uint8_t* expected) { ++ // Infer prf length from mechanism ++ int prf_len = 0; ++ std::string mac = "unknown"; ++ ++ switch (hash_mech) { ++ case CKM_AES_XCBC_MAC: ++ prf_len = kAesXcbcLen; ++ mac = "CKM_AES_XCBC_MAC"; ++ break; ++ case CKM_SHA_1_HMAC: ++ prf_len = kSha1Len; ++ mac = "CKM_SHA_1_HMAC"; ++ break; ++ case CKM_SHA224_HMAC: ++ prf_len = kSha224Len; ++ mac = "CKM_SHA224_HMAC"; ++ break; ++ case CKM_SHA256_HMAC: ++ prf_len = kSha256Len; ++ mac = "CKM_SHA256_HMAC"; ++ break; ++ case CKM_SHA384_HMAC: ++ prf_len = kSha384Len; ++ mac = "CKM_SHA384_HMAC"; ++ break; ++ case CKM_SHA512_HMAC: ++ prf_len = kSha512Len; ++ mac = "CKM_SHA512_HMAC"; ++ break; ++ default: ++ ASSERT_TRUE(false) << "Invalid PRF Mechanism"; ++ } ++ ++ Inner(derive_mech, hash_mech, mac, prf_len, expected); ++ } ++ ++ // Set output == nullptr to test when errors occur ++ void Inner(CK_MECHANISM_TYPE derive_mech, CK_MECHANISM_TYPE hash_mech, ++ std::string mac, size_t prf_len, const uint8_t* expected) { ++ PRBool use_skey = PR_FALSE; ++ size_t output_len = 0; ++ PK11SymKey *derive_key = nullptr; ++ std::stringstream s; ++ s << "Derive:"; ++ std::string msg; ++ ++ ClearTempVars(); ++ ++ // Import the params ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf; ++ CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ikep_prf; ++ CK_MECHANISM_TYPE ike1_app_b; ++ ++ switch (derive_mech) { ++ case CKM_NSS_IKE_PRF_DERIVE: ++ ike_prf.prfMechanism = hash_mech; ++ ike_prf.bDataAsKey = PR_TRUE; ++ ike_prf.bRekey = PR_FALSE; ++ ike_prf.pNi = toUcharPtr(kSeed); ++ ike_prf.ulNiLen = kSeedSize; ++ ike_prf.pNr = toUcharPtr(kSeed); ++ ike_prf.ulNrLen = kSeedSize; ++ ike_prf.hNewKey = CK_INVALID_HANDLE; ++ output_len = 0; ++ use_skey = PR_FALSE; ++ params_.data = reinterpret_cast(&ike_prf); ++ params_.len = sizeof(ike_prf); ++ s << "CKM_NSS_IKE_PRF_DERIVE"; ++ break; ++ case CKM_NSS_IKE_PRF_PLUS_DERIVE: ++ ikep_prf.prfMechanism = hash_mech; ++ ikep_prf.bHasSeedKey = PR_FALSE; ++ ikep_prf.pSeedData= toUcharPtr(kSeed); ++ ikep_prf.ulSeedDataLen = kSeedSize*4; ++ output_len = kLongKeySize; ++ use_skey = PR_TRUE; ++ params_.data = reinterpret_cast(&ikep_prf); ++ params_.len = sizeof(ikep_prf); ++ s << "CKM_NSS_IKE_PRF_PLUS_DERIVE"; ++ break; ++ case CKM_NSS_IKE1_PRF_DERIVE: ++ ike1_prf.prfMechanism = hash_mech; ++ ike1_prf.bHasPrevKey = PR_FALSE; ++ ike1_prf.hKeygxy = PK11_GetSymKeyHandle(gxy_); ++ ike1_prf.hPrevKey = CK_INVALID_HANDLE; ++ ike1_prf.pCKYi = toUcharPtr(kSeed); ++ ike1_prf.ulCKYiLen = kSeedSize; ++ ike1_prf.pCKYr = toUcharPtr(kSeed); ++ ike1_prf.ulCKYrLen = kSeedSize; ++ ike1_prf.keyNumber = 0; ++ output_len = prf_len; ++ use_skey = PR_TRUE; ++ params_.data = reinterpret_cast(&ike1_prf); ++ params_.len = sizeof(ike1_prf); ++ s << "CKM_NSS_IKE1_PRF_DERIVE"; ++ break; ++ case CKM_NSS_IKE1_APP_B_PRF_DERIVE: ++ ike1_app_b = hash_mech; ++ output_len = kLongKeySize; ++ use_skey = PR_TRUE; ++ params_.data = reinterpret_cast(&ike1_app_b); ++ params_.len = sizeof(ike1_app_b); ++ s << "CKM_NSS_IKE1_APP_B_DERIVE"; ++ break; ++ default: ++ ASSERT_TRUE(false) << "Invalid IKE DERIVE mechanism"; ++ } ++ ++ s << " Mac/Prf:" << mac; ++ msg = s.str(); ++ ++ ++ // Import the PMS ++ derive_key = gxy_; ++ if (use_skey) { ++ skey_item_.len = prf_len; ++ skey_ = PK11_ImportSymKey(slot_, derive_mech, PK11_OriginUnwrap, ++ CKA_DERIVE, &skey_item_, NULL); ++ ASSERT_NE(nullptr, skey_) << msg; ++ derive_key = skey_; ++ } ++ ++ // Compute the result key ++ okey_ = PK11_DeriveWithFlags(derive_key, derive_mech, ¶ms_, key_mech_, ++ CKA_DERIVE, output_len, CKF_SIGN | CKF_VERIFY); ++ ++ // Verify the result has the expected value (null or otherwise) ++ int error = PORT_GetError(); ++ s << " Error=" << error; ++ msg = s.str(); ++ if (!expected) { ++ EXPECT_EQ(nullptr, okey_) << msg; ++ } else { ++ ASSERT_NE(nullptr, okey_) << msg; ++ ++ SECStatus rv = PK11_ExtractKeyValue(okey_); ++ ASSERT_EQ(SECSuccess, rv) << "PK11_ExtractKeyValue"; ++ ++ SECItem* oData = PK11_GetKeyData(okey_); ++ ASSERT_NE(nullptr, oData) << "PK11_GetKeyData"; ++ ++ if (output_len == 0) { ++ output_len = prf_len; ++ } ++ s << "\n" << "output_len=" << output_len << " oData->len=" << oData->len << ".\n"; ++ for (unsigned int i=0; i < oData->len; i++) { ++ if (i % 12 == 0) s << "\n "; ++ s << " 0x" << std::setfill('0') ++ << std::setw(2) << std::hex << (int) oData->data[i] << ","; ++ } ++ s << "};\n"; ++ msg = s.str(); ++ ASSERT_EQ(output_len, oData->len) << msg ; ++ ++ EXPECT_EQ(0, memcmp(oData->data, expected, output_len)) << msg; ++ } ++ } ++ ++ protected: ++ SECItem params_; ++ SECItem gxy_item_; ++ SECItem skey_item_; ++ CK_MECHANISM_TYPE key_mech_; ++ PK11SlotInfo* slot_; ++ PK11SymKey* gxy_; ++ PK11SymKey* skey_; ++ PK11SymKey* okey_; ++}; ++ ++// ++// The full range is tested with the FIPS vectors in the cavs tests. ++// just make sure the NSS Derive iterfaces are working for everything. ++// ++TEST_F(IkeKdfTest, IkePrfSha256) { ++ Init(); ++ ComputeAndVerifyKey(CKM_NSS_IKE_PRF_DERIVE, CKM_SHA256_HMAC, ++ kExpectedOutputIkeSha256); ++} ++ ++TEST_F(IkeKdfTest, Ike1PrfSha256) { ++ Init(); ++ ComputeAndVerifyKey(CKM_NSS_IKE1_PRF_DERIVE, CKM_SHA256_HMAC, ++ kExpectedOutputIke1Sha256); ++} ++ ++TEST_F(IkeKdfTest, IkePlusPrfSha256) { ++ Init(); ++ ComputeAndVerifyKey(CKM_NSS_IKE_PRF_PLUS_DERIVE, CKM_SHA256_HMAC, ++ kExpectedOutputIkePlusSha256); ++} ++ ++TEST_F(IkeKdfTest, Ike1AppBPrfSha256) { ++ Init(); ++ ComputeAndVerifyKey(CKM_NSS_IKE1_APP_B_PRF_DERIVE, CKM_SHA256_HMAC, ++ kExpectedOutputIkeAppBSha256); ++} ++ ++} // namespace nss_test +diff -up ./lib/softoken/pkcs11.c.missing_kdf ./lib/softoken/pkcs11.c +--- ./lib/softoken/pkcs11.c.missing_kdf 2019-08-07 14:18:55.039435109 -0700 ++++ ./lib/softoken/pkcs11.c 2019-08-08 10:28:12.449792962 -0700 +@@ -516,7 +516,8 @@ static const struct mechanismList mechan + /* --------------------IPSEC ----------------------- */ + { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE }, +- { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE } ++ { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE }, ++ { CKM_NSS_IKE1_APP_B_PRF_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE } + }; + static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]); + +diff -up ./lib/softoken/sftkike.c.missing_kdf ./lib/softoken/sftkike.c +--- ./lib/softoken/sftkike.c.missing_kdf 2019-08-08 10:24:27.872008887 -0700 ++++ ./lib/softoken/sftkike.c 2019-08-08 10:27:34.416829530 -0700 +@@ -744,7 +744,7 @@ sftk_ike1_appendix_b_prf(CK_SESSION_HAND + * key is inKey + */ + thisKey = outKeyData; +- for (genKeySize = 0; genKeySize <= keySize; genKeySize += macSize) { ++ for (genKeySize = 0; genKeySize < keySize; genKeySize += macSize) { + crv = prf_init(&context, inKey->attrib.pValue, inKey->attrib.ulValueLen); + if (crv != CKR_OK) { + goto fail; diff --git a/SOURCES/nss-539183.patch b/SOURCES/nss-539183.patch new file mode 100644 index 0000000..267e71e --- /dev/null +++ b/SOURCES/nss-539183.patch @@ -0,0 +1,62 @@ +--- nss/cmd/httpserv/httpserv.c.539183 2016-05-21 18:31:39.879585420 -0700 ++++ nss/cmd/httpserv/httpserv.c 2016-05-21 18:37:22.374464057 -0700 +@@ -953,23 +953,23 @@ + getBoundListenSocket(unsigned short port) + { + PRFileDesc *listen_sock; + int listenQueueDepth = 5 + (2 * maxThreads); + PRStatus prStatus; + PRNetAddr addr; + PRSocketOptionData opt; + +- addr.inet.family = PR_AF_INET; +- addr.inet.ip = PR_INADDR_ANY; +- addr.inet.port = PR_htons(port); ++ if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { ++ errExit("PR_SetNetAddr"); ++ } + +- listen_sock = PR_NewTCPSocket(); ++ listen_sock = PR_OpenTCPSocket(PR_AF_INET6); + if (listen_sock == NULL) { +- errExit("PR_NewTCPSocket"); ++ errExit("PR_OpenTCPSockett"); + } + + opt.option = PR_SockOpt_Nonblocking; + opt.value.non_blocking = PR_FALSE; + prStatus = PR_SetSocketOption(listen_sock, &opt); + if (prStatus < 0) { + PR_Close(listen_sock); + errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); +--- nss/cmd/selfserv/selfserv.c.539183 2016-05-21 18:31:39.882585367 -0700 ++++ nss/cmd/selfserv/selfserv.c 2016-05-21 18:41:43.092801174 -0700 +@@ -1711,23 +1711,23 @@ + getBoundListenSocket(unsigned short port) + { + PRFileDesc *listen_sock; + int listenQueueDepth = 5 + (2 * maxThreads); + PRStatus prStatus; + PRNetAddr addr; + PRSocketOptionData opt; + +- addr.inet.family = PR_AF_INET; +- addr.inet.ip = PR_INADDR_ANY; +- addr.inet.port = PR_htons(port); ++ if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr) != PR_SUCCESS) { ++ errExit("PR_SetNetAddr"); ++ } + +- listen_sock = PR_NewTCPSocket(); ++ listen_sock = PR_OpenTCPSocket(PR_AF_INET6); + if (listen_sock == NULL) { +- errExit("PR_NewTCPSocket"); ++ errExit("PR_OpenTCPSocket error"); + } + + opt.option = PR_SockOpt_Nonblocking; + opt.value.non_blocking = PR_FALSE; + prStatus = PR_SetSocketOption(listen_sock, &opt); + if (prStatus < 0) { + PR_Close(listen_sock); + errExit("PR_SetSocketOption(PR_SockOpt_Nonblocking)"); diff --git a/SOURCES/nss-8-add-ipsec-usage-to-manpage.patch b/SOURCES/nss-8-add-ipsec-usage-to-manpage.patch new file mode 100644 index 0000000..028ad4b --- /dev/null +++ b/SOURCES/nss-8-add-ipsec-usage-to-manpage.patch @@ -0,0 +1,13 @@ +diff -up ./doc/certutil.xml.ipsec_doc ./doc/certutil.xml +--- ./doc/certutil.xml.ipsec_doc 2019-05-10 14:14:18.000000000 -0700 ++++ ./doc/certutil.xml 2019-06-05 16:49:44.229301383 -0700 +@@ -428,6 +428,9 @@ of the attribute codes: + + J (as an object signer) + ++ ++I (as an IPSEC user) ++ + + + diff --git a/SOURCES/nss-8-fix-public-key-from-priv.patch b/SOURCES/nss-8-fix-public-key-from-priv.patch new file mode 100644 index 0000000..1a3d1b4 --- /dev/null +++ b/SOURCES/nss-8-fix-public-key-from-priv.patch @@ -0,0 +1,571 @@ +diff -up ./gtests/pk11_gtest/pk11_import_unittest.cc.pub-priv-mech ./gtests/pk11_gtest/pk11_import_unittest.cc +--- ./gtests/pk11_gtest/pk11_import_unittest.cc.pub-priv-mech 2019-05-10 14:14:18.000000000 -0700 ++++ ./gtests/pk11_gtest/pk11_import_unittest.cc 2019-06-05 16:43:42.276498676 -0700 +@@ -78,17 +78,40 @@ class Pk11KeyImportTestBase : public ::t + CK_MECHANISM_TYPE mech_; + + private: ++ SECItem GetPublicComponent(ScopedSECKEYPublicKey& pub_key) { ++ SECItem null = { siBuffer, NULL, 0}; ++ switch(SECKEY_GetPublicKeyType(pub_key.get())) { ++ case rsaKey: ++ case rsaPssKey: ++ case rsaOaepKey: ++ return pub_key->u.rsa.modulus; ++ case keaKey: ++ return pub_key->u.kea.publicValue; ++ case dsaKey: ++ return pub_key->u.dsa.publicValue; ++ case dhKey: ++ return pub_key->u.dh.publicValue; ++ case ecKey: ++ return pub_key->u.ec.publicValue; ++ case fortezzaKey: /* depricated */ ++ case nullKey: ++ /* didn't use default here so we can catch new key types at compile time */ ++ break; ++ } ++ return null; ++ } + void CheckForPublicKey(const ScopedSECKEYPrivateKey& priv_key, + const SECItem* expected_public) { + // Verify the public key exists. + StackSECItem priv_id; ++ KeyType type = SECKEY_GetPrivateKeyType(priv_key.get()); + SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, priv_key.get(), + CKA_ID, &priv_id); + ASSERT_EQ(SECSuccess, rv) << "Couldn't read CKA_ID from private key: " + << PORT_ErrorToName(PORT_GetError()); + + CK_ATTRIBUTE_TYPE value_type = CKA_VALUE; +- switch (SECKEY_GetPrivateKeyType(priv_key.get())) { ++ switch (type) { + case rsaKey: + value_type = CKA_MODULUS; + break; +@@ -106,6 +129,8 @@ class Pk11KeyImportTestBase : public ::t + FAIL() << "unknown key type"; + } + ++ // Scan public key objects until we find one with the same CKA_ID as ++ // priv_key + std::unique_ptr objs( + PK11_FindGenericObjects(slot_.get(), CKO_PUBLIC_KEY)); + ASSERT_NE(nullptr, objs); +@@ -128,20 +153,46 @@ class Pk11KeyImportTestBase : public ::t + ASSERT_EQ(1U, token.len); + ASSERT_NE(0, token.data[0]); + +- StackSECItem value; +- rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, value_type, &value); ++ StackSECItem raw_value; ++ SECItem decoded_value; ++ rv = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, value_type, &raw_value); + ASSERT_EQ(SECSuccess, rv); ++ SECItem value = raw_value; + ++ // Decode the EC_POINT and check the output against expected. + // CKA_EC_POINT isn't stable, see Bug 1520649. ++ ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); ++ ASSERT_TRUE(arena); + if (value_type == CKA_EC_POINT) { +- continue; +- } + ++ // If this fails due to the noted inconsistency, we may need to ++ // check the whole raw_value, or remove a leading UNCOMPRESSED_POINT tag ++ rv = SEC_QuickDERDecodeItem(arena.get(), &decoded_value, ++ SEC_ASN1_GET(SEC_OctetStringTemplate), ++ &raw_value); ++ ASSERT_EQ(SECSuccess, rv); ++ value = decoded_value; ++ } + ASSERT_TRUE(SECITEM_ItemsAreEqual(expected_public, &value)) + << "expected: " + << DataBuffer(expected_public->data, expected_public->len) + << std::endl + << "actual: " << DataBuffer(value.data, value.len) << std::endl; ++ ++ // Finally, convert the private to public and ensure it matches. ++ ScopedSECKEYPublicKey pub_key( ++ SECKEY_ConvertToPublicKey(priv_key.get())); ++ ASSERT_TRUE(pub_key); ++ SECItem converted_public = GetPublicComponent(pub_key); ++ ASSERT_TRUE(converted_public.len != 0); ++ ++ ASSERT_TRUE(SECITEM_ItemsAreEqual(expected_public, &converted_public)) ++ << "expected: " ++ << DataBuffer(expected_public->data, expected_public->len) ++ << std::endl ++ << "actual: " ++ << DataBuffer(converted_public.data, converted_public.len) ++ << std::endl; + } + } + +diff -up ./lib/cryptohi/seckey.c.pub-priv-mech ./lib/cryptohi/seckey.c +--- ./lib/cryptohi/seckey.c.pub-priv-mech 2019-05-10 14:14:18.000000000 -0700 ++++ ./lib/cryptohi/seckey.c 2019-06-05 16:43:42.277498676 -0700 +@@ -1206,6 +1206,37 @@ SECKEY_CopyPublicKey(const SECKEYPublicK + return NULL; + } + ++/* ++ * Use the private key to find a public key handle. The handle will be on ++ * the same slot as the private key. ++ */ ++static CK_OBJECT_HANDLE ++seckey_FindPublicKeyHandle(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk) ++{ ++ CK_OBJECT_HANDLE keyID; ++ ++ /* this helper function is only used below. If we want to make this more ++ * general, we would need to free up any already cached handles if the ++ * slot doesn't match up with the private key slot */ ++ PORT_Assert(pubk->pkcs11ID == CK_INVALID_HANDLE); ++ ++ /* first look for a matching public key */ ++ keyID = PK11_MatchItem(privk->pkcs11Slot, privk->pkcs11ID, CKO_PUBLIC_KEY); ++ if (keyID != CK_INVALID_HANDLE) { ++ return keyID; ++ } ++ ++ /* none found, create a temp one, make the pubk the owner */ ++ pubk->pkcs11ID = PK11_DerivePubKeyFromPrivKey(privk); ++ if (pubk->pkcs11ID == CK_INVALID_HANDLE) { ++ /* end of the road. Token doesn't have matching public key, nor can ++ * token regenerate a new public key from and existing private key. */ ++ return CK_INVALID_HANDLE; ++ } ++ pubk->pkcs11Slot = PK11_ReferenceSlot(privk->pkcs11Slot); ++ return pubk->pkcs11ID; ++} ++ + SECKEYPublicKey * + SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk) + { +@@ -1213,6 +1244,8 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK + PLArenaPool *arena; + CERTCertificate *cert; + SECStatus rv; ++ CK_OBJECT_HANDLE pubKeyHandle; ++ SECItem decodedPoint; + + /* + * First try to look up the cert. +@@ -1243,11 +1276,47 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK + + switch (privk->keyType) { + case nullKey: +- case dhKey: +- case dsaKey: + /* Nothing to query, if the cert isn't there, we're done -- no way + * to get the public key */ + break; ++ case dsaKey: ++ pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); ++ if (pubKeyHandle == CK_INVALID_HANDLE) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_BASE, arena, &pubk->u.dsa.params.base); ++ if (rv != SECSuccess) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_PRIME, arena, &pubk->u.dsa.params.prime); ++ if (rv != SECSuccess) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_SUBPRIME, arena, &pubk->u.dsa.params.subPrime); ++ if (rv != SECSuccess) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_VALUE, arena, &pubk->u.dsa.publicValue); ++ if (rv != SECSuccess) ++ break; ++ return pubk; ++ case dhKey: ++ pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); ++ if (pubKeyHandle == CK_INVALID_HANDLE) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_BASE, arena, &pubk->u.dh.base); ++ if (rv != SECSuccess) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_PRIME, arena, &pubk->u.dh.prime); ++ if (rv != SECSuccess) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_VALUE, arena, &pubk->u.dh.publicValue); ++ if (rv != SECSuccess) ++ break; ++ return pubk; + case rsaKey: + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_MODULUS, arena, &pubk->u.rsa.modulus); +@@ -1258,7 +1327,6 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK + if (rv != SECSuccess) + break; + return pubk; +- break; + case ecKey: + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_PARAMS, arena, &pubk->u.ec.DEREncodedParams); +@@ -1268,7 +1336,23 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK + rv = PK11_ReadAttribute(privk->pkcs11Slot, privk->pkcs11ID, + CKA_EC_POINT, arena, &pubk->u.ec.publicValue); + if (rv != SECSuccess || pubk->u.ec.publicValue.len == 0) { +- break; ++ pubKeyHandle = seckey_FindPublicKeyHandle(privk, pubk); ++ if (pubKeyHandle == CK_INVALID_HANDLE) ++ break; ++ rv = PK11_ReadAttribute(privk->pkcs11Slot, pubKeyHandle, ++ CKA_EC_POINT, arena, &pubk->u.ec.publicValue); ++ if (rv != SECSuccess) ++ break; ++ } ++ /* ec.publicValue should be decoded, PKCS #11 defines CKA_EC_POINT ++ * as encoded, but it's not always. try do decoded it and if it ++ * succeeds store the decoded value */ ++ rv = SEC_QuickDERDecodeItem(arena, &decodedPoint, ++ SEC_ASN1_GET(SEC_OctetStringTemplate), &pubk->u.ec.publicValue); ++ if (rv == SECSuccess) { ++ /* both values are in the public key arena, so it's safe to ++ * overwrite the old value */ ++ pubk->u.ec.publicValue = decodedPoint; + } + pubk->u.ec.encoding = ECPoint_Undefined; + return pubk; +@@ -1276,7 +1360,9 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK + break; + } + +- PORT_FreeArena(arena, PR_FALSE); ++ /* must use Destroy public key here, because some paths create temporary ++ * PKCS #11 objects which need to be freed */ ++ SECKEY_DestroyPublicKey(pubk); + return NULL; + } + +diff -up ./lib/pk11wrap/pk11priv.h.pub-priv-mech ./lib/pk11wrap/pk11priv.h +--- ./lib/pk11wrap/pk11priv.h.pub-priv-mech 2019-05-10 14:14:18.000000000 -0700 ++++ ./lib/pk11wrap/pk11priv.h 2019-06-05 16:43:42.277498676 -0700 +@@ -111,6 +111,7 @@ CK_OBJECT_HANDLE PK11_FindObjectForCert( + PK11SymKey *pk11_CopyToSlot(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, + CK_ATTRIBUTE_TYPE operation, PK11SymKey *symKey); + unsigned int pk11_GetPredefinedKeyLength(CK_KEY_TYPE keyType); ++CK_OBJECT_HANDLE PK11_DerivePubKeyFromPrivKey(SECKEYPrivateKey *privKey); + + /********************************************************************** + * Certs +diff -up ./lib/pk11wrap/pk11skey.c.pub-priv-mech ./lib/pk11wrap/pk11skey.c +--- ./lib/pk11wrap/pk11skey.c.pub-priv-mech 2019-06-05 16:37:38.726685789 -0700 ++++ ./lib/pk11wrap/pk11skey.c 2019-06-05 16:43:42.278498675 -0700 +@@ -1841,6 +1841,35 @@ loser: + } + + /* ++ * This regenerate a public key from a private key. This function is currently ++ * NSS private. If we want to make it public, we need to add and optional ++ * template or at least flags (a.la. PK11_DeriveWithFlags). ++ */ ++CK_OBJECT_HANDLE ++PK11_DerivePubKeyFromPrivKey(SECKEYPrivateKey *privKey) ++{ ++ PK11SlotInfo *slot = privKey->pkcs11Slot; ++ CK_MECHANISM mechanism; ++ CK_OBJECT_HANDLE objectID = CK_INVALID_HANDLE; ++ CK_RV crv; ++ ++ mechanism.mechanism = CKM_NSS_PUB_FROM_PRIV; ++ mechanism.pParameter = NULL; ++ mechanism.ulParameterLen = 0; ++ ++ PK11_EnterSlotMonitor(slot); ++ crv = PK11_GETTAB(slot)->C_DeriveKey(slot->session, &mechanism, ++ privKey->pkcs11ID, NULL, 0, ++ &objectID); ++ PK11_ExitSlotMonitor(slot); ++ if (crv != CKR_OK) { ++ PORT_SetError(PK11_MapError(crv)); ++ return CK_INVALID_HANDLE; ++ } ++ return objectID; ++} ++ ++/* + * This Generates a wrapping key based on a privateKey, publicKey, and two + * random numbers. For Mail usage RandomB should be NULL. In the Sender's + * case RandomA is generate, outherwize it is passed. +diff -up ./lib/softoken/lowkey.c.pub-priv-mech ./lib/softoken/lowkey.c +--- ./lib/softoken/lowkey.c.pub-priv-mech 2019-05-10 14:14:18.000000000 -0700 ++++ ./lib/softoken/lowkey.c 2019-06-05 16:44:20.469479019 -0700 +@@ -261,6 +261,7 @@ NSSLOWKEYPublicKey * + nsslowkey_ConvertToPublicKey(NSSLOWKEYPrivateKey *privk) + { + NSSLOWKEYPublicKey *pubk; ++ SECItem publicValue; + PLArenaPool *arena; + + arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); +@@ -301,6 +302,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPr + + pubk->arena = arena; + pubk->keyType = privk->keyType; ++ /* if the public key value doesn't exist, calculate it */ ++ if (privk->u.dsa.publicValue.len == 0) { ++ rv = DH_Derive(&privk->u.dsa.params.base, &privk->u.dsa.params.prime, ++ &privk->u.dsa.privateValue, &publicValue, 0); ++ if (rv != SECSuccess) { ++ break; ++ } ++ rv = SECITEM_CopyItem(privk->arena, &privk->u.dsa.publicValue, &publicValue); ++ SECITEM_FreeItem(&publicValue, PR_FALSE); ++ if (rv != SECSuccess) { ++ break; ++ } ++ } + rv = SECITEM_CopyItem(arena, &pubk->u.dsa.publicValue, + &privk->u.dsa.publicValue); + if (rv != SECSuccess) +@@ -327,6 +341,19 @@ nsslowkey_ConvertToPublicKey(NSSLOWKEYPr + + pubk->arena = arena; + pubk->keyType = privk->keyType; ++ /* if the public key value doesn't exist, calculate it */ ++ if (privk->u.dh.publicValue.len == 0) { ++ rv = DH_Derive(&privk->u.dh.base, &privk->u.dh.prime, ++ &privk->u.dh.privateValue, &publicValue, 0); ++ if (rv != SECSuccess) { ++ break; ++ } ++ rv = SECITEM_CopyItem(privk->arena, &privk->u.dh.publicValue, &publicValue); ++ SECITEM_FreeItem(&publicValue, PR_FALSE); ++ if (rv != SECSuccess) { ++ break; ++ } ++ } + rv = SECITEM_CopyItem(arena, &pubk->u.dh.publicValue, + &privk->u.dh.publicValue); + if (rv != SECSuccess) +diff -up ./lib/softoken/pkcs11c.c.pub-priv-mech ./lib/softoken/pkcs11c.c +--- ./lib/softoken/pkcs11c.c.pub-priv-mech 2019-06-05 16:37:38.743685780 -0700 ++++ ./lib/softoken/pkcs11c.c 2019-06-05 16:44:20.472479017 -0700 +@@ -6569,6 +6569,10 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + extractValue = PR_FALSE; + classType = CKO_PRIVATE_KEY; + break; ++ case CKM_NSS_PUB_FROM_PRIV: ++ extractValue = PR_FALSE; ++ classType = CKO_PUBLIC_KEY; ++ break; + case CKM_NSS_JPAKE_FINAL_SHA1: /* fall through */ + case CKM_NSS_JPAKE_FINAL_SHA256: /* fall through */ + case CKM_NSS_JPAKE_FINAL_SHA384: /* fall through */ +@@ -6610,6 +6614,35 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + } + + switch (mechanism) { ++ /* get a public key from a private key. nsslowkey_ConvertToPublickey() ++ * will generate the public portion if it doesn't already exist. */ ++ case CKM_NSS_PUB_FROM_PRIV: { ++ NSSLOWKEYPrivateKey *privKey; ++ NSSLOWKEYPublicKey *pubKey; ++ int error; ++ ++ crv = sftk_GetULongAttribute(sourceKey, CKA_KEY_TYPE, &keyType); ++ if (crv != CKR_OK) { ++ break; ++ } ++ ++ /* privKey is stored in sourceKey and will be destroyed when ++ * the sourceKey is freed. */ ++ privKey = sftk_GetPrivKey(sourceKey, keyType, &crv); ++ if (privKey == NULL) { ++ break; ++ } ++ pubKey = nsslowkey_ConvertToPublicKey(privKey); ++ if (pubKey == NULL) { ++ error = PORT_GetError(); ++ crv = sftk_MapCryptError(error); ++ break; ++ } ++ crv = sftk_PutPubKey(key, sourceKey, keyType, pubKey); ++ nsslowkey_DestroyPublicKey(pubKey); ++ break; ++ } ++ + case CKM_NSS_IKE_PRF_DERIVE: + if (pMechanism->ulParameterLen != + sizeof(CK_NSS_IKE_PRF_DERIVE_PARAMS)) { +diff -up ./lib/softoken/pkcs11.c.pub-priv-mech ./lib/softoken/pkcs11.c +--- ./lib/softoken/pkcs11.c.pub-priv-mech 2019-06-05 16:37:38.728685788 -0700 ++++ ./lib/softoken/pkcs11.c 2019-06-05 16:44:20.473479017 -0700 +@@ -2206,6 +2206,123 @@ sftk_GetPrivKey(SFTKObject *object, CK_K + return priv; + } + ++/* populate a public key object from a lowpublic keys structure */ ++CK_RV ++sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privateKey, CK_KEY_TYPE keyType, NSSLOWKEYPublicKey *pubKey) ++{ ++ CK_OBJECT_CLASS classType = CKO_PUBLIC_KEY; ++ CK_BBOOL cktrue = CK_TRUE; ++ CK_RV crv = CKR_OK; ++ sftk_DeleteAttributeType(publicKey, CKA_CLASS); ++ sftk_DeleteAttributeType(publicKey, CKA_KEY_TYPE); ++ sftk_DeleteAttributeType(publicKey, CKA_VALUE); ++ ++ switch (keyType) { ++ case CKK_RSA: ++ sftk_DeleteAttributeType(publicKey, CKA_MODULUS); ++ sftk_DeleteAttributeType(publicKey, CKA_PUBLIC_EXPONENT); ++ /* format the keys */ ++ /* fill in the RSA dependent paramenters in the public key */ ++ crv = sftk_AddAttributeType(publicKey, CKA_MODULUS, ++ sftk_item_expand(&pubKey->u.rsa.modulus)); ++ if (crv != CKR_OK) ++ break; ++ crv = sftk_AddAttributeType(publicKey, CKA_PUBLIC_EXPONENT, ++ sftk_item_expand(&pubKey->u.rsa.publicExponent)); ++ break; ++ case CKK_DSA: ++ sftk_DeleteAttributeType(publicKey, CKA_PRIME); ++ sftk_DeleteAttributeType(publicKey, CKA_SUBPRIME); ++ sftk_DeleteAttributeType(publicKey, CKA_BASE); ++ crv = sftk_AddAttributeType(publicKey, CKA_PRIME, ++ sftk_item_expand(&pubKey->u.dsa.params.prime)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_SUBPRIME, ++ sftk_item_expand(&pubKey->u.dsa.params.subPrime)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_BASE, ++ sftk_item_expand(&pubKey->u.dsa.params.base)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_VALUE, ++ sftk_item_expand(&pubKey->u.dsa.publicValue)); ++ break; ++ ++ case CKK_DH: ++ sftk_DeleteAttributeType(publicKey, CKA_PRIME); ++ sftk_DeleteAttributeType(publicKey, CKA_BASE); ++ crv = sftk_AddAttributeType(publicKey, CKA_PRIME, ++ sftk_item_expand(&pubKey->u.dh.prime)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_BASE, ++ sftk_item_expand(&pubKey->u.dh.base)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_VALUE, ++ sftk_item_expand(&pubKey->u.dh.publicValue)); ++ break; ++ ++ case CKK_EC: ++ sftk_DeleteAttributeType(publicKey, CKA_EC_PARAMS); ++ sftk_DeleteAttributeType(publicKey, CKA_EC_POINT); ++ ++ crv = sftk_AddAttributeType(publicKey, CKA_EC_PARAMS, ++ sftk_item_expand(&pubKey->u.ec.ecParams.DEREncoding)); ++ if (crv != CKR_OK) { ++ break; ++ } ++ ++ crv = sftk_AddAttributeType(publicKey, CKA_EC_POINT, ++ sftk_item_expand(&pubKey->u.ec.publicValue)); ++ break; ++ ++ default: ++ return CKR_KEY_TYPE_INCONSISTENT; ++ } ++ crv = sftk_AddAttributeType(publicKey, CKA_CLASS, &classType, ++ sizeof(CK_OBJECT_CLASS)); ++ if (crv != CKR_OK) ++ return crv; ++ crv = sftk_AddAttributeType(publicKey, CKA_KEY_TYPE, &keyType, ++ sizeof(CK_KEY_TYPE)); ++ if (crv != CKR_OK) ++ return crv; ++ /* now handle the operator attributes */ ++ if (sftk_isTrue(privateKey, CKA_DECRYPT)) { ++ crv = sftk_forceAttribute(publicKey, CKA_ENCRYPT, &cktrue, sizeof(CK_BBOOL)); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ } ++ if (sftk_isTrue(privateKey, CKA_SIGN)) { ++ crv = sftk_forceAttribute(publicKey, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ } ++ if (sftk_isTrue(privateKey, CKA_SIGN_RECOVER)) { ++ crv = sftk_forceAttribute(publicKey, CKA_VERIFY_RECOVER, &cktrue, sizeof(CK_BBOOL)); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ } ++ if (sftk_isTrue(privateKey, CKA_DERIVE)) { ++ crv = sftk_forceAttribute(publicKey, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ } ++ return crv; ++} ++ + /* + **************************** Symetric Key utils ************************ + */ +diff -up ./lib/softoken/pkcs11i.h.pub-priv-mech ./lib/softoken/pkcs11i.h +--- ./lib/softoken/pkcs11i.h.pub-priv-mech 2019-06-05 16:37:38.730685787 -0700 ++++ ./lib/softoken/pkcs11i.h 2019-06-05 16:44:20.473479017 -0700 +@@ -695,6 +695,9 @@ extern NSSLOWKEYPublicKey *sftk_GetPubKe + CK_KEY_TYPE key_type, CK_RV *crvp); + extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object, + CK_KEY_TYPE key_type, CK_RV *crvp); ++extern CK_RV sftk_PutPubKey(SFTKObject *publicKey, SFTKObject *privKey, ++ CK_KEY_TYPE keyType, ++ NSSLOWKEYPublicKey *pubKey); + extern void sftk_FormatDESKey(unsigned char *key, int length); + extern PRBool sftk_CheckDESKey(unsigned char *key); + extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type); +diff -up ./lib/util/pkcs11n.h.pub-priv-mech ./lib/util/pkcs11n.h +--- ./lib/util/pkcs11n.h.pub-priv-mech 2019-06-05 16:37:38.733685785 -0700 ++++ ./lib/util/pkcs11n.h 2019-06-05 16:44:54.389461561 -0700 +@@ -152,11 +152,6 @@ + #define CKM_NSS_HKDF_SHA384 (CKM_NSS + 5) + #define CKM_NSS_HKDF_SHA512 (CKM_NSS + 6) + +-/* IKE mechanism (to be proposed to PKCS #11 */ +-#define CKM_NSS_IKE_PRF_PLUS_DERIVE (CKM_NSS + 7) +-#define CKM_NSS_IKE_PRF_DERIVE (CKM_NSS + 8) +-#define CKM_NSS_IKE1_PRF_DERIVE (CKM_NSS + 9) +-#define CKM_NSS_IKE1_APP_B_PRF_DERIVE (CKM_NSS + 10) + + /* J-PAKE round 1 key generation mechanisms. + * +@@ -238,6 +233,15 @@ + + #define CKM_NSS_CHACHA20_CTR (CKM_NSS + 33) + ++/* IKE mechanism (to be proposed to PKCS #11 */ ++#define CKM_NSS_IKE_PRF_PLUS_DERIVE (CKM_NSS + 34) ++#define CKM_NSS_IKE_PRF_DERIVE (CKM_NSS + 35) ++#define CKM_NSS_IKE1_PRF_DERIVE (CKM_NSS + 36) ++#define CKM_NSS_IKE1_APP_B_PRF_DERIVE (CKM_NSS + 37) ++ ++/* Derive a public key from a bare private key */ ++#define CKM_NSS_PUB_FROM_PRIV (CKM_NSS + 40) ++ + /* + * HISTORICAL: + * Do not attempt to use these. They are only used by NETSCAPE's internal diff --git a/SOURCES/nss-config.in b/SOURCES/nss-config.in new file mode 100644 index 0000000..f8f893e --- /dev/null +++ b/SOURCES/nss-config.in @@ -0,0 +1,145 @@ +#!/bin/sh + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&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=`pkg-config --variable=exec_prefix nss` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss` +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 + diff --git a/SOURCES/nss-disable-pkcs1-sigalgs-tls13.patch b/SOURCES/nss-disable-pkcs1-sigalgs-tls13.patch new file mode 100644 index 0000000..1b57e75 --- /dev/null +++ b/SOURCES/nss-disable-pkcs1-sigalgs-tls13.patch @@ -0,0 +1,202 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1559031046 -7200 +# Tue May 28 10:10:46 2019 +0200 +# Node ID 0a4e8b72a92e144663c2f35d3836f7828cfc97f2 +# Parent 370a9e85f216f5f4ff277995a997c5c9b23a819f +Bug 1552208, prohibit use of RSASSA-PKCS1-v1_5 algorithms in TLS 1.3, r=mt + +Reviewers: mt + +Reviewed By: mt + +Subscribers: mt, jcj, ueno, rrelyea, HubertKario, KevinJacobs + +Tags: #secure-revision, #bmo-crypto-core-security + +Bug #: 1552208 + +Differential Revision: https://phabricator.services.mozilla.com/D32454 + +diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc +--- a/gtests/ssl_gtest/ssl_auth_unittest.cc ++++ b/gtests/ssl_gtest/ssl_auth_unittest.cc +@@ -701,6 +701,44 @@ TEST_P(TlsConnectTls12, ClientAuthIncons + ConnectExpectAlert(server_, kTlsAlertIllegalParameter); + } + ++TEST_P(TlsConnectTls13, ClientAuthPkcs1SignatureScheme) { ++ static const SSLSignatureScheme kSignatureScheme[] = { ++ ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pss_rsae_sha256}; ++ ++ Reset(TlsAgent::kServerRsa, "rsa"); ++ client_->SetSignatureSchemes(kSignatureScheme, ++ PR_ARRAY_SIZE(kSignatureScheme)); ++ server_->SetSignatureSchemes(kSignatureScheme, ++ PR_ARRAY_SIZE(kSignatureScheme)); ++ client_->SetupClientAuth(); ++ server_->RequestClientAuth(true); ++ ++ auto capture_cert_verify = MakeTlsFilter( ++ client_, kTlsHandshakeCertificateVerify); ++ capture_cert_verify->EnableDecryption(); ++ ++ Connect(); ++ CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_rsae_sha256, ++ 1024); ++} ++ ++TEST_P(TlsConnectTls13, ClientAuthPkcs1SignatureSchemeOnly) { ++ static const SSLSignatureScheme kSignatureScheme[] = { ++ ssl_sig_rsa_pkcs1_sha256}; ++ ++ Reset(TlsAgent::kServerRsa, "rsa"); ++ client_->SetSignatureSchemes(kSignatureScheme, ++ PR_ARRAY_SIZE(kSignatureScheme)); ++ server_->SetSignatureSchemes(kSignatureScheme, ++ PR_ARRAY_SIZE(kSignatureScheme)); ++ client_->SetupClientAuth(); ++ server_->RequestClientAuth(true); ++ ++ ConnectExpectAlert(server_, kTlsAlertHandshakeFailure); ++ server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM); ++ client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP); ++} ++ + class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter { + public: + TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr& a) +@@ -933,7 +971,7 @@ TEST_P(TlsConnectTls13, InconsistentSign + client_->CheckErrorCode(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM); + } + +-TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) { ++TEST_P(TlsConnectTls12, RequestClientAuthWithSha384) { + server_->SetSignatureSchemes(kSignatureSchemeRsaSha384, + PR_ARRAY_SIZE(kSignatureSchemeRsaSha384)); + server_->RequestClientAuth(false); +@@ -1395,12 +1433,21 @@ TEST_P(TlsSignatureSchemeConfiguration, + INSTANTIATE_TEST_CASE_P( + SignatureSchemeRsa, TlsSignatureSchemeConfiguration, + ::testing::Combine( +- TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12Plus, ++ TlsConnectTestBase::kTlsVariantsAll, TlsConnectTestBase::kTlsV12, + ::testing::Values(TlsAgent::kServerRsaSign), + ::testing::Values(ssl_auth_rsa_sign), + ::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, + ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_rsae_sha256, + ssl_sig_rsa_pss_rsae_sha384))); ++// RSASSA-PKCS1-v1_5 is not allowed to be used in TLS 1.3 ++INSTANTIATE_TEST_CASE_P( ++ SignatureSchemeRsaTls13, TlsSignatureSchemeConfiguration, ++ ::testing::Combine(TlsConnectTestBase::kTlsVariantsAll, ++ TlsConnectTestBase::kTlsV13, ++ ::testing::Values(TlsAgent::kServerRsaSign), ++ ::testing::Values(ssl_auth_rsa_sign), ++ ::testing::Values(ssl_sig_rsa_pss_rsae_sha256, ++ ssl_sig_rsa_pss_rsae_sha384))); + // PSS with SHA-512 needs a bigger key to work. + INSTANTIATE_TEST_CASE_P( + SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration, +diff --git a/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc b/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc +--- a/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc ++++ b/gtests/ssl_gtest/ssl_ciphersuite_unittest.cc +@@ -68,12 +68,6 @@ class TlsCipherSuiteTestBase : public Tl + virtual void SetupCertificate() { + if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) { + switch (sig_scheme_) { +- case ssl_sig_rsa_pkcs1_sha256: +- case ssl_sig_rsa_pkcs1_sha384: +- case ssl_sig_rsa_pkcs1_sha512: +- Reset(TlsAgent::kServerRsaSign); +- auth_type_ = ssl_auth_rsa_sign; +- break; + case ssl_sig_rsa_pss_rsae_sha256: + case ssl_sig_rsa_pss_rsae_sha384: + Reset(TlsAgent::kServerRsaSign); +@@ -330,6 +324,12 @@ static SSLSignatureScheme kSignatureSche + ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_pss_sha384, + ssl_sig_rsa_pss_pss_sha512}; + ++static SSLSignatureScheme kSignatureSchemesParamsArrTls13[] = { ++ ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384, ++ ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_rsae_sha384, ++ ssl_sig_rsa_pss_rsae_sha512, ssl_sig_rsa_pss_pss_sha256, ++ ssl_sig_rsa_pss_pss_sha384, ssl_sig_rsa_pss_pss_sha512}; ++ + INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, kDummyNamedGroupParams, + kDummySignatureSchemesParams, + TLS_RSA_WITH_RC4_128_SHA, +@@ -394,7 +394,7 @@ INSTANTIATE_CIPHER_TEST_P( + #ifndef NSS_DISABLE_TLS_1_3 + INSTANTIATE_CIPHER_TEST_P(TLS13, All, V13, + ::testing::ValuesIn(kFasterDHEGroups), +- ::testing::ValuesIn(kSignatureSchemesParamsArr), ++ ::testing::ValuesIn(kSignatureSchemesParamsArrTls13), + TLS_AES_128_GCM_SHA256, TLS_CHACHA20_POLY1305_SHA256, + TLS_AES_256_GCM_SHA384); + INSTANTIATE_CIPHER_TEST_P(TLS13AllGroups, All, V13, +diff --git a/gtests/ssl_gtest/ssl_extension_unittest.cc b/gtests/ssl_gtest/ssl_extension_unittest.cc +--- a/gtests/ssl_gtest/ssl_extension_unittest.cc ++++ b/gtests/ssl_gtest/ssl_extension_unittest.cc +@@ -436,14 +436,14 @@ TEST_P(TlsExtensionTest12Plus, Signature + } + + TEST_F(TlsExtensionTest13Stream, SignatureAlgorithmsPrecedingGarbage) { +- // 31 unknown signature algorithms followed by sha-256, rsa ++ // 31 unknown signature algorithms followed by sha-256, rsa-pss + const uint8_t val[] = { + 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x01}; ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x04}; + DataBuffer extension(val, sizeof(val)); + MakeTlsFilter(client_, ssl_signature_algorithms_xtn, + extension); +diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c +--- a/lib/ssl/ssl3con.c ++++ b/lib/ssl/ssl3con.c +@@ -64,6 +64,7 @@ static SECStatus ssl3_FlushHandshakeMess + static CK_MECHANISM_TYPE ssl3_GetHashMechanismByHashType(SSLHashType hashType); + static CK_MECHANISM_TYPE ssl3_GetMgfMechanismByHashType(SSLHashType hash); + PRBool ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme); ++PRBool ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme); + PRBool ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme); + + const PRUint8 ssl_hello_retry_random[] = { +@@ -4101,6 +4102,9 @@ ssl_SignatureSchemeValid(SSLSignatureSch + if (ssl_SignatureSchemeToHashType(scheme) == ssl_hash_sha1) { + return PR_FALSE; + } ++ if (ssl_IsRsaPkcs1SignatureScheme(scheme)) { ++ return PR_FALSE; ++ } + /* With TLS 1.3, EC keys should have been selected based on calling + * ssl_SignatureSchemeFromSpki(), reject them otherwise. */ + return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY; +@@ -4351,6 +4355,22 @@ ssl_IsRsaPssSignatureScheme(SSLSignature + } + + PRBool ++ssl_IsRsaPkcs1SignatureScheme(SSLSignatureScheme scheme) ++{ ++ switch (scheme) { ++ case ssl_sig_rsa_pkcs1_sha256: ++ case ssl_sig_rsa_pkcs1_sha384: ++ case ssl_sig_rsa_pkcs1_sha512: ++ case ssl_sig_rsa_pkcs1_sha1: ++ return PR_TRUE; ++ ++ default: ++ return PR_FALSE; ++ } ++ return PR_FALSE; ++} ++ ++PRBool + ssl_IsDsaSignatureScheme(SSLSignatureScheme scheme) + { + switch (scheme) { diff --git a/SOURCES/nss-drbg-continuous.patch b/SOURCES/nss-drbg-continuous.patch new file mode 100644 index 0000000..742f2e4 --- /dev/null +++ b/SOURCES/nss-drbg-continuous.patch @@ -0,0 +1,169 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1561465415 -7200 +# Tue Jun 25 14:23:35 2019 +0200 +# Node ID a0114e3d8b22d4c6ee77504c483a0fe0037f4c71 +# Parent 313dfef345bd93bc67982249bffa2cfdd5a9d1b5 +Bug 1560329, drbg: perform continuous test on entropy source + +Summary: FIPS 140-2 section 4.9.2 requires a conditional self test to check that consecutive entropy blocks from the system are different. As neither getentropy() nor /dev/urandom provides that check on the output, this adds the self test at caller side. + +Reviewers: rrelyea + +Bug #: 1560329 + +Differential Revision: https://phabricator.services.mozilla.com/D35636 + +diff --git a/lib/freebl/drbg.c b/lib/freebl/drbg.c +--- a/lib/freebl/drbg.c ++++ b/lib/freebl/drbg.c +@@ -30,6 +30,7 @@ + #define PRNG_ADDITONAL_DATA_CACHE_SIZE (8 * 1024) /* must be less than \ + * PRNG_MAX_ADDITIONAL_BYTES \ + */ ++#define PRNG_ENTROPY_BLOCK_SIZE SHA256_LENGTH + + /* RESEED_COUNT is how many calls to the prng before we need to reseed + * under normal NIST rules, you must return an error. In the NSS case, we +@@ -96,6 +97,8 @@ struct RNGContextStr { + PRUint32 additionalAvail; + PRBool isValid; /* false if RNG reaches an invalid state */ + PRBool isKatTest; /* true if running NIST PRNG KAT tests */ ++ /* for continuous entropy check */ ++ PRUint8 previousEntropyHash[SHA256_LENGTH]; + }; + + typedef struct RNGContextStr RNGContext; +@@ -169,6 +172,82 @@ prng_instantiate(RNGContext *rng, const + return SECSuccess; + } + ++static PRCallOnceType coRNGInitEntropy; ++ ++static PRStatus ++prng_initEntropy(void) ++{ ++ size_t length; ++ PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE]; ++ SHA256Context ctx; ++ ++ /* 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) { ++ return PR_FAILURE; /* error is already set */ ++ } ++ PORT_Assert(length == sizeof(block)); ++ ++ /* Store the hash of the entropy block rather than the block ++ * itself for backward secrecy. */ ++ SHA256_Begin(&ctx); ++ SHA256_Update(&ctx, block, sizeof(block)); ++ SHA256_End(&ctx, globalrng->previousEntropyHash, NULL, ++ sizeof(globalrng->previousEntropyHash)); ++ PORT_Memset(block, 0, sizeof(block)); ++ return PR_SUCCESS; ++} ++ ++static SECStatus ++prng_getEntropy(PRUint8 *buffer, size_t requestLength) ++{ ++ size_t total = 0; ++ PRUint8 block[PRNG_ENTROPY_BLOCK_SIZE]; ++ PRUint8 hash[SHA256_LENGTH]; ++ SHA256Context ctx; ++ SECStatus rv = SECSuccess; ++ ++ if (PR_CallOnce(&coRNGInitEntropy, prng_initEntropy) != PR_SUCCESS) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ ++ /* For FIPS 140-2 4.9.2 continuous random generator test, ++ * 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) { ++ rv = SECFailure; /* error is already set */ ++ goto out; ++ } ++ PORT_Assert(length == sizeof(block)); ++ ++ /* Store the hash of the entropy block rather than the block ++ * itself for backward secrecy. */ ++ SHA256_Begin(&ctx); ++ SHA256_Update(&ctx, block, sizeof(block)); ++ SHA256_End(&ctx, hash, NULL, sizeof(hash)); ++ ++ if (PORT_Memcmp(globalrng->previousEntropyHash, hash, sizeof(hash)) == 0) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ rv = SECFailure; ++ goto out; ++ } ++ PORT_Memcpy(globalrng->previousEntropyHash, hash, sizeof(hash)); ++ length = PR_MIN(requestLength - total, sizeof(block)); ++ PORT_Memcpy(buffer, block, length); ++ total += length; ++ buffer += length; ++ } ++ ++ out: ++ PORT_Memset(block, 0, sizeof block); ++ return rv; ++} ++ + /* + * Update the global random number generator with more seeding + * material. Use the Hash_DRBG reseed algorithm from NIST SP-800-90 +@@ -182,11 +261,15 @@ prng_reseed(RNGContext *rng, const PRUin + { + PRUint8 noiseData[(sizeof rng->V_Data) + PRNG_SEEDLEN]; + PRUint8 *noise = &noiseData[0]; ++ SECStatus rv; + + /* if entropy wasn't supplied, fetch it. (normal operation case) */ + if (entropy == NULL) { +- entropy_len = (unsigned int)RNG_SystemRNG( +- &noiseData[sizeof rng->V_Data], PRNG_SEEDLEN); ++ entropy_len = PRNG_SEEDLEN; ++ rv = prng_getEntropy(&noiseData[sizeof rng->V_Data], entropy_len); ++ if (rv != SECSuccess) { ++ return SECFailure; /* error is already set */ ++ } + } else { + /* NOTE: this code is only available for testing, not to applications */ + /* if entropy was too big for the stack variable, get it from malloc */ +@@ -384,7 +467,6 @@ static PRStatus + rng_init(void) + { + PRUint8 bytes[PRNG_SEEDLEN * 2]; /* entropy + nonce */ +- unsigned int numBytes; + SECStatus rv = SECSuccess; + + if (globalrng == NULL) { +@@ -403,18 +485,17 @@ rng_init(void) + } + + /* Try to get some seed data for the RNG */ +- numBytes = (unsigned int)RNG_SystemRNG(bytes, sizeof bytes); +- PORT_Assert(numBytes == 0 || numBytes == sizeof bytes); +- if (numBytes != 0) { ++ rv = prng_getEntropy(bytes, sizeof bytes); ++ if (rv == SECSuccess) { + /* if this is our first call, instantiate, otherwise reseed + * prng_instantiate gets a new clean state, we want to mix + * any previous entropy we may have collected */ + if (V(globalrng)[0] == 0) { +- rv = prng_instantiate(globalrng, bytes, numBytes); ++ rv = prng_instantiate(globalrng, bytes, sizeof bytes); + } else { +- rv = prng_reseed_test(globalrng, bytes, numBytes, NULL, 0); ++ rv = prng_reseed_test(globalrng, bytes, sizeof bytes, NULL, 0); + } +- memset(bytes, 0, numBytes); ++ memset(bytes, 0, sizeof bytes); + } else { + PZ_DestroyLock(globalrng->lock); + globalrng->lock = NULL; diff --git a/SOURCES/nss-dso-ldflags.patch b/SOURCES/nss-dso-ldflags.patch new file mode 100644 index 0000000..d5485ae --- /dev/null +++ b/SOURCES/nss-dso-ldflags.patch @@ -0,0 +1,13 @@ +Index: nss/coreconf/Linux.mk +=================================================================== +--- nss.orig/coreconf/Linux.mk ++++ nss/coreconf/Linux.mk +@@ -144,7 +144,7 @@ ifdef USE_PTHREADS + endif + + DSO_CFLAGS = -fPIC +-DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections ++DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections $(DSO_LDFLAGS) + # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8) + # incorrectly reports undefined references in the libraries we link with, so + # we don't use -z defs there. diff --git a/SOURCES/nss-fips-disable-tls13.patch b/SOURCES/nss-fips-disable-tls13.patch new file mode 100644 index 0000000..8b30bbc --- /dev/null +++ b/SOURCES/nss-fips-disable-tls13.patch @@ -0,0 +1,30 @@ +diff --git a/lib/ssl/sslsock.c b/lib/ssl/sslsock.c +--- a/lib/ssl/sslsock.c ++++ b/lib/ssl/sslsock.c +@@ -2382,16 +2382,26 @@ ssl3_CreateOverlapWithPolicy(SSLProtocol + rv = ssl3_GetEffectiveVersionPolicy(protocolVariant, + &effectivePolicyBoundary); + if (rv == SECFailure) { + /* SECFailure means internal failure or invalid configuration. */ + overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE; + return SECFailure; + } + ++ /* TODO: TLSv1.3 doesn't work yet under FIPS mode */ ++ if (PK11_IsFIPS()) { ++ if (effectivePolicyBoundary.min >= SSL_LIBRARY_VERSION_TLS_1_3) { ++ effectivePolicyBoundary.min = SSL_LIBRARY_VERSION_TLS_1_2; ++ } ++ if (effectivePolicyBoundary.max >= SSL_LIBRARY_VERSION_TLS_1_3) { ++ effectivePolicyBoundary.max = SSL_LIBRARY_VERSION_TLS_1_2; ++ } ++ } ++ + vrange.min = PR_MAX(input->min, effectivePolicyBoundary.min); + vrange.max = PR_MIN(input->max, effectivePolicyBoundary.max); + + if (vrange.max < vrange.min) { + /* there was no overlap, turn off range altogether */ + overlap->min = overlap->max = SSL_LIBRARY_VERSION_NONE; + return SECFailure; + } diff --git a/SOURCES/nss-fipstest-tls12-prf.patch b/SOURCES/nss-fipstest-tls12-prf.patch new file mode 100644 index 0000000..207a0c0 --- /dev/null +++ b/SOURCES/nss-fipstest-tls12-prf.patch @@ -0,0 +1,81 @@ +# HG changeset patch +# User Tomas Mraz +# Date 1560861770 -7200 +# Tue Jun 18 14:42:50 2019 +0200 +# Node ID 6ef49fe67d6227a1d290da5537ec0dade379a15a +# Parent ebc93d6daeaa9001d31fd18b5199779da99ae9aa +Bug 1559906, fipstest: use CKM_TLS12_MASTER_KEY_DERIVE in TLS test, r=rrelyea + +This also lets us CAVS tests more than just SHA256. + +diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c +--- a/cmd/fipstest/fipstest.c ++++ b/cmd/fipstest/fipstest.c +@@ -6669,12 +6669,13 @@ tls(char *reqfn) + + CK_MECHANISM master_mech = { CKM_TLS_MASTER_KEY_DERIVE, NULL, 0 }; + CK_MECHANISM key_block_mech = { CKM_TLS_KEY_AND_MAC_DERIVE, NULL, 0 }; +- CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; +- CK_SSL3_KEY_MAT_PARAMS key_block_params; ++ CK_TLS12_MASTER_KEY_DERIVE_PARAMS master_params; ++ CK_TLS12_KEY_MAT_PARAMS key_block_params; + CK_SSL3_KEY_MAT_OUT key_material; + CK_RV crv; + + /* set up PKCS #11 parameters */ ++ master_params.prfHashMechanism = CKM_SHA256; + master_params.pVersion = NULL; + master_params.RandomInfo.pClientRandom = clientHello_random; + master_params.RandomInfo.ulClientRandomLen = sizeof(clientHello_random); +@@ -6682,6 +6683,7 @@ tls(char *reqfn) + master_params.RandomInfo.ulServerRandomLen = sizeof(serverHello_random); + master_mech.pParameter = (void *)&master_params; + master_mech.ulParameterLen = sizeof(master_params); ++ key_block_params.prfHashMechanism = CKM_SHA256; + key_block_params.ulMacSizeInBits = 0; + key_block_params.ulKeySizeInBits = 0; + key_block_params.ulIVSizeInBits = 0; +@@ -6724,13 +6726,39 @@ tls(char *reqfn) + if (buf[0] == '[') { + if (strncmp(buf, "[TLS", 4) == 0) { + if (buf[7] == '0') { ++ /* CK_SSL3_MASTER_KEY_DERIVE_PARAMS is a subset of ++ * CK_TLS12_MASTER_KEY_DERIVE_PARAMS and ++ * CK_SSL3_KEY_MAT_PARAMS is a subset of ++ * CK_TLS12_KEY_MAT_PARAMS. The latter params have ++ * an extra prfHashMechanism field at the end. */ + master_mech.mechanism = CKM_TLS_MASTER_KEY_DERIVE; + key_block_mech.mechanism = CKM_TLS_KEY_AND_MAC_DERIVE; ++ master_mech.ulParameterLen = sizeof(CK_SSL3_MASTER_KEY_DERIVE_PARAMS); ++ key_block_mech.ulParameterLen = sizeof(CK_SSL3_KEY_MAT_PARAMS); + } else if (buf[7] == '2') { +- master_mech.mechanism = +- CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256; +- key_block_mech.mechanism = +- CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256; ++ if (strncmp(&buf[10], "SHA-1", 5) == 0) { ++ master_params.prfHashMechanism = CKM_SHA_1; ++ key_block_params.prfHashMechanism = CKM_SHA_1; ++ } else if (strncmp(&buf[10], "SHA-224", 7) == 0) { ++ master_params.prfHashMechanism = CKM_SHA224; ++ key_block_params.prfHashMechanism = CKM_SHA224; ++ } else if (strncmp(&buf[10], "SHA-256", 7) == 0) { ++ master_params.prfHashMechanism = CKM_SHA256; ++ key_block_params.prfHashMechanism = CKM_SHA256; ++ } else if (strncmp(&buf[10], "SHA-384", 7) == 0) { ++ master_params.prfHashMechanism = CKM_SHA384; ++ key_block_params.prfHashMechanism = CKM_SHA384; ++ } else if (strncmp(&buf[10], "SHA-512", 7) == 0) { ++ master_params.prfHashMechanism = CKM_SHA512; ++ key_block_params.prfHashMechanism = CKM_SHA512; ++ } else { ++ fprintf(tlsresp, "ERROR: Unable to find prf Hash type"); ++ goto loser; ++ } ++ master_mech.mechanism = CKM_TLS12_MASTER_KEY_DERIVE; ++ key_block_mech.mechanism = CKM_TLS12_KEY_AND_MAC_DERIVE; ++ master_mech.ulParameterLen = sizeof(master_params); ++ key_block_mech.ulParameterLen = sizeof(key_block_params); + } else { + fprintf(stderr, "Unknown TLS type %x\n", + (unsigned int)buf[0]); diff --git a/SOURCES/nss-ike-patch.patch b/SOURCES/nss-ike-patch.patch new file mode 100644 index 0000000..3ecfa63 --- /dev/null +++ b/SOURCES/nss-ike-patch.patch @@ -0,0 +1,4513 @@ +diff --git a/cmd/fipstest/README b/cmd/fipstest/README +new file mode 100644 +--- /dev/null ++++ b/cmd/fipstest/README +@@ -0,0 +1,1 @@ ++The scripts have been moved to tests/fips/cavs_scripts +diff --git a/cmd/fipstest/aes.sh b/cmd/fipstest/aes.sh +deleted file mode 100644 +--- a/cmd/fipstest/aes.sh ++++ /dev/null +@@ -1,112 +0,0 @@ +-#!/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 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}/AES +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-cbc_kat_requests=" +-CBCGFSbox128.req +-CBCGFSbox192.req +-CBCGFSbox256.req +-CBCKeySbox128.req +-CBCKeySbox192.req +-CBCKeySbox256.req +-CBCVarKey128.req +-CBCVarKey192.req +-CBCVarKey256.req +-CBCVarTxt128.req +-CBCVarTxt192.req +-CBCVarTxt256.req +-" +- +-cbc_mct_requests=" +-CBCMCT128.req +-CBCMCT192.req +-CBCMCT256.req +-" +- +-cbc_mmt_requests=" +-CBCMMT128.req +-CBCMMT192.req +-CBCMMT256.req +-" +- +-ecb_kat_requests=" +-ECBGFSbox128.req +-ECBGFSbox192.req +-ECBGFSbox256.req +-ECBKeySbox128.req +-ECBKeySbox192.req +-ECBKeySbox256.req +-ECBVarKey128.req +-ECBVarKey192.req +-ECBVarKey256.req +-ECBVarTxt128.req +-ECBVarTxt192.req +-ECBVarTxt256.req +-" +- +-ecb_mct_requests=" +-ECBMCT128.req +-ECBMCT192.req +-ECBMCT256.req +-" +- +-ecb_mmt_requests=" +-ECBMMT128.req +-ECBMMT192.req +-ECBMMT256.req +-" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do +- sh ./validate1.sh ${TESTDIR} $request +- done +- exit 0 +-fi +- +-for request in $cbc_kat_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $cbc_mct_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $cbc_mmt_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_kat_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_mct_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_mmt_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +diff --git a/cmd/fipstest/aesgcm.sh b/cmd/fipstest/aesgcm.sh +deleted file mode 100644 +--- a/cmd/fipstest/aesgcm.sh ++++ /dev/null +@@ -1,67 +0,0 @@ +-#!/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 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}/AES_GCM +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-gcm_decrypt_requests=" +-gcmDecrypt128.req +-gcmDecrypt192.req +-gcmDecrypt256.req +-" +- +-gcm_encrypt_extiv_requests=" +-gcmEncryptExtIV128.req +-gcmEncryptExtIV192.req +-gcmEncryptExtIV256.req +-" +-gcm_encrypt_intiv_requests=" +-" +- +-#gcm_encrypt_intiv_requests=" +-#gcmEncryptIntIV128.req +-#gcmEncryptIntIV192.req +-#gcmEncryptIntIV256.req +-#" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do +- sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d' +- done +- for request in $gcm_encrypt_intiv_requests; do +- name=`basename $request .req` +- echo ">>>>> $name" +- fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL +- done +- exit 0 +-fi +- +-for request in $gcm_decrypt_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $gcm_encrypt_intiv_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $gcm_encrypt_extiv_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response +-done +diff --git a/cmd/fipstest/dsa.sh b/cmd/fipstest/dsa.sh +deleted file mode 100755 +--- a/cmd/fipstest/dsa.sh ++++ /dev/null +@@ -1,71 +0,0 @@ +-#!/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 DSA Validation System +-# +-# 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}/DSA2 +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +- +-# +-# several of the DSA tests do use known answer tests to verify the result. +-# in those cases, feed generated tests back into the fipstest tool and +-# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify +-# the dsa pqgver and dsa sigver functions, so we know they can detect errors +-# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular. +-# +-if [ ${COMMAND} = "verify" ]; then +-# verify generated keys +- name=KeyPair +- echo ">>>>> $name" +- fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify generated pqg values +- name=PQGGen +- echo ">>>>> $name" +- fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify PQGVer with known answer +-# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' +-# verify signatures +- name=SigGen +- echo ">>>>> $name" +- fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify SigVer with known answer +- sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;' +- exit 0 +-fi +- +-request=KeyPair.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=PQGGen.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=PQGVer1863.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=SigGen.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=SigVer.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response +diff --git a/cmd/fipstest/ecdsa.sh b/cmd/fipstest/ecdsa.sh +deleted file mode 100644 +--- a/cmd/fipstest/ecdsa.sh ++++ /dev/null +@@ -1,60 +0,0 @@ +-#!/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 ECDSA Validation System +-# +-# 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}/ECDSA2 +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-# +-# several of the ECDSA tests do not use known answer tests to verify the result. +-# In those cases, feed generated tests back into the fipstest tool and +-# see if we can verify those value. NOTE: PQGVer and SigVer tests verify +-# the dsa pqgver and dsa sigver functions, so we know they can detect errors +-# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular. +-# +-if [ ${COMMAND} = "verify" ]; then +-# verify generated keys +- name=KeyPair +- echo ">>>>> $name" +- fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F +- sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' +-# verify signatures +- name=SigGen +- echo ">>>>> $name" +- fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify SigVer with known answer +- sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' +- exit 0 +-fi +- +-request=KeyPair.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=PKV.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=SigGen.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=SigVer.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response +diff --git a/cmd/fipstest/fipstest.c b/cmd/fipstest/fipstest.c +--- a/cmd/fipstest/fipstest.c ++++ b/cmd/fipstest/fipstest.c +@@ -29,16 +29,21 @@ + #undef CK_PKCS11_FUNCTION_INFO + #undef CK_NEED_ARG_LIST + #undef __PASTE + #define SSL3_RANDOM_LENGTH 32 + + #if 0 + #include "../../lib/freebl/mpi/mpi.h" + #endif ++#define MATCH_OPENSSL 1 ++/*#define MATCH_NIST 1 */ ++#ifdef MATCH_NIST ++#define VERBOSE_REASON 1 ++#endif + + extern SECStatus + EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams); + extern SECStatus + EC_CopyParams(PLArenaPool *arena, ECParams *dstParams, + const ECParams *srcParams); + + #define ENCRYPT 1 +@@ -3164,16 +3169,20 @@ ecdh_functional(char *reqfn, PRBool resp + fprintf(stderr, "generate key had invalid public value len\n"); + goto loser; + } + uit_len = (uit_len - 1) / 2; + if (ecpriv->publicValue.data[0] != EC_POINT_FORM_UNCOMPRESSED) { + fprintf(stderr, "generate key was compressed\n"); + goto loser; + } ++ fputs("deIUT = ", ecdhresp); ++ to_hex_str(buf, ecpriv->privateValue.data, ecpriv->privateValue.len); ++ fputs(buf, ecdhresp); ++ fputc('\n', ecdhresp); + fputs("QeIUTx = ", ecdhresp); + to_hex_str(buf, &ecpriv->publicValue.data[1], uit_len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + fputs("QeIUTy = ", ecdhresp); + to_hex_str(buf, &ecpriv->publicValue.data[1 + uit_len], uit_len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); +@@ -3210,17 +3219,16 @@ loser: + } + } + if (pubkey.data != NULL) { + PORT_Free(pubkey.data); + } + fclose(ecdhreq); + } + +-#define MATCH_OPENSSL 1 + /* + * Perform the ECDH Validity Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ + void +@@ -3403,42 +3411,47 @@ ecdh_verify(char *reqfn, PRBool response + if (strncmp(buf, "QeIUTx", 6) == 0) { + fputs(buf, ecdhresp); + continue; + } + if (strncmp(buf, "QeIUTy", 6) == 0) { + fputs(buf, ecdhresp); + continue; + } +- if (strncmp(buf, "CAVSHashZZ", 10) == 0) { ++ if ((strncmp(buf, "CAVSHashZZ", 10) == 0) || ++ (strncmp(buf, "HashZZ", 6) == 0)) { + fputs(buf, ecdhresp); +- i = 10; ++ i = (buf[0] == 'C') ? 10 : 6; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]); + if (current_ecparams == NULL) { + fprintf(stderr, "no curve defined for type defined\n"); + goto loser; + } + /* validate CAVS public key */ + if (EC_ValidatePublicKey(current_ecparams, &pubkey) != SECSuccess) { +-#ifdef MATCH_OPENSSL ++#ifdef VERBOSE_REASON ++ fprintf(ecdhresp, "Result = F # key didn't validate\n"); ++#else + fprintf(ecdhresp, "Result = F\n"); +-#else +- fprintf(ecdhresp, "Result = F # key didn't validate\n"); + #endif + continue; + } + + /* ECDH */ + if (ECDH_Derive(&pubkey, current_ecparams, &private_value, + PR_FALSE, &ZZ) != SECSuccess) { +- fprintf(stderr, "Derive failed\n"); +- goto loser; ++#ifdef VERBOSE_REASON ++ fprintf(ecdhresp, "Result = F # derive failure\n"); ++#else ++ fprintf(ecdhresp, "Result = F\n"); ++#endif ++ continue; + } + /* output ZZ */ + #ifndef MATCH_OPENSSL + fputs("Z = ", ecdhresp); + to_hex_str(buf, ZZ.data, ZZ.len); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + #endif +@@ -3450,20 +3463,20 @@ ecdh_verify(char *reqfn, PRBool response + SECITEM_FreeItem(&ZZ, PR_FALSE); + #ifndef MATCH_NIST + fputs("IUTHashZZ = ", ecdhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, ecdhresp); + fputc('\n', ecdhresp); + #endif + if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) { +-#ifdef MATCH_OPENSSL ++#ifdef VERBOSE_REASON ++ fprintf(ecdhresp, "Result = F # hash doesn't match\n"); ++#else + fprintf(ecdhresp, "Result = F\n"); +-#else +- fprintf(ecdhresp, "Result = F # hash doesn't match\n"); + #endif + } else { + fprintf(ecdhresp, "Result = P\n"); + } + #ifndef MATCH_OPENSSL + fputc('\n', ecdhresp); + #endif + continue; +@@ -3670,17 +3683,16 @@ dh_functional(char *reqfn, PRBool respon + } + loser: + if (dsapriv != NULL) { + PORT_FreeArena(dsapriv->params.arena, PR_TRUE); + } + fclose(dhreq); + } + +-#define MATCH_OPENSSL 1 + /* + * Perform the DH Validity Test. + * + * reqfn is the pathname of the REQUEST file. + * + * The output RESPONSE file is written to stdout. + */ + void +@@ -3841,19 +3853,20 @@ dh_verify(char *reqfn, PRBool response) + continue; + } + /* YephemUIT = ... */ + if (strncmp(buf, "YephemIUT", 9) == 0) { + fputs(buf, dhresp); + continue; + } + /* CAVSHashZZ = ... */ +- if (strncmp(buf, "CAVSHashZZ", 10) == 0) { ++ if ((strncmp(buf, "CAVSHashZZ", 10) == 0) || ++ (strncmp(buf, "HashZZ", 6) == 0)) { + fputs(buf, dhresp); +- i = 10; ++ i = buf[0] == 'C' ? 10 : 6; + while (isspace(buf[i]) || buf[i] == '=') { + i++; + } + from_hex_str(cavsHashBuf, fips_hashLen(hash), &buf[i]); + /* do the DH operation*/ + if (DH_Derive(&pubkey, &pqg.prime, &privkey, + &ZZ, pqg.prime.len) != SECSuccess) { + fprintf(stderr, "Derive failed\n"); +@@ -3866,17 +3879,17 @@ dh_verify(char *reqfn, PRBool response) + fputs(buf, dhresp); + fputc('\n', dhresp); + #endif + if (fips_hashBuf(hash, hashBuf, ZZ.data, ZZ.len) != SECSuccess) { + fprintf(stderr, "hash of derived key failed\n"); + goto loser; + } + SECITEM_FreeItem(&ZZ, PR_FALSE); +-#ifndef MATCH_NIST_ ++#ifndef MATCH_NIST + fputs("IUTHashZZ = ", dhresp); + to_hex_str(buf, hashBuf, fips_hashLen(hash)); + fputs(buf, dhresp); + fputc('\n', dhresp); + #endif + if (memcmp(hashBuf, cavsHashBuf, fips_hashLen(hash)) != 0) { + fprintf(dhresp, "Result = F\n"); + } else { +@@ -6895,16 +6908,1306 @@ loser: + if (master_secret) + free(master_secret); + if (key_block) + free(key_block); + if (tlsreq) + fclose(tlsreq); + } + ++void ++ikev1(char *reqfn) ++{ ++ char buf[4096]; /* holds one line from the input REQUEST file. ++ * needs to be large enough to hold the longest ++ * line "g^xy = <2048 hex digits>\n". ++ */ ++ unsigned char *gxy = NULL; ++ int gxy_len; ++ unsigned char *Ni = NULL; ++ int Ni_len; ++ unsigned char *Nr = NULL; ++ int Nr_len; ++ unsigned char CKYi[8]; ++ int CKYi_len; ++ unsigned char CKYr[8]; ++ int CKYr_len; ++ unsigned int i, j; ++ FILE *ikereq = NULL; /* input stream from the REQUEST file */ ++ FILE *ikeresp; /* output stream to the RESPONSE file */ ++ ++ CK_SLOT_ID slotList[10]; ++ CK_SLOT_ID slotID; ++ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); ++ CK_ULONG count; ++ static const CK_C_INITIALIZE_ARGS pk11args = { ++ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, ++ (void *)"flags=readOnly,noCertDB,noModDB", NULL ++ }; ++ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; ++ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; ++ static CK_BBOOL ck_true = CK_TRUE; ++ static CK_ULONG keyLen = 1; ++ CK_ATTRIBUTE gxy_template[] = { ++ { CKA_VALUE, NULL, 0 }, /* must be first */ ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ }; ++ CK_ULONG gxy_template_count = ++ sizeof(gxy_template) / sizeof(gxy_template[0]); ++ CK_ATTRIBUTE derive_template[] = { ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */ ++ }; ++ CK_ULONG derive_template_count = ++ sizeof(derive_template) / sizeof(derive_template[0]); ++ CK_ATTRIBUTE skeyid_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_d_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_a_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_e_template = ++ { CKA_VALUE, NULL, 0 }; ++ unsigned char skeyid_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_d_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_a_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_e_secret[HASH_LENGTH_MAX]; ++ ++ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; ++ CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 }; ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf; ++ CK_RV crv; ++ ++ /* set up PKCS #11 parameters */ ++ ike_prf.bDataAsKey = PR_TRUE; ++ ike_prf.bRekey = PR_FALSE; ++ ike_prf.hNewKey = CK_INVALID_HANDLE; ++ CKYi_len = sizeof(CKYi); ++ CKYr_len = sizeof(CKYr); ++ ike1_prf.pCKYi = CKYi; ++ ike1_prf.ulCKYiLen = CKYi_len; ++ ike1_prf.pCKYr = CKYr; ++ ike1_prf.ulCKYrLen = CKYr_len; ++ ike_mech.pParameter = &ike_prf; ++ ike_mech.ulParameterLen = sizeof(ike_prf); ++ ike1_mech.pParameter = &ike1_prf; ++ ike1_mech.ulParameterLen = sizeof(ike1_prf); ++ skeyid_template.pValue = skeyid_secret; ++ skeyid_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_d_template.pValue = skeyid_d_secret; ++ skeyid_d_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_a_template.pValue = skeyid_a_secret; ++ skeyid_a_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_e_template.pValue = skeyid_e_secret; ++ skeyid_e_template.ulValueLen = HASH_LENGTH_MAX; ++ ++ crv = NSC_Initialize((CK_VOID_PTR)&pk11args); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ count = slotListCount; ++ crv = NSC_GetSlotList(PR_TRUE, slotList, &count); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ if ((count > slotListCount) || count < 1) { ++ fprintf(stderr, ++ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", ++ (int)count, (int)slotListCount); ++ goto loser; ++ } ++ slotID = slotList[0]; ++ ikereq = fopen(reqfn, "r"); ++ ikeresp = stdout; ++ while (fgets(buf, sizeof buf, ikereq) != NULL) { ++ /* a comment or blank line */ ++ if (buf[0] == '#' || buf[0] == '\n') { ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* [.....] */ ++ if (buf[0] == '[') { ++ if (strncmp(buf, "[SHA-1]", 7) == 0) { ++ ike_prf.prfMechanism = CKM_SHA_1_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA_1_HMAC; ++ } ++ if (strncmp(buf, "[SHA-224]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA224_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA224_HMAC; ++ } ++ if (strncmp(buf, "[SHA-256]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA256_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA256_HMAC; ++ } ++ if (strncmp(buf, "[SHA-384]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA384_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA384_HMAC; ++ } ++ if (strncmp(buf, "[SHA-512]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA512_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA512_HMAC; ++ } ++ if (strncmp(buf, "[AES-XCBC", 9) == 0) { ++ ike_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ ike1_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ } ++ if (strncmp(buf, "[g^xy", 5) == 0) { ++ if (sscanf(buf, "[g^xy length = %d]", ++ &gxy_len) != 1) { ++ goto loser; ++ } ++ gxy_len = gxy_len / 8; ++ if (gxy) ++ free(gxy); ++ gxy = malloc(gxy_len); ++ gxy_template[0].pValue = gxy; ++ gxy_template[0].ulValueLen = gxy_len; ++ } ++ if (strncmp(buf, "[Ni", 3) == 0) { ++ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { ++ goto loser; ++ } ++ Ni_len = Ni_len / 8; ++ if (Ni) ++ free(Ni); ++ Ni = malloc(Ni_len); ++ ike_prf.pNi = Ni; ++ ike_prf.ulNiLen = Ni_len; ++ } ++ if (strncmp(buf, "[Nr", 3) == 0) { ++ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { ++ goto loser; ++ } ++ Nr_len = Nr_len / 8; ++ if (Nr) ++ free(Nr); ++ Nr = malloc(Nr_len); ++ ike_prf.pNr = Nr; ++ ike_prf.ulNrLen = Nr_len; ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* "COUNT = x" begins a new data set */ ++ if (strncmp(buf, "COUNT", 5) == 0) { ++ /* zeroize the variables for the test with this data set */ ++ memset(gxy, 0, gxy_len); ++ memset(Ni, 0, Ni_len); ++ memset(Nr, 0, Nr_len); ++ memset(CKYi, 0, CKYi_len); ++ memset(CKYr, 0, CKYr_len); ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Ni = ... */ ++ if (strncmp(buf, "Ni", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Ni_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Ni[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Nr = ... */ ++ if (strncmp(buf, "Nr", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Nr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Nr[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* CKYi = ... */ ++ if (strncmp(buf, "CKY_I", 5) == 0) { ++ i = 5; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < CKYi_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &CKYi[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* CKYr = ... */ ++ if (strncmp(buf, "CKY_R", 5) == 0) { ++ i = 5; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < CKYr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &CKYr[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* g^xy = ... */ ++ if (strncmp(buf, "g^xy", 4) == 0) { ++ CK_SESSION_HANDLE session; ++ CK_OBJECT_HANDLE gxy_handle; ++ CK_OBJECT_HANDLE skeyid_handle; ++ CK_OBJECT_HANDLE skeyid_d_handle; ++ CK_OBJECT_HANDLE skeyid_a_handle; ++ CK_OBJECT_HANDLE skeyid_e_handle; ++ i = 4; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < gxy_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &gxy[j]); ++ } ++ fputs(buf, ikeresp); ++ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_CreateObject(session, gxy_template, ++ gxy_template_count, &gxy_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_CreateObject failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ /* get the skeyid key */ ++ crv = NSC_DeriveKey(session, &ike_mech, gxy_handle, ++ derive_template, derive_template_count - 1, ++ &skeyid_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ skeyid_template.ulValueLen = HASH_LENGTH_MAX; ++ crv = NSC_GetAttributeValue(session, skeyid_handle, ++ &skeyid_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ /* use the length of the skeyid to set the target length of all the ++ * other keys */ ++ keyLen = skeyid_template.ulValueLen; ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = PR_FALSE; ++ ike1_prf.keyNumber = 0; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_d_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = CK_TRUE; ++ ike1_prf.hPrevKey = skeyid_d_handle; ++ ike1_prf.keyNumber = 1; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_a_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = CK_TRUE; ++ ike1_prf.hPrevKey = skeyid_a_handle; ++ ike1_prf.keyNumber = 2; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_e_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID = ", ikeresp); ++ to_hex_str(buf, skeyid_secret, keyLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_d_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_d_handle, ++ &skeyid_d_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_d = ", ikeresp); ++ to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_a_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_a_handle, ++ &skeyid_a_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_a = ", ikeresp); ++ to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_e_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_e_handle, ++ &skeyid_e_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_e = ", ikeresp); ++ to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ crv = NSC_CloseSession(session); ++ continue; ++ } ++ } ++loser: ++ NSC_Finalize(NULL); ++ if (gxy) ++ free(gxy); ++ if (Ni) ++ free(Ni); ++ if (Nr) ++ free(Nr); ++ if (ikereq) ++ fclose(ikereq); ++} ++ ++void ++ikev1_psk(char *reqfn) ++{ ++ char buf[4096]; /* holds one line from the input REQUEST file. ++ * needs to be large enough to hold the longest ++ * line "g^xy = <2048 hex digits>\n". ++ */ ++ unsigned char *gxy = NULL; ++ int gxy_len; ++ unsigned char *Ni = NULL; ++ int Ni_len; ++ unsigned char *Nr = NULL; ++ int Nr_len; ++ unsigned char CKYi[8]; ++ int CKYi_len; ++ unsigned char CKYr[8]; ++ int CKYr_len; ++ unsigned char *psk = NULL; ++ int psk_len; ++ unsigned int i, j; ++ FILE *ikereq = NULL; /* input stream from the REQUEST file */ ++ FILE *ikeresp; /* output stream to the RESPONSE file */ ++ ++ CK_SLOT_ID slotList[10]; ++ CK_SLOT_ID slotID; ++ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); ++ CK_ULONG count; ++ static const CK_C_INITIALIZE_ARGS pk11args = { ++ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, ++ (void *)"flags=readOnly,noCertDB,noModDB", NULL ++ }; ++ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; ++ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; ++ static CK_BBOOL ck_true = CK_TRUE; ++ static CK_ULONG keyLen = 1; ++ CK_ATTRIBUTE gxy_template[] = { ++ { CKA_VALUE, NULL, 0 }, /* must be first */ ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ }; ++ CK_ULONG gxy_template_count = ++ sizeof(gxy_template) / sizeof(gxy_template[0]); ++ CK_ATTRIBUTE psk_template[] = { ++ { CKA_VALUE, NULL, 0 }, /* must be first */ ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ }; ++ CK_ULONG psk_template_count = ++ sizeof(psk_template) / sizeof(psk_template[0]); ++ CK_ATTRIBUTE derive_template[] = { ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, /* must be last */ ++ }; ++ CK_ULONG derive_template_count = ++ sizeof(derive_template) / sizeof(derive_template[0]); ++ CK_ATTRIBUTE skeyid_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_d_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_a_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE skeyid_e_template = ++ { CKA_VALUE, NULL, 0 }; ++ unsigned char skeyid_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_d_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_a_secret[HASH_LENGTH_MAX]; ++ unsigned char skeyid_e_secret[HASH_LENGTH_MAX]; ++ ++ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; ++ CK_MECHANISM ike1_mech = { CKM_NSS_IKE1_PRF_DERIVE, NULL, 0 }; ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; ++ CK_NSS_IKE1_PRF_DERIVE_PARAMS ike1_prf; ++ CK_RV crv; ++ ++ /* set up PKCS #11 parameters */ ++ ike_prf.bDataAsKey = PR_FALSE; ++ ike_prf.bRekey = PR_FALSE; ++ ike_prf.hNewKey = CK_INVALID_HANDLE; ++ CKYi_len = 8; ++ CKYr_len = 8; ++ ike1_prf.pCKYi = CKYi; ++ ike1_prf.ulCKYiLen = CKYi_len; ++ ike1_prf.pCKYr = CKYr; ++ ike1_prf.ulCKYrLen = CKYr_len; ++ ike_mech.pParameter = &ike_prf; ++ ike_mech.ulParameterLen = sizeof(ike_prf); ++ ike1_mech.pParameter = &ike1_prf; ++ ike1_mech.ulParameterLen = sizeof(ike1_prf); ++ skeyid_template.pValue = skeyid_secret; ++ skeyid_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_d_template.pValue = skeyid_d_secret; ++ skeyid_d_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_a_template.pValue = skeyid_a_secret; ++ skeyid_a_template.ulValueLen = HASH_LENGTH_MAX; ++ skeyid_e_template.pValue = skeyid_e_secret; ++ skeyid_e_template.ulValueLen = HASH_LENGTH_MAX; ++ ++ crv = NSC_Initialize((CK_VOID_PTR)&pk11args); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ count = slotListCount; ++ crv = NSC_GetSlotList(PR_TRUE, slotList, &count); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ if ((count > slotListCount) || count < 1) { ++ fprintf(stderr, ++ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", ++ (int)count, (int)slotListCount); ++ goto loser; ++ } ++ slotID = slotList[0]; ++ ikereq = fopen(reqfn, "r"); ++ ikeresp = stdout; ++ while (fgets(buf, sizeof buf, ikereq) != NULL) { ++ /* a comment or blank line */ ++ if (buf[0] == '#' || buf[0] == '\n') { ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* [.....] */ ++ if (buf[0] == '[') { ++ if (strncmp(buf, "[SHA-1]", 7) == 0) { ++ ike_prf.prfMechanism = CKM_SHA_1_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA_1_HMAC; ++ } ++ if (strncmp(buf, "[SHA-224]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA224_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA224_HMAC; ++ } ++ if (strncmp(buf, "[SHA-256]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA256_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA256_HMAC; ++ } ++ if (strncmp(buf, "[SHA-384]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA384_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA384_HMAC; ++ } ++ if (strncmp(buf, "[SHA-512]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA512_HMAC; ++ ike1_prf.prfMechanism = CKM_SHA512_HMAC; ++ } ++ if (strncmp(buf, "[AES-XCBC", 9) == 0) { ++ ike_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ ike1_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ } ++ if (strncmp(buf, "[g^xy", 5) == 0) { ++ if (sscanf(buf, "[g^xy length = %d]", ++ &gxy_len) != 1) { ++ goto loser; ++ } ++ gxy_len = gxy_len / 8; ++ if (gxy) ++ free(gxy); ++ gxy = malloc(gxy_len); ++ gxy_template[0].pValue = gxy; ++ gxy_template[0].ulValueLen = gxy_len; ++ } ++ if (strncmp(buf, "[pre-shared-key", 15) == 0) { ++ if (sscanf(buf, "[pre-shared-key length = %d]", ++ &psk_len) != 1) { ++ goto loser; ++ } ++ psk_len = psk_len / 8; ++ if (psk) ++ free(psk); ++ psk = malloc(psk_len); ++ psk_template[0].pValue = psk; ++ psk_template[0].ulValueLen = psk_len; ++ } ++ if (strncmp(buf, "[Ni", 3) == 0) { ++ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { ++ goto loser; ++ } ++ Ni_len = Ni_len / 8; ++ if (Ni) ++ free(Ni); ++ Ni = malloc(Ni_len); ++ ike_prf.pNi = Ni; ++ ike_prf.ulNiLen = Ni_len; ++ } ++ if (strncmp(buf, "[Nr", 3) == 0) { ++ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { ++ goto loser; ++ } ++ Nr_len = Nr_len / 8; ++ if (Nr) ++ free(Nr); ++ Nr = malloc(Nr_len); ++ ike_prf.pNr = Nr; ++ ike_prf.ulNrLen = Nr_len; ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* "COUNT = x" begins a new data set */ ++ if (strncmp(buf, "COUNT", 5) == 0) { ++ /* zeroize the variables for the test with this data set */ ++ memset(gxy, 0, gxy_len); ++ memset(Ni, 0, Ni_len); ++ memset(Nr, 0, Nr_len); ++ memset(CKYi, 0, CKYi_len); ++ memset(CKYr, 0, CKYr_len); ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Ni = ... */ ++ if (strncmp(buf, "Ni", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Ni_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Ni[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Nr = ... */ ++ if (strncmp(buf, "Nr", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Nr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Nr[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* CKYi = ... */ ++ if (strncmp(buf, "CKY_I", 5) == 0) { ++ i = 5; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < CKYi_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &CKYi[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* CKYr = ... */ ++ if (strncmp(buf, "CKY_R", 5) == 0) { ++ i = 5; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < CKYr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &CKYr[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* g^xy = ... */ ++ if (strncmp(buf, "g^xy", 4) == 0) { ++ i = 4; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < gxy_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &gxy[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* pre-shared-key = ... */ ++ if (strncmp(buf, "pre-shared-key", 14) == 0) { ++ CK_SESSION_HANDLE session; ++ CK_OBJECT_HANDLE gxy_handle; ++ CK_OBJECT_HANDLE psk_handle; ++ CK_OBJECT_HANDLE skeyid_handle; ++ CK_OBJECT_HANDLE skeyid_d_handle; ++ CK_OBJECT_HANDLE skeyid_a_handle; ++ CK_OBJECT_HANDLE skeyid_e_handle; ++ i = 14; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < psk_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &psk[j]); ++ } ++ fputs(buf, ikeresp); ++ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_CreateObject(session, psk_template, ++ psk_template_count, &psk_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_CreateObject(psk) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_CreateObject(session, gxy_template, ++ gxy_template_count, &gxy_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_CreateObject(gxy) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ /* get the skeyid key */ ++ crv = NSC_DeriveKey(session, &ike_mech, psk_handle, ++ derive_template, derive_template_count - 1, ++ &skeyid_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ skeyid_template.ulValueLen = HASH_LENGTH_MAX; ++ crv = NSC_GetAttributeValue(session, skeyid_handle, ++ &skeyid_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ /* use the length of the skeyid to set the target length of all the ++ * other keys */ ++ keyLen = skeyid_template.ulValueLen; ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = PR_FALSE; ++ ike1_prf.keyNumber = 0; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_d_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_d) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = CK_TRUE; ++ ike1_prf.hPrevKey = skeyid_d_handle; ++ ike1_prf.keyNumber = 1; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_a_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_a) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ ike1_prf.hKeygxy = gxy_handle; ++ ike1_prf.bHasPrevKey = CK_TRUE; ++ ike1_prf.hPrevKey = skeyid_a_handle; ++ ike1_prf.keyNumber = 2; ++ crv = NSC_DeriveKey(session, &ike1_mech, skeyid_handle, ++ derive_template, derive_template_count, ++ &skeyid_e_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid_e) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID = ", ikeresp); ++ to_hex_str(buf, skeyid_secret, keyLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_d_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_d_handle, ++ &skeyid_d_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_d) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_d = ", ikeresp); ++ to_hex_str(buf, skeyid_d_secret, skeyid_d_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_a_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_a_handle, ++ &skeyid_a_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_a) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_a = ", ikeresp); ++ to_hex_str(buf, skeyid_a_secret, skeyid_a_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ skeyid_e_template.ulValueLen = keyLen; ++ crv = NSC_GetAttributeValue(session, skeyid_e_handle, ++ &skeyid_e_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid_e) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYID_e = ", ikeresp); ++ to_hex_str(buf, skeyid_e_secret, skeyid_e_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ crv = NSC_CloseSession(session); ++ continue; ++ } ++ } ++loser: ++ NSC_Finalize(NULL); ++ if (psk) ++ free(psk); ++ if (gxy) ++ free(gxy); ++ if (Ni) ++ free(Ni); ++ if (Nr) ++ free(Nr); ++ if (ikereq) ++ fclose(ikereq); ++} ++ ++void ++ikev2(char *reqfn) ++{ ++ char buf[4096]; /* holds one line from the input REQUEST file. ++ * needs to be large enough to hold the longest ++ * line "g^xy = <2048 hex digits>\n". ++ */ ++ unsigned char *gir = NULL; ++ unsigned char *gir_new = NULL; ++ int gir_len; ++ unsigned char *Ni = NULL; ++ int Ni_len; ++ unsigned char *Nr = NULL; ++ int Nr_len; ++ unsigned char *SPIi = NULL; ++ int SPIi_len = 8; ++ unsigned char *SPIr = NULL; ++ int SPIr_len = 8; ++ unsigned char *DKM = NULL; ++ int DKM_len; ++ unsigned char *DKM_child = NULL; ++ int DKM_child_len; ++ unsigned char *seed_data = NULL; ++ int seed_data_len = 0; ++ unsigned int i, j; ++ FILE *ikereq = NULL; /* input stream from the REQUEST file */ ++ FILE *ikeresp; /* output stream to the RESPONSE file */ ++ ++ CK_SLOT_ID slotList[10]; ++ CK_SLOT_ID slotID; ++ CK_ULONG slotListCount = sizeof(slotList) / sizeof(slotList[0]); ++ CK_ULONG count; ++ static const CK_C_INITIALIZE_ARGS pk11args = { ++ NULL, NULL, NULL, NULL, CKF_LIBRARY_CANT_CREATE_OS_THREADS, ++ (void *)"flags=readOnly,noCertDB,noModDB", NULL ++ }; ++ static CK_OBJECT_CLASS ck_secret = CKO_SECRET_KEY; ++ static CK_KEY_TYPE ck_generic = CKK_GENERIC_SECRET; ++ static CK_BBOOL ck_true = CK_TRUE; ++ static CK_ULONG keyLen = 1; ++ CK_ATTRIBUTE gir_template[] = { ++ { CKA_VALUE, NULL, 0 }, ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ }; ++ CK_ULONG gir_template_count = ++ sizeof(gir_template) / sizeof(gir_template[0]); ++ CK_ATTRIBUTE gir_new_template[] = { ++ { CKA_VALUE, NULL, 0 }, ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ }; ++ CK_ULONG gir_new_template_count = ++ sizeof(gir_new_template) / sizeof(gir_new_template[0]); ++ CK_ATTRIBUTE derive_template[] = { ++ { CKA_CLASS, &ck_secret, sizeof(ck_secret) }, ++ { CKA_KEY_TYPE, &ck_generic, sizeof(ck_generic) }, ++ { CKA_DERIVE, &ck_true, sizeof(ck_true) }, ++ { CKA_VALUE_LEN, &keyLen, sizeof(keyLen) }, ++ }; ++ CK_ULONG derive_template_count = ++ sizeof(derive_template) / sizeof(derive_template[0]); ++ CK_ATTRIBUTE skeyseed_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE dkm_template = ++ { CKA_VALUE, NULL, 0 }; ++ CK_ATTRIBUTE dkm_child_template = ++ { CKA_VALUE, NULL, 0 }; ++ unsigned char skeyseed_secret[HASH_LENGTH_MAX]; ++ ++ CK_MECHANISM ike_mech = { CKM_NSS_IKE_PRF_DERIVE, NULL, 0 }; ++ CK_MECHANISM ike2_mech = { CKM_NSS_IKE_PRF_PLUS_DERIVE, NULL, 0 }; ++ CK_MECHANISM subset_mech = { CKM_EXTRACT_KEY_FROM_KEY, NULL, 0 }; ++ CK_NSS_IKE_PRF_DERIVE_PARAMS ike_prf; ++ CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS ike2_prf; ++ CK_EXTRACT_PARAMS subset_params; ++ CK_RV crv; ++ ++ /* set up PKCS #11 parameters */ ++ ike_mech.pParameter = &ike_prf; ++ ike_mech.ulParameterLen = sizeof(ike_prf); ++ ike2_mech.pParameter = &ike2_prf; ++ ike2_mech.ulParameterLen = sizeof(ike2_prf); ++ subset_mech.pParameter = &subset_params; ++ subset_mech.ulParameterLen = sizeof(subset_params); ++ subset_params = 0; ++ skeyseed_template.pValue = skeyseed_secret; ++ skeyseed_template.ulValueLen = HASH_LENGTH_MAX; ++ ++ crv = NSC_Initialize((CK_VOID_PTR)&pk11args); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_Initialize failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ count = slotListCount; ++ crv = NSC_GetSlotList(PR_TRUE, slotList, &count); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetSlotList failed crv=0x%x\n", (unsigned int)crv); ++ goto loser; ++ } ++ if ((count > slotListCount) || count < 1) { ++ fprintf(stderr, ++ "NSC_GetSlotList returned too many or too few slots: %d slots max=%d min=1\n", ++ (int)count, (int)slotListCount); ++ goto loser; ++ } ++ slotID = slotList[0]; ++ ikereq = fopen(reqfn, "r"); ++ ikeresp = stdout; ++ while (fgets(buf, sizeof buf, ikereq) != NULL) { ++ /* a comment or blank line */ ++ if (buf[0] == '#' || buf[0] == '\n') { ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* [.....] */ ++ if (buf[0] == '[') { ++ if (strncmp(buf, "[SHA-1]", 7) == 0) { ++ ike_prf.prfMechanism = CKM_SHA_1_HMAC; ++ ike2_prf.prfMechanism = CKM_SHA_1_HMAC; ++ } ++ if (strncmp(buf, "[SHA-224]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA224_HMAC; ++ ike2_prf.prfMechanism = CKM_SHA224_HMAC; ++ } ++ if (strncmp(buf, "[SHA-256]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA256_HMAC; ++ ike2_prf.prfMechanism = CKM_SHA256_HMAC; ++ } ++ if (strncmp(buf, "[SHA-384]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA384_HMAC; ++ ike2_prf.prfMechanism = CKM_SHA384_HMAC; ++ } ++ if (strncmp(buf, "[SHA-512]", 9) == 0) { ++ ike_prf.prfMechanism = CKM_SHA512_HMAC; ++ ike2_prf.prfMechanism = CKM_SHA512_HMAC; ++ } ++ if (strncmp(buf, "[AES-XCBC", 9) == 0) { ++ ike_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ ike2_prf.prfMechanism = CKM_AES_XCBC_MAC; ++ } ++ if (strncmp(buf, "[g^ir", 5) == 0) { ++ if (sscanf(buf, "[g^ir length = %d]", ++ &gir_len) != 1) { ++ goto loser; ++ } ++ gir_len = gir_len / 8; ++ if (gir) ++ free(gir); ++ if (gir_new) ++ free(gir_new); ++ gir = malloc(gir_len); ++ gir_new = malloc(gir_len); ++ gir_template[0].pValue = gir; ++ gir_template[0].ulValueLen = gir_len; ++ gir_new_template[0].pValue = gir_new; ++ gir_new_template[0].ulValueLen = gir_len; ++ } ++ if (strncmp(buf, "[Ni", 3) == 0) { ++ if (sscanf(buf, "[Ni length = %d]", &Ni_len) != 1) { ++ goto loser; ++ } ++ Ni_len = Ni_len / 8; ++ } ++ if (strncmp(buf, "[Nr", 3) == 0) { ++ if (sscanf(buf, "[Nr length = %d]", &Nr_len) != 1) { ++ goto loser; ++ } ++ Nr_len = Nr_len / 8; ++ } ++ if (strncmp(buf, "[DKM", 4) == 0) { ++ if (sscanf(buf, "[DKM length = %d]", ++ &DKM_len) != 1) { ++ goto loser; ++ } ++ DKM_len = DKM_len / 8; ++ if (DKM) ++ free(DKM); ++ DKM = malloc(DKM_len); ++ dkm_template.pValue = DKM; ++ dkm_template.ulValueLen = DKM_len; ++ } ++ if (strncmp(buf, "[Child SA DKM", 13) == 0) { ++ if (sscanf(buf, "[Child SA DKM length = %d]", ++ &DKM_child_len) != 1) { ++ goto loser; ++ } ++ DKM_child_len = DKM_child_len / 8; ++ if (DKM_child) ++ free(DKM_child); ++ DKM_child = malloc(DKM_child_len); ++ dkm_child_template.pValue = DKM_child; ++ dkm_child_template.ulValueLen = DKM_child_len; ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* "COUNT = x" begins a new data set */ ++ if (strncmp(buf, "COUNT", 5) == 0) { ++ /* zeroize the variables for the test with this data set */ ++ int new_seed_len = Ni_len + Nr_len + SPIi_len + SPIr_len; ++ if (seed_data_len != new_seed_len) { ++ if (seed_data) ++ free(seed_data); ++ seed_data_len = new_seed_len; ++ seed_data = malloc(seed_data_len); ++ Ni = seed_data; ++ Nr = &seed_data[Ni_len]; ++ SPIi = &seed_data[Ni_len + Nr_len]; ++ SPIr = &seed_data[new_seed_len - SPIr_len]; ++ ike_prf.pNi = Ni; ++ ike_prf.ulNiLen = Ni_len; ++ ike_prf.pNr = Nr; ++ ike_prf.ulNrLen = Nr_len; ++ ike2_prf.pSeedData = seed_data; ++ } ++ memset(gir, 0, gir_len); ++ memset(gir_new, 0, gir_len); ++ memset(seed_data, 0, seed_data_len); ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Ni = ... */ ++ if (strncmp(buf, "Ni", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Ni_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Ni[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* Nr = ... */ ++ if (strncmp(buf, "Nr", 2) == 0) { ++ i = 2; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < Nr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &Nr[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* g^ir (new) = ... */ ++ if (strncmp(buf, "g^ir (new)", 10) == 0) { ++ i = 10; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < gir_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &gir_new[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* g^ir = ... */ ++ if (strncmp(buf, "g^ir", 4) == 0) { ++ i = 4; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < gir_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &gir[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* SPIi = ... */ ++ if (strncmp(buf, "SPIi", 4) == 0) { ++ i = 4; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < SPIi_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &SPIi[j]); ++ } ++ fputs(buf, ikeresp); ++ continue; ++ } ++ /* SPIr = ... */ ++ if (strncmp(buf, "SPIr", 4) == 0) { ++ CK_SESSION_HANDLE session; ++ CK_OBJECT_HANDLE gir_handle; ++ CK_OBJECT_HANDLE gir_new_handle; ++ CK_OBJECT_HANDLE skeyseed_handle; ++ CK_OBJECT_HANDLE sk_d_handle; ++ CK_OBJECT_HANDLE skeyseed_new_handle; ++ CK_OBJECT_HANDLE dkm_handle; ++ CK_OBJECT_HANDLE dkm_child_handle; ++ i = 4; ++ while (isspace(buf[i]) || buf[i] == '=') { ++ i++; ++ } ++ for (j = 0; j < SPIr_len; i += 2, j++) { ++ hex_to_byteval(&buf[i], &SPIr[j]); ++ } ++ fputs(buf, ikeresp); ++ crv = NSC_OpenSession(slotID, 0, NULL, NULL, &session); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_OpenSession failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_CreateObject(session, gir_template, ++ gir_template_count, &gir_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_CreateObject (g^ir) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_CreateObject(session, gir_new_template, ++ gir_new_template_count, &gir_new_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_CreateObject (g^ir new) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ /* get the SKEYSEED key */ ++ ike_prf.bDataAsKey = CK_TRUE; ++ ike_prf.bRekey = CK_FALSE; ++ ike_prf.hNewKey = CK_INVALID_HANDLE; ++ crv = NSC_DeriveKey(session, &ike_mech, gir_handle, ++ derive_template, derive_template_count - 1, ++ &skeyseed_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ skeyseed_template.ulValueLen = HASH_LENGTH_MAX; ++ crv = NSC_GetAttributeValue(session, skeyseed_handle, ++ &skeyseed_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYSEED = ", ikeresp); ++ to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ /* get DKM */ ++ keyLen = DKM_len; ++ ike2_prf.bHasSeedKey = CK_FALSE; ++ ike2_prf.hSeedKey = CK_INVALID_HANDLE; ++ ike2_prf.ulSeedDataLen = seed_data_len; ++ crv = NSC_DeriveKey(session, &ike2_mech, skeyseed_handle, ++ derive_template, derive_template_count, ++ &dkm_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(DKM) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_GetAttributeValue(session, dkm_handle, ++ &dkm_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(DKM) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("DKM = ", ikeresp); ++ to_hex_str(buf, DKM, DKM_len); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ /* get the sk_d from the DKM */ ++ keyLen = skeyseed_template.ulValueLen; ++ crv = NSC_DeriveKey(session, &subset_mech, dkm_handle, ++ derive_template, derive_template_count, ++ &sk_d_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(sk_d) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ ++ /* get DKM child */ ++ keyLen = DKM_child_len; ++ ike2_prf.bHasSeedKey = CK_FALSE; ++ ike2_prf.hSeedKey = CK_INVALID_HANDLE; ++ ike2_prf.ulSeedDataLen = Ni_len + Nr_len; ++ crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle, ++ derive_template, derive_template_count, ++ &dkm_child_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(DKM Child SA) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_GetAttributeValue(session, dkm_child_handle, ++ &dkm_child_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(DKM Child SA) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("DKM(Child SA) = ", ikeresp); ++ to_hex_str(buf, DKM_child, DKM_child_len); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ /* get DKM child D-H*/ ++ keyLen = DKM_child_len; ++ ike2_prf.bHasSeedKey = CK_TRUE; ++ ike2_prf.hSeedKey = gir_new_handle; ++ ike2_prf.ulSeedDataLen = Ni_len + Nr_len; ++ crv = NSC_DeriveKey(session, &ike2_mech, sk_d_handle, ++ derive_template, derive_template_count, ++ &dkm_child_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(DKM Child SA D-H) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ crv = NSC_GetAttributeValue(session, dkm_child_handle, ++ &dkm_child_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(DKM Child SA D-H) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("DKM(Child SA D-H) = ", ikeresp); ++ to_hex_str(buf, DKM_child, DKM_child_len); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ /* get SKEYSEED(rekey) */ ++ ike_prf.bDataAsKey = CK_FALSE; ++ ike_prf.bRekey = CK_TRUE; ++ ike_prf.hNewKey = gir_new_handle; ++ crv = NSC_DeriveKey(session, &ike_mech, sk_d_handle, ++ derive_template, derive_template_count - 1, ++ &skeyseed_new_handle); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_DeriveKey(skeyid rekey) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ skeyseed_template.ulValueLen = HASH_LENGTH_MAX; ++ crv = NSC_GetAttributeValue(session, skeyseed_new_handle, ++ &skeyseed_template, 1); ++ if (crv != CKR_OK) { ++ fprintf(stderr, "NSC_GetAttribute(skeyid) failed crv=0x%x\n", ++ (unsigned int)crv); ++ goto loser; ++ } ++ fputs("SKEYSEED(rekey) = ", ikeresp); ++ to_hex_str(buf, skeyseed_secret, skeyseed_template.ulValueLen); ++ fputs(buf, ikeresp); ++ fputc('\n', ikeresp); ++ ++ crv = NSC_CloseSession(session); ++ continue; ++ } ++ } ++loser: ++ NSC_Finalize(NULL); ++ if (gir) ++ free(gir); ++ if (gir_new) ++ free(gir_new); ++ if (seed_data) ++ free(seed_data); ++ if (DKM) ++ free(DKM); ++ if (DKM_child) ++ free(DKM_child); ++ if (ikereq) ++ fclose(ikereq); ++} ++ + int + main(int argc, char **argv) + { + if (argc < 2) + exit(-1); + + RNG_RNGInit(); + SECOID_Init(); +@@ -7066,11 +8369,19 @@ main(int argc, char **argv) + rng_mct(argv[3]); + } + } else if (strcmp(argv[1], "drbg") == 0) { + /* Variable Seed Test */ + drbg(argv[2]); + } else if (strcmp(argv[1], "ddrbg") == 0) { + debug = 1; + drbg(argv[2]); ++ } else if (strcmp(argv[1], "tls") == 0) { ++ tls(argv[2]); ++ } else if (strcmp(argv[1], "ikev1") == 0) { ++ ikev1(argv[2]); ++ } else if (strcmp(argv[1], "ikev1-psk") == 0) { ++ ikev1_psk(argv[2]); ++ } else if (strcmp(argv[1], "ikev2") == 0) { ++ ikev2(argv[2]); + } + return 0; + } +diff --git a/cmd/fipstest/hmac.sh b/cmd/fipstest/hmac.sh +deleted file mode 100755 +--- a/cmd/fipstest/hmac.sh ++++ /dev/null +@@ -1,36 +0,0 @@ +-#!/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 HMAC 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}/HMAC +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-hmac_requests=" +-HMAC.req +-" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $hmac_requests; do +- sh ./validate1.sh ${TESTDIR} $request +- done +- exit 0 +-fi +-for request in $hmac_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response +-done +- +diff --git a/cmd/fipstest/kas.sh b/cmd/fipstest/kas.sh +deleted file mode 100755 +--- a/cmd/fipstest/kas.sh ++++ /dev/null +@@ -1,84 +0,0 @@ +-#!/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 DSA Validation System +-# +-# 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 +- +- +-# +-if [ ${COMMAND} = "verify" ]; then +-# +-# need verify for KAS tests +- +-# verify generated keys +-# name=KeyPair +-# echo ">>>>> $name" +-# fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify generated pqg values +-# name=PQGGen +-# echo ">>>>> $name" +-# fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify PQGVer with known answer +-# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;' +-# verify signatures +-# name=SigGen +-# echo ">>>>> $name" +-# fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# verify SigVer with known answer +-# sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;' +- exit 0 +-fi +- +-request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdh init-func ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASFunctionTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdh resp-func ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_init.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdh init-verify ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASValidityTest_ECCEphemeralUnified_NOKC_ZZOnly_resp.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest ecdh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_init.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dh init-func ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASFunctionTest_FFCEphem_NOKC_ZZOnly_resp.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dh resp-func ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASValidityTest_FFCEphem_NOKC_ZZOnly_init.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dh init-verify ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=KASValidityTest_FFCEphem_NOKC_ZZOnly_resp.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest dh resp-verify ${REQDIR}/$request > ${RSPDIR}/$response +- +diff --git a/cmd/fipstest/rng.sh b/cmd/fipstest/rng.sh +deleted file mode 100644 +--- a/cmd/fipstest/rng.sh ++++ /dev/null +@@ -1,34 +0,0 @@ +-#!/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}/DRBG800-90A +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-drbg_requests=" +-Hash_DRBG.req +-" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $drbg_requests; do +- sh ./validate1.sh ${TESTDIR} $request +- done +- exit 0 +-fi +-for request in $drbg_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response +-done +diff --git a/cmd/fipstest/rsa.sh b/cmd/fipstest/rsa.sh +deleted file mode 100644 +--- a/cmd/fipstest/rsa.sh ++++ /dev/null +@@ -1,50 +0,0 @@ +-#!/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 RSA Validation System +-# +-# 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}/RSA2 +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-if [ ${COMMAND} = "verify" ]; then +-#verify the signatures. The fax file does not have any known answers, so +-#use our own verify function. +- name=SigGen15_186-3 +- echo ">>>>> $name" +- fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F +-# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F +-#The Fax file has the private exponent and the salt value, remove it +-#also remove the false reason +- sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;' +-# +-# currently don't have a way to verify the RSA keygen +-# +- exit 0 +-fi +- +-request=SigGen15_186-3.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response +- +-request=SigVer15_186-3.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response +- +-#request=KeyGen_186-3.req +-request=KeyGen_RandomProbablyPrime3_3.req +-response=`echo $request | sed -e "s/req/rsp/"` +-echo $request $response +-fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response +diff --git a/cmd/fipstest/runtest.sh b/cmd/fipstest/runtest.sh +deleted file mode 100644 +--- a/cmd/fipstest/runtest.sh ++++ /dev/null +@@ -1,14 +0,0 @@ +-#!/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/. +-# +-TESTDIR=${1-.} +-COMMAND=${2-run} +-TESTS="aes aesgcm dsa ecdsa hmac kas tls rng rsa sha tdea" +-for i in $TESTS +-do +- echo "********************Running $i tests" +- sh ./${i}.sh ${TESTDIR} ${COMMAND} +-done +diff --git a/cmd/fipstest/sha.sh b/cmd/fipstest/sha.sh +deleted file mode 100644 +--- a/cmd/fipstest/sha.sh ++++ /dev/null +@@ -1,66 +0,0 @@ +-#!/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 SHA 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}/SHA +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-sha_ShortMsg_requests=" +-SHA1ShortMsg.req +-SHA224ShortMsg.req +-SHA256ShortMsg.req +-SHA384ShortMsg.req +-SHA512ShortMsg.req +-" +- +-sha_LongMsg_requests=" +-SHA1LongMsg.req +-SHA224LongMsg.req +-SHA256LongMsg.req +-SHA384LongMsg.req +-SHA512LongMsg.req +-" +- +-sha_Monte_requests=" +-SHA1Monte.req +-SHA224Monte.req +-SHA256Monte.req +-SHA384Monte.req +-SHA512Monte.req +-" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do +- sh ./validate1.sh ${TESTDIR} $request +- done +- exit 0 +-fi +- +-for request in $sha_ShortMsg_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $sha_LongMsg_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $sha_Monte_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response +-done +- +diff --git a/cmd/fipstest/tdea.sh b/cmd/fipstest/tdea.sh +deleted file mode 100644 +--- a/cmd/fipstest/tdea.sh ++++ /dev/null +@@ -1,106 +0,0 @@ +-#!/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 tdea 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}/TDES +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-#CBC_Known_Answer_tests +-#Initial Permutation KAT +-#Permutation Operation KAT +-#Subsitution Table KAT +-#Variable Key KAT +-#Variable PlainText KAT +-cbc_kat_requests=" +-TCBCinvperm.req +-TCBCpermop.req +-TCBCsubtab.req +-TCBCvarkey.req +-TCBCvartext.req +-" +- +-#CBC Monte Carlo KATs +-cbc_monte_requests=" +-TCBCMonte1.req +-TCBCMonte2.req +-TCBCMonte3.req +-" +-#Multi-block Message KATs +-cbc_mmt_requests=" +-TCBCMMT1.req +-TCBCMMT2.req +-TCBCMMT3.req +-" +- +-ecb_kat_requests=" +-TECBinvperm.req +-TECBpermop.req +-TECBsubtab.req +-TECBvarkey.req +-TECBvartext.req +-" +- +-ecb_monte_requests=" +-TECBMonte1.req +-TECBMonte2.req +-TECBMonte3.req +-" +- +-ecb_mmt_requests=" +-TECBMMT1.req +-TECBMMT2.req +-TECBMMT3.req +-" +- +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests +- do +- sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d" +- done +- exit 0 +-fi +- +-for request in $cbc_kat_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $cbc_mmt_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $cbc_monte_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_kat_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_mmt_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +-for request in $ecb_monte_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response +-done +diff --git a/cmd/fipstest/tls.sh b/cmd/fipstest/tls.sh +deleted file mode 100644 +--- a/cmd/fipstest/tls.sh ++++ /dev/null +@@ -1,34 +0,0 @@ +-#!/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}/KDF135 +-COMMAND=${2-run} +-REQDIR=${TESTDIR}/req +-RSPDIR=${TESTDIR}/resp +- +-drbg_requests=" +-tls.req +-" +- +-if [ ${COMMAND} = "verify" ]; then +- for request in $drbg_requests; do +- sh ./validate1.sh ${TESTDIR} $request +- done +- exit 0 +-fi +-for request in $drbg_requests; do +- response=`echo $request | sed -e "s/req/rsp/"` +- echo $request $response +- fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response +-done +diff --git a/cmd/fipstest/validate.sh b/cmd/fipstest/validate.sh +deleted file mode 100644 +--- a/cmd/fipstest/validate.sh ++++ /dev/null +@@ -1,7 +0,0 @@ +-#!/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/. +-# +-sh ./runtest.sh ${1-.} verify +diff --git a/cmd/fipstest/validate1.sh b/cmd/fipstest/validate1.sh +deleted file mode 100644 +--- a/cmd/fipstest/validate1.sh ++++ /dev/null +@@ -1,30 +0,0 @@ +-#!/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/. +-# +-# Validate1.sh is a helper shell script that each of the base test shell +-# scripts call to help validate that the generated response (response) +-# matches the known answer response (fax). Sometimes (depending on the +-# individual tests) there are extraneous output in either or both response +-# and fax files. These allow the caller to pass in additional sed commands +-# to clear out those extraneous outputs before we compare the two files. +-# The sed line always clears out Windows line endings, replaces tabs with +-# spaces, and removed comments. +-# +-TESTDIR=${1-.} +-request=${2} +-extraneous_response=${3} +-extraneous_fax=${4} +-name=`basename $request .req` +-echo ">>>>> $name" +-sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1 +-# if we didn't generate any output, flag that as an error +-size=`sum /tmp/y1 | awk '{ print $NF }'` +-if [ $size -eq 0 ]; then +- echo "${TESTDIR}/resp/${name}.rsp: empty" +- exit 1; +-fi +-sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2 +-diff -i -w -B /tmp/y1 /tmp/y2 +diff --git a/lib/pk11wrap/pk11mech.c b/lib/pk11wrap/pk11mech.c +--- a/lib/pk11wrap/pk11mech.c ++++ b/lib/pk11wrap/pk11mech.c +@@ -234,16 +234,18 @@ PK11_GetKeyType(CK_MECHANISM_TYPE type, + case CKM_AES_CTS: + case CKM_AES_GCM: + case CKM_AES_MAC: + case CKM_AES_MAC_GENERAL: + case CKM_AES_CBC_PAD: + case CKM_AES_KEY_GEN: + case CKM_NETSCAPE_AES_KEY_WRAP: + case CKM_NETSCAPE_AES_KEY_WRAP_PAD: ++ case CKM_AES_XCBC_MAC: ++ case CKM_AES_XCBC_MAC_96: + return CKK_AES; + case CKM_DES_ECB: + case CKM_DES_CBC: + case CKM_DES_MAC: + case CKM_DES_MAC_GENERAL: + case CKM_DES_CBC_PAD: + case CKM_DES_KEY_GEN: + case CKM_KEY_WRAP_LYNKS: +diff --git a/lib/pk11wrap/pk11skey.c b/lib/pk11wrap/pk11skey.c +--- a/lib/pk11wrap/pk11skey.c ++++ b/lib/pk11wrap/pk11skey.c +@@ -1593,16 +1593,17 @@ PK11_DeriveWithTemplate(PK11SymKey *base + } else { + pk11_ExitKeyMonitor(symKey); + } + } + if (newBaseKey) + PK11_FreeSymKey(newBaseKey); + if (crv != CKR_OK) { + PK11_FreeSymKey(symKey); ++ PORT_SetError(PK11_MapError(crv)); + return NULL; + } + return symKey; + } + + /* Create a new key by concatenating base and data + */ + static PK11SymKey * +diff --git a/lib/softoken/fipstest.c b/lib/softoken/fipstest.c +--- a/lib/softoken/fipstest.c ++++ b/lib/softoken/fipstest.c +@@ -7,16 +7,17 @@ + + #ifndef NSS_FIPS_DISABLED + #include "seccomon.h" + #include "blapi.h" + #include "softoken.h" + #include "lowkeyi.h" + #include "secoid.h" + #include "secerr.h" ++#include "pkcs11i.h" + + /* + * different platforms have different ways of calling and initial entry point + * when the dll/.so is loaded. Most platforms support either a posix pragma + * or the GCC attribute. Some platforms suppor a pre-defined name, and some + * platforms have a link line way of invoking this function. + */ + +@@ -621,16 +622,20 @@ sftk_startup_tests(void) + return; + } + if (!BLAPI_SHVerify(libraryName, + (PRFuncPtr)&sftk_fips_RSA_PowerUpSelfTest)) { + /* something is wrong with the library, fail without enabling + * the token */ + return; + } ++ rv = sftk_fips_IKE_PowerUpSelfTests(); ++ if (rv != SECSuccess) { ++ return; ++ } + sftk_self_tests_success = PR_TRUE; + } + + /* + * this is called from nsc_Common_Initizialize entry points that gates access + * to * all other pkcs11 functions. This prevents softoken operation if our + * power on selftest failed. + */ +diff --git a/lib/softoken/manifest.mn b/lib/softoken/manifest.mn +--- a/lib/softoken/manifest.mn ++++ b/lib/softoken/manifest.mn +@@ -41,16 +41,17 @@ CSRCS = \ + lowpbe.c \ + padbuf.c \ + pkcs11.c \ + pkcs11c.c \ + pkcs11u.c \ + sdb.c \ + sftkdb.c \ + sftkhmac.c \ ++ sftkike.c \ + sftkpars.c \ + sftkpwd.c \ + softkver.c \ + tlsprf.c \ + jpakesftk.c \ + $(NULL) + + ifdef SQLITE_UNSAFE_THREADS +diff --git a/lib/softoken/pkcs11.c b/lib/softoken/pkcs11.c +--- a/lib/softoken/pkcs11.c ++++ b/lib/softoken/pkcs11.c +@@ -323,16 +323,18 @@ static const struct mechanismList mechan + { CKM_AES_ECB, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + { CKM_AES_CBC, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + { CKM_AES_MAC, { 16, 32, CKF_SN_VR }, PR_TRUE }, + { CKM_AES_MAC_GENERAL, { 16, 32, CKF_SN_VR }, PR_TRUE }, + { CKM_AES_CBC_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + { CKM_AES_CTS, { 16, 32, CKF_EN_DE }, PR_TRUE }, + { CKM_AES_CTR, { 16, 32, CKF_EN_DE }, PR_TRUE }, + { CKM_AES_GCM, { 16, 32, CKF_EN_DE }, PR_TRUE }, ++ { CKM_AES_XCBC_MAC_96, { 12, 12, CKF_SN_VR }, PR_TRUE }, ++ { CKM_AES_XCBC_MAC, { 16, 16, CKF_SN_VR }, PR_TRUE }, + /* ------------------------- Camellia Operations --------------------- */ + { CKM_CAMELLIA_KEY_GEN, { 16, 32, CKF_GENERATE }, PR_TRUE }, + { CKM_CAMELLIA_ECB, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + { CKM_CAMELLIA_CBC, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + { CKM_CAMELLIA_MAC, { 16, 32, CKF_SN_VR }, PR_TRUE }, + { CKM_CAMELLIA_MAC_GENERAL, { 16, 32, CKF_SN_VR }, PR_TRUE }, + { CKM_CAMELLIA_CBC_PAD, { 16, 32, CKF_EN_DE_WR_UN }, PR_TRUE }, + /* ------------------------- SEED Operations --------------------------- */ +@@ -504,17 +506,21 @@ static const struct mechanismList mechan + { CKM_NSS_JPAKE_ROUND2_SHA384, { 0, 0, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_JPAKE_ROUND2_SHA512, { 0, 0, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_JPAKE_FINAL_SHA1, { 0, 0, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_JPAKE_FINAL_SHA256, { 0, 0, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_JPAKE_FINAL_SHA384, { 0, 0, CKF_DERIVE }, PR_TRUE }, + { CKM_NSS_JPAKE_FINAL_SHA512, { 0, 0, CKF_DERIVE }, PR_TRUE }, + /* -------------------- Constant Time TLS MACs ----------------------- */ + { CKM_NSS_HMAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE }, +- { CKM_NSS_SSL3_MAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE } ++ { CKM_NSS_SSL3_MAC_CONSTANT_TIME, { 0, 0, CKF_DIGEST }, PR_TRUE }, ++ /* --------------------IPSEC ----------------------- */ ++ { CKM_NSS_IKE_PRF_PLUS_DERIVE, { 8, 255 * 64, CKF_DERIVE }, PR_TRUE }, ++ { CKM_NSS_IKE_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE }, ++ { CKM_NSS_IKE1_PRF_DERIVE, { 8, 64, CKF_DERIVE }, PR_TRUE } + }; + static const CK_ULONG mechanismCount = sizeof(mechanisms) / sizeof(mechanisms[0]); + + /* sigh global so fipstokn can read it */ + PRBool nsc_init = PR_FALSE; + + #if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED) + +diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c +--- a/lib/softoken/pkcs11c.c ++++ b/lib/softoken/pkcs11c.c +@@ -94,49 +94,16 @@ sftk_Space(void *data, PRBool freeit) + PORT_Free(data); + } + + /* + * map all the SEC_ERROR_xxx error codes that may be returned by freebl + * functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward + * compatibility. + */ +-static CK_RV +-sftk_MapCryptError(int error) +-{ +- switch (error) { +- case SEC_ERROR_INVALID_ARGS: +- case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */ +- return CKR_ARGUMENTS_BAD; +- case SEC_ERROR_INPUT_LEN: +- return CKR_DATA_LEN_RANGE; +- case SEC_ERROR_OUTPUT_LEN: +- return CKR_BUFFER_TOO_SMALL; +- case SEC_ERROR_LIBRARY_FAILURE: +- return CKR_GENERAL_ERROR; +- case SEC_ERROR_NO_MEMORY: +- return CKR_HOST_MEMORY; +- case SEC_ERROR_BAD_SIGNATURE: +- return CKR_SIGNATURE_INVALID; +- case SEC_ERROR_INVALID_KEY: +- return CKR_KEY_SIZE_RANGE; +- case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */ +- return CKR_KEY_SIZE_RANGE; /* the closest error code */ +- case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM: +- return CKR_TEMPLATE_INCONSISTENT; +- case SEC_ERROR_UNSUPPORTED_KEYALG: +- return CKR_MECHANISM_INVALID; +- case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE: +- return CKR_DOMAIN_PARAMS_INVALID; +- /* key pair generation failed after max number of attempts */ +- case SEC_ERROR_NEED_RANDOM: +- return CKR_FUNCTION_FAILED; +- } +- return CKR_DEVICE_ERROR; +-} + + /* used by Decrypt and UnwrapKey (indirectly) */ + static CK_RV + sftk_MapDecryptError(int error) + { + switch (error) { + case SEC_ERROR_BAD_DATA: + return CKR_ENCRYPTED_DATA_INVALID; +@@ -2075,19 +2042,22 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSessi + CK_MECHANISM cbc_mechanism; + CK_ULONG mac_bytes = SFTK_INVALID_MAC_SIZE; + CK_RC2_CBC_PARAMS rc2_params; + #if NSS_SOFTOKEN_DOES_RC5 + CK_RC5_CBC_PARAMS rc5_params; + CK_RC5_MAC_GENERAL_PARAMS *rc5_mac; + #endif + unsigned char ivBlock[SFTK_MAX_BLOCK_SIZE]; ++ unsigned char k2[SFTK_MAX_BLOCK_SIZE]; ++ unsigned char k3[SFTK_MAX_BLOCK_SIZE]; + SFTKSessionContext *context; + CK_RV crv; + unsigned int blockSize; ++ PRBool isXCBC = PR_FALSE; + + switch (pMechanism->mechanism) { + case CKM_RC2_MAC_GENERAL: + if (!pMechanism->pParameter) { + return CKR_MECHANISM_PARAM_INVALID; + } + mac_bytes = + ((CK_RC2_MAC_GENERAL_PARAMS *)pMechanism->pParameter)->ulMacLength; +@@ -2181,43 +2151,82 @@ sftk_InitCBCMac(CK_SESSION_HANDLE hSessi + /* fall through */ + case CKM_AES_MAC: + blockSize = 16; + PORT_Memset(ivBlock, 0, blockSize); + cbc_mechanism.mechanism = CKM_AES_CBC; + cbc_mechanism.pParameter = &ivBlock; + cbc_mechanism.ulParameterLen = blockSize; + break; ++ case CKM_AES_XCBC_MAC_96: ++ case CKM_AES_XCBC_MAC: ++ /* The only difference between CKM_AES_XCBC_MAC ++ * and CKM_AES_XCBC_MAC_96 is the size of the returned mac. */ ++ mac_bytes = pMechanism->mechanism == CKM_AES_XCBC_MAC_96 ? 12 : 16; ++ blockSize = 16; ++ PORT_Memset(ivBlock, 0, blockSize); ++ cbc_mechanism.mechanism = CKM_AES_CBC; ++ cbc_mechanism.pParameter = &ivBlock; ++ cbc_mechanism.ulParameterLen = blockSize; ++ /* is XCBC requires extra processing at the end of the operation */ ++ isXCBC = PR_TRUE; ++ /* The input key is used to generate k1, k2, and k3. k2 and k3 ++ * are used at the end in the pad step. k1 replaces the input ++ * key in the aes cbc mac */ ++ crv = sftk_aes_xcbc_new_keys(hSession, hKey, &hKey, k2, k3); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ break; + default: + return CKR_FUNCTION_NOT_SUPPORTED; + } + + /* if MAC size is externally supplied, it should be checked. + */ + if (mac_bytes == SFTK_INVALID_MAC_SIZE) + mac_bytes = blockSize >> 1; + else { +- if (mac_bytes > blockSize) +- return CKR_MECHANISM_PARAM_INVALID; ++ if (mac_bytes > blockSize) { ++ crv = CKR_MECHANISM_PARAM_INVALID; ++ goto fail; ++ } + } + + crv = sftk_CryptInit(hSession, &cbc_mechanism, hKey, + CKA_ENCRYPT, /* CBC mech is able to ENCRYPT, not SIGN/VERIFY */ + keyUsage, contextType, PR_TRUE); + if (crv != CKR_OK) +- return crv; ++ goto fail; + crv = sftk_GetContext(hSession, &context, contextType, PR_TRUE, NULL); + + /* this shouldn't happen! */ + PORT_Assert(crv == CKR_OK); + if (crv != CKR_OK) +- return crv; ++ goto fail; + context->blockSize = blockSize; + context->macSize = mac_bytes; ++ context->isXCBC = isXCBC; ++ if (isXCBC) { ++ /* save the xcbc specific parameters */ ++ PORT_Memcpy(context->k2, k2, blockSize); ++ PORT_Memcpy(context->k3, k3, blockSize); ++ PORT_Memset(k2, 0, blockSize); ++ PORT_Memset(k3, 0, blockSize); ++ /* get rid of the temp key now that the context has been created */ ++ NSC_DestroyObject(hSession, hKey); ++ } + return CKR_OK; ++fail: ++ if (isXCBC) { ++ PORT_Memset(k2, 0, blockSize); ++ PORT_Memset(k3, 0, blockSize); ++ NSC_DestroyObject(hSession, hKey); /* get rid of our temp key */ ++ } ++ return crv; + } + + /* + * encode RSA PKCS #1 Signature data before signing... + */ + static SECStatus + sftk_RSAHashSign(SFTKHashSignInfo *info, unsigned char *sig, + unsigned int *sigLen, unsigned int maxLen, +@@ -2823,16 +2832,23 @@ sftk_MACBlock(SFTKSessionContext *ctx, v + * + * Call once, then terminate MACing operation. + */ + static CK_RV + sftk_MACFinal(SFTKSessionContext *ctx) + { + unsigned int padLen = ctx->padDataLength; + /* pad and proceed the residual */ ++ if (ctx->isXCBC) { ++ CK_RV crv = sftk_xcbc_mac_pad(ctx->padBuf, padLen, ctx->blockSize, ++ ctx->k2, ctx->k3); ++ if (crv != CKR_OK) ++ return crv; ++ return sftk_MACBlock(ctx, ctx->padBuf); ++ } + if (padLen) { + /* shd clr ctx->padLen to make sftk_MACFinal idempotent */ + PORT_Memset(ctx->padBuf + padLen, 0, ctx->blockSize - padLen); + return sftk_MACBlock(ctx, ctx->padBuf); + } else + return CKR_OK; + } + +@@ -2861,31 +2877,31 @@ sftk_MACUpdate(CK_SESSION_HANDLE hSessio + + unsigned int blkSize = context->blockSize; + unsigned char *residual = /* free room in context->padBuf */ + context->padBuf + context->padDataLength; + unsigned int minInput = /* min input for MACing at least one block */ + blkSize - context->padDataLength; + + /* not enough data even for one block */ +- if (ulPartLen < minInput) { ++ if (ulPartLen <= minInput) { + PORT_Memcpy(residual, pPart, ulPartLen); + context->padDataLength += ulPartLen; + goto cleanup; + } + /* MACing residual */ + if (context->padDataLength) { + PORT_Memcpy(residual, pPart, minInput); + ulPartLen -= minInput; + pPart += minInput; + if (CKR_OK != (crv = sftk_MACBlock(context, context->padBuf))) + goto terminate; + } + /* MACing full blocks */ +- while (ulPartLen >= blkSize) { ++ while (ulPartLen > blkSize) { + if (CKR_OK != (crv = sftk_MACBlock(context, pPart))) + goto terminate; + ulPartLen -= blkSize; + pPart += blkSize; + } + /* save the residual */ + if ((context->padDataLength = ulPartLen)) + PORT_Memcpy(context->padBuf, pPart, ulPartLen); +@@ -6513,16 +6529,55 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + if (att == NULL) { + sftk_FreeObject(key); + sftk_FreeObject(sourceKey); + return CKR_KEY_HANDLE_INVALID; + } + } + + switch (mechanism) { ++ case CKM_NSS_IKE_PRF_DERIVE: ++ if (pMechanism->ulParameterLen != ++ sizeof(CK_NSS_IKE_PRF_DERIVE_PARAMS)) { ++ crv = CKR_MECHANISM_PARAM_INVALID; ++ break; ++ } ++ crv = sftk_ike_prf(hSession, att, ++ (CK_NSS_IKE_PRF_DERIVE_PARAMS *)pMechanism->pParameter, key); ++ break; ++ case CKM_NSS_IKE1_PRF_DERIVE: ++ if (pMechanism->ulParameterLen != ++ sizeof(CK_NSS_IKE1_PRF_DERIVE_PARAMS)) { ++ crv = CKR_MECHANISM_PARAM_INVALID; ++ break; ++ } ++ crv = sftk_ike1_prf(hSession, att, ++ (CK_NSS_IKE1_PRF_DERIVE_PARAMS *)pMechanism->pParameter, ++ key, keySize); ++ break; ++ case CKM_NSS_IKE1_APP_B_PRF_DERIVE: ++ if (pMechanism->ulParameterLen != ++ sizeof(CK_MECHANISM_TYPE)) { ++ crv = CKR_MECHANISM_PARAM_INVALID; ++ break; ++ } ++ crv = sftk_ike1_appendix_b_prf(hSession, att, ++ (CK_MECHANISM_TYPE *)pMechanism->pParameter, ++ key, keySize); ++ break; ++ case CKM_NSS_IKE_PRF_PLUS_DERIVE: ++ if (pMechanism->ulParameterLen != ++ sizeof(CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS)) { ++ crv = CKR_MECHANISM_PARAM_INVALID; ++ break; ++ } ++ crv = sftk_ike_prf_plus(hSession, att, ++ (CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *)pMechanism->pParameter, ++ key, keySize); ++ break; + /* + * generate the master secret + */ + case CKM_TLS12_MASTER_KEY_DERIVE: + case CKM_TLS12_MASTER_KEY_DERIVE_DH: + case CKM_NSS_TLS_MASTER_KEY_DERIVE_SHA256: + case CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256: + case CKM_TLS_MASTER_KEY_DERIVE: +diff --git a/lib/softoken/pkcs11i.h b/lib/softoken/pkcs11i.h +--- a/lib/softoken/pkcs11i.h ++++ b/lib/softoken/pkcs11i.h +@@ -248,22 +248,25 @@ typedef enum { + * multi=0 hashInfo=0 PKC S/V one shot (w/o hashing) + * multi=0 hashInfo=X *** shouldn't happen *** + */ + struct SFTKSessionContextStr { + SFTKContextType type; + PRBool multi; /* is multipart */ + PRBool rsa; /* is rsa */ + PRBool doPad; /* use PKCS padding for block ciphers */ ++ PRBool isXCBC; /* xcbc, use special handling in final */ + unsigned int blockSize; /* blocksize for padding */ + unsigned int padDataLength; /* length of the valid data in padbuf */ + /** latest incomplete block of data for block cipher */ + unsigned char padBuf[SFTK_MAX_BLOCK_SIZE]; + /** result of MAC'ing of latest full block of data with block cipher */ + unsigned char macBuf[SFTK_MAX_BLOCK_SIZE]; ++ unsigned char k2[SFTK_MAX_BLOCK_SIZE]; ++ unsigned char k3[SFTK_MAX_BLOCK_SIZE]; + CK_ULONG macSize; /* size of a general block cipher mac*/ + void *cipherInfo; + void *hashInfo; + unsigned int cipherInfoLen; + CK_MECHANISM_TYPE currentMech; + SFTKCipher update; + SFTKHash hashUpdate; + SFTKEnd end; +@@ -600,16 +603,17 @@ extern CK_RV SFTK_SlotInit(char *configd + extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir, + char *updatedir, char *updateID, + sftk_token_parameters *params, int moduleIndex); + extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot); + extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot); + extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot, PRBool logout); + + /* internal utility functions used by pkcs11.c */ ++extern CK_RV sftk_MapCryptError(int error); + extern SFTKAttribute *sftk_FindAttribute(SFTKObject *object, + CK_ATTRIBUTE_TYPE type); + extern void sftk_FreeAttribute(SFTKAttribute *attribute); + extern CK_RV sftk_AddAttributeType(SFTKObject *object, CK_ATTRIBUTE_TYPE type, + const void *valPtr, CK_ULONG length); + extern CK_RV sftk_Attribute2SecItem(PLArenaPool *arena, SECItem *item, + SFTKObject *object, CK_ATTRIBUTE_TYPE type); + extern CK_RV sftk_MultipleAttribute2SecItem(PLArenaPool *arena, +@@ -681,16 +685,40 @@ extern void sftk_CleanupFreeLists(void); + extern NSSLOWKEYPublicKey *sftk_GetPubKey(SFTKObject *object, + CK_KEY_TYPE key_type, CK_RV *crvp); + extern NSSLOWKEYPrivateKey *sftk_GetPrivKey(SFTKObject *object, + CK_KEY_TYPE key_type, CK_RV *crvp); + extern void sftk_FormatDESKey(unsigned char *key, int length); + extern PRBool sftk_CheckDESKey(unsigned char *key); + extern PRBool sftk_IsWeakKey(unsigned char *key, CK_KEY_TYPE key_type); + ++/* ike and xcbc helpers */ ++extern CK_RV sftk_ike_prf(CK_SESSION_HANDLE hSession, ++ const SFTKAttribute *inKey, ++ const CK_NSS_IKE_PRF_DERIVE_PARAMS *params, SFTKObject *outKey); ++extern CK_RV sftk_ike1_prf(CK_SESSION_HANDLE hSession, ++ const SFTKAttribute *inKey, ++ const CK_NSS_IKE1_PRF_DERIVE_PARAMS *params, SFTKObject *outKey, ++ unsigned int keySize); ++extern CK_RV sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession, ++ const SFTKAttribute *inKey, ++ const CK_MECHANISM_TYPE *params, SFTKObject *outKey, ++ unsigned int keySize); ++extern CK_RV sftk_ike_prf_plus(CK_SESSION_HANDLE hSession, ++ const SFTKAttribute *inKey, ++ const CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *params, SFTKObject *outKey, ++ unsigned int keySize); ++extern CK_RV sftk_aes_xcbc_new_keys(CK_SESSION_HANDLE hSession, ++ CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE_PTR phKey, ++ unsigned char *k2, unsigned char *k3); ++extern CK_RV sftk_xcbc_mac_pad(unsigned char *padBuf, unsigned int bufLen, ++ int blockSize, const unsigned char *k2, ++ const unsigned char *k3); ++extern SECStatus sftk_fips_IKE_PowerUpSelfTests(void); ++ + /* mechanism allows this operation */ + extern CK_RV sftk_MechAllowsOperation(CK_MECHANISM_TYPE type, CK_ATTRIBUTE_TYPE op); + + /* helper function which calls nsslowkey_FindKeyByPublicKey after safely + * acquiring a reference to the keydb from the slot */ + NSSLOWKEYPrivateKey *sftk_FindKeyByPublicKey(SFTKSlot *slot, SECItem *dbKey); + + /* +diff --git a/lib/softoken/pkcs11u.c b/lib/softoken/pkcs11u.c +--- a/lib/softoken/pkcs11u.c ++++ b/lib/softoken/pkcs11u.c +@@ -10,16 +10,57 @@ + #include "secasn1.h" + #include "blapi.h" + #include "secerr.h" + #include "prnetdb.h" /* for PR_ntohl */ + #include "sftkdb.h" + #include "softoken.h" + + /* ++ * ******************** Error mapping ******************************* ++ */ ++/* ++ * map all the SEC_ERROR_xxx error codes that may be returned by freebl ++ * functions to CKR_xxx. return CKR_DEVICE_ERROR by default for backward ++ * compatibility. ++ */ ++CK_RV ++sftk_MapCryptError(int error) ++{ ++ switch (error) { ++ case SEC_ERROR_INVALID_ARGS: ++ case SEC_ERROR_BAD_DATA: /* MP_RANGE gets mapped to this */ ++ return CKR_ARGUMENTS_BAD; ++ case SEC_ERROR_INPUT_LEN: ++ return CKR_DATA_LEN_RANGE; ++ case SEC_ERROR_OUTPUT_LEN: ++ return CKR_BUFFER_TOO_SMALL; ++ case SEC_ERROR_LIBRARY_FAILURE: ++ return CKR_GENERAL_ERROR; ++ case SEC_ERROR_NO_MEMORY: ++ return CKR_HOST_MEMORY; ++ case SEC_ERROR_BAD_SIGNATURE: ++ return CKR_SIGNATURE_INVALID; ++ case SEC_ERROR_INVALID_KEY: ++ return CKR_KEY_SIZE_RANGE; ++ case SEC_ERROR_BAD_KEY: /* an EC public key that fails validation */ ++ return CKR_KEY_SIZE_RANGE; /* the closest error code */ ++ case SEC_ERROR_UNSUPPORTED_EC_POINT_FORM: ++ return CKR_TEMPLATE_INCONSISTENT; ++ case SEC_ERROR_UNSUPPORTED_KEYALG: ++ return CKR_MECHANISM_INVALID; ++ case SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE: ++ return CKR_DOMAIN_PARAMS_INVALID; ++ /* key pair generation failed after max number of attempts */ ++ case SEC_ERROR_NEED_RANDOM: ++ return CKR_FUNCTION_FAILED; ++ } ++ return CKR_DEVICE_ERROR; ++} ++/* + * ******************** Attribute Utilities ******************************* + */ + + /* + * create a new attribute with type, value, and length. Space is allocated + * to hold value. + */ + static SFTKAttribute * +diff --git a/lib/softoken/sftkike.c b/lib/softoken/sftkike.c +new file mode 100644 +--- /dev/null ++++ b/lib/softoken/sftkike.c +@@ -0,0 +1,1288 @@ ++/* 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/. */ ++/* ++ * This file implements PKCS 11 on top of our existing security modules ++ * ++ * For more information about PKCS 11 See PKCS 11 Token Inteface Standard. ++ * This implementation has two slots: ++ * slot 1 is our generic crypto support. It does not require login. ++ * It supports Public Key ops, and all they bulk ciphers and hashes. ++ * It can also support Private Key ops for imported Private keys. It does ++ * not have any token storage. ++ * slot 2 is our private key support. It requires a login before use. It ++ * can store Private Keys and Certs as token objects. Currently only private ++ * keys and their associated Certificates are saved on the token. ++ * ++ * In this implementation, session objects are only visible to the session ++ * that created or generated them. ++ */ ++#include "seccomon.h" ++#include "secitem.h" ++#include "secport.h" ++#include "blapi.h" ++#include "pkcs11.h" ++#include "pkcs11i.h" ++#include "pkcs1sig.h" ++#include "lowkeyi.h" ++#include "secder.h" ++#include "secdig.h" ++#include "lowpbe.h" /* We do PBE below */ ++#include "pkcs11t.h" ++#include "secoid.h" ++#include "alghmac.h" ++#include "softoken.h" ++#include "secasn1.h" ++#include "secerr.h" ++ ++#include "prprf.h" ++#include "prenv.h" ++ ++/* ++ * A common prfContext to handle both hmac and aes xcbc ++ * hash contexts have non-null hashObj and hmac, aes ++ * contexts have non-null aes */ ++typedef struct prfContextStr { ++ HASH_HashType hashType; ++ const SECHashObject *hashObj; ++ HMACContext *hmac; ++ AESContext *aes; ++ unsigned int nextChar; ++ unsigned char padBuf[AES_BLOCK_SIZE]; ++ unsigned char macBuf[AES_BLOCK_SIZE]; ++ unsigned char k1[AES_BLOCK_SIZE]; ++ unsigned char k2[AES_BLOCK_SIZE]; ++ unsigned char k3[AES_BLOCK_SIZE]; ++} prfContext; ++ ++/* iv full of zeros used in several places in aex xcbc */ ++static const unsigned char iv_zero[] = { ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++}; ++ ++/* ++ * Generate AES XCBC keys from the AES MAC key. ++ * k1 is used in the actual mac. ++ * k2 and k3 are used in the final pad step. ++ */ ++static CK_RV ++sftk_aes_xcbc_get_keys(const unsigned char *keyValue, unsigned int keyLen, ++ unsigned char *k1, unsigned char *k2, unsigned char *k3) ++{ ++ SECStatus rv; ++ CK_RV crv; ++ unsigned int tmpLen; ++ AESContext *aes_context = NULL; ++ unsigned char newKey[AES_BLOCK_SIZE]; ++ ++ /* AES XCBC keys. k1, k2, and k3 are derived by encrypting ++ * k1data, k2data, and k3data with the mac key. ++ */ ++ static const unsigned char k1data[] = { ++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, ++ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 ++ }; ++ static const unsigned char k2data[] = { ++ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ++ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 ++ }; ++ static const unsigned char k3data[] = { ++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, ++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 ++ }; ++ ++ /* k1_0 = aes_ecb(0, k1data) */ ++ static const unsigned char k1_0[] = { ++ 0xe1, 0x4d, 0x5d, 0x0e, 0xe2, 0x77, 0x15, 0xdf, ++ 0x08, 0xb4, 0x15, 0x2b, 0xa2, 0x3d, 0xa8, 0xe0 ++ ++ }; ++ /* k2_0 = aes_ecb(0, k2data) */ ++ static const unsigned char k2_0[] = { ++ 0x5e, 0xba, 0x73, 0xf8, 0x91, 0x42, 0xc5, 0x48, ++ 0x80, 0xf6, 0x85, 0x94, 0x37, 0x3c, 0x5c, 0x37 ++ }; ++ /* k3_0 = aes_ecb(0, k3data) */ ++ static const unsigned char k3_0[] = { ++ 0x8d, 0x34, 0xef, 0xcb, 0x3b, 0xd5, 0x45, 0xca, ++ 0x06, 0x2a, 0xec, 0xdf, 0xef, 0x7c, 0x0b, 0xfa ++ }; ++ ++ /* first make sure out input key is the correct length ++ * rfc 4434. If key is shorter, pad with zeros to the ++ * the right. If key is longer newKey = aes_xcbc(0, key, keyLen). ++ */ ++ if (keyLen < AES_BLOCK_SIZE) { ++ PORT_Memcpy(newKey, keyValue, keyLen); ++ PORT_Memset(&newKey[keyLen], 0, AES_BLOCK_SIZE - keyLen); ++ keyValue = newKey; ++ } else if (keyLen > AES_BLOCK_SIZE) { ++ /* calculate our new key = aes_xcbc(0, key, keyLen). Because the ++ * key above is fixed (0), we can precalculate k1, k2, and k2. ++ * if this code ever needs to be more generic (support any xcbc ++ * function rather than just aes, we would probably want to just ++ * recurse here using our prf functions. This would be safe because ++ * the recurse case would have keyLen == blocksize and thus skip ++ * this conditional. ++ */ ++ aes_context = AES_CreateContext(k1_0, iv_zero, NSS_AES_CBC, ++ PR_TRUE, AES_BLOCK_SIZE, AES_BLOCK_SIZE); ++ /* we know the following loop will execute at least once */ ++ while (keyLen > AES_BLOCK_SIZE) { ++ rv = AES_Encrypt(aes_context, newKey, &tmpLen, AES_BLOCK_SIZE, ++ keyValue, AES_BLOCK_SIZE); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ keyValue += AES_BLOCK_SIZE; ++ keyLen -= AES_BLOCK_SIZE; ++ } ++ PORT_Memcpy(newKey, keyValue, keyLen); ++ sftk_xcbc_mac_pad(newKey, keyLen, AES_BLOCK_SIZE, k2_0, k3_0); ++ rv = AES_Encrypt(aes_context, newKey, &tmpLen, AES_BLOCK_SIZE, ++ newKey, AES_BLOCK_SIZE); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ keyValue = newKey; ++ AES_DestroyContext(aes_context, PR_TRUE); ++ } ++ /* the length of the key in keyValue is known to be AES_BLOCK_SIZE, ++ * either because it was on input, or it was shorter and extended, or ++ * because it was mac'd down using aes_xcbc_prf. ++ */ ++ aes_context = AES_CreateContext(keyValue, iv_zero, ++ NSS_AES, PR_TRUE, AES_BLOCK_SIZE, AES_BLOCK_SIZE); ++ if (aes_context == NULL) { ++ goto fail; ++ } ++ rv = AES_Encrypt(aes_context, k1, &tmpLen, AES_BLOCK_SIZE, ++ k1data, sizeof(k1data)); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ rv = AES_Encrypt(aes_context, k2, &tmpLen, AES_BLOCK_SIZE, ++ k2data, sizeof(k2data)); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ rv = AES_Encrypt(aes_context, k3, &tmpLen, AES_BLOCK_SIZE, ++ k3data, sizeof(k3data)); ++ if (rv != SECSuccess) { ++ goto fail; ++ } ++ AES_DestroyContext(aes_context, PR_TRUE); ++ PORT_Memset(newKey, 0, AES_BLOCK_SIZE); ++ return CKR_OK; ++fail: ++ crv = sftk_MapCryptError(PORT_GetError()); ++ if (aes_context) { ++ AES_DestroyContext(aes_context, PR_TRUE); ++ } ++ PORT_Memset(k1, 0, AES_BLOCK_SIZE); ++ PORT_Memset(k2, 0, AES_BLOCK_SIZE); ++ PORT_Memset(k3, 0, AES_BLOCK_SIZE); ++ PORT_Memset(newKey, 0, AES_BLOCK_SIZE); ++ return crv; ++} ++ ++/* encode the final pad block of aes xcbc, padBuf is modified */ ++CK_RV ++sftk_xcbc_mac_pad(unsigned char *padBuf, unsigned int bufLen, int blockSize, ++ const unsigned char *k2, const unsigned char *k3) ++{ ++ int i; ++ if (bufLen == blockSize) { ++ for (i = 0; i < blockSize; i++) { ++ padBuf[i] ^= k2[i]; ++ } ++ } else { ++ padBuf[bufLen++] = 0x80; ++ for (i = bufLen; i < blockSize; i++) { ++ padBuf[i] = 0x00; ++ } ++ for (i = 0; i < blockSize; i++) { ++ padBuf[i] ^= k3[i]; ++ } ++ } ++ return CKR_OK; ++} ++ ++/* Map the mechanism to the underlying hash. If the type is not a hash ++ * or HMAC, return HASH_AlgNULL. This can happen legitimately if ++ * we are doing AES XCBC */ ++static HASH_HashType ++sftk_map_hmac_to_hash(CK_MECHANISM_TYPE type) ++{ ++ switch (type) { ++ case CKM_SHA_1_HMAC: ++ case CKM_SHA_1: ++ return HASH_AlgSHA1; ++ case CKM_MD5_HMAC: ++ case CKM_MD5: ++ return HASH_AlgMD5; ++ case CKM_MD2_HMAC: ++ case CKM_MD2: ++ return HASH_AlgMD2; ++ case CKM_SHA224_HMAC: ++ case CKM_SHA224: ++ return HASH_AlgSHA224; ++ case CKM_SHA256_HMAC: ++ case CKM_SHA256: ++ return HASH_AlgSHA256; ++ case CKM_SHA384_HMAC: ++ case CKM_SHA384: ++ return HASH_AlgSHA384; ++ case CKM_SHA512_HMAC: ++ case CKM_SHA512: ++ return HASH_AlgSHA512; ++ } ++ return HASH_AlgNULL; ++} ++ ++/* ++ * Generally setup the context based on the mechanism. ++ * If the mech is HMAC, context->hashObj should be set ++ * Otherwise it is assumed to be AES XCBC. prf_setup ++ * checks these assumptions and will return an error ++ * if they are not met. NOTE: this function does not allocate ++ * anything, so there is no requirement to free context after ++ * prf_setup like there is if you call prf_init. ++ */ ++static CK_RV ++prf_setup(prfContext *context, CK_MECHANISM_TYPE mech) ++{ ++ context->hashType = sftk_map_hmac_to_hash(mech); ++ context->hashObj = NULL; ++ context->hmac = NULL; ++ context->aes = NULL; ++ if (context->hashType != HASH_AlgNULL) { ++ context->hashObj = HASH_GetRawHashObject(context->hashType); ++ if (context->hashObj == NULL) { ++ return CKR_GENERAL_ERROR; ++ } ++ return CKR_OK; ++ } else if (mech == CKM_AES_XCBC_MAC) { ++ return CKR_OK; ++ } ++ return CKR_MECHANISM_PARAM_INVALID; ++} ++ ++/* return the underlying prf length for this context. This will ++ * function once the context is setup */ ++static CK_RV ++prf_length(prfContext *context) ++{ ++ if (context->hashObj) { ++ return context->hashObj->length; ++ } ++ return AES_BLOCK_SIZE; /* AES */ ++} ++ ++/* set up the key for the prf. prf_update or prf_final should not be called if ++ * prf_init has not been called first. Once prf_init returns hmac and ++ * aes contexts should set and valid. ++ */ ++static CK_RV ++prf_init(prfContext *context, const unsigned char *keyValue, ++ unsigned int keyLen) ++{ ++ CK_RV crv; ++ ++ context->hmac = NULL; ++ if (context->hashObj) { ++ context->hmac = HMAC_Create(context->hashObj, ++ keyValue, keyLen, PR_FALSE); ++ if (context->hmac == NULL) { ++ return sftk_MapCryptError(PORT_GetError()); ++ } ++ HMAC_Begin(context->hmac); ++ } else { ++ crv = sftk_aes_xcbc_get_keys(keyValue, keyLen, context->k1, ++ context->k2, context->k3); ++ if (crv != CKR_OK) ++ return crv; ++ context->nextChar = 0; ++ context->aes = AES_CreateContext(context->k1, iv_zero, NSS_AES_CBC, ++ PR_TRUE, sizeof(context->k1), AES_BLOCK_SIZE); ++ if (context->aes == NULL) { ++ crv = sftk_MapCryptError(PORT_GetError()); ++ PORT_Memset(context->k1, 0, sizeof(context->k1)); ++ PORT_Memset(context->k2, 0, sizeof(context->k2)); ++ PORT_Memset(context->k3, 0, sizeof(context->k2)); ++ return crv; ++ } ++ } ++ return CKR_OK; ++} ++ ++/* ++ * process input to the prf ++ */ ++static CK_RV ++prf_update(prfContext *context, const unsigned char *buf, unsigned int len) ++{ ++ unsigned int tmpLen; ++ SECStatus rv; ++ ++ if (context->hmac) { ++ HMAC_Update(context->hmac, buf, len); ++ } else { ++ /* AES MAC XCBC*/ ++ /* We must keep the last block back so that it can be processed in ++ * final. This is why we only check that nextChar + len > blocksize, ++ * rather than checking that nextChar + len >= blocksize */ ++ while (context->nextChar + len > AES_BLOCK_SIZE) { ++ if (context->nextChar != 0) { ++ /* first handle fill in any partial blocks in the buffer */ ++ unsigned int left = AES_BLOCK_SIZE - context->nextChar; ++ /* note: left can be zero */ ++ PORT_Memcpy(context->padBuf + context->nextChar, buf, left); ++ /* NOTE: AES MAC XCBC xors the data with the previous block ++ * We don't do that step here because our AES_Encrypt mode ++ * is CBC, which does the xor automatically */ ++ rv = AES_Encrypt(context->aes, context->macBuf, &tmpLen, ++ sizeof(context->macBuf), context->padBuf, ++ sizeof(context->padBuf)); ++ if (rv != SECSuccess) { ++ return sftk_MapCryptError(PORT_GetError()); ++ } ++ context->nextChar = 0; ++ len -= left; ++ buf += left; ++ } else { ++ /* optimization. if we have complete blocks to write out ++ * (and will still have leftover blocks for padbuf in the end). ++ * we can mac directly out of our buffer without first copying ++ * them to padBuf */ ++ rv = AES_Encrypt(context->aes, context->macBuf, &tmpLen, ++ sizeof(context->macBuf), buf, AES_BLOCK_SIZE); ++ if (rv != SECSuccess) { ++ return sftk_MapCryptError(PORT_GetError()); ++ } ++ len -= AES_BLOCK_SIZE; ++ buf += AES_BLOCK_SIZE; ++ } ++ } ++ PORT_Memcpy(context->padBuf + context->nextChar, buf, len); ++ context->nextChar += len; ++ } ++ return CKR_OK; ++} ++ ++/* ++ * free the data associated with the prf. Clear any possible CSPs ++ * This can safely be called on any context after prf_setup. It can ++ * also be called an an already freed context. ++ * A free context can be reused by calling prf_init again without ++ * the need to call prf_setup. ++ */ ++static void ++prf_free(prfContext *context) ++{ ++ if (context->hmac) { ++ HMAC_Destroy(context->hmac, PR_TRUE); ++ context->hmac = NULL; ++ } ++ if (context->aes) { ++ PORT_Memset(context->k1, 0, sizeof(context->k1)); ++ PORT_Memset(context->k2, 0, sizeof(context->k2)); ++ PORT_Memset(context->k3, 0, sizeof(context->k2)); ++ PORT_Memset(context->padBuf, 0, sizeof(context->padBuf)); ++ PORT_Memset(context->macBuf, 0, sizeof(context->macBuf)); ++ AES_DestroyContext(context->aes, PR_TRUE); ++ context->aes = NULL; ++ } ++} ++ ++/* ++ * extract the final prf value. On success, this has the side effect of ++ * also freeing the context data and clearing the keys ++ */ ++static CK_RV ++prf_final(prfContext *context, unsigned char *buf, unsigned int len) ++{ ++ unsigned int tmpLen; ++ SECStatus rv; ++ ++ if (context->hmac) { ++ unsigned int outLen; ++ HMAC_Finish(context->hmac, buf, &outLen, len); ++ if (outLen != len) { ++ return CKR_GENERAL_ERROR; ++ } ++ } else { ++ /* prf_update had guarrenteed that the last full block is still in ++ * the padBuf if the input data is a multiple of the blocksize. This ++ * allows sftk_xcbc_mac_pad to process that pad buf accordingly */ ++ sftk_xcbc_mac_pad(context->padBuf, context->nextChar, AES_BLOCK_SIZE, ++ context->k2, context->k3); ++ rv = AES_Encrypt(context->aes, context->macBuf, &tmpLen, ++ sizeof(context->macBuf), context->padBuf, AES_BLOCK_SIZE); ++ if (rv != SECSuccess) { ++ return sftk_MapCryptError(PORT_GetError()); ++ } ++ PORT_Memcpy(buf, context->macBuf, len); ++ } ++ prf_free(context); ++ return CKR_OK; ++} ++ ++/* ++ * There are four flavors of ike prf functions here. ++ * ike_prf is used in both ikeV1 and ikeV2 to generate ++ * an initial key that all the other keys are generated with. ++ * ++ * These functions are called from NSC_DeriveKey with the inKey value ++ * already looked up, and it expects the CKA_VALUE for outKey to be set. ++ * ++ * Depending on usage it returns either: ++ * 1. prf(Ni|Nr, inKey); (bDataAsKey=TRUE, bRekey=FALSE) ++ * 2. prf(inKey, Ni|Nr); (bDataAsKkey=FALSE, bRekey=FALSE) ++ * 3. prf(inKey, newKey | Ni | Nr); (bDataAsKey=FALSE, bRekey=TRUE) ++ * The resulting output key is always the length of the underlying prf ++ * (as returned by prf_length()). ++ * The combination of bDataAsKey=TRUE and bRekey=TRUE is not allowed ++ * ++ * Case 1 is used in ++ * a. ikev2 (rfc5996) inKey is called g^ir, the output is called SKEYSEED ++ * b. ikev1 (rfc2409) inKey is called g^ir, the output is called SKEYID ++ * Case 2 is used in ikev1 (rfc2409) inkey is called pre-shared-key, output ++ * is called SKEYID ++ * Case 3 is used in ikev2 (rfc5996) rekey case, inKey is SK_d, newKey is ++ * g^ir (new), the output is called SKEYSEED ++ */ ++CK_RV ++sftk_ike_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, ++ const CK_NSS_IKE_PRF_DERIVE_PARAMS *params, SFTKObject *outKey) ++{ ++ SFTKAttribute *newKeyValue = NULL; ++ SFTKObject *newKeyObj = NULL; ++ unsigned char outKeyData[HASH_LENGTH_MAX]; ++ unsigned char *newInKey = NULL; ++ unsigned int newInKeySize; ++ unsigned int macSize; ++ CK_RV crv = CKR_OK; ++ prfContext context; ++ ++ crv = prf_setup(&context, params->prfMechanism); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ macSize = prf_length(&context); ++ if ((params->bDataAsKey) && (params->bRekey)) { ++ return CKR_ARGUMENTS_BAD; ++ } ++ if (params->bRekey) { ++ /* lookup the value of new key from the session and key handle */ ++ SFTKSession *session = sftk_SessionFromHandle(hSession); ++ if (session == NULL) { ++ return CKR_SESSION_HANDLE_INVALID; ++ } ++ newKeyObj = sftk_ObjectFromHandle(params->hNewKey, session); ++ sftk_FreeSession(session); ++ if (newKeyObj == NULL) { ++ return CKR_KEY_HANDLE_INVALID; ++ } ++ newKeyValue = sftk_FindAttribute(newKeyObj, CKA_VALUE); ++ if (newKeyValue == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ } ++ if (params->bDataAsKey) { ++ /* The key is Ni || Np, so we need to concatenate them together first */ ++ newInKeySize = params->ulNiLen + params->ulNrLen; ++ newInKey = PORT_Alloc(newInKeySize); ++ if (newInKey == NULL) { ++ crv = CKR_HOST_MEMORY; ++ goto fail; ++ } ++ PORT_Memcpy(newInKey, params->pNi, params->ulNiLen); ++ PORT_Memcpy(newInKey + params->ulNiLen, params->pNr, params->ulNrLen); ++ crv = prf_init(&context, newInKey, newInKeySize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ /* key as the data */ ++ crv = prf_update(&context, inKey->attrib.pValue, ++ inKey->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } else { ++ crv = prf_init(&context, inKey->attrib.pValue, ++ inKey->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ if (newKeyValue) { ++ crv = prf_update(&context, newKeyValue->attrib.pValue, ++ newKeyValue->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ crv = prf_update(&context, params->pNi, params->ulNiLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, params->pNr, params->ulNrLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ crv = prf_final(&context, outKeyData, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, macSize); ++fail: ++ if (newInKey) { ++ PORT_Free(newInKey); ++ } ++ if (newKeyValue) { ++ sftk_FreeAttribute(newKeyValue); ++ } ++ if (newKeyObj) { ++ sftk_FreeObject(newKeyObj); ++ } ++ PORT_Memset(outKeyData, 0, macSize); ++ prf_free(&context); ++ return crv; ++} ++ ++/* ++ * The second flavor of ike prf is ike1_prf. ++ * ++ * It is used by ikeV1 to generate the various session keys used in the ++ * connection. It uses the initial key, an optional previous key, and a one byte ++ * key number to generate a unique key for each of the various session ++ * functions (encryption, decryption, mac). These keys expect a key size ++ * (as they may vary in length based on usage). If no length is provided, ++ * it will default to the length of the prf. ++ * ++ * This function returns either: ++ * prf(inKey, gxyKey || CKYi || CKYr || key_number) ++ * or ++ * prf(inKey, prevkey || gxyKey || CKYi || CKYr || key_number) ++ * depending on the stats of bHasPrevKey ++ * ++ * This is defined in rfc2409. For each of the following keys. ++ * inKey is SKEYID, gxyKey is g^xy ++ * for outKey = SKEYID_d, bHasPrevKey = false, key_number = 0 ++ * for outKey = SKEYID_a, prevKey= SKEYID_d, key_number = 1 ++ * for outKey = SKEYID_e, prevKey= SKEYID_a, key_number = 2 ++ */ ++CK_RV ++sftk_ike1_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, ++ const CK_NSS_IKE1_PRF_DERIVE_PARAMS *params, SFTKObject *outKey, ++ unsigned int keySize) ++{ ++ SFTKAttribute *gxyKeyValue = NULL; ++ SFTKObject *gxyKeyObj = NULL; ++ SFTKAttribute *prevKeyValue = NULL; ++ SFTKObject *prevKeyObj = NULL; ++ SFTKSession *session; ++ unsigned char outKeyData[HASH_LENGTH_MAX]; ++ unsigned int macSize; ++ CK_RV crv; ++ prfContext context; ++ ++ crv = prf_setup(&context, params->prfMechanism); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ macSize = prf_length(&context); ++ if (keySize > macSize) { ++ return CKR_KEY_SIZE_RANGE; ++ } ++ if (keySize == 0) { ++ keySize = macSize; ++ } ++ ++ /* lookup the two keys from their passed in handles */ ++ session = sftk_SessionFromHandle(hSession); ++ if (session == NULL) { ++ return CKR_SESSION_HANDLE_INVALID; ++ } ++ gxyKeyObj = sftk_ObjectFromHandle(params->hKeygxy, session); ++ if (params->bHasPrevKey) { ++ prevKeyObj = sftk_ObjectFromHandle(params->hPrevKey, session); ++ } ++ sftk_FreeSession(session); ++ if ((gxyKeyObj == NULL) || ((params->bHasPrevKey) && ++ (prevKeyObj == NULL))) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ gxyKeyValue = sftk_FindAttribute(gxyKeyObj, CKA_VALUE); ++ if (gxyKeyValue == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ if (prevKeyObj) { ++ prevKeyValue = sftk_FindAttribute(prevKeyObj, CKA_VALUE); ++ if (prevKeyValue == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ } ++ ++ /* outKey = prf(inKey, [prevKey|] gxyKey | CKYi | CKYr | keyNumber) */ ++ crv = prf_init(&context, inKey->attrib.pValue, inKey->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ if (prevKeyValue) { ++ crv = prf_update(&context, prevKeyValue->attrib.pValue, ++ prevKeyValue->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ crv = prf_update(&context, gxyKeyValue->attrib.pValue, ++ gxyKeyValue->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, params->pCKYi, params->ulCKYiLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, params->pCKYr, params->ulCKYrLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, ¶ms->keyNumber, 1); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_final(&context, outKeyData, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, keySize); ++fail: ++ if (gxyKeyValue) { ++ sftk_FreeAttribute(gxyKeyValue); ++ } ++ if (prevKeyValue) { ++ sftk_FreeAttribute(prevKeyValue); ++ } ++ if (gxyKeyObj) { ++ sftk_FreeObject(gxyKeyObj); ++ } ++ if (prevKeyObj) { ++ sftk_FreeObject(prevKeyObj); ++ } ++ PORT_Memset(outKeyData, 0, macSize); ++ prf_free(&context); ++ return crv; ++} ++ ++/* ++ * The third flavor of ike prf is ike1_appendix_b. ++ * ++ * It is used by ikeV1 to generate longer key material from skeyid_e. ++ * Unlike ike1_prf, if no length is provided, this function ++ * will generate a KEY_RANGE_ERROR. ++ * ++ * This function returns (from rfc2409 appendix b): ++ * Ka = K1 | K2 | K3 | K4 |... Kn ++ * where: ++ * K1 = prf(K, 0x00) ++ * K2 = prf(K, K1) ++ * K3 = prf(K, K2) ++ * K4 = prf(K, K3) ++ * . ++ * Kn = prf(K, K(n-1)) ++ * K = inKey ++ */ ++CK_RV ++sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, ++ const CK_MECHANISM_TYPE *mech, SFTKObject *outKey, unsigned int keySize) ++{ ++ unsigned char *outKeyData = NULL; ++ unsigned char *thisKey = NULL; ++ unsigned char *lastKey = NULL; ++ unsigned int macSize; ++ unsigned int outKeySize; ++ unsigned int genKeySize; ++ CK_RV crv; ++ prfContext context; ++ ++ crv = prf_setup(&context, *mech); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ ++ macSize = prf_length(&context); ++ ++ if (keySize == 0) { ++ keySize = macSize; ++ } ++ ++ if (keySize <= inKey->attrib.ulValueLen) { ++ return sftk_forceAttribute(outKey, CKA_VALUE, ++ inKey->attrib.pValue, keySize); ++ } ++ outKeySize = PR_ROUNDUP(keySize, macSize); ++ outKeyData = PORT_Alloc(outKeySize); ++ if (outKeyData == NULL) { ++ crv = CKR_HOST_MEMORY; ++ goto fail; ++ } ++ ++ /* ++ * this loop generates on block of the prf, basically ++ * kn = prf(key, Kn-1) ++ * Kn is thisKey, Kn-1 is lastKey ++ * key is inKey ++ */ ++ thisKey = outKeyData; ++ for (genKeySize = 0; genKeySize <= keySize; genKeySize += macSize) { ++ crv = prf_init(&context, inKey->attrib.pValue, inKey->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ if (lastKey == NULL) { ++ const unsigned char zero = 0; ++ crv = prf_update(&context, &zero, 1); ++ } else { ++ crv = prf_update(&context, lastKey, macSize); ++ } ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_final(&context, thisKey, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ lastKey = thisKey; ++ thisKey += macSize; ++ } ++ crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, keySize); ++fail: ++ if (outKeyData) { ++ PORT_ZFree(outKeyData, outKeySize); ++ } ++ prf_free(&context); ++ return crv; ++} ++ ++/* ++ * The final flavor of ike prf is ike_prf_plus ++ * ++ * It is used by ikeV2 to generate the various session keys used in the ++ * connection. It uses the initial key and a feedback version of the prf ++ * to generate sufficient bytes to cover all the session keys. The application ++ * will then use CK_EXTRACT_KEY_FROM_KEY to pull out the various subkeys. ++ * This function expects a key size to be set by the application to cover ++ * all the keys. Unlike ike1_prf, if no length is provided, this function ++ * will generate a KEY_RANGE_ERROR ++ * ++ * This function returns (from rfc5996): ++ * prfplus = T1 | T2 | T3 | T4 |... Tn ++ * where: ++ * T1 = prf(K, S | 0x01) ++ * T2 = prf(K, T1 | S | 0x02) ++ * T3 = prf(K, T3 | S | 0x03) ++ * T4 = prf(K, T4 | S | 0x04) ++ * . ++ * Tn = prf(K, T(n-1) | n) ++ * K = inKey, S = seedKey | seedData ++ */ ++ ++CK_RV ++sftk_ike_prf_plus(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey, ++ const CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS *params, SFTKObject *outKey, ++ unsigned int keySize) ++{ ++ SFTKAttribute *seedValue = NULL; ++ SFTKObject *seedKeyObj = NULL; ++ unsigned char *outKeyData = NULL; ++ unsigned int outKeySize; ++ unsigned char *thisKey; ++ unsigned char *lastKey = NULL; ++ unsigned char currentByte = 0; ++ unsigned int getKeySize; ++ unsigned int macSize; ++ CK_RV crv; ++ prfContext context; ++ ++ if (keySize == 0) { ++ return CKR_KEY_SIZE_RANGE; ++ } ++ ++ crv = prf_setup(&context, params->prfMechanism); ++ if (crv != CKR_OK) { ++ return crv; ++ } ++ /* pull in optional seedKey */ ++ if (params->bHasSeedKey) { ++ SFTKSession *session = sftk_SessionFromHandle(hSession); ++ if (session == NULL) { ++ return CKR_SESSION_HANDLE_INVALID; ++ } ++ seedKeyObj = sftk_ObjectFromHandle(params->hSeedKey, session); ++ sftk_FreeSession(session); ++ if (seedKeyObj == NULL) { ++ return CKR_KEY_HANDLE_INVALID; ++ } ++ seedValue = sftk_FindAttribute(seedKeyObj, CKA_VALUE); ++ if (seedValue == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ } else if (params->ulSeedDataLen == 0) { ++ crv = CKR_ARGUMENTS_BAD; ++ goto fail; ++ } ++ macSize = prf_length(&context); ++ outKeySize = PR_ROUNDUP(keySize, macSize); ++ outKeyData = PORT_Alloc(outKeySize); ++ if (outKeyData == NULL) { ++ crv = CKR_HOST_MEMORY; ++ goto fail; ++ } ++ ++ /* ++ * this loop generates on block of the prf, basically ++ * Tn = prf(key, Tn-1 | S | n) ++ * Tn is thisKey, Tn-2 is lastKey, S is seedKey || seedData, ++ * key is inKey. currentByte = n-1 on entry. ++ */ ++ thisKey = outKeyData; ++ for (getKeySize = 0; getKeySize < keySize; getKeySize += macSize) { ++ /* if currentByte is 255, we'll overflow when we increment it below. ++ * This can only happen if keysize > 255*macSize. In that case ++ * the application has asked for too much key material, so return ++ * an error */ ++ if (currentByte == 255) { ++ crv = CKR_KEY_SIZE_RANGE; ++ goto fail; ++ } ++ crv = prf_init(&context, inKey->attrib.pValue, ++ inKey->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ if (lastKey) { ++ crv = prf_update(&context, lastKey, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ /* prf the key first */ ++ if (seedValue) { ++ crv = prf_update(&context, seedValue->attrib.pValue, ++ seedValue->attrib.ulValueLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ /* then prf the data */ ++ if (params->ulSeedDataLen != 0) { ++ crv = prf_update(&context, params->pSeedData, ++ params->ulSeedDataLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ } ++ currentByte++; ++ crv = prf_update(&context, ¤tByte, 1); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_final(&context, thisKey, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ lastKey = thisKey; ++ thisKey += macSize; ++ } ++ crv = sftk_forceAttribute(outKey, CKA_VALUE, outKeyData, keySize); ++fail: ++ if (outKeyData) { ++ PORT_ZFree(outKeyData, outKeySize); ++ } ++ if (seedValue) { ++ sftk_FreeAttribute(seedValue); ++ } ++ if (seedKeyObj) { ++ sftk_FreeObject(seedKeyObj); ++ } ++ prf_free(&context); ++ return crv; ++} ++ ++/* sftk_aes_xcbc_new_keys: ++ * ++ * aes xcbc creates 3 new keys from the input key. The first key will be the ++ * base key of the underlying cbc. The sign code hooks directly into encrypt ++ * so we'll have to create a full PKCS #11 key with handle for that key. The ++ * caller needs to delete the key when it's through setting up the context. ++ * ++ * The other two keys will be stored in the sign context until we need them ++ * at the end. ++ */ ++CK_RV ++sftk_aes_xcbc_new_keys(CK_SESSION_HANDLE hSession, ++ CK_OBJECT_HANDLE hKey, CK_OBJECT_HANDLE_PTR phKey, ++ unsigned char *k2, unsigned char *k3) ++{ ++ SFTKObject *key = NULL; ++ SFTKSession *session = NULL; ++ SFTKObject *inKeyObj = NULL; ++ SFTKAttribute *inKeyValue = NULL; ++ CK_KEY_TYPE key_type = CKK_AES; ++ CK_OBJECT_CLASS objclass = CKO_SECRET_KEY; ++ CK_BBOOL ck_true = CK_TRUE; ++ CK_RV crv = CKR_OK; ++ SFTKSlot *slot = sftk_SlotFromSessionHandle(hSession); ++ unsigned char buf[AES_BLOCK_SIZE]; ++ ++ if (!slot) { ++ return CKR_SESSION_HANDLE_INVALID; ++ } ++ ++ /* get the session */ ++ session = sftk_SessionFromHandle(hSession); ++ if (session == NULL) { ++ crv = CKR_SESSION_HANDLE_INVALID; ++ goto fail; ++ } ++ ++ inKeyObj = sftk_ObjectFromHandle(hKey, session); ++ if (inKeyObj == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ ++ inKeyValue = sftk_FindAttribute(inKeyObj, CKA_VALUE); ++ if (inKeyValue == NULL) { ++ crv = CKR_KEY_HANDLE_INVALID; ++ goto fail; ++ } ++ ++ crv = sftk_aes_xcbc_get_keys(inKeyValue->attrib.pValue, ++ inKeyValue->attrib.ulValueLen, buf, k2, k3); ++ ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ /* ++ * now lets create an object to hang the attributes off of ++ */ ++ key = sftk_NewObject(slot); /* fill in the handle later */ ++ if (key == NULL) { ++ crv = CKR_HOST_MEMORY; ++ goto fail; ++ } ++ ++ /* make sure we don't have any class, key_type, or value fields */ ++ sftk_DeleteAttributeType(key, CKA_CLASS); ++ sftk_DeleteAttributeType(key, CKA_KEY_TYPE); ++ sftk_DeleteAttributeType(key, CKA_VALUE); ++ sftk_DeleteAttributeType(key, CKA_SIGN); ++ ++ /* Add the class, key_type, and value */ ++ crv = sftk_AddAttributeType(key, CKA_CLASS, &objclass, sizeof(CK_OBJECT_CLASS)); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = sftk_AddAttributeType(key, CKA_KEY_TYPE, &key_type, sizeof(CK_KEY_TYPE)); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = sftk_AddAttributeType(key, CKA_SIGN, &ck_true, sizeof(CK_BBOOL)); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = sftk_AddAttributeType(key, CKA_VALUE, buf, AES_BLOCK_SIZE); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ /* ++ * finish filling in the key and link it with our global system. ++ */ ++ crv = sftk_handleObject(key, session); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ *phKey = key->handle; ++fail: ++ if (session) { ++ sftk_FreeSession(session); ++ } ++ ++ if (inKeyValue) { ++ sftk_FreeAttribute(inKeyValue); ++ } ++ if (inKeyObj) { ++ sftk_FreeObject(inKeyObj); ++ } ++ if (key) { ++ sftk_FreeObject(key); ++ } ++ /* clear our CSPs */ ++ if (crv != CKR_OK) { ++ PORT_Memset(k2, 0, AES_BLOCK_SIZE); ++ PORT_Memset(k3, 0, AES_BLOCK_SIZE); ++ } ++ return crv; ++} ++ ++/* ++ * Helper function that tests a single prf test vector ++ */ ++static SECStatus ++prf_test(CK_MECHANISM_TYPE mech, ++ const unsigned char *inKey, unsigned int inKeyLen, ++ const unsigned char *plainText, unsigned int plainTextLen, ++ const unsigned char *expectedResult, unsigned int expectedResultLen) ++{ ++ PRUint8 ike_computed_mac[HASH_LENGTH_MAX]; ++ prfContext context; ++ unsigned int macSize; ++ CK_RV crv; ++ ++ crv = prf_setup(&context, mech); ++ if (crv != CKR_OK) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++ } ++ macSize = prf_length(&context); ++ crv = prf_init(&context, inKey, inKeyLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, plainText, plainTextLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_final(&context, ike_computed_mac, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ ++ if (macSize != expectedResultLen) { ++ goto fail; ++ } ++ if (PORT_Memcmp(expectedResult, ike_computed_mac, macSize) != 0) { ++ goto fail; ++ } ++ ++ /* only do the alignment if the plaintext is long enough */ ++ if (plainTextLen <= macSize) { ++ return SECSuccess; ++ } ++ /* do it again, but this time tweak with the alignment */ ++ crv = prf_init(&context, inKey, inKeyLen); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, plainText, 1); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, &plainText[1], macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_update(&context, &plainText[1 + macSize], plainTextLen - (macSize + 1)); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ crv = prf_final(&context, ike_computed_mac, macSize); ++ if (crv != CKR_OK) { ++ goto fail; ++ } ++ if (PORT_Memcmp(expectedResult, ike_computed_mac, macSize) != 0) { ++ goto fail; ++ } ++ return SECSuccess; ++fail: ++ prf_free(&context); ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return SECFailure; ++} ++ ++/* ++ * FIPS Power up Self Tests for IKE. This is in this function so it ++ * can access the private prf_ functions here. It's called out of fipstest.c ++ */ ++SECStatus ++sftk_fips_IKE_PowerUpSelfTests(void) ++{ ++ /* PRF known test vectors */ ++ static const PRUint8 ike_xcbc_known_key[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f ++ }; ++ static const PRUint8 ike_xcbc_known_plain_text[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f ++ }; ++ static const PRUint8 ike_xcbc_known_mac[] = { ++ 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, 0x68, 0xa7, ++ 0x99, 0x98, 0xa4, 0x39, 0x4f, 0xf7, 0xa2, 0x63 ++ }; ++ /* test 2 uses the same key as test 1 */ ++ static const PRUint8 ike_xcbc_known_plain_text_2[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0x10, 0x11, 0x12, 0x13 ++ }; ++ static const PRUint8 ike_xcbc_known_mac_2[] = { ++ 0x47, 0xf5, 0x1b, 0x45, 0x64, 0x96, 0x62, 0x15, ++ 0xb8, 0x98, 0x5c, 0x63, 0x05, 0x5e, 0xd3, 0x08 ++ }; ++ static const PRUint8 ike_xcbc_known_key_3[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09 ++ }; ++ /* test 3 uses the same plaintest as test 2 */ ++ static const PRUint8 ike_xcbc_known_mac_3[] = { ++ 0x0f, 0xa0, 0x87, 0xaf, 0x7d, 0x86, 0x6e, 0x76, ++ 0x53, 0x43, 0x4e, 0x60, 0x2f, 0xdd, 0xe8, 0x35 ++ }; ++ static const PRUint8 ike_xcbc_known_key_4[] = { ++ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, ++ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, ++ 0xed, 0xcb ++ }; ++ /* test 4 uses the same plaintest as test 2 */ ++ static const PRUint8 ike_xcbc_known_mac_4[] = { ++ 0x8c, 0xd3, 0xc9, 0x3a, 0xe5, 0x98, 0xa9, 0x80, ++ 0x30, 0x06, 0xff, 0xb6, 0x7c, 0x40, 0xe9, 0xe4 ++ }; ++ static const PRUint8 ike_sha1_known_key[] = { ++ 0x59, 0x98, 0x2b, 0x5b, 0xa5, 0x7e, 0x62, 0xc0, ++ 0x46, 0x0d, 0xef, 0xc7, 0x1e, 0x18, 0x64, 0x63 ++ }; ++ static const PRUint8 ike_sha1_known_plain_text[] = { ++ 0x1c, 0x07, 0x32, 0x1a, 0x9a, 0x7e, 0x41, 0xcd, ++ 0x88, 0x0c, 0xa3, 0x7a, 0xdb, 0x10, 0xc7, 0x3b, ++ 0xf0, 0x0e, 0x7a, 0xe3, 0xcf, 0xc6, 0xfd, 0x8b, ++ 0x51, 0xbc, 0xe2, 0xb9, 0x90, 0xe6, 0xf2, 0x01 ++ }; ++ static const PRUint8 ike_sha1_known_mac[] = { ++ 0x0c, 0x2a, 0xf3, 0x42, 0x97, 0x15, 0x62, 0x1d, ++ 0x2a, 0xad, 0xc9, 0x94, 0x5a, 0x90, 0x26, 0xfa, ++ 0xc7, 0x91, 0xe2, 0x4b ++ }; ++ static const PRUint8 ike_sha256_known_key[] = { ++ 0x9d, 0xa2, 0xd5, 0x8f, 0x57, 0xf0, 0x39, 0xf9, ++ 0x20, 0x4e, 0x0d, 0xd0, 0xef, 0x04, 0xf3, 0x72 ++ }; ++ static const PRUint8 ike_sha256_known_plain_text[] = { ++ 0x33, 0xf1, 0x7a, 0xfc, 0xb6, 0x13, 0x4c, 0xbf, ++ 0x1c, 0xab, 0x59, 0x87, 0x7d, 0x42, 0xdb, 0x35, ++ 0x82, 0x22, 0x6e, 0xff, 0x74, 0xdd, 0x37, 0xeb, ++ 0x8b, 0x75, 0xe6, 0x75, 0x64, 0x5f, 0xc1, 0x69 ++ }; ++ static const PRUint8 ike_sha256_known_mac[] = { ++ 0x80, 0x4b, 0x4a, 0x1e, 0x0e, 0xc5, 0x93, 0xcf, 0xb6, ++ 0xe4, 0x54, 0x52, 0x41, 0x49, 0x39, 0x6d, 0xe2, 0x34, ++ 0xd0, 0xda, 0xe2, 0x9f, 0x34, 0xa8, 0xfd, 0xb5, 0xf9, ++ 0xaf, 0xe7, 0x6e, 0xa6, 0x52 ++ }; ++ static const PRUint8 ike_sha384_known_key[] = { ++ 0xce, 0xc8, 0x9d, 0x84, 0x5a, 0xdd, 0x83, 0xef, ++ 0xce, 0xbd, 0x43, 0xab, 0x71, 0xd1, 0x7d, 0xb9 ++ }; ++ static const PRUint8 ike_sha384_known_plain_text[] = { ++ 0x17, 0x24, 0xdb, 0xd8, 0x93, 0x52, 0x37, 0x64, ++ 0xbf, 0xef, 0x8c, 0x6f, 0xa9, 0x27, 0x85, 0x6f, ++ 0xcc, 0xfb, 0x77, 0xae, 0x25, 0x43, 0x58, 0xcc, ++ 0xe2, 0x9c, 0x27, 0x69, 0xa3, 0x29, 0x15, 0xc1 ++ }; ++ static const PRUint8 ike_sha384_known_mac[] = { ++ 0x6e, 0x45, 0x14, 0x61, 0x0b, 0xf8, 0x2d, 0x0a, ++ 0xb7, 0xbf, 0x02, 0x60, 0x09, 0x6f, 0x61, 0x46, ++ 0xa1, 0x53, 0xc7, 0x12, 0x07, 0x1a, 0xbb, 0x63, ++ 0x3c, 0xed, 0x81, 0x3c, 0x57, 0x21, 0x56, 0xc7, ++ 0x83, 0xe3, 0x68, 0x74, 0xa6, 0x5a, 0x64, 0x69, ++ 0x0c, 0xa7, 0x01, 0xd4, 0x0d, 0x56, 0xea, 0x18 ++ }; ++ static const PRUint8 ike_sha512_known_key[] = { ++ 0xac, 0xad, 0xc6, 0x31, 0x4a, 0x69, 0xcf, 0xcd, ++ 0x4e, 0x4a, 0xd1, 0x77, 0x18, 0xfe, 0xa7, 0xce ++ }; ++ static const PRUint8 ike_sha512_known_plain_text[] = { ++ 0xb1, 0x5a, 0x9c, 0xfc, 0xe8, 0xc8, 0xd7, 0xea, ++ 0xb8, 0x79, 0xd6, 0x24, 0x30, 0x29, 0xd4, 0x01, ++ 0x88, 0xd3, 0xb7, 0x40, 0x87, 0x5a, 0x6a, 0xc6, ++ 0x2f, 0x56, 0xca, 0xc4, 0x37, 0x7e, 0x2e, 0xdd ++ }; ++ static const PRUint8 ike_sha512_known_mac[] = { ++ 0xf0, 0x5a, 0xa0, 0x36, 0xdf, 0xce, 0x45, 0xa5, ++ 0x58, 0xd4, 0x04, 0x18, 0xde, 0xa9, 0x80, 0x96, ++ 0xe5, 0x19, 0xbc, 0x78, 0x41, 0xe3, 0xdb, 0x3d, ++ 0xd9, 0x36, 0x58, 0xd1, 0x18, 0xc3, 0xe8, 0x3b, ++ 0x50, 0x2f, 0x39, 0x8e, 0xcb, 0x13, 0x61, 0xec, ++ 0x77, 0xd3, 0x8a, 0x88, 0x55, 0xef, 0xff, 0x40, ++ 0x7f, 0x6f, 0x77, 0x2e, 0x5d, 0x65, 0xb5, 0x8e, ++ 0xb1, 0x13, 0x40, 0x96, 0xe8, 0x47, 0x8d, 0x2b ++ }; ++ SECStatus rv; ++ ++ rv = prf_test(CKM_AES_XCBC_MAC, ++ ike_xcbc_known_key, sizeof(ike_xcbc_known_key), ++ ike_xcbc_known_plain_text, sizeof(ike_xcbc_known_plain_text), ++ ike_xcbc_known_mac, sizeof(ike_xcbc_known_mac)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_AES_XCBC_MAC, ++ ike_xcbc_known_key, sizeof(ike_xcbc_known_key), ++ ike_xcbc_known_plain_text_2, sizeof(ike_xcbc_known_plain_text_2), ++ ike_xcbc_known_mac_2, sizeof(ike_xcbc_known_mac_2)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_AES_XCBC_MAC, ++ ike_xcbc_known_key_3, sizeof(ike_xcbc_known_key_3), ++ ike_xcbc_known_plain_text_2, sizeof(ike_xcbc_known_plain_text_2), ++ ike_xcbc_known_mac_3, sizeof(ike_xcbc_known_mac_3)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_AES_XCBC_MAC, ++ ike_xcbc_known_key_4, sizeof(ike_xcbc_known_key_4), ++ ike_xcbc_known_plain_text_2, sizeof(ike_xcbc_known_plain_text_2), ++ ike_xcbc_known_mac_4, sizeof(ike_xcbc_known_mac_4)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_SHA_1_HMAC, ++ ike_sha1_known_key, sizeof(ike_sha1_known_key), ++ ike_sha1_known_plain_text, sizeof(ike_sha1_known_plain_text), ++ ike_sha1_known_mac, sizeof(ike_sha1_known_mac)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_SHA256_HMAC, ++ ike_sha256_known_key, sizeof(ike_sha256_known_key), ++ ike_sha256_known_plain_text, ++ sizeof(ike_sha256_known_plain_text), ++ ike_sha256_known_mac, sizeof(ike_sha256_known_mac)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_SHA384_HMAC, ++ ike_sha384_known_key, sizeof(ike_sha384_known_key), ++ ike_sha384_known_plain_text, ++ sizeof(ike_sha384_known_plain_text), ++ ike_sha384_known_mac, sizeof(ike_sha384_known_mac)); ++ if (rv != SECSuccess) ++ return rv; ++ rv = prf_test(CKM_SHA512_HMAC, ++ ike_sha512_known_key, sizeof(ike_sha512_known_key), ++ ike_sha512_known_plain_text, ++ sizeof(ike_sha512_known_plain_text), ++ ike_sha512_known_mac, sizeof(ike_sha512_known_mac)); ++ return rv; ++} +diff --git a/lib/softoken/softoken.gyp b/lib/softoken/softoken.gyp +--- a/lib/softoken/softoken.gyp ++++ b/lib/softoken/softoken.gyp +@@ -53,16 +53,17 @@ + 'lowpbe.c', + 'padbuf.c', + 'pkcs11.c', + 'pkcs11c.c', + 'pkcs11u.c', + 'sdb.c', + 'sftkdb.c', + 'sftkhmac.c', ++ 'sftkike.c', + 'sftkpars.c', + 'sftkpwd.c', + 'softkver.c', + 'tlsprf.c' + ], + }, + }, + { +diff --git a/lib/util/pkcs11n.h b/lib/util/pkcs11n.h +--- a/lib/util/pkcs11n.h ++++ b/lib/util/pkcs11n.h +@@ -147,16 +147,22 @@ + #define CKM_NSS_AES_KEY_WRAP_PAD (CKM_NSS + 2) + + /* HKDF key derivation mechanisms. See CK_NSS_HKDFParams for documentation. */ + #define CKM_NSS_HKDF_SHA1 (CKM_NSS + 3) + #define CKM_NSS_HKDF_SHA256 (CKM_NSS + 4) + #define CKM_NSS_HKDF_SHA384 (CKM_NSS + 5) + #define CKM_NSS_HKDF_SHA512 (CKM_NSS + 6) + ++/* IKE mechanism (to be proposed to PKCS #11 */ ++#define CKM_NSS_IKE_PRF_PLUS_DERIVE (CKM_NSS + 7) ++#define CKM_NSS_IKE_PRF_DERIVE (CKM_NSS + 8) ++#define CKM_NSS_IKE1_PRF_DERIVE (CKM_NSS + 9) ++#define CKM_NSS_IKE1_APP_B_PRF_DERIVE (CKM_NSS + 10) ++ + /* J-PAKE round 1 key generation mechanisms. + * + * Required template attributes: CKA_PRIME, CKA_SUBPRIME, CKA_BASE, + * CKA_NSS_JPAKE_SIGNERID + * Output key type: CKK_NSS_JPAKE_ROUND1 + * Output key class: CKO_PRIVATE_KEY + * Parameter type: CK_NSS_JPAKERound1Params + * +@@ -337,16 +343,82 @@ typedef struct CK_NSS_HKDFParams { + CK_BYTE_PTR pSalt; + CK_ULONG ulSaltLen; + CK_BBOOL bExpand; + CK_BYTE_PTR pInfo; + CK_ULONG ulInfoLen; + } CK_NSS_HKDFParams; + + /* ++ * CK_NSS_IKE_PRF_PLUS_PARAMS is a structure that provides the parameters to ++ * the CKM_NSS_IKE_PRF_PLUS_DERIVE mechanism. ++ * The fields of the structure have the following meanings: ++ * prfMechanism underlying MAC mechanism used to generate the prf. ++ * bHasSeedKey hSeed key is present. ++ * hSeedKey optional seed from key ++ * pSeedData optional seed from data. ++ * ulSeedDataLen length of optional seed data. ++ * If no seed data is present this value is NULL. ++ */ ++typedef struct CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS { ++ CK_MECHANISM_TYPE prfMechanism; ++ CK_BBOOL bHasSeedKey; ++ CK_OBJECT_HANDLE hSeedKey; ++ CK_BYTE_PTR pSeedData; ++ CK_ULONG ulSeedDataLen; ++} CK_NSS_IKE_PRF_PLUS_DERIVE_PARAMS; ++ ++/* CK_NSS_IKE_PRF_DERIVE_PARAMS is a structure that provides the parameters to ++ * the CKM_NSS_IKE_PRF_DERIVE mechanism. ++ * ++ * The fields of the structure have the following meanings: ++ * prfMechanism underlying MAC mechanism used to generate the prf. ++ * bRekey hNewKey is present. ++ * pNi Ni value ++ * ulNiLen length of Ni ++ * pNr Nr value ++ * ulNrLen length of Nr ++ * hNewKey New key value to drive the rekey. ++ */ ++typedef struct CK_NSS_IKE_PRF_DERIVE_PARAMS { ++ CK_MECHANISM_TYPE prfMechanism; ++ CK_BBOOL bDataAsKey; ++ CK_BBOOL bRekey; ++ CK_BYTE_PTR pNi; ++ CK_ULONG ulNiLen; ++ CK_BYTE_PTR pNr; ++ CK_ULONG ulNrLen; ++ CK_OBJECT_HANDLE hNewKey; ++} CK_NSS_IKE_PRF_DERIVE_PARAMS; ++ ++/* CK_NSS_IKE1_PRF_DERIVE_PARAMS is a structure that provides the parameters ++ * to the CKM_NSS_IKE_PRF_DERIVE mechanism. ++ * ++ * The fields of the structure have the following meanings: ++ * prfMechanism underlying MAC mechanism used to generate the prf. ++ * bRekey hNewKey is present. ++ * pCKYi CKYi value ++ * ulCKYiLen length of CKYi ++ * pCKYr CKYr value ++ * ulCKYrLen length of CKYr ++ * hNewKey New key value to drive the rekey. ++ */ ++typedef struct CK_NSS_IKE1_PRF_DERIVE_PARAMS { ++ CK_MECHANISM_TYPE prfMechanism; ++ CK_BBOOL bHasPrevKey; ++ CK_OBJECT_HANDLE hKeygxy; ++ CK_OBJECT_HANDLE hPrevKey; ++ CK_BYTE_PTR pCKYi; ++ CK_ULONG ulCKYiLen; ++ CK_BYTE_PTR pCKYr; ++ CK_ULONG ulCKYrLen; ++ CK_BYTE keyNumber; ++} CK_NSS_IKE1_PRF_DERIVE_PARAMS; ++ ++/* + * Parameter for the TLS extended master secret key derivation mechanisms: + * + * * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE + * * CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH + * + * For the TLS 1.2 PRF, the prfHashMechanism parameter determines the hash + * function used. For earlier versions of the PRF, set the prfHashMechanism + * value to CKM_TLS_PRF. +diff --git a/lib/util/pkcs11t.h b/lib/util/pkcs11t.h +--- a/lib/util/pkcs11t.h ++++ b/lib/util/pkcs11t.h +@@ -877,16 +877,18 @@ typedef CK_ULONG CK_MECHANISM_TYPE; + #define CKM_AES_MAC_GENERAL 0x00001084 + #define CKM_AES_CBC_PAD 0x00001085 + /* new for v2.20 amendment 3 */ + #define CKM_AES_CTR 0x00001086 + /* new for v2.30 */ + #define CKM_AES_GCM 0x00001087 + #define CKM_AES_CCM 0x00001088 + #define CKM_AES_CTS 0x00001089 ++#define CKM_AES_XCBC_MAC 0x0000108C ++#define CKM_AES_XCBC_MAC_96 0x0000108D + + /* BlowFish and TwoFish are new for v2.20 */ + #define CKM_BLOWFISH_KEY_GEN 0x00001090 + #define CKM_BLOWFISH_CBC 0x00001091 + #define CKM_TWOFISH_KEY_GEN 0x00001092 + #define CKM_TWOFISH_CBC 0x00001093 + + /* Camellia is proposed for v2.20 Amendment 3 */ +diff --git a/tests/common/init.sh b/tests/common/init.sh +--- a/tests/common/init.sh ++++ b/tests/common/init.sh +@@ -646,18 +646,21 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOU + + TOTAL_CRL_RANGE=`expr ${CRL_GRP_1_RANGE} + ${CRL_GRP_2_RANGE} + \ + ${CRL_GRP_3_RANGE}` + + TOTAL_GRP_NUM=3 + + RELOAD_CRL=1 + +- NSS_DEFAULT_DB_TYPE="dbm" +- export NSS_DEFAULT_DB_TYPE ++ # if test mode isn't set, test scripts default to expecting dbm ++ if [ "${TEST_MODE}" = "" ]; then ++ NSS_DEFAULT_DB_TYPE="dbm" ++ export NSS_DEFAULT_DB_TYPE ++ fi + + MSG_ID=0 + + ################################################# + # Interoperability testing constatnts + # + # if suite is setup for testing, IOPR_HOSTADDR_LIST should have + # at least one host name(FQDN) +diff --git a/tests/fips/fips.sh b/tests/fips/fips.sh +--- a/tests/fips/fips.sh ++++ b/tests/fips/fips.sh +@@ -40,27 +40,31 @@ fips_init() + SCRIPTNAME=fips.sh + html_head "FIPS 140 Compliance Tests" + + grep "SUCCESS: FIPS passed" $CERT_LOG_FILE >/dev/null || { + Exit 15 "Fatal - FIPS of cert.sh needs to pass first" + } + + COPYDIR=${FIPSDIR}/copydir ++ CAVSDIR=${FIPSDIR}/cavs/tests ++ CAVSRUNDIR=${FIPSDIR}/cavs/scripts + + R_FIPSDIR=../fips + P_R_FIPSDIR=../fips + R_COPYDIR=../fips/copydir + + if [ -n "${MULTIACCESS_DBM}" ]; then + P_R_FIPSDIR="multiaccess:${D_FIPS}" + fi + + mkdir -p ${FIPSDIR} + mkdir -p ${COPYDIR} ++ mkdir -p ${CAVSDIR} ++ mkdir -p ${CAVSRUNDIR} + + cd ${FIPSDIR} + } + + ############################## fips_140 ############################## + # local shell function to test basic functionality of NSS while in + # FIPS 140 compliant mode + ######################################################################## +@@ -269,25 +273,51 @@ fips_140() + fi + + html_msg ${RESULT} 46 "Init NSS with a corrupted library (dbtest -r)" "." + else + html_failed "Mangle ${DLL_PREFIX}softokn3.${DLL_SUFFIX}" + fi + } + ++fips_cavs() ++{ ++ if [ "${CAVS_VECTORS}" = "all" ]; then ++ VECTORS= ++ elif [ "${CAVS_VECTORS}" = "" ]; then ++ VECTORS="aesgcm ecdsa hmac kas tls ike rng sha" ++ else ++ VECTORS=${CAVS_VECTORS} ++ fi ++ echo "Copying CAVS vectors" ++ cp -r ${QADIR}/fips/cavs_samples/* ${CAVSDIR} ++# we copy the scripts to the test directory because they are designed to run from their ++# own directory and we want any resulting core dumps to wind up in the test_results directory. ++ echo "Copying CAVS scripts" ++ cp -r ${QADIR}/fips/cavs_scripts/* ${CAVSRUNDIR} ++ echo "cd ${CAVSRUNDIR}" ++ cd ${CAVSRUNDIR} ++ echo "Running CAVS tests in ${CAVSDIR}" ++ ./runtest.sh ${CAVSDIR} run ${VECTORS} ++ echo "Verifying CAVS results in ${CAVSDIR}" ++ ./runtest.sh ${CAVSDIR} verify ${VECTORS} ++ RESULT=$? ++ html_msg $RESULT 0 "NIST CAVS test" "${CAVSDIR}" ++} ++ + ############################## fips_cleanup ############################ + # local shell function to finish this script (no exit since it might be + # sourced) + ######################################################################## + fips_cleanup() + { + html "
" + cd ${QADIR} + . common/cleanup.sh + } + + ################## main ################################################# + + fips_init + fips_140 ++fips_cavs + fips_cleanup + echo "fips.sh done" diff --git a/SOURCES/nss-input-check.patch b/SOURCES/nss-input-check.patch new file mode 100644 index 0000000..366b793 --- /dev/null +++ b/SOURCES/nss-input-check.patch @@ -0,0 +1,127 @@ +# HG changeset patch +# User Martin Thomson +# Date 1560498951 0 +# Fri Jun 14 07:55:51 2019 +0000 +# Branch NSS_3_44_BRANCH +# Node ID fb9932d6e083322e7b5dfcd3d6e67477e0bb075a +# Parent 876bca2723a1f969422edc93e7504420d8331d3c +Bug 1515342 - More thorough input checking, r=jcj + +All part of applying better discipline throughout. + +Differential Revision: https://phabricator.services.mozilla.com/D33736 + +diff --git a/lib/cryptohi/seckey.c b/lib/cryptohi/seckey.c +--- a/lib/cryptohi/seckey.c ++++ b/lib/cryptohi/seckey.c +@@ -639,6 +639,11 @@ seckey_ExtractPublicKey(const CERTSubjec + return pubk; + break; + case SEC_OID_ANSIX962_EC_PUBLIC_KEY: ++ /* A basic sanity check on inputs. */ ++ if (spki->algorithm.parameters.len == 0 || newOs.len == 0) { ++ PORT_SetError(SEC_ERROR_INPUT_LEN); ++ break; ++ } + pubk->keyType = ecKey; + pubk->u.ec.size = 0; + +diff --git a/lib/freebl/dh.c b/lib/freebl/dh.c +--- a/lib/freebl/dh.c ++++ b/lib/freebl/dh.c +@@ -210,7 +210,8 @@ DH_Derive(SECItem *publicValue, + unsigned int len = 0; + unsigned int nb; + unsigned char *secret = NULL; +- if (!publicValue || !prime || !privateValue || !derivedSecret) { ++ if (!publicValue || !publicValue->len || !prime || !prime->len || ++ !privateValue || !privateValue->len || !derivedSecret) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } +diff --git a/lib/freebl/ec.c b/lib/freebl/ec.c +--- a/lib/freebl/ec.c ++++ b/lib/freebl/ec.c +@@ -202,8 +202,8 @@ ec_NewKey(ECParams *ecParams, ECPrivateK + #endif + MP_DIGITS(&k) = 0; + +- if (!ecParams || !privKey || !privKeyBytes || (privKeyLen < 0) || +- !ecParams->name) { ++ if (!ecParams || ecParams->name == ECCurve_noName || ++ !privKey || !privKeyBytes || privKeyLen <= 0) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } +@@ -391,7 +391,7 @@ EC_NewKey(ECParams *ecParams, ECPrivateK + int len; + unsigned char *privKeyBytes = NULL; + +- if (!ecParams) { ++ if (!ecParams || ecParams->name == ECCurve_noName || !privKey) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } +@@ -430,7 +430,8 @@ EC_ValidatePublicKey(ECParams *ecParams, + mp_err err = MP_OKAY; + int len; + +- if (!ecParams || !publicValue || !ecParams->name) { ++ if (!ecParams || ecParams->name == ECCurve_noName || ++ !publicValue || !publicValue->len) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } +@@ -536,8 +537,9 @@ ECDH_Derive(SECItem *publicValue, + int i; + #endif + +- if (!publicValue || !ecParams || !privateValue || !derivedSecret || +- !ecParams->name) { ++ if (!publicValue || !publicValue->len || ++ !ecParams || ecParams->name == ECCurve_noName || ++ !privateValue || !privateValue->len || !derivedSecret) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } +diff --git a/lib/util/quickder.c b/lib/util/quickder.c +--- a/lib/util/quickder.c ++++ b/lib/util/quickder.c +@@ -757,6 +757,13 @@ DecodeItem(void* dest, + } + + case SEC_ASN1_BIT_STRING: { ++ /* Can't be 8 or more spare bits, or any spare bits ++ * if there are no octets. */ ++ if (temp.data[0] >= 8 || (temp.data[0] > 0 && temp.len == 1)) { ++ PORT_SetError(SEC_ERROR_BAD_DER); ++ rv = SECFailure; ++ break; ++ } + /* change the length in the SECItem to be the number + of bits */ + temp.len = (temp.len - 1) * 8 - (temp.data[0] & 0x7); +# HG changeset patch +# User Kevin Jacobs +# Date 1561145635 0 +# Fri Jun 21 19:33:55 2019 +0000 +# Branch NSS_3_44_BRANCH +# Node ID 416a8f7cf8986103b4d74694aac1198edbb08b3e +# Parent fb9932d6e083322e7b5dfcd3d6e67477e0bb075a +Bug 1515342 - Ignore spki decode failures on negative (expect_fail) tests. r=jcj + +Differential Revision: https://phabricator.services.mozilla.com/D35565 + +diff --git a/gtests/pk11_gtest/pk11_curve25519_unittest.cc b/gtests/pk11_gtest/pk11_curve25519_unittest.cc +--- a/gtests/pk11_gtest/pk11_curve25519_unittest.cc ++++ b/gtests/pk11_gtest/pk11_curve25519_unittest.cc +@@ -40,6 +40,9 @@ class Pkcs11Curve25519Test + + ScopedCERTSubjectPublicKeyInfo certSpki( + SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem)); ++ if (!expect_success && !certSpki) { ++ return; ++ } + ASSERT_TRUE(certSpki); + + ScopedSECKEYPublicKey pubKey(SECKEY_ExtractPublicKey(certSpki.get())); diff --git a/SOURCES/nss-leading-zero.patch b/SOURCES/nss-leading-zero.patch new file mode 100644 index 0000000..4ea008c --- /dev/null +++ b/SOURCES/nss-leading-zero.patch @@ -0,0 +1,143 @@ +# HG changeset patch +# User Kevin Jacobs +# Date 1560499074 0 +# Fri Jun 14 07:57:54 2019 +0000 +# Branch NSS_3_44_BRANCH +# Node ID 876bca2723a1f969422edc93e7504420d8331d3c +# Parent 20671f860c2619dc27208d64a84a759fdffc5ed1 +Bug 1540541 - Don't unnecessarily strip leading 0's from key material during PKCS11 import. r=jcj,mt + +Differential Revision: https://phabricator.services.mozilla.com/D31671 + +diff --git a/lib/freebl/ecl/ecp_25519.c b/lib/freebl/ecl/ecp_25519.c +--- a/lib/freebl/ecl/ecp_25519.c ++++ b/lib/freebl/ecl/ecp_25519.c +@@ -114,6 +114,9 @@ ec_Curve25519_pt_mul(SECItem *X, SECItem + } + px = P->data; + } ++ if (k->len != 32) { ++ return SECFailure; ++ } + + SECStatus rv = ec_Curve25519_mul(X->data, k->data, px); + if (NSS_SecureMemcmpZero(X->data, X->len) == 0) { +diff --git a/lib/pk11wrap/pk11akey.c b/lib/pk11wrap/pk11akey.c +--- a/lib/pk11wrap/pk11akey.c ++++ b/lib/pk11wrap/pk11akey.c +@@ -190,7 +190,6 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, + attrs++; + PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); + attrs++; +- signedattr = attrs; + PK11_SETATTRS(attrs, CKA_EC_PARAMS, + pubKey->u.ec.DEREncodedParams.data, + pubKey->u.ec.DEREncodedParams.len); +@@ -222,12 +221,14 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, + PORT_SetError(SEC_ERROR_BAD_KEY); + return CK_INVALID_HANDLE; + } +- + templateCount = attrs - theTemplate; +- signedcount = attrs - signedattr; + PORT_Assert(templateCount <= (sizeof(theTemplate) / sizeof(CK_ATTRIBUTE))); +- for (attrs = signedattr; signedcount; attrs++, signedcount--) { +- pk11_SignedToUnsigned(attrs); ++ if (pubKey->keyType != ecKey) { ++ PORT_Assert(signedattr); ++ signedcount = attrs - signedattr; ++ for (attrs = signedattr; signedcount; attrs++, signedcount--) { ++ pk11_SignedToUnsigned(attrs); ++ } + } + rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate, + templateCount, isToken, &objectID); +@@ -1074,9 +1075,13 @@ pk11_loadPrivKeyWithFlags(PK11SlotInfo * + &cktrue, &ckfalse); + + /* Not everyone can handle zero padded key values, give +- * them the raw data as unsigned */ +- for (ap = attrs; extra_count; ap++, extra_count--) { +- pk11_SignedToUnsigned(ap); ++ * them the raw data as unsigned. The exception is EC, ++ * where the values are encoded or zero-preserving ++ * per-RFC5915 */ ++ if (privKey->keyType != ecKey) { ++ for (ap = attrs; extra_count; ap++, extra_count--) { ++ pk11_SignedToUnsigned(ap); ++ } + } + + /* now Store the puppies */ +diff --git a/lib/pk11wrap/pk11cert.c b/lib/pk11wrap/pk11cert.c +--- a/lib/pk11wrap/pk11cert.c ++++ b/lib/pk11wrap/pk11cert.c +@@ -184,7 +184,9 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERT + SECKEY_DestroyPublicKey(pubKey); + return PR_FALSE; + } +- pk11_SignedToUnsigned(&theTemplate); ++ if (pubKey->keyType != ecKey) { ++ pk11_SignedToUnsigned(&theTemplate); ++ } + if (pk11_FindObjectByTemplate(slot, &theTemplate, 1) != CK_INVALID_HANDLE) { + SECKEY_DestroyPublicKey(pubKey); + return PR_TRUE; +diff --git a/lib/pk11wrap/pk11pk12.c b/lib/pk11wrap/pk11pk12.c +--- a/lib/pk11wrap/pk11pk12.c ++++ b/lib/pk11wrap/pk11pk12.c +@@ -505,7 +505,7 @@ PK11_ImportAndReturnPrivateKey(PK11SlotI + } + PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len); + attrs++; +- signedattr = attrs; ++ /* No signed attrs for EC */ + /* curveOID always is a copy of AlgorithmID.parameters. */ + PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data, + lpk->u.ec.curveOID.len); +@@ -523,11 +523,12 @@ PK11_ImportAndReturnPrivateKey(PK11SlotI + } + templateCount = attrs - theTemplate; + PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE)); +- PORT_Assert(signedattr != NULL); +- signedcount = attrs - signedattr; +- +- for (ap = signedattr; signedcount; ap++, signedcount--) { +- pk11_SignedToUnsigned(ap); ++ if (lpk->keyType != ecKey) { ++ PORT_Assert(signedattr); ++ signedcount = attrs - signedattr; ++ for (ap = signedattr; signedcount; ap++, signedcount--) { ++ pk11_SignedToUnsigned(ap); ++ } + } + + rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, +diff --git a/lib/softoken/legacydb/lgattr.c b/lib/softoken/legacydb/lgattr.c +--- a/lib/softoken/legacydb/lgattr.c ++++ b/lib/softoken/legacydb/lgattr.c +@@ -950,9 +950,9 @@ lg_FindECPrivateKeyAttribute(NSSLOWKEYPr + case CKA_UNWRAP: + return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr); + case CKA_VALUE: +- return lg_CopyPrivAttrSigned(attribute, type, +- key->u.ec.privateValue.data, +- key->u.ec.privateValue.len, sdbpw); ++ return lg_CopyPrivAttribute(attribute, type, ++ key->u.ec.privateValue.data, ++ key->u.ec.privateValue.len, sdbpw); + case CKA_EC_PARAMS: + return lg_CopyAttributeSigned(attribute, type, + key->u.ec.ecParams.DEREncoding.data, +diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c +--- a/lib/softoken/pkcs11c.c ++++ b/lib/softoken/pkcs11c.c +@@ -7747,7 +7747,7 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + + rv = ECDH_Derive(&ecPoint, &privKey->u.ec.ecParams, &ecScalar, + withCofactor, &tmp); +- PORT_Free(ecScalar.data); ++ PORT_ZFree(ecScalar.data, ecScalar.len); + ecScalar.data = NULL; + if (privKey != sourceKey->objectInfo) { + nsslowkey_DestroyPrivateKey(privKey); diff --git a/SOURCES/nss-module-leak.patch b/SOURCES/nss-module-leak.patch new file mode 100644 index 0000000..7acf3f3 --- /dev/null +++ b/SOURCES/nss-module-leak.patch @@ -0,0 +1,35 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1557150127 -7200 +# Mon May 06 15:42:07 2019 +0200 +# Node ID 438ac983bda9ec7944990d22a37877e9111caa90 +# Parent b018f3e84d87cce99a1fd81feeecb31123058687 +pk11slot: reference module from slot for finalization + +diff --git a/lib/pk11wrap/pk11slot.c b/lib/pk11wrap/pk11slot.c +--- a/lib/pk11wrap/pk11slot.c ++++ b/lib/pk11wrap/pk11slot.c +@@ -1439,6 +1439,11 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT + slot->slotID = slotID; + slot->isThreadSafe = mod->isThreadSafe; + slot->hasRSAInfo = PR_FALSE; ++ slot->module = mod; /* NOTE: we don't make a reference here because ++ * modules have references to their slots. This ++ * works because modules keep implicit references ++ * from their slots, and won't unload and disappear ++ * until all their slots have been freed */ + + if (PK11_GETTAB(slot)->C_GetSlotInfo(slotID, &slotInfo) != CKR_OK) { + slot->disabled = PR_TRUE; +@@ -1448,11 +1453,6 @@ PK11_InitSlot(SECMODModule *mod, CK_SLOT + + /* test to make sure claimed mechanism work */ + slot->needTest = mod->internal ? PR_FALSE : PR_TRUE; +- slot->module = mod; /* NOTE: we don't make a reference here because +- * modules have references to their slots. This +- * works because modules keep implicit references +- * from their slots, and won't unload and disappear +- * until all their slots have been freed */ + (void)PK11_MakeString(NULL, slot->slot_name, + (char *)slotInfo.slotDescription, sizeof(slotInfo.slotDescription)); + slot->isHW = (PRBool)((slotInfo.flags & CKF_HW_SLOT) == CKF_HW_SLOT); diff --git a/SOURCES/nss-mpi-loop.patch b/SOURCES/nss-mpi-loop.patch new file mode 100644 index 0000000..d919a5e --- /dev/null +++ b/SOURCES/nss-mpi-loop.patch @@ -0,0 +1,24 @@ +# HG changeset patch +# User Greg Rubin +# Date 1558464083 25200 +# Tue May 21 11:41:23 2019 -0700 +# Branch NSS_3_44_BRANCH +# Node ID 1eac9016c021055018389a5cb117678ecc61782a +# Parent 416a8f7cf8986103b4d74694aac1198edbb08b3e +Bug 1554336 - Optimize away unneeded loop in mpi.c r=kevinjacobs,jcj + +diff --git a/lib/freebl/mpi/mpi.c b/lib/freebl/mpi/mpi.c +--- a/lib/freebl/mpi/mpi.c ++++ b/lib/freebl/mpi/mpi.c +@@ -2063,7 +2063,10 @@ s_mp_almost_inverse(const mp_int *a, con + } + } + if (res >= 0) { +- while (MP_SIGN(c) != MP_ZPOS) { ++ if (mp_cmp_mag(c, p) >= 0) { ++ MP_CHECKOK(mp_div(c, p, NULL, c)); ++ } ++ if (MP_SIGN(c) != MP_ZPOS) { + MP_CHECKOK(mp_add(c, p, c)); + } + res = k; diff --git a/SOURCES/nss-p11-kit.config b/SOURCES/nss-p11-kit.config new file mode 100644 index 0000000..0ebf073 --- /dev/null +++ b/SOURCES/nss-p11-kit.config @@ -0,0 +1,4 @@ +name=p11-kit-proxy +library=p11-kit-proxy.so + + diff --git a/SOURCES/nss-post-handshake-auth-with-tickets.patch b/SOURCES/nss-post-handshake-auth-with-tickets.patch new file mode 100644 index 0000000..ac51f07 --- /dev/null +++ b/SOURCES/nss-post-handshake-auth-with-tickets.patch @@ -0,0 +1,96 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1559121620 -7200 +# Wed May 29 11:20:20 2019 +0200 +# Node ID 29a48b604602a523defd6f9322a5adeca7e284a5 +# Parent 43a7fb4f994a31222c308113b0fccdd5480d5b8e +Bug 1553443, send session ticket only after handshake is marked as finished + +Reviewers: mt + +Reviewed By: mt + +Bug #: 1553443 + +Differential Revision: https://phabricator.services.mozilla.com/D32128 + +diff --git a/gtests/ssl_gtest/ssl_auth_unittest.cc b/gtests/ssl_gtest/ssl_auth_unittest.cc +--- a/gtests/ssl_gtest/ssl_auth_unittest.cc ++++ b/gtests/ssl_gtest/ssl_auth_unittest.cc +@@ -537,6 +537,40 @@ TEST_F(TlsConnectStreamTls13, PostHandsh + capture_cert_req->buffer().len())); + } + ++// Check if post-handshake auth still works when session tickets are enabled: ++// https://bugzilla.mozilla.org/show_bug.cgi?id=1553443 ++TEST_F(TlsConnectStreamTls13, PostHandshakeAuthWithSessionTicketsEnabled) { ++ EnsureTlsSetup(); ++ client_->SetupClientAuth(); ++ EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), ++ SSL_ENABLE_POST_HANDSHAKE_AUTH, PR_TRUE)); ++ EXPECT_EQ(SECSuccess, SSL_OptionSet(client_->ssl_fd(), ++ SSL_ENABLE_SESSION_TICKETS, PR_TRUE)); ++ EXPECT_EQ(SECSuccess, SSL_OptionSet(server_->ssl_fd(), ++ SSL_ENABLE_SESSION_TICKETS, PR_TRUE)); ++ size_t called = 0; ++ server_->SetAuthCertificateCallback( ++ [&called](TlsAgent*, PRBool, PRBool) -> SECStatus { ++ called++; ++ return SECSuccess; ++ }); ++ Connect(); ++ EXPECT_EQ(0U, called); ++ // Send CertificateRequest. ++ EXPECT_EQ(SECSuccess, SSL_GetClientAuthDataHook( ++ client_->ssl_fd(), GetClientAuthDataHook, nullptr)); ++ EXPECT_EQ(SECSuccess, SSL_SendCertificateRequest(server_->ssl_fd())) ++ << "Unexpected error: " << PORT_ErrorToName(PORT_GetError()); ++ server_->SendData(50); ++ client_->ReadBytes(50); ++ client_->SendData(50); ++ server_->ReadBytes(50); ++ EXPECT_EQ(1U, called); ++ ScopedCERTCertificate cert1(SSL_PeerCertificate(server_->ssl_fd())); ++ ScopedCERTCertificate cert2(SSL_LocalCertificate(client_->ssl_fd())); ++ EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert)); ++} ++ + // In TLS 1.3, the client sends its cert rejection on the + // second flight, and since it has already received the + // server's Finished, it transitions to complete and +diff --git a/lib/ssl/tls13con.c b/lib/ssl/tls13con.c +--- a/lib/ssl/tls13con.c ++++ b/lib/ssl/tls13con.c +@@ -4561,6 +4561,11 @@ tls13_ServerHandleFinished(sslSocket *ss + return SECFailure; + } + ++ rv = tls13_FinishHandshake(ss); ++ if (rv != SECSuccess) { ++ return SECFailure; ++ } ++ + ssl_GetXmitBufLock(ss); + if (ss->opt.enableSessionTickets) { + rv = tls13_SendNewSessionTicket(ss, NULL, 0); +@@ -4573,8 +4578,7 @@ tls13_ServerHandleFinished(sslSocket *ss + } + } + ssl_ReleaseXmitBufLock(ss); +- +- return tls13_FinishHandshake(ss); ++ return SECSuccess; + + loser: + ssl_ReleaseXmitBufLock(ss); +diff --git a/tests/ssl/sslauth.txt b/tests/ssl/sslauth.txt +--- a/tests/ssl/sslauth.txt ++++ b/tests/ssl/sslauth.txt +@@ -42,6 +42,7 @@ + noECC 0 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Require client auth on post hs (client auth) + noECC 0 -r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Request don't require client auth on post hs (client does not provide auth) + noECC 1 -r_-r_-r_-r_-E -V_tls1.3:tls1.3_-E_-n_none_-w_nss TLS 1.3 Require client auth on post hs (client does not provide auth) ++ noECC 0 -r_-r_-r_-E_-u -V_tls1.3:tls1.3_-E_-n_TestUser_-w_nss TLS 1.3 Request don't require client auth on post hs with session ticket (client auth) + # + # Use EC cert for client authentication + # diff --git a/SOURCES/nss-skip-sysinit-gtests.patch b/SOURCES/nss-skip-sysinit-gtests.patch new file mode 100644 index 0000000..4c3ea29 --- /dev/null +++ b/SOURCES/nss-skip-sysinit-gtests.patch @@ -0,0 +1,11 @@ +diff -up nss/gtests/manifest.mn.skip-sysinit-gtests nss/gtests/manifest.mn +--- nss/gtests/manifest.mn.skip-sysinit-gtests 2019-04-26 12:55:05.979302035 +0200 ++++ nss/gtests/manifest.mn 2019-04-26 12:55:09.507228984 +0200 +@@ -27,7 +27,6 @@ NSS_SRCDIRS = \ + smime_gtest \ + softoken_gtest \ + ssl_gtest \ +- $(SYSINIT_GTEST) \ + nss_bogo_shim \ + $(NULL) + endif diff --git a/SOURCES/nss-skip-tls13-fips.patch b/SOURCES/nss-skip-tls13-fips.patch new file mode 100644 index 0000000..4a7c707 --- /dev/null +++ b/SOURCES/nss-skip-tls13-fips.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# User Daiki Ueno +# Date 1558341826 -7200 +# Mon May 20 10:43:46 2019 +0200 +# Node ID b447f0046807b718d2928d0e33313620d38a287a +# Parent 02ea5f29ac3c1f1c6e6eb4b655afd9b4fc075a9e +tests: skip TLS 1.3 tests under FIPS mode + +diff --git a/tests/ssl/ssl.sh b/tests/ssl/ssl.sh +--- a/tests/ssl/ssl.sh ++++ b/tests/ssl/ssl.sh +@@ -393,6 +393,15 @@ ssl_auth() + echo "${testname}" | grep "TLS 1.3" > /dev/null + TLS13=$? + ++ # Currently TLS 1.3 tests are known to fail under FIPS mode, ++ # because HKDF is implemented using the PKCS #11 functions ++ # prohibited under FIPS mode. ++ if [ "${TLS13}" -eq 0 ] && \ ++ [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then ++ echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" ++ continue ++ fi ++ + if [ "${CLIENT_MODE}" = "fips" -a "${CAUTH}" -eq 0 ] ; then + echo "$SCRIPTNAME: skipping $testname (non-FIPS only)" + elif [ "$ectype" = "SNI" -a "$NORM_EXT" = "Extended Test" ] ; then diff --git a/SOURCES/nss-softokn-config.in b/SOURCES/nss-softokn-config.in new file mode 100644 index 0000000..c7abe29 --- /dev/null +++ b/SOURCES/nss-softokn-config.in @@ -0,0 +1,116 @@ +#!/bin/sh + +prefix=@prefix@ + +major_version=@MOD_MAJOR_VERSION@ +minor_version=@MOD_MINOR_VERSION@ +patch_version=@MOD_PATCH_VERSION@ + +usage() +{ + cat <&2 +fi + +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=`pkg-config --variable=exec_prefix nss-softokn` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss-softokn` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss-softokn` +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" + echo $libdirs +fi + diff --git a/SOURCES/nss-softokn-dracut-module-setup.sh b/SOURCES/nss-softokn-dracut-module-setup.sh new file mode 100644 index 0000000..010ec18 --- /dev/null +++ b/SOURCES/nss-softokn-dracut-module-setup.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + return 255 +} + +depends() { + return 0 +} + +install() { + local _dir + + inst_libdir_file libfreeblpriv3.so libfreeblpriv3.chk \ + libfreebl3.so +} diff --git a/SOURCES/nss-softokn-dracut.conf b/SOURCES/nss-softokn-dracut.conf new file mode 100644 index 0000000..2d9232e --- /dev/null +++ b/SOURCES/nss-softokn-dracut.conf @@ -0,0 +1,3 @@ +# turn on nss-softokn module + +add_dracutmodules+=" nss-softokn " diff --git a/SOURCES/nss-softokn-fips-update.patch b/SOURCES/nss-softokn-fips-update.patch new file mode 100644 index 0000000..604b947 --- /dev/null +++ b/SOURCES/nss-softokn-fips-update.patch @@ -0,0 +1,1148 @@ +diff --git a/lib/freebl/fipsfreebl.c b/lib/freebl/fipsfreebl.c +--- a/lib/freebl/fipsfreebl.c ++++ b/lib/freebl/fipsfreebl.c +@@ -10,18 +10,20 @@ + #ifdef FREEBL_NO_DEPEND + #include "stubs.h" + #endif + + #include "blapi.h" + #include "seccomon.h" /* Required for RSA and DSA. */ + #include "secerr.h" + #include "prtypes.h" ++#include "secitem.h" ++#include "pkcs11t.h" + +-#include "ec.h" /* Required for ECDSA */ ++#include "ec.h" /* Required for EC */ + + /* + * different platforms have different ways of calling and initial entry point + * when the dll/.so is loaded. Most platforms support either a posix pragma + * or the GCC attribute. Some platforms suppor a pre-defined name, and some + * platforms have a link line way of invoking this function. + */ + +@@ -283,61 +285,88 @@ freebl_fips_AES_PowerUpSelfTest(int aes_ + + /* AES-CBC Known Initialization Vector (128-bits). */ + static const PRUint8 aes_cbc_known_initialization_vector[] = + { "SecurityytiruceS" }; + + /* AES Known Plaintext (128-bits). (blocksize is 128-bits) */ + static const PRUint8 aes_known_plaintext[] = { "NetscapeepacsteN" }; + ++ static const PRUint8 aes_gcm_known_aad[] = { "MozillaallizoM" }; ++ + /* AES Known Ciphertext (128-bit key). */ + static const PRUint8 aes_ecb128_known_ciphertext[] = { + 0x3c, 0xa5, 0x96, 0xf3, 0x34, 0x6a, 0x96, 0xc1, + 0x03, 0x88, 0x16, 0x7b, 0x20, 0xbf, 0x35, 0x47 + }; + + static const PRUint8 aes_cbc128_known_ciphertext[] = { + 0xcf, 0x15, 0x1d, 0x4f, 0x96, 0xe4, 0x4f, 0x63, + 0x15, 0x54, 0x14, 0x1d, 0x4e, 0xd8, 0xd5, 0xea + }; + ++ static const PRUint8 aes_gcm128_known_ciphertext[] = { ++ 0x63, 0xf4, 0x95, 0x28, 0xe6, 0x78, 0xee, 0x6e, ++ 0x4f, 0xe0, 0xfc, 0x8d, 0xd7, 0xa2, 0xb1, 0xff, ++ 0x0c, 0x97, 0x1b, 0x0a, 0xdd, 0x97, 0x75, 0xed, ++ 0x8b, 0xde, 0xbf, 0x16, 0x5e, 0x57, 0x6b, 0x4f ++ }; ++ + /* AES Known Ciphertext (192-bit key). */ + static const PRUint8 aes_ecb192_known_ciphertext[] = { + 0xa0, 0x18, 0x62, 0xed, 0x88, 0x19, 0xcb, 0x62, + 0x88, 0x1d, 0x4d, 0xfe, 0x84, 0x02, 0x89, 0x0e + }; + + static const PRUint8 aes_cbc192_known_ciphertext[] = { + 0x83, 0xf7, 0xa4, 0x76, 0xd1, 0x6f, 0x07, 0xbe, + 0x07, 0xbc, 0x43, 0x2f, 0x6d, 0xad, 0x29, 0xe1 + }; + ++ static const PRUint8 aes_gcm192_known_ciphertext[] = { ++ 0xc1, 0x0b, 0x92, 0x1d, 0x68, 0x21, 0xf4, 0x25, ++ 0x41, 0x61, 0x20, 0x2d, 0x59, 0x7f, 0x53, 0xde, ++ 0x93, 0x39, 0xab, 0x09, 0x76, 0x41, 0x57, 0x2b, ++ 0x90, 0x2e, 0x44, 0xbb, 0x52, 0x03, 0xe9, 0x07 ++ }; ++ + /* AES Known Ciphertext (256-bit key). */ + static const PRUint8 aes_ecb256_known_ciphertext[] = { + 0xdb, 0xa6, 0x52, 0x01, 0x8a, 0x70, 0xae, 0x66, + 0x3a, 0x99, 0xd8, 0x95, 0x7f, 0xfb, 0x01, 0x67 + }; + + static const PRUint8 aes_cbc256_known_ciphertext[] = { + 0x37, 0xea, 0x07, 0x06, 0x31, 0x1c, 0x59, 0x27, + 0xc5, 0xc5, 0x68, 0x71, 0x6e, 0x34, 0x40, 0x16 + }; + ++ static const PRUint8 aes_gcm256_known_ciphertext[] = { ++ 0x5d, 0x9e, 0xd2, 0xa2, 0x74, 0x9c, 0xd9, 0x1c, ++ 0xd1, 0xc9, 0xee, 0x5d, 0xb6, 0xf2, 0xc9, 0xb6, ++ 0x79, 0x27, 0x53, 0x02, 0xa3, 0xdc, 0x22, 0xce, ++ 0xf4, 0xb0, 0xc1, 0x8c, 0x86, 0x51, 0xf5, 0xa1 ++ }; ++ + 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; + + const PRUint8 *aes_cbc_known_ciphertext = + (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_cbc128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_cbc192_known_ciphertext : aes_cbc256_known_ciphertext; + ++ const PRUint8 *aes_gcm_known_ciphertext = ++ (aes_key_size == FIPS_AES_128_KEY_SIZE) ? aes_gcm128_known_ciphertext : (aes_key_size == FIPS_AES_192_KEY_SIZE) ? aes_gcm192_known_ciphertext : aes_gcm256_known_ciphertext; ++ + /* AES variables. */ +- PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH]; +- PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH]; ++ PRUint8 aes_computed_ciphertext[FIPS_AES_ENCRYPT_LENGTH * 2]; ++ PRUint8 aes_computed_plaintext[FIPS_AES_DECRYPT_LENGTH * 2]; + AESContext *aes_context; + unsigned int aes_bytes_encrypted; + unsigned int aes_bytes_decrypted; ++ CK_GCM_PARAMS gcmParams; + SECStatus aes_status; + + /*check if aes_key_size is 128, 192, or 256 bits */ + if ((aes_key_size != FIPS_AES_128_KEY_SIZE) && + (aes_key_size != FIPS_AES_192_KEY_SIZE) && + (aes_key_size != FIPS_AES_256_KEY_SIZE)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return (SECFailure); +@@ -450,16 +479,79 @@ freebl_fips_AES_PowerUpSelfTest(int aes_ + if ((aes_status != SECSuccess) || + (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) || + (PORT_Memcmp(aes_computed_plaintext, aes_known_plaintext, + FIPS_AES_DECRYPT_LENGTH) != 0)) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return (SECFailure); + } + ++ /******************************************************/ ++ /* AES-GCM Single-Round Known Answer Encryption Test. */ ++ /******************************************************/ ++ ++ gcmParams.pIv = (PRUint8 *)aes_cbc_known_initialization_vector; ++ gcmParams.ulIvLen = FIPS_AES_BLOCK_SIZE; ++ gcmParams.pAAD = (PRUint8 *)aes_gcm_known_aad; ++ gcmParams.ulAADLen = sizeof(aes_gcm_known_aad); ++ gcmParams.ulTagBits = FIPS_AES_BLOCK_SIZE * 8; ++ aes_context = AES_CreateContext(aes_known_key, ++ (PRUint8 *)&gcmParams, ++ NSS_AES_GCM, PR_TRUE, aes_key_size, ++ FIPS_AES_BLOCK_SIZE); ++ ++ if (aes_context == NULL) { ++ PORT_SetError(SEC_ERROR_NO_MEMORY); ++ return (SECFailure); ++ } ++ ++ aes_status = AES_Encrypt(aes_context, aes_computed_ciphertext, ++ &aes_bytes_encrypted, FIPS_AES_ENCRYPT_LENGTH * 2, ++ aes_known_plaintext, ++ FIPS_AES_DECRYPT_LENGTH); ++ ++ AES_DestroyContext(aes_context, PR_TRUE); ++ ++ if ((aes_status != SECSuccess) || ++ (aes_bytes_encrypted != FIPS_AES_ENCRYPT_LENGTH * 2) || ++ (PORT_Memcmp(aes_computed_ciphertext, aes_gcm_known_ciphertext, ++ FIPS_AES_ENCRYPT_LENGTH * 2) != 0)) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return (SECFailure); ++ } ++ ++ /******************************************************/ ++ /* AES-GCM Single-Round Known Answer Decryption Test. */ ++ /******************************************************/ ++ ++ aes_context = AES_CreateContext(aes_known_key, ++ (PRUint8 *)&gcmParams, ++ NSS_AES_GCM, PR_FALSE, aes_key_size, ++ FIPS_AES_BLOCK_SIZE); ++ ++ if (aes_context == NULL) { ++ PORT_SetError(SEC_ERROR_NO_MEMORY); ++ return (SECFailure); ++ } ++ ++ aes_status = AES_Decrypt(aes_context, aes_computed_plaintext, ++ &aes_bytes_decrypted, FIPS_AES_DECRYPT_LENGTH * 2, ++ aes_gcm_known_ciphertext, ++ FIPS_AES_ENCRYPT_LENGTH * 2); ++ ++ AES_DestroyContext(aes_context, PR_TRUE); ++ ++ if ((aes_status != SECSuccess) || ++ (aes_bytes_decrypted != FIPS_AES_DECRYPT_LENGTH) || ++ (PORT_Memcmp(aes_computed_plaintext, aes_known_plaintext, ++ FIPS_AES_DECRYPT_LENGTH) != 0)) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return (SECFailure); ++ } ++ + return (SECSuccess); + } + + /* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */ + static const PRUint8 known_hash_message[] = { + "The test message for the MD2, MD5, and SHA-1 hashing algorithms." + }; + +@@ -1089,17 +1181,17 @@ freebl_fips_ECDSA_Test(ECParams *ecparam + 0x7b, 0x5a, 0x3b, 0x76, 0x4e, 0x7b, 0x7c, 0xbc, + 0xf2, 0x76, 0x1c, 0x1c, 0x7f, 0xc5, 0x53, 0x2f + }; + + static const PRUint8 msg[] = { + "Firefox and ThunderBird are awesome!" + }; + +- unsigned char sha1[SHA1_LENGTH]; /* SHA-1 hash (160 bits) */ ++ unsigned char sha256[SHA256_LENGTH]; /* SHA-256 hash (256 bits) */ + unsigned char sig[2 * MAX_ECKEY_LEN]; + SECItem signature, digest; + ECPrivateKey *ecdsa_private_key = NULL; + ECPublicKey ecdsa_public_key; + SECStatus ecdsaStatus = SECSuccess; + + /* Generates a new EC key pair. The private key is a supplied + * random value (in seed) and the public key is the result of +@@ -1131,23 +1223,23 @@ freebl_fips_ECDSA_Test(ECParams *ecparam + if (ecdsaStatus != SECSuccess) { + goto loser; + } + + /***************************************************/ + /* ECDSA Single-Round Known Answer Signature Test. */ + /***************************************************/ + +- ecdsaStatus = SHA1_HashBuf(sha1, msg, sizeof msg); ++ ecdsaStatus = SHA256_HashBuf(sha256, msg, sizeof msg); + if (ecdsaStatus != SECSuccess) { + goto loser; + } + digest.type = siBuffer; +- digest.data = sha1; +- digest.len = SHA1_LENGTH; ++ digest.data = sha256; ++ digest.len = SHA256_LENGTH; + + memset(sig, 0, sizeof sig); + signature.type = siBuffer; + signature.data = sig; + signature.len = sizeof sig; + + ecdsaStatus = ECDSA_SignDigestWithSeed(ecdsa_private_key, &signature, + &digest, ecdsa_Known_Seed, sizeof ecdsa_Known_Seed); +@@ -1176,20 +1268,93 @@ loser: + if (ecdsaStatus != SECSuccess) { + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return (SECFailure); + } + return (SECSuccess); + } + + static SECStatus +-freebl_fips_ECDSA_PowerUpSelfTest() ++freebl_fips_ECDH_Test(ECParams *ecparams) + { + +- /* ECDSA Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */ ++ /* ECDH Known result (reused old CAVS vector) */ ++ static const PRUint8 ecdh_known_pub_key_1[] = { ++ EC_POINT_FORM_UNCOMPRESSED, ++ /* pubX */ ++ 0x16, 0x81, 0x32, 0x86, 0xc8, 0xe4, 0x3a, 0x1f, ++ 0x5d, 0xe3, 0x06, 0x22, 0x8b, 0x99, 0x14, 0x25, ++ 0xf7, 0x9c, 0x5b, 0x1e, 0x96, 0x84, 0x85, 0x3b, ++ 0x17, 0xfe, 0xf3, 0x1c, 0x0e, 0xed, 0xc4, 0xce, ++ /* pubY */ ++ 0x7a, 0x44, 0xfe, 0xbd, 0x91, 0x71, 0x7d, 0x73, ++ 0xd9, 0x45, 0xea, 0xae, 0x66, 0x78, 0xfa, 0x6e, ++ 0x46, 0xcd, 0xfa, 0x95, 0x15, 0x47, 0x62, 0x5d, ++ 0xbb, 0x1b, 0x9f, 0xe6, 0x39, 0xfc, 0xfd, 0x47 ++ }; ++ static const PRUint8 ecdh_known_priv_key_2[] = { ++ 0xb4, 0x2a, 0xe3, 0x69, 0x19, 0xec, 0xf0, 0x42, ++ 0x6d, 0x45, 0x8c, 0x94, 0x4a, 0x26, 0xa7, 0x5c, ++ 0xea, 0x9d, 0xd9, 0x0f, 0x59, 0xe0, 0x1a, 0x9d, ++ 0x7c, 0xb7, 0x1c, 0x04, 0x53, 0xb8, 0x98, 0x5a ++ }; ++ static const PRUint8 ecdh_known_hash_result[] = { ++ 0x16, 0xf3, 0x85, 0xa2, 0x41, 0xf3, 0x7f, 0xc4, ++ 0x0b, 0x56, 0x47, 0xee, 0xa7, 0x74, 0xb9, 0xdb, ++ 0xe1, 0xfa, 0x22, 0xe9, 0x04, 0xf1, 0xb6, 0x12, ++ 0x4b, 0x44, 0x8a, 0xbb, 0xbc, 0x08, 0x2b, 0xa7, ++ }; ++ ++ SECItem ecdh_priv_2, ecdh_pub_1; ++ SECItem ZZ = { 0, 0, 0 }; ++ SECStatus ecdhStatus = SECSuccess; ++ PRUint8 computed_hash_result[HASH_LENGTH_MAX]; ++ ++ ecdh_priv_2.data = (PRUint8 *)ecdh_known_priv_key_2; ++ ecdh_priv_2.len = sizeof(ecdh_known_priv_key_2); ++ ecdh_pub_1.data = (PRUint8 *)ecdh_known_pub_key_1; ++ ecdh_pub_1.len = sizeof(ecdh_known_pub_key_1); ++ ++ /* Generates a new EC key pair. The private key is a supplied ++ * random value (in seed) and the public key is the result of ++ * performing a scalar point multiplication of that value with ++ * the curve's base point. ++ */ ++ ecdhStatus = ECDH_Derive(&ecdh_pub_1, ecparams, &ecdh_priv_2, PR_FALSE, &ZZ); ++ if (ecdhStatus != SECSuccess) { ++ goto loser; ++ } ++ ecdhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len); ++ if (ecdhStatus != SECSuccess) { ++ goto loser; ++ } ++ ++ if (PORT_Memcmp(computed_hash_result, ecdh_known_hash_result, ++ sizeof(ecdh_known_hash_result)) != 0) { ++ ecdhStatus = SECFailure; ++ goto loser; ++ } ++ ++loser: ++ if (ZZ.data) { ++ SECITEM_FreeItem(&ZZ, PR_FALSE); ++ } ++ ++ if (ecdhStatus != SECSuccess) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return (SECFailure); ++ } ++ return (SECSuccess); ++} ++ ++static SECStatus ++freebl_fips_EC_PowerUpSelfTest() ++{ ++ ++ /* EC Known curve nistp256 == ECCCurve_X9_62_PRIME_256V1 params */ + static const unsigned char p256_prime[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + static const unsigned char p256_a[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +@@ -1212,17 +1377,17 @@ freebl_fips_ECDSA_PowerUpSelfTest() + static const unsigned char p256_order[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, + 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 + }; + static const unsigned char p256_encoding[] = { + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 + }; +- static const ECParams ecdsa_known_P256_Params = { ++ static const ECParams ec_known_P256_Params = { + NULL, ec_params_named, /* arena, type */ + /* fieldID */ + { 256, ec_field_GFp, /* size and type */ + { { siBuffer, (unsigned char *)p256_prime, sizeof(p256_prime) } }, /* u.prime */ + 0, + 0, + 0 }, + /* curve */ +@@ -1245,34 +1410,39 @@ freebl_fips_ECDSA_PowerUpSelfTest() + { siBuffer, (unsigned char *)(p256_encoding) + 2, sizeof(p256_encoding) - 2 }, + }; + + static const PRUint8 ecdsa_known_P256_signature[] = { + 0x07, 0xb1, 0xcb, 0x57, 0x20, 0xa7, 0x10, 0xd6, + 0x9d, 0x37, 0x4b, 0x1c, 0xdc, 0x35, 0x90, 0xff, + 0x1a, 0x2d, 0x98, 0x95, 0x1b, 0x2f, 0xeb, 0x7f, + 0xbb, 0x81, 0xca, 0xc0, 0x69, 0x75, 0xea, 0xc5, +- 0x59, 0x6a, 0x62, 0x49, 0x3d, 0x50, 0xc9, 0xe1, +- 0x27, 0x3b, 0xff, 0x9b, 0x13, 0x66, 0x67, 0xdd, +- 0x7d, 0xd1, 0x0d, 0x2d, 0x7c, 0x44, 0x04, 0x1b, +- 0x16, 0x21, 0x12, 0xc5, 0xcb, 0xbd, 0x9e, 0x75 ++ 0xa7, 0xd2, 0x20, 0xdd, 0x45, 0xf9, 0x2b, 0xdd, ++ 0xda, 0x98, 0x99, 0x5b, 0x1c, 0x02, 0x3a, 0x27, ++ 0x8b, 0x7d, 0xb6, 0xed, 0x0e, 0xe0, 0xa7, 0xac, ++ 0xaa, 0x36, 0x2c, 0xfa, 0x1a, 0xdf, 0x0d, 0xe1, + }; + + ECParams ecparams; + + SECStatus rv; + + /* ECDSA GF(p) prime field curve test */ +- ecparams = ecdsa_known_P256_Params; ++ ecparams = ec_known_P256_Params; + rv = freebl_fips_ECDSA_Test(&ecparams, + ecdsa_known_P256_signature, + sizeof ecdsa_known_P256_signature); + if (rv != SECSuccess) { + return (SECFailure); + } ++ /* ECDH GF(p) prime field curve test */ ++ rv = freebl_fips_ECDH_Test(&ecparams); ++ if (rv != SECSuccess) { ++ return (SECFailure); ++ } + + return (SECSuccess); + } + + static SECStatus + freebl_fips_DSA_PowerUpSelfTest(void) + { + /* DSA Known P (1024-bits), Q (160-bits), and G (1024-bits) Values. */ +@@ -1413,16 +1583,148 @@ freebl_fips_DSA_PowerUpSelfTest(void) + PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); + return SECFailure; + } + + return (SECSuccess); + } + + static SECStatus ++freebl_fips_DH_PowerUpSelfTest(void) ++{ ++ /* DH Known P (2048-bits) */ ++ static const PRUint8 dh_known_P[] = { ++ 0xc2, 0x79, 0xbb, 0x76, 0x32, 0x0d, 0x43, 0xfd, ++ 0x1b, 0x8c, 0xa2, 0x3c, 0x00, 0xdd, 0x6d, 0xef, ++ 0xf8, 0x1a, 0xd9, 0xc1, 0xa2, 0xf5, 0x73, 0x2b, ++ 0xdb, 0x1a, 0x3e, 0x84, 0x90, 0xeb, 0xe7, 0x8e, ++ 0x5f, 0x5c, 0x6b, 0xb6, 0x61, 0x89, 0xd1, 0x03, ++ 0xb0, 0x5f, 0x91, 0xe4, 0xd2, 0x82, 0x90, 0xfc, ++ 0x3c, 0x49, 0x69, 0x59, 0xc1, 0x51, 0x6a, 0x85, ++ 0x71, 0xe7, 0x5d, 0x72, 0x5a, 0x45, 0xad, 0x01, ++ 0x6f, 0x82, 0xae, 0xec, 0x91, 0x08, 0x2e, 0x7c, ++ 0x64, 0x93, 0x46, 0x1c, 0x68, 0xef, 0xc2, 0x03, ++ 0x28, 0x1d, 0x75, 0x3a, 0xeb, 0x9c, 0x46, 0xf0, ++ 0xc9, 0xdb, 0x99, 0x95, 0x13, 0x66, 0x4d, 0xd5, ++ 0x1a, 0x78, 0x92, 0x51, 0x89, 0x72, 0x28, 0x7f, ++ 0x20, 0x70, 0x41, 0x49, 0xa2, 0x86, 0xe9, 0xf9, ++ 0x78, 0x5f, 0x8d, 0x2e, 0x5d, 0xfa, 0xdb, 0x57, ++ 0xd4, 0x71, 0xdf, 0x66, 0xe3, 0x9e, 0x88, 0x70, ++ 0xa4, 0x21, 0x44, 0x6a, 0xc7, 0xae, 0x30, 0x2c, ++ 0x9c, 0x1f, 0x91, 0x57, 0xc8, 0x24, 0x34, 0x2d, ++ 0x7a, 0x4a, 0x43, 0xc2, 0x5f, 0xab, 0x64, 0x2e, ++ 0xaa, 0x28, 0x32, 0x95, 0x42, 0x7b, 0xa0, 0xcc, ++ 0xdf, 0xfd, 0x22, 0xc8, 0x56, 0x84, 0xc1, 0x62, ++ 0x15, 0xb2, 0x77, 0x86, 0x81, 0xfc, 0xa5, 0x12, ++ 0x3c, 0xca, 0x28, 0x17, 0x8f, 0x03, 0x16, 0x6e, ++ 0xb8, 0x24, 0xfa, 0x1b, 0x15, 0x02, 0xfd, 0x8b, ++ 0xb6, 0x0a, 0x1a, 0xf7, 0x47, 0x41, 0xc5, 0x2b, ++ 0x37, 0x3e, 0xa1, 0xbf, 0x68, 0xda, 0x1c, 0x55, ++ 0x44, 0xc3, 0xee, 0xa1, 0x63, 0x07, 0x11, 0x3b, ++ 0x5f, 0x00, 0x84, 0xb4, 0xc4, 0xe4, 0xa7, 0x97, ++ 0x29, 0xf8, 0xce, 0xab, 0xfc, 0x27, 0x3e, 0x34, ++ 0xe4, 0xc7, 0x81, 0x52, 0x32, 0x0e, 0x27, 0x3c, ++ 0xa6, 0x70, 0x3f, 0x4a, 0x54, 0xda, 0xdd, 0x60, ++ 0x26, 0xb3, 0x6e, 0x45, 0x26, 0x19, 0x41, 0x6f ++ }; ++ ++ static const PRUint8 dh_known_Y_1[] = { ++ 0xb4, 0xc7, 0x85, 0xba, 0xa6, 0x98, 0xb3, 0x77, ++ 0x41, 0x2b, 0xd9, 0x9a, 0x72, 0x90, 0xa4, 0xac, ++ 0xc4, 0xf7, 0xc2, 0x23, 0x9a, 0x68, 0xe2, 0x7d, ++ 0x3a, 0x54, 0x45, 0x91, 0xc1, 0xd7, 0x8a, 0x17, ++ 0x54, 0xd3, 0x37, 0xaa, 0x0c, 0xcd, 0x0b, 0xe2, ++ 0xf2, 0x34, 0x0f, 0x17, 0xa8, 0x07, 0x88, 0xaf, ++ 0xed, 0xc1, 0x02, 0xd4, 0xdb, 0xdc, 0x0f, 0x22, ++ 0x51, 0x23, 0x40, 0xb9, 0x65, 0x6d, 0x39, 0xf4, ++ 0xe1, 0x8b, 0x57, 0x7d, 0xb6, 0xd3, 0xf2, 0x6b, ++ 0x02, 0xa9, 0x36, 0xf0, 0x0d, 0xe3, 0xdb, 0x9a, ++ 0xbf, 0x20, 0x00, 0x4d, 0xec, 0x6f, 0x68, 0x95, ++ 0xee, 0x59, 0x4e, 0x3c, 0xb6, 0xda, 0x7b, 0x19, ++ 0x08, 0x9a, 0xef, 0x61, 0x43, 0xf5, 0xfb, 0x25, ++ 0x70, 0x19, 0xc1, 0x5f, 0x0e, 0x0f, 0x6a, 0x63, ++ 0x44, 0xe9, 0xcf, 0x33, 0xce, 0x13, 0x4f, 0x34, ++ 0x3c, 0x94, 0x40, 0x8d, 0xf2, 0x65, 0x42, 0xef, ++ 0x70, 0x54, 0xdd, 0x5f, 0xc1, 0xd7, 0x0b, 0xa6, ++ 0x06, 0xd5, 0xa6, 0x47, 0xae, 0x2c, 0x1f, 0x5a, ++ 0xa6, 0xb3, 0xc1, 0x38, 0x3a, 0x3b, 0x60, 0x94, ++ 0xa2, 0x95, 0xab, 0xb2, 0x86, 0x82, 0xc5, 0x3b, ++ 0xb8, 0x6f, 0x3e, 0x55, 0x86, 0x84, 0xe0, 0x00, ++ 0xe5, 0xef, 0xca, 0x5c, 0xec, 0x7e, 0x38, 0x0f, ++ 0x82, 0xa2, 0xb1, 0xee, 0x48, 0x1b, 0x32, 0xbb, ++ 0x5a, 0x33, 0xa5, 0x01, 0xba, 0xca, 0xa6, 0x64, ++ 0x61, 0xb6, 0xe5, 0x5c, 0x0e, 0x5f, 0x2c, 0x66, ++ 0x0d, 0x01, 0x6a, 0x20, 0x04, 0x70, 0x68, 0x82, ++ 0x93, 0x29, 0x15, 0x3b, 0x7a, 0x06, 0xb2, 0x92, ++ 0x61, 0xcd, 0x7e, 0xa4, 0xc1, 0x15, 0x64, 0x3b, ++ 0x3c, 0x51, 0x10, 0x4c, 0x87, 0xa6, 0xaf, 0x07, ++ 0xce, 0x46, 0x82, 0x75, 0xf3, 0x90, 0xf3, 0x21, ++ 0x55, 0x74, 0xc2, 0xe4, 0x96, 0x7d, 0xc3, 0xe6, ++ 0x33, 0xa5, 0xc6, 0x51, 0xef, 0xec, 0x90, 0x08 ++ }; ++ ++ static const PRUint8 dh_known_x_2[] = { ++ 0x9e, 0x9b, 0xc3, 0x25, 0x53, 0xf9, 0xfc, 0x92, ++ 0xb6, 0xae, 0x54, 0x8e, 0x23, 0x4c, 0x94, 0xba, ++ 0x41, 0xe6, 0x29, 0x33, 0xb9, 0xdb, 0xff, 0x6d, ++ 0xa8, 0xb8, 0x48, 0x49, 0x66, 0x11, 0xa6, 0x13 ++ }; ++ ++ static const PRUint8 dh_known_hash_result[] = { ++ 0x93, 0xa2, 0x89, 0x1c, 0x8a, 0xc3, 0x70, 0xbf, ++ 0xa7, 0xdf, 0xb6, 0xd7, 0x82, 0xfb, 0x87, 0x81, ++ 0x09, 0x47, 0xf3, 0x9f, 0x5a, 0xbf, 0x4f, 0x3f, ++ 0x8e, 0x5e, 0x06, 0xca, 0x30, 0xa7, 0xaf, 0x10 ++ }; ++ ++ /* DH variables. */ ++ SECStatus dhStatus; ++ SECItem dh_prime; ++ SECItem dh_pub_key_1; ++ SECItem dh_priv_key_2; ++ SECItem ZZ = { 0, 0, 0 }; ++ PRUint8 computed_hash_result[HASH_LENGTH_MAX]; ++ ++ dh_prime.data = (PRUint8 *)dh_known_P; ++ dh_prime.len = sizeof(dh_known_P); ++ dh_pub_key_1.data = (PRUint8 *)dh_known_Y_1; ++ dh_pub_key_1.len = sizeof(dh_known_Y_1); ++ dh_priv_key_2.data = (PRUint8 *)dh_known_x_2; ++ dh_priv_key_2.len = sizeof(dh_known_x_2); ++ ++ /* execute the derive */ ++ dhStatus = DH_Derive(&dh_pub_key_1, &dh_prime, &dh_priv_key_2, &ZZ, dh_prime.len); ++ if (dhStatus != SECSuccess) { ++ goto loser; ++ } ++ ++ dhStatus = SHA256_HashBuf(computed_hash_result, ZZ.data, ZZ.len); ++ if (dhStatus != SECSuccess) { ++ goto loser; ++ } ++ ++ if (PORT_Memcmp(computed_hash_result, dh_known_hash_result, ++ sizeof(dh_known_hash_result)) != 0) { ++ dhStatus = SECFailure; ++ goto loser; ++ } ++ ++loser: ++ if (ZZ.data) { ++ SECITEM_FreeItem(&ZZ, PR_FALSE); ++ } ++ ++ if (dhStatus != SECSuccess) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); ++ return (SECFailure); ++ } ++ return (SECSuccess); ++} ++ ++static SECStatus + freebl_fips_RNG_PowerUpSelfTest(void) + { + static const PRUint8 Q[] = { + 0x85, 0x89, 0x9c, 0x77, 0xa3, 0x79, 0xff, 0x1a, + 0x86, 0x6f, 0x2f, 0x3e, 0x2e, 0xf9, 0x8c, 0x9c, + 0x9d, 0xef, 0xeb, 0xed + }; + static const PRUint8 GENX[] = { +@@ -1536,31 +1838,37 @@ freebl_fipsPowerUpSelfTest(unsigned int + + /* HMAC SHA-X Power-Up SelfTest(s). */ + rv = freebl_fips_HMAC_PowerUpSelfTest(); + + if (rv != SECSuccess) + return rv; + + /* NOTE: RSA can only be tested in full freebl. It requires access to +- * the locking primitives */ ++ * the locking primitives */ + /* RSA Power-Up SelfTest(s). */ + rv = freebl_fips_RSA_PowerUpSelfTest(); + + if (rv != SECSuccess) + return rv; + + /* DSA Power-Up SelfTest(s). */ + rv = freebl_fips_DSA_PowerUpSelfTest(); + + if (rv != SECSuccess) + return rv; + +- /* ECDSA Power-Up SelfTest(s). */ +- rv = freebl_fips_ECDSA_PowerUpSelfTest(); ++ /* DH Power-Up SelfTest(s). */ ++ rv = freebl_fips_DH_PowerUpSelfTest(); ++ ++ if (rv != SECSuccess) ++ return rv; ++ ++ /* EC Power-Up SelfTest(s). */ ++ rv = freebl_fips_EC_PowerUpSelfTest(); + + if (rv != SECSuccess) + return rv; + } + /* Passed Power-Up SelfTest(s). */ + return (SECSuccess); + } + +diff --git a/lib/freebl/intel-gcm-wrap.c b/lib/freebl/intel-gcm-wrap.c +--- a/lib/freebl/intel-gcm-wrap.c ++++ b/lib/freebl/intel-gcm-wrap.c +@@ -138,16 +138,17 @@ intel_AES_GCM_CreateContext(void *contex + loser: + PORT_Free(gcm); + return NULL; + } + + void + intel_AES_GCM_DestroyContext(intel_AES_GCMContext *gcm, PRBool freeit) + { ++ PORT_Memset(gcm, 0, sizeof(intel_AES_GCMContext)); + if (freeit) { + PORT_Free(gcm); + } + } + + SECStatus + intel_AES_GCM_EncryptUpdate(intel_AES_GCMContext *gcm, + unsigned char *outbuf, +diff --git a/lib/freebl/pqg.c b/lib/freebl/pqg.c +--- a/lib/freebl/pqg.c ++++ b/lib/freebl/pqg.c +@@ -486,21 +486,21 @@ cleanup: + ** Perform steps from FIPS 186-3, Appendix A.1.2.1 and Appendix C.6 + ** + ** This generates a provable prime from two smaller prime. The resulting + ** prime p will have q0 as a multiple of p-1. q0 can be 1. + ** + ** This implments steps 4 thorough 22 of FIPS 186-3 A.1.2.1 and + ** steps 16 through 34 of FIPS 186-2 C.6 + */ +-#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX * PR_BITS_PER_BYTE) + static SECStatus + makePrimefromPrimesShaweTaylor( + HASH_HashType hashtype, /* selected Hashing algorithm */ + unsigned int length, /* input. Length of prime in bits. */ ++ unsigned int seedlen, /* input seed length in bits */ + mp_int *c0, /* seed prime */ + mp_int *q, /* sub prime, can be 1 */ + mp_int *prime, /* output. */ + SECItem *prime_seed, /* input/output. */ + unsigned int *prime_gen_counter) /* input/output. */ + { + mp_int c; + mp_int c0_2; +@@ -552,33 +552,32 @@ makePrimefromPrimesShaweTaylor( + */ + + /* Step 4/16 iterations = ceiling(length/outlen)-1 */ + iterations = (length + outlen - 1) / outlen; /* NOTE: iterations +1 */ + /* Step 5/17 old_counter = prime_gen_counter */ + old_counter = *prime_gen_counter; + /* + ** Comment: Generate a pseudorandom integer x in the interval +- ** [2**(lenght-1), 2**length]. ++ ** [2**(length-1), 2**length]. + ** + ** Step 6/18 x = 0 + */ + PORT_Memset(x, 0, sizeof(x)); + /* + ** Step 7/19 for i = 0 to iterations do + ** x = x + (HASH(prime_seed + i) * 2^(i*outlen)) + */ + for (i = 0; i < iterations; i++) { + /* is bigger than prime_seed should get to */ + CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i, +- MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen])); ++ seedlen, &x[(iterations - i - 1) * hashlen])); + } + /* Step 8/20 prime_seed = prime_seed + iterations + 1 */ +- CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS, +- prime_seed)); ++ CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed)); + /* + ** Step 9/21 x = 2 ** (length-1) + x mod 2 ** (length-1) + ** + ** This step mathematically sets the high bit and clears out + ** all the other bits higher than length. 'x' is stored + ** in the x array, MSB first. The above formula gives us an 'x' + ** which is length bytes long and has the high bit set. We also know + ** that length <= iterations*outlen since +@@ -590,17 +589,17 @@ makePrimefromPrimesShaweTaylor( + * multiple of 8,*/ + bit = 1 << ((length - 1) & 0x7); /* select the proper bit in the byte */ + /* we need to zero out the rest of the bits in the byte above */ + mask = (bit - 1); + /* now we set it */ + x[offset] = (mask & x[offset]) | bit; + /* + ** Comment: Generate a candidate prime c in the interval +- ** [2**(lenght-1), 2**length]. ++ ** [2**(length-1), 2**length]. + ** + ** Step 10 t = ceiling(x/(2q(p0))) + ** Step 22 t = ceiling(x/(2(c0))) + */ + CHECK_MPI_OK(mp_read_unsigned_octets(&t, &x[offset], + hashlen * iterations - offset)); /* t = x */ + CHECK_MPI_OK(mp_mul(c0, q, &c0_2)); /* c0_2 is now c0*q */ + CHECK_MPI_OK(mp_add(&c0_2, &c0_2, &c0_2)); /* c0_2 is now 2*q*c0 */ +@@ -619,17 +618,17 @@ makePrimefromPrimesShaweTaylor( + step_23: + CHECK_MPI_OK(mp_mul(&t, &c0_2, &c)); /* c = t*2qc0 */ + CHECK_MPI_OK(mp_add_d(&c, (mp_digit)1, &c)); /* c= 2tqc0 + 1*/ + if (mpl_significant_bits(&c) > length) { /* if c > 2**length */ + CHECK_MPI_OK(mp_sub_d(&c0_2, (mp_digit)1, &t)); /* t = 2qc0-1 */ + /* t = 2**(length-1) + 2qc0 -1 */ + CHECK_MPI_OK(mp_add(&two_length_minus_1, &t, &t)); + /* t = floor((2**(length-1)+2qc0 -1)/2qco) +- * = ceil(2**(lenght-2)/2qc0) */ ++ * = ceil(2**(length-2)/2qc0) */ + CHECK_MPI_OK(mp_div(&t, &c0_2, &t, NULL)); + CHECK_MPI_OK(mp_mul(&t, &c0_2, &c)); + CHECK_MPI_OK(mp_add_d(&c, (mp_digit)1, &c)); /* c= 2tqc0 + 1*/ + } + /* Step 13/25 prime_gen_counter = prime_gen_counter + 1*/ + (*prime_gen_counter)++; + /* + ** Comment: Test the candidate prime c for primality; first pick an +@@ -640,23 +639,21 @@ step_23: + PORT_Memset(x, 0, sizeof(x)); /* use x for a */ + /* + ** Step 15/27 for i = 0 to iterations do + ** a = a + (HASH(prime_seed + i) * 2^(i*outlen)) + ** + ** NOTE: we reuse the x array for 'a' initially. + */ + for (i = 0; i < iterations; i++) { +- /* MAX_ST_SEED_BITS is bigger than prime_seed should get to */ + CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, i, +- MAX_ST_SEED_BITS, &x[(iterations - i - 1) * hashlen])); ++ seedlen, &x[(iterations - i - 1) * hashlen])); + } + /* Step 16/28 prime_seed = prime_seed + iterations + 1 */ +- CHECK_SEC_OK(addToSeed(prime_seed, iterations, MAX_ST_SEED_BITS, +- prime_seed)); ++ CHECK_SEC_OK(addToSeed(prime_seed, iterations, seedlen, prime_seed)); + /* Step 17/29 a = 2 + (a mod (c-3)). */ + CHECK_MPI_OK(mp_read_unsigned_octets(&a, x, iterations * hashlen)); + CHECK_MPI_OK(mp_sub_d(&c, (mp_digit)3, &z)); /* z = c -3 */ + CHECK_MPI_OK(mp_mod(&a, &z, &a)); /* a = a mod c -3 */ + CHECK_MPI_OK(mp_add_d(&a, (mp_digit)2, &a)); /* a = 2 + a mod c -3 */ + /* + ** Step 18 z = a**(2tq) mod p. + ** Step 30 z = a**(2t) mod c. +@@ -737,16 +734,17 @@ makePrimefromSeedShaweTaylor( + { + mp_int c; + mp_int c0; + mp_int one; + SECStatus rv = SECFailure; + int hashlen = HASH_ResultLen(hashtype); + int outlen = hashlen * PR_BITS_PER_BYTE; + int offset; ++ int seedlen = input_seed->len * 8; /*seedlen is in bits */ + unsigned char bit, mask; + unsigned char x[HASH_LENGTH_MAX * 2]; + mp_digit dummy; + mp_err err = MP_OKAY; + int i; + + MP_DIGITS(&c) = 0; + MP_DIGITS(&c0) = 0; +@@ -770,30 +768,29 @@ makePrimefromSeedShaweTaylor( + */ + rv = makePrimefromSeedShaweTaylor(hashtype, (length + 1) / 2 + 1, + input_seed, &c0, prime_seed, prime_gen_counter); + /* Step 15 if FAILURE is returned, return (FAILURE, 0, 0, 0). */ + if (rv != SECSuccess) { + goto cleanup; + } + /* Steps 16-34 */ +- rv = makePrimefromPrimesShaweTaylor(hashtype, length, &c0, &one, ++ rv = makePrimefromPrimesShaweTaylor(hashtype, length, seedlen, &c0, &one, + prime, prime_seed, prime_gen_counter); + goto cleanup; /* we're done, one way or the other */ + } + /* Step 3 prime_seed = input_seed */ + CHECK_SEC_OK(SECITEM_CopyItem(NULL, prime_seed, input_seed)); + /* Step 4 prime_gen_count = 0 */ + *prime_gen_counter = 0; + + step_5: + /* Step 5 c = Hash(prime_seed) xor Hash(prime_seed+1). */ + CHECK_SEC_OK(HASH_HashBuf(hashtype, x, prime_seed->data, prime_seed->len)); +- CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1, +- MAX_ST_SEED_BITS, &x[hashlen])); ++ CHECK_SEC_OK(addToSeedThenHash(hashtype, prime_seed, 1, seedlen, &x[hashlen])); + for (i = 0; i < hashlen; i++) { + x[i] = x[i] ^ x[i + hashlen]; + } + /* Step 6 c = 2**length-1 + c mod 2**length-1 */ + /* This step mathematically sets the high bit and clears out + ** all the other bits higher than length. Right now c is stored + ** in the x array, MSB first. The above formula gives us a c which + ** is length bytes long and has the high bit set. We also know that +@@ -812,17 +809,17 @@ step_5: + /* Step 7 c = c*floor(c/2) + 1 */ + /* set the low bit. much easier to find (the end of the array) */ + x[hashlen - 1] |= 1; + /* now that we've set our bits, we can create our candidate "c" */ + CHECK_MPI_OK(mp_read_unsigned_octets(&c, &x[offset], hashlen - offset)); + /* Step 8 prime_gen_counter = prime_gen_counter + 1 */ + (*prime_gen_counter)++; + /* Step 9 prime_seed = prime_seed + 2 */ +- CHECK_SEC_OK(addToSeed(prime_seed, 2, MAX_ST_SEED_BITS, prime_seed)); ++ CHECK_SEC_OK(addToSeed(prime_seed, 2, seedlen, prime_seed)); + /* Step 10 Perform deterministic primality test on c. For example, since + ** c is small, it's primality can be tested by trial division, See + ** See Appendic C.7. + ** + ** We in fact test with trial division. mpi has a built int trial divider + ** that divides all divisors up to 2^16. + */ + if (prime_tab[prime_tab_size - 1] < 0xFFF1) { +@@ -885,17 +882,18 @@ findQfromSeed( + unsigned int L, /* input. Length of p in bits. */ + unsigned int N, /* input. Length of q in bits. */ + unsigned int g, /* input. Length of seed in bits. */ + const SECItem *seed, /* input. */ + mp_int *Q, /* input. */ + mp_int *Q_, /* output. */ + unsigned int *qseed_len, /* output */ + HASH_HashType *hashtypePtr, /* output. Hash uses */ +- pqgGenType *typePtr) /* output. Generation Type used */ ++ pqgGenType *typePtr, /* output. Generation Type used */ ++ unsigned int *qgen_counter) /* output. q_counter */ + { + HASH_HashType hashtype; + SECItem firstseed = { 0, 0, 0 }; + SECItem qseed = { 0, 0, 0 }; + SECStatus rv; + + *qseed_len = 0; /* only set if FIPS186_3_ST_TYPE */ + +@@ -959,16 +957,17 @@ findQfromSeed( + * accident, someone has been tweeking with the seeds, just + * fail a this point. */ + SECITEM_FreeItem(&qseed, PR_FALSE); + return SECFailure; + } + *qseed_len = qseed.len; + *hashtypePtr = hashtype; + *typePtr = FIPS186_3_ST_TYPE; ++ *qgen_counter = count; + SECITEM_FreeItem(&qseed, PR_FALSE); + return SECSuccess; + } + SECITEM_FreeItem(&qseed, PR_FALSE); + } + /* no hash algorithms found which match seed to Q, fail */ + return SECFailure; + } +@@ -1383,29 +1382,33 @@ step_5: + CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, N, &firstseed, &Q, + &qseed, &qgen_counter)); + /* Step 3. Use floor(L/2+1) and qseed to generate random prime p0 + * using Appendix C.6 */ + pgen_counter = 0; + CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1, + &qseed, &p0, &pseed, &pgen_counter)); + /* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */ +- CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, ++ CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, seedBytes * 8, + &p0, &Q, &P, &pseed, &pgen_counter)); + + /* combine all the seeds */ +- seed->len = firstseed.len + qseed.len + pseed.len; ++ if ((qseed.len > firstseed.len) || (pseed.len > firstseed.len)) { ++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); /* shouldn't happen */ ++ goto cleanup; ++ } ++ seed->len = firstseed.len * 3; /*handle leading zeros in pseed and qseed*/ + seed->data = PORT_ArenaZAlloc(verify->arena, seed->len); + if (seed->data == NULL) { + goto cleanup; + } + PORT_Memcpy(seed->data, firstseed.data, firstseed.len); +- PORT_Memcpy(seed->data + firstseed.len, pseed.data, pseed.len); +- PORT_Memcpy(seed->data + firstseed.len + pseed.len, qseed.data, qseed.len); +- counter = 0; /* (qgen_counter << 16) | pgen_counter; */ ++ PORT_Memcpy(seed->data + 2 * firstseed.len - pseed.len, pseed.data, pseed.len); ++ PORT_Memcpy(seed->data + 3 * firstseed.len - qseed.len, qseed.data, qseed.len); ++ counter = (qgen_counter << 16) | pgen_counter; + + /* we've generated both P and Q now, skip to generating G */ + goto generate_G; + } + /* ****************************************************************** + ** Step 8. (Step 4 in 186-1) + ** "Use a robust primality testing algorithm to test whether q is prime." + ** +@@ -1615,16 +1618,17 @@ PQG_VerifyParams(const PQGParams *params + { + SECStatus rv = SECSuccess; + unsigned int g, n, L, N, offset, outlen; + mp_int p0, P, Q, G, P_, Q_, G_, r, h; + mp_err err = MP_OKAY; + int j; + unsigned int counter_max = 0; /* handle legacy L < 1024 */ + unsigned int qseed_len; ++ unsigned int qgen_counter_ = 0; + SECItem pseed_ = { 0, 0, 0 }; + HASH_HashType hashtype; + pqgGenType type; + + #define CHECKPARAM(cond) \ + if (!(cond)) { \ + *result = SECFailure; \ + goto cleanup; \ +@@ -1694,77 +1698,104 @@ PQG_VerifyParams(const PQGParams *params + CHECKPARAM(mp_cmp_d(&r, 1) == 0); + /* 5. Q is prime */ + CHECKPARAM(mpp_pprime(&Q, prime_testcount_q(L, N)) == MP_YES); + /* 6. P is prime */ + CHECKPARAM(mpp_pprime(&P, prime_testcount_p(L, N)) == MP_YES); + /* Steps 7-12 are done only if the optional PQGVerify is supplied. */ + /* continue processing P */ + /* 7. counter < 4*L */ +- CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max)); + /* 8. g >= N and g < 2*L (g is length of seed in bits) */ +- g = vfy->seed.len * 8; +- CHECKPARAM(g >= N && g < counter_max / 2); ++ /* step 7 and 8 are delayed until we determine which type of generation ++ * was used */ + /* 9. Q generated from SEED matches Q in PQGParams. */ + /* This function checks all possible hash and generation types to + * find a Q_ which matches Q. */ ++ g = vfy->seed.len * 8; + CHECKPARAM(findQfromSeed(L, N, g, &vfy->seed, &Q, &Q_, &qseed_len, +- &hashtype, &type) == SECSuccess); ++ &hashtype, &type, &qgen_counter_) == SECSuccess); + CHECKPARAM(mp_cmp(&Q, &Q_) == 0); ++ /* now we can do steps 7 & 8*/ ++ if ((type == FIPS186_1_TYPE) || (type == FIPS186_3_TYPE)) { ++ CHECKPARAM((vfy->counter == -1) || (vfy->counter < counter_max)); ++ CHECKPARAM(g >= N && g < counter_max / 2); ++ } + if (type == FIPS186_3_ST_TYPE) { + SECItem qseed = { 0, 0, 0 }; + SECItem pseed = { 0, 0, 0 }; + unsigned int first_seed_len; +- unsigned int pgen_counter = 0; ++ unsigned int pgen_counter_ = 0; ++ unsigned int qgen_counter = (vfy->counter >> 16) & 0xffff; ++ unsigned int pgen_counter = (vfy->counter) & 0xffff; + + /* extract pseed and qseed from domain_parameter_seed, which is + * first_seed || pseed || qseed. qseed is first_seed + small_integer +- * pseed is qseed + small_integer. This means most of the time ++ * mod the length of first_seed. pseed is qseed + small_integer mod ++ * the length of first_seed. This means most of the time + * first_seed.len == qseed.len == pseed.len. Rarely qseed.len and/or +- * pseed.len will be one greater than first_seed.len, so we can +- * depend on the fact that +- * first_seed.len = floor(domain_parameter_seed.len/3). +- * findQfromSeed returned qseed.len, so we can calculate pseed.len as +- * pseed.len = domain_parameter_seed.len - first_seed.len - qseed.len +- * this is probably over kill, since 99.999% of the time they will all +- * be equal. +- * +- * With the lengths, we can now find the offsets; ++ * pseed.len will be smaller because mpi clamps them. pqgGen ++ * automatically adds the zero pad back though, so we can depend ++ * domain_parameter_seed.len to be a multiple of three. We only have ++ * to deal with the fact that the returned seeds from our functions ++ * could be shorter. ++ * first_seed.len = domain_parameter_seed.len/3 ++ * We can now find the offsets; + * first_seed.data = domain_parameter_seed.data + 0 + * pseed.data = domain_parameter_seed.data + first_seed.len + * qseed.data = domain_parameter_seed.data + * + domain_paramter_seed.len - qseed.len +- * ++ * We deal with pseed possibly having zero pad in the pseed check later. + */ + first_seed_len = vfy->seed.len / 3; + CHECKPARAM(qseed_len < vfy->seed.len); + CHECKPARAM(first_seed_len * 8 > N - 1); +- CHECKPARAM(first_seed_len + qseed_len < vfy->seed.len); ++ CHECKPARAM(first_seed_len * 8 < counter_max / 2); ++ CHECKPARAM(first_seed_len >= qseed_len); + qseed.len = qseed_len; + qseed.data = vfy->seed.data + vfy->seed.len - qseed.len; +- pseed.len = vfy->seed.len - (first_seed_len + qseed_len); ++ pseed.len = first_seed_len; + pseed.data = vfy->seed.data + first_seed_len; + + /* + * now complete FIPS 186-3 A.1.2.1.2. Step 1 was completed + * above in our initial checks, Step 2 was completed by + * findQfromSeed */ + + /* Step 3 (status, c0, prime_seed, prime_gen_counter) = + ** (ST_Random_Prime((ceil(length/2)+1, input_seed) + */ + CHECK_SEC_OK(makePrimefromSeedShaweTaylor(hashtype, (L + 1) / 2 + 1, +- &qseed, &p0, &pseed_, &pgen_counter)); ++ &qseed, &p0, &pseed_, &pgen_counter_)); + /* Steps 4-22 FIPS 186-3 appendix A.1.2.1.2 */ +- CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, +- &p0, &Q_, &P_, &pseed_, &pgen_counter)); ++ CHECK_SEC_OK(makePrimefromPrimesShaweTaylor(hashtype, L, first_seed_len * 8, ++ &p0, &Q_, &P_, &pseed_, &pgen_counter_)); + CHECKPARAM(mp_cmp(&P, &P_) == 0); + /* make sure pseed wasn't tampered with (since it is part of + * calculating G) */ ++ if (pseed.len > pseed_.len) { ++ /* handle the case of zero pad for pseed */ ++ int extra = pseed.len - pseed_.len; ++ int i; ++ for (i = 0; i < extra; i++) { ++ if (pseed.data[i] != 0) { ++ *result = SECFailure; ++ goto cleanup; ++ } ++ } ++ pseed.data += extra; ++ pseed.len -= extra; ++ /* the rest is handled in the normal compare below */ ++ } + CHECKPARAM(SECITEM_CompareItem(&pseed, &pseed_) == SECEqual); ++ if (vfy->counter != -1) { ++ CHECKPARAM(pgen_counter < counter_max); ++ CHECKPARAM(qgen_counter < counter_max); ++ CHECKPARAM((pgen_counter_ == pgen_counter)); ++ CHECKPARAM((qgen_counter_ == qgen_counter)); ++ } + } else if (vfy->counter == -1) { + /* If counter is set to -1, we are really only verifying G, skip + * the remainder of the checks for P */ + CHECKPARAM(type != FIPS186_1_TYPE); /* we only do this for DSA2 */ + } else { + /* 10. P generated from (L, counter, g, SEED, Q) matches P + * in PQGParams. */ + outlen = HASH_ResultLen(hashtype) * PR_BITS_PER_BYTE; +diff --git a/lib/freebl/rijndael.c b/lib/freebl/rijndael.c +--- a/lib/freebl/rijndael.c ++++ b/lib/freebl/rijndael.c +@@ -1027,23 +1027,25 @@ AES_CreateContext(const unsigned char *k + * AES_DestroyContext + * + * Zero an AES cipher context. If freeit is true, also free the pointer + * to the context. + */ + void + AES_DestroyContext(AESContext *cx, PRBool freeit) + { ++ void *mem = cx->mem; + if (cx->worker_cx && cx->destroy) { + (*cx->destroy)(cx->worker_cx, PR_TRUE); + cx->worker_cx = NULL; + cx->destroy = NULL; + } ++ PORT_Memset(cx, 0, sizeof(AESContext)); + if (freeit) { +- PORT_Free(cx->mem); ++ PORT_Free(mem); + } + } + + /* + * AES_Encrypt + * + * Encrypt an arbitrary-length buffer. The output buffer must already be + * allocated to at least inputLen. +diff --git a/lib/softoken/pkcs11c.c b/lib/softoken/pkcs11c.c +--- a/lib/softoken/pkcs11c.c ++++ b/lib/softoken/pkcs11c.c +@@ -4708,16 +4708,24 @@ sftk_PairwiseConsistencyCheck(CK_SESSION + 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) { ++ if (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, +@@ -7543,40 +7551,55 @@ NSC_DeriveKey(CK_SESSION_HANDLE hSession + SHA512_HashBuf(key_block, (const unsigned char *)att->attrib.pValue, + att->attrib.ulValueLen); + + crv = sftk_forceAttribute(key, CKA_VALUE, key_block, keySize); + break; + + case CKM_DH_PKCS_DERIVE: { + SECItem derived, dhPublic; +- SECItem dhPrime, dhValue; ++ SECItem dhPrime, dhSubPrime, dhValue; + /* sourceKey - values for the local existing low key */ + /* get prime and value attributes */ + crv = sftk_Attribute2SecItem(NULL, &dhPrime, sourceKey, CKA_PRIME); +- if (crv != SECSuccess) ++ if (crv != CKR_OK) + break; + crv = sftk_Attribute2SecItem(NULL, &dhValue, sourceKey, CKA_VALUE); +- if (crv != SECSuccess) { ++ if (crv != CKR_OK) { + PORT_Free(dhPrime.data); + break; + } + + dhPublic.data = pMechanism->pParameter; + dhPublic.len = pMechanism->ulParameterLen; + ++ /* if the caller bothered to provide Q, use Q to validate. ++ * the public key */ ++ crv = sftk_Attribute2SecItem(NULL, &dhSubPrime, sourceKey, CKA_SUBPRIME); ++ if (crv == CKR_OK) { ++ rv = KEA_Verify(&dhPublic, &dhPrime, &dhSubPrime); ++ PORT_Free(dhSubPrime.data); ++ if (rv != SECSuccess) { ++ crv = CKR_ARGUMENTS_BAD; ++ PORT_Free(dhPrime.data); ++ PORT_Free(dhValue.data); ++ break; ++ } ++ } ++ + /* calculate private value - oct */ + rv = DH_Derive(&dhPublic, &dhPrime, &dhValue, &derived, keySize); + + PORT_Free(dhPrime.data); + PORT_Free(dhValue.data); + + if (rv == SECSuccess) { + sftk_forceAttribute(key, CKA_VALUE, derived.data, derived.len); + PORT_ZFree(derived.data, derived.len); ++ crv = CKR_OK; + } else + crv = CKR_HOST_MEMORY; + + break; + } + + case CKM_ECDH1_DERIVE: + case CKM_ECDH1_COFACTOR_DERIVE: { diff --git a/SOURCES/nss-softokn.pc.in b/SOURCES/nss-softokn.pc.in new file mode 100644 index 0000000..022ebbf --- /dev/null +++ b/SOURCES/nss-softokn.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS-SOFTOKN +Description: Network Security Services Softoken PKCS #11 Module +Version: %SOFTOKEN_VERSION% +Requires: nspr >= %NSPR_VERSION%, nss-util >= %NSSUTIL_VERSION% +Libs: -L${libdir} -lfreebl3 -lnssdbm3 -lsoftokn3 +Cflags: -I${includedir} diff --git a/SOURCES/nss-sysinit-userdb.patch b/SOURCES/nss-sysinit-userdb.patch new file mode 100644 index 0000000..7347260 --- /dev/null +++ b/SOURCES/nss-sysinit-userdb.patch @@ -0,0 +1,106 @@ +Index: nss/lib/sysinit/nsssysinit.c +=================================================================== +--- nss.orig/lib/sysinit/nsssysinit.c ++++ nss/lib/sysinit/nsssysinit.c +@@ -36,41 +36,9 @@ testdir(char *dir) + return S_ISDIR(buf.st_mode); + } + +-/** +- * Append given @dir to @path and creates the directory with mode @mode. +- * Returns 0 if successful, -1 otherwise. +- * Assumes that the allocation for @path has sufficient space for @dir +- * to be added. +- */ +-static int +-appendDirAndCreate(char *path, char *dir, mode_t mode) +-{ +- PORT_Strcat(path, dir); +- if (!testdir(path)) { +- if (mkdir(path, mode)) { +- return -1; +- } +- } +- return 0; +-} +- +-#define XDG_NSS_USER_PATH1 "/.local" +-#define XDG_NSS_USER_PATH2 "/share" +-#define XDG_NSS_USER_PATH3 "/pki" +- + #define NSS_USER_PATH1 "/.pki" + #define NSS_USER_PATH2 "/nssdb" +- +-/** +- * Return the path to user's NSS database. +- * We search in the following dirs in order: +- * (1) $HOME/.pki/nssdb; +- * (2) $XDG_DATA_HOME/pki/nssdb if XDG_DATA_HOME is set; +- * (3) $HOME/.local/share/pki/nssdb (default XDG_DATA_HOME value). +- * If (1) does not exist, then the returned dir will be set to either +- * (2) or (3), depending if XDG_DATA_HOME is set. +- */ +-char * ++static char * + getUserDB(void) + { + char *userdir = PR_GetEnvSecure("HOME"); +@@ -81,47 +49,22 @@ getUserDB(void) + } + + nssdir = PORT_Alloc(strlen(userdir) + sizeof(NSS_USER_PATH1) + sizeof(NSS_USER_PATH2)); ++ if (nssdir == NULL) { ++ return NULL; ++ } + PORT_Strcpy(nssdir, userdir); +- PORT_Strcat(nssdir, NSS_USER_PATH1 NSS_USER_PATH2); +- if (testdir(nssdir)) { +- /* $HOME/.pki/nssdb exists */ +- return nssdir; +- } else { +- /* either $HOME/.pki or $HOME/.pki/nssdb does not exist */ ++ /* verify it exists */ ++ if (!testdir(nssdir)) { + PORT_Free(nssdir); +- } +- int size = 0; +- char *xdguserdatadir = PR_GetEnvSecure("XDG_DATA_HOME"); +- if (xdguserdatadir) { +- size = strlen(xdguserdatadir); +- } else { +- size = strlen(userdir) + sizeof(XDG_NSS_USER_PATH1) + sizeof(XDG_NSS_USER_PATH2); +- } +- size += sizeof(XDG_NSS_USER_PATH3) + sizeof(NSS_USER_PATH2); +- +- nssdir = PORT_Alloc(size); +- if (nssdir == NULL) { + return NULL; + } +- +- if (xdguserdatadir) { +- PORT_Strcpy(nssdir, xdguserdatadir); +- if (!testdir(nssdir)) { +- PORT_Free(nssdir); +- return NULL; +- } +- +- } else { +- PORT_Strcpy(nssdir, userdir); +- if (appendDirAndCreate(nssdir, XDG_NSS_USER_PATH1, 0755) || +- appendDirAndCreate(nssdir, XDG_NSS_USER_PATH2, 0755)) { +- PORT_Free(nssdir); +- return NULL; +- } ++ PORT_Strcat(nssdir, NSS_USER_PATH1); ++ if (!testdir(nssdir) && mkdir(nssdir, 0760)) { ++ PORT_Free(nssdir); ++ return NULL; + } +- /* ${XDG_DATA_HOME:-$HOME/.local/share}/pki/nssdb */ +- if (appendDirAndCreate(nssdir, XDG_NSS_USER_PATH3, 0760) || +- appendDirAndCreate(nssdir, NSS_USER_PATH2, 0760)) { ++ PORT_Strcat(nssdir, NSS_USER_PATH2); ++ if (!testdir(nssdir) && mkdir(nssdir, 0760)) { + PORT_Free(nssdir); + return NULL; + } diff --git a/SOURCES/nss-util-config.in b/SOURCES/nss-util-config.in new file mode 100644 index 0000000..532abbe --- /dev/null +++ b/SOURCES/nss-util-config.in @@ -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 <&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=`pkg-config --variable=exec_prefix nss-util` +fi +if test -z "$includedir"; then + includedir=`pkg-config --variable=includedir nss-util` +fi +if test -z "$libdir"; then + libdir=`pkg-config --variable=libdir nss-util` +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 + diff --git a/SOURCES/nss-util.pc.in b/SOURCES/nss-util.pc.in new file mode 100644 index 0000000..1310248 --- /dev/null +++ b/SOURCES/nss-util.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS-UTIL +Description: Network Security Services Utility Library +Version: %NSSUTIL_VERSION% +Requires: nspr >= %NSPR_VERSION% +Libs: -L${libdir} -lnssutil3 +Cflags: -I${includedir} diff --git a/SOURCES/nss.pc.in b/SOURCES/nss.pc.in new file mode 100644 index 0000000..69823cb --- /dev/null +++ b/SOURCES/nss.pc.in @@ -0,0 +1,11 @@ +prefix=%prefix% +exec_prefix=%exec_prefix% +libdir=%libdir% +includedir=%includedir% + +Name: NSS +Description: Network Security Services +Version: %NSS_VERSION% +Requires: nspr >= %NSPR_VERSION%, nss-util >= %NSSUTIL_VERSION% +Libs: -L${libdir} -lssl3 -lsmime3 -lnss3 +Cflags: -I${includedir} diff --git a/SOURCES/pkcs11.txt.xml b/SOURCES/pkcs11.txt.xml new file mode 100644 index 0000000..d30e469 --- /dev/null +++ b/SOURCES/pkcs11.txt.xml @@ -0,0 +1,56 @@ + + + +]> + + + + + &date; + Network Security Services + nss + &version; + + + + pkcs11.txt + 5 + + + + pkcs11.txt + NSS PKCS #11 module configuration file + + + + Description + +The pkcs11.txt file is used to configure initialization parameters for the nss security module and optionally other pkcs #11 modules. + + +For full documentation visit PKCS #11 Module Specs. + + + + + Files + /etc/pki/nssdb/pkcs11.txt + + + + Authors + The nss libraries were written and maintained by developers with Netscape, Red Hat, Sun, Oracle, Mozilla, and Google. + Authors: Elio Maldonado <emaldona@redhat.com>. + + + + + LICENSE + Licensed under 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/. + + + + + diff --git a/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch b/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch new file mode 100644 index 0000000..970c84e --- /dev/null +++ b/SOURCES/rhbz1185708-enable-ecc-3des-ciphers-by-default.patch @@ -0,0 +1,14 @@ +diff -up nss/lib/ssl/ssl3con.c.1185708_3des nss/lib/ssl/ssl3con.c +--- nss/lib/ssl/ssl3con.c.1185708_3des 2018-12-11 18:28:06.736592552 +0100 ++++ nss/lib/ssl/ssl3con.c 2018-12-11 18:29:06.273314692 +0100 +@@ -106,8 +106,8 @@ static ssl3CipherSuiteCfg cipherSuites[s + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, +- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, ++ { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, ++ { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_ALLOWED, PR_TRUE, PR_FALSE}, + { TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + { TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_ALLOWED, PR_FALSE, PR_FALSE}, + diff --git a/SOURCES/setup-nsssysinit.sh b/SOURCES/setup-nsssysinit.sh new file mode 100755 index 0000000..8e1f5f7 --- /dev/null +++ b/SOURCES/setup-nsssysinit.sh @@ -0,0 +1,68 @@ +#!/bin/sh +# +# Turns on or off the nss-sysinit module db by editing the +# global PKCS #11 congiguration file. Displays the status. +# +# This script can be invoked by the user as super user. +# It is invoked at nss-sysinit post install time with argument on. +# +usage() +{ + cat <&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 + +# check if nsssysinit is currently enabled or disabled +sysinit_enabled() +{ + grep -q '^library=libnsssysinit' ${p11conf} +} + +umask 022 +case "$1" in + on | ON ) + if sysinit_enabled; then + exit 0 + fi + 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 ! sysinit_enabled; 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} + ;; + status ) + echo -n 'NSS sysinit is ' + sysinit_enabled && echo 'enabled' || echo 'disabled' + ;; + * ) + usage 1 1>&2 + ;; +esac diff --git a/SOURCES/system-pkcs11.txt b/SOURCES/system-pkcs11.txt new file mode 100644 index 0000000..c2f5704 --- /dev/null +++ b/SOURCES/system-pkcs11.txt @@ -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}) + diff --git a/SPECS/nss.spec b/SPECS/nss.spec new file mode 100644 index 0000000..a9127cb --- /dev/null +++ b/SPECS/nss.spec @@ -0,0 +1,2334 @@ +%global nspr_version 4.21.0 +%global nss_version 3.44.0 +%global unsupported_tools_directory %{_libdir}/nss/unsupported-tools +%global saved_files_dir %{_libdir}/nss/saved +%global dracutlibdir %{_prefix}/lib/dracut +%global dracut_modules_dir %{dracutlibdir}/modules.d/05nss-softokn/ +%global dracut_conf_dir %{dracutlibdir}/dracut.conf.d + +# The timestamp of our downstream manual pages, e.g., nss-config.1 +%global manual_date "Nov 13 2013" + +%bcond_without tests + +# Produce .chk files for the final stripped binaries +# +# NOTE: The LD_LIBRARY_PATH line guarantees shlibsign links +# against the freebl that we just built. This is necessary +# because the signing algorithm changed on 3.14 to DSA2 with SHA256 +# whereas we previously signed with DSA and SHA1. We must Keep this line +# until all mock platforms have been updated. +# After %%{__os_install_post} we would add +# export LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%%{_libdir} +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libsoftokn3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libfreeblpriv3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libfreebl3.so \ + $RPM_BUILD_ROOT/%{unsupported_tools_directory}/shlibsign -i $RPM_BUILD_ROOT/%{_libdir}/libnssdbm3.so \ +%{nil} + +# The upstream omits the trailing ".0", while we need it for +# consistency with the pkg-config version: +# https://bugzilla.redhat.com/show_bug.cgi?id=1578106 +%{lua: +rpm.define(string.format("nss_archive_version %s", + string.gsub(rpm.expand("%nss_version"), "(.*)%.0$", "%1"))) +} + +%{lua: +rpm.define(string.format("nss_release_tag NSS_%s_RTM", + string.gsub(rpm.expand("%nss_archive_version"), "%.", "_"))) +} + +Summary: Network Security Services +Name: nss +Version: %{nss_version} +Release: 8%{?dist} +License: MPLv2.0 +URL: http://www.mozilla.org/projects/security/pki/nss/ +Requires: nspr >= %{nspr_version} +Requires: nss-util >= %{nss_version} +# TODO: revert to same version as nss once we are done with the merge +Requires: nss-softokn%{_isa} >= %{nss_version} +Requires: nss-system-init +Requires: p11-kit-trust +Requires: crypto-policies +BuildRequires: nspr-devel >= %{nspr_version} +# for shlibsign +BuildRequires: nss-softokn +BuildRequires: sqlite-devel +BuildRequires: zlib-devel +BuildRequires: pkgconfig +BuildRequires: gawk +BuildRequires: psmisc +BuildRequires: perl-interpreter +BuildRequires: gcc-c++ + +Source0: https://ftp.mozilla.org/pub/security/nss/releases/%{nss_release_tag}/src/%{name}-%{nss_archive_version}.tar.gz +Source1: nss-util.pc.in +Source2: nss-util-config.in +Source3: nss-softokn.pc.in +Source4: nss-softokn-config.in +Source6: nss-softokn-dracut-module-setup.sh +Source7: nss-softokn-dracut.conf +Source8: nss.pc.in +Source9: nss-config.in +Source10: blank-cert8.db +Source11: blank-key3.db +Source12: blank-secmod.db +Source13: blank-cert9.db +Source14: blank-key4.db +Source15: system-pkcs11.txt +Source16: setup-nsssysinit.sh +Source20: nss-config.xml +Source21: setup-nsssysinit.xml +Source22: pkcs11.txt.xml +Source23: cert8.db.xml +Source24: cert9.db.xml +Source25: key3.db.xml +Source26: key4.db.xml +Source27: secmod.db.xml +Source28: nss-p11-kit.config +Source29: nss-softokn-cavs-1.0.tar.gz + +# To inject hardening flags for DSO +Patch1: nss-dso-ldflags.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=617723 +Patch2: nss-539183.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1549382 +Patch3: nss-module-leak.patch +# This patch uses the GCC -iquote option documented at +# http://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html#Directory-Options +# to give the in-tree headers a higher priority over the system headers, +# when they are included through the quote form (#include "file.h"). +# +# This ensures a build even when system headers are older. Such is the +# case when starting an update with API changes or even private export +# changes. +# +# Once the buildroot aha been bootstrapped the patch may be removed +# but it doesn't hurt to keep it. +Patch4: iquote.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1552767 +Patch5: nss-skip-tls13-fips.patch +# TLS 1.3 currently doesn't work under FIPS mode: +# https://bugzilla.redhat.com/show_bug.cgi?id=1710372 +Patch6: nss-fips-disable-tls13.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1552208 +Patch7: nss-disable-pkcs1-sigalgs-tls13.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1553443 +Patch8: nss-post-handshake-auth-with-tickets.patch +# To revert the change in: +# https://bugzilla.mozilla.org/show_bug.cgi?id=818686 +Patch9: nss-sysinit-userdb.patch +# Disable nss-sysinit test which is sorely to test the above change +Patch10: nss-skip-sysinit-gtests.patch +# Upstream patch didn't make 3.44 +# https://bugzilla.mozilla.org/show_bug.cgi?id=1546229 +Patch200: nss-ike-patch.patch +# https://bugzilla.mozilla.org/show_bug.cgi?id=1546477 +Patch201: nss-softokn-fips-update.patch +# Local patch for TLS_ECDHE_{ECDSA|RSA}_WITH_3DES_EDE_CBC_SHA ciphers +Patch58: rhbz1185708-enable-ecc-3des-ciphers-by-default.patch +# https://bugzilla.mozilla.org/show_bug.cgi?id=1473806 +Patch202: nss-8-fix-public-key-from-priv.patch +Patch204: nss-8-add-ipsec-usage-to-manpage.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1560329 +Patch205: nss-drbg-continuous.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1559906 +Patch206: nss-fipstest-tls12-prf.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1554336 +Patch210: nss-mpi-loop.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1540541 +Patch211: nss-leading-zero.patch +# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1515342 +Patch212: nss-input-check.patch +Patch213: nss-3.44-missing-softokn-kdf.patch + + +%description +Network Security Services (NSS) is a set of libraries designed to +support cross-platform development of security-enabled client and +server applications. Applications built with NSS can support SSL v2 +and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 +v3 certificates, and other security standards. + +%package tools +Summary: Tools for the Network Security Services +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description tools +Network Security Services (NSS) is a set of libraries designed to +support cross-platform development of security-enabled client and +server applications. Applications built with NSS can support SSL v2 +and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 +v3 certificates, and other security standards. + +Install the nss-tools package if you need command-line tools to +manipulate the NSS certificate and key database. + +%package sysinit +Summary: System NSS Initialization +# providing nss-system-init without version so that it can +# be replaced by a better one, e.g. supplied by the os vendor +Provides: nss-system-init +Requires: nss = %{version}-%{release} +Requires(post): coreutils, sed + +%description sysinit +Default Operating 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 devel +Summary: Development libraries for Network Security Services +Provides: nss-static = %{version}-%{release} +Requires: nss%{?_isa} = %{version}-%{release} +Requires: nss-util-devel +Requires: nss-softokn-devel +Requires: nspr-devel >= %{nspr_version} +Requires: pkgconfig +BuildRequires: xmlto + +%description devel +Header and Library files for doing development with Network Security Services. + + +%package pkcs11-devel +Summary: Development libraries for PKCS #11 (Cryptoki) using NSS +Provides: nss-pkcs11-devel-static = %{version}-%{release} +Requires: nss-devel = %{version}-%{release} +Requires: nss-softokn-freebl-devel = %{version}-%{release} + +%description pkcs11-devel +Library files for developing PKCS #11 modules using basic NSS +low level services. + + +%package util +Summary: Network Security Services Utilities Library +Requires: nspr >= %{nspr_version} + +%description util +Utilities for Network Security Services and the Softoken module + +%package util-devel +Summary: Development libraries for Network Security Services Utilities +Requires: nss-util%{?_isa} = %{version}-%{release} +Requires: nspr-devel >= %{nspr_version} +Requires: pkgconfig + +%description util-devel +Header and library files for doing development with Network Security Services. + + +%package softokn +Summary: Network Security Services Softoken Module +Requires: nspr >= %{nspr_version} +Requires: nss-util >= %{version}-%{release} +Requires: nss-softokn-freebl%{_isa} >= %{version}-%{release} + +%description softokn +Network Security Services Softoken Cryptographic Module + +%package softokn-freebl +Summary: Freebl library for the Network Security Services +# For PR_GetEnvSecure() from nspr >= 4.12 +Requires: nspr >= 4.12 +# For NSS_SecureMemcmpZero() from nss-util >= 3.33 +Requires: nss-util >= 3.33 +Conflicts: nss < 3.12.2.99.3-5 +Conflicts: filesystem < 3 + +%description softokn-freebl +NSS Softoken Cryptographic Module Freebl Library + +Install the nss-softokn-freebl package if you need the freebl library. + +%package softokn-freebl-devel +Summary: Header and Library files for doing development with the Freebl library for NSS +Provides: nss-softokn-freebl-static = %{version}-%{release} +Requires: nss-softokn-freebl%{?_isa} = %{version}-%{release} + +%description softokn-freebl-devel +NSS Softoken Cryptographic Module Freebl Library Development Tools +This package supports special needs of some PKCS #11 module developers and +is otherwise considered private to NSS. As such, the programming interfaces +may change and the usual NSS binary compatibility commitments do not apply. +Developers should rely only on the officially supported NSS public API. + +%package softokn-devel +Summary: Development libraries for Network Security Services +Requires: nss-softokn%{?_isa} = %{version}-%{release} +Requires: nss-softokn-freebl-devel%{?_isa} = %{version}-%{release} +Requires: nspr-devel >= %{nspr_version} +Requires: nss-util-devel >= %{version}-%{release} +Requires: pkgconfig +BuildRequires: nspr-devel >= %{nspr_version} + +%description softokn-devel +Header and library files for doing development with Network Security Services. + + +%prep +#autosetup -N -S quilt -n %{name}-%{nss_archive_version} +%autosetup -N -n %{name}-%{nss_archive_version} -a 29 +pushd nss +%autopatch -p1 +popd + +# https://bugzilla.redhat.com/show_bug.cgi?id=1247353 +find nss/lib/libpkix -perm /u+x -type f -exec chmod -x {} \; + + +%build + +export FREEBL_NO_DEPEND=1 + +# Must export FREEBL_LOWHASH=1 for nsslowhash.h so that it gets +# copied to dist and the rpm install phase can find it +# This due of the upstream changes to fix +# https://bugzilla.mozilla.org/show_bug.cgi?id=717906 +export FREEBL_LOWHASH=1 + +# uncomment if the iquote patch is activated +export IN_TREE_FREEBL_HEADERS_FIRST=1 + +export NSS_FORCE_FIPS=1 + +# Enable compiler optimizations and disable debugging code +export BUILD_OPT=1 + +# Uncomment to disable optimizations +#RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed -e 's/-O2/-O0/g'` +#export RPM_OPT_FLAGS + +# Generate symbolic info for debuggers +export XCFLAGS=$RPM_OPT_FLAGS + +export LDFLAGS=$RPM_LD_FLAGS + +export DSO_LDFLAGS=$RPM_LD_FLAGS + +export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 +export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 + +export NSPR_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nspr | sed 's/-I//'` +export NSPR_LIB_DIR=%{_libdir} + +export NSS_USE_SYSTEM_SQLITE=1 + +export NSS_ALLOW_SSLKEYLOGFILE=1 + +export NSS_SEED_ONLY_DEV_URANDOM=1 + +%ifnarch noarch +%if 0%{__isa_bits} == 64 +export USE_64=1 +%endif +%endif + +##### phase 2: build the rest of nss +make -C ./nss/coreconf +make -C ./nss/lib/dbm + +# 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" + +make -C ./nss + +# build the man pages clean +pushd ./nss/doc +rm -rf ./nroff +make clean +echo -n %{manual_date} > date.xml +echo -n %{version} > version.xml +make +popd + +# and copy them to the dist directory for %%install to find them +mkdir -p ./dist/docs/nroff +cp ./nss/doc/nroff/* ./dist/docs/nroff + +# Set up our package files +mkdir -p ./dist/pkgconfig + +cat %{SOURCE1} | 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,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{version},g" > \ + ./dist/pkgconfig/nss-util.pc + +NSSUTIL_VMAJOR=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VMAJOR" | awk '{print $3}'` +NSSUTIL_VMINOR=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VMINOR" | awk '{print $3}'` +NSSUTIL_VPATCH=`cat nss/lib/util/nssutil.h | grep "#define.*NSSUTIL_VPATCH" | awk '{print $3}'` + +cat %{SOURCE2} | 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" \ + > ./dist/pkgconfig/nss-util-config + +chmod 755 ./dist/pkgconfig/nss-util-config + +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,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{nss_version},g" \ + -e "s,%%SOFTOKEN_VERSION%%,%{version},g" > \ + ./dist/pkgconfig/nss-softokn.pc + +SOFTOKEN_VMAJOR=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VMAJOR" | awk '{print $3}'` +SOFTOKEN_VMINOR=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VMINOR" | awk '{print $3}'` +SOFTOKEN_VPATCH=`cat nss/lib/softoken/softkver.h | grep "#define.*SOFTOKEN_VPATCH" | awk '{print $3}'` + +cat %{SOURCE4} | 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@,$SOFTOKEN_VMAJOR,g" \ + -e "s,@MOD_MINOR_VERSION@,$SOFTOKEN_VMINOR,g" \ + -e "s,@MOD_PATCH_VERSION@,$SOFTOKEN_VPATCH,g" \ + > ./dist/pkgconfig/nss-softokn-config + +chmod 755 ./dist/pkgconfig/nss-softokn-config + +cat %{SOURCE8} | 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,%%NSS_VERSION%%,%{version},g" \ + -e "s,%%NSPR_VERSION%%,%{nspr_version},g" \ + -e "s,%%NSSUTIL_VERSION%%,%{nss_version},g" \ + -e "s,%%SOFTOKEN_VERSION%%,%{nss_version},g" > \ + ./dist/pkgconfig/nss.pc + +NSS_VMAJOR=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VMAJOR" | awk '{print $3}'` +NSS_VMINOR=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VMINOR" | awk '{print $3}'` +NSS_VPATCH=`cat nss/lib/nss/nss.h | grep "#define.*NSS_VPATCH" | awk '{print $3}'` + +cat %{SOURCE9} | 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" \ + > ./dist/pkgconfig/nss-config + +chmod 755 ./dist/pkgconfig/nss-config + +cat %{SOURCE16} > ./dist/pkgconfig/setup-nsssysinit.sh +chmod 755 ./dist/pkgconfig/setup-nsssysinit.sh + +cp ./nss/lib/ckfw/nssck.api ./dist/private/nss/ + +date +"%e %B %Y" | tr -d '\n' > date.xml +echo -n %{version} > version.xml + +# configuration files and setup script +for m in %{SOURCE20} %{SOURCE21} %{SOURCE22}; do + cp ${m} . +done +for m in nss-config.xml setup-nsssysinit.xml pkcs11.txt.xml; do + xmlto man ${m} +done + +# nss databases considered to be configuration files +for m in %{SOURCE23} %{SOURCE24} %{SOURCE25} %{SOURCE26} %{SOURCE27}; do + cp ${m} . +done +for m in cert8.db.xml cert9.db.xml key3.db.xml key4.db.xml secmod.db.xml; do + xmlto man ${m} +done + + +%check +%if %{with tests} +# Begin -- copied from the build section + +export FREEBL_NO_DEPEND=1 + +export BUILD_OPT=1 + +%ifnarch noarch +%if 0%{__isa_bits} == 64 +export USE_64=1 +%endif +%endif + +# End -- copied from the build section + +# This is necessary because the test suite tests algorithms that are +# disabled by the system policy. +export NSS_IGNORE_SYSTEM_POLICY=1 + +# enable the following line to force a test failure +# find ./nss -name \*.chk | xargs rm -f + +# Run test suite. +# In order to support multiple concurrent executions of the test suite +# (caused by concurrent RPM builds) on a single host, +# we'll use a random port. Also, we want to clean up any stuck +# selfserv processes. If process name "selfserv" is used everywhere, +# we can't simply do a "killall selfserv", because it could disturb +# concurrent builds. Therefore we'll do a search and replace and use +# a different process name. +# Using xargs doesn't mix well with spaces in filenames, in order to +# avoid weird quoting we'll require that no spaces are being used. + +SPACEISBAD=`find ./nss/tests | grep -c ' '` ||: +if [ $SPACEISBAD -ne 0 ]; then + echo "error: filenames containing space are not supported (xargs)" + exit 1 +fi +MYRAND=`perl -e 'print 9000 + int rand 1000'`; echo $MYRAND ||: +RANDSERV=selfserv_${MYRAND}; echo $RANDSERV ||: +DISTBINDIR=`ls -d ./dist/*.OBJ/bin`; echo $DISTBINDIR ||: +pushd "$DISTBINDIR" +ln -s selfserv $RANDSERV +popd +# man perlrun, man perlrequick +# replace word-occurrences of selfserv with selfserv_$MYRAND +find ./nss/tests -type f |\ + grep -v "\.db$" |grep -v "\.crl$" | grep -v "\.crt$" |\ + grep -vw CVS |xargs grep -lw selfserv |\ + xargs -l perl -pi -e "s/\bselfserv\b/$RANDSERV/g" ||: + +killall $RANDSERV || : + +rm -rf ./tests_results +pushd nss/tests +# all.sh is the test suite script + +# don't need to run all the tests when testing packaging +# nss_cycles: standard pkix upgradedb sharedb +# the full list from all.sh is: +# "cipher lowhash libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests" +%define nss_tests "libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains ec gtests ssl_gtests" +# nss_ssl_tests: crl bypass_normal normal_bypass normal_fips fips_normal iopr policy +# nss_ssl_run: cov auth stapling stress +# +# Uncomment these lines if you need to temporarily +# disable some test suites for faster test builds +# % define nss_ssl_tests "normal_fips" +# % define nss_ssl_run "cov" + +HOST=localhost DOMSUF=localdomain PORT=$MYRAND NSS_CYCLES=%{?nss_cycles} NSS_TESTS=%{?nss_tests} NSS_SSL_TESTS=%{?nss_ssl_tests} NSS_SSL_RUN=%{?nss_ssl_run} ./all.sh +popd + +%endif + +%install + +# There is no make install target so we'll do it ourselves. + +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/nss3 +mkdir -p $RPM_BUILD_ROOT/%{_includedir}/nss3/templates +mkdir -p $RPM_BUILD_ROOT/%{_bindir} +mkdir -p $RPM_BUILD_ROOT/%{_libdir} +mkdir -p $RPM_BUILD_ROOT/%{unsupported_tools_directory} +mkdir -p $RPM_BUILD_ROOT/%{_libdir}/pkgconfig +mkdir -p $RPM_BUILD_ROOT/%{saved_files_dir} +mkdir -p $RPM_BUILD_ROOT/%{dracut_modules_dir} +mkdir -p $RPM_BUILD_ROOT/%{dracut_conf_dir} +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/crypto-policies/local.d +%if %{defined rhel} +# not needed for rhel and its derivatives only fedora +%else +# because of the pp.1 conflict with perl-PAR-Packer +mkdir -p $RPM_BUILD_ROOT%{_datadir}/doc/nss-tools +%endif + +install -m 755 %{SOURCE6} $RPM_BUILD_ROOT/%{dracut_modules_dir}/module-setup.sh +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT/%{dracut_conf_dir}/50-nss-softokn.conf + +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man5 + +# Copy the binary libraries we want +for file in libnssutil3.so libsoftokn3.so libnssdbm3.so libfreebl3.so libfreeblpriv3.so libnss3.so libnsssysinit.so libsmime3.so libssl3.so +do + install -p -m 755 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Install the empty NSS db files +# Legacy db +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb +install -p -m 644 %{SOURCE10} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/cert8.db +install -p -m 644 %{SOURCE11} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/key3.db +install -p -m 644 %{SOURCE12} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/secmod.db +# Shared db +install -p -m 644 %{SOURCE13} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/cert9.db +install -p -m 644 %{SOURCE14} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/key4.db +install -p -m 644 %{SOURCE15} $RPM_BUILD_ROOT/%{_sysconfdir}/pki/nssdb/pkcs11.txt + +# Copy the development libraries we want +for file in libcrmf.a libnssb.a libnssckfw.a +do + install -p -m 644 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Copy the binaries we want +for file in certutil cmsutil crlutil modutil nss-policy-check pk12util signver ssltap +do + install -p -m 755 dist/*.OBJ/bin/$file $RPM_BUILD_ROOT/%{_bindir} +done + +# Copy the binaries we ship as unsupported +for file in bltest ecperf fbectest fipstest shlibsign atob btoa derdump listsuites ocspclnt pp selfserv signtool strsclnt symkeyutil tstclnt vfyserv vfychain +do + install -p -m 755 dist/*.OBJ/bin/$file $RPM_BUILD_ROOT/%{unsupported_tools_directory} +done + +# Copy the include files we want +for file in dist/public/nss/*.h +do + install -p -m 644 $file $RPM_BUILD_ROOT/%{_includedir}/nss3 +done + +# Copy some freebl include files we also want +for file in blapi.h alghmac.h +do + install -p -m 644 dist/private/nss/$file $RPM_BUILD_ROOT/%{_includedir}/nss3 +done + +# Copy the static freebl library +for file in libfreebl.a +do +install -p -m 644 dist/*.OBJ/lib/$file $RPM_BUILD_ROOT/%{_libdir} +done + +# Copy the template files we want +for file in dist/private/nss/templates.c dist/private/nss/nssck.api +do + install -p -m 644 $file $RPM_BUILD_ROOT/%{_includedir}/nss3/templates +done + +# Copy the package configuration files +install -p -m 644 ./dist/pkgconfig/nss-util.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss-util.pc +install -p -m 755 ./dist/pkgconfig/nss-util-config $RPM_BUILD_ROOT/%{_bindir}/nss-util-config +install -p -m 644 ./dist/pkgconfig/nss-softokn.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss-softokn.pc +install -p -m 755 ./dist/pkgconfig/nss-softokn-config $RPM_BUILD_ROOT/%{_bindir}/nss-softokn-config +install -p -m 644 ./dist/pkgconfig/nss.pc $RPM_BUILD_ROOT/%{_libdir}/pkgconfig/nss.pc +install -p -m 755 ./dist/pkgconfig/nss-config $RPM_BUILD_ROOT/%{_bindir}/nss-config +# Copy the pkcs #11 configuration script +install -p -m 755 ./dist/pkgconfig/setup-nsssysinit.sh $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit.sh +# install a symbolic link to it, without the ".sh" suffix, +# that matches the man page documentation +ln -r -s -f $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit.sh $RPM_BUILD_ROOT/%{_bindir}/setup-nsssysinit + +# Copy the man pages for scripts +for f in nss-config setup-nsssysinit; do + install -c -m 644 ${f}.1 $RPM_BUILD_ROOT%{_mandir}/man1/${f}.1 +done +# Copy the man pages for the nss tools +for f in certutil cmsutil crlutil derdump modutil nss-policy-check pk12util signtool signver ssltap vfychain vfyserv; do + install -c -m 644 ./dist/docs/nroff/${f}.1 $RPM_BUILD_ROOT%{_mandir}/man1/${f}.1 +done +%if %{defined rhel} +install -c -m 644 ./dist/docs/nroff/pp.1 $RPM_BUILD_ROOT%{_mandir}/man1/pp.1 +%else +install -c -m 644 ./dist/docs/nroff/pp.1 $RPM_BUILD_ROOT%{_datadir}/doc/nss-tools/pp.1 +%endif + +# Copy the man pages for the configuration files +for f in pkcs11.txt; do + install -c -m 644 ${f}.5 $RPM_BUILD_ROOT%{_mandir}/man5/${f}.5 +done +# Copy the man pages for the nss databases +for f in cert8.db cert9.db key3.db key4.db secmod.db; do + install -c -m 644 ${f}.5 $RPM_BUILD_ROOT%{_mandir}/man5/${f}.5 +done + +# Copy the crypto-policies configuration file +install -p -m 644 %{SOURCE28} $RPM_BUILD_ROOT/%{_sysconfdir}/crypto-policies/local.d + +%triggerpostun -n nss-sysinit -- nss-sysinit < 3.12.8-3 +# Reverse unwanted disabling of sysinit by faulty preun sysinit scriplet +# from previous versions of nss.spec +/usr/bin/setup-nsssysinit.sh on + +%post +update-crypto-policies --no-reload &> /dev/null || : + +%postun +update-crypto-policies --no-reload &> /dev/null || : + + +%files +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libnss3.so +%{_libdir}/libssl3.so +%{_libdir}/libsmime3.so +%dir %{_sysconfdir}/pki/nssdb +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/cert8.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/key3.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/secmod.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/cert9.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/key4.db +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/pki/nssdb/pkcs11.txt +%config(noreplace) %verify(not md5 size mtime) %{_sysconfdir}/crypto-policies/local.d/nss-p11-kit.config +%doc %{_mandir}/man5/cert8.db.5* +%doc %{_mandir}/man5/key3.db.5* +%doc %{_mandir}/man5/secmod.db.5* +%doc %{_mandir}/man5/cert9.db.5* +%doc %{_mandir}/man5/key4.db.5* +%doc %{_mandir}/man5/pkcs11.txt.5* + +%files sysinit +%{_libdir}/libnsssysinit.so +%{_bindir}/setup-nsssysinit.sh +# symbolic link to setup-nsssysinit.sh +%{_bindir}/setup-nsssysinit +%doc %{_mandir}/man1/setup-nsssysinit.1* + +%files tools +%{_bindir}/certutil +%{_bindir}/cmsutil +%{_bindir}/crlutil +%{_bindir}/modutil +%{_bindir}/nss-policy-check +%{_bindir}/pk12util +%{_bindir}/signver +%{_bindir}/ssltap +%{unsupported_tools_directory}/atob +%{unsupported_tools_directory}/btoa +%{unsupported_tools_directory}/derdump +%{unsupported_tools_directory}/listsuites +%{unsupported_tools_directory}/ocspclnt +%{unsupported_tools_directory}/pp +%{unsupported_tools_directory}/selfserv +%{unsupported_tools_directory}/signtool +%{unsupported_tools_directory}/strsclnt +%{unsupported_tools_directory}/symkeyutil +%{unsupported_tools_directory}/tstclnt +%{unsupported_tools_directory}/vfyserv +%{unsupported_tools_directory}/vfychain +# instead of %%{_mandir}/man*/* let's list them explicitly +# supported tools +%doc %{_mandir}/man1/certutil.1* +%doc %{_mandir}/man1/cmsutil.1* +%doc %{_mandir}/man1/crlutil.1* +%doc %{_mandir}/man1/modutil.1* +%doc %{_mandir}/man1/nss-policy-check.1* +%doc %{_mandir}/man1/pk12util.1* +%doc %{_mandir}/man1/signver.1* +# unsupported tools +%doc %{_mandir}/man1/derdump.1* +%doc %{_mandir}/man1/signtool.1* +%if %{defined rhel} +%doc %{_mandir}/man1/pp.1* +%else +%dir %{_datadir}/doc/nss-tools +%doc %{_datadir}/doc/nss-tools/pp.1 +%endif +%doc %{_mandir}/man1/ssltap.1* +%doc %{_mandir}/man1/vfychain.1* +%doc %{_mandir}/man1/vfyserv.1* + +%files devel +%{_libdir}/libcrmf.a +%{_libdir}/pkgconfig/nss.pc +%{_bindir}/nss-config +%doc %{_mandir}/man1/nss-config.1* + +%dir %{_includedir}/nss3 +%{_includedir}/nss3/cert.h +%{_includedir}/nss3/certdb.h +%{_includedir}/nss3/certt.h +%{_includedir}/nss3/cmmf.h +%{_includedir}/nss3/cmmft.h +%{_includedir}/nss3/cms.h +%{_includedir}/nss3/cmsreclist.h +%{_includedir}/nss3/cmst.h +%{_includedir}/nss3/crmf.h +%{_includedir}/nss3/crmft.h +%{_includedir}/nss3/cryptohi.h +%{_includedir}/nss3/cryptoht.h +%{_includedir}/nss3/sechash.h +%{_includedir}/nss3/jar-ds.h +%{_includedir}/nss3/jar.h +%{_includedir}/nss3/jarfile.h +%{_includedir}/nss3/key.h +%{_includedir}/nss3/keyhi.h +%{_includedir}/nss3/keyt.h +%{_includedir}/nss3/keythi.h +%{_includedir}/nss3/nss.h +%{_includedir}/nss3/nssckbi.h +%{_includedir}/nss3/ocsp.h +%{_includedir}/nss3/ocspt.h +%{_includedir}/nss3/p12.h +%{_includedir}/nss3/p12plcy.h +%{_includedir}/nss3/p12t.h +%{_includedir}/nss3/pk11func.h +%{_includedir}/nss3/pk11pqg.h +%{_includedir}/nss3/pk11priv.h +%{_includedir}/nss3/pk11pub.h +%{_includedir}/nss3/pk11sdr.h +%{_includedir}/nss3/pkcs12.h +%{_includedir}/nss3/pkcs12t.h +%{_includedir}/nss3/pkcs7t.h +%{_includedir}/nss3/preenc.h +%{_includedir}/nss3/secmime.h +%{_includedir}/nss3/secmod.h +%{_includedir}/nss3/secmodt.h +%{_includedir}/nss3/secpkcs5.h +%{_includedir}/nss3/secpkcs7.h +%{_includedir}/nss3/smime.h +%{_includedir}/nss3/ssl.h +%{_includedir}/nss3/sslerr.h +%{_includedir}/nss3/sslexp.h +%{_includedir}/nss3/sslproto.h +%{_includedir}/nss3/sslt.h + +%files pkcs11-devel +%{_includedir}/nss3/nssbase.h +%{_includedir}/nss3/nssbaset.h +%{_includedir}/nss3/nssckepv.h +%{_includedir}/nss3/nssckft.h +%{_includedir}/nss3/nssckfw.h +%{_includedir}/nss3/nssckfwc.h +%{_includedir}/nss3/nssckfwt.h +%{_includedir}/nss3/nssckg.h +%{_includedir}/nss3/nssckmdt.h +%{_includedir}/nss3/nssckt.h +%{_includedir}/nss3/templates/nssck.api +%{_libdir}/libnssb.a +%{_libdir}/libnssckfw.a + +%files util +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libnssutil3.so + +%files util-devel +# package configuration files +%{_libdir}/pkgconfig/nss-util.pc +%{_bindir}/nss-util-config + +# co-owned with nss +%dir %{_includedir}/nss3 +# these are marked as public export in nss/lib/util/manifest.mk +%{_includedir}/nss3/base64.h +%{_includedir}/nss3/ciferfam.h +%{_includedir}/nss3/eccutil.h +%{_includedir}/nss3/hasht.h +%{_includedir}/nss3/nssb64.h +%{_includedir}/nss3/nssb64t.h +%{_includedir}/nss3/nsslocks.h +%{_includedir}/nss3/nssilock.h +%{_includedir}/nss3/nssilckt.h +%{_includedir}/nss3/nssrwlk.h +%{_includedir}/nss3/nssrwlkt.h +%{_includedir}/nss3/nssutil.h +%{_includedir}/nss3/pkcs1sig.h +%{_includedir}/nss3/pkcs11.h +%{_includedir}/nss3/pkcs11f.h +%{_includedir}/nss3/pkcs11n.h +%{_includedir}/nss3/pkcs11p.h +%{_includedir}/nss3/pkcs11t.h +%{_includedir}/nss3/pkcs11u.h +%{_includedir}/nss3/pkcs11uri.h +%{_includedir}/nss3/portreg.h +%{_includedir}/nss3/secasn1.h +%{_includedir}/nss3/secasn1t.h +%{_includedir}/nss3/seccomon.h +%{_includedir}/nss3/secder.h +%{_includedir}/nss3/secdert.h +%{_includedir}/nss3/secdig.h +%{_includedir}/nss3/secdigt.h +%{_includedir}/nss3/secerr.h +%{_includedir}/nss3/secitem.h +%{_includedir}/nss3/secoid.h +%{_includedir}/nss3/secoidt.h +%{_includedir}/nss3/secport.h +%{_includedir}/nss3/utilmodt.h +%{_includedir}/nss3/utilpars.h +%{_includedir}/nss3/utilparst.h +%{_includedir}/nss3/utilrename.h +%{_includedir}/nss3/templates/templates.c + +%files softokn +%{_libdir}/libnssdbm3.so +%{_libdir}/libnssdbm3.chk +%{_libdir}/libsoftokn3.so +%{_libdir}/libsoftokn3.chk +# shared with nss-tools +%dir %{_libdir}/nss +%dir %{saved_files_dir} +%dir %{unsupported_tools_directory} +%{unsupported_tools_directory}/bltest +%{unsupported_tools_directory}/ecperf +%{unsupported_tools_directory}/fbectest +%{unsupported_tools_directory}/fipstest +%{unsupported_tools_directory}/shlibsign + +%files softokn-freebl +%{!?_licensedir:%global license %%doc} +%license nss/COPYING +%{_libdir}/libfreebl3.so +%{_libdir}/libfreebl3.chk +%{_libdir}/libfreeblpriv3.so +%{_libdir}/libfreeblpriv3.chk +#shared +%dir %{dracut_modules_dir} +%{dracut_modules_dir}/module-setup.sh +%{dracut_conf_dir}/50-nss-softokn.conf + +%files softokn-freebl-devel +%{_libdir}/libfreebl.a +%{_includedir}/nss3/blapi.h +%{_includedir}/nss3/blapit.h +%{_includedir}/nss3/alghmac.h +%{_includedir}/nss3/lowkeyi.h +%{_includedir}/nss3/lowkeyti.h + +%files softokn-devel +%{_libdir}/pkgconfig/nss-softokn.pc +%{_bindir}/nss-softokn-config + +# co-owned with nss +%dir %{_includedir}/nss3 +# +# The following headers are those exported public in +# nss/lib/freebl/manifest.mn and +# nss/lib/softoken/manifest.mn +# +# The following list is short because many headers, such as +# the pkcs #11 ones, have been provided by nss-util-devel +# which installed them before us. +# +%{_includedir}/nss3/ecl-exp.h +%{_includedir}/nss3/nsslowhash.h +%{_includedir}/nss3/shsign.h + + +%changelog +* Thu Aug 8 2019 Bob Relyea - 3.44.0-8 +- CKM_NSS_IKE1_APP_B_PRF_DERIVE was missing from the mechanism list, preventing + PK11_Derive*() from using it. Add gtests for the PK11_Derive interface for + all the CKM_NSS_IKE*_DERIVE mechanism. + +* Wed Jul 3 2019 Daiki Ueno - 3.44.0-7 +- Backport fixes from 3.44.1 + +* Wed Jun 26 2019 Daiki Ueno - 3.44.0-6 +- Add continuous RNG test required by FIPS +- fipstest: use CKM_TLS12_MASTER_KEY_DERIVE instead of vendor specific mechanism + +* Mon Jun 10 2019 Daiki Ueno - 3.44.0-5 +- Rebuild with the correct build target + +*Fri Jun 7 2019 Bob Relyea - 3.44.0-4.1 +- rebuild to try to retrigger CI tests + +*Wed Jun 5 2019 Bob Relyea - 3.44.0-4 +- Fix certutil man page +- Fix extracting a public key from a private key for dh, ec, and dsa + +* Thu May 30 2019 Daiki Ueno - 3.44.0-3 +- Disable TLS 1.3 under FIPS mode +- Disable RSASSA-PKCS1-v1_5 in TLS 1.3 +- Fix post-handshake auth transcript calculation if + SSL_ENABLE_SESSION_TICKETS is set +- Revert the change to use XDG basedirs (mozilla#818686) + +* Fri May 24 2019 Bob Relyea - 3.44.0-2 +- Add ike mechanisms in softokn +- Add FIPS checks in softoken + +* Fri May 24 2019 Daiki Ueno - 3.44.0-1 +- Update to NSS 3.44 +- Define NSS_SEED_ONLY_DEV_URANDOM=1 to exclusively use getentropy +- Use %%autosetup +- Clean up manual pages generation +- Clean up %%check +- Remove prelink dependency, which is not available in RHEL-8 +- Remove upstreamed patches + +* Mon Dec 17 2018 Daiki Ueno - 3.41.0-5 +- Update manual pages to reflect recent changes in commands + +* Fri Dec 14 2018 Bob Relyea - 3.41.0-4 +- Make sure corresponding public keys are created when importing private keys. + +* Thu Dec 13 2018 Daiki Ueno - 3.41.0-3 +- Fix the last change +- Add --no-reload option to update-crypto-policies to avoid + unnecessary restart of daemons + +* Thu Dec 13 2018 Daiki Ueno - 3.41.0-2 +- Restore LDFLAGS injection when linking DSO + +* Mon Dec 10 2018 Daiki Ueno - 3.41.0-1 +- Update to NSS 3.41 +- Consolidate nss-util, nss-softokn, and nss into a single source package + +* Fri Dec 7 2018 Daiki Ueno - 3.39.0-1.5 +- Fix the last commit + +* Tue Dec 4 2018 Bob Relyea - 3.39.0-1.4 +- Support for IKE/IPsec typical PKIX usage so libreswan can use nss + without rejecting certs based on EKU + +* Thu Nov 29 2018 Daiki Ueno - 3.39.0-1.3 +- Backport upstream fixes for rhbz#1649026, rhbz#1608895, rhbz#1644854 +- Document PKCS #11 URI +- Add warning when adding module with modutil while p11-kit is enabled + +* Tue Nov 13 2018 Daiki Ueno - 3.39.0-1.2 +- Update nss-dsa.patch to not advertise DSA signature algorithm +- Update PayPal test certs for testing + +* Thu Oct 18 2018 Daiki Ueno - 3.39.0-1.1 +- Backport "DSA" keyword in crypto-policies + +* Tue Sep 25 2018 Daiki Ueno - 3.39.0-1.0 +- Update to NSS 3.39 + +* Fri Sep 14 2018 Daiki Ueno - 3.38.0-1.2 +- Fix LDFLAGS injection when linking DSO + +* Tue Jul 24 2018 Daiki Ueno - 3.38.0-1.1 +- Install crypto-policies configuration file for + https://fedoraproject.org/wiki/Changes/NSSLoadP11KitModules +- Port enable-fips-when-system-is-in-fips-mode.patch from RHEL-7 +- Use %%ldconfig_scriptlets +- Remove needless use of %defattr, by Jason Tibbitts + +* Wed Jul 18 2018 Daiki Ueno - 3.38.0-1.0 +- Update to NSS 3.38 + +* Tue Jul 17 2018 Kai Engert - 3.36.1-1.2 +- Backport upstream addition of nss-policy-check utility, rhbz#1428746, + includes required fixes for mozbz#1296263 and mozbz#1474875 + +* Fri May 25 2018 Daiki Ueno - 3.36.1-1.1 +- Switch the default DB type to SQL +- Enable SSLKEYLOGFILE + +* Wed Apr 11 2018 Daiki Ueno - 3.36.1-1.0 +- Update to NSS 3.36.1 +- Remove nss-3.14.0.0-disble-ocsp-test.patch +- Fix partial injection of LDFLAGS +- Remove NSS_NO_PKCS11_BYPASS, which is no-op in upstream + +* Fri Mar 9 2018 Daiki Ueno - 3.36.0-1.0 +- Update to NSS 3.36.0 +- Add gcc-c++ to BuildRequires (C++ is needed for gtests) +- Make test failure detection robuster + +* Thu Feb 08 2018 Fedora Release Engineering - 3.35.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Jan 29 2018 Kai Engert - 3.35.0-4 +- Fix a compiler error with gcc 8, mozbz#1434070 +- Set NSS_FORCE_FIPS=1 at %%build time, and remove from %%check. + +* Mon Jan 29 2018 Kai Engert - 3.35.0-3 +- Stop pulling in nss-pem automatically, packages that need it should + depend on it, rhbz#1539401 + +* Tue Jan 23 2018 Daiki Ueno - 3.35.0-2 +- Update to NSS 3.35.0 + +* Tue Nov 14 2017 Daiki Ueno - 3.34.0-2 +- Update to NSS 3.34.0 + +* Fri Nov 10 2017 Daiki Ueno - 3.33.0-6 +- Make sure 32bit nss-pem always be installed with 32bit nss in + multlib environment, patch by Kamil Dudka + +* Wed Nov 8 2017 Kai Engert - 3.33.0-5 +- Fix test script + +* Tue Nov 7 2017 Kai Engert - 3.33.0-4 +- Update tests to be compatible with default NSS DB changed to sql + (the default was changed in the nss-util package). + +* Tue Oct 24 2017 Kai Engert - 3.33.0-3 +- rhbz#1505487, backport upstream fixes required for rhbz#1496560 + +* Tue Oct 3 2017 Daiki Ueno - 3.33.0-2 +- Update to NSS 3.33.0 + +* Fri Sep 15 2017 Daiki Ueno - 3.32.1-2 +- Update to NSS 3.32.1 + +* Wed Sep 6 2017 Daiki Ueno - 3.32.0-4 +- Update iquote.patch to really prefer in-tree headers over system headers + +* Wed Aug 23 2017 Kai Engert - 3.32.0-3 +- NSS libnssckbi.so has already been obsoleted by p11-kit-trust, rhbz#1484449 + +* Mon Aug 7 2017 Daiki Ueno - 3.32.0-2 +- Update to NSS 3.32.0 + +* Thu Aug 03 2017 Fedora Release Engineering - 3.31.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 3.31.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 18 2017 Daiki Ueno - 3.31.0-4 +- Backport mozbz#1381784 to avoid deadlock in dnf + +* Thu Jul 13 2017 Daiki Ueno - 3.31.0-3 +- Move signtool to %%_libdir/nss/unsupported-tools, for: + https://fedoraproject.org/wiki/Changes/NSSSigntoolDeprecation + +* Wed Jun 21 2017 Daiki Ueno - 3.31.0-2 +- Rebase to NSS 3.31.0 + +* Fri Jun 2 2017 Daiki Ueno - 3.30.2-3 +- Enable gtests + +* Mon Apr 24 2017 Daiki Ueno - 3.30.2-2 +- Rebase to NSS 3.30.2 +- Enable TLS 1.3 + +* Thu Mar 30 2017 Kai Engert - 3.30.0-3 +- Backport upstream mozbz#1328318 to support crypto policy FUTURE. + +* Tue Mar 21 2017 Daiki Ueno - 3.30.0-2 +- Rebase to NSS 3.30.0 +- Remove upstreamed patches + +* Thu Mar 02 2017 Kai Engert - 3.29.1-3 +- Backport mozbz#1334976 and mozbz#1336487. + +* Fri Feb 17 2017 Daiki Ueno - 3.29.1-2 +- Rebase to NSS 3.29.1 + +* Thu Feb 9 2017 Daiki Ueno - 3.29.0-3 +- Disable TLS 1.3, following the upstream change + +* Wed Feb 8 2017 Daiki Ueno - 3.29.0-2 +- Rebase to NSS 3.29.0 +- Suppress -Werror=int-in-bool-context warnings with GCC7 + +* Mon Jan 23 2017 Daiki Ueno - 3.28.1-6 +- Work around pkgconfig -> pkgconf transition issue (releng#6597) + +* Fri Jan 20 2017 Daiki Ueno - 3.28.1-5 +- Disable TLS 1.3 +- Add "Conflicts" with packages using older Mozilla codebase, which is + not compatible with NSS 3.28.1 +- Remove NSS_ECC_MORE_THAN_SUITE_B setting, as it was removed in upstream + +* Tue Jan 17 2017 Daiki Ueno - 3.28.1-4 +- Add "Conflicts" with older firefox packages which don't have support + for smaller curves added in NSS 3.28.1 + +* Fri Jan 13 2017 Daiki Ueno - 3.28.1-3 +- Fix incorrect version specification in %%nss_{util,softokn}_version, + pointed by Elio Maldonado + +* Fri Jan 6 2017 Daiki Ueno - 3.28.1-2 +- Rebase to NSS 3.28.1 +- Remove upstreamed patch for disabling RSA-PSS +- Re-enable TLS 1.3 + +* Wed Nov 30 2016 Daiki Ueno - 3.27.2-2 +- Rebase to NSS 3.27.2 + +* Tue Nov 15 2016 Daiki Ueno - 3.27.0-5 +- Revert the previous fix for RSA-PSS and use the upstream fix instead + +* Wed Nov 02 2016 Kai Engert - 3.27.0-4 +- Disable the use of RSA-PSS with SSL/TLS. #1383809 + +* Sun Oct 2 2016 Daiki Ueno - 3.27.0-3 +- Disable TLS 1.3 for now, to avoid reported regression with TLS to + version intolerant servers + +* Thu Sep 29 2016 Daiki Ueno - 3.27.0-2 +- Rebase to NSS 3.27.0 +- Remove upstreamed ectest patch + +* Mon Aug 8 2016 Daiki Ueno - 3.26.0-2 +- Rebase to NSS 3.26.0 +- Update check policy file patch to better match what was upstreamed +- Remove conditionally ignore system policy patch as it has been upstreamed +- Skip ectest as well as ecperf, which are built as part of nss-softokn +- Fix rpmlint error regarding %%define usage + +* Thu Jul 14 2016 Elio Maldonado - 3.25.0-6 +- Incorporate some changes requested in upstream review and commited upstream (#1157720) + +* Fri Jul 01 2016 Elio Maldonado - 3.25.0-5 +- Add support for conditionally ignoring the system policy (#1157720) +- Remove unneeded test scripts patches in order to run more tests +- Remove unneeded test data modifications from the spec file + +* Tue Jun 28 2016 Elio Maldonado - 3.25.0-4 +- Remove obsolete patch and spurious lines from the spec file (#1347336) + +* Sun Jun 26 2016 Elio Maldonado - 3.25.0-3 +- Cleanup spec file and patches and add references to bugs filed upstream + +* Fri Jun 24 2016 Elio Maldonado - 3.25.0-2 +- Rebase to nss 3.25 + +* Thu Jun 16 2016 Kamil Dudka - 3.24.0-3 +- decouple nss-pem from the nss package (#1347336) + +* Fri Jun 03 2016 Elio Maldonado - 3.24.0-2.3 +- Apply the patch that was last introduced +- Renumber and reorder some of the patches +- Resolves: Bug 1342158 + +* Thu Jun 02 2016 Elio Maldonado - 3.24.0-2.2 +- Allow application requests to disable SSL v2 to succeed +- Resolves: Bug 1342158 - nss-3.24 does no longer support ssl V2, installation of IPA fails because nss init fails + +* Sun May 29 2016 Elio Maldonado - 3.24.0-2.1 +- Rebase to NSS 3.24.0 +- Restore setting the policy file location +- Make ssl tests scripts aware of policy +- Ajust tests data expected result for policy + +* Tue May 24 2016 Elio Maldonado - 3.24.0-2.0 +- Bootstrap build to rebase to NSS 3.24.0 +- Temporarily not setting the policy file location + +* Thu May 12 2016 Elio Maldonado - 3.23.0-9 +- Change POLICY_FILE to "nss.config" + +* Fri Apr 22 2016 Elio Maldonado - 3.23.0-8 +- Change POLICY_FILE to "nss.cfg" + +* Wed Apr 20 2016 Elio Maldonado - 3.23.0-7 +- Change the POLICY_PATH to "/etc/crypto-policies/back-ends" +- Regenerate the check policy patch with hg to provide more context + +* Thu Apr 14 2016 Elio Maldonado - 3.23.0-6 +- Fix typo in the last %%changelog entry + +* Thu Mar 24 2016 Elio Maldonado - 3.23.0-5 +- Load policy file if /etc/pki/nssdb/policy.cfg exists +- Resolves: Bug 1157720 - NSS should enforce the system-wide crypto policy + +* Tue Mar 08 2016 Elio Maldonado - 3.23.0-4 +- Remove unused patch rendered obsolete by pem update + +* Tue Mar 08 2016 Elio Maldonado - 3.23.0-3 +- Update pem sources to latest from nss-pem upstream +- Resolves: Bug 1300652 - [PEM] insufficient input validity checking while loading a private key + +* Sat Mar 05 2016 Elio Maldonado - 3.23.0-2 +- Rebase to NSS 3.23 + +* Sat Feb 27 2016 Elio Maldonado - 3.22.2-2 +- Rebase to NSS 3.22.2 + +* Tue Feb 23 2016 Elio Maldonado - 3.22.1-3 +- Fix ssl2/exp test disabling to run all the required tests + +* Sun Feb 21 2016 Elio Maldonado - 3.22.1-1 +- Rebase to NSS 3.22.1 + +* Mon Feb 08 2016 Elio Maldonado - 3.22.0-3 +- Update .gitignore as part of updating to nss 3.22 + +* Mon Feb 08 2016 Elio Maldonado - 3.22.0-2 +- Update to NSS 3.22 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.21.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Fri Jan 15 2016 Elio Maldonado - 3.21.0-6 +- Resolves: Bug 1299040 - Enable ssl_gtests upstream test suite +- Remove 'export NSS_DISABLE_GTESTS=1' go ssl_gtests are built +- Use %%define when specifying the nss_tests to run + +* Wed Dec 30 2015 Michal Toman - 3.21.0-5 +- Add 64-bit MIPS to multilib arches + +* Fri Nov 20 2015 Elio Maldonado - 3.21.0-4 +- Update %%{nss_util_version} and %%{nss_softokn_version} to 3.21.0 +- Resolves: Bug 1284095 - all https fails with sec_error_no_token + +* Sun Nov 15 2015 Elio Maldonado - 3.21.0-3 +- Add references to bugs filed upstream + +* Fri Nov 13 2015 Elio Maldonado Batiz - 3.21.1-2 +- Update to NSS 3.21 +- Package listsuites as part of the unsupported tools set +- Resolves: Bug 1279912 - nss-3.21 is available +- Resolves: Bug 1258425 - Use __isa_bits macro instead of list of 64-bit +- Resolves: Bug 1280032 - Package listsuites as part of the nss unsupported tools set + +* Fri Oct 30 2015 Elio Maldonado - 3.20.1-2 +- Update to NSS 3.20.1 + +* Wed Sep 30 2015 Elio Maldonado - 3.20.0-6 +- Enable ECC cipher-suites by default [hrbz#1185708] +- Split the enabling patch in two for easier maintenance +- Remove unused patches rendered obsolete by prior rebase + +* Wed Sep 16 2015 Elio Maldonado - 3.20.0-5 +- Enable ECC cipher-suites by default [hrbz#1185708] +- Implement corrections requested in code review + +* Tue Sep 15 2015 Elio Maldonado - 3.20.0-4 +- Enable ECC cipher-suites by default [hrbz#1185708] + +* Mon Sep 14 2015 Elio Maldonado - 3.20.0-3 +- Fix patches that disable ssl2 and export cipher suites support +- Fix libssl patch that disable ssl2 & export cipher suites to not disable RSA_WITH_NULL ciphers +- Fix syntax errors in patch to skip ssl2 and export cipher suite tests +- Turn ssl2 off by default in the tstclnt tool +- Disable ssl stress tests containing TLS RC4 128 with MD5 + +* Thu Aug 20 2015 Elio Maldonado - 3.20.0-2 +- Update to NSS 3.20 + +* Sat Aug 08 2015 Elio Maldonado - 3.19.3-2 +- Update to NSS 3.19.3 + +* Fri Jun 26 2015 Elio Maldonado - 3.19.2-3 +- Create on the fly versions of sslcov.txt and sslstress.txt that disable tests for SSL2 and EXPORT ciphers + +* Wed Jun 17 2015 Kai Engert - 3.19.2-2 +- Update to NSS 3.19.2 + +* Thu May 28 2015 Kai Engert - 3.19.1-2 +- Update to NSS 3.19.1 + +* Tue May 19 2015 Kai Engert - 3.19.0-2 +- Update to NSS 3.19 + +* Fri May 15 2015 Kai Engert - 3.18.0-2 +- Replace expired test certificates, upstream bug 1151037 + +* Thu Mar 19 2015 Elio Maldonado - 3.18.0-1 +- Update to nss-3.18.0 +- Resolves: Bug 1203689 - nss-3.18 is available + +* Tue Mar 03 2015 Elio Maldonado - 3.17.4-5 +- Disable export suites and SSL2 support at build time +- Fix syntax errors in various shell scripts +- Resolves: Bug 1189952 - Disable SSL2 and the export cipher suites + +* Sat Feb 21 2015 Till Maas - 3.17.4-4 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Tue Feb 10 2015 Elio Maldonado - 3.17.4-3 +- Commented out the export NSS_NO_SSL2=1 line to not disable ssl2 +- Backing out from disabling ssl2 until the patches are fixed + +* Mon Feb 09 2015 Elio Maldonado - 3.17.4-2 +- Disable SSL2 support at build time +- Fix syntax errors in various shell scripts +- Resolves: Bug 1189952 - Disable SSL2 and the export cipher suites + +* Wed Jan 28 2015 Elio Maldonado - 3.17.4-1 +- Update to nss-3.17.4 + +* Sat Jan 24 2015 Ville Skyttä - 3.17.3-4 +- Own the %%{_datadir}/doc/nss-tools dir + +* Tue Dec 16 2014 Elio Maldonado - 3.17.3-3 +- Resolves: Bug 987189 - nss-tools RPM conflicts with perl-PAR-Packer +- Install pp man page in %%{_datadir}/doc/nss-tools/pp.1 +- Use %%{_mandir} instead of /usr/share/man as more generic + +* Mon Dec 15 2014 Elio Maldonado - 3.17.3-2 +- Install pp man page in alternative location +- Resolves: Bug 987189 - nss-tools RPM conflicts with perl-PAR-Packer + +* Fri Dec 05 2014 Elio Maldonado - 3.17.3-1 +- Update to nss-3.17.3 +- Resolves: Bug 1171012 - nss-3.17.3 is available + +* Thu Oct 16 2014 Elio Maldonado - 3.17.2-2 +- Resolves: Bug 994599 - Enable TLS 1.2 by default + +* Sun Oct 12 2014 Elio Maldonado - 3.17.2-1 +- Update to nss-3.17.2 + +* Wed Sep 24 2014 Kai Engert - 3.17.1-1 +- Update to nss-3.17.1 +- Add a mechanism to skip test suite execution during development work + +* Thu Aug 21 2014 Kevin Fenzi - 3.17.0-2 +- Rebuild for rpm bug 1131960 + +* Tue Aug 19 2014 Elio Maldonado - 3.17.0-1 +- Update to nss-3.17.0 + +* Sun Aug 17 2014 Fedora Release Engineering - 3.16.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Wed Jul 30 2014 Elio Maldonado - 3.16.2-3 +- Replace expired PayPal test cert with current one to prevent build failure + +* Fri Jul 18 2014 Tom Callaway - 3.16.2-2 +- fix license handling + +* Sun Jun 29 2014 Elio Maldonado - 3.16.2-1 +- Update to nss-3.16.2 + +* Sun Jun 15 2014 Elio Maldonado - 3.16.1-4 +- Remove unwanted source directories at end of %%prep so it truly does it +- Skip the cipher suite already run as part of the nss-softokn build + +* Sat Jun 07 2014 Fedora Release Engineering - 3.16.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon May 12 2014 Jaromir Capik - 3.16.1-2 +- Replacing ppc64 and ppc64le with the power64 macro +- Related: Bug 1052545 - Trivial change for ppc64le in nss spec + +* Tue May 06 2014 Elio Maldonado - 3.16.1-1 +- Update to nss-3.16.1 +- Update the iquote patch on account of the rebase +- Improve error detection in the %%section +- Resolves: Bug 1094702 - nss-3.16.1 is available + +* Tue Mar 18 2014 Elio Maldonado - 3.16.0-1 +- Update to nss-3.16.0 +- Cleanup the copying of the tools man pages +- Update the iquote.patch on account of the rebase + +* Tue Mar 04 2014 Elio Maldonado - 3.15.5-2 +- Restore requiring nss_softokn_version >= 3.15.5 + +* Wed Feb 19 2014 Elio Maldonado - 3.15.5-1 +- Update to nss-3.15.5 +- Temporarily requiring only nss_softokn_version >= 3.15.4 +- Fix location of sharedb files and their manpages +- Move cert9.db, key4.db, and pkcs11.txt to the main package +- Move nss-sysinit manpages tar archives to the main package +- Resolves: Bug 1066877 - nss-3.15.5 is available +- Resolves: Bug 1067091 - Move sharedb files to the %%files section + +* Thu Feb 06 2014 Elio Maldonado - 3.15.4-5 +- Revert previous change that moved some sysinit manpages +- Restore nss-sysinit manpages tar archives to %%files sysinit +- Removing spurious wildcard entry was the only change needed + +* Mon Jan 27 2014 Elio Maldonado - 3.15.4-4 +- Add explanatory comments for iquote.patch as was done on f20 + +* Sat Jan 25 2014 Elio Maldonado - 3.15.4-3 +- Update pem sources to latest from nss-pem upstream +- Pick up pem fixes verified on RHEL and applied upstream +- Fix a problem where same files in two rpms created rpm conflict +- Move some nss-sysinit manpages tar archives to the %%files the +- All man pages are listed by name so there shouldn't be wildcard inclusion +- Add support for ppc64le, Resolves: Bug 1052545 + +* Mon Jan 20 2014 Peter Robinson 3.15.4-2 +- ARM tests pass so remove ARM conditional + +* Tue Jan 07 2014 Elio Maldonado - 3.15.4-1 +- Update to nss-3.15.4 (hg tag NSS_3_15_4_RTM) +- Resolves: Bug 1049229 - nss-3.15.4 is available +- Update pem sources to latest from the interim upstream for pem +- Remove no longer needed patches +- Update pem/rsawrapr.c patch on account of upstream changes to freebl/softoken +- Update iquote.patch on account of upstream changes + +* Wed Dec 11 2013 Elio Maldonado - 3.15.3.1-1 +- Update to nss-3.15.3.1 (hg tag NSS_3_15_3_1_RTM) +- Resolves: Bug 1040282 - nss: Mis-issued ANSSI/DCSSI certificate (MFSA 2013-117) +- Resolves: Bug 1040192 - nss-3.15.3.1 is available + +* Tue Dec 03 2013 Elio Maldonado - 3.15.3-2 +- Bump the release tag + +* Sun Nov 24 2013 Elio Maldonado - 3.15.3-1 +- Update to NSS_3_15_3_RTM +- Resolves: Bug 1031897 - CVE-2013-5605 CVE-2013-5606 CVE-2013-1741 nss: various flaws +- Fix option descriptions for setup-nsssysinit manpage +- Fix man page of nss-sysinit wrong path and other flaws +- Document email option for certutil manpage +- Remove unused patches + +* Sun Oct 27 2013 Elio Maldonado - 3.15.2-3 +- Revert one change from last commit to preserve full nss pluggable ecc supprt [1019245] + +* Wed Oct 23 2013 Elio Maldonado - 3.15.2-2 +- Use the full sources from upstream +- Bug 1019245 - ECDHE in openssl available -> NSS needs too for Firefox/Thunderbird + +* Thu Sep 26 2013 Elio Maldonado - 3.15.2-1 +- Update to NSS_3_15_2_RTM +- Update iquote.patch on account of modified prototype on cert.h installed by nss-devel + +* Wed Aug 28 2013 Elio Maldonado - 3.15.1-7 +- Update pem sources to pick up a patch applied upstream which a faulty merge had missed +- The pem module should not require unique file basenames + +* Tue Aug 27 2013 Elio Maldonado - 3.15.1-6 +- Update pem sources to the latest from interim upstream + +* Mon Aug 19 2013 Elio Maldonado - 3.15.1-5 +- Resolves: rhbz#996639 - Minor bugs in nss man pages +- Fix some typos and improve description and see also sections + +* Sun Aug 11 2013 Elio Maldonado - 3.15.1-4 +- Cleanup spec file to address most rpmlint errors and warnings +- Using double percent symbols to fix macro-in-comment warnings +- Ignore unversioned-explicit-provides nss-system-init per spec comments +- Ignore invalid-url Source0 as it comes from the git lookaside cache +- Ignore invalid-url Source12 as it comes from the git lookaside cache + +* Thu Jul 25 2013 Elio Maldonado - 3.15.1-3 +- Add man page for pkcs11.txt configuration file and cert and key databases +- Resolves: rhbz#985114 - Provide man pages for the nss configuration files + +* Fri Jul 19 2013 Elio Maldonado - 3.15.1-2 +- Fix errors in the man pages +- Resolves: rhbz#984106 - Add missing option descriptions to man pages for {cert|cms|crl}util +- Resolves: rhbz#982856 - Fix path to script in man page for nss-sysinit + +* Tue Jul 02 2013 Elio Maldonado - 3.15.1-1 +- Update to NSS_3_15_1_RTM +- Enable the iquote.patch to access newly introduced types + +* Wed Jun 19 2013 Elio Maldonado - 3.15-5 +- Install man pages for nss-tools and the nss-config and setup-nsssysinit scripts +- Resolves: rhbz#606020 - nss security tools lack man pages + +* Tue Jun 18 2013 emaldona - 3.15-4 +- Build nss without softoken or util sources in the tree +- Resolves: rhbz#689918 + +* Mon Jun 17 2013 emaldona - 3.15-3 +- Update ssl-cbc-random-iv-by-default.patch + +* Sun Jun 16 2013 Elio Maldonado - 3.15-2 +- Fix generation of NSS_VMAJOR, NSS_VMINOR, and NSS_VPATCH for nss-config + +* Sat Jun 15 2013 Elio Maldonado - 3.15-1 +- Update to NSS_3_15_RTM + +* Wed Apr 24 2013 Elio Maldonado - 3.15-0.1.beta1.2 +- Fix incorrect path that hid failed test from view +- Add ocsp to the test suites to run but ... +- Temporarily disable the ocsp stapling tests +- Do not treat failed attempts at ssl pkcs11 bypass as fatal errors + +* Thu Apr 04 2013 Elio Maldonado - 3.15-0.1.beta1.1 +- Update to NSS_3_15_BETA1 +- Update spec file, patches, and helper scripts on account of a shallower source tree + +* Sun Mar 24 2013 Kai Engert - 3.14.3-12 +- Update expired test certificates (fixed in upstream bug 852781) + +* Fri Mar 08 2013 Kai Engert - 3.14.3-10 +- Fix incorrect post/postun scripts. Fix broken links in posttrans. + +* Wed Mar 06 2013 Kai Engert - 3.14.3-9 +- Configure libnssckbi.so to use the alternatives system + in order to prepare for a drop in replacement. + +* Fri Feb 15 2013 Elio Maldonado - 3.14.3-1 +- Update to NSS_3_14_3_RTM +- sync up pem rsawrapr.c with softoken upstream changes for nss-3.14.3 +- Resolves: rhbz#908257 - CVE-2013-1620 nss: TLS CBC padding timing attack +- Resolves: rhbz#896651 - PEM module trashes private keys if login fails +- Resolves: rhbz#909775 - specfile support for AArch64 +- Resolves: rhbz#910584 - certutil -a does not produce ASCII output + +* Mon Feb 04 2013 Elio Maldonado - 3.14.2-2 +- Allow building nss against older system sqlite + +* Fri Feb 01 2013 Elio Maldonado - 3.14.2-1 +- Update to NSS_3_14_2_RTM + +* Wed Jan 02 2013 Kai Engert - 3.14.1-3 +- Update to NSS_3_14_1_WITH_CKBI_1_93_RTM + +* Sat Dec 22 2012 Elio Maldonado - 3.14.1-2 +- Require nspr >= 4.9.4 +- Fix changelog invalid dates + +* Mon Dec 17 2012 Elio Maldonado - 3.14.1-1 +- Update to NSS_3_14_1_RTM + +* Wed Dec 12 2012 Elio Maldonado - 3.14-12 +- Bug 879978 - Install the nssck.api header template where mod_revocator can access it +- Install nssck.api in /usr/includes/nss3/templates + +* Tue Nov 27 2012 Elio Maldonado - 3.14-11 +- Bug 879978 - Install the nssck.api header template in a place where mod_revocator can access it +- Install nssck.api in /usr/includes/nss3 + +* Mon Nov 19 2012 Elio Maldonado - 3.14-10 +- Bug 870864 - Add support in NSS for Secure Boot + +* Sat Nov 10 2012 Elio Maldonado - 3.14-9 +- Disable bypass code at build time and return failure on attempts to enable at runtime +- Bug 806588 - Disable SSL PKCS #11 bypass at build time + +* Sun Nov 04 2012 Elio Maldonado - 3.14-8 +- Fix pk11wrap locking which fixes 'fedpkg new-sources' and 'fedpkg update' hangs +- Bug 872124 - nss-3.14 breaks fedpkg new-sources +- Fix should be considered preliminary since the patch may change upon upstream approval + +* Thu Nov 01 2012 Elio Maldonado - 3.14-7 +- Add a dummy source file for testing /preventing fedpkg breakage +- Helps test the fedpkg new-sources and upload commands for breakage by nss updates +- Related to Bug 872124 - nss 3.14 breaks fedpkg new-sources + +* Thu Nov 01 2012 Elio Maldonado - 3.14-6 +- Fix a previous unwanted merge from f18 +- Update the SS_SSL_CBC_RANDOM_IV patch to match new sources while +- Keeping the patch disabled while we are still in rawhide and +- State in comment that patch is needed for both stable and beta branches +- Update .gitignore to download only the new sources + +* Wed Oct 31 2012 Elio Maldonado - 3.14-5 +- Fix the spec file so sechash.h gets installed +- Resolves: rhbz#871882 - missing header: sechash.h in nss 3.14 + +* Sat Oct 27 2012 Elio Maldonado - 3.14-4 +- Update the license to MPLv2.0 + +* Wed Oct 24 2012 Elio Maldonado - 3.14-3 +- Use only -f when removing unwanted headers + +* Tue Oct 23 2012 Elio Maldonado - 3.14-2 +- Add secmodt.h to the headers installed by nss-devel +- nss-devel must install secmodt.h which moved from softoken to pk11wrap with nss-3.14 + +* Mon Oct 22 2012 Elio Maldonado - 3.14-1 +- Update to NSS_3_14_RTM + +* Sun Oct 21 2012 Elio Maldonado - 3.14-0.1.rc.1 +- Update to NSS_3_14_RC1 +- update nss-589636.patch to apply to httpdserv +- turn off ocsp tests for now +- remove no longer needed patches +- remove headers shipped by nss-util + +* Fri Oct 05 2012 Kai Engert - 3.13.6-1 +- Update to NSS_3_13_6_RTM + +* Mon Aug 27 2012 Elio Maldonado - 3.13.5-8 +- Rebase pem sources to fedora-hosted upstream to pick up two fixes from rhel-6.3 +- Resolves: rhbz#847460 - Fix invalid read and free on invalid cert load +- Resolves: rhbz#847462 - PEM module may attempt to free uninitialized pointer +- Remove unneeded fix gcc 4.7 c++ issue in secmodt.h that actually undoes the upstream fix + +* Mon Aug 13 2012 Elio Maldonado - 3.13.5-7 +- Fix pluggable ecc support + +* Fri Jul 20 2012 Fedora Release Engineering - 3.13.5-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun Jul 01 2012 Elio Maldonado - 3.13.5-5 +- Fix checkin comment to prevent unwanted expansions of percents + +* Sun Jul 01 2012 Elio Maldonado - 3.13.5-4 +- Resolves: Bug 830410 - Missing Requires %%{?_isa} +- Use Requires: %%{name}%%{?_isa} = %%{version}-%%{release} on tools +- Drop zlib requires which rpmlint reports as error E: explicit-lib-dependency zlib +- Enable sha224 portion of powerup selftest when running test suites +- Require nspr 4.9.1 + +* Wed Jun 20 2012 Elio Maldonado - 3.13.5-3 +- Resolves: rhbz#833529 - revert unwanted change to nss.pc.in + +* Tue Jun 19 2012 Elio Maldonado - 3.13.5-2 +- Resolves: rhbz#833529 - Remove unwanted space from the Libs: line on nss.pc.in + +* Mon Jun 18 2012 Elio Maldonado - 3.13.5-1 +- Update to NSS_3_13_5_RTM + +* Fri Apr 13 2012 Elio Maldonado - 3.13.4-3 +- Resolves: Bug 812423 - nss_Init leaks memory, fix from RHEL 6.3 + +* Sun Apr 08 2012 Elio Maldonado - 3.13.4-2 +- Resolves: Bug 805723 - Library needs partial RELRO support added +- Patch coreconf/Linux.mk as done on RHEL 6.2 + +* Fri Apr 06 2012 Elio Maldonado - 3.13.4-1 +- Update to NSS_3_13_4_RTM +- Update the nss-pem source archive to the latest version +- Remove no longer needed patches +- Resolves: Bug 806043 - use pem files interchangeably in a single process +- Resolves: Bug 806051 - PEM various flaws detected by Coverity +- Resolves: Bug 806058 - PEM pem_CreateObject leaks memory given a non-existing file name + +* Wed Mar 21 2012 Elio Maldonado - 3.13.3-4 +- Resolves: Bug 805723 - Library needs partial RELRO support added + +* Fri Mar 09 2012 Elio Maldonado - 3.13.3-3 +- Cleanup of the spec file +- Add references to the upstream bugs +- Fix typo in Summary for sysinit + +* Thu Mar 08 2012 Elio Maldonado - 3.13.3-2 +- Pick up fixes from RHEL +- Resolves: rhbz#800674 - Unable to contact LDAP Server during winsync +- Resolves: rhbz#800682 - Qpid AMQP daemon fails to load after nss update +- Resolves: rhbz#800676 - NSS workaround for freebl bug that causes openswan to drop connections + +* Thu Mar 01 2012 Elio Maldonado - 3.13.3-1 +- Update to NSS_3_13_3_RTM + +* Mon Jan 30 2012 Tom Callaway - 3.13.1-13 +- fix issue with gcc 4.7 in secmodt.h and C++11 user-defined literals + +* Thu Jan 26 2012 Elio Maldonado - 3.13.1-12 +- Resolves: Bug 784672 - nss should protect against being called before nss_Init + +* Fri Jan 13 2012 Fedora Release Engineering - 3.13.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Jan 06 2012 Elio Maldonado - 3.13.1-11 +- Deactivate a patch currently meant for stable branches only + +* Fri Jan 06 2012 Elio Maldonado - 3.13.1-10 +- Resolves: Bug 770682 - nss update breaks pidgin-sipe connectivity +- NSS_SSL_CBC_RANDOM_IV set to 0 by default and changed to 1 on user request + +* Tue Dec 13 2011 elio maldonado - 3.13.1-9 +- Revert to using current nss_softokn_version +- Patch to deal with lack of sha224 is no longer needed + +* Tue Dec 13 2011 Elio Maldonado - 3.13.1-8 +- Resolves: Bug 754771 - [PEM] an unregistered callback causes a SIGSEGV + +* Mon Dec 12 2011 Elio Maldonado - 3.13.1-7 +- Resolves: Bug 750376 - nss 3.13 breaks sssd TLS +- Fix how pem is built so that nss-3.13.x works with nss-softokn-3.12.y +- Only patch blapitest for the lack of sha224 on system freebl +- Completed the patch to make pem link against system freebl + +* Mon Dec 05 2011 Elio Maldonado - 3.13.1-6 +- Removed unwanted /usr/include/nss3 in front of the normal cflags include path +- Removed unnecessary patch dealing with CERTDB_TERMINAL_RECORD, it's visible + +* Sun Dec 04 2011 Elio Maldonado - 3.13.1-5 +- Statically link the pem module against system freebl found in buildroot +- Disabling sha224-related powerup selftest until we update softokn +- Disable sha224 and pss tests which nss-softokn 3.12.x doesn't support + +* Fri Dec 02 2011 Elio Maldonado Batiz - 3.13.1-4 +- Rebuild with nss-softokn from 3.12 in the buildroot +- Allows the pem module to statically link against 3.12.x freebl +- Required for using nss-3.13.x with nss-softokn-3.12.y for a merge inrto rhel git repo +- Build will be temprarily placed on buildroot override but not pushed in bodhi + +* Fri Nov 04 2011 Elio Maldonado - 3.13.1-2 +- Fix broken dependencies by updating the nss-util and nss-softokn versions + +* Thu Nov 03 2011 Elio Maldonado - 3.13.1-1 +- Update to NSS_3_13_1_RTM +- Update builtin certs to those from NSSCKBI_1_88_RTM + +* Sat Oct 15 2011 Elio Maldonado - 3.13-1 +- Update to NSS_3_13_RTM + +* Sat Oct 08 2011 Elio Maldonado - 3.13-0.1.rc0.1 +- Update to NSS_3_13_RC0 + +* Wed Sep 14 2011 Elio Maldonado - 3.12.11-3 +- Fix attempt to free initilized pointer (#717338) +- Fix leak on pem_CreateObject when given non-existing file name (#734760) +- Fix pem_Initialize to return CKR_CANT_LOCK on multi-treaded calls (#736410) + +* Tue Sep 06 2011 Kai Engert - 3.12.11-2 +- Update builtins certs to those from NSSCKBI_1_87_RTM + +* Tue Aug 09 2011 Elio Maldonado - 3.12.11-1 +- Update to NSS_3_12_11_RTM + +* Sat Jul 23 2011 Elio Maldonado - 3.12.10-6 +- Indicate the provenance of stripped source tarball (#688015) + +* Mon Jun 27 2011 Michael Schwendt - 3.12.10-5 +- Provide virtual -static package to meet guidelines (#609612). + +* Fri Jun 10 2011 Elio Maldonado - 3.12.10-4 +- Enable pluggable ecc support (#712556) +- Disable the nssdb write-access-on-read-only-dir tests when user is root (#646045) + +* Fri May 20 2011 Dennis Gilmore - 3.12.10-3 +- make the testsuite non fatal on arm arches + +* Tue May 17 2011 Elio Maldonado - 3.12.10-2 +- Fix crmf hard-coded maximum size for wrapped private keys (#703656) + +* Fri May 06 2011 Elio Maldonado - 3.12.10-1 +- Update to NSS_3_12_10_RTM + +* Wed Apr 27 2011 Elio Maldonado - 3.12.10-0.1.beta1 +- Update to NSS_3_12_10_BETA1 + +* Mon Apr 11 2011 Elio Maldonado - 3.12.9-15 +- Implement PEM logging using NSPR's own (#695011) + +* Wed Mar 23 2011 Elio Maldonado - 3.12.9-14 +- Update to NSS_3.12.9_WITH_CKBI_1_82_RTM + +* Thu Feb 24 2011 Elio Maldonado - 3.12.9-13 +- Short-term fix for ssl test suites hangs on ipv6 type connections (#539183) + +* Fri Feb 18 2011 Elio Maldonado - 3.12.9-12 +- Add a missing requires for pkcs11-devel (#675196) + +* Tue Feb 15 2011 Elio Maldonado - 3.12.9-11 +- Run the test suites in the check section (#677809) + +* Thu Feb 10 2011 Elio Maldonado - 3.12.9-10 +- Fix cms headers to not use c++ reserved words (#676036) +- Reenabling Bug 499444 patches +- Fix to swap internal key slot on fips mode switches + +* Tue Feb 08 2011 Elio Maldonado - 3.12.9-9 +- Revert patches for 499444 until all c++ reserved words are found and extirpated + +* Tue Feb 08 2011 Fedora Release Engineering - 3.12.9-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Feb 08 2011 Elio Maldonado - 3.12.9-7 +- Fix cms header to not use c++ reserved word (#676036) +- Reenable patches for bug 499444 + +* Tue Feb 08 2011 Christopher Aillon - 3.12.9-6 +- Revert patches for 499444 as they use a C++ reserved word and + cause compilation of Firefox to fail + +* Fri Feb 04 2011 Elio Maldonado - 3.12.9-5 +- Fix the earlier infinite recursion patch (#499444) +- Remove a header that now nss-softokn-freebl-devel ships + +* Tue Feb 01 2011 Elio Maldonado - 3.12.9-4 +- Fix infinite recursion when encoding NSS enveloped/digested data (#499444) + +* Mon Jan 31 2011 Elio Maldonado - 3.12.9-3 +- Update the cacert trust patch per upstream review requests (#633043) + +* Wed Jan 19 2011 Elio Maldonado - 3.12.9-2 +- Fix to honor the user's cert trust preferences (#633043) +- Remove obsoleted patch + +* Wed Jan 12 2011 Elio Maldonado - 3.12.9-1 +- Update to 3.12.9 + +* Mon Dec 27 2010 Elio Maldonado - 3.12.9-0.1.beta2 +- Rebuilt according to fedora pre-release package naming guidelines + +* Fri Dec 10 2010 Elio Maldonado - 3.12.8.99.2-1 +- Update to NSS_3_12_9_BETA2 +- Fix libpnsspem crash when cacert dir contains other directories (#642433) + +* Wed Dec 08 2010 Elio Maldonado - 3.12.8.99.1-1 +- Update to NSS_3_12_9_BETA1 + +* Thu Nov 25 2010 Elio Maldonado - 3.12.8-9 +- Update pem source tar with fixes for 614532 and 596674 +- Remove no longer needed patches + +* Fri Nov 05 2010 Elio Maldonado - 3.12.8-8 +- Update PayPalEE.cert test certificate which had expired + +* Sun Oct 31 2010 Elio Maldonado - 3.12.8-7 +- Tell rpm not to verify md5, size, and modtime of configurations file + +* Mon Oct 18 2010 Elio Maldonado - 3.12.8-6 +- Fix certificates trust order (#643134) +- Apply nss-sysinit-userdb-first.patch last + +* Wed Oct 06 2010 Elio Maldonado - 3.12.8-5 +- Move triggerpostun -n nss-sysinit script ahead of the other ones (#639248) + +* Tue Oct 05 2010 Elio Maldonado - 3.12.8-4 +- Fix invalid %%postun scriptlet (#639248) + +* Wed Sep 29 2010 Elio Maldonado - 3.12.8-3 +- Replace posttrans sysinit scriptlet with a triggerpostun one (#636787) +- Fix and cleanup the setup-nsssysinit.sh script (#636792, #636801) + +* Mon Sep 27 2010 Elio Maldonado - 3.12.8-2 +- Add posttrans scriptlet (#636787) + +* Thu Sep 23 2010 Elio Maldonado - 3.12.8-1 +- Update to 3.12.8 +- Prevent disabling of nss-sysinit on package upgrade (#636787) +- Create pkcs11.txt with correct permissions regardless of umask (#636792) +- Setup-nsssysinit.sh reports whether nss-sysinit is turned on or off (#636801) +- Added provides pkcs11-devel-static to comply with packaging guidelines (#609612) + +* Sat Sep 18 2010 Elio Maldonado - 3.12.7.99.4-1 +- NSS 3.12.8 RC0 + +* Sun Sep 05 2010 Elio Maldonado - 3.12.7.99.3-2 +- Fix nss-util_version and nss_softokn_version required to be 3.12.7.99.3 + +* Sat Sep 04 2010 Elio Maldonado - 3.12.7.99.3-1 +- NSS 3.12.8 Beta3 +- Fix unclosed comment in renegotiate-transitional.patch + +* Sat Aug 28 2010 Elio Maldonado - 3.12.7-3 +- Change BuildRequries to available version of nss-util-devel + +* Sat Aug 28 2010 Elio Maldonado - 3.12.7-2 +- Define NSS_USE_SYSTEM_SQLITE and remove unneeded patch +- Add comments regarding an unversioned provides which triggers rpmlint warning +- Build requires nss-softokn-devel >= 3.12.7 + +* Mon Aug 16 2010 Elio Maldonado - 3.12.7-1 +- Update to 3.12.7 + +* Sat Aug 14 2010 Elio Maldonado - 3.12.6-12 +- Apply the patches to fix rhbz#614532 + +* Mon Aug 09 2010 Elio Maldonado - 3.12.6-11 +- Removed pem sourecs as they are in the cache + +* Mon Aug 09 2010 Elio Maldonado - 3.12.6-10 +- Add support for PKCS#8 encoded PEM RSA private key files (#614532) + +* Sat Jul 31 2010 Elio Maldonado - 3.12.6-9 +- Fix nsssysinit to return userdb ahead of systemdb (#603313) + +* Tue Jun 08 2010 Dennis Gilmore - 3.12.6-8 +- Require and BuildRequire >= the listed version not = + +* Tue Jun 08 2010 Elio Maldonado - 3.12.6-7 +- Require nss-softoken 3.12.6 + +* Sun Jun 06 2010 Elio Maldonado - 3.12.6-6 +- Fix SIGSEGV within CreateObject (#596674) + +* Mon Apr 12 2010 Elio Maldonado - 3.12.6-5 +- Update pem source tar to pick up the following bug fixes: +- PEM - Allow collect objects to search through all objects +- PEM - Make CopyObject return a new shallow copy +- PEM - Fix memory leak in pem_mdCryptoOperationRSAPriv + +* Wed Apr 07 2010 Elio Maldonado - 3.12.6-4 +- Update the test cert in the setup phase + +* Wed Apr 07 2010 Elio Maldonado - 3.12.6-3 +- Add sed to sysinit requires as setup-nsssysinit.sh requires it (#576071) +- Update PayPalEE test cert with unexpired one (#580207) + +* Thu Mar 18 2010 Elio Maldonado - 3.12.6-2 +- Fix ns.spec to not require nss-softokn (#575001) + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1.2 +- rebuilt with all tests enabled + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1.1 +- Using SSL_RENEGOTIATE_TRANSITIONAL as default while on transition period +- Disabling ssl tests suites until bug 539183 is resolved + +* Sat Mar 06 2010 Elio Maldonado - 3.12.6-1 +- Update to 3.12.6 +- Reactivate all tests +- Patch tools to validate command line options arguments + +* Mon Jan 25 2010 Elio Maldonado - 3.12.5-8 +- Fix curl related regression and general patch code clean up + +* Wed Jan 13 2010 Elio Maldonado - 3.12.5-5 +- retagging + +* Tue Jan 12 2010 Elio Maldonado - 3.12.5-1.1 +- Fix SIGSEGV on call of NSS_Initialize (#553638) + +* Wed Jan 06 2010 Elio Maldonado - 3.12.5-1.13.2 +- New version of patch to allow root to modify ystem database (#547860) + +* Thu Dec 31 2009 Elio Maldonado - 3.12.5-1.13.1 +- Temporarily disabling the ssl tests + +* Sat Dec 26 2009 Elio Maldonado - 3.12.5-1.13 +- Fix nsssysinit to allow root to modify the nss system database (#547860) + +* Fri Dec 25 2009 Elio Maldonado - 3.12.5-1.11 +- Fix an error introduced when adapting the patch for rhbz #546211 + +* Sat Dec 19 2009 Elio maldonado - 3.12.5-1.9 +- Remove left over trace statements from nsssysinit patching + +* Fri Dec 18 2009 Elio Maldonado - 3.12.5-2.7 +- Fix a misconstructed patch + +* Thu Dec 17 2009 Elio Maldonado - 3.12.5-1.6 +- Fix nsssysinit to enable apps to use system cert store, patch contributed by David Woodhouse (#546221) +- Fix spec so sysinit requires coreutils for post install scriplet (#547067) +- Fix segmentation fault when listing keys or certs in the database, patch contributed by Kamil Dudka (#540387) + +* Thu Dec 10 2009 Elio Maldonado - 3.12.5-1.5 +- Fix nsssysinit to set the default flags on the crypto module (#545779) +- Remove redundant header from the pem module + +* Wed Dec 09 2009 Elio Maldonado - 3.12.5-1.1 +- Remove unneeded patch + +* Thu Dec 03 2009 Elio Maldonado - 3.12.5-1.1 +- Retagging to include missing patch + +* Thu Dec 03 2009 Elio Maldonado - 3.12.5-1 +- Update to 3.12.5 +- Patch to allow ssl/tls clients to interoperate with servers that require renogiation + +* Fri Nov 20 2009 Elio Maldonado - 3.12.4-14.1 +- Retagging + +* Tue Oct 20 2009 Elio Maldonado - 3.12.4-13.1 +- Require nss-softoken of same architecture as nss (#527867) +- Merge setup-nsssysinit.sh improvements from F-12 (#527051) + +* Sat Oct 03 2009 Elio Maldonado - 3.12.4-13 +- User no longer prompted for a password when listing keys an empty system db (#527048) +- Fix setup-nsssysinit to handle more general formats (#527051) + +* Sun Sep 27 2009 Elio Maldonado - 3.12.4-12 +- Fix syntax error in setup-nsssysinit.sh + +* Sun Sep 27 2009 Elio Maldonado - 3.12.4-11 +- Fix sysinit to be under mozilla/security/nss/lib + +* Sat Sep 26 2009 Elio Maldonado - 3.12.4-10 +- Add nss-sysinit activation/deactivation script + +* Fri Sep 18 2009 Elio Maldonado - 3.12.4-8 +- Restoring nssutil and -rpath-link to nss-config for now - 522477 + +* Tue Sep 08 2009 Elio Maldonado - 3.12.4-6 +- Installing shared libraries to %%{_libdir} + +* Mon Sep 07 2009 Elio Maldonado - 3.12.4-5 +- Retagging to pick up new sources + +* Mon Sep 07 2009 Elio Maldonado - 3.12.4-4 +- Update pem enabling source tar with latest fixes (509705, 51209) + +* Sun Sep 06 2009 Elio Maldonado - 3.12.4-3 +- PEM module implements memory management for internal objects - 509705 +- PEM module doesn't crash when processing malformed key files - 512019 + +* Sat Sep 05 2009 Elio Maldonado - 3.12.4-2 +- Remove symbolic links to shared libraries from devel - 521155 +- No rpath-link in nss-softokn-config + +* Tue Sep 01 2009 Elio Maldonado - 3.12.4-1 +- Update to 3.12.4 + +* Mon Aug 31 2009 Elio Maldonado - 3.12.3.99.3-30 +- Fix FORTIFY_SOURCE buffer overflows in test suite on ppc and ppc64 - bug 519766 +- Fixed requires and buildrequires as per recommendations in spec file review + +* Sun Aug 30 2009 Elio Maldonado - 3.12.3.99.3-29 +- Restoring patches 2 and 7 as we still compile all sources +- Applying the nss-nolocalsql.patch solves nss-tools sqlite dependency problems + +* Sun Aug 30 2009 Elio Maldonado - 3.12.3.99.3-28 +- restore require sqlite + +* Sat Aug 29 2009 Elio Maldonado - 3.12.3.99.3-27 +- Don't require sqlite for nss + +* Sat Aug 29 2009 Elio Maldonado - 3.12.3.99.3-26 +- Ensure versions in the requires match those used when creating nss.pc + +* Fri Aug 28 2009 Elio Maldonado - 3.12.3.99.3-25 +- Remove nss-prelink.conf as signed all shared libraries moved to nss-softokn +- Add a temprary hack to nss.pc.in to unblock builds + +* Fri Aug 28 2009 Warren Togami - 3.12.3.99.3-24 +- caolan's nss.pc patch + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-23 +- Bump the release number for a chained build of nss-util, nss-softokn and nss + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-22 +- Fix nss-config not to include nssutil +- Add BuildRequires on nss-softokn and nss-util since build also runs the test suite + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-21 +- disabling all tests while we investigate a buffer overflow bug + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-20 +- disabling some tests while we investigate a buffer overflow bug - 519766 + +* Thu Aug 27 2009 Elio Maldonado - 3.12.3.99.3-19 +- remove patches that are now in nss-softokn and +- remove spurious exec-permissions for nss.pc per rpmlint +- single requires line in nss.pc.in + +* Wed Aug 26 2009 Elio Maldonado - 3.12.3.99.3-18 +- Fix BuildRequires: nss-softokn-devel release number + +* Wed Aug 26 2009 Elio Maldonado - 3.12.3.99.3-16 +- cleanups for softokn + +* Tue Aug 25 2009 Dennis Gilmore - 3.12.3.99.3-15 +- remove the softokn subpackages + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-14 +- don install the nss-util pkgconfig bits + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-13 +- remove from -devel the 3 headers that ship in nss-util-devel + +* Mon Aug 24 2009 Dennis Gilmore - 3.12.3.99.3-12 +- kill off the nss-util nss-util-devel subpackages + +* Sun Aug 23 2009 Elio Maldonado+emaldona@redhat.com - 3.12.3.99.3-11 +- split off nss-softokn and nss-util as subpackages with their own rpms +- first phase of splitting nss-softokn and nss-util as their own packages + +* Thu Aug 20 2009 Elio Maldonado - 3.12.3.99.3-10 +- must install libnssutil3.since nss-util is untagged at the moment +- preserve time stamps when installing various files + +* Thu Aug 20 2009 Dennis Gilmore - 3.12.3.99.3-9 +- dont install libnssutil3.so since its now in nss-util + +* Thu Aug 06 2009 Elio Maldonado - 3.12.3.99.3-7.1 +- Fix spec file problems uncovered by Fedora_12_Mass_Rebuild + +* Sat Jul 25 2009 Fedora Release Engineering - 3.12.3.99.3-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jun 22 2009 Elio Maldonado - 3.12.3.99.3-6 +- removed two patch files which are no longer needed and fixed previous change log number +* Mon Jun 22 2009 Elio Maldonado - 3.12.3.99.3-5 +- updated pem module incorporates various patches +- fix off-by-one error when computing size to reduce memory leak. (483855) +- fix data type to work on x86_64 systems. (429175) +- fix various memory leaks and free internal objects on module unload. (501080) +- fix to not clone internal objects in collect_objects(). (501118) +- fix to not bypass initialization if module arguments are omitted. (501058) +- fix numerous gcc warnings. (500815) +- fix to support arbitrarily long password while loading a private key. (500180) +- fix memory leak in make_key and memory leaks and return values in pem_mdSession_Login (501191) +* Mon Jun 08 2009 Elio Maldonado - 3.12.3.99.3-4 +- add patch for bug 502133 upstream bug 496997 +* Fri Jun 05 2009 Kai Engert - 3.12.3.99.3-3 +- rebuild with higher release number for upgrade sanity +* Fri Jun 05 2009 Kai Engert - 3.12.3.99.3-2 +- updated to NSS_3_12_4_FIPS1_WITH_CKBI_1_75 +* Thu May 07 2009 Kai Engert - 3.12.3-7 +- re-enable test suite +- add patch for upstream bug 488646 and add newer paypal + certs in order to make the test suite pass +* Wed May 06 2009 Kai Engert - 3.12.3-4 +- add conflicts info in order to fix bug 499436 +* Tue Apr 14 2009 Kai Engert - 3.12.3-3 +- ship .chk files instead of running shlibsign at install time +- include .chk file in softokn-freebl subpackage +- add patch for upstream nss bug 488350 +* Tue Apr 14 2009 Kai Engert - 3.12.3-2 +- Update to NSS 3.12.3 +* Mon Apr 06 2009 Kai Engert - 3.12.2.99.3-7 +- temporarily disable the test suite because of bug 494266 +* Mon Apr 06 2009 Kai Engert - 3.12.2.99.3-6 +- fix softokn-freebl dependency for multilib (bug 494122) +* Thu Apr 02 2009 Kai Engert - 3.12.2.99.3-5 +- introduce separate nss-softokn-freebl package +* Thu Apr 02 2009 Kai Engert - 3.12.2.99.3-4 +- disable execstack when building freebl +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-3 +- add upstream patch to fix bug 483855 +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-2 +- build nspr-less freebl library +* Tue Mar 31 2009 Kai Engert - 3.12.2.99.3-1 +- Update to NSS_3_12_3_BETA4 + +* Wed Feb 25 2009 Fedora Release Engineering - 3.12.2.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Oct 22 2008 Kai Engert - 3.12.2.0-3 +- update to NSS_3_12_2_RC1 +- use system zlib +* Tue Sep 30 2008 Dennis Gilmore - 3.12.1.1-4 +- add sparc64 to the list of 64 bit arches + +* Wed Sep 24 2008 Kai Engert - 3.12.1.1-3 +- bug 456847, move pkgconfig requirement to devel package +* Fri Sep 05 2008 Kai Engert - 3.12.1.1-2 +- Update to NSS_3_12_1_RC2 +* Fri Aug 22 2008 Kai Engert - 3.12.1.0-2 +- NSS 3.12.1 RC1 +* Fri Aug 15 2008 Kai Engert - 3.12.0.3-7 +- fix bug bug 429175 in libpem module +* Tue Aug 05 2008 Kai Engert - 3.12.0.3-6 +- bug 456847, add Requires: pkgconfig +* Tue Jun 24 2008 Kai Engert - 3.12.0.3-3 +- nss package should own /etc/prelink.conf.d folder, rhbz#452062 +- use upstream patch to fix test suite abort +* Mon Jun 02 2008 Kai Engert - 3.12.0.3-2 +- Update to NSS_3_12_RC4 +* Mon Apr 14 2008 Kai Engert - 3.12.0.1-1 +- Update to NSS_3_12_RC2 +* Thu Mar 20 2008 Jesse Keating - 3.11.99.5-2 +- Zapping old Obsoletes/Provides. No longer needed, causes multilib headache. +* Mon Mar 17 2008 Kai Engert - 3.11.99.5-1 +- Update to NSS_3_12_BETA3 +* Fri Feb 22 2008 Kai Engert - 3.11.99.4-1 +- NSS 3.12 Beta 2 +- Use /usr/lib{64} as devel libdir, create symbolic links. +* Sat Feb 16 2008 Kai Engert - 3.11.99.3-6 +- Apply upstream patch for bug 417664, enable test suite on pcc. +* Fri Feb 15 2008 Kai Engert - 3.11.99.3-5 +- Support concurrent runs of the test suite on a single build host. +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-4 +- disable test suite on ppc +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-3 +- disable test suite on ppc64 + +* Thu Feb 14 2008 Kai Engert - 3.11.99.3-2 +- Build against gcc 4.3.0, use workaround for bug 432146 +- Run the test suite after the build and abort on failures. + +* Thu Jan 24 2008 Kai Engert - 3.11.99.3-1 +* NSS 3.12 Beta 1 + +* Mon Jan 07 2008 Kai Engert - 3.11.99.2b-3 +- move .so files to /lib + +* Wed Dec 12 2007 Kai Engert - 3.11.99.2b-2 +- NSS 3.12 alpha 2b + +* Mon Dec 03 2007 Kai Engert - 3.11.99.2-2 +- upstream patches to avoid calling netstat for random data + +* Wed Nov 07 2007 Kai Engert - 3.11.99.2-1 +- NSS 3.12 alpha 2 + +* Wed Oct 10 2007 Kai Engert - 3.11.7-10 +- Add /etc/prelink.conf.d/nss-prelink.conf in order to blacklist + our signed libraries and protect them from modification. + +* Thu Sep 06 2007 Rob Crittenden - 3.11.7-9 +- Fix off-by-one error in the PEM module + +* Thu Sep 06 2007 Kai Engert - 3.11.7-8 +- fix a C++ mode compilation error + +* Wed Sep 05 2007 Bob Relyea - 3.11.7-7 +- Add 3.12 ckfw and libnsspem + +* Tue Aug 28 2007 Kai Engert - 3.11.7-6 +- Updated license tag + +* Wed Jul 11 2007 Kai Engert - 3.11.7-5 +- Ensure the workaround for mozilla bug 51429 really get's built. + +* Mon Jun 18 2007 Kai Engert - 3.11.7-4 +- Better approach to ship freebl/softokn based on 3.11.5 +- Remove link time dependency on softokn + +* Sun Jun 10 2007 Kai Engert - 3.11.7-3 +- Fix unowned directories, rhbz#233890 + +* Fri Jun 01 2007 Kai Engert - 3.11.7-2 +- Update to 3.11.7, but freebl/softokn remain at 3.11.5. +- Use a workaround to avoid mozilla bug 51429. + +* Fri Mar 02 2007 Kai Engert - 3.11.5-2 +- Fix rhbz#230545, failure to enable FIPS mode +- Fix rhbz#220542, make NSS more tolerant of resets when in the + middle of prompting for a user password. + +* Sat Feb 24 2007 Kai Engert - 3.11.5-1 +- Update to 3.11.5 +- This update fixes two security vulnerabilities with SSL 2 +- Do not use -rpath link option +- Added several unsupported tools to tools package + +* Tue Jan 9 2007 Bob Relyea - 3.11.4-4 +- disable ECC, cleanout dead code + +* Tue Nov 28 2006 Kai Engert - 3.11.4-1 +- Update to 3.11.4 + +* Thu Sep 14 2006 Kai Engert - 3.11.3-2 +- Revert the attempt to require latest NSPR, as it is not yet available + in the build infrastructure. + +* Thu Sep 14 2006 Kai Engert - 3.11.3-1 +- Update to 3.11.3 + +* Thu Aug 03 2006 Kai Engert - 3.11.2-2 +- Add /etc/pki/nssdb + +* Wed Jul 12 2006 Jesse Keating - 3.11.2-1.1 +- rebuild + +* Fri Jun 30 2006 Kai Engert - 3.11.2-1 +- Update to 3.11.2 +- Enable executable bit on shared libs, also fixes debug info. + +* Wed Jun 14 2006 Kai Engert - 3.11.1-2 +- Enable Elliptic Curve Cryptography (ECC) + +* Fri May 26 2006 Kai Engert - 3.11.1-1 +- Update to 3.11.1 +- Include upstream patch to limit curves + +* Wed Feb 15 2006 Kai Engert - 3.11-4 +- add --noexecstack when compiling assembler on x86_64 + +* Fri Feb 10 2006 Jesse Keating - 3.11-3.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 3.11-3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Jan 19 2006 Ray Strode 3.11-3 +- rebuild + +* Fri Dec 16 2005 Christopher Aillon 3.11-2 +- Update file list for the devel packages + +* Thu Dec 15 2005 Christopher Aillon 3.11-1 +- Update to 3.11 + +* Thu Dec 15 2005 Christopher Aillon 3.11-0.cvs.2 +- Add patch to allow building on ppc* +- Update the pkgconfig file to Require nspr + +* Thu Dec 15 2005 Christopher Aillon 3.11-0.cvs +- Initial import into Fedora Core, based on a CVS snapshot of + the NSS_3_11_RTM tag +- Fix up the pkcs11-devel subpackage to contain the proper headers +- Build with RPM_OPT_FLAGS +- No need to have rpath of /usr/lib in the pc file + +* Thu Dec 15 2005 Kai Engert +- Adressed review comments by Wan-Teh Chang, Bob Relyea, + Christopher Aillon. + +* Sat Jul 9 2005 Rob Crittenden 3.10-1 +- Initial build