aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/util')
-rw-r--r--src/util/.gitignore2
-rw-r--r--src/util/Makefile.am47
-rw-r--r--src/util/buffer.c226
-rw-r--r--src/util/common_logging.c8
-rw-r--r--src/util/crypto_ecc.c109
-rw-r--r--src/util/gnunet-crypto-tvg.c278
-rw-r--r--src/util/test_crypto_ecdh_ecdsa.c97
-rw-r--r--src/util/tweetnacl-gnunet.c20
-rw-r--r--src/util/tweetnacl-gnunet.h4
9 files changed, 660 insertions, 131 deletions
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 01ebcc834..84c13708e 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -1,6 +1,7 @@
1test_common_logging_dummy 1test_common_logging_dummy
2gnunet-config 2gnunet-config
3gnunet-config-diff 3gnunet-config-diff
4gnunet-crypto-tvg
4gnunet-ecc 5gnunet-ecc
5gnunet-qr 6gnunet-qr
6gnunet-resolver 7gnunet-resolver
@@ -30,6 +31,7 @@ test_container_multihashmap32
30test_container_multipeermap 31test_container_multipeermap
31test_crypto_crc 32test_crypto_crc
32test_crypto_ecc_dlog 33test_crypto_ecc_dlog
34test_crypto_ecdh_ecdsa
33test_crypto_ecdh_eddsa 35test_crypto_ecdh_eddsa
34test_crypto_ecdhe 36test_crypto_ecdhe
35test_crypto_ecdsa 37test_crypto_ecdsa
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 0f6251f96..fc8f424dc 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -39,6 +39,7 @@ libgnunetutil_la_SOURCES = \
39 bandwidth.c \ 39 bandwidth.c \
40 $(BENCHMARK) \ 40 $(BENCHMARK) \
41 bio.c \ 41 bio.c \
42 buffer.c \
42 client.c \ 43 client.c \
43 common_allocation.c \ 44 common_allocation.c \
44 common_endian.c \ 45 common_endian.c \
@@ -138,41 +139,11 @@ libgnunetutil_la_LDFLAGS = \
138 $(GN_LIB_LDFLAGS) \ 139 $(GN_LIB_LDFLAGS) \
139 -version-info 13:2:0 140 -version-info 13:2:0
140 141
141libgnunetutil_taler_wallet_la_SOURCES = \
142 common_allocation.c \
143 common_endian.c \
144 common_logging.c \
145 container_heap.c \
146 container_multihashmap.c \
147 container_multihashmap32.c \
148 crypto_symmetric.c \
149 crypto_crc.c \
150 crypto_ecc.c \
151 crypto_hash.c \
152 crypto_hkdf.c \
153 crypto_kdf.c \
154 crypto_mpi.c \
155 crypto_random.c \
156 crypto_rsa.c \
157 strings.c \
158 time.c
159
160libgnunetutil_taler_wallet_la_LIBADD = \
161 $(LIBGCRYPT_LIBS) \
162 -lunistring
163
164libgnunetutil_taler_wallet_la_LDFLAGS = \
165 $(GN_LIB_LDFLAGS) \
166 -version-info 0:0:0
167
168if HAVE_TESTING 142if HAVE_TESTING
169 GNUNET_ECC = gnunet-ecc 143 GNUNET_ECC = gnunet-ecc
170 GNUNET_SCRYPT = gnunet-scrypt 144 GNUNET_SCRYPT = gnunet-scrypt
171endif 145endif
172 146
173if TALER_ONLY
174lib_LTLIBRARIES = libgnunetutil_taler_wallet.la
175else
176lib_LTLIBRARIES = libgnunetutil.la 147lib_LTLIBRARIES = libgnunetutil.la
177 148
178libexec_PROGRAMS = \ 149libexec_PROGRAMS = \
@@ -182,6 +153,7 @@ libexec_PROGRAMS = \
182bin_PROGRAMS = \ 153bin_PROGRAMS = \
183 gnunet-resolver \ 154 gnunet-resolver \
184 gnunet-config \ 155 gnunet-config \
156 gnunet-crypto-tvg \
185 $(GNUNET_ECC) \ 157 $(GNUNET_ECC) \
186 $(GNUNET_SCRYPT) \ 158 $(GNUNET_SCRYPT) \
187 gnunet-uri 159 gnunet-uri
@@ -199,8 +171,6 @@ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PAT
199TESTS = $(check_PROGRAMS) 171TESTS = $(check_PROGRAMS)
200endif 172endif
201 173
202endif
203
204gnunet_timeout_SOURCES = \ 174gnunet_timeout_SOURCES = \
205 gnunet-timeout.c 175 gnunet-timeout.c
206 176
@@ -220,6 +190,11 @@ gnunet_resolver_LDADD = \
220 libgnunetutil.la \ 190 libgnunetutil.la \
221 $(GN_LIBINTL) 191 $(GN_LIBINTL)
222 192
193gnunet_crypto_tvg_SOURCES = \
194 gnunet-crypto-tvg.c
195gnunet_crypto_tvg_LDADD = \
196 libgnunetutil.la \
197 $(GN_LIBINTL) -lgcrypt
223 198
224gnunet_ecc_SOURCES = \ 199gnunet_ecc_SOURCES = \
225 gnunet-ecc.c 200 gnunet-ecc.c
@@ -298,6 +273,7 @@ check_PROGRAMS = \
298 test_crypto_eddsa \ 273 test_crypto_eddsa \
299 test_crypto_ecdhe \ 274 test_crypto_ecdhe \
300 test_crypto_ecdh_eddsa \ 275 test_crypto_ecdh_eddsa \
276 test_crypto_ecdh_ecdsa \
301 test_crypto_ecc_dlog \ 277 test_crypto_ecc_dlog \
302 test_crypto_hash \ 278 test_crypto_hash \
303 test_crypto_hash_context \ 279 test_crypto_hash_context \
@@ -476,6 +452,13 @@ test_crypto_ecdh_eddsa_LDADD = \
476 libgnunetutil.la \ 452 libgnunetutil.la \
477 $(LIBGCRYPT_LIBS) 453 $(LIBGCRYPT_LIBS)
478 454
455test_crypto_ecdh_ecdsa_SOURCES = \
456 test_crypto_ecdh_ecdsa.c
457test_crypto_ecdh_ecdsa_LDADD = \
458 libgnunetutil.la \
459 $(LIBGCRYPT_LIBS)
460
461
479test_crypto_hash_SOURCES = \ 462test_crypto_hash_SOURCES = \
480 test_crypto_hash.c 463 test_crypto_hash.c
481test_crypto_hash_LDADD = \ 464test_crypto_hash_LDADD = \
diff --git a/src/util/buffer.c b/src/util/buffer.c
new file mode 100644
index 000000000..d89565d68
--- /dev/null
+++ b/src/util/buffer.c
@@ -0,0 +1,226 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify it under the
6 terms of the GNU Affero General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
12
13 You should have received a copy of the GNU Affero General Public License along with
14 GNUnet; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15*/
16/**
17 * @file buffer.c
18 * @brief Common buffer management functions.
19 * @author Florian Dold
20 */
21#include "platform.h"
22#include "gnunet_util_lib.h"
23#include "gnunet_buffer_lib.h"
24
25/**
26 * Initialize a buffer with the given capacity.
27 *
28 * When a buffer is allocated with this function, a warning is logged
29 * when the buffer exceeds the initial capacity.
30 *
31 * @param buf the buffer to initialize
32 * @param capacity the capacity (in bytes) to allocate for @a buf
33 */
34void
35GNUNET_buffer_prealloc (struct GNUNET_Buffer *buf, size_t capacity)
36{
37 /* Buffer should be zero-initialized */
38 GNUNET_assert (0 == buf->mem);
39 GNUNET_assert (0 == buf->capacity);
40 GNUNET_assert (0 == buf->position);
41 buf->mem = GNUNET_malloc (capacity);
42 buf->capacity = capacity;
43 buf->warn_grow = GNUNET_YES;
44}
45
46
47/**
48 * Make sure that at least @a n bytes remaining in the buffer.
49 *
50 * @param buf buffer to potentially grow
51 * @param n number of bytes that should be available to write
52 */
53void
54GNUNET_buffer_ensure_remaining (struct GNUNET_Buffer *buf, size_t n)
55{
56 size_t new_capacity = buf->position + n;
57
58 if (new_capacity <= buf->capacity)
59 return;
60 /* warn if calculation of expected size was wrong */
61 GNUNET_break (GNUNET_YES != buf->warn_grow);
62 if (new_capacity < buf->capacity * 2)
63 new_capacity = buf->capacity * 2;
64 buf->capacity = new_capacity;
65 if (NULL != buf->mem)
66 buf->mem = GNUNET_realloc (buf->mem, new_capacity);
67 else
68 buf->mem = GNUNET_malloc (new_capacity);
69}
70
71
72/**
73 * Write bytes to the buffer.
74 *
75 * Grows the buffer if necessary.
76 *
77 * @param buf buffer to write to
78 * @param data data to read from
79 * @param len number of bytes to copy from @a data to @a buf
80 *
81 */
82void
83GNUNET_buffer_write (struct GNUNET_Buffer *buf, const char *data, size_t len)
84{
85 GNUNET_buffer_ensure_remaining (buf, len);
86 memcpy (buf->mem + buf->position, data, len);
87 buf->position += len;
88}
89
90
91/**
92 * Write a 0-terminated string to a buffer, excluding the 0-terminator.
93 *
94 * @param buf the buffer to write to
95 * @param str the string to write to @a buf
96 */
97void
98GNUNET_buffer_write_str (struct GNUNET_Buffer *buf, const char *str)
99{
100 size_t len = strlen (str);
101
102 GNUNET_buffer_write (buf, str, len);
103}
104
105
106/**
107 * Clear the buffer and return the string it contained.
108 * The caller is responsible to eventually #GNUNET_free
109 * the returned string.
110 *
111 * The returned string is always 0-terminated.
112 *
113 * @param buf the buffer to reap the string from
114 * @returns the buffer contained in the string
115 */
116char *
117GNUNET_buffer_reap_str (struct GNUNET_Buffer *buf)
118{
119 char *res;
120
121 /* ensure 0-termination */
122 if ( (0 == buf->position) || ('\0' != buf->mem[buf->position - 1]))
123 {
124 GNUNET_buffer_ensure_remaining (buf, 1);
125 buf->mem[buf->position++] = '\0';
126 }
127 res = buf->mem;
128 *buf = (struct GNUNET_Buffer) { 0 };
129 return res;
130}
131
132
133/**
134 * Free the backing memory of the given buffer.
135 * Does not free the memory of the buffer control structure,
136 * which is typically stack-allocated.
137 */
138void
139GNUNET_buffer_clear (struct GNUNET_Buffer *buf)
140{
141 GNUNET_free_non_null (buf->mem);
142 *buf = (struct GNUNET_Buffer) { 0 };
143}
144
145
146/**
147 * Write a path component to a buffer, ensuring that
148 * there is exactly one slash between the previous contents
149 * of the buffer and the new string.
150 *
151 * @param buf buffer to write to
152 * @param str string containing the new path component
153 */
154void
155GNUNET_buffer_write_path (struct GNUNET_Buffer *buf, const char *str)
156{
157 size_t len = strlen (str);
158
159 while ( (0 != len) && ('/' == str[0]) )
160 {
161 str++;
162 len--;
163 }
164 if ( (0 == buf->position) || ('/' != buf->mem[buf->position - 1]) )
165 {
166 GNUNET_buffer_ensure_remaining (buf, 1);
167 buf->mem[buf->position++] = '/';
168 }
169 GNUNET_buffer_write (buf, str, len);
170}
171
172
173/**
174 * Write a 0-terminated formatted string to a buffer, excluding the
175 * 0-terminator.
176 *
177 * Grows the buffer if necessary.
178 *
179 * @param buf the buffer to write to
180 * @param fmt format string
181 * @param ... format arguments
182 */
183void
184GNUNET_buffer_write_fstr (struct GNUNET_Buffer *buf, const char *fmt, ...)
185{
186 va_list args;
187
188 va_start (args, fmt);
189 GNUNET_buffer_write_vfstr (buf, fmt, args);
190 va_end (args);
191}
192
193
194/**
195 * Write a 0-terminated formatted string to a buffer, excluding the
196 * 0-terminator.
197 *
198 * Grows the buffer if necessary.
199 *
200 * @param buf the buffer to write to
201 * @param fmt format string
202 * @param args format argument list
203 */
204void
205GNUNET_buffer_write_vfstr (struct GNUNET_Buffer *buf,
206 const char *fmt,
207 va_list args)
208{
209 int res;
210 va_list args2;
211
212 va_copy (args2, args);
213 res = vsnprintf (NULL, 0, fmt, args2);
214 va_end (args2);
215
216 GNUNET_assert (res >= 0);
217 GNUNET_buffer_ensure_remaining (buf, res + 1);
218
219 va_copy (args2, args);
220 res = vsnprintf (buf->mem + buf->position, res + 1, fmt, args2);
221 va_end (args2);
222
223 GNUNET_assert (res >= 0);
224 buf->position += res;
225 GNUNET_assert (buf->position <= buf->capacity);
226}
diff --git a/src/util/common_logging.c b/src/util/common_logging.c
index 430f75e70..27ac88a05 100644
--- a/src/util/common_logging.c
+++ b/src/util/common_logging.c
@@ -294,7 +294,6 @@ resize_logdefs ()
294} 294}
295 295
296 296
297#if ! TALER_WALLET_ONLY
298/** 297/**
299 * Rotate logs, deleting the oldest log. 298 * Rotate logs, deleting the oldest log.
300 * 299 *
@@ -403,9 +402,6 @@ setup_log_file (const struct tm *tm)
403} 402}
404 403
405 404
406#endif
407
408
409/** 405/**
410 * Utility function - adds a parsed definition to logdefs array. 406 * Utility function - adds a parsed definition to logdefs array.
411 * 407 *
@@ -731,7 +727,7 @@ GNUNET_log_setup (const char *comp, const char *loglevel, const char *logfile)
731 log_file_name = GNUNET_STRINGS_filename_expand (logfile); 727 log_file_name = GNUNET_STRINGS_filename_expand (logfile);
732 if (NULL == log_file_name) 728 if (NULL == log_file_name)
733 return GNUNET_SYSERR; 729 return GNUNET_SYSERR;
734#if TALER_WALLET_ONLY || defined(GNUNET_CULL_LOGGING) 730#if defined(GNUNET_CULL_LOGGING)
735 /* log file option not allowed for wallet logic */ 731 /* log file option not allowed for wallet logic */
736 GNUNET_assert (NULL == logfile); 732 GNUNET_assert (NULL == logfile);
737 return GNUNET_OK; 733 return GNUNET_OK;
@@ -1023,7 +1019,7 @@ mylog (enum GNUNET_ErrorType kind,
1023 } 1019 }
1024 1020
1025 vsnprintf (buf, size, message, va); 1021 vsnprintf (buf, size, message, va);
1026#if ! (defined(GNUNET_CULL_LOGGING) || TALER_WALLET_ONLY) 1022#if ! defined(GNUNET_CULL_LOGGING)
1027 if (NULL != tmptr) 1023 if (NULL != tmptr)
1028 (void) setup_log_file (tmptr); 1024 (void) setup_log_file (tmptr);
1029#endif 1025#endif
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index bd7c425d4..237062eb7 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -173,22 +173,8 @@ GNUNET_CRYPTO_ecdsa_key_get_public (
173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, 173 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
174 struct GNUNET_CRYPTO_EcdsaPublicKey *pub) 174 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
175{ 175{
176 gcry_sexp_t sexp;
177 gcry_ctx_t ctx;
178 gcry_mpi_t q;
179
180 BENCHMARK_START (ecdsa_key_get_public); 176 BENCHMARK_START (ecdsa_key_get_public);
181 177 GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (pub->q_y, priv->d);
182 sexp = decode_private_ecdsa_key (priv);
183 GNUNET_assert (NULL != sexp);
184 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
185 gcry_sexp_release (sexp);
186 q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
187 GNUNET_assert (NULL != q);
188 GNUNET_CRYPTO_mpi_print_unsigned (pub->q_y, sizeof(pub->q_y), q);
189 gcry_mpi_release (q);
190 gcry_ctx_release (ctx);
191
192 BENCHMARK_END (ecdsa_key_get_public); 178 BENCHMARK_END (ecdsa_key_get_public);
193} 179}
194 180
@@ -1041,45 +1027,6 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
1041 1027
1042 1028
1043/** 1029/**
1044 * Take point from ECDH and convert it to key material.
1045 *
1046 * @param result point from ECDH
1047 * @param ctx ECC context
1048 * @param key_material[out] set to derived key material
1049 * @return #GNUNET_OK on success
1050 */
1051static int
1052point_to_hash (gcry_mpi_point_t result,
1053 gcry_ctx_t ctx,
1054 struct GNUNET_HashCode *key_material)
1055{
1056 gcry_mpi_t result_x;
1057 unsigned char xbuf[256 / 8];
1058 size_t rsize;
1059
1060 /* finally, convert point to string for hashing */
1061 result_x = gcry_mpi_new (256);
1062 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1063 {
1064 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1065 return GNUNET_SYSERR;
1066 }
1067
1068 rsize = sizeof(xbuf);
1069 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1070 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1071 as that does not include the sign bit; x should be a 255-bit
1072 value, so with the sign it should fit snugly into the 256-bit
1073 xbuf */
1074 GNUNET_assert (
1075 0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x));
1076 GNUNET_CRYPTO_hash (xbuf, rsize, key_material);
1077 gcry_mpi_release (result_x);
1078 return GNUNET_OK;
1079}
1080
1081
1082/**
1083 * @ingroup crypto 1030 * @ingroup crypto
1084 * Derive key material from a ECDH public key and a private EdDSA key. 1031 * Derive key material from a ECDH public key and a private EdDSA key.
1085 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa. 1032 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
@@ -1125,41 +1072,18 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1125 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1072 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1126 struct GNUNET_HashCode *key_material) 1073 struct GNUNET_HashCode *key_material)
1127{ 1074{
1128 gcry_mpi_point_t result; 1075 uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1129 gcry_mpi_point_t q; 1076 uint8_t d_rev[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1130 gcry_mpi_t d;
1131 gcry_ctx_t ctx;
1132 gcry_sexp_t pub_sexpr;
1133 int ret;
1134 1077
1135 BENCHMARK_START (ecdsa_ecdh); 1078 BENCHMARK_START (ecdsa_ecdh);
1136 1079 for (size_t i = 0; i < 32; i++)
1137 /* first, extract the q = dP value from the public key */ 1080 d_rev[i] = priv->d[31 - i];
1138 if (0 != gcry_sexp_build (&pub_sexpr, 1081 GNUNET_TWEETNACL_scalarmult_curve25519 (p, d_rev, pub->q_y);
1139 NULL, 1082 GNUNET_CRYPTO_hash (p,
1140 "(public-key(ecc(curve " CURVE ")(q %b)))", 1083 GNUNET_TWEETNACL_SCALARMULT_BYTES,
1141 (int) sizeof(pub->q_y), 1084 key_material);
1142 pub->q_y))
1143 return GNUNET_SYSERR;
1144 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1145 gcry_sexp_release (pub_sexpr);
1146 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1147
1148 /* second, extract the d value from our private key */
1149 GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof(priv->d));
1150
1151 /* then call the 'multiply' function, to compute the product */
1152 result = gcry_mpi_point_new (0);
1153 gcry_mpi_ec_mul (result, d, q, ctx);
1154 gcry_mpi_point_release (q);
1155 gcry_mpi_release (d);
1156
1157 /* finally, convert point to string for hashing */
1158 ret = point_to_hash (result, ctx, key_material);
1159 gcry_mpi_point_release (result);
1160 gcry_ctx_release (ctx);
1161 BENCHMARK_END (ecdsa_ecdh); 1085 BENCHMARK_END (ecdsa_ecdh);
1162 return ret; 1086 return GNUNET_OK;
1163} 1087}
1164 1088
1165 1089
@@ -1191,7 +1115,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1191/** 1115/**
1192 * @ingroup crypto 1116 * @ingroup crypto
1193 * Derive key material from a ECDSA public key and a private ECDH key. 1117 * Derive key material from a ECDSA public key and a private ECDH key.
1194 * Dual to #GNUNET_CRRYPTO_eddsa_ecdh. 1118 * Dual to #GNUNET_CRYPTO_ecdsa_ecdh.
1195 * 1119 *
1196 * @param priv private key to use for the ECDH (y) 1120 * @param priv private key to use for the ECDH (y)
1197 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G) 1121 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
@@ -1203,10 +1127,13 @@ GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1203 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, 1127 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1204 struct GNUNET_HashCode *key_material) 1128 struct GNUNET_HashCode *key_material)
1205{ 1129{
1206 return GNUNET_CRYPTO_ecdh_eddsa (priv, 1130 uint8_t p[GNUNET_TWEETNACL_SCALARMULT_BYTES];
1207 (const struct GNUNET_CRYPTO_EddsaPublicKey *) 1131 uint8_t curve25510_pk[GNUNET_TWEETNACL_SIGN_PUBLICBYTES];
1208 pub, 1132
1209 key_material); 1133 GNUNET_TWEETNACL_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y);
1134 GNUNET_TWEETNACL_scalarmult_curve25519 (p, priv->d, curve25510_pk);
1135 GNUNET_CRYPTO_hash (p, GNUNET_TWEETNACL_SCALARMULT_BYTES, key_material);
1136 return GNUNET_OK;
1210} 1137}
1211 1138
1212 1139
diff --git a/src/util/gnunet-crypto-tvg.c b/src/util/gnunet-crypto-tvg.c
new file mode 100644
index 000000000..7d151c10b
--- /dev/null
+++ b/src/util/gnunet-crypto-tvg.c
@@ -0,0 +1,278 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file util/gnunet-crypto-tgv.c
23 * @brief Generate test vectors for cryptographic operations.
24 * @author Florian Dold
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_signatures.h"
29#include "gnunet_testing_lib.h"
30#include <gcrypt.h>
31
32GNUNET_NETWORK_STRUCT_BEGIN
33
34/**
35 * Sample signature struct.
36 *
37 * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST
38 */
39struct TestSignatureDataPS
40{
41 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
42 uint32_t testval;
43};
44
45GNUNET_NETWORK_STRUCT_END
46
47
48/**
49 * Print data base32-crockford with a preceding label.
50 *
51 * @param label label to print
52 * @param data data to print
53 * @param size size of data
54 */
55static void
56display_data (char *label, void *data, size_t size)
57{
58 char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size);
59 printf ("%s %s\n", label, enc);
60 GNUNET_free (enc);
61}
62
63
64/**
65 * Main function that will be run.
66 *
67 * @param cls closure
68 * @param args remaining command-line arguments
69 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
70 * @param cfg configuration
71 */
72static void
73run (void *cls,
74 char *const *args,
75 const char *cfgfile,
76 const struct GNUNET_CONFIGURATION_Handle *cfg)
77{
78 {
79 struct GNUNET_HashCode hc;
80 char *str = "Hello, GNUnet";
81
82 GNUNET_CRYPTO_hash (str, strlen (str), &hc);
83
84 printf ("hash code:\n");
85 display_data (" input", str, strlen (str));
86 display_data (" output", &hc, sizeof (struct GNUNET_HashCode));
87 }
88 {
89 struct GNUNET_CRYPTO_EcdhePrivateKey *priv1;
90 struct GNUNET_CRYPTO_EcdhePublicKey pub1;
91 struct GNUNET_CRYPTO_EcdhePrivateKey *priv2;
92 struct GNUNET_HashCode skm;
93 priv1 = GNUNET_CRYPTO_ecdhe_key_create ();
94 priv2 = GNUNET_CRYPTO_ecdhe_key_create ();
95 GNUNET_CRYPTO_ecdhe_key_get_public (priv1, &pub1);
96 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (priv2, &pub1, &skm));
97
98 printf ("ecdhe key:\n");
99 display_data (" priv1", priv1, sizeof (struct
100 GNUNET_CRYPTO_EcdhePrivateKey));
101 display_data (" pub1", &pub1, sizeof (struct
102 GNUNET_CRYPTO_EcdhePublicKey));
103 display_data (" priv2", priv2, sizeof (struct
104 GNUNET_CRYPTO_EcdhePrivateKey));
105 display_data (" skm", &skm, sizeof (struct GNUNET_HashCode));
106 GNUNET_free (priv1);
107 GNUNET_free (priv2);
108 }
109
110 {
111 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
112 struct GNUNET_CRYPTO_EddsaPublicKey pub;
113 priv = GNUNET_CRYPTO_eddsa_key_create ();
114 GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
115
116 printf ("eddsa key:\n");
117 display_data (" priv", priv, sizeof (struct
118 GNUNET_CRYPTO_EddsaPrivateKey));
119 display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
120 GNUNET_free (priv);
121 }
122 {
123 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
124 struct GNUNET_CRYPTO_EddsaPublicKey pub;
125 struct GNUNET_CRYPTO_EddsaSignature sig;
126 struct TestSignatureDataPS data = { 0 };
127 priv = GNUNET_CRYPTO_eddsa_key_create ();
128 GNUNET_CRYPTO_eddsa_key_get_public (priv, &pub);
129 data.purpose.size = htonl (sizeof (struct TestSignatureDataPS));
130 data.purpose.size = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
131 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (priv, &data.purpose,
132 &sig));
133 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (0,
134 &data.purpose,
135 &sig,
136 &pub));
137
138 printf ("eddsa sig:\n");
139 display_data (" priv", priv, sizeof (struct
140 GNUNET_CRYPTO_EddsaPrivateKey));
141 display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey));
142 display_data (" data", &data, sizeof (struct TestSignatureDataPS));
143 display_data (" sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature));
144 GNUNET_free (priv);
145 }
146
147 {
148 size_t out_len = 64;
149 char out[out_len];
150 char *ikm = "I'm the secret input key material";
151 char *salt = "I'm very salty";
152 char *ctx = "I'm a context chunk, also known as 'info' in the RFC";
153
154 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out,
155 out_len,
156 salt,
157 strlen (salt),
158 ikm,
159 strlen (ikm),
160 ctx,
161 strlen (ctx),
162 NULL));
163
164 printf ("kdf:\n");
165 display_data (" salt", salt, strlen (salt));
166 display_data (" ikm", ikm, strlen (ikm));
167 display_data (" ctx", ctx, strlen (ctx));
168 printf (" out_len %u\n", (unsigned int) out_len);
169 display_data (" out", out, out_len);
170 }
171 {
172 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdhe;
173 struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe;
174 struct GNUNET_CRYPTO_EddsaPrivateKey *priv_eddsa;
175 struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa;
176 struct GNUNET_HashCode key_material;
177 priv_ecdhe = GNUNET_CRYPTO_ecdhe_key_create ();
178 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdhe, &pub_ecdhe);
179 priv_eddsa = GNUNET_CRYPTO_eddsa_key_create ();
180 GNUNET_CRYPTO_eddsa_key_get_public (priv_eddsa, &pub_eddsa);
181 GNUNET_CRYPTO_ecdh_eddsa (priv_ecdhe, &pub_eddsa, &key_material);
182
183 printf ("eddsa_ecdh:\n");
184 display_data (" priv_ecdhe", priv_ecdhe, sizeof (struct
185 GNUNET_CRYPTO_EcdhePrivateKey));
186 display_data (" pub_ecdhe", &pub_ecdhe, sizeof (struct
187 GNUNET_CRYPTO_EcdhePublicKey));
188 display_data (" priv_eddsa", priv_eddsa, sizeof (struct
189 GNUNET_CRYPTO_EddsaPrivateKey));
190 display_data (" pub_eddsa", &pub_eddsa, sizeof (struct
191 GNUNET_CRYPTO_EddsaPublicKey));
192 display_data (" key_material", &key_material, sizeof (struct
193 GNUNET_HashCode));
194 }
195
196 {
197 struct GNUNET_CRYPTO_RsaPrivateKey *skey;
198 struct GNUNET_CRYPTO_RsaPublicKey *pkey;
199 struct GNUNET_HashCode message_hash;
200 struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
201 struct GNUNET_CRYPTO_RsaSignature *blinded_sig;
202 struct GNUNET_CRYPTO_RsaSignature *sig;
203 char *blinded_data;
204 size_t blinded_len;
205 char *public_enc_data;
206 size_t public_enc_len;
207 char *blinded_sig_enc_data;
208 size_t blinded_sig_enc_length;
209 char *sig_enc_data;
210 size_t sig_enc_length;
211 skey = GNUNET_CRYPTO_rsa_private_key_create (2048);
212 pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey);
213 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash,
214 sizeof (struct GNUNET_HashCode));
215 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct
216 GNUNET_CRYPTO_RsaBlindingKeySecret));
217 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks,
218 pkey, &blinded_data,
219 &blinded_len));
220 blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data,
221 blinded_len);
222 sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey);
223 GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig,
224 pkey));
225 public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey,
226 &public_enc_data);
227 blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig,
228 &
229 blinded_sig_enc_data);
230 sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data);
231 printf ("blind signing:\n");
232 display_data (" message_hash", &message_hash, sizeof (struct
233 GNUNET_HashCode));
234 display_data (" rsa_public_key", public_enc_data, public_enc_len);
235 display_data (" blinding_key_secret", &bks, sizeof (struct
236 GNUNET_CRYPTO_RsaBlindingKeySecret));
237 display_data (" blinded_message", blinded_data, blinded_len);
238 display_data (" blinded_sig", blinded_sig_enc_data,
239 blinded_sig_enc_length);
240 display_data (" sig", sig_enc_data, sig_enc_length);
241 GNUNET_CRYPTO_rsa_private_key_free (skey);
242 GNUNET_CRYPTO_rsa_public_key_free (pkey);
243 GNUNET_CRYPTO_rsa_signature_free (sig);
244 GNUNET_CRYPTO_rsa_signature_free (blinded_sig);
245 }
246}
247
248
249/**
250 * The main function of the test vector generation tool.
251 *
252 * @param argc number of arguments from the command line
253 * @param argv command line arguments
254 * @return 0 ok, 1 on error
255 */
256int
257main (int argc,
258 char *const *argv)
259{
260 const struct GNUNET_GETOPT_CommandLineOption options[] = {
261 GNUNET_GETOPT_OPTION_END
262 };
263
264 GNUNET_assert (GNUNET_OK ==
265 GNUNET_log_setup ("gnunet-crypto-tvg",
266 "INFO",
267 NULL));
268 if (GNUNET_OK !=
269 GNUNET_PROGRAM_run (argc, argv,
270 "gnunet-crypto-tvg",
271 "Generate test vectors for cryptographic operations",
272 options,
273 &run, NULL))
274 return 1;
275 return 0;
276}
277
278/* end of gnunet-crypto-tvg.c */
diff --git a/src/util/test_crypto_ecdh_ecdsa.c b/src/util/test_crypto_ecdh_ecdsa.c
new file mode 100644
index 000000000..8a581ef73
--- /dev/null
+++ b/src/util/test_crypto_ecdh_ecdsa.c
@@ -0,0 +1,97 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2002-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19
20 */
21/**
22 * @file util/test_crypto_ecdh_ecdsa.c
23 * @brief testcase for ECC DH key exchange with ECDSA private keys.
24 * @author Christian Grothoff
25 * @author Bart Polot
26 */
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include <gcrypt.h>
30
31
32static int
33test_ecdh ()
34{
35 struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_dsa;
36 struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ecdh;
37 struct GNUNET_CRYPTO_EcdsaPublicKey id1;
38 struct GNUNET_CRYPTO_EcdhePublicKey id2;
39 struct GNUNET_HashCode dh[2];
40
41 /* Generate keys */
42 priv_dsa = GNUNET_CRYPTO_ecdsa_key_create ();
43 GNUNET_CRYPTO_ecdsa_key_get_public (priv_dsa,
44 &id1);
45 for (unsigned int j = 0; j < 4; j++)
46 {
47 fprintf (stderr, ",");
48 priv_ecdh = GNUNET_CRYPTO_ecdhe_key_create ();
49 /* Extract public keys */
50 GNUNET_CRYPTO_ecdhe_key_get_public (priv_ecdh,
51 &id2);
52 /* Do ECDH */
53 GNUNET_assert (GNUNET_OK ==
54 GNUNET_CRYPTO_ecdsa_ecdh (priv_dsa,
55 &id2,
56 &dh[0]));
57 GNUNET_assert (GNUNET_OK ==
58 GNUNET_CRYPTO_ecdh_ecdsa (priv_ecdh,
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 }
67 GNUNET_free (priv_dsa);
68 return 0;
69}
70
71
72int
73main (int argc, char *argv[])
74{
75 if (! gcry_check_version ("1.6.0"))
76 {
77 fprintf (stderr,
78 _ (
79 "libgcrypt has not the expected version (version %s is required).\n"),
80 "1.6.0");
81 return 0;
82 }
83 if (getenv ("GNUNET_GCRYPT_DEBUG"))
84 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
85 GNUNET_log_setup ("test-crypto-ecdh-ecdsa", "WARNING", NULL);
86 for (unsigned int i = 0; i < 4; i++)
87 {
88 fprintf (stderr,
89 ".");
90 if (0 != test_ecdh ())
91 return 1;
92 }
93 return 0;
94}
95
96
97/* end of test_crypto_ecdh_ecdsa.c */
diff --git a/src/util/tweetnacl-gnunet.c b/src/util/tweetnacl-gnunet.c
index 1c27730a4..f01667adb 100644
--- a/src/util/tweetnacl-gnunet.c
+++ b/src/util/tweetnacl-gnunet.c
@@ -424,8 +424,24 @@ GNUNET_TWEETNACL_sign_pk_from_seed (u8 *pk, const u8 *seed)
424 d[31] &= 127; 424 d[31] &= 127;
425 d[31] |= 64; 425 d[31] |= 64;
426 426
427 scalarbase (p,d); 427 scalarbase (p, d);
428 pack (pk,p); 428 pack (pk, p);
429}
430
431void
432GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (u8 *pk, const u8 *s)
433{
434 u8 d[64];
435 gf p[4];
436
437 // Treat s as little endian.
438 for (u32 i = 0; i < 32; i++)
439 d[i] = s[31 - i];
440
441 // For GNUnet, we don't normalize d
442
443 scalarbase (p, d);
444 pack (pk, p);
429} 445}
430 446
431void 447void
diff --git a/src/util/tweetnacl-gnunet.h b/src/util/tweetnacl-gnunet.h
index 239166ffc..d052d8824 100644
--- a/src/util/tweetnacl-gnunet.h
+++ b/src/util/tweetnacl-gnunet.h
@@ -47,4 +47,8 @@ GNUNET_TWEETNACL_sign_detached (uint8_t *sig,
47 const uint8_t *m, 47 const uint8_t *m,
48 uint64_t n, 48 uint64_t n,
49 const uint8_t *sk); 49 const uint8_t *sk);
50
51void
52GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (uint8_t *pk, const uint8_t *s);
53
50#endif 54#endif