mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-08-01 01:44:22 +03:00
Remove throws from PacketNumberCipher
Summary: Continuing the theme. Reviewed By: kvtsoy Differential Revision: D74944002 fbshipit-source-id: 9f23780aada2841ee88a365b93850fde4bb27a70
This commit is contained in:
committed by
Facebook GitHub Bot
parent
ab8a6386c2
commit
92c50dad6f
@ -309,13 +309,19 @@ continuousMemoryBuildScheduleEncrypt(
|
||||
packetBuf->prepend(headerLen);
|
||||
|
||||
HeaderForm headerForm = packet->packet.header.getHeaderForm();
|
||||
encryptPacketHeader(
|
||||
auto headerEncryptResult = encryptPacketHeader(
|
||||
headerForm,
|
||||
packetBuf->writableData(),
|
||||
headerLen,
|
||||
packetBuf->data() + headerLen,
|
||||
packetBuf->length() - headerLen,
|
||||
headerCipher);
|
||||
if (headerEncryptResult.hasError()) {
|
||||
return folly::makeUnexpected(headerEncryptResult.error());
|
||||
}
|
||||
if (headerEncryptResult.hasError()) {
|
||||
return folly::makeUnexpected(headerEncryptResult.error());
|
||||
}
|
||||
CHECK(!packetBuf->isChained());
|
||||
auto encodedSize = packetBuf->length();
|
||||
auto encodedBodySize = encodedSize - headerLen;
|
||||
@ -413,13 +419,16 @@ iobufChainBasedBuildScheduleEncrypt(
|
||||
packetBuf->append(headerLen + bodyLen + aead.getCipherOverhead());
|
||||
|
||||
HeaderForm headerForm = packet->packet.header.getHeaderForm();
|
||||
encryptPacketHeader(
|
||||
auto headerEncryptResult = encryptPacketHeader(
|
||||
headerForm,
|
||||
packetBuf->writableData(),
|
||||
headerLen,
|
||||
packetBuf->data() + headerLen,
|
||||
packetBuf->length() - headerLen,
|
||||
headerCipher);
|
||||
if (headerEncryptResult.hasError()) {
|
||||
return folly::makeUnexpected(headerEncryptResult.error());
|
||||
}
|
||||
auto encodedSize = packetBuf->computeChainDataLength();
|
||||
auto encodedBodySize = encodedSize - headerLen;
|
||||
if (encodedSize > connection.udpSendPacketLen) {
|
||||
@ -1525,7 +1534,7 @@ void writeShortClose(
|
||||
headerCipher);
|
||||
}
|
||||
|
||||
void encryptPacketHeader(
|
||||
folly::Expected<folly::Unit, QuicError> encryptPacketHeader(
|
||||
HeaderForm headerForm,
|
||||
uint8_t* header,
|
||||
size_t headerLen,
|
||||
@ -1546,12 +1555,19 @@ void encryptPacketHeader(
|
||||
MutableByteRange packetNumByteRange(
|
||||
header + headerLen - packetNumberLength, packetNumberLength);
|
||||
if (headerForm == HeaderForm::Short) {
|
||||
headerCipher.encryptShortHeader(
|
||||
sample, initialByteRange, packetNumByteRange);
|
||||
} else {
|
||||
headerCipher.encryptLongHeader(
|
||||
auto result = headerCipher.encryptShortHeader(
|
||||
sample, initialByteRange, packetNumByteRange);
|
||||
if (result.hasError()) {
|
||||
return folly::makeUnexpected(result.error());
|
||||
}
|
||||
} else {
|
||||
auto result = headerCipher.encryptLongHeader(
|
||||
sample, initialByteRange, packetNumByteRange);
|
||||
if (result.hasError()) {
|
||||
return folly::makeUnexpected(result.error());
|
||||
}
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,7 +268,7 @@ void writeShortClose(
|
||||
* whether or not there are enough bytes to sample for the header encryption
|
||||
* from the encryptedBody via a CHECK.
|
||||
*/
|
||||
void encryptPacketHeader(
|
||||
folly::Expected<folly::Unit, QuicError> encryptPacketHeader(
|
||||
HeaderForm headerForm,
|
||||
uint8_t* header,
|
||||
size_t headerLen,
|
||||
|
@ -76,7 +76,10 @@ mvfst_cpp_library(
|
||||
":types",
|
||||
],
|
||||
exported_deps = [
|
||||
"//folly:expected",
|
||||
"//folly:unit",
|
||||
"//folly/io:iobuf",
|
||||
"//quic:exception",
|
||||
"//quic/common:buf_util",
|
||||
"//quic/common:optional",
|
||||
],
|
||||
|
@ -13,14 +13,18 @@
|
||||
|
||||
namespace quic {
|
||||
|
||||
void PacketNumberCipher::decipherHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::decipherHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes,
|
||||
uint8_t initialByteMask,
|
||||
uint8_t /* packetNumLengthMask */) const {
|
||||
CHECK_EQ(packetNumberBytes.size(), kMaxPacketNumEncodingSize);
|
||||
HeaderProtectionMask headerMask = mask(sample);
|
||||
auto maskResult = mask(sample);
|
||||
if (maskResult.hasError()) {
|
||||
return folly::makeUnexpected(maskResult.error());
|
||||
}
|
||||
HeaderProtectionMask headerMask = std::move(maskResult.value());
|
||||
// Mask size should be > packet number length + 1.
|
||||
DCHECK_GE(headerMask.size(), 5);
|
||||
initialByte.data()[0] ^= headerMask.data()[0] & initialByteMask;
|
||||
@ -28,15 +32,20 @@ void PacketNumberCipher::decipherHeader(
|
||||
for (size_t i = 0; i < packetNumLength; ++i) {
|
||||
packetNumberBytes.data()[i] ^= headerMask.data()[i + 1];
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
void PacketNumberCipher::cipherHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::cipherHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes,
|
||||
uint8_t initialByteMask,
|
||||
uint8_t /* packetNumLengthMask */) const {
|
||||
HeaderProtectionMask headerMask = mask(sample);
|
||||
auto maskResult = mask(sample);
|
||||
if (maskResult.hasError()) {
|
||||
return folly::makeUnexpected(maskResult.error());
|
||||
}
|
||||
HeaderProtectionMask headerMask = std::move(maskResult.value());
|
||||
// Mask size should be > packet number length + 1.
|
||||
DCHECK_GE(headerMask.size(), kMaxPacketNumEncodingSize + 1);
|
||||
size_t packetNumLength = parsePacketNumberLength(*initialByte.data());
|
||||
@ -44,13 +53,14 @@ void PacketNumberCipher::cipherHeader(
|
||||
for (size_t i = 0; i < packetNumLength; ++i) {
|
||||
packetNumberBytes.data()[i] ^= headerMask.data()[i + 1];
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
void PacketNumberCipher::decryptLongHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::decryptLongHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const {
|
||||
decipherHeader(
|
||||
return decipherHeader(
|
||||
sample,
|
||||
initialByte,
|
||||
packetNumberBytes,
|
||||
@ -58,11 +68,11 @@ void PacketNumberCipher::decryptLongHeader(
|
||||
LongHeader::kPacketNumLenMask);
|
||||
}
|
||||
|
||||
void PacketNumberCipher::decryptShortHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::decryptShortHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const {
|
||||
decipherHeader(
|
||||
return decipherHeader(
|
||||
sample,
|
||||
initialByte,
|
||||
packetNumberBytes,
|
||||
@ -70,11 +80,11 @@ void PacketNumberCipher::decryptShortHeader(
|
||||
ShortHeader::kPacketNumLenMask);
|
||||
}
|
||||
|
||||
void PacketNumberCipher::encryptLongHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::encryptLongHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const {
|
||||
cipherHeader(
|
||||
return cipherHeader(
|
||||
sample,
|
||||
initialByte,
|
||||
packetNumberBytes,
|
||||
@ -82,11 +92,11 @@ void PacketNumberCipher::encryptLongHeader(
|
||||
LongHeader::kPacketNumLenMask);
|
||||
}
|
||||
|
||||
void PacketNumberCipher::encryptShortHeader(
|
||||
folly::Expected<folly::Unit, QuicError> PacketNumberCipher::encryptShortHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const {
|
||||
cipherHeader(
|
||||
return cipherHeader(
|
||||
sample,
|
||||
initialByte,
|
||||
packetNumberBytes,
|
||||
|
@ -7,7 +7,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <folly/Expected.h>
|
||||
#include <folly/Unit.h>
|
||||
#include <folly/io/Cursor.h>
|
||||
#include <quic/QuicException.h>
|
||||
#include <quic/common/BufUtil.h>
|
||||
#include <quic/common/Optional.h>
|
||||
|
||||
@ -20,9 +23,11 @@ class PacketNumberCipher {
|
||||
public:
|
||||
virtual ~PacketNumberCipher() = default;
|
||||
|
||||
virtual void setKey(ByteRange key) = 0;
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError> setKey(
|
||||
ByteRange key) = 0;
|
||||
|
||||
virtual HeaderProtectionMask mask(ByteRange sample) const = 0;
|
||||
[[nodiscard]] virtual folly::Expected<HeaderProtectionMask, QuicError> mask(
|
||||
ByteRange sample) const = 0;
|
||||
|
||||
/**
|
||||
* Decrypts a long header from a sample.
|
||||
@ -30,7 +35,8 @@ class PacketNumberCipher {
|
||||
* initialByte is the initial byte.
|
||||
* packetNumberBytes should be supplied with at least 4 bytes.
|
||||
*/
|
||||
virtual void decryptLongHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError>
|
||||
decryptLongHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const;
|
||||
@ -41,7 +47,8 @@ class PacketNumberCipher {
|
||||
* initialByte is the initial byte.
|
||||
* packetNumberBytes should be supplied with at least 4 bytes.
|
||||
*/
|
||||
virtual void decryptShortHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError>
|
||||
decryptShortHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const;
|
||||
@ -51,7 +58,8 @@ class PacketNumberCipher {
|
||||
* sample should be 16 bytes long.
|
||||
* initialByte is the initial byte.
|
||||
*/
|
||||
virtual void encryptLongHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError>
|
||||
encryptLongHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const;
|
||||
@ -61,7 +69,8 @@ class PacketNumberCipher {
|
||||
* sample should be 16 bytes long.
|
||||
* initialByte is the initial byte.
|
||||
*/
|
||||
virtual void encryptShortHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError>
|
||||
encryptShortHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes) const;
|
||||
@ -69,22 +78,22 @@ class PacketNumberCipher {
|
||||
/**
|
||||
* Returns the length of key needed for the pn cipher.
|
||||
*/
|
||||
virtual size_t keyLength() const = 0;
|
||||
[[nodiscard]] virtual size_t keyLength() const = 0;
|
||||
|
||||
/**
|
||||
* Get the packet protection key
|
||||
*/
|
||||
virtual const BufPtr& getKey() const = 0;
|
||||
[[nodiscard]] virtual const BufPtr& getKey() const = 0;
|
||||
|
||||
protected:
|
||||
virtual void cipherHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError> cipherHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes,
|
||||
uint8_t initialByteMask,
|
||||
uint8_t packetNumLengthMask) const;
|
||||
|
||||
virtual void decipherHeader(
|
||||
[[nodiscard]] virtual folly::Expected<folly::Unit, QuicError> decipherHeader(
|
||||
ByteRange sample,
|
||||
MutableByteRange initialByte,
|
||||
MutableByteRange packetNumberBytes,
|
||||
|
@ -91,7 +91,7 @@ static PacketDropReason getDecryptErrorReason(ProtectionType protectionType) {
|
||||
}
|
||||
}
|
||||
|
||||
CodecResult QuicReadCodec::parseLongHeaderPacket(
|
||||
folly::Expected<CodecResult, QuicError> QuicReadCodec::parseLongHeaderPacket(
|
||||
BufQueue& queue,
|
||||
const AckStates& ackStates) {
|
||||
Cursor cursor(queue.front());
|
||||
@ -213,8 +213,12 @@ CodecResult QuicReadCodec::parseLongHeaderPacket(
|
||||
MutableByteRange packetNumberByteRange(
|
||||
currentPacketData->writableData() + packetNumberOffset,
|
||||
kMaxPacketNumEncodingSize);
|
||||
headerCipher->decryptLongHeader(
|
||||
auto decryptResult = headerCipher->decryptLongHeader(
|
||||
folly::range(sample), initialByteRange, packetNumberByteRange);
|
||||
if (decryptResult.hasError()) {
|
||||
VLOG(4) << "Failed to decrypt long header " << connIdToHex();
|
||||
return folly::makeUnexpected(decryptResult.error());
|
||||
}
|
||||
std::pair<PacketNum, size_t> packetNum = parsePacketNumber(
|
||||
initialByteRange.data()[0], packetNumberByteRange, expectedNextPacketNum);
|
||||
|
||||
@ -260,7 +264,8 @@ CodecResult QuicReadCodec::parseLongHeaderPacket(
|
||||
return CodecResult(std::move(*packetRes));
|
||||
}
|
||||
|
||||
CodecResult QuicReadCodec::tryParseShortHeaderPacket(
|
||||
folly::Expected<CodecResult, QuicError>
|
||||
QuicReadCodec::tryParseShortHeaderPacket(
|
||||
BufPtr data,
|
||||
const AckStates& ackStates,
|
||||
size_t dstConnIdSize,
|
||||
@ -284,8 +289,12 @@ CodecResult QuicReadCodec::tryParseShortHeaderPacket(
|
||||
data->writableData() + packetNumberOffset, kMaxPacketNumEncodingSize);
|
||||
ByteRange sampleByteRange(data->writableData() + sampleOffset, sample.size());
|
||||
|
||||
oneRttHeaderCipher_->decryptShortHeader(
|
||||
auto decryptResult = oneRttHeaderCipher_->decryptShortHeader(
|
||||
sampleByteRange, initialByteRange, packetNumberByteRange);
|
||||
if (decryptResult.hasError()) {
|
||||
VLOG(4) << "Failed to decrypt short header " << connIdToHex();
|
||||
return folly::makeUnexpected(decryptResult.error());
|
||||
}
|
||||
std::pair<PacketNum, size_t> packetNum = parsePacketNumber(
|
||||
initialByteRange.data()[0], packetNumberByteRange, expectedNextPacketNum);
|
||||
auto shortHeader =
|
||||
@ -411,7 +420,11 @@ CodecResult QuicReadCodec::parsePacket(
|
||||
uint8_t initialByte = cursor.readBE<uint8_t>();
|
||||
auto headerForm = getHeaderForm(initialByte);
|
||||
if (headerForm == HeaderForm::Long) {
|
||||
return parseLongHeaderPacket(queue, ackStates);
|
||||
auto result = parseLongHeaderPacket(queue, ackStates);
|
||||
if (result.hasError()) {
|
||||
return CodecResult(CodecError(std::move(result.error())));
|
||||
}
|
||||
return std::move(result.value());
|
||||
}
|
||||
// Missing 1-rtt header cipher is the only case we wouldn't consider reset
|
||||
if (!currentOneRttReadCipher_ || !oneRttHeaderCipher_) {
|
||||
@ -447,8 +460,12 @@ CodecResult QuicReadCodec::parsePacket(
|
||||
}
|
||||
}
|
||||
}
|
||||
return tryParseShortHeaderPacket(
|
||||
auto result = tryParseShortHeaderPacket(
|
||||
std::move(data), ackStates, dstConnIdSize, cursor);
|
||||
if (result.hasError()) {
|
||||
return CodecResult(CodecError(std::move(result.error())));
|
||||
}
|
||||
return std::move(result.value());
|
||||
}
|
||||
|
||||
bool QuicReadCodec::canInitiateKeyUpdate() const {
|
||||
|
@ -198,12 +198,12 @@ class QuicReadCodec {
|
||||
Optional<TimePoint> getHandshakeDoneTime();
|
||||
|
||||
private:
|
||||
CodecResult tryParseShortHeaderPacket(
|
||||
folly::Expected<CodecResult, QuicError> tryParseShortHeaderPacket(
|
||||
BufPtr data,
|
||||
const AckStates& ackStates,
|
||||
size_t dstConnIdSize,
|
||||
Cursor& cursor);
|
||||
CodecResult parseLongHeaderPacket(
|
||||
folly::Expected<CodecResult, QuicError> parseLongHeaderPacket(
|
||||
BufQueue& queue,
|
||||
const AckStates& ackStates);
|
||||
|
||||
|
@ -95,13 +95,19 @@ bool PacketGroupWriter::writeSingleQuicPacket(
|
||||
packetbuildBuf->prepend(headerLen);
|
||||
|
||||
HeaderForm headerForm = packet.packet.header.getHeaderForm();
|
||||
encryptPacketHeader(
|
||||
auto headerEncryptResult = encryptPacketHeader(
|
||||
headerForm,
|
||||
packetbuildBuf->writableData(),
|
||||
headerLen,
|
||||
packetbuildBuf->data() + headerLen,
|
||||
packetbuildBuf->length() - headerLen,
|
||||
headerCipher);
|
||||
if (headerEncryptResult.hasError()) {
|
||||
throw QuicInternalException(
|
||||
"DSR Send failed: Header encryption error: " +
|
||||
headerEncryptResult.error().message,
|
||||
LocalErrorCode::INTERNAL_ERROR);
|
||||
}
|
||||
CHECK(!packetbuildBuf->isChained());
|
||||
auto encodedSize = packetbuildBuf->length();
|
||||
// Include previous packets back.
|
||||
|
@ -68,7 +68,9 @@ class CipherBuilder {
|
||||
throw std::runtime_error("Failed to create header cipher");
|
||||
}
|
||||
auto headerCipher = std::move(headerCipherResult.value());
|
||||
headerCipher->setKey(packetProtectionKey->coalesce());
|
||||
if (headerCipher->setKey(packetProtectionKey->coalesce()).hasError()) {
|
||||
throw std::runtime_error("Failed to set header cipher key");
|
||||
}
|
||||
|
||||
return {std::move(aead), std::move(headerCipher)};
|
||||
}
|
||||
|
@ -77,7 +77,10 @@ FizzCryptoFactory::makePacketNumberCipher(ByteRange baseSecret) const {
|
||||
fizzFactory_->makeKeyDeriver(fizz::CipherSuite::TLS_AES_128_GCM_SHA256);
|
||||
auto pnKey = deriver->expandLabel(
|
||||
baseSecret, kQuicPNLabel, BufHelpers::create(0), pnCipher->keyLength());
|
||||
pnCipher->setKey(pnKey->coalesce());
|
||||
auto setKeyResult = pnCipher->setKey(pnKey->coalesce());
|
||||
if (setKeyResult.hasError()) {
|
||||
return folly::makeUnexpected(setKeyResult.error());
|
||||
}
|
||||
return pnCipher;
|
||||
}
|
||||
|
||||
|
@ -9,22 +9,26 @@
|
||||
|
||||
namespace quic {
|
||||
|
||||
static void setKeyImpl(
|
||||
static folly::Expected<folly::Unit, QuicError> setKeyImpl(
|
||||
folly::ssl::EvpCipherCtxUniquePtr& context,
|
||||
const EVP_CIPHER* cipher,
|
||||
ByteRange key) {
|
||||
DCHECK_EQ(key.size(), EVP_CIPHER_key_length(cipher));
|
||||
context.reset(EVP_CIPHER_CTX_new());
|
||||
if (context == nullptr) {
|
||||
throw std::runtime_error("Unable to allocate an EVP_CIPHER_CTX object");
|
||||
return folly::makeUnexpected(QuicError(
|
||||
TransportErrorCode::INTERNAL_ERROR,
|
||||
"Unable to allocate an EVP_CIPHER_CTX object"));
|
||||
}
|
||||
if (EVP_EncryptInit_ex(context.get(), cipher, nullptr, key.data(), nullptr) !=
|
||||
1) {
|
||||
throw std::runtime_error("Init error");
|
||||
return folly::makeUnexpected(
|
||||
QuicError(TransportErrorCode::INTERNAL_ERROR, "Init error"));
|
||||
}
|
||||
return folly::unit;
|
||||
}
|
||||
|
||||
static HeaderProtectionMask maskImpl(
|
||||
static folly::Expected<HeaderProtectionMask, QuicError> maskImpl(
|
||||
const folly::ssl::EvpCipherCtxUniquePtr& context,
|
||||
ByteRange sample) {
|
||||
HeaderProtectionMask outMask;
|
||||
@ -35,19 +39,22 @@ static HeaderProtectionMask maskImpl(
|
||||
outMask.data(),
|
||||
&outLen,
|
||||
sample.data(),
|
||||
sample.size()) != 1 ||
|
||||
static_cast<int>(sample.size())) != 1 ||
|
||||
static_cast<HeaderProtectionMask::size_type>(outLen) != outMask.size()) {
|
||||
throw std::runtime_error("Encryption error");
|
||||
return folly::makeUnexpected(
|
||||
QuicError(TransportErrorCode::INTERNAL_ERROR, "Encryption error"));
|
||||
}
|
||||
return outMask;
|
||||
}
|
||||
|
||||
void Aes128PacketNumberCipher::setKey(ByteRange key) {
|
||||
folly::Expected<folly::Unit, QuicError> Aes128PacketNumberCipher::setKey(
|
||||
ByteRange key) {
|
||||
pnKey_ = BufHelpers::copyBuffer(key);
|
||||
return setKeyImpl(encryptCtx_, EVP_aes_128_ecb(), key);
|
||||
}
|
||||
|
||||
void Aes256PacketNumberCipher::setKey(ByteRange key) {
|
||||
folly::Expected<folly::Unit, QuicError> Aes256PacketNumberCipher::setKey(
|
||||
ByteRange key) {
|
||||
pnKey_ = BufHelpers::copyBuffer(key);
|
||||
return setKeyImpl(encryptCtx_, EVP_aes_256_ecb(), key);
|
||||
}
|
||||
@ -60,11 +67,13 @@ const BufPtr& Aes256PacketNumberCipher::getKey() const {
|
||||
return pnKey_;
|
||||
}
|
||||
|
||||
HeaderProtectionMask Aes128PacketNumberCipher::mask(ByteRange sample) const {
|
||||
folly::Expected<HeaderProtectionMask, QuicError> Aes128PacketNumberCipher::mask(
|
||||
ByteRange sample) const {
|
||||
return maskImpl(encryptCtx_, sample);
|
||||
}
|
||||
|
||||
HeaderProtectionMask Aes256PacketNumberCipher::mask(ByteRange sample) const {
|
||||
folly::Expected<HeaderProtectionMask, QuicError> Aes256PacketNumberCipher::mask(
|
||||
ByteRange sample) const {
|
||||
return maskImpl(encryptCtx_, sample);
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,15 @@ class Aes128PacketNumberCipher : public PacketNumberCipher {
|
||||
public:
|
||||
~Aes128PacketNumberCipher() override = default;
|
||||
|
||||
void setKey(ByteRange key) override;
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> setKey(
|
||||
ByteRange key) override;
|
||||
|
||||
const BufPtr& getKey() const override;
|
||||
[[nodiscard]] const BufPtr& getKey() const override;
|
||||
|
||||
HeaderProtectionMask mask(ByteRange sample) const override;
|
||||
[[nodiscard]] folly::Expected<HeaderProtectionMask, QuicError> mask(
|
||||
ByteRange sample) const override;
|
||||
|
||||
size_t keyLength() const override;
|
||||
[[nodiscard]] size_t keyLength() const override;
|
||||
|
||||
private:
|
||||
folly::ssl::EvpCipherCtxUniquePtr encryptCtx_;
|
||||
@ -35,13 +37,15 @@ class Aes256PacketNumberCipher : public PacketNumberCipher {
|
||||
public:
|
||||
~Aes256PacketNumberCipher() override = default;
|
||||
|
||||
void setKey(ByteRange key) override;
|
||||
[[nodiscard]] folly::Expected<folly::Unit, QuicError> setKey(
|
||||
ByteRange key) override;
|
||||
|
||||
const BufPtr& getKey() const override;
|
||||
[[nodiscard]] const BufPtr& getKey() const override;
|
||||
|
||||
HeaderProtectionMask mask(ByteRange sample) const override;
|
||||
[[nodiscard]] folly::Expected<HeaderProtectionMask, QuicError> mask(
|
||||
ByteRange sample) const override;
|
||||
|
||||
size_t keyLength() const override;
|
||||
[[nodiscard]] size_t keyLength() const override;
|
||||
|
||||
private:
|
||||
folly::ssl::EvpCipherCtxUniquePtr encryptCtx_;
|
||||
|
@ -51,6 +51,7 @@ class FizzCryptoFactoryTest : public Test {
|
||||
EXPECT_CALL(*mockPacketNumberCipher, setKey(_))
|
||||
.WillOnce(Invoke([&](ByteRange key) {
|
||||
packetCipherKey_ = folly::IOBuf::copyBuffer(key);
|
||||
return folly::Expected<folly::Unit, QuicError>(folly::unit);
|
||||
}));
|
||||
EXPECT_CALL(*mockPacketNumberCipher, keyLength())
|
||||
.WillRepeatedly(Return(fizz::AESGCM128::kKeyLength));
|
||||
|
@ -66,23 +66,26 @@ TEST_P(LongPacketNumberCipherTest, TestEncryptDecrypt) {
|
||||
auto cipher = std::move(cipherResult.value());
|
||||
auto key = folly::unhexlify(GetParam().key);
|
||||
EXPECT_EQ(cipher->keyLength(), key.size());
|
||||
cipher->setKey(folly::range(key));
|
||||
auto setKeyResult = cipher->setKey(folly::range(key));
|
||||
ASSERT_FALSE(setKeyResult.hasError());
|
||||
EXPECT_TRUE(!memcmp(cipher->getKey()->data(), key.c_str(), key.size()));
|
||||
CipherBytes cipherBytes(
|
||||
GetParam().sample,
|
||||
GetParam().decryptedInitialByte,
|
||||
GetParam().decryptedPacketNumberBytes);
|
||||
cipher->encryptLongHeader(
|
||||
auto encryptResult = cipher->encryptLongHeader(
|
||||
cipherBytes.sample,
|
||||
folly::range(cipherBytes.initial),
|
||||
folly::range(cipherBytes.packetNumber));
|
||||
ASSERT_FALSE(encryptResult.hasError());
|
||||
EXPECT_EQ(folly::hexlify(cipherBytes.initial), GetParam().initialByte);
|
||||
EXPECT_EQ(
|
||||
folly::hexlify(cipherBytes.packetNumber), GetParam().packetNumberBytes);
|
||||
cipher->decryptLongHeader(
|
||||
auto decryptResult = cipher->decryptLongHeader(
|
||||
cipherBytes.sample,
|
||||
folly::range(cipherBytes.initial),
|
||||
folly::range(cipherBytes.packetNumber));
|
||||
ASSERT_FALSE(decryptResult.hasError());
|
||||
EXPECT_EQ(
|
||||
folly::hexlify(cipherBytes.initial), GetParam().decryptedInitialByte);
|
||||
EXPECT_EQ(
|
||||
|
@ -25,7 +25,9 @@ mvfst_cpp_library(
|
||||
],
|
||||
exported_deps = [
|
||||
":aead",
|
||||
"//folly:expected",
|
||||
"//quic:constants",
|
||||
"//quic:exception",
|
||||
"//quic/codec:packet_number_cipher",
|
||||
"//quic/codec:types",
|
||||
],
|
||||
@ -44,6 +46,7 @@ mvfst_cpp_library(
|
||||
"//quic/state:quic_state_machine",
|
||||
],
|
||||
exported_deps = [
|
||||
"//folly:expected",
|
||||
"//quic:constants",
|
||||
"//quic:exception",
|
||||
"//quic/codec:types",
|
||||
|
@ -8,7 +8,10 @@ mvfst_cpp_library(
|
||||
"Mocks.h",
|
||||
],
|
||||
exported_deps = [
|
||||
"//folly:expected",
|
||||
"//folly:unit",
|
||||
"//folly/portability:gmock",
|
||||
"//quic:exception",
|
||||
"//quic/codec:packet_number_cipher",
|
||||
"//quic/fizz/handshake:fizz_handshake",
|
||||
"//quic/handshake:aead",
|
||||
|
@ -7,7 +7,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <folly/Expected.h>
|
||||
#include <folly/Unit.h>
|
||||
#include <folly/portability/GMock.h>
|
||||
#include <quic/QuicException.h>
|
||||
#include <quic/codec/PacketNumberCipher.h>
|
||||
#include <quic/fizz/handshake/FizzCryptoFactory.h>
|
||||
#include <quic/handshake/Aead.h>
|
||||
@ -23,8 +26,15 @@ class MockPacketNumberCipher : public PacketNumberCipher {
|
||||
public:
|
||||
virtual ~MockPacketNumberCipher() = default;
|
||||
|
||||
MOCK_METHOD(void, setKey, (ByteRange key));
|
||||
MOCK_METHOD(HeaderProtectionMask, mask, (ByteRange), (const));
|
||||
MOCK_METHOD(
|
||||
(folly::Expected<folly::Unit, QuicError>),
|
||||
setKey,
|
||||
(ByteRange key));
|
||||
MOCK_METHOD(
|
||||
(folly::Expected<HeaderProtectionMask, QuicError>),
|
||||
mask,
|
||||
(ByteRange),
|
||||
(const));
|
||||
MOCK_METHOD(size_t, keyLength, (), (const));
|
||||
MOCK_METHOD(const BufPtr&, getKey, (), (const));
|
||||
|
||||
|
Reference in New Issue
Block a user