summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-04-16 19:57:15 +0200
committerChristian Grothoff <christian@grothoff.org>2019-04-16 19:57:15 +0200
commit3266ea560ea1b243810dce4d46ee2889da7b4f6c (patch)
tree555ce759adf099350f89fd520f11d04161e8df1c /src
parentcb169441f0ed127dd07e2c6f98436dcd0ece8f61 (diff)
implement backchannel encryption/decryption
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_crypto_lib.h20
-rw-r--r--src/transport/Makefile.am1
-rw-r--r--src/transport/gnunet-communicator-tcp.c10
-rw-r--r--src/transport/gnunet-service-tng.c68
-rw-r--r--src/util/crypto_random.c39
5 files changed, 108 insertions, 30 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index 6822de2f1..45da5f6ba 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -456,6 +456,18 @@ int32_t
GNUNET_CRYPTO_crc32_n (const void *buf,
size_t len);
+/**
+ * @ingroup crypto
+ * Zero out @a buffer, securely against compiler optimizations.
+ * Used to delete key material.
+ *
+ * @param buffer the buffer to zap
+ * @param length buffer length
+ */
+void
+GNUNET_CRYPTO_zero_keys (void *buffer,
+ size_t length);
+
/**
* @ingroup crypto
@@ -721,8 +733,8 @@ GNUNET_CRYPTO_hash_context_abort (struct GNUNET_HashContext *hc);
*/
void
GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
- const void *plaintext, size_t plaintext_len,
- struct GNUNET_HashCode *hmac);
+ const void *plaintext, size_t plaintext_len,
+ struct GNUNET_HashCode *hmac);
/**
@@ -1866,7 +1878,7 @@ GNUNET_CRYPTO_rsa_private_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key);
*/
size_t
GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
- char **buffer);
+ char **buffer);
/**
@@ -1879,7 +1891,7 @@ GNUNET_CRYPTO_rsa_private_key_encode (const struct GNUNET_CRYPTO_RsaPrivateKey *
*/
struct GNUNET_CRYPTO_RsaPrivateKey *
GNUNET_CRYPTO_rsa_private_key_decode (const char *buf,
- size_t len);
+ size_t len);
/**
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index f83fa669c..53fd9c973 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -374,6 +374,7 @@ gnunet_service_tng_LDADD = \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la \
+ $(LIBGCRYPT_LIBS) \
$(GN_LIBINTL)
plugin_LTLIBRARIES = \
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c
index a8f88c5e4..e9223401f 100644
--- a/src/transport/gnunet-communicator-tcp.c
+++ b/src/transport/gnunet-communicator-tcp.c
@@ -814,9 +814,9 @@ pass_plaintext_to_core (struct Queue *queue,
*/
static void
setup_cipher (const struct GNUNET_HashCode *dh,
- const struct GNUNET_PeerIdentity *pid,
- gcry_cipher_hd_t *cipher,
- struct GNUNET_HashCode *hmac_key)
+ const struct GNUNET_PeerIdentity *pid,
+ gcry_cipher_hd_t *cipher,
+ struct GNUNET_HashCode *hmac_key)
{
char key[256/8];
char ctr[128/8];
@@ -872,7 +872,7 @@ setup_cipher (const struct GNUNET_HashCode *dh,
*/
static void
setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
- struct Queue *queue)
+ struct Queue *queue)
{
struct GNUNET_HashCode dh;
@@ -896,7 +896,7 @@ setup_in_cipher (const struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral,
*/
static void
do_rekey (struct Queue *queue,
- const struct TCPRekey *rekey)
+ const struct TCPRekey *rekey)
{
struct TcpHandshakeSignature thp;
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index bb1656876..53b9ba0c8 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -33,7 +33,6 @@
* transport-to-transport traffic)
*
* Implement next:
- * - backchannel message encryption & decryption
* - DV data structures:
* + using DV routes!
* - handling of DV-boxed messages that need to be forwarded
@@ -59,7 +58,6 @@
* FIXME (without marks in the code!):
* - proper use/initialization of timestamps in messages exchanged
* during DV learning
- * -
*
* Optimizations:
* - use shorthashmap on msg_uuid's when matching reliability/fragment ACKs
@@ -3238,21 +3236,32 @@ route_message (const struct GNUNET_PeerIdentity *target,
*/
struct BackchannelKeyState
{
- // FIXME: actual data types in this struct are likely still totally wrong
/**
- *
+ * State of our block cipher.
*/
- char hdr_key[128];
+ gcry_cipher_hd_t cipher;
/**
- *
+ * Actual key material.
*/
- char body_key[128];
+ struct {
- /**
- *
- */
- char hmac_key[128];
+ /**
+ * Key used for HMAC calculations (via #GNUNET_CRYPTO_hmac()).
+ */
+ struct GNUNET_CRYPTO_AuthKey hmac_key;
+
+ /**
+ * Symmetric key to use for encryption.
+ */
+ char aes_key[256/8];
+
+ /**
+ * Counter value to use during setup.
+ */
+ char aes_ctr[128/8];
+
+ } material;
};
@@ -3263,14 +3272,24 @@ bc_setup_key_state_from_km (const struct GNUNET_HashCode *km,
{
/* must match #dh_key_derive_eph_pub */
GNUNET_assert (GNUNET_YES ==
- GNUNET_CRYPTO_kdf (key,
- sizeof (*key),
+ GNUNET_CRYPTO_kdf (&key->material,
+ sizeof (key->material),
"transport-backchannel-key",
strlen ("transport-backchannel-key"),
&km,
sizeof (km),
iv,
sizeof (*iv)));
+ gcry_cipher_open (&key->cipher,
+ GCRY_CIPHER_AES256 /* low level: go for speed */,
+ GCRY_CIPHER_MODE_CTR,
+ 0 /* flags */);
+ gcry_cipher_setkey (key->cipher,
+ &key->material.aes_key,
+ sizeof (key->material.aes_key));
+ gcry_cipher_setctr (key->cipher,
+ &key->material.aes_ctr,
+ sizeof (key->material.aes_ctr));
}
@@ -3342,7 +3361,10 @@ bc_hmac (const struct BackchannelKeyState *key,
const void *data,
size_t data_size)
{
- // FIXME!
+ GNUNET_CRYPTO_hmac (&key->material.hmac_key,
+ data,
+ data_size,
+ hmac);
}
@@ -3361,7 +3383,12 @@ bc_encrypt (struct BackchannelKeyState *key,
void *dst,
size_t in_size)
{
- // FIXME!
+ GNUNET_assert (0 ==
+ gcry_cipher_encrypt (key->cipher,
+ dst,
+ in_size,
+ in,
+ in_size));
}
@@ -3380,7 +3407,12 @@ bc_decrypt (struct BackchannelKeyState *key,
const void *ciph,
size_t out_size)
{
- // FIXME!
+ GNUNET_assert (0 ==
+ gcry_cipher_decrypt (key->cipher,
+ out,
+ out_size,
+ ciph,
+ out_size));
}
@@ -3392,7 +3424,9 @@ bc_decrypt (struct BackchannelKeyState *key,
static void
bc_key_clean (struct BackchannelKeyState *key)
{
- // FIXME!
+ gcry_cipher_close (key->cipher);
+ GNUNET_CRYPTO_zero_keys (&key->material,
+ sizeof (key->material));
}
diff --git a/src/util/crypto_random.c b/src/util/crypto_random.c
index 54bea58e1..8bb5f0587 100644
--- a/src/util/crypto_random.c
+++ b/src/util/crypto_random.c
@@ -98,6 +98,34 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed)
/**
* @ingroup crypto
+ * Zero out @a buffer, securely against compiler optimizations.
+ * Used to delete key material.
+ *
+ * @param buffer the buffer to zap
+ * @param length buffer length
+ */
+void
+GNUNET_CRYPTO_zero_keys (void *buffer,
+ size_t length)
+{
+#if HAVE_MEMSET_S
+ memset_s (buffer,
+ length,
+ 0,
+ length);
+#elif HAVE_EXPLICIT_BZERO
+ explicit_bzero (buffer,
+ length);
+#else
+ volatile unsigned char *p = buffer;
+ while (length--)
+ *p++ = 0;
+#endif
+}
+
+
+/**
+ * @ingroup crypto
* Fill block with a random values.
*
* @param mode desired quality of the random number
@@ -105,7 +133,9 @@ GNUNET_CRYPTO_seed_weak_random (int32_t seed)
* @param length buffer length
*/
void
-GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
+GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode,
+ void *buffer,
+ size_t length)
{
#ifdef gcry_fast_random_poll
static unsigned int invokeCount;
@@ -146,7 +176,7 @@ GNUNET_CRYPTO_random_block (enum GNUNET_CRYPTO_Quality mode, void *buffer, size_
*/
uint32_t
GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode,
- uint32_t i)
+ uint32_t i)
{
#ifdef gcry_fast_random_poll
static unsigned int invokeCount;
@@ -202,7 +232,7 @@ GNUNET_CRYPTO_random_u32 (enum GNUNET_CRYPTO_Quality mode,
*/
unsigned int *
GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode,
- unsigned int n)
+ unsigned int n)
{
unsigned int *ret;
unsigned int i;
@@ -232,7 +262,8 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode,
* @return random 64-bit number
*/
uint64_t
-GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode, uint64_t max)
+GNUNET_CRYPTO_random_u64 (enum GNUNET_CRYPTO_Quality mode,
+ uint64_t max)
{
uint64_t ret;
uint64_t ul;