diff options
author | Christian Grothoff <christian@grothoff.org> | 2018-05-17 12:26:30 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2018-05-17 12:26:30 +0200 |
commit | dd8289771b35e5ea36ebdcbfd5b09b599bd59c67 (patch) | |
tree | e79e565302867ab16d9ed8560793919094288716 /src | |
parent | 3175cde841a8a7836fcf74a3e1b804c71a3aa153 (diff) | |
download | gnunet-dd8289771b35e5ea36ebdcbfd5b09b599bd59c67.tar.gz gnunet-dd8289771b35e5ea36ebdcbfd5b09b599bd59c67.zip |
work-around for crypto bug (to be documented more)
Diffstat (limited to 'src')
-rw-r--r-- | src/cadet/gnunet-service-cadet_tunnels.c | 8 | ||||
-rw-r--r-- | src/util/Makefile.am | 3 | ||||
-rw-r--r-- | src/util/crypto_bug.c | 79 | ||||
-rw-r--r-- | src/util/crypto_ecc.c | 34 | ||||
-rw-r--r-- | src/util/crypto_ecc_setup.c | 14 | ||||
-rw-r--r-- | src/util/test_crypto_ecdh_eddsa.c | 44 |
6 files changed, 153 insertions, 29 deletions
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c index 2565b8f18..75d454522 100644 --- a/src/cadet/gnunet-service-cadet_tunnels.c +++ b/src/cadet/gnunet-service-cadet_tunnels.c | |||
@@ -1889,9 +1889,11 @@ GCT_handle_kx_auth (struct CadetTConnection *ct, | |||
1889 | GNUNET_NO); | 1889 | GNUNET_NO); |
1890 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1890 | LOG (GNUNET_ERROR_TYPE_WARNING, |
1891 | "KX AUTH missmatch!\n"); | 1891 | "KX AUTH missmatch!\n"); |
1892 | send_kx (t, | 1892 | if (NULL == t->kx_task) |
1893 | ct, | 1893 | t->kx_task |
1894 | &t->ax); | 1894 | = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, |
1895 | &retry_kx, | ||
1896 | t); | ||
1895 | return; | 1897 | return; |
1896 | } | 1898 | } |
1897 | /* Yep, we're good. */ | 1899 | /* Yep, we're good. */ |
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index eb655157d..407f482df 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -598,4 +598,5 @@ EXTRA_DIST = \ | |||
598 | test_resolver_api_data.conf \ | 598 | test_resolver_api_data.conf \ |
599 | test_service_data.conf \ | 599 | test_service_data.conf \ |
600 | test_speedup_data.conf \ | 600 | test_speedup_data.conf \ |
601 | gnunet-qr.py.in | 601 | gnunet-qr.py.in \ |
602 | crypto_bug.c | ||
diff --git a/src/util/crypto_bug.c b/src/util/crypto_bug.c new file mode 100644 index 000000000..c25e79c63 --- /dev/null +++ b/src/util/crypto_bug.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2018 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | Boston, MA 02110-1301, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file util/crypto_bug.c | ||
23 | * @brief work around unidentified public key cryptography bug | ||
24 | * @author Christian Grothoff | ||
25 | */ | ||
26 | |||
27 | /** | ||
28 | * Enable work-around. Will cause code to call #check_eddsa_key() to | ||
29 | * see if we have a bad key, and if so, create a new one. | ||
30 | */ | ||
31 | #define CRYPTO_BUG 1 | ||
32 | |||
33 | |||
34 | #if CRYPTO_BUG | ||
35 | /** | ||
36 | * Check if ECDH works with @a priv_dsa and this version | ||
37 | * of libgcrypt. | ||
38 | * | ||
39 | * @param priv_dsa key to check | ||
40 | * @return #GNUNET_OK if key passes | ||
41 | */ | ||
42 | static int | ||
43 | check_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv_dsa) | ||
44 | { | ||
45 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh; | ||
46 | struct GNUNET_CRYPTO_EddsaPublicKey id1; | ||
47 | struct GNUNET_CRYPTO_EcdhePublicKey id2; | ||
48 | struct GNUNET_HashCode dh[2]; | ||
49 | |||
50 | GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa, | ||
51 | &id1); | ||
52 | for (unsigned int j=0;j<4;j++) | ||
53 | { | ||
54 | priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create (); | ||
55 | /* Extract public keys */ | ||
56 | GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh, | ||
57 | &id2); | ||
58 | /* Do ECDH */ | ||
59 | GNUNET_assert (GNUNET_OK == | ||
60 | GNUNET_CRYPTO_eddsa_ecdh (priv_dsa, | ||
61 | &id2, | ||
62 | &dh[0])); | ||
63 | GNUNET_assert (GNUNET_OK == | ||
64 | GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh, | ||
65 | &id1, | ||
66 | &dh[1])); | ||
67 | /* Check that both DH results are equal. */ | ||
68 | if (0 != memcmp (&dh[0], | ||
69 | &dh[1], | ||
70 | sizeof (struct GNUNET_HashCode))) | ||
71 | { | ||
72 | GNUNET_break (0); /* bad EdDSA key! */ | ||
73 | return GNUNET_SYSERR; | ||
74 | } | ||
75 | GNUNET_free (priv_ecdh); | ||
76 | } | ||
77 | return GNUNET_OK; | ||
78 | } | ||
79 | #endif | ||
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index 8cc6c18cb..1abf0fddc 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -52,6 +52,9 @@ | |||
52 | #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) | 52 | #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) |
53 | 53 | ||
54 | 54 | ||
55 | #include "crypto_bug.c" | ||
56 | |||
57 | |||
55 | /** | 58 | /** |
56 | * Extract values from an S-expression. | 59 | * Extract values from an S-expression. |
57 | * | 60 | * |
@@ -455,7 +458,7 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, | |||
455 | int | 458 | int |
456 | GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, | 459 | GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, |
457 | size_t enclen, | 460 | size_t enclen, |
458 | struct GNUNET_CRYPTO_EddsaPrivateKey *pub) | 461 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv) |
459 | { | 462 | { |
460 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; | 463 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; |
461 | 464 | ||
@@ -465,10 +468,19 @@ GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, | |||
465 | if (enclen != keylen) | 468 | if (enclen != keylen) |
466 | return GNUNET_SYSERR; | 469 | return GNUNET_SYSERR; |
467 | 470 | ||
468 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, | 471 | if (GNUNET_OK != |
469 | pub, | 472 | GNUNET_STRINGS_string_to_data (enc, enclen, |
470 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | 473 | priv, |
474 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
471 | return GNUNET_SYSERR; | 475 | return GNUNET_SYSERR; |
476 | #if CRYPTO_BUG | ||
477 | if (GNUNET_OK != | ||
478 | check_eddsa_key (priv)) | ||
479 | { | ||
480 | GNUNET_break (0); | ||
481 | return GNUNET_OK; | ||
482 | } | ||
483 | #endif | ||
472 | return GNUNET_OK; | 484 | return GNUNET_OK; |
473 | } | 485 | } |
474 | 486 | ||
@@ -651,6 +663,9 @@ GNUNET_CRYPTO_eddsa_key_create () | |||
651 | gcry_mpi_t d; | 663 | gcry_mpi_t d; |
652 | int rc; | 664 | int rc; |
653 | 665 | ||
666 | #if CRYPTO_BUG | ||
667 | again: | ||
668 | #endif | ||
654 | if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, | 669 | if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, |
655 | "(genkey(ecc(curve \"" CURVE "\")" | 670 | "(genkey(ecc(curve \"" CURVE "\")" |
656 | "(flags eddsa)))"))) | 671 | "(flags eddsa)))"))) |
@@ -683,6 +698,17 @@ GNUNET_CRYPTO_eddsa_key_create () | |||
683 | priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey); | 698 | priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey); |
684 | GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d); | 699 | GNUNET_CRYPTO_mpi_print_unsigned (priv->d, sizeof (priv->d), d); |
685 | gcry_mpi_release (d); | 700 | gcry_mpi_release (d); |
701 | |||
702 | #if CRYPTO_BUG | ||
703 | if (GNUNET_OK != | ||
704 | check_eddsa_key (priv)) | ||
705 | { | ||
706 | GNUNET_break (0); | ||
707 | GNUNET_free (priv); | ||
708 | goto again; | ||
709 | } | ||
710 | #endif | ||
711 | |||
686 | return priv; | 712 | return priv; |
687 | } | 713 | } |
688 | 714 | ||
diff --git a/src/util/crypto_ecc_setup.c b/src/util/crypto_ecc_setup.c index e7caf9ded..76c25dc70 100644 --- a/src/util/crypto_ecc_setup.c +++ b/src/util/crypto_ecc_setup.c | |||
@@ -41,6 +41,9 @@ | |||
41 | #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) | 41 | #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) |
42 | 42 | ||
43 | 43 | ||
44 | #include "crypto_bug.c" | ||
45 | |||
46 | |||
44 | /** | 47 | /** |
45 | * Wait for a short time (we're trying to lock a file or want | 48 | * Wait for a short time (we're trying to lock a file or want |
46 | * to give another process a shot at finishing a disk write, etc.). | 49 | * to give another process a shot at finishing a disk write, etc.). |
@@ -221,6 +224,15 @@ GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename) | |||
221 | filename); | 224 | filename); |
222 | GNUNET_assert (GNUNET_YES == | 225 | GNUNET_assert (GNUNET_YES == |
223 | GNUNET_DISK_file_close (fd)); | 226 | GNUNET_DISK_file_close (fd)); |
227 | #if CRYPTO_BUG | ||
228 | if (GNUNET_OK != | ||
229 | check_eddsa_key (priv)) | ||
230 | { | ||
231 | GNUNET_break (0); | ||
232 | GNUNET_free (priv); | ||
233 | return NULL; | ||
234 | } | ||
235 | #endif | ||
224 | return priv; | 236 | return priv; |
225 | } | 237 | } |
226 | 238 | ||
@@ -248,7 +260,7 @@ GNUNET_CRYPTO_ecdsa_key_create_from_file (const char *filename) | |||
248 | int ec; | 260 | int ec; |
249 | uint64_t fs; | 261 | uint64_t fs; |
250 | ssize_t sret; | 262 | ssize_t sret; |
251 | 263 | ||
252 | if (GNUNET_SYSERR == | 264 | if (GNUNET_SYSERR == |
253 | GNUNET_DISK_directory_create_for_file (filename)) | 265 | GNUNET_DISK_directory_create_for_file (filename)) |
254 | return NULL; | 266 | return NULL; |
diff --git a/src/util/test_crypto_ecdh_eddsa.c b/src/util/test_crypto_ecdh_eddsa.c index 246cec27f..356c64bf1 100644 --- a/src/util/test_crypto_ecdh_eddsa.c +++ b/src/util/test_crypto_ecdh_eddsa.c | |||
@@ -36,31 +36,35 @@ test_ecdh() | |||
36 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh; | 36 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh; |
37 | struct GNUNET_CRYPTO_EddsaPublicKey id1; | 37 | struct GNUNET_CRYPTO_EddsaPublicKey id1; |
38 | struct GNUNET_CRYPTO_EcdhePublicKey id2; | 38 | struct GNUNET_CRYPTO_EcdhePublicKey id2; |
39 | struct GNUNET_HashCode dh[3]; | 39 | struct GNUNET_HashCode dh[2]; |
40 | 40 | ||
41 | /* Generate keys */ | 41 | /* Generate keys */ |
42 | priv_dsa = GNUNET_CRYPTO_eddsa_key_create (); | 42 | priv_dsa = GNUNET_CRYPTO_eddsa_key_create (); |
43 | priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create (); | ||
44 | /* Extract public keys */ | ||
45 | GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa, | 43 | GNUNET_CRYPTO_eddsa_key_get_public (priv_dsa, |
46 | &id1); | 44 | &id1); |
47 | GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh, | 45 | for (unsigned int j=0;j<10;j++) |
48 | &id2); | 46 | { |
49 | /* Do ECDH */ | 47 | fprintf (stderr, ","); |
50 | GNUNET_assert (GNUNET_OK == | 48 | priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create (); |
51 | GNUNET_CRYPTO_eddsa_ecdh (priv_dsa, | 49 | /* Extract public keys */ |
52 | &id2, | 50 | GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh, |
53 | &dh[0])); | 51 | &id2); |
54 | GNUNET_assert (GNUNET_OK == | 52 | /* Do ECDH */ |
55 | GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh, | 53 | GNUNET_assert (GNUNET_OK == |
56 | &id1, | 54 | GNUNET_CRYPTO_eddsa_ecdh (priv_dsa, |
57 | &dh[1])); | 55 | &id2, |
58 | /* Check that both DH results are equal. */ | 56 | &dh[0])); |
59 | GNUNET_assert (0 == memcmp (&dh[0], | 57 | GNUNET_assert (GNUNET_OK == |
60 | &dh[1], | 58 | GNUNET_CRYPTO_ecdh_eddsa (priv_ecdh, |
61 | sizeof (struct GNUNET_HashCode))); | 59 | &id1, |
60 | &dh[1])); | ||
61 | /* Check that both DH results are equal. */ | ||
62 | GNUNET_assert (0 == memcmp (&dh[0], | ||
63 | &dh[1], | ||
64 | sizeof (struct GNUNET_HashCode))); | ||
65 | GNUNET_free (priv_ecdh); | ||
66 | } | ||
62 | GNUNET_free (priv_dsa); | 67 | GNUNET_free (priv_dsa); |
63 | GNUNET_free (priv_ecdh); | ||
64 | return 0; | 68 | return 0; |
65 | } | 69 | } |
66 | 70 | ||
@@ -78,7 +82,7 @@ main (int argc, char *argv[]) | |||
78 | if (getenv ("GNUNET_GCRYPT_DEBUG")) | 82 | if (getenv ("GNUNET_GCRYPT_DEBUG")) |
79 | gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); | 83 | gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); |
80 | GNUNET_log_setup ("test-crypto-ecdh-eddsa", "WARNING", NULL); | 84 | GNUNET_log_setup ("test-crypto-ecdh-eddsa", "WARNING", NULL); |
81 | for (unsigned int i=0;i<10000;i++) | 85 | for (unsigned int i=0;i<100;i++) |
82 | { | 86 | { |
83 | fprintf (stderr, | 87 | fprintf (stderr, |
84 | "."); | 88 | "."); |