NamedGroup.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. #pragma warning disable
  3. using System;
  4. namespace BestHTTP.SecureProtocol.Org.BouncyCastle.Tls
  5. {
  6. /// <summary>RFC 7919</summary>
  7. public abstract class NamedGroup
  8. {
  9. /*
  10. * RFC 4492 5.1.1
  11. * <p>
  12. * The named curves defined here are those specified in SEC 2 [13]. Note that many of these curves
  13. * are also recommended in ANSI X9.62 [7] and FIPS 186-2 [11]. Values 0xFE00 through 0xFEFF are
  14. * reserved for private use. Values 0xFF01 and 0xFF02 indicate that the client supports arbitrary
  15. * prime and characteristic-2 curves, respectively (the curve parameters must be encoded explicitly
  16. * in ECParameters).
  17. */
  18. public const int sect163k1 = 1;
  19. public const int sect163r1 = 2;
  20. public const int sect163r2 = 3;
  21. public const int sect193r1 = 4;
  22. public const int sect193r2 = 5;
  23. public const int sect233k1 = 6;
  24. public const int sect233r1 = 7;
  25. public const int sect239k1 = 8;
  26. public const int sect283k1 = 9;
  27. public const int sect283r1 = 10;
  28. public const int sect409k1 = 11;
  29. public const int sect409r1 = 12;
  30. public const int sect571k1 = 13;
  31. public const int sect571r1 = 14;
  32. public const int secp160k1 = 15;
  33. public const int secp160r1 = 16;
  34. public const int secp160r2 = 17;
  35. public const int secp192k1 = 18;
  36. public const int secp192r1 = 19;
  37. public const int secp224k1 = 20;
  38. public const int secp224r1 = 21;
  39. public const int secp256k1 = 22;
  40. public const int secp256r1 = 23;
  41. public const int secp384r1 = 24;
  42. public const int secp521r1 = 25;
  43. /*
  44. * RFC 7027
  45. */
  46. public const int brainpoolP256r1 = 26;
  47. public const int brainpoolP384r1 = 27;
  48. public const int brainpoolP512r1 = 28;
  49. /*
  50. * RFC 8422
  51. */
  52. public const int x25519 = 29;
  53. public const int x448 = 30;
  54. /*
  55. * RFC 8734
  56. */
  57. public const int brainpoolP256r1tls13 = 31;
  58. public const int brainpoolP384r1tls13 = 32;
  59. public const int brainpoolP512r1tls13 = 33;
  60. /*
  61. * draft-smyshlyaev-tls12-gost-suites-10
  62. */
  63. public const int GC256A = 34;
  64. public const int GC256B = 35;
  65. public const int GC256C = 36;
  66. public const int GC256D = 37;
  67. public const int GC512A = 38;
  68. public const int GC512B = 39;
  69. public const int GC512C = 40;
  70. /*
  71. * RFC 8998
  72. */
  73. public const int curveSM2 = 41;
  74. /*
  75. * RFC 7919 2. Codepoints in the "Supported Groups Registry" with a high byte of 0x01 (that is,
  76. * between 256 and 511, inclusive) are set aside for FFDHE groups, though only a small number of
  77. * them are initially defined and we do not expect many other FFDHE groups to be added to this
  78. * range. No codepoints outside of this range will be allocated to FFDHE groups.
  79. */
  80. public const int ffdhe2048 = 256;
  81. public const int ffdhe3072 = 257;
  82. public const int ffdhe4096 = 258;
  83. public const int ffdhe6144 = 259;
  84. public const int ffdhe8192 = 260;
  85. /*
  86. * RFC 8446 reserved ffdhe_private_use (0x01FC..0x01FF)
  87. */
  88. /*
  89. * RFC 4492 reserved ecdhe_private_use (0xFE00..0xFEFF)
  90. */
  91. /*
  92. * RFC 4492
  93. */
  94. public const int arbitrary_explicit_prime_curves = 0xFF01;
  95. public const int arbitrary_explicit_char2_curves = 0xFF02;
  96. /* Names of the actual underlying elliptic curves (not necessarily matching the NamedGroup names). */
  97. private static readonly string[] CurveNames = new string[]{ "sect163k1", "sect163r1", "sect163r2", "sect193r1",
  98. "sect193r2", "sect233k1", "sect233r1", "sect239k1", "sect283k1", "sect283r1", "sect409k1", "sect409r1",
  99. "sect571k1", "sect571r1", "secp160k1", "secp160r1", "secp160r2", "secp192k1", "secp192r1", "secp224k1",
  100. "secp224r1", "secp256k1", "secp256r1", "secp384r1", "secp521r1", "brainpoolP256r1", "brainpoolP384r1",
  101. "brainpoolP512r1", "X25519", "X448", "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1",
  102. "Tc26-Gost-3410-12-256-paramSetA", "GostR3410-2001-CryptoPro-A", "GostR3410-2001-CryptoPro-B",
  103. "GostR3410-2001-CryptoPro-C", "Tc26-Gost-3410-12-512-paramSetA", "Tc26-Gost-3410-12-512-paramSetB",
  104. "Tc26-Gost-3410-12-512-paramSetC", "sm2p256v1" };
  105. private static readonly string[] FiniteFieldNames = new string[]{ "ffdhe2048", "ffdhe3072", "ffdhe4096",
  106. "ffdhe6144", "ffdhe8192" };
  107. public static bool CanBeNegotiated(int namedGroup, ProtocolVersion version)
  108. {
  109. if (TlsUtilities.IsTlsV13(version))
  110. {
  111. if ((namedGroup >= sect163k1 && namedGroup <= secp256k1)
  112. || (namedGroup >= brainpoolP256r1 && namedGroup <= brainpoolP512r1)
  113. || (namedGroup >= GC256A && namedGroup <= GC512C)
  114. || (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves))
  115. {
  116. return false;
  117. }
  118. }
  119. else
  120. {
  121. if ((namedGroup >= brainpoolP256r1tls13 && namedGroup <= brainpoolP512r1tls13)
  122. || (namedGroup == curveSM2))
  123. {
  124. return false;
  125. }
  126. }
  127. return IsValid(namedGroup);
  128. }
  129. public static int GetCurveBits(int namedGroup)
  130. {
  131. switch (namedGroup)
  132. {
  133. case secp160k1:
  134. case secp160r1:
  135. case secp160r2:
  136. return 160;
  137. case sect163k1:
  138. case sect163r1:
  139. case sect163r2:
  140. return 163;
  141. case secp192k1:
  142. case secp192r1:
  143. return 192;
  144. case sect193r1:
  145. case sect193r2:
  146. return 193;
  147. case secp224k1:
  148. case secp224r1:
  149. return 224;
  150. case sect233k1:
  151. case sect233r1:
  152. return 233;
  153. case sect239k1:
  154. return 239;
  155. case x25519:
  156. return 252;
  157. case brainpoolP256r1:
  158. case brainpoolP256r1tls13:
  159. case curveSM2:
  160. case GC256A:
  161. case GC256B:
  162. case GC256C:
  163. case GC256D:
  164. case secp256k1:
  165. case secp256r1:
  166. return 256;
  167. case sect283k1:
  168. case sect283r1:
  169. return 283;
  170. case brainpoolP384r1:
  171. case brainpoolP384r1tls13:
  172. case secp384r1:
  173. return 384;
  174. case sect409k1:
  175. case sect409r1:
  176. return 409;
  177. case x448:
  178. return 446;
  179. case brainpoolP512r1:
  180. case brainpoolP512r1tls13:
  181. case GC512A:
  182. case GC512B:
  183. case GC512C:
  184. return 512;
  185. case secp521r1:
  186. return 521;
  187. case sect571k1:
  188. case sect571r1:
  189. return 571;
  190. default:
  191. return 0;
  192. }
  193. }
  194. public static string GetCurveName(int namedGroup)
  195. {
  196. if (RefersToASpecificCurve(namedGroup))
  197. {
  198. return CurveNames[namedGroup - sect163k1];
  199. }
  200. return null;
  201. }
  202. public static int GetFiniteFieldBits(int namedGroup)
  203. {
  204. switch (namedGroup)
  205. {
  206. case ffdhe2048:
  207. return 2048;
  208. case ffdhe3072:
  209. return 3072;
  210. case ffdhe4096:
  211. return 4096;
  212. case ffdhe6144:
  213. return 6144;
  214. case ffdhe8192:
  215. return 8192;
  216. default:
  217. return 0;
  218. }
  219. }
  220. public static string GetFiniteFieldName(int namedGroup)
  221. {
  222. if (RefersToASpecificFiniteField(namedGroup))
  223. {
  224. return FiniteFieldNames[namedGroup - ffdhe2048];
  225. }
  226. return null;
  227. }
  228. public static int GetMaximumChar2CurveBits()
  229. {
  230. return 571;
  231. }
  232. public static int GetMaximumCurveBits()
  233. {
  234. return 571;
  235. }
  236. public static int GetMaximumFiniteFieldBits()
  237. {
  238. return 8192;
  239. }
  240. public static int GetMaximumPrimeCurveBits()
  241. {
  242. return 521;
  243. }
  244. public static string GetName(int namedGroup)
  245. {
  246. if (IsPrivate(namedGroup))
  247. {
  248. return "PRIVATE";
  249. }
  250. switch (namedGroup)
  251. {
  252. case x25519:
  253. return "x25519";
  254. case x448:
  255. return "x448";
  256. case brainpoolP256r1tls13:
  257. return "brainpoolP256r1tls13";
  258. case brainpoolP384r1tls13:
  259. return "brainpoolP384r1tls13";
  260. case brainpoolP512r1tls13:
  261. return "brainpoolP512r1tls13";
  262. case GC256A:
  263. return "GC256A";
  264. case GC256B:
  265. return "GC256B";
  266. case GC256C:
  267. return "GC256C";
  268. case GC256D:
  269. return "GC256D";
  270. case GC512A:
  271. return "GC512A";
  272. case GC512B:
  273. return "GC512B";
  274. case GC512C:
  275. return "GC512C";
  276. case curveSM2:
  277. return "curveSM2";
  278. case arbitrary_explicit_prime_curves:
  279. return "arbitrary_explicit_prime_curves";
  280. case arbitrary_explicit_char2_curves:
  281. return "arbitrary_explicit_char2_curves";
  282. }
  283. string standardName = GetStandardName(namedGroup);
  284. if (null != standardName)
  285. {
  286. return standardName;
  287. }
  288. return "UNKNOWN";
  289. }
  290. public static string GetStandardName(int namedGroup)
  291. {
  292. string curveName = GetCurveName(namedGroup);
  293. if (null != curveName)
  294. {
  295. return curveName;
  296. }
  297. string finiteFieldName = GetFiniteFieldName(namedGroup);
  298. if (null != finiteFieldName)
  299. {
  300. return finiteFieldName;
  301. }
  302. return null;
  303. }
  304. public static string GetText(int namedGroup)
  305. {
  306. return GetName(namedGroup) + "(" + namedGroup + ")";
  307. }
  308. public static bool IsChar2Curve(int namedGroup)
  309. {
  310. return (namedGroup >= sect163k1 && namedGroup <= sect571r1)
  311. || (namedGroup == arbitrary_explicit_char2_curves);
  312. }
  313. public static bool IsPrimeCurve(int namedGroup)
  314. {
  315. return (namedGroup >= secp160k1 && namedGroup <= curveSM2)
  316. || (namedGroup == arbitrary_explicit_prime_curves);
  317. }
  318. public static bool IsPrivate(int namedGroup)
  319. {
  320. return (namedGroup >> 2) == 0x7F || (namedGroup >> 8) == 0xFE;
  321. }
  322. public static bool IsValid(int namedGroup)
  323. {
  324. return RefersToASpecificGroup(namedGroup)
  325. || IsPrivate(namedGroup)
  326. || (namedGroup >= arbitrary_explicit_prime_curves && namedGroup <= arbitrary_explicit_char2_curves);
  327. }
  328. public static bool RefersToAnECDHCurve(int namedGroup)
  329. {
  330. return RefersToASpecificCurve(namedGroup);
  331. }
  332. public static bool RefersToAnECDSACurve(int namedGroup)
  333. {
  334. /*
  335. * TODO[RFC 8998] Double-check whether this method is only being used to mean
  336. * "signature-capable" or specifically ECDSA, and consider curveSM2 behaviour
  337. * accordingly.
  338. */
  339. return RefersToASpecificCurve(namedGroup)
  340. && !RefersToAnXDHCurve(namedGroup);
  341. }
  342. public static bool RefersToAnXDHCurve(int namedGroup)
  343. {
  344. return namedGroup >= x25519 && namedGroup <= x448;
  345. }
  346. public static bool RefersToASpecificCurve(int namedGroup)
  347. {
  348. return namedGroup >= sect163k1 && namedGroup <= curveSM2;
  349. }
  350. public static bool RefersToASpecificFiniteField(int namedGroup)
  351. {
  352. return namedGroup >= ffdhe2048 && namedGroup <= ffdhe8192;
  353. }
  354. public static bool RefersToASpecificGroup(int namedGroup)
  355. {
  356. return RefersToASpecificCurve(namedGroup)
  357. || RefersToASpecificFiniteField(namedGroup);
  358. }
  359. }
  360. }
  361. #pragma warning restore
  362. #endif