-
-
Notifications
You must be signed in to change notification settings - Fork 939
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AesGcmCipher uses BouncyCastle as a fallback if BCL does not support. (…
…#1450) * [AesGcmCipher] Use BouncyCastle as a fallback if BCL does not support. * Switch back to collection initializer * Remove conditional compilation * Throw SshConnectionException with Reason MacError when authentication tag mismatch * Separate BCL and BouncyCastle implementation * Update AesGcmCipher.BclImpl.cs * Naming enhancement * Remove empty line * Disable S1199. See #1371 (comment) * Set InnerException when MAC error. Remove Message check. * Store KeyParameter as private field * Use GcmCipher.ProcessAadBytes to avoid the copy of associated data * Move nonce to constructor to avoid creating AeadParameters each packet * Use const int for tag size --------- Co-authored-by: Wojciech Nagórski <wojtpl2@gmail.com>
- Loading branch information
1 parent
1af0169
commit ebb31bb
Showing
10 changed files
with
198 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
72 changes: 72 additions & 0 deletions
72
src/Renci.SshNet/Security/Cryptography/Ciphers/AesGcmCipher.BclImpl.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#if NET6_0_OR_GREATER | ||
using System; | ||
using System.Security.Cryptography; | ||
|
||
using Renci.SshNet.Common; | ||
using Renci.SshNet.Messages.Transport; | ||
|
||
namespace Renci.SshNet.Security.Cryptography.Ciphers | ||
{ | ||
internal partial class AesGcmCipher | ||
{ | ||
private sealed class BclImpl : Impl | ||
{ | ||
private readonly AesGcm _aesGcm; | ||
private readonly byte[] _nonce; | ||
|
||
public BclImpl(byte[] key, byte[] nonce) | ||
{ | ||
#if NET8_0_OR_GREATER | ||
_aesGcm = new AesGcm(key, TagSizeInBytes); | ||
#else | ||
_aesGcm = new AesGcm(key); | ||
#endif | ||
_nonce = nonce; | ||
} | ||
|
||
public override void Encrypt(byte[] input, int plainTextOffset, int plainTextLength, int associatedDataOffset, int associatedDataLength, byte[] output, int cipherTextOffset) | ||
{ | ||
var cipherTextLength = plainTextLength; | ||
var plainText = new ReadOnlySpan<byte>(input, plainTextOffset, plainTextLength); | ||
var cipherText = new Span<byte>(output, cipherTextOffset, cipherTextLength); | ||
var tag = new Span<byte>(output, cipherTextOffset + cipherTextLength, TagSizeInBytes); | ||
var associatedData = new ReadOnlySpan<byte>(input, associatedDataOffset, associatedDataLength); | ||
|
||
_aesGcm.Encrypt(_nonce, plainText, cipherText, tag, associatedData); | ||
} | ||
|
||
public override void Decrypt(byte[] input, int cipherTextOffset, int cipherTextLength, int associatedDataOffset, int associatedDataLength, byte[] output, int plainTextOffset) | ||
{ | ||
var plainTextLength = cipherTextLength; | ||
var cipherText = new ReadOnlySpan<byte>(input, cipherTextOffset, cipherTextLength); | ||
var tag = new ReadOnlySpan<byte>(input, cipherTextOffset + cipherTextLength, TagSizeInBytes); | ||
var plainText = new Span<byte>(output, plainTextOffset, plainTextLength); | ||
var associatedData = new ReadOnlySpan<byte>(input, associatedDataOffset, associatedDataLength); | ||
|
||
try | ||
{ | ||
_aesGcm.Decrypt(_nonce, cipherText, tag, output, associatedData); | ||
} | ||
#if NET8_0_OR_GREATER | ||
catch (AuthenticationTagMismatchException ex) | ||
#else | ||
catch (CryptographicException ex) | ||
#endif | ||
{ | ||
throw new SshConnectionException("MAC error", DisconnectReason.MacError, ex); | ||
} | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
base.Dispose(disposing); | ||
|
||
if (disposing) | ||
{ | ||
_aesGcm.Dispose(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
#endif |
48 changes: 48 additions & 0 deletions
48
src/Renci.SshNet/Security/Cryptography/Ciphers/AesGcmCipher.BouncyCastleImpl.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
using Org.BouncyCastle.Crypto; | ||
using Org.BouncyCastle.Crypto.Engines; | ||
using Org.BouncyCastle.Crypto.Modes; | ||
using Org.BouncyCastle.Crypto.Parameters; | ||
|
||
using Renci.SshNet.Common; | ||
using Renci.SshNet.Messages.Transport; | ||
|
||
namespace Renci.SshNet.Security.Cryptography.Ciphers | ||
{ | ||
internal partial class AesGcmCipher | ||
{ | ||
private sealed class BouncyCastleImpl : Impl | ||
{ | ||
private readonly GcmBlockCipher _cipher; | ||
private readonly AeadParameters _parameters; | ||
|
||
public BouncyCastleImpl(byte[] key, byte[] nonce) | ||
{ | ||
_cipher = new GcmBlockCipher(new AesEngine()); | ||
_parameters = new AeadParameters(new KeyParameter(key), TagSizeInBytes * 8, nonce); | ||
} | ||
|
||
public override void Encrypt(byte[] input, int plainTextOffset, int plainTextLength, int associatedDataOffset, int associatedDataLength, byte[] output, int cipherTextOffset) | ||
{ | ||
_cipher.Init(forEncryption: true, _parameters); | ||
_cipher.ProcessAadBytes(input, associatedDataOffset, associatedDataLength); | ||
var cipherTextLength = _cipher.ProcessBytes(input, plainTextOffset, plainTextLength, output, cipherTextOffset); | ||
_ = _cipher.DoFinal(output, cipherTextOffset + cipherTextLength); | ||
} | ||
|
||
public override void Decrypt(byte[] input, int cipherTextOffset, int cipherTextLength, int associatedDataOffset, int associatedDataLength, byte[] output, int plainTextOffset) | ||
{ | ||
_cipher.Init(forEncryption: false, _parameters); | ||
_cipher.ProcessAadBytes(input, associatedDataOffset, associatedDataLength); | ||
var plainTextLength = _cipher.ProcessBytes(input, cipherTextOffset, cipherTextLength + TagSizeInBytes, output, plainTextOffset); | ||
try | ||
{ | ||
_ = _cipher.DoFinal(output, plainTextLength); | ||
} | ||
catch (InvalidCipherTextException ex) | ||
{ | ||
throw new SshConnectionException("MAC error", DisconnectReason.MacError, ex); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters