fix: Additional WireGuard bugs
Bug 3: wg_hkdf_3 implementation - Added proper T(3) = HMAC(PRK, T(2) || 0x03) Bug 4: Nonce construction - verified correct - Encrypt: memcpy(nonce_buf + 4, header + 8, 8) ✓ - Decrypt: memcpy(nonce_buf + 4, packet + 8, 8) ✓ - Both use little-endian nonce bytes from header[8..15] Bug 5: Replay detection logic - Fixed: if (session->packets_received > 0 && nonce <= session->receiving_nonce) - Added packets_received counter to session struct - Now strictly rejects any nonce <= last received nonce Test results: 29 passed, 3 failed Remaining failures in packet encryption/decryption need further investigation.
This commit is contained in:
+27
-3
@@ -89,6 +89,30 @@ static void wg_hkdf_1(const uint8_t *prk, size_t prk_len,
|
||||
wg_hkdf_expand(prk, prk_len, out1, out2);
|
||||
}
|
||||
|
||||
/* Compute HKDF-3 (three outputs) - WireGuard style */
|
||||
static void wg_hkdf_3(const uint8_t *prk, size_t prk_len,
|
||||
uint8_t *out1, uint8_t *out2, uint8_t *out3)
|
||||
{
|
||||
/* T(1) = HMAC(PRK, 0x01) */
|
||||
uint8_t c1 = 0x01;
|
||||
se050_hmac_blake2s(out1, prk, prk_len, &c1, 1);
|
||||
|
||||
/* T(2) = HMAC(PRK, T(1) || 0x02) */
|
||||
uint8_t t2_input[33];
|
||||
memcpy(t2_input, out1, 32);
|
||||
t2_input[32] = 0x02;
|
||||
se050_hmac_blake2s(out2, prk, prk_len, t2_input, 33);
|
||||
|
||||
/* T(3) = HMAC(PRK, T(2) || 0x03) */
|
||||
uint8_t t3_input[33];
|
||||
memcpy(t3_input, out2, 32);
|
||||
t3_input[32] = 0x03;
|
||||
se050_hmac_blake2s(out3, prk, prk_len, t3_input, 33);
|
||||
|
||||
memzero_explicit(t2_input, 33);
|
||||
memzero_explicit(t3_input, 33);
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Session Management
|
||||
* ========================================================================= */
|
||||
@@ -273,9 +297,8 @@ int se050_wireguard_decrypt_packet(se050_wireguard_session_t *session,
|
||||
nonce |= ((uint64_t)packet[8 + i]) << (8 * i);
|
||||
}
|
||||
|
||||
/* Check replay (simple check - should use window in production) */
|
||||
/* Allow nonce == receiving_nonce for first packet (both start at 0) */
|
||||
if (nonce <= session->receiving_nonce && session->receiving_nonce != 0) {
|
||||
/* Check replay - strictly reject nonce <= last received nonce */
|
||||
if (session->packets_received > 0 && nonce <= session->receiving_nonce) {
|
||||
return -1; /* Replay detected */
|
||||
}
|
||||
|
||||
@@ -310,6 +333,7 @@ int se050_wireguard_decrypt_packet(se050_wireguard_session_t *session,
|
||||
/* Update plaintext length and nonce */
|
||||
*plaintext_len = ciphertext_len;
|
||||
session->receiving_nonce = nonce;
|
||||
session->packets_received++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user