aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Durner <durner@gnunet.org>2010-10-05 17:50:55 +0000
committerNils Durner <durner@gnunet.org>2010-10-05 17:50:55 +0000
commit273e959d9136d601c898fb29833e367e994f280c (patch)
treef87f07d6ca6cd039c9e5ac48b50b1841358917b7
parenta64be7c7ae18efb4214e7335e39cf90348d1039f (diff)
downloadgnunet-273e959d9136d601c898fb29833e367e994f280c.tar.gz
gnunet-273e959d9136d601c898fb29833e367e994f280c.zip
authentication of ciphertexts (+ seed)
-rw-r--r--TODO1
-rw-r--r--src/core/gnunet-service-core.c88
2 files changed, 48 insertions, 41 deletions
diff --git a/TODO b/TODO
index be292e2bf..9da60b063 100644
--- a/TODO
+++ b/TODO
@@ -8,7 +8,6 @@
8 - track paths content travels (PUT, reply-to-get) in messages, 8 - track paths content travels (PUT, reply-to-get) in messages,
9 pass to client (client API & protocol already support this!) 9 pass to client (client API & protocol already support this!)
10* CORE: 10* CORE:
11 - authentication of ciphertexts [Nils]
12 - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616. 11 - Jun 27 11:51:54 core-7670 ERROR Assertion failed at gnunet-service-core.c:3616.
13 (transport notified us that we connected to ourselves!!!) 12 (transport notified us that we connected to ourselves!!!)
14 - transport-level disconnect (i.e. TCP) does not cause core-level 13 - transport-level disconnect (i.e. TCP) does not cause core-level
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 00a18677d..d74925fae 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -161,13 +161,6 @@ enum PeerStateMachine
161 161
162 162
163/** 163/**
164 * Number of bytes (at the beginning) of "struct EncryptedMessage"
165 * that are NOT encrypted.
166 */
167#define ENCRYPTED_HEADER_SIZE (sizeof(struct GNUNET_MessageHeader) + sizeof(uint32_t))
168
169
170/**
171 * Encapsulation for encrypted messages exchanged between 164 * Encapsulation for encrypted messages exchanged between
172 * peers. Followed by the actual encrypted data. 165 * peers. Followed by the actual encrypted data.
173 */ 166 */
@@ -179,22 +172,23 @@ struct EncryptedMessage
179 struct GNUNET_MessageHeader header; 172 struct GNUNET_MessageHeader header;
180 173
181 /** 174 /**
182 * Random value used for IV generation. ENCRYPTED_HEADER_SIZE must 175 * MAC of the (partially) encrypted message (starting at 'iv_seed'),
183 * be set to the offset of the *next* field. 176 * used to verify message integrity. Everything after this value
177 * will be authenticated. AUTHENTICATED_HEADER_SIZE must be set to
178 * the offset of the *next* field.
184 */ 179 */
185 uint32_t iv_seed GNUNET_PACKED; 180 GNUNET_HashCode hmac;
186 181
187 /** 182 /**
188 * Hash of the plaintext (starting at 'sequence_number'), used to 183 * Random value used for IV generation. Everything after this value
189 * verify message integrity. Everything after this hash (including 184 * (excluding this value itself) will be encrypted.
190 * this hash itself) will be encrypted. 185 * ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field.
191 */ 186 */
192 GNUNET_HashCode hmac; 187 uint32_t iv_seed GNUNET_PACKED;
193 188
194 /** 189 /**
195 * Sequence number, in network byte order. This field 190 * Sequence number, in network byte order. This field
196 * must be the first encrypted/decrypted field and the 191 * must be the first encrypted/decrypted field
197 * first byte that is hashed for the plaintext hash.
198 */ 192 */
199 uint32_t sequence_number GNUNET_PACKED; 193 uint32_t sequence_number GNUNET_PACKED;
200 194
@@ -214,6 +208,20 @@ struct EncryptedMessage
214 208
215 209
216/** 210/**
211 * Number of bytes (at the beginning) of "struct EncryptedMessage"
212 * that are NOT encrypted.
213 */
214#define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
215
216
217/**
218 * Number of bytes (at the beginning) of "struct EncryptedMessage"
219 * that are NOT authenticated.
220 */
221#define AUTHENTICATED_HEADER_SIZE (offsetof(struct EncryptedMessage, iv_seed))
222
223
224/**
217 * We're sending an (encrypted) PING to the other peer to check if he 225 * We're sending an (encrypted) PING to the other peer to check if he
218 * can decrypt. The other peer should respond with a PONG with the 226 * can decrypt. The other peer should respond with a PONG with the
219 * same content, except this time encrypted with the receiver's key. 227 * same content, except this time encrypted with the receiver's key.
@@ -2089,7 +2097,6 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
2089{ 2097{
2090 char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)]; /* plaintext */ 2098 char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)]; /* plaintext */
2091 size_t used; 2099 size_t used;
2092 size_t esize;
2093 struct EncryptedMessage *em; /* encrypted message */ 2100 struct EncryptedMessage *em; /* encrypted message */
2094 struct EncryptedMessage *ph; /* plaintext header */ 2101 struct EncryptedMessage *ph; /* plaintext header */
2095 struct MessageEntry *me; 2102 struct MessageEntry *me;
@@ -2203,32 +2210,32 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
2203 em->header.size = htons (used); 2210 em->header.size = htons (used);
2204 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE); 2211 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
2205 em->iv_seed = ph->iv_seed; 2212 em->iv_seed = ph->iv_seed;
2206 esize = used - ENCRYPTED_HEADER_SIZE;
2207 GNUNET_CRYPTO_hmac (&n->encrypt_auth_key,
2208 &ph->sequence_number,
2209 esize - sizeof (GNUNET_HashCode),
2210 &ph->hmac);
2211 derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer); 2213 derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer);
2212#if DEBUG_HANDSHAKE
2213 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2214 "Hashed %u bytes of plaintext (`%s') using IV `%d'\n",
2215 (unsigned int) (esize - sizeof (GNUNET_HashCode)),
2216 GNUNET_h2s (&ph->hmac),
2217 (int) ph->iv_seed);
2218#endif
2219 /* encrypt */ 2214 /* encrypt */
2220#if DEBUG_HANDSHAKE 2215#if DEBUG_HANDSHAKE
2221 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2222 "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n", 2217 "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n",
2223 (unsigned int) esize, 2218 (unsigned int) used - ENCRYPTED_HEADER_SIZE,
2224 GNUNET_i2s(&n->peer), 2219 GNUNET_i2s(&n->peer),
2225 (unsigned long long) GNUNET_TIME_absolute_get_remaining (deadline).value); 2220 (unsigned long long) GNUNET_TIME_absolute_get_remaining (deadline).value);
2226#endif 2221#endif
2227 GNUNET_assert (GNUNET_OK == 2222 GNUNET_assert (GNUNET_OK ==
2228 do_encrypt (n, 2223 do_encrypt (n,
2229 &iv, 2224 &iv,
2230 &ph->hmac, 2225 &ph->sequence_number,
2231 &em->hmac, esize)); 2226 &em->sequence_number, used - ENCRYPTED_HEADER_SIZE));
2227 GNUNET_CRYPTO_hmac (&n->encrypt_auth_key,
2228 &em->iv_seed,
2229 used - AUTHENTICATED_HEADER_SIZE,
2230 &em->hmac);
2231#if DEBUG_HANDSHAKE
2232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2233 "Authenticated %u bytes of ciphertext %u: `%s'\n",
2234 used - AUTHENTICATED_HEADER_SIZE,
2235 GNUNET_CRYPTO_crc32_n (&em->iv_seed,
2236 used - AUTHENTICATED_HEADER_SIZE),
2237 GNUNET_h2s (&em->hmac));
2238#endif
2232 /* append to transmission list */ 2239 /* append to transmission list */
2233 GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, 2240 GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head,
2234 n->encrypted_tail, 2241 n->encrypted_tail,
@@ -3453,24 +3460,25 @@ handle_encrypted_message (struct Neighbour *n,
3453 if (GNUNET_OK != 3460 if (GNUNET_OK !=
3454 do_decrypt (n, 3461 do_decrypt (n,
3455 &iv, 3462 &iv,
3456 &m->hmac, 3463 &m->sequence_number,
3457 &buf[ENCRYPTED_HEADER_SIZE], 3464 &buf[ENCRYPTED_HEADER_SIZE],
3458 size - ENCRYPTED_HEADER_SIZE)) 3465 size - ENCRYPTED_HEADER_SIZE))
3459 return; 3466 return;
3460 pt = (struct EncryptedMessage *) buf; 3467 pt = (struct EncryptedMessage *) buf;
3461 /* validate hash */ 3468 /* validate hash */
3462 GNUNET_CRYPTO_hmac (&n->decrypt_auth_key, 3469 GNUNET_CRYPTO_hmac (&n->decrypt_auth_key,
3463 &pt->sequence_number, 3470 &m->iv_seed,
3464 size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode), &ph); 3471 size - AUTHENTICATED_HEADER_SIZE, &ph);
3465#if DEBUG_HANDSHAKE 3472#if DEBUG_HANDSHAKE
3466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3467 "V-Hashed %u bytes of plaintext (`%s') using IV `%d'\n", 3474 "Re-Authenticated %u bytes of ciphertext (`%u'): `%s'\n",
3468 (unsigned int) (size - ENCRYPTED_HEADER_SIZE - sizeof (GNUNET_HashCode)), 3475 (unsigned int) size - AUTHENTICATED_HEADER_SIZE,
3469 GNUNET_h2s (&ph), 3476 GNUNET_CRYPTO_crc32_n (&m->iv_seed,
3470 (int) m->iv_seed); 3477 size - AUTHENTICATED_HEADER_SIZE),
3478 GNUNET_h2s (&ph));
3471#endif 3479#endif
3472 if (0 != memcmp (&ph, 3480 if (0 != memcmp (&ph,
3473 &pt->hmac, 3481 &m->hmac,
3474 sizeof (GNUNET_HashCode))) 3482 sizeof (GNUNET_HashCode)))
3475 { 3483 {
3476 /* checksum failed */ 3484 /* checksum failed */