Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crypto/BouncyCastle.Android.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1057,6 +1057,7 @@
<Compile Include="src\crypto\signers\Ed25519Signer.cs" />
<Compile Include="src\crypto\signers\Ed448phSigner.cs" />
<Compile Include="src\crypto\signers\Ed448Signer.cs" />
<Compile Include="src\crypto\signers\EdDsa25519Signer.cs" />
<Compile Include="src\crypto\signers\GOST3410DigestSigner.cs" />
<Compile Include="src\crypto\signers\GOST3410Signer.cs" />
<Compile Include="src\crypto\signers\GenericSigner.cs" />
Expand Down Expand Up @@ -1486,7 +1487,8 @@
<Compile Include="src\openpgp\PgpUtilities.cs" />
<Compile Include="src\openpgp\PgpV3SignatureGenerator.cs" />
<Compile Include="src\openpgp\Rfc6637Utilities.cs" />
<Compile Include="src\openpgp\SXprUtilities.cs" />
<Compile Include="src\openpgp\SXprReader.cs" />
<Compile Include="src\openpgp\SXprWriter.cs" />
<Compile Include="src\openpgp\WrappedGeneratorStream.cs" />
<Compile Include="src\openssl\EncryptionException.cs" />
<Compile Include="src\openssl\IPasswordFinder.cs" />
Expand Down
4 changes: 3 additions & 1 deletion crypto/BouncyCastle.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,7 @@
<Compile Include="src\crypto\signers\Ed25519Signer.cs" />
<Compile Include="src\crypto\signers\Ed448phSigner.cs" />
<Compile Include="src\crypto\signers\Ed448Signer.cs" />
<Compile Include="src\crypto\signers\EdDsa25519Signer.cs" />
<Compile Include="src\crypto\signers\GOST3410DigestSigner.cs" />
<Compile Include="src\crypto\signers\GOST3410Signer.cs" />
<Compile Include="src\crypto\signers\GenericSigner.cs" />
Expand Down Expand Up @@ -1480,7 +1481,8 @@
<Compile Include="src\openpgp\PgpUtilities.cs" />
<Compile Include="src\openpgp\PgpV3SignatureGenerator.cs" />
<Compile Include="src\openpgp\Rfc6637Utilities.cs" />
<Compile Include="src\openpgp\SXprUtilities.cs" />
<Compile Include="src\openpgp\SXprReader.cs" />
<Compile Include="src\openpgp\SXprWriter.cs" />
<Compile Include="src\openpgp\WrappedGeneratorStream.cs" />
<Compile Include="src\openssl\EncryptionException.cs" />
<Compile Include="src\openssl\IPasswordFinder.cs" />
Expand Down
4 changes: 3 additions & 1 deletion crypto/BouncyCastle.iOS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,7 @@
<Compile Include="src\crypto\signers\Ed25519Signer.cs" />
<Compile Include="src\crypto\signers\Ed448phSigner.cs" />
<Compile Include="src\crypto\signers\Ed448Signer.cs" />
<Compile Include="src\crypto\signers\EdDsa25519Signer.cs" />
<Compile Include="src\crypto\signers\GOST3410DigestSigner.cs" />
<Compile Include="src\crypto\signers\GOST3410Signer.cs" />
<Compile Include="src\crypto\signers\GenericSigner.cs" />
Expand Down Expand Up @@ -1481,7 +1482,8 @@
<Compile Include="src\openpgp\PgpUtilities.cs" />
<Compile Include="src\openpgp\PgpV3SignatureGenerator.cs" />
<Compile Include="src\openpgp\Rfc6637Utilities.cs" />
<Compile Include="src\openpgp\SXprUtilities.cs" />
<Compile Include="src\openpgp\SXprReader.cs" />
<Compile Include="src\openpgp\SXprWriter.cs" />
<Compile Include="src\openpgp\WrappedGeneratorStream.cs" />
<Compile Include="src\openssl\EncryptionException.cs" />
<Compile Include="src\openssl\IPasswordFinder.cs" />
Expand Down
12 changes: 11 additions & 1 deletion crypto/crypto.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5143,6 +5143,11 @@
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "src\crypto\signers\EdDsa25519Signer.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "src\crypto\signers\GenericSigner.cs"
SubType = "Code"
Expand Down Expand Up @@ -7289,7 +7294,12 @@
BuildAction = "Compile"
/>
<File
RelPath = "src\openpgp\SXprUtilities.cs"
RelPath = "src\openpgp\SXprReader.cs"
SubType = "Code"
BuildAction = "Compile"
/>
<File
RelPath = "src\openpgp\SXprWriter.cs"
SubType = "Code"
BuildAction = "Compile"
/>
Expand Down
6 changes: 3 additions & 3 deletions crypto/src/asn1/gnu/GNUObjectIdentifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public abstract class GnuObjectIdentifiers
public static readonly DerObjectIdentifier Crc = new DerObjectIdentifier("1.3.6.1.4.1.11591.14"); // CRC algorithms
public static readonly DerObjectIdentifier Crc32 = new DerObjectIdentifier("1.3.6.1.4.1.11591.14.1"); // CRC 32

