aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2015-10-02 03:37:52 +0000
committerBart Polot <bart@net.in.tum.de>2015-10-02 03:37:52 +0000
commita101e9b37474e82102637b09de03c5d602201983 (patch)
tree46e33de632aafc73d7c3b5fc30f64ecf55e5e2b6 /src/cadet
parentcef0009520797f29eefb74e68a0020e4cdb3d5a8 (diff)
downloadgnunet-a101e9b37474e82102637b09de03c5d602201983.tar.gz
gnunet-a101e9b37474e82102637b09de03c5d602201983.zip
Fix try_old_keys, in order to use it for data with the same Header key but out-of-order message number
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/cadet_protocol.h4
-rw-r--r--src/cadet/gnunet-service-cadet_tunnel.c92
2 files changed, 70 insertions, 26 deletions
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h
index 0e0030986..cba574c08 100644
--- a/src/cadet/cadet_protocol.h
+++ b/src/cadet/cadet_protocol.h
@@ -319,6 +319,8 @@ struct GNUNET_CADET_AX
319 */ 319 */
320 struct GNUNET_CADET_Hash hmac; 320 struct GNUNET_CADET_Hash hmac;
321 321
322 /**************** AX_HEADER start ****************/
323
322 /** 324 /**
323 * Number of messages sent with the current ratchet key. 325 * Number of messages sent with the current ratchet key.
324 */ 326 */
@@ -334,6 +336,8 @@ struct GNUNET_CADET_AX
334 */ 336 */
335 struct GNUNET_CRYPTO_EcdhePublicKey DHRs; 337 struct GNUNET_CRYPTO_EcdhePublicKey DHRs;
336 338
339 /**************** AX_HEADER end ****************/
340
337 /** 341 /**
338 * Encrypted content follows. 342 * Encrypted content follows.
339 */ 343 */
diff --git a/src/cadet/gnunet-service-cadet_tunnel.c b/src/cadet/gnunet-service-cadet_tunnel.c
index be99f4b47..67f770246 100644
--- a/src/cadet/gnunet-service-cadet_tunnel.c
+++ b/src/cadet/gnunet-service-cadet_tunnel.c
@@ -188,6 +188,11 @@ struct CadetTunnelSkippedKey
188 * Message key. 188 * Message key.
189 */ 189 */
190 struct GNUNET_CRYPTO_SymmetricSessionKey MK; 190 struct GNUNET_CRYPTO_SymmetricSessionKey MK;
191
192 /**
193 * Key number for a given HK.
194 */
195 unsigned int Kn;
191}; 196};
192 197
193 198
@@ -1325,38 +1330,60 @@ t_decrypt_and_validate (struct CadetTunnel *t,
1325 * @return Size of the decrypted data, -1 if an error was encountered. 1330 * @return Size of the decrypted data, -1 if an error was encountered.
1326 */ 1331 */
1327static int 1332static int
1328try_old_ax_keys (struct CadetTunnel *t, struct GNUNET_CADET_AX *dst, 1333try_old_ax_keys (struct CadetTunnel *t, void *dst,
1329 const struct GNUNET_CADET_AX *src, size_t size) 1334 const struct GNUNET_CADET_AX *src, size_t size)
1330{ 1335{
1331 struct CadetTunnelSkippedKey *key; 1336 struct CadetTunnelSkippedKey *key;
1332 struct GNUNET_CADET_Hash hmac; 1337 struct GNUNET_CADET_Hash *hmac;
1333 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1338 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1339 struct GNUNET_CADET_AX plaintext_header;
1340 size_t esize;
1334 size_t res; 1341 size_t res;
1335 size_t len; 1342 size_t len;
1336 1343
1337 1344 hmac = &plaintext_header.hmac;
1345 esize = size - sizeof (struct GNUNET_CADET_AX);
1338 for (key = t->ax->skipped_head; NULL != key; key = key->next) 1346 for (key = t->ax->skipped_head; NULL != key; key = key->next)
1339 { 1347 {
1340 t_hmac (&src->Ns, AX_HEADER_SIZE, 0, &key->HK, &hmac); 1348 t_hmac (&src->Ns, AX_HEADER_SIZE + esize, 0, &key->HK, hmac);
1341 if (0 != memcmp (&hmac, &src->hmac, sizeof (hmac))) 1349 if (0 == memcmp (hmac, &src->hmac, sizeof (*hmac)))
1350 {
1342 break; 1351 break;
1352 }
1343 } 1353 }
1344 if (NULL == key) 1354 if (NULL == key)
1345 return -1; 1355 return -1;
1346 1356
1347 #if DUMP_KEYS_TO_STDERR 1357 #if DUMP_KEYS_TO_STDERR
1348 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with skipped key %s\n", 1358 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC_H with skipped key %s\n",
1349 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK)); 1359 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->HK));
1360 LOG (GNUNET_ERROR_TYPE_INFO, " AX_DEC with skipped key %u: %s\n",
1361 key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK));
1350 #endif 1362 #endif
1351 1363
1364 /* Should've been checked in -cadet_connection.c handle_cadet_encrypted. */
1352 GNUNET_assert (size > sizeof (struct GNUNET_CADET_AX)); 1365 GNUNET_assert (size > sizeof (struct GNUNET_CADET_AX));
1353 len = size - sizeof (struct GNUNET_CADET_AX); 1366 len = size - sizeof (struct GNUNET_CADET_AX);
1367 GNUNET_assert (len >= sizeof (struct GNUNET_MessageHeader));
1368
1369 /* Decrypt header */
1370 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->HK, NULL, 0, NULL);
1371 res = GNUNET_CRYPTO_symmetric_decrypt (&src->Ns, AX_HEADER_SIZE,
1372 &key->HK, &iv, &plaintext_header.Ns);
1373 GNUNET_assert (AX_HEADER_SIZE == res);
1374 LOG (GNUNET_ERROR_TYPE_INFO, " Message %u, previous: %u\n",
1375 ntohl (plaintext_header.Ns), ntohl (plaintext_header.PNs));
1376
1377 // FIXME find correct key
1378
1379 /* Decrypt payload */
1354 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->MK, NULL, 0, NULL); 1380 GNUNET_CRYPTO_symmetric_derive_iv (&iv, &key->MK, NULL, 0, NULL);
1355 res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], len, &key->MK, &iv, &dst[1]); 1381 res = GNUNET_CRYPTO_symmetric_decrypt (&src[1], len, &key->MK, &iv, dst);
1356 1382
1383 /* Remove key */
1357 GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key); 1384 GNUNET_CONTAINER_DLL_remove (t->ax->skipped_head, t->ax->skipped_tail, key);
1358 t->ax->skipped--; 1385 t->ax->skipped--;
1359 GNUNET_free (key); 1386 GNUNET_free (key); /* GNUNET_free overwrites memory with 0xbaadf00d */
1360 1387
1361 return res; 1388 return res;
1362} 1389}
@@ -1376,11 +1403,12 @@ store_skipped_key (struct CadetTunnel *t,
1376 1403
1377 key = GNUNET_new (struct CadetTunnelSkippedKey); 1404 key = GNUNET_new (struct CadetTunnelSkippedKey);
1378 key->timestamp = GNUNET_TIME_absolute_get (); 1405 key->timestamp = GNUNET_TIME_absolute_get ();
1406 key->Kn = t->ax->Nr;
1379 key->HK = t->ax->HKr; 1407 key->HK = t->ax->HKr;
1380 t_hmac_derive_key (&t->ax->CKr, &key->MK, "0", 1); 1408 t_hmac_derive_key (&t->ax->CKr, &key->MK, "0", 1);
1381 #if DUMP_KEYS_TO_STDERR 1409 #if DUMP_KEYS_TO_STDERR
1382 LOG (GNUNET_ERROR_TYPE_INFO, " storing MK for Nr %u: %s\n", 1410 LOG (GNUNET_ERROR_TYPE_INFO, " storing MK for Nr %u: %s\n",
1383 t->ax->Nr, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK)); 1411 key->Kn, GNUNET_i2s ((struct GNUNET_PeerIdentity *) &key->MK));
1384 LOG (GNUNET_ERROR_TYPE_INFO, " for CKr: %s\n", 1412 LOG (GNUNET_ERROR_TYPE_INFO, " for CKr: %s\n",
1385 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &t->ax->CKr)); 1413 GNUNET_i2s ((struct GNUNET_PeerIdentity *) &t->ax->CKr));
1386 #endif 1414 #endif
@@ -1414,23 +1442,32 @@ delete_skipped_key (struct CadetTunnel *t, struct CadetTunnelSkippedKey *key)
1414 * @param t Tunnel where to stage the keys. 1442 * @param t Tunnel where to stage the keys.
1415 * @param HKr Header key. 1443 * @param HKr Header key.
1416 * @param Np Received meesage number. 1444 * @param Np Received meesage number.
1445 *
1446 * @return GNUNET_OK if keys were stored.
1447 * GNUNET_SYSERR if an error ocurred (Np not expected).
1417 */ 1448 */
1418static void 1449static int
1419store_ax_keys (struct CadetTunnel *t, 1450store_ax_keys (struct CadetTunnel *t,
1420 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr, 1451 const struct GNUNET_CRYPTO_SymmetricSessionKey *HKr,
1421 uint32_t Np) 1452 uint32_t Np)
1422{ 1453{
1423 int gap; 1454 int gap;
1424 1455
1456
1425 gap = Np - t->ax->Nr; 1457 gap = Np - t->ax->Nr;
1426 if (MAX_KEY_GAP < gap || 0 > gap) 1458 if (MAX_KEY_GAP < gap)
1427 { 1459 {
1428 /* Avoid DoS (forcing peer to do 2*33 chain HMAC operations) */ 1460 /* Avoid DoS (forcing peer to do 2*33 chain HMAC operations) */
1429 /* TODO: start new key exchange on return */ 1461 /* TODO: start new key exchange on return */
1430 GNUNET_break_op (0); 1462 GNUNET_break_op (0);
1431 LOG (GNUNET_ERROR_TYPE_WARNING, "Got message %u, expected %u+\n", 1463 LOG (GNUNET_ERROR_TYPE_WARNING, "Got message %u, expected %u+\n",
1432 Np, t->ax->Nr); 1464 Np, t->ax->Nr);
1433 return; 1465 return GNUNET_SYSERR;
1466 }
1467 if (0 > gap)
1468 {
1469 /* Delayed message: don't store keys, flag to try old keys. */
1470 return GNUNET_SYSERR;
1434 } 1471 }
1435 1472
1436 while (t->ax->Nr < Np) 1473 while (t->ax->Nr < Np)
@@ -1438,6 +1475,8 @@ store_ax_keys (struct CadetTunnel *t,
1438 1475
1439 while (t->ax->skipped > MAX_SKIPPED_KEYS) 1476 while (t->ax->skipped > MAX_SKIPPED_KEYS)
1440 delete_skipped_key (t, t->ax->skipped_tail); 1477 delete_skipped_key (t, t->ax->skipped_tail);
1478
1479 return GNUNET_OK;
1441} 1480}
1442 1481
1443 1482
@@ -1459,14 +1498,13 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, void *dst,
1459 struct CadetTunnelAxolotl *ax; 1498 struct CadetTunnelAxolotl *ax;
1460 struct GNUNET_CADET_Hash msg_hmac; 1499 struct GNUNET_CADET_Hash msg_hmac;
1461 struct GNUNET_HashCode hmac; 1500 struct GNUNET_HashCode hmac;
1462 struct GNUNET_CADET_AX *dstmsg; 1501 struct GNUNET_CADET_AX plaintext_header;
1463 uint32_t Np; 1502 uint32_t Np;
1464 uint32_t PNp; 1503 uint32_t PNp;
1465 size_t esize; 1504 size_t esize;
1466 size_t osize; 1505 size_t osize;
1467 1506
1468 ax = t->ax; 1507 ax = t->ax;
1469 dstmsg = dst;
1470 esize = size - sizeof (struct GNUNET_CADET_AX); 1508 esize = size - sizeof (struct GNUNET_CADET_AX);
1471 1509
1472 if (NULL == ax) 1510 if (NULL == ax)
@@ -1489,14 +1527,14 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, void *dst,
1489 /* Try the skipped keys, if that fails, we're out of luck. */ 1527 /* Try the skipped keys, if that fails, we're out of luck. */
1490 return try_old_ax_keys (t, dst, src, size); 1528 return try_old_ax_keys (t, dst, src, size);
1491 } 1529 }
1492 LOG (GNUNET_ERROR_TYPE_INFO, "next HK\n"); 1530 LOG (GNUNET_ERROR_TYPE_INFO, "next HK worked\n");
1493 1531
1494 HK = ax->HKr; 1532 HK = ax->HKr;
1495 ax->HKr = ax->NHKr; 1533 ax->HKr = ax->NHKr;
1496 t_h_decrypt (t, src, dstmsg); 1534 t_h_decrypt (t, src, &plaintext_header);
1497 Np = ntohl (dstmsg->Ns); 1535 Np = ntohl (plaintext_header.Ns);
1498 PNp = ntohl (dstmsg->PNs); 1536 PNp = ntohl (plaintext_header.PNs);
1499 DHRp = &dstmsg->DHRs; 1537 DHRp = &plaintext_header.DHRs;
1500 store_ax_keys (t, &HK, PNp); 1538 store_ax_keys (t, &HK, PNp);
1501 1539
1502 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */ 1540 /* RKp, NHKp, CKp = KDF (HMAC-HASH (RK, DH (DHRp, DHRs))) */
@@ -1516,13 +1554,15 @@ t_ax_decrypt_and_validate (struct CadetTunnel *t, void *dst,
1516 else 1554 else
1517 { 1555 {
1518 LOG (GNUNET_ERROR_TYPE_DEBUG, "current HK\n"); 1556 LOG (GNUNET_ERROR_TYPE_DEBUG, "current HK\n");
1519 t_h_decrypt (t, src, dstmsg); 1557 t_h_decrypt (t, src, &plaintext_header);
1520 Np = ntohl (dstmsg->Ns); 1558 Np = ntohl (plaintext_header.Ns);
1521 PNp = ntohl (dstmsg->PNs); 1559 PNp = ntohl (plaintext_header.PNs);
1522 } 1560 }
1523 1561 LOG (GNUNET_ERROR_TYPE_INFO, " got AX Nr %u\n", Np);
1524 if (Np > ax->Nr) 1562 if (Np != ax->Nr)
1525 store_ax_keys (t, &ax->HKr, Np); 1563 if (GNUNET_OK != store_ax_keys (t, &ax->HKr, Np))
1564 /* Try the skipped keys, if that fails, we're out of luck. */
1565 return try_old_ax_keys (t, dst, src, size);
1526 1566
1527 osize = t_ax_decrypt (t, dst, &src[1], esize); 1567 osize = t_ax_decrypt (t, dst, &src[1], esize);
1528 ax->Nr = Np + 1; 1568 ax->Nr = Np + 1;