}
+/**
+ * Derive an IV from packet information
+ */
+static void
+derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
+ const struct GNUNET_PeerIdentity *identity)
+{
+ static char ctx[] = "initialization vector";
+
+ GNUNET_CRYPTO_aes_derive_iv (iv,
+ skey,
+ &seed,
+ sizeof(seed),
+ &identity->hashPubKey.bits,
+ sizeof(identity->hashPubKey.bits),
+ ctx,
+ sizeof(ctx), NULL);
+}
+
+/**
+ * Derive an IV from pong packet information
+ */
+static void
+derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
+ const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
+ uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
+{
+ static char ctx[] = "pong initialization vector";
+
+ GNUNET_CRYPTO_aes_derive_iv (iv,
+ skey,
+ &seed,
+ sizeof(seed),
+ &identity->hashPubKey.bits,
+ sizeof(identity->hashPubKey.bits),
+ &challenge,
+ sizeof(challenge),
+ ctx,
+ sizeof(ctx), NULL);
+}
+
+
/**
* A preference value for a neighbour was update. Update
* the preference sum accordingly.
*/
static int
do_encrypt (struct Neighbour *n,
- const GNUNET_HashCode * iv,
+ const struct GNUNET_CRYPTO_AesInitializationVector * iv,
const void *in, void *out, size_t size)
{
if (size != (uint16_t) size)
GNUNET_CRYPTO_aes_encrypt (in,
(uint16_t) size,
&n->encrypt_key,
- (const struct
- GNUNET_CRYPTO_AesInitializationVector
- *) iv, out));
+ iv, out));
GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes encrypted"), size, GNUNET_NO);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypted %u bytes for `%4s' using key %u\n",
+ "Encrypted %u bytes for `%4s' using key %u, IV %u\n",
(unsigned int) size,
GNUNET_i2s (&n->peer),
- (unsigned int) n->encrypt_key.crc32);
+ (unsigned int) n->encrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (iv, sizeof(iv)));
#endif
return GNUNET_OK;
}
struct MessageEntry *me;
struct PingMessage pp;
struct PingMessage *pm;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
/* send PING */
pm = (struct PingMessage *) &me[1];
pm->header.size = htons (sizeof (struct PingMessage));
pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
+ pm->iv_seed = htonl (GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ UINT32_MAX));
+ derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
pp.challenge = htonl (n->ping_challenge);
pp.target = n->peer;
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypting `%s' message with challenge %u for `%4s' using key %u.\n",
+ "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
"PING",
(unsigned int) n->ping_challenge,
GNUNET_i2s (&n->peer),
- (unsigned int) n->encrypt_key.crc32);
+ (unsigned int) n->encrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (&iv, sizeof(iv)),
+ pm->iv_seed);
#endif
do_encrypt (n,
- &n->peer.hashPubKey,
+ &iv,
&pp.challenge,
&pm->challenge,
sizeof (struct PingMessage) -
*/
static int
do_decrypt (struct Neighbour *n,
- const GNUNET_HashCode * iv,
+ const struct GNUNET_CRYPTO_AesInitializationVector * iv,
const void *in, void *out, size_t size)
{
if (size != (uint16_t) size)
GNUNET_CRYPTO_aes_decrypt (in,
(uint16_t) size,
&n->decrypt_key,
- (const struct
- GNUNET_CRYPTO_AesInitializationVector *) iv,
+ iv,
out))
{
GNUNET_break (0);
GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes decrypted"), size, GNUNET_NO);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Decrypted %u bytes from `%4s' using key %u\n",
+ "Decrypted %u bytes from `%4s' using key %u, IV %u\n",
(unsigned int) size,
GNUNET_i2s (&n->peer),
- (unsigned int) n->decrypt_key.crc32);
+ (unsigned int) n->decrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (iv, sizeof(*iv)));
#endif
return GNUNET_OK;
}
unsigned int priority;
struct GNUNET_TIME_Absolute deadline;
struct GNUNET_TIME_Relative retry_time;
- GNUNET_HashCode iv;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
{
&ph->sequence_number,
esize - sizeof (GNUNET_HashCode),
&ph->hmac);
- GNUNET_CRYPTO_hash (&ph->iv_seed, sizeof (uint32_t), &iv);
+ derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer);
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Hashed %u bytes of plaintext (`%s') using IV `%d'\n",
struct MessageEntry *me;
struct PingMessage pp;
struct PingMessage *pm;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
{
pm = (struct PingMessage *) &sm[1];
pm->header.size = htons (sizeof (struct PingMessage));
pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
+ pm->iv_seed = htonl (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
+ derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
pp.challenge = htonl (n->ping_challenge);
pp.target = n->peer;
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u.\n",
+ "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
"SET_KEY", "PING",
(unsigned int) n->ping_challenge,
GNUNET_i2s (&n->peer),
- (unsigned int) n->encrypt_key.crc32);
+ (unsigned int) n->encrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (&iv, sizeof(iv)),
+ pm->iv_seed);
#endif
do_encrypt (n,
- &n->peer.hashPubKey,
+ &iv,
&pp.challenge,
&pm->challenge,
sizeof (struct PingMessage) -
struct PongMessage tx;
struct PongMessage *tp;
struct MessageEntry *me;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core service receives `%s' request from `%4s'.\n",
"PING", GNUNET_i2s (&n->peer));
#endif
+ derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
if (GNUNET_OK !=
do_decrypt (n,
- &my_identity.hashPubKey,
+ &iv,
&m->challenge,
&t.challenge,
sizeof (struct PingMessage) -
return;
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
+ "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u, IV %u (salt %u)\n",
"PING",
GNUNET_i2s (&t.target),
(unsigned int) ntohl (t.challenge),
- (unsigned int) n->decrypt_key.crc32);
+ (unsigned int) n->decrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (&iv, sizeof(iv)),
+ m->iv_seed);
#endif
GNUNET_STATISTICS_update (stats,
gettext_noop ("# PING messages decrypted"),
tp = (struct PongMessage *) &me[1];
tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
tp->header.size = htons (sizeof (struct PongMessage));
+ tp->iv_seed = htonl (GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
+ derive_pong_iv (&iv, &n->encrypt_key, tp->iv_seed, t.challenge, &n->peer);
do_encrypt (n,
- &my_identity.hashPubKey,
+ &iv,
&tx.challenge,
&tp->challenge,
sizeof (struct PongMessage) -
GNUNET_NO);
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Encrypting `%s' with challenge %u using key %u\n",
+ "Encrypting `%s' with challenge %u using key %u, IV %u (salt %u)\n",
"PONG",
(unsigned int) ntohl (t.challenge),
- (unsigned int) n->encrypt_key.crc32);
+ (unsigned int) n->encrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (&iv, sizeof(iv)),
+ tp->iv_seed);
#endif
/* trigger queue processing */
process_encrypted_neighbour_queue (n);
{
struct PongMessage t;
struct ConnectNotifyMessage cnm;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
#endif
/* mark as garbage, just to be sure */
memset (&t, 255, sizeof (t));
+ derive_pong_iv (&iv, &n->decrypt_key, m->iv_seed, htonl (n->ping_challenge),
+ &my_identity);
if (GNUNET_OK !=
do_decrypt (n,
- &n->peer.hashPubKey,
+ &iv,
&m->challenge,
&t.challenge,
sizeof (struct PongMessage) -
gettext_noop ("# PONG messages decrypted"),
1,
GNUNET_NO);
- if (0 != ntohl (t.reserved))
- {
- GNUNET_break_op (0);
- return;
- }
#if DEBUG_HANDSHAKE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
+ "Decrypted `%s' from `%4s' with challenge %u using key %u, IV %u (salt %u)\n",
"PONG",
GNUNET_i2s (&t.target),
(unsigned int) ntohl (t.challenge),
- (unsigned int) n->decrypt_key.crc32);
+ (unsigned int) n->decrypt_key.crc32,
+ GNUNET_CRYPTO_crc32_n (&iv, sizeof(iv)),
+ m->iv_seed);
#endif
+ if (0 != ntohl (t.reserved))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
if ((0 != memcmp (&t.target,
&n->peer,
sizeof (struct GNUNET_PeerIdentity))) ||
1,
GNUNET_NO);
n->decrypt_key = k;
+ derive_auth_key(&n->decrypt_auth_key, &n->decrypt_key, t, &my_identity);
if (n->decrypt_key_created.value != t.value)
{
/* fresh key, reset sequence numbers */
GNUNET_HashCode ph;
uint32_t snum;
struct GNUNET_TIME_Absolute t;
- GNUNET_HashCode iv;
+ struct GNUNET_CRYPTO_AesInitializationVector iv;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core service receives `%s' request from `%4s'.\n",
"ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
#endif
- GNUNET_CRYPTO_hash (&m->iv_seed, sizeof (uint32_t), &iv);
+ derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
/* decrypt */
if (GNUNET_OK !=
do_decrypt (n,