JNI: add synchronization around native Hmac pointer access in Hmac class
parent
f6ffb7489e
commit
79bed5d9d3
|
@ -50,6 +50,9 @@ public class Hmac extends NativeStruct {
|
|||
private int type = -1;
|
||||
private byte[] key;
|
||||
|
||||
/* Lock around object state */
|
||||
protected final Object stateLock = new Object();
|
||||
|
||||
/**
|
||||
* Create new Hmac object
|
||||
*/
|
||||
|
@ -90,7 +93,9 @@ public class Hmac extends NativeStruct {
|
|||
|
||||
/* check if type is -1, if so that type is not compiled in at native
|
||||
* wolfSSL level. Throw exception if so. */
|
||||
private void checkHashTypeCompiledIn(int type) throws WolfCryptException {
|
||||
private void checkHashTypeCompiledIn(int type)
|
||||
throws WolfCryptException {
|
||||
|
||||
WolfCryptError notCompiledIn = WolfCryptError.NOT_COMPILED_IN;
|
||||
if (type == -1) {
|
||||
throw new WolfCryptException(notCompiledIn.getCode());
|
||||
|
@ -105,16 +110,21 @@ public class Hmac extends NativeStruct {
|
|||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
*/
|
||||
public void setKey(int type, byte[] key) {
|
||||
public synchronized void setKey(int type, byte[] key)
|
||||
throws WolfCryptException {
|
||||
|
||||
/* verify hash type is compiled in */
|
||||
checkHashTypeCompiledIn(type);
|
||||
synchronized (stateLock) {
|
||||
/* verify hash type is compiled in */
|
||||
checkHashTypeCompiledIn(type);
|
||||
|
||||
wc_HmacSetKey(type, key);
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
synchronized (pointerLock) {
|
||||
wc_HmacSetKey(type, key);
|
||||
}
|
||||
this.type = type;
|
||||
this.key = key;
|
||||
|
||||
state = WolfCryptState.READY;
|
||||
state = WolfCryptState.READY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,12 +133,16 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public void reset() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
setKey(type, key);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized void reset()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
setKey(type, key);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,12 +154,19 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public void update(byte data) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
wc_HmacUpdate(data);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized void update(byte data)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
wc_HmacUpdate(data);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,12 +178,19 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public void update(byte[] data) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
wc_HmacUpdate(data, 0, data.length);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public void update(byte[] data)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
wc_HmacUpdate(data, 0, data.length);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,12 +204,19 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public void update(byte[] data, int offset, int length) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
wc_HmacUpdate(data, offset, length);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized void update(byte[] data, int offset, int length)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
wc_HmacUpdate(data, offset, length);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,17 +228,23 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public void update(ByteBuffer data) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
int offset = data.position();
|
||||
int length = data.remaining();
|
||||
public synchronized void update(ByteBuffer data)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
wc_HmacUpdate(data, offset, length);
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
int offset = data.position();
|
||||
int length = data.remaining();
|
||||
|
||||
data.position(offset + length);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
synchronized (pointerLock) {
|
||||
wc_HmacUpdate(data, offset, length);
|
||||
}
|
||||
|
||||
data.position(offset + length);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,12 +256,19 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] doFinal() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_HmacFinal();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] doFinal()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
|
||||
synchronized (pointerLock) {
|
||||
return wc_HmacFinal();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,13 +282,20 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public byte[] doFinal(byte[] data) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
update(data);
|
||||
return wc_HmacFinal();
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized byte[] doFinal(byte[] data)
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
update(data);
|
||||
|
||||
synchronized (pointerLock) {
|
||||
return wc_HmacFinal();
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -251,28 +306,30 @@ public class Hmac extends NativeStruct {
|
|||
*
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public String getAlgorithm() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
public synchronized String getAlgorithm()
|
||||
throws IllegalStateException {
|
||||
|
||||
if (type == MD5) {
|
||||
return "HmacMD5";
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
if (type == MD5) {
|
||||
return "HmacMD5";
|
||||
}
|
||||
else if (type == SHA256) {
|
||||
return "HmacSHA256";
|
||||
}
|
||||
else if (type == SHA384) {
|
||||
return "HmacSHA384";
|
||||
}
|
||||
else if (type == SHA512) {
|
||||
return "HmacSHA512";
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
else if (type == SHA256) {
|
||||
return "HmacSHA256";
|
||||
}
|
||||
else if (type == SHA384) {
|
||||
return "HmacSHA384";
|
||||
}
|
||||
else if (type == SHA512) {
|
||||
return "HmacSHA512";
|
||||
}
|
||||
else {
|
||||
return "";
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -284,12 +341,18 @@ public class Hmac extends NativeStruct {
|
|||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if object has no key
|
||||
*/
|
||||
public int getMacLength() {
|
||||
if (state == WolfCryptState.READY) {
|
||||
return wc_HmacSizeByType(type);
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation.");
|
||||
public synchronized int getMacLength()
|
||||
throws WolfCryptException, IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (state == WolfCryptState.READY) {
|
||||
/* Does not use Hmac poiner, no need to lock */
|
||||
return wc_HmacSizeByType(type);
|
||||
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"No available key to perform the operation");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,17 @@ import org.junit.Test;
|
|||
import org.junit.Assume;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import java.security.Security;
|
||||
import java.security.Provider;
|
||||
|
@ -665,6 +671,274 @@ public class WolfCryptMacTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void threadRunnerMacTest(String hmacAlgo, String digest,
|
||||
HmacVector vector) throws InterruptedException {
|
||||
|
||||
int numThreads = 20;
|
||||
ExecutorService service = Executors.newFixedThreadPool(numThreads);
|
||||
final CountDownLatch latch = new CountDownLatch(numThreads);
|
||||
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
|
||||
final String currentAlgo = hmacAlgo;
|
||||
final String mdAlgo = digest;
|
||||
final byte[] key = vector.getKey();
|
||||
final byte[] input = vector.getInput();
|
||||
final byte[] output = vector.getOutput();
|
||||
|
||||
/* Do MAC in parallel across numThreads threads, all ops should pass */
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
service.submit(new Runnable() {
|
||||
@Override public void run() {
|
||||
|
||||
int failed = 0;
|
||||
SecretKeySpec keyspec = null;
|
||||
Mac mac = null;
|
||||
|
||||
try {
|
||||
keyspec = new SecretKeySpec(key, mdAlgo);
|
||||
mac = Mac.getInstance(currentAlgo, "wolfJCE");
|
||||
|
||||
mac.init(keyspec);
|
||||
mac.update(input);
|
||||
byte out[] = mac.doFinal();
|
||||
|
||||
if (!Arrays.equals(out, output)) {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed = 1;
|
||||
|
||||
} 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 MAC thread test: " + currentAlgo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadedMac() throws InterruptedException {
|
||||
|
||||
HmacVector md5Vector = new HmacVector(
|
||||
new byte[] {
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0x56, (byte)0xbe, (byte)0x34, (byte)0x52,
|
||||
(byte)0x1d, (byte)0x14, (byte)0x4c, (byte)0x88,
|
||||
(byte)0xdb, (byte)0xb8, (byte)0xc7, (byte)0x33,
|
||||
(byte)0xf0, (byte)0xe8, (byte)0xb3, (byte)0xf6
|
||||
}
|
||||
);
|
||||
|
||||
HmacVector sha1Vector = new HmacVector(
|
||||
new byte[] {
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0x12, (byte)0x5d, (byte)0x73, (byte)0x42,
|
||||
(byte)0xb9, (byte)0xac, (byte)0x11, (byte)0xcd,
|
||||
(byte)0x91, (byte)0xa3, (byte)0x9a, (byte)0xf4,
|
||||
(byte)0x8a, (byte)0xa1, (byte)0x7b, (byte)0x4f,
|
||||
(byte)0x63, (byte)0xf1, (byte)0x75, (byte)0xd3
|
||||
}
|
||||
);
|
||||
|
||||
HmacVector sha256Vector = new HmacVector(
|
||||
new byte[] {
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0x77, (byte)0x3e, (byte)0xa9, (byte)0x1e,
|
||||
(byte)0x36, (byte)0x80, (byte)0x0e, (byte)0x46,
|
||||
(byte)0x85, (byte)0x4d, (byte)0xb8, (byte)0xeb,
|
||||
(byte)0xd0, (byte)0x91, (byte)0x81, (byte)0xa7,
|
||||
(byte)0x29, (byte)0x59, (byte)0x09, (byte)0x8b,
|
||||
(byte)0x3e, (byte)0xf8, (byte)0xc1, (byte)0x22,
|
||||
(byte)0xd9, (byte)0x63, (byte)0x55, (byte)0x14,
|
||||
(byte)0xce, (byte)0xd5, (byte)0x65, (byte)0xfe
|
||||
}
|
||||
);
|
||||
|
||||
HmacVector sha384Vector = new HmacVector(
|
||||
new byte[] {
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0x88, (byte)0x06, (byte)0x26, (byte)0x08,
|
||||
(byte)0xd3, (byte)0xe6, (byte)0xad, (byte)0x8a,
|
||||
(byte)0x0a, (byte)0xa2, (byte)0xac, (byte)0xe0,
|
||||
(byte)0x14, (byte)0xc8, (byte)0xa8, (byte)0x6f,
|
||||
(byte)0x0a, (byte)0xa6, (byte)0x35, (byte)0xd9,
|
||||
(byte)0x47, (byte)0xac, (byte)0x9f, (byte)0xeb,
|
||||
(byte)0xe8, (byte)0x3e, (byte)0xf4, (byte)0xe5,
|
||||
(byte)0x59, (byte)0x66, (byte)0x14, (byte)0x4b,
|
||||
(byte)0x2a, (byte)0x5a, (byte)0xb3, (byte)0x9d,
|
||||
(byte)0xc1, (byte)0x38, (byte)0x14, (byte)0xb9,
|
||||
(byte)0x4e, (byte)0x3a, (byte)0xb6, (byte)0xe1,
|
||||
(byte)0x01, (byte)0xa3, (byte)0x4f, (byte)0x27
|
||||
}
|
||||
);
|
||||
|
||||
HmacVector sha512Vector = new HmacVector(
|
||||
new byte[] {
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA,
|
||||
(byte)0xAA, (byte)0xAA, (byte)0xAA, (byte)0xAA
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD, (byte)0xDD, (byte)0xDD,
|
||||
(byte)0xDD, (byte)0xDD
|
||||
},
|
||||
new byte[] {
|
||||
(byte)0xfa, (byte)0x73, (byte)0xb0, (byte)0x08,
|
||||
(byte)0x9d, (byte)0x56, (byte)0xa2, (byte)0x84,
|
||||
(byte)0xef, (byte)0xb0, (byte)0xf0, (byte)0x75,
|
||||
(byte)0x6c, (byte)0x89, (byte)0x0b, (byte)0xe9,
|
||||
(byte)0xb1, (byte)0xb5, (byte)0xdb, (byte)0xdd,
|
||||
(byte)0x8e, (byte)0xe8, (byte)0x1a, (byte)0x36,
|
||||
(byte)0x55, (byte)0xf8, (byte)0x3e, (byte)0x33,
|
||||
(byte)0xb2, (byte)0x27, (byte)0x9d, (byte)0x39,
|
||||
(byte)0xbf, (byte)0x3e, (byte)0x84, (byte)0x82,
|
||||
(byte)0x79, (byte)0xa7, (byte)0x22, (byte)0xc8,
|
||||
(byte)0x06, (byte)0xb4, (byte)0x85, (byte)0xa4,
|
||||
(byte)0x7e, (byte)0x67, (byte)0xc8, (byte)0x07,
|
||||
(byte)0xb9, (byte)0x46, (byte)0xa3, (byte)0x37,
|
||||
(byte)0xbe, (byte)0xe8, (byte)0x94, (byte)0x26,
|
||||
(byte)0x74, (byte)0x27, (byte)0x88, (byte)0x59,
|
||||
(byte)0xe1, (byte)0x32, (byte)0x92, (byte)0xfb
|
||||
}
|
||||
);
|
||||
|
||||
if (enabledAlgos.contains("HmacMD5")) {
|
||||
threadRunnerMacTest("HmacMD5", "MD5", md5Vector);
|
||||
}
|
||||
|
||||
if (enabledAlgos.contains("HmacSHA1")) {
|
||||
threadRunnerMacTest("HmacSHA1", "SHA1", sha1Vector);
|
||||
}
|
||||
|
||||
if (enabledAlgos.contains("HmacSHA256")) {
|
||||
threadRunnerMacTest("HmacSHA256", "SHA256", sha256Vector);
|
||||
}
|
||||
|
||||
if (enabledAlgos.contains("HmacSHA384")) {
|
||||
threadRunnerMacTest("HmacSHA384", "SHA384", sha384Vector);
|
||||
}
|
||||
|
||||
if (enabledAlgos.contains("HmacSHA512")) {
|
||||
threadRunnerMacTest("HmacSHA512", "SHA512", sha512Vector);
|
||||
}
|
||||
}
|
||||
|
||||
private class HmacVector {
|
||||
|
||||
private byte key[];
|
||||
|
|
|
@ -29,6 +29,15 @@ import org.junit.Assume;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import com.wolfssl.wolfcrypt.Hmac;
|
||||
import com.wolfssl.wolfcrypt.NativeStruct;
|
||||
import com.wolfssl.wolfcrypt.WolfCryptError;
|
||||
|
@ -253,4 +262,153 @@ public class HmacTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void threadRunnerHmacTest(int hmacType, byte[] inKey,
|
||||
byte[] inData, byte[] inExpected)
|
||||
throws InterruptedException {
|
||||
|
||||
int numThreads = 20;
|
||||
ExecutorService service = Executors.newFixedThreadPool(numThreads);
|
||||
final CountDownLatch latch = new CountDownLatch(numThreads);
|
||||
final LinkedBlockingQueue<Integer> results = new LinkedBlockingQueue<>();
|
||||
final int type = hmacType;
|
||||
final byte[] key = inKey;
|
||||
final byte[] data = inData;
|
||||
final byte[] expected = inExpected;
|
||||
|
||||
/* Do HMAC across numThread threads, all should be successful */
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
service.submit(new Runnable() {
|
||||
@Override public void run() {
|
||||
|
||||
int failed = 0;
|
||||
Hmac hmac = null;
|
||||
|
||||
try {
|
||||
|
||||
hmac = new Hmac();
|
||||
hmac.setKey(type, key);
|
||||
hmac.update(data);
|
||||
|
||||
if (!Arrays.equals(expected, hmac.doFinal())) {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (failed == 0) {
|
||||
hmac.reset();
|
||||
hmac.update(data);
|
||||
if (!Arrays.equals(expected, hmac.doFinal())) {
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failed = 1;
|
||||
|
||||
} 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 HMAC thread test");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThreadedHmac() throws InterruptedException {
|
||||
|
||||
if (Hmac.SHA != -1) {
|
||||
threadRunnerHmacTest(Hmac.SHA,
|
||||
Util.h2b("fd42f5044e3f70825102017f8521"), /* key */
|
||||
Util.h2b("c9995cad63f60f7c7c552ac12c08" + /* data */
|
||||
"0a7262cec4636d47c460c2abb47a" +
|
||||
"f9bca09e18f9576c1415144595a7" +
|
||||
"5da6fa232cb59d094d1a585c0710" +
|
||||
"4856febcd05a58bde12a1f04795a" +
|
||||
"e6e66a05b06f5dbe0dfa16c986fe" +
|
||||
"fa8c3b2bce40cbb6c1ec74f1ad94" +
|
||||
"7c1e9aadcf8584d5e9c45ec1f667" +
|
||||
"567738b85bbdaad8dcd1e30fd35a" +
|
||||
"3c61"),
|
||||
Util.h2b("8865eb9df41dcc2e74360f0c97ae" + /* expected */
|
||||
"567cb2377022")
|
||||
);
|
||||
}
|
||||
if (Hmac.SHA256 != -1) {
|
||||
threadRunnerHmacTest(Hmac.SHA256,
|
||||
Util.h2b("26afdd2445b1f3cecbd4a797fed8"), /* key */
|
||||
Util.h2b("bd74f8646cdd9b217927b04ef4ee" + /* data */
|
||||
"ef0b8ef0b78fafcabb11c202f8e8" +
|
||||
"d44aeaf15d03ff315d014cbbab8e" +
|
||||
"7ed48ab114567eb0cc525ed35bf9" +
|
||||
"a96b61bd1d139cb386365c3cd5d1" +
|
||||
"37e4717afd8ad2a2efc24b172b77" +
|
||||
"27cc6bd5f8ddef652cceb87ae114" +
|
||||
"f7cdfbd6c56473f414b8f149e616" +
|
||||
"9e2dbd46333e526b5761892a2703" +
|
||||
"a50e"),
|
||||
Util.h2b("208661dd6bdeab1c2843dfb8226c" + /* expected */
|
||||
"be0a69db31aa183004e12025039f" +
|
||||
"9fc2446a")
|
||||
);
|
||||
}
|
||||
if (Hmac.SHA384 != -1) {
|
||||
threadRunnerHmacTest(Hmac.SHA384,
|
||||
Util.h2b("d35d6a733af2947fbdb4a67f5b3d"), /* key */
|
||||
Util.h2b("44a8e36ec9b42a94a9627bd391f7" + /* data */
|
||||
"114dad4296d31c3639a8a1d80188" +
|
||||
"9b5c61e9378a0c81e4670a080712" +
|
||||
"0c3ff0ecfd310dfbd9b95e91c244" +
|
||||
"292851d8ef912a569e4ed3fc083c" +
|
||||
"c62d9475c47534746dc8977a0e0a" +
|
||||
"9f31bad5158f9c769cfe8b38e3ba" +
|
||||
"dfe61f7a838bb9524c7c43d88998" +
|
||||
"b186dccfc65f48e1ccd58a6888eb" +
|
||||
"ad19"),
|
||||
Util.h2b("346ff5f9b77866d72154b6b6965f" + /* expected */
|
||||
"1f56e7c21ddf3392bdbe12e5dffb" +
|
||||
"1d75e2f0d919c1e133c83b9b56d3" +
|
||||
"17c3db1364de")
|
||||
);
|
||||
}
|
||||
if (Hmac.SHA512 != -1) {
|
||||
threadRunnerHmacTest(Hmac.SHA512,
|
||||
Util.h2b("c3ec1135bb477eb81ca421deb9e0"), /* key */
|
||||
Util.h2b("837dbbb0371bf60082c788c8f16f" + /* data */
|
||||
"f883dd9216d235f7decf7ea09f9e" +
|
||||
"17fa5d46c25673bf609c7c4dfc3e" +
|
||||
"740c0b6c1bcbf2879a1dc9d769ae" +
|
||||
"5f8070d47eb26d66702195d1c1b5" +
|
||||
"7e6847823cfc60facbad7b61adff" +
|
||||
"da82d33196a1c1cae3b0ee7495c6" +
|
||||
"690de3ccc2fc6b7a28c17782cfd0" +
|
||||
"7f0a95a0ef60e4ff29e9daa8ce5b" +
|
||||
"a717"),
|
||||
Util.h2b("517bd0146fe52cb464a0d555a7c2" + /* expected */
|
||||
"9b5f9a604b07f32ff255f139156e" +
|
||||
"214b6eb3836aa089987a5aca585e" +
|
||||
"3cb10af8cb19c12a89628e8f59b6" +
|
||||
"952ac4b7da7131f0")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue