Skip to content

Commit 58940b9

Browse files
committed
added constraints check to SM2Engine.
1 parent 204326e commit 58940b9

File tree

3 files changed

+128
-1
lines changed

3 files changed

+128
-1
lines changed

core/src/main/java/org/bouncycastle/crypto/engines/SM2Engine.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
import java.security.SecureRandom;
55

66
import org.bouncycastle.crypto.CipherParameters;
7+
import org.bouncycastle.crypto.CryptoServicesRegistrar;
8+
import org.bouncycastle.crypto.DataLengthException;
79
import org.bouncycastle.crypto.Digest;
810
import org.bouncycastle.crypto.InvalidCipherTextException;
11+
import org.bouncycastle.crypto.constraints.ConstraintUtils;
12+
import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
913
import org.bouncycastle.crypto.digests.SM3Digest;
1014
import org.bouncycastle.crypto.params.ECDomainParameters;
1115
import org.bouncycastle.crypto.params.ECKeyParameters;
@@ -91,6 +95,8 @@ public void init(boolean forEncryption, CipherParameters param)
9195
}
9296

9397
curveLength = (ecParams.getCurve().getFieldSize() + 7) / 8;
98+
99+
CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("SM2", ConstraintUtils.bitsOfSecurityFor(ecParams.getCurve()), ecKey, Utils.getPurpose(forEncryption)));
94100
}
95101

