Skip to content

Commit dcac367

Browse files
author
gefeili
committed
Merge branch 'main' into pg-synchronize-bc_csharp
# Conflicts: # pg/src/main/java/org/bouncycastle/bcpg/PublicKeyPacket.java # pg/src/main/java/org/bouncycastle/bcpg/SignaturePacket.java # pg/src/main/java/org/bouncycastle/bcpg/StreamUtil.java # pg/src/main/java/org/bouncycastle/openpgp/PGPSignatureGenerator.java
2 parents 73e08f6 + 5d3edd0 commit dcac367

File tree

63 files changed

+3452
-566
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+3452
-566
lines changed

core/src/main/java/org/bouncycastle/crypto/hpke/DHKEM.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737

3838
class DHKEM
39+
extends KEM
3940
{
4041
private AsymmetricCipherKeyPairGenerator kpGen;
4142

@@ -48,6 +49,7 @@ class DHKEM
4849
private byte bitmask;
4950
private int Nsk;
5051
private int Nsecret;
52+
private int Nenc;
5153

5254
ECDomainParameters domainParams;
5355

@@ -74,7 +76,7 @@ protected DHKEM(short kemid)
7476
bitmask = (byte)0xff;
7577
Nsk = 32;
7678
Nsecret = 32;
77-
79+
Nenc = 65;
7880
this.kpGen = new ECKeyPairGenerator();
7981
this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom()));
8082

@@ -96,6 +98,7 @@ protected DHKEM(short kemid)
9698
bitmask = (byte)0xff;
9799
Nsk = 48;
98100
Nsecret = 48;
101+
Nenc = 97;
99102

100103
this.kpGen = new ECKeyPairGenerator();
101104
this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom()));
@@ -119,6 +122,7 @@ protected DHKEM(short kemid)
119122
bitmask = 0x01;
120123
Nsk = 66;
121124
Nsecret = 64;
125+
Nenc = 133;
122126

123127
this.kpGen = new ECKeyPairGenerator();
124128
this.kpGen.init(new ECKeyGenerationParameters(domainParams, new SecureRandom()));
@@ -129,6 +133,7 @@ protected DHKEM(short kemid)
129133
this.agreement = new XDHBasicAgreement();
130134
Nsecret = 32;
131135
Nsk = 32;
136+
Nenc = 32;
132137
this.kpGen = new X25519KeyPairGenerator();
133138
this.kpGen.init(new X25519KeyGenerationParameters(new SecureRandom()));
134139

@@ -138,6 +143,7 @@ protected DHKEM(short kemid)
138143
this.agreement = new XDHBasicAgreement();
139144
Nsecret = 64;
140145
Nsk = 56;
146+
Nenc = 56;
141147

142148
this.kpGen = new X448KeyPairGenerator();
143149
this.kpGen.init(new X448KeyGenerationParameters(new SecureRandom()));
@@ -242,6 +248,11 @@ public AsymmetricCipherKeyPair DeserializePrivateKey(byte[] skEncoded, byte[] pk
242248
}
243249
}
244250

