Make OPENSSL_memcmp call CRYPTO_memcmp for constant-time comparison#3183
Draft
WillChilds-Klein wants to merge 2 commits into
Draft
Make OPENSSL_memcmp call CRYPTO_memcmp for constant-time comparison#3183WillChilds-Klein wants to merge 2 commits into
WillChilds-Klein wants to merge 2 commits into
Conversation
9d735ec to
07c2a2e
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3183 +/- ##
==========================================
- Coverage 78.12% 78.00% -0.12%
==========================================
Files 689 689
Lines 123717 122651 -1066
Branches 17085 17074 -11
==========================================
- Hits 96652 95673 -979
+ Misses 26167 26080 -87
Partials 898 898 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OPENSSL_memcmpincrypto/internal.hto delegate toCRYPTO_memcmpinstead of libcmemcmp, providing constant-time comparison semanticsOPENSSL_memcmp_ordered— a NULL-safememcmpwrapper that preserves ordering semantics (negative/zero/positive) for call sites that require itOPENSSL_memcmptoOPENSSL_memcmp_orderedOPENSSL_memcmpcall sites against timing side-channel attacks while preserving correctness for sort comparators and structured comparisonsChanged files
crypto/internal.hOPENSSL_memcmpnow callsCRYPTO_memcmp; newOPENSSL_memcmp_orderedwrapper addedcrypto/asn1/tasn_enc.cder_cmp→OPENSSL_memcmp_ordered(qsort comparator for DER SET OF)crypto/asn1/asn1_lib.cASN1_STRING_cmp→OPENSSL_memcmp_ordered(string ordering)crypto/obj/obj.cOBJ_cmp→OPENSSL_memcmp_ordered(OID ordering)crypto/bytestring/cbb.ccompare_set_of_element→OPENSSL_memcmp_ordered(qsort for DER SET OF)crypto/x509/x509_cmp.cX509_cmp,X509_NAME_cmp→OPENSSL_memcmp_ordered(cert/name ordering)crypto/pool/pool.cCRYPTO_BUFFER_cmp→OPENSSL_memcmp_ordered(buffer comparison)Performance Benchmark Report
Benchmarks were run on the same machine (macOS/ARM64, Release build) before and after the
OPENSSL_memcmp→CRYPTO_memcmpchange, with multiple iterations to reduce noise. The benchmark suite isbssl speed.Methodology
memcmp)OPENSSL_memcmpcallingCRYPTO_memcmpECDSA Benchmarks (5 iterations each)
These are the most relevant benchmarks since ECDSA verification calls
OPENSSL_memcmpin thecmp_x_coordinateand DER roundtrip code paths.RSA / Ed25519 / X25519 Benchmarks (5 iterations each)
Full Benchmark Suite Summary (633 benchmarks, single pass)
Interpretation
No statistically significant performance impact detected. The observed differences across all benchmarks are within the expected range of run-to-run variance on a laptop:
OPENSSL_memcmp(ECDSA verify, RSA verify) show no consistent directional changeOPENSSL_memcmp(signing, key generation) show similar magnitude variance, confirming this is measurement noiseThe
CRYPTO_memcmpfunction is a simple XOR-accumulate loop over the input bytes — the same asymptotic cost asmemcmp, just without early-exit optimization. For the small buffer sizes compared at these call sites (typically 32-64 bytes for hashes, or a few hundred bytes for DER encodings), the difference between early-exit and full-scan comparison is negligible.Ordering Semantics
CRYPTO_memcmpreturns 0 (equal) or non-zero (not equal) — it does not provide ordering (negative/positive). SevenOPENSSL_memcmpcall sites depend on ordering semantics for sort comparators and structured comparisons. These have been migrated toOPENSSL_memcmp_ordered, a new NULL-safememcmpwrapper that preserves ordering and is explicitly not constant-time.All 7 migrated sites compare only public, non-secret data where constant-time behavior is unnecessary:
crypto/asn1/tasn_enc.c:373der_cmpcrypto/asn1/asn1_lib.c:353ASN1_STRING_cmpcrypto/obj/obj.c:118OBJ_cmpcrypto/bytestring/cbb.c:653compare_set_of_elementcrypto/x509/x509_cmp.c:86X509_cmpcrypto/x509/x509_cmp.c:114X509_NAME_cmpcrypto/pool/pool.c:30CRYPTO_BUFFER_cmpBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.