/** 1.3.6.1.4.1.11591.15 - ellipticCurve */
public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.6.1.4.1.11591.15");
/** 1.3.6.1.4.1.11591.15 - ellipticCurve */
public static readonly DerObjectIdentifier EllipticCurve = new DerObjectIdentifier("1.3.6.1.4.1.11591.15");

public static readonly DerObjectIdentifier Ed25519 = EllipticCurve.Branch("1");
public static readonly DerObjectIdentifier Ed25519 = EllipticCurve.Branch("1");
}
}
3 changes: 3 additions & 0 deletions crypto/src/asn1/misc/MiscObjectIdentifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public abstract class MiscObjectIdentifiers
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_CFB = cryptlib_algorithm.Branch("1.3");
public static readonly DerObjectIdentifier cryptlib_algorithm_blowfish_OFB = cryptlib_algorithm.Branch("1.4");

// OpenPGP (draft-ietf-openpgp-rfc4880bis-10)
public static readonly DerObjectIdentifier Curve25519 = cryptlib_algorithm.Branch("5.1");

//
// Blake2b
//
Expand Down
16 changes: 16 additions & 0 deletions crypto/src/bcpg/ECDHPublicBCPGKey.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;

namespace Org.BouncyCastle.Bcpg
Expand Down Expand Up @@ -48,6 +49,21 @@ public ECDHPublicBcpgKey(
VerifySymmetricKeyAlgorithm();
}

public ECDHPublicBcpgKey(
DerObjectIdentifier oid,
BigInteger encodedPoint,
HashAlgorithmTag hashAlgorithm,
SymmetricKeyAlgorithmTag symmetricKeyAlgorithm)
: base(oid, encodedPoint)
{
reserved = 1;
hashFunctionId = hashAlgorithm;
symAlgorithmId = symmetricKeyAlgorithm;

VerifyHashAlgorithm();
VerifySymmetricKeyAlgorithm();
}

