verifier.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <openssl/err.h>
  4. #include <openssl/obj_mac.h>
  5. #include <openssl/ec.h>
  6. #include <unistd.h>
  7. #include <fcntl.h>
  8. #include <sys/types.h>
  9. #include <sys/errno.h>
  10. #include <argon2.h>
  11. extern uint8_t key_hashes[150388][6];
  12. extern size_t CustomBase32Decode(const char* __restrict src, size_t len,
  13. void* __restrict out_buf, size_t out_len);
  14. const uint8_t OfficialPublicKey[2][14] = {
  15. 0x47, 0xcf, 0xb5, 0xf7, 0xe8, 0x93, 0x1e, 0xc9, 0x3d, 0x42, 0xd1, 0x22, 0x1e, 0x7f,
  16. 0x98, 0x5d, 0x74, 0xaf, 0x45, 0x53, 0x70, 0xf3, 0x47, 0x39, 0x8e, 0x1b, 0x1d, 0x3e
  17. };
  18. const uint8_t salt_for_short_product_key[16] = {
  19. 0x06, 0x9c, 0x5e, 0xf4, 0x90, 0x67, 0x39, 0x4c,
  20. 0x7b, 0x61, 0xa7, 0xee, 0x36, 0x97, 0xc6, 0x02
  21. };
  22. const uint8_t salt_for_long_product_key[16] = {
  23. 0xa1, 0x38, 0x11, 0x98, 0x12, 0x2f, 0x28, 0xee,
  24. 0x2c, 0x3a, 0xa0, 0x57, 0xbd, 0xcf, 0x2d, 0x83
  25. };
  26. const uint8_t InverseSubstitutionTable[256] = {
  27. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  28. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  29. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  30. 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xff,0xff,0xff,0xff,0xff,0xff,
  31. 0xff,0x0a,0xff,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0xff,0x11,0x12,0x13,0x14,0x15,0xff,
  32. 0x16,0x17,0x18,0xff,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0xff,0xff,0xff,0xff,0xff,
  33. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  34. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  35. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  36. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  37. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  38. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  39. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  40. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  41. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  42. 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
  43. };
  44. int IsTheKeyRecorded(uint8_t Hash[6]) {
  45. int start = 0;
  46. int end = 150388;
  47. while (start != end) {
  48. int mid = (start + end) / 2;
  49. int j = 0;
  50. for (; j < 6; ++j) {
  51. if (Hash[j] < key_hashes[mid][j]) {
  52. end = mid;
  53. break;
  54. } else if (Hash[j] > key_hashes[mid][j]) {
  55. start = mid + 1;
  56. break;
  57. }
  58. }
  59. if (j == 6)
  60. return 1;
  61. }
  62. return 0;
  63. }
  64. int DecodeShortProductKey(const char* lpcszProductKey, uint8_t data[20]) {
  65. if (strlen(lpcszProductKey) != 23)
  66. return 0;
  67. data[0] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[22]];
  68. data[1] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[21]];
  69. data[2] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[20]];
  70. data[3] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[19]];
  71. data[4] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[18]];
  72. data[5] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[16]];
  73. data[6] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[15]];
  74. data[7] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[14]];
  75. data[8] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[13]];
  76. data[9] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[12]];
  77. data[10] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[10]];
  78. data[11] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[9]];
  79. data[12] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[8]];
  80. data[13] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[7]];
  81. data[14] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[6]];
  82. data[15] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[4]];
  83. data[16] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[3]];
  84. data[17] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[2]];
  85. data[18] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[1]];
  86. data[19] = InverseSubstitutionTable[(uint8_t)lpcszProductKey[0]];
  87. for (int i = 0; i < 20; ++i)
  88. if (data[i] >= 32)
  89. return 0;
  90. return 1;
  91. }
  92. int DecodeLongProductKey(const char* lpcszProductKey, uint8_t data[14 + 5]) {
  93. if (strlen(lpcszProductKey) != 34)
  94. return 0;
  95. char prekey_str[30 + 1] = {};
  96. prekey_str[0] = lpcszProductKey[33];
  97. prekey_str[1] = lpcszProductKey[32];
  98. prekey_str[2] = lpcszProductKey[31];
  99. prekey_str[3] = lpcszProductKey[30];
  100. prekey_str[4] = lpcszProductKey[29];
  101. prekey_str[5] = lpcszProductKey[28];
  102. prekey_str[6] = lpcszProductKey[26];
  103. prekey_str[7] = lpcszProductKey[25];
  104. prekey_str[8] = lpcszProductKey[24];
  105. prekey_str[9] = lpcszProductKey[23];
  106. prekey_str[10] = lpcszProductKey[22];
  107. prekey_str[11] = lpcszProductKey[21];
  108. prekey_str[12] = lpcszProductKey[19];
  109. prekey_str[13] = lpcszProductKey[18];
  110. prekey_str[14] = lpcszProductKey[17];
  111. prekey_str[15] = lpcszProductKey[16];
  112. prekey_str[16] = lpcszProductKey[15];
  113. prekey_str[17] = lpcszProductKey[14];
  114. prekey_str[18] = lpcszProductKey[12];
  115. prekey_str[19] = lpcszProductKey[11];
  116. prekey_str[20] = lpcszProductKey[10];
  117. prekey_str[21] = lpcszProductKey[9];
  118. prekey_str[22] = lpcszProductKey[8];
  119. prekey_str[23] = lpcszProductKey[7];
  120. prekey_str[24] = lpcszProductKey[5];
  121. prekey_str[25] = lpcszProductKey[4];
  122. prekey_str[26] = lpcszProductKey[3];
  123. prekey_str[27] = lpcszProductKey[2];
  124. prekey_str[28] = lpcszProductKey[1];
  125. prekey_str[29] = lpcszProductKey[0];
  126. return CustomBase32Decode(prekey_str, 30, data, 14 + 5) ? 1 : 0;
  127. }
  128. // return key_type,
  129. // short product key if return 1 or 2
  130. // long product key if return 3
  131. // otherwise invalid
  132. int GetKeyType(const char* lpcszProductKey) {
  133. size_t KeyLength = strlen(lpcszProductKey);
  134. if (KeyLength == 23) {
  135. uint8_t data[20] = {};
  136. if (!DecodeShortProductKey(lpcszProductKey, data))
  137. return 0;
  138. uint64_t keydata_a = 0, keydata_b = 0;
  139. keydata_b |= (uint64_t)data[0];
  140. keydata_b |= (uint64_t)data[1] << 5;
  141. keydata_b |= (uint64_t)data[2] << 10;
  142. keydata_b |= (uint64_t)data[3] << 15;
  143. keydata_b |= (uint64_t)data[4] << 20;
  144. keydata_b |= (uint64_t)data[5] << 25;
  145. keydata_b |= (uint64_t)data[6] << 30;
  146. keydata_b |= (uint64_t)data[7] << 35;
  147. keydata_b |= (uint64_t)data[8] << 40;
  148. keydata_b |= (uint64_t)data[9] << 45;
  149. keydata_b |= (uint64_t)data[10] << 50;
  150. keydata_b |= (uint64_t)data[11] << 55;
  151. keydata_b |= (uint64_t)data[12] << 60;
  152. keydata_a |= (uint64_t)data[12] >> 4;
  153. keydata_a |= (uint64_t)data[13] << 1;
  154. keydata_a |= (uint64_t)data[14] << 6;
  155. keydata_a |= (uint64_t)data[15] << 11;
  156. keydata_a |= (uint64_t)data[16] << 16;
  157. keydata_a |= (uint64_t)data[17] << 21;
  158. keydata_a |= (uint64_t)data[18] << 26;
  159. keydata_a |= (uint64_t)data[19] << 31;
  160. int checksum = 0;
  161. if ((keydata_a & 0xc8b85c312ull) == 0x882818002ull && (keydata_b & 0x30688298668b32aull) == 0x306880904202200ull) {
  162. for (int i = 0; i < 20; ++i) {
  163. if (i == 12)
  164. continue;
  165. checksum += data[i];
  166. }
  167. if (checksum % 32 == data[12])
  168. return 1;
  169. } else if ((keydata_a & 0x6306a9612ull) == 0x430228000ull && (keydata_b & 0xc4d0ac3165804a43ull) == 0x4050a01165800a42ull) {
  170. for (int i = 0; i < 20; ++i) {
  171. if (i == 3)
  172. continue;
  173. checksum += data[i];
  174. }
  175. if (checksum % 32 == data[3])
  176. return 2;
  177. }
  178. } else if (KeyLength == 34) {
  179. return 3;
  180. }
  181. return 0;
  182. }
  183. void help() {
  184. printf("Usage:\n");
  185. printf(" ./TuxeraNTFS-verifier [path to tuxera_key.bin] <Product Key>\n");
  186. printf("\n");
  187. }
  188. int VerifyShortProductKey(const char* lpcszProductKey) {
  189. if (strlen(lpcszProductKey) != 23)
  190. return 0;
  191. char buf[25] = {};
  192. uint8_t Hash[6] = {};
  193. sprintf(buf, "%s\n", lpcszProductKey);
  194. argon2_hash(1,
  195. 1 << 16,
  196. 1,
  197. buf,
  198. sizeof(buf),
  199. salt_for_short_product_key,
  200. sizeof(salt_for_short_product_key),
  201. Hash,
  202. sizeof(Hash),
  203. NULL,
  204. 0,
  205. Argon2_d,
  206. ARGON2_VERSION_13);
  207. return IsTheKeyRecorded(Hash);
  208. }
  209. int VerifyLongProductKey(uint8_t key_data[14 + 5], const EC_POINT* PublicKey) {
  210. int status = 0;
  211. BIGNUM* s = NULL;
  212. BIGNUM* h = NULL;
  213. EC_GROUP* ec_curve = NULL;
  214. EC_POINT* R = NULL;
  215. BIGNUM* Rx = NULL;
  216. BIGNUM* Ry = NULL;
  217. uint8_t bin_R[2][14] = {};
  218. uint8_t Hash[5] = {};
  219. s = BN_bin2bn(key_data, 14, NULL);
  220. if (s == NULL)
  221. goto On_VerifyLongProductKey_Error;
  222. h = BN_bin2bn(key_data + 14, 5, NULL);
  223. if (h == NULL)
  224. goto On_VerifyLongProductKey_Error;
  225. ec_curve = EC_GROUP_new_by_curve_name(NID_secp112r1);
  226. if (ec_curve == NULL)
  227. goto On_VerifyLongProductKey_Error;
  228. R = EC_POINT_new(ec_curve);
  229. if (R == NULL)
  230. goto On_VerifyLongProductKey_Error;
  231. Rx = BN_new();
  232. if (Rx == NULL)
  233. goto On_VerifyLongProductKey_Error;
  234. Ry = BN_new();
  235. if (Ry == NULL)
  236. goto On_VerifyLongProductKey_Error;
  237. if (!EC_POINT_mul(ec_curve, R, s, PublicKey, h, NULL))
  238. goto On_VerifyLongProductKey_Error;
  239. if (!EC_POINT_get_affine_coordinates_GFp(ec_curve, R, Rx, Ry, NULL))
  240. goto On_VerifyLongProductKey_Error;
  241. BN_bn2bin(Rx, bin_R[0] + 14 - BN_num_bytes(Rx));
  242. BN_bn2bin(Ry, bin_R[1] + 14 - BN_num_bytes(Ry));
  243. argon2_hash(1,
  244. 1 << 16,
  245. 1,
  246. bin_R,
  247. sizeof(bin_R),
  248. salt_for_long_product_key,
  249. sizeof(salt_for_long_product_key),
  250. Hash,
  251. sizeof(Hash),
  252. NULL,
  253. 0,
  254. Argon2_d,
  255. ARGON2_VERSION_13);
  256. Hash[4] &= 0xFC;
  257. status = memcmp(key_data + 14, Hash, 5) == 0 ? 1 : 0;
  258. On_VerifyLongProductKey_Error:
  259. if (Ry)
  260. BN_free(Ry);
  261. if (Rx)
  262. BN_free(Rx);
  263. if (R)
  264. EC_POINT_free(R);
  265. if (ec_curve)
  266. EC_GROUP_free(ec_curve);
  267. if (h)
  268. BN_free(h);
  269. if (s)
  270. BN_free(s);
  271. return status;
  272. }
  273. EC_POINT* LoadPublicKey(const char* key_file) {
  274. EC_GROUP* ec_curve = NULL;
  275. EC_POINT* PublicKey = NULL;
  276. uint8_t binPublicKey[2][14] = {};
  277. BIGNUM* Px = NULL;
  278. BIGNUM* Py = NULL;
  279. ec_curve = EC_GROUP_new_by_curve_name(NID_secp112r1);
  280. if (ec_curve == NULL)
  281. goto On_LoadPublicKey_Error;
  282. PublicKey = EC_POINT_new(ec_curve);
  283. if (PublicKey == NULL)
  284. goto On_LoadPublicKey_Error;
  285. if (key_file == NULL) {
  286. memcpy(binPublicKey, OfficialPublicKey, sizeof(OfficialPublicKey));
  287. } else {
  288. int fd = -1;
  289. fd = open(key_file, O_RDONLY);
  290. if (fd == -1) {
  291. EC_POINT_free(PublicKey);
  292. PublicKey = NULL;
  293. goto On_LoadPublicKey_Error;
  294. }
  295. read(fd, binPublicKey, 14);
  296. if (14 != read(fd, binPublicKey[0], 14)) {
  297. EC_POINT_free(PublicKey);
  298. PublicKey = NULL;
  299. goto On_LoadPublicKey_Error;
  300. }
  301. if (14 != read(fd, binPublicKey[1], 14)) {
  302. EC_POINT_free(PublicKey);
  303. PublicKey = NULL;
  304. goto On_LoadPublicKey_Error;
  305. }
  306. }
  307. Px = BN_bin2bn(binPublicKey[0], sizeof(binPublicKey[0]), NULL);
  308. if (Px == NULL) {
  309. EC_POINT_free(PublicKey);
  310. PublicKey = NULL;
  311. goto On_LoadPublicKey_Error;
  312. }
  313. Py = BN_bin2bn(binPublicKey[1], sizeof(binPublicKey[1]), NULL);
  314. if (Py == NULL) {
  315. EC_POINT_free(PublicKey);
  316. PublicKey = NULL;
  317. goto On_LoadPublicKey_Error;
  318. }
  319. if (!EC_POINT_set_affine_coordinates_GFp(ec_curve, PublicKey, Px, Py, NULL)) {
  320. EC_POINT_free(PublicKey);
  321. PublicKey = NULL;
  322. goto On_LoadPublicKey_Error;
  323. }
  324. On_LoadPublicKey_Error:
  325. if (Py)
  326. BN_free(Py);
  327. if (Px)
  328. BN_free(Px);
  329. if (ec_curve)
  330. EC_GROUP_free(ec_curve);
  331. return PublicKey;
  332. }
  333. int main(int argc, char* argv[]) {
  334. if (argc != 2 && argc != 3) {
  335. help();
  336. return 0;
  337. }
  338. int KeyType = GetKeyType(argv[argc - 1]);
  339. switch (KeyType) {
  340. case 1:
  341. case 2:
  342. printf("%s\n", VerifyShortProductKey(argv[argc - 1]) ? "Valid Key" : "Invalid Key");
  343. break;
  344. case 3: {
  345. uint8_t key_data[14 + 5] = {};
  346. EC_POINT* PublicKey = NULL;
  347. PublicKey = LoadPublicKey(argc == 3 ? argv[1] : NULL);
  348. if (PublicKey == NULL) {
  349. printf("Failed to load public key.\n");
  350. return 0;
  351. }
  352. if (!DecodeLongProductKey(argv[argc - 1], key_data)) {
  353. printf("Invalid Key\n");
  354. EC_POINT_free(PublicKey);
  355. return 0;
  356. }
  357. printf("%s\n", VerifyLongProductKey(key_data, PublicKey) ? "Valid Key" : "Invalid Key");
  358. EC_POINT_free(PublicKey);
  359. }
  360. break;
  361. default:
  362. printf("Invalid Key\n");
  363. break;
  364. }
  365. return 0;
  366. }