Validate output point when calling P256.pointFromBinary

Function unsafePointFromBinary is added when validation is not needed.
This commit is contained in:
Olivier Chéron 2017-06-25 17:11:45 +02:00
parent 099f3405cb
commit 8e274f8e60
3 changed files with 14 additions and 9 deletions

View File

@ -118,7 +118,7 @@ instance EllipticCurve Curve_P256R1 where
Nothing -> CryptoFailed $ CryptoError_PointSizeInvalid
Just (m,xy)
-- uncompressed
| m == 4 -> P256.pointFromBinary xy >>= validateP256Point
| m == 4 -> P256.pointFromBinary xy
| otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid
instance EllipticCurveArith Curve_P256R1 where
@ -210,11 +210,6 @@ instance EllipticCurveDH Curve_X448 where
ecdh _ s p = SharedSecret $ convert secret
where secret = X448.dh p s
validateP256Point :: P256.Point -> CryptoFailable P256.Point
validateP256Point p
| P256.pointIsValid p = CryptoPassed p
| otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid
encodeECPoint :: forall curve bs . (Simple.Curve curve, ByteArray bs) => Simple.Point curve -> bs
encodeECPoint Simple.PointO = error "encodeECPoint: cannot serialize point at infinity"
encodeECPoint (Simple.Point x y) = B.concat [uncompressed,xb,yb]

View File

@ -26,6 +26,7 @@ module Crypto.PubKey.ECC.P256
, pointFromIntegers
, pointToBinary
, pointFromBinary
, unsafePointFromBinary
-- * scalar arithmetic
, scalarGenerate
, scalarZero
@ -172,9 +173,18 @@ pointToBinary p = B.unsafeCreate pointSize $ \dst -> withPoint p $ \px py -> do
ccryptonite_p256_to_bin (castPtr px) dst
ccryptonite_p256_to_bin (castPtr py) (dst `plusPtr` 32)
-- | Convert from binary to a point
-- | Convert from binary to a valid point
pointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point
pointFromBinary ba
pointFromBinary ba = unsafePointFromBinary ba >>= validatePoint
where
validatePoint :: Point -> CryptoFailable Point
validatePoint p
| pointIsValid p = CryptoPassed p
| otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid
-- | Convert from binary to a point, possibly invalid
unsafePointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point
unsafePointFromBinary ba
| B.length ba /= pointSize = CryptoFailed $ CryptoError_PublicKeySizeInvalid
| otherwise =
CryptoPassed $ withNewPoint $ \px py -> B.withByteArray ba $ \src -> do

View File

@ -97,7 +97,7 @@ tests = testGroup "P256"
[ testProperty "marshalling" $ \rx ry ->
let p = P256.pointFromIntegers (unP256 rx, unP256 ry)
b = P256.pointToBinary p :: Bytes
p' = P256.pointFromBinary b
p' = P256.unsafePointFromBinary b
in propertyHold [ eqTest "point" (CryptoPassed p) p' ]
, testProperty "marshalling-integer" $ \rx ry ->
let p = P256.pointFromIntegers (unP256 rx, unP256 ry)