in fizz/protocol/ech/Encryption.cpp [263:326]
folly::Optional<ClientHello> tryToDecryptECH(
const ClientHello& clientHelloOuter,
const ECHConfig& echConfig,
ECHCipherSuite cipherSuite,
std::unique_ptr<folly::IOBuf> encapsulatedKey,
std::unique_ptr<folly::IOBuf> encryptedCh,
std::unique_ptr<KeyExchange> kex,
ECHVersion version) {
const std::unique_ptr<folly::IOBuf> prefix =
folly::IOBuf::copyBuffer("HPKE-07");
// Get crypto primitive types used for decrypting
hpke::KDFId kdfId = cipherSuite.kdf_id;
folly::io::Cursor echConfigCursor(echConfig.ech_config_content.get());
auto decodedConfigContent = decode<ECHConfigContentDraft>(echConfigCursor);
auto kemId = decodedConfigContent.kem_id;
NamedGroup group = hpke::getKexGroup(kemId);
// Try to decrypt and get the client hello inner
try {
auto dhkem = std::make_unique<DHKEM>(
std::move(kex), group, hpke::makeHpkeHkdf(prefix->clone(), kdfId));
auto aeadId = cipherSuite.aead_id;
auto suiteId = hpke::generateHpkeSuiteId(
group, hpke::getHashFunction(kdfId), hpke::getCipherSuite(aeadId));
hpke::SetupParam setupParam{
std::move(dhkem),
makeCipher(aeadId),
hpke::makeHpkeHkdf(prefix->clone(), kdfId),
std::move(suiteId)};
std::unique_ptr<folly::IOBuf> info = makeHpkeContextInfoParam(echConfig);
auto context = hpke::setupWithDecap(
hpke::Mode::Base,
encapsulatedKey->coalesce(),
std::move(info),
folly::none,
std::move(setupParam));
auto encodedClientHelloInner = extractEncodedClientHelloInner(
version,
constructConfigId(cipherSuite.kdf_id, echConfig),
cipherSuite,
encapsulatedKey,
std::move(encryptedCh),
context,
clientHelloOuter);
// Set actual client hello, ECH acceptance
folly::io::Cursor encodedECHInnerCursor(encodedClientHelloInner.get());
auto decodedChlo = decode<ClientHello>(encodedECHInnerCursor);
decodedChlo.originalEncoding = encodeHandshake(decodedChlo);
// Replace legacy_session_id that got removed during encryption
decodedChlo.legacy_session_id = clientHelloOuter.legacy_session_id->clone();
// TODO: Scan for outer_extensions extension.
return decodedChlo;
} catch (const std::exception&) {
}
return folly::none;
}