Rename CryptoUtils::SetKeyAndIV to InitializeCrypterSecrets and add separate SetKeyAndIV and GenerateHeaderProtectionKey methods. PiperOrigin-RevId: 336346481 Change-Id: I189096c76ea4fc7fa8790db4ad12a910e18ece6b
diff --git a/quic/core/crypto/crypto_utils.cc b/quic/core/crypto/crypto_utils.cc index 6c435ff..e6ec275 100644 --- a/quic/core/crypto/crypto_utils.cc +++ b/quic/core/crypto/crypto_utils.cc
@@ -96,6 +96,18 @@ } // namespace +void CryptoUtils::InitializeCrypterSecrets( + const EVP_MD* prf, + const std::vector<uint8_t>& pp_secret, + QuicCrypter* crypter) { + SetKeyAndIV(prf, pp_secret, crypter); + std::vector<uint8_t> header_protection_key = + GenerateHeaderProtectionKey(prf, pp_secret, crypter->GetKeySize()); + crypter->SetHeaderProtectionKey( + absl::string_view(reinterpret_cast<char*>(header_protection_key.data()), + header_protection_key.size())); +} + void CryptoUtils::SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, QuicCrypter* crypter) { @@ -103,14 +115,17 @@ HkdfExpandLabel(prf, pp_secret, "quic key", crypter->GetKeySize()); std::vector<uint8_t> iv = HkdfExpandLabel(prf, pp_secret, "quic iv", crypter->GetIVSize()); - std::vector<uint8_t> pn = - HkdfExpandLabel(prf, pp_secret, "quic hp", crypter->GetKeySize()); crypter->SetKey( absl::string_view(reinterpret_cast<char*>(key.data()), key.size())); crypter->SetIV( absl::string_view(reinterpret_cast<char*>(iv.data()), iv.size())); - crypter->SetHeaderProtectionKey( - absl::string_view(reinterpret_cast<char*>(pn.data()), pn.size())); +} + +std::vector<uint8_t> CryptoUtils::GenerateHeaderProtectionKey( + const EVP_MD* prf, + const std::vector<uint8_t>& pp_secret, + size_t out_len) { + return HkdfExpandLabel(prf, pp_secret, "quic hp", out_len); } namespace { @@ -317,12 +332,12 @@ std::vector<uint8_t> encryption_secret = HkdfExpandLabel( hash, handshake_secret, encryption_label, EVP_MD_size(hash)); crypters->encrypter = std::make_unique<Aes128GcmEncrypter>(); - SetKeyAndIV(hash, encryption_secret, crypters->encrypter.get()); + InitializeCrypterSecrets(hash, encryption_secret, crypters->encrypter.get()); std::vector<uint8_t> decryption_secret = HkdfExpandLabel( hash, handshake_secret, decryption_label, EVP_MD_size(hash)); crypters->decrypter = std::make_unique<Aes128GcmDecrypter>(); - SetKeyAndIV(hash, decryption_secret, crypters->decrypter.get()); + InitializeCrypterSecrets(hash, decryption_secret, crypters->decrypter.get()); } // static
diff --git a/quic/core/crypto/crypto_utils.h b/quic/core/crypto/crypto_utils.h index c21c534..543173a 100644 --- a/quic/core/crypto/crypto_utils.h +++ b/quic/core/crypto/crypto_utils.h
@@ -74,15 +74,30 @@ DiversificationNonce* nonce_; }; - // SetKeyAndIV derives the key and IV from the given packet protection secret - // |pp_secret| and sets those fields on the given QuicCrypter |*crypter|. + // InitializeCrypterSecrets derives the key and IV and header protection key + // from the given packet protection secret |pp_secret| and sets those fields + // on the given QuicCrypter |*crypter|. // This follows the derivation described in section 7.3 of RFC 8446, except // with the label prefix in HKDF-Expand-Label changed from "tls13 " to "quic " // as described in draft-ietf-quic-tls-14, section 5.1. + static void InitializeCrypterSecrets(const EVP_MD* prf, + const std::vector<uint8_t>& pp_secret, + QuicCrypter* crypter); + + // Derives the key and IV from the packet protection secret and sets those + // fields on the given QuicCrypter |*crypter|, but does not set the header + // protection key. GenerateHeaderProtectionKey/SetHeaderProtectionKey must be + // called before using |crypter|. static void SetKeyAndIV(const EVP_MD* prf, const std::vector<uint8_t>& pp_secret, QuicCrypter* crypter); + // Derives the header protection key from the packet protection secret. + static std::vector<uint8_t> GenerateHeaderProtectionKey( + const EVP_MD* prf, + const std::vector<uint8_t>& pp_secret, + size_t out_len); + // IETF QUIC encrypts ENCRYPTION_INITIAL messages with a version-specific key // (to prevent network observers that are not aware of that QUIC version from // making decisions based on the TLS handshake). This packet protection secret
diff --git a/quic/core/tls_handshaker.cc b/quic/core/tls_handshaker.cc index 7e66302..362a1e8 100644 --- a/quic/core/tls_handshaker.cc +++ b/quic/core/tls_handshaker.cc
@@ -70,7 +70,8 @@ const std::vector<uint8_t>& write_secret) { std::unique_ptr<QuicEncrypter> encrypter = QuicEncrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher)); - CryptoUtils::SetKeyAndIV(Prf(cipher), write_secret, encrypter.get()); + CryptoUtils::InitializeCrypterSecrets(Prf(cipher), write_secret, + encrypter.get()); handshaker_delegate_->OnNewEncryptionKeyAvailable(level, std::move(encrypter)); } @@ -80,7 +81,8 @@ const std::vector<uint8_t>& read_secret) { std::unique_ptr<QuicDecrypter> decrypter = QuicDecrypter::CreateFromCipherSuite(SSL_CIPHER_get_id(cipher)); - CryptoUtils::SetKeyAndIV(Prf(cipher), read_secret, decrypter.get()); + CryptoUtils::InitializeCrypterSecrets(Prf(cipher), read_secret, + decrypter.get()); return handshaker_delegate_->OnNewDecryptionKeyAvailable( level, std::move(decrypter), /*set_alternative_decrypter=*/false,