diff --git a/jni/jni_md5.c b/jni/jni_md5.c index 4fba9197..483061aa 100644 --- a/jni/jni_md5.c +++ b/jni/jni_md5.c @@ -190,8 +190,8 @@ Java_com_wolfssl_wolfcrypt_Md5_native_1update_1internal___3BII( data = getByteArray(env, data_buffer); dataSz = getByteArrayLength(env, data_buffer); - if (md5 == NULL || data == NULL || - ((word32)(offset + len) > dataSz)) { + if (md5 == NULL || data == NULL || offset < 0 || len < 0 || + (((jlong)offset + (jlong)len) > (jlong)dataSz)) { ret = BAD_FUNC_ARG; } else { ret = wc_Md5Update(md5, data + offset, len); diff --git a/jni/jni_sha.c b/jni/jni_sha.c index d3945514..b2a0d802 100644 --- a/jni/jni_sha.c +++ b/jni/jni_sha.c @@ -319,7 +319,7 @@ Java_com_wolfssl_wolfcrypt_Sha_native_1update_1internal___3BII( dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } else { @@ -536,7 +536,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Sha224_native_1update_1interna dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } else { @@ -763,7 +763,7 @@ Java_com_wolfssl_wolfcrypt_Sha256_native_1update_1internal___3BII( dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } else { @@ -969,7 +969,7 @@ Java_com_wolfssl_wolfcrypt_Sha384_native_1update_1internal___3BII( dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } else { @@ -1176,7 +1176,7 @@ Java_com_wolfssl_wolfcrypt_Sha512_native_1update_1internal___3BII( dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } else { @@ -1471,7 +1471,7 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_Sha3_native_1update_1internal_ dataSz = getByteArrayLength(env, data_buffer); if (sha == NULL || data == NULL || offset < 0 || len < 0 || - (word32)(offset + len) > dataSz) { + ((jlong)offset + (jlong)len) > (jlong)dataSz) { ret = BAD_FUNC_ARG; } diff --git a/src/main/java/com/wolfssl/wolfcrypt/MessageDigest.java b/src/main/java/com/wolfssl/wolfcrypt/MessageDigest.java index c787f9da..aba9d0c2 100644 --- a/src/main/java/com/wolfssl/wolfcrypt/MessageDigest.java +++ b/src/main/java/com/wolfssl/wolfcrypt/MessageDigest.java @@ -169,9 +169,8 @@ public abstract class MessageDigest extends NativeStruct { checkStateAndInitialize(); - if (((offset + len) > data.length) || offset < 0 || len < 0) { - throw new RuntimeException( - "Invalid offset or length"); + if (offset < 0 || len < 0 || len > (data.length - offset)) { + throw new RuntimeException("Invalid offset or length"); } native_update(data, offset, len); diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Md5Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Md5Test.java index ea11abc4..1e2ba71c 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Md5Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Md5Test.java @@ -75,6 +75,23 @@ public class Md5Test { assertEquals(NativeStruct.NULL, new Md5().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Md5 md5 = new Md5(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + md5.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { String[] dataVector = new String[] { diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Sha224Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Sha224Test.java index ad2235fa..2c606f24 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Sha224Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Sha224Test.java @@ -85,6 +85,23 @@ public class Sha224Test { assertEquals(NativeStruct.NULL, new Sha224().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha224 sha = new Sha224(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Sha256Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Sha256Test.java index e0a5cf8a..7e4809c2 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Sha256Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Sha256Test.java @@ -75,6 +75,23 @@ public class Sha256Test { assertEquals(NativeStruct.NULL, new Sha256().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha256 sha = new Sha256(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { String[] dataVector = new String[] { diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Sha384Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Sha384Test.java index 99644a51..c27604da 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Sha384Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Sha384Test.java @@ -75,6 +75,23 @@ public class Sha384Test { assertEquals(NativeStruct.NULL, new Sha384().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha384 sha = new Sha384(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { String[] dataVector = new String[] { "", "c2edba56a6b82cc3", diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Sha3Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Sha3Test.java index af4bbf1a..0901ce66 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Sha3Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Sha3Test.java @@ -75,6 +75,23 @@ public class Sha3Test { new Sha3(Sha3.TYPE_SHA3_256).getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha3 sha = new Sha3(Sha3.TYPE_SHA3_256); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void sha3_256HashShouldMatchUsingByteArray() { /* Test vectors from NIST FIPS 202 - SHA-3 Standard */ diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/Sha512Test.java b/src/test/java/com/wolfssl/wolfcrypt/test/Sha512Test.java index b6fe0fea..3c9e8982 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/Sha512Test.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/Sha512Test.java @@ -75,6 +75,23 @@ public class Sha512Test { assertEquals(NativeStruct.NULL, new Sha512().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha512 sha = new Sha512(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { String[] dataVector = new String[] { "", "20580a530f01e771", diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/ShaTest.java b/src/test/java/com/wolfssl/wolfcrypt/test/ShaTest.java index 5c9c4b29..acf46713 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/ShaTest.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/ShaTest.java @@ -75,6 +75,23 @@ public class ShaTest { assertEquals(NativeStruct.NULL, new Sha().getNativeStruct()); } + @Test + public void updateWithWrappedOffsetAndLenShouldThrow() { + Sha sha = new Sha(); + byte[] data = new byte[8]; + + /* offset + len wraps int arithmetic, update must reject it */ + try { + sha.update(data, 1, Integer.MAX_VALUE); + fail("update() should have thrown for wrapped offset + len"); + } catch (IllegalStateException e) { + /* init failure is not the bounds rejection */ + throw e; + } catch (RuntimeException e) { + /* expected */ + } + } + @Test public void hashShouldMatchUsingByteBuffer() throws ShortBufferException { String[] dataVector = new String[] {