diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-03-20 12:52:04 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-03-20 12:52:04 +0000 |
commit | f6e6cf33fd48df1730685e788fd27dbf33a49791 (patch) | |
tree | 564fe4ff87e4c26cdd933cec7d422ae7770a978d | |
parent | 7c3f11301f4092f88296a71adfbefa4b97e06a01 (diff) | |
download | gnunet-f6e6cf33fd48df1730685e788fd27dbf33a49791.tar.gz gnunet-f6e6cf33fd48df1730685e788fd27dbf33a49791.zip |
-fixing #2563
-rw-r--r-- | src/util/Makefile.am | 3 | ||||
-rw-r--r-- | src/util/crypto_ecc.c | 134 | ||||
-rw-r--r-- | src/util/test_crypto_ecc.c | 11 |
3 files changed, 78 insertions, 70 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 425cc8cca..9920fce0b 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am | |||
@@ -342,7 +342,8 @@ test_crypto_crc_LDADD = \ | |||
342 | test_crypto_ecc_SOURCES = \ | 342 | test_crypto_ecc_SOURCES = \ |
343 | test_crypto_ecc.c | 343 | test_crypto_ecc.c |
344 | test_crypto_ecc_LDADD = \ | 344 | test_crypto_ecc_LDADD = \ |
345 | $(top_builddir)/src/util/libgnunetutil.la | 345 | $(top_builddir)/src/util/libgnunetutil.la \ |
346 | $(LIBGCRYPT_LIBS) | ||
346 | 347 | ||
347 | test_crypto_hash_SOURCES = \ | 348 | test_crypto_hash_SOURCES = \ |
348 | test_crypto_hash.c | 349 | test_crypto_hash.c |
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index a3c92a335..088d765cd 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009, 2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2012, 2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -263,9 +263,7 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *publicK | |||
263 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ | 263 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ |
264 | return NULL; | 264 | return NULL; |
265 | } | 265 | } |
266 | // FIXME: is this key expected to pass pk_testkey? | 266 | #if EXTRA_CHECKS |
267 | #if 0 | ||
268 | #if EXTRA_CHECKS | ||
269 | if (0 != (rc = gcry_pk_testkey (result))) | 267 | if (0 != (rc = gcry_pk_testkey (result))) |
270 | { | 268 | { |
271 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); | 269 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc); |
@@ -273,7 +271,6 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *publicK | |||
273 | return NULL; | 271 | return NULL; |
274 | } | 272 | } |
275 | #endif | 273 | #endif |
276 | #endif | ||
277 | return result; | 274 | return result; |
278 | } | 275 | } |
279 | 276 | ||
@@ -1066,74 +1063,85 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *key, | |||
1066 | const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub, | 1063 | const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub, |
1067 | struct GNUNET_HashCode *key_material) | 1064 | struct GNUNET_HashCode *key_material) |
1068 | { | 1065 | { |
1069 | size_t size; | ||
1070 | size_t slen; | 1066 | size_t slen; |
1067 | size_t erroff; | ||
1071 | int rc; | 1068 | int rc; |
1072 | gcry_sexp_t data; | 1069 | unsigned char sdata_buf[2048]; /* big enough to print dh-shared-secret as S-expression */ |
1073 | unsigned char sdata_buf[2048]; /* big enough to print 'sdata' and 'r_sig' */ | 1070 | gcry_mpi_point_t result; |
1071 | gcry_mpi_point_t q; | ||
1072 | gcry_mpi_t d; | ||
1073 | gcry_ctx_t ctx; | ||
1074 | gcry_sexp_t psexp; | ||
1075 | gcry_mpi_t result_x; | ||
1076 | gcry_mpi_t result_y; | ||
1074 | 1077 | ||
1075 | /* first, extract the q value from the public key */ | 1078 | /* first, extract the q = dP value from the public key */ |
1079 | if (! (psexp = decode_public_key (pub))) | ||
1080 | return GNUNET_SYSERR; | ||
1081 | if (0 != (rc = gcry_mpi_ec_new (&ctx, psexp, NULL))) | ||
1076 | { | 1082 | { |
1077 | gcry_sexp_t psexp; | 1083 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ |
1078 | gcry_mpi_t sdata; | 1084 | return GNUNET_SYSERR; |
1079 | |||
1080 | if (! (psexp = decode_public_key (pub))) | ||
1081 | return GNUNET_SYSERR; | ||
1082 | rc = key_from_sexp (&sdata, psexp, "public-key", "q"); | ||
1083 | if (rc) | ||
1084 | rc = key_from_sexp (&sdata, psexp, "ecc", "q"); | ||
1085 | GNUNET_assert (0 == rc); | ||
1086 | gcry_sexp_release (psexp); | ||
1087 | size = sizeof (sdata_buf); | ||
1088 | GNUNET_assert (0 == | ||
1089 | gcry_mpi_print (GCRYMPI_FMT_USG, sdata_buf, size, &size, | ||
1090 | sdata)); | ||
1091 | gcry_mpi_release (sdata); | ||
1092 | } | 1085 | } |
1093 | /* convert q value into an S-expression -- whatever format libgcrypt wants, | 1086 | gcry_sexp_release (psexp); |
1094 | re-using format from sign operation for now... */ | 1087 | q = gcry_mpi_ec_get_point ("q", ctx, 0); |
1088 | gcry_ctx_release (ctx); | ||
1089 | |||
1090 | /* second, extract the d value from our private key */ | ||
1091 | rc = key_from_sexp (&d, key->sexp, "private-key", "d"); | ||
1092 | if (rc) | ||
1093 | rc = key_from_sexp (&d, key->sexp, "ecc", "d"); | ||
1094 | if (0 != rc) | ||
1095 | { | 1095 | { |
1096 | char *sexp_string; | 1096 | GNUNET_break (0); |
1097 | 1097 | gcry_mpi_point_release (q); | |
1098 | #define FORMATPREFIX "(4:data(5:flags3:raw)(5:value%u:" | 1098 | return GNUNET_SYSERR; |
1099 | #define FORMATPOSTFIX "))" | ||
1100 | sexp_string = GNUNET_malloc (strlen (FORMATPREFIX) + size + 12 + | ||
1101 | strlen (FORMATPOSTFIX) + 1); | ||
1102 | GNUNET_snprintf (sexp_string, | ||
1103 | strlen (FORMATPREFIX) + 12, | ||
1104 | FORMATPREFIX, | ||
1105 | size); | ||
1106 | slen = strlen (sexp_string); | ||
1107 | memcpy (&sexp_string[slen], | ||
1108 | sdata_buf, | ||
1109 | size); | ||
1110 | memcpy (&sexp_string[slen + size], | ||
1111 | FORMATPOSTFIX, | ||
1112 | strlen (FORMATPOSTFIX) + 1); | ||
1113 | GNUNET_assert (0 == gcry_sexp_new (&data, | ||
1114 | sexp_string, | ||
1115 | slen + size + strlen (FORMATPOSTFIX), | ||
1116 | 0)); | ||
1117 | GNUNET_free (sexp_string); | ||
1118 | } | 1099 | } |
1119 | /* then call the 'multiply' function, hoping it simply multiplies the points; | 1100 | |
1120 | here we need essentially a WRAPPER around _gcry_mpi_ex_mul_point! - FIXME-WK!*/ | 1101 | /* create a new context for definitively the correct curve; |
1121 | #if WK | 1102 | theoretically the 'public_key' might not use the right curve */ |
1103 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, "NIST P-256"))) | ||
1122 | { | 1104 | { |
1123 | gcry_sexp_t result; | 1105 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ |
1124 | 1106 | gcry_mpi_release (d); | |
1125 | rc = gcry_ecc_mul_point (&result, data /* scalar */, key->sexp /* point and ctx */); | 1107 | gcry_mpi_point_release (q); |
1126 | GNUNET_assert (0 == rc); | 1108 | return GNUNET_SYSERR; |
1127 | slen = gcry_sexp_sprint (result, GCRYSEXP_FMT_DEFAULT, sdata_buf, sizeof (sdata_buf)); | ||
1128 | GNUNET_assert (0 != slen); | ||
1129 | } | 1109 | } |
1130 | #else | ||
1131 | /* use broken version, insecure! */ | ||
1132 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("To be implemented: not secure at the moment, please read README\n")); | ||
1133 | slen = sprintf ((char*) sdata_buf, "FIXME-this is not key material"); | ||
1134 | #endif | ||
1135 | gcry_sexp_release (data); | ||
1136 | 1110 | ||
1111 | /* then call the 'multiply' function, to compute the product */ | ||
1112 | GNUNET_assert (NULL != ctx); | ||
1113 | result = gcry_mpi_point_new (0); | ||
1114 | gcry_mpi_ec_mul (result, d, q, ctx); | ||
1115 | gcry_mpi_point_release (q); | ||
1116 | gcry_mpi_release (d); | ||
1117 | |||
1118 | /* finally, convert point to string for hashing */ | ||
1119 | result_x = gcry_mpi_new (256); | ||
1120 | result_y = gcry_mpi_new (256); | ||
1121 | if (gcry_mpi_ec_get_affine (result_x, result_y, result, ctx)) | ||
1122 | { | ||
1123 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0); | ||
1124 | gcry_mpi_point_release (result); | ||
1125 | gcry_ctx_release (ctx); | ||
1126 | return GNUNET_SYSERR; | ||
1127 | } | ||
1128 | gcry_mpi_point_release (result); | ||
1129 | gcry_ctx_release (ctx); | ||
1130 | if (0 != (rc = gcry_sexp_build (&psexp, &erroff, | ||
1131 | "(dh-shared-secret (x %m)(y %m))", | ||
1132 | result_x, | ||
1133 | result_y))) | ||
1134 | { | ||
1135 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ | ||
1136 | gcry_mpi_release (result_x); | ||
1137 | gcry_mpi_release (result_y); | ||
1138 | return GNUNET_SYSERR; | ||
1139 | } | ||
1140 | gcry_mpi_release (result_x); | ||
1141 | gcry_mpi_release (result_y); | ||
1142 | slen = gcry_sexp_sprint (psexp, GCRYSEXP_FMT_DEFAULT, sdata_buf, sizeof (sdata_buf)); | ||
1143 | GNUNET_assert (0 != slen); | ||
1144 | gcry_sexp_release (psexp); | ||
1137 | /* finally, get a string of the resulting S-expression and hash it to generate the key material */ | 1145 | /* finally, get a string of the resulting S-expression and hash it to generate the key material */ |
1138 | GNUNET_CRYPTO_hash (sdata_buf, slen, key_material); | 1146 | GNUNET_CRYPTO_hash (sdata_buf, slen, key_material); |
1139 | return GNUNET_OK; | 1147 | return GNUNET_OK; |
diff --git a/src/util/test_crypto_ecc.c b/src/util/test_crypto_ecc.c index fb6d5968a..8aa58971f 100644 --- a/src/util/test_crypto_ecc.c +++ b/src/util/test_crypto_ecc.c | |||
@@ -195,12 +195,13 @@ test_ecdh () | |||
195 | GNUNET_CRYPTO_ecc_key_get_public (priv2, &pub2); | 195 | GNUNET_CRYPTO_ecc_key_get_public (priv2, &pub2); |
196 | GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1); | 196 | GNUNET_CRYPTO_ecc_ecdh (priv1, &pub2, &ecdh1); |
197 | GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2); | 197 | GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &ecdh2); |
198 | GNUNET_CRYPTO_ecc_key_free (priv1); | ||
199 | GNUNET_CRYPTO_ecc_key_free (priv2); | ||
200 | GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2, | 198 | GNUNET_assert (0 == memcmp (&ecdh1, &ecdh2, |
201 | sizeof (struct GNUNET_HashCode))); | 199 | sizeof (struct GNUNET_HashCode))); |
200 | GNUNET_CRYPTO_ecc_key_free (priv1); | ||
201 | GNUNET_CRYPTO_ecc_key_free (priv2); | ||
202 | } | 202 | } |
203 | 203 | ||
204 | |||
204 | static void | 205 | static void |
205 | perf_keygen () | 206 | perf_keygen () |
206 | { | 207 | { |
@@ -216,13 +217,11 @@ perf_keygen () | |||
216 | GNUNET_CRYPTO_ecc_key_free (pk); | 217 | GNUNET_CRYPTO_ecc_key_free (pk); |
217 | } | 218 | } |
218 | fprintf (stderr, "\n"); | 219 | fprintf (stderr, "\n"); |
219 | printf ("Creating 10 ECC keys took %llu ms\n", | 220 | printf ("Creating 10 ECC keys took %s\n", |
220 | (unsigned long long) | 221 | GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES)); |
221 | GNUNET_TIME_absolute_get_duration (start).rel_value); | ||
222 | } | 222 | } |
223 | 223 | ||
224 | 224 | ||
225 | |||
226 | int | 225 | int |
227 | main (int argc, char *argv[]) | 226 | main (int argc, char *argv[]) |
228 | { | 227 | { |