Identity.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /*
  2. * Copyright (c)2013-2020 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: 2024-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. #include <cstring>
  14. #include <cstdint>
  15. #include "Constants.hpp"
  16. #include "Identity.hpp"
  17. #include "SHA512.hpp"
  18. #include "Salsa20.hpp"
  19. #include "Utils.hpp"
  20. namespace ZeroTier {
  21. namespace {
  22. // These can't be changed without a new identity type. They define the
  23. // parameters of the hashcash hashing/searching algorithm for type 0
  24. // identities.
  25. #define ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN 17
  26. #define ZT_IDENTITY_GEN_MEMORY 2097152
  27. // A memory-hard composition of SHA-512 and Salsa20 for hashcash hashing
  28. static void _computeMemoryHardHash(const void *publicKey,unsigned int publicKeyBytes,void *digest,void *genmem)
  29. {
  30. // Digest publicKey[] to obtain initial digest
  31. SHA512(digest,publicKey,publicKeyBytes);
  32. // Initialize genmem[] using Salsa20 in a CBC-like configuration since
  33. // ordinary Salsa20 is randomly seek-able. This is good for a cipher
  34. // but is not what we want for sequential memory-hardness.
  35. memset(genmem,0,ZT_IDENTITY_GEN_MEMORY);
  36. Salsa20 s20(digest,(char *)digest + 32);
  37. s20.crypt20((char *)genmem,(char *)genmem,64);
  38. for(unsigned long i=64;i<ZT_IDENTITY_GEN_MEMORY;i+=64) {
  39. unsigned long k = i - 64;
  40. *((uint64_t *)((char *)genmem + i)) = *((uint64_t *)((char *)genmem + k));
  41. *((uint64_t *)((char *)genmem + i + 8)) = *((uint64_t *)((char *)genmem + k + 8));
  42. *((uint64_t *)((char *)genmem + i + 16)) = *((uint64_t *)((char *)genmem + k + 16));
  43. *((uint64_t *)((char *)genmem + i + 24)) = *((uint64_t *)((char *)genmem + k + 24));
  44. *((uint64_t *)((char *)genmem + i + 32)) = *((uint64_t *)((char *)genmem + k + 32));
  45. *((uint64_t *)((char *)genmem + i + 40)) = *((uint64_t *)((char *)genmem + k + 40));
  46. *((uint64_t *)((char *)genmem + i + 48)) = *((uint64_t *)((char *)genmem + k + 48));
  47. *((uint64_t *)((char *)genmem + i + 56)) = *((uint64_t *)((char *)genmem + k + 56));
  48. s20.crypt20((char *)genmem + i,(char *)genmem + i,64);
  49. }
  50. // Render final digest using genmem as a lookup table
  51. for(unsigned long i=0;i<(ZT_IDENTITY_GEN_MEMORY / sizeof(uint64_t));) {
  52. unsigned long idx1 = (unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (64 / sizeof(uint64_t)));
  53. unsigned long idx2 = (unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (ZT_IDENTITY_GEN_MEMORY / sizeof(uint64_t)));
  54. uint64_t tmp = ((uint64_t *)genmem)[idx2];
  55. ((uint64_t *)genmem)[idx2] = ((uint64_t *)digest)[idx1];
  56. ((uint64_t *)digest)[idx1] = tmp;
  57. s20.crypt20(digest,digest,64);
  58. }
  59. }
  60. // Hashcash generation halting condition -- halt when first byte is less than
  61. // threshold value.
  62. struct _Identity_generate_cond
  63. {
  64. inline _Identity_generate_cond() {}
  65. inline _Identity_generate_cond(unsigned char *sb,char *gm) : digest(sb),genmem(gm) {}
  66. inline bool operator()(const uint8_t pub[ZT_C25519_PUBLIC_KEY_LEN]) const
  67. {
  68. _computeMemoryHardHash(pub,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
  69. return (digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN);
  70. }
  71. unsigned char *digest;
  72. char *genmem;
  73. };
  74. } // anonymous namespace
  75. void Identity::generate(const Type t)
  76. {
  77. uint8_t digest[64];
  78. _type = t;
  79. _hasPrivate = true;
  80. char *const genmem = new char[ZT_IDENTITY_GEN_MEMORY];
  81. do {
  82. C25519::generateSatisfying(_Identity_generate_cond(digest,genmem),_pub.c25519,_priv.c25519);
  83. _address.setTo(digest + 59,ZT_ADDRESS_LENGTH); // last 5 bytes are address
  84. } while (_address.isReserved());
  85. delete [] genmem;
  86. if (t == P384) {
  87. // We sign with both because in pure FIPS environments we might have to say
  88. // that we do not rely on any non-FIPS algorithms, or may even have to disable
  89. // them.
  90. ECC384GenerateKey(_pub.p384,_priv.p384);
  91. C25519::sign(_priv.c25519,_pub.c25519,&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE,_pub.c25519s);
  92. SHA384(digest,&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE);
  93. ECC384ECDSASign(_priv.p384,digest,_pub.p384s);
  94. }
  95. }
  96. bool Identity::locallyValidate() const
  97. {
  98. uint8_t digest[64];
  99. if (_address.isReserved())
  100. return false;
  101. switch(_type) {
  102. case C25519:
  103. break;
  104. case P384:
  105. if (!C25519::verify(_pub.c25519,&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE,_pub.c25519s,ZT_C25519_SIGNATURE_LEN))
  106. return false;
  107. SHA384(digest,&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE);
  108. if (!ECC384ECDSAVerify(_pub.p384,digest,_pub.p384s))
  109. return false;
  110. break;
  111. default:
  112. return false;
  113. }
  114. char *genmem = nullptr;
  115. try {
  116. genmem = new char[ZT_IDENTITY_GEN_MEMORY];
  117. _computeMemoryHardHash(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,digest,genmem);
  118. delete [] genmem;
  119. return ((_address == Address(digest + 59,ZT_ADDRESS_LENGTH))&&(!_address.isReserved())&&(digest[0] < ZT_IDENTITY_GEN_HASHCASH_FIRST_BYTE_LESS_THAN));
  120. } catch ( ... ) {
  121. if (genmem) delete [] genmem;
  122. }
  123. return false;
  124. }
  125. bool Identity::hash(uint8_t h[48],const bool includePrivate) const
  126. {
  127. switch(_type) {
  128. case C25519:
  129. if ((_hasPrivate)&&(includePrivate))
  130. SHA384(h,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
  131. else SHA384(h,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
  132. return true;
  133. case P384:
  134. if ((_hasPrivate)&&(includePrivate))
  135. SHA384(h,&_pub,sizeof(_pub),&_priv,sizeof(_priv));
  136. else SHA384(h,&_pub,sizeof(_pub));
  137. return true;
  138. }
  139. return false;
  140. }
  141. unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
  142. {
  143. if (_hasPrivate) {
  144. switch(_type) {
  145. case C25519:
  146. if (siglen >= ZT_C25519_SIGNATURE_LEN) {
  147. C25519::sign(_priv.c25519,_pub.c25519,data,len,sig);
  148. return ZT_C25519_SIGNATURE_LEN;
  149. }
  150. case P384:
  151. if (siglen >= ZT_ECC384_SIGNATURE_SIZE) {
  152. // When signing with P384 we also hash the C25519 public key as an
  153. // extra measure to ensure that only this identity can verify.
  154. uint8_t h[48];
  155. SHA384(h,data,len,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
  156. ECC384ECDSASign(_priv.p384,h,(uint8_t *)sig);
  157. return ZT_ECC384_SIGNATURE_SIZE;
  158. }
  159. }
  160. }
  161. return 0;
  162. }
  163. bool Identity::verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const
  164. {
  165. switch(_type) {
  166. case C25519:
  167. return C25519::verify(_pub.c25519,data,len,sig,siglen);
  168. case P384:
  169. if (siglen == ZT_ECC384_SIGNATURE_SIZE) {
  170. uint8_t h[48];
  171. SHA384(h,data,len,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
  172. return ECC384ECDSAVerify(_pub.p384,h,(const uint8_t *)sig);
  173. }
  174. break;
  175. }
  176. return false;
  177. }
  178. bool Identity::agree(const Identity &id,uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]) const
  179. {
  180. uint8_t rawkey[128];
  181. uint8_t h[64];
  182. if (_hasPrivate) {
  183. if (_type == C25519) {
  184. if ((id._type == C25519)||(id._type == P384)) {
  185. // If we are a C25519 key we can agree with another C25519 key or with only the
  186. // C25519 portion of a type 1 P-384 key.
  187. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  188. SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
  189. memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
  190. return true;
  191. }
  192. } else if (_type == P384) {
  193. if (id._type == P384) {
  194. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  195. ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_SHARED_KEY_LEN);
  196. SHA384(h,rawkey,ZT_C25519_SHARED_KEY_LEN + ZT_ECC384_SHARED_SECRET_SIZE);
  197. memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
  198. return true;
  199. } else if (id._type == C25519) {
  200. // If the other identity is a C25519 identity we can agree using only that type.
  201. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  202. SHA512(h,rawkey,ZT_C25519_SHARED_KEY_LEN);
  203. memcpy(key,h,ZT_PEER_SECRET_KEY_LENGTH);
  204. return true;
  205. }
  206. }
  207. }
  208. return false;
  209. }
  210. char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
  211. {
  212. switch(_type) {
  213. case C25519: {
  214. char *p = buf;
  215. Utils::hex10(_address.toInt(),p);
  216. p += 10;
  217. *(p++) = ':';
  218. *(p++) = '0';
  219. *(p++) = ':';
  220. Utils::hex(_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN,p);
  221. p += ZT_C25519_PUBLIC_KEY_LEN * 2;
  222. if ((_hasPrivate)&&(includePrivate)) {
  223. *(p++) = ':';
  224. Utils::hex(_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN,p);
  225. p += ZT_C25519_PRIVATE_KEY_LEN * 2;
  226. }
  227. *p = (char)0;
  228. return buf;
  229. } break;
  230. case P384: {
  231. char *p = buf;
  232. Utils::hex10(_address.toInt(),p);
  233. p += 10;
  234. *(p++) = ':';
  235. *(p++) = '1';
  236. *(p++) = ':';
  237. int el = Utils::b32e((const uint8_t *)(&_pub),sizeof(_pub),p,(unsigned int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
  238. if (el <= 0) return nullptr;
  239. p += el;
  240. if ((_hasPrivate)&&(includePrivate)) {
  241. *(p++) = ':';
  242. el = Utils::b32e((const uint8_t *)(&_priv),sizeof(_priv),p,(unsigned int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
  243. if (el <= 0) return nullptr;
  244. p += el;
  245. }
  246. *p = (char)0;
  247. return buf;
  248. } break;
  249. }
  250. return nullptr;
  251. }
  252. bool Identity::fromString(const char *str)
  253. {
  254. _hasPrivate = false;
  255. if (!str) {
  256. _address.zero();
  257. return false;
  258. }
  259. char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
  260. if (!Utils::scopy(tmp,sizeof(tmp),str)) {
  261. _address.zero();
  262. return false;
  263. }
  264. int fno = 0;
  265. char *saveptr = (char *)0;
  266. for(char *f=Utils::stok(tmp,":",&saveptr);((f)&&(fno < 4));f=Utils::stok((char *)0,":",&saveptr)) {
  267. switch(fno++) {
  268. case 0:
  269. _address = Address(Utils::hexStrToU64(f));
  270. if (_address.isReserved()) {
  271. _address.zero();
  272. return false;
  273. }
  274. break;
  275. case 1:
  276. if ((f[0] == '0')&&(!f[1])) {
  277. _type = C25519;
  278. } else if ((f[0] == '1')&&(!f[1])) {
  279. _type = P384;
  280. } else {
  281. _address.zero();
  282. return false;
  283. }
  284. break;
  285. case 2:
  286. switch(_type) {
  287. case C25519:
  288. if (Utils::unhex(f,strlen(f),_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN) != ZT_C25519_PUBLIC_KEY_LEN) {
  289. _address.zero();
  290. return false;
  291. }
  292. break;
  293. case P384:
  294. if (Utils::b32d(f,(uint8_t *)(&_pub),sizeof(_pub)) != sizeof(_pub)) {
  295. _address.zero();
  296. return false;
  297. }
  298. break;
  299. }
  300. break;
  301. case 3:
  302. if (strlen(f) > 1) {
  303. switch(_type) {
  304. case C25519:
  305. if (Utils::unhex(f,strlen(f),_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN) != ZT_C25519_PRIVATE_KEY_LEN) {
  306. _address.zero();
  307. return false;
  308. } else {
  309. _hasPrivate = true;
  310. }
  311. break;
  312. case P384:
  313. if (Utils::b32d(f,(uint8_t *)(&_priv),sizeof(_priv)) != sizeof(_priv)) {
  314. _address.zero();
  315. return false;
  316. } else {
  317. _hasPrivate = true;
  318. }
  319. break;
  320. }
  321. break;
  322. }
  323. }
  324. }
  325. if (fno < 3) {
  326. _address.zero();
  327. return false;
  328. }
  329. return true;
  330. }
  331. } // namespace ZeroTier
  332. extern "C" {
  333. ZT_Identity *ZT_Identity_new(enum ZT_Identity_Type type)
  334. {
  335. if ((type != ZT_IDENTITY_TYPE_C25519)&&(type != ZT_IDENTITY_TYPE_P384))
  336. return nullptr;
  337. try {
  338. ZeroTier::Identity *id = new ZeroTier::Identity();
  339. id->generate((ZeroTier::Identity::Type)type);
  340. return reinterpret_cast<ZT_Identity *>(id);
  341. } catch ( ... ) {
  342. return nullptr;
  343. }
  344. }
  345. ZT_Identity *ZT_Identity_fromString(const char *idStr)
  346. {
  347. if (!idStr)
  348. return nullptr;
  349. try {
  350. ZeroTier::Identity *id = new ZeroTier::Identity();
  351. if (!id->fromString(idStr)) {
  352. delete id;
  353. return nullptr;
  354. }
  355. return reinterpret_cast<ZT_Identity *>(id);
  356. } catch ( ... ) {
  357. return nullptr;
  358. }
  359. }
  360. int ZT_Identity_validate(const ZT_Identity *id)
  361. {
  362. if (!id)
  363. return 0;
  364. return reinterpret_cast<const ZeroTier::Identity *>(id)->locallyValidate() ? 1 : 0;
  365. }
  366. unsigned int ZT_Identity_sign(const ZT_Identity *id,const void *data,unsigned int len,void *signature,unsigned int signatureBufferLength)
  367. {
  368. if (!id)
  369. return 0;
  370. if (signatureBufferLength < ZT_SIGNATURE_BUFFER_SIZE)
  371. return 0;
  372. return reinterpret_cast<const ZeroTier::Identity *>(id)->sign(data,len,signature,signatureBufferLength);
  373. }
  374. int ZT_Identity_verify(const ZT_Identity *id,const void *data,unsigned int len,const void *signature,unsigned int sigLen)
  375. {
  376. if ((!id)||(!signature)||(!sigLen))
  377. return 0;
  378. return reinterpret_cast<const ZeroTier::Identity *>(id)->verify(data,len,signature,sigLen) ? 1 : 0;
  379. }
  380. enum ZT_Identity_Type ZT_Identity_type(const ZT_Identity *id)
  381. {
  382. if (!id)
  383. return (ZT_Identity_Type)0;
  384. return (enum ZT_Identity_Type)reinterpret_cast<const ZeroTier::Identity *>(id)->type();
  385. }
  386. char *ZT_Identity_toString(const ZT_Identity *id,char *buf,int capacity,int includePrivate)
  387. {
  388. if ((!id)||(!buf)||(capacity < ZT_IDENTITY_STRING_BUFFER_LENGTH))
  389. return nullptr;
  390. reinterpret_cast<const ZeroTier::Identity *>(id)->toString(includePrivate != 0,buf);
  391. return buf;
  392. }
  393. int ZT_Identity_hasPrivate(const ZT_Identity *id)
  394. {
  395. if (!id)
  396. return 0;
  397. return reinterpret_cast<const ZeroTier::Identity *>(id)->hasPrivate() ? 1 : 0;
  398. }
  399. uint64_t ZT_Identity_address(const ZT_Identity *id)
  400. {
  401. if (!id)
  402. return 0;
  403. return reinterpret_cast<const ZeroTier::Identity *>(id)->address().toInt();
  404. }
  405. void ZT_Identity_hash(const ZT_Identity *id,uint8_t h[48],int includePrivate)
  406. {
  407. reinterpret_cast<const ZeroTier::Identity *>(id)->hash(h,includePrivate != 0);
  408. }
  409. ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
  410. {
  411. if (id)
  412. delete reinterpret_cast<ZeroTier::Identity *>(id);
  413. }
  414. }