HpkeContext keySchedule()

in fizz/crypto/hpke/Hpke.cpp [28:91]


HpkeContext keySchedule(KeyScheduleParams params) {
  auto hkdf = std::move(params.hkdf);

  auto psk = params.pskInputs.hasValue()
      ? std::move(params.pskInputs.value().psk)
      : PskInputs::getDefaultPsk();
  auto pskId = params.pskInputs.hasValue()
      ? std::move(params.pskInputs.value().id)
      : PskInputs::getDefaultId();

  // Generate hashes for key schedule context
  std::vector<uint8_t> pskIdHash = hkdf->labeledExtract(
      folly::IOBuf::copyBuffer(""),
      folly::ByteRange(folly::StringPiece("psk_id_hash")),
      std::move(pskId),
      params.suiteId->clone());
  std::vector<uint8_t> infoHash = hkdf->labeledExtract(
      folly::IOBuf::copyBuffer(""),
      folly::ByteRange(folly::StringPiece("info_hash")),
      std::move(params.info),
      params.suiteId->clone());
  std::unique_ptr<folly::IOBuf> keyScheduleContext =
      writeKeyScheduleContext(params.mode, pskIdHash, infoHash);

  // Generate hashes for cipher key
  std::vector<uint8_t> secret = hkdf->labeledExtract(
      std::move(params.sharedSecret),
      folly::ByteRange(folly::StringPiece("secret")),
      std::move(psk),
      params.suiteId->clone());

  // Generate additional values needed for contructing context
  std::unique_ptr<folly::IOBuf> key = hkdf->labeledExpand(
      secret,
      folly::ByteRange(folly::StringPiece("key")),
      keyScheduleContext->clone(),
      params.cipher->keyLength(),
      params.suiteId->clone());
  std::unique_ptr<folly::IOBuf> nonce = hkdf->labeledExpand(
      secret,
      folly::ByteRange(folly::StringPiece("base_nonce")),
      keyScheduleContext->clone(),
      params.cipher->ivLength(),
      params.suiteId->clone());
  std::unique_ptr<folly::IOBuf> exporterSecret = hkdf->labeledExpand(
      secret,
      folly::ByteRange(folly::StringPiece("exp")),
      std::move(keyScheduleContext),
      hkdf->hashLength(),
      params.suiteId->clone());

  // Configure cipher to use our generated key
  TrafficKey trafficKey;
  trafficKey.key = std::move(key);
  trafficKey.iv = std::move(nonce);
  params.cipher->setKey(std::move(trafficKey));

  return HpkeContext(
      std::move(params.cipher),
      std::move(exporterSecret),
      std::move(hkdf),
      std::move(params.suiteId),
      params.ctxRole);
}