diff options
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 88 |
2 files changed, 48 insertions, 41 deletions
@@ -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 */ |