fixes aes jbyteArray access

pull/2/merge
Moisés Guimarães 2017-03-20 01:53:58 -03:00
parent 4c6b2f1720
commit 330dbc73f5
4 changed files with 174 additions and 20 deletions

View File

@ -29,7 +29,7 @@ extern "C" {
#define LogStr printf
static inline void LogHex(byte* data, word32 length)
static inline void LogHex(byte* data, word32 offset, word32 length)
{
#define LINE_LEN 16
@ -42,6 +42,8 @@ static inline void LogHex(byte* data, word32 length)
return;
}
data += offset;
for (i = 0; i < LINE_LEN; i++) {
if (i < length)
printf("%02x ", data[i]);
@ -58,7 +60,7 @@ static inline void LogHex(byte* data, word32 length)
printf("\n");
if (length > LINE_LEN)
LogHex(data + LINE_LEN, length - LINE_LEN);
LogHex(data, LINE_LEN, length - LINE_LEN);
}
#else

View File

@ -62,11 +62,18 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1set_1key(
byte* iv = getByteArray(env, iv_object);
word32 keySz = getByteArrayLength(env, key_object);
ret = wc_AesSetKey(aes, key, keySz, iv, opmode);
ret = (!aes || !key) /* iv is optional */
? BAD_FUNC_ARG
: wc_AesSetKey(aes, key, keySz, iv, opmode);
if (ret != 0)
throwWolfCryptExceptionFromError(env, ret);
LogStr("wc_AesSetKey(aes=%p, key, iv, opmode) = %d\n", aes, ret);
LogStr("wc_AesSetKey(aes=%p, key=%p, iv=%p, opmode) = %d\n",
aes, key, iv, ret);
releaseByteArray(env, key_object, key, JNI_ABORT);
releaseByteArray(env, iv_object, iv, JNI_ABORT);
#else
throwNotCompiledInException(env);
#endif
@ -85,19 +92,26 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update__I_3BII_3BI(
byte* output = getByteArray(env, output_object);
if (opmode == AES_ENCRYPTION) {
ret = wc_AesCbcEncrypt(aes, output+outputOffset, input+offset, length);
ret = (!aes || !input || !output)
? BAD_FUNC_ARG
: wc_AesCbcEncrypt(aes, output+outputOffset, input+offset, length);
LogStr("wc_AesCbcEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret);
}
else {
ret = wc_AesCbcDecrypt(aes, output+outputOffset, input+offset, length);
ret = (!aes || !input || !output)
? BAD_FUNC_ARG
: wc_AesCbcDecrypt(aes, output+outputOffset, input+offset, length);
LogStr("wc_AesCbcDecrypt(aes=%p, out, in, inSz) = %d\n", aes, ret);
}
LogStr("input[%u]: [%p]\n", (word32)length, input + offset);
LogHex((byte*) input + offset, length);
LogHex((byte*) input, offset, length);
LogStr("output[%u]: [%p]\n", (word32)length, output + outputOffset);
LogHex((byte*) output + outputOffset, length);
LogHex((byte*) output, outputOffset, length);
releaseByteArray(env, input_object, input, JNI_ABORT);
releaseByteArray(env, output_object, output, ret);
if (ret != 0) {
@ -128,11 +142,17 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update__ILjava_nio_ByteBuffer_2IILjava_ni
byte* output = getDirectBufferAddress(env, output_object);
if (opmode == AES_ENCRYPTION) {
ret = wc_AesCbcEncrypt(aes, output, input + offset, length);
ret = (!aes || !input || !output)
? BAD_FUNC_ARG
: wc_AesCbcEncrypt(aes, output, input + offset, length);
LogStr("wc_AesCbcEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret);
}
else {
ret = wc_AesCbcDecrypt(aes, output, input + offset, length);
ret = (!aes || !input || !output)
? BAD_FUNC_ARG
: wc_AesCbcDecrypt(aes, output, input + offset, length);
LogStr("wc_AesCbcDecrypt(aes=%p, out, in, inSz) = %d\n", aes, ret);
}
@ -145,9 +165,9 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update__ILjava_nio_ByteBuffer_2IILjava_ni
}
LogStr("input[%u]: [%p]\n", (word32)length, input + offset);
LogHex((byte*) input + offset, length);
LogHex((byte*) input, offset, length);
LogStr("output[%u]: [%p]\n", (word32)length, output);
LogHex((byte*) output, length);
LogHex((byte*) output, 0, length);
#else
throwNotCompiledInException(env);
#endif

View File

@ -1,24 +1,50 @@
/* BlockCipher.java
*
* Copyright (C) 2006-2016 wolfSSL Inc.
*
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* 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-1301, USA
*/
package com.wolfssl.wolfcrypt;
import java.nio.ByteBuffer;
import javax.crypto.ShortBufferException;
/**
* Common API for block ciphers.
*
* @author Moisés Guimarães
* @version 1.0, March 2017
*/
public abstract class BlockCipher extends NativeStruct {
private WolfCryptState state = WolfCryptState.UNINITIALIZED;
private int opmode;
protected abstract void native_set_key(byte[] key, byte[] iv, int opmode);
protected abstract int native_update(int opmode, byte[] input, int offset,
int length, byte[] output, int outputOffset);
protected abstract int native_update(int opmode, ByteBuffer plain, int offset,
int length, ByteBuffer cipher);
protected abstract int native_update(int opmode, ByteBuffer plain,
int offset, int length, ByteBuffer cipher);
public void setKey(byte[] key, byte[] iv, int opmode) {
native_set_key(key, iv, opmode);
@ -26,6 +52,10 @@ public abstract class BlockCipher extends NativeStruct {
state = WolfCryptState.READY;
}
public byte[] update(byte[] input) {
return update(input, 0, input.length);
}
public byte[] update(byte[] input, int offset, int length) {
byte[] output;

View File

@ -35,6 +35,11 @@ import com.wolfssl.wolfcrypt.Aes;
public class AesTest {
private static final byte[] KEY = Util
.h2b("00112233445566778899AABBCCDDEEFF");
private static final byte[] IV = Util
.h2b("000102030405060708090A0B0C0D0E0F");
@BeforeClass
public static void checkAvailability() {
try {
@ -51,7 +56,104 @@ public class AesTest {
assertNotEquals(NativeStruct.NULL, new Aes().getNativeStruct());
}
@Test(expected=ShortBufferException.class)
@Test
public void checkSetKeyParams() {
/* iv is optional, should not raise. */
Aes aes = new Aes(KEY, null, Aes.ENCRYPT_MODE);
try {
aes.setKey(null, IV, Aes.ENCRYPT_MODE);
fail("key should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
aes.setKey(KEY, IV, Aes.ENCRYPT_MODE);
aes.releaseNativeStruct();
try {
aes.setKey(KEY, IV, Aes.ENCRYPT_MODE);
fail("native struct should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
}
@Test
public void checkUpdateParams() throws ShortBufferException {
Aes enc = new Aes(KEY, IV, Aes.ENCRYPT_MODE);
Aes dec = new Aes(KEY, IV, Aes.DECRYPT_MODE);
byte[] input = new byte[Aes.BLOCK_SIZE];
byte[] output = new byte[Aes.BLOCK_SIZE];
enc.update(input);
dec.update(input);
try {
enc.update(null, 0, Aes.BLOCK_SIZE, output, 0);
fail("input should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
try {
dec.update(null, 0, Aes.BLOCK_SIZE, output, 0);
fail("input should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
try {
enc.update(input, 0, Aes.BLOCK_SIZE, null, 0);
fail("output should not be null.");
} catch (NullPointerException e) {
/* test must throw */
}
try {
dec.update(input, 0, Aes.BLOCK_SIZE, null, 0);
fail("output should not be null.");
} catch (NullPointerException e) {
/* test must throw */
}
enc.update(input, 0, Aes.BLOCK_SIZE, output, 0);
dec.update(input, 0, Aes.BLOCK_SIZE, output, 0);
enc.releaseNativeStruct();
dec.releaseNativeStruct();
try {
enc.update(input, 0, Aes.BLOCK_SIZE, output, 0);
fail("native struct should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
try {
dec.update(input, 0, Aes.BLOCK_SIZE, output, 0);
fail("native struct should not be null.");
} catch (WolfCryptException e) {
/* test must throw */
}
}
@Test(expected = WolfCryptException.class)
public void inputShouldNotBeNull() {
Aes aes = new Aes();
try {
aes.setKey(Util.h2b("2b7e151628aed2a6abf7158809cf4f3c"), null,
Aes.ENCRYPT_MODE);
} catch (WolfCryptException e) {
if (e.getError() == WolfCryptError.BAD_FUNC_ARG)
fail("iv should be optional when setting key.");
}
aes.setKey(null, null, Aes.ENCRYPT_MODE);
}
@Test(expected = ShortBufferException.class)
public void updateShouldMatchUsingByteByffer() throws ShortBufferException {
String[] keys = new String[] {
"2b7e151628aed2a6abf7158809cf4f3c",
@ -144,7 +246,7 @@ public class AesTest {
assertEquals(output, cipher);
assertEquals(input, plain);
/* tests ShortBufferException */
if (i == inputs.length - 1) {
cipher.position(cipher.limit());
@ -153,7 +255,7 @@ public class AesTest {
}
}
@Test(expected=ShortBufferException.class)
@Test(expected = ShortBufferException.class)
public void updateShouldMatchUsingByteArray() throws ShortBufferException {
String[] keys = new String[] {
"2b7e151628aed2a6abf7158809cf4f3c",
@ -236,7 +338,7 @@ public class AesTest {
assertArrayEquals(output, cipher);
assertArrayEquals(input, plain);
/* tests ShortBufferException */
if (i == inputs.length - 1)
enc.update(input, 0, input.length, cipher, Aes.BLOCK_SIZE);