Merge pull request #73 from cconlon/release16

Prep for 1.6 Release
pull/74/head v1.6.0-stable
JacobBarthelmeh 2024-04-17 12:07:44 -06:00 committed by GitHub
commit e25d43d0b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 679 additions and 378 deletions

155
ChangeLog.md 100644
View File

@ -0,0 +1,155 @@
### wolfCrypt JNI Release 1.6.0 (4/17/2024)
Release 1.6.0 of wolfCrypt JNI and JCE has bug fixes and new features including:
**New JCE Functionality:**
- Add RSA support to `KeyPairGenerator` class (PR 49)
- Add `AES/CBC/PKCS5Padding` support to `Cipher` class (PR 51)
- Add `RSA` support to `Cipher` class (PR 51)
- Add `PKIX` implementation of `CertPathValidator` class (PR 60, 66)
- Add `SHA1` alias for `MessageDigest` `SHA-1` for interop compatibility (PR 61)
- Add `AES/GCM/NoPadding` support to `Cipher` class (PR 62)
- Add `SecretKeyFactory` implementation supporting `PBKDF2` (PR 70)
- Add `DEFAULT` support to `SecureRandom` class (PR 72)
**New JNI Wrapped APIs and Functionality:**
- Add `AES-GCM` support to `com.wolfssl.wolfcrypt.AesGcm` class (PR 62)
**JNI and JCE Changes:**
- Add synchronization to `com.wolfssl.wolfcrypt.Rng` class (PR 44)
- Correct preprocessor guards for 3DES with wolfCrypt FIPS (PR 47)
- Correct order of operations in `wc_CreatePKCS8Key()` JNI wrapper API (PR 50)
- Add synchronization around native structure pointer use (PR 53)
- Remove inclusion of CyaSSL header includes, switch to wolfSSL (PR 56)
- Call `PRIVATE_KEY_LOCK/UNLOCK()` for wolfCrypt FIPS 140-3 compatibility (PR 57)
- Improve native HMAC feature detection (PR 58)
- Prepend zero byte to DH shared secret if less than prime length (PR 69)
- Add synchronization to protected methods in `WolfCryptSignature` (PR 68)
- Add synchronization to public methods of `WolfCryptKeyPairGenerator` (PR 73)
- Only allocate one `Rng` object per `WolfCryptSignature`, not per sign operation (PR 73)
- Reduce extra `WolfCryptRng` object creation in `Signature` and `KeyPairGenerator` (PR 73)
**New Platform Support:**
- Add Windows support with Visual Studio, see IDE/WIN/README.md (PR 46)
**Build System Changes:**
- Support custom wolfSSL library prefix and name in `makefile.linux` (PR 45)
- Standardize JNI library name on OSX to .dylib (PR 54)
- Update Maven build support (PR 55)
**Example Changes:**
- Print provider of `SecureRandom` from `ProviderTest.java` (PR 43)
- Add Windows batch script to run `ProviderTest` example (PR 52)
**Testing Changes:**
- Add extended threading test for `WolfCryptRandom` class (PR 44)
- Add Facebook Infer test script, make fixes (PR 48, 63)
- Add GitHub Actions tests for Oracle/Zulu/Coretto/Temurin/Microsoft JDKs on Linux and OS X (PR 65)
**Documentation Changes:**
- Remove build instructions from `README.md` for FIPS historical cert #2425 (PR 56)
- Fix Javadoc warnings for Java 21 and 22 (PR 71)
The wolfCrypt JNI/JCE Manual is available at:
https://www.wolfssl.com/documentation/manuals/wolfcryptjni/. For build
instructions and more details comments, please check the manual.
### wolfCrypt JNI Release 1.5.0 (11/14/2022)
Release 1.5.0 of wolfCrypt JNI has bug fixes and new features including:
- Add build compatibility for Java 7 (PR 38)
- Add support for "SHA" algorithm string in wolfJCE (PR 39)
- Add rpm package support (PR 40)
- Add wolfJCE MessageDigest.clone() support (PR 41)
- Improve error checking of native Md5 API calls (PR 41)
- Add unit tests for com.wolfssl.wolfcrypt.Md5 (PR 41)
### wolfCrypt JNI Release 1.4.0 (08/11/2022)
Release 1.4.0 of wolfCrypt JNI has bug fixes and new features including:
- Add example directory with one simple ProviderTest example (PR 32)
- Fix double free of ChaCha pointer (PR 34)
- Add test cases for ChaCha.java (PR 34)
- Skip WolfCryptMacTest for HMAC-MD5 when using wolfCrypt FIPS 140-3 (PR 35)
- Use new hash struct names (wc\_Md5/wc\_Sha/etc) in native code (PR 35)
- Fix potential build error with non-ASCII apostrophes in Fips.java (PR 36)
### wolfCrypt JNI Release 1.3.0 (05/13/2022)
Release 1.3.0 of wolfCrypt JNI has bug fixes and new features including:
- Run FIPS tests on `ant test` when linked against a wolfCrypt FIPS library (PR 24)
- Wrap native AesGcmSetExtIV\_fips() API (PR 24)
- Fix releaseByteArray() usage in Fips.RsaSSL\_Sign() (PR 24)
- Fix AES-GCM FIPS test cases (PR 24)
- Keep existing JAVA\_HOME in makefiles if already set (PR 25)
- Add JCE support for MessageDigestSpi.engineGetDigestLength() (PR 27)
- Update junit to 4.13.2 (PR 28)
- Update missing Javadocs, fixes warnings on newer Java versions (PR 29)
### wolfCrypt JNI Release 1.2.0 (11/16/2021)
Release 1.2.0 of wolfCrypt JNI has bug fixes and new features including:
- Add **FIPS 140-3** compatibility when using wolfCrypt FIPS or FIPS Ready
- Increase junit version from 4.12 to 4.13 in pom.xml
- Add local `./lib` directory to `java.library.path` in pom.xml
- Fix builds with `WOLFCRYPT_JNI_DEBUG_ON` defined
- Fix compatibility with wolfCrypt `NO_OLD_*` defines
- Fix compatibility with wolfSSL `./configure --enable-all` and ECC tests
### wolfCrypt JNI Release 1.1.0 (08/26/2020)
Release 1.1.0 of wolfCrypt JNI has bug fixes and new features including:
- New JNI-level wrappers for ChaCha, Curve25519, and Ed25519
- Maven pom.xml build file
- Runtime detection of hash type enum values for broader wolfSSL support
- Updated wolfSSL error codes to match native wolfSSL updates
- Native HMAC wrapper fixes for building with wolfCrypt FIPSv2
- Native wrapper to return `HAVE_FIPS_VERSION` value to Java
- Remove Blake2b from HMAC types, to match native wolfSSL changes
- Better native wolfSSL feature detection
- Increase Junit version to 4.13
- Use nativeheaderdir on supported platforms instead of javah
- Use hamcrest-all-1.3.jar in build.xml
- Add call to `wc_ecc_set_rng()` when needed
### wolfCrypt JNI Release 1.0.0 (7/10/2017)
Release 1.0.0 of wolfCrypt JNI has bug fixes and new features including:
- Bug fixes to JCE classes: Cipher, KeyAgreement (DH), Signature
- JCE debug logging with wolfjce.debug system property
- Additional unit tests for JCE provider
- Conditional ant build for JNI and/or JCE
- New ant targets with choice of debug or release builds
### wolfCrypt JNI Release 0.3 BETA
Release 0.3 BETA of wolfCrypt JNI includes:
- Support for ECC and DH key generation
- Bug fixes regarding key import/export
- Better argument sanitization at JNI level
### wolfCrypt JNI Release 0.2 BETA
Release 0.2 BETA of wolfCrypt JNI includes:
- Support for Android
- Support for Oracle JDK/JVM
- Support for code signing wolfcrypt-jni.jar file
- Compatibility with non-FIPS wolfSSL and wolfCrypt builds
- Bug fixes regarding releasing native resources
- Test package changed to (com.wolfssl.provider.jce.test)
### wolfCrypt JNI Release 0.1 BETA
Release 0.1 BETA of wolfCrypt JNI includes:
- Initial JCE package
- Support for OpenJDK

