ECC.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright (c)2019 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2026-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. /*
  14. * This file defines the elliptic curve crypto used for ZeroTier V1. The normal
  15. * public version uses C25519 and Ed25519, while the FIPS version uses NIST.
  16. * FIPS builds are completely incompatible with regular ZeroTier, but that's
  17. * fine since FIPS users typically want a fully isolated private network. If you
  18. * are not such a user you probably don't want this.
  19. */
  20. #ifndef ZT_ECC_HPP
  21. #define ZT_ECC_HPP
  22. #include "Utils.hpp"
  23. #ifdef ZT_FIPS
  24. /* FIPS140/NIST ECC cryptography */
  25. /* Note that to be FIPS we also need to link against a FIPS-certified library. */
  26. #include <openssl/evp.h>
  27. #include <openssl/ec.h>
  28. #include <openssl/err.h>
  29. #include <openssl/pem.h>
  30. #include <openssl/bn.h>
  31. #define ZT_ECC_PUBLIC_KEY_SET_LEN (97 * 2) /* Two ECC P-384 keys */
  32. #define ZT_ECC_PRIVATE_KEY_SET_LEN (48 * 2) /* Two ECC P-384 secret keys */
  33. #define ZT_ECC_SIGNATURE_LEN 96 /* NIST P-384 ECDSA signature */
  34. class ECC
  35. {
  36. public:
  37. struct Public { uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; };
  38. struct Private { uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; };
  39. struct Signature { uint8_t data[ZT_ECC_SIGNATURE_LEN]; };
  40. struct Pair { Public pub; Private priv; };
  41. };
  42. #else // Curve25519 / Ed25519
  43. namespace ZeroTier {
  44. #define ZT_ECC_PUBLIC_KEY_SET_LEN 64
  45. #define ZT_ECC_PRIVATE_KEY_SET_LEN 64
  46. #define ZT_ECC_SIGNATURE_LEN 96
  47. class ECC
  48. {
  49. public:
  50. struct Public { uint8_t data[ZT_ECC_PUBLIC_KEY_SET_LEN]; };
  51. struct Private { uint8_t data[ZT_ECC_PRIVATE_KEY_SET_LEN]; };
  52. struct Signature { uint8_t data[ZT_ECC_SIGNATURE_LEN]; };
  53. struct Pair { Public pub; Private priv; };
  54. /**
  55. * Generate an elliptic curve key pair
  56. */
  57. static inline Pair generate()
  58. {
  59. Pair kp;
  60. Utils::getSecureRandom(kp.priv.data,ZT_ECC_PRIVATE_KEY_SET_LEN);
  61. _calcPubDH(kp);
  62. _calcPubED(kp);
  63. return kp;
  64. }
  65. /**
  66. * Generate a key pair satisfying a condition
  67. *
  68. * This begins with a random keypair from a random secret key and then
  69. * iteratively increments the random secret until cond(kp) returns true.
  70. * This is used to compute key pairs in which the public key, its hash
  71. * or some other aspect of it satisfies some condition, such as for a
  72. * hashcash criteria.
  73. *
  74. * @param cond Condition function or function object
  75. * @return Key pair where cond(kp) returns true
  76. * @tparam F Type of 'cond'
  77. */
  78. template<typename F>
  79. static inline Pair generateSatisfying(F cond)
  80. {
  81. Pair kp;
  82. void *const priv = (void *)kp.priv.data;
  83. Utils::getSecureRandom(priv,ZT_ECC_PRIVATE_KEY_SET_LEN);
  84. _calcPubED(kp); // do Ed25519 key -- bytes 32-63 of pub and priv
  85. do {
  86. ++(((uint64_t *)priv)[1]);
  87. --(((uint64_t *)priv)[2]);
  88. _calcPubDH(kp); // keep regenerating bytes 0-31 until satisfied
  89. } while (!cond(kp));
  90. return kp;
  91. }
  92. /**
  93. * Perform C25519 ECC key agreement
  94. *
  95. * Actual key bytes are generated from one or more SHA-512 digests of
  96. * the raw result of key agreement.
  97. *
  98. * @param mine My private key
  99. * @param their Their public key
  100. * @param keybuf Buffer to fill
  101. * @param keylen Number of key bytes to generate
  102. */
  103. static void agree(const Private &mine,const Public &their,void *keybuf,unsigned int keylen);
  104. static inline void agree(const Pair &mine,const Public &their,void *keybuf,unsigned int keylen) { agree(mine.priv,their,keybuf,keylen); }
  105. /**
  106. * Sign a message with a sender's key pair
  107. *
  108. * This takes the SHA-521 of msg[] and then signs the first 32 bytes of this
  109. * digest, returning it and the 64-byte ed25519 signature in signature[].
  110. * This results in a signature that verifies both the signer's authenticity
  111. * and the integrity of the message.
  112. *
  113. * This is based on the original ed25519 code from NaCl and the SUPERCOP
  114. * cipher benchmark suite, but with the modification that it always
  115. * produces a signature of fixed 96-byte length based on the hash of an
  116. * arbitrary-length message.
  117. *
  118. * @param myPrivate My private key
  119. * @param myPublic My public key
  120. * @param msg Message to sign
  121. * @param len Length of message in bytes
  122. * @param signature Buffer to fill with signature -- MUST be 96 bytes in length
  123. */
  124. static void sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len,void *signature);
  125. static inline void sign(const Pair &mine,const void *msg,unsigned int len,void *signature) { sign(mine.priv,mine.pub,msg,len,signature); }
  126. /**
  127. * Sign a message with a sender's key pair
  128. *
  129. * @param myPrivate My private key
  130. * @param myPublic My public key
  131. * @param msg Message to sign
  132. * @param len Length of message in bytes
  133. * @return Signature
  134. */
  135. static inline Signature sign(const Private &myPrivate,const Public &myPublic,const void *msg,unsigned int len)
  136. {
  137. Signature sig;
  138. sign(myPrivate,myPublic,msg,len,sig.data);
  139. return sig;
  140. }
  141. static inline Signature sign(const Pair &mine,const void *msg,unsigned int len)
  142. {
  143. Signature sig;
  144. sign(mine.priv,mine.pub,msg,len,sig.data);
  145. return sig;
  146. }
  147. /**
  148. * Verify a message's signature
  149. *
  150. * @param their Public key to verify against
  151. * @param msg Message to verify signature integrity against
  152. * @param len Length of message in bytes
  153. * @param signature 96-byte signature
  154. * @return True if signature is valid and the message is authentic and unmodified
  155. */
  156. static bool verify(const Public &their,const void *msg,unsigned int len,const void *signature);
  157. /**
  158. * Verify a message's signature
  159. *
  160. * @param their Public key to verify against
  161. * @param msg Message to verify signature integrity against
  162. * @param len Length of message in bytes
  163. * @param signature 96-byte signature
  164. * @return True if signature is valid and the message is authentic and unmodified
  165. */
  166. static inline bool verify(const Public &their,const void *msg,unsigned int len,const Signature &signature)
  167. {
  168. return verify(their,msg,len,signature.data);
  169. }
  170. private:
  171. // derive first 32 bytes of kp.pub from first 32 bytes of kp.priv
  172. // this is the ECDH key
  173. static void _calcPubDH(Pair &kp);
  174. // derive 2nd 32 bytes of kp.pub from 2nd 32 bytes of kp.priv
  175. // this is the Ed25519 sign/verify key
  176. static void _calcPubED(Pair &kp);
  177. };
  178. } // namespace ZeroTier
  179. #endif
  180. #endif