IesEngine.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Math;
  6. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  7. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
  8. {
  9. /**
  10. * support class for constructing intergrated encryption ciphers
  11. * for doing basic message exchanges on top of key agreement ciphers
  12. */
  13. public class IesEngine
  14. {
  15. private readonly IBasicAgreement agree;
  16. private readonly IDerivationFunction kdf;
  17. private readonly IMac mac;
  18. private readonly BufferedBlockCipher cipher;
  19. private readonly byte[] macBuf;
  20. private bool forEncryption;
  21. private ICipherParameters privParam, pubParam;
  22. private IesParameters param;
  23. /**
  24. * set up for use with stream mode, where the key derivation function
  25. * is used to provide a stream of bytes to xor with the message.
  26. *
  27. * @param agree the key agreement used as the basis for the encryption
  28. * @param kdf the key derivation function used for byte generation
  29. * @param mac the message authentication code generator for the message
  30. */
  31. public IesEngine(
  32. IBasicAgreement agree,
  33. IDerivationFunction kdf,
  34. IMac mac)
  35. {
  36. this.agree = agree;
  37. this.kdf = kdf;
  38. this.mac = mac;
  39. this.macBuf = new byte[mac.GetMacSize()];
  40. // this.cipher = null;
  41. }
  42. /**
  43. * set up for use in conjunction with a block cipher to handle the
  44. * message.
  45. *
  46. * @param agree the key agreement used as the basis for the encryption
  47. * @param kdf the key derivation function used for byte generation
  48. * @param mac the message authentication code generator for the message
  49. * @param cipher the cipher to used for encrypting the message
  50. */
  51. public IesEngine(
  52. IBasicAgreement agree,
  53. IDerivationFunction kdf,
  54. IMac mac,
  55. BufferedBlockCipher cipher)
  56. {
  57. this.agree = agree;
  58. this.kdf = kdf;
  59. this.mac = mac;
  60. this.macBuf = new byte[mac.GetMacSize()];
  61. this.cipher = cipher;
  62. }
  63. /**
  64. * Initialise the encryptor.
  65. *
  66. * @param forEncryption whether or not this is encryption/decryption.
  67. * @param privParam our private key parameters
  68. * @param pubParam the recipient's/sender's public key parameters
  69. * @param param encoding and derivation parameters.
  70. */
  71. public virtual void Init(
  72. bool forEncryption,
  73. ICipherParameters privParameters,
  74. ICipherParameters pubParameters,
  75. ICipherParameters iesParameters)
  76. {
  77. this.forEncryption = forEncryption;
  78. this.privParam = privParameters;
  79. this.pubParam = pubParameters;
  80. this.param = (IesParameters)iesParameters;
  81. }
  82. private byte[] DecryptBlock(
  83. byte[] in_enc,
  84. int inOff,
  85. int inLen,
  86. byte[] z)
  87. {
  88. byte[] M = null;
  89. KeyParameter macKey = null;
  90. KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
  91. int macKeySize = param.MacKeySize;
  92. kdf.Init(kParam);
  93. // Ensure that the length of the input is greater than the MAC in bytes
  94. if (inLen < mac.GetMacSize())
  95. throw new InvalidCipherTextException("Length of input must be greater than the MAC");
  96. inLen -= mac.GetMacSize();
  97. if (cipher == null) // stream mode
  98. {
  99. byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8));
  100. M = new byte[inLen];
  101. for (int i = 0; i != inLen; i++)
  102. {
  103. M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]);
  104. }
  105. macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8));
  106. }
  107. else
  108. {
  109. int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
  110. byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8));
  111. cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8)));
  112. M = cipher.DoFinal(in_enc, inOff, inLen);
  113. macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8));
  114. }
  115. byte[] macIV = param.GetEncodingV();
  116. mac.Init(macKey);
  117. mac.BlockUpdate(in_enc, inOff, inLen);
  118. mac.BlockUpdate(macIV, 0, macIV.Length);
  119. mac.DoFinal(macBuf, 0);
  120. inOff += inLen;
  121. byte[] T1 = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length);
  122. if (!Arrays.ConstantTimeAreEqual(T1, macBuf))
  123. throw (new InvalidCipherTextException("Invalid MAC."));
  124. return M;
  125. }
  126. private byte[] EncryptBlock(
  127. byte[] input,
  128. int inOff,
  129. int inLen,
  130. byte[] z)
  131. {
  132. byte[] C = null;
  133. KeyParameter macKey = null;
  134. KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
  135. int c_text_length = 0;
  136. int macKeySize = param.MacKeySize;
  137. if (cipher == null) // stream mode
  138. {
  139. byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8));
  140. C = new byte[inLen + mac.GetMacSize()];
  141. c_text_length = inLen;
  142. for (int i = 0; i != inLen; i++)
  143. {
  144. C[i] = (byte)(input[inOff + i] ^ Buffer[i]);
  145. }
  146. macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8));
  147. }
  148. else
  149. {
  150. int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
  151. byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8));
  152. cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8)));
  153. c_text_length = cipher.GetOutputSize(inLen);
  154. byte[] tmp = new byte[c_text_length];
  155. int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0);
  156. len += cipher.DoFinal(tmp, len);
  157. C = new byte[len + mac.GetMacSize()];
  158. c_text_length = len;
  159. Array.Copy(tmp, 0, C, 0, len);
  160. macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8));
  161. }
  162. byte[] macIV = param.GetEncodingV();
  163. mac.Init(macKey);
  164. mac.BlockUpdate(C, 0, c_text_length);
  165. mac.BlockUpdate(macIV, 0, macIV.Length);
  166. //
  167. // return the message and it's MAC
  168. //
  169. mac.DoFinal(C, c_text_length);
  170. return C;
  171. }
  172. private byte[] GenerateKdfBytes(
  173. KdfParameters kParam,
  174. int length)
  175. {
  176. byte[] buf = new byte[length];
  177. kdf.Init(kParam);
  178. kdf.GenerateBytes(buf, 0, buf.Length);
  179. return buf;
  180. }
  181. public virtual byte[] ProcessBlock(
  182. byte[] input,
  183. int inOff,
  184. int inLen)
  185. {
  186. agree.Init(privParam);
  187. BigInteger z = agree.CalculateAgreement(pubParam);
  188. byte[] zBytes = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z);
  189. try
  190. {
  191. return forEncryption
  192. ? EncryptBlock(input, inOff, inLen, zBytes)
  193. : DecryptBlock(input, inOff, inLen, zBytes);
  194. }
  195. finally
  196. {
  197. Array.Clear(zBytes, 0, zBytes.Length);
  198. }
  199. }
  200. }
  201. }
  202. #pragma warning restore
  203. #endif