From 84141aa0523f4f6e10b9c5f6472e88870839d310 Mon Sep 17 00:00:00 2001 From: "Craig Edwards (Brain)" Date: Wed, 16 Oct 2024 17:18:44 +0100 Subject: [PATCH] docs: add docblock comments to all libdave class variables (#1286) --- src/dpp/dave/array_view.h | 3 +- src/dpp/dave/cipher_interface.cpp | 3 +- src/dpp/dave/cipher_interface.h | 3 +- src/dpp/dave/clock.h | 3 +- src/dpp/dave/codec_utils.cpp | 12 ++-- src/dpp/dave/codec_utils.h | 4 +- src/dpp/dave/cryptor_manager.h | 33 ++++++++++ src/dpp/dave/decryptor.h | 24 ++++++++ src/dpp/dave/encryptor.cpp | 9 ++- src/dpp/dave/encryptor.h | 60 +++++++++++++++++- src/dpp/dave/frame_processors.cpp | 17 +++--- src/dpp/dave/frame_processors.h | 56 ++++++++++++++++- src/dpp/dave/leb128.cpp | 2 +- src/dpp/dave/parameters.h | 2 +- src/dpp/dave/persisted_key_pair_generic.cpp | 2 +- src/dpp/dave/session.h | 67 +++++++++++++++++++++ src/dpp/voice/enabled/discover_ip.cpp | 6 +- 17 files changed, 270 insertions(+), 36 deletions(-) diff --git a/src/dpp/dave/array_view.h b/src/dpp/dave/array_view.h index b5752e83d7..e1e9c18c80 100755 --- a/src/dpp/dave/array_view.h +++ b/src/dpp/dave/array_view.h @@ -116,5 +116,4 @@ inline array_view make_array_view(std::vector& data) return array_view(data.data(), data.size()); } -} // namespace dpp::dave - +} diff --git a/src/dpp/dave/cipher_interface.cpp b/src/dpp/dave/cipher_interface.cpp index 140debcbc3..58784c51bc 100755 --- a/src/dpp/dave/cipher_interface.cpp +++ b/src/dpp/dave/cipher_interface.cpp @@ -34,5 +34,4 @@ std::unique_ptr create_cipher(dpp::cluster& cl, const encrypti return cipher->is_valid() ? std::move(cipher) : nullptr; } -} // namespace dpp::dave - +} diff --git a/src/dpp/dave/cipher_interface.h b/src/dpp/dave/cipher_interface.h index ea99e0c554..44004883e8 100755 --- a/src/dpp/dave/cipher_interface.h +++ b/src/dpp/dave/cipher_interface.h @@ -99,5 +99,4 @@ class cipher_interface { // NOLINT */ std::unique_ptr create_cipher(dpp::cluster& cl, const encryption_key& key); -} // namespace dpp::dave - +} diff --git a/src/dpp/dave/clock.h b/src/dpp/dave/clock.h index c8a2ab6872..db93afd914 100755 --- a/src/dpp/dave/clock.h +++ b/src/dpp/dave/clock.h @@ -74,5 +74,4 @@ class clock : public clock_interface { } }; -} // namespace dpp::dave - +} diff --git a/src/dpp/dave/codec_utils.cpp b/src/dpp/dave/codec_utils.cpp index 85c8469412..3cae886066 100755 --- a/src/dpp/dave/codec_utils.cpp +++ b/src/dpp/dave/codec_utils.cpp @@ -31,8 +31,7 @@ namespace dpp::dave::codec_utils { -unencrypted_frame_header_size BytesCoveringH264PPS(const uint8_t* payload, const uint64_t size_remaining) -{ +unencrypted_frame_header_size bytes_covering_h264_pps(const uint8_t* payload, const uint64_t size_remaining) { // the payload starts with three exponential golomb encoded values // (first_mb_in_slice, sps_id, pps_id) // the depacketizer needs the pps_id unencrypted @@ -77,7 +76,12 @@ unencrypted_frame_header_size BytesCoveringH264PPS(const uint8_t* payload, const } // return the number of bytes that covers the last exp golomb encoded value - return (payload_bit_index / 8) + 1; + auto result = (payload_bit_index / 8) + 1; + if (result > std::numeric_limits::max()) { + // bytes covering H264 PPS result cannot fit into unencrypted frame header size + return 0; + } + return static_cast(result); } const uint8_t nalu_long_start_code[] = {0, 0, 0, 1}; @@ -208,7 +212,7 @@ bool process_frame_h264(outbound_frame_processor& processor, array_view frame); -} // namespace dpp::dave::codec_utils - - +} diff --git a/src/dpp/dave/cryptor_manager.h b/src/dpp/dave/cryptor_manager.h index 88d2454e4c..731c145234 100755 --- a/src/dpp/dave/cryptor_manager.h +++ b/src/dpp/dave/cryptor_manager.h @@ -149,16 +149,49 @@ class aead_cipher_manager { */ void cleanup_expired_ciphers(); + /** + * @brief chrono clock + */ const clock_interface& current_clock; + + /** + * @brief key ratchet for cryptor + */ std::unique_ptr current_key_ratchet; + + /** + * @brief Cryptor for each generation with expiry + */ std::unordered_map cryptor_generations; + /** + * @brief Time ratchet was created + */ time_point ratchet_creation; + + /** + * @brief Time ratchet expired + */ time_point ratchet_expiry; + + /** + * @brief Oldest generation for ratchet + */ key_generation oldest_generation{0}; + + /** + * @brief Newest generation for ratchet + */ key_generation newest_generation{0}; + /** + * @brief Newest nonce + */ std::optional newest_processed_nonce; + + /** + * @brief List of missing nonces from sequence + */ std::deque missing_nonces; /** diff --git a/src/dpp/dave/decryptor.h b/src/dpp/dave/decryptor.h index bdf7718ee6..e093dc46fb 100755 --- a/src/dpp/dave/decryptor.h +++ b/src/dpp/dave/decryptor.h @@ -177,15 +177,39 @@ class decryptor { */ void return_frame_processor(std::unique_ptr frame_processor); + /** + * @brief Chrono clock + */ clock current_clock; + + /** + * @brief Cryptor manager list + */ std::deque cryptor_managers; + /** + * @brief Mutex for thread safety of frame processor list + */ std::mutex frame_processors_mutex; + + /** + * @brief List of frame processors + */ std::vector> frame_processors; + /** + * @brief Passthrough expiry time + */ time_point allow_pass_through_until{time_point::min()}; + /** + * @brief Last stats generation time + */ time_point last_stats_time{time_point::min()}; + + /** + * @brief Stats for audio and video decryption + */ std::array stats; /** diff --git a/src/dpp/dave/encryptor.cpp b/src/dpp/dave/encryptor.cpp index 716332977b..782d02984a 100755 --- a/src/dpp/dave/encryptor.cpp +++ b/src/dpp/dave/encryptor.cpp @@ -164,7 +164,14 @@ encryptor::result_code encryptor::encrypt(media_type this_media_type, uint32_t s } // write the supplemental bytes size - supplemental_bytes_size supplemental_bytes = SUPPLEMENTAL_BYTES + size + ranges_size; + uint64_t supplemental_bytes_large = SUPPLEMENTAL_BYTES + size + ranges_size; + + if (supplemental_bytes_large > std::numeric_limits::max()) { + result = rc_encryption_failure; + break; + } + + supplemental_bytes_size supplemental_bytes = supplemental_bytes_large; std::memcpy(supplemental_bytes_buffer.data(), &supplemental_bytes, sizeof(supplemental_bytes_size)); // write the marker bytes, ends the frame diff --git a/src/dpp/dave/encryptor.h b/src/dpp/dave/encryptor.h index d5ec5e8c23..6b327c83ff 100755 --- a/src/dpp/dave/encryptor.h +++ b/src/dpp/dave/encryptor.h @@ -77,9 +77,9 @@ struct encryption_stats { class encryptor { public: /** - * @brief Constructor - * @param cl Creator - */ + * @brief Constructor + * @param cl Creator + */ encryptor(dpp::cluster& cl) : creator(cl) { }; /** @@ -219,25 +219,79 @@ class encryptor { */ void update_current_protocol_version(protocol_version version); + /** + * @brief True if passthrough is enabled + */ std::atomic_bool passthrough_mode_enable{false}; + /** + * @brief Key generation mutex for thread safety + */ std::mutex key_gen_mutex; + + /** + * @brief Current encryption (send) ratchet + */ std::unique_ptr ratchet; + + /** + * @brief Current encryption cipher + */ std::shared_ptr cryptor; + + /** + * @brief Current key generation number + */ key_generation current_key_generation{0}; + + /** + * @brief Current truncated sync nonce + */ truncated_sync_nonce truncated_nonce{0}; + /** + * @brief Frame processor list mutex + */ std::mutex frame_processors_mutex; + + /** + * @brief List of outbound frame processors + */ std::vector> frame_processors; + /** + * @brief A pair of 32 bit SSRC and codec in use for that SSRC + */ using ssrc_codec_pair = std::pair; + + /** + * @brief List of codec pairs for SSRCs + */ std::vector ssrc_codec_pairs; + /** + * @brief A chrono time point + */ using time_point = std::chrono::time_point; + + /** + * @brief Last time stats were updated + */ time_point last_stats_time{time_point::min()}; + + /** + * @brief Stores audio/video encryption stats + */ std::array stats; + /** + * @brief Callback for version change, if any + */ protocol_version_changed_callback changed_callback; + + /** + * Current protocol version supported + */ protocol_version current_protocol_version{max_protocol_version()}; /** diff --git a/src/dpp/dave/frame_processors.cpp b/src/dpp/dave/frame_processors.cpp index 79ae115693..a8b7aa185e 100755 --- a/src/dpp/dave/frame_processors.cpp +++ b/src/dpp/dave/frame_processors.cpp @@ -59,7 +59,7 @@ namespace dpp::dave { } #endif -std::pair OverflowAdd(size_t a, size_t b) +std::pair overflow_add(size_t a, size_t b) { size_t res; #if defined(_MSC_VER) && defined(_M_X64) @@ -97,10 +97,10 @@ uint8_t serialize_unencrypted_ranges(const ranges& unencrypted_ranges, uint8_t* write_at += write_leb128(range.offset, write_at); write_at += write_leb128(range.size, write_at); } - return write_at - buffer; + return static_cast(write_at - buffer); } -uint8_t deserialize_unencrypted_ranges(const uint8_t*& read_at, const size_t buffer_size, ranges& unencrypted_ranges) +uint8_t deserialize_unencrypted_ranges(const uint8_t*& read_at, const uint8_t buffer_size, ranges& unencrypted_ranges) { auto start = read_at; auto end = read_at + buffer_size; @@ -123,7 +123,7 @@ uint8_t deserialize_unencrypted_ranges(const uint8_t*& read_at, const size_t buf return 0; } - return read_at - start; + return static_cast(read_at - start); } bool validate_unencrypted_ranges(const ranges& unencrypted_ranges, size_t frame_size) @@ -140,7 +140,7 @@ bool validate_unencrypted_ranges(const ranges& unencrypted_ranges, size_t frame_ auto max_end = i + 1 < unencrypted_ranges.size() ? unencrypted_ranges[i + 1].offset : frame_size; - auto [did_overflow, current_end] = OverflowAdd(current.offset, current.size); + auto [did_overflow, current_end] = overflow_add(current.offset, current.size); if (did_overflow || current_end > max_end) { return false; } @@ -197,8 +197,7 @@ void inbound_frame_processor::parse_frame(array_view frame) { clear(); - constexpr auto min_supplemental_bytes_size = - AES_GCM_127_TRUNCATED_TAG_BYTES + sizeof(supplemental_bytes_size) + sizeof(magic_marker); + constexpr auto min_supplemental_bytes_size = AES_GCM_127_TRUNCATED_TAG_BYTES + sizeof(supplemental_bytes_size) + sizeof(magic_marker); if (frame.size() < min_supplemental_bytes_size) { creator.log(dpp::ll_warning, "Encrypted frame is too small to contain min supplemental bytes"); return; @@ -236,14 +235,14 @@ void inbound_frame_processor::parse_frame(array_view frame) auto nonce_buffer = supplemental_bytes_buffer + AES_GCM_127_TRUNCATED_TAG_BYTES; auto read_at = nonce_buffer; auto end = bytes_size_buffer; - truncated_nonce = read_leb128(read_at, end); + truncated_nonce = static_cast(read_leb128(read_at, end)); if (read_at == nullptr) { creator.log(dpp::ll_warning, "Failed to read truncated nonce"); return; } // Read the unencrypted ranges - auto ranges_size = end - read_at; + auto ranges_size = static_cast(end - read_at); deserialize_unencrypted_ranges(read_at, ranges_size, unencrypted_ranges); if (read_at == nullptr) { creator.log(dpp::ll_warning, "Failed to read unencrypted ranges"); diff --git a/src/dpp/dave/frame_processors.h b/src/dpp/dave/frame_processors.h index e7301429c3..0ec4b8e255 100755 --- a/src/dpp/dave/frame_processors.h +++ b/src/dpp/dave/frame_processors.h @@ -73,7 +73,7 @@ uint8_t serialize_unencrypted_ranges(const ranges& unencrypted_ranges, uint8_t* * @param unencrypted_ranges unencrypted ranges to write to * @return size of unencrypted ranges written */ -uint8_t deserialize_unencrypted_ranges(const uint8_t*& read_at, const size_t buffer_size, ranges& unencrypted_ranges); +uint8_t deserialize_unencrypted_ranges(const uint8_t*& read_at, const uint8_t buffer_size, ranges& unencrypted_ranges); /** * @brief Validate unencrypted ranges @@ -183,13 +183,44 @@ class inbound_frame_processor { */ void add_ciphertext_bytes(const uint8_t* data, size_t size); + /** + * @brief True if frames are encrypted + */ bool encrypted{false}; + + /** + * @brief Original size + */ size_t original_size{0}; + + /** + * @brief AEAD tag + */ array_view tag; + + /** + * @brief Truncated nonce + */ truncated_sync_nonce truncated_nonce; + + /** + * @brief Unencrypted parts of the frames + */ ranges unencrypted_ranges; + + /** + * @brief additional authenticated data + */ std::vector authenticated; + + /** + * @brief Ciphertext + */ std::vector ciphertext; + + /** + * @brief Plaintext + */ std::vector plaintext; /** @@ -283,11 +314,34 @@ class outbound_frame_processor { void add_encrypted_bytes(const uint8_t* bytes, size_t size); private: + /** + * @brief Codec used to decrypt + */ codec frame_codec{codec::cd_unknown}; + + /** + * @brief Frame index + */ size_t frame_index{0}; + + /** + * @brief Unencrypted bytes + */ std::vector unencrypted_bytes; + + /** + * @brief Encrypted bytes + */ std::vector encrypted_bytes; + + /** + * @brief Ciphertext bytes + */ std::vector ciphertext_bytes; + + /** + * @brief Unencrypted ranges that need to be kept plaintext to allow for RTP routing + */ ranges unencrypted_ranges; /** diff --git a/src/dpp/dave/leb128.cpp b/src/dpp/dave/leb128.cpp index 414e2ff4b7..f43de97772 100755 --- a/src/dpp/dave/leb128.cpp +++ b/src/dpp/dave/leb128.cpp @@ -76,7 +76,7 @@ size_t write_leb128(uint64_t value, uint8_t* buffer) ++size; value >>= 7; } - buffer[size] = value; + buffer[size] = static_cast(value); ++size; return size; } diff --git a/src/dpp/dave/parameters.h b/src/dpp/dave/parameters.h index 798e8fa03e..ca8590d42d 100755 --- a/src/dpp/dave/parameters.h +++ b/src/dpp/dave/parameters.h @@ -82,4 +82,4 @@ ::mlspp::ExtensionList leaf_node_extensions_for_protocol_version(protocol_versio */ ::mlspp::ExtensionList group_extensions_for_protocol_version(protocol_version version, const ::mlspp::ExternalSender& external_sender) noexcept; -} // namespace dpp::dave::mls +} diff --git a/src/dpp/dave/persisted_key_pair_generic.cpp b/src/dpp/dave/persisted_key_pair_generic.cpp index cf1f056fee..1bc315eda6 100755 --- a/src/dpp/dave/persisted_key_pair_generic.cpp +++ b/src/dpp/dave/persisted_key_pair_generic.cpp @@ -141,7 +141,7 @@ std::shared_ptr<::mlspp::SignaturePrivateKey> get_generic_persisted_key_pair(dpp } #ifdef _WIN32 - int written = _write(fd, newstr.c_str(), newstr.size()); + int written = _write(fd, newstr.c_str(), static_cast(newstr.size())); _close(fd); #else ssize_t written = write(fd, newstr.c_str(), newstr.size()); diff --git a/src/dpp/dave/session.h b/src/dpp/dave/session.h index 93851b3ee5..36e5dabb17 100755 --- a/src/dpp/dave/session.h +++ b/src/dpp/dave/session.h @@ -247,32 +247,99 @@ class session { // NOLINT */ inline static const std::string USER_MEDIA_KEY_BASE_LABEL = "Discord Secure Frames v0"; + /** + * @brief DAVE protocol version for the session + */ protocol_version session_protocol_version; + + /** + * @brief Session group ID (voice channel id) + */ std::vector session_group_id; + + /** + * @brief Signing key id + */ std::string signing_key_id; + + /** + * @brief The bot's user snowflake ID + */ std::string bot_user_id; + + /** + * @brief The bot's key pair context + */ key_pair_context_type key_pair_context{nullptr}; + /** + * @brief Our leaf node in the ratchet tree + */ std::unique_ptr<::mlspp::LeafNode> self_leaf_node; + + /** + * @brief The bots signature private key + */ std::shared_ptr<::mlspp::SignaturePrivateKey> signature_private_key; + + /** + * @brief HPKE private key + */ std::unique_ptr<::mlspp::HPKEPrivateKey> hpke_private_key; + /** + * @brief Private key for join initialisation + */ std::unique_ptr<::mlspp::HPKEPrivateKey> join_init_private_key; + + /** + * @brief Join key package + */ std::unique_ptr<::mlspp::KeyPackage> join_key_package; + /** + * @brief MLS External sender (the discord voice gateway server) + */ std::unique_ptr<::mlspp::ExternalSender> mls_external_sender; + /** + * @brief Pending MLS group state + */ std::unique_ptr<::mlspp::State> pending_group_state; + + /** + * @brief Pending MLS group commit + */ std::unique_ptr<::mlspp::MLSMessage> pending_group_commit; + /** + * @brief Outbound cached group state + */ std::unique_ptr<::mlspp::State> outbound_cached_group_state; + /** + * @brief Current MLS state + */ std::unique_ptr<::mlspp::State> current_state; + + /** + * @brief Participant roster, all users who are in the VC with dave enabled + */ roster_map roster; + /** + * @brief Current state containing proposals + */ std::unique_ptr<::mlspp::State> state_with_proposals; + + /** + * @brief Queue of proposals to process + */ std::list proposal_queue; + /** + * @brief Function to call on failure, if any + */ mls_failure_callback failure_callback{}; /** diff --git a/src/dpp/voice/enabled/discover_ip.cpp b/src/dpp/voice/enabled/discover_ip.cpp index 341be4a80e..7061c20f08 100644 --- a/src/dpp/voice/enabled/discover_ip.cpp +++ b/src/dpp/voice/enabled/discover_ip.cpp @@ -38,13 +38,11 @@ namespace dpp { -/** - * https://discord.com/developers/docs/topics/voice-connections#ip-discovery - */ - /** * @brief Represents an IP discovery packet sent to Discord or received * from Discord. + * + * https://discord.com/developers/docs/topics/voice-connections#ip-discovery */ struct ip_discovery_packet {