View File

@ -136,6 +136,7 @@ section titled `/* Configuration */`:
```
#define WOLFSSL_KEY_GEN
#define HAVE_CRL
```
After editing and saving the `user_settings.h` file, select one of the following
@ -202,6 +203,7 @@ and set the values for `HAVE_FIPS`, `HAVE_FIPS_VERSION`, and
```
#define WOLFSSL_KEY_GEN
#define HAVE_CRL
```
6. Build the `wolfssl-fips` project, which will create a DLL in one of the
@ -258,6 +260,7 @@ The following additional defines will also need to be added to
```
#define WOLFSSL_KEY_GEN
#define HAVE_CRL
```
For additional help, contact support@wolfssl.com.

View File

@ -66,6 +66,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\jni\jni_aes.c" />
<ClCompile Include="..\..\jni\jni_aesgcm.c" />
<ClCompile Include="..\..\jni\jni_asn.c" />
<ClCompile Include="..\..\jni\jni_chacha.c" />
<ClCompile Include="..\..\jni\jni_curve25519.c" />
@ -80,10 +81,13 @@
<ClCompile Include="..\..\jni\jni_logging.c" />
<ClCompile Include="..\..\jni\jni_md5.c" />
<ClCompile Include="..\..\jni\jni_native_struct.c" />
<ClCompile Include="..\..\jni\jni_pwdbased.c" />
<ClCompile Include="..\..\jni\jni_rng.c" />
<ClCompile Include="..\..\jni\jni_rsa.c" />
<ClCompile Include="..\..\jni\jni_sha.c" />
<ClCompile Include="..\..\jni\jni_wolfcrypt.c" />
<ClCompile Include="..\..\jni\jni_wolfobject.c" />
<ClCompile Include="..\..\jni\jni_wolfssl_cert_manager.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
@ -97,52 +101,52 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug FIPS|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release FIPS|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Debug FIPS|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DLL Release FIPS|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

View File

@ -158,5 +158,17 @@
<ClCompile Include="..\..\jni\jni_wolfobject.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\jni\jni_aesgcm.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\jni\jni_pwdbased.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\jni\jni_wolfcrypt.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\jni\jni_wolfssl_cert_manager.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

132
README.md
View File