251+
int getEncryptionSize()
252+
{
253+
return Nenc;
254+
}
255+
245256
private boolean ValidateSk(BigInteger d)
246257
{
247258
BigInteger n = domainParams.getN();

core/src/main/java/org/bouncycastle/crypto/hpke/HPKE.java

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class HPKE
4040
private final short kemId;
4141
private final short kdfId;
4242
private final short aeadId;
43-
private final DHKEM dhkem;
43+
private final KEM kem;
4444
private final HKDF hkdf;
4545

4646
short Nk;
@@ -58,7 +58,7 @@ public HPKE(byte mode, short kemId, short kdfId, short aeadId)
5858
this.kdfId = kdfId;
5959
this.aeadId = aeadId;
6060
this.hkdf = new HKDF(kdfId);
61-
this.dhkem = new DHKEM(kemId);
61+
this.kem = new DHKEM(kemId);
6262
if (aeadId == aead_AES_GCM128)
6363
{
6464
Nk = 16;
@@ -67,25 +67,12 @@ public HPKE(byte mode, short kemId, short kdfId, short aeadId)
6767
{
6868
Nk = 32;
6969
}
70+
7071
}
7172

7273
public int getEncSize()
7374
{
74-
switch (kemId)
75-
{
76-
case HPKE.kem_P256_SHA256:
77-
return 65;
78-
case HPKE.kem_P384_SHA348:
79-
return 97;
80-
case HPKE.kem_P521_SHA512:
81-
return 133;
82-
case HPKE.kem_X25519_SHA256:
83-
return 32;
84-
case HPKE.kem_X448_SHA512:
85-
return 56;
86-
default:
87-
throw new IllegalArgumentException("invalid kem id");
88-
}
75+
return kem.getEncryptionSize();
8976
}
9077
public short getAeadId()
9178
{
@@ -139,32 +126,32 @@ private HPKEContext keySchedule(byte mode, byte[] sharedSecret, byte[] info, byt
139126

140127
public AsymmetricCipherKeyPair generatePrivateKey()
141128
{
142-
return dhkem.GeneratePrivateKey();
129+
return kem.GeneratePrivateKey();
143130
}
144131

145132

146133
public byte[] serializePublicKey(AsymmetricKeyParameter pk)
147134
{
148-
return dhkem.SerializePublicKey(pk);
135+
return kem.SerializePublicKey(pk);
149136
}
150137

151138
public byte[] serializePrivateKey(AsymmetricKeyParameter sk)
152139
{
153-
return dhkem.SerializePrivateKey(sk);
140+
return kem.SerializePrivateKey(sk);
154141
}
155142
public AsymmetricKeyParameter deserializePublicKey(byte[] pkEncoded)
156143
{
157-
return dhkem.DeserializePublicKey(pkEncoded);
144+
return kem.DeserializePublicKey(pkEncoded);
158145
}
159146

160147
public AsymmetricCipherKeyPair deserializePrivateKey(byte[] skEncoded, byte[] pkEncoded)
161148
{
162-
return dhkem.DeserializePrivateKey(skEncoded, pkEncoded);
149+
return kem.DeserializePrivateKey(skEncoded, pkEncoded);
163150
}
164151

165152
public AsymmetricCipherKeyPair deriveKeyPair(byte[] ikm)
166153
{
167-
return dhkem.DeriveKeyPair(ikm);
154+
return kem.DeriveKeyPair(ikm);
168155
}
169156

170157
public byte[][] sendExport(AsymmetricKeyParameter pkR, byte[] info, byte[] exporterContext, int L,
@@ -273,7 +260,7 @@ public byte[] open(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[]
273260

274261
public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[] info)
275262
{
276-
byte[][] output = dhkem.Encap(pkR); // sharedSecret, enc
263+
byte[][] output = kem.Encap(pkR); // sharedSecret, enc
277264
HPKEContext ctx = keySchedule(mode_base, output[0], info, default_psk, default_psk_id);
278265

279266
return new HPKEContextWithEncapsulation(ctx, output[1]);
@@ -283,21 +270,21 @@ public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[
283270
// This should only be used to validate test vectors.
284271
public HPKEContextWithEncapsulation setupBaseS(AsymmetricKeyParameter pkR, byte[] info, AsymmetricCipherKeyPair kpE)
285272
{
286-
byte[][] output = dhkem.Encap(pkR, kpE); // sharedSecret, enc
273+
byte[][] output = kem.Encap(pkR, kpE); // sharedSecret, enc
287274
HPKEContext ctx = keySchedule(mode_base, output[0], info, default_psk, default_psk_id);
288275

289276
return new HPKEContextWithEncapsulation(ctx, output[1]);
290277
}
291278

292279
public HPKEContext setupBaseR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info)
293280
{
294-
byte[] sharedSecret = dhkem.Decap(enc, skR);
281+
byte[] sharedSecret = kem.Decap(enc, skR);
295282
return keySchedule(mode_base, sharedSecret, info, default_psk, default_psk_id);
296283
}
297284

298285
public HPKEContextWithEncapsulation SetupPSKS(AsymmetricKeyParameter pkR, byte[] info, byte[] psk, byte[] psk_id)
299286
{
300-
byte[][] output = dhkem.Encap(pkR); // sharedSecret, enc
287+
byte[][] output = kem.Encap(pkR); // sharedSecret, enc
301288

302289
HPKEContext ctx = keySchedule(mode_psk, output[0], info, psk, psk_id);
303290

@@ -306,35 +293,35 @@ public HPKEContextWithEncapsulation SetupPSKS(AsymmetricKeyParameter pkR, byte[]
306293

307294
public HPKEContext setupPSKR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[] psk, byte[] psk_id)
308295
{
309-
byte[] sharedSecret = dhkem.Decap(enc, skR);
296+
byte[] sharedSecret = kem.Decap(enc, skR);
310297
return keySchedule(mode_psk, sharedSecret, info, psk, psk_id);
311298
}
312299

313300
public HPKEContextWithEncapsulation setupAuthS(AsymmetricKeyParameter pkR, byte[] info, AsymmetricCipherKeyPair skS)
314301
{
315-
byte[][] output = dhkem.AuthEncap(pkR, skS);
302+
byte[][] output = kem.AuthEncap(pkR, skS);
316303
HPKEContext ctx = keySchedule(mode_auth, output[0], info, default_psk, default_psk_id);
317304

318305
return new HPKEContextWithEncapsulation(ctx, output[1]);
319306
}
320307

321308
public HPKEContext setupAuthR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, AsymmetricKeyParameter pkS)
322309
{
323-
byte[] sharedSecret = dhkem.AuthDecap(enc, skR, pkS);
310+
byte[] sharedSecret = kem.AuthDecap(enc, skR, pkS);
324311
return keySchedule(mode_auth, sharedSecret, info, default_psk, default_psk_id);
325312
}
326313

327314
public HPKEContextWithEncapsulation setupAuthPSKS(AsymmetricKeyParameter pkR, byte[] info, byte[] psk, byte[] psk_id, AsymmetricCipherKeyPair skS)
328315
{
329-
byte[][] output = dhkem.AuthEncap(pkR, skS);
316+
byte[][] output = kem.AuthEncap(pkR, skS);
330317
HPKEContext ctx = keySchedule(mode_auth_psk, output[0], info, psk, psk_id);
331318

332319
return new HPKEContextWithEncapsulation(ctx, output[1]);
333320
}
334321

335322
public HPKEContext setupAuthPSKR(byte[] enc, AsymmetricCipherKeyPair skR, byte[] info, byte[] psk, byte[] psk_id, AsymmetricKeyParameter pkS)
336323
{
337-
byte[] sharedSecret = dhkem.AuthDecap(enc, skR, pkS);
324+
byte[] sharedSecret = kem.AuthDecap(enc, skR, pkS);
338325
return keySchedule(mode_auth_psk, sharedSecret, info, psk, psk_id);
339326
}
340327
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package org.bouncycastle.crypto.hpke;
2+
3+
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
4+
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
5+
6+
7+
/**
8+
* base class for HPKE KEM
9+
*/
10+
public abstract class KEM
11+
{
12+
// Key Generation
13+
abstract AsymmetricCipherKeyPair GeneratePrivateKey();
14+
abstract AsymmetricCipherKeyPair DeriveKeyPair(byte[] ikm);
15+
16+
// Encapsulates a shared secret for a given public key and returns the encapsulated key and shared secret.
17+
abstract byte[][] Encap(AsymmetricKeyParameter recipientPublicKey);
18+
abstract byte[][] Encap(AsymmetricKeyParameter pkR, AsymmetricCipherKeyPair kpE);
19+
abstract byte[][] AuthEncap(AsymmetricKeyParameter pkR, AsymmetricCipherKeyPair kpS);
20+
21+
// Decapsulates the given encapsulated key using the recipient's key pair and returns the shared secret.
22+
abstract byte[] Decap(byte[] encapsulatedKey, AsymmetricCipherKeyPair recipientKeyPair);
23+
abstract byte[] AuthDecap(byte[] enc, AsymmetricCipherKeyPair kpR, AsymmetricKeyParameter pkS);
24+
25+
// Serialization
26+
abstract byte[] SerializePublicKey(AsymmetricKeyParameter publicKey);
27+
abstract byte[] SerializePrivateKey(AsymmetricKeyParameter key);
28+
29+
// Deserialization
30+
abstract AsymmetricKeyParameter DeserializePublicKey(byte[] encodedPublicKey);
31+
abstract AsymmetricCipherKeyPair DeserializePrivateKey(byte[] skEncoded, byte[] pkEncoded);
32+
33+
abstract int getEncryptionSize();
34+
35+
}

core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java

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

55
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
6+
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
67
import org.bouncycastle.asn1.x9.X9ECParameters;
8+
import org.bouncycastle.crypto.ec.CustomNamedCurves;
79
import org.bouncycastle.math.ec.ECConstants;
810
import org.bouncycastle.math.ec.ECCurve;
911
import org.bouncycastle.math.ec.ECPoint;
1012

1113
public class ECNamedDomainParameters
1214
extends ECDomainParameters
1315
{
16+
public static ECNamedDomainParameters lookup(ASN1ObjectIdentifier name)
17+
{
18+
X9ECParameters x9 = CustomNamedCurves.getByOID(name);
19+
if (x9 == null)
20+
{
21+
x9 = ECNamedCurveTable.getByOID(name);
22+
}
23+
return new ECNamedDomainParameters(name, x9);
24+
}
25+
1426
private ASN1ObjectIdentifier name;
1527

1628
public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n)

core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
1414
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
1515
import org.bouncycastle.asn1.sec.ECPrivateKey;
16-
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
16+
import org.bouncycastle.asn1.x9.X962Parameters;
1717
import org.bouncycastle.asn1.x9.X9ECParameters;
1818
import org.bouncycastle.crypto.CryptoServicesRegistrar;
1919
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
2020
import org.bouncycastle.crypto.params.DSAParameters;
2121
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
22+
import org.bouncycastle.crypto.params.ECDomainParameters;
2223
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
2324
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
2425
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
@@ -199,13 +200,24 @@ else if (sequence.size() == 4)
199200
&& sequence.getObjectAt(2) instanceof ASN1TaggedObject)
200201
{
201202
ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(sequence);
202-
ASN1ObjectIdentifier curveOID = ASN1ObjectIdentifier.getInstance(ecPrivateKey.getParametersObject());
203-
X9ECParameters x9Params = ECNamedCurveTable.getByOID(curveOID);
204-
result = new ECPrivateKeyParameters(
205-
ecPrivateKey.getKey(),
206-
new ECNamedDomainParameters(
207-
curveOID,
208-
x9Params));
203+
204+
X962Parameters parameters = X962Parameters.getInstance(
205+
ecPrivateKey.getParametersObject().toASN1Primitive());
206+
ECDomainParameters domainParams;
207+
if (parameters.isNamedCurve())
208+
{
209+
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters());
210+
domainParams = ECNamedDomainParameters.lookup(oid);
211+
}
212+
else
213+
{
214+
X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters());
215+
domainParams = new ECDomainParameters(x9);
216+
}
217+
218+
BigInteger d = ecPrivateKey.getKey();
219+
220+
result = new ECPrivateKeyParameters(d, domainParams);
209221
}
210222
}
211223
}

