Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/main/java/com/wolfssl/provider/jce/WolfCryptProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@

import java.security.Provider;
import java.security.Security;
import java.util.concurrent.atomic.AtomicInteger;
import com.wolfssl.wolfcrypt.FeatureDetect;
import com.wolfssl.wolfcrypt.Fips;
import com.wolfssl.wolfcrypt.WolfCryptError;
import com.wolfssl.wolfcrypt.WolfSSLX509StoreCtx;

/**
Expand All @@ -34,6 +36,51 @@ public final class WolfCryptProvider extends Provider {

private static final long serialVersionUID = 1L;

/**
* Default FIPS error callback for wolfJCE provider.
*
* Logs FIPS errors to aid in debugging module failures. Registered
* automatically when wolfJCE provider is instantiated with FIPS wolfCrypt.
*/
private static class JCEFIPSErrorCallback implements Fips.ErrorCallback {

/* Track last error code to suppress repeated consecutive messages.
* Native wolfCrypt may call the callback with the same error code
* multiple times during a failure sequence. */
private static final AtomicInteger lastErr = new AtomicInteger(0);

/**
* Called by native wolfCrypt when FIPS error occurs.
*
* @param ok 1 if verification passed, otherwise 0
* @param err wolfCrypt FIPS error code
* @param hash expected verifyCore hash value
*/
@Override
public void errorCallback(int ok, int err, String hash) {

int prev = lastErr.getAndSet(err);
if (prev == err) {
return;
}

String errStr = WolfCryptError.fromInt(err).getDescription();

System.err.println("wolfJCE FIPS error: ok = " + ok + ", err = " +
err + " (" + errStr + "), hash = " + hash);

if (err == WolfCryptError.IN_CORE_FIPS_E.getCode()) {
System.err.println("wolfJCE FIPS: in core integrity hash " +
"check failure. Copy hash above into verifyCore[] in " +
"fips_test.c and rebuild");
}

WolfCryptDebug.log(JCEFIPSErrorCallback.class, WolfCryptDebug.ERROR,
() -> "FIPS error: ok = " + ok + ", err = " + err + " (" +
errStr + "), hash = " + hash);
}
}

/**
* Create new WolfCryptProvider object
*/
Expand All @@ -44,6 +91,14 @@ public WolfCryptProvider() {
* WolfCryptDebug class was first loaded (e.g., via JAVA_OPTS) */
WolfCryptDebug.refreshDebugFlags();

/* Register default FIPS error callback if FIPS enabled. */
if (Fips.enabled) {
Fips.wolfCrypt_SetCb_fips(new JCEFIPSErrorCallback());

WolfCryptDebug.log(getClass(), WolfCryptDebug.INFO,
() -> "Registered wolfCrypt FIPS error callback");
}

registerServices();
}

Expand Down
35 changes: 34 additions & 1 deletion src/main/java/com/wolfssl/wolfcrypt/WolfCryptException.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,45 @@ public WolfCryptException(String reason) {
* @param code wolfCrypt error code
*/
public WolfCryptException(int code) {
super(WolfCryptError.fromInt(code).getDescription());
super(getErrorMessage(code));

this.error = WolfCryptError.fromInt(code);
this.code = code;
}

/**
* Build exception message from error code. For FIPS_NOT_ALLOWED_E
* errors, queries and appends the current FIPS module status to help
* diagnose the root cause.
*
* @param code wolfCrypt error code
* @return descriptive error message string
*/
private static String getErrorMessage(int code) {

String msg = WolfCryptError.fromInt(code).getDescription();

/* Get module status for root cause of FIPS not allowed failure */
if (code == WolfCryptError.FIPS_NOT_ALLOWED_E.getCode()) {
try {
if (Fips.enabled) {
int status = Fips.wolfCrypt_GetStatus_fips();
if (status != 0) {
String statusDesc =
WolfCryptError.fromInt(status).getDescription();
msg += " [FIPS module status: " + status + " (" +
statusDesc + ")]";
}
}
}
catch (Exception e) {
/* FIPS status query not available */
}
}

return msg;
}

/**
* Create new WolfCryptException from reason and cause
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,27 +314,33 @@ public void testMd5Threaded()
service.submit(new Runnable() {
@Override public void run() {

MessageDigest md5 = null;

try {
md5 = MessageDigest.getInstance(
"MD5", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
/* add empty array on failure, will error out below */
MessageDigest md5 = null;

try {
md5 = MessageDigest.getInstance(
"MD5", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
results.add(new byte[] {0});
return;
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
md5.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = md5.digest();
results.add(hash.clone());

} catch (Exception e) {
/* ensure result added so iterator is not empty */
results.add(new byte[] {0});
} finally {
latch.countDown();
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
md5.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = md5.digest();
results.add(hash.clone());

latch.countDown();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,27 +303,33 @@ public void testSha256Threaded()
service.submit(new Runnable() {
@Override public void run() {

MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-256", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
/* add empty array on failure, will error out below */
MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-256", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
results.add(new byte[] {0});
return;
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

} catch (Exception e) {
/* ensure result added so iterator is not empty */
results.add(new byte[] {0});
} finally {
latch.countDown();
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

latch.countDown();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,27 +326,33 @@ public void testSha384Threaded()
service.submit(new Runnable() {
@Override public void run() {

MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-384", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
/* add empty array on failure, will error out below */
MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-384", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
results.add(new byte[] {0});
return;
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

} catch (Exception e) {
/* ensure result added so iterator is not empty */
results.add(new byte[] {0});
} finally {
latch.countDown();
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

latch.countDown();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,26 +337,33 @@ public void testSha3Threaded()
service.submit(new Runnable() {
@Override public void run() {

MessageDigest sha3 = null;

try {
sha3 = MessageDigest.getInstance("SHA3-256", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
/* Add empty array on failure, will error out below */
MessageDigest sha3 = null;

try {
sha3 = MessageDigest.getInstance(
"SHA3-256", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
results.add(new byte[] {0});
return;
}

/* Process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha3.update(rand10kBuf, j, 1024);
}

/* Get final hash */
byte[] hash = sha3.digest();
results.add(hash.clone());

} catch (Exception e) {
/* ensure result added so iterator is not empty */
results.add(new byte[] {0});
} finally {
latch.countDown();
}

/* Process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha3.update(rand10kBuf, j, 1024);
}

/* Get final hash */
byte[] hash = sha3.digest();
results.add(hash.clone());

latch.countDown();
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,27 +346,33 @@ public void testSha512Threaded()
service.submit(new Runnable() {
@Override public void run() {

MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-512", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
/* add empty array on failure, will error out below */
MessageDigest sha = null;

try {
sha = MessageDigest.getInstance(
"SHA-512", "wolfJCE");
} catch (NoSuchAlgorithmException |
NoSuchProviderException e) {
results.add(new byte[] {0});
return;
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

} catch (Exception e) {
/* ensure result added so iterator is not empty */
results.add(new byte[] {0});
} finally {
latch.countDown();
}

/* process/update in 1024-byte chunks */
for (int j = 0; j < rand10kBuf.length; j+= 1024) {
sha.update(rand10kBuf, j, 1024);
}

/* get final hash */
byte[] hash = sha.digest();
results.add(hash.clone());

latch.countDown();
}
});
}
Expand Down
Loading
Loading