diff --git a/CHANGES b/CHANGES index 10706d629e..e16a2e91d1 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4729. [bug] Don't use memset() to wipe memory, as it may be + removed by compiler optimizations when the + memset() occurs on automatic stack allocation + just before function return. [RT #45947] + 4728. [func] Use C11's stdatomic.h instead of isc_atomic where available. [RT #40668] diff --git a/config.h.in b/config.h.in index 8c669e276a..24a1780e8d 100644 --- a/config.h.in +++ b/config.h.in @@ -242,6 +242,9 @@ int sigwait(const unsigned int *set, int *sig); /* Define to 1 if you have the `EVP_sha512' function. */ #undef HAVE_EVP_SHA512 +/* Define to 1 if you have the `explicit_bzero' function. */ +#undef HAVE_EXPLICIT_BZERO + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H diff --git a/configure b/configure index 25081d21b2..b405dd0f63 100755 --- a/configure +++ b/configure @@ -20111,7 +20111,7 @@ $as_echo "#define HAVE_IF_NAMETOINDEX 1" >>confdefs.h esac -for ac_func in nanosleep usleep +for ac_func in nanosleep usleep explicit_bzero do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index 9fa10c48e2..6de99872c8 100644 --- a/configure.in +++ b/configure.in @@ -4001,7 +4001,7 @@ yes) esac AC_SUBST(ISC_PLATFORM_HAVEIFNAMETOINDEX) -AC_CHECK_FUNCS(nanosleep usleep) +AC_CHECK_FUNCS(nanosleep usleep explicit_bzero) # # Machine architecture dependent features diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 5496bf4c2c..920843e370 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -1259,8 +1260,8 @@ dst_key_free(dst_key_t **keyp) { if (key->key_tkeytoken) { isc_buffer_free(&key->key_tkeytoken); } - memset(key, 0, sizeof(dst_key_t)); - isc_mem_putanddetach(&mctx, key, sizeof(dst_key_t)); + isc_safe_memwipe(key, sizeof(*key)); + isc_mem_putanddetach(&mctx, key, sizeof(*key)); *keyp = NULL; } diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c index 7c28df3863..c19d8638de 100644 --- a/lib/dns/hmac_link.c +++ b/lib/dns/hmac_link.c @@ -165,7 +165,7 @@ hmacmd5_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacmd5_fromdns(key, &b); - memset(data, 0, ISC_MD5_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -180,8 +180,8 @@ static void hmacmd5_destroy(dst_key_t *key) { dst_hmacmd5_key_t *hkey = key->keydata.hmacmd5; - memset(hkey, 0, sizeof(dst_hmacmd5_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacmd5_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacmd5 = NULL; } @@ -307,7 +307,7 @@ hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } @@ -451,7 +451,7 @@ hmacsha1_generate(dst_key_t *key, int pseudorandom_ok, void (*callback)(int)) { isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha1_fromdns(key, &b); - memset(data, 0, ISC_SHA1_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -466,8 +466,8 @@ static void hmacsha1_destroy(dst_key_t *key) { dst_hmacsha1_key_t *hkey = key->keydata.hmacsha1; - memset(hkey, 0, sizeof(dst_hmacsha1_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha1_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacsha1 = NULL; } @@ -593,7 +593,7 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } @@ -738,7 +738,7 @@ hmacsha224_generate(dst_key_t *key, int pseudorandom_ok, isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha224_fromdns(key, &b); - memset(data, 0, ISC_SHA224_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -753,8 +753,8 @@ static void hmacsha224_destroy(dst_key_t *key) { dst_hmacsha224_key_t *hkey = key->keydata.hmacsha224; - memset(hkey, 0, sizeof(dst_hmacsha224_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha224_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacsha224 = NULL; } @@ -880,7 +880,7 @@ hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } @@ -1025,7 +1025,7 @@ hmacsha256_generate(dst_key_t *key, int pseudorandom_ok, isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha256_fromdns(key, &b); - memset(data, 0, ISC_SHA256_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -1040,8 +1040,8 @@ static void hmacsha256_destroy(dst_key_t *key) { dst_hmacsha256_key_t *hkey = key->keydata.hmacsha256; - memset(hkey, 0, sizeof(dst_hmacsha256_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha256_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacsha256 = NULL; } @@ -1167,7 +1167,7 @@ hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } @@ -1312,7 +1312,7 @@ hmacsha384_generate(dst_key_t *key, int pseudorandom_ok, isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha384_fromdns(key, &b); - memset(data, 0, ISC_SHA384_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -1327,8 +1327,8 @@ static void hmacsha384_destroy(dst_key_t *key) { dst_hmacsha384_key_t *hkey = key->keydata.hmacsha384; - memset(hkey, 0, sizeof(dst_hmacsha384_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha384_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacsha384 = NULL; } @@ -1454,7 +1454,7 @@ hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } @@ -1599,7 +1599,7 @@ hmacsha512_generate(dst_key_t *key, int pseudorandom_ok, isc_buffer_init(&b, data, bytes); isc_buffer_add(&b, bytes); ret = hmacsha512_fromdns(key, &b); - memset(data, 0, ISC_SHA512_BLOCK_LENGTH); + isc_safe_memwipe(data, sizeof(data)); return (ret); } @@ -1614,8 +1614,8 @@ static void hmacsha512_destroy(dst_key_t *key) { dst_hmacsha512_key_t *hkey = key->keydata.hmacsha512; - memset(hkey, 0, sizeof(dst_hmacsha512_key_t)); - isc_mem_put(key->mctx, hkey, sizeof(dst_hmacsha512_key_t)); + isc_safe_memwipe(hkey, sizeof(*hkey)); + isc_mem_put(key->mctx, hkey, sizeof(*hkey)); key->keydata.hmacsha512 = NULL; } @@ -1741,7 +1741,7 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (result); } diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c index f334230a1c..059bae2849 100644 --- a/lib/dns/openssldh_link.c +++ b/lib/dns/openssldh_link.c @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -685,7 +686,7 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { BN_free(priv_key); openssldh_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c index ba583dc026..bfebaa7d16 100644 --- a/lib/dns/openssldsa_link.c +++ b/lib/dns/openssldsa_link.c @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -711,7 +712,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -747,7 +748,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); DSA_set0_key(dsa, pub_key, priv_key); DSA_set0_pqg(dsa, p, q, g); key->key_size = BN_num_bits(p); @@ -762,7 +763,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { BN_free(g); openssldsa_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c index 42b929a33e..84cde676bc 100644 --- a/lib/dns/opensslecdsa_link.c +++ b/lib/dns/opensslecdsa_link.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -559,7 +560,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -601,7 +602,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (eckey != NULL) EC_KEY_free(eckey); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c index 58f9293748..820b5b30c7 100644 --- a/lib/dns/openssleddsa_link.c +++ b/lib/dns/openssleddsa_link.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -597,7 +598,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->keydata.pkey = pub->keydata.pkey; pub->keydata.pkey = NULL; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -624,7 +625,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { err: dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c index 1ea60607a8..58ddf243d3 100644 --- a/lib/dns/opensslgost_link.c +++ b/lib/dns/opensslgost_link.c @@ -471,7 +471,7 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -523,7 +523,7 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->keydata.pkey = pkey; key->key_size = EVP_PKEY_bits(pkey); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); err: @@ -533,7 +533,7 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { EVP_PKEY_free(pkey); opensslgost_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c index 8e3a4ef994..5dddc2eda4 100644 --- a/lib/dns/opensslrsa_link.c +++ b/lib/dns/opensslrsa_link.c @@ -1487,7 +1487,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { pub->keydata.pkey = NULL; key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -1555,7 +1555,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { EVP_PKEY_free(pkey); #endif dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); #else DST_RET(DST_R_NOENGINE); @@ -1619,7 +1619,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { } } dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); if (RSA_set0_key(rsa, n, e, d) == 0) { if (n != NULL) BN_free(n); @@ -1660,7 +1660,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { RSA_free(pubrsa); key->keydata.generic = NULL; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c index 29b73a8a9d..179b2c0b7e 100644 --- a/lib/dns/pkcs11dh_link.c +++ b/lib/dns/pkcs11dh_link.c @@ -139,8 +139,8 @@ pkcs11dh_loadpriv(const dst_key_t *key, err: for (i = 6; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(key->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -240,7 +240,8 @@ pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, if (hDerived != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx.session, hDerived); if (valTemplate[0].pValue != NULL) { - memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen); + isc_safe_memwipe(valTemplate[0].pValue, + valTemplate[0].ulValueLen); isc_mem_put(pub->mctx, valTemplate[0].pValue, valTemplate[0].ulValueLen); @@ -248,7 +249,7 @@ pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) (void) pkcs_C_DestroyObject(ctx.session, hKey); if (mech.pParameter != NULL) { - memset(mech.pParameter, 0, mech.ulParameterLen); + isc_safe_memwipe(mech.pParameter, mech.ulParameterLen); isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); } pk11_return_session(&ctx); @@ -540,7 +541,7 @@ pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); @@ -555,32 +556,36 @@ pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); if (pubTemplate[4].pValue != NULL) { - memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen); + isc_safe_memwipe(pubTemplate[4].pValue, + pubTemplate[4].ulValueLen); isc_mem_put(key->mctx, pubTemplate[4].pValue, pubTemplate[4].ulValueLen); } if (pubTemplate[5].pValue != NULL) { - memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen); + isc_safe_memwipe(pubTemplate[5].pValue, + pubTemplate[5].ulValueLen); isc_mem_put(key->mctx, pubTemplate[5].pValue, pubTemplate[5].ulValueLen); } if (pTemplate[0].pValue != NULL) { - memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); + isc_safe_memwipe(pTemplate[0].pValue, + pTemplate[0].ulValueLen); isc_mem_put(key->mctx, pTemplate[0].pValue, pTemplate[0].ulValueLen); } if (pTemplate[1].pValue != NULL) { - memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); + isc_safe_memwipe(pTemplate[1].pValue, + pTemplate[1].ulValueLen); isc_mem_put(key->mctx, pTemplate[1].pValue, pTemplate[1].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -616,7 +621,8 @@ pkcs11dh_destroy(dst_key_t *key) { case CKA_PRIME: case CKA_BASE: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -624,10 +630,10 @@ pkcs11dh_destroy(dst_key_t *key) { break; } if (dh->repr != NULL) { - memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); + isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); } - memset(dh, 0, sizeof(*dh)); + isc_safe_memwipe(dh, sizeof(*dh)); isc_mem_put(key->mctx, dh, sizeof(*dh)); key->keydata.pkey = NULL; } @@ -732,42 +738,43 @@ pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) { static isc_result_t pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { - pk11_object_t *dh; + pk11_object_t *dh = NULL; isc_region_t r; isc_uint16_t plen, glen, plen_, glen_, publen; CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; CK_ATTRIBUTE *attr; int special = 0; + isc_result_t result; isc_buffer_remainingregion(data, &r); - if (r.length == 0) - return (ISC_R_SUCCESS); + if (r.length == 0) { + result = ISC_R_SUCCESS; + goto cleanup; + } dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); - if (dh == NULL) - return (ISC_R_NOMEMORY); + if (dh == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + memset(dh, 0, sizeof(*dh)); + result = DST_R_INVALIDPUBLICKEY; /* * Read the prime length. 1 & 2 are table entries, > 16 means a * prime follows, otherwise an error. */ - if (r.length < 2) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (r.length < 2) + goto cleanup; + plen = uint16_fromregion(&r); - if (plen < 16 && plen != 1 && plen != 2) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } - if (r.length < plen) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (plen < 16 && plen != 1 && plen != 2) + goto cleanup; + + if (r.length < plen) + goto cleanup; + plen_ = plen; if (plen == 1 || plen == 2) { if (plen == 1) { @@ -790,9 +797,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { plen_ = sizeof(pk11_dh_bn1536); break; default: - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); + goto cleanup; } } else { @@ -805,17 +810,13 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { * special, but it might not be. If it's 0 and the prime is not * special, we have a problem. */ - if (r.length < 2) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (r.length < 2) + goto cleanup; + glen = uint16_fromregion(&r); - if (r.length < glen) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (r.length < glen) + goto cleanup; + glen_ = glen; if (special != 0) { if (glen == 0) { @@ -824,38 +825,26 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { } else { base = r.base; - if (isc_safe_memequal(base, pk11_dh_bn2, glen)) { - base = pk11_dh_bn2; - glen_ = sizeof(pk11_dh_bn2); - } - else { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (!isc_safe_memequal(base, pk11_dh_bn2, glen)) + goto cleanup; + base = pk11_dh_bn2; + glen_ = sizeof(pk11_dh_bn2); } } else { - if (glen == 0) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (glen == 0) + goto cleanup; base = r.base; } isc_region_consume(&r, glen); - if (r.length < 2) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (r.length < 2) + goto cleanup; + publen = uint16_fromregion(&r); - if (r.length < publen) { - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (DST_R_INVALIDPUBLICKEY); - } + if (r.length < publen) + goto cleanup; + pub = r.base; isc_region_consume(&r, publen); @@ -895,7 +884,7 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { return (ISC_R_SUCCESS); - nomemory: + nomemory: for (attr = pk11_attribute_first(dh); attr != NULL; attr = pk11_attribute_next(dh, attr)) @@ -904,7 +893,8 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { case CKA_PRIME: case CKA_BASE: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -912,12 +902,18 @@ pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { break; } if (dh->repr != NULL) { - memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); + isc_safe_memwipe(dh->repr, dh->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); } - memset(dh, 0, sizeof(*dh)); - isc_mem_put(key->mctx, dh, sizeof(*dh)); - return (ISC_R_NOMEMORY); + + result = ISC_R_NOMEMORY; + + cleanup: + if (dh != NULL) { + isc_safe_memwipe(dh, sizeof(*dh)); + isc_mem_put(key->mctx, dh, sizeof(*dh)); + } + return (result); } static isc_result_t @@ -1001,7 +997,7 @@ pkcs11dh_tofile(const dst_key_t *key, const char *directory) { for (i = 0; i < 4; i++) { if (bufs[i] == NULL) break; - memset(bufs[i], 0, prime->ulValueLen); + isc_safe_memwipe(bufs[i], prime->ulValueLen); isc_mem_put(key->mctx, bufs[i], prime->ulValueLen); } return (result); @@ -1089,7 +1085,7 @@ pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { err: pkcs11dh_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c index 0632f198c2..df38e85aa1 100644 --- a/lib/dns/pkcs11dsa_link.c +++ b/lib/dns/pkcs11dsa_link.c @@ -178,8 +178,8 @@ pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -192,14 +192,14 @@ pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 9; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -310,8 +310,8 @@ pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) { for (i = 5; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -324,14 +324,14 @@ pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 8; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -355,7 +355,7 @@ pkcs11dsa_destroyctx(dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } @@ -637,7 +637,7 @@ pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); @@ -651,7 +651,7 @@ pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { if (dp != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -688,7 +688,8 @@ pkcs11dsa_destroy(dst_key_t *key) { case CKA_VALUE: case CKA_VALUE2: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -696,12 +697,12 @@ pkcs11dsa_destroy(dst_key_t *key) { break; } if (dsa->repr != NULL) { - memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); + isc_safe_memwipe(dsa->repr, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } - memset(dsa, 0, sizeof(*dsa)); + isc_safe_memwipe(dsa, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); key->keydata.pkey = NULL; } @@ -799,14 +800,14 @@ pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { t = (unsigned int) *r.base; isc_region_consume(&r, 1); if (t > 8) { - memset(dsa, 0, sizeof(*dsa)); + isc_safe_memwipe(dsa, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } p_bytes = 64 + 8 * t; if (r.length < ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { - memset(dsa, 0, sizeof(*dsa)); + isc_safe_memwipe(dsa, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (DST_R_INVALIDPUBLICKEY); } @@ -876,7 +877,8 @@ pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { case CKA_BASE: case CKA_VALUE: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -884,12 +886,12 @@ pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { break; } if (dsa->repr != NULL) { - memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); + isc_safe_memwipe(dsa->repr, dsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, dsa->repr, dsa->attrcnt * sizeof(*attr)); } - memset(dsa, 0, sizeof(*dsa)); + isc_safe_memwipe(dsa, sizeof(*dsa)); isc_mem_put(key->mctx, dsa, sizeof(*dsa)); return (ISC_R_NOMEMORY); } @@ -997,7 +999,7 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -1073,7 +1075,7 @@ pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { err: pkcs11dsa_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/pkcs11gost_link.c b/lib/dns/pkcs11gost_link.c index a979b9090e..dd4f3667cc 100644 --- a/lib/dns/pkcs11gost_link.c +++ b/lib/dns/pkcs11gost_link.c @@ -90,7 +90,7 @@ isc_gost_invalidate(isc_gost_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(ctx); } @@ -209,8 +209,8 @@ pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) { for (i = 6; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -223,14 +223,14 @@ pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 6; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -314,8 +314,8 @@ pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -328,14 +328,14 @@ pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); for (i = 5; i <= 5; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -359,7 +359,7 @@ pkcs11gost_destroyctx(dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } @@ -566,7 +566,7 @@ pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); @@ -578,7 +578,7 @@ pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -612,7 +612,8 @@ pkcs11gost_destroy(dst_key_t *key) { case CKA_VALUE: case CKA_VALUE2: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -620,12 +621,11 @@ pkcs11gost_destroy(dst_key_t *key) { break; } if (gost->repr != NULL) { - memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); + isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, - gost->repr, - gost->attrcnt * sizeof(*attr)); + gost->repr, gost->attrcnt * sizeof(*attr)); } - memset(gost, 0, sizeof(*gost)); + isc_safe_memwipe(gost, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); key->keydata.pkey = NULL; } @@ -693,7 +693,8 @@ pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { switch (attr->type) { case CKA_VALUE: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -701,12 +702,11 @@ pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { break; } if (gost->repr != NULL) { - memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); + isc_safe_memwipe(gost->repr, gost->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, - gost->repr, - gost->attrcnt * sizeof(*attr)); + gost->repr, gost->attrcnt * sizeof(*attr)); } - memset(gost, 0, sizeof(*gost)); + isc_safe_memwipe(gost, sizeof(*gost)); isc_mem_put(key->mctx, gost, sizeof(*gost)); return (ISC_R_NOMEMORY); } @@ -765,7 +765,7 @@ pkcs11gost_tofile(const dst_key_t *key, const char *directory) { ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) { - memset(buf, 0, attr->ulValueLen); + isc_safe_memwipe(buf, attr->ulValueLen); isc_mem_put(key->mctx, buf, attr->ulValueLen); } return (ret); @@ -808,7 +808,7 @@ pkcs11gost_tofile(const dst_key_t *key, const char *directory) { ret = dst__privstruct_writefile(key, &priv, directory); if (buf != NULL) { - memset(buf, 0, attr->ulValueLen); + isc_safe_memwipe(buf, attr->ulValueLen); isc_mem_put(key->mctx, buf, attr->ulValueLen); } return (ret); @@ -840,7 +840,7 @@ pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -899,14 +899,14 @@ pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { attr->ulValueLen = priv.elements[0].length; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); err: pkcs11gost_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c index 32aa5df80f..861a6c0d30 100644 --- a/lib/dns/pkcs11rsa_link.c +++ b/lib/dns/pkcs11rsa_link.c @@ -264,8 +264,8 @@ pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -279,14 +279,14 @@ pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { pk11_ctx->object); for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -432,8 +432,8 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); @@ -447,14 +447,14 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, pk11_ctx->object); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -487,7 +487,7 @@ pkcs11rsa_destroyctx(dst_context_t *dctx) { (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } @@ -670,7 +670,7 @@ pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { err: pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -684,9 +684,9 @@ pkcs11rsa_destroyctx(dst_context_t *dctx) { if (pk11_ctx != NULL) { (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; } @@ -953,14 +953,14 @@ pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); for (i = 6; i <= 13; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; @@ -1097,14 +1097,14 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); for (i = 5; i <= 6; i++) if (keyTemplate[i].pValue != NULL) { - memset(keyTemplate[i].pValue, 0, - keyTemplate[i].ulValueLen); + isc_safe_memwipe(keyTemplate[i].pValue, + keyTemplate[i].ulValueLen); isc_mem_put(dctx->mctx, keyTemplate[i].pValue, keyTemplate[i].ulValueLen); } pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); dctx->ctxdata.pk11_ctx = NULL; @@ -1313,7 +1313,7 @@ pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); @@ -1325,7 +1325,7 @@ pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { if (pub != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ret); @@ -1367,7 +1367,8 @@ pkcs11rsa_destroy(dst_key_t *key) { case CKA_EXPONENT_2: case CKA_COEFFICIENT: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -1375,12 +1376,12 @@ pkcs11rsa_destroy(dst_key_t *key) { break; } if (rsa->repr != NULL) { - memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); + isc_safe_memwipe(rsa->repr, rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } - memset(rsa, 0, sizeof(*rsa)); + isc_safe_memwipe(rsa, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); key->keydata.pkey = NULL; } @@ -1464,7 +1465,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { if (e_bytes == 0) { if (r.length < 2) { - memset(rsa, 0, sizeof(*rsa)); + isc_safe_memwipe(rsa, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } @@ -1475,7 +1476,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } if (r.length < e_bytes) { - memset(rsa, 0, sizeof(*rsa)); + isc_safe_memwipe(rsa, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (DST_R_INVALIDPUBLICKEY); } @@ -1519,7 +1520,8 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { case CKA_MODULUS: case CKA_PUBLIC_EXPONENT: if (attr->pValue != NULL) { - memset(attr->pValue, 0, attr->ulValueLen); + isc_safe_memwipe(attr->pValue, + attr->ulValueLen); isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); @@ -1527,12 +1529,13 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { break; } if (rsa->repr != NULL) { - memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); + isc_safe_memwipe(rsa->repr, + rsa->attrcnt * sizeof(*attr)); isc_mem_put(key->mctx, rsa->repr, rsa->attrcnt * sizeof(*attr)); } - memset(rsa, 0, sizeof(*rsa)); + isc_safe_memwipe(rsa, sizeof(*rsa)); isc_mem_put(key->mctx, rsa, sizeof(*rsa)); return (ISC_R_NOMEMORY); } @@ -1686,7 +1689,7 @@ pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { for (i = 0; i < 10; i++) { if (bufs[i] == NULL) break; - memset(bufs[i], 0, modulus->ulValueLen); + isc_safe_memwipe(bufs[i], modulus->ulValueLen); isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); } return (result); @@ -1792,7 +1795,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, DST_RET(ISC_R_NOMEMORY); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); attr = pk11_attribute_bytype(rsa, CKA_MODULUS); @@ -1804,7 +1807,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, err: if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } @@ -1900,7 +1903,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { key->key_size = pub->key_size; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); } @@ -1929,7 +1932,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { if (ret != ISC_R_SUCCESS) goto err; dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } @@ -2034,14 +2037,14 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { DST_RET(ISC_R_RANGE); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ISC_R_SUCCESS); err: pkcs11rsa_destroy(key); dst__privstruct_free(&priv, mctx); - memset(&priv, 0, sizeof(priv)); + isc_safe_memwipe(&priv, sizeof(priv)); return (ret); } @@ -2168,7 +2171,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); return (ISC_R_SUCCESS); @@ -2177,7 +2180,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, pkcs11rsa_destroy(key); if (pk11_ctx != NULL) { pk11_return_session(pk11_ctx); - memset(pk11_ctx, 0, sizeof(*pk11_ctx)); + isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); } diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c index 65278b9bee..173bd681d2 100644 --- a/lib/isc/entropy.c +++ b/lib/isc/entropy.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -643,7 +644,7 @@ isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, } partial_output: - memset(digest, 0, sizeof(digest)); + isc_safe_memwipe(digest, sizeof(digest)); if (returned != NULL) *returned = (length - remain); @@ -655,8 +656,8 @@ isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length, zeroize: /* put the entropy we almost extracted back */ add_entropy(ent, total); - memset(data, 0, length); - memset(digest, 0, sizeof(digest)); + isc_safe_memwipe(data, length); + isc_safe_memwipe(digest, sizeof(digest)); if (returned != NULL) *returned = 0; @@ -767,9 +768,8 @@ destroysource(isc_entropysource_t **sourcep) { break; } - memset(source, 0, sizeof(isc_entropysource_t)); - - isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); + isc_safe_memwipe(source, sizeof(*source)); + isc_mem_put(ent->mctx, source, sizeof(*source)); } static inline isc_boolean_t @@ -835,8 +835,8 @@ destroy(isc_entropy_t **entp) { DESTROYLOCK(&ent->lock); - memset(ent, 0, sizeof(isc_entropy_t)); - isc_mem_put(mctx, ent, sizeof(isc_entropy_t)); + isc_safe_memwipe(ent, sizeof(*ent)); + isc_mem_put(mctx, ent, sizeof(*ent)); isc_mem_detach(&mctx); } diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c index bd6e454a26..03b50c5a50 100644 --- a/lib/isc/hmacmd5.c +++ b/lib/isc/hmacmd5.c @@ -124,7 +124,7 @@ isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -279,7 +279,7 @@ isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, void isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { isc_md5_invalidate(&ctx->md5ctx); - memset(ctx->key, 0, sizeof(ctx->key)); + isc_safe_memwipe(ctx->key, sizeof(ctx->key)); } /*! diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c index d57ea7a511..3ae1a0bb3e 100644 --- a/lib/isc/hmacsha.c +++ b/lib/isc/hmacsha.c @@ -70,7 +70,7 @@ isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { HMAC_CTX_free(ctx->ctx); ctx->ctx = NULL; memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } void @@ -108,7 +108,7 @@ isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { HMAC_CTX_free(ctx->ctx); ctx->ctx = NULL; memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } void @@ -146,7 +146,7 @@ isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { HMAC_CTX_free(ctx->ctx); ctx->ctx = NULL; memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } void @@ -184,7 +184,7 @@ isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { HMAC_CTX_free(ctx->ctx); ctx->ctx = NULL; memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } void @@ -222,7 +222,7 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { HMAC_CTX_free(ctx->ctx); ctx->ctx = NULL; memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #elif PKCS11CRYPTO @@ -294,7 +294,7 @@ isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -327,7 +327,7 @@ isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #else void @@ -411,7 +411,7 @@ isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, newdigest, &psl)); pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif @@ -464,7 +464,7 @@ isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -497,7 +497,7 @@ isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #else void @@ -581,7 +581,7 @@ isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, newdigest, &psl)); pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif @@ -634,7 +634,7 @@ isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -667,7 +667,7 @@ isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #else void @@ -751,7 +751,7 @@ isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, newdigest, &psl)); pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif @@ -804,7 +804,7 @@ isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -837,7 +837,7 @@ isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #else void @@ -921,7 +921,7 @@ isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, newdigest, &psl)); pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif @@ -974,7 +974,7 @@ isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_SignFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); if (ctx->object != CK_INVALID_HANDLE) (void) pkcs_C_DestroyObject(ctx->session, ctx->object); ctx->object = CK_INVALID_HANDLE; @@ -1007,7 +1007,7 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { ctx->object = CK_INVALID_HANDLE; pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #else void @@ -1091,7 +1091,7 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { PK11_FATALCHECK(pkcs_C_DigestFinal, (ctx->session, newdigest, &psl)); pk11_return_session(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif @@ -1129,7 +1129,7 @@ isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, void isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { isc_sha1_invalidate(&ctx->sha1ctx); - memset(ctx, 0, sizeof(*ctx)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /* @@ -1165,7 +1165,7 @@ isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { isc_sha1_final(&ctx->sha1ctx, newdigest); isc_hmacsha1_invalidate(ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } /* @@ -1196,7 +1196,7 @@ isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, void isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { - memset(ctx, 0, sizeof(*ctx)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /* @@ -1231,7 +1231,7 @@ isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH); isc_sha224_final(newdigest, &ctx->sha224ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } /* @@ -1262,7 +1262,7 @@ isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, void isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { - memset(ctx, 0, sizeof(*ctx)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /* @@ -1297,7 +1297,7 @@ isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH); isc_sha256_final(newdigest, &ctx->sha256ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } /* @@ -1328,7 +1328,7 @@ isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, void isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { - memset(ctx, 0, sizeof(*ctx)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /* @@ -1363,7 +1363,7 @@ isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH); isc_sha384_final(newdigest, &ctx->sha384ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } /* @@ -1394,7 +1394,7 @@ isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, void isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { - memset(ctx, 0, sizeof(*ctx)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /* @@ -1429,7 +1429,7 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH); isc_sha512_final(newdigest, &ctx->sha512ctx); memmove(digest, newdigest, len); - memset(newdigest, 0, sizeof(newdigest)); + isc_safe_memwipe(newdigest, sizeof(newdigest)); } #endif /* !ISC_PLATFORM_OPENSSLHASH */ diff --git a/lib/isc/include/isc/safe.h b/lib/isc/include/isc/safe.h index a734a91dd2..f17f4d34a3 100644 --- a/lib/isc/include/isc/safe.h +++ b/lib/isc/include/isc/safe.h @@ -14,6 +14,7 @@ /*! \file isc/safe.h */ #include +#include ISC_LANG_BEGINDECLS @@ -31,6 +32,18 @@ isc_safe_memcompare(const void *b1, const void *b2, size_t len); * Clone of libc memcmp() which is safe to differential timing attacks. */ +void +isc_safe_memwipe(void *ptr, size_t len); +/*%< + * Clear the memory of length `len` pointed to by `ptr`. + * + * Some crypto code calls memset() on stack allocated buffers just + * before return so that they are wiped. Such memset() calls can be + * optimized away by the compiler. We provide this external non-inline C + * function to perform the memset operation so that the compiler cannot + * infer about what the function does and optimize the call away. + */ + ISC_LANG_ENDDECLS #endif /* ISC_SAFE_H */ diff --git a/lib/isc/md5.c b/lib/isc/md5.c index 6440e58b2c..939a1464f7 100644 --- a/lib/isc/md5.c +++ b/lib/isc/md5.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -99,7 +100,7 @@ isc_md5_invalidate(isc_md5_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(ctx); } @@ -154,7 +155,7 @@ isc_md5_init(isc_md5_t *ctx) { void isc_md5_invalidate(isc_md5_t *ctx) { - memset(ctx, 0, sizeof(isc_md5_t)); + isc_safe_memwipe(ctx, sizeof(*ctx)); } /*@{*/ @@ -330,7 +331,7 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { byteSwap(ctx->buf, 4); memmove(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */ + isc_safe_memwipe(ctx, sizeof(*ctx)); /* In case it's sensitive */ } #endif diff --git a/lib/isc/random.c b/lib/isc/random.c index 697ead5152..99d91c5074 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -342,13 +343,7 @@ chacha_stir(isc_rng_t *rng) { chacha_rekey(rng, rnd.rnd, sizeof(rnd.rnd)); - /* - * The OpenBSD implementation explicit_bzero()s the random seed - * rnd.rnd at this point, but it may not be required here. This - * memset() may also be optimized away by the compiler as - * rnd.rnd is not used further. - */ - memset(rnd.rnd, 0, sizeof(rnd.rnd)); + isc_safe_memwipe(rnd.rnd, sizeof(rnd.rnd)); /* Invalidate the buffer too. */ rng->have = 0; diff --git a/lib/isc/safe.c b/lib/isc/safe.c index a2598f78bd..0d6574ae1e 100644 --- a/lib/isc/safe.c +++ b/lib/isc/safe.c @@ -13,6 +13,14 @@ #include #include +#ifdef WIN32 +#include +#elif HAVE_EXPLICIT_BZERO +#include +#else +#include +#endif + #ifdef _MSC_VER #pragma optimize("", off) #endif @@ -57,3 +65,17 @@ isc_safe_memcompare(const void *b1, const void *b2, size_t len) { return (res); } + +void +isc_safe_memwipe(void *ptr, size_t len) { + if (ISC_UNLIKELY(ptr == NULL || len == 0)) + return; + +#ifdef WIN32 + SecureZeroMemory(ptr, len); +#elif HAVE_EXPLICIT_BZERO + explicit_bzero(ptr, len); +#else + memset(ptr, 0, len); +#endif +} diff --git a/lib/isc/sha1.c b/lib/isc/sha1.c index acfc5082ec..f564ad2ccc 100644 --- a/lib/isc/sha1.c +++ b/lib/isc/sha1.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -104,7 +105,7 @@ isc_sha1_invalidate(isc_sha1_t *ctx) { if (ctx->handle == NULL) return; (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(ctx); } @@ -332,7 +333,7 @@ isc_sha1_init(isc_sha1_t *context) void isc_sha1_invalidate(isc_sha1_t *context) { - memset(context, 0, sizeof(isc_sha1_t)); + isc_safe_memwipe(context, sizeof(*context)); } /*! @@ -400,6 +401,6 @@ isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { >> ((3 - (i & 3)) * 8)) & 255); } - memset(context, 0, sizeof(isc_sha1_t)); + isc_safe_memwipe(context, sizeof(*context)); } #endif diff --git a/lib/isc/sha2.c b/lib/isc/sha2.c index 4a813efe1c..9591c91e05 100644 --- a/lib/isc/sha2.c +++ b/lib/isc/sha2.c @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -270,7 +271,7 @@ isc_sha224_invalidate(isc_sha224_t *context) { if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(context); } @@ -310,7 +311,7 @@ isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); } pk11_return_session(context); } @@ -336,7 +337,7 @@ isc_sha256_invalidate(isc_sha256_t *context) { if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(context); } @@ -376,7 +377,7 @@ isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); } pk11_return_session(context); } @@ -402,7 +403,7 @@ isc_sha512_invalidate(isc_sha512_t *context) { if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(context); } @@ -442,7 +443,7 @@ isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); } pk11_return_session(context); } @@ -468,7 +469,7 @@ isc_sha384_invalidate(isc_sha384_t *context) { if (context->handle == NULL) return; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); pk11_return_session(context); } @@ -508,7 +509,7 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; (void) pkcs_C_DigestFinal(context->session, garbage, &len); - memset(garbage, 0, sizeof(garbage)); + isc_safe_memwipe(garbage, sizeof(garbage)); } pk11_return_session(context); } @@ -862,7 +863,7 @@ isc_sha224_init(isc_sha224_t *context) { void isc_sha224_invalidate(isc_sha224_t *context) { - memset(context, 0, sizeof(isc_sha224_t)); + isc_safe_memwipe(context, sizeof(*context)); } void @@ -875,7 +876,7 @@ isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { isc_uint8_t sha256_digest[ISC_SHA256_DIGESTLENGTH]; isc_sha256_final(sha256_digest, (isc_sha256_t *)context); memmove(digest, sha256_digest, ISC_SHA224_DIGESTLENGTH); - memset(sha256_digest, 0, ISC_SHA256_DIGESTLENGTH); + isc_safe_memwipe(sha256_digest, sizeof(sha256_digest)); } /*** SHA-256: *********************************************************/ @@ -892,7 +893,7 @@ isc_sha256_init(isc_sha256_t *context) { void isc_sha256_invalidate(isc_sha256_t *context) { - memset(context, 0, sizeof(isc_sha256_t)); + isc_safe_memwipe(context, sizeof(*context)); } #ifdef ISC_SHA2_UNROLL_TRANSFORM @@ -1199,7 +1200,7 @@ isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { } /* Clean up state data: */ - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); usedspace = 0; POST(usedspace); } @@ -1218,7 +1219,7 @@ isc_sha512_init(isc_sha512_t *context) { void isc_sha512_invalidate(isc_sha512_t *context) { - memset(context, 0, sizeof(isc_sha512_t)); + isc_safe_memwipe(context, sizeof(*context)); } #ifdef ISC_SHA2_UNROLL_TRANSFORM @@ -1523,7 +1524,7 @@ void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { } /* Zero out state data */ - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); } @@ -1541,7 +1542,7 @@ isc_sha384_init(isc_sha384_t *context) { void isc_sha384_invalidate(isc_sha384_t *context) { - memset(context, 0, sizeof(isc_sha384_t)); + isc_safe_memwipe(context, sizeof(*context)); } void @@ -1576,7 +1577,7 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { } /* Zero out state data */ - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); } #endif /* !ISC_PLATFORM_OPENSSLHASH */ @@ -1609,10 +1610,10 @@ isc_sha224_end(isc_sha224_t *context, char buffer[]) { #elif PKCS11CRYPTO pk11_return_session(context); #else - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); #endif } - memset(digest, 0, ISC_SHA224_DIGESTLENGTH); + isc_safe_memwipe(digest, sizeof(digest)); return buffer; } @@ -1650,10 +1651,10 @@ isc_sha256_end(isc_sha256_t *context, char buffer[]) { #elif PKCS11CRYPTO pk11_return_session(context); #else - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); #endif } - memset(digest, 0, ISC_SHA256_DIGESTLENGTH); + isc_safe_memwipe(digest, sizeof(digest)); return buffer; } @@ -1691,10 +1692,10 @@ isc_sha512_end(isc_sha512_t *context, char buffer[]) { #elif PKCS11CRYPTO pk11_return_session(context); #else - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); #endif } - memset(digest, 0, ISC_SHA512_DIGESTLENGTH); + isc_safe_memwipe(digest, sizeof(digest)); return buffer; } @@ -1732,10 +1733,10 @@ isc_sha384_end(isc_sha384_t *context, char buffer[]) { #elif PKCS11CRYPTO pk11_return_session(context); #else - memset(context, 0, sizeof(*context)); + isc_safe_memwipe(context, sizeof(*context)); #endif } - memset(digest, 0, ISC_SHA384_DIGESTLENGTH); + isc_safe_memwipe(digest, sizeof(digest)); return buffer; } diff --git a/lib/isc/tests/safe_test.c b/lib/isc/tests/safe_test.c index 049fbc0fc3..6354fb5c1e 100644 --- a/lib/isc/tests/safe_test.c +++ b/lib/isc/tests/safe_test.c @@ -55,11 +55,56 @@ ATF_TC_BODY(isc_safe_memcompare, tc) { "\x00\x00\x00\x00", 4) > 0); } +ATF_TC(isc_safe_memwipe); +ATF_TC_HEAD(isc_safe_memwipe, tc) { + atf_tc_set_md_var(tc, "descr", "isc_safe_memwipe()"); +} +ATF_TC_BODY(isc_safe_memwipe, tc) { + UNUSED(tc); + + /* These should pass. */ + isc_safe_memwipe(NULL, 0); + isc_safe_memwipe((void *) -1, 0); + isc_safe_memwipe(NULL, 42); + + /* + * isc_safe_memwipe(ptr, size) should function same as + * memset(ptr, 0, size); + */ + { + char buf1[4] = { 1, 2, 3, 4 }; + char buf2[4] = { 1, 2, 3, 4 }; + + isc_safe_memwipe(buf1, sizeof(buf1)); + memset(buf2, 0, sizeof(buf2)); + + ATF_CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0); + } + + /* + * Boundary test. + */ + { + char buf1[4] = { 1, 2, 3, 4 }; + char buf2[4] = { 1, 2, 3, 4 }; + + /* + * We wipe 3 elements on purpose, keeping the 4th in + * place. + */ + isc_safe_memwipe(buf1, 3); + memset(buf2, 0, 3); + + ATF_CHECK(memcmp(buf1, buf2, sizeof(buf1)) == 0); + } +} + /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, isc_safe_memequal); ATF_TP_ADD_TC(tp, isc_safe_memcompare); + ATF_TP_ADD_TC(tp, isc_safe_memwipe); return (atf_no_error()); } diff --git a/lib/isc/win32/libisc.def.in b/lib/isc/win32/libisc.def.in index 5d7d9e50b4..7d57a8c180 100644 --- a/lib/isc/win32/libisc.def.in +++ b/lib/isc/win32/libisc.def.in @@ -562,6 +562,7 @@ isc_rwlock_tryupgrade isc_rwlock_unlock isc_safe_memcompare isc_safe_memequal +isc_safe_memwipe isc_serial_eq isc_serial_ge isc_serial_gt