VMPCEngine.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Crypto.Parameters;
  4. namespace Org.BouncyCastle.Crypto.Engines
  5. {
  6. public class VmpcEngine
  7. : IStreamCipher
  8. {
  9. /*
  10. * variables to hold the state of the VMPC engine during encryption and
  11. * decryption
  12. */
  13. protected byte n = 0;
  14. protected byte[] P = null;
  15. protected byte s = 0;
  16. protected byte[] workingIV;
  17. protected byte[] workingKey;
  18. public virtual string AlgorithmName
  19. {
  20. get { return "VMPC"; }
  21. }
  22. /**
  23. * initialise a VMPC cipher.
  24. *
  25. * @param forEncryption
  26. * whether or not we are for encryption.
  27. * @param params
  28. * the parameters required to set up the cipher.
  29. * @exception ArgumentException
  30. * if the params argument is inappropriate.
  31. */
  32. public virtual void Init(
  33. bool forEncryption,
  34. ICipherParameters parameters)
  35. {
  36. if (!(parameters is ParametersWithIV))
  37. throw new ArgumentException("VMPC Init parameters must include an IV");
  38. ParametersWithIV ivParams = (ParametersWithIV) parameters;
  39. if (!(ivParams.Parameters is KeyParameter))
  40. throw new ArgumentException("VMPC Init parameters must include a key");
  41. KeyParameter key = (KeyParameter)ivParams.Parameters;
  42. this.workingIV = ivParams.GetIV();
  43. if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
  44. throw new ArgumentException("VMPC requires 1 to 768 bytes of IV");
  45. this.workingKey = key.GetKey();
  46. InitKey(this.workingKey, this.workingIV);
  47. }
  48. protected virtual void InitKey(
  49. byte[] keyBytes,
  50. byte[] ivBytes)
  51. {
  52. s = 0;
  53. P = new byte[256];
  54. for (int i = 0; i < 256; i++)
  55. {
  56. P[i] = (byte) i;
  57. }
  58. for (int m = 0; m < 768; m++)
  59. {
  60. s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
  61. byte temp = P[m & 0xff];
  62. P[m & 0xff] = P[s & 0xff];
  63. P[s & 0xff] = temp;
  64. }
  65. for (int m = 0; m < 768; m++)
  66. {
  67. s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
  68. byte temp = P[m & 0xff];
  69. P[m & 0xff] = P[s & 0xff];
  70. P[s & 0xff] = temp;
  71. }
  72. n = 0;
  73. }
  74. public virtual void ProcessBytes(
  75. byte[] input,
  76. int inOff,
  77. int len,
  78. byte[] output,
  79. int outOff)
  80. {
  81. Check.DataLength(input, inOff, len, "input buffer too short");
  82. Check.OutputLength(output, outOff, len, "output buffer too short");
  83. for (int i = 0; i < len; i++)
  84. {
  85. s = P[(s + P[n & 0xff]) & 0xff];
  86. byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
  87. // encryption
  88. byte temp = P[n & 0xff];
  89. P[n & 0xff] = P[s & 0xff];
  90. P[s & 0xff] = temp;
  91. n = (byte) ((n + 1) & 0xff);
  92. // xor
  93. output[i + outOff] = (byte) (input[i + inOff] ^ z);
  94. }
  95. }
  96. public virtual void Reset()
  97. {
  98. InitKey(this.workingKey, this.workingIV);
  99. }
  100. public virtual byte ReturnByte(
  101. byte input)
  102. {
  103. s = P[(s + P[n & 0xff]) & 0xff];
  104. byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
  105. // encryption
  106. byte temp = P[n & 0xff];
  107. P[n & 0xff] = P[s & 0xff];
  108. P[s & 0xff] = temp;
  109. n = (byte) ((n + 1) & 0xff);
  110. // xor
  111. return (byte) (input ^ z);
  112. }
  113. }
  114. }
  115. #endif