parseOpenSSHPrivateKey builds an rsa.PrivateKey directly from the
unmarshalled OpenSSH key blob, bypassing parseRSA and its modulus
limit. Validate() and Precompute() then perform several modular
exponentiations whose cost grows with the size of the prime factors;
in particular Precompute() recomputes the CRT coefficient as
q^(p-2) mod p, which is cubic in |p|. A maliciously crafted key with
oversized N and P can keep the CPU busy for hours or days during a
single load.
Mirror the parseRSA validation here: cap the modulus at 8192 bits
(the same limit enforced by crypto/tls), reject exponents larger than
24 bits, and reject invalid exponent values (< 3 or even). In addition,
bound each prime factor at 4096 bits to prevent the CRT computation
from becoming the dominant cost.
This issue was found during a security audit by NCC Group Cryptography
Services, sponsored by Teleport, and was assessed and is being fixed as
a non-security bug.
Change-Id: Ia5991f25dd41a22eddd7cf63a8fc5106de9e9663
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/782420
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>