DrbgUtilities.cs 3.8 KB

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