@ -1,15 +1,15 @@
## wolfCrypt JCE Provider and JNI Wrapper
This package provides a Java, JNI-based interface to the native wolfCrypt
(and wolfCrypt FIPS API, if using with a FIPS version of wolfCrypt). It also
includes a JCE provider for wolfCrypt.
This packages includes both a JNI wrapper and JCE provider around the native
wolfCrypt cryptography library. It supports both normal and FIPS validated
versions of wolfCrypt.
For instructions and notes on the JNI wrapper, please reference this README.md,
or the wolfSSL online documentation.
For instructions and notes on the **JNI wrapper**, please reference this
README.md, or the wolfSSL online user manual.
For instructions and notes on the JCE provider, please reference the
[README_JCE.md](./README_JCE.md) file, or online instructions.
For instructions and notes on the **JCE provider**, please reference the
[README_JCE.md](./README_JCE.md) file, or online user manual.
### Compiling Native wolfSSL (Dependency)
---------
@ -18,14 +18,19 @@ To compile the wolfCrypt JNI wrapper and JCE provider, first the native (C)
wolfSSL library must be compiled and installed.
Compile and install a wolfSSL (wolfssl-x.x.x), wolfSSL FIPS
release (wolfssl-x.x.x-commercial-fips), or wolfSSL FIPS Ready release:
release (wolfssl-x.x.x-commercial-fips), or wolfSSL FIPS Ready release.
In any of these cases, you will need the `--enable-keygen` ./configure option.
In any of these cases, you will need the `--enable-jni` ./configure option.
The `--enable-jni` option includes all native wolfSSL features needed by
both wolfCrypt JNI/JCE (this package) as well as wolfSSL JNI/JSSE (a
separate package and repo). If you want the minimal set of requirements needed
for only wolfJCE, you can use `--enable-keygen --enable-crl`, where
CRL support is needed to support JCE `CertPathValidator(PKIX)` CRL support.
**wolfSSL Standard Build**:
```
$ cd wolfssl-x.x.x
$ ./configure --enable-keygen
$ ./configure --enable-jni
$ make check
$ sudo make install
```
@ -34,7 +39,7 @@ $ sudo make install
```
$ cd wolfssl-x.x.x-commercial-fips
$ ./configure --enable-fips=v2 --enable-keygen
$ ./configure --enable-fips=v2 --enable-jni
$ make check
$ sudo make install
```
@ -43,7 +48,7 @@ $ sudo make install
```
$ cd wolfssl-x.x.x-commercial-fips
$ ./configure --enable-fips=ready --enable-keygen
$ ./configure --enable-fips=ready --enable-jni
$ make check
$ sudo make install
```
@ -203,7 +208,7 @@ on the current release):
<dependency>
<groupId>com.wolfssl</groupId>
<artifactId>wolfcrypt-jni</artifactId>
<version>1.5.0-SNAPSHOT</version>
<version>1.6.0-SNAPSHOT</version>
</dependency>
</dependencies>
...
@ -248,105 +253,8 @@ Signing the JAR is important especially if using the JCE Provider with a JDK
that requires JCE provider JAR's to be authenticated. Please see
[README_JCE.md](./README_JCE.md) for more details.
### Revision History
### Release Notes
---------
#### wolfCrypt JNI Release 1.5.0 (11/14/2022)
Release 1.5.0 of wolfCrypt JNI has bug fixes and new features including:
- Add build compatibility for Java 7 (PR 38)
- Add support for "SHA" algorithm string in wolfJCE (PR 39)
- Add rpm package support (PR 40)
- Add wolfJCE MessageDigest.clone() support (PR 41)
- Improve error checking of native Md5 API calls (PR 41)
- Add unit tests for com.wolfssl.wolfcrypt.Md5 (PR 41)
#### wolfCrypt JNI Release 1.4.0 (08/11/2022)
Release 1.4.0 of wolfCrypt JNI has bug fixes and new features including:
- Add example directory with one simple ProviderTest example (PR 32)
- Fix double free of ChaCha pointer (PR 34)
- Add test cases for ChaCha.java (PR 34)
- Skip WolfCryptMacTest for HMAC-MD5 when using wolfCrypt FIPS 140-3 (PR 35)
- Use new hash struct names (wc\_Md5/wc\_Sha/etc) in native code (PR 35)
- Fix potential build error with non-ASCII apostrophes in Fips.java (PR 36)
#### wolfCrypt JNI Release 1.3.0 (05/13/2022)
Release 1.3.0 of wolfCrypt JNI has bug fixes and new features including:
- Run FIPS tests on `ant test` when linked against a wolfCrypt FIPS library (PR 24)
- Wrap native AesGcmSetExtIV\_fips() API (PR 24)
- Fix releaseByteArray() usage in Fips.RsaSSL\_Sign() (PR 24)
- Fix AES-GCM FIPS test cases (PR 24)
- Keep existing JAVA\_HOME in makefiles if already set (PR 25)
- Add JCE support for MessageDigestSpi.engineGetDigestLength() (PR 27)
- Update junit to 4.13.2 (PR 28)
- Update missing Javadocs, fixes warnings on newer Java versions (PR 29)
#### wolfCrypt JNI Release 1.2.0 (11/16/2021)
Release 1.2.0 of wolfCrypt JNI has bug fixes and new features including:
- Add **FIPS 140-3** compatibility when using wolfCrypt FIPS or FIPS Ready
- Increase junit version from 4.12 to 4.13 in pom.xml
- Add local `./lib` directory to `java.library.path` in pom.xml
- Fix builds with `WOLFCRYPT_JNI_DEBUG_ON` defined
- Fix compatibility with wolfCrypt `NO_OLD_*` defines
- Fix compatibility with wolfSSL `./configure --enable-all` and ECC tests
#### wolfCrypt JNI Release 1.1.0 (08/26/2020)
Release 1.1.0 of wolfCrypt JNI has bug fixes and new features including:
- New JNI-level wrappers for ChaCha, Curve25519, and Ed25519
- Maven pom.xml build file
- Runtime detection of hash type enum values for broader wolfSSL support
- Updated wolfSSL error codes to match native wolfSSL updates
- Native HMAC wrapper fixes for building with wolfCrypt FIPSv2
- Native wrapper to return `HAVE_FIPS_VERSION` value to Java
- Remove Blake2b from HMAC types, to match native wolfSSL changes
- Better native wolfSSL feature detection
- Increase Junit version to 4.13
- Use nativeheaderdir on supported platforms instead of javah
- Use hamcrest-all-1.3.jar in build.xml
- Add call to `wc_ecc_set_rng()` when needed
#### wolfCrypt JNI Release 1.0.0 (7/10/2017)
Release 1.0.0 of wolfCrypt JNI has bug fixes and new features including:
- Bug fixes to JCE classes: Cipher, KeyAgreement (DH), Signature
- JCE debug logging with wolfjce.debug system property
- Additional unit tests for JCE provider
- Conditional ant build for JNI and/or JCE
- New ant targets with choice of debug or release builds
#### wolfCrypt JNI Release 0.3 BETA
Release 0.3 BETA of wolfCrypt JNI includes:
- Support for ECC and DH key generation
- Bug fixes regarding key import/export
- Better argument sanitization at JNI level
#### wolfCrypt JNI Release 0.2 BETA
Release 0.2 BETA of wolfCrypt JNI includes:
- Support for Android
- Support for Oracle JDK/JVM
- Support for code signing wolfcrypt-jni.jar file
- Compatibility with non-FIPS wolfSSL and wolfCrypt builds
- Bug fixes regarding releasing native resources
- Test package changed to (com.wolfssl.provider.jce.test)
#### wolfCrypt JNI Release 0.1 BETA
Release 0.1 BETA of wolfCrypt JNI includes:
- Initial JCE package
- Support for OpenJDK
Release notes can be found in [ChangeLog.md](./ChangeLog.md).

View File

@ -19,7 +19,7 @@
<!-- versioning/manifest properties -->
<property name="implementation.vendor" value="wolfSSL Inc." />
<property name="implementation.title" value="wolfCrypt JNI" />
<property name="implementation.version" value="1.5" />
<property name="implementation.version" value="1.6" />
<!-- set properties for this build -->
<property name="src.dir" value="src/main/java/" />

View File

