diff --git a/jni/jni_aes.c b/jni/jni_aes.c index 149cabeb..6eef74a2 100644 --- a/jni/jni_aes.c +++ b/jni/jni_aes.c @@ -193,7 +193,7 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update_1internal__ILjava_nio_ByteBuffer_2 if (!aes || !input || !output) { ret = BAD_FUNC_ARG; /* NULL sanitizers */ } - else if (offset < 0 || length < 0) { + else if (offset < 0 || length < 0 || outputOffset < 0) { ret = BAD_FUNC_ARG; /* signed sanizizers */ } else if (((jlong)offset + (jlong)length) > @@ -205,11 +205,13 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update_1internal__ILjava_nio_ByteBuffer_2 ret = BUFFER_E; /* buffer overflow check */ } else if (opmode == AES_ENCRYPTION) { - ret = wc_AesCbcEncrypt(aes, output, input + offset, length); + ret = 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, input + offset, length); + ret = wc_AesCbcDecrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesCbcDecrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); } @@ -223,8 +225,8 @@ Java_com_wolfssl_wolfcrypt_Aes_native_1update_1internal__ILjava_nio_ByteBuffer_2 LogStr("input[%u]: [%p]\n", (word32)length, input + offset); LogHex((byte*) input, offset, length); - LogStr("output[%u]: [%p]\n", (word32)length, output); - LogHex((byte*) output, 0, length); + LogStr("output[%u]: [%p]\n", (word32)length, output + outputOffset); + LogHex((byte*) output, outputOffset, length); #else throwNotCompiledInException(env); ret = NOT_COMPILED_IN; diff --git a/jni/jni_aesccm.c b/jni/jni_aesccm.c index bbd68951..d01a0664 100644 --- a/jni/jni_aesccm.c +++ b/jni/jni_aesccm.c @@ -383,7 +383,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_AesCcm_wc_1AesCcmDecrypt } if (out != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(out, inLen); + #else XMEMSET(out, 0, inLen); + #endif XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); } diff --git a/jni/jni_aesctr.c b/jni/jni_aesctr.c index 7ba28d39..1516acb4 100644 --- a/jni/jni_aesctr.c +++ b/jni/jni_aesctr.c @@ -193,7 +193,7 @@ Java_com_wolfssl_wolfcrypt_AesCtr_native_1update_1internal__Ljava_nio_ByteBuffer if (aes == NULL || input == NULL || output == NULL) { ret = BAD_FUNC_ARG; } - else if (offset < 0 || length < 0) { + else if (offset < 0 || length < 0 || outputOffset < 0) { ret = BAD_FUNC_ARG; } else if (((jlong)offset + (jlong)length) > @@ -205,7 +205,8 @@ Java_com_wolfssl_wolfcrypt_AesCtr_native_1update_1internal__Ljava_nio_ByteBuffer ret = BUFFER_E; /* buffer overflow check */ } else { - ret = wc_AesCtrEncrypt(aes, output, input + offset, length); + ret = wc_AesCtrEncrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesCtrEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); } diff --git a/jni/jni_aesecb.c b/jni/jni_aesecb.c index 04e22db5..226792a9 100644 --- a/jni/jni_aesecb.c +++ b/jni/jni_aesecb.c @@ -199,7 +199,7 @@ Java_com_wolfssl_wolfcrypt_AesEcb_native_1update_1internal__ILjava_nio_ByteBuffe if (aes == NULL || input == NULL || output == NULL) { ret = BAD_FUNC_ARG; } - else if (offset < 0 || length < 0) { + else if (offset < 0 || length < 0 || outputOffset < 0) { ret = BAD_FUNC_ARG; } else if ((length % AES_BLOCK_SIZE) != 0) { @@ -214,11 +214,13 @@ Java_com_wolfssl_wolfcrypt_AesEcb_native_1update_1internal__ILjava_nio_ByteBuffe ret = BUFFER_E; /* buffer overflow check */ } else if (opmode == AES_ENCRYPTION) { - ret = wc_AesEcbEncrypt(aes, output, input + offset, length); + ret = wc_AesEcbEncrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesEcbEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); } else { - ret = wc_AesEcbDecrypt(aes, output, input + offset, length); + ret = wc_AesEcbDecrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesEcbDecrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); } @@ -232,8 +234,8 @@ Java_com_wolfssl_wolfcrypt_AesEcb_native_1update_1internal__ILjava_nio_ByteBuffe LogStr("input[%u]: [%p]\n", (word32)length, input + offset); LogHex((byte*) input, offset, length); - LogStr("output[%u]: [%p]\n", (word32)length, output); - LogHex((byte*) output, 0, length); + LogStr("output[%u]: [%p]\n", (word32)length, output + outputOffset); + LogHex((byte*) output, outputOffset, length); #else throwNotCompiledInException(env); ret = NOT_COMPILED_IN; diff --git a/jni/jni_aesgcm.c b/jni/jni_aesgcm.c index 110454e0..f14cac2b 100644 --- a/jni/jni_aesgcm.c +++ b/jni/jni_aesgcm.c @@ -385,7 +385,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_AesGcm_wc_1AesGcmDecrypt } if (out != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(out, inLen); + #else XMEMSET(out, 0, inLen); + #endif XFREE(out, NULL, DYNAMIC_TYPE_TMP_BUFFER); } diff --git a/jni/jni_aesofb.c b/jni/jni_aesofb.c index ec486b27..8911256d 100644 --- a/jni/jni_aesofb.c +++ b/jni/jni_aesofb.c @@ -207,7 +207,7 @@ Java_com_wolfssl_wolfcrypt_AesOfb_native_1update_1internal__ILjava_nio_ByteBuffe if (aes == NULL || input == NULL || output == NULL) { ret = BAD_FUNC_ARG; } - else if (offset < 0 || length < 0) { + else if (offset < 0 || length < 0 || outputOffset < 0) { ret = BAD_FUNC_ARG; } else if (((jlong)offset + (jlong)length) > @@ -219,17 +219,20 @@ Java_com_wolfssl_wolfcrypt_AesOfb_native_1update_1internal__ILjava_nio_ByteBuffe ret = BUFFER_E; /* buffer overflow check */ } else if (opmode == AES_ENCRYPTION) { - ret = wc_AesOfbEncrypt(aes, output, input + offset, length); + ret = wc_AesOfbEncrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesOfbEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); } else { #ifdef HAVE_AES_DECRYPT - ret = wc_AesOfbDecrypt(aes, output, input + offset, length); + ret = wc_AesOfbDecrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesOfbDecrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); #else /* If HAVE_AES_DECRYPT not defined, fall back to encrypt * (OFB mode uses same operation for both) */ - ret = wc_AesOfbEncrypt(aes, output, input + offset, length); + ret = wc_AesOfbEncrypt(aes, output + outputOffset, + input + offset, length); LogStr("wc_AesOfbEncrypt(aes=%p, out, in, inSz) = %d\n", aes, ret); #endif } @@ -244,8 +247,8 @@ Java_com_wolfssl_wolfcrypt_AesOfb_native_1update_1internal__ILjava_nio_ByteBuffe LogStr("input[%u]: [%p]\n", (word32)length, input + offset); LogHex((byte*) input, offset, length); - LogStr("output[%u]: [%p]\n", (word32)length, output); - LogHex((byte*) output, 0, length); + LogStr("output[%u]: [%p]\n", (word32)length, output + outputOffset); + LogHex((byte*) output, outputOffset, length); #else throwNotCompiledInException(env); ret = NOT_COMPILED_IN; diff --git a/jni/jni_asn.c b/jni/jni_asn.c index 99e3613d..719b0056 100644 --- a/jni/jni_asn.c +++ b/jni/jni_asn.c @@ -147,7 +147,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getPkcs8AlgoID } if (p8Copy != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(p8Copy, p8Len); + #else XMEMSET(p8Copy, 0, p8Len); + #endif XFREE(p8Copy, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -158,6 +163,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getPkcs8AlgoID if (ret == 0) { ret = (int)algoId; } + else { + throwWolfCryptExceptionFromError(env, ret); + } return (jint)ret; @@ -165,7 +173,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getPkcs8AlgoID (void)env; (void)class; (void)pkcs8Der; - return (jint)NOT_COMPILED_IN; + throwNotCompiledInException(env); + return 0; #endif } diff --git a/jni/jni_des3.c b/jni/jni_des3.c index 9b71ff4e..9562e572 100644 --- a/jni/jni_des3.c +++ b/jni/jni_des3.c @@ -187,7 +187,7 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1update_1internal__ILjava_nio_ByteBuffer_ if (!des || !input || !output) { ret = BAD_FUNC_ARG; /* NULL sanitizers */ } - else if (offset < 0 || length < 0) { + else if (offset < 0 || length < 0 || outputOffset < 0) { ret = BAD_FUNC_ARG; /* signed sanizizers */ } else if (((jlong)offset + (jlong)length) > @@ -199,11 +199,13 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1update_1internal__ILjava_nio_ByteBuffer_ ret = BUFFER_E; /* buffer overflow check */ } else if (opmode == DES_ENCRYPTION) { - ret = wc_Des3_CbcEncrypt(des, output, input + offset, length); + ret = wc_Des3_CbcEncrypt(des, output + outputOffset, + input + offset, length); LogStr("wc_Des3CbcEncrypt(des=%p, out, in, inSz) = %d\n", des, ret); } else { - ret = wc_Des3_CbcDecrypt(des, output, input + offset, length); + ret = wc_Des3_CbcDecrypt(des, output + outputOffset, + input + offset, length); LogStr("wc_Des3CbcDecrypt(des=%p, out, in, inSz) = %d\n", des, ret); } @@ -217,8 +219,8 @@ Java_com_wolfssl_wolfcrypt_Des3_native_1update_1internal__ILjava_nio_ByteBuffer_ LogStr("input[%u]: [%p]\n", (word32)length, input + offset); LogHex((byte*) input, offset, length); - LogStr("output[%u]: [%p]\n", (word32)length, output); - LogHex((byte*) output, 0, length); + LogStr("output[%u]: [%p]\n", (word32)length, output + outputOffset); + LogHex((byte*) output, outputOffset, length); #else throwNotCompiledInException(env); #endif diff --git a/jni/jni_dh.c b/jni/jni_dh.c index 71ec8cfc..352c0e00 100644 --- a/jni/jni_dh.c +++ b/jni/jni_dh.c @@ -190,7 +190,6 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair( word32 pubSz = size; int lBitPriv = 0, lBitPub = 0; byte lBit[1] = { 0x00 }; - int exceptionThrown = 0; key = (DhKey*) getNativeStruct(env, this); if ((*env)->ExceptionOccurred(env)) { @@ -245,44 +244,47 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair( } jbyteArray privateKey = (*env)->NewByteArray(env, lBitPriv + privSz); - jbyteArray publicKey = (*env)->NewByteArray(env, lBitPub + pubSz); + jbyteArray publicKey = NULL; + if (!privateKey) { + (*env)->ExceptionClear(env); + throwOutOfMemoryException(env, "Failed to allocate privateKey"); + } + + if (!(*env)->ExceptionOccurred(env)) { + publicKey = (*env)->NewByteArray(env, lBitPub + pubSz); + if (!publicKey) { + (*env)->ExceptionClear(env); + throwOutOfMemoryException(env, "Failed to allocate publicKey"); + } + } - if (privateKey) { + if (!(*env)->ExceptionOccurred(env)) { if (lBitPriv) { (*env)->SetByteArrayRegion(env, privateKey, 0, 1, - (const jbyte*)lBit); + (const jbyte*)lBit); (*env)->SetByteArrayRegion(env, privateKey, 1, privSz, - (const jbyte*)priv); - } else { + (const jbyte*)priv); + } + else { (*env)->SetByteArrayRegion(env, privateKey, 0, privSz, - (const jbyte*)priv); + (const jbyte*)priv); } - setByteArrayMember(env, this, "privateKey", privateKey); - if ((*env)->ExceptionOccurred(env)) { - /* if exception raised, skip any additional JNI functions */ - exceptionThrown = 1; - } - - } else { - throwWolfCryptException(env, "Failed to allocate privateKey"); - exceptionThrown = 1; } - if (publicKey && (exceptionThrown == 0)) { + /* if exception raised, skip any additional JNI functions */ + if (!(*env)->ExceptionOccurred(env)) { if (lBitPub) { - (*env)->SetByteArrayRegion(env, publicKey, 0, 1, - (const jbyte*)lBit); - (*env)->SetByteArrayRegion(env, publicKey, 1, pubSz, - (const jbyte*)pub); - } else { - (*env)->SetByteArrayRegion(env, publicKey, 0, pubSz, - (const jbyte*)pub); + (*env)->SetByteArrayRegion(env, publicKey, 0, + 1, (const jbyte*)lBit); + (*env)->SetByteArrayRegion(env, publicKey, 1, + pubSz, (const jbyte*)pub); + } + else { + (*env)->SetByteArrayRegion(env, publicKey, 0, + pubSz, (const jbyte*)pub); } - setByteArrayMember(env, this, "publicKey", publicKey); - } else { - throwWolfCryptException(env, "Failed to allocate publicKey"); } } else { throwWolfCryptExceptionFromError(env, ret); @@ -296,11 +298,21 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhGenerateKeyPair( LogHex(pub, 0, pubSz); if (priv != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(priv, privSz); + #else XMEMSET(priv, 0, privSz); + #endif XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); } if (pub != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(pub, pubSz); + #else XMEMSET(pub, 0, pubSz); + #endif XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -417,7 +429,12 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhAgree( LogHex(secret, 0, secretSz); if (secret != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(secret, secretSz); + #else XMEMSET(secret, 0, secretSz); + #endif XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -856,7 +873,12 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhExportKeyPair( pub = (byte*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (pub == NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(priv, privSz); + #else XMEMSET(priv, 0, privSz); + #endif XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); throwOutOfMemoryException(env, "Failed to allocate public key buffer"); return NULL; @@ -902,11 +924,21 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhExportKeyPair( /* Clean up */ if (priv != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(priv, privSz); + #else XMEMSET(priv, 0, privSz); + #endif XFREE(priv, NULL, DYNAMIC_TYPE_TMP_BUFFER); } if (pub != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(pub, pubSz); + #else XMEMSET(pub, 0, pubSz); + #endif XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -1187,7 +1219,12 @@ Java_com_wolfssl_wolfcrypt_Dh_wc_1DhPrivateKeyEncode( /* Clean up */ if (der != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(der, derSz); + #else XMEMSET(der, 0, derSz); + #endif XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); } diff --git a/jni/jni_ecc.c b/jni/jni_ecc.c index d13fec33..74663e9f 100644 --- a/jni/jni_ecc.c +++ b/jni/jni_ecc.c @@ -388,7 +388,12 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1export_1private( LogHex((byte*) output, 0, outputSz); if (output != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(output, outputBufSz); + #else XMEMSET(output, 0, outputBufSz); + #endif XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -616,7 +621,12 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1EccKeyToDer( LogHex((byte*) output, 0, outputSz); if (output != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(output, outputBufSz); + #else XMEMSET(output, 0, outputBufSz); + #endif XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -827,7 +837,12 @@ Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1shared_1secret( LogHex((byte*) output, 0, outputSz); if (output != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(output, outputBufSz); + #else XMEMSET(output, 0, outputBufSz); + #endif XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -1133,11 +1148,21 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1private_1ke } if (derKey != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(derKey, derKeyBufSz); + #else XMEMSET(derKey, 0, derKeyBufSz); + #endif XFREE(derKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); } if (pkcs8 != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(pkcs8, pkcs8Sz); + #else XMEMSET(pkcs8, 0, pkcs8Sz); + #endif XFREE(pkcs8, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -1250,7 +1275,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1export_1pri ecc, output, ret); if (output != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(output, outputSz); + #else XMEMSET(output, 0, outputSz); + #endif XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -1581,6 +1611,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_wolfcrypt_Ecc_wc_1ecc_1get_1curv curveIdx = wc_ecc_get_curve_idx_from_name(name); if (curveIdx < 0) { LogStr("wc_ecc_get_curve_idx_from_name failed, idx: %d\n", curveIdx); + (*env)->ReleaseStringUTFChars(env, curveName, name); throwWolfCryptExceptionFromError(env, curveIdx); return NULL; } diff --git a/jni/jni_pwdbased.c b/jni/jni_pwdbased.c index d1a372b0..97f457b3 100644 --- a/jni/jni_pwdbased.c +++ b/jni/jni_pwdbased.c @@ -80,7 +80,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PKCS12_1PBK } if (outKey != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(outKey, kLen); + #else XMEMSET(outKey, 0, kLen); + #endif XFREE(outKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -159,7 +164,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2 } if (outKey != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(outKey, kLen); + #else XMEMSET(outKey, 0, kLen); + #endif XFREE(outKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -181,7 +191,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2 (void)jcl; (void)passBuf; (void)passBufLen; - (void)salt; + (void)saltBuf; (void)sBufLen; (void)iterations; (void)kLen; diff --git a/jni/jni_rsa.c b/jni/jni_rsa.c index 6d4be8ce..1f805f38 100644 --- a/jni/jni_rsa.c +++ b/jni/jni_rsa.c @@ -418,7 +418,12 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaKeyToDer LogHex((byte*) output, 0, outputSz); if (output != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(output, outputBufSz); + #else XMEMSET(output, 0, outputBufSz); + #endif XFREE(output, NULL, DYNAMIC_TYPE_TMP_BUFFER); } #else @@ -602,11 +607,21 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPrivateKeyToP } if (derKey != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(derKey, derKeyBufSz); + #else XMEMSET(derKey, 0, derKeyBufSz); + #endif XFREE(derKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); } if (pkcs8 != NULL) { + #if (LIBWOLFSSL_VERSION_HEX >= 0x05008004) && \ + !defined(WOLFSSL_NO_FORCE_ZERO) + wc_ForceZero(pkcs8, pkcs8BufSz); + #else XMEMSET(pkcs8, 0, pkcs8BufSz); + #endif XFREE(pkcs8, NULL, DYNAMIC_TYPE_TMP_BUFFER); } diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java index 755ca264..12454b60 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java @@ -948,86 +948,94 @@ private void wolfCryptSetKey(Key key) throw new InvalidKeyException("Key does not support encoding"); } - switch (cipherType) { - case WC_AES: - if (this.direction == OpMode.WC_ENCRYPT) { - if (cipherMode == CipherMode.WC_GCM) { - this.aesGcm.setKey(encodedKey); - } - else if (cipherMode == CipherMode.WC_CCM) { - this.aesCcm.setKey(encodedKey); - } - else if (cipherMode == CipherMode.WC_CTS) { - this.aesCts.setKey(encodedKey, iv, AesCts.ENCRYPT_MODE); - } - else if (cipherMode == CipherMode.WC_ECB) { - this.aesEcb.setKey( - encodedKey, null, AesEcb.ENCRYPT_MODE); - } - else if (cipherMode == CipherMode.WC_CTR) { - this.aesCtr.setKey(encodedKey, iv); - } - else if (cipherMode == CipherMode.WC_OFB) { - this.aesOfb.setKey(encodedKey, iv, AesOfb.ENCRYPT_MODE); - } - else { - this.aes.setKey(encodedKey, iv, Aes.ENCRYPT_MODE); - } - } else { - if (cipherMode == CipherMode.WC_GCM) { - this.aesGcm.setKey(encodedKey); - } - else if (cipherMode == CipherMode.WC_CCM) { - this.aesCcm.setKey(encodedKey); - } - else if (cipherMode == CipherMode.WC_CTS) { - this.aesCts.setKey(encodedKey, iv, AesCts.DECRYPT_MODE); - } - else if (cipherMode == CipherMode.WC_ECB) { - this.aesEcb.setKey( - encodedKey, null, AesEcb.DECRYPT_MODE); - } - else if (cipherMode == CipherMode.WC_CTR) { - this.aesCtr.setKey(encodedKey, iv); - } - else if (cipherMode == CipherMode.WC_OFB) { - this.aesOfb.setKey(encodedKey, iv, AesOfb.ENCRYPT_MODE); - } - else { - this.aes.setKey(encodedKey, iv, Aes.DECRYPT_MODE); + try { + switch (cipherType) { + case WC_AES: + if (this.direction == OpMode.WC_ENCRYPT) { + if (cipherMode == CipherMode.WC_GCM) { + this.aesGcm.setKey(encodedKey); + } + else if (cipherMode == CipherMode.WC_CCM) { + this.aesCcm.setKey(encodedKey); + } + else if (cipherMode == CipherMode.WC_CTS) { + this.aesCts.setKey( + encodedKey, iv, AesCts.ENCRYPT_MODE); + } + else if (cipherMode == CipherMode.WC_ECB) { + this.aesEcb.setKey( + encodedKey, null, AesEcb.ENCRYPT_MODE); + } + else if (cipherMode == CipherMode.WC_CTR) { + this.aesCtr.setKey(encodedKey, iv); + } + else if (cipherMode == CipherMode.WC_OFB) { + this.aesOfb.setKey( + encodedKey, iv, AesOfb.ENCRYPT_MODE); + } + else { + this.aes.setKey(encodedKey, iv, Aes.ENCRYPT_MODE); + } + } else { + if (cipherMode == CipherMode.WC_GCM) { + this.aesGcm.setKey(encodedKey); + } + else if (cipherMode == CipherMode.WC_CCM) { + this.aesCcm.setKey(encodedKey); + } + else if (cipherMode == CipherMode.WC_CTS) { + this.aesCts.setKey( + encodedKey, iv, AesCts.DECRYPT_MODE); + } + else if (cipherMode == CipherMode.WC_ECB) { + this.aesEcb.setKey( + encodedKey, null, AesEcb.DECRYPT_MODE); + } + else if (cipherMode == CipherMode.WC_CTR) { + this.aesCtr.setKey(encodedKey, iv); + } + else if (cipherMode == CipherMode.WC_OFB) { + this.aesOfb.setKey( + encodedKey, iv, AesOfb.ENCRYPT_MODE); + } + else { + this.aes.setKey(encodedKey, iv, Aes.DECRYPT_MODE); + } } - } - break; + break; - case WC_DES3: - if (this.direction == OpMode.WC_ENCRYPT) { - this.des3.setKey(encodedKey, iv, Des3.ENCRYPT_MODE); - } else { - this.des3.setKey(encodedKey, iv, Des3.DECRYPT_MODE); - } - break; + case WC_DES3: + if (this.direction == OpMode.WC_ENCRYPT) { + this.des3.setKey(encodedKey, iv, Des3.ENCRYPT_MODE); + } else { + this.des3.setKey(encodedKey, iv, Des3.DECRYPT_MODE); + } + break; - case WC_RSA: + case WC_RSA: - /* reset key struct if needed */ - if (this.rsa != null) - this.rsa.releaseNativeStruct(); + /* reset key struct if needed */ + if (this.rsa != null) + this.rsa.releaseNativeStruct(); - if (this.rng == null) { - this.rng = new Rng(); - this.rng.init(); - } - this.rsa = new Rsa(); - this.rsa.setRng(this.rng); + if (this.rng == null) { + this.rng = new Rng(); + this.rng.init(); + } + this.rsa = new Rsa(); + this.rsa.setRng(this.rng); - if (this.rsaKeyType == RsaKeyType.WC_RSA_PRIVATE) { + if (this.rsaKeyType == RsaKeyType.WC_RSA_PRIVATE) { - this.rsa.decodePrivateKeyPKCS8(encodedKey); + this.rsa.decodePrivateKeyPKCS8(encodedKey); - } else { - this.rsa.decodePublicKey(encodedKey); - } - break; + } else { + this.rsa.decodePublicKey(encodedKey); + } + break; + } + } finally { + zeroArray(encodedKey); } } @@ -1756,6 +1764,7 @@ protected int engineGetKeySize(Key key) throws InvalidKeyException { byte encodedKey[] = null; + int kLen = 0; /* validate key class type */ if (this.cipherType == CipherType.WC_RSA) { @@ -1781,7 +1790,9 @@ protected int engineGetKeySize(Key key) if (encodedKey == null) throw new InvalidKeyException("Key does not support encoding"); - return encodedKey.length; + kLen = encodedKey.length; + zeroArray(encodedKey); + return kLen; } @Override @@ -1857,6 +1868,7 @@ protected byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException { byte[] encodedKey = null; + byte[] wcBuf; if (key == null) { throw new InvalidKeyException( @@ -1870,12 +1882,14 @@ protected byte[] engineWrap(Key key) } try { - return wolfCryptFinal(encodedKey, 0, encodedKey.length); - + wcBuf = wolfCryptFinal(encodedKey, 0, encodedKey.length); } catch (BadPaddingException e) { throw new InvalidKeyException("Failed to wrap key: " + e.getMessage(), e); + } finally { + zeroArray(encodedKey); } + return wcBuf; } @Override diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptDHKeyFactory.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptDHKeyFactory.java index 82adaefa..3eb3efed 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptDHKeyFactory.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptDHKeyFactory.java @@ -440,7 +440,9 @@ private T getPrivateKeySpec(DHPrivateKey key, throw new InvalidKeySpecException( "DHPrivateKey.getEncoded() returned null"); } - return (T) new PKCS8EncodedKeySpec(encoded); + T pkcs8EncKS = (T) new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + return pkcs8EncKS; } else if (keySpec.isAssignableFrom(DHPrivateKeySpec.class)) { /* Extract private value and params directly from key */ @@ -542,6 +544,8 @@ private PrivateKey translatePrivateKey(DHPrivateKey key) } keySpec = new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + return engineGeneratePrivate(keySpec); } catch (InvalidKeySpecException e) { diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptECKeyFactory.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptECKeyFactory.java index 8a67d019..b5451989 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptECKeyFactory.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptECKeyFactory.java @@ -653,7 +653,10 @@ private T getPrivateKeySpec(ECPrivateKey key, throw new InvalidKeySpecException( "ECPrivateKey.getEncoded() returned null"); } - return (T) new PKCS8EncodedKeySpec(encoded); + T pkcs8EncKS = (T) new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + + return pkcs8EncKS; } else if (keySpec.isAssignableFrom(ECPrivateKeySpec.class)) { /* Extract private value and params directly from key */ @@ -748,6 +751,8 @@ private PrivateKey translatePrivateKey(ECPrivateKey key) } PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + return engineGeneratePrivate(keySpec); } catch (InvalidKeySpecException e) { diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptKeyAgreement.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptKeyAgreement.java index 188803ca..3c6ca726 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptKeyAgreement.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptKeyAgreement.java @@ -332,8 +332,12 @@ protected int engineGenerateSecret(byte[] sharedSecret, int offset) this.ecPublic = new Ecc(); this.ecPrivate.releaseNativeStruct(); this.ecPrivate = new Ecc(); - this.ecPrivate.importPrivateOnCurve(priv, null, this.curveName); - zeroArray(priv); + try { + this.ecPrivate.importPrivateOnCurve(priv, null, + this.curveName); + } finally { + zeroArray(priv); + } this.state = EngineState.WC_PRIVKEY_DONE; @@ -489,8 +493,11 @@ private void wcInitDHParams(Key key, AlgorithmParameterSpec params) "Unable to get DH private key from Key object"); } - this.dh.setPrivateKey(dhPriv); - zeroArray(dhPriv); + try { + this.dh.setPrivateKey(dhPriv); + } finally { + zeroArray(dhPriv); + } return; } @@ -531,6 +538,7 @@ private void wcInitECDHParams(Key key, AlgorithmParameterSpec params) BigInteger privateValue = null; BigInteger order = null; ECParameterSpec ecParams = null; + byte[] privKeyBytes; if (!(key instanceof ECPrivateKey)) { throw new InvalidKeyException( @@ -568,8 +576,15 @@ private void wcInitECDHParams(Key key, AlgorithmParameterSpec params) throw new InvalidAlgorithmParameterException( "ECC curve is null, please check algorithm parameters"); } - this.ecPrivate.importPrivateOnCurve(ecKey.getS().toByteArray(), + + privKeyBytes = ecKey.getS().toByteArray(); + + try { + this.ecPrivate.importPrivateOnCurve(privKeyBytes, null, this.curveName); + } finally { + zeroArray(privKeyBytes); + } } /** diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptMac.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptMac.java index 93e68132..5fc2af31 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptMac.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptMac.java @@ -24,6 +24,7 @@ import javax.crypto.MacSpi; import java.security.Key; import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; import java.security.InvalidKeyException; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; @@ -232,6 +233,8 @@ protected void engineInit(Key key, AlgorithmParameterSpec params) } } catch (com.wolfssl.wolfcrypt.WolfCryptException e) { throw new InvalidKeyException("Invalid key: " + e.getMessage()); + } finally { + Arrays.fill(encodedKey, (byte)0); } log("init with key and spec"); diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAKeyFactory.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAKeyFactory.java index 1f8e525a..0c765557 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAKeyFactory.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAKeyFactory.java @@ -534,7 +534,10 @@ private T getPrivateCrtKeySpec(RSAPrivateCrtKey key, throw new InvalidKeySpecException( "RSAPrivateCrtKey.getEncoded() returned null"); } - return (T) new PKCS8EncodedKeySpec(encoded); + T pkcs8EncKS = (T) new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + + return pkcs8EncKS; } else if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class)) { /* Extract CRT parameters directly from key */ @@ -600,7 +603,10 @@ private T getPrivateKeySpec(RSAPrivateKey key, throw new InvalidKeySpecException( "RSAPrivateKey.getEncoded() returned null"); } - return (T) new PKCS8EncodedKeySpec(encoded); + T pkcs8EncKS = (T) new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); + + return pkcs8EncKS; } else if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class)) { /* Extract basic private key parameters */ @@ -705,6 +711,7 @@ private PrivateKey translatePrivateKey(RSAPrivateKey key) } keySpec = new PKCS8EncodedKeySpec(encoded); + Arrays.fill(encoded, (byte)0); return engineGeneratePrivate(keySpec); diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateCrtKey.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateCrtKey.java index fc656c25..f0536cb9 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateCrtKey.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateCrtKey.java @@ -240,6 +240,7 @@ private byte[] removeLeadingZero(byte[] data) { if ((data != null) && (data.length > 1) && (data[0] == 0)) { byte[] result = new byte[data.length - 1]; System.arraycopy(data, 1, result, 0, data.length - 1); + Arrays.fill(data, (byte)0); return result; } return data; diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateKey.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateKey.java index 2cd6dff0..23a3eb67 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateKey.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptRSAPrivateKey.java @@ -160,7 +160,9 @@ private byte[] convertBigIntegerToUnsignedBytes(BigInteger value) { /* Remove leading zero byte if present (sign byte) */ if ((bytes.length > 0) && (bytes[0] == 0)) { - return Arrays.copyOfRange(bytes, 1, bytes.length); + byte[] cpyBytes = Arrays.copyOfRange(bytes, 1, bytes.length); + Arrays.fill(bytes, (byte)0); + return cpyBytes; } return bytes; } diff --git a/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java b/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java index 37fbb8dd..10de7527 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java @@ -345,7 +345,11 @@ private void wolfCryptInitPrivateKey(PrivateKey key, byte[] encodedKey) privKeyBytes = ecPriv.getS().toByteArray(); } - this.ecc.importPrivate(privKeyBytes, null); + try { + this.ecc.importPrivate(privKeyBytes, null); + } finally { + zeroArray(privKeyBytes); + } break; } @@ -447,69 +451,74 @@ protected synchronized void engineInitSign(PrivateKey privateKey) if (encodedKey == null) throw new InvalidKeyException("Key does not support encoding"); - /* initialize native struct */ - switch (keyType) { - case WC_RSA: - if (this.rsa != null) { - this.rsa.releaseNativeStruct(); - } - this.rsa = new Rsa(); - break; - case WC_ECDSA: - if (this.ecc != null) { - this.ecc.releaseNativeStruct(); - } - synchronized (this.rngLock) { - this.ecc = new Ecc(this.rng); - } - break; - } + try { + /* initialize native struct */ + switch (keyType) { + case WC_RSA: + if (this.rsa != null) { + this.rsa.releaseNativeStruct(); + } + this.rsa = new Rsa(); + break; + case WC_ECDSA: + if (this.ecc != null) { + this.ecc.releaseNativeStruct(); + } + synchronized (this.rngLock) { + this.ecc = new Ecc(this.rng); + } + break; + } - wolfCryptInitPrivateKey(privateKey, encodedKey); + wolfCryptInitPrivateKey(privateKey, encodedKey); - /* init hash object if digest type is set */ - if (this.digestType == null) { - /* For RSASSA-PSS, hash init will happen in engineSetParameter() */ - log("init sign with PrivateKey (hash init deferred for PSS)"); - return; - } + /* init hash object if digest type is set */ + if (this.digestType == null) { + /* For RSASSA-PSS, hash init will happen in + * engineSetParameter() */ + log("init sign with PrivateKey (hash init deferred for PSS)"); + return; + } - synchronized (hashLock) { - switch (this.digestType) { - case WC_MD5: - this.md5.init(); - break; + synchronized (hashLock) { + switch (this.digestType) { + case WC_MD5: + this.md5.init(); + break; - case WC_SHA1: - this.sha.init(); - break; + case WC_SHA1: + this.sha.init(); + break; - case WC_SHA224: - this.sha224.init(); - break; + case WC_SHA224: + this.sha224.init(); + break; - case WC_SHA256: - this.sha256.init(); - break; + case WC_SHA256: + this.sha256.init(); + break; - case WC_SHA384: - this.sha384.init(); - break; + case WC_SHA384: + this.sha384.init(); + break; - case WC_SHA512: - this.sha512.init(); - break; + case WC_SHA512: + this.sha512.init(); + break; - case WC_SHA3_224: - case WC_SHA3_256: - case WC_SHA3_384: - case WC_SHA3_512: - this.sha3.init(); - break; + case WC_SHA3_224: + case WC_SHA3_256: + case WC_SHA3_384: + case WC_SHA3_512: + this.sha3.init(); + break; + } } - } - log("init sign with PrivateKey"); + log("init sign with PrivateKey"); + } finally { + zeroArray(encodedKey); + } } @Override diff --git a/src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java b/src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java index 749ee0e1..74103803 100644 --- a/src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java +++ b/src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java @@ -1186,6 +1186,8 @@ else if (entry instanceof WKSSecretKey) { sKey = new SecretKeySpec(plainKey, sk.keyAlgo); } + } catch (WolfCryptException wce) { + throw new UnrecoverableKeyException("Error getting key: " + wce); } finally { if (plainKey != null) { Arrays.fill(plainKey, (byte)0); @@ -1459,11 +1461,14 @@ private void checkCertificateChainMatchesPrivateKey( if (pkcs8Key == null || pkcs8Key.length == 0) { throw new KeyStoreException("Bad PrivateKey PKCS#8 encoding"); } - - match = X509CheckPrivateKey(derCert, pkcs8Key); - if (!match) { - throw new KeyStoreException("X509Certificate does not match " + - "provided private key"); + try { + match = X509CheckPrivateKey(derCert, pkcs8Key); + if (!match) { + throw new KeyStoreException("X509Certificate does not match " + + "provided private key"); + } + } finally { + Arrays.fill(pkcs8Key, (byte)0); } } @@ -1986,7 +1991,7 @@ else if (entry.getValue() instanceof WKSSecretKey) { log("KeyStore successfully stored to OutputStream"); - return; + return; } /** diff --git a/src/main/java/com/wolfssl/wolfcrypt/Ecc.java b/src/main/java/com/wolfssl/wolfcrypt/Ecc.java index 503b3cd0..efb185b2 100644 --- a/src/main/java/com/wolfssl/wolfcrypt/Ecc.java +++ b/src/main/java/com/wolfssl/wolfcrypt/Ecc.java @@ -24,6 +24,7 @@ import java.math.BigInteger; import java.security.InvalidAlgorithmParameterException; import java.security.spec.EllipticCurve; +import java.util.Arrays; import java.security.spec.ECParameterSpec; import java.security.spec.ECFieldFp; @@ -673,6 +674,7 @@ public static byte[] bigIntToFixedSizeByteArray(BigInteger value, if ((bytes.length == fieldSizeBytes + 1) && (bytes[0] == 0)) { byte[] result = new byte[fieldSizeBytes]; System.arraycopy(bytes, 1, result, 0, fieldSizeBytes); + Arrays.fill(bytes, (byte)0); return result; } @@ -681,6 +683,7 @@ public static byte[] bigIntToFixedSizeByteArray(BigInteger value, byte[] result = new byte[fieldSizeBytes]; System.arraycopy(bytes, 0, result, fieldSizeBytes - bytes.length, bytes.length); + Arrays.fill(bytes, (byte)0); return result; }