From 377a6f0d2bf1c01cd297c491998245056b8ebff7 Mon Sep 17 00:00:00 2001 From: David Hook Date: Wed, 23 Mar 2022 14:26:36 +1100 Subject: added RSA/EC checks --- crypto/src/asn1/anssi/ANSSINamedCurves.cs | 2 +- crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs | 16 ++--- crypto/src/asn1/gm/GMNamedCurves.cs | 4 +- crypto/src/asn1/sec/SECNamedCurves.cs | 30 ++++---- crypto/src/asn1/x9/X962NamedCurves.cs | 14 ++-- crypto/src/crypto/parameters/RsaKeyParameters.cs | 21 ++++++ crypto/src/math/ec/ECCurve.cs | 82 +++++++++++++++++++++- 7 files changed, 135 insertions(+), 34 deletions(-) diff --git a/crypto/src/asn1/anssi/ANSSINamedCurves.cs b/crypto/src/asn1/anssi/ANSSINamedCurves.cs index 48017fc2a..3a9e4dd03 100644 --- a/crypto/src/asn1/anssi/ANSSINamedCurves.cs +++ b/crypto/src/asn1/anssi/ANSSINamedCurves.cs @@ -48,7 +48,7 @@ namespace Org.BouncyCastle.Asn1.Anssi BigInteger n = FromHex("F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs index 121843ada..5ac8cadfe 100644 --- a/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs +++ b/crypto/src/asn1/cryptopro/ECGOST3410NamedCurves.cs @@ -58,7 +58,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94"), FromHex("A6"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("8000000000000000000000000000000000000000000000000000000000000C96"), FromHex("3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -128,7 +128,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598"), FromHex("805A"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -163,7 +163,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598"), FromHex("805A"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -198,7 +198,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("C2173F1513981673AF4892C23035A27CE25E2013BF95AA33B22C656F277E7335"), FromHex("295F9BAE7428ED9CCC20E7C359A9D41A22FCCD9108E17BF7BA9337A6F8AE9513"), - mod_q, BigInteger.Four)); + mod_q, BigInteger.Four, true)); } protected override X9ECParameters CreateParameters() @@ -233,7 +233,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4"), FromHex("E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -268,7 +268,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006C"), FromHex("687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116"), - mod_q, BigInteger.One)); + mod_q, BigInteger.One, true)); } protected override X9ECParameters CreateParameters() @@ -303,7 +303,7 @@ namespace Org.BouncyCastle.Asn1.CryptoPro mod_p, FromHex("DC9203E514A721875485A529D2C722FB187BC8980EB866644DE41C68E143064546E861C0E2C9EDD92ADE71F46FCF50FF2AD97F951FDA9F2A2EB6546F39689BD3"), FromHex("B4C4EE28CEBC6C2C8AC12952CF37F16AC7EFB6A9F69F4B57FFDA2E4F0DE5ADE038CBC2FFF719D2C18DE0284B8BFEF3B52B8CC7A5F5BF0A3C8D2319A5312557E1"), - mod_q, BigInteger.Four)); + mod_q, BigInteger.Four, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/asn1/gm/GMNamedCurves.cs b/crypto/src/asn1/gm/GMNamedCurves.cs index 9cb2cef14..f906a2b95 100644 --- a/crypto/src/asn1/gm/GMNamedCurves.cs +++ b/crypto/src/asn1/gm/GMNamedCurves.cs @@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Asn1.GM BigInteger n = FromHex("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Asn1.GM BigInteger n = FromHex("BDB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F56564677"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/asn1/sec/SECNamedCurves.cs b/crypto/src/asn1/sec/SECNamedCurves.cs index 68e9b7eca..ad2f3e333 100644 --- a/crypto/src/asn1/sec/SECNamedCurves.cs +++ b/crypto/src/asn1/sec/SECNamedCurves.cs @@ -60,7 +60,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("DB7C2ABF62E35E7628DFAC6561C5"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -94,7 +94,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("36DF0AAFD8B8D7597CA10520D04B"); BigInteger h = BigInteger.ValueOf(4); - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -128,7 +128,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("FFFFFFFE0000000075A30D1B9038A115"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -162,7 +162,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3"); BigInteger h = BigInteger.ValueOf(4); - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -210,7 +210,7 @@ namespace Org.BouncyCastle.Asn1.Sec new BigInteger("96341f1138933bc2f503fd44", 16), 176)); - return ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv); } protected override X9ECParameters CreateParameters() @@ -244,7 +244,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("0100000000000000000001F4C8F927AED3CA752257"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -278,7 +278,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("0100000000000000000000351EE786A818F3A1A16B"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -326,7 +326,7 @@ namespace Org.BouncyCastle.Asn1.Sec new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16), 208)); - return ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv); } protected override X9ECParameters CreateParameters() @@ -360,7 +360,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -408,7 +408,7 @@ namespace Org.BouncyCastle.Asn1.Sec new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16), 240)); - return ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv); } protected override X9ECParameters CreateParameters() @@ -442,7 +442,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -490,7 +490,7 @@ namespace Org.BouncyCastle.Asn1.Sec new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16), 272)); - return ConfigureCurveGlv(new FpCurve(p, a, b, n, h), glv); + return ConfigureCurveGlv(new FpCurve(p, a, b, n, h, true), glv); } protected override X9ECParameters CreateParameters() @@ -524,7 +524,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -558,7 +558,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() @@ -593,7 +593,7 @@ namespace Org.BouncyCastle.Asn1.Sec BigInteger n = FromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); BigInteger h = BigInteger.One; - return ConfigureCurve(new FpCurve(p, a, b, n, h)); + return ConfigureCurve(new FpCurve(p, a, b, n, h, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/asn1/x9/X962NamedCurves.cs b/crypto/src/asn1/x9/X962NamedCurves.cs index 04f3d335a..4fd3c8d1e 100644 --- a/crypto/src/asn1/x9/X962NamedCurves.cs +++ b/crypto/src/asn1/x9/X962NamedCurves.cs @@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Asn1.X9 FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), FromHex("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Asn1.X9 FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), FromHex("cc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Asn1.X9 FromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"), FromHex("fffffffffffffffffffffffffffffffefffffffffffffffc"), FromHex("22123dc2395a05caa7423daeccc94760a7d462256bd56916"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -145,7 +145,7 @@ namespace Org.BouncyCastle.Asn1.X9 new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), FromHex("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -176,7 +176,7 @@ namespace Org.BouncyCastle.Asn1.X9 new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), FromHex("617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -207,7 +207,7 @@ namespace Org.BouncyCastle.Asn1.X9 new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), FromHex("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc"), FromHex("255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() @@ -238,7 +238,7 @@ namespace Org.BouncyCastle.Asn1.X9 new BigInteger("115792089210356248762697446949407573530086143415290314195533631308867097853951"), FromHex("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc"), FromHex("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"), - n, h)); + n, h, true)); } protected override X9ECParameters CreateParameters() diff --git a/crypto/src/crypto/parameters/RsaKeyParameters.cs b/crypto/src/crypto/parameters/RsaKeyParameters.cs index 48ea0ab5b..b1e1a8edf 100644 --- a/crypto/src/crypto/parameters/RsaKeyParameters.cs +++ b/crypto/src/crypto/parameters/RsaKeyParameters.cs @@ -2,6 +2,7 @@ using System; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; +using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Crypto.Parameters { @@ -23,6 +24,14 @@ namespace Org.BouncyCastle.Crypto.Parameters if (!modulus.Gcd(SmallPrimesProduct).Equals(BigInteger.One)) throw new ArgumentException("RSA modulus has a small prime factor"); + int maxBitLength = AsInteger("Org.BouncyCastle.Rsa.MaxSize", 15360); + + int modBitLength = modulus.BitLength; + if (maxBitLength < modBitLength) + { + throw new ArgumentException("modulus value out of range"); + } + // TODO: add additional primePower/Composite test - expensive!! return modulus; @@ -81,5 +90,17 @@ namespace Org.BouncyCastle.Crypto.Parameters { return modulus.GetHashCode() ^ exponent.GetHashCode() ^ IsPrivate.GetHashCode(); } + + int AsInteger(string envVariable, int defaultValue) + { + String v = Platform.GetEnvironmentVariable(envVariable); + + if (v == null) + { + return defaultValue; + } + + return Int32.Parse(v); + } } } diff --git a/crypto/src/math/ec/ECCurve.cs b/crypto/src/math/ec/ECCurve.cs index f011b1baf..2b193ba06 100644 --- a/crypto/src/math/ec/ECCurve.cs +++ b/crypto/src/math/ec/ECCurve.cs @@ -677,6 +677,9 @@ namespace Org.BouncyCastle.Math.EC { private const int FP_DEFAULT_COORDS = COORD_JACOBIAN_MODIFIED; + private static readonly IDictionary knownQs = Platform.CreateHashtable(); + private static readonly SecureRandom random = new SecureRandom(); + protected readonly BigInteger m_q, m_r; protected readonly FpPoint m_infinity; @@ -687,9 +690,42 @@ namespace Org.BouncyCastle.Math.EC } public FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor) + : this(q, a, b, order, cofactor, false) + { + } + + internal FpCurve(BigInteger q, BigInteger a, BigInteger b, BigInteger order, BigInteger cofactor, bool isInternal) : base(q) { - this.m_q = q; + if (isInternal) + { + this.m_q = q; + knownQs.add(q); + } + else if (knownQs.contains(q)) + { + this.m_q = q; + } + else + { + int maxBitLength = AsInteger("Org.BouncyCastle.EC.Fp_MaxSize", 1042); // 2 * 521 + int certainty = AsInteger("Org.BouncyCastle.EC.Fp_Certainty", 100); + + int qBitLength = q.BitLength; + if (maxBitLength < qBitLength) + { + throw new ArgumentException("Fp q value out of range"); + } + + if (Primes.HasAnySmallFactors(q) || !Primes.IsMRProbablePrime( + q, random, getNumberOfIterations(qBitLength, certainty))) + { + throw new ArgumentException("Fp q value not prime"); + } + + this.m_q = q; + } + this.m_r = FpFieldElement.CalculateResidue(q); this.m_infinity = new FpPoint(this, null, null, false); @@ -790,6 +826,50 @@ namespace Org.BouncyCastle.Math.EC return base.ImportPoint(p); } + + private int GetNumberOfIterations(int bits, int certainty) + { + /* + * NOTE: We enforce a minimum 'certainty' of 100 for bits >= 1024 (else 80). Where the + * certainty is higher than the FIPS 186-4 tables (C.2/C.3) cater to, extra iterations + * are added at the "worst case rate" for the excess. + */ + if (bits >= 1536) + { + return certainty <= 100 ? 3 + : certainty <= 128 ? 4 + : 4 + (certainty - 128 + 1) / 2; + } + else if (bits >= 1024) + { + return certainty <= 100 ? 4 + : certainty <= 112 ? 5 + : 5 + (certainty - 112 + 1) / 2; + } + else if (bits >= 512) + { + return certainty <= 80 ? 5 + : certainty <= 100 ? 7 + : 7 + (certainty - 100 + 1) / 2; + } + else + { + return certainty <= 80 ? 40 + : 40 + (certainty - 80 + 1) / 2; + } + } + + int AsInteger(string envVariable, int defaultValue) + { + String v = Platform.GetEnvironmentVariable(envVariable); + + if (v == null) + { + return defaultValue; + } + + return Int32.Parse(v); + } } public abstract class AbstractF2mCurve -- cgit 1.4.1