Assessment reports>Biconomy Secp256r1>High findings>Validity of public keys is not checked
Category: Coding Mistakes

Validity of public keys is not checked

High Severity
Medium Impact
Low Likelihood

Description

The Verify function does not check the validity of the public key passKey. To be valid, a public key needs to

  1. not be the point at infinity,

  2. have coordinates satisfying , and

  3. satisfy the equation modulo p.

The public key is only used after conversion to Jacobian coordinates in _preComputeJacobianPoints with JPoint(passKey.pubKeyX, passKey.pubKeyY, 1), which is never the point at infinity. The _affineFromJacobian function uses the convention that (0,0) in affine coordinates represents the point at infinity. So for this special case, conversion as JPoint(passKey.pubKeyX, passKey.pubKeyY, 1) would be incorrect. But given that the point at infinity is not a valid public key anyway, this is not an issue if instead the public key (0,0) is rejected by recognizing that (0,0) does not lie on the curve.

As x and y coordinates of passKey always get reduced modulo p in calculations, the missing check for property 2 means that Verify will in effect check the signature for the public key with coordinates (x % p, y % p). This means that for some public keys (x,y), where or , there exists another pair (x', y') --- for example, (x+p, y) --- that can be used as a public key and for which signatures made for (x,y) would also verify.

Finally, if the public key passed to Verify does not lie on the curve, then results returned by Verify do not have a meaningful interpretation.

Impact

Whether the possibility an attacker could generate two different keys for which the same signature is valid is a problem depends on how the caller uses public keys and signature verification.

This bug allows an attacker to generate public keys together with signatures that will be rejected by verification algorithms that validate the public key but will be accepted by Verify. The impact on the security of projects making use of the Secp256r1 library for signature verification is highly dependent on how signatures are otherwise used. See section ref for a discussion of this as well as the reason for our severity rating.

Recommendations

Ensure that (passKey.pubKeyX, passKey.pubKeyY) is a valid public key for the secp256r1 curve. One option is to check this in the Verify function. If this is instead ensured by callers to Verify, then one could alternatively document that Verify assumes validity of the public key and that the caller must ensure this.

Remediation

This issue has been acknowledged by Biconomy Labs, and fixes were implemented in the following commits:

Zellic © 2024Back to top ↑