aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 = \
282 test_gns_caa_lookup.sh\ 282 test_gns_caa_lookup.sh\
283 test_gns_mx_lookup.sh \ 283 test_gns_mx_lookup.sh \
284 test_gns_gns2dns_lookup.sh \ 284 test_gns_gns2dns_lookup.sh \
285 test_gns_gns2dns_zkey_lookup.sh \
285 test_gns_gns2dns_cname_lookup.sh \ 286 test_gns_gns2dns_cname_lookup.sh \
286 test_gns_dht_lookup.sh\ 287 test_gns_dht_lookup.sh\
287 test_gns_delegated_lookup.sh \ 288 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,
1232{ 1232{
1233 size_t nlen; 1233 size_t nlen;
1234 char *res; 1234 char *res;
1235 const char *tld;
1235 struct AuthorityChain *ac; 1236 struct AuthorityChain *ac;
1236 int af; 1237 int af;
1238 struct GNUNET_CRYPTO_EcdsaPublicKey zone;
1237 1239
1238 nlen = strlen (cname); 1240 nlen = strlen (cname);
1239 if ((nlen > 2) && 1241 tld = GNS_get_tld (cname);
1240 (0 == strcmp (".+", 1242 if (0 == strcmp ("+", tld))
1241 &cname[nlen - 2])))
1242 { 1243 {
1243 /* CNAME resolution continues relative to current domain */ 1244 /* CNAME resolution continues relative to current domain */
1244 if (0 == rh->name_resolution_pos) 1245 if (0 == rh->name_resolution_pos)
@@ -1272,6 +1273,42 @@ handle_gns_cname_result (struct GNS_ResolverHandle *rh,
1272 rh); 1273 rh);
1273 return; 1274 return;
1274 } 1275 }
1276 if (GNUNET_OK == GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone))
1277 {
1278 /* CNAME resolution continues relative to current domain */
1279 if (0 == rh->name_resolution_pos)
1280 {
1281 GNUNET_asprintf (&res,
1282 "%.*s",
1283 strlen (cname) - (strlen (tld) + 1),
1284 cname);
1285 }
1286 else
1287 {
1288 GNUNET_asprintf (&res,
1289 "%.*s.%.*s",
1290 (int) rh->name_resolution_pos,
1291 rh->name,
1292 (int) strlen (cname) - (strlen(tld)+1),
1293 cname);
1294 }
1295 rh->name_resolution_pos = strlen (res);
1296 GNUNET_free (rh->name);
1297 rh->name = res;
1298 ac = GNUNET_new (struct AuthorityChain);
1299 ac->rh = rh;
1300 ac->gns_authority = GNUNET_YES;
1301 ac->authority_info.gns_authority = zone;
1302 ac->label = resolver_lookup_get_next_label (rh);
1303 /* add AC to tail */
1304 GNUNET_CONTAINER_DLL_insert_tail (rh->ac_head,
1305 rh->ac_tail,
1306 ac);
1307 rh->task_id = GNUNET_SCHEDULER_add_now (&recursive_resolution,
1308 rh);
1309 return;
1310 }
1311
1275 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1312 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1276 "Got CNAME `%s' from GNS for `%s'\n", 1313 "Got CNAME `%s' from GNS for `%s'\n",
1277 cname, 1314 cname,
@@ -1766,8 +1803,8 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
1766 continue; 1803 continue;
1767 } 1804 }
1768 tld = GNS_get_tld (ip); 1805 tld = GNS_get_tld (ip);
1769 if (0 != strcmp (tld, 1806 if ((0 != strcmp (tld, "+")) &&
1770 "+")) 1807 (GNUNET_OK != GNUNET_GNSRECORD_zkey_to_pkey (tld, &zone)))
1771 { 1808 {
1772 /* 'ip' is a DNS name */ 1809 /* 'ip' is a DNS name */
1773 gp = GNUNET_new (struct Gns2DnsPending); 1810 gp = GNUNET_new (struct Gns2DnsPending);
@@ -1790,16 +1827,19 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
1790 ac->authority_info.dns_authority.gp_tail, 1827 ac->authority_info.dns_authority.gp_tail,
1791 gp); 1828 gp);
1792 gp->rh = GNUNET_new (struct GNS_ResolverHandle); 1829 gp->rh = GNUNET_new (struct GNS_ResolverHandle);
1793 ip = translate_dot_plus (rh, 1830 if (0 == strcmp (tld, "+"))
1794 ip);
1795 tld = GNS_get_tld (ip);
1796 if (GNUNET_OK !=
1797 GNUNET_GNSRECORD_zkey_to_pkey (tld,
1798 &zone))
1799 { 1831 {
1800 GNUNET_break_op (0); 1832 ip = translate_dot_plus (rh,
1801 GNUNET_free (ip); 1833 ip);
1802 continue; 1834 tld = GNS_get_tld (ip);
1835 if (GNUNET_OK !=
1836 GNUNET_GNSRECORD_zkey_to_pkey (tld,
1837 &zone))
1838 {
1839 GNUNET_break_op (0);
1840 GNUNET_free (ip);
1841 continue;
1842 }
1803 } 1843 }
1804 gp->rh->authority_zone = zone; 1844 gp->rh->authority_zone = zone;
1805 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1845 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1845,7 +1885,7 @@ recursive_gns2dns_resolution (struct GNS_ResolverHandle *rh,
1845 if (IDNA_SUCCESS != idna_to_ascii_8z (tmp, &ac->label, IDNA_ALLOW_UNASSIGNED)) 1885 if (IDNA_SUCCESS != idna_to_ascii_8z (tmp, &ac->label, IDNA_ALLOW_UNASSIGNED))
1846 { 1886 {
1847 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1887 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1848 _("Name `%s' cannot be converted to IDNA."), tmp); 1888 _ ("Name `%s' cannot be converted to IDNA."), tmp);
1849 return GNUNET_SYSERR; 1889 return GNUNET_SYSERR;
1850 } 1890 }
1851 GNUNET_free (tmp); 1891 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)
63 int out[2]; 63 int out[2];
64 pid_t pid; 64 pid_t pid;
65 65
66 if (0 == getuid ())
67 return -2; /* GNS via NSS is NEVER for root */
66 if (0 != pipe (out)) 68 if (0 != pipe (out))
67 return -1; 69 return -1;
68 pid = fork (); 70 pid = fork ();
@@ -71,9 +73,9 @@ gns_resolve_name (int af, const char *name, struct userdata *u)
71 if (0 == pid) 73 if (0 == pid)
72 { 74 {
73 char *argv[] = { "gnunet-gns", 75 char *argv[] = { "gnunet-gns",
74 "-r", //Raw output for easier parsing 76 "-r", /* Raw output for easier parsing */
75#ifdef LSD001 77#ifdef LSD001
76 "-d", //DNS compatibility (allow IDNA names, no UTF-8) 78 "-d", /* DNS compatibility (allow IDNA names, no UTF-8) */
77#endif 79#endif
78 "-t", 80 "-t",
79 (AF_INET6 == af) ? "AAAA" : "A", 81 (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.+"
32TEST_RECORD_CNAME_DNS="gnunet.org" 32TEST_RECORD_CNAME_DNS="gnunet.org"
33TEST_RECORD_NAME_SERVER="server" 33TEST_RECORD_NAME_SERVER="server"
34TEST_RECORD_NAME_PLUS="www" 34TEST_RECORD_NAME_PLUS="www"
35TEST_RECORD_NAME_ZKEY="www2"
35TEST_RECORD_NAME_DNS="www3" 36TEST_RECORD_NAME_DNS="www3"
36MY_EGO="myego" 37MY_EGO="myego"
37TEST_DOMAIN_PLUS="www.$MY_EGO" 38TEST_DOMAIN_PLUS="www.$MY_EGO"
39TEST_DOMAIN_ZKEY="www2.$MY_EGO"
38TEST_DOMAIN_DNS="www3.$MY_EGO" 40TEST_DOMAIN_DNS="www3.$MY_EGO"
39which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15" 41which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
40 42
41gnunet-arm -s -c test_gns_lookup.conf 43gnunet-arm -s -c test_gns_lookup.conf
42gnunet-identity -C $MY_EGO -c test_gns_lookup.conf 44gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
45MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
46TEST_RECORD_CNAME_ZKEY="server.${MY_EGO_PKEY}"
43gnunet-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 47gnunet-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
44gnunet-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 48gnunet-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
49gnunet-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
45gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf 50gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
46RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf` 51RES_CNAME=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t A -c test_gns_lookup.conf`
47RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf` 52RES_CNAME_RAW=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_PLUS -t CNAME -c test_gns_lookup.conf`
53RES_CNAME_ZKEY=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ZKEY -t A -c test_gns_lookup.conf`
48RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS` 54RES_CNAME_DNS=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf | grep $TEST_IP_DNS`
49echo NOW 55
50gnunet-gns --raw -u $TEST_DOMAIN_DNS -t A -c test_gns_lookup.conf
51echo WON
52TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'` 56TESTEGOZONE=`gnunet-identity -c test_gns_lookup.conf -d | awk '{print $3}'`
53gnunet-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 57gnunet-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
54gnunet-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 58gnunet-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
59gnunet-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
55gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf 60gnunet-namestore -p -z $MY_EGO -d -n $TEST_RECORD_CNAME_SERVER -t A -V $TEST_IP_PLUS -e never -c test_gns_lookup.conf
56gnunet-identity -D $MY_EGO -c test_gns_lookup.conf 61gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
57gnunet-arm -e -c test_gns_lookup.conf 62gnunet-arm -e -c test_gns_lookup.conf
@@ -70,9 +75,17 @@ fi
70 75
71if [ "$RES_CNAME" = "$TEST_IP_PLUS" ] 76if [ "$RES_CNAME" = "$TEST_IP_PLUS" ]
72then 77then
73 echo "PASS: IP resolution from GNS" 78 echo "PASS: IP resolution from GNS (.+)"
79else
80 echo "FAIL: IP resolution from GNS (.+), got $RES_CNAME, expected $TEST_IP_PLUS."
81 exit 1
82fi
83
84if [ "$RES_CNAME_ZKEY" = "$TEST_IP_PLUS" ]
85then
86 echo "PASS: IP resolution from GNS (.zkey)"
74else 87else
75 echo "FAIL: IP resolution from GNS, got $RES_CNAME, expected $TEST_IP_PLUS." 88 echo "FAIL: IP resolution from GNS (.zkey), got $RES_CNAME, expected $TEST_IP_PLUS."
76 exit 1 89 exit 1
77fi 90fi
78 91
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 @@
1#!/bin/sh
2trap "gnunet-arm -e -c test_gns_lookup.conf" SIGINT
3
4LOCATION=$(which gnunet-config)
5if [ -z $LOCATION ]
6then
7 LOCATION="gnunet-config"
8fi
9$LOCATION --version 1> /dev/null
10if test $? != 0
11then
12 echo "GNUnet command line tools cannot be found, check environmental variables PATH and GNUNET_PREFIX"
13 exit 77
14fi
15
16rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
17# IP address of 'docs.gnunet.org'
18TEST_IP_ALT2="147.87.255.218"
19# IP address of 'www.gnunet.org'
20TEST_IP="131.159.74.67"
21# IPv6 address of 'gnunet.org'
22TEST_IP6="2001:4ca0:2001:42:225:90ff:fe6b:d60"
23# permissive DNS resolver we will use for the test
24TEST_IP_GNS2DNS="8.8.8.8"
25
26# main label used during resolution
27TEST_RECORD_NAME="homepage"
28
29if ! nslookup gnunet.org $TEST_IP_GNS2DNS > /dev/null 2>&1
30then
31 echo "Cannot reach DNS, skipping test"
32 exit 77
33fi
34
35# helper record for pointing to the DNS resolver
36TEST_RESOLVER_LABEL="resolver"
37
38MY_EGO="myego"
39# various names we will use for resolution
40TEST_DOMAIN="www.${TEST_RECORD_NAME}.$MY_EGO"
41TEST_DOMAIN_ALT="${TEST_RECORD_NAME}.$MY_EGO"
42TEST_DOMAIN_ALT2="docs.${TEST_RECORD_NAME}.$MY_EGO"
43
44which timeout > /dev/null 2>&1 && DO_TIMEOUT="timeout 15"
45
46
47gnunet-arm -s -c test_gns_lookup.conf
48
49OUT=`$DO_TIMEOUT gnunet-resolver -c test_gns_lookup.conf gnunet.org`
50echo $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; }
51echo $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; }
52
53
54
55gnunet-identity -C $MY_EGO -c test_gns_lookup.conf
56MY_EGO_PKEY=$(gnunet-identity -d -c test_gns_lookup.conf | grep ${MY_EGO} | awk '{print $3}')
57# GNS2DNS record value: delegate to DNS domain 'gnunet.org'
58# using the TEST_RESOLVER_LABEL DNS server for resolution
59TEST_RECORD_GNS2DNS="gnunet.org@${TEST_RESOLVER_LABEL}.${MY_EGO_PKEY}"
60
61# set IP address for DNS resolver for resolving in gnunet.org domain
62gnunet-namestore -p -z $MY_EGO -a -n $TEST_RESOLVER_LABEL -t A -V $TEST_IP_GNS2DNS -e never -c test_gns_lookup.conf
63# map '$TEST_RECORD_NAME.$MY_EGO' to 'gnunet.org' in DNS
64gnunet-namestore -p -z $MY_EGO -a -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS -e never -c test_gns_lookup.conf
65
66# lookup 'www.gnunet.org', IPv4
67RES_IP=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t A -c test_gns_lookup.conf`
68# lookup 'www.gnunet.org', IPv6
69RES_IP6=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN -t AAAA -c test_gns_lookup.conf`
70# lookup 'gnunet.org', IPv4
71RES_IP_ALT=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT -t A -c test_gns_lookup.conf`
72# lookup 'docs.gnunet.org', IPv4
73RES_IP_ALT2=`$DO_TIMEOUT gnunet-gns --raw -u $TEST_DOMAIN_ALT2 -t A -c test_gns_lookup.conf`
74
75# clean up
76gnunet-namestore -z $MY_EGO -d -n $TEST_RESOLVER_LABEL -t A -V $TEST_IP_GNS2DNS -e never -c test_gns_lookup.conf
77gnunet-namestore -z $MY_EGO -d -n $TEST_RECORD_NAME -t GNS2DNS -V $TEST_RECORD_GNS2DNS -e never -c test_gns_lookup.conf
78gnunet-identity -D $MY_EGO -c test_gns_lookup.conf
79gnunet-arm -e -c test_gns_lookup.conf
80rm -rf `gnunet-config -c test_gns_lookup.conf -f -s paths -o GNUNET_TEST_HOME`
81
82ret=0
83if echo "$RES_IP" | grep "$TEST_IP" > /dev/null
84then
85 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP."
86else
87 echo "Failed to resolve to proper IP for $TEST_DOMAIN, got $RES_IP, wanted $TEST_IP."
88 ret=1
89fi
90
91if [ "$RES_IP6" = "$TEST_IP6" ]
92then
93 echo "PASS: Resolved $TEST_DOMAIN to $RES_IP6."
94else
95 echo "Failed to resolve to proper IP for $TEST_DOMAIN, got $RES_IP6, wanted $TEST_IP6."
96 ret=1
97fi
98
99if echo "$RES_IP_ALT" | grep "$TEST_IP" > /dev/null
100then
101 echo "PASS: Resolved $TEST_DOMAIN_ALT to $RES_IP_ALT."
102else
103 echo "Failed to resolve to proper IP for $TEST_DOMAIN_ALT, got $RES_IP_ALT, wanted $TEST_IP."
104 ret=1
105fi
106
107if echo "$RES_IP_ALT2" | grep "$TEST_IP_ALT2" > /dev/null
108then
109 echo "PASS: Resolved $TEST_DOMAIN_ALT2 to $RES_IP_ALT2."
110else
111 echo "Failed to resolve to proper IP for $TEST_DOMAIN_ALT2, got $RES_IP_ALT2, wanted $TEST_IP_ALT2."
112 ret=1
113fi
114exit $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,
655 655
656 656
657/** 657/**
658 * Calculate the 'proof-of-work' hash (an expensive hash).
659 *
660 * @param salt salt to use in pow calculation
661 * @param buf data to hash
662 * @param buf_len number of bytes in @a buf
663 * @param result where to write the resulting hash
664 */
665void
666GNUNET_CRYPTO_pow_hash (const char *salt,
667 const void *buf,
668 size_t buf_len,
669 struct GNUNET_HashCode *result);
670
671
672/**
658 * Context for cummulative hashing. 673 * Context for cummulative hashing.
659 */ 674 */
660struct GNUNET_HashContext; 675struct 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)
488 488
489 489
490/** 490/**
491 * Calculate the 'proof-of-work' hash (an expensive hash).
492 *
493 * @param buf data to hash
494 * @param buf_len number of bytes in @a buf
495 * @param result where to write the resulting hash
496 */
497static void
498pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
499{
500 GNUNET_break (
501 0 == gcry_kdf_derive (buf,
502 buf_len,
503 GCRY_KDF_SCRYPT,
504 1 /* subalgo */,
505 "gnunet-proof-of-work",
506 strlen ("gnunet-proof-of-work"),
507 2 /* iterations; keep cost of individual op small */,
508 sizeof(struct GNUNET_HashCode),
509 result));
510}
511
512
513/**
514 * Get the number of matching bits that the given timestamp has to the given peer ID. 491 * Get the number of matching bits that the given timestamp has to the given peer ID.
515 * 492 *
516 * @param timestamp time to generate key 493 * @param timestamp time to generate key
@@ -828,7 +805,10 @@ check_proof_of_work (const struct GNUNET_CRYPTO_EddsaPublicKey *pkey,
828 GNUNET_memcpy (&buf[sizeof(val)], 805 GNUNET_memcpy (&buf[sizeof(val)],
829 pkey, 806 pkey,
830 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)); 807 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey));
831 pow_hash (buf, sizeof(buf), &result); 808 GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
809 buf,
810 sizeof(buf),
811 &result);
832 return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES 812 return (count_leading_zeroes (&result) >= nse_work_required) ? GNUNET_YES
833 : GNUNET_NO; 813 : GNUNET_NO;
834} 814}
@@ -880,7 +860,10 @@ find_proof (void *cls)
880 while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) 860 while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
881 { 861 {
882 GNUNET_memcpy (buf, &counter, sizeof(uint64_t)); 862 GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
883 pow_hash (buf, sizeof(buf), &result); 863 GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
864 buf,
865 sizeof(buf),
866 &result);
884 if (nse_work_required <= count_leading_zeroes (&result)) 867 if (nse_work_required <= count_leading_zeroes (&result))
885 { 868 {
886 my_proof = counter; 869 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
31# DO NOT CHANGE THIS VALUE, doing so will break the protocol! 31# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
32INTERVAL = 1 h 32INTERVAL = 1 h
33 33
34# 2^22 hash operations take about 2-3h on a modern i7 (single-core) 34# 2^22 hash operations take about 2-3h on a first-generation i7 (single-core)
35# for SCRYPT; with 2ms/op and 5ms workdelay, we can expect 35# for SCRYPT; with 2ms/op and 5ms workdelay, we can expect
36# the POW calculation to be done by a high-end peer in about 6h 36# the POW calculation to be done by a high-end peer in about 6h
37# DO NOT CHANGE THIS VALUE, doing so will break the protocol! 37# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
38WORKBITS = 22 38WORKBITS = 22
39
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 @@
29#include <gauger.h> 29#include <gauger.h>
30 30
31 31
32/**
33 * Calculate the 'proof-of-work' hash (an expensive hash).
34 *
35 * @param buf data to hash
36 * @param buf_len number of bytes in 'buf'
37 * @param result where to write the resulting hash
38 */
39static void
40pow_hash (const void *buf,
41 size_t buf_len,
42 struct GNUNET_HashCode *result)
43{
44 GNUNET_break (0 ==
45 gcry_kdf_derive (buf, buf_len,
46 GCRY_KDF_SCRYPT,
47 1 /* subalgo */,
48 "gnunet-proof-of-work", strlen (
49 "gnunet-proof-of-work"),
50 2 /* iterations; keep cost of individual op small */,
51 sizeof(struct GNUNET_HashCode), result));
52}
53
54
55static void 32static void
56perfHash () 33perfHash ()
57{ 34{
58 struct GNUNET_HashCode hc; 35 struct GNUNET_HashCode hc;
59 unsigned int i;
60 char buf[64]; 36 char buf[64];
61 37
62 memset (buf, 1, sizeof(buf)); 38 memset (buf, 1, sizeof(buf));
63 for (i = 0; i < 1024; i++) 39 for (unsigned int i = 0; i < 1024; i++)
64 pow_hash (buf, sizeof(buf), &hc); 40 GNUNET_CRYPTO_pow_hash ("gnunet-proof-of-work",
41 buf,
42 sizeof(buf),
43 &hc);
65} 44}
66 45
67 46
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
10UNIX_MATCH_UID = NO 10UNIX_MATCH_UID = NO
11UNIX_MATCH_GID = YES 11UNIX_MATCH_GID = YES
12 12
13# 2^25 hash operations take about 16-24h on a modern i7 13# 2^25 hash operations take about 16-24h on a first-generation i7
14# (using only a single-core) with SCRYPT. 14# (using only a single-core) with SCRYPT.
15# DO NOT CHANGE THIS VALUE, doing so will break the protocol! 15# DO NOT CHANGE THIS VALUE, doing so will break the protocol!
16WORKBITS = 25 16WORKBITS = 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)
324 324
325 325
326/** 326/**
327 * Calculate the 'proof-of-work' hash (an expensive hash).
328 *
329 * @param buf data to hash
330 * @param buf_len number of bytes in @a buf
331 * @param result where to write the resulting hash
332 */
333static void
334pow_hash (const void *buf,
335 size_t buf_len,
336 struct GNUNET_HashCode *result)
337{
338 GNUNET_break (0 ==
339 gcry_kdf_derive (buf, buf_len,
340 GCRY_KDF_SCRYPT,
341 1 /* subalgo */,
342 "gnunet-revocation-proof-of-work",
343 strlen ("gnunet-revocation-proof-of-work"),
344 2 /* iterations; keep cost of individual op small */,
345 sizeof(struct GNUNET_HashCode), result));
346}
347
348
349/**
350 * Count the leading zeroes in hash. 327 * Count the leading zeroes in hash.
351 * 328 *
352 * @param hash to count leading zeros in 329 * @param hash to count leading zeros in
@@ -385,7 +362,10 @@ GNUNET_REVOCATION_check_pow (const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
385 GNUNET_memcpy (buf, &pow, sizeof(pow)); 362 GNUNET_memcpy (buf, &pow, sizeof(pow));
386 GNUNET_memcpy (&buf[sizeof(pow)], key, 363 GNUNET_memcpy (&buf[sizeof(pow)], key,
387 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 364 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
388 pow_hash (buf, sizeof(buf), &result); 365 GNUNET_CRYPTO_pow_hash ("gnunet-revocation-proof-of-work",
366 buf,
367 sizeof(buf),
368 &result);
389 return (count_leading_zeroes (&result) >= 369 return (count_leading_zeroes (&result) >=
390 matching_bits) ? GNUNET_YES : GNUNET_NO; 370 matching_bits) ? GNUNET_YES : GNUNET_NO;
391} 371}
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 = \
64 crypto_kdf.c \ 64 crypto_kdf.c \
65 crypto_mpi.c \ 65 crypto_mpi.c \
66 crypto_paillier.c \ 66 crypto_paillier.c \
67 crypto_pow.c \
67 crypto_random.c \ 68 crypto_random.c \
68 crypto_rsa.c \ 69 crypto_rsa.c \
69 disk.c \ 70 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 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2019 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 * @file util/crypto_pow.c
22 * @brief proof-of-work hashing
23 * @author Christian Grothoff
24 * @author Bart Polot
25 */
26#include "platform.h"
27#include "gnunet_crypto_lib.h"
28#include <gcrypt.h>
29
30/* FIXME: change to 1 for #3795 / 0.12! */
31#define NEW_CRYPTO 0
32
33/**
34 * Calculate the 'proof-of-work' hash (an expensive hash).
35 * We're using a non-standard formula to avoid issues with
36 * ASICs appearing (see #3795).
37 *
38 * @param salt salt for the hash
39 * @param buf data to hash
40 * @param buf_len number of bytes in @a buf
41 * @param result where to write the resulting hash
42 */
43void
44GNUNET_CRYPTO_pow_hash (const char *salt,
45 const void *buf,
46 size_t buf_len,
47 struct GNUNET_HashCode *result)
48{
49#if NEW_CRYPTO
50 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
51 struct GNUNET_CRYPTO_SymmetricSessionKey skey;
52 char rbuf[buf_len];
53
54 GNUNET_break (0 == gcry_kdf_derive (buf,
55 buf_len,
56 GCRY_KDF_SCRYPT,
57 1 /* subalgo */,
58 salt,
59 strlen (salt),
60 2 /* iterations; keep cost of individual op small */,
61 sizeof(skey),
62 &skey));
63 GNUNET_CRYPTO_symmetric_derive_iv (&iv,
64 &skey,
65 "gnunet-proof-of-work-iv",
66 strlen ("gnunet-proof-of-work-iv"),
67 salt,
68 strlen (salt),
69 NULL, 0);
70 GNUNET_CRYPTO_symmetric_encrypt (buf,
71 buf_len,
72 &skey,
73 &iv,
74 &rbuf);
75 GNUNET_break (0 == gcry_kdf_derive (rbuf,
76 buf_len,
77 GCRY_KDF_SCRYPT,
78 1 /* subalgo */,
79 salt,
80 strlen (salt),
81 2 /* iterations; keep cost of individual op small */,
82 sizeof(struct GNUNET_HashCode),
83 result));
84#else
85 GNUNET_break (0 == gcry_kdf_derive (buf,
86 buf_len,
87 GCRY_KDF_SCRYPT,
88 1 /* subalgo */,
89 salt,
90 strlen (salt),
91 2 /* iterations; keep cost of individual op small */,
92 sizeof(struct GNUNET_HashCode),
93 result));
94#endif
95}
96
97
98/* 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)
68 68
69 69
70/** 70/**
71 * Calculate the 'proof-of-work' hash (an expensive hash).
72 *
73 * @param buf data to hash
74 * @param buf_len number of bytes in @a buf
75 * @param result where to write the resulting hash
76 */
77static void
78pow_hash (const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
79{
80 GNUNET_break (
81 0 == gcry_kdf_derive (buf,
82 buf_len,
83 GCRY_KDF_SCRYPT,
84 1 /* subalgo */,
85 "gnunet-proof-of-work",
86 strlen ("gnunet-proof-of-work"),
87 2 /* iterations; keep cost of individual op small */,
88 sizeof(struct GNUNET_HashCode),
89 result));
90}
91
92
93/**
94 * Count the leading zeroes in hash. 71 * Count the leading zeroes in hash.
95 * 72 *
96 * @param hash to count leading zeros in 73 * @param hash to count leading zeros in
@@ -140,7 +117,10 @@ find_proof (void *cls)
140 while ((counter != UINT64_MAX) && (i < ROUND_SIZE)) 117 while ((counter != UINT64_MAX) && (i < ROUND_SIZE))
141 { 118 {
142 GNUNET_memcpy (buf, &counter, sizeof(uint64_t)); 119 GNUNET_memcpy (buf, &counter, sizeof(uint64_t));
143 pow_hash (buf, sizeof(buf), &result); 120 GNUNET_CRYPTO_pow_hash ("gnunet-nse-proof-of-work",
121 buf,
122 sizeof(buf),
123 &result);
144 if (nse_work_required <= count_leading_zeroes (&result)) 124 if (nse_work_required <= count_leading_zeroes (&result))
145 { 125 {
146 proof = counter; 126 proof = counter;