diff --git a/configure.ac b/configure.ac index 0a6bdd1d73..463c69c043 100644 --- a/configure.ac +++ b/configure.ac @@ -1317,6 +1317,7 @@ AC_CHECK_FUNCS([ \ unlinkat \ posix_fallocate \ sendmmsg \ + explicit_bzero \ ]) AC_CHECK_MEMBERS([struct mmsghdr.msg_hdr], [], [], FRR_INCLUDES) diff --git a/lib/explicit_bzero.c b/lib/explicit_bzero.c new file mode 100644 index 0000000000..fa64ed85bf --- /dev/null +++ b/lib/explicit_bzero.c @@ -0,0 +1,39 @@ +/* + * Public domain. + * Written by Matthew Dempsky. + * Adapted for frr. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#ifndef HAVE_EXPLICIT_BZERO +#undef explicit_bzero + + +void explicit_bzero(void *buf, size_t len); +__attribute__((__weak__)) void +__explicit_bzero_hook(void *buf, size_t len); + +__attribute__((__weak__)) void +__explicit_bzero_hook(void *buf, size_t len) +{ +} + +#if defined(__clang__) +#pragma clang optimize off +#else +#pragma GCC optimize("00") +#endif + +void +explicit_bzero(void *buf, size_t len) +{ + memset(buf, 0, len); + __explicit_bzero_hook(buf, len); +} + +#endif diff --git a/lib/md5.c b/lib/md5.c index 5c93c7bc1f..20da6488c4 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -439,4 +439,5 @@ void hmac_md5(unsigned char *text, int text_len, unsigned char *key, MD5Update(&context, digest, 16); /* then results of 1st * hash */ MD5Final(digest, &context); /* finish up 2nd pass */ + explicit_bzero(&context, sizeof(context)); } diff --git a/lib/sha256.c b/lib/sha256.c index a9b7a4aefc..f1727b6323 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -186,10 +186,10 @@ static void SHA256_Transform(uint32_t *state, const unsigned char block[64]) state[i] += S[i]; /* Clean the stack. */ - memset(W, 0, 256); - memset(S, 0, 32); - memset(&t0, 0, sizeof(t0)); - memset(&t1, 0, sizeof(t0)); + explicit_bzero(W, 256); + explicit_bzero(S, 32); + explicit_bzero(&t0, sizeof(t0)); + explicit_bzero(&t1, sizeof(t0)); } static unsigned char PAD[64] = { @@ -292,7 +292,7 @@ void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) be32enc_vect(digest, ctx->state, 32); /* Clear the context state */ - memset((void *)ctx, 0, sizeof(*ctx)); + explicit_bzero((void *)ctx, sizeof(*ctx)); } /* Initialize an HMAC-SHA256 operation with the given key. */ @@ -327,7 +327,7 @@ void HMAC__SHA256_Init(HMAC_SHA256_CTX *ctx, const void *_K, size_t Klen) SHA256_Update(&ctx->octx, pad, 64); /* Clean the stack. */ - memset(khash, 0, 32); + explicit_bzero(khash, 32); } /* Add bytes to the HMAC-SHA256 operation. */ @@ -353,7 +353,7 @@ void HMAC__SHA256_Final(unsigned char digest[32], HMAC_SHA256_CTX *ctx) SHA256_Final(digest, &ctx->octx); /* Clean the stack. */ - memset(ihash, 0, 32); + explicit_bzero(ihash, 32); } /** @@ -409,5 +409,5 @@ void PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, } /* Clean PShctx, since we never called _Final on it. */ - memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX)); + explicit_bzero(&PShctx, sizeof(HMAC_SHA256_CTX)); } diff --git a/lib/subdir.am b/lib/subdir.am index c3899c4e0f..b0c311e7f2 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -1,6 +1,7 @@ # # libfrr # + lib_LTLIBRARIES += lib/libfrr.la lib_libfrr_la_LDFLAGS = $(LIB_LDFLAGS) -version-info 0:0:0 -Xlinker -e_libfrr_version lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST_LIBS) $(LIBCRYPT) $(LIBDL) $(LIBM) @@ -22,6 +23,7 @@ lib_libfrr_la_SOURCES = \ lib/debug.c \ lib/defaults.c \ lib/distribute.c \ + lib/explicit_bzero.c \ lib/ferr.c \ lib/filter.c \ lib/filter_cli.c \ @@ -337,6 +339,7 @@ lib_libfrrsnmp_la_SOURCES = \ lib/snmp.c \ # end + # # c-ares support # diff --git a/lib/zebra.h b/lib/zebra.h index e8ddd869bb..53ae5b4e9e 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -230,6 +230,10 @@ size_t strlcpy(char *__restrict dest, const char *__restrict src, size_t destsize); #endif +#ifndef HAVE_EXPLICIT_BZERO +void explicit_bzero(void *buf, size_t len); +#endif + #if !defined(HAVE_STRUCT_MMSGHDR_MSG_HDR) || !defined(HAVE_SENDMMSG) /* avoid conflicts in case we have partial support */ #define mmsghdr frr_mmsghdr