F-9993: free active CMAC context in native free and setKey reinit

pull/259/head
Chris Conlon 2026-08-17 14:25:10 -06:00
parent 3970e39c1d
commit 8de26b2fe7
2 changed files with 45 additions and 3 deletions

View File

@ -37,6 +37,11 @@
/* #define WOLFCRYPT_JNI_DEBUG_ON */
#include <wolfcrypt_jni_debug.h>
#if (LIBWOLFSSL_VERSION_HEX >= 0x05006006) && (!defined(HAVE_FIPS) || \
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 6)))
#define WC_JNI_CMAC_HAVE_FREE
#endif
JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_mallocNativeStruct_1internal(
JNIEnv* env, jobject this)
{
@ -94,10 +99,19 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_native_1free(
LogStr("free Cmac %p\n", cmac);
if (cmac) {
/* Only clear the CMAC struct - do NOT free the memory here.
* The base class NativeStruct.xfree() will handle the actual
* memory deallocation to avoid double-free. */
/* Release and zeroize CMAC context contents, not freeing the
* memory since base class NativeStruct.xfree() will handle that
* deallocation. */
#ifdef WC_JNI_CMAC_HAVE_FREE
if (cmac->type == WC_CMAC_AES) {
wc_CmacFree(cmac);
}
else {
XMEMSET(cmac, 0, sizeof(Cmac));
}
#else
XMEMSET(cmac, 0, sizeof(Cmac));
#endif
}
#else
throwNotCompiledInException(env);
@ -126,6 +140,13 @@ JNIEXPORT void JNICALL Java_com_wolfssl_wolfcrypt_AesCmac_wc_1CmacSetKey(
if (!cmac || !key) {
ret = BAD_FUNC_ARG;
} else {
#ifdef WC_JNI_CMAC_HAVE_FREE
/* Free any active context first, reset() and repeated setKey() calls
* reinitialize the same struct */
if (cmac->type == WC_CMAC_AES) {
wc_CmacFree(cmac);
}
#endif
/* Initialize CMAC with the provided key */
ret = wc_InitCmac(cmac, key, keySz, WC_CMAC_AES, NULL);
}

View File

@ -248,6 +248,27 @@ public class AesCmacTest {
}
}
@Test
public void aesCmacResetAndRekeyMidStreamShouldWork() {
byte[] keyBytes = Util.h2b("2b7e151628aed2a6abf7158809cf4f3c");
byte[] dataBytes = Util.h2b("6bc1bee22e409f96e93d7e117393172a");
byte[] expectedBytes = Util.h2b("070a16b46b4d4144f79bdd9dd04a287c");
/* reset() mid stream must reinitialize the active context */
AesCmac cmac = new AesCmac();
cmac.setKey(keyBytes);
cmac.update(new byte[8]);
cmac.reset();
cmac.update(dataBytes);
assertArrayEquals(expectedBytes, cmac.doFinal());
/* setKey() again without doFinal() must also reinitialize */
cmac.setKey(keyBytes);
cmac.update(new byte[4]);
cmac.setKey(keyBytes);
assertArrayEquals(expectedBytes, cmac.doFinal(dataBytes));
}
@Test
public void aesCmacAlgorithmInfoShouldWork() {
try {