96102
public byte[] processBlock(
@@ -99,6 +105,11 @@ public byte[] processBlock(
99105
int inLen)
100106
throws InvalidCipherTextException
101107
{
108+
if ((inOff + inLen) > in.length || inLen == 0)
109+
{
110+
throw new DataLengthException("input buffer too short");
111+
}
112+
102113
if (forEncryption)
103114
{
104115
return encrypt(in, inOff, inLen);

core/src/test/java/org/bouncycastle/crypto/test/CryptoServiceConstraintsTest.java

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.security.SecureRandom;
55
import java.util.Collections;
66

7+
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
78
import org.bouncycastle.asn1.x9.X962NamedCurves;
89
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
910
import org.bouncycastle.crypto.BasicAgreement;
@@ -44,7 +45,40 @@
4445
import org.bouncycastle.crypto.digests.SHA3Digest;
4546
import org.bouncycastle.crypto.digests.SHA512Digest;
4647
import org.bouncycastle.crypto.digests.SHAKEDigest;
47-
import org.bouncycastle.crypto.engines.*;
48+
import org.bouncycastle.crypto.engines.AESEngine;
49+
import org.bouncycastle.crypto.engines.AESFastEngine;
50+
import org.bouncycastle.crypto.engines.AESLightEngine;
51+
import org.bouncycastle.crypto.engines.BlowfishEngine;
52+
import org.bouncycastle.crypto.engines.CAST5Engine;
53+
import org.bouncycastle.crypto.engines.CamelliaEngine;
54+
import org.bouncycastle.crypto.engines.CamelliaLightEngine;
55+
import org.bouncycastle.crypto.engines.ChaCha7539Engine;
56+
import org.bouncycastle.crypto.engines.ChaChaEngine;
57+
import org.bouncycastle.crypto.engines.DESEngine;
58+
import org.bouncycastle.crypto.engines.DESedeEngine;
59+
import org.bouncycastle.crypto.engines.ElGamalEngine;
60+
import org.bouncycastle.crypto.engines.HC128Engine;
61+
import org.bouncycastle.crypto.engines.HC256Engine;
62+
import org.bouncycastle.crypto.engines.IDEAEngine;
63+
import org.bouncycastle.crypto.engines.RC4Engine;
64+
import org.bouncycastle.crypto.engines.RC532Engine;
65+
import org.bouncycastle.crypto.engines.RC564Engine;
66+
import org.bouncycastle.crypto.engines.RSAEngine;
67+
import org.bouncycastle.crypto.engines.RijndaelEngine;
68+
import org.bouncycastle.crypto.engines.SM2Engine;
69+
import org.bouncycastle.crypto.engines.SM4Engine;
70+
import org.bouncycastle.crypto.engines.Salsa20Engine;
71+
import org.bouncycastle.crypto.engines.SerpentEngine;
72+
import org.bouncycastle.crypto.engines.SkipjackEngine;
73+
import org.bouncycastle.crypto.engines.TEAEngine;
74+
import org.bouncycastle.crypto.engines.ThreefishEngine;
75+
import org.bouncycastle.crypto.engines.TnepresEngine;
76+
import org.bouncycastle.crypto.engines.TwofishEngine;
77+
import org.bouncycastle.crypto.engines.VMPCEngine;
78+
import org.bouncycastle.crypto.engines.VMPCKSA3Engine;
79+
import org.bouncycastle.crypto.engines.XSalsa20Engine;
80+
import org.bouncycastle.crypto.engines.Zuc128Engine;
81+
import org.bouncycastle.crypto.engines.Zuc256Engine;
4882
import org.bouncycastle.crypto.generators.DESKeyGenerator;
4983
import org.bouncycastle.crypto.generators.DESedeKeyGenerator;
5084
import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator;
@@ -90,6 +124,7 @@
90124
import org.bouncycastle.crypto.params.MQVPrivateParameters;
91125
import org.bouncycastle.crypto.params.MQVPublicParameters;
92126
import org.bouncycastle.crypto.params.ParametersWithIV;
127+
import org.bouncycastle.crypto.params.ParametersWithRandom;
93128
import org.bouncycastle.crypto.params.ParametersWithUKM;
94129
import org.bouncycastle.crypto.params.RC5Parameters;
95130
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
@@ -167,6 +202,7 @@ public void performTest()
167202
testRSA();
168203
testRsaKEM();
169204
testECIESKEM();
205+
testSM2Cipher();
170206
testSM4();
171207
testTEA();
172208
testThreefish();
@@ -1851,6 +1887,33 @@ private void testHC128AndHC256()
18511887
CryptoServicesRegistrar.setServicesConstraints(null);
18521888
}
18531889

1890+
private void testSM2Cipher()
1891+
{
1892+
SecureRandom random = new SecureRandom();
1893+
ECKeyPairGenerator kpGen = new ECKeyPairGenerator();
1894+
1895+
kpGen.init(new ECKeyGenerationParameters(new ECDomainParameters(ECNamedCurveTable.getByName("P-256")), random));
1896+
1897+
AsymmetricCipherKeyPair kp = kpGen.generateKeyPair();
1898+
1899+
CryptoServicesRegistrar.setServicesConstraints(new LegacyBitsOfSecurityConstraint(256, 128));
1900+
SM2Engine engine = new SM2Engine();
1901+
try
1902+
{
1903+
engine.init(true, new ParametersWithRandom(kp.getPublic(), random));
1904+
fail("no exception!");
1905+
}
1906+
catch (CryptoServiceConstraintsException e)
1907+
{
1908+
isEquals(e.getMessage(),"service does not provide 256 bits of security only 128", e.getMessage());
1909+
}
1910+
1911+
// decryption should be okay
1912+
engine.init(false, kp.getPrivate());
1913+
1914+
CryptoServicesRegistrar.setServicesConstraints(null);
1915+
}
1916+
18541917
public static void main(
18551918
String[] args)
18561919
{

core/src/test/java/org/bouncycastle/crypto/test/SM2EngineTest.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.math.BigInteger;
44

55
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
6+
import org.bouncycastle.crypto.DataLengthException;
67
import org.bouncycastle.crypto.InvalidCipherTextException;
78
import org.bouncycastle.crypto.engines.SM2Engine;
89
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
@@ -233,12 +234,64 @@ private void doEngineTestF2m()
233234
isTrue("f2m dec wrong", Arrays.areEqual(m, dec));
234235
}
235236

237+
public void doDudInputTest()
238+
throws Exception
239+
{
240+
BigInteger SM2_ECC_A = new BigInteger("00", 16);
241+
BigInteger SM2_ECC_B = new BigInteger("E78BCD09746C202378A7E72B12BCE00266B9627ECB0B5A25367AD1AD4CC6242B", 16);
242+
BigInteger SM2_ECC_N = new BigInteger("7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBC972CF7E6B6F900945B3C6A0CF6161D", 16);
243+
BigInteger SM2_ECC_H = BigInteger.valueOf(4);
244+
BigInteger SM2_ECC_GX = new BigInteger("00CDB9CA7F1E6B0441F658343F4B10297C0EF9B6491082400A62E7A7485735FADD", 16);
245+
BigInteger SM2_ECC_GY = new BigInteger("013DE74DA65951C4D76DC89220D5F7777A611B1C38BAE260B175951DC8060C2B3E", 16);
246+
247+
ECCurve curve = new ECCurve.F2m(257, 12, SM2_ECC_A, SM2_ECC_B, SM2_ECC_N, SM2_ECC_H);
248+
249+
ECPoint g = curve.createPoint(SM2_ECC_GX, SM2_ECC_GY);
250+
ECDomainParameters domainParams = new ECDomainParameters(curve, g, SM2_ECC_N, SM2_ECC_H);
251+
252+
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
253+
254+
ECKeyGenerationParameters aKeyGenParams = new ECKeyGenerationParameters(domainParams, new TestRandomBigInteger("56A270D17377AA9A367CFA82E46FA5267713A9B91101D0777B07FCE018C757EB", 16));
255+
256+
keyPairGenerator.init(aKeyGenParams);
257+
258+
AsymmetricCipherKeyPair aKp = keyPairGenerator.generateKeyPair();
259+
260+
ECPublicKeyParameters aPub = (ECPublicKeyParameters)aKp.getPublic();
261+
ECPrivateKeyParameters aPriv = (ECPrivateKeyParameters)aKp.getPrivate();
262+
263+
SM2Engine sm2Engine = new SM2Engine();
264+
265+
// zero length input
266+
try
267+
{
268+
sm2Engine.processBlock(new byte[0], 0, 0);
269+
fail("no expection");
270+
}
271+
catch (DataLengthException e)
272+
{
273+
isEquals("input buffer too short", e.getMessage());
274+
}
275+
276+
// buffer too small
277+
try
278+
{
279+
sm2Engine.processBlock(new byte[1], 0, 2);
280+
fail("no expection");
281+
}
282+
catch (DataLengthException e)
283+
{
284+
isEquals("input buffer too short", e.getMessage());
285+
}
286+
}
287+
236288
public void performTest()
237289
throws Exception
238290
{
239291
doEngineTestFp();
240292
doEngineTestF2m();
241293
doEngineTestFpC1C3C2();
294+
doDudInputTest();
242295
}
243296

244297
public static void main(String[] args)

0 commit comments

Comments
 (0)