public virtual byte Reserved
{
get { return reserved; }
Expand Down
1 change: 1 addition & 0 deletions crypto/src/bcpg/PublicKeyPacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ internal PublicKeyPacket(
key = new ECDHPublicBcpgKey(bcpgIn);
break;
case PublicKeyAlgorithmTag.ECDsa:
case PublicKeyAlgorithmTag.EdDsa:
key = new ECDsaPublicBcpgKey(bcpgIn);
break;
default:
Expand Down
1 change: 1 addition & 0 deletions crypto/src/bcpg/SignaturePacket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ internal SignaturePacket(
signature = new MPInteger[]{ p, g, y };
break;
case PublicKeyAlgorithmTag.ECDsa:
case PublicKeyAlgorithmTag.EdDsa:
MPInteger ecR = new MPInteger(bcpgIn);
MPInteger ecS = new MPInteger(bcpgIn);
signature = new MPInteger[]{ ecR, ecS };
Expand Down
5 changes: 4 additions & 1 deletion crypto/src/crypto/ec/CustomNamedCurves.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.Gnu;
using Org.BouncyCastle.Asn1.Misc;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Math;
Expand Down Expand Up @@ -789,7 +791,8 @@ private static void DefineCurveAlias(string name, DerObjectIdentifier oid)

static CustomNamedCurves()
{
DefineCurve("curve25519", Curve25519Holder.Instance);
DefineCurveWithOid("ed25519", GnuObjectIdentifiers.Ed25519, Curve25519Holder.Instance);
DefineCurveWithOid("curve25519", MiscObjectIdentifiers.Curve25519, Curve25519Holder.Instance);

//DefineCurveWithOid("secp112r1", SecObjectIdentifiers.SecP112r1, SecP112R1Holder.Instance);
//DefineCurveWithOid("secp112r2", SecObjectIdentifiers.SecP112r2, SecP112R2Holder.Instance);
Expand Down
50 changes: 37 additions & 13 deletions crypto/src/openpgp/PgpEncryptedDataGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
using System.Diagnostics;
using System.IO;

using Org.BouncyCastle.Asn1.Misc;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;

Expand Down Expand Up @@ -102,10 +104,12 @@ public override void AddSessionInfo(

private byte[] EncryptSessionInfo(byte[] sessionInfo, SecureRandom random)
{
AsymmetricKeyParameter akp = pubKey.GetKey();

if (pubKey.Algorithm != PublicKeyAlgorithmTag.ECDH)
{
IBufferedCipher c;
switch (pubKey.Algorithm)
switch (pubKey.Algorithm)
{
case PublicKeyAlgorithmTag.RsaEncrypt:
case PublicKeyAlgorithmTag.RsaGeneral:
Expand All @@ -119,37 +123,57 @@ private byte[] EncryptSessionInfo(byte[] sessionInfo, SecureRandom random)
throw new PgpException("Can't use DSA for encryption.");
case PublicKeyAlgorithmTag.ECDsa:
throw new PgpException("Can't use ECDSA for encryption.");
case PublicKeyAlgorithmTag.EdDsa:
throw new PgpException("Can't use EdDSA for encryption.");
default:
throw new PgpException("unknown asymmetric algorithm: " + pubKey.Algorithm);
}

AsymmetricKeyParameter akp = pubKey.GetKey();
c.Init(true, new ParametersWithRandom(akp, random));
c.Init(true, new ParametersWithRandom(akp, random));
return c.DoFinal(sessionInfo);
}

ECDHPublicBcpgKey ecKey = (ECDHPublicBcpgKey)pubKey.PublicKeyPacket.Key;
KeyParameter key;
byte[] encodedPublicKey;

// Generate the ephemeral key pair
IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH");
gen.Init(new ECKeyGenerationParameters(ecKey.CurveOid, random));
if (akp is X25519PublicKeyParameters)
{
X25519PublicKeyParameters pub = (X25519PublicKeyParameters)akp;
byte[] privateKey = new byte[X25519.PointSize];
X25519.GeneratePrivateKey(random, privateKey);
byte[] sharedKey = new byte[32];
X25519.CalculateAgreement(privateKey, 0, pub.GetEncoded(), 0, sharedKey, 0);
byte[] publicKey = new byte[X25519.PointSize + 1];
publicKey[0] = 0x40; // compressed point
X25519.GeneratePublicKey(privateKey, 0, publicKey, 1);
encodedPublicKey = publicKey;
key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, sharedKey));
}
else
{
// Generate the ephemeral key pair
IAsymmetricCipherKeyPairGenerator gen = GeneratorUtilities.GetKeyPairGenerator("ECDH");
gen.Init(new ECKeyGenerationParameters(ecKey.CurveOid, random));

AsymmetricCipherKeyPair ephKp = gen.GenerateKeyPair();
ECPrivateKeyParameters ephPriv = (ECPrivateKeyParameters)ephKp.Private;
ECPublicKeyParameters ephPub = (ECPublicKeyParameters)ephKp.Public;
AsymmetricCipherKeyPair ephKp = gen.GenerateKeyPair();
ECPrivateKeyParameters ephPriv = (ECPrivateKeyParameters)ephKp.Private;
ECPublicKeyParameters ephPub = (ECPublicKeyParameters)ephKp.Public;

ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey.GetKey();
ECPoint S = pub.Q.Multiply(ephPriv.D).Normalize();
ECPublicKeyParameters pub = (ECPublicKeyParameters)akp;
ECPoint S = pub.Q.Multiply(ephPriv.D).Normalize();

KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, S));
key = new KeyParameter(Rfc6637Utilities.CreateKey(pubKey.PublicKeyPacket, S));
encodedPublicKey = ephPub.Q.GetEncoded(false);
}

IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm);
w.Init(true, new ParametersWithRandom(key, random));

byte[] paddedSessionData = PgpPad.PadSessionData(sessionInfo, sessionKeyObfuscation);

byte[] C = w.Wrap(paddedSessionData, 0, paddedSessionData.Length);
byte[] VB = new MPInteger(new BigInteger(1, ephPub.Q.GetEncoded(false))).GetEncoded();
byte[] VB = new MPInteger(new BigInteger(1, encodedPublicKey)).GetEncoded();

byte[] rv = new byte[VB.Length + 1 + C.Length];

Expand Down
39 changes: 37 additions & 2 deletions crypto/src/openpgp/PgpPublicKey.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System.Collections;
using System.IO;

using Org.BouncyCastle.Asn1.Gnu;
using Org.BouncyCastle.Asn1.Misc;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
Expand All @@ -10,6 +11,8 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Math.EC.Rfc8032;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Collections;
Expand Down Expand Up @@ -177,11 +180,35 @@ public PgpPublicKey(
{
bcpgKey = new ECDsaPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q);
}
else if (algorithm == PublicKeyAlgorithmTag.EdDsa)
{
bcpgKey = new ECDsaPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q);
}
else
{
throw new PgpException("unknown EC algorithm");
}
}
else if (pubKey is Ed25519PublicKeyParameters)
{
Ed25519PublicKeyParameters ecK = (Ed25519PublicKeyParameters)pubKey;
byte[] encodedPoint = new byte[Ed25519.PublicKeySize + 1];
encodedPoint[0] = 0x40;
ecK.Encode(encodedPoint, 1);
bcpgKey = new ECDsaPublicBcpgKey(GnuObjectIdentifiers.Ed25519, new BigInteger(1, encodedPoint));
}
else if (pubKey is X25519PublicKeyParameters)
{
X25519PublicKeyParameters ecK = (X25519PublicKeyParameters)pubKey;
byte[] encodedPoint = new byte[X25519.PointSize + 1];
encodedPoint[0] = 0x40;
ecK.Encode(encodedPoint, 1);
bcpgKey = new ECDHPublicBcpgKey(
MiscObjectIdentifiers.Curve25519,
new BigInteger(1, encodedPoint),
HashAlgorithmTag.Sha256,
SymmetricKeyAlgorithmTag.Aes128);
}
else if (pubKey is ElGamalPublicKeyParameters)
{
ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters) pubKey;
Expand Down Expand Up @@ -495,7 +522,15 @@ public AsymmetricKeyParameter GetKey()
case PublicKeyAlgorithmTag.ECDsa:
return GetECKey("ECDSA");
case PublicKeyAlgorithmTag.ECDH:
return GetECKey("ECDH");
if (((ECPublicBcpgKey)publicPk.Key).CurveOid.Id.Equals(MiscObjectIdentifiers.Curve25519.Id))
{
byte[] encodedPoint = ((ECPublicBcpgKey)publicPk.Key).EncodedPoint.ToByteArrayUnsigned();
return new X25519PublicKeyParameters(encodedPoint, 1);
}
else
return GetECKey("ECDH");
case PublicKeyAlgorithmTag.EdDsa:
return new Ed25519PublicKeyParameters(((ECPublicBcpgKey)publicPk.Key).EncodedPoint.ToByteArrayUnsigned(), 1);
case PublicKeyAlgorithmTag.ElGamalEncrypt:
case PublicKeyAlgorithmTag.ElGamalGeneral:
ElGamalPublicBcpgKey elK = (ElGamalPublicBcpgKey)publicPk.Key;
Expand Down
24 changes: 19 additions & 5 deletions crypto/src/openpgp/PgpPublicKeyEncryptedData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Custom.Djb;
using Org.BouncyCastle.Math.EC.Rfc7748;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.IO;
using Org.BouncyCastle.Utilities;

