From 04680a67cd904abcb4c0e4332d59d763d45d4c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Obernd=C3=B6rfer?= Date: Fri, 21 Mar 2014 16:45:19 +0100 Subject: [PATCH] OP-01-020 Missing check in DSA signature generation (Medium). Add check and repeat until r and s not equal to 0. --- src/crypto/public_key/dsa.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index 29190daa..c98bfee4 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -42,9 +42,20 @@ function DSA() { // directly in the DSA signature algorithm. var hashed_data = util.getLeftNBits(hashModule.digest(hashalgo, m), q.bitLength()); var hash = new BigInteger(util.hexstrdump(hashed_data), 16); - var k = random.getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); - var s1 = (g.modPow(k, p)).mod(q); - var s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); + // FIPS-186-4, section 4.6: + // The values of r and s shall be checked to determine if r = 0 or s = 0. + // If either r = 0 or s = 0, a new value of k shall be generated, and the + // signature shall be recalculated. It is extremely unlikely that r = 0 + // or s = 0 if signatures are generated properly. + var k, s1, s2; + while (true) { + k = random.getRandomBigIntegerInRange(BigInteger.ONE.add(BigInteger.ONE), q.subtract(BigInteger.ONE)); + s1 = (g.modPow(k, p)).mod(q); + s2 = (k.modInverse(q).multiply(hash.add(x.multiply(s1)))).mod(q); + if (s1 != 0 && s2 != 0) { + break; + } + } var result = []; result[0] = s1.toMPI(); result[1] = s2.toMPI();