folly::Optional tryToDecryptECH()

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;
}