EaR: Helper routines to support configurable encryption (#9368)
* EaR: Helper routines to support configurable encryption Description Add helper methods to BlobCipherEncryptHeaderRef enabling: 1. Extract 'IV' abstracting out underlying algorithm header 1. Extract 'cipherDetails' abstracting out underlying algorithm header Testing BlobCipherUnitTest & EncryptionOps are updated - 100K loop * EaR: Helper routines to support configurable encryption Description Add helper methods to BlobCipherEncryptHeaderRef enabling: 1. Extract 'IV' abstracting out underlying algorithm header 1. Extract 'cipherDetails' abstracting out underlying algorithm header Testing BlobCipherUnitTest & EncryptionOps are updated - 100K loop
This commit is contained in:
parent
05e73b7836
commit
401b9c8918
|
@ -60,6 +60,58 @@
|
||||||
#define BLOB_CIPHER_DEBUG false
|
#define BLOB_CIPHER_DEBUG false
|
||||||
#define BLOB_CIPHER_SERIALIZATION_CHECKS false
|
#define BLOB_CIPHER_SERIALIZATION_CHECKS false
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void validateEncryptHeaderFlagVersion(const int flagsVersion) {
|
||||||
|
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
||||||
|
|
||||||
|
if (flagsVersion > CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION) {
|
||||||
|
TraceEvent("EncryptHeaderUnsupportedFlagVersion")
|
||||||
|
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION)
|
||||||
|
.detail("Version", flagsVersion);
|
||||||
|
throw not_implemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void validateEncryptHeaderAlgoHeaderVersion(const EncryptCipherMode cipherMode,
|
||||||
|
const EncryptAuthTokenMode authMode,
|
||||||
|
const EncryptAuthTokenAlgo authAlgo,
|
||||||
|
const int version) {
|
||||||
|
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
||||||
|
|
||||||
|
if (cipherMode != ENCRYPT_CIPHER_MODE_AES_256_CTR) {
|
||||||
|
TraceEvent("EncryptHeaderUnsupportedEncryptCipherMode")
|
||||||
|
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION)
|
||||||
|
.detail("CipherMode", cipherMode);
|
||||||
|
throw not_implemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxSupportedVersion = -1;
|
||||||
|
if (authMode == ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE) {
|
||||||
|
maxSupportedVersion = CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_NO_AUTH_VERSION;
|
||||||
|
} else {
|
||||||
|
ASSERT_EQ(authMode, ENCRYPT_HEADER_AUTH_TOKEN_MODE_SINGLE);
|
||||||
|
|
||||||
|
if (authAlgo == ENCRYPT_HEADER_AUTH_TOKEN_ALGO_HMAC_SHA) {
|
||||||
|
maxSupportedVersion = CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_HMAC_SHA_AUTH_VERSION;
|
||||||
|
} else if (authAlgo == ENCRYPT_HEADER_AUTH_TOKEN_ALGO_AES_CMAC) {
|
||||||
|
maxSupportedVersion = CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_AES_CMAC_AUTH_VERSION;
|
||||||
|
} else {
|
||||||
|
// Unknown encryption authentication algo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version > maxSupportedVersion || maxSupportedVersion == -1) {
|
||||||
|
TraceEvent("EncryptHeaderUnsupportedEncryptAuthToken")
|
||||||
|
.detail("CipherMode", cipherMode)
|
||||||
|
.detail("AuthMode", authMode)
|
||||||
|
.detail("AuthAlgo", authAlgo)
|
||||||
|
.detail("AlgoHeaderVersion", version)
|
||||||
|
.detail("MaxSsupportedVersion", maxSupportedVersion);
|
||||||
|
throw not_implemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
// BlobCipherEncryptHeaderRef
|
// BlobCipherEncryptHeaderRef
|
||||||
|
|
||||||
uint32_t BlobCipherEncryptHeaderRef::getHeaderSize(const int flagVersion,
|
uint32_t BlobCipherEncryptHeaderRef::getHeaderSize(const int flagVersion,
|
||||||
|
@ -91,62 +143,93 @@ uint32_t BlobCipherEncryptHeaderRef::getHeaderSize(const int flagVersion,
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t* BlobCipherEncryptHeaderRef::getIV() const {
|
||||||
|
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
||||||
|
|
||||||
|
validateEncryptHeaderFlagVersion(flagsVersion);
|
||||||
|
ASSERT_EQ(flagsVersion, 1);
|
||||||
|
|
||||||
|
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(this->flags);
|
||||||
|
|
||||||
|
validateEncryptHeaderAlgoHeaderVersion((EncryptCipherMode)flags.encryptMode,
|
||||||
|
(EncryptAuthTokenMode)flags.authTokenMode,
|
||||||
|
(EncryptAuthTokenAlgo)flags.authTokenAlgo,
|
||||||
|
algoHeaderVersion);
|
||||||
|
ASSERT_EQ(algoHeaderVersion, 1);
|
||||||
|
|
||||||
|
return std::visit([](auto& h) { return h.iv; }, algoHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
inline constexpr bool always_false_v = false;
|
||||||
|
|
||||||
|
const EncryptHeaderCipherDetails BlobCipherEncryptHeaderRef::getCipherDetails() const {
|
||||||
|
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
||||||
|
|
||||||
|
validateEncryptHeaderFlagVersion(flagsVersion);
|
||||||
|
ASSERT_EQ(flagsVersion, 1);
|
||||||
|
|
||||||
|
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(this->flags);
|
||||||
|
|
||||||
|
validateEncryptHeaderAlgoHeaderVersion((EncryptCipherMode)flags.encryptMode,
|
||||||
|
(EncryptAuthTokenMode)flags.authTokenMode,
|
||||||
|
(EncryptAuthTokenAlgo)flags.authTokenAlgo,
|
||||||
|
algoHeaderVersion);
|
||||||
|
ASSERT_EQ(algoHeaderVersion, 1);
|
||||||
|
|
||||||
|
// TODO: Replace with "Overload visitor pattern" someday.
|
||||||
|
return std::visit(
|
||||||
|
[](auto&& h) {
|
||||||
|
using T = std::decay_t<decltype(h)>;
|
||||||
|
if constexpr (std::is_same_v<T, AesCtrNoAuthV1>) {
|
||||||
|
return EncryptHeaderCipherDetails(h.cipherTextDetails);
|
||||||
|
} else if constexpr (std::is_same_v<T, AesCtrWithAuthV1<AUTH_TOKEN_HMAC_SHA_SIZE>> ||
|
||||||
|
std::is_same_v<T, AesCtrWithAuthV1<AUTH_TOKEN_AES_CMAC_SIZE>>) {
|
||||||
|
return EncryptHeaderCipherDetails(h.cipherTextDetails, h.cipherHeaderDetails);
|
||||||
|
} else {
|
||||||
|
static_assert(always_false_v<T>, "Unknown encryption authentication");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
algoHeader);
|
||||||
|
}
|
||||||
|
|
||||||
void BlobCipherEncryptHeaderRef::validateEncryptionHeaderDetails(const BlobCipherDetails& textCipherDetails,
|
void BlobCipherEncryptHeaderRef::validateEncryptionHeaderDetails(const BlobCipherDetails& textCipherDetails,
|
||||||
const BlobCipherDetails& headerCipherDetails,
|
const BlobCipherDetails& headerCipherDetails,
|
||||||
const StringRef& ivRef) const {
|
const StringRef& ivRef) const {
|
||||||
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
ASSERT(CLIENT_KNOBS->ENABLE_CONFIGURABLE_ENCRYPTION);
|
||||||
|
|
||||||
if (flagsVersion > CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION) {
|
validateEncryptHeaderFlagVersion(flagsVersion);
|
||||||
TraceEvent("ValidateEncryptHeaderUnsupportedFlagVersion")
|
ASSERT_EQ(flagsVersion, 1);
|
||||||
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION)
|
|
||||||
.detail("Version", flagsVersion);
|
|
||||||
throw not_implemented();
|
|
||||||
}
|
|
||||||
|
|
||||||
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(this->flags);
|
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(this->flags);
|
||||||
|
|
||||||
|
validateEncryptHeaderAlgoHeaderVersion((EncryptCipherMode)flags.encryptMode,
|
||||||
|
(EncryptAuthTokenMode)flags.authTokenMode,
|
||||||
|
(EncryptAuthTokenAlgo)flags.authTokenAlgo,
|
||||||
|
algoHeaderVersion);
|
||||||
|
ASSERT_EQ(algoHeaderVersion, 1);
|
||||||
|
|
||||||
BlobCipherDetails persistedTextCipherDetails;
|
BlobCipherDetails persistedTextCipherDetails;
|
||||||
BlobCipherDetails persistedHeaderCipherDetails;
|
BlobCipherDetails persistedHeaderCipherDetails;
|
||||||
uint8_t* persistedIV = nullptr;
|
uint8_t* persistedIV = nullptr;
|
||||||
|
|
||||||
if (flags.authTokenMode == ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE) {
|
// TODO: Replace with "Overload visitor pattern" someday.
|
||||||
if (algoHeaderVersion > CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_NO_AUTH_VERSION) {
|
return std::visit(
|
||||||
TraceEvent("ValidateEncryptHeaderUnsupportedAlgoHeaderVersion")
|
[&persistedTextCipherDetails, &persistedHeaderCipherDetails, &persistedIV](auto&& h) {
|
||||||
.detail("AuthMode", "No-Auth")
|
using T = std::decay_t<decltype(h)>;
|
||||||
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_NO_AUTH_VERSION)
|
if constexpr (std::is_same_v<T, AesCtrNoAuthV1>) {
|
||||||
.detail("Version", algoHeaderVersion);
|
persistedTextCipherDetails = h.cipherTextDetails;
|
||||||
throw not_implemented();
|
persistedIV = (uint8_t*)&h.iv[0];
|
||||||
}
|
} else if constexpr (std::is_same_v<T, AesCtrWithAuthV1<AUTH_TOKEN_HMAC_SHA_SIZE>> ||
|
||||||
persistedTextCipherDetails = std::get<AesCtrNoAuthV1>(this->algoHeader).cipherTextDetails;
|
std::is_same_v<T, AesCtrWithAuthV1<AUTH_TOKEN_AES_CMAC_SIZE>>) {
|
||||||
persistedIV = (uint8_t*)(&std::get<AesCtrNoAuthV1>(this->algoHeader).iv[0]);
|
persistedTextCipherDetails = h.cipherTextDetails;
|
||||||
} else {
|
persistedHeaderCipherDetails = h.cipherHeaderDetails;
|
||||||
if (flags.authTokenAlgo == ENCRYPT_HEADER_AUTH_TOKEN_ALGO_HMAC_SHA) {
|
persistedIV = (uint8_t*)&h.iv[0];
|
||||||
if (algoHeaderVersion > CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_NO_AUTH_VERSION) {
|
} else {
|
||||||
TraceEvent("ValidateEncryptHeaderUnsupportedAlgoHeaderVersion")
|
static_assert(always_false_v<T>, "Unknown encryption authentication");
|
||||||
.detail("AuthMode", "Hmac-Sha")
|
}
|
||||||
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_HMAC_SHA_AUTH_VERSION)
|
},
|
||||||
.detail("Version", algoHeaderVersion);
|
algoHeader);
|
||||||
}
|
|
||||||
persistedTextCipherDetails =
|
|
||||||
std::get<AesCtrWithAuthV1<AUTH_TOKEN_HMAC_SHA_SIZE>>(this->algoHeader).cipherTextDetails;
|
|
||||||
persistedHeaderCipherDetails =
|
|
||||||
std::get<AesCtrWithAuthV1<AUTH_TOKEN_HMAC_SHA_SIZE>>(this->algoHeader).cipherHeaderDetails;
|
|
||||||
persistedIV = (uint8_t*)(&std::get<AesCtrWithAuthV1<AUTH_TOKEN_HMAC_SHA_SIZE>>(this->algoHeader).iv[0]);
|
|
||||||
} else if (flags.authTokenAlgo == ENCRYPT_HEADER_AUTH_TOKEN_ALGO_AES_CMAC) {
|
|
||||||
if (algoHeaderVersion > CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_AES_CMAC_AUTH_VERSION) {
|
|
||||||
TraceEvent("ValidateEncryptHeaderUnsupportedAlgoHeaderVersion")
|
|
||||||
.detail("AuthMode", "Aes-Cmac")
|
|
||||||
.detail("MaxSupportedVersion", CLIENT_KNOBS->ENCRYPT_HEADER_AES_CTR_AES_CMAC_AUTH_VERSION)
|
|
||||||
.detail("Version", algoHeaderVersion);
|
|
||||||
}
|
|
||||||
persistedTextCipherDetails =
|
|
||||||
std::get<AesCtrWithAuthV1<AUTH_TOKEN_AES_CMAC_SIZE>>(this->algoHeader).cipherTextDetails;
|
|
||||||
persistedHeaderCipherDetails =
|
|
||||||
std::get<AesCtrWithAuthV1<AUTH_TOKEN_AES_CMAC_SIZE>>(this->algoHeader).cipherHeaderDetails;
|
|
||||||
persistedIV = (uint8_t*)(&std::get<AesCtrWithAuthV1<AUTH_TOKEN_AES_CMAC_SIZE>>(this->algoHeader).iv[0]);
|
|
||||||
} else {
|
|
||||||
throw not_implemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate encryption header 'cipherHeader' details sanity
|
// Validate encryption header 'cipherHeader' details sanity
|
||||||
if (flags.authTokenMode != ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE &&
|
if (flags.authTokenMode != ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE &&
|
||||||
|
@ -1808,8 +1891,17 @@ void testConfigurableEncryptionHeaderNoAuthMode(const int minDomainId) {
|
||||||
|
|
||||||
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(headerRef.flags);
|
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(headerRef.flags);
|
||||||
AesCtrNoAuthV1 noAuth = std::get<AesCtrNoAuthV1>(headerRef.algoHeader);
|
AesCtrNoAuthV1 noAuth = std::get<AesCtrNoAuthV1>(headerRef.algoHeader);
|
||||||
Standalone<StringRef> serHeaderRef = BlobCipherEncryptHeaderRef::toStringRef(headerRef);
|
|
||||||
|
|
||||||
|
const uint8_t* headerIV = headerRef.getIV();
|
||||||
|
ASSERT_EQ(memcmp(&headerIV[0], &iv[0], AES_256_IV_LENGTH), 0);
|
||||||
|
|
||||||
|
EncryptHeaderCipherDetails validateDetails = headerRef.getCipherDetails();
|
||||||
|
ASSERT(validateDetails.textCipherDetails.isValid() &&
|
||||||
|
validateDetails.textCipherDetails ==
|
||||||
|
BlobCipherDetails(cipherKey->getDomainId(), cipherKey->getBaseCipherId(), cipherKey->getSalt()));
|
||||||
|
ASSERT(!validateDetails.headerCipherDetails.present());
|
||||||
|
|
||||||
|
Standalone<StringRef> serHeaderRef = BlobCipherEncryptHeaderRef::toStringRef(headerRef);
|
||||||
BlobCipherEncryptHeaderRef validateHeader = BlobCipherEncryptHeaderRef::fromStringRef(serHeaderRef);
|
BlobCipherEncryptHeaderRef validateHeader = BlobCipherEncryptHeaderRef::fromStringRef(serHeaderRef);
|
||||||
BlobCipherEncryptHeaderFlagsV1 validateFlags = std::get<BlobCipherEncryptHeaderFlagsV1>(validateHeader.flags);
|
BlobCipherEncryptHeaderFlagsV1 validateFlags = std::get<BlobCipherEncryptHeaderFlagsV1>(validateHeader.flags);
|
||||||
ASSERT(validateFlags == flags);
|
ASSERT(validateFlags == flags);
|
||||||
|
@ -2093,8 +2185,20 @@ void testConfigurableEncryptionHeaderSingleAuthMode(int minDomainId) {
|
||||||
|
|
||||||
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(headerRef.flags);
|
BlobCipherEncryptHeaderFlagsV1 flags = std::get<BlobCipherEncryptHeaderFlagsV1>(headerRef.flags);
|
||||||
AesCtrWithAuthV1<AuthTokenSize> algoHeader = std::get<AesCtrWithAuthV1<AuthTokenSize>>(headerRef.algoHeader);
|
AesCtrWithAuthV1<AuthTokenSize> algoHeader = std::get<AesCtrWithAuthV1<AuthTokenSize>>(headerRef.algoHeader);
|
||||||
Standalone<StringRef> serHeaderRef = BlobCipherEncryptHeaderRef::toStringRef(headerRef);
|
|
||||||
|
|
||||||
|
const uint8_t* headerIV = headerRef.getIV();
|
||||||
|
ASSERT_EQ(memcmp(&headerIV[0], &iv[0], AES_256_IV_LENGTH), 0);
|
||||||
|
|
||||||
|
EncryptHeaderCipherDetails validateDetails = headerRef.getCipherDetails();
|
||||||
|
ASSERT(validateDetails.textCipherDetails.isValid() &&
|
||||||
|
validateDetails.textCipherDetails ==
|
||||||
|
BlobCipherDetails(cipherKey->getDomainId(), cipherKey->getBaseCipherId(), cipherKey->getSalt()));
|
||||||
|
ASSERT(validateDetails.headerCipherDetails.present() && validateDetails.headerCipherDetails.get().isValid() &&
|
||||||
|
validateDetails.headerCipherDetails.get() == BlobCipherDetails(headerCipherKey->getDomainId(),
|
||||||
|
headerCipherKey->getBaseCipherId(),
|
||||||
|
headerCipherKey->getSalt()));
|
||||||
|
|
||||||
|
Standalone<StringRef> serHeaderRef = BlobCipherEncryptHeaderRef::toStringRef(headerRef);
|
||||||
BlobCipherEncryptHeaderRef validateHeader = BlobCipherEncryptHeaderRef::fromStringRef(serHeaderRef);
|
BlobCipherEncryptHeaderRef validateHeader = BlobCipherEncryptHeaderRef::fromStringRef(serHeaderRef);
|
||||||
BlobCipherEncryptHeaderFlagsV1 validateFlags = std::get<BlobCipherEncryptHeaderFlagsV1>(validateHeader.flags);
|
BlobCipherEncryptHeaderFlagsV1 validateFlags = std::get<BlobCipherEncryptHeaderFlagsV1>(validateHeader.flags);
|
||||||
ASSERT(validateFlags == flags);
|
ASSERT(validateFlags == flags);
|
||||||
|
@ -2105,7 +2209,7 @@ void testConfigurableEncryptionHeaderSingleAuthMode(int minDomainId) {
|
||||||
ASSERT_EQ(memcmp(&iv[0], &validateAlgo.iv[0], AES_256_IV_LENGTH), 0);
|
ASSERT_EQ(memcmp(&iv[0], &validateAlgo.iv[0], AES_256_IV_LENGTH), 0);
|
||||||
ASSERT_EQ(memcmp(&algoHeader.authToken[0], &validateAlgo.authToken[0], AuthTokenSize), 0);
|
ASSERT_EQ(memcmp(&algoHeader.authToken[0], &validateAlgo.authToken[0], AuthTokenSize), 0);
|
||||||
|
|
||||||
TraceEvent("HmacShaHeaderSize")
|
TraceEvent("HeaderSize")
|
||||||
.detail("Flags", sizeof(flags))
|
.detail("Flags", sizeof(flags))
|
||||||
.detail("AlgoHeader", sizeof(algoHeader))
|
.detail("AlgoHeader", sizeof(algoHeader))
|
||||||
.detail("TotalHeader", serHeaderRef.size());
|
.detail("TotalHeader", serHeaderRef.size());
|
||||||
|
|
|
@ -174,6 +174,11 @@ struct BlobCipherDetails {
|
||||||
}
|
}
|
||||||
bool operator!=(const BlobCipherDetails& o) const { return !(*this == o); }
|
bool operator!=(const BlobCipherDetails& o) const { return !(*this == o); }
|
||||||
|
|
||||||
|
bool isValid() const {
|
||||||
|
return this->encryptDomainId != INVALID_ENCRYPT_DOMAIN_ID &&
|
||||||
|
this->baseCipherId != INVALID_ENCRYPT_CIPHER_KEY_ID && this->salt != INVALID_ENCRYPT_RANDOM_SALT;
|
||||||
|
}
|
||||||
|
|
||||||
template <class Ar>
|
template <class Ar>
|
||||||
void serialize(Ar& ar) {
|
void serialize(Ar& ar) {
|
||||||
serializer(ar, encryptDomainId, baseCipherId, salt);
|
serializer(ar, encryptDomainId, baseCipherId, salt);
|
||||||
|
@ -333,6 +338,15 @@ struct AesCtrNoAuthV1 {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EncryptHeaderCipherDetails {
|
||||||
|
BlobCipherDetails textCipherDetails;
|
||||||
|
Optional<BlobCipherDetails> headerCipherDetails;
|
||||||
|
|
||||||
|
EncryptHeaderCipherDetails(const BlobCipherDetails& tCipherDetails) : textCipherDetails(tCipherDetails) {}
|
||||||
|
EncryptHeaderCipherDetails(const BlobCipherDetails& tCipherDetails, const BlobCipherDetails& hCipherDetails)
|
||||||
|
: textCipherDetails(tCipherDetails), headerCipherDetails(hCipherDetails) {}
|
||||||
|
};
|
||||||
|
|
||||||
struct BlobCipherEncryptHeaderRef {
|
struct BlobCipherEncryptHeaderRef {
|
||||||
// Serializable fields
|
// Serializable fields
|
||||||
|
|
||||||
|
@ -460,6 +474,9 @@ struct BlobCipherEncryptHeaderRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint8_t* getIV() const;
|
||||||
|
const EncryptHeaderCipherDetails getCipherDetails() const;
|
||||||
|
|
||||||
void validateEncryptionHeaderDetails(const BlobCipherDetails& textCipherDetails,
|
void validateEncryptionHeaderDetails(const BlobCipherDetails& textCipherDetails,
|
||||||
const BlobCipherDetails& headerCipherDetails,
|
const BlobCipherDetails& headerCipherDetails,
|
||||||
const StringRef& ivRef) const;
|
const StringRef& ivRef) const;
|
||||||
|
|
|
@ -315,6 +315,24 @@ struct EncryptionOpsWorkload : TestWorkload {
|
||||||
auto end = std::chrono::high_resolution_clock::now();
|
auto end = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
// validate encrypted buffer size and contents (not matching with plaintext)
|
// validate encrypted buffer size and contents (not matching with plaintext)
|
||||||
|
const uint8_t* headerIV = headerRef->getIV();
|
||||||
|
ASSERT_EQ(memcmp(&headerIV[0], &iv[0], AES_256_IV_LENGTH), 0);
|
||||||
|
|
||||||
|
EncryptHeaderCipherDetails validateDetails = headerRef->getCipherDetails();
|
||||||
|
ASSERT(validateDetails.textCipherDetails.isValid() &&
|
||||||
|
validateDetails.textCipherDetails == BlobCipherDetails(textCipherKey->getDomainId(),
|
||||||
|
textCipherKey->getBaseCipherId(),
|
||||||
|
textCipherKey->getSalt()));
|
||||||
|
if (authMode == ENCRYPT_HEADER_AUTH_TOKEN_MODE_NONE) {
|
||||||
|
ASSERT(!validateDetails.headerCipherDetails.present());
|
||||||
|
} else {
|
||||||
|
ASSERT(validateDetails.headerCipherDetails.present() &&
|
||||||
|
validateDetails.headerCipherDetails.get().isValid() &&
|
||||||
|
validateDetails.headerCipherDetails.get() == BlobCipherDetails(headerCipherKey->getDomainId(),
|
||||||
|
headerCipherKey->getBaseCipherId(),
|
||||||
|
headerCipherKey->getSalt()));
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_EQ(encrypted.size(), len);
|
ASSERT_EQ(encrypted.size(), len);
|
||||||
ASSERT_EQ(headerRef->flagsVersion, CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION);
|
ASSERT_EQ(headerRef->flagsVersion, CLIENT_KNOBS->ENCRYPT_HEADER_FLAGS_VERSION);
|
||||||
ASSERT_NE(memcmp(encrypted.begin(), payload, len), 0);
|
ASSERT_NE(memcmp(encrypted.begin(), payload, len), 0);
|
||||||
|
|
Loading…
Reference in New Issue