crypto_dh_nss.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /* Copyright (c) 2001, Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file crypto_dh_nss.h
  8. *
  9. * \brief NSS implementation of Diffie-Hellman over Z_p.
  10. **/
  11. #include "lib/crypt_ops/crypto_dh.h"
  12. #include "lib/crypt_ops/crypto_nss_mgt.h"
  13. #include "lib/encoding/binascii.h"
  14. #include "lib/log/util_bug.h"
  15. #include "lib/malloc/malloc.h"
  16. #include <cryptohi.h>
  17. #include <keyhi.h>
  18. #include <pk11pub.h>
  19. static int dh_initialized = 0;
  20. static SECKEYDHParams tls_dh_param, circuit_dh_param;
  21. static unsigned char tls_dh_prime_data[DH1024_KEY_LEN];
  22. static unsigned char circuit_dh_prime_data[DH1024_KEY_LEN];
  23. static unsigned char dh_generator_data[1];
  24. void
  25. crypto_dh_init_nss(void)
  26. {
  27. if (dh_initialized)
  28. return;
  29. int r;
  30. r = base16_decode((char*)tls_dh_prime_data,
  31. sizeof(tls_dh_prime_data),
  32. TLS_DH_PRIME, strlen(TLS_DH_PRIME));
  33. tor_assert(r == DH1024_KEY_LEN);
  34. r = base16_decode((char*)circuit_dh_prime_data,
  35. sizeof(circuit_dh_prime_data),
  36. OAKLEY_PRIME_2, strlen(OAKLEY_PRIME_2));
  37. tor_assert(r == DH1024_KEY_LEN);
  38. dh_generator_data[0] = DH_GENERATOR;
  39. tls_dh_param.prime.data = tls_dh_prime_data;
  40. tls_dh_param.prime.len = DH1024_KEY_LEN;
  41. tls_dh_param.base.data = dh_generator_data;
  42. tls_dh_param.base.len = 1;
  43. circuit_dh_param.prime.data = circuit_dh_prime_data;
  44. circuit_dh_param.prime.len = DH1024_KEY_LEN;
  45. circuit_dh_param.base.data = dh_generator_data;
  46. circuit_dh_param.base.len = 1;
  47. dh_initialized = 1;
  48. }
  49. void
  50. crypto_dh_free_all_nss(void)
  51. {
  52. dh_initialized = 0;
  53. }
  54. struct crypto_dh_t {
  55. int dh_type; // XXXX let's remove this later on.
  56. SECKEYPrivateKey *seckey;
  57. SECKEYPublicKey *pubkey;
  58. };
  59. crypto_dh_t *
  60. crypto_dh_new(int dh_type)
  61. {
  62. crypto_dh_t *r = tor_malloc_zero(sizeof(crypto_dh_t));
  63. r->dh_type = dh_type;
  64. return r;
  65. }
  66. crypto_dh_t *
  67. crypto_dh_dup(const crypto_dh_t *dh)
  68. {
  69. tor_assert(dh);
  70. crypto_dh_t *r = crypto_dh_new(dh->dh_type);
  71. if (dh->seckey)
  72. r->seckey = SECKEY_CopyPrivateKey(dh->seckey);
  73. if (dh->pubkey)
  74. r->pubkey = SECKEY_CopyPublicKey(dh->pubkey);
  75. return r;
  76. }
  77. int
  78. crypto_dh_get_bytes(crypto_dh_t *dh)
  79. {
  80. (void)dh;
  81. return DH1024_KEY_LEN;
  82. }
  83. int
  84. crypto_dh_generate_public(crypto_dh_t *dh)
  85. {
  86. tor_assert(dh);
  87. SECKEYDHParams *p;
  88. if (dh->dh_type == DH_TYPE_TLS)
  89. p = &tls_dh_param;
  90. else
  91. p = &circuit_dh_param;
  92. dh->seckey = SECKEY_CreateDHPrivateKey(p, &dh->pubkey, NULL);
  93. if (!dh->seckey || !dh->pubkey)
  94. return -1;
  95. else
  96. return 0;
  97. }
  98. int
  99. crypto_dh_get_public(crypto_dh_t *dh, char *pubkey_out,
  100. size_t pubkey_out_len)
  101. {
  102. tor_assert(dh);
  103. tor_assert(pubkey_out);
  104. if (!dh->pubkey) {
  105. if (crypto_dh_generate_public(dh) < 0)
  106. return -1;
  107. }
  108. const SECItem *item = &dh->pubkey->u.dh.publicValue;
  109. if (item->len > pubkey_out_len)
  110. return -1;
  111. /* Left-pad the result with 0s. */
  112. memset(pubkey_out, 0, pubkey_out_len);
  113. memcpy(pubkey_out + pubkey_out_len - item->len,
  114. item->data,
  115. item->len);
  116. return 0;
  117. }
  118. void
  119. crypto_dh_free_(crypto_dh_t *dh)
  120. {
  121. if (!dh)
  122. return;
  123. if (dh->seckey)
  124. SECKEY_DestroyPrivateKey(dh->seckey);
  125. if (dh->pubkey)
  126. SECKEY_DestroyPublicKey(dh->pubkey);
  127. tor_free(dh);
  128. }
  129. ssize_t
  130. crypto_dh_handshake(int severity, crypto_dh_t *dh,
  131. const char *pubkey, size_t pubkey_len,
  132. unsigned char *secret_out,
  133. size_t secret_bytes_out)
  134. {
  135. tor_assert(dh);
  136. if (pubkey_len > DH1024_KEY_LEN)
  137. return -1;
  138. if (!dh->pubkey || !dh->seckey)
  139. return -1;
  140. if (secret_bytes_out < DH1024_KEY_LEN)
  141. return -1;
  142. SECKEYPublicKey peer_key;
  143. memset(&peer_key, 0, sizeof(peer_key));
  144. peer_key.keyType = dhKey;
  145. peer_key.pkcs11ID = CK_INVALID_HANDLE;
  146. if (dh->dh_type == DH_TYPE_TLS)
  147. peer_key.u.dh.prime.data = tls_dh_prime_data; // should never use this code
  148. else
  149. peer_key.u.dh.prime.data = circuit_dh_prime_data;
  150. peer_key.u.dh.prime.len = DH1024_KEY_LEN;
  151. peer_key.u.dh.base.data = dh_generator_data;
  152. peer_key.u.dh.base.len = 1;
  153. peer_key.u.dh.publicValue.data = (unsigned char *)pubkey;
  154. peer_key.u.dh.publicValue.len = (int) pubkey_len;
  155. PK11SymKey *sym = PK11_PubDerive(dh->seckey, &peer_key,
  156. PR_FALSE, NULL, NULL, CKM_DH_PKCS_DERIVE,
  157. CKM_GENERIC_SECRET_KEY_GEN /* ??? */,
  158. CKA_DERIVE, 0, NULL);
  159. if (! sym) {
  160. crypto_nss_log_errors(severity, "deriving a DH shared secret");
  161. return -1;
  162. }
  163. SECStatus s = PK11_ExtractKeyValue(sym);
  164. if (s != SECSuccess) {
  165. crypto_nss_log_errors(severity, "extracting a DH shared secret");
  166. PK11_FreeSymKey(sym);
  167. return -1;
  168. }
  169. SECItem *result = PK11_GetKeyData(sym);
  170. tor_assert(result); // This cannot fail.
  171. if (BUG(result->len > secret_bytes_out)) {
  172. PK11_FreeSymKey(sym);
  173. return -1;
  174. }
  175. ssize_t len = result->len;
  176. memcpy(secret_out, result->data, len);
  177. PK11_FreeSymKey(sym);
  178. return len;
  179. }