namespace Org.BouncyCastle.Bcpg.OpenPgp
{
Expand Down Expand Up @@ -210,12 +213,23 @@ private byte[] RecoverSessionData(PgpPrivateKey privKey)
byte[] keyEnc = new byte[keyLen];
Array.Copy(enc, 2 + pLen + 1, keyEnc, 0, keyEnc.Length);

ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc);
KeyParameter key;

ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key;
ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize();

KeyParameter key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S));
if (privKey.Key is X25519PrivateKeyParameters x25519privKeyParams)
{
byte[] sharedKey = new byte[X25519.PointSize];
byte[] privateKey = new byte[X25519.PointSize];
x25519privKeyParams.Encode(privateKey, 0);
X25519.CalculateAgreement(privateKey, 0, pEnc, 1, sharedKey, 0);
key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, sharedKey));
}
else
{
ECPoint publicPoint = x9Params.Curve.DecodePoint(pEnc);
ECPrivateKeyParameters privKeyParams = (ECPrivateKeyParameters)privKey.Key;
ECPoint S = publicPoint.Multiply(privKeyParams.D).Normalize();
key = new KeyParameter(Rfc6637Utilities.CreateKey(privKey.PublicKeyPacket, S));
}

IWrapper w = PgpUtilities.CreateWrapper(ecKey.SymmetricKeyAlgorithm);
w.Init(false, key);
Expand Down
Loading