Hi, Here a little patch proposal which is usually relevant in cryptographics matters. Usually memset/bzero/... is used to clear private structures but the compiler can possibly optimize those calls but with this change we can unsure sensitive data is properly zero'ed using if possible native calls or memory fence.
Kind regards.
diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c b/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c --- a/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c +++ b/src/jdk.crypto.ec/share/native/libsunec/impl/ec.c @@ -59,11 +59,7 @@ #ifdef _KERNEL #define PORT_ZFree(p, l) bzero((p), (l)); kmem_free((p), (l)) #else -#ifndef _WIN32 -#define PORT_ZFree(p, l) bzero((p), (l)); free((p)) -#else -#define PORT_ZFree(p, l) memset((p), 0, (l)); free((p)) -#endif /* _WIN32 */ +#define PORT_ZFree(p, l) mp_safe_memzero((p), (l)); free((p)) #endif /* @@ -323,7 +319,7 @@ if (privKeyLen >= len) { memcpy(key->privateValue.data, privKeyBytes, len); } else { - memset(key->privateValue.data, 0, (len - privKeyLen)); + mp_safe_memzero(key->privateValue.data, (len - privKeyLen)); memcpy(key->privateValue.data + (len - privKeyLen), privKeyBytes, privKeyLen); } @@ -415,7 +411,7 @@ CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); - memset(privKeyBytes+len, 0, len); + mp_safe_memzero(privKeyBytes+len, len); cleanup: mp_clear(&privKeyVal); mp_clear(&order_1); @@ -592,7 +588,7 @@ return SECFailure; } - memset(derivedSecret, 0, sizeof *derivedSecret); + mp_safe_memzero(derivedSecret, sizeof *derivedSecret); len = (ecParams->fieldID.size + 7) >> 3; pointQ.len = 2*len + 1; if ((pointQ.data = PORT_Alloc(2*len + 1, kmflag)) == NULL) goto cleanup; diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c b/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c --- a/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c +++ b/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.c @@ -2077,6 +2077,20 @@ return n; } +void mp_safe_memzero(void *a, mp_size len) +{ +#if defined(_WIN32) + SecureZeroMemory(a, len); +#elif defined(__FreeBSD__) || defined(__OpenBSD__) + explicit_bzero(a, len); +#elif defined(__NetBSD__) + explicit_memset(a, 0, len); +#else + memset(a, 0, len); + __asm__ volatile("" :: "r"(a) : "memory"); +#endif +} + /* Given a and prime p, computes c and k such that a*c == 2**k (mod p). ** Returns k (positive) or error (negative). ** This technique from the paper "Fast Modular Reciprocals" (unpublished) diff --git a/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.h b/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.h --- a/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.h +++ b/src/jdk.crypto.ec/share/native/libsunec/impl/mpi.h @@ -351,6 +351,7 @@ /* Miscellaneous */ mp_size mp_trailing_zeros(const mp_int *mp); +void mp_safe_memzero(void *, mp_size); #define MP_CHECKOK(x) if (MP_OKAY > (res = (x))) goto CLEANUP #define MP_CHECKERR(x) if (MP_OKAY > (res = (x))) goto CLEANUP