OpenSSL's optimized SM2 scalar multiplication in ecp_sm2p256.c has
data-dependent branches on the secret scalar, unlike the equivalent
P-256 code (ecp_nistz256.c) in the same codebase.

The function ecp_sm2p256_point_P_mul_by_scalar() processes the 256-bit
scalar in 4-bit nibble windows. When a nibble is zero, point_add is
skipped entirely:

    for (i = 63; i >= 0; --i) {
        index = (k[i / 16] >> (4 * (i % 16))) & 0x0f;
        // ...
        if (index)
            ecp_sm2p256_point_add(R, R, &precomputed[index]);
    }

This is called during SM2 decryption (sm2_crypt.c:360) with the static
private key d as the scalar. A second function (point_G_mul_by_scalar)
has the same pattern with 8-bit byte windows for SM2 signing
(sm2_sign.c:295), where the scalar is the ephemeral nonce k.

AFFECTED PLATFORMS: ARM64 measured. The optimized ARM64 path is present
in OpenSSL 3.2.0 through 3.6.1 and current master. RISC-V compiles the
same source path on current master, confirmed by code inspection only.
x86_64 does not compile this optimized ecp_sm2p256 path.

MEASURED EVIDENCE (ARM64 Neoverse-N1):
- Direct EC_POINT_mul: r = -0.9828, slope = -389 ns/zero nibble
  (100 crafted keys, Fisher-Yates shuffled)
- Full SM2 decrypt (EVP_PKEY_decrypt): r = -0.9752 (shuffled crafted
  keys), r = -0.9829 (random keygen keys)
- Blind zero-nibble-count inference: 80% within +/-2 nibbles
  (40 keys, attacker has no key access)
- x86_64 control: optimized symbol absent, no comparable signal
  (r = 0.152)

INFORMATION LEAKAGE: The timing allows estimating the zero-nibble count
of the private key. That count has about 3 bits of entropy for a random
256-bit scalar (B(64, 1/16)). Full key recovery from this timing
signal alone has not
been demonstrated. The same non-constant-time control flow may also be
relevant to local cache side channels; this report demonstrates only
timing leakage.

CVE-2025-9231 fixed a timing issue in modular inversion in the same
file. The scalar multiplication loop was not modified as part of that
fix.

CONTEXT: SM2 is used in Chinese commercial-cryptography deployments;
the affected optimized path targets ARM64 and RISC-V.

DISCLOSURE:
- 2026-05-02: Reported to [email protected] with full
  evidence (correlation data, 4 independent PoCs, negative controls)
- 2026-05-06: OpenSSL response: handle as regular bug/hardening, no
  CVE. Asked for a public GitHub issue.

Full write-up:
https://abhinavagarwal07.github.io/posts/openssl-sm2-timing/?utm_campaign=openssl&src=oss

GitHub issue:
https://github.com/openssl/openssl/issues/31133

Evidence artifacts (PoC source, tarballs, transcripts) available on
request.

-- Abhinav Agarwal

Reply via email to