diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-10-06 16:44:01 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2018-10-06 16:44:01 +0700 |
commit | f5078e451501d43882308d8322b9c8863e2a2723 (patch) | |
tree | 6fe93ae3363b7a7492e099a363286fee29bc8115 | |
parent | Fix initialization checks (diff) | |
download | BouncyCastle.NET-ed25519-f5078e451501d43882308d8322b9c8863e2a2723.tar.xz |
RFC 7748: Exclude all-zeroes agreement value
-rw-r--r-- | crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs | 3 | ||||
-rw-r--r-- | crypto/src/crypto/parameters/X448PrivateKeyParameters.cs | 3 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X25519.cs | 8 | ||||
-rw-r--r-- | crypto/src/math/ec/rfc7748/X448.cs | 8 | ||||
-rw-r--r-- | crypto/src/util/Arrays.cs | 10 |
5 files changed, 30 insertions, 2 deletions
diff --git a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs index c25ab9364..fb49a02b3 100644 --- a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs @@ -56,7 +56,8 @@ namespace Org.BouncyCastle.Crypto.Parameters { byte[] encoded = new byte[X25519.PointSize]; publicKey.Encode(encoded, 0); - X25519.ScalarMult(data, 0, encoded, 0, buf, off); + if (!X25519.CalculateAgreement(data, 0, encoded, 0, buf, off)) + throw new InvalidOperationException("X25519 agreement failed"); } } } diff --git a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs index 291eac10f..d17aa7947 100644 --- a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs @@ -56,7 +56,8 @@ namespace Org.BouncyCastle.Crypto.Parameters { byte[] encoded = new byte[X448.PointSize]; publicKey.Encode(encoded, 0); - X448.ScalarMult(data, 0, encoded, 0, buf, off); + if (!X448.CalculateAgreement(data, 0, encoded, 0, buf, off)) + throw new InvalidOperationException("X448 agreement failed"); } } } diff --git a/crypto/src/math/ec/rfc7748/X25519.cs b/crypto/src/math/ec/rfc7748/X25519.cs index d63cc5a3e..6b6acdecd 100644 --- a/crypto/src/math/ec/rfc7748/X25519.cs +++ b/crypto/src/math/ec/rfc7748/X25519.cs @@ -2,6 +2,8 @@ using System.Diagnostics; using System.Runtime.CompilerServices; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Math.EC.Rfc7748 { public abstract class X25519 @@ -21,6 +23,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private static int[] precompBase = null; + public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + ScalarMult(k, kOff, u, uOff, r, rOff); + return !Arrays.AreAllZeroes(r, rOff, PointSize); + } + private static uint Decode32(byte[] bs, int off) { uint n = bs[off]; diff --git a/crypto/src/math/ec/rfc7748/X448.cs b/crypto/src/math/ec/rfc7748/X448.cs index aac603b08..b93cb24c5 100644 --- a/crypto/src/math/ec/rfc7748/X448.cs +++ b/crypto/src/math/ec/rfc7748/X448.cs @@ -2,6 +2,8 @@ using System.Diagnostics; using System.Runtime.CompilerServices; +using Org.BouncyCastle.Utilities; + namespace Org.BouncyCastle.Math.EC.Rfc7748 { public abstract class X448 @@ -24,6 +26,12 @@ namespace Org.BouncyCastle.Math.EC.Rfc7748 private static uint[] precompBase = null; + public static bool CalculateAgreement(byte[] k, int kOff, byte[] u, int uOff, byte[] r, int rOff) + { + ScalarMult(k, kOff, u, uOff, r, rOff); + return !Arrays.AreAllZeroes(r, rOff, PointSize); + } + private static uint Decode32(byte[] bs, int off) { uint n = bs[off]; diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs index 3df908240..a9a574dbf 100644 --- a/crypto/src/util/Arrays.cs +++ b/crypto/src/util/Arrays.cs @@ -11,6 +11,16 @@ namespace Org.BouncyCastle.Utilities public static readonly byte[] EmptyBytes = new byte[0]; public static readonly int[] EmptyInts = new int[0]; + public static bool AreAllZeroes(byte[] buf, int off, int len) + { + uint bits = 0; + for (int i = 0; i < len; ++i) + { + bits |= buf[off + i]; + } + return bits == 0; + } + public static bool AreEqual( bool[] a, bool[] b) |