@ -821,7 +821,9 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1sign_1hash(
RNG* rng = NULL;
byte* hash = NULL;
byte* signature = NULL;
word32 hashSz = 0, signatureSz = 0;
word32 hashSz = 0;
word32 expectedSigSz = 0;
word32 signatureSz = 0;
word32 signatureBufSz = 0;
ecc = (ecc_key*) getNativeStruct(env, this);
@ -844,7 +846,8 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1sign_1hash(
}
if (ret == 0) {
signatureSz = wc_ecc_sig_size(ecc);
expectedSigSz = wc_ecc_sig_size(ecc);
signatureSz = expectedSigSz;
signatureBufSz = signatureSz;
signature = (byte*)XMALLOC(signatureSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@ -860,25 +863,39 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1sign_1hash(
ret = wc_ecc_sign_hash(hash, hashSz, signature, &signatureSz, rng, ecc);
}
if (ret == 0) {
/* Sanity check on wc_ecc_sig_size() and actual length */
if (expectedSigSz < signatureSz) {
ret = BUFFER_E;
throwWolfCryptException(env,
"wc_ecc_sig_size() less than actual sig size");
}
}
if (ret == 0) {
result = (*env)->NewByteArray(env, signatureSz);
if (result) {
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, signatureSz,
(const jbyte*)signature);
} else {
releaseByteArray(env, hash_object, hash, JNI_ABORT);
throwWolfCryptException(env, "Failed to allocate signature");
return NULL;
}
} else {
releaseByteArray(env, hash_object, hash, JNI_ABORT);
throwWolfCryptExceptionFromError(env, ret);
return NULL;
}
LogStr("wc_ecc_sign_hash(input, inSz, output, &outSz, rng, ecc) = %d\n",
ret);
LogStr("signature[%u]: [%p]\n", (word32)signatureSz, signature);
LogHex((byte*) signature, 0, signatureSz);
if (signature != NULL) {
LogStr("signature[%u]: [%p]\n", (word32)signatureSz, signature);
LogHex((byte*) signature, 0, signatureSz);
XMEMSET(signature, 0, signatureBufSz);
XFREE(signature, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
@ -896,8 +913,8 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1verify_1hash(
JNIEnv* env, jobject this, jbyteArray hash_object,
jbyteArray signature_object)
{
int ret = 0;
#ifdef HAVE_ECC_VERIFY
int ret = 0;
int status = 0;
ecc_key* ecc = NULL;
byte* hash = NULL;
@ -907,7 +924,7 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1verify_1hash(
ecc = (ecc_key*) getNativeStruct(env, this);
if ((*env)->ExceptionOccurred(env)) {
/* getNativeStruct may throw exception, prevent throwing another */
return 0;
return JNI_FALSE;
}
hash = getByteArray(env, hash_object);
@ -921,26 +938,29 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1verify_1hash(
}
else {
ret = wc_ecc_verify_hash(signature, signatureSz, hash,
hashSz, &status, ecc);
hashSz, &status, ecc);
}
if (ret == 0) {
ret = status;
} else {
throwWolfCryptExceptionFromError(env, ret);
}
releaseByteArray(env, hash_object, hash, JNI_ABORT);
releaseByteArray(env, signature_object, signature, JNI_ABORT);
LogStr(
"wc_ecc_verify_hash(sig, sigSz, hash, hashSz, &status, ecc); = %d\n",
ret);
releaseByteArray(env, hash_object, hash, JNI_ABORT);
releaseByteArray(env, signature_object, signature, JNI_ABORT);
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
}
if (status == 1) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
#else
throwNotCompiledInException(env);
return JNI_FALSE;
#endif
return ret;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1get_1curve_1size_1from_1name

View File

@ -213,7 +213,7 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha224En
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && !defined(WOLFSSL_SHA224)
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA224)
return JNI_TRUE;
#else
return JNI_FALSE;

View File

@ -151,9 +151,10 @@ byte* getByteArray(JNIEnv* env, jbyteArray array)
void releaseByteArray(JNIEnv* env, jbyteArray array, byte* elements, jint abort)
{
if (elements)
if ((env != NULL) && (array != NULL) && (elements != NULL)) {
(*env)->ReleaseByteArrayElements(env, array, (jbyte*) elements,
abort ? JNI_ABORT : 0);
}
}
word32 getByteArrayLength(JNIEnv* env, jbyteArray array)

View File

@ -49,7 +49,17 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfObject_init
}
#endif
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION == 5)
#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)

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.wolfssl</groupId>
<artifactId>wolfcrypt-jni</artifactId>
<version>1.5.0-SNAPSHOT</version>
<version>1.6.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>wolfcrypt-jni</name>
<url>https://www.wolfssl.com</url>

View File

@ -80,6 +80,9 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
private Rng rng = null;
/* Lock around Rng access */
private final Object rngLock = new Object();
/* for debug logging */
private WolfCryptDebug debug;
private String algString;
@ -88,15 +91,12 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
this.type = type;
rng = new Rng();
rng.init();
if (debug.DEBUG)
algString = typeToString(type);
}
@Override
public void initialize(int keysize, SecureRandom random) {
public synchronized void initialize(int keysize, SecureRandom random) {
if (type == KeyType.WC_DH) {
throw new RuntimeException(
@ -111,19 +111,33 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
this.publicExponent = Rsa.getDefaultRsaExponent();
}
synchronized (rngLock) {
if (this.rng == null) {
this.rng = new Rng();
this.rng.init();
}
}
if (debug.DEBUG)
log("init with keysize: " + keysize);
}
@Override
public void initialize(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
public synchronized void initialize(AlgorithmParameterSpec params,
SecureRandom random) throws InvalidAlgorithmParameterException {
if (params == null) {
throw new InvalidAlgorithmParameterException(
"AlgorithmParameterSpec must not be null");
}
synchronized (rngLock) {
if (this.rng == null) {
this.rng = new Rng();
this.rng.init();
}
}
switch (type) {
case WC_RSA:
@ -206,7 +220,7 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
}
@Override
public KeyPair generateKeyPair() {
public synchronized KeyPair generateKeyPair() {
KeyPair pair = null;
@ -232,7 +246,10 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
Rsa rsa = new Rsa();
try {
rsa.makeKey(this.keysize, this.publicExponent, rng);
synchronized (rngLock) {
rsa.makeKey(this.keysize, this.publicExponent,
this.rng);
}
/* private key */
privDer = rsa.privateKeyEncodePKCS8();
@ -280,13 +297,16 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
ECPrivateKey eccPriv = null;
ECPublicKey eccPub = null;
Ecc ecc = null;
Ecc ecc = new Ecc();
synchronized (rngLock) {
ecc = new Ecc(this.rng);
if (this.curve == null) {
ecc.makeKey(rng, this.keysize);
} else {
ecc.makeKeyOnCurve(rng, this.keysize, this.curve);
if (this.curve == null) {
ecc.makeKey(this.rng, this.keysize);
} else {
ecc.makeKeyOnCurve(this.rng, this.keysize, this.curve);
}
}
/* private key */
@ -343,7 +363,9 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
dh.setParams(dhP, dhG);
/* make key */
dh.makeKey(rng);
synchronized (rngLock) {
dh.makeKey(this.rng);
}
privSpec = new DHPrivateKeySpec(
new BigInteger(dh.getPrivateKey()),
@ -401,11 +423,13 @@ public class WolfCryptKeyPairGenerator extends KeyPairGeneratorSpi {
@SuppressWarnings("deprecation")
@Override
protected void finalize() throws Throwable {
protected synchronized void finalize() throws Throwable {
try {
if (this.rng != null) {
rng.free();
rng.releaseNativeStruct();
synchronized (rngLock) {
if (this.rng != null) {
this.rng.free();
this.rng.releaseNativeStruct();
}
}
} finally {
super.finalize();

View File

@ -34,7 +34,7 @@ public final class WolfCryptProvider extends Provider {
* Create new WolfCryptProvider object
*/
public WolfCryptProvider() {
super("wolfJCE", 1.5, "wolfCrypt JCE Provider");
super("wolfJCE", 1.6, "wolfCrypt JCE Provider");
/* MessageDigest */
if (FeatureDetect.Md5Enabled()) {
@ -181,41 +181,43 @@ public final class WolfCryptProvider extends Provider {
"com.wolfssl.provider.jce.WolfCryptPKIXCertPathValidator");
/* SecretKeyFactory */
if (FeatureDetect.HmacShaEnabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA1",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA1");
}
if (FeatureDetect.HmacSha224Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA224",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA224");
}
if (FeatureDetect.HmacSha256Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA256",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA256");
}
if (FeatureDetect.HmacSha384Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA384",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA384");
}
if (FeatureDetect.HmacSha512Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA512",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA512");
}
if (FeatureDetect.HmacSha3_224Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-224",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_224");
}
if (FeatureDetect.HmacSha3_256Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-256",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_256");
}
if (FeatureDetect.HmacSha3_384Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-384",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_384");
}
if (FeatureDetect.HmacSha3_512Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-512",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_512");
if (FeatureDetect.Pbkdf2Enabled()) {
if (FeatureDetect.HmacShaEnabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA1",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA1");
}
if (FeatureDetect.HmacSha224Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA224",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA224");
}
if (FeatureDetect.HmacSha256Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA256",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA256");
}
if (FeatureDetect.HmacSha384Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA384",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA384");
}
if (FeatureDetect.HmacSha512Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA512",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA512");
}
if (FeatureDetect.HmacSha3_224Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-224",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_224");
}
if (FeatureDetect.HmacSha3_256Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-256",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_256");
}
if (FeatureDetect.HmacSha3_384Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-384",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_384");
}
if (FeatureDetect.HmacSha3_512Enabled()) {
put("SecretKeyFactory.PBKDF2WithHmacSHA3-512",
"com.wolfssl.provider.jce.WolfCryptSecretKeyFactory$wcPBKDF2WithHmacSHA3_512");
}
}
/* If using a FIPS version of wolfCrypt, allow private key to be

View File

@ -101,21 +101,30 @@ public class WolfCryptSignature extends SignatureSpi {
private String keyString;
private String digestString;
/* Class-wide RNG to be used for padding during sign operations */
private Rng rng = null;
private final Object rngLock = new Object();
private WolfCryptSignature(KeyType ktype, DigestType dtype)
throws NoSuchAlgorithmException {
this.keyType = ktype;
this.digestType = dtype;
/* init asn object */
asn = new Asn();
if ((ktype != KeyType.WC_RSA) &&
(ktype != KeyType.WC_ECDSA)) {
throw new NoSuchAlgorithmException(
"Signature algorithm key type must be RSA or ECC");
}
synchronized (rngLock) {
this.rng = new Rng();
this.rng.init();
}
/* init asn object */
asn = new Asn();
/* init hash type */
switch (dtype) {
case WC_MD5:
@ -238,14 +247,18 @@ public class WolfCryptSignature extends SignatureSpi {
/* initialize native struct */
switch (keyType) {
case WC_RSA:
if (this.rsa != null)
if (this.rsa != null) {
this.rsa.releaseNativeStruct();
}
this.rsa = new Rsa();
break;
case WC_ECDSA:
if (this.ecc != null)
if (this.ecc != null) {
this.ecc.releaseNativeStruct();
this.ecc = new Ecc();
}
synchronized (this.rngLock) {
this.ecc = new Ecc(this.rng);
}
break;
}
@ -303,14 +316,18 @@ public class WolfCryptSignature extends SignatureSpi {
/* initialize native struct */
switch (keyType) {
case WC_RSA:
if (this.rsa != null)
if (this.rsa != null) {
this.rsa.releaseNativeStruct();
}
this.rsa = new Rsa();
break;
case WC_ECDSA:
if (this.ecc != null)
if (this.ecc != null) {
this.ecc.releaseNativeStruct();
this.ecc = new Ecc();
}
synchronized (this.rngLock) {
this.ecc = new Ecc(this.rng);
}
break;
}
@ -390,10 +407,6 @@ public class WolfCryptSignature extends SignatureSpi {
throw new SignatureException(e.getMessage());
}
/* init RNG for padding */
Rng rng = new Rng();
rng.init();
/* sign digest */
switch (this.keyType) {
case WC_RSA:
@ -409,7 +422,9 @@ public class WolfCryptSignature extends SignatureSpi {
byte[] tmp = new byte[encodedSz];
System.arraycopy(encDigest, 0, tmp, 0, encodedSz);
signature = this.rsa.sign(tmp, rng);
synchronized (rngLock) {
signature = this.rsa.sign(tmp, this.rng);
}
zeroArray(tmp);
break;
@ -417,7 +432,9 @@ public class WolfCryptSignature extends SignatureSpi {
case WC_ECDSA:
/* ECC sign */
signature = this.ecc.sign(digest, rng);
synchronized (rngLock) {
signature = this.ecc.sign(digest, this.rng);
}
break;
@ -426,10 +443,6 @@ public class WolfCryptSignature extends SignatureSpi {
"Invalid signature algorithm type");
}
/* release RNG */
rng.free();
rng.releaseNativeStruct();
if (debug.DEBUG) {
if (signature != null) {
log("generated signature, len: " + signature.length);
@ -617,7 +630,7 @@ public class WolfCryptSignature extends SignatureSpi {
@SuppressWarnings("deprecation")
@Override
protected void finalize() throws Throwable {
protected synchronized void finalize() throws Throwable {
try {
/* free native digest objects */
if (this.md5 != null)
@ -642,6 +655,15 @@ public class WolfCryptSignature extends SignatureSpi {
if (this.ecc != null)
this.ecc.releaseNativeStruct(); /* frees internally */
synchronized (rngLock) {
if (this.rng != null) {
/* release RNG */
this.rng.free();
this.rng.releaseNativeStruct();
this.rng = null;
}
}
} finally {
super.finalize();
}

View File

@ -38,9 +38,17 @@ public class Ecc extends NativeStruct {
/* used with native wc_ecc_set_rng() */
private Rng rng = null;
/* Do we own the Rng struct, or has that been passed in? Used
* during Rng cleanup. */
private boolean weOwnRng = true;
/** Lock around Rng object access */
private final Object rngLock = new Object();
/** Lock around object state */
protected final Object stateLock = new Object();
/**
* Create new Ecc object
*/
@ -48,6 +56,18 @@ public class Ecc extends NativeStruct {
init();
}
/**
* Create new Ecc object with existing Rng object.
*
* @param rng initialized com.wolfssl.wolfcrypt.Rng object
*/
public Ecc(Rng rng) {
this.rng = rng;
weOwnRng = false;
init();
}
@Override
public synchronized void releaseNativeStruct() {
free();
@ -100,9 +120,12 @@ public class Ecc extends NativeStruct {
}
/* used with native wc_ecc_set_rng() */
if (rng == null) {
rng = new Rng();
rng.init();
synchronized (rngLock) {
if (rng == null) {
rng = new Rng();
rng.init();
weOwnRng = true;
}
}
state = WolfCryptState.INITIALIZED;
@ -124,9 +147,11 @@ public class Ecc extends NativeStruct {
wc_ecc_free();
}
if (this.rng != null) {
rng.free();
rng.releaseNativeStruct();
synchronized (rngLock) {
if (this.weOwnRng && this.rng != null) {
rng.free();
rng.releaseNativeStruct();
}
}
state = WolfCryptState.UNINITIALIZED;
@ -445,7 +470,9 @@ public class Ecc extends NativeStruct {
if (state == WolfCryptState.READY) {
synchronized (pointerLock) {
return wc_ecc_shared_secret(pubKey, this.rng);
synchronized (rngLock) {
return wc_ecc_shared_secret(pubKey, this.rng);
}
}
} else {
throw new IllegalStateException(
@ -473,7 +500,9 @@ public class Ecc extends NativeStruct {
synchronized (stateLock) {
if (state == WolfCryptState.READY) {
synchronized (pointerLock) {
signature = wc_ecc_sign_hash(hash, rng);
synchronized (rngLock) {
signature = wc_ecc_sign_hash(hash, rng);
}
}
} else {
throw new IllegalStateException(

View File

@ -29,10 +29,11 @@ import java.util.Arrays;
import java.util.ArrayList;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicIntegerArray;
import javax.crypto.KeyAgreement;
import javax.crypto.ShortBufferException;
@ -537,9 +538,18 @@ public class WolfCryptKeyAgreementTest {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final String currentAlgo = algo;
/* Used to detect timeout of CountDownLatch, don't run indefinitely
* if threads are stalled out or deadlocked */
boolean returnWithoutTimeout = true;
/* Keep track of failure and success count */
final AtomicIntegerArray failures = new AtomicIntegerArray(1);
final AtomicIntegerArray success = new AtomicIntegerArray(1);
failures.set(0, 0);
success.set(0, 0);
/* DH Tests */
AlgorithmParameterGenerator paramGen =
AlgorithmParameterGenerator.getInstance("DH");
@ -552,7 +562,6 @@ public class WolfCryptKeyAgreementTest {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
KeyPairGenerator keyGen = null;
KeyAgreement aKeyAgree = null;
KeyAgreement bKeyAgree = null;
@ -603,53 +612,56 @@ public class WolfCryptKeyAgreementTest {
byte secretB[] = bKeyAgree.generateSecret();
if (!Arrays.equals(secretA, secretB)) {
failed = 1;
throw new Exception(
"Secrets A and B to not match");
}
if (failed == 0) {
cKeyAgree = KeyAgreement.getInstance(
currentAlgo, "wolfJCE");
cPair = keyGen.generateKeyPair();
cKeyAgree.init(cPair.getPrivate());
cKeyAgree = KeyAgreement.getInstance(
currentAlgo, "wolfJCE");
cPair = keyGen.generateKeyPair();
cKeyAgree.init(cPair.getPrivate());
aKeyAgree.doPhase(cPair.getPublic(), true);
cKeyAgree.doPhase(aPair.getPublic(), true);
aKeyAgree.doPhase(cPair.getPublic(), true);
cKeyAgree.doPhase(aPair.getPublic(), true);
byte secretA2[] = aKeyAgree.generateSecret();
byte secretC[] = cKeyAgree.generateSecret();
byte secretA2[] = aKeyAgree.generateSecret();
byte secretC[] = cKeyAgree.generateSecret();
if (!Arrays.equals(secretA2, secretC)) {
failed = 1;
}
if (!Arrays.equals(secretA2, secretC)) {
throw new Exception(
"Secrets A2 and C do not match");
}
/* Log success */
success.incrementAndGet(0);
} catch (Exception e) {
e.printStackTrace();
failed = 1;
/* Log failure */
failures.incrementAndGet(0);
} finally {
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
returnWithoutTimeout = latch.await(10, TimeUnit.SECONDS);
service.shutdown();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in KeyAgreement thread test");
/* Check failure count and success count against thread count */
if ((failures.get(0) != 0) ||
(success.get(0) != numThreads)) {
if (returnWithoutTimeout == true) {
fail("KeyAgreement test threading error: " +
failures.get(0) + " failures, " +
success.get(0) + " success, " +
numThreads + " num threads total");
} else {
fail("KeyAgreement test threading error, threads timed out");
}
}
}

View File

@ -55,6 +55,7 @@ import java.security.spec.PKCS8EncodedKeySpec;
import com.wolfssl.wolfcrypt.Rsa;
import com.wolfssl.wolfcrypt.Ecc;
import com.wolfssl.wolfcrypt.Fips;
import com.wolfssl.wolfcrypt.test.Util;
import com.wolfssl.wolfcrypt.WolfCryptException;
import com.wolfssl.provider.jce.WolfCryptProvider;
@ -93,6 +94,16 @@ public class WolfCryptKeyPairGeneratorTest {
"brainpoolp512r1"
};
private static String supportedCurvesFIPS1403[] = {
"secp224r1",
"secp256r1",
"secp384r1",
"secp521r1",
"secp224k1",
"secp256k1",
};
private static ArrayList<String> enabledCurves =
new ArrayList<String>();
@ -100,9 +111,7 @@ public class WolfCryptKeyPairGeneratorTest {
new ArrayList<Integer>();
/* Test generation of these RSA key sizes */
private static int testedRSAKeySizes[] = {
1024, 2048, 3072, 4096
};
private static int testedRSAKeySizes[] = null;
/* DH test params */
private static byte[] prime = Util.h2b(
@ -127,16 +136,35 @@ public class WolfCryptKeyPairGeneratorTest {
Provider p = Security.getProvider("wolfJCE");
assertNotNull(p);
if (Fips.enabled && Fips.fipsVersion >= 5) {
/* FIPS after 2425 doesn't allow 1024-bit RSA key gen */
testedRSAKeySizes = new int[] {
2048, 3072, 4096
};
}
else {
testedRSAKeySizes = new int[] {
1024, 2048, 3072, 4096
};
}
/* build list of enabled curves and key sizes,
* getCurveSizeFromName() will return 0 if curve not found */
Ecc tmp = new Ecc();
for (int i = 0; i < supportedCurves.length; i++) {
String[] curves = null;
int size = tmp.getCurveSizeFromName(
supportedCurves[i].toUpperCase());
if (Fips.enabled && Fips.fipsVersion >= 5) {
curves = supportedCurvesFIPS1403;
} else {
curves = supportedCurves;
}
for (int i = 0; i < curves.length; i++) {
int size = tmp.getCurveSizeFromName(curves[i].toUpperCase());
if (size > 0) {
enabledCurves.add(supportedCurves[i]);
enabledCurves.add(curves[i]);
if (!enabledEccKeySizes.contains(Integer.valueOf(size))) {
enabledEccKeySizes.add(Integer.valueOf(size));

View File

@ -63,6 +63,7 @@ import java.security.cert.CertStore;
import java.security.cert.CollectionCertStoreParameters;
import java.lang.IllegalArgumentException;
import com.wolfssl.wolfcrypt.WolfCrypt;
import com.wolfssl.provider.jce.WolfCryptProvider;
public class WolfCryptPKIXCertPathValidatorTest {
@ -388,6 +389,13 @@ public class WolfCryptPKIXCertPathValidatorTest {
Collection<CRL> crls = null;
List<CertStore> certStores = null;
if (!WolfCrypt.CrlEnabled()) {
/* Native CRL not enabled, skip CRL test */
System.out.println("CertPathValidator CRL test skipped, " +
"CRL not compiled in");
return;
}
/* Use example KeyStore that verifies server-cert.der */
store = createKeyStoreFromFile(jksCaServerRSA2048, keyStorePass);
if (store == null || store.size() != 1) {

View File

@ -29,10 +29,12 @@ import java.util.Arrays;
import java.util.ArrayList;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.security.Security;
import java.security.Provider;
@ -343,15 +345,48 @@ public class WolfCryptSignatureTest {
return pair;
}
private void threadRunnerSignVerify(byte[] inBuf, String algo)
throws InterruptedException {
private void threadRunnerSignVerify(byte[] inBuf, String algo,
final AtomicIntegerArray failures, final AtomicIntegerArray success,
ExecutorService service, final CountDownLatch latch, int numThreads)
throws InterruptedException, Exception {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
final String currentAlgo = algo;
final String currentAlg = algo;
final byte[] toSignBuf = inBuf;
KeyPair pair = null;
KeyPairGenerator keyGen = null;
final PrivateKey priv;
final PublicKey pub;
/* Generate key pairs once up front to minimize use of entropy from
* RNG. We also are just interested in testing sign/verify across
* multiple threads, not key gen in this test. */
if (currentAlg.contains("RSA")) {
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048, secureRandom);
pair = keyGen.generateKeyPair();
} else if (currentAlg.contains("ECDSA")) {
keyGen = KeyPairGenerator.getInstance("EC",
"wolfJCE");
ECGenParameterSpec ecSpec =
new ECGenParameterSpec("secp521r1");
keyGen.initialize(ecSpec);
pair = keyGen.generateKeyPair();
}
if (pair == null) {
throw new Exception("KeyPair from generateKeyPair() is null");
}
else {
priv = pair.getPrivate();
if (priv == null) {
throw new Exception("KeyPair.getPrivate() returned null");
}
pub = pair.getPublic();
if (pub == null) {
throw new Exception("KeyPair.getPublic() returned null");
}
}
/* Do encrypt/decrypt and sign/verify in parallel across numThreads
* threads, all operations should pass */
@ -359,107 +394,115 @@ public class WolfCryptSignatureTest {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
KeyPair pair = null;
KeyPairGenerator keyGen = null;
PrivateKey priv = null;
PublicKey pub = null;
byte[] signature = null;
Signature signer = null;
Signature verifier = null;
byte[] signature = null;
try {
signer = Signature.getInstance(
currentAlgo, "wolfJCE");
verifier = Signature.getInstance(
currentAlgo, "wolfJCE");
signer = Signature.getInstance(currentAlg, "wolfJCE");
verifier = Signature.getInstance(currentAlg, "wolfJCE");
if (signer == null || verifier == null) {
failed = 1;
throw new Exception(
"signer or verifier Signature object null");
}
/* generate key pair */
if (failed == 0) {
if (currentAlgo.contains("RSA")) {
keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048, secureRandom);
pair = keyGen.generateKeyPair();
} else if (currentAlgo.contains("ECDSA")) {
keyGen = KeyPairGenerator.getInstance("EC",
"wolfJCE");
ECGenParameterSpec ecSpec =
new ECGenParameterSpec("secp521r1");
keyGen.initialize(ecSpec);
pair = keyGen.generateKeyPair();
}
if (pair == null) {
failed = 1;
}
else {
priv = pair.getPrivate();
pub = pair.getPublic();
}
/* generate signature */
signer.initSign(priv);
signer.update(toSignBuf, 0, toSignBuf.length);
signature = signer.sign();
if (signature == null || signature.length == 0) {
throw new Exception(
"signer.sign() returned null or zero " +
"length array");
}
if (failed == 0) {
/* generate signature */
signer.initSign(priv);
signer.update(toSignBuf, 0, toSignBuf.length);
signature = signer.sign();
/* verify signature */
verifier.initVerify(pub);
verifier.update(toSignBuf, 0, toSignBuf.length);
boolean verified = verifier.verify(signature);
/* verify signature */
verifier.initVerify(pub);
verifier.update(toSignBuf, 0, toSignBuf.length);
boolean verified = verifier.verify(signature);
if (verified == false) {
failed = 1;
}
if (verified == false) {
throw new Exception(
"verifier.verify() returned false:\n" +
"algo: " + currentAlg + "\n" +
"signature (" + signature.length + " bytes): " +
arrayToHex(signature) + "\n" +
"private (" + priv.getEncoded().length +
" bytes): " + arrayToHex(priv.getEncoded()) +
"\npublic (" + pub.getEncoded().length +
" bytes): " + arrayToHex(pub.getEncoded()));
}
/* Log success */
success.incrementAndGet(0);
} catch (Exception e) {
e.printStackTrace();
failed = 1;
/* Log failure */
failures.incrementAndGet(0);
} finally {
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
}
/* wait for all threads to complete */
latch.await();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in RSA sign/verify thread test");
}
private synchronized String arrayToHex(byte[] in) {
StringBuilder builder = new StringBuilder();
for (byte b: in) {
builder.append(String.format("%02X", b));
}
return builder.toString();
}
@Test
public void testThreadedWolfSignWolfVerify() throws InterruptedException {
public void testThreadedWolfSignWolfVerify() throws Exception {
final String toSign = "Hello World";
final byte[] toSignBuf = toSign.getBytes();
int numThreads = 10;
int numAlgos = enabledAlgos.size();
ExecutorService service =
Executors.newFixedThreadPool(numAlgos * numThreads);
final CountDownLatch latch = new CountDownLatch(numAlgos * numThreads);
/* Used to detect timeout of CountDownLatch, don't run indefinitely
* if threads are stalled out or deadlocked */
boolean returnWithoutTimeout = true;
/* Keep track of failure and success count */
final AtomicIntegerArray failures = new AtomicIntegerArray(1);
final AtomicIntegerArray success = new AtomicIntegerArray(1);
failures.set(0, 0);
success.set(0, 0);
/* run threaded test for each enabled Signature algorithm */
for (int i = 0; i < enabledAlgos.size(); i++) {
threadRunnerSignVerify(toSignBuf, enabledAlgos.get(i));
for (int i = 0; i < numAlgos; i++) {
threadRunnerSignVerify(toSignBuf, enabledAlgos.get(i),
failures, success, service, latch, numThreads);
}
/* wait for all threads to complete */
returnWithoutTimeout = latch.await(10, TimeUnit.SECONDS);
service.shutdown();
/* Check failure count and success count against thread count */
if ((failures.get(0) != 0) ||
(success.get(0) != (enabledAlgos.size() * numThreads))) {
if (returnWithoutTimeout == true) {
fail("Signature test threading error: " +
failures.get(0) + " failures, " +
success.get(0) + " success, " +
(numThreads * enabledAlgos.size()) + " num threads total");
} else {
fail("Signature test threading error, threads timed out");
}
}
}
}

View File

@ -30,10 +30,11 @@ import org.junit.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicIntegerArray;
import com.wolfssl.wolfcrypt.Dh;
import com.wolfssl.wolfcrypt.Rng;
@ -105,7 +106,16 @@ public class DhTest {
int numThreads = 10;
ExecutorService service = Executors.newFixedThreadPool(numThreads);
final CountDownLatch latch = new CountDownLatch(numThreads);
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
/* Used to detect timeout of CountDownLatch, don't run indefinitely
* if threads are stalled out or deadlocked */
boolean returnWithoutTimeout = true;
/* Keep track of failure and success count */
final AtomicIntegerArray failures = new AtomicIntegerArray(1);
final AtomicIntegerArray success = new AtomicIntegerArray(1);
failures.set(0, 0);
success.set(0, 0);
final byte[] p = Util.h2b(
"E6969D3D495BE32C7CF180C3BDD4798E91B7818251BB055E"
@ -121,7 +131,6 @@ public class DhTest {
service.submit(new Runnable() {
@Override public void run() {
int failed = 0;
Dh alice = null;
Dh bob = null;
@ -134,65 +143,65 @@ public class DhTest {
/* keys should be null before generation */
if (alice.getPublicKey() != null ||
bob.getPublicKey() != null) {
failed = 1;
throw new Exception(
"keys not null before generation");
}
/* generate Dh keys */
if (failed == 0) {
synchronized (rngLock) {
alice.makeKey(rng);
bob.makeKey(rng);
}
synchronized (rngLock) {
alice.makeKey(rng);
bob.makeKey(rng);
}
/* keys should not be null after generation */
if (failed == 0) {
if (alice.getPublicKey() == null ||
bob.getPublicKey() == null) {
failed = 1;
}
if (alice.getPublicKey() == null ||
bob.getPublicKey() == null) {
throw new Exception(
"keys null after generation");
}
if (failed == 0) {
byte[] sharedSecretA = alice.makeSharedSecret(bob);
byte[] sharedSecretB = bob.makeSharedSecret(alice);
byte[] sharedSecretA = alice.makeSharedSecret(bob);
byte[] sharedSecretB = bob.makeSharedSecret(alice);
if (sharedSecretA == null ||
sharedSecretB == null ||
!Arrays.equals(sharedSecretA, sharedSecretB)) {
failed = 1;
}
if (sharedSecretA == null ||
sharedSecretB == null ||
!Arrays.equals(sharedSecretA, sharedSecretB)) {
throw new Exception(
"shared secrets null or not equal");
}
/* Log success */
success.incrementAndGet(0);
} catch (Exception e) {
e.printStackTrace();
failed = 1;
/* Log failure */
failures.incrementAndGet(0);
} finally {
alice.releaseNativeStruct();
bob.releaseNativeStruct();
latch.countDown();
}
if (failed == 1) {
results.add(1);
}
else {
results.add(0);
}
}
});
}
/* wait for all threads to complete */
latch.await();
returnWithoutTimeout = latch.await(10, TimeUnit.SECONDS);
service.shutdown();
/* Look for any failures that happened */
Iterator<Integer> listIterator = results.iterator();
while (listIterator.hasNext()) {
Integer cur = listIterator.next();
if (cur == 1) {
fail("Threading error in DH shared secret thread test");
/* Check failure count and success count against thread count */
if ((failures.get(0) != 0) ||
(success.get(0) != numThreads)) {
if (returnWithoutTimeout == true) {
fail("DH shared secret test threading error: " +
failures.get(0) + " failures, " +
success.get(0) + " success, " +
numThreads + " num threads total");
} else {
fail("DH shared secret test error, threads timed out");
}
}
}

View File

@ -71,9 +71,14 @@ public class RsaTest {
@Test
public void testMakeKey() {
Rsa key = new Rsa();
key.makeKey(1024, 65537, rng);
key.releaseNativeStruct();
Rsa key = null;
/* FIPS after 2425 doesn't allow 1024-bit RSA key gen */
if (Fips.enabled && Fips.fipsVersion < 5) {
key = new Rsa();
key.makeKey(1024, 65537, rng);
key.releaseNativeStruct();
}
key = new Rsa();
key.makeKey(2048, 65537, rng);
@ -219,6 +224,12 @@ public class RsaTest {
+ "4e8c3a458fe69640eb63f919863a51dd894bb0f3f99f5d289538"
+ "be35abca5ce7935334a1455d1339654246a19fcdf5bf");
/* FIPS after 2425 doesn't allow 1024-bit RSA key gen */
if (Fips.enabled && Fips.fipsVersion >= 5) {
/* skip */
return;
}
/* Test that exception is thrown without private key available */
try {
pkcs8 = key.privateKeyEncodePKCS8();