diff --git a/.cspell.json b/.cspell.json index e8ef129aca..e19a259067 100644 --- a/.cspell.json +++ b/.cspell.json @@ -146,7 +146,8 @@ "chacha20", "chacha", "nullopt", - "chrono" + "chrono", + "ciphersuite" ], "flagWords": [ "hte" diff --git a/src/dpp/dave/key_ratchet.h b/src/dpp/dave/key_ratchet.h index 0f822de0e1..3847f5f757 100755 --- a/src/dpp/dave/key_ratchet.h +++ b/src/dpp/dave/key_ratchet.h @@ -29,12 +29,34 @@ namespace dpp::dave { +/** + * @brief Key generation number + */ using key_generation = uint32_t; -class key_ratchet_interface { +/** + * @brief Represents the interface used for a key ratchet. + * A key ratchet is a way of propogating key pairs up the tree used by MLS + * so we dont have to store O(n^n) key combinations. + */ +class key_ratchet_interface { // NOLINT public: + /** + * @brief Default destructor + */ virtual ~key_ratchet_interface() noexcept = default; + + /** + * @brief Get key for ratchet + * @param generation current generation number + * @return encryption key + */ virtual encryption_key get_key(key_generation generation) noexcept = 0; + + /** + * @brief Delete key for ratchet + * @param generation current generation number + */ virtual void delete_key(key_generation generation) noexcept = 0; }; diff --git a/src/dpp/dave/leb128.h b/src/dpp/dave/leb128.h index 3d3732faaa..292df06864 100755 --- a/src/dpp/dave/leb128.h +++ b/src/dpp/dave/leb128.h @@ -35,17 +35,34 @@ namespace dpp::dave { +/** + * @brief Maximum size of LEB128 value + */ constexpr size_t LEB128_MAX_SIZE = 10; -// Returns number of bytes needed to store `value` in leb128 format. +/** + * @brief Returns number of bytes needed to store `value` in leb128 format. + * @param value value to return size for + * @return size of leb128 + */ size_t leb128_size(uint64_t value); -// Reads leb128 encoded value and advance read_at by number of bytes consumed. -// Sets read_at to nullptr on error. +/** + * @brief Reads leb128 encoded value and advance read_at by number of bytes consumed. + * Sets read_at to nullptr on error. + * @param readAt start position + * @param end end position + * @return decoded value + */ uint64_t read_leb128(const uint8_t*& readAt, const uint8_t* end); -// Encodes `value` in leb128 format. Assumes buffer has size of at least -// Leb128Size(value). Returns number of bytes consumed. +/** + * @brief Encodes `value` in leb128 format. Assumes buffer has size of + * at least Leb128Size(value). Returns number of bytes consumed. + * @param value value to encode + * @param buffer buffer to encode into + * @return size of encoding + */ size_t write_leb128(uint64_t value, uint8_t* buffer); } // namespace dpp::dave diff --git a/src/dpp/dave/mls_key_ratchet.h b/src/dpp/dave/mls_key_ratchet.h index 4b69e1f27d..65f4f382b0 100755 --- a/src/dpp/dave/mls_key_ratchet.h +++ b/src/dpp/dave/mls_key_ratchet.h @@ -29,15 +29,40 @@ namespace dpp::dave { -class mls_key_ratchet : public key_ratchet_interface { +/** + * @brief An implementation of the key ratchet using MLS + */ +class mls_key_ratchet : public key_ratchet_interface { // NOLINT public: + /** + * @brief Constructor + * @param suite MLS ciphersuite to use + * @param baseSecret base secret + */ mls_key_ratchet(::mlspp::CipherSuite suite, bytes baseSecret) noexcept; + + /** + * @brief Destructor + */ ~mls_key_ratchet() noexcept override; + /** + * @brief Gey key for ratchet + * @param generation current generation + * @return encryption key + */ encryption_key get_key(key_generation generation) noexcept override; + + /** + * Delete key for ratchet + * @param generation current generation + */ void delete_key(key_generation generation) noexcept override; private: + /** + * @brief MLS hash ratchet + */ ::mlspp::HashRatchet hashRatchet_; }; diff --git a/src/dpp/dave/openssl_aead_cipher.h b/src/dpp/dave/openssl_aead_cipher.h index 9bf077d555..26070a91c0 100755 --- a/src/dpp/dave/openssl_aead_cipher.h +++ b/src/dpp/dave/openssl_aead_cipher.h @@ -28,23 +28,65 @@ namespace dpp::dave { +/** + * @brief OpenSSL AES 128 GCM AEAD cipher + * + * Replaces the boringSSL AES cipher in the Discord implementation, so we don't + * have a conflicting dependency. + */ class openssl_aead_cipher : public cipher_interface { // NOLINT public: + /** + * @brief constructor + * @param encryptionKey encryption key + */ openssl_aead_cipher(const encryption_key& encryptionKey); + /** + * @brief Destructor + */ ~openssl_aead_cipher() override; + /** + * @brief Returns true if valid + * @return True if valid + */ [[nodiscard]] bool inline is_valid() const { return cipherCtx_ != nullptr; } + /** + * @brief Encrypt plaintext to ciphertext and authenticate it with tag/AAD + * @param ciphertextBufferOut ciphertext + * @param plaintextBuffer plaintext + * @param nonceBuffer nonce/IV + * @param additionalData additional authenticated data + * @param tagBufferOut tag + * @return True if encryption succeeded + */ bool encrypt(byte_view ciphertextBufferOut, const_byte_view plaintextBuffer, const_byte_view nonceBuffer, const_byte_view additionalData, byte_view tagBufferOut) override; + + /** + * @brief Decrypt ciphertext to plaintext if it authenticates with tag/AAD + * @param plaintextBufferOut plaintext + * @param ciphertextBuffer ciphertext + * @param tagBuffer tag + * @param nonceBuffer nonce/IV + * @param additionalData additional authenticated data + * @return True if decryption succeeded + */ bool decrypt(byte_view plaintextBufferOut, const_byte_view ciphertextBuffer, const_byte_view tagBuffer, const_byte_view nonceBuffer, const_byte_view additionalData) override; private: - EVP_CIPHER_CTX* cipherCtx_; // Using EVP_CIPHER_CTX instead of EVP_AEAD_CTX - std::vector key_; + /** + * @brief Using EVP_CIPHER_CTX instead of EVP_AEAD_CTX + */ + EVP_CIPHER_CTX* cipherCtx_; + /** + * @brief Encryption/decryption key + */ + std::vector key_; }; } // namespace dpp::dave diff --git a/src/dpp/dave/parameters.h b/src/dpp/dave/parameters.h index 4f994fdf32..a5a8d4a813 100755 --- a/src/dpp/dave/parameters.h +++ b/src/dpp/dave/parameters.h @@ -32,16 +32,54 @@ namespace dpp::dave::mls { +/** + * @brief Get ciphersuite id for protocol version + * @param version protocol version + * @return ciphersuite id + */ ::mlspp::CipherSuite::ID ciphersuite_id_for_protocol_version(protocol_version version) noexcept; + +/** + * @brief Get ciphersuite for protocol version + * @param version protocol version + * @return ciphersuite + */ ::mlspp::CipherSuite ciphersuite_for_protocol_version(protocol_version version) noexcept; + +/** + * @brief Get ciphersuite id for signature version + * @param version signature version + * @return Ciphersuite id + */ ::mlspp::CipherSuite::ID ciphersuite_id_for_signature_version(signature_version version) noexcept; + +/** + * @brief Get ciphersuite for singnature version + * @param version signature version + * @return Ciphersuite + */ ::mlspp::CipherSuite ciphersuite_for_signature_version(signature_version version) noexcept; + +/** + * @brief Get leaf node capabilities for protocol version + * @param version protocol version + * @return capabilities + */ ::mlspp::Capabilities leaf_node_capabilities_for_protocol_version(protocol_version version) noexcept; -::mlspp::ExtensionList leaf_node_extensions_for_protocol_version(protocol_version version) noexcept; -::mlspp::ExtensionList group_extensions_for_protocol_version( - protocol_version version, - const ::mlspp::ExternalSender& externalSender) noexcept; -} // namespace dpp::dave::mls +/** + * @brief Get leaf node extensions for protocol version + * @param version protocol version + * @return extension list + */ +::mlspp::ExtensionList leaf_node_extensions_for_protocol_version(protocol_version version) noexcept; +/** + * @brief Get group extensions for protocol version + * @param version protocol bersion + * @param externalSender external sender + * @return extension list + */ +::mlspp::ExtensionList group_extensions_for_protocol_version(protocol_version version, const ::mlspp::ExternalSender& externalSender) noexcept; +} // namespace dpp::dave::mls