Cleanup crypto comments
Some checks failed
Build Linux Binaries / linux/amd64 (push) Has been cancelled
Build Linux Binaries / linux/arm64 (push) Has been cancelled

This commit is contained in:
2026-07-03 15:37:39 +01:00
parent 826b3bfb86
commit 158a2df062
3 changed files with 18 additions and 20 deletions

View File

@@ -12,7 +12,6 @@
namespace voicecat::crypto {
// ── Helpers ───────────────────────────────────────────────────────────────────
static void throw_if(int rc, const char* msg) {
if (rc != 0) {
@@ -35,7 +34,7 @@ static std::string compute_hex_fingerprint(const uint8_t* data, size_t len) {
return s;
}
// ── ServerIdentity ────────────────────────────────────────────────────────────
// ServerIdentity
ServerIdentity ServerIdentity::generate() {
ServerIdentity id;
@@ -75,7 +74,7 @@ std::string ServerIdentity::fingerprint_hex() const {
return s;
}
// ── ServerCert ────────────────────────────────────────────────────────────────
// ServerCert
ServerCert ServerCert::generate(const std::string& server_name) {
mbedtls_entropy_context entropy;
@@ -171,7 +170,7 @@ void ServerCert::save(const std::filesystem::path& cert_path,
write_file(key_path, pem_key);
}
// ── TlsContext ────────────────────────────────────────────────────────────────
// TlsContext
TlsContext::TlsContext(Role role, const ServerCert* server_cert,
const std::array<uint8_t, 32>* pinned_fp)
@@ -217,7 +216,7 @@ TlsContext::TlsContext(Role role, const ServerCert* server_cert,
}
if (role == Role::Client) {
// Skip CA chain verification we use TOFU via the server identity fingerprint.
// Skip CA chain verification, we use TOFU via the server identity fingerprint.
mbedtls_ssl_conf_authmode(&conf_, MBEDTLS_SSL_VERIFY_NONE);
}
@@ -284,7 +283,7 @@ bool TlsContext::peer_cert_fingerprint(std::array<uint8_t, 32>& out) const {
return true;
}
// ── SodiumMediaCrypto ─────────────────────────────────────────────────────────
// SodiumMediaCrypto
SodiumMediaCrypto::SodiumMediaCrypto(
const uint8_t key[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) {
@@ -347,8 +346,7 @@ long SodiumMediaCrypto::open(const uint8_t* sealed, size_t len, const uint8_t* a
if (out_cap < len - crypto_aead_chacha20poly1305_ietf_ABYTES) return -1;
// Read the full 64-bit nonce counter directly from aad[8..15] (seq, big-endian
// u64). Protocol v2 carries the full counter on the wire, so the nonce is exact —
// no reconstruction/rollover guessing needed.
// u64).
if (aad_len < 16) return -1;
uint64_t counter = (static_cast<uint64_t>(aad[8]) << 56) |
(static_cast<uint64_t>(aad[9]) << 48) |
@@ -364,7 +362,7 @@ long SodiumMediaCrypto::open(const uint8_t* sealed, size_t len, const uint8_t* a
// window before the AEAD tag is verified — otherwise a single corrupted/forged
// packet would shove recv_highest_ far ahead and reject every later legitimate
// packet as "too old", permanently wedging the stream. Order per RFC 3711 §3.3:
// replay-check authenticate update.
// replay-check authenticate update.
if (recv_initialized_ && counter <= recv_highest_) {
uint64_t offset = recv_highest_ - counter;
if (offset >= 64) return -1; // too old
@@ -381,7 +379,7 @@ long SodiumMediaCrypto::open(const uint8_t* sealed, size_t len, const uint8_t* a
nonce, key_.data()) != 0)
return -1; // auth failure — leave the replay window untouched
// ── Authenticated: now it's safe to advance the window ────────────────────
// Authenticated: now it's safe to advance the window ────────────────────
if (!recv_initialized_) {
recv_highest_ = counter;
recv_window_ = 1; // bit0 = highest itself

View File

@@ -1,7 +1,7 @@
/*
* crypto/crypto.h TLS 1.3 (mbedTLS) and the media AEAD (libsodium).
* crypto/crypto.h: TLS 1.3 (mbedTLS) and the media AEAD (libsodium).
*
* Design: docs/security.md. Control channel = TLS 1.3. Media = keys exported from the TLS
*Control channel = TLS 1.3. Media = keys exported from the TLS
* session (RFC 5705 / 8446) + per-frame ChaCha20-Poly1305 with a counter nonce and a
* sliding-window replay filter. Encryption is MANDATORY — never add a plaintext path.
*/
@@ -30,7 +30,7 @@
namespace voicecat::crypto {
// ── Server identity ────────────────────────────────────────────────────────────
// Server identity
// Long-lived Ed25519 key identifying this server instance across cert rotations.
// Fingerprint is the 32-byte SHA-256 of the public key.
struct ServerIdentity {
@@ -44,7 +44,7 @@ struct ServerIdentity {
std::string fingerprint_hex() const;
};
// ── Server TLS certificate ─────────────────────────────────────────────────────
// Server TLS certificate
// Self-signed ECDSA-P256 cert for TLS. On first run, generated and persisted.
struct ServerCert {
std::string pem_cert;
@@ -57,7 +57,7 @@ struct ServerCert {
const std::filesystem::path& key_path) const;
};
// ── TLS 1.3 context ───────────────────────────────────────────────────────────
// TLS 1.3 context
// Wraps mbedTLS for one TLS connection (server or client side).
// All public methods must be called from a single thread at a time.
class TlsContext {
@@ -119,7 +119,7 @@ class TlsContext {
mbedtls_net_context net_ctx_{};
};
// ── Media AEAD ─────────────────────────────────────────────────────────────────
// Media AEAD
// Per-frame voice encryption. Abstracted so the backend is swappable.
class MediaCrypto {
public:
@@ -135,7 +135,7 @@ class MediaCrypto {
uint8_t* out, size_t out_cap) = 0;
};
// ── ChaCha20-Poly1305 backend ──────────────────────────────────────────────────
// ChaCha20-Poly1305 backend
// Keys are derived from the TLS session via RFC 5705 / mbedTLS exporter.
// Nonce scheme: 4 zero bytes ‖ monotonic-counter(u64 big-endian, 8 bytes).
// Anti-replay: 64-bit sliding window keyed on the received counter.
@@ -145,10 +145,10 @@ class SodiumMediaCrypto final : public MediaCrypto {
static std::unique_ptr<SodiumMediaCrypto> derive(TlsContext& tls, uint8_t ctx_byte);
// Convenience: derive the key used to encrypt outgoing frames.
// is_client=true ctx=0x00 (client sends); is_client=false ctx=0x01 (server sends).
// is_client=true ctx=0x00 (client sends); is_client=false ctx=0x01 (server sends).
static std::unique_ptr<SodiumMediaCrypto> derive_send(TlsContext& tls, bool is_client);
// Convenience: derive the key used to decrypt incoming frames.
// is_client=true ctx=0x01 (client recvs); is_client=false ctx=0x00 (server recvs).
// is_client=true ctx=0x01 (client recvs); is_client=false ctx=0x00 (server recvs).
static std::unique_ptr<SodiumMediaCrypto> derive_recv(TlsContext& tls, bool is_client);
// Unit-test constructor: supply a raw 32-byte key directly.

View File

@@ -1,5 +1,5 @@
/*
* crypto/tofu_store.h Trust-On-First-Use pin storage.
* crypto/tofu_store.h: Trust-On-First-Use pin storage.
*
* File format: one "host:port <hex-fingerprint>\n" line per entry.
* Used by clients to remember server fingerprints across reconnects.