|
|
@@ -1,7 +1,6 @@
|
|
|
using System.Globalization;
|
|
|
using System.Linq;
|
|
|
|
|
|
-using Org.BouncyCastle.Crypto.Agreement;
|
|
|
using Org.BouncyCastle.Crypto.Generators;
|
|
|
using Org.BouncyCastle.Crypto.Kems;
|
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
|
@@ -12,10 +11,9 @@ using Renci.SshNet.Messages.Transport;
|
|
|
|
|
|
namespace Renci.SshNet.Security
|
|
|
{
|
|
|
- internal sealed class KeyExchangeMLKem768X25519Sha256 : KeyExchangeEC
|
|
|
+ internal sealed class KeyExchangeMLKem768X25519Sha256 : KeyExchangeECCurve25519
|
|
|
{
|
|
|
private MLKemDecapsulator _mlkemDecapsulator;
|
|
|
- private X25519Agreement _x25519Agreement;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets algorithm name.
|
|
|
@@ -37,10 +35,8 @@ namespace Renci.SshNet.Security
|
|
|
}
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
- public override void Start(Session session, KeyExchangeInitMessage message, bool sendClientInitMessage)
|
|
|
+ protected override void StartImpl()
|
|
|
{
|
|
|
- base.Start(session, message, sendClientInitMessage);
|
|
|
-
|
|
|
Session.RegisterMessage("SSH_MSG_KEX_HYBRID_REPLY");
|
|
|
|
|
|
Session.KeyExchangeHybridReplyMessageReceived += Session_KeyExchangeHybridReplyMessageReceived;
|
|
|
@@ -52,28 +48,18 @@ namespace Renci.SshNet.Security
|
|
|
_mlkemDecapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_768);
|
|
|
_mlkemDecapsulator.Init(mlkem768KeyPair.Private);
|
|
|
|
|
|
- var x25519KeyPairGenerator = new X25519KeyPairGenerator();
|
|
|
- x25519KeyPairGenerator.Init(new X25519KeyGenerationParameters(CryptoAbstraction.SecureRandom));
|
|
|
- var x25519KeyPair = x25519KeyPairGenerator.GenerateKeyPair();
|
|
|
-
|
|
|
- _x25519Agreement = new X25519Agreement();
|
|
|
- _x25519Agreement.Init(x25519KeyPair.Private);
|
|
|
-
|
|
|
var mlkem768PublicKey = ((MLKemPublicKeyParameters)mlkem768KeyPair.Public).GetEncoded();
|
|
|
- var x25519PublicKey = ((X25519PublicKeyParameters)x25519KeyPair.Public).GetEncoded();
|
|
|
+
|
|
|
+ var x25519PublicKey = _impl.GenerateClientPublicKey();
|
|
|
|
|
|
_clientExchangeValue = mlkem768PublicKey.Concat(x25519PublicKey);
|
|
|
|
|
|
SendMessage(new KeyExchangeHybridInitMessage(_clientExchangeValue));
|
|
|
}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Finishes key exchange algorithm.
|
|
|
- /// </summary>
|
|
|
- public override void Finish()
|
|
|
+ /// <inheritdoc/>
|
|
|
+ protected override void FinishImpl()
|
|
|
{
|
|
|
- base.Finish();
|
|
|
-
|
|
|
Session.KeyExchangeHybridReplyMessageReceived -= Session_KeyExchangeHybridReplyMessageReceived;
|
|
|
}
|
|
|
|
|
|
@@ -114,21 +100,20 @@ namespace Renci.SshNet.Security
|
|
|
_hostKey = hostKey;
|
|
|
_signature = signature;
|
|
|
|
|
|
- if (serverExchangeValue.Length != _mlkemDecapsulator.EncapsulationLength + _x25519Agreement.AgreementSize)
|
|
|
+ if (serverExchangeValue.Length != _mlkemDecapsulator.EncapsulationLength + X25519PublicKeyParameters.KeySize)
|
|
|
{
|
|
|
throw new SshConnectionException(
|
|
|
string.Format(CultureInfo.CurrentCulture, "Bad S_Reply length: {0}.", serverExchangeValue.Length),
|
|
|
DisconnectReason.KeyExchangeFailed);
|
|
|
}
|
|
|
|
|
|
- var secret = new byte[_mlkemDecapsulator.SecretLength + _x25519Agreement.AgreementSize];
|
|
|
+ var mlkemSecret = new byte[_mlkemDecapsulator.SecretLength];
|
|
|
|
|
|
- _mlkemDecapsulator.Decapsulate(serverExchangeValue, 0, _mlkemDecapsulator.EncapsulationLength, secret, 0, _mlkemDecapsulator.SecretLength);
|
|
|
+ _mlkemDecapsulator.Decapsulate(serverExchangeValue, 0, _mlkemDecapsulator.EncapsulationLength, mlkemSecret, 0, _mlkemDecapsulator.SecretLength);
|
|
|
|
|
|
- var x25519PublicKey = new X25519PublicKeyParameters(serverExchangeValue, _mlkemDecapsulator.EncapsulationLength);
|
|
|
- _x25519Agreement.CalculateAgreement(x25519PublicKey, secret, _mlkemDecapsulator.SecretLength);
|
|
|
+ var x25519Agreement = _impl.CalculateAgreement(serverExchangeValue.Take(_mlkemDecapsulator.EncapsulationLength, X25519PublicKeyParameters.KeySize));
|
|
|
|
|
|
- SharedKey = CryptoAbstraction.HashSHA256(secret);
|
|
|
+ SharedKey = CryptoAbstraction.HashSHA256(mlkemSecret.Concat(x25519Agreement));
|
|
|
}
|
|
|
}
|
|
|
}
|