From b337c025f632cdc8e5c69d5deeb784127663f7a2 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 18 Aug 2026 15:35:58 -0600 Subject: [PATCH] F-4437: skip output allocation for zero length Chacha process input --- jni/jni_chacha.c | 15 ++++++------- .../wolfssl/wolfcrypt/test/ChachaTest.java | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/jni/jni_chacha.c b/jni/jni_chacha.c index 7fb8589b..614b2233 100644 --- a/jni/jni_chacha.c +++ b/jni/jni_chacha.c @@ -161,16 +161,14 @@ Java_com_wolfssl_wolfcrypt_Chacha_wc_1Chacha_1process( ret = BAD_FUNC_ARG; } - if (ret == 0) { + if (ret == 0 && inputSz > 0) { output = (byte*)XMALLOC(inputSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (output == NULL) { releaseByteArray(env, input_obj, input, JNI_ABORT); - throwOutOfMemoryException(env, "Failed to allocate key buffer"); + throwOutOfMemoryException(env, "Failed to allocate output buffer"); return result; } - } - if (ret == 0) { XMEMSET(output, 0, inputSz); ret = wc_Chacha_Process(chacha, output, input, inputSz); @@ -179,13 +177,14 @@ Java_com_wolfssl_wolfcrypt_Chacha_wc_1Chacha_1process( if (ret == 0) { result = (*env)->NewByteArray(env, inputSz); - if (result) { - (*env)->SetByteArrayRegion(env, result, 0, inputSz, - (const jbyte*) output); - } else { + if (result == NULL) { throwWolfCryptException(env, "Failed to allocate memory for Chacha_process"); } + else if (inputSz > 0) { + (*env)->SetByteArrayRegion(env, result, 0, inputSz, + (const jbyte*) output); + } } else { throwWolfCryptExceptionFromError(env, ret); } diff --git a/src/test/java/com/wolfssl/wolfcrypt/test/ChachaTest.java b/src/test/java/com/wolfssl/wolfcrypt/test/ChachaTest.java index 582fa4c7..5ffd5527 100644 --- a/src/test/java/com/wolfssl/wolfcrypt/test/ChachaTest.java +++ b/src/test/java/com/wolfssl/wolfcrypt/test/ChachaTest.java @@ -150,6 +150,28 @@ public class ChachaTest { } } + @Test + public void processWithEmptyInputShouldReturnEmptyArray() { + Chacha chacha = new Chacha(); + + try { + chacha.setKey(KEY); + chacha.setIV(IV); + + /* Empty input is a no-op that must return an empty array, + * not throw */ + byte[] empty = chacha.process(new byte[0]); + assertNotNull(empty); + assertEquals(0, empty.length); + + /* Keystream position must be unchanged by the empty call */ + byte[] cipher = chacha.process(INPUT); + assertArrayEquals(EXPECTED, cipher); + } finally { + chacha.releaseNativeStruct(); + } + } + @Test public void checkChachaVectors() {