core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.bouncycastle.asn1.x9.X962Parameters;
2727
import org.bouncycastle.asn1.x9.X9ECParameters;
2828
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
29-
import org.bouncycastle.crypto.ec.CustomNamedCurves;
3029
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
3130
import org.bouncycastle.crypto.params.DHParameters;
3231
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
@@ -155,33 +154,24 @@ else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
155154
}
156155
else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
157156
{
158-
X962Parameters params = X962Parameters.getInstance(algId.getParameters());
157+
ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
159158

160-
X9ECParameters x9;
161-
ECDomainParameters dParams;
162-
163-
if (params.isNamedCurve())
159+
X962Parameters parameters = X962Parameters.getInstance(algId.getParameters().toASN1Primitive());
160+
ECDomainParameters domainParams;
161+
if (parameters.isNamedCurve())
164162
{
165-
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
166-
167-
x9 = CustomNamedCurves.getByOID(oid);
168-
if (x9 == null)
169-
{
170-
x9 = ECNamedCurveTable.getByOID(oid);
171-
}
172-
dParams = new ECNamedDomainParameters(oid, x9);
163+
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters());
164+
domainParams = ECNamedDomainParameters.lookup(oid);
173165
}
174166
else
175167
{
176-
x9 = X9ECParameters.getInstance(params.getParameters());
177-
dParams = new ECDomainParameters(
178-
x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
168+
X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters());
169+
domainParams = new ECDomainParameters(x9);
179170
}
180171

181-
ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
182-
BigInteger d = ec.getKey();
172+
BigInteger d = ecPrivateKey.getKey();
183173

184-
return new ECPrivateKeyParameters(d, dParams);
174+
return new ECPrivateKeyParameters(d, domainParams);
185175
}
186176
else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
187177
{

0 commit comments

Comments
 (0)