From 349e6ab916b3dd106fea9b56dacec065df5fa457 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 27 Apr 2020 18:55:36 +0200 Subject: [PATCH] Introduce separate _clear functions for hash module This gives the caller more control about whether the state should be cleaned (= should be considered secret). Moreover, it gives the caller the possibility to clean a hash struct without finalizing it. --- src/ecmult_gen_impl.h | 1 + src/hash.h | 3 +++ src/hash_impl.h | 16 ++++++++++++---- src/modules/ecdh/main_impl.h | 1 + src/modules/ellswift/main_impl.h | 2 ++ src/modules/musig/session_impl.h | 4 ++-- src/modules/schnorrsig/main_impl.h | 1 + src/secp256k1.c | 5 ++++- 8 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 6903cd1bb8..070a121308 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -335,6 +335,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const secp256k1_scalar_clear(&b); secp256k1_gej_clear(&gb); secp256k1_fe_clear(&f); + secp256k1_rfc6979_hmac_sha256_clear(&rng); } #endif /* SECP256K1_ECMULT_GEN_IMPL_H */ diff --git a/src/hash.h b/src/hash.h index 4e0384cfbf..6d903ca7e0 100644 --- a/src/hash.h +++ b/src/hash.h @@ -19,6 +19,7 @@ typedef struct { static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); +static void secp256k1_sha256_clear(secp256k1_sha256 *hash); typedef struct { secp256k1_sha256 inner, outer; @@ -27,6 +28,7 @@ typedef struct { static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); +static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash); typedef struct { unsigned char v[32]; @@ -37,5 +39,6 @@ typedef struct { static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); +static void secp256k1_rfc6979_hmac_sha256_clear(secp256k1_rfc6979_hmac_sha256 *rng); #endif /* SECP256K1_HASH_H */ diff --git a/src/hash_impl.h b/src/hash_impl.h index 49393c6750..956e0ea48b 100644 --- a/src/hash_impl.h +++ b/src/hash_impl.h @@ -156,9 +156,6 @@ static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out secp256k1_write_be32(&out32[4*i], hash->s[i]); hash->s[i] = 0; } - - secp256k1_memclear(sizedesc, sizeof(sizedesc)); - secp256k1_memclear(hash, sizeof(secp256k1_sha256)); } /* Initializes a sha256 struct and writes the 64 byte string @@ -174,6 +171,10 @@ static void secp256k1_sha256_initialize_tagged(secp256k1_sha256 *hash, const uns secp256k1_sha256_write(hash, buf, 32); } +static void secp256k1_sha256_clear(secp256k1_sha256 *hash) { + secp256k1_memclear(hash, sizeof(*hash)); +} + static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) { size_t n; unsigned char rkey[64]; @@ -214,6 +215,9 @@ static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned secp256k1_sha256_finalize(&hash->outer, out32); } +static void secp256k1_hmac_sha256_clear(secp256k1_hmac_sha256 *hash) { + secp256k1_memclear(hash, sizeof(*hash)); +} static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen) { secp256k1_hmac_sha256 hmac; @@ -277,7 +281,11 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 } static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng) { - secp256k1_memclear(rng, sizeof(secp256k1_rfc6979_hmac_sha256)); + (void) rng; +} + +static void secp256k1_rfc6979_hmac_sha256_clear(secp256k1_rfc6979_hmac_sha256 *rng) { + secp256k1_memclear(rng, sizeof(*rng)); } #undef Round diff --git a/src/modules/ecdh/main_impl.h b/src/modules/ecdh/main_impl.h index 9286f70f35..a3dc18332b 100644 --- a/src/modules/ecdh/main_impl.h +++ b/src/modules/ecdh/main_impl.h @@ -19,6 +19,7 @@ static int ecdh_hash_function_sha256(unsigned char *output, const unsigned char secp256k1_sha256_write(&sha, &version, 1); secp256k1_sha256_write(&sha, x32, 32); secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); return 1; } diff --git a/src/modules/ellswift/main_impl.h b/src/modules/ellswift/main_impl.h index 78e850048a..745a969139 100644 --- a/src/modules/ellswift/main_impl.h +++ b/src/modules/ellswift/main_impl.h @@ -510,6 +510,7 @@ static int ellswift_xdh_hash_function_prefix(unsigned char *output, const unsign secp256k1_sha256_write(&sha, ell_b64, 64); secp256k1_sha256_write(&sha, x32, 32); secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); return 1; } @@ -539,6 +540,7 @@ static int ellswift_xdh_hash_function_bip324(unsigned char* output, const unsign secp256k1_sha256_write(&sha, ell_b64, 64); secp256k1_sha256_write(&sha, x32, 32); secp256k1_sha256_finalize(&sha, output); + secp256k1_sha256_clear(&sha); return 1; } diff --git a/src/modules/musig/session_impl.h b/src/modules/musig/session_impl.h index e22d1a5451..d646ec11e0 100644 --- a/src/modules/musig/session_impl.h +++ b/src/modules/musig/session_impl.h @@ -386,10 +386,10 @@ static void secp256k1_nonce_function_musig(secp256k1_scalar *k, const unsigned c /* Attempt to erase secret data */ secp256k1_memclear(buf, sizeof(buf)); - secp256k1_memclear(&sha_tmp, sizeof(sha_tmp)); + secp256k1_sha256_clear(&sha_tmp); } secp256k1_memclear(rand, sizeof(rand)); - secp256k1_memclear(&sha, sizeof(sha)); + secp256k1_sha256_clear(&sha); } int secp256k1_musig_nonce_gen_internal(const secp256k1_context* ctx, secp256k1_musig_secnonce *secnonce, secp256k1_musig_pubnonce *pubnonce, const unsigned char *input_nonce, const unsigned char *seckey, const secp256k1_pubkey *pubkey, const unsigned char *msg32, const secp256k1_musig_keyagg_cache *keyagg_cache, const unsigned char *extra_input32) { diff --git a/src/modules/schnorrsig/main_impl.h b/src/modules/schnorrsig/main_impl.h index 783714fec7..261f4e4e27 100644 --- a/src/modules/schnorrsig/main_impl.h +++ b/src/modules/schnorrsig/main_impl.h @@ -93,6 +93,7 @@ static int nonce_function_bip340(unsigned char *nonce32, const unsigned char *ms secp256k1_sha256_write(&sha, xonly_pk32, 32); secp256k1_sha256_write(&sha, msg, msglen); secp256k1_sha256_finalize(&sha, nonce32); + secp256k1_sha256_clear(&sha); return 1; } diff --git a/src/secp256k1.c b/src/secp256k1.c index f4e83dc2cc..00c7285a0e 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -494,11 +494,13 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m buffer_append(keydata, &offset, algo16, 16); } secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset); - secp256k1_memclear(keydata, sizeof(keydata)); for (i = 0; i <= counter; i++) { secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32); } secp256k1_rfc6979_hmac_sha256_finalize(&rng); + + secp256k1_memclear(keydata, sizeof(keydata)); + secp256k1_rfc6979_hmac_sha256_clear(&rng); return 1; } @@ -799,6 +801,7 @@ int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32, secp256k1_sha256_initialize_tagged(&sha, tag, taglen); secp256k1_sha256_write(&sha, msg, msglen); secp256k1_sha256_finalize(&sha, hash32); + secp256k1_sha256_clear(&sha); return 1; }