dh_util.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /* dh_util.c
  2. *
  3. * Adapted from ZNC-fish
  4. */
  5. #include "src/libcrypto.h"
  6. #include "src/compat/compat.h"
  7. #include <bdlib/src/String.h>
  8. #include <bdlib/src/base64.h>
  9. #include "dh_util.h"
  10. /*
  11. int b64toh(lpBase64String, lpDestinationBuffer);
  12. Converts base64 string b to hexnumber d.
  13. Returns size of hexnumber in bytes.
  14. */
  15. int b64toh(char *b, char *d){
  16. int i,k,l;
  17. l=strlen(b);
  18. if (l<2) return 0;
  19. for (i=l-1;i>-1;i--){
  20. if (bd::b64_indexes[(unsigned char)(b[i])]==0) l--;
  21. else break;
  22. }
  23. if (l<2) return 0;
  24. i=0, k=0;
  25. while (1) {
  26. i++;
  27. if (k+1<l) d[i-1]=((bd::b64_indexes[(unsigned char)(b[k])])<<2);
  28. else break;
  29. k++;
  30. if (k<l) d[i-1]|=((bd::b64_indexes[(unsigned char)(b[k])])>>4);
  31. else break;
  32. i++;
  33. if (k+1<l) d[i-1]=((bd::b64_indexes[(unsigned char)(b[k])])<<4);
  34. else break;
  35. k++;
  36. if (k<l) d[i-1]|=((bd::b64_indexes[(unsigned char)(b[k])])>>2);
  37. else break;
  38. i++;
  39. if (k+1<l) d[i-1]=((bd::b64_indexes[(unsigned char)(b[k])])<<6);
  40. else break;
  41. k++;
  42. if (k<l) d[i-1]|=(bd::b64_indexes[(unsigned char)(b[k])]);
  43. else break;
  44. k++;
  45. }
  46. return i-1;
  47. }
  48. /*
  49. int htob64(lpHexNumber, lpDestinationBuffer);
  50. Converts hexnumber h (with length l bytes) to base64 string d.
  51. Returns length of base64 string.
  52. */
  53. int htob64(char *h, char *d, unsigned int l){
  54. unsigned int i,j,k;
  55. unsigned char m,t;
  56. if (!l) return 0;
  57. l<<=3; // no. bits
  58. m=0x80;
  59. for (i=0,j=0,k=0,t=0; i<l; i++){
  60. if (h[(i>>3)]&m) t|=1;
  61. j++;
  62. if (!(m>>=1)) m=0x80;
  63. if (!(j%6)) {
  64. d[k]=bd::b64_charset[t];
  65. t&=0;
  66. k++;
  67. }
  68. t<<=1;
  69. }
  70. m=5-(j%6);
  71. t<<=m;
  72. if (m) {
  73. d[k]=bd::b64_charset[t];
  74. k++;
  75. }
  76. d[k]&=0;
  77. return strlen(d);
  78. }
  79. // ### new sophie-germain 1080bit prime number ###
  80. //static const char *prime1080 = "++ECLiPSE+is+proud+to+present+latest+FiSH+release+featuring+even+more+security+for+you+++shouts+go+out+to+TMG+for+helping+to+generate+this+cool+sophie+germain+prime+number++++/C32L";
  81. static const char *prime1080 = "FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B";
  82. // Base16: FBE1022E23D213E8ACFA9AE8B9DFADA3EA6B7AC7A7B7E95AB5EB2DF858921FEADE95E6AC7BE7DE6ADBAB8A783E7AF7A7FA6A2B7BEB1E72EAE2B72F9FA2BFB2A2EFBEFAC868BADB3E828FA8BADFADA3E4CC1BE7E8AFE85E9698A783EB68FA07A77AB6AD7BEB618ACF9CA2897EB28A6189EFA07AB99A8A7FA9AE299EFA7BA66DEAFEFBEFBF0B7D8B
  83. // Base10: 12745216229761186769575009943944198619149164746831579719941140425076456621824834322853258804883232842877311723249782818608677050956745409379781245497526069657222703636504651898833151008222772087491045206203033063108075098874712912417029101508315117935752962862335062591404043092163187352352197487303798807791605274487594646923
  84. void DH1080_gen(bd::String& privateKey, bd::String& publicKeyB64) {
  85. BIGNUM *b_prime = NULL;
  86. BIGNUM *b_generator = NULL;
  87. if (!BN_hex2bn(&b_prime, prime1080)) {
  88. sdprintf("BAD PRIME");
  89. return;
  90. }
  91. if (!BN_dec2bn(&b_generator, "2")) {
  92. sdprintf("BAD GENERATOR");
  93. return;
  94. }
  95. DH *dh = NULL;
  96. dh = DH_new();
  97. dh->p = b_prime;
  98. dh->g = b_generator;
  99. if (!DH_generate_key(dh)) {
  100. DH_free(dh);
  101. return;
  102. }
  103. // Get private key
  104. privateKey.resize(BN_num_bytes(dh->priv_key), 0);
  105. BN_bn2bin(dh->priv_key, reinterpret_cast<unsigned char*>(privateKey.mdata()));
  106. // Get public key
  107. bd::String publicKey;
  108. // Resize as the mdata() modification won't update the internal length, but resize() will
  109. publicKey.resize(static_cast<size_t>(BN_num_bytes(dh->pub_key)));
  110. BN_bn2bin(dh->pub_key, reinterpret_cast<unsigned char*>(publicKey.mdata()));;
  111. // base64 encode
  112. publicKeyB64 = bd::base64Encode(publicKey);
  113. DH_free(dh);
  114. }
  115. bool DH1080_comp(const bd::String privateKey, const bd::String theirPublicKeyB64, bd::String& sharedKey) {
  116. BIGNUM *b_prime = NULL, *b_generator = NULL;
  117. if (!BN_hex2bn(&b_prime, prime1080)) {
  118. sharedKey = "Bad prime";
  119. return false;
  120. }
  121. if (!BN_dec2bn(&b_generator, "2")) {
  122. sharedKey = "Bad generator";
  123. return false;
  124. }
  125. size_t len = 0;
  126. unsigned char raw_buf[200] = "";
  127. BIGNUM *b_myPrivkey = NULL, *b_HisPubkey = NULL;
  128. DH *dh = NULL;
  129. dh = DH_new();
  130. dh->p = b_prime;
  131. dh->g = b_generator;
  132. // Setup my private key
  133. b_myPrivkey = BN_bin2bn(reinterpret_cast<const unsigned char*>(privateKey.data()), privateKey.length(), NULL);
  134. dh->priv_key = b_myPrivkey;
  135. // Prep their public key
  136. len = theirPublicKeyB64.length();
  137. bd::b64dec_buf(reinterpret_cast<const unsigned char*>(theirPublicKeyB64.data()), &len, reinterpret_cast<char*>(raw_buf));
  138. b_HisPubkey = BN_bin2bn(reinterpret_cast<const unsigned char*>(raw_buf), len, NULL);
  139. // Compute the Shared key
  140. char *key = (char *)my_calloc(1, DH_size(dh));
  141. len = DH_compute_key((unsigned char *)key, b_HisPubkey, dh);
  142. DH_free(dh);
  143. BN_clear_free(b_HisPubkey);
  144. if (len == static_cast<size_t>(-1)) {
  145. // Bad pub key
  146. unsigned long err = ERR_get_error();
  147. sdprintf("** DH Error: %s", ERR_error_string(err, NULL));
  148. free(key);
  149. sharedKey = ERR_error_string(err, NULL);
  150. return false;
  151. }
  152. SHA256_CTX c;
  153. unsigned char SHA256digest[SHA256_DIGEST_LENGTH] = "";
  154. SHA256_Init(&c);
  155. SHA256_Update(&c, key, len);
  156. SHA256_Final(SHA256digest, &c);
  157. memset(raw_buf, 0, sizeof(raw_buf));
  158. len = htob64((char *)SHA256digest, (char *)raw_buf, sizeof(SHA256digest));
  159. sharedKey = bd::String(reinterpret_cast<char *>(raw_buf), len);
  160. free(key);
  161. return true;
  162. }