DH1080.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // New Diffie-Hellman 1080bit Key-exchange
  2. /* For Diffie-Hellman key-exchange a 1080bit germain prime is used, the
  3. generator g=2 renders a field Fp from 1 to p-1. Therefore breaking it
  4. means to solve a discrete logarithm problem with no less than 1080bit.
  5. Base64 format is used to send the public keys over IRC.
  6. The calculated secret key is hashed with SHA-256, the result is converted
  7. to base64 for final use with blowfish. */
  8. #include "DH1080.h"
  9. // ### new sophie-germain 1080bit prime number ###
  10. static const unsigned char prime1080[DH1080_PRIME_BYTES] =
  11. {
  12. 0xFB, 0xE1, 0x02, 0x2E, 0x23, 0xD2, 0x13, 0xE8, 0xAC, 0xFA, 0x9A, 0xE8,
  13. 0xB9, 0xDF, 0xAD, 0xA3, 0xEA,
  14. 0x6B, 0x7A, 0xC7, 0xA7, 0xB7, 0xE9, 0x5A, 0xB5, 0xEB, 0x2D, 0xF8, 0x58,
  15. 0x92, 0x1F, 0xEA, 0xDE, 0x95,
  16. 0xE6, 0xAC, 0x7B, 0xE7, 0xDE, 0x6A, 0xDB, 0xAB, 0x8A, 0x78, 0x3E, 0x7A,
  17. 0xF7, 0xA7, 0xFA, 0x6A, 0x2B,
  18. 0x7B, 0xEB, 0x1E, 0x72, 0xEA, 0xE2, 0xB7, 0x2F, 0x9F, 0xA2, 0xBF, 0xB2,
  19. 0xA2, 0xEF, 0xBE, 0xFA, 0xC8,
  20. 0x68, 0xBA, 0xDB, 0x3E, 0x82, 0x8F, 0xA8, 0xBA, 0xDF, 0xAD, 0xA3, 0xE4,
  21. 0xCC, 0x1B, 0xE7, 0xE8, 0xAF,
  22. 0xE8, 0x5E, 0x96, 0x98, 0xA7, 0x83, 0xEB, 0x68, 0xFA, 0x07, 0xA7, 0x7A,
  23. 0xB6, 0xAD, 0x7B, 0xEB, 0x61,
  24. 0x8A, 0xCF, 0x9C, 0xA2, 0x89, 0x7E, 0xB2, 0x8A, 0x61, 0x89, 0xEF, 0xA0,
  25. 0x7A, 0xB9, 0x9A, 0x8A, 0x7F,
  26. 0xA9, 0xAE, 0x29, 0x9E, 0xFA, 0x7B, 0xA6, 0x6D, 0xEA, 0xFE, 0xFB, 0xEF,
  27. 0xBF, 0x0B, 0x7D, 0x8B
  28. };
  29. // base16: FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B
  30. // base10: 12745216229761186769575009943944198619149164746831579719941140425076456621824834322853258804883232842877311723249782818608677050956745409379781245497526069657222703636504651898833151008222772087491045206203033063108075098874712912417029101508315117935752962862335062591404043092163187352352197487303798807791605274487594646923
  31. static DH * g_dh;
  32. int DH1080_Init(void)
  33. {
  34. initb64();
  35. g_dh = DH_new();
  36. if(g_dh) {
  37. int codes = 0;
  38. #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
  39. g_dh->p = BN_bin2bn(prime1080, DH1080_PRIME_BYTES, NULL);
  40. g_dh->g = BN_new(); BN_set_word(g_dh->g, 2);
  41. return DH_check(g_dh, &codes) && codes == 0;
  42. #else
  43. BIGNUM *p;
  44. BIGNUM *g = BN_new();
  45. p = BN_bin2bn(prime1080, DH1080_PRIME_BYTES, NULL);
  46. BN_set_word(g, 2);
  47. DH_set0_pqg(g_dh, p, NULL, g);
  48. return DH_check(g_dh, &codes) && codes == 0;
  49. #endif
  50. }
  51. return 0;
  52. }
  53. void DH1080_DeInit(void)
  54. {
  55. DH_free(g_dh);
  56. }
  57. // verify the Diffie-Hellman public key as described in RFC 2631
  58. int DH_verifyPubKey(BIGNUM * pk)
  59. {
  60. int codes = 0;
  61. return DH_check_pub_key(g_dh, pk, &codes) && codes == 0;
  62. }
  63. // Input: priv_key = buffer of 200 bytes
  64. // pub_key = buffer of 200 bytes
  65. // Output: priv_key = Your private key
  66. // pub_key = Your public key
  67. int DH1080_gen(char *priv_key, char *pub_key)
  68. {
  69. unsigned char w[DH1080_PRIME_BYTES];
  70. int n;
  71. DH * dh = DHparams_dup(g_dh);
  72. DH_generate_key(dh);
  73. #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
  74. memset(w, 0, sizeof w);
  75. n = BN_bn2bin(dh->priv_key, w);
  76. htob64((char *)w, priv_key, n);
  77. memset(w, 0, sizeof w);
  78. n = BN_bn2bin(dh->pub_key, w);
  79. htob64((char *)w, pub_key, n);
  80. #else
  81. const BIGNUM *pubkey, *privkey;
  82. DH_get0_key(dh, &pubkey, &privkey);
  83. memset(w, 0, sizeof w);
  84. n = BN_bn2bin(privkey, w);
  85. htob64((char *)w, priv_key, n);
  86. memset(w, 0, sizeof w);
  87. n = BN_bn2bin(pubkey, w);
  88. htob64((char *)w, pub_key, n);
  89. #endif
  90. OPENSSL_cleanse(w, sizeof w);
  91. DH_free(dh);
  92. return 1;
  93. }
  94. // Input: MyPrivKey = Your private key
  95. // HisPubKey = Someones public key
  96. // Output: MyPrivKey has been destroyed for security reasons
  97. // HisPubKey = the secret key
  98. int DH1080_comp(char *MyPrivKey, char *HisPubKey)
  99. {
  100. unsigned char base64_tmp[512] = {0};
  101. int result = 0;
  102. int len;
  103. BIGNUM * pk = NULL;
  104. DH * dh = NULL;
  105. // Verify base64 strings
  106. if ((strspn(MyPrivKey, B64ABC) != strlen(MyPrivKey))
  107. || (strspn(HisPubKey, B64ABC) != strlen(HisPubKey))) {
  108. memset(MyPrivKey, 0x20, strlen(MyPrivKey));
  109. memset(HisPubKey, 0x20, strlen(HisPubKey));
  110. return 0;
  111. }
  112. dh = DHparams_dup(g_dh);
  113. len = b64toh(HisPubKey, (char *)base64_tmp);
  114. pk = BN_bin2bn(base64_tmp, len, NULL);
  115. if( DH_verifyPubKey(pk) ) {
  116. unsigned char shared_key[DH1080_PRIME_BYTES] = {0};
  117. unsigned char sha256[32] = {0};
  118. len = b64toh(MyPrivKey, (char *)base64_tmp);
  119. #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
  120. dh->priv_key = BN_bin2bn(base64_tmp, len, NULL);
  121. #else
  122. BIGNUM *temp_pub_key = BN_new();
  123. BIGNUM *priv_key = BN_bin2bn(base64_tmp, len, NULL);
  124. DH_set0_key(dh, temp_pub_key, priv_key);
  125. #endif
  126. memset(MyPrivKey, 0x20, strlen(MyPrivKey));
  127. len = DH_compute_key(shared_key, pk, dh);
  128. SHA256(shared_key, len, sha256);
  129. htob64((char *)sha256, HisPubKey, 32);
  130. result = 1;
  131. }
  132. BN_free(pk);
  133. DH_free(dh);
  134. OPENSSL_cleanse(base64_tmp, sizeof base64_tmp);
  135. return result;
  136. }