Skip to content

Commit

Permalink
Refactor AEGISCipher::doDecrypt
Browse files Browse the repository at this point in the history
Summary: Remove redundant code from AEGSICipher::doDecrypt and use the helper function CryptoUtils::DecryptHelper

Reviewed By: mingtaoy

Differential Revision: D54318326

fbshipit-source-id: 9a42b25643d51bf1f42f9e6a7b39e9cea008743e
  • Loading branch information
Huilin Chen authored and facebook-github-bot committed Mar 8, 2024
1 parent b0551ad commit 2c1956f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 75 deletions.
153 changes: 79 additions & 74 deletions fizz/crypto/aead/AEGISCipher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,81 +186,91 @@ folly::Optional<std::unique_ptr<folly::IOBuf>> AEGISCipher::doDecrypt(
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,
folly::ByteRange iv,
folly::ByteRange key,
folly::MutableByteRange tagOut,
bool inPlace) const {
const uint8_t* adData = nullptr;
size_t adLen = 0;
std::unique_ptr<folly::IOBuf> ad;
if (associatedData) {
if (associatedData->isChained()) {
ad = associatedData->cloneCoalesced();
adData = ad->data();
adLen = ad->length();
} else {
adData = associatedData->data();
adLen = associatedData->length();
}
}
struct AeadImpl {
const AEGISCipher& self;

auto inputLength = ciphertext->computeChainDataLength();
// the stateInit function will skip adding aad to the state when adData is
// null and adLen is 0
impl_->stateInit(adData, adLen, iv.data(), key.data(), inputLength);

folly::IOBuf* input;
std::unique_ptr<folly::IOBuf> output;
if (!inPlace) {
output = folly::IOBuf::create(inputLength);
output->append(inputLength);
input = ciphertext.get();
} else {
output = std::move(ciphertext);
input = output.get();
}
explicit AeadImpl(const AEGISCipher& s) : self(s) {}
void init(
folly::ByteRange iv,
const folly::IOBuf* associatedData,
size_t ciphertextLength) {
const uint8_t* adData = nullptr;
size_t adLen = 0;
std::unique_ptr<folly::IOBuf> ad;
if (associatedData) {
if (associatedData->isChained()) {
ad = associatedData->cloneCoalesced();
adData = ad->data();
adLen = ad->length();
} else {
adData = associatedData->data();
adLen = associatedData->length();
}
}

struct Impl {
const AEGISCipher& self;
const unsigned char* expectedTag{nullptr};

explicit Impl(const AEGISCipher& s) : self(s) {}
bool decryptUpdate(
uint8_t* plain,
const uint8_t* cipher,
size_t len,
int* outLen) {
size_t tempOutLen;
auto ret = self.impl_->decryptUpdate(plain, &tempOutLen, cipher, len);
*outLen = static_cast<int>(tempOutLen);
return ret == 0;
}
bool setExpectedTag(int /*tagSize*/, const unsigned char* tag) {
this->expectedTag = tag;
return true;
// the stateInit function will skip adding aad to the state when adData is
// null and adLen is 0
// @lint-ignore CLANGTIDY facebook-hte-NullableDereference
self.impl_->stateInit(
adData,
adLen,
iv.data(),
self.trafficKeyKey_.data(),
ciphertextLength);
}
bool decryptFinal(unsigned char* outm, int* outLen) {
size_t tempOutLen;
auto ret =
self.impl_->decryptFinal(outm, &tempOutLen, expectedTag, kTagLength);
*outLen = static_cast<int>(tempOutLen);
return ret == 0;

bool decryptAndFinal(
folly::IOBuf& ciphertext,
folly::IOBuf& plaintext,
folly::MutableByteRange tagOut) {
struct EVPDecImpl {
const AEGISCipher& self;
const unsigned char* expectedTag{nullptr};

explicit EVPDecImpl(const AEGISCipher& s) : self(s) {}
bool decryptUpdate(
uint8_t* plain,
const uint8_t* cipher,
size_t len,
int* outLen) {
size_t tempOutLen;
auto ret = self.impl_->decryptUpdate(plain, &tempOutLen, cipher, len);
*outLen = static_cast<int>(tempOutLen);
return ret == 0;
}
bool setExpectedTag(int /*tagSize*/, const unsigned char* tag) {
this->expectedTag = tag;
return true;
}
bool decryptFinal(unsigned char* outm, int* outLen) {
size_t tempOutLen;
auto ret = self.impl_->decryptFinal(
outm, &tempOutLen, expectedTag, kTagLength);
*outLen = static_cast<int>(tempOutLen);
return ret == 0;
}
};

if (self.mms_ == AEGISCipher::kAEGIS128LMMS) {
return decFuncBlocks<AEGISCipher::kAEGIS128LMMS>(
EVPDecImpl(self), ciphertext, plaintext, tagOut);
} else if (self.mms_ == AEGISCipher::kAEGIS256MMS) {
return decFuncBlocks<AEGISCipher::kAEGIS256MMS>(
EVPDecImpl(self), ciphertext, plaintext, tagOut);
} else {
throw std::runtime_error("Unsupported AEGIS state size");
}
}
};

bool decrypted;
if (mms_ == AEGISCipher::kAEGIS128LMMS) {
decrypted = decFuncBlocks<AEGISCipher::kAEGIS128LMMS>(
Impl(*this), *input, *output, tagOut);
} else if (mms_ == AEGISCipher::kAEGIS256MMS) {
decrypted = decFuncBlocks<AEGISCipher::kAEGIS256MMS>(
Impl(*this), *input, *output, tagOut);
} else {
throw std::runtime_error("Unsupported AEGIS state size");
}
if (!decrypted) {
return folly::none;
}
return output;
return decryptHelper(
AeadImpl{*this},
std::move(ciphertext),
associatedData,
iv,
tagOut,
inPlace);
}

AEGISCipher::AEGISCipher(
Expand Down Expand Up @@ -414,12 +424,7 @@ folly::Optional<std::unique_ptr<folly::IOBuf>> AEGISCipher::tryDecrypt(
trimBytes(*ciphertext, tagOut);
}
return doDecrypt(
std::move(ciphertext),
associatedData,
nonce,
trafficKeyKey_,
tagOut,
inPlace);
std::move(ciphertext), associatedData, nonce, tagOut, inPlace);
}

size_t AEGISCipher::getCipherOverhead() const {
Expand Down
1 change: 0 additions & 1 deletion fizz/crypto/aead/AEGISCipher.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ class AEGISCipher : public Aead {
std::unique_ptr<folly::IOBuf>&& ciphertext,
const folly::IOBuf* associatedData,
folly::ByteRange iv,
folly::ByteRange key,
folly::MutableByteRange tagOut,
bool inPlace) const;

Expand Down

0 comments on commit 2c1956f

Please sign in to comment.