#include "quiche/quic/core/crypto/crypto_utils.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/bytestring.h"
#include "openssl/hkdf.h"
#include "openssl/mem.h"
#include "openssl/sha.h"
#include "quiche/quic/core/crypto/aes_128_gcm_12_decrypter.h"
#include "quiche/quic/core/crypto/aes_128_gcm_12_encrypter.h"
#include "quiche/quic/core/crypto/aes_128_gcm_decrypter.h"
#include "quiche/quic/core/crypto/aes_128_gcm_encrypter.h"
#include "quiche/quic/core/crypto/crypto_handshake.h"
#include "quiche/quic/core/crypto/crypto_protocol.h"
#include "quiche/quic/core/crypto/null_decrypter.h"
#include "quiche/quic/core/crypto/null_encrypter.h"
#include "quiche/quic/core/crypto/quic_decrypter.h"
#include "quiche/quic/core/crypto/quic_encrypter.h"
#include "quiche/quic/core/crypto/quic_hkdf.h"
#include "quiche/quic/core/crypto/quic_random.h"
#include "quiche/quic/core/quic_connection_id.h"
#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/core/quic_data_writer.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_bug_tracker.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/common/quiche_endian.h"
namespace quic {
namespace {
std::vector<uint8_t> HkdfExpandLabel(const EVP_MD* prf,
absl::Span<const uint8_t> secret,
const std::string& label, size_t out_len) { … }
}
const std::string getLabelForVersion(const ParsedQuicVersion& version,
const absl::string_view& predicate) { … }
void CryptoUtils::InitializeCrypterSecrets(
const EVP_MD* prf, const std::vector<uint8_t>& pp_secret,
const ParsedQuicVersion& version, QuicCrypter* crypter) { … }
void CryptoUtils::SetKeyAndIV(const EVP_MD* prf,
absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version,
QuicCrypter* crypter) { … }
std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey(
const EVP_MD* prf, absl::Span<const uint8_t> pp_secret,
const ParsedQuicVersion& version, size_t out_len) { … }
std::vector<uint8_t> CryptoUtils::GenerateNextKeyPhaseSecret(
const EVP_MD* prf, const ParsedQuicVersion& version,
const std::vector<uint8_t>& current_secret) { … }
namespace {
const uint8_t kDraft29InitialSalt[] = …;
const uint8_t kRFCv1InitialSalt[] = …;
const uint8_t kRFCv2InitialSalt[] = …;
const uint8_t kReservedForNegotiationSalt[] = …;
const uint8_t* InitialSaltForVersion(const ParsedQuicVersion& version,
size_t* out_len) { … }
const char kPreSharedKeyLabel[] = …;
const uint8_t kDraft29RetryIntegrityKey[] = …;
const uint8_t kDraft29RetryIntegrityNonce[] = …;
const uint8_t kRFCv1RetryIntegrityKey[] = …;
const uint8_t kRFCv1RetryIntegrityNonce[] = …;
const uint8_t kRFCv2RetryIntegrityKey[] = …;
const uint8_t kRFCv2RetryIntegrityNonce[] = …;
const uint8_t kReservedForNegotiationRetryIntegrityKey[] = …;
const uint8_t kReservedForNegotiationRetryIntegrityNonce[] = …;
bool RetryIntegrityKeysForVersion(const ParsedQuicVersion& version,
absl::string_view* key,
absl::string_view* nonce) { … }
}
void CryptoUtils::CreateInitialObfuscators(Perspective perspective,
ParsedQuicVersion version,
QuicConnectionId connection_id,
CrypterPair* crypters) { … }
bool CryptoUtils::ValidateRetryIntegrityTag(
ParsedQuicVersion version, QuicConnectionId original_connection_id,
absl::string_view retry_without_tag, absl::string_view integrity_tag) { … }
void CryptoUtils::GenerateNonce(QuicWallTime now, QuicRandom* random_generator,
absl::string_view orbit, std::string* nonce) { … }
bool CryptoUtils::DeriveKeys(
const ParsedQuicVersion& version, absl::string_view premaster_secret,
QuicTag aead, absl::string_view client_nonce,
absl::string_view server_nonce, absl::string_view pre_shared_key,
const std::string& hkdf_input, Perspective perspective,
Diversification diversification, CrypterPair* crypters,
std::string* subkey_secret) { … }
uint64_t CryptoUtils::ComputeLeafCertHash(absl::string_view cert) { … }
QuicErrorCode CryptoUtils::ValidateServerHello(
const CryptoHandshakeMessage& server_hello,
const ParsedQuicVersionVector& negotiated_versions,
std::string* error_details) { … }
QuicErrorCode CryptoUtils::ValidateServerHelloVersions(
const QuicVersionLabelVector& server_versions,
const ParsedQuicVersionVector& negotiated_versions,
std::string* error_details) { … }
QuicErrorCode CryptoUtils::ValidateClientHello(
const CryptoHandshakeMessage& client_hello, ParsedQuicVersion version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) { … }
QuicErrorCode CryptoUtils::ValidateClientHelloVersion(
QuicVersionLabel client_version, ParsedQuicVersion connection_version,
const ParsedQuicVersionVector& supported_versions,
std::string* error_details) { … }
bool CryptoUtils::ValidateChosenVersion(
const QuicVersionLabel& version_information_chosen_version,
const ParsedQuicVersion& session_version, std::string* error_details) { … }
bool CryptoUtils::ValidateServerVersions(
const QuicVersionLabelVector& version_information_other_versions,
const ParsedQuicVersion& session_version,
const ParsedQuicVersionVector& client_original_supported_versions,
std::string* error_details) { … }
#define RETURN_STRING_LITERAL …
const char* CryptoUtils::HandshakeFailureReasonToString(
HandshakeFailureReason reason) { … }
#undef RETURN_STRING_LITERAL
std::string CryptoUtils::EarlyDataReasonToString(
ssl_early_data_reason_t reason) { … }
std::string CryptoUtils::HashHandshakeMessage(
const CryptoHandshakeMessage& message, Perspective ) { … }
bool CryptoUtils::GetSSLCapabilities(const SSL* ssl,
bssl::UniquePtr<uint8_t>* capabilities,
size_t* capabilities_len) { … }
std::optional<std::string> CryptoUtils::GenerateProofPayloadToBeSigned(
absl::string_view chlo_hash, absl::string_view server_config) { … }
}