JNI/JCE: only run FIPS CASTs once up front, for JCE run once when WolfCryptProvider is created
parent
3b627be193
commit
acbad58f17
|
@ -49,6 +49,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_setPrivateKeyReadEnable
|
|||
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_getPrivateKeyReadEnable
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_wolfcrypt_Fips
|
||||
* Method: wc_runAllCast_fips
|
||||
* Signature: ()I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_wc_1runAllCast_1fips
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_wolfcrypt_Fips
|
||||
* Method: getFipsVersion
|
||||
|
|
171
jni/jni_fips.c
171
jni/jni_fips.c
|
@ -170,6 +170,177 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_getPrivateKeyReadEnable
|
|||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_wc_1runAllCast_1fips
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
#if defined (WC_RNG_SEED_CB) || (defined(HAVE_FIPS) && \
|
||||
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 5))
|
||||
int ret = 0;
|
||||
#endif
|
||||
int failCount = 0;
|
||||
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
#ifdef WC_RNG_SEED_CB
|
||||
ret = wc_SetSeed_Cb(wc_GenerateSeed);
|
||||
if (ret != 0) {
|
||||
printf("wc_SetSeed_Cb() failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
|
||||
(HAVE_FIPS_VERSION >= 7)
|
||||
|
||||
failCount = wc_RunAllCast_fips();
|
||||
if (failCount != 0) {
|
||||
printf("FIPS CASTs failed to run");
|
||||
}
|
||||
|
||||
#elif defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
|
||||
(HAVE_FIPS_VERSION == 5)
|
||||
|
||||
/* run FIPS 140-3 conditional algorithm self tests early to prevent
|
||||
* multi threaded issues later on */
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_AES_CBC);
|
||||
if (ret != 0) {
|
||||
printf("AES-CBC CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_AESGCM
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_AES_GCM);
|
||||
if (ret != 0) {
|
||||
printf("AES-GCM CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA1);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA1 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* the only non-optional CAST */
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_256);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA2-256 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_SHA512
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_512);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA2-512 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA3_256);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA3-256 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_HASHDRBG
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_DRBG);
|
||||
if (ret != 0) {
|
||||
printf("Hash_DRBG CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_RSA
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_RSA_SIGN_PKCS1v15);
|
||||
if (ret != 0) {
|
||||
printf("RSA sign CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_ECC_CDH) && defined(HAVE_ECC_CDH_CAST)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECC_CDH);
|
||||
if (ret != 0) {
|
||||
printf("ECC CDH CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC_DHE
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECC_PRIMITIVE_Z);
|
||||
if (ret != 0) {
|
||||
printf("ECC Primitive Z CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECDSA);
|
||||
if (ret != 0) {
|
||||
printf("ECDSA CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_DH_PRIMITIVE_Z);
|
||||
if (ret != 0) {
|
||||
printf("DH Primitive Z CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_PRF
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_TLS12);
|
||||
if (ret != 0) {
|
||||
printf("KDF TLSv1.2 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_PRF) && defined(WOLFSSL_TLS13)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_TLS13);
|
||||
if (ret != 0) {
|
||||
printf("KDF TLSv1.3 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_WOLFSSH
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_SSH);
|
||||
if (ret != 0) {
|
||||
printf("KDF SSHv2.0 CAST failed");
|
||||
failCount++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_FIPS && HAVE_FIPS_VERSION == 5 */
|
||||
|
||||
return failCount;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Fips_getFipsVersion
|
||||
(JNIEnv* env, jclass this)
|
||||
{
|
||||
|
|
|
@ -40,152 +40,13 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfObject_init
|
|||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
#ifdef WC_RNG_SEED_CB
|
||||
ret = wc_SetSeed_Cb(wc_GenerateSeed);
|
||||
if (ret != 0) {
|
||||
printf("wc_SetSeed_Cb() failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
|
||||
(HAVE_FIPS_VERSION >= 7)
|
||||
|
||||
ret = wc_RunAllCast_fips();
|
||||
if (ret != 0) {
|
||||
printf("FIPS CASTs failed to run");
|
||||
}
|
||||
|
||||
#elif defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
|
||||
(HAVE_FIPS_VERSION == 5)
|
||||
|
||||
/* run FIPS 140-3 conditional algorithm self tests early to prevent
|
||||
* multi threaded issues later on */
|
||||
#if !defined(NO_AES) && !defined(NO_AES_CBC)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_AES_CBC);
|
||||
if (ret != 0) {
|
||||
printf("AES-CBC CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_AESGCM
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_AES_GCM);
|
||||
if (ret != 0) {
|
||||
printf("AES-GCM CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_SHA
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA1);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA1 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* the only non-optional CAST */
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_256);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA2-256 CAST failed");
|
||||
}
|
||||
}
|
||||
#ifdef WOLFSSL_SHA512
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA2_512);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA2-512 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA3
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_HMAC_SHA3_256);
|
||||
if (ret != 0) {
|
||||
printf("HMAC-SHA3-256 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_HASHDRBG
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_DRBG);
|
||||
if (ret != 0) {
|
||||
printf("Hash_DRBG CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_RSA
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_RSA_SIGN_PKCS1v15);
|
||||
if (ret != 0) {
|
||||
printf("RSA sign CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_ECC_CDH) && defined(HAVE_ECC_CDH_CAST)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECC_CDH);
|
||||
if (ret != 0) {
|
||||
printf("ECC CDH CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC_DHE
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECC_PRIMITIVE_Z);
|
||||
if (ret != 0) {
|
||||
printf("ECC Primitive Z CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_ECDSA);
|
||||
if (ret != 0) {
|
||||
printf("ECDSA CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_DH
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_DH_PRIMITIVE_Z);
|
||||
if (ret != 0) {
|
||||
printf("DH Primitive Z CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_PRF
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_TLS12);
|
||||
if (ret != 0) {
|
||||
printf("KDF TLSv1.2 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_PRF) && defined(WOLFSSL_TLS13)
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_TLS13);
|
||||
if (ret != 0) {
|
||||
printf("KDF TLSv1.3 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_WOLFSSH
|
||||
if (ret == 0) {
|
||||
ret = wc_RunCast_fips(FIPS_CAST_KDF_SSH);
|
||||
if (ret != 0) {
|
||||
printf("KDF SSHv2.0 CAST failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_FIPS && HAVE_FIPS_VERSION == 5 */
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
/* Code which runs the FIPS CASTs up front has been moved to the
|
||||
* com.wolfssl.wolfcrypt.Fips.runAllCast_fips() method. runAllCast_fips()
|
||||
* includes a synchronized check that only runs the CASTs once as long
|
||||
* as they were successful. Fips.runAllCast_fips() is called at both
|
||||
* the JNI-only level (WolfObject.init()), and the JCE level
|
||||
* (WolfCryptProvider constructor). Both of these runAllCast_fips()
|
||||
* at JNI/JCE levels are called before this wolfCrypt_Init() below. */
|
||||
|
||||
return (jint)wolfCrypt_Init();
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@ public final class WolfCryptProvider extends Provider {
|
|||
String mapJksToWks = null;
|
||||
String mapPkcs12ToWks = null;
|
||||
|
||||
/* Run FIPS algorithm self tests (CASTs) if needed */
|
||||
if (Fips.enabled) {
|
||||
Fips.runAllCast_fips();
|
||||
}
|
||||
|
||||
/* MessageDigest */
|
||||
if (FeatureDetect.Md5Enabled()) {
|
||||
put("MessageDigest.MD5",
|
||||
|
|
|
@ -52,6 +52,13 @@ public class Fips extends WolfObject {
|
|||
/** Native wolfCrypt FIPS version (HAVE_FIPS_VERSION) */
|
||||
public static final int fipsVersion = Fips.getFipsVersion();
|
||||
|
||||
/* Internal flag to keep track of if FIPS CAST has already been run and
|
||||
* passed successfully. */
|
||||
private static volatile boolean fipsCastRunSuccessfully = false;
|
||||
|
||||
/* Lock around fipsCastRunSuccessfully */
|
||||
private static final Object fipsCastLock = new Object();
|
||||
|
||||
private Fips() {
|
||||
}
|
||||
|
||||
|
@ -119,6 +126,55 @@ public class Fips extends WolfObject {
|
|||
*/
|
||||
public static native int getPrivateKeyReadEnable(int keyType);
|
||||
|
||||
/**
|
||||
* Native JNI wrapper around running FIPS CASTs.
|
||||
*
|
||||
* Called by public runAllCast_fips() in this class.
|
||||
*
|
||||
* @return 0 on success, otherwise greater than zero if some algorithm
|
||||
* self tests have failed. The count of tests failed will be
|
||||
* returned on error.
|
||||
*/
|
||||
private static native int wc_runAllCast_fips();
|
||||
|
||||
/**
|
||||
* Run all FIPS Conditional Algorithm Self Tests (CAST).
|
||||
*
|
||||
* In wolfCrypt FIPS 140-3, the algorithm self tests are Conditional (CAST),
|
||||
* meaning they will run on-demand per algorithm the first time that
|
||||
* algorithm is used. This can be convienent for startup time if on a
|
||||
* single threaded application, but can introduce potentially unwanted
|
||||
* errors at runtime if operating in a multi threaded environment where
|
||||
* multiple threads will be using wolfCrypt cryptography in parallel. If
|
||||
* one thread is actively running an algorithm CAST and another thread
|
||||
* tries to use the algorithm, it may return a FIPS not allowed error.
|
||||
*
|
||||
* To avoid multi threaded errors at runtime due to the above, this method
|
||||
* can be called once up front when an application starts. It will run
|
||||
* all algorithm CASTS, and if run before threaded operations start will
|
||||
* avoid the FIPS not allowed errors which may occur otherwise.
|
||||
*
|
||||
* @return 0 on success, otherwise greater than zero if some algorithm
|
||||
* self tests have failed. The count of tests failed will be
|
||||
* returned on error.
|
||||
*/
|
||||
public static int runAllCast_fips() {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
synchronized (fipsCastLock) {
|
||||
if (!fipsCastRunSuccessfully) {
|
||||
ret = wc_runAllCast_fips();
|
||||
if (ret == 0) {
|
||||
/* Only forcefully run FIPS CAST once */
|
||||
fipsCastRunSuccessfully = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static native int getFipsVersion();
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
package com.wolfssl.wolfcrypt;
|
||||
|
||||
import com.wolfssl.wolfcrypt.Fips;
|
||||
|
||||
/**
|
||||
* Loader for the native WolfCrypt implementation.
|
||||
* All classes in this package must inherit from it.
|
||||
|
@ -62,6 +64,12 @@ public class WolfObject {
|
|||
/* Load wolfcryptjni library */
|
||||
System.loadLibrary("wolfcryptjni");
|
||||
|
||||
/* Run FIPS CAST if we are in FIPS mode. Will only forcefully
|
||||
* be run once - Fips class keeps track of a successful run. */
|
||||
if (Fips.enabled) {
|
||||
Fips.runAllCast_fips();
|
||||
}
|
||||
|
||||
/* initialize native wolfCrypt library */
|
||||
init();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue