aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/crypto_ecc.c91
-rw-r--r--src/util/crypto_mpi.c28
2 files changed, 53 insertions, 66 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 17986a9d1..96d546185 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -139,13 +139,17 @@ decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
139{ 139{
140 gcry_sexp_t result; 140 gcry_sexp_t result;
141 int rc; 141 int rc;
142 uint8_t d[32];
143
144 for (size_t i=0; i<32; i++)
145 d[i] = priv->d[31 - i];
142 146
143 rc = gcry_sexp_build (&result, 147 rc = gcry_sexp_build (&result,
144 NULL, 148 NULL,
145 "(private-key(ecc(curve \"" CURVE "\")" 149 "(private-key(ecc(curve \"" CURVE "\")"
146 "(d %b)))", 150 "(d %b)))",
147 (int) sizeof(priv->d), 151 32,
148 priv->d); 152 d);
149 if (0 != rc) 153 if (0 != rc)
150 { 154 {
151 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 155 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -173,14 +177,8 @@ GNUNET_CRYPTO_ecdsa_key_get_public (
173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, 177 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
174 struct GNUNET_CRYPTO_EcdsaPublicKey *pub) 178 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
175{ 179{
176 uint8_t d[32];
177
178 /* Treat priv as little endian, due to libgcrypt. */
179 for (size_t i = 0; i < 32; i++)
180 d[i] = priv->d[31 - i];
181 BENCHMARK_START (ecdsa_key_get_public); 180 BENCHMARK_START (ecdsa_key_get_public);
182 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, d); 181 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
183 sodium_memzero (d, 32);
184 BENCHMARK_END (ecdsa_key_get_public); 182 BENCHMARK_END (ecdsa_key_get_public);
185} 183}
186 184
@@ -525,57 +523,14 @@ GNUNET_CRYPTO_ecdhe_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
525void 523void
526GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk) 524GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
527{ 525{
528 gcry_sexp_t priv_sexp;
529 gcry_sexp_t s_keyparam;
530 gcry_mpi_t d;
531 int rc;
532
533 BENCHMARK_START (ecdsa_key_create); 526 BENCHMARK_START (ecdsa_key_create);
534 if (0 != (rc = gcry_sexp_build (&s_keyparam, 527 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
535 NULL, 528 pk,
536 "(genkey(ecc(curve \"" CURVE "\")" 529 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
537 "(flags)))"))) 530 pk->d[0] &= 248;
538 { 531 pk->d[31] &= 127;
539 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, 532 pk->d[31] |= 64;
540 "gcry_sexp_build", 533
541 rc);
542 GNUNET_assert (0);
543 }
544 if (0 != (rc = gcry_pk_genkey (&priv_sexp,
545 s_keyparam)))
546 {
547 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
548 "gcry_pk_genkey",
549 rc);
550 gcry_sexp_release (s_keyparam);
551 GNUNET_assert (0);
552 }
553 gcry_sexp_release (s_keyparam);
554#if EXTRA_CHECKS
555 if (0 != (rc = gcry_pk_testkey (priv_sexp)))
556 {
557 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
558 "gcry_pk_testkey",
559 rc);
560 gcry_sexp_release (priv_sexp);
561 GNUNET_assert (0);
562 }
563#endif
564 if (0 != (rc = key_from_sexp (&d, priv_sexp,
565 "private-key",
566 "d")))
567 {
568 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
569 "key_from_sexp",
570 rc);
571 gcry_sexp_release (priv_sexp);
572 GNUNET_assert (0);
573 }
574 gcry_sexp_release (priv_sexp);
575 GNUNET_CRYPTO_mpi_print_unsigned (pk->d,
576 sizeof(pk->d),
577 d);
578 gcry_mpi_release (d);
579 BENCHMARK_END (ecdsa_key_create); 534 BENCHMARK_END (ecdsa_key_create);
580} 535}
581 536
@@ -952,6 +907,7 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (
952{ 907{
953 struct GNUNET_CRYPTO_EcdsaPublicKey pub; 908 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
954 struct GNUNET_CRYPTO_EcdsaPrivateKey *ret; 909 struct GNUNET_CRYPTO_EcdsaPrivateKey *ret;
910 uint8_t dc[32];
955 gcry_mpi_t h; 911 gcry_mpi_t h;
956 gcry_mpi_t x; 912 gcry_mpi_t x;
957 gcry_mpi_t d; 913 gcry_mpi_t d;
@@ -964,7 +920,10 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (
964 GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub); 920 GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub);
965 921
966 h = derive_h (&pub, label, context); 922 h = derive_h (&pub, label, context);
967 GNUNET_CRYPTO_mpi_scan_unsigned (&x, priv->d, sizeof(priv->d)); 923 /* Convert to big endian for libgcrypt */
924 for (size_t i=0; i < 32; i++)
925 dc[i] = priv->d[31 - i];
926 GNUNET_CRYPTO_mpi_scan_unsigned (&x, dc, sizeof(dc));
968 d = gcry_mpi_new (256); 927 d = gcry_mpi_new (256);
969 gcry_mpi_mulm (d, h, x, n); 928 gcry_mpi_mulm (d, h, x, n);
970 gcry_mpi_release (h); 929 gcry_mpi_release (h);
@@ -972,7 +931,11 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (
972 gcry_mpi_release (n); 931 gcry_mpi_release (n);
973 gcry_ctx_release (ctx); 932 gcry_ctx_release (ctx);
974 ret = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); 933 ret = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
975 GNUNET_CRYPTO_mpi_print_unsigned (ret->d, sizeof(ret->d), d); 934 GNUNET_CRYPTO_mpi_print_unsigned (dc, sizeof(dc), d);
935 /* Convert to big endian for libgcrypt */
936 for (size_t i=0; i < 32; i++)
937 ret->d[i] = dc[31 - i];
938 sodium_memzero(dc, sizeof(dc));
976 gcry_mpi_release (d); 939 gcry_mpi_release (d);
977 return ret; 940 return ret;
978} 941}
@@ -1087,13 +1050,9 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1087 struct GNUNET_HashCode *key_material) 1050 struct GNUNET_HashCode *key_material)
1088{ 1051{
1089 uint8_t p[crypto_scalarmult_BYTES]; 1052 uint8_t p[crypto_scalarmult_BYTES];
1090 uint8_t d_rev[crypto_scalarmult_SCALARBYTES];
1091 1053
1092 BENCHMARK_START (ecdsa_ecdh); 1054 BENCHMARK_START (ecdsa_ecdh);
1093 // FIXME: byte order 1055 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
1094 for (size_t i = 0; i < 32; i++)
1095 d_rev[i] = priv->d[31 - i];
1096 if (0 != crypto_scalarmult (p, d_rev, pub->q_y))
1097 return GNUNET_SYSERR; 1056 return GNUNET_SYSERR;
1098 GNUNET_CRYPTO_hash (p, 1057 GNUNET_CRYPTO_hash (p,
1099 crypto_scalarmult_BYTES, 1058 crypto_scalarmult_BYTES,
diff --git a/src/util/crypto_mpi.c b/src/util/crypto_mpi.c
index 51a29ac7c..099921611 100644
--- a/src/util/crypto_mpi.c
+++ b/src/util/crypto_mpi.c
@@ -146,4 +146,32 @@ GNUNET_CRYPTO_mpi_scan_unsigned (gcry_mpi_t *result,
146} 146}
147 147
148 148
149/**
150 * Convert little endian data buffer into MPI value.
151 * The buffer is interpreted as network
152 * byte order, unsigned integer.
153 *
154 * @param result where to store MPI value (allocated)
155 * @param data raw data (GCRYMPI_FMT_USG)
156 * @param size number of bytes in @a data
157 */
158void
159GNUNET_CRYPTO_mpi_scan_unsigned_le (gcry_mpi_t *result,
160 const void *data,
161 size_t size)
162{
163 int rc;
164
165 if (0 != (rc = gcry_mpi_scan (result,
166 GCRYMPI_FMT_USG,
167 data, size, &size)))
168 {
169 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
170 "gcry_mpi_scan",
171 rc);
172 GNUNET_assert (0);
173 }
174}
175
176
149/* end of crypto_mpi.c */ 177/* end of crypto_mpi.c */