DrbgUtilities.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. using System.Collections;
  5. using BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities;
  6. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Crypto.Prng.Drbg
  7. {
  8. internal class DrbgUtilities
  9. {
  10. private static readonly IDictionary maxSecurityStrengths = BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateHashtable();
  11. static DrbgUtilities()
  12. {
  13. maxSecurityStrengths.Add("SHA-1", 128);
  14. maxSecurityStrengths.Add("SHA-224", 192);
  15. maxSecurityStrengths.Add("SHA-256", 256);
  16. maxSecurityStrengths.Add("SHA-384", 256);
  17. maxSecurityStrengths.Add("SHA-512", 256);
  18. maxSecurityStrengths.Add("SHA-512/224", 192);
  19. maxSecurityStrengths.Add("SHA-512/256", 256);
  20. }
  21. internal static int GetMaxSecurityStrength(IDigest d)
  22. {
  23. return (int)maxSecurityStrengths[d.AlgorithmName];
  24. }
  25. internal static int GetMaxSecurityStrength(IMac m)
  26. {
  27. string name = m.AlgorithmName;
  28. return (int)maxSecurityStrengths[name.Substring(0, name.IndexOf("/"))];
  29. }
  30. /**
  31. * Used by both Dual EC and Hash.
  32. */
  33. internal static byte[] HashDF(IDigest digest, byte[] seedMaterial, int seedLength)
  34. {
  35. // 1. temp = the Null string.
  36. // 2. .
  37. // 3. counter = an 8-bit binary value representing the integer "1".
  38. // 4. For i = 1 to len do
  39. // Comment : In step 4.1, no_of_bits_to_return
  40. // is used as a 32-bit string.
  41. // 4.1 temp = temp || Hash (counter || no_of_bits_to_return ||
  42. // input_string).
  43. // 4.2 counter = counter + 1.
  44. // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp.
  45. // 6. Return SUCCESS and requested_bits.
  46. byte[] temp = new byte[(seedLength + 7) / 8];
  47. int len = temp.Length / digest.GetDigestSize();
  48. int counter = 1;
  49. byte[] dig = new byte[digest.GetDigestSize()];
  50. for (int i = 0; i <= len; i++)
  51. {
  52. digest.Update((byte)counter);
  53. digest.Update((byte)(seedLength >> 24));
  54. digest.Update((byte)(seedLength >> 16));
  55. digest.Update((byte)(seedLength >> 8));
  56. digest.Update((byte)seedLength);
  57. digest.BlockUpdate(seedMaterial, 0, seedMaterial.Length);
  58. digest.DoFinal(dig, 0);
  59. int bytesToCopy = ((temp.Length - i * dig.Length) > dig.Length)
  60. ? dig.Length
  61. : (temp.Length - i * dig.Length);
  62. Array.Copy(dig, 0, temp, i * dig.Length, bytesToCopy);
  63. counter++;
  64. }
  65. // do a left shift to get rid of excess bits.
  66. if (seedLength % 8 != 0)
  67. {
  68. int shift = 8 - (seedLength % 8);
  69. uint carry = 0;
  70. for (int i = 0; i != temp.Length; i++)
  71. {
  72. uint b = temp[i];
  73. temp[i] = (byte)((b >> shift) | (carry << (8 - shift)));
  74. carry = b;
  75. }
  76. }
  77. return temp;
  78. }
  79. internal static bool IsTooLarge(byte[] bytes, int maxBytes)
  80. {
  81. return bytes != null && bytes.Length > maxBytes;
  82. }
  83. }
  84. }
  85. #pragma warning restore
  86. #endif