You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

AEADAesGcmNativeEncryptor.cs 3.5 kB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Security.Cryptography;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace Shadowsocks.Encryption.AEAD
  8. {
  9. public class AEADAesGcmNativeEncryptor : AEADEncryptor
  10. {
  11. public AEADAesGcmNativeEncryptor(string method, string password) : base(method, password)
  12. {
  13. }
  14. #region Cipher Info
  15. private static readonly Dictionary<string, CipherInfo> _ciphers = new Dictionary<string, CipherInfo>
  16. {
  17. {"aes-128-gcm", new CipherInfo("aes-128-gcm", 16, 16, 12, 16, CipherFamily.AesGcm)},
  18. {"aes-192-gcm", new CipherInfo("aes-192-gcm", 24, 24, 12, 16, CipherFamily.AesGcm)},
  19. {"aes-256-gcm", new CipherInfo("aes-256-gcm", 32, 32, 12, 16, CipherFamily.AesGcm)},
  20. };
  21. protected override Dictionary<string, CipherInfo> getCiphers()
  22. {
  23. return _ciphers;
  24. }
  25. public static Dictionary<string, CipherInfo> SupportedCiphers()
  26. {
  27. return _ciphers;
  28. }
  29. #endregion
  30. public override void cipherDecrypt(byte[] ciphertext, uint clen, byte[] plaintext, ref uint plen)
  31. {
  32. using (var aes = new AesGcm(sessionKey))
  33. {
  34. byte[] tag = new byte[tagLen];
  35. byte[] cipherWithoutTag = new byte[clen];
  36. Array.Copy(ciphertext, 0, cipherWithoutTag, 0, clen - tagLen);
  37. Array.Copy(ciphertext, clen - tagLen, tag, 0, tagLen);
  38. aes.Decrypt(nonce, ciphertext, cipherWithoutTag, tag);
  39. }
  40. }
  41. public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)
  42. {
  43. using (var aes = new AesGcm(sessionKey))
  44. {
  45. byte[] tag = new byte[tagLen];
  46. byte[] cipherWithoutTag = new byte[clen];
  47. aes.Encrypt(nonce, plaintext, cipherWithoutTag, tag);
  48. cipherWithoutTag.CopyTo(ciphertext, 0);
  49. tag.CopyTo(ciphertext, clen);
  50. }
  51. }
  52. public override byte[] CipherDecrypt2(byte[] cipher)
  53. {
  54. var (cipherMem, tagMem) = GetCipherTextAndTagMem(cipher);
  55. Span<byte> plainMem = new Span<byte>(new byte[cipherMem.Length]);
  56. using var aes = new AesGcm(sessionKey);
  57. aes.Decrypt(nonce.AsSpan(), cipherMem.Span, tagMem.Span, plainMem);
  58. return plainMem.ToArray();
  59. }
  60. public override byte[] CipherEncrypt2(byte[] plain)
  61. {
  62. Span<byte> d = new Span<byte>(new byte[plain.Length + tagLen]);
  63. using var aes = new AesGcm(sessionKey);
  64. aes.Encrypt(nonce.AsSpan(), plain.AsSpan(), d.Slice(0, plain.Length), d.Slice(plain.Length));
  65. return d.ToArray();
  66. }
  67. public override int CipherEncrypt(Span<byte> plain, Span<byte> cipher)
  68. {
  69. using var aes = new AesGcm(sessionKey);
  70. aes.Encrypt(nonce.AsSpan(), plain, cipher.Slice(0, plain.Length), cipher.Slice(plain.Length, tagLen));
  71. return plain.Length + tagLen;
  72. }
  73. public override int CipherDecrypt(Span<byte> plain, Span<byte> cipher)
  74. {
  75. int clen = cipher.Length - tagLen;
  76. using var aes = new AesGcm(sessionKey);
  77. aes.Decrypt(nonce.AsSpan(), plain, cipher.Slice(0, clen), cipher.Slice(clen));
  78. return clen;
  79. }
  80. }
  81. }