12 std::unique_ptr<folly::IOBuf>&& ciphertext,
17 EVP_CIPHER_CTX* decryptCtx);
20 std::unique_ptr<folly::IOBuf>&& plaintext,
26 EVP_CIPHER_CTX* encryptCtx);
29 template <
typename EVPImpl>
31 encryptCtx_.reset(EVP_CIPHER_CTX_new());
32 if (encryptCtx_ ==
nullptr) {
33 throw std::runtime_error(
"Unable to allocate an EVP_CIPHER_CTX object");
35 decryptCtx_.reset(EVP_CIPHER_CTX_new());
36 if (decryptCtx_ ==
nullptr) {
37 throw std::runtime_error(
"Unable to allocate an EVP_CIPHER_CTX object");
39 if (EVP_EncryptInit_ex(
40 encryptCtx_.get(), EVPImpl::Cipher(),
nullptr,
nullptr,
nullptr) !=
42 throw std::runtime_error(
"Init error");
44 if (EVP_CIPHER_CTX_ctrl(
46 EVP_CTRL_GCM_SET_IVLEN,
49 throw std::runtime_error(
"Error setting iv length");
51 if (EVP_DecryptInit_ex(
52 decryptCtx_.get(), EVPImpl::Cipher(),
nullptr,
nullptr,
nullptr) !=
54 throw std::runtime_error(
"Init error");
56 if (EVP_CIPHER_CTX_ctrl(
58 EVP_CTRL_GCM_SET_IVLEN,
61 throw std::runtime_error(
"Error setting iv length");
64 if (EVPImpl::kRequiresPresetTagLen) {
65 if (EVP_CIPHER_CTX_ctrl(
70 throw std::runtime_error(
"Error setting enc tag length");
73 if (EVP_CIPHER_CTX_ctrl(
78 throw std::runtime_error(
"Error setting dec tag length");
83 template <
typename EVPImpl>
85 trafficKey.
key->coalesce();
86 trafficKey.
iv->coalesce();
87 if (trafficKey.
key->length() != EVPImpl::kKeyLength) {
88 throw std::runtime_error(
"Invalid key");
90 if (trafficKey.
iv->length() != EVPImpl::kIVLength) {
91 throw std::runtime_error(
"Invalid IV");
94 if (EVP_EncryptInit_ex(
98 trafficKey_.key->data(),
100 throw std::runtime_error(
"Error setting encrypt key");
102 if (EVP_DecryptInit_ex(
106 trafficKey_.key->data(),
108 throw std::runtime_error(
"Error setting decrypt key");
112 template <
typename EVPImpl>
114 std::unique_ptr<folly::IOBuf>&& plaintext,
117 auto iv = createIV(seqNum);
123 EVPImpl::kOperatesInBlocks,
128 template <
typename EVPImpl>
131 std::unique_ptr<folly::IOBuf>&& ciphertext,
134 auto iv = createIV(seqNum);
136 std::array<uint8_t, EVPImpl::kTagLength> tagData;
143 EVPImpl::kOperatesInBlocks,
147 template <
typename EVPImpl>
149 return EVPImpl::kTagLength;
152 template <
typename EVPImpl>
155 std::array<uint8_t, EVPImpl::kIVLength> iv;
157 const size_t prefixLength = EVPImpl::kIVLength -
sizeof(
uint64_t);
158 memset(iv.data(), 0, prefixLength);
159 memcpy(iv.data() + prefixLength, &bigEndianSeqNum, 8);
std::unique_ptr< folly::IOBuf > encrypt(std::unique_ptr< folly::IOBuf > &&plaintext, const folly::IOBuf *associatedData, uint64_t seqNum) const override
constexpr detail::Map< Move > move
std::unique_ptr< folly::IOBuf > key
std::unique_ptr< folly::IOBuf > iv
void XOR(ByteRange first, MutableByteRange second)
constexpr Range< Iter > range(Iter first, Iter last)
std::array< uint8_t, EVPImpl::kIVLength > createIV(uint64_t seqNum) const
folly::Optional< std::unique_ptr< folly::IOBuf > > tryDecrypt(std::unique_ptr< folly::IOBuf > &&ciphertext, const folly::IOBuf *associatedData, uint64_t seqNum) const override
std::unique_ptr< folly::IOBuf > evpEncrypt(std::unique_ptr< folly::IOBuf > &&plaintext, const folly::IOBuf *associatedData, folly::ByteRange iv, size_t tagLen, bool useBlockOps, size_t headroom, EVP_CIPHER_CTX *encryptCtx)
void setKey(TrafficKey trafficKey) override
size_t getCipherOverhead() const override
folly::Optional< std::unique_ptr< folly::IOBuf > > evpDecrypt(std::unique_ptr< folly::IOBuf > &&ciphertext, const folly::IOBuf *associatedData, folly::ByteRange iv, folly::MutableByteRange tag, bool useBlockOps, EVP_CIPHER_CTX *decryptCtx)