Refactor td::AesState::Impl
GitOrigin-RevId: 5731ddc8d85c912cbfb141bd4e5eefea22d8ab21
This commit is contained in:
parent
86ca096840
commit
005611e924
@ -211,9 +211,9 @@ class AesIgeShortBench : public td::Benchmark {
|
||||
|
||||
void run(int n) override {
|
||||
td::MutableSlice data_slice(data, SHORT_DATA_SIZE);
|
||||
td::AesIgeState ige;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (use_state) {
|
||||
td::AesIgeState ige;
|
||||
ige.init(as_slice(key), as_slice(iv), false);
|
||||
ige.decrypt(data_slice, data_slice);
|
||||
} else {
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
#include "td/utils/crypto.h"
|
||||
|
||||
#include "td/utils/Slice-decl.h"
|
||||
#include "td/utils/as.h"
|
||||
#include "td/utils/BigNum.h"
|
||||
#include "td/utils/common.h"
|
||||
@ -55,6 +56,9 @@ struct AesBlock {
|
||||
uint8 *raw() {
|
||||
return reinterpret_cast<uint8 *>(this);
|
||||
}
|
||||
Slice as_mutable_slice() {
|
||||
return td::MutableSlice(raw(), 16);
|
||||
}
|
||||
|
||||
AesBlock operator^(const AesBlock &b) const {
|
||||
AesBlock res;
|
||||
@ -362,18 +366,80 @@ int pq_factorize(Slice pq_str, string *p_str, string *q_str) {
|
||||
|
||||
class AesState::Impl {
|
||||
public:
|
||||
EVP_CIPHER_CTX *ctx{nullptr};
|
||||
|
||||
Impl() = default;
|
||||
Impl() {
|
||||
ctx_ = EVP_CIPHER_CTX_new();
|
||||
LOG_IF(FATAL, !ctx_);
|
||||
}
|
||||
Impl(const Impl &from) = delete;
|
||||
Impl &operator=(const Impl &from) = delete;
|
||||
Impl(Impl &&from) = delete;
|
||||
Impl &operator=(Impl &&from) = delete;
|
||||
~Impl() {
|
||||
if (ctx != nullptr) {
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
if (ctx_ != nullptr) {
|
||||
EVP_CIPHER_CTX_free(ctx_);
|
||||
}
|
||||
}
|
||||
|
||||
void init_encrypt_ecb(Slice key) {
|
||||
type_ = EncryptEcb;
|
||||
int res = EVP_EncryptInit_ex(ctx_, EVP_aes_256_ecb(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
EVP_CIPHER_CTX_set_padding(ctx_, 0);
|
||||
}
|
||||
|
||||
void init_decrypt_ecb(Slice key) {
|
||||
type_ = DecryptEcb;
|
||||
int res = EVP_DecryptInit_ex(ctx_, EVP_aes_256_ecb(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
EVP_CIPHER_CTX_set_padding(ctx_, 0);
|
||||
}
|
||||
|
||||
void init_encrypt_cbc(Slice key) {
|
||||
type_ = EncryptCbc;
|
||||
int res = EVP_EncryptInit_ex(ctx_, EVP_aes_256_cbc(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
EVP_CIPHER_CTX_set_padding(ctx_, 0);
|
||||
}
|
||||
|
||||
void init_decrypt_cbc(Slice key) {
|
||||
type_ = DecryptCbc;
|
||||
int res = EVP_DecryptInit_ex(ctx_, EVP_aes_256_cbc(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
EVP_CIPHER_CTX_set_padding(ctx_, 0);
|
||||
}
|
||||
|
||||
void init_encrypt_cbc_iv(Slice iv) {
|
||||
CHECK(type_ == EncryptCbc);
|
||||
int res = EVP_EncryptInit(ctx_, nullptr, nullptr, iv.ubegin());
|
||||
LOG_IF(FATAL, res != 1);
|
||||
}
|
||||
|
||||
void init_decrypt_cbc_iv(Slice iv) {
|
||||
CHECK(type_ == DecryptCbc);
|
||||
int res = EVP_DecryptInit(ctx_, nullptr, nullptr, iv.ubegin());
|
||||
LOG_IF(FATAL, res != 1);
|
||||
}
|
||||
|
||||
void encrypt(const uint8 *src, uint8 *dst, int size) {
|
||||
CHECK(type_ == EncryptCbc || type_ == EncryptEcb);
|
||||
CHECK(size % 16 == 0);
|
||||
int len;
|
||||
int res = EVP_EncryptUpdate(ctx_, dst, &len, src, size);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
CHECK(len == size);
|
||||
}
|
||||
void decrypt(const uint8 *src, uint8 *dst, int size) {
|
||||
CHECK(type_ == DecryptCbc || type_ == DecryptEcb);
|
||||
CHECK(size % 16 == 0);
|
||||
int len;
|
||||
int res = EVP_DecryptUpdate(ctx_, dst, &len, src, size);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
CHECK(len == size);
|
||||
}
|
||||
|
||||
private:
|
||||
EVP_CIPHER_CTX *ctx_{nullptr};
|
||||
enum Type { Empty, EncryptEcb, DecryptEcb, EncryptCbc, DecryptCbc } type_{Empty};
|
||||
};
|
||||
|
||||
AesState::AesState() = default;
|
||||
@ -383,38 +449,22 @@ void AesState::init(Slice key, bool encrypt) {
|
||||
CHECK(key.size() == 32);
|
||||
if (!impl_) {
|
||||
impl_ = make_unique<Impl>();
|
||||
impl_->ctx = EVP_CIPHER_CTX_new();
|
||||
}
|
||||
CHECK(impl_->ctx);
|
||||
|
||||
if (encrypt) {
|
||||
int res = EVP_EncryptInit_ex(impl_->ctx, EVP_aes_256_ecb(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
impl_->init_encrypt_ecb(key);
|
||||
} else {
|
||||
int res = EVP_DecryptInit_ex(impl_->ctx, EVP_aes_256_ecb(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
impl_->init_decrypt_ecb(key);
|
||||
}
|
||||
EVP_CIPHER_CTX_set_padding(impl_->ctx, 0);
|
||||
}
|
||||
|
||||
void AesState::encrypt(const uint8 *src, uint8 *dst, int size) {
|
||||
CHECK(impl_ != nullptr);
|
||||
CHECK(impl_->ctx != nullptr);
|
||||
CHECK(size % 16 == 0);
|
||||
int len;
|
||||
int res = EVP_EncryptUpdate(impl_->ctx, dst, &len, src, size);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
CHECK(len == size);
|
||||
impl_->encrypt(src, dst, size);
|
||||
}
|
||||
|
||||
void AesState::decrypt(const uint8 *src, uint8 *dst, int size) {
|
||||
CHECK(impl_ != nullptr);
|
||||
CHECK(impl_->ctx != nullptr);
|
||||
CHECK(size % 16 == 0);
|
||||
int len;
|
||||
int res = EVP_DecryptUpdate(impl_->ctx, dst, &len, src, size);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
CHECK(len == size);
|
||||
impl_->decrypt(src, dst, size);
|
||||
}
|
||||
|
||||
static void aes_ige_xcrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to, bool encrypt_flag) {
|
||||
@ -433,6 +483,9 @@ static void aes_ige_xcrypt(Slice aes_key, MutableSlice aes_iv, Slice from, Mutab
|
||||
}
|
||||
|
||||
void aes_ige_encrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to) {
|
||||
if (from.size() <= 128) {
|
||||
return aes_ige_xcrypt(aes_key, aes_iv, from, to, true);
|
||||
}
|
||||
AesIgeState state;
|
||||
state.init(aes_key, aes_iv, true);
|
||||
state.encrypt(from, to);
|
||||
@ -475,11 +528,10 @@ class AesIgeState::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
EVP_EncryptInit(state.impl_->ctx, nullptr, nullptr, encrypted_iv.raw());
|
||||
state.impl_->init_encrypt_cbc_iv(encrypted_iv.as_mutable_slice());
|
||||
int outlen = 0;
|
||||
int inlen = static_cast<int>(AES_BLOCK_SIZE * count);
|
||||
EVP_EncryptUpdate(state.impl_->ctx, data_xored[0].raw(), &outlen, data_xored[0].raw(), inlen);
|
||||
CHECK(outlen == inlen);
|
||||
state.impl_->encrypt(data_xored[0].raw(), data_xored[0].raw(), inlen);
|
||||
|
||||
data_xored[0] ^= plaintext_iv;
|
||||
for (size_t i = 1; i < count; i++) {
|
||||
@ -530,19 +582,17 @@ void AesIgeState::init(Slice key, Slice iv, bool encrypt) {
|
||||
if (!impl_) {
|
||||
impl_ = make_unique<Impl>();
|
||||
}
|
||||
if (encrypt) {
|
||||
auto &impl = impl_->state.impl_;
|
||||
if (!impl) {
|
||||
impl = make_unique<AesState::Impl>();
|
||||
impl->ctx = EVP_CIPHER_CTX_new();
|
||||
}
|
||||
|
||||
int res = EVP_EncryptInit_ex(impl->ctx, EVP_aes_256_cbc(), nullptr, key.ubegin(), nullptr);
|
||||
LOG_IF(FATAL, res != 1);
|
||||
EVP_CIPHER_CTX_set_padding(impl->ctx, 0);
|
||||
} else {
|
||||
impl_->state.init(key, encrypt);
|
||||
auto &impl = impl_->state.impl_;
|
||||
if (!impl) {
|
||||
impl = make_unique<AesState::Impl>();
|
||||
}
|
||||
if (encrypt) {
|
||||
impl->init_encrypt_cbc(key);
|
||||
} else {
|
||||
impl->init_decrypt_ecb(key);
|
||||
}
|
||||
|
||||
impl_->encrypted_iv.load(iv.ubegin());
|
||||
impl_->plaintext_iv.load(iv.ubegin() + AES_BLOCK_SIZE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user