commit
e25d43d0b7
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
132
README.md
|
@ -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).
|
||||
|
||||
|
|
|
@ -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/" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue