summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-12-01 11:01:08 +0000
committerng0 <ng0@n0.is>2019-12-01 11:01:08 +0000
commit435596a7cb2e5b9adbb8de90f3f917a61d089a1b (patch)
treeece3dacd8808923f884807ca1b8ac93fa24cfad4
parent2f599ebe8ffcd76cfc92ae9fef56f397592becb5 (diff)
parent56d7341763046244bce789f1355441345711958c (diff)
Merge branch 'master' of gnunet.org:gnunet
-rw-r--r--src/gns/Makefile.am1
-rw-r--r--src/gns/gnunet-service-gns_resolver.c70
-rw-r--r--src/gns/nss/nss_gns_query.c6
-rwxr-xr-xsrc/gns/test_gns_cname_lookup.sh23
-rwxr-xr-xsrc/gns/test_gns_gns2dns_zkey_lookup.sh114
-rw-r--r--src/include/gnunet_crypto_lib.h15
-rw-r--r--src/nse/gnunet-service-nse.c33
-rw-r--r--src/nse/nse.conf.in3
-rw-r--r--src/nse/perf_kdf.c31
-rw-r--r--src/revocation/revocation.conf.in2
-rw-r--r--src/revocation/revocation_api.c28
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/crypto_pow.c98
-rw-r--r--src/util/gnunet-scrypt.c28
14 files changed, 329 insertions, 124 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
index 764590589..9f0e0bbb6 100644
--- a/src/gns/Makefile.am
+++ b/src/gns/Makefile.am
@@ -282,6 +282,7 @@ check_SCRIPTS = \
test_gns_caa_lookup.sh\
test_gns_mx_lookup.sh \
test_gns_gns2dns_lookup.sh \
+ test_gns_gns2dns_zkey_lookup.sh \
test_gns_gns2dns_cname_lookup.sh \
test_gns_dht_lookup.sh\
test_gns_delegated_lookup.sh \
diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c
index 9792aff58..4b2641818 100644
--- a/src/gns/gnunet-service-gns_resolver.c
+++ b/src/gns/gnunet-service-gns_resolver.c
@@ -1232,13 +1232,14 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
{
size_t nlen;
char *res;
+ const char *tld;
struct AuthorityChain *ac;
int af;
+ struct GNUNET_CRYPTO_EcdsaPublicKey zone;
nlen = strlen (cname);
- if ((nlen > 2) &&
- (0 == strcmp (".+",
- &cname[nlen - 2])))
+ tld = GNS_get_tld (cname);
+ if (0 == strcmp ("+", tld))
{
/* CNAME resolution continues relative to current domain */
if (0 == rh->name_resolution_pos)
@@ -1272,6 +1273,42 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
rh);
return;
}
+ if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone))
+ {
+ /* CNAME resolution continues relative to current domain */
+ if (0 == rh->name_resolution_pos)
+ {
+ GNUNET_asprintf (&res,
+ "%.*s",
+ strlen (cname) - (strlen (tld) + 1),
+ cname);
+ }
+ else
+ {
+ GNUNET_asprintf (&res,
+ "%.*s.%.*s",
+ (int) rh->name_resolution_pos,
+ rh->name,
+ (int) strlen (cname) - (strlen(tld)+1),
+ cname);
+ }
+ rh->name_resolution_pos = strlen (res);
+ GNUNET_free (rh->name);
+ rh->name = res;
+ ac = GNUNET_new (struct AuthorityChain);
+ ac->rh = rh;
+ ac->gns_authority = GNUNET_YES;
+ ac->authority_info.gns_authority = zone;
+ ac->label = resolver_lookup_get_next_label (rh);
+ /* add AC to tail */
+ GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
+ rh->ac_tail,
+ ac);
+ rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
+ rh);
+ return;
+ }
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Got CNAME `%s' from GNS for `%s'\n",
cname,
@@ -1766,8 +1803,8 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
continue;
}
tld = GNS_get_tld (ip);
- if (0 != strcmp (tld,
- "+"))
+ if ((0 != strcmp (tld, "+")) &&
+ (GNUNET_OK != GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)))
{
/* 'ip' is a DNS name */
gp = GNUNET_new (struct Gns2DnsPending);
@@ -1790,16 +1827,19 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
ac->authority_info.dns_authority.gp_tail,
gp);
gp->rh = GNUNET_new (struct GNS_ResolverHandle);
- ip = translate_dot_plus (rh,
- ip);
- tld = GNS_get_tld (ip);
- if (GNUNET_OK !=
- GNUNET_GNSRECORD_zkey_to_pkey (tld,
- &zone))
+ if (0 == strcmp (tld, "+"))
{
- GNUNET_break_op (0);
- GNUNET_free (ip);
- continue;
+ ip = translate_dot_plus (rh,
+ ip);
+ tld = GNS_get_tld (ip);
+ if (GNUNET_OK !=
+ GNUNET_GNSRECORD_zkey_to_pkey (tld,
+ &zone))
+ {
+ GNUNET_break_op (0);
+ GNUNET_free (ip);
+ continue;
+ }
}
gp->rh->authority_zone = zone;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1845,7 +1885,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
if (IDNA_SUCCESS != idna_to_ascii_8z (tmp, &ac->label, IDNA_ALLOW_UNASSIGNED))
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Name `%s' cannot be converted to IDNA."), tmp);
+ _ ("Name `%s' cannot be converted to IDNA."), tmp);
return GNUNET_SYSERR;
}
GNUNET_free (tmp);
diff --git a/src/gns/nss/nss_gns_query.c b/src/gns/nss/nss_gns_query.c
index 4f5f06cfa..7b69282cb 100644
--- a/src/gns/nss/nss_gns_query.c
+++ b/src/gns/nss/nss_gns_query.c
@@ -63,6 +63,8 @@ gns_resolve_name (int af, const char *name, struct userdata *u)
int out[2];
pid_t pid;
+ if (0 == getuid ())
+ return -2; /* GNS via NSS is NEVER for root */
if (0 != pipe (out))
return -1;
pid = fork ();
@@ -71,9 +73,9 @@ gns_resolve_name (int af, const char *name, struct userdata *u)
if (0 == pid)
{
char *argv[] = { "gnunet-gns",
- "-r", //Raw output for easier parsing
+ "-r", /* Raw output for easier parsing */
#ifdef LSD001
- "-d", //DNS compatibility (allow IDNA names, no UTF-8)
+ "-d", /* DNS compatibility (allow IDNA names, no UTF-8) */
#endif
"-t",
(AF_INET6 == af) ? "AAAA" : "A",
diff --git a/src/gns/test_gns_cname_lookup.sh b/src/gns/test_gns_cname_lookup.sh
index f71346127..748198074 100755
--- a/src/gns/test_gns_cname_lookup.sh
+++ b/src/gns/test_gns_cname_lookup.sh
@@ -32,26 +32,31 @@ TEST_RECORD_CNAME_PLUS="server.+"
TEST_RECORD_CNAME_DNS="gnunet.org"
TEST_RECORD_NAME_SERVER="server"
TEST_RECORD_NAME_PLUS="www"
+TEST_RECORD_NAME_ZKEY="www2"
TEST_RECORD_NAME_DNS="www3"
MY_EGO="myego"
TEST_DOMAIN_PLUS="www.$MY_EGO"
+TEST_DOMAIN_ZKEY="www2.$MY_EGO"
TEST_DOMAIN_DNS="www3.$MY_EGO"
which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
gnunet-arm -s -c test_gns_lookup.conf
gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
+MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
+TEST_RECORD_CNAME_ZKEY="server.${MY_EGO_PKEY}"
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf
+gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf
gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf`
RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf`
+RES_CNAME_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf`
RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS`
-echo NOW
-gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf
-echo WON
+
TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'`
gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_DNS -t CNAME -V $TEST_RECORD_CNAME_DNS -e never -c test_gns_lookup.conf
gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_PLUS -t CNAME -V $TEST_RECORD_CNAME_PLUS -e never -c test_gns_lookup.conf
+gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_NAME_ZKEY -t CNAME -V $TEST_RECORD_CNAME_ZKEY -e never -c test_gns_lookup.conf
gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
gnunet-arm -e -c test_gns_lookup.conf
@@ -70,9 +75,17 @@ fi
if [ "$RES_CNAME" = "$TEST_IP_PLUS" ]
then
- echo "PASS: IP resolution from GNS"
+ echo "PASS: IP resolution from GNS (.+)"
+else
+ echo "FAIL: IP resolution from GNS (.+), got $RES_CNAME, expected $TEST_IP_PLUS."
+ exit 1
+fi
+
+if [ "$RES_CNAME_ZKEY" = "$TEST_IP_PLUS" ]
+then
+ echo "PASS: IP resolution from GNS (.zkey)"
else
- echo "FAIL: IP resolution from GNS, got $RES_CNAME, expected $TEST_IP_PLUS."
+ echo "FAIL: IP resolution from GNS (.zkey), got $RES_CNAME, expected $TEST_IP_PLUS."
exit 1
fi
diff --git a/src/gns/test_gns_gns2dns_zkey_lookup.sh b/src/gns/test_gns_gns2dns_zkey_lookup.sh
new file mode 100755
index 000000000..5c2cddd3c
--- /dev/null
+++ b/src/gns/test_gns_gns2dns_zkey_lookup.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT
+
+LOCATION=$(which gnunet-config)
+if [ -z $LOCATION ]
+then
+ LOCATION="gnunet-config"
+fi
+$LOCATION --version 1> /dev/null
+if test $? != 0
+then
+ echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
+ exit 77
+fi
+
+rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
+# IP address of 'docs.gnunet.org'
+TEST_IP_ALT2="147.87.255.218"
+# IP address of 'www.gnunet.org'
+TEST_IP="131.159.74.67"
+# IPv6 address of 'gnunet.org'
+TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60"
+# permissive DNS resolver we will use for the test
+TEST_IP_GNS2DNS="8.8.8.8"
+
+# main label used during resolution
+TEST_RECORD_NAME="homepage"
+
+if ! nslookup gnunet.org $TEST_IP_GNS2DNS > /dev/null 2>&1
+then
+ echo "Cannot reach DNS, skipping test"
+ exit 77
+fi
+
+# helper record for pointing to the DNS resolver
+TEST_RESOLVER_LABEL="resolver"
+
+MY_EGO="myego"
+# various names we will use for resolution
+TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO"
+TEST_DOMAIN_ALT="${TEST_RECORD_NAME}.$MY_EGO"
+TEST_DOMAIN_ALT2="docs.${TEST_RECORD_NAME}.$MY_EGO"
+
+which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
+
+
+gnunet-arm -s -c test_gns_lookup.conf
+
+OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org`
+echo $OUT | grep $TEST_IP - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv4 for gnunet.org not found ($OUT), skipping test"; exit 77; }
+echo $OUT | grep $TEST_IP6 - > /dev/null || { gnunet-arm -e -c test_gns_lookup.conf ; echo "IPv6 for gnunet.org not found ($OUT), skipping test"; exit 77; }
+
+
+
+gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
+MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
+# GNS2DNS record value: delegate to DNS domain 'gnunet.org'
+# using the TEST_RESOLVER_LABEL DNS server for resolution
+TEST_RECORD_GNS2DNS="gnunet.org@${TEST_RESOLVER_LABEL}.${MY_EGO_PKEY}"
+
+# set IP address for DNS resolver for resolving in gnunet.org domain
+gnunet-namestore -p -z $MY_EGO -a -n $TEST_RESOLVER_LABEL -t A -V $TEST_IP_GNS2DNS -e never -c test_gns_lookup.conf
+# map '$TEST_RECORD_NAME.$MY_EGO' to 'gnunet.org' in DNS
+gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS -e never -c test_gns_lookup.conf
+
+# lookup 'www.gnunet.org', IPv4
+RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf`
+# lookup 'www.gnunet.org', IPv6
+RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf`
+# lookup 'gnunet.org', IPv4
+RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf`
+# lookup 'docs.gnunet.org', IPv4
+RES_IP_ALT2=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT2 -t A -c test_gns_lookup.conf`
+
+# clean up
+gnunet-namestore -z $MY_EGO -d -n $TEST_RESOLVER_LABEL -t A -V $TEST_IP_GNS2DNS -e never -c test_gns_lookup.conf
+gnunet-namestore -z $MY_EGO -d -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS -e never -c test_gns_lookup.conf
+gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
+gnunet-arm -e -c test_gns_lookup.conf
+rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
+
+ret=0
+if echo "$RES_IP" | grep "$TEST_IP" > /dev/null
+then
+ echo "PASS: Resolved $TEST_DOMAIN to $RES_IP."
+else
+ echo "Failed to resolve to proper IP for $TEST_DOMAIN, got $RES_IP, wanted $TEST_IP."
+ ret=1
+fi
+
+if [ "$RES_IP6" = "$TEST_IP6" ]
+then
+ echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6."
+else
+ echo "Failed to resolve to proper IP for $TEST_DOMAIN, got $RES_IP6, wanted $TEST_IP6."
+ ret=1
+fi
+
+if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null
+then
+ echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT."
+else
+ echo "Failed to resolve to proper IP for $TEST_DOMAIN_ALT, got $RES_IP_ALT, wanted $TEST_IP."
+ ret=1
+fi
+
+if echo "$RES_IP_ALT2" | grep "$TEST_IP_ALT2" > /dev/null
+then
+ echo "PASS: Resolved $TEST_DOMAIN_ALT2 to $RES_IP_ALT2."
+else
+ echo "Failed to resolve to proper IP for $TEST_DOMAIN_ALT2, got $RES_IP_ALT2, wanted $TEST_IP_ALT2."
+ ret=1
+fi
+exit $ret
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 507705e50..00fe3fbef 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -655,6 +655,21 @@ GNUNET_CRYPTO_hash (const void *block,
/**
+ * Calculate the 'proof-of-work' hash (an expensive hash).
+ *
+ * @param salt salt to use in pow calculation
+ * @param buf data to hash
+ * @param buf_len number of bytes in @a buf
+ * @param result where to write the resulting hash
+ */
+void
+GNUNET_CRYPTO_pow_hash (const char *salt,
+ const void *buf,
+ size_t buf_len,
+ struct GNUNET_HashCode *result);
+
+
+/**
* Context for cummulative hashing.
*/
struct GNUNET_HashContext;
diff --git a/src/nse/gnunet-service-nse.c b/src/nse/gnunet-service-nse.c
index 3e72be1c5..f4d4e3e2f 100644
--- a/src/nse/gnunet-service-nse.c
+++ b/src/nse/gnunet-service-nse.c
@@ -488,29 +488,6 @@ get_delay_randomization (uint32_t matching_bits)
/**
- * Calculate the 'proof-of-work' hash (an expensive hash).
- *
- * @param buf data to hash
- * @param buf_len number of bytes in @a buf
- * @param result where to write the resulting hash
- */
-static void
-pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
-{
- GNUNET_break (
- 0 == gcry_kdf_derive (buf,
- buf_len,
- GCRY_KDF_SCRYPT,
- 1 /* subalgo */,
- "gnunet-proof-of-work",
- strlen ("gnunet-proof-of-work"),
- 2 /* iterations; keep cost of individual op small */,
- sizeof(struct GNUNET_HashCode),
- result));
-}
-
-
-/**
* Get the number of matching bits that the given timestamp has to the given peer ID.
*
* @param timestamp time to generate key
@@ -828,7 +805,10 @@ check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
GNUNET_memcpy (&buf[sizeof(val)],
pkey,
sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
- pow_hash (buf, sizeof(buf), &result);
+ GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
+ buf,
+ sizeof(buf),
+ &result);
return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES
: GNUNET_NO;
}
@@ -880,7 +860,10 @@ find_proof (void *cls)
while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
{
GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
- pow_hash (buf, sizeof(buf), &result);
+ GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
+ buf,
+ sizeof(buf),
+ &result);
if (nse_work_required <= count_leading_zeroes (&result))
{
my_proof = counter;
diff --git a/src/nse/nse.conf.in b/src/nse/nse.conf.in
index f3bd90e42..d3c9a64b1 100644
--- a/src/nse/nse.conf.in
+++ b/src/nse/nse.conf.in
@@ -31,9 +31,8 @@ WORKDELAY = 5 ms
# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
INTERVAL = 1 h
-# 2^22 hash operations take about 2-3h on a modern i7 (single-core)
+# 2^22 hash operations take about 2-3h on a first-generation i7 (single-core)
# for SCRYPT; with 2ms/op and 5ms workdelay, we can expect
# the POW calculation to be done by a high-end peer in about 6h
# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
WORKBITS = 22
-
diff --git a/src/nse/perf_kdf.c b/src/nse/perf_kdf.c
index ec6dc7ff3..c5975aaf2 100644
--- a/src/nse/perf_kdf.c
+++ b/src/nse/perf_kdf.c
@@ -29,39 +29,18 @@
#include <gauger.h>
-/**
- * Calculate the 'proof-of-work' hash (an expensive hash).
- *
- * @param buf data to hash
- * @param buf_len number of bytes in 'buf'
- * @param result where to write the resulting hash
- */
-static void
-pow_hash (const void *buf,
- size_t buf_len,
- struct GNUNET_HashCode *result)
-{
- GNUNET_break (0 ==
- gcry_kdf_derive (buf, buf_len,
- GCRY_KDF_SCRYPT,
- 1 /* subalgo */,
- "gnunet-proof-of-work", strlen (
- "gnunet-proof-of-work"),
- 2 /* iterations; keep cost of individual op small */,
- sizeof(struct GNUNET_HashCode), result));
-}
-
-
static void
perfHash ()
{
struct GNUNET_HashCode hc;
- unsigned int i;
char buf[64];
memset (buf, 1, sizeof(buf));
- for (i = 0; i < 1024; i++)
- pow_hash (buf, sizeof(buf), &hc);
+ for (unsigned int i = 0; i < 1024; i++)
+ GNUNET_CRYPTO_pow_hash ("gnunet-proof-of-work",
+ buf,
+ sizeof(buf),
+ &hc);
}
diff --git a/src/revocation/revocation.conf.in b/src/revocation/revocation.conf.in
index d7ad174c9..5ad41cd49 100644
--- a/src/revocation/revocation.conf.in
+++ b/src/revocation/revocation.conf.in
@@ -10,7 +10,7 @@ UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-revocation.sock
UNIX_MATCH_UID = NO
UNIX_MATCH_GID = YES
-# 2^25 hash operations take about 16-24h on a modern i7
+# 2^25 hash operations take about 16-24h on a first-generation i7
# (using only a single-core) with SCRYPT.
# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
WORKBITS = 25
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c
index fd25050e2..ea8db835f 100644
--- a/src/revocation/revocation_api.c
+++ b/src/revocation/revocation_api.c
@@ -324,29 +324,6 @@ GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h)
/**
- * Calculate the 'proof-of-work' hash (an expensive hash).
- *
- * @param buf data to hash
- * @param buf_len number of bytes in @a buf
- * @param result where to write the resulting hash
- */
-static void
-pow_hash (const void *buf,
- size_t buf_len,
- struct GNUNET_HashCode *result)
-{
- GNUNET_break (0 ==
- gcry_kdf_derive (buf, buf_len,
- GCRY_KDF_SCRYPT,
- 1 /* subalgo */,
- "gnunet-revocation-proof-of-work",
- strlen ("gnunet-revocation-proof-of-work"),
- 2 /* iterations; keep cost of individual op small */,
- sizeof(struct GNUNET_HashCode), result));
-}
-
-
-/**
* Count the leading zeroes in hash.
*
* @param hash to count leading zeros in
@@ -385,7 +362,10 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
GNUNET_memcpy (buf, &pow, sizeof(pow));
GNUNET_memcpy (&buf[sizeof(pow)], key,
sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
- pow_hash (buf, sizeof(buf), &result);
+ GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
+ buf,
+ sizeof(buf),
+ &result);
return (count_leading_zeroes (&result) >=
matching_bits) ? GNUNET_YES : GNUNET_NO;
}
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 67e131810..0f6251f96 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -64,6 +64,7 @@ libgnunetutil_la_SOURCES = \
crypto_kdf.c \
crypto_mpi.c \
crypto_paillier.c \
+ crypto_pow.c \
crypto_random.c \
crypto_rsa.c \
disk.c \
diff --git a/src/util/crypto_pow.c b/src/util/crypto_pow.c
new file mode 100644
index 000000000..af6837e03
--- /dev/null
+++ b/src/util/crypto_pow.c
@@ -0,0 +1,98 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2012, 2013, 2019 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/**
+ * @file util/crypto_pow.c
+ * @brief proof-of-work hashing
+ * @author Christian Grothoff
+ * @author Bart Polot
+ */
+#include "platform.h"
+#include "gnunet_crypto_lib.h"
+#include <gcrypt.h>
+
+/* FIXME: change to 1 for #3795 / 0.12! */
+#define NEW_CRYPTO 0
+
+/**
+ * Calculate the 'proof-of-work' hash (an expensive hash).
+ * We're using a non-standard formula to avoid issues with
+ * ASICs appearing (see #3795).
+ *
+ * @param salt salt for the hash
+ * @param buf data to hash
+ * @param buf_len number of bytes in @a buf
+ * @param result where to write the resulting hash
+ */
+void
+GNUNET_CRYPTO_pow_hash (const char *salt,
+ const void *buf,
+ size_t buf_len,
+ struct GNUNET_HashCode *result)
+{
+#if NEW_CRYPTO
+ struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+ struct GNUNET_CRYPTO_SymmetricSessionKey skey;
+ char rbuf[buf_len];
+
+ GNUNET_break (0 == gcry_kdf_derive (buf,
+ buf_len,
+ GCRY_KDF_SCRYPT,
+ 1 /* subalgo */,
+ salt,
+ strlen (salt),
+ 2 /* iterations; keep cost of individual op small */,
+ sizeof(skey),
+ &skey));
+ GNUNET_CRYPTO_symmetric_derive_iv (&iv,
+ &skey,
+ "gnunet-proof-of-work-iv",
+ strlen ("gnunet-proof-of-work-iv"),
+ salt,
+ strlen (salt),
+ NULL, 0);
+ GNUNET_CRYPTO_symmetric_encrypt (buf,
+ buf_len,
+ &skey,
+ &iv,
+ &rbuf);
+ GNUNET_break (0 == gcry_kdf_derive (rbuf,
+ buf_len,
+ GCRY_KDF_SCRYPT,
+ 1 /* subalgo */,
+ salt,
+ strlen (salt),
+ 2 /* iterations; keep cost of individual op small */,
+ sizeof(struct GNUNET_HashCode),
+ result));
+#else
+ GNUNET_break (0 == gcry_kdf_derive (buf,
+ buf_len,
+ GCRY_KDF_SCRYPT,
+ 1 /* subalgo */,
+ salt,
+ strlen (salt),
+ 2 /* iterations; keep cost of individual op small */,
+ sizeof(struct GNUNET_HashCode),
+ result));
+#endif
+}
+
+
+/* end of crypto_pow.c */
diff --git a/src/util/gnunet-scrypt.c b/src/util/gnunet-scrypt.c
index 8d8451950..bc8ce83c0 100644
--- a/src/util/gnunet-scrypt.c
+++ b/src/util/gnunet-scrypt.c
@@ -68,29 +68,6 @@ shutdown_task (void *cls)
/**
- * Calculate the 'proof-of-work' hash (an expensive hash).
- *
- * @param buf data to hash
- * @param buf_len number of bytes in @a buf
- * @param result where to write the resulting hash
- */
-static void
-pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
-{
- GNUNET_break (
- 0 == gcry_kdf_derive (buf,
- buf_len,
- GCRY_KDF_SCRYPT,
- 1 /* subalgo */,
- "gnunet-proof-of-work",
- strlen ("gnunet-proof-of-work"),
- 2 /* iterations; keep cost of individual op small */,
- sizeof(struct GNUNET_HashCode),
- result));
-}
-
-
-/**
* Count the leading zeroes in hash.
*
* @param hash to count leading zeros in
@@ -140,7 +117,10 @@ find_proof (void *cls)
while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
{
GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
- pow_hash (buf, sizeof(buf), &result);
+ GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
+ buf,
+ sizeof(buf),
+ &result);
if (nse_work_required <= count_leading_zeroes (&result))
{
proof = counter;