andyperlitch / jsbn

The jsbn library is a fast, portable implementation of large-number math in pure JavaScript, enabling public-key crypto and other applications on desktop and mobile browsers.
Other
166 stars 41 forks source link

Cryptographic Side-Channels (Timing Leaks) in JSBN #43

Open soatok opened 2 years ago

soatok commented 2 years ago

Issue Summary

JSBN contains a lot of timing leaks that make it unsuitable for cryptographic use. However, JSBN is broadly used in JavaScript implementations of asymmetric cryptography.

Modular Exponentiation

JSBN's implementation of modular exponentiation can be found here. The critical loop of this implementation can be found here. For odd moduli larger than 255 (a.k.a. any cryptographic usage), Montgomery reduction is used.

Interestingly, the base (called g in the critical loop) is never directly leaked in this loop, which would superficially make it only safe for RSA encryption.

(However, values derived directly from the base are passed as parameters to mulTo(), which passes to the Montgomery reduction functions linked above. At minimum, this leaks via comparison.)

Modular Inversion

JSBN's implementation of modular inversion can be found here.

Bignum Comparison

The implementation of compareTo() can be found here. I've reproduced the algorithm below, but reformatted it to be more legible.

// (public) return + if this > a, - if this < a, 0 if equal
function bnCompareTo(a) {
    var r = this.s - a.s;
    if (r != 0) {
        return r;
    }
    var i = this.t;
    r = i - a.t;
    if (r != 0) {
        return this.s < 0 ? -r : r;
    }
    while (--i >= 0) {
        if ((r = this[i] - a[i]) != 0) {
            return r;
        }
    }
    return 0;
}

It should be clear that this will return a value quicker if the first limb differs between this and a than if a later limb differs. This function leaks information about the two numbers being compared.

Exploitation and Impact

Timing leaks are pernicious to cryptographic implementations. A cache-timing attack on software AES famously revealed the secret key in an attack that took about 65 milliseconds to conclude.

The main exploitation path for a library like JSBN is to have malicious code running in another browser window or service worker that probes the JavaScript engine (i.e. v8 in Chrome) to perform this sort of timing attack. For prior art, see Rowhammer, Meltdown, and Spectre.

If successful, this will leak the following for the respective asymmetric cryptography algorithms.

Algorithm / Operation What Gets Leaked
RSA encryption Message (base in exponentiation)
RSA signing Private key (exponent)
Diffie-Hellman Private key (exponent)
SRP Private key (exponent x)
ECDSA signing One-time secret k (via modular inverse)

Mitigations

The only effective mitigation is to make the JSBN code constant-time. I've previously written an open source constant-time implementation of bignum arithmetic in TypeScript (which can be trivially compiled to JavaScript).

My code uses constant-time conditional swaps instead of branches and peasant multiplication (which side-steps variable time multiplication opcodes on some architectures). It also avoids touching the high bit of JavaScript numbers, which the v8 engine uses to store a flag and would create a memory access timing leak.

This can serve as a reference implementation for recommending patch strategies to JSBN.

Disclosure Timeline

krishnaUIDev commented 2 years ago

Any update on this issue? I am looking alternative ways to fix this issue.

soatok commented 2 weeks ago

Well, it's been more than two years. I'm guessing @andyperlitch won't be fixing it?