GcmUtilities.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using Org.BouncyCastle.Crypto.Utilities;
  4. using Org.BouncyCastle.Utilities;
  5. namespace Org.BouncyCastle.Crypto.Modes.Gcm
  6. {
  7. internal abstract class GcmUtilities
  8. {
  9. private const uint E1 = 0xe1000000;
  10. private const ulong E1L = (ulong)E1 << 32;
  11. private static uint[] GenerateLookup()
  12. {
  13. uint[] lookup = new uint[256];
  14. for (int c = 0; c < 256; ++c)
  15. {
  16. uint v = 0;
  17. for (int i = 7; i >= 0; --i)
  18. {
  19. if ((c & (1 << i)) != 0)
  20. {
  21. v ^= (E1 >> (7 - i));
  22. }
  23. }
  24. lookup[c] = v;
  25. }
  26. return lookup;
  27. }
  28. private static readonly uint[] LOOKUP = GenerateLookup();
  29. internal static byte[] OneAsBytes()
  30. {
  31. byte[] tmp = new byte[16];
  32. tmp[0] = 0x80;
  33. return tmp;
  34. }
  35. internal static uint[] OneAsUints()
  36. {
  37. uint[] tmp = new uint[4];
  38. tmp[0] = 0x80000000;
  39. return tmp;
  40. }
  41. internal static ulong[] OneAsUlongs()
  42. {
  43. ulong[] tmp = new ulong[2];
  44. tmp[0] = 1UL << 63;
  45. return tmp;
  46. }
  47. internal static byte[] AsBytes(uint[] x)
  48. {
  49. return Pack.UInt32_To_BE(x);
  50. }
  51. internal static void AsBytes(uint[] x, byte[] z)
  52. {
  53. Pack.UInt32_To_BE(x, z, 0);
  54. }
  55. internal static byte[] AsBytes(ulong[] x)
  56. {
  57. byte[] z = new byte[16];
  58. Pack.UInt64_To_BE(x, z, 0);
  59. return z;
  60. }
  61. internal static void AsBytes(ulong[] x, byte[] z)
  62. {
  63. Pack.UInt64_To_BE(x, z, 0);
  64. }
  65. internal static uint[] AsUints(byte[] bs)
  66. {
  67. uint[] output = new uint[4];
  68. Pack.BE_To_UInt32(bs, 0, output);
  69. return output;
  70. }
  71. internal static void AsUints(byte[] bs, uint[] output)
  72. {
  73. Pack.BE_To_UInt32(bs, 0, output);
  74. }
  75. internal static ulong[] AsUlongs(byte[] x)
  76. {
  77. ulong[] z = new ulong[2];
  78. Pack.BE_To_UInt64(x, 0, z);
  79. return z;
  80. }
  81. public static void AsUlongs(byte[] x, ulong[] z)
  82. {
  83. Pack.BE_To_UInt64(x, 0, z);
  84. }
  85. internal static void Multiply(byte[] x, byte[] y)
  86. {
  87. uint[] t1 = GcmUtilities.AsUints(x);
  88. uint[] t2 = GcmUtilities.AsUints(y);
  89. GcmUtilities.Multiply(t1, t2);
  90. GcmUtilities.AsBytes(t1, x);
  91. }
  92. internal static void Multiply(uint[] x, uint[] y)
  93. {
  94. uint r00 = x[0], r01 = x[1], r02 = x[2], r03 = x[3];
  95. uint r10 = 0, r11 = 0, r12 = 0, r13 = 0;
  96. for (int i = 0; i < 4; ++i)
  97. {
  98. int bits = (int)y[i];
  99. for (int j = 0; j < 32; ++j)
  100. {
  101. uint m1 = (uint)(bits >> 31); bits <<= 1;
  102. r10 ^= (r00 & m1);
  103. r11 ^= (r01 & m1);
  104. r12 ^= (r02 & m1);
  105. r13 ^= (r03 & m1);
  106. uint m2 = (uint)((int)(r03 << 31) >> 8);
  107. r03 = (r03 >> 1) | (r02 << 31);
  108. r02 = (r02 >> 1) | (r01 << 31);
  109. r01 = (r01 >> 1) | (r00 << 31);
  110. r00 = (r00 >> 1) ^ (m2 & E1);
  111. }
  112. }
  113. x[0] = r10;
  114. x[1] = r11;
  115. x[2] = r12;
  116. x[3] = r13;
  117. }
  118. internal static void Multiply(ulong[] x, ulong[] y)
  119. {
  120. ulong r00 = x[0], r01 = x[1], r10 = 0, r11 = 0;
  121. for (int i = 0; i < 2; ++i)
  122. {
  123. long bits = (long)y[i];
  124. for (int j = 0; j < 64; ++j)
  125. {
  126. ulong m1 = (ulong)(bits >> 63); bits <<= 1;
  127. r10 ^= (r00 & m1);
  128. r11 ^= (r01 & m1);
  129. ulong m2 = (ulong)((long)(r01 << 63) >> 8);
  130. r01 = (r01 >> 1) | (r00 << 63);
  131. r00 = (r00 >> 1) ^ (m2 & E1L);
  132. }
  133. }
  134. x[0] = r10;
  135. x[1] = r11;
  136. }
  137. // P is the value with only bit i=1 set
  138. internal static void MultiplyP(uint[] x)
  139. {
  140. uint m = (uint)((int)ShiftRight(x) >> 8);
  141. x[0] ^= (m & E1);
  142. }
  143. internal static void MultiplyP(uint[] x, uint[] z)
  144. {
  145. uint m = (uint)((int)ShiftRight(x, z) >> 8);
  146. z[0] ^= (m & E1);
  147. }
  148. internal static void MultiplyP8(uint[] x)
  149. {
  150. // for (int i = 8; i != 0; --i)
  151. // {
  152. // MultiplyP(x);
  153. // }
  154. uint c = ShiftRightN(x, 8);
  155. x[0] ^= LOOKUP[c >> 24];
  156. }
  157. internal static void MultiplyP8(uint[] x, uint[] y)
  158. {
  159. uint c = ShiftRightN(x, 8, y);
  160. y[0] ^= LOOKUP[c >> 24];
  161. }
  162. internal static uint ShiftRight(uint[] x)
  163. {
  164. uint b = x[0];
  165. x[0] = b >> 1;
  166. uint c = b << 31;
  167. b = x[1];
  168. x[1] = (b >> 1) | c;
  169. c = b << 31;
  170. b = x[2];
  171. x[2] = (b >> 1) | c;
  172. c = b << 31;
  173. b = x[3];
  174. x[3] = (b >> 1) | c;
  175. return b << 31;
  176. }
  177. internal static uint ShiftRight(uint[] x, uint[] z)
  178. {
  179. uint b = x[0];
  180. z[0] = b >> 1;
  181. uint c = b << 31;
  182. b = x[1];
  183. z[1] = (b >> 1) | c;
  184. c = b << 31;
  185. b = x[2];
  186. z[2] = (b >> 1) | c;
  187. c = b << 31;
  188. b = x[3];
  189. z[3] = (b >> 1) | c;
  190. return b << 31;
  191. }
  192. internal static uint ShiftRightN(uint[] x, int n)
  193. {
  194. uint b = x[0]; int nInv = 32 - n;
  195. x[0] = b >> n;
  196. uint c = b << nInv;
  197. b = x[1];
  198. x[1] = (b >> n) | c;
  199. c = b << nInv;
  200. b = x[2];
  201. x[2] = (b >> n) | c;
  202. c = b << nInv;
  203. b = x[3];
  204. x[3] = (b >> n) | c;
  205. return b << nInv;
  206. }
  207. internal static uint ShiftRightN(uint[] x, int n, uint[] z)
  208. {
  209. uint b = x[0]; int nInv = 32 - n;
  210. z[0] = b >> n;
  211. uint c = b << nInv;
  212. b = x[1];
  213. z[1] = (b >> n) | c;
  214. c = b << nInv;
  215. b = x[2];
  216. z[2] = (b >> n) | c;
  217. c = b << nInv;
  218. b = x[3];
  219. z[3] = (b >> n) | c;
  220. return b << nInv;
  221. }
  222. #if true //!ENABLE_IL2CPP || UNITY_WEBGL
  223. internal static void Xor(byte[] x, byte[] y)
  224. {
  225. int i = 0;
  226. do
  227. {
  228. x[i] ^= y[i]; ++i;
  229. x[i] ^= y[i]; ++i;
  230. x[i] ^= y[i]; ++i;
  231. x[i] ^= y[i]; ++i;
  232. }
  233. while (i < 16);
  234. }
  235. #else
  236. internal static unsafe void Xor(byte[] x, byte[] y)
  237. {
  238. //int i = 0;
  239. fixed (byte* px = x)
  240. fixed (byte* py = y)
  241. {
  242. //do
  243. //{
  244. // px[i] ^= py[i]; ++i;
  245. // px[i] ^= py[i]; ++i;
  246. // px[i] ^= py[i]; ++i;
  247. // px[i] ^= py[i]; ++i;
  248. //}
  249. //while (i < 16);
  250. px[0] ^= py[0];
  251. px[1] ^= py[1];
  252. px[2] ^= py[2];
  253. px[3] ^= py[3];
  254. px[4] ^= py[4];
  255. px[5] ^= py[5];
  256. px[6] ^= py[6];
  257. px[7] ^= py[7];
  258. px[8] ^= py[8];
  259. px[9] ^= py[9];
  260. px[10] ^= py[10];
  261. px[11] ^= py[11];
  262. px[12] ^= py[12];
  263. px[13] ^= py[13];
  264. px[14] ^= py[14];
  265. px[15] ^= py[15];
  266. }
  267. }
  268. #endif
  269. #if true //!ENABLE_IL2CPP || UNITY_WEBGL
  270. internal static void Xor(byte[] x, byte[] y, int yOff, int yLen)
  271. {
  272. while (--yLen >= 0)
  273. {
  274. x[yLen] ^= y[yOff + yLen];
  275. }
  276. }
  277. #else
  278. internal static unsafe void Xor(byte[] x, byte[] y, int yOff, int yLen)
  279. {
  280. fixed (byte* px = x)
  281. fixed(byte* py = y)
  282. while (--yLen >= 0)
  283. {
  284. px[yLen] ^= py[yOff + yLen];
  285. }
  286. }
  287. #endif
  288. internal static void Xor(byte[] x, byte[] y, byte[] z)
  289. {
  290. int i = 0;
  291. do
  292. {
  293. z[i] = (byte)(x[i] ^ y[i]); ++i;
  294. z[i] = (byte)(x[i] ^ y[i]); ++i;
  295. z[i] = (byte)(x[i] ^ y[i]); ++i;
  296. z[i] = (byte)(x[i] ^ y[i]); ++i;
  297. }
  298. while (i < 16);
  299. }
  300. #if true //!ENABLE_IL2CPP || UNITY_WEBGL
  301. internal static void Xor(uint[] x, uint[] y)
  302. {
  303. x[0] ^= y[0];
  304. x[1] ^= y[1];
  305. x[2] ^= y[2];
  306. x[3] ^= y[3];
  307. }
  308. #else
  309. internal static unsafe void Xor(uint[] x, uint[] y)
  310. {
  311. fixed (uint* px = x)
  312. fixed (uint* py = y)
  313. {
  314. px[0] ^= py[0];
  315. px[1] ^= py[1];
  316. px[2] ^= py[2];
  317. px[3] ^= py[3];
  318. }
  319. }
  320. #endif
  321. internal static void Xor(uint[] x, uint[] y, uint[] z)
  322. {
  323. z[0] = x[0] ^ y[0];
  324. z[1] = x[1] ^ y[1];
  325. z[2] = x[2] ^ y[2];
  326. z[3] = x[3] ^ y[3];
  327. }
  328. internal static void Xor(ulong[] x, ulong[] y)
  329. {
  330. x[0] ^= y[0];
  331. x[1] ^= y[1];
  332. }
  333. internal static void Xor(ulong[] x, ulong[] y, ulong[] z)
  334. {
  335. z[0] = x[0] ^ y[0];
  336. z[1] = x[1] ^ y[1];
  337. }
  338. }
  339. }
  340. #endif