Merge pull request #70 from cconlon/SecretKeyFactory

JCE: add SecretKeyFactory implementation (PBKDF2)
pull/72/head
Daniel Pouzzner 2024-03-30 02:55:28 -04:00 committed by GitHub
commit f3bf4131a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 2951 additions and 13 deletions

View File

@ -75,6 +75,17 @@ The JCE provider currently supports the following algorithms:
CertPathValidator Class
PKIX
SecretKeyFactory
PBKDF2WithHmacSHA1
PBKDF2WithHmacSHA224
PBKDF2WithHmacSHA256
PBKDF2WithHmacSHA384
PBKDF2WithHmacSHA512
PBKDF2WithHmacSHA3-224
PBKDF2WithHmacSHA3-256
PBKDF2WithHmacSHA3-384
PBKDF2WithHmacSHA3-512
### SecureRandom.getInstanceStrong()
When registered as the highest priority security provider, wolfJCE will provide

View File

@ -127,6 +127,14 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacMd5Enabl
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacShaEnabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha224Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha224Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha256Enabled
@ -151,6 +159,46 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha384En
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha512Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha3_224Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1224Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha3_256Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1256Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha3_384Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1384Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: HmacSha3_512Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1512Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: Pbkdf2Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: RsaEnabled

View File

@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_wolfssl_wolfcrypt_Pwdbased */
#ifndef _Included_com_wolfssl_wolfcrypt_Pwdbased
#define _Included_com_wolfssl_wolfcrypt_Pwdbased
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_wolfssl_wolfcrypt_Pwdbased
* Method: wc_PKCS12_PBKDF
* Signature: ([BI[BIIIII)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PKCS12_1PBKDF
(JNIEnv *, jclass, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jint);
/*
* Class: com_wolfssl_wolfcrypt_Pwdbased
* Method: wc_PBKDF2
* Signature: ([BI[BIIII)[B
*/
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2
(JNIEnv *, jclass, jbyteArray, jint, jbyteArray, jint, jint, jint, jint);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -29,6 +29,118 @@ extern "C" {
#define com_wolfssl_wolfcrypt_WolfCrypt_SIZE_OF_1024_BITS 128L
#undef com_wolfssl_wolfcrypt_WolfCrypt_SIZE_OF_2048_BITS
#define com_wolfssl_wolfcrypt_WolfCrypt_SIZE_OF_2048_BITS 256L
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_NONE
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1NONE
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_MD2
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD2
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_MD4
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD4
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_MD5
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD5
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA224
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA224
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA256
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA256
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA384
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA384
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA512
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA512
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_MD5_SHA
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD5_1SHA
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA3_224
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1224
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA3_256
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1256
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA3_384
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1384
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: getWC_HASH_TYPE_SHA3_512
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1512
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_WolfCrypt
* Method: CrlEnabled

View File

@ -208,6 +208,18 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacShaEnabl
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha224Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && !defined(WOLFSSL_SHA224)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha256Enabled
(JNIEnv* env, jclass jcl)
{
@ -244,6 +256,66 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha512En
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1224Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_224)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1256Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_256)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1384Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_384)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1512Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_HMAC) && defined(WOLFSSL_SHA3) && !defined(WOLFSSL_NOSHA3_512)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_PWDBASED) && defined(HAVE_PBKDF2) && !defined(NO_HMAC)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_RsaEnabled
(JNIEnv* env, jclass jcl)
{

180
jni/jni_pwdbased.c 100644
View File

@ -0,0 +1,180 @@
/* jni_pwdbased.c
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <stdint.h>
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#elif !defined(__ANDROID__)
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/pwdbased.h>
#include <com_wolfssl_wolfcrypt_Pwdbased.h>
#include <wolfcrypt_jni_error.h>
/* #define WOLFCRYPT_JNI_DEBUG_ON */
#include <wolfcrypt_jni_debug.h>
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PKCS12_1PBKDF
(JNIEnv* env, jclass jcl, jbyteArray passBuf, jint passBufLen,
jbyteArray saltBuf, jint sBufLen, jint iterations, jint kLen,
jint typeH, jint id)
{
#if !defined(NO_PWDBASED) && defined(WOLFSSL_PKCS12)
int ret = 0;
byte* pass = NULL;
byte* salt = NULL;
byte* outKey = NULL;
jbyteArray result = NULL;
(void)jcl;
if (env == NULL || kLen == 0) {
throwWolfCryptExceptionFromError(env, BAD_FUNC_ARG);
return NULL;
}
outKey = (byte*)XMALLOC(kLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (outKey == NULL) {
throwWolfCryptExceptionFromError(env, MEMORY_E);
return NULL;
}
XMEMSET(outKey, 0, kLen);
pass = (byte*)(*env)->GetByteArrayElements(env, passBuf, NULL);
salt = (byte*)(*env)->GetByteArrayElements(env, saltBuf, NULL);
ret = wc_PKCS12_PBKDF(outKey, pass, passBufLen, salt, sBufLen,
iterations, kLen, typeH, id);
if (ret == 0) {
result = (*env)->NewByteArray(env, kLen);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, kLen,
(const jbyte*) outKey);
} else {
LogStr("NewByteArray failed in JNI PKCS12_PBKDF\n");
ret = MEMORY_E;
}
}
if (outKey != NULL) {
XMEMSET(outKey, 0, kLen);
XFREE(outKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
(*env)->ReleaseByteArrayElements(env, passBuf, (jbyte*)pass, JNI_ABORT);
(*env)->ReleaseByteArrayElements(env, saltBuf, (jbyte*)salt, JNI_ABORT);
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
return NULL;
}
return result;
#else
(void)env;
(void)jcl;
(void)passBuf;
(void)passBufLen;
(void)saltBuf;
(void)sBufLen;
(void)iterations;
(void)kLen;
(void)typeH;
(void)id;
throwWolfCryptExceptionFromError(env, NOT_COMPILED_IN);
return NULL;
#endif
}
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2
(JNIEnv* env, jclass jcl, jbyteArray passBuf, jint passBufLen,
jbyteArray saltBuf, jint sBufLen, jint iterations, jint kLen, jint hashType)
{
#if !defined(NO_PWDBASED) && defined(HAVE_PBKDF2) && !defined(NO_HMAC)
int ret = 0;
byte* pass = NULL;
byte* salt = NULL;
byte* outKey = NULL;
jbyteArray result = NULL;
(void)jcl;
if (env == NULL || kLen == 0) {
throwWolfCryptExceptionFromError(env, BAD_FUNC_ARG);
return NULL;
}
outKey = (byte*)XMALLOC(kLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (outKey == NULL) {
throwWolfCryptExceptionFromError(env, MEMORY_E);
return NULL;
}
XMEMSET(outKey, 0, kLen);
if ((passBuf != NULL) && (passBufLen > 0)) {
pass = (byte*)(*env)->GetByteArrayElements(env, passBuf, NULL);
}
salt = (byte*)(*env)->GetByteArrayElements(env, saltBuf, NULL);
ret = wc_PBKDF2(outKey, pass, passBufLen, salt, sBufLen,
iterations, kLen, hashType);
if (ret == 0) {
result = (*env)->NewByteArray(env, kLen);
if (result != NULL) {
(*env)->SetByteArrayRegion(env, result, 0, kLen,
(const jbyte*) outKey);
} else {
LogStr("NewByteArray failed in JNI PBKDF2\n");
ret = MEMORY_E;
}
}
if (outKey != NULL) {
XMEMSET(outKey, 0, kLen);
XFREE(outKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (pass != NULL) {
(*env)->ReleaseByteArrayElements(env, passBuf, (jbyte*)pass, JNI_ABORT);
}
(*env)->ReleaseByteArrayElements(env, saltBuf, (jbyte*)salt, JNI_ABORT);
if (ret != 0) {
throwWolfCryptExceptionFromError(env, ret);
return NULL;
}
return result;
#else
(void)env;
(void)jcl;
(void)passBuf;
(void)passBufLen;
(void)salt;
(void)sBufLen;
(void)iterations;
(void)kLen;
(void)hashType;
throwWolfCryptExceptionFromError(env, NOT_COMPILED_IN);
return NULL;
#endif
}

View File

@ -33,6 +33,90 @@
/* #define WOLFCRYPT_JNI_DEBUG_ON */
#include <wolfcrypt_jni_debug.h>
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1NONE
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_NONE;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD2
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_MD2;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD4
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_MD4;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD5
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_MD5;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA224
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA224;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA256
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA256;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA384
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA384;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA512
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA512;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1MD5_1SHA
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_MD5_SHA;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1224
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA3_224;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1256
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA3_256;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1384
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA3_384;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_getWC_1HASH_1TYPE_1SHA3_1512
(JNIEnv* env, jclass class)
{
return WC_HASH_TYPE_SHA3_512;
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_WolfCrypt_CrlEnabled
(JNIEnv* env, jclass jcl)
{

View File

@ -26,11 +26,12 @@ endif
DIST_FILES = AUTHORS build.xml COPYING examples jni LICENSING makefile makefile.linux makefile.macosx \
pom.xml README_JCE.md README.md rpm src
OBJ_LIST = jni_fips.o jni_native_struct.o jni_aes.o jni_aesgcm.o jni_des3.o \
jni_md5.o jni_sha.o jni_hmac.o jni_rng.o jni_rsa.o jni_dh.o \
jni_ecc.o jni_ed25519.o jni_curve25519.o jni_chacha.o jni_error.o \
jni_asn.o jni_logging.o jni_feature_detect.o jni_wolfobject.o \
jni_wolfcrypt.o jni_wolfssl_cert_manager.o
OBJ_LIST = jni_fips.o jni_native_struct.o jni_pwdbased.o jni_aes.o \
jni_aesgcm.o jni_des3.o jni_md5.o jni_sha.o jni_hmac.o \
jni_rng.o jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o \
jni_curve25519.o jni_chacha.o jni_error.o jni_asn.o jni_logging.o \
jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \
jni_wolfssl_cert_manager.o
OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST))
TARGET = $(OUT_PATH)/libwolfcryptjni.so

View File

@ -20,11 +20,12 @@ ifeq ($(WOLFSSL_LIBNAME),)
WOLFSSL_LIBNAME=wolfssl
endif
OBJ_LIST = jni_fips.o jni_native_struct.o jni_aes.o jni_aesgcm.o jni_des3.o \
jni_md5.o jni_sha.o jni_hmac.o jni_rng.o jni_rsa.o jni_dh.o \
jni_ecc.o jni_ed25519.o jni_curve25519.o jni_chacha.o jni_error.o \
jni_asn.o jni_logging.o jni_feature_detect.o jni_wolfobject.o \
jni_wolfcrypt.o jni_wolfssl_cert_manager.o
OBJ_LIST = jni_fips.o jni_native_struct.o jni_pwdbased.o jni_aes.o \
jni_aesgcm.o jni_des3.o jni_md5.o jni_sha.o jni_hmac.o jni_rng.o \
jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o jni_curve25519.o \
jni_chacha.o jni_error.o jni_asn.o jni_logging.o \
jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \
jni_wolfssl_cert_manager.o
OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST))
TARGET = $(OUT_PATH)/libwolfcryptjni.dylib

View File

@ -34,29 +34,34 @@ infer run -- javac \
src/main/java/com/wolfssl/wolfcrypt/Md5.java \
src/main/java/com/wolfssl/wolfcrypt/MessageDigest.java \
src/main/java/com/wolfssl/wolfcrypt/NativeStruct.java \
src/main/java/com/wolfssl/wolfcrypt/Pwdbased.java \
src/main/java/com/wolfssl/wolfcrypt/Rng.java \
src/main/java/com/wolfssl/wolfcrypt/Rsa.java \
src/main/java/com/wolfssl/wolfcrypt/Sha.java \
src/main/java/com/wolfssl/wolfcrypt/Sha256.java \
src/main/java/com/wolfssl/wolfcrypt/Sha384.java \
src/main/java/com/wolfssl/wolfcrypt/Sha512.java \
src/main/java/com/wolfssl/wolfcrypt/Sha.java \
src/main/java/com/wolfssl/wolfcrypt/WolfCrypt.java \
src/main/java/com/wolfssl/wolfcrypt/WolfCryptError.java \
src/main/java/com/wolfssl/wolfcrypt/WolfCryptException.java \
src/main/java/com/wolfssl/wolfcrypt/WolfCrypt.java \
src/main/java/com/wolfssl/wolfcrypt/WolfCryptState.java \
src/main/java/com/wolfssl/wolfcrypt/WolfObject.java \
src/main/java/com/wolfssl/wolfcrypt/WolfSSLCertManager.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptDebug.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptKeyAgreement.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptKeyPairGenerator.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMac.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestMd5.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestSha.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestSha256.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestSha384.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestSha512.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptMessageDigestSha.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptPBEKey.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptPKIXCertPathValidator.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptProvider.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptRandom.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptSecretKeyFactory.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java
# remove compiled class files

View File

@ -0,0 +1,291 @@
/* WolfCryptPBEKey.java
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
package com.wolfssl.provider.jce;
import java.util.Arrays;
import java.security.spec.InvalidKeySpecException;
import javax.security.auth.Destroyable;
import javax.crypto.interfaces.PBEKey;
import com.wolfssl.provider.jce.WolfCryptDebug;
/**
* wolfCrypt PBEKey implementation.
*/
public class WolfCryptPBEKey implements PBEKey, Destroyable {
private static final long serialVersionUID = 1L;
/** PBKDF2 iterations used to derive encoded key */
private int iterations = 0;
/** Password used to derive encoded key */
private char[] password = null;
/** Salt used to derive encoded key */
private byte[] salt = null;
/** Key encoded as byte array */
private byte[] encoded = null;
/** Algorithm used by this key */
private String algorithm = null;
/** Track if object has been destroyed */
private boolean destroyed = false;
/** Lock around use of destroyed boolean */
private final Object destroyedLock = new Object();
/**
* Create new WolfCryptPBEKey object.
*
* @param password password used to derive the encoded key
* @param salt salt used to derive the encoded key
* @param iterations PBKDF iterations used to derive the encoded key
* @param algorithm algorithm of this key
* @param encoded encoded byte array of key
*
* @throws InvalidKeySpecException if arguments are not compatible
* with creation of this object
*/
protected WolfCryptPBEKey(char[] password, byte[] salt,
int iterations, String algorithm, byte[] encoded)
throws InvalidKeySpecException {
if (salt == null || salt.length == 0) {
throw new InvalidKeySpecException(
"Salt cannot be null or zero length");
}
if (iterations <= 0) {
throw new InvalidKeySpecException(
"Iterations cannot be less than or equal to zero");
}
if (algorithm == null || algorithm.isEmpty()) {
throw new InvalidKeySpecException(
"Algorithm String cannot be null or empty");
}
if (encoded == null || encoded.length == 0) {
throw new InvalidKeySpecException(
"Encoded key cannot be null or zero length");
}
this.password = password.clone();
this.salt = salt.clone();
this.iterations = iterations;
this.algorithm = algorithm;
this.encoded = encoded.clone();
}
/**
* Check if this object has been destroyed with destroy().
*
* @throws IllegalStateException if object has been destroyed
*/
private synchronized void checkDestroyed()
throws IllegalStateException {
synchronized (destroyedLock) {
if (this.destroyed == true) {
throw new IllegalStateException(
"PBEKey has been destroyed");
}
}
}
/**
* Return password used with this PBEKey.
*
* @return a copy of the internal password buffer
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized char[] getPassword() {
checkDestroyed();
if (this.password == null) {
return null;
}
return this.password.clone();
}
/**
* Return salt used with this PBEKey.
*
* @return a copy of the internal salt buffer
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized byte[] getSalt() {
checkDestroyed();
return this.salt.clone();
}
/**
* Return iteration count used with this PBEKey.
*
* @return iteration count
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized int getIterationCount() {
checkDestroyed();
return this.iterations;
}
/**
* Return algorithm String representing this PBEKey.
*
* @return PBE algorithm string matching this object
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized String getAlgorithm() {
checkDestroyed();
return this.algorithm;
}
/**
* Return encoding format for this PBEKey.
*
* @return encoding format string, will be "RAW" for this object
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized String getFormat() {
checkDestroyed();
return "RAW";
}
/**
* Return encoded byte array of this PBEKey.
*
* @return encoded byte array
*
* @throws IllegalStateException if object has been destroyed
*/
public synchronized byte[] getEncoded() {
checkDestroyed();
return this.encoded.clone();
}
/**
* Destroy this object.
*
* Calling this method will zeroize the password and salt arrays
* contained in this object and mark it as unusable.
*/
public synchronized void destroy() {
synchronized (destroyedLock) {
if (this.password != null) {
Arrays.fill(this.password, (char)0);
}
if (this.salt != null) {
Arrays.fill(this.salt, (byte)0);
}
this.iterations = 0;
this.algorithm = null;
this.destroyed = true;
}
}
/**
* Return if this object has been destroyed.
*
* Object can be destroyed by calling destroy(), which will zeroize
* internal buffers for this object.
*
* @return true if object has been destroyed, otherwise false
*/
public synchronized boolean isDestroyed() {
synchronized (destroyedLock) {
if (this.destroyed) {
return true;
}
return false;
}
}
@Override
public synchronized int hashCode() {
return Arrays.hashCode(encoded);
}
@Override
public synchronized boolean equals(Object obj) {
PBEKey pKey = null;
synchronized (destroyedLock) {
if (obj == this) {
return true;
}
if (!(obj instanceof PBEKey)) {
return false;
}
pKey = (PBEKey)obj;
if (!Arrays.equals(pKey.getEncoded(), getEncoded())) {
return false;
}
if (!Arrays.equals(pKey.getSalt(), getSalt())) {
return false;
}
if (!Arrays.equals(pKey.getPassword(), getPassword())) {
return false;
}
if (pKey.getIterationCount() != getIterationCount()) {
return false;
}
if (!pKey.getAlgorithm().equals(getAlgorithm())) {
return false;
}
if (!pKey.getFormat().equals(getFormat())) {
return false;
}
return true;
}
}
}

View File

@ -178,6 +178,44 @@ public final class WolfCryptProvider extends Provider {
put("CertPathValidator.PKIX",
"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 using a FIPS version of wolfCrypt, allow private key to be
* exported for use. Only applicable to FIPS 140-3 */
if (Fips.enabled) {

View File

@ -0,0 +1,721 @@
/* WolfCryptSecretKeyFactory.java
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
package com.wolfssl.provider.jce;
import java.util.Arrays;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactorySpi;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.interfaces.PBEKey;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.spec.KeySpec;
import java.security.spec.InvalidKeySpecException;
import com.wolfssl.wolfcrypt.WolfCrypt;
import com.wolfssl.wolfcrypt.Pwdbased;
import com.wolfssl.provider.jce.WolfCryptDebug;
/**
* wolfCrypt JCE SecretKeyFactory implementation.
*/
public class WolfCryptSecretKeyFactory extends SecretKeyFactorySpi {
private enum FactoryType {
WC_SKF_PBKDF2_HMAC_SHA1,
WC_SKF_PBKDF2_HMAC_SHA224,
WC_SKF_PBKDF2_HMAC_SHA256,
WC_SKF_PBKDF2_HMAC_SHA384,
WC_SKF_PBKDF2_HMAC_SHA512,
WC_SKF_PBKDF2_HMAC_SHA3_224,
WC_SKF_PBKDF2_HMAC_SHA3_256,
WC_SKF_PBKDF2_HMAC_SHA3_384,
WC_SKF_PBKDF2_HMAC_SHA3_512
}
/* PBKDF2/HMAC type of this factory */
private FactoryType factoryType;
/* String representation of this factory type */
private String typeString;
/* wolfCrypt int representing hash used in this factory */
private int hashType;
private WolfCryptDebug debug;
private WolfCryptSecretKeyFactory(FactoryType type)
throws NoSuchAlgorithmException {
this.factoryType = type;
switch (type) {
case WC_SKF_PBKDF2_HMAC_SHA1:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA;
break;
case WC_SKF_PBKDF2_HMAC_SHA224:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA224;
break;
case WC_SKF_PBKDF2_HMAC_SHA256:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA256;
break;
case WC_SKF_PBKDF2_HMAC_SHA384:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA384;
break;
case WC_SKF_PBKDF2_HMAC_SHA512:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA512;
break;
case WC_SKF_PBKDF2_HMAC_SHA3_224:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA3_224;
break;
case WC_SKF_PBKDF2_HMAC_SHA3_256:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA3_256;
break;
case WC_SKF_PBKDF2_HMAC_SHA3_384:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA3_384;
break;
case WC_SKF_PBKDF2_HMAC_SHA3_512:
this.hashType = WolfCrypt.WC_HASH_TYPE_SHA3_512;
break;
default:
throw new NoSuchAlgorithmException(
"Unsupported SecretKeyFactory type");
}
typeString = typeToString(type);
log("created new SecretKeyFactory");
}
/**
* Internal method for logging output.
*
* @param msg message to be logged
*/
private void log(String msg) {
if (debug.DEBUG) {
debug.print("[SecretKeyFactory, " + typeString + "] " + msg);
}
}
/**
* Return String name of provided FactoryType.
*
* @param type FactoryType to return corresponding name String for
*
* @return String name matching provided FactoryType
*/
private String typeToString(FactoryType type) {
switch (type) {
case WC_SKF_PBKDF2_HMAC_SHA1:
return "PBKDF2WithHmacSHA1";
case WC_SKF_PBKDF2_HMAC_SHA224:
return "PBKDF2WithHmacSHA224";
case WC_SKF_PBKDF2_HMAC_SHA256:
return "PBKDF2WithHmacSHA256";
case WC_SKF_PBKDF2_HMAC_SHA384:
return "PBKDF2WithHmacSHA384";
case WC_SKF_PBKDF2_HMAC_SHA512:
return "PBKDF2WithHmacSHA512";
case WC_SKF_PBKDF2_HMAC_SHA3_224:
return "PBKDF2WithHmacSHA3-224";
case WC_SKF_PBKDF2_HMAC_SHA3_256:
return "PBKDF2WithHmacSHA3-256";
case WC_SKF_PBKDF2_HMAC_SHA3_384:
return "PBKDF2WithHmacSHA3-384";
case WC_SKF_PBKDF2_HMAC_SHA3_512:
return "PBKDF2WithHmacSHA3-512";
default:
return "None";
}
}
/**
* Test if this SecretKeyFactory is PBKDF2.
*
* @return true if PBKDF2 factory, otherwise false
*/
private boolean isFactoryPBKDF() {
switch (this.factoryType) {
case WC_SKF_PBKDF2_HMAC_SHA1:
case WC_SKF_PBKDF2_HMAC_SHA224:
case WC_SKF_PBKDF2_HMAC_SHA256:
case WC_SKF_PBKDF2_HMAC_SHA384:
case WC_SKF_PBKDF2_HMAC_SHA512:
case WC_SKF_PBKDF2_HMAC_SHA3_224:
case WC_SKF_PBKDF2_HMAC_SHA3_256:
case WC_SKF_PBKDF2_HMAC_SHA3_384:
case WC_SKF_PBKDF2_HMAC_SHA3_512:
return true;
default:
return false;
}
}
/**
* Test if provided algorithm String is supported by this
* SecretKeyFactory.
*
* @param algorithm String to test for support
*
* @return true if supported, otherwise false
*/
private boolean isAlgorithmSupported(String algo) {
if (algo == null) {
return false;
}
switch (algo) {
case "PBKDF2WithHmacSHA1":
case "PBKDF2WithHmacSHA224":
case "PBKDF2WithHmacSHA256":
case "PBKDF2WithHmacSHA384":
case "PBKDF2WithHmacSHA512":
case "PBKDF2WithHmacSHA3-224":
case "PBKDF2WithHmacSHA3-256":
case "PBKDF2WithHmacSHA3-384":
case "PBKDF2WithHmacSHA3-512":
return true;
default:
return false;
}
}
/**
* Check if provided KeySpec is supported by this SecretKeyFactory.
*
* @throws InvalidKeySpecException if KeySpec is invalid or incompatible
* with this factory
*/
private void checkKeySpecSupported(KeySpec spec)
throws InvalidKeySpecException {
if (spec == null) {
throw new InvalidKeySpecException("KeySpec cannot be null");
}
if (isFactoryPBKDF()) {
if (!(spec instanceof PBEKeySpec)) {
throw new InvalidKeySpecException(
"KeySpec must be type PBEKeySpec");
}
} else {
throw new InvalidKeySpecException(
"Unsupported SecretKeyFactory type");
}
}
/**
* Convert password from char[] to byte[].
*
* RFC 2898 (PBKDF2) considers password to be an octet string and
* recommends for interop ASCII or UTF-8 encoding is used. SunJCE uses
* UTF-8 for PBKDF2 SecretKeyFactory, so we do the same here for interop
* compatibility.
*
* @param pass password as char array
*
* @return password as UTF-8 encoded byte array, or null if input password
* is null or zero length
*/
private static byte[] passwordToByteArray(char[] pass) {
byte[] passBytes = null;
CharBuffer passBuf = null;
ByteBuffer utf8Buf = null;
if (pass == null || pass.length == 0) {
return null;
}
passBuf = CharBuffer.wrap(pass);
utf8Buf = StandardCharsets.UTF_8.encode(passBuf);
passBytes = new byte[utf8Buf.limit()];
utf8Buf.get(passBytes);
return passBytes;
}
/**
* Generate SecretKey (PBEKey) from provided PBEKeySpec.
*
* @param spec PBEKeySpec to use for generating SecretKey
*
* @throws InvalidKeySpecException if SecretKey generation fails
*/
private SecretKey genSecretKeyFromPBEKeySpec(PBEKeySpec spec)
throws InvalidKeySpecException {
int iterations;
int kLen;
byte[] salt = null;
char[] pass = null;
byte[] derivedKey = null;
SecretKey key = null;
try {
iterations = spec.getIterationCount();
kLen = spec.getKeyLength();
salt = spec.getSalt();
pass = spec.getPassword();
if (salt == null || salt.length == 0) {
throw new InvalidKeySpecException(
"Null or zero length salt not allowed");
}
if (kLen < 8) {
throw new InvalidKeySpecException(
"Key length must be at least one byte (8 bits)");
}
if ((kLen % 8) != 0) {
throw new InvalidKeySpecException(
"Key length bits is not divisible by 8 (byte conversion)");
}
/* Key length is given in bits, convert to bytes */
kLen = kLen / 8;
log("generating PBEKey (iterations: " + iterations +
", key len: " + kLen + " bytes)");
derivedKey = Pwdbased.PBKDF2(passwordToByteArray(pass),
salt, iterations, kLen, this.hashType);
if (derivedKey == null || derivedKey.length == 0) {
throw new InvalidKeySpecException(
"Error deriving key with PBKDF2");
}
key = new WolfCryptPBEKey(pass, salt, iterations,
this.typeString, derivedKey);
} finally {
iterations = 0;
kLen = 0;
if (salt != null) {
Arrays.fill(salt, (byte)0);
}
if (pass != null) {
Arrays.fill(pass, (char)0);
}
if (derivedKey != null) {
Arrays.fill(derivedKey, (byte)0);
}
}
return key;
}
/**
* Generate a SecretKey object from the provided KeySpec.
*
* @param spec specification of the secret key
*
* @return SecretKey generated from KeySpec
*
* @throws InvalidKeySpecException if provided KeySpec is incorrect
* or incomplete for generating a SecretKey
*/
@Override
protected synchronized SecretKey engineGenerateSecret(KeySpec spec)
throws InvalidKeySpecException {
log("generating SecretKey from KeySpec");
checkKeySpecSupported(spec);
return genSecretKeyFromPBEKeySpec((PBEKeySpec)spec);
}
/**
* Return a KeySpec from the provided PBEKey in the requested format.
*
* Called by engineGetKeySpec().
*
* @param key PBEKey for which to return KeySpec
* @param keSpec the requested format that the KeySpec should be returned in
*
* @return KeySpec for the PBEKey, in the requested format
*
* @throws InvalidKeySpecException if the requested format is not
* appropriate for the given key, or the provided PBEKey
* cannot be used.
*/
private KeySpec getKeySpecFromPBEKeyByType(PBEKey key, Class<?> keySpec)
throws InvalidKeySpecException {
int iterations = 0;
char[] password = null;
byte[] salt = null;
byte[] encoded = null;
PBEKeySpec pbSpec = null;
if (key != null && keySpec != null) {
if (keySpec.isAssignableFrom(PBEKeySpec.class)) {
try {
password = key.getPassword();
salt = key.getSalt();
iterations = key.getIterationCount();
encoded = key.getEncoded();
if (encoded == null) {
throw new InvalidKeySpecException(
"Error getting encoded key from PBEKey");
}
pbSpec = new PBEKeySpec(password, salt, iterations,
encoded.length);
} finally {
if (password != null) {
Arrays.fill(password, (char)0);
}
if (salt != null) {
Arrays.fill(salt, (byte)0);
}
if (encoded != null) {
Arrays.fill(encoded, (byte)0);
}
}
}
}
return pbSpec;
}
/**
* Return a KeySpec (key material) of the provided SecretKey in the
* requested format.
*
* @param key SecretKey for which to return KeySpec
* @param keySpec the requested format that the KeySpec should be
* returned in
*
* @return the KeySpec for the SecretKey in the requested format
*
* @throws InvalidKeySpecException if the requested format is not
* appropriate for the given key, or the provided SecretKey
* cannot be used.
*/
@Override
protected synchronized KeySpec engineGetKeySpec(SecretKey key,
Class<?> keySpec) throws InvalidKeySpecException {
PBEKey pKey = null;
int iterations = 0;
char[] password = null;
byte[] salt = null;
byte[] encoded = null;
log("returning KeySpec from SecretKey in requested type");
if (key == null) {
throw new InvalidKeySpecException("SecretKey cannot be null");
}
if (keySpec == null) {
throw new InvalidKeySpecException(
"Requested KeySpec format cannot be null");
}
if (key instanceof PBEKey) {
return getKeySpecFromPBEKeyByType((PBEKey)key, keySpec);
}
else {
throw new InvalidKeySpecException(
"Only SecretKey of type PBEKey currently supported");
}
}
/**
* Translates PBEKey to one generated by this SecretKeyFactory.
*
* Called by engineTranslateKey().
*
* @param PBEKey (SecretKey) to translate
*
* @return New/translated SecretKey (PBEKey) generated by this
* SecretKeyFactory.
*
* @throws InvalidKeyException if the provided SecretKey can not be
* used or converted
*/
private SecretKey translatePBEKey(PBEKey key)
throws InvalidKeyException {
char[] password = null;
byte[] salt = null;
byte[] enc = null;
int iterations = 0;
PBEKeySpec spec = null;
SecretKey sKey = null;
if (key != null) {
if (!isAlgorithmSupported(key.getAlgorithm())) {
throw new InvalidKeyException(
"SecretKey algorithm not supported: " + key.getAlgorithm());
}
try {
iterations = key.getIterationCount();
salt = key.getSalt();
password = key.getPassword();
enc = key.getEncoded();
if (enc == null) {
throw new InvalidKeySpecException(
"Error getting encoded key from PBEKey");
}
/* PBEKeySpec holds key length in bits */
spec = new PBEKeySpec(password, salt, iterations,
enc.length * 8);
sKey = genSecretKeyFromPBEKeySpec(spec);
} catch (InvalidKeySpecException e) {
throw new InvalidKeyException(e);
} finally {
spec.clearPassword();
if (password != null) {
Arrays.fill(password, (char)0);
}
if (salt != null) {
Arrays.fill(salt, (byte)0);
}
if (enc != null) {
Arrays.fill(enc, (byte)0);
}
}
}
return sKey;
}
/**
* Translate a SecretKey object from another provider (or unknown source)
* into a SecretKey object from this SecretKeyFactory.
*
* This method will extract necessary parameters from the original
* SecretKey then re-generate the SecretKey using this factory.
*
* @param key SecretKey to translate
*
* @return Translated SecretKey object from this SecretKeyFactory
*
* @throws InvalidKeyException if the provided SecretKey can not be
* used or converted
*/
@Override
protected synchronized SecretKey engineTranslateKey(SecretKey key)
throws InvalidKeyException {
log("translating SecretKey to wolfJCE SecretKeyFactory type");
if (key == null) {
throw new InvalidKeyException("SecretKey cannot be null");
}
if (key instanceof PBEKey) {
return translatePBEKey((PBEKey)key);
}
else {
throw new InvalidKeyException(
"Only SecretKey of type PBEKey currently supported");
}
}
/**
* wolfJCE PBKDF2WithHmacSHA1 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA1
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA1 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA1 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA1() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA1);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA224 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA224
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA224 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA224 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA224() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA224);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA256 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA256
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA256 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA256 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA256() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA256);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA384 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA384
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA384 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA384 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA384() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA384);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA512 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA512
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA512 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA512 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA512() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA512);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA3_224 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA3_224
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA3_224 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA3-224 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA3_224() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA3_224);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA3_256 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA3_256
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA3_256 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA3-256 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA3_256() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA3_256);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA3_384 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA3_384
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA3_384 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA3-384 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA3_384() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA3_384);
}
}
/**
* wolfJCE PBKDF2WithHmacSHA3_512 SecretKeyFactory class.
*/
public static final class wcPBKDF2WithHmacSHA3_512
extends WolfCryptSecretKeyFactory {
/**
* Create new wcPBKDF2WithHmacSHA3_512 object.
*
* @throws NoSuchAlgorithmException if PBKDF2-HMAC-SHA3-512 is not
* available in native wolfCrypt.
*/
public wcPBKDF2WithHmacSHA3_512() throws NoSuchAlgorithmException {
super(FactoryType.WC_SKF_PBKDF2_HMAC_SHA3_512);
}
}
}

View File

@ -139,6 +139,13 @@ public class FeatureDetect {
*/
public static native boolean HmacShaEnabled();
/**
* Tests if HMAC-SHA224 is compiled into the native wolfSSL library.
*
* @return true if enabled, otherwise false.
*/
public static native boolean HmacSha224Enabled();
/**
* Tests if HMAC-SHA256 is compiled into the native wolfSSL library.
*
@ -160,6 +167,42 @@ public class FeatureDetect {
*/
public static native boolean HmacSha512Enabled();
/**
* Tests if HMAC-SHA3-224 is compiled into the native wolfSSL library.
*
* @return true if enabled, otherwise false.
*/
public static native boolean HmacSha3_224Enabled();
/**
* Tests if HMAC-SHA3-256 is compiled into the native wolfSSL library.
*
* @return true if enabled, otherwise false.
*/
public static native boolean HmacSha3_256Enabled();
/**
* Tests if HMAC-SHA3-384 is compiled into the native wolfSSL library.
*
* @return true if enabled, otherwise false.
*/
public static native boolean HmacSha3_384Enabled();
/**
* Tests if HMAC-SHA3-512 is compiled into the native wolfSSL library.
*
* @return true if enabled, otherwise false.
*/
public static native boolean HmacSha3_512Enabled();
/**
* Tests if PKCS#5 v2.1 PBKDF2 is compiled into the native wolfSSL library.
*
* @return true if PBKDF2 is enabled (HAVE_PBKDF2, !NO_PWDBASED, !NO_HMAC),
* otherwise false.
*/
public static native boolean Pbkdf2Enabled();
/**
* Tests if RSA is compiled into the native wolfSSL library.
*

View File

@ -0,0 +1,135 @@
/* Pwdbased.java
*
* Copyright (C) 2006-2024 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
package com.wolfssl.wolfcrypt;
import java.util.Enumeration;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.X509CRL;
import java.security.cert.CRLException;
import java.security.cert.CertificateEncodingException;
/**
* Password based key derivation class with wraps native wolfCrypt
* pwdbased.c/h APIs.
*
* @author wolfSSL
*/
public class Pwdbased {
static native byte[] wc_PKCS12_PBKDF(byte[] passwd, int pLen,
byte[] salt, int sLen, int iterations, int kLen, int typeH,
int id);
static native byte[] wc_PBKDF2(byte[] passwd, int pLen, byte[] salt,
int sLen, int iterations, int kLen, int hashType);
/**
* Create new Pwdbased object.
*
* Currently all methods in this class are static, so no initialization
* logic needed.
*/
public Pwdbased() {
}
/**
* PKCS#12 PBKDF (Password Based Key Derivation Function).
*
* Implements the PBKDF from RFC 7292 Appendix B. This method converts
* an input password with a concatenated salt into a more secure key,
* which it returns as output. It allows a user to select any of the
* supported HMAC hash functions.
*
* @param passwd byte array containing the password to use for key
* derivation
* @param salt byte array containing salt to use for key generation
* @param iterations number of times to process the hash
* @param kLen desired length of the derived key
* @param typeH the hashing algorithm to use
* @param id byte identifier indicating the purpose of the key
* generation. It is used to diversify the key output, and should
* be assigned as follows:
* ID=1: pseudorandom bits are to be used as key material for
* performing encryption or decryption
* ID=2: pseduorandom bits are to be used as asn IV (Initial
* Value) for encryption or decryption.
* ID=3: pseudorandom bits are to be used as an integrity key
* for MACing.
*
* @return new byte[] containing derived key
*
* @throws WolfCryptException on native wolfCrypt error
*/
public static synchronized byte[] PKCS12_PBKDF(byte[] passwd, byte[] salt,
int iterations, int kLen, int typeH, int id) throws WolfCryptException {
/* Throws WolfCryptException with error on failure */
return wc_PKCS12_PBKDF(passwd, passwd.length, salt, salt.length,
iterations, kLen, typeH, id);
}
/**
* Implements the PBKDF2 from PKCS#5. This method converts and input
* password with a concatenated salt into a more secure key,
* which it returns as output. It allows a user to select any of the
* supported hash functions.
*
* @param passwd byte array containing the password to use for key
* derivation, can be null
* @param salt byte array containing salt to use for key generation
* @param iterations number of times to process the hash
* @param kLen desired length of the derived key
* @param hashType the hashing algorithm to use, from WolfCrypt class and
* one of the following:
* WolfCrypt.WC_HASH_TYPE_MD5
* WolfCrypt.WC_HASH_TYPE_SHA
* WolfCrypt.WC_HASH_TYPE_SHA224
* WolfCrypt.WC_HASH_TYPE_SHA256
* WolfCrypt.WC_HASH_TYPE_SHA384
* WolfCrypt.WC_HASH_TYPE_SHA512
* WolfCrypt.WC_HASH_TYPE_SHA3_224
* WolfCrypt.WC_HASH_TYPE_SHA3_256
* WolfCrypt.WC_HASH_TYPE_SHA3_384
* WolfCrypt.WC_HASH_TYPE_SHA3_512
*
* @return new byte[] containing derived key
*
* @throws IllegalArgumentException on invalid arguments
* @throws WolfCryptException on native wolfCrypt error
*/
public static synchronized byte[] PBKDF2(byte[] passwd, byte[] salt,
int iterations, int kLen, int hashType) throws WolfCryptException {
int passLen = 0;
if (passwd != null) {
passLen = passwd.length;
}
/* Throws WolfCryptException with error on failure */
return wc_PBKDF2(passwd, passLen, salt, salt.length,
iterations, kLen, hashType);
}
}

View File

@ -51,6 +51,82 @@ public class WolfCrypt extends WolfObject {
/** Size of 2048 bits in bytes */
public static final int SIZE_OF_2048_BITS = 256;
/*
* Native wolfCrypt hash types, from wolfssl/wolfcrypt/types.h
* wc_HashType enum.
*/
/** wolfSSL hash type: None */
public static int WC_HASH_TYPE_NONE =
WolfCrypt.getWC_HASH_TYPE_NONE();
/** wolfSSL hash type: MD2 */
public static int WC_HASH_TYPE_MD2 =
WolfCrypt.getWC_HASH_TYPE_MD2();
/** wolfSSL hash type: MD4 */
public static int WC_HASH_TYPE_MD4 =
WolfCrypt.getWC_HASH_TYPE_MD4();
/** wolfSSL hash type: MD5 */
public static int WC_HASH_TYPE_MD5 =
WolfCrypt.getWC_HASH_TYPE_MD5();
/** wolfSSL hash type: SHA-1 */
public static int WC_HASH_TYPE_SHA =
WolfCrypt.getWC_HASH_TYPE_SHA();
/** wolfSSL hash type: SHA-224 */
public static int WC_HASH_TYPE_SHA224 =
WolfCrypt.getWC_HASH_TYPE_SHA224();
/** wolfSSL hash type: SHA-256 */
public static int WC_HASH_TYPE_SHA256 =
WolfCrypt.getWC_HASH_TYPE_SHA256();
/** wolfSSL hash type: SHA-384 */
public static int WC_HASH_TYPE_SHA384 =
WolfCrypt.getWC_HASH_TYPE_SHA384();
/** wolfSSL hash type: SHA-512 */
public static int WC_HASH_TYPE_SHA512 =
WolfCrypt.getWC_HASH_TYPE_SHA512();
/** wolfSSL hash type: MD5-SHA */
public static int WC_HASH_TYPE_MD5_SHA =
WolfCrypt.getWC_HASH_TYPE_MD5_SHA();
/** wolfSSL hash type: SHA3-224 */
public static int WC_HASH_TYPE_SHA3_224 =
WolfCrypt.getWC_HASH_TYPE_SHA3_224();
/** wolfSSL hash type: SHA3-256 */
public static int WC_HASH_TYPE_SHA3_256 =
WolfCrypt.getWC_HASH_TYPE_SHA3_256();
/** wolfSSL hash type: SHA3-384 */
public static int WC_HASH_TYPE_SHA3_384 =
WolfCrypt.getWC_HASH_TYPE_SHA3_384();
/** wolfSSL hash type: SHA3-512 */
public static int WC_HASH_TYPE_SHA3_512 =
WolfCrypt.getWC_HASH_TYPE_SHA3_512();
private static native int getWC_HASH_TYPE_NONE();
private static native int getWC_HASH_TYPE_MD2();
private static native int getWC_HASH_TYPE_MD4();
private static native int getWC_HASH_TYPE_MD5();
private static native int getWC_HASH_TYPE_SHA();
private static native int getWC_HASH_TYPE_SHA224();
private static native int getWC_HASH_TYPE_SHA256();
private static native int getWC_HASH_TYPE_SHA384();
private static native int getWC_HASH_TYPE_SHA512();
private static native int getWC_HASH_TYPE_MD5_SHA();
private static native int getWC_HASH_TYPE_SHA3_224();
private static native int getWC_HASH_TYPE_SHA3_256();
private static native int getWC_HASH_TYPE_SHA3_384();
private static native int getWC_HASH_TYPE_SHA3_512();
/* Public mappings of some SSL/TLS level enums/defines */
/** wolfSSL file type: PEM */
public static int SSL_FILETYPE_PEM = 1;

View File

@ -33,6 +33,7 @@ import org.junit.runners.Suite.SuiteClasses;
WolfCryptMessageDigestSha384Test.class,
WolfCryptMessageDigestSha512Test.class,
WolfCryptRandomTest.class,
WolfCryptSecretKeyFactoryTest.class,
WolfCryptSignatureTest.class,
WolfCryptMacTest.class,
WolfCryptCipherTest.class,