diff options
author | Florian Dold <florian.dold@gmail.com> | 2014-04-14 23:07:14 +0000 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2014-04-14 23:07:14 +0000 |
commit | b6cc69953e7669e31db2a194d11ae134e8dfb86d (patch) | |
tree | 0add410650f6e4352a466f8803894bd1890ca446 /src/secretsharing | |
parent | cdb389d8d3c4ac54739961c9e90cd8cabb2cbed5 (diff) | |
download | gnunet-b6cc69953e7669e31db2a194d11ae134e8dfb86d.tar.gz gnunet-b6cc69953e7669e31db2a194d11ae134e8dfb86d.zip |
fix lots of memory leaks in secretsharing key generation
Diffstat (limited to 'src/secretsharing')
-rw-r--r-- | src/secretsharing/gnunet-service-secretsharing.c | 94 | ||||
-rw-r--r-- | src/secretsharing/secretsharing_common.c | 13 | ||||
-rw-r--r-- | src/secretsharing/test_secretsharing.conf | 2 |
3 files changed, 97 insertions, 12 deletions
diff --git a/src/secretsharing/gnunet-service-secretsharing.c b/src/secretsharing/gnunet-service-secretsharing.c index 0359fd0d7..f169a1655 100644 --- a/src/secretsharing/gnunet-service-secretsharing.c +++ b/src/secretsharing/gnunet-service-secretsharing.c | |||
@@ -574,6 +574,26 @@ decrypt_session_destroy (struct DecryptSession *ds) | |||
574 | GNUNET_free (ds); | 574 | GNUNET_free (ds); |
575 | } | 575 | } |
576 | 576 | ||
577 | static void | ||
578 | keygen_info_destroy (struct KeygenPeerInfo *info) | ||
579 | { | ||
580 | if (NULL != info->sigma) | ||
581 | { | ||
582 | gcry_mpi_release (info->sigma); | ||
583 | info->sigma = NULL; | ||
584 | } | ||
585 | if (NULL != info->presecret_commitment) | ||
586 | { | ||
587 | gcry_mpi_release (info->presecret_commitment); | ||
588 | info->presecret_commitment = NULL; | ||
589 | } | ||
590 | if (NULL != info->preshare_commitment) | ||
591 | { | ||
592 | gcry_mpi_release (info->preshare_commitment); | ||
593 | info->presecret_commitment = NULL; | ||
594 | } | ||
595 | } | ||
596 | |||
577 | 597 | ||
578 | static void | 598 | static void |
579 | keygen_session_destroy (struct KeygenSession *ks) | 599 | keygen_session_destroy (struct KeygenSession *ks) |
@@ -582,12 +602,34 @@ keygen_session_destroy (struct KeygenSession *ks) | |||
582 | 602 | ||
583 | GNUNET_CONTAINER_DLL_remove (keygen_sessions_head, keygen_sessions_tail, ks); | 603 | GNUNET_CONTAINER_DLL_remove (keygen_sessions_head, keygen_sessions_tail, ks); |
584 | 604 | ||
605 | if (NULL != ks->info) | ||
606 | { | ||
607 | unsigned int i; | ||
608 | for (i = 0; i < ks->num_peers; i++) | ||
609 | keygen_info_destroy (&ks->info[i]); | ||
610 | GNUNET_free (ks->info); | ||
611 | ks->info = NULL; | ||
612 | } | ||
613 | |||
585 | if (NULL != ks->consensus) | 614 | if (NULL != ks->consensus) |
586 | { | 615 | { |
587 | GNUNET_CONSENSUS_destroy (ks->consensus); | 616 | GNUNET_CONSENSUS_destroy (ks->consensus); |
588 | ks->consensus = NULL; | 617 | ks->consensus = NULL; |
589 | } | 618 | } |
590 | 619 | ||
620 | if (NULL != ks->presecret_polynomial) | ||
621 | { | ||
622 | unsigned int i; | ||
623 | for (i = 0; i < ks->threshold; i++) | ||
624 | { | ||
625 | GNUNET_assert (NULL != ks->presecret_polynomial[i]); | ||
626 | gcry_mpi_release (ks->presecret_polynomial[i]); | ||
627 | ks->presecret_polynomial[i] = NULL; | ||
628 | } | ||
629 | GNUNET_free (ks->presecret_polynomial); | ||
630 | ks->presecret_polynomial = NULL; | ||
631 | } | ||
632 | |||
591 | if (NULL != ks->client_mq) | 633 | if (NULL != ks->client_mq) |
592 | { | 634 | { |
593 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen MQ\n"); | 635 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying keygen MQ\n"); |
@@ -595,6 +637,24 @@ keygen_session_destroy (struct KeygenSession *ks) | |||
595 | ks->client_mq = NULL; | 637 | ks->client_mq = NULL; |
596 | } | 638 | } |
597 | 639 | ||
640 | if (NULL != ks->my_share) | ||
641 | { | ||
642 | gcry_mpi_release (ks->my_share); | ||
643 | ks->my_share = NULL; | ||
644 | } | ||
645 | |||
646 | if (NULL != ks->public_key) | ||
647 | { | ||
648 | gcry_mpi_release (ks->public_key); | ||
649 | ks->public_key = NULL; | ||
650 | } | ||
651 | |||
652 | if (NULL != ks->peers) | ||
653 | { | ||
654 | GNUNET_free (ks->peers); | ||
655 | ks->peers = NULL; | ||
656 | } | ||
657 | |||
598 | if (NULL != ks->client) | 658 | if (NULL != ks->client) |
599 | { | 659 | { |
600 | GNUNET_SERVER_client_disconnect (ks->client); | 660 | GNUNET_SERVER_client_disconnect (ks->client); |
@@ -802,9 +862,6 @@ keygen_round2_conclude (void *cls) | |||
802 | /* Write the share. If 0 peers completed the dkg, an empty | 862 | /* Write the share. If 0 peers completed the dkg, an empty |
803 | * share will be sent. */ | 863 | * share will be sent. */ |
804 | 864 | ||
805 | m = GNUNET_malloc (sizeof (struct GNUNET_SECRETSHARING_SecretReadyMessage) + | ||
806 | ks->num_peers * sizeof (struct GNUNET_PeerIdentity)); | ||
807 | |||
808 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size)); | 865 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, NULL, 0, &share_size)); |
809 | 866 | ||
810 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "writing share of size %u\n", | 867 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "writing share of size %u\n", |
@@ -815,6 +872,9 @@ keygen_round2_conclude (void *cls) | |||
815 | 872 | ||
816 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], share_size, NULL)); | 873 | GNUNET_assert (GNUNET_OK == GNUNET_SECRETSHARING_share_write (share, &m[1], share_size, NULL)); |
817 | 874 | ||
875 | GNUNET_SECRETSHARING_share_destroy (share); | ||
876 | share = NULL; | ||
877 | |||
818 | GNUNET_MQ_send (ks->client_mq, ev); | 878 | GNUNET_MQ_send (ks->client_mq, ev); |
819 | } | 879 | } |
820 | 880 | ||
@@ -840,14 +900,12 @@ insert_round2_element (struct KeygenSession *ks) | |||
840 | unsigned int i; | 900 | unsigned int i; |
841 | gcry_mpi_t idx; | 901 | gcry_mpi_t idx; |
842 | gcry_mpi_t v; | 902 | gcry_mpi_t v; |
843 | gcry_mpi_t c; | ||
844 | 903 | ||
845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting round2 element\n", | 904 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "P%u: Inserting round2 element\n", |
846 | ks->local_peer_idx); | 905 | ks->local_peer_idx); |
847 | 906 | ||
848 | GNUNET_assert (NULL != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | 907 | GNUNET_assert (NULL != (v = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
849 | GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | 908 | GNUNET_assert (NULL != (idx = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); |
850 | GNUNET_assert (NULL != (c = gcry_mpi_new (GNUNET_SECRETSHARING_ELGAMAL_BITS))); | ||
851 | 909 | ||
852 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + | 910 | element_size = (sizeof (struct GNUNET_SECRETSHARING_KeygenRevealData) + |
853 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + | 911 | GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * ks->num_peers + |
@@ -941,8 +999,6 @@ keygen_reveal_get_exp_preshare (struct KeygenSession *ks, | |||
941 | 999 | ||
942 | GNUNET_assert (idx < ks->num_peers); | 1000 | GNUNET_assert (idx < ks->num_peers); |
943 | 1001 | ||
944 | GNUNET_assert (NULL != (exp_preshare = gcry_mpi_new (0))); | ||
945 | |||
946 | pos = (void *) &d[1]; | 1002 | pos = (void *) &d[1]; |
947 | // skip exponentiated pre-shares we don't want | 1003 | // skip exponentiated pre-shares we don't want |
948 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; | 1004 | pos += GNUNET_SECRETSHARING_ELGAMAL_BITS / 8 * idx; |
@@ -959,7 +1015,6 @@ keygen_reveal_get_exp_coeff (struct KeygenSession *ks, | |||
959 | gcry_mpi_t exp_coeff; | 1015 | gcry_mpi_t exp_coeff; |
960 | 1016 | ||
961 | GNUNET_assert (idx < ks->threshold); | 1017 | GNUNET_assert (idx < ks->threshold); |
962 | GNUNET_assert (NULL != (exp_coeff = gcry_mpi_new (0))); | ||
963 | 1018 | ||
964 | pos = (void *) &d[1]; | 1019 | pos = (void *) &d[1]; |
965 | // skip exponentiated pre-shares | 1020 | // skip exponentiated pre-shares |
@@ -1001,6 +1056,7 @@ keygen_round2_new_element (void *cls, | |||
1001 | struct KeygenPeerInfo *info; | 1056 | struct KeygenPeerInfo *info; |
1002 | size_t expected_element_size; | 1057 | size_t expected_element_size; |
1003 | unsigned int j; | 1058 | unsigned int j; |
1059 | int cmp_result; | ||
1004 | gcry_mpi_t tmp; | 1060 | gcry_mpi_t tmp; |
1005 | gcry_mpi_t public_key_share; | 1061 | gcry_mpi_t public_key_share; |
1006 | gcry_mpi_t preshare; | 1062 | gcry_mpi_t preshare; |
@@ -1077,6 +1133,9 @@ keygen_round2_new_element (void *cls, | |||
1077 | gcry_mpi_set_ui (ks->public_key, 1); | 1133 | gcry_mpi_set_ui (ks->public_key, 1); |
1078 | } | 1134 | } |
1079 | gcry_mpi_mulm (ks->public_key, ks->public_key, public_key_share, elgamal_p); | 1135 | gcry_mpi_mulm (ks->public_key, ks->public_key, public_key_share, elgamal_p); |
1136 | |||
1137 | gcry_mpi_release (public_key_share); | ||
1138 | public_key_share = NULL; | ||
1080 | 1139 | ||
1081 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); | 1140 | GNUNET_assert (NULL != (preshare = gcry_mpi_new (0))); |
1082 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, | 1141 | GNUNET_CRYPTO_paillier_decrypt (&ks->paillier_private_key, |
@@ -1088,7 +1147,10 @@ keygen_round2_new_element (void *cls, | |||
1088 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); | 1147 | gcry_mpi_powm (tmp, elgamal_g, preshare, elgamal_p); |
1089 | 1148 | ||
1090 | // TODO: restore a valid secret from the decryption (the hard part, solving SVP with gauss) | 1149 | // TODO: restore a valid secret from the decryption (the hard part, solving SVP with gauss) |
1091 | if (0 != gcry_mpi_cmp (tmp, info->preshare_commitment)) | 1150 | cmp_result = gcry_mpi_cmp (tmp, info->preshare_commitment); |
1151 | gcry_mpi_release (tmp); | ||
1152 | tmp = NULL; | ||
1153 | if (0 != cmp_result) | ||
1092 | { | 1154 | { |
1093 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Got invalid presecret from P%u\n", | 1155 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: Got invalid presecret from P%u\n", |
1094 | (unsigned int) ks->local_peer_idx, (unsigned int) (info - ks->info)); | 1156 | (unsigned int) ks->local_peer_idx, (unsigned int) (info - ks->info)); |
@@ -1111,6 +1173,7 @@ keygen_round2_new_element (void *cls, | |||
1111 | } | 1173 | } |
1112 | presigma = keygen_reveal_get_exp_preshare (ks, d, j); | 1174 | presigma = keygen_reveal_get_exp_preshare (ks, d, j); |
1113 | gcry_mpi_mulm (ks->info[j].sigma, ks->info[j].sigma, presigma, elgamal_p); | 1175 | gcry_mpi_mulm (ks->info[j].sigma, ks->info[j].sigma, presigma, elgamal_p); |
1176 | gcry_mpi_release (presigma); | ||
1114 | } | 1177 | } |
1115 | 1178 | ||
1116 | gcry_mpi_t prod; | 1179 | gcry_mpi_t prod; |
@@ -1121,21 +1184,26 @@ keygen_round2_new_element (void *cls, | |||
1121 | for (j = 0; j < ks->num_peers; j++) | 1184 | for (j = 0; j < ks->num_peers; j++) |
1122 | { | 1185 | { |
1123 | unsigned int k; | 1186 | unsigned int k; |
1124 | gcry_mpi_t tmp; | 1187 | int cmp_result; |
1125 | gcry_mpi_t exp_preshare; | 1188 | gcry_mpi_t exp_preshare; |
1126 | gcry_mpi_set_ui (prod, 1); | 1189 | gcry_mpi_set_ui (prod, 1); |
1127 | for (k = 0; k < ks->threshold; k++) | 1190 | for (k = 0; k < ks->threshold; k++) |
1128 | { | 1191 | { |
1129 | // Using pow(double,double) is a bit sketchy. | 1192 | // Using pow(double,double) is a bit sketchy. |
1130 | // We count players from 1, but shares from 0. | 1193 | // We count players from 1, but shares from 0. |
1194 | gcry_mpi_t tmp; | ||
1131 | gcry_mpi_set_ui (j_to_k, (unsigned int) pow(j+1, k)); | 1195 | gcry_mpi_set_ui (j_to_k, (unsigned int) pow(j+1, k)); |
1132 | tmp = keygen_reveal_get_exp_coeff (ks, d, k); | 1196 | tmp = keygen_reveal_get_exp_coeff (ks, d, k); |
1133 | gcry_mpi_powm (tmp, tmp, j_to_k, elgamal_p); | 1197 | gcry_mpi_powm (tmp, tmp, j_to_k, elgamal_p); |
1134 | gcry_mpi_mulm (prod, prod, tmp, elgamal_p); | 1198 | gcry_mpi_mulm (prod, prod, tmp, elgamal_p); |
1199 | gcry_mpi_release (tmp); | ||
1135 | } | 1200 | } |
1136 | exp_preshare = keygen_reveal_get_exp_preshare (ks, d, j); | 1201 | exp_preshare = keygen_reveal_get_exp_preshare (ks, d, j); |
1137 | gcry_mpi_mod (exp_preshare, exp_preshare, elgamal_p); | 1202 | gcry_mpi_mod (exp_preshare, exp_preshare, elgamal_p); |
1138 | if (0 != gcry_mpi_cmp (prod, exp_preshare)) | 1203 | cmp_result = gcry_mpi_cmp (prod, exp_preshare); |
1204 | gcry_mpi_release (exp_preshare); | ||
1205 | exp_preshare = NULL; | ||
1206 | if (0 != cmp_result) | ||
1139 | { | 1207 | { |
1140 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: reveal data from P%u incorrect\n", | 1208 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "P%u: reveal data from P%u incorrect\n", |
1141 | ks->local_peer_idx, j); | 1209 | ks->local_peer_idx, j); |
@@ -1147,6 +1215,10 @@ keygen_round2_new_element (void *cls, | |||
1147 | // TODO: verify proof of fair encryption (once implemented) | 1215 | // TODO: verify proof of fair encryption (once implemented) |
1148 | 1216 | ||
1149 | info->round2_valid = GNUNET_YES; | 1217 | info->round2_valid = GNUNET_YES; |
1218 | |||
1219 | gcry_mpi_release (preshare); | ||
1220 | gcry_mpi_release (prod); | ||
1221 | gcry_mpi_release (j_to_k); | ||
1150 | } | 1222 | } |
1151 | 1223 | ||
1152 | 1224 | ||
diff --git a/src/secretsharing/secretsharing_common.c b/src/secretsharing/secretsharing_common.c index 2f5b3f583..c1e5acb9c 100644 --- a/src/secretsharing/secretsharing_common.c +++ b/src/secretsharing/secretsharing_common.c | |||
@@ -135,3 +135,16 @@ GNUNET_SECRETSHARING_share_write (const struct GNUNET_SECRETSHARING_Share *share | |||
135 | } | 135 | } |
136 | 136 | ||
137 | 137 | ||
138 | void | ||
139 | GNUNET_SECRETSHARING_share_destroy (struct GNUNET_SECRETSHARING_Share *share) | ||
140 | { | ||
141 | GNUNET_free (share->original_indices); | ||
142 | share->original_indices = NULL; | ||
143 | GNUNET_free (share->sigmas); | ||
144 | share->sigmas = NULL; | ||
145 | GNUNET_free (share->peers); | ||
146 | share->peers = NULL; | ||
147 | GNUNET_free (share); | ||
148 | } | ||
149 | |||
150 | |||
diff --git a/src/secretsharing/test_secretsharing.conf b/src/secretsharing/test_secretsharing.conf index f0b04052b..6c09255a3 100644 --- a/src/secretsharing/test_secretsharing.conf +++ b/src/secretsharing/test_secretsharing.conf | |||
@@ -1,6 +1,6 @@ | |||
1 | [secretsharing] | 1 | [secretsharing] |
2 | AUTOSTART = YES | 2 | AUTOSTART = YES |
3 | #PREFIX = valgrind | 3 | PREFIX = valgrind --leak-check=full |
4 | #OPTIONS = -LINFO | 4 | #OPTIONS = -LINFO |
5 | 5 | ||
6 | [consensus] | 6 | [consensus] |