crypto_rsa.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2014,2016 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/crypto_rsa.c
  18. * @brief Chaum-style Blind signatures based on RSA
  19. * @author Sree Harsha Totakura <sreeharsha@totakura.in>
  20. * @author Christian Grothoff
  21. * @author Jeffrey Burdges <burdges@gnunet.org>
  22. */
  23. #include "platform.h"
  24. #include <gcrypt.h>
  25. #include "gnunet_crypto_lib.h"
  26. #include "benchmark.h"
  27. #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-rsa", __VA_ARGS__)
  28. /**
  29. * The private information of an RSA key pair.
  30. */
  31. struct GNUNET_CRYPTO_RsaPrivateKey
  32. {
  33. /**
  34. * Libgcrypt S-expression for the RSA private key.
  35. */
  36. gcry_sexp_t sexp;
  37. };
  38. /**
  39. * The public information of an RSA key pair.
  40. */
  41. struct GNUNET_CRYPTO_RsaPublicKey
  42. {
  43. /**
  44. * Libgcrypt S-expression for the RSA public key.
  45. */
  46. gcry_sexp_t sexp;
  47. };
  48. /**
  49. * @brief an RSA signature
  50. */
  51. struct GNUNET_CRYPTO_RsaSignature
  52. {
  53. /**
  54. * Libgcrypt S-expression for the RSA signature.
  55. */
  56. gcry_sexp_t sexp;
  57. };
  58. /**
  59. * @brief RSA blinding key
  60. */
  61. struct RsaBlindingKey
  62. {
  63. /**
  64. * Random value used for blinding.
  65. */
  66. gcry_mpi_t r;
  67. };
  68. /**
  69. * Extract values from an S-expression.
  70. *
  71. * @param array where to store the result(s)
  72. * @param sexp S-expression to parse
  73. * @param topname top-level name in the S-expression that is of interest
  74. * @param elems names of the elements to extract
  75. * @return 0 on success
  76. */
  77. static int
  78. key_from_sexp (gcry_mpi_t *array,
  79. gcry_sexp_t sexp,
  80. const char *topname,
  81. const char *elems)
  82. {
  83. gcry_sexp_t list;
  84. gcry_sexp_t l2;
  85. const char *s;
  86. unsigned int idx;
  87. if (! (list = gcry_sexp_find_token (sexp, topname, 0)))
  88. return 1;
  89. l2 = gcry_sexp_cadr (list);
  90. gcry_sexp_release (list);
  91. list = l2;
  92. if (! list)
  93. return 2;
  94. idx = 0;
  95. for (s = elems; *s; s++, idx++)
  96. {
  97. if (! (l2 = gcry_sexp_find_token (list, s, 1)))
  98. {
  99. for (unsigned int i = 0; i < idx; i++)
  100. {
  101. gcry_free (array[i]);
  102. array[i] = NULL;
  103. }
  104. gcry_sexp_release (list);
  105. return 3; /* required parameter not found */
  106. }
  107. array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
  108. gcry_sexp_release (l2);
  109. if (! array[idx])
  110. {
  111. for (unsigned int i = 0; i < idx; i++)
  112. {
  113. gcry_free (array[i]);
  114. array[i] = NULL;
  115. }
  116. gcry_sexp_release (list);
  117. return 4; /* required parameter is invalid */
  118. }
  119. }
  120. gcry_sexp_release (list);
  121. return 0;
  122. }
  123. /**
  124. * Create a new private key. Caller must free return value.
  125. *
  126. * @param len length of the key in bits (i.e. 2048)
  127. * @return fresh private key
  128. */
  129. struct GNUNET_CRYPTO_RsaPrivateKey *
  130. GNUNET_CRYPTO_rsa_private_key_create (unsigned int len)
  131. {
  132. struct GNUNET_CRYPTO_RsaPrivateKey *ret;
  133. gcry_sexp_t s_key;
  134. gcry_sexp_t s_keyparam;
  135. BENCHMARK_START (rsa_private_key_create);
  136. GNUNET_assert (0 ==
  137. gcry_sexp_build (&s_keyparam,
  138. NULL,
  139. "(genkey(rsa(nbits %d)))",
  140. len));
  141. GNUNET_assert (0 ==
  142. gcry_pk_genkey (&s_key,
  143. s_keyparam));
  144. gcry_sexp_release (s_keyparam);
  145. #if EXTRA_CHECKS
  146. GNUNET_assert (0 ==
  147. gcry_pk_testkey (s_key));
  148. #endif
  149. ret = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
  150. ret->sexp = s_key;
  151. BENCHMARK_END (rsa_private_key_create);
  152. return ret;
  153. }
  154. /**
  155. * Free memory occupied by the private key.
  156. *
  157. * @param key pointer to the memory to free
  158. */
  159. void
  160. GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key)
  161. {
  162. gcry_sexp_release (key->sexp);
  163. GNUNET_free (key);
  164. }
  165. /**
  166. * Encode the private key in a format suitable for
  167. * storing it into a file.
  168. *
  169. * @param key the private key
  170. * @param[out] buffer set to a buffer with the encoded key
  171. * @return size of memory allocated in @a buffer
  172. */
  173. size_t
  174. GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
  175. char **buffer)
  176. {
  177. size_t n;
  178. char *b;
  179. n = gcry_sexp_sprint (key->sexp,
  180. GCRYSEXP_FMT_DEFAULT,
  181. NULL,
  182. 0);
  183. b = GNUNET_malloc (n);
  184. GNUNET_assert ((n - 1) == /* since the last byte is \0 */
  185. gcry_sexp_sprint (key->sexp,
  186. GCRYSEXP_FMT_DEFAULT,
  187. b,
  188. n));
  189. *buffer = b;
  190. return n;
  191. }
  192. /**
  193. * Decode the private key from the data-format back
  194. * to the "normal", internal format.
  195. *
  196. * @param buf the buffer where the private key data is stored
  197. * @param len the length of the data in @a buf
  198. * @return NULL on error
  199. */
  200. struct GNUNET_CRYPTO_RsaPrivateKey *
  201. GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
  202. size_t len)
  203. {
  204. struct GNUNET_CRYPTO_RsaPrivateKey *key;
  205. key = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
  206. if (0 !=
  207. gcry_sexp_new (&key->sexp,
  208. buf,
  209. len,
  210. 0))
  211. {
  212. LOG (GNUNET_ERROR_TYPE_WARNING,
  213. "Decoded private key is not valid\n");
  214. GNUNET_free (key);
  215. return NULL;
  216. }
  217. if (0 != gcry_pk_testkey (key->sexp))
  218. {
  219. LOG (GNUNET_ERROR_TYPE_WARNING,
  220. "Decoded private key is not valid\n");
  221. GNUNET_CRYPTO_rsa_private_key_free (key);
  222. return NULL;
  223. }
  224. return key;
  225. }
  226. /**
  227. * Extract the public key of the given private key.
  228. *
  229. * @param priv the private key
  230. * @retur NULL on error, otherwise the public key
  231. */
  232. struct GNUNET_CRYPTO_RsaPublicKey *
  233. GNUNET_CRYPTO_rsa_private_key_get_public (const struct GNUNET_CRYPTO_RsaPrivateKey *priv)
  234. {
  235. struct GNUNET_CRYPTO_RsaPublicKey *pub;
  236. gcry_mpi_t ne[2];
  237. int rc;
  238. gcry_sexp_t result;
  239. BENCHMARK_START (rsa_private_key_get_public);
  240. rc = key_from_sexp (ne, priv->sexp, "public-key", "ne");
  241. if (0 != rc)
  242. rc = key_from_sexp (ne, priv->sexp, "private-key", "ne");
  243. if (0 != rc)
  244. rc = key_from_sexp (ne, priv->sexp, "rsa", "ne");
  245. if (0 != rc)
  246. {
  247. GNUNET_break_op (0);
  248. return NULL;
  249. }
  250. rc = gcry_sexp_build (&result,
  251. NULL,
  252. "(public-key(rsa(n %m)(e %m)))",
  253. ne[0],
  254. ne[1]);
  255. gcry_mpi_release (ne[0]);
  256. gcry_mpi_release (ne[1]);
  257. pub = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
  258. pub->sexp = result;
  259. BENCHMARK_END (rsa_private_key_get_public);
  260. return pub;
  261. }
  262. /**
  263. * Free memory occupied by the public key.
  264. *
  265. * @param key pointer to the memory to free
  266. */
  267. void
  268. GNUNET_CRYPTO_rsa_public_key_free (struct GNUNET_CRYPTO_RsaPublicKey *key)
  269. {
  270. gcry_sexp_release (key->sexp);
  271. GNUNET_free (key);
  272. }
  273. /**
  274. * Encode the public key in a format suitable for
  275. * storing it into a file.
  276. *
  277. * @param key the private key
  278. * @param[out] buffer set to a buffer with the encoded key
  279. * @return size of memory allocated in @a buffer
  280. */
  281. size_t
  282. GNUNET_CRYPTO_rsa_public_key_encode (const struct GNUNET_CRYPTO_RsaPublicKey *key,
  283. char **buffer)
  284. {
  285. size_t n;
  286. char *b;
  287. n = gcry_sexp_sprint (key->sexp,
  288. GCRYSEXP_FMT_ADVANCED,
  289. NULL,
  290. 0);
  291. b = GNUNET_malloc (n);
  292. GNUNET_assert ((n -1) == /* since the last byte is \0 */
  293. gcry_sexp_sprint (key->sexp,
  294. GCRYSEXP_FMT_ADVANCED,
  295. b,
  296. n));
  297. *buffer = b;
  298. return n;
  299. }
  300. /**
  301. * Compute hash over the public key.
  302. *
  303. * @param key public key to hash
  304. * @param hc where to store the hash code
  305. */
  306. void
  307. GNUNET_CRYPTO_rsa_public_key_hash (const struct GNUNET_CRYPTO_RsaPublicKey *key,
  308. struct GNUNET_HashCode *hc)
  309. {
  310. char *buf;
  311. size_t buf_size;
  312. buf_size = GNUNET_CRYPTO_rsa_public_key_encode (key,
  313. &buf);
  314. GNUNET_CRYPTO_hash (buf,
  315. buf_size,
  316. hc);
  317. GNUNET_free (buf);
  318. }
  319. /**
  320. * Decode the public key from the data-format back
  321. * to the "normal", internal format.
  322. *
  323. * @param buf the buffer where the public key data is stored
  324. * @param len the length of the data in @a buf
  325. * @return NULL on error
  326. */
  327. struct GNUNET_CRYPTO_RsaPublicKey *
  328. GNUNET_CRYPTO_rsa_public_key_decode (const char *buf,
  329. size_t len)
  330. {
  331. struct GNUNET_CRYPTO_RsaPublicKey *key;
  332. gcry_mpi_t n;
  333. int ret;
  334. key = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
  335. if (0 !=
  336. gcry_sexp_new (&key->sexp,
  337. buf,
  338. len,
  339. 0))
  340. {
  341. GNUNET_break_op (0);
  342. GNUNET_free (key);
  343. return NULL;
  344. }
  345. /* verify that this is an RSA public key */
  346. ret = key_from_sexp (&n, key->sexp, "public-key", "n");
  347. if (0 != ret)
  348. ret = key_from_sexp (&n, key->sexp, "rsa", "n");
  349. if (0 != ret)
  350. {
  351. /* this is no public RSA key */
  352. GNUNET_break (0);
  353. gcry_sexp_release (key->sexp);
  354. GNUNET_free (key);
  355. return NULL;
  356. }
  357. gcry_mpi_release (n);
  358. return key;
  359. }
  360. /**
  361. * Test for malicious RSA key.
  362. *
  363. * Assuming n is an RSA modulous and r is generated using a call to
  364. * GNUNET_CRYPTO_kdf_mod_mpi, if gcd(r,n) != 1 then n must be a
  365. * malicious RSA key designed to deanomize the user.
  366. *
  367. * @param r KDF result
  368. * @param n RSA modulus
  369. * @return True if gcd(r,n) = 1, False means RSA key is malicious
  370. */
  371. static int
  372. rsa_gcd_validate(gcry_mpi_t r, gcry_mpi_t n)
  373. {
  374. gcry_mpi_t g;
  375. int t;
  376. g = gcry_mpi_new (0);
  377. t = gcry_mpi_gcd(g,r,n);
  378. gcry_mpi_release (g);
  379. return t;
  380. }
  381. /**
  382. * Create a blinding key
  383. *
  384. * @param len length of the key in bits (i.e. 2048)
  385. * @param bks pre-secret to use to derive the blinding key
  386. * @return the newly created blinding key, NULL if RSA key is malicious
  387. */
  388. static struct RsaBlindingKey *
  389. rsa_blinding_key_derive (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
  390. const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks)
  391. {
  392. char *xts = "Blinding KDF extrator HMAC key"; /* Trusts bks' randomness more */
  393. struct RsaBlindingKey *blind;
  394. gcry_mpi_t n;
  395. blind = GNUNET_new (struct RsaBlindingKey);
  396. GNUNET_assert( NULL != blind );
  397. /* Extract the composite n from the RSA public key */
  398. GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
  399. /* Assert that it at least looks like an RSA key */
  400. GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
  401. GNUNET_CRYPTO_kdf_mod_mpi (&blind->r,
  402. n,
  403. xts, strlen(xts),
  404. bks, sizeof(*bks),
  405. "Blinding KDF");
  406. if (0 == rsa_gcd_validate(blind->r, n)) {
  407. GNUNET_free (blind);
  408. blind = NULL;
  409. }
  410. gcry_mpi_release (n);
  411. return blind;
  412. }
  413. /*
  414. We originally added GNUNET_CRYPTO_kdf_mod_mpi for the benifit of the
  415. previous routine.
  416. There was previously a call to GNUNET_CRYPTO_kdf in
  417. bkey = rsa_blinding_key_derive (len, bks);
  418. that gives exactly len bits where
  419. len = GNUNET_CRYPTO_rsa_public_key_len (pkey);
  420. Now r = 2^(len-1)/pkey.n is the probability that a set high bit being
  421. okay, meaning bkey < pkey.n. It follows that (1-r)/2 of the time bkey >
  422. pkey.n making the effective bkey be
  423. bkey mod pkey.n = bkey - pkey.n
  424. so the effective bkey has its high bit set with probability r/2.
  425. We expect r to be close to 1/2 if the exchange is honest, but the
  426. exchange can choose r otherwise.
  427. In blind signing, the exchange sees
  428. B = bkey * S mod pkey.n
  429. On deposit, the exchange sees S so they can compute bkey' = B/S mod
  430. pkey.n for all B they recorded to see if bkey' has it's high bit set.
  431. Also, note the exchange can compute 1/S efficiently since they know the
  432. factors of pkey.n.
  433. I suppose that happens with probability r/(1+r) if its the wrong B, not
  434. completely sure. If otoh we've the right B, then we've the probability
  435. r/2 of a set high bit in the effective bkey.
  436. Interestingly, r^2-r has a maximum at the default r=1/2 anyways, giving
  437. the wrong and right probabilities 1/3 and 1/4, respectively.
  438. I feared this gives the exchange a meaningful fraction of a bit of
  439. information per coin involved in the transaction. It sounds damaging if
  440. numerous coins were involved. And it could run across transactions in
  441. some scenarios.
  442. We fixed this by using a more uniform deterministic pseudo-random number
  443. generator for blinding factors. I do not believe this to be a problem
  444. for the rsa_full_domain_hash routine, but better safe than sorry.
  445. */
  446. /**
  447. * Compare the values of two signatures.
  448. *
  449. * @param s1 one signature
  450. * @param s2 the other signature
  451. * @return 0 if the two are equal
  452. */
  453. int
  454. GNUNET_CRYPTO_rsa_signature_cmp (struct GNUNET_CRYPTO_RsaSignature *s1,
  455. struct GNUNET_CRYPTO_RsaSignature *s2)
  456. {
  457. char *b1;
  458. char *b2;
  459. size_t z1;
  460. size_t z2;
  461. int ret;
  462. z1 = GNUNET_CRYPTO_rsa_signature_encode (s1,
  463. &b1);
  464. z2 = GNUNET_CRYPTO_rsa_signature_encode (s2,
  465. &b2);
  466. if (z1 != z2)
  467. ret = 1;
  468. else
  469. ret = memcmp (b1,
  470. b2,
  471. z1);
  472. GNUNET_free (b1);
  473. GNUNET_free (b2);
  474. return ret;
  475. }
  476. /**
  477. * Compare the values of two public keys.
  478. *
  479. * @param p1 one public key
  480. * @param p2 the other public key
  481. * @return 0 if the two are equal
  482. */
  483. int
  484. GNUNET_CRYPTO_rsa_public_key_cmp (struct GNUNET_CRYPTO_RsaPublicKey *p1,
  485. struct GNUNET_CRYPTO_RsaPublicKey *p2)
  486. {
  487. char *b1;
  488. char *b2;
  489. size_t z1;
  490. size_t z2;
  491. int ret;
  492. z1 = GNUNET_CRYPTO_rsa_public_key_encode (p1,
  493. &b1);
  494. z2 = GNUNET_CRYPTO_rsa_public_key_encode (p2,
  495. &b2);
  496. if (z1 != z2)
  497. ret = 1;
  498. else
  499. ret = memcmp (b1,
  500. b2,
  501. z1);
  502. GNUNET_free (b1);
  503. GNUNET_free (b2);
  504. return ret;
  505. }
  506. /**
  507. * Compare the values of two private keys.
  508. *
  509. * @param p1 one private key
  510. * @param p2 the other private key
  511. * @return 0 if the two are equal
  512. */
  513. int
  514. GNUNET_CRYPTO_rsa_private_key_cmp (struct GNUNET_CRYPTO_RsaPrivateKey *p1,
  515. struct GNUNET_CRYPTO_RsaPrivateKey *p2)
  516. {
  517. char *b1;
  518. char *b2;
  519. size_t z1;
  520. size_t z2;
  521. int ret;
  522. z1 = GNUNET_CRYPTO_rsa_private_key_encode (p1,
  523. &b1);
  524. z2 = GNUNET_CRYPTO_rsa_private_key_encode (p2,
  525. &b2);
  526. if (z1 != z2)
  527. ret = 1;
  528. else
  529. ret = memcmp (b1,
  530. b2,
  531. z1);
  532. GNUNET_free (b1);
  533. GNUNET_free (b2);
  534. return ret;
  535. }
  536. /**
  537. * Obtain the length of the RSA key in bits.
  538. *
  539. * @param key the public key to introspect
  540. * @return length of the key in bits
  541. */
  542. unsigned int
  543. GNUNET_CRYPTO_rsa_public_key_len (const struct GNUNET_CRYPTO_RsaPublicKey *key)
  544. {
  545. gcry_mpi_t n;
  546. unsigned int rval;
  547. if (0 != key_from_sexp (&n, key->sexp, "rsa", "n"))
  548. { /* Not an RSA public key */
  549. GNUNET_break (0);
  550. return 0;
  551. }
  552. rval = gcry_mpi_get_nbits (n);
  553. gcry_mpi_release (n);
  554. return rval;
  555. }
  556. /**
  557. * Destroy a blinding key
  558. *
  559. * @param bkey the blinding key to destroy
  560. */
  561. static void
  562. rsa_blinding_key_free (struct RsaBlindingKey *bkey)
  563. {
  564. gcry_mpi_release (bkey->r);
  565. GNUNET_free (bkey);
  566. }
  567. /**
  568. * Print an MPI to a newly created buffer
  569. *
  570. * @param v MPI to print.
  571. * @param[out] newly allocated buffer containing the result
  572. * @return number of bytes stored in @a buffer
  573. */
  574. static size_t
  575. numeric_mpi_alloc_n_print (gcry_mpi_t v,
  576. char **buffer)
  577. {
  578. size_t n;
  579. char *b;
  580. size_t rsize;
  581. gcry_mpi_print (GCRYMPI_FMT_USG,
  582. NULL,
  583. 0,
  584. &n,
  585. v);
  586. b = GNUNET_malloc (n);
  587. GNUNET_assert (0 ==
  588. gcry_mpi_print (GCRYMPI_FMT_USG,
  589. (unsigned char *) b,
  590. n,
  591. &rsize,
  592. v));
  593. *buffer = b;
  594. return n;
  595. }
  596. /**
  597. * Computes a full domain hash seeded by the given public key.
  598. * This gives a measure of provable security to the Taler exchange
  599. * against one-more forgery attacks. See:
  600. * https://eprint.iacr.org/2001/002.pdf
  601. * http://www.di.ens.fr/~pointche/Documents/Papers/2001_fcA.pdf
  602. *
  603. * @param hash initial hash of the message to sign
  604. * @param pkey the public key of the signer
  605. * @param rsize If not NULL, the number of bytes actually stored in buffer
  606. * @return MPI value set to the FDH, NULL if RSA key is malicious
  607. */
  608. static gcry_mpi_t
  609. rsa_full_domain_hash (const struct GNUNET_CRYPTO_RsaPublicKey *pkey,
  610. const struct GNUNET_HashCode *hash)
  611. {
  612. gcry_mpi_t r,n;
  613. char *xts;
  614. size_t xts_len;
  615. int ok;
  616. /* Extract the composite n from the RSA public key */
  617. GNUNET_assert( 0 == key_from_sexp (&n, pkey->sexp, "rsa", "n") );
  618. /* Assert that it at least looks like an RSA key */
  619. GNUNET_assert( 0 == gcry_mpi_get_flag(n, GCRYMPI_FLAG_OPAQUE) );
  620. /* We key with the public denomination key as a homage to RSA-PSS by *
  621. * Mihir Bellare and Phillip Rogaway. Doing this lowers the degree *
  622. * of the hypothetical polyomial-time attack on RSA-KTI created by a *
  623. * polynomial-time one-more forgary attack. Yey seeding! */
  624. xts_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &xts);
  625. GNUNET_CRYPTO_kdf_mod_mpi (&r,
  626. n,
  627. xts, xts_len,
  628. hash, sizeof(*hash),
  629. "RSA-FDA FTpsW!");
  630. GNUNET_free (xts);
  631. ok = rsa_gcd_validate(r,n);
  632. gcry_mpi_release (n);
  633. if (ok)
  634. return r;
  635. gcry_mpi_release (r);
  636. return NULL;
  637. }
  638. /**
  639. * Blinds the given message with the given blinding key
  640. *
  641. * @param hash hash of the message to sign
  642. * @param bkey the blinding key
  643. * @param pkey the public key of the signer
  644. * @param[out] buf set to a buffer with the blinded message to be signed
  645. * @param[out] buf_size number of bytes stored in @a buf
  646. * @return #GNUNET_YES if successful, #GNUNET_NO if RSA key is malicious
  647. */
  648. int
  649. GNUNET_CRYPTO_rsa_blind (const struct GNUNET_HashCode *hash,
  650. const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
  651. struct GNUNET_CRYPTO_RsaPublicKey *pkey,
  652. char **buf, size_t *buf_size)
  653. {
  654. struct RsaBlindingKey *bkey;
  655. gcry_mpi_t data;
  656. gcry_mpi_t ne[2];
  657. gcry_mpi_t r_e;
  658. gcry_mpi_t data_r_e;
  659. int ret;
  660. BENCHMARK_START (rsa_blind);
  661. GNUNET_assert (buf != NULL && buf_size != NULL);
  662. ret = key_from_sexp (ne, pkey->sexp, "public-key", "ne");
  663. if (0 != ret)
  664. ret = key_from_sexp (ne, pkey->sexp, "rsa", "ne");
  665. if (0 != ret)
  666. {
  667. GNUNET_break (0);
  668. *buf = NULL;
  669. *buf_size = 0;
  670. return 0;
  671. }
  672. data = rsa_full_domain_hash (pkey, hash);
  673. if (NULL == data)
  674. goto rsa_gcd_validate_failure;
  675. bkey = rsa_blinding_key_derive (pkey, bks);
  676. if (NULL == bkey) {
  677. gcry_mpi_release (data);
  678. goto rsa_gcd_validate_failure;
  679. }
  680. r_e = gcry_mpi_new (0);
  681. gcry_mpi_powm (r_e,
  682. bkey->r,
  683. ne[1],
  684. ne[0]);
  685. data_r_e = gcry_mpi_new (0);
  686. gcry_mpi_mulm (data_r_e,
  687. data,
  688. r_e,
  689. ne[0]);
  690. gcry_mpi_release (data);
  691. gcry_mpi_release (ne[0]);
  692. gcry_mpi_release (ne[1]);
  693. gcry_mpi_release (r_e);
  694. rsa_blinding_key_free (bkey);
  695. *buf_size = numeric_mpi_alloc_n_print (data_r_e, buf);
  696. gcry_mpi_release (data_r_e);
  697. BENCHMARK_END (rsa_blind);
  698. return GNUNET_YES;
  699. rsa_gcd_validate_failure:
  700. /* We know the RSA key is malicious here, so warn the wallet. */
  701. /* GNUNET_break_op (0); */
  702. gcry_mpi_release (ne[0]);
  703. gcry_mpi_release (ne[1]);
  704. *buf = NULL;
  705. *buf_size = 0;
  706. return GNUNET_NO;
  707. }
  708. /**
  709. * Convert an MPI to an S-expression suitable for signature operations.
  710. *
  711. * @param value pointer to the data to convert
  712. * @return converted s-expression
  713. */
  714. static gcry_sexp_t
  715. mpi_to_sexp (gcry_mpi_t value)
  716. {
  717. gcry_sexp_t data = NULL;
  718. GNUNET_assert (0 ==
  719. gcry_sexp_build (&data,
  720. NULL,
  721. "(data (flags raw) (value %M))",
  722. value));
  723. return data;
  724. }
  725. /**
  726. * Sign the given MPI.
  727. *
  728. * @param key private key to use for the signing
  729. * @param value the MPI to sign
  730. * @return NULL on error, signature on success
  731. */
  732. static struct GNUNET_CRYPTO_RsaSignature *
  733. rsa_sign_mpi (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
  734. gcry_mpi_t value)
  735. {
  736. struct GNUNET_CRYPTO_RsaSignature *sig;
  737. gcry_sexp_t data;
  738. gcry_sexp_t result;
  739. int rc;
  740. data = mpi_to_sexp (value);
  741. if (0 !=
  742. (rc = gcry_pk_sign (&result,
  743. data,
  744. key->sexp)))
  745. {
  746. LOG (GNUNET_ERROR_TYPE_WARNING,
  747. _("RSA signing failed at %s:%d: %s\n"),
  748. __FILE__,
  749. __LINE__,
  750. gcry_strerror (rc));
  751. GNUNET_break (0);
  752. return NULL;
  753. }
  754. /* Lenstra protection was first added to libgcrypt 1.6.4
  755. * with commit c17f84bd02d7ee93845e92e20f6ddba814961588.
  756. */
  757. #if GCRYPT_VERSION_NUMBER < 0x010604
  758. /* verify signature (guards against Lenstra's attack with fault injection...) */
  759. struct GNUNET_CRYPTO_RsaPublicKey *public_key = GNUNET_CRYPTO_rsa_private_key_get_public (key);
  760. if (0 !=
  761. gcry_pk_verify (result,
  762. data,
  763. public_key->sexp))
  764. {
  765. GNUNET_break (0);
  766. GNUNET_CRYPTO_rsa_public_key_free (public_key);
  767. gcry_sexp_release (data);
  768. gcry_sexp_release (result);
  769. return NULL;
  770. }
  771. GNUNET_CRYPTO_rsa_public_key_free (public_key);
  772. #endif
  773. /* return signature */
  774. gcry_sexp_release (data);
  775. sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
  776. sig->sexp = result;
  777. return sig;
  778. }
  779. /**
  780. * Sign a blinded value, which must be a full domain hash of a message.
  781. *
  782. * @param key private key to use for the signing
  783. * @param msg the message to sign
  784. * @param msg_len number of bytes in @a msg to sign
  785. * @return NULL on error, signature on success
  786. */
  787. struct GNUNET_CRYPTO_RsaSignature *
  788. GNUNET_CRYPTO_rsa_sign_blinded (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
  789. const void *msg,
  790. size_t msg_len)
  791. {
  792. gcry_mpi_t v = NULL;
  793. struct GNUNET_CRYPTO_RsaSignature *sig;
  794. BENCHMARK_START (rsa_sign_blinded);
  795. GNUNET_assert (0 ==
  796. gcry_mpi_scan (&v,
  797. GCRYMPI_FMT_USG,
  798. msg,
  799. msg_len,
  800. NULL));
  801. sig = rsa_sign_mpi (key, v);
  802. gcry_mpi_release (v);
  803. BENCHMARK_END (rsa_sign_blinded);
  804. return sig;
  805. }
  806. /**
  807. * Create and sign a full domain hash of a message.
  808. *
  809. * @param key private key to use for the signing
  810. * @param hash the hash of the message to sign
  811. * @return NULL on error, including a malicious RSA key, signature on success
  812. */
  813. struct GNUNET_CRYPTO_RsaSignature *
  814. GNUNET_CRYPTO_rsa_sign_fdh (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
  815. const struct GNUNET_HashCode *hash)
  816. {
  817. struct GNUNET_CRYPTO_RsaPublicKey *pkey;
  818. gcry_mpi_t v = NULL;
  819. struct GNUNET_CRYPTO_RsaSignature *sig;
  820. pkey = GNUNET_CRYPTO_rsa_private_key_get_public (key);
  821. v = rsa_full_domain_hash (pkey, hash);
  822. GNUNET_CRYPTO_rsa_public_key_free (pkey);
  823. if (NULL == v) /* rsa_gcd_validate failed meaning */
  824. return NULL; /* our *own* RSA key is malicious. */
  825. sig = rsa_sign_mpi (key, v);
  826. gcry_mpi_release (v);
  827. return sig;
  828. }
  829. /**
  830. * Free memory occupied by signature.
  831. *
  832. * @param sig memory to freee
  833. */
  834. void
  835. GNUNET_CRYPTO_rsa_signature_free (struct GNUNET_CRYPTO_RsaSignature *sig)
  836. {
  837. gcry_sexp_release (sig->sexp);
  838. GNUNET_free (sig);
  839. }
  840. /**
  841. * Encode the given signature in a format suitable for storing it into a file.
  842. *
  843. * @param sig the signature
  844. * @param[out] buffer set to a buffer with the encoded key
  845. * @return size of memory allocated in @a buffer
  846. */
  847. size_t
  848. GNUNET_CRYPTO_rsa_signature_encode (const struct GNUNET_CRYPTO_RsaSignature *sig,
  849. char **buffer)
  850. {
  851. size_t n;
  852. char *b;
  853. n = gcry_sexp_sprint (sig->sexp,
  854. GCRYSEXP_FMT_ADVANCED,
  855. NULL,
  856. 0);
  857. b = GNUNET_malloc (n);
  858. GNUNET_assert ((n - 1) == /* since the last byte is \0 */
  859. gcry_sexp_sprint (sig->sexp,
  860. GCRYSEXP_FMT_ADVANCED,
  861. b,
  862. n));
  863. *buffer = b;
  864. return n;
  865. }
  866. /**
  867. * Decode the signature from the data-format back to the "normal", internal
  868. * format.
  869. *
  870. * @param buf the buffer where the public key data is stored
  871. * @param len the length of the data in @a buf
  872. * @return NULL on error
  873. */
  874. struct GNUNET_CRYPTO_RsaSignature *
  875. GNUNET_CRYPTO_rsa_signature_decode (const char *buf,
  876. size_t len)
  877. {
  878. struct GNUNET_CRYPTO_RsaSignature *sig;
  879. int ret;
  880. gcry_mpi_t s;
  881. sig = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
  882. if (0 !=
  883. gcry_sexp_new (&sig->sexp,
  884. buf,
  885. len,
  886. 0))
  887. {
  888. GNUNET_break_op (0);
  889. GNUNET_free (sig);
  890. return NULL;
  891. }
  892. /* verify that this is an RSA signature */
  893. ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  894. if (0 != ret)
  895. ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  896. if (0 != ret)
  897. {
  898. /* this is no RSA Signature */
  899. GNUNET_break_op (0);
  900. gcry_sexp_release (sig->sexp);
  901. GNUNET_free (sig);
  902. return NULL;
  903. }
  904. gcry_mpi_release (s);
  905. return sig;
  906. }
  907. /**
  908. * Duplicate the given public key
  909. *
  910. * @param key the public key to duplicate
  911. * @return the duplicate key; NULL upon error
  912. */
  913. struct GNUNET_CRYPTO_RsaPublicKey *
  914. GNUNET_CRYPTO_rsa_public_key_dup (const struct GNUNET_CRYPTO_RsaPublicKey *key)
  915. {
  916. struct GNUNET_CRYPTO_RsaPublicKey *dup;
  917. gcry_sexp_t dup_sexp;
  918. size_t erroff;
  919. /* check if we really are exporting a public key */
  920. dup_sexp = gcry_sexp_find_token (key->sexp, "public-key", 0);
  921. GNUNET_assert (NULL != dup_sexp);
  922. gcry_sexp_release (dup_sexp);
  923. /* copy the sexp */
  924. GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
  925. dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPublicKey);
  926. dup->sexp = dup_sexp;
  927. return dup;
  928. }
  929. /**
  930. * Unblind a blind-signed signature. The signature should have been generated
  931. * with #GNUNET_CRYPTO_rsa_sign() using a hash that was blinded with
  932. * #GNUNET_CRYPTO_rsa_blind().
  933. *
  934. * @param sig the signature made on the blinded signature purpose
  935. * @param bks the blinding key secret used to blind the signature purpose
  936. * @param pkey the public key of the signer
  937. * @return unblinded signature on success, NULL if RSA key is bad or malicious.
  938. */
  939. struct GNUNET_CRYPTO_RsaSignature *
  940. GNUNET_CRYPTO_rsa_unblind (const struct GNUNET_CRYPTO_RsaSignature *sig,
  941. const struct GNUNET_CRYPTO_RsaBlindingKeySecret *bks,
  942. struct GNUNET_CRYPTO_RsaPublicKey *pkey)
  943. {
  944. struct RsaBlindingKey *bkey;
  945. gcry_mpi_t n;
  946. gcry_mpi_t s;
  947. gcry_mpi_t r_inv;
  948. gcry_mpi_t ubsig;
  949. int ret;
  950. struct GNUNET_CRYPTO_RsaSignature *sret;
  951. BENCHMARK_START (rsa_unblind);
  952. ret = key_from_sexp (&n, pkey->sexp, "public-key", "n");
  953. if (0 != ret)
  954. ret = key_from_sexp (&n, pkey->sexp, "rsa", "n");
  955. if (0 != ret)
  956. {
  957. GNUNET_break_op (0);
  958. return NULL;
  959. }
  960. ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  961. if (0 != ret)
  962. ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  963. if (0 != ret)
  964. {
  965. gcry_mpi_release (n);
  966. GNUNET_break_op (0);
  967. return NULL;
  968. }
  969. bkey = rsa_blinding_key_derive (pkey, bks);
  970. if (NULL == bkey)
  971. {
  972. /* RSA key is malicious since rsa_gcd_validate failed here.
  973. * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
  974. * so the exchange is being malicious in an unfamilair way, maybe
  975. * just trying to crash us. */
  976. GNUNET_break_op (0);
  977. gcry_mpi_release (n);
  978. gcry_mpi_release (s);
  979. return NULL;
  980. }
  981. r_inv = gcry_mpi_new (0);
  982. if (1 !=
  983. gcry_mpi_invm (r_inv,
  984. bkey->r,
  985. n))
  986. {
  987. /* We cannot find r mod n, so gcd(r,n) != 1, which should get *
  988. * caught above, but we handle it the same here. */
  989. GNUNET_break_op (0);
  990. gcry_mpi_release (r_inv);
  991. rsa_blinding_key_free (bkey);
  992. gcry_mpi_release (n);
  993. gcry_mpi_release (s);
  994. return NULL;
  995. }
  996. ubsig = gcry_mpi_new (0);
  997. gcry_mpi_mulm (ubsig, s, r_inv, n);
  998. gcry_mpi_release (n);
  999. gcry_mpi_release (r_inv);
  1000. gcry_mpi_release (s);
  1001. rsa_blinding_key_free (bkey);
  1002. sret = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
  1003. GNUNET_assert (0 ==
  1004. gcry_sexp_build (&sret->sexp,
  1005. NULL,
  1006. "(sig-val (rsa (s %M)))",
  1007. ubsig));
  1008. gcry_mpi_release (ubsig);
  1009. BENCHMARK_END (rsa_unblind);
  1010. return sret;
  1011. }
  1012. /**
  1013. * Verify whether the given hash corresponds to the given signature and
  1014. * the signature is valid with respect to the given public key.
  1015. *
  1016. * @param hash hash of the message to verify to match the @a sig
  1017. * @param sig signature that is being validated
  1018. * @param pkey public key of the signer
  1019. * @returns #GNUNET_YES if ok, #GNUNET_NO if RSA key is malicious, #GNUNET_SYSERR if signature is invalid
  1020. */
  1021. int
  1022. GNUNET_CRYPTO_rsa_verify (const struct GNUNET_HashCode *hash,
  1023. const struct GNUNET_CRYPTO_RsaSignature *sig,
  1024. const struct GNUNET_CRYPTO_RsaPublicKey *pkey)
  1025. {
  1026. gcry_sexp_t data;
  1027. gcry_mpi_t r;
  1028. int rc;
  1029. BENCHMARK_START (rsa_verify);
  1030. r = rsa_full_domain_hash (pkey, hash);
  1031. if (NULL == r) {
  1032. GNUNET_break_op (0);
  1033. /* RSA key is malicious since rsa_gcd_validate failed here.
  1034. * It should have failed during GNUNET_CRYPTO_rsa_blind too though,
  1035. * so the exchange is being malicious in an unfamilair way, maybe
  1036. * just trying to crash us. Arguably, we've only an internal error
  1037. * though because we should've detected this in our previous call
  1038. * to GNUNET_CRYPTO_rsa_unblind. */
  1039. return GNUNET_NO;
  1040. }
  1041. data = mpi_to_sexp(r);
  1042. gcry_mpi_release (r);
  1043. rc = gcry_pk_verify (sig->sexp,
  1044. data,
  1045. pkey->sexp);
  1046. gcry_sexp_release (data);
  1047. if (0 != rc)
  1048. {
  1049. LOG (GNUNET_ERROR_TYPE_WARNING,
  1050. _("RSA signature verification failed at %s:%d: %s\n"),
  1051. __FILE__,
  1052. __LINE__,
  1053. gcry_strerror (rc));
  1054. return GNUNET_SYSERR;
  1055. BENCHMARK_END (rsa_verify);
  1056. }
  1057. BENCHMARK_END (rsa_verify);
  1058. return GNUNET_OK;
  1059. }
  1060. /**
  1061. * Duplicate the given private key
  1062. *
  1063. * @param key the private key to duplicate
  1064. * @return the duplicate key; NULL upon error
  1065. */
  1066. struct GNUNET_CRYPTO_RsaPrivateKey *
  1067. GNUNET_CRYPTO_rsa_private_key_dup (const struct GNUNET_CRYPTO_RsaPrivateKey *key)
  1068. {
  1069. struct GNUNET_CRYPTO_RsaPrivateKey *dup;
  1070. gcry_sexp_t dup_sexp;
  1071. size_t erroff;
  1072. /* check if we really are exporting a private key */
  1073. dup_sexp = gcry_sexp_find_token (key->sexp, "private-key", 0);
  1074. GNUNET_assert (NULL != dup_sexp);
  1075. gcry_sexp_release (dup_sexp);
  1076. /* copy the sexp */
  1077. GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", key->sexp));
  1078. dup = GNUNET_new (struct GNUNET_CRYPTO_RsaPrivateKey);
  1079. dup->sexp = dup_sexp;
  1080. return dup;
  1081. }
  1082. /**
  1083. * Duplicate the given private key
  1084. *
  1085. * @param key the private key to duplicate
  1086. * @return the duplicate key; NULL upon error
  1087. */
  1088. struct GNUNET_CRYPTO_RsaSignature *
  1089. GNUNET_CRYPTO_rsa_signature_dup (const struct GNUNET_CRYPTO_RsaSignature *sig)
  1090. {
  1091. struct GNUNET_CRYPTO_RsaSignature *dup;
  1092. gcry_sexp_t dup_sexp;
  1093. size_t erroff;
  1094. gcry_mpi_t s;
  1095. int ret;
  1096. /* verify that this is an RSA signature */
  1097. ret = key_from_sexp (&s, sig->sexp, "sig-val", "s");
  1098. if (0 != ret)
  1099. ret = key_from_sexp (&s, sig->sexp, "rsa", "s");
  1100. GNUNET_assert (0 == ret);
  1101. gcry_mpi_release (s);
  1102. /* copy the sexp */
  1103. GNUNET_assert (0 == gcry_sexp_build (&dup_sexp, &erroff, "%S", sig->sexp));
  1104. dup = GNUNET_new (struct GNUNET_CRYPTO_RsaSignature);
  1105. dup->sexp = dup_sexp;
  1106. return dup;
  1107. }
  1108. /* end of util/rsa.c */