-
Notifications
You must be signed in to change notification settings - Fork 1.1k
musig: Invalidate secnonce in secp256k1_musig_partial_sign #1735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
musig: Invalidate secnonce in secp256k1_musig_partial_sign #1735
Conversation
Why do you think it can be optimized out? I think it can be optimized out if the compiler can prove that no other code will read it. That seems unlikely, as the call is an API call. But if the compiler can prove this, then it's indeed fine to optimize it out? Or are you saying we should make absolutely sure that it's cleared out, even if the caller won't read it? Perhaps. |
cc @jonasnick who wrote this module |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @john-moffett. I think it would be an improvement to use secp256k1_memclear
in this case.
But if the compiler can prove this, then it's indeed fine to optimize it out?
I think in this case it still makes sense to clear it to try to avoid having secret data in memory that we don't use anymore. This is also the argument for clearing local secret variables at the end of functions.
10c46ec
to
fb40a68
Compare
I agree that it's unlikely to be optimized out, and I confirmed on my setup (arm64 macOS Clang 17.0.0) that even with -O3 and full LTO that it wasn't. However, that's not guaranteed since it's possible a different compiler (or later version) can prove no later reads, so I figured it's just best practice to use a wiper much less likely to be DSE'd.
The latter. If they assumed the callee wiped the memory (as is promised in the API comment), they might not bother themselves and it could be left in caller memory. |
fb40a68
to
312ff27
Compare
8b771f8
to
54bd42d
Compare
@john-moffett Can you remove the remaining |
54bd42d
to
16f62f5
Compare
16f62f5
to
d872a08
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK d872a08
I agree it's better to prevent the compiler from optimizing out that store. I'm not sure if this PR adds another code smell. I know it's me who suggested What could we do instead?We could use We could instead call We could also call edit: @john-moffett Sorry that this PR escalated quickly given that the issue is seemingly simple... |
That's a good point that I hadn't considered. An alternative to your suggestion is to have both a |
I was going to make the same suggestion. But is there any value in just reusing
No problem! I should've been aware of the issue from the start, but I've learned a lot, so I'm happy. At this point, I think the |
I suppose this usage of |
Ok, sure, that's another option. Concept ACK . I was considering that option too, but I didn't mention it because I had the feeling that the existence of two functions may confuse future devs. But now that I think about it, I guess it's fine. Perhaps then we can make it clear from the naming that both variants protect against optimization, e.g., by adding an
That's an interesting point you raise. Regarding its usage: I think it was initially introduced to clear the But all its three usages in How would a function look like that is both non-elidable and protects the So if we can't have the best of both worlds, we need to decide what protection we want. Currently, whenever we use secp256k1/src/modules/musig/session_impl.h Line 485 in 03fb60a
But this may be a larger discussion, and I'd like to hear @jonasnick's opinion on it. So my suggestion is to leave |
3c26af6
to
8165ac9
Compare
secp256k1_memclear has the side effect of undefining bytes for valgrind checks. In some cases, we may want to zero bytes but allow subsequent reads. So we split memclear into memclear_explicit, which makes no guarantees about the content of the buffer on return, and memzero_explicit, which guarantees zero value on return. Change the memset in partial_sign to use memzero_explicit.
8165ac9
to
399b582
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK 399b582 thanks!
I agree. We have issue #1621 pointing out the inconsistencies in handling constant-timeness with respect to invalid arguments in the library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 399b582
post-merge ACK 399b582 |
a44a339384 Merge bitcoin-core/secp256k1#1750: ci: Use clang-snapshot in "MSan" job 53585f93b7 ci: Use clang-snapshot in "MSan" job 6894c964f3 Fix Clang 21+ `-Wuninitialized-const-pointer` warning when using MSan 2b7337f63a Merge bitcoin-core/secp256k1#1756: ci: Fix image caching and apply other improvements f163c35897 ci: Set `DEBIAN_FRONTEND=noninteractive` 70ae177ca0 ci: Bump `docker/build-push-action` version b2a95a420f ci: Drop `tags` input for `docker/build-push-action` 122014edb3 ci: Add `scope` parameter to `cache-{to,from}` options baa265429f Merge bitcoin-core/secp256k1#1727: docs: Clarify that callback can be called more than once 4d90585fea docs: Improve API docs of _context_set_illegal_callback 895f53d1cf docs: Clarify that callback can be called more than once de6af6ae35 Merge bitcoin-core/secp256k1#1748: bench: improve context creation in ECDH benchmark 5817885153 Merge bitcoin-core/secp256k1#1749: build: Fix warnings in x86_64 assembly check ab560078aa build: Fix warnings in x86_64 assembly check 10dab907e7 Merge bitcoin-core/secp256k1#1741: doc: clarify API doc of `secp256k1_ecdsa_recover` return value dfe284ed2d bench: improve context creation in ECDH benchmark 7321bdf27b doc: clarify API doc of `secp256k1_ecdsa_recover` return value b475654302 Merge bitcoin-core/secp256k1#1745: test: introduce group order byte-array constant for deduplication 0c91c56041 test: introduce group order byte-array constant for deduplication 88be4e8d86 Merge bitcoin-core/secp256k1#1735: musig: Invalidate secnonce in secp256k1_musig_partial_sign 36e76952cb Merge bitcoin-core/secp256k1#1738: check-abi: remove support for obsolete CMake library output location (src/libsecp256k1.so) 399b582a5f Split memclear into two versions 4985ac0f89 Merge bitcoin-core/secp256k1#1737: doc: mention ctx requirement for `_ellswift_create` (not secp256k1_context_static) 7ebaa134a7 check-abi: remove support for obsolete CMake library output location (src/libsecp256k1.so) 806de38bfc doc: mention ctx requirement for `_ellswift_create` (not secp256k1_context_static) 03fb60ad2e Merge bitcoin-core/secp256k1#1681: doc: Recommend clang-cl when building on Windows d93380fb35 Merge bitcoin-core/secp256k1#1731: schnorrsig: Securely clear buf containing k or its negation 8113671f80 Merge bitcoin-core/secp256k1#1729: hash: Use size_t instead of int for RFC6979 outlen copy 325d65a8cf Rename and clear var containing k or -k 960ba5f9c6 Use size_t instead of int for RFC6979 outlen copy 737912430d ci: Add more tests for clang-cl 7379a5bed3 doc: Recommend clang-cl when building on Windows f36afb8b3d Merge bitcoin-core/secp256k1#1725: tests: refactor tagged hash verification 5153cf1c91 tests: refactor tagged hash tests d2dcf52091 Merge bitcoin-core/secp256k1#1726: docs: fix broken link to Tromer's cache.pdf paper 489a43d1bf docs: fix broken link to eprint cache.pdf paper d599714147 Merge bitcoin-core/secp256k1#1722: docs: Exclude modules' `bench_impl.h` headers from coverage report 0458def51e doc: Add `--gcov-ignore-parse-errors=all` option to `gcovr` invocations 1aecce5936 doc: Add `--merge-mode-functions=separate` option to `gcovr` invocations 106a7cbf41 doc: Exclude modules' `bench_impl.h` headers from coverage report a9e955d3ea autotools, docs: Adjust help string for `--enable-coverage` option e523e4f90e Merge bitcoin-core/secp256k1#1720: chore(ci): Fix typo in Dockerfile comment 24ba8ff168 chore(ci): Fix typo in Dockerfile comment 74b8068c5d Merge bitcoin-core/secp256k1#1717: test: update wycheproof test vectors c25c3c8a88 test: update wycheproof test vectors 20e3b44746 Merge bitcoin-core/secp256k1#1688: cmake: Avoid contaminating parent project's cache with `BUILD_SHARED_LIBS` 2c076d907a Merge bitcoin-core/secp256k1#1711: tests: update Wycheproof 7b07b22957 cmake: Avoid contaminating parent project's cache with BUILD_SHARED_LIBS 5433648ca0 Fix typos and spellings 9ea54c69b7 tests: update Wycheproof files git-subtree-dir: src/secp256k1 git-subtree-split: a44a339384e1e4b1c0ed7fa59e2857b057f075bf
d543c0d917 Merge bitcoin-core/secp256k1#1734: Introduce (mini) unit test framework f44c1ebd96 Merge bitcoin-core/secp256k1#1719: ci: DRY workflow using anchors a44a339384 Merge bitcoin-core/secp256k1#1750: ci: Use clang-snapshot in "MSan" job 15d014804e ci: Drop default for `inputs.command` in `run-in-docker-action` 1decc49a1f ci: Use YAML anchor and aliases for repeated "CI script" steps dff1bc107d ci, refactor: Generalize use of `matrix.configuration.env_vars` 4b644da199 ci: Use YAML anchor and aliases for repeated "Print logs" steps a889cd93df ci: Bump `actions/checkout` version 574c2f3080 ci: Use YAML anchor and aliases for repeated "Checkout" steps 53585f93b7 ci: Use clang-snapshot in "MSan" job 6894c964f3 Fix Clang 21+ `-Wuninitialized-const-pointer` warning when using MSan 2b7337f63a Merge bitcoin-core/secp256k1#1756: ci: Fix image caching and apply other improvements f163c35897 ci: Set `DEBIAN_FRONTEND=noninteractive` 70ae177ca0 ci: Bump `docker/build-push-action` version b2a95a420f ci: Drop `tags` input for `docker/build-push-action` 122014edb3 ci: Add `scope` parameter to `cache-{to,from}` options 2f4546ce56 test: add --log option to display tests execution 95b9953ea4 test: Add option to display all available tests 953f7b0088 test: support running specific tests/modules targets 0302c1a3d7 test: add --help for command-line options 9ec3bfe22d test: adapt modules to the new test infrastructure 48789dafc2 test: introduce (mini) unit test framework baa265429f Merge bitcoin-core/secp256k1#1727: docs: Clarify that callback can be called more than once 4d90585fea docs: Improve API docs of _context_set_illegal_callback 895f53d1cf docs: Clarify that callback can be called more than once de6af6ae35 Merge bitcoin-core/secp256k1#1748: bench: improve context creation in ECDH benchmark 5817885153 Merge bitcoin-core/secp256k1#1749: build: Fix warnings in x86_64 assembly check ab560078aa build: Fix warnings in x86_64 assembly check 10dab907e7 Merge bitcoin-core/secp256k1#1741: doc: clarify API doc of `secp256k1_ecdsa_recover` return value dfe284ed2d bench: improve context creation in ECDH benchmark 7321bdf27b doc: clarify API doc of `secp256k1_ecdsa_recover` return value b475654302 Merge bitcoin-core/secp256k1#1745: test: introduce group order byte-array constant for deduplication 9cce703863 refactor: move 'gettime_i64()' to tests_common.h 0c91c56041 test: introduce group order byte-array constant for deduplication 88be4e8d86 Merge bitcoin-core/secp256k1#1735: musig: Invalidate secnonce in secp256k1_musig_partial_sign 36e76952cb Merge bitcoin-core/secp256k1#1738: check-abi: remove support for obsolete CMake library output location (src/libsecp256k1.so) 399b582a5f Split memclear into two versions 4985ac0f89 Merge bitcoin-core/secp256k1#1737: doc: mention ctx requirement for `_ellswift_create` (not secp256k1_context_static) 7ebaa134a7 check-abi: remove support for obsolete CMake library output location (src/libsecp256k1.so) 806de38bfc doc: mention ctx requirement for `_ellswift_create` (not secp256k1_context_static) 03fb60ad2e Merge bitcoin-core/secp256k1#1681: doc: Recommend clang-cl when building on Windows d93380fb35 Merge bitcoin-core/secp256k1#1731: schnorrsig: Securely clear buf containing k or its negation 8113671f80 Merge bitcoin-core/secp256k1#1729: hash: Use size_t instead of int for RFC6979 outlen copy 325d65a8cf Rename and clear var containing k or -k 960ba5f9c6 Use size_t instead of int for RFC6979 outlen copy 737912430d ci: Add more tests for clang-cl 7379a5bed3 doc: Recommend clang-cl when building on Windows f36afb8b3d Merge bitcoin-core/secp256k1#1725: tests: refactor tagged hash verification 5153cf1c91 tests: refactor tagged hash tests d2dcf52091 Merge bitcoin-core/secp256k1#1726: docs: fix broken link to Tromer's cache.pdf paper 489a43d1bf docs: fix broken link to eprint cache.pdf paper d599714147 Merge bitcoin-core/secp256k1#1722: docs: Exclude modules' `bench_impl.h` headers from coverage report 0458def51e doc: Add `--gcov-ignore-parse-errors=all` option to `gcovr` invocations 1aecce5936 doc: Add `--merge-mode-functions=separate` option to `gcovr` invocations 106a7cbf41 doc: Exclude modules' `bench_impl.h` headers from coverage report a9e955d3ea autotools, docs: Adjust help string for `--enable-coverage` option e523e4f90e Merge bitcoin-core/secp256k1#1720: chore(ci): Fix typo in Dockerfile comment 24ba8ff168 chore(ci): Fix typo in Dockerfile comment 74b8068c5d Merge bitcoin-core/secp256k1#1717: test: update wycheproof test vectors c25c3c8a88 test: update wycheproof test vectors 20e3b44746 Merge bitcoin-core/secp256k1#1688: cmake: Avoid contaminating parent project's cache with `BUILD_SHARED_LIBS` 2c076d907a Merge bitcoin-core/secp256k1#1711: tests: update Wycheproof 7b07b22957 cmake: Avoid contaminating parent project's cache with BUILD_SHARED_LIBS 5433648ca0 Fix typos and spellings 9ea54c69b7 tests: update Wycheproof files git-subtree-dir: src/secp256k1 git-subtree-split: d543c0d917a76a201578948701cc30ef336e0fe6
Replace
memset
which can still be optimized out assecnonce
isn't read later in this function. The API makes it clear the callee is responsible for it, so we need to assure it's cleared properly.