diff --git a/tdutils/td/utils/crypto.cpp b/tdutils/td/utils/crypto.cpp index 75b47a71f..aae1c1e12 100644 --- a/tdutils/td/utils/crypto.cpp +++ b/tdutils/td/utils/crypto.cpp @@ -50,133 +50,6 @@ namespace td { -struct AesBlock { - uint64 hi; - uint64 lo; - - uint8 *raw() { - return reinterpret_cast(this); - } - const uint8 *raw() const { - return reinterpret_cast(this); - } - Slice as_slice() const { - return Slice(raw(), AES_BLOCK_SIZE); - } - - AesBlock operator^(const AesBlock &b) const { - AesBlock res; - res.hi = hi ^ b.hi; - res.lo = lo ^ b.lo; - return res; - } - void operator^=(const AesBlock &b) { - hi ^= b.hi; - lo ^= b.lo; - } - - void load(const uint8 *from) { - *this = as(from); - } - void store(uint8 *to) { - as(to) = *this; - } - - AesBlock inc() const { -#if SIZE_MAX == UINT64_MAX - AesBlock res; - res.lo = host_to_big_endian64(big_endian_to_host64(lo) + 1); - if (res.lo == 0) { - res.hi = host_to_big_endian64(big_endian_to_host64(hi) + 1); - } else { - res.hi = hi; - } - return res; -#else - AesBlock res = *this; - auto ptr = res.raw(); - if (++ptr[15] == 0) { - for (int i = 14; i >= 0; i--) { - if (++ptr[i] != 0) { - break; - } - } - } - return res; -#endif - } -}; -static_assert(sizeof(AesBlock) == 16, ""); -static_assert(sizeof(AesBlock) == AES_BLOCK_SIZE, ""); - -class XorBytes { - public: - static void run(const uint8 *a, const uint8 *b, uint8 *c, size_t n) { - static constexpr int BLOCK_SIZE = 16; - auto block_cnt = n / BLOCK_SIZE; - n -= block_cnt * BLOCK_SIZE; - while (block_cnt-- > 0) { - Block a_big = as>(a); - Block b_big = as>(b); - as>(c) = a_big ^ b_big; - a += BLOCK_SIZE; - b += BLOCK_SIZE; - c += BLOCK_SIZE; - } - while (n-- > 0) { - c[n] = a[n] ^ b[n]; - } - } - - private: - template - struct alignas(N) Block { - uint8 data[N]; - Block operator^(const Block &b) const & { - Block res; - for (size_t i = 0; i < N; i++) { - res.data[i] = data[i] ^ b.data[i]; - } - return res; - } - }; -}; - -struct AesCtrCounterPack { - static constexpr size_t BLOCK_COUNT = 32; - AesBlock blocks[BLOCK_COUNT]; - uint8 *raw() { - return reinterpret_cast(this); - } - const uint8 *raw() const { - return reinterpret_cast(this); - } - - size_t size() const { - return sizeof(blocks); - } - - Slice as_slice() const { - return Slice(raw(), size()); - } - MutableSlice as_mutable_slice() { - return MutableSlice(raw(), size()); - } - - void init(AesBlock block) { - blocks[0] = block; - for (size_t i = 1; i < BLOCK_COUNT; i++) { - blocks[i] = blocks[i - 1].inc(); - } - } - void rotate() { - blocks[0] = blocks[BLOCK_COUNT - 1].inc(); - for (size_t i = 1; i < BLOCK_COUNT; i++) { - blocks[i] = blocks[i - 1].inc(); - } - } -}; - static uint64 gcd(uint64 a, uint64 b) { if (a == 0) { return b; @@ -379,6 +252,133 @@ int pq_factorize(Slice pq_str, string *p_str, string *q_str) { return 0; } +struct AesBlock { + uint64 hi; + uint64 lo; + + uint8 *raw() { + return reinterpret_cast(this); + } + const uint8 *raw() const { + return reinterpret_cast(this); + } + Slice as_slice() const { + return Slice(raw(), AES_BLOCK_SIZE); + } + + AesBlock operator^(const AesBlock &b) const { + AesBlock res; + res.hi = hi ^ b.hi; + res.lo = lo ^ b.lo; + return res; + } + void operator^=(const AesBlock &b) { + hi ^= b.hi; + lo ^= b.lo; + } + + void load(const uint8 *from) { + *this = as(from); + } + void store(uint8 *to) { + as(to) = *this; + } + + AesBlock inc() const { +#if SIZE_MAX == UINT64_MAX + AesBlock res; + res.lo = host_to_big_endian64(big_endian_to_host64(lo) + 1); + if (res.lo == 0) { + res.hi = host_to_big_endian64(big_endian_to_host64(hi) + 1); + } else { + res.hi = hi; + } + return res; +#else + AesBlock res = *this; + auto ptr = res.raw(); + if (++ptr[15] == 0) { + for (int i = 14; i >= 0; i--) { + if (++ptr[i] != 0) { + break; + } + } + } + return res; +#endif + } +}; +static_assert(sizeof(AesBlock) == 16, ""); +static_assert(sizeof(AesBlock) == AES_BLOCK_SIZE, ""); + +class XorBytes { + public: + static void run(const uint8 *a, const uint8 *b, uint8 *c, size_t n) { + static constexpr int BLOCK_SIZE = 16; + auto block_cnt = n / BLOCK_SIZE; + n -= block_cnt * BLOCK_SIZE; + while (block_cnt-- > 0) { + Block a_big = as>(a); + Block b_big = as>(b); + as>(c) = a_big ^ b_big; + a += BLOCK_SIZE; + b += BLOCK_SIZE; + c += BLOCK_SIZE; + } + while (n-- > 0) { + c[n] = a[n] ^ b[n]; + } + } + + private: + template + struct alignas(N) Block { + uint8 data[N]; + Block operator^(const Block &b) const & { + Block res; + for (size_t i = 0; i < N; i++) { + res.data[i] = data[i] ^ b.data[i]; + } + return res; + } + }; +}; + +struct AesCtrCounterPack { + static constexpr size_t BLOCK_COUNT = 32; + AesBlock blocks[BLOCK_COUNT]; + uint8 *raw() { + return reinterpret_cast(this); + } + const uint8 *raw() const { + return reinterpret_cast(this); + } + + size_t size() const { + return sizeof(blocks); + } + + Slice as_slice() const { + return Slice(raw(), size()); + } + MutableSlice as_mutable_slice() { + return MutableSlice(raw(), size()); + } + + void init(AesBlock block) { + blocks[0] = block; + for (size_t i = 1; i < BLOCK_COUNT; i++) { + blocks[i] = blocks[i - 1].inc(); + } + } + void rotate() { + blocks[0] = blocks[BLOCK_COUNT - 1].inc(); + for (size_t i = 1; i < BLOCK_COUNT; i++) { + blocks[i] = blocks[i - 1].inc(); + } + } +}; + class Evp { public: Evp() { diff --git a/tdutils/td/utils/crypto.h b/tdutils/td/utils/crypto.h index 43b93f371..42cc343d4 100644 --- a/tdutils/td/utils/crypto.h +++ b/tdutils/td/utils/crypto.h @@ -19,6 +19,8 @@ uint64 pq_factorize(uint64 pq); #if TD_HAVE_OPENSSL void init_crypto(); +int pq_factorize(Slice pq_str, string *p_str, string *q_str); + class AesState { public: AesState(); @@ -39,8 +41,6 @@ class AesState { unique_ptr impl_; }; -int pq_factorize(Slice pq_str, string *p_str, string *q_str); - void aes_ige_encrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to); void aes_ige_decrypt(Slice aes_key, MutableSlice aes_iv, Slice from, MutableSlice to);