8288508: Enhance ECDSA usage

Reviewed-by: ascarpino, ahgross, rhalade
This commit is contained in:
Weijun Wang 2022-07-11 18:35:50 +00:00 committed by Henry Jen
parent 40539de8da
commit 1ae6836521
3 changed files with 74 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -347,5 +347,40 @@ public final class ECUtil {
return prv;
}
// Partial Public key validation as described in NIST SP 800-186 Appendix D.1.1.1.
// The extra step in the full validation (described in Appendix D.1.1.2) is implemented
// as sun.security.ec.ECOperations#checkOrder inside the jdk.crypto.ec module.
public static void validatePublicKey(ECPoint point, ECParameterSpec spec)
throws InvalidKeyException {
BigInteger p;
if (spec.getCurve().getField() instanceof ECFieldFp f) {
p = f.getP();
} else {
throw new InvalidKeyException("Only curves over prime fields are supported");
}
// 1. If Q is the point at infinity, output REJECT
if (point.equals(ECPoint.POINT_INFINITY)) {
throw new InvalidKeyException("Public point is at infinity");
}
// 2. Verify that x and y are integers in the interval [0, p-1]. Output REJECT if verification fails.
BigInteger x = point.getAffineX();
if (x.signum() < 0 || x.compareTo(p) >= 0) {
throw new InvalidKeyException("Public point x is not in the interval [0, p-1]");
}
BigInteger y = point.getAffineY();
if (y.signum() < 0 || y.compareTo(p) >= 0) {
throw new InvalidKeyException("Public point y is not in the interval [0, p-1]");
}
// 3. Verify that (x, y) is a point on the W_a,b by checking that (x, y) satisfies the defining
// equation y^2 = x^3 + a x + b where computations are carried out in GF(p). Output REJECT
// if verification fails.
BigInteger left = y.modPow(BigInteger.TWO, p);
BigInteger right = x.pow(3).add(spec.getCurve().getA().multiply(x)).add(spec.getCurve().getB()).mod(p);
if (!left.equals(right)) {
throw new InvalidKeyException("Public point is not on the curve");
}
}
private ECUtil() {}
}