AesState::Impl -> Evp
GitOrigin-RevId: 536640cffeb4fac1cc6f5a3499554d685891f45e
This commit is contained in:
parent
005611e924
commit
4c288d9398
@ -364,17 +364,17 @@ int pq_factorize(Slice pq_str, string *p_str, string *q_str) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
class AesState::Impl {
|
class Evp {
|
||||||
public:
|
public:
|
||||||
Impl() {
|
Evp() {
|
||||||
ctx_ = EVP_CIPHER_CTX_new();
|
ctx_ = EVP_CIPHER_CTX_new();
|
||||||
LOG_IF(FATAL, !ctx_);
|
LOG_IF(FATAL, !ctx_);
|
||||||
}
|
}
|
||||||
Impl(const Impl &from) = delete;
|
Evp(const Evp &from) = delete;
|
||||||
Impl &operator=(const Impl &from) = delete;
|
Evp &operator=(const Evp &from) = delete;
|
||||||
Impl(Impl &&from) = delete;
|
Evp(Evp &&from) = delete;
|
||||||
Impl &operator=(Impl &&from) = delete;
|
Evp &operator=(Evp &&from) = delete;
|
||||||
~Impl() {
|
~Evp() {
|
||||||
if (ctx_ != nullptr) {
|
if (ctx_ != nullptr) {
|
||||||
EVP_CIPHER_CTX_free(ctx_);
|
EVP_CIPHER_CTX_free(ctx_);
|
||||||
}
|
}
|
||||||
@ -442,6 +442,10 @@ class AesState::Impl {
|
|||||||
enum Type { Empty, EncryptEcb, DecryptEcb, EncryptCbc, DecryptCbc } type_{Empty};
|
enum Type { Empty, EncryptEcb, DecryptEcb, EncryptCbc, DecryptCbc } type_{Empty};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AesState::Impl {
|
||||||
|
Evp evp;
|
||||||
|
};
|
||||||
|
|
||||||
AesState::AesState() = default;
|
AesState::AesState() = default;
|
||||||
AesState::~AesState() = default;
|
AesState::~AesState() = default;
|
||||||
|
|
||||||
@ -451,20 +455,20 @@ void AesState::init(Slice key, bool encrypt) {
|
|||||||
impl_ = make_unique<Impl>();
|
impl_ = make_unique<Impl>();
|
||||||
}
|
}
|
||||||
if (encrypt) {
|
if (encrypt) {
|
||||||
impl_->init_encrypt_ecb(key);
|
impl_->evp.init_encrypt_ecb(key);
|
||||||
} else {
|
} else {
|
||||||
impl_->init_decrypt_ecb(key);
|
impl_->evp.init_decrypt_ecb(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesState::encrypt(const uint8 *src, uint8 *dst, int size) {
|
void AesState::encrypt(const uint8 *src, uint8 *dst, int size) {
|
||||||
CHECK(impl_ != nullptr);
|
CHECK(impl_);
|
||||||
impl_->encrypt(src, dst, size);
|
impl_->evp.encrypt(src, dst, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesState::decrypt(const uint8 *src, uint8 *dst, int size) {
|
void AesState::decrypt(const uint8 *src, uint8 *dst, int size) {
|
||||||
CHECK(impl_ != nullptr);
|
CHECK(impl_);
|
||||||
impl_->decrypt(src, dst, size);
|
impl_->evp.decrypt(src, dst, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aes_ige_xcrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to, bool encrypt_flag) {
|
static void aes_ige_xcrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to, bool encrypt_flag) {
|
||||||
@ -502,10 +506,18 @@ void aes_ige_decrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlic
|
|||||||
|
|
||||||
class AesIgeState::Impl {
|
class AesIgeState::Impl {
|
||||||
public:
|
public:
|
||||||
AesState state;
|
void init(Slice key, Slice iv, bool encrypt) {
|
||||||
AesBlock encrypted_iv;
|
CHECK(key.size() == 32);
|
||||||
AesBlock plaintext_iv;
|
CHECK(iv.size() == 32);
|
||||||
|
if (encrypt) {
|
||||||
|
evp_.init_encrypt_cbc(key);
|
||||||
|
} else {
|
||||||
|
evp_.init_decrypt_ecb(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
encrypted_iv_.load(iv.ubegin());
|
||||||
|
plaintext_iv_.load(iv.ubegin() + AES_BLOCK_SIZE);
|
||||||
|
}
|
||||||
void encrypt(Slice from, MutableSlice to) {
|
void encrypt(Slice from, MutableSlice to) {
|
||||||
CHECK(from.size() % AES_BLOCK_SIZE == 0);
|
CHECK(from.size() % AES_BLOCK_SIZE == 0);
|
||||||
CHECK(to.size() >= from.size());
|
CHECK(to.size() >= from.size());
|
||||||
@ -522,23 +534,22 @@ class AesIgeState::Impl {
|
|||||||
std::memcpy(data, in, AES_BLOCK_SIZE * count);
|
std::memcpy(data, in, AES_BLOCK_SIZE * count);
|
||||||
data_xored[0] = data[0];
|
data_xored[0] = data[0];
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
data_xored[1] = plaintext_iv ^ data[1];
|
data_xored[1] = plaintext_iv_ ^ data[1];
|
||||||
for (size_t i = 2; i < count; i++) {
|
for (size_t i = 2; i < count; i++) {
|
||||||
data_xored[i] = data[i - 2] ^ data[i];
|
data_xored[i] = data[i - 2] ^ data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.impl_->init_encrypt_cbc_iv(encrypted_iv.as_mutable_slice());
|
evp_.init_encrypt_cbc_iv(encrypted_iv_.as_mutable_slice());
|
||||||
int outlen = 0;
|
|
||||||
int inlen = static_cast<int>(AES_BLOCK_SIZE * count);
|
int inlen = static_cast<int>(AES_BLOCK_SIZE * count);
|
||||||
state.impl_->encrypt(data_xored[0].raw(), data_xored[0].raw(), inlen);
|
evp_.encrypt(data_xored[0].raw(), data_xored[0].raw(), inlen);
|
||||||
|
|
||||||
data_xored[0] ^= plaintext_iv;
|
data_xored[0] ^= plaintext_iv_;
|
||||||
for (size_t i = 1; i < count; i++) {
|
for (size_t i = 1; i < count; i++) {
|
||||||
data_xored[i] ^= data[i - 1];
|
data_xored[i] ^= data[i - 1];
|
||||||
}
|
}
|
||||||
plaintext_iv = data[count - 1];
|
plaintext_iv_ = data[count - 1];
|
||||||
encrypted_iv = data_xored[count - 1];
|
encrypted_iv_ = data_xored[count - 1];
|
||||||
|
|
||||||
std::memcpy(out, data_xored, AES_BLOCK_SIZE * count);
|
std::memcpy(out, data_xored, AES_BLOCK_SIZE * count);
|
||||||
len -= count;
|
len -= count;
|
||||||
@ -559,42 +570,34 @@ class AesIgeState::Impl {
|
|||||||
while (len) {
|
while (len) {
|
||||||
encrypted.load(in);
|
encrypted.load(in);
|
||||||
|
|
||||||
plaintext_iv ^= encrypted;
|
plaintext_iv_ ^= encrypted;
|
||||||
state.decrypt(plaintext_iv.raw(), plaintext_iv.raw(), AES_BLOCK_SIZE);
|
evp_.decrypt(plaintext_iv_.raw(), plaintext_iv_.raw(), AES_BLOCK_SIZE);
|
||||||
plaintext_iv ^= encrypted_iv;
|
plaintext_iv_ ^= encrypted_iv_;
|
||||||
|
|
||||||
plaintext_iv.store(out);
|
plaintext_iv_.store(out);
|
||||||
encrypted_iv = encrypted;
|
encrypted_iv_ = encrypted;
|
||||||
|
|
||||||
--len;
|
--len;
|
||||||
in += AES_BLOCK_SIZE;
|
in += AES_BLOCK_SIZE;
|
||||||
out += AES_BLOCK_SIZE;
|
out += AES_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Evp evp_;
|
||||||
|
AesBlock encrypted_iv_;
|
||||||
|
AesBlock plaintext_iv_;
|
||||||
};
|
};
|
||||||
|
|
||||||
AesIgeState::AesIgeState() = default;
|
AesIgeState::AesIgeState() = default;
|
||||||
AesIgeState::~AesIgeState() = default;
|
AesIgeState::~AesIgeState() = default;
|
||||||
|
|
||||||
void AesIgeState::init(Slice key, Slice iv, bool encrypt) {
|
void AesIgeState::init(Slice key, Slice iv, bool encrypt) {
|
||||||
CHECK(key.size() == 32);
|
|
||||||
CHECK(iv.size() == 32);
|
|
||||||
if (!impl_) {
|
if (!impl_) {
|
||||||
impl_ = make_unique<Impl>();
|
impl_ = make_unique<Impl>();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &impl = impl_->state.impl_;
|
impl_->init(key, iv, encrypt);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesIgeState::encrypt(Slice from, MutableSlice to) {
|
void AesIgeState::encrypt(Slice from, MutableSlice to) {
|
||||||
@ -646,10 +649,10 @@ class AesCtrState::Impl {
|
|||||||
CHECK(key.size() == 32);
|
CHECK(key.size() == 32);
|
||||||
CHECK(iv.size() == 16);
|
CHECK(iv.size() == 16);
|
||||||
static_assert(AES_BLOCK_SIZE == 16, "");
|
static_assert(AES_BLOCK_SIZE == 16, "");
|
||||||
aes_state.init(key, true);
|
evp_.init_encrypt_ecb(key);
|
||||||
AesBlock block;
|
AesBlock block;
|
||||||
block.load(iv.ubegin());
|
block.load(iv.ubegin());
|
||||||
counter.init(block);
|
counter_.init(block);
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -658,29 +661,29 @@ class AesCtrState::Impl {
|
|||||||
auto *dst = to.ubegin();
|
auto *dst = to.ubegin();
|
||||||
auto n = from.size();
|
auto n = from.size();
|
||||||
while (n != 0) {
|
while (n != 0) {
|
||||||
if (current.empty()) {
|
if (current_.empty()) {
|
||||||
counter.rotate();
|
counter_.rotate();
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
size_t min_n = td::min(n, current.size());
|
size_t min_n = td::min(n, current_.size());
|
||||||
XorBytes::run(src, current.ubegin(), dst, min_n);
|
XorBytes::run(src, current_.ubegin(), dst, min_n);
|
||||||
src += min_n;
|
src += min_n;
|
||||||
dst += min_n;
|
dst += min_n;
|
||||||
n -= min_n;
|
n -= min_n;
|
||||||
current.remove_prefix(min_n);
|
current_.remove_prefix(min_n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AesState aes_state;
|
Evp evp_;
|
||||||
|
|
||||||
AesCtrCounterPack counter;
|
AesCtrCounterPack counter_;
|
||||||
AesCtrCounterPack encrypted_counter;
|
AesCtrCounterPack encrypted_counter_;
|
||||||
Slice current;
|
Slice current_;
|
||||||
|
|
||||||
void fill() {
|
void fill() {
|
||||||
aes_state.encrypt(counter.raw(), encrypted_counter.raw(), static_cast<int>(counter.size()));
|
evp_.encrypt(counter_.raw(), encrypted_counter_.raw(), static_cast<int>(counter_.size()));
|
||||||
current = encrypted_counter.as_slice();
|
current_ = encrypted_counter_.as_slice();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class AesState {
|
|||||||
void decrypt(const uint8 *src, uint8 *dst, int size);
|
void decrypt(const uint8 *src, uint8 *dst, int size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
struct Impl;
|
||||||
unique_ptr<Impl> impl_;
|
unique_ptr<Impl> impl_;
|
||||||
|
|
||||||
friend class AesIgeState;
|
friend class AesIgeState;
|
||||||
|
Loading…
Reference in New Issue
Block a user