Skip to content

Diffie-Hellman implementation causes key exchange to hang and consume CPU #191

Closed
@mzhurovich

Description

@mzhurovich

Hi,

We've recently faced an issue when our JRuby app started hanging and consuming CPU while trying to connect to SFTP server and exchange keys using diffie-hellman-group-exchange-sha256 algorithm. Here is the backtrace:

   java.lang.Thread.State: RUNNABLE
    at java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1227)
    at java.math.MutableBigInteger.divideKnuth(MutableBigInteger.java:1163)
    at java.math.MutableBigInteger.divide2n1n(MutableBigInteger.java:1316)
    at java.math.MutableBigInteger.divide3n2n(MutableBigInteger.java:1362)
    at java.math.MutableBigInteger.divide2n1n(MutableBigInteger.java:1330)
    at java.math.MutableBigInteger.divide3n2n(MutableBigInteger.java:1362)
    at java.math.MutableBigInteger.divide2n1n(MutableBigInteger.java:1326)
    at java.math.MutableBigInteger.divideAndRemainderBurnikelZiegler(MutableBigInteger.java:1293)
    at java.math.BigInteger.divideAndRemainderBurnikelZiegler(BigInteger.java:2293)
    at java.math.BigInteger.remainderBurnikelZiegler(BigInteger.java:2282)
    at java.math.BigInteger.remainder(BigInteger.java:2254)
    at java.math.BigInteger.mod(BigInteger.java:2561)
    at java.math.BigInteger.lucasLehmerSequence(BigInteger.java:982)
    at java.math.BigInteger.passesLucasLehmer(BigInteger.java:912)
    at java.math.BigInteger.primeToCertainty(BigInteger.java:892)
    at java.math.BitSieve.retrieve(BitSieve.java:203)
    at java.math.BigInteger.largePrime(BigInteger.java:761)
    at java.math.BigInteger.<init>(BigInteger.java:667)
    at org.jruby.ext.openssl.PKeyDH.generateX(PKeyDH.java:220)
    at org.jruby.ext.openssl.PKeyDH.generateX(PKeyDH.java:228)
    at org.jruby.ext.openssl.PKeyDH.generate_key(PKeyDH.java:246)

IIUC, it happens because current implementation tries to generate not just a random number, but a prime random number:

        // adapting algorithm from org.bouncycastle.crypto.generators.DHKeyGeneratorHelper,
        // which seems a little stronger (?) than OpenSSL's (OSSL just generates a random,
        // while BC generates a random potential prime [for limit > 0], though it's not
        // subject to Miller-Rabin [certainty = 0], but is subject to other constraints)
        // see also [ossl]/crypto/dh/dh_key.c #generate_key

I'm not a cryptography expert, but maybe it's worth to make it closer to OSSL implementation and not try generating prime here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions