File nss-CC-constructor_selftests.patch of Package mozilla-nss.972
# HG changeset patch
# Parent a4116725d048eff8480c58c19ba4abe30351b906
# Parent f829facc22ff686079f0db710fd693b527c6ca10
Perform necessary selftests in the libraaary constructors so that they get
called at library load time. Do not test non-FIPS-approved tests by default.
diff --git a/cmd/chktest/chktest.c b/cmd/chktest/chktest.c
--- a/cmd/chktest/chktest.c
+++ b/cmd/chktest/chktest.c
@@ -31,13 +31,13 @@ int main(int argc, char **argv)
}
rv = BL_Init();
if (rv != SECSuccess) {
SECU_PrintPRandOSError("");
return -1;
}
RNG_SystemInfoForRNG();
- good_result = BLAPI_SHVerifyFile(argv[1]);
+ good_result = BLAPI_SHVerifyFile(argv[1], NULL);
printf("%s\n",
(good_result ? "SUCCESS" : "FAILURE"));
return (good_result) ? SECSuccess : SECFailure;
}
diff --git a/lib/freebl/blapi.h b/lib/freebl/blapi.h
--- a/lib/freebl/blapi.h
+++ b/lib/freebl/blapi.h
@@ -1554,27 +1554,27 @@ extern void PQG_DestroyVerify(PQGVerify
extern void BL_Cleanup(void);
/* unload freebl shared library from memory */
extern void BL_Unload(void);
/**************************************************************************
* Verify a given Shared library signature *
**************************************************************************/
-PRBool BLAPI_SHVerify(const char *name, PRFuncPtr addr);
+PRBool BLAPI_SHVerify(const char *name, PRFuncPtr addr, int *err);
/**************************************************************************
* Verify a given filename's signature *
**************************************************************************/
-PRBool BLAPI_SHVerifyFile(const char *shName);
+PRBool BLAPI_SHVerifyFile(const char *shName, int *err);
/**************************************************************************
* Verify Are Own Shared library signature *
**************************************************************************/
-PRBool BLAPI_VerifySelf(const char *name);
+PRBool BLAPI_VerifySelf(const char *name, int *err);
/*********************************************************************/
extern const SECHashObject * HASH_GetRawHashObject(HASH_HashType hashType);
extern void BL_SetForkState(PRBool forked);
#ifndef NSS_DISABLE_ECC
/*
diff --git a/lib/freebl/fips-selftest.inc b/lib/freebl/fips-selftest.inc
new file mode 100644
--- /dev/null
+++ b/lib/freebl/fips-selftest.inc
@@ -0,0 +1,279 @@
+/*
+ * PKCS #11 FIPS Power-Up Self Test - common stuff.
+ *
+ * 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/. */
+
+#ifndef FIPS_INC
+#define FIPS_INC
+
+/* common functions used for FIPS selftests. Due to the modular design of NSS
+ * putting these into libfreebl would mean either amending the API represented
+ * by FREEBLVectorStr - which might cause problems with newer applications, or
+ * extending the API with another similar function set. Thus, to make things
+ * less complicated in the binaries, we mess up the source a bit. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <prtypes.h>
+#include <prerror.h>
+
+#include <prlink.h>
+
+#include "blapi.h"
+
+#define NSS_FORCE_FIPS_ENV "NSS_FIPS"
+#define FIPS_PROC_PATH "/proc/sys/crypto/fips_enabled"
+
+#define CHECKSUM_SUFFIX ".chk"
+
+typedef enum fips_check_status {
+ CHECK_UNCHECKED = -1,
+ CHECK_OK = 0,
+ CHECK_FAIL,
+ CHECK_FAIL_CRYPTO,
+ CHECK_MISSING
+} fips_check_status;
+
+/* initial value of FIPS state is -1 */
+static int fips_state = -1;
+
+static int fips_wanted = -1;
+
+/* debug messages are sent to stderr */
+static void
+debug(const char *fmt,...)
+{
+#ifdef DEBUG_FIPS
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fputc('\n', stderr);
+#endif
+ return;
+}
+
+/* Fatal messages ending with abort(); this function never returns */
+static void __attribute__ ((__noreturn__))
+fatal(const char *fmt,...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fputc('\n', stderr);
+ abort();
+}
+
+/* check whether FIPS moode is mandated by the kernel */
+static int
+fips_isWantedProc(void)
+{
+ int fips_wanted = 0;
+ int fips_fd;
+ char fips_sys = 0;
+
+ struct stat dummy;
+ if (-1 == stat(FIPS_PROC_PATH, &dummy)) {
+ switch (errno) {
+ case ENOENT:
+ case ENOTDIR:
+ break;
+ default:
+ fatal("Check for system-wide FIPS mode is required and %s cannot"
+ " be accessed for reason other than non-existence - aborting"
+ , FIPS_PROC_PATH);
+ break;
+ }
+ } else {
+ if (-1 == (fips_fd = open(FIPS_PROC_PATH, O_RDONLY))) {
+ fatal("Check for system-wide FIPS mode is required and %s cannot"
+ " be opened for reading - aborting"
+ , FIPS_PROC_PATH);
+ }
+ if (1 > read(fips_fd, &fips_sys, 1)) {
+ fatal("Check for system-wide FIPS mode is required and %s doesn't"
+ " return at least one character - aborting"
+ , FIPS_PROC_PATH);
+ }
+ close(fips_sys);
+ switch (fips_sys) {
+ case '0':
+ case '1':
+ fips_wanted = fips_sys - '0';
+ break;
+ default:
+ fatal("Bogus character %c found in %s - aborting"
+ , fips_sys, FIPS_PROC_PATH);
+ }
+ }
+ return fips_wanted;
+}
+
+/* "legacy" from lib/sysinit/nsssysinit.c */
+static PRBool
+getFIPSEnv(void)
+{
+ char *fipsEnv = getenv("NSS_FIPS");
+ if (!fipsEnv) {
+ return PR_FALSE;
+ }
+ if ((strcasecmp(fipsEnv,"fips") == 0) ||
+ (strcasecmp(fipsEnv,"true") == 0) ||
+ (strcasecmp(fipsEnv,"on") == 0) ||
+ (strcasecmp(fipsEnv,"1") == 0)) {
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+static int
+fips_isWantedEnv(void)
+{
+ return getFIPSEnv() ? 1 : 0;
+}
+
+static int
+fips_isWanted(void)
+{
+ int fips_requests = 0;
+#ifdef LINUX
+ fips_requests += fips_isWantedProc();
+#endif
+ fips_requests += fips_isWantedEnv();
+ return fips_requests;
+}
+
+/* check integrity signatures (if present) */
+static fips_check_status
+fips_checkSignature(char *libName, PRFuncPtr addr)
+{
+ PRBool rv;
+ fips_check_status rv_check = CHECK_UNCHECKED;
+ int l = PATH_MAX;
+ int err = 0;
+ int err_NOENT = 0;
+ char full_lib_name[PATH_MAX+1];
+ full_lib_name[0] = '\0';
+
+ if (NULL == libName) {
+ err_NOENT = ENOENT;
+ rv = BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX, &err);
+ } else {
+ err_NOENT = PR_FILE_NOT_FOUND_ERROR;
+ strncat(full_lib_name, SHLIB_PREFIX, l);
+ l -= strlen(SHLIB_PREFIX);
+ strncat(full_lib_name, libName, l);
+ l -= strlen(libName);
+ strncat(full_lib_name, SHLIB_VERSION"."SHLIB_SUFFIX, l);
+ l -= strlen(SHLIB_VERSION"."SHLIB_SUFFIX);
+ rv = BLAPI_SHVerify(full_lib_name, addr, &err);
+ }
+
+ if (rv) {
+ rv_check = CHECK_OK;
+ } else {
+ if (err_NOENT == err) {
+ rv_check = CHECK_MISSING;
+ } else {
+ rv_check = CHECK_FAIL;
+ }
+ }
+
+ return rv_check;
+}
+
+/* decide what to do depending on the results of tests and system/required FIPS
+ * mode */
+static int
+fips_resolve(fips_check_status check, char *libName)
+{
+ int state;
+
+ if (fips_wanted) {
+ switch (check) {
+ case CHECK_OK:
+ debug("fips - %s: mandatory checksum ok"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_FAIL:
+ fatal("fips - %s: mandatory checksum failed - aborting"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_FAIL_CRYPTO:
+ fatal("fips - %s: mandatory crypto test failed - aborting"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_MISSING:
+ fatal("fips - %s: mandatory checksum data missing - aborting"
+ , (libName) ? libName : "freebl");
+ break;
+ default:
+ fatal("Fatal error: internal error at %s:%u"
+ , __FILE__, __LINE__);
+ break;
+ }
+ state = 1;
+ } else {
+ switch (check) {
+ case CHECK_OK:
+ debug("fips - %s: checksum ok"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_FAIL:
+ fatal("fips - %s: checksum failed - aborting"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_FAIL_CRYPTO:
+ fatal("fips - %s: crypto test failed - aborting"
+ , (libName) ? libName : "freebl");
+ break;
+ case CHECK_MISSING:
+ debug("fips - %s: mandatory checksum data missing, but not required in non FIPS mode; continuing non-FIPS"
+ , (libName) ? libName : "freebl");
+ break;
+ default:
+ fatal("Fatal error: internal error at %s:%u"
+ , __FILE__, __LINE__);
+ break;
+ }
+ state = 0;
+ }
+ return state;
+}
+
+/* generic selftest
+ * libName and addr are the name of shared object to check and a function
+ * contained therein; (NULL, NULL) performs selfcheck of freebl.
+ * crypto_check is callback that performs cryptographic algorithms checks; NULL
+ * for libraries that do not implement any cryptographic algorithms per se
+ */
+static int
+fips_initTest(char *libName, PRFuncPtr addr, fips_check_status cryptoCheck(void))
+{
+ fips_check_status check = fips_checkSignature(libName, addr);
+
+ fips_wanted = fips_isWanted();
+
+ if ((cryptoCheck) && (CHECK_OK == check)) {
+ check = cryptoCheck();
+ debug("fips - %s: crypto check %s"
+ , (libName) ? libName : "freebl"
+ , (CHECK_OK == check) ? "ok" : "failed");
+ }
+
+ return fips_resolve(check, libName);
+}
+
+#endif
diff --git a/lib/freebl/fips.c b/lib/freebl/fips.c
new file mode 100644
--- /dev/null
+++ b/lib/freebl/fips.c
@@ -0,0 +1,69 @@
+/*
+ * PKCS #11 FIPS Power-Up Self Test.
+ *
+ * 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 "fips-selftest.inc"
+
+#include "fips.h"
+
+#define RNG_DEV_FIPS0 "/dev/urandom"
+#define RNG_DEV_FIPS1 "/dev/random"
+
+/* crypto algorithms selftest wrapper */
+static fips_check_status
+fips_checkCryptoFreebl(void)
+{
+ /* currently there are no crypto selftets in FreeBL, since it is not
+ * considered to be a stand-alone FIPS crypto module */
+ return CHECK_OK;
+}
+
+/* constructor - load-time selfchecks */
+static void __attribute__ ((constructor))
+fips_initTestFreebl(void)
+{
+ fips_state = fips_initTest(NULL, NULL, fips_checkCryptoFreebl);
+
+ debug("FIPS mode: %i\n", FIPS_mode());
+ return;
+}
+
+/* returns the FIPS mode we are running in or the one that we aspire to if the
+ * tests have not completed yet - which might happen during the crypto selftest
+ */
+int
+FIPS_mode(void)
+{
+ int fips;
+
+ /* until FIPS mode is cleared up, assume we are running in whatever is
+ * wanted by the environment */
+ fips = (-1 != fips_state) ? fips_state : fips_wanted;
+ switch (fips) {
+ case 0:
+ case 1:
+ return fips;
+ default:
+ fatal("Fatal error: internal error at %s:%u"
+ , __FILE__, __LINE__);
+ }
+}
+
+/* returns string specifying what system RNG file to use for seeding */
+char *
+FIPS_rngDev(void)
+{
+ switch (FIPS_mode()) {
+ case 0:
+ return RNG_DEV_FIPS0;
+ case 1:
+ return RNG_DEV_FIPS1;
+ default:
+ fatal("Fatal error: internal error at %s:%u"
+ , __FILE__, __LINE__);
+ }
+}
+
diff --git a/lib/freebl/fips.h b/lib/freebl/fips.h
new file mode 100644
--- /dev/null
+++ b/lib/freebl/fips.h
@@ -0,0 +1,15 @@
+/*
+ * PKCS #11 FIPS Power-Up Self Test.
+ *
+ * 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/. */
+
+#ifndef FIPS_H
+#define FIPS_H
+
+int FIPS_mode(void);
+char* FIPS_rngDev(void);
+
+#endif
+
diff --git a/lib/freebl/loader.c b/lib/freebl/loader.c
--- a/lib/freebl/loader.c
+++ b/lib/freebl/loader.c
@@ -1217,36 +1217,36 @@ AESKeyWrap_Decrypt(AESKeyWrapContext *cx
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return SECFailure;
return vector->p_AESKeyWrap_Decrypt(cx, output, outputLen, maxOutputLen,
input, inputLen);
}
PRBool
-BLAPI_SHVerify(const char *name, PRFuncPtr addr)
+BLAPI_SHVerify(const char *name, PRFuncPtr addr, int *err)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return PR_FALSE;
- return vector->p_BLAPI_SHVerify(name, addr);
+ return vector->p_BLAPI_SHVerify(name, addr, err);
}
/*
* The Caller is expected to pass NULL as the name, which will
* trigger the p_BLAPI_VerifySelf() to return 'TRUE'. Pass the real
* name of the shared library we loaded (the static libraryName set
* in freebl_LoadDSO) to p_BLAPI_VerifySelf.
*/
PRBool
-BLAPI_VerifySelf(const char *name)
+BLAPI_VerifySelf(const char *name, int *err)
{
PORT_Assert(!name);
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return PR_FALSE;
- return vector->p_BLAPI_VerifySelf(libraryName);
+ return vector->p_BLAPI_VerifySelf(libraryName, err);
}
/* ============== New for 3.006 =============================== */
SECStatus
EC_NewKey(ECParams * params, ECPrivateKey ** privKey)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
@@ -1831,21 +1831,21 @@ void
SHA224_Clone(SHA224Context *dest, SHA224Context *src)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_SHA224_Clone)(dest, src);
}
PRBool
-BLAPI_SHVerifyFile(const char *name)
+BLAPI_SHVerifyFile(const char *name, int *err)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return PR_FALSE;
- return vector->p_BLAPI_SHVerifyFile(name);
+ return vector->p_BLAPI_SHVerifyFile(name, err);
}
/* === new for DSA-2 === */
SECStatus
PQG_ParamGenV2( unsigned int L, unsigned int N, unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
diff --git a/lib/freebl/loader.h b/lib/freebl/loader.h
--- a/lib/freebl/loader.h
+++ b/lib/freebl/loader.h
@@ -294,18 +294,18 @@ struct FREEBLVectorStr {
SECStatus (* p_AESKeyWrap_Decrypt)(AESKeyWrapContext *cx,
unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
const unsigned char *input, unsigned int inputLen);
/* Version 3.004 came to here */
- PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr);
- PRBool (*p_BLAPI_VerifySelf)(const char *name);
+ PRBool (*p_BLAPI_SHVerify)(const char *name, PRFuncPtr addr, int *err);
+ PRBool (*p_BLAPI_VerifySelf)(const char *name, int *err);
/* Version 3.005 came to here */
SECStatus (* p_EC_NewKey)(ECParams * params,
ECPrivateKey ** privKey);
SECStatus (* p_EC_NewKeyFromSeed)(ECParams * params,
ECPrivateKey ** privKey,
@@ -553,17 +553,17 @@ struct FREEBLVectorStr {
SECStatus (*p_SHA224_HashBuf)(unsigned char *dest, const unsigned char *src,
PRUint32 src_length);
SECStatus (*p_SHA224_Hash)(unsigned char *dest, const char *src);
void (*p_SHA224_TraceState)(SHA224Context *cx);
unsigned int (* p_SHA224_FlattenSize)(SHA224Context *cx);
SECStatus (* p_SHA224_Flatten)(SHA224Context *cx,unsigned char *space);
SHA224Context * (* p_SHA224_Resurrect)(unsigned char *space, void *arg);
void (* p_SHA224_Clone)(SHA224Context *dest, SHA224Context *src);
- PRBool (*p_BLAPI_SHVerifyFile)(const char *name);
+ PRBool (*p_BLAPI_SHVerifyFile)(const char *name, int *err);
/* Version 3.013 came to here */
SECStatus (* p_PQG_ParamGenV2)( unsigned int L, unsigned int N,
unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy);
SECStatus (*p_PRNGTEST_RunHealthTests)(void);
diff --git a/lib/freebl/manifest.mn b/lib/freebl/manifest.mn
--- a/lib/freebl/manifest.mn
+++ b/lib/freebl/manifest.mn
@@ -57,16 +57,17 @@ PRIVATE_EXPORTS = \
alghmac.h \
blapi.h \
hmacct.h \
secmpi.h \
secrng.h \
ec.h \
ecl.h \
ecl-curve.h \
+ fips.h \
$(NULL)
MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
MPI_SRCS = mpprime.c mpmontg.c mplogic.c mpi.c mp_gf2m.c
ECL_HDRS = ecl-exp.h ecl.h ec2.h ecp.h ecl-priv.h
ifndef NSS_DISABLE_ECC
@@ -120,16 +121,17 @@ CSRCS = \
seed.c \
jpake.c \
$(MPI_SRCS) \
$(MPCPU_SRCS) \
$(ECL_SRCS) \
$(STUBS_SRCS) \
$(LOWHASH_SRCS) \
$(EXTRA_SRCS) \
+ fips.c \
$(NULL)
ALL_CSRCS := $(CSRCS)
ALL_HDRS = \
alghmac.h \
blapi.h \
blapit.h \
@@ -139,16 +141,17 @@ ALL_HDRS = \
rijndael.h \
camellia.h \
secmpi.h \
sha_fast.h \
sha256.h \
shsign.h \
vis_proto.h \
seed.h \
+ fips.h \
$(NULL)
ifdef AES_GEN_TBL
DEFINES += -DRIJNDAEL_GENERATE_TABLES
else
ifdef AES_GEN_TBL_M
DEFINES += -DRIJNDAEL_GENERATE_TABLES_MACRO
diff --git a/lib/freebl/nsslowhash.c b/lib/freebl/nsslowhash.c
--- a/lib/freebl/nsslowhash.c
+++ b/lib/freebl/nsslowhash.c
@@ -8,343 +8,75 @@
#include "prtypes.h"
#include "secerr.h"
#include "pkcs11t.h"
#include "blapi.h"
#include "hasht.h"
#include "plhash.h"
#include "nsslowhash.h"
-/* FIPS preprocessor directives for message digests */
-#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
-
-/* 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." };
-
-static CK_RV
-freebl_fips_MD2_PowerUpSelfTest( void )
-{
- /* MD2 Known Digest Message (128-bits). */
- static const PRUint8 md2_known_digest[] = {
- 0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
- 0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
-
- /* MD2 variables. */
- MD2Context * md2_context;
- unsigned int md2_bytes_hashed;
- PRUint8 md2_computed_digest[MD2_LENGTH];
-
-
- /***********************************************/
- /* MD2 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md2_context = MD2_NewContext();
-
- if( md2_context == NULL )
- return( CKR_HOST_MEMORY );
-
- MD2_Begin( md2_context );
-
- MD2_Update( md2_context, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
-
- MD2_DestroyContext( md2_context , PR_TRUE );
-
- if( ( md2_bytes_hashed != MD2_LENGTH ) ||
- ( PORT_Memcmp( md2_computed_digest, md2_known_digest,
- MD2_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-
-static CK_RV
-freebl_fips_MD5_PowerUpSelfTest( void )
-{
- /* MD5 Known Digest Message (128-bits). */
- static const PRUint8 md5_known_digest[] = {
- 0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
- 0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
-
- /* MD5 variables. */
- PRUint8 md5_computed_digest[MD5_LENGTH];
- SECStatus md5_status;
-
-
- /***********************************************/
- /* MD5 Single-Round Known Answer Hashing Test. */
- /***********************************************/
-
- md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( md5_status != SECSuccess ) ||
- ( PORT_Memcmp( md5_computed_digest, md5_known_digest,
- MD5_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-static CK_RV
-freebl_fips_SHA_PowerUpSelfTest( void )
-{
- /* SHA-1 Known Digest Message (160-bits). */
- static const PRUint8 sha1_known_digest[] = {
- 0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
- 0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
- 0xe0,0x68,0x47,0x7a};
-
- /* SHA-224 Known Digest Message (224-bits). */
- static const PRUint8 sha224_known_digest[] = {
- 0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
- 0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
- 0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
- 0x8e,0x08,0xe5,0xcb};
-
- /* SHA-256 Known Digest Message (256-bits). */
- static const PRUint8 sha256_known_digest[] = {
- 0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
- 0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
- 0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
- 0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
-
- /* SHA-384 Known Digest Message (384-bits). */
- static const PRUint8 sha384_known_digest[] = {
- 0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
- 0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
- 0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
- 0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
- 0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
- 0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
-
- /* SHA-512 Known Digest Message (512-bits). */
- static const PRUint8 sha512_known_digest[] = {
- 0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
- 0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
- 0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
- 0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
- 0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
- 0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
- 0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
- 0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
-
- /* SHA-X variables. */
- PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
- SECStatus sha_status;
-
- /*************************************************/
- /* SHA-1 Single-Round Known Answer Hashing Test. */
- /*************************************************/
-
- sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
- SHA1_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-224 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
- SHA224_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-256 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
- SHA256_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-384 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
- SHA384_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- /***************************************************/
- /* SHA-512 Single-Round Known Answer Hashing Test. */
- /***************************************************/
-
- sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
- FIPS_KNOWN_HASH_MESSAGE_LENGTH );
-
- if( ( sha_status != SECSuccess ) ||
- ( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
- SHA512_LENGTH ) != 0 ) )
- return( CKR_DEVICE_ERROR );
-
- return( CKR_OK );
-}
-
-
-static CK_RV
-freebl_fipsSoftwareIntegrityTest(void)
-{
- CK_RV crv = CKR_OK;
-
- /* make sure that our check file signatures are OK */
- if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- }
- return crv;
-}
-
+/* FIPS selftests are implemented in library constructors and abort on failure
+ * - if anybody gets to call this function it means the tests passed and this
+ * can be a successful no-op; the integrity selftest that used to be here is
+ * handled by the freebl constructor as well
+ */
CK_RV
freebl_fipsPowerUpSelfTest( void )
{
- CK_RV rv;
-
- /* MD2 Power-Up SelfTest(s). */
- rv = freebl_fips_MD2_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* MD5 Power-Up SelfTest(s). */
- rv = freebl_fips_MD5_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* SHA-X Power-Up SelfTest(s). */
- rv = freebl_fips_SHA_PowerUpSelfTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Software/Firmware Integrity Test. */
- rv = freebl_fipsSoftwareIntegrityTest();
-
- if( rv != CKR_OK )
- return rv;
-
- /* Passed Power-Up SelfTest(s). */
return( CKR_OK );
}
struct NSSLOWInitContextStr {
int count;
};
struct NSSLOWHASHContextStr {
const SECHashObject *hashObj;
void *hashCtxt;
};
-static int nsslow_GetFIPSEnabled(void) {
-#ifdef LINUX
- FILE *f;
- char d;
- size_t size;
-
- f = fopen("/proc/sys/crypto/fips_enabled", "r");
- if (!f)
- return 0;
-
- size = fread(&d, 1, 1, f);
- fclose(f);
- if (size != 1)
- return 0;
- if (d != '1')
- return 0;
-#endif
- return 1;
-}
-
-
-static int post = 0;
-static int post_failed = 0;
-
static NSSLOWInitContext dummyContext = { 0 };
NSSLOWInitContext *
NSSLOW_Init(void)
{
SECStatus rv;
CK_RV crv;
#ifdef FREEBL_NO_DEPEND
PRBool nsprAvailable = PR_FALSE;
rv = FREEBL_InitStubs();
nsprAvailable = (rv == SECSuccess ) ? PR_TRUE : PR_FALSE;
#endif
- if (post_failed) {
- return NULL;
- }
-
-
- if (!post && nsslow_GetFIPSEnabled()) {
- crv = freebl_fipsPowerUpSelfTest();
- if (crv != CKR_OK) {
- post_failed = 1;
- return NULL;
- }
- }
- post = 1;
-
-
return &dummyContext;
}
void
NSSLOW_Shutdown(NSSLOWInitContext *context)
{
PORT_Assert(context == &dummyContext);
return;
}
void
NSSLOW_Reset(NSSLOWInitContext *context)
{
PORT_Assert(context == &dummyContext);
- post_failed = 0;
- post = 0;
return;
}
NSSLOWHASHContext *
NSSLOWHASH_NewContext(NSSLOWInitContext *initContext,
HASH_HashType hashType)
{
NSSLOWHASHContext *context;
- if (post_failed) {
- PORT_SetError(SEC_ERROR_PKCS11_DEVICE_ERROR);
- return NULL;
- }
-
if (initContext != &dummyContext) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return (NULL);
}
context = PORT_ZNew(NSSLOWHASHContext);
if (!context) {
return NULL;
diff --git a/lib/freebl/shvfy.c b/lib/freebl/shvfy.c
--- a/lib/freebl/shvfy.c
+++ b/lib/freebl/shvfy.c
@@ -269,37 +269,37 @@ readItem(PRFileDesc *fd, SECItem *item)
item->data = NULL;
item->len = 0;
return SECFailure;
}
return SECSuccess;
}
PRBool
-BLAPI_SHVerify(const char *name, PRFuncPtr addr)
+BLAPI_SHVerify(const char *name, PRFuncPtr addr, int *err)
{
PRBool result = PR_FALSE; /* if anything goes wrong,
* the signature does not verify */
/* find our shared library name */
char *shName = PR_GetLibraryFilePathname(name, addr);
if (!shName) {
goto loser;
}
- result = BLAPI_SHVerifyFile(shName);
+ result = BLAPI_SHVerifyFile(shName, err);
loser:
if (shName != NULL) {
PR_Free(shName);
}
return result;
}
PRBool
-BLAPI_SHVerifyFile(const char *shName)
+BLAPI_SHVerifyFile(const char *shName, int *err)
{
char *checkName = NULL;
PRFileDesc *checkFD = NULL;
PRFileDesc *shFD = NULL;
void *hashcx = NULL;
const SECHashObject *hashObj = NULL;
SECItem signature = { 0, NULL, 0 };
SECItem hash;
@@ -332,16 +332,19 @@ BLAPI_SHVerifyFile(const char *shName)
/* open the check File */
checkFD = PR_Open(checkName, PR_RDONLY, 0);
if (checkFD == NULL) {
#ifdef DEBUG_SHVERIFY
fprintf(stderr, "Failed to open the check file %s: (%d, %d)\n",
checkName, (int)PR_GetError(), (int)PR_GetOSError());
#endif /* DEBUG_SHVERIFY */
+ if (err) {
+ *err = PORT_GetError();
+ }
goto loser;
}
/* read and Verify the headerthe header */
bytesRead = PR_Read(checkFD, buf, 12);
if (bytesRead != 12) {
goto loser;
}
@@ -490,19 +493,19 @@ loser:
if (key.publicValue.data != NULL) {
PORT_Free(key.publicValue.data);
}
return result;
}
PRBool
-BLAPI_VerifySelf(const char *name)
+BLAPI_VerifySelf(const char *name, int *err)
{
if (name == NULL) {
/*
* If name is NULL, freebl is statically linked into softoken.
* softoken will call BLAPI_SHVerify next to verify itself.
*/
return PR_TRUE;
}
- return BLAPI_SHVerify(name, (PRFuncPtr) decodeInt);
+ return BLAPI_SHVerify(name, (PRFuncPtr) decodeInt, err);
}
diff --git a/lib/softoken/fips.c b/lib/softoken/fips.c
new file mode 100644
--- /dev/null
+++ b/lib/softoken/fips.c
@@ -0,0 +1,26 @@
+#include "../freebl/fips-selftest.inc"
+
+#include "fips.h"
+
+#include "softoken.h"
+
+/* crypto algorithms selftest wrapper */
+static fips_check_status
+fips_checkCryptoSoftoken(void)
+{
+ if (CKR_OK == FIPS_cryptoSelftestSoftoken()) {
+ return CHECK_OK;
+ } else {
+ return CHECK_FAIL_CRYPTO;
+ }
+}
+
+/* constructor - load-time selfchecks */
+static void __attribute__ ((constructor))
+fips_initTestSoftoken(void)
+{
+ fips_state = fips_initTest("softokn", (PRFuncPtr)fips_initTestSoftoken, fips_checkCryptoSoftoken);
+
+ return;
+}
+
diff --git a/lib/softoken/fips.h b/lib/softoken/fips.h
new file mode 100644
--- /dev/null
+++ b/lib/softoken/fips.h
@@ -0,0 +1,10 @@
+#ifndef FIPS_H
+#define FIPS_H
+
+#include "softoken.h"
+
+CK_RV FIPS_cryptoSelftestSoftoken(void);
+CK_RV sftk_fipsPowerUpSelfTest(void);
+
+#endif
+
diff --git a/lib/softoken/fipstest.c b/lib/softoken/fipstest.c
--- a/lib/softoken/fipstest.c
+++ b/lib/softoken/fipstest.c
@@ -77,16 +77,22 @@
#define FIPS_DSA_SUBPRIME_LENGTH 20 /* 160-bits */
#define FIPS_DSA_SIGNATURE_LENGTH 40 /* 320-bits */
#define FIPS_DSA_PRIME_LENGTH 128 /* 1024-bits */
#define FIPS_DSA_BASE_LENGTH 128 /* 1024-bits */
/* FIPS preprocessor directives for RNG. */
#define FIPS_RNG_XKEY_LENGTH 32 /* 256-bits */
+/* Do not test algorithms not approved for use in FIPS 140-2 - it adds
+ * unnecessary time and code overhead for no noticable gain.
+ * Build with -DRUN_ALL_SELFTESTS to compile the tests in
+ */
+
+#ifdef RUN_ALL_SELFTESTS
static CK_RV
sftk_fips_RC2_PowerUpSelfTest( void )
{
/* RC2 Known Key (40-bits). */
static const PRUint8 rc2_known_key[] = { "RSARC" };
/* RC2-CBC Known Initialization Vector (64-bits). */
static const PRUint8 rc2_cbc_known_initialization_vector[] = {"Security"};
@@ -402,16 +408,17 @@ sftk_fips_DES_PowerUpSelfTest( void )
if( ( des_status != SECSuccess ) ||
( des_bytes_decrypted != FIPS_DES_DECRYPT_LENGTH ) ||
( PORT_Memcmp( des_computed_plaintext, des_cbc_known_plaintext,
FIPS_DES_DECRYPT_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
return( CKR_OK );
}
+#endif
static CK_RV
sftk_fips_DES3_PowerUpSelfTest( void )
{
/* DES3 Known Key (56-bits). */
static const PRUint8 des3_known_key[] = { "ANSI Triple-DES Key Data" };
@@ -1985,34 +1992,40 @@ sftk_fips_RNG_PowerUpSelfTest( void )
if( ( rng_status != SECSuccess ) ||
( PORT_Memcmp( DSAX, rng_known_DSAX,
(FIPS_DSA_SUBPRIME_LENGTH) ) != 0 ) )
return( CKR_DEVICE_ERROR );
return( CKR_OK );
}
-static CK_RV
-sftk_fipsSoftwareIntegrityTest(void)
+/* FIPS selftests are implemented in library constructors and abort on failure
+ * - if anybody gets to call this function it means the tests passed and this
+ * can be a successful no-op
+ */
+CK_RV
+sftk_fipsPowerUpSelfTest( void )
{
- CK_RV crv = CKR_OK;
-
- /* make sure that our check file signatures are OK */
- if( !BLAPI_VerifySelf( NULL ) ||
- !BLAPI_SHVerify( SOFTOKEN_LIB_NAME, (PRFuncPtr) sftk_fips_HMAC ) ) {
- crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
- }
- return crv;
+ return CKR_OK;
}
CK_RV
-sftk_fipsPowerUpSelfTest( void )
+FIPS_cryptoSelftestSoftoken( void )
{
CK_RV rv;
+ /* intialise BL */
+ if( SECSuccess != BL_Init() )
+ return CKR_GENERAL_ERROR;
+
+ /* intialise RNG (needed for RSA blinging parameters */
+ if( SECSuccess != RNG_RNGInit() )
+ return CKR_GENERAL_ERROR;
+
+#ifdef RUN_ALL_SELFTESTS
/* RC2 Power-Up SelfTest(s). */
rv = sftk_fips_RC2_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* RC4 Power-Up SelfTest(s). */
rv = sftk_fips_RC4_PowerUpSelfTest();
@@ -2020,16 +2033,17 @@ sftk_fipsPowerUpSelfTest( void )
if( rv != CKR_OK )
return rv;
/* DES Power-Up SelfTest(s). */
rv = sftk_fips_DES_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
+#endif
/* DES3 Power-Up SelfTest(s). */
rv = sftk_fips_DES3_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* AES Power-Up SelfTest(s) for 128-bit key. */
@@ -2045,27 +2059,29 @@ sftk_fipsPowerUpSelfTest( void )
return rv;
/* AES Power-Up SelfTest(s) for 256-bit key. */
rv = sftk_fips_AES_PowerUpSelfTest(FIPS_AES_256_KEY_SIZE);
if( rv != CKR_OK )
return rv;
+#ifdef RUN_ALL_SELFTESTS
/* MD2 Power-Up SelfTest(s). */
rv = sftk_fips_MD2_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* MD5 Power-Up SelfTest(s). */
rv = sftk_fips_MD5_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
+#endif
/* SHA-X Power-Up SelfTest(s). */
rv = sftk_fips_SHA_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* HMAC SHA-X Power-Up SelfTest(s). */
@@ -2095,18 +2111,12 @@ sftk_fipsPowerUpSelfTest( void )
#ifndef NSS_DISABLE_ECC
/* ECDSA Power-Up SelfTest(s). */
rv = sftk_fips_ECDSA_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
#endif
- /* Software/Firmware Integrity Test. */
- rv = sftk_fipsSoftwareIntegrityTest();
-
- if( rv != CKR_OK )
- return rv;
-
/* Passed Power-Up SelfTest(s). */
return( CKR_OK );
}
diff --git a/lib/softoken/fipstokn.c b/lib/softoken/fipstokn.c
--- a/lib/softoken/fipstokn.c
+++ b/lib/softoken/fipstokn.c
@@ -445,30 +445,19 @@ CK_RV FC_Initialize(CK_VOID_PTR pReserve
/* not an 'else' rv can be set by either SFTK_LowInit or SFTK_SlotInit*/
if (crv != CKR_OK) {
sftk_fatalError = PR_TRUE;
return crv;
}
sftk_fatalError = PR_FALSE; /* any error has been reset */
- crv = sftk_fipsPowerUpSelfTest();
- if (crv != CKR_OK) {
- nsc_CommonFinalize(NULL, PR_TRUE);
- sftk_fatalError = PR_TRUE;
- if (sftk_audit_enabled) {
- char msg[128];
- PR_snprintf(msg,sizeof msg,
- "C_Initialize()=0x%08lX "
- "power-up self-tests failed",
- (PRUint32)crv);
- sftk_LogAuditMessage(NSS_AUDIT_ERROR, NSS_AUDIT_SELF_TEST, msg);
- }
- return crv;
- }
+ /* FIPS selftests that were here have been moved to constructors
+ * (freebl, softoken and dbm) as to be executed at library load time */
+
nsf_init = PR_TRUE;
return CKR_OK;
}
/*FC_Finalize indicates that an application is done with the PKCS #11 library.*/
CK_RV FC_Finalize (CK_VOID_PTR pReserved) {
CK_RV crv;
diff --git a/lib/softoken/legacydb/fips.c b/lib/softoken/legacydb/fips.c
new file mode 100644
--- /dev/null
+++ b/lib/softoken/legacydb/fips.c
@@ -0,0 +1,25 @@
+#include "../../freebl/fips-selftest.inc"
+
+#include "fips.h"
+
+/*** private per-module symbols ***/
+
+/* crypto algorithms selftest wrapper */
+static fips_check_status
+fips_checkCryptoDbm(void)
+{
+ /* no checks in dbm */
+ return CHECK_OK;
+}
+
+/* constructor - load-time selfchecks */
+static void __attribute__ ((constructor))
+fips_initTestDbm(void)
+{
+ fips_state = fips_initTest("nssdbm", (PRFuncPtr)fips_checkCryptoDbm, NULL);
+
+ return;
+}
+
+/*** public per-module symbols ***/
+
diff --git a/lib/softoken/legacydb/fips.h b/lib/softoken/legacydb/fips.h
new file mode 100644
--- /dev/null
+++ b/lib/softoken/legacydb/fips.h
@@ -0,0 +1,5 @@
+#ifndef FIPS_H
+#define FIPS_H
+
+#endif
+
diff --git a/lib/softoken/legacydb/manifest.mn b/lib/softoken/legacydb/manifest.mn
--- a/lib/softoken/legacydb/manifest.mn
+++ b/lib/softoken/legacydb/manifest.mn
@@ -2,16 +2,17 @@
# 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/.
CORE_DEPTH = ../../..
MODULE = nss
REQUIRES = dbm
+DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\" -DSHLIB_VERSION=\"$(LIBRARY_VERSION)\"
LIBRARY_NAME = nssdbm
LIBRARY_VERSION = 3
MAPFILE = $(OBJDIR)/nssdbm.def
DEFINES += -DSHLIB_SUFFIX=\"$(DLL_SUFFIX)\" -DSHLIB_PREFIX=\"$(DLL_PREFIX)\"
CSRCS = \
@@ -22,10 +23,11 @@ CSRCS = \
lgdestroy.c \
lgfind.c \
lginit.c \
lgutil.c \
lowcert.c \
lowkey.c \
pcertdb.c \
pk11db.c \
+ fips.c \
$(NULL)
diff --git a/lib/softoken/lgglue.c b/lib/softoken/lgglue.c
--- a/lib/softoken/lgglue.c
+++ b/lib/softoken/lgglue.c
@@ -256,17 +256,17 @@ sftkdbLoad_Legacy(PRBool isFIPS)
LGSetCryptFunc setCryptFunction = NULL;
if (legacy_glue_lib) {
/* this check is necessary because it's possible we loaded the
* legacydb to read secmod.db, which told us whether we were in
* FIPS mode or not. */
if (isFIPS && !legacy_glue_libCheckSucceeded) {
if (legacy_glue_libCheckFailed ||
- !BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
+ !BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open, NULL)) {
legacy_glue_libCheckFailed = PR_TRUE;
/* don't clobber legacy glue to avoid race. just let it
* get cleared in shutdown */
return SECFailure;
}
legacy_glue_libCheckSucceeded = PR_TRUE;
}
return SECSuccess;
@@ -295,17 +295,17 @@ sftkdbLoad_Legacy(PRBool isFIPS)
!legacy_glue_releaseSecmod || !legacy_glue_deleteSecmod ||
!legacy_glue_addSecmod || !setCryptFunction) {
PR_UnloadLibrary(lib);
return SECFailure;
}
/* verify the loaded library if we are in FIPS mode */
if (isFIPS) {
- if (!BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
+ if (!BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open, NULL)) {
PR_UnloadLibrary(lib);
return SECFailure;
}
legacy_glue_libCheckSucceeded = PR_TRUE;
}
setCryptFunction(sftkdb_encrypt_stub,sftkdb_decrypt_stub);
legacy_glue_lib = lib;
diff --git a/lib/softoken/manifest.mn b/lib/softoken/manifest.mn
--- a/lib/softoken/manifest.mn
+++ b/lib/softoken/manifest.mn
@@ -25,16 +25,17 @@ PRIVATE_EXPORTS = \
lowkeyi.h \
lowkeyti.h \
pkcs11ni.h \
softoken.h \
softoknt.h \
softkver.h \
sdb.h \
sftkdbt.h \
+ fips.h \
$(NULL)
CSRCS = \
fipsaudt.c \
fipstest.c \
fipstokn.c \
lgglue.c \
lowkey.c \
@@ -46,16 +47,17 @@ CSRCS = \
sdb.c \
sftkdb.c \
sftkhmac.c \
sftkpars.c \
sftkpwd.c \
softkver.c \
tlsprf.c \
jpakesftk.c \
+ fips.c \
$(NULL)
ifdef SQLITE_UNSAFE_THREADS
DEFINES += -DSQLITE_UNSAFE_THREADS
endif
# This part of the code, including all sub-dirs, can be optimized for size
export ALLOW_OPT_CODE_SIZE = 1