From 2e833f3ab84daf058c703219bee5dbdc215754bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Mon, 18 Apr 2022 15:22:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96tea?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++-- simplecrypto.h | 12 ++-- tea.c | 188 +++++++++++++++++++++++++++++-------------------- 3 files changed, 123 insertions(+), 89 deletions(-) diff --git a/README.md b/README.md index 4a17e5e..6a5b2b4 100644 --- a/README.md +++ b/README.md @@ -59,10 +59,10 @@ make install ```c uint8_t* md5(const uint8_t *data, size_t data_len, uint8_t digest[16]); -TEADAT* tea_encrypt_qq(const TEA t[4], const TEADAT* src); -TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_decrypt_qq(const TEA t[4], const TEADAT* src); -TEADAT* tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); +int64_t tea_encrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out); +int64_t tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); ``` \ No newline at end of file diff --git a/simplecrypto.h b/simplecrypto.h index 7a108f6..adea95e 100644 --- a/simplecrypto.h +++ b/simplecrypto.h @@ -21,12 +21,12 @@ struct TEADAT { }; typedef struct TEADAT TEADAT; -TEADAT* tea_encrypt_qq(const TEA t[4], const TEADAT* src); -TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_decrypt_qq(const TEA t[4], const TEADAT* src); -TEADAT* tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); -TEADAT* tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); +int64_t tea_encrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out); +int64_t tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); +int64_t tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out); // ---------------TEA area--------------- diff --git a/tea.c b/tea.c index 27ea46b..eeaad1f 100644 --- a/tea.c +++ b/tea.c @@ -28,11 +28,7 @@ const static uint32_t qqsumtable[0x10] = { 0xe3779b90, }; -TEADAT* tea_encrypt_qq(const TEA t[4], const TEADAT* src) { - return tea_encrypt(t, qqsumtable, src); -} - -TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src) { +int64_t tea_encrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out) { int64_t lens = src->len; int64_t fill = 10 - (lens+1)%8; int64_t dstlen = fill+lens+7; @@ -42,7 +38,6 @@ TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* ((uint32_t*)dstdat)[2] = rand(); dstdat[0] = (fill-3)|0xF8; // 存储pad长度 memcpy(dstdat+fill, src->data, lens); - uint64_t iv1 = 0, iv2 = 0, holder; for(int64_t i = 0; i < dstlen/8; i++) { #ifdef WORDS_BIGENDIAN @@ -51,17 +46,15 @@ TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* uint64_t block = __builtin_bswap64(((uint64_t*)dstdat)[i]); #endif holder = block ^ iv1; - iv1 = holder; uint32_t v1 = holder; iv1 >>= 32; uint32_t v0 = iv1; for (int i = 0; i < 0x10; i++) { - v0 += (v1 + sumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); - v1 += (v0 + sumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); + v0 += (v1 + qqsumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); + v1 += (v0 + qqsumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); } iv1 = ((uint64_t)v0<<32) | (uint64_t)v1; - iv1 = iv1 ^ iv2; iv2 = holder; #ifdef WORDS_BIGENDIAN @@ -70,15 +63,13 @@ TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* ((uint64_t*)dstdat)[i] = __builtin_bswap64(iv1); #endif } - - TEADAT* dst = (TEADAT*)malloc(sizeof(TEADAT)); - dst->len = dstlen; - dst->data = dstdat; - dst->ptr = dstdat; - return dst; + out->len = dstlen; + out->data = dstdat; + out->ptr = dstdat; + return dstlen; } -TEADAT* tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src) { +int64_t tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out) { int64_t lens = src->len; int64_t fill = 10 - (lens+1)%8; int64_t dstlen = fill+lens+7; @@ -88,12 +79,14 @@ TEADAT* tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], ((uint32_t*)dstdat)[2] = rand(); dstdat[0] = (fill-3)|0xF8; // 存储pad长度 memcpy(dstdat+fill, src->data, lens); - uint64_t iv1 = 0, iv2 = 0, holder; for(int64_t i = 0; i < dstlen/8; i++) { - uint64_t block = ((uint64_t*)dstdat)[i]; + #ifdef WORDS_BIGENDIAN + uint64_t block = ((uint64_t*)dstdat)[i]; + #else + uint64_t block = __builtin_bswap64(((uint64_t*)dstdat)[i]); + #endif holder = block ^ iv1; - iv1 = holder; uint32_t v1 = holder; iv1 >>= 32; @@ -103,29 +96,56 @@ TEADAT* tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], v1 += (v0 + sumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); } iv1 = ((uint64_t)v0<<32) | (uint64_t)v1; + iv1 = iv1 ^ iv2; + iv2 = holder; + #ifdef WORDS_BIGENDIAN + ((uint64_t*)dstdat)[i] = iv1; + #else + ((uint64_t*)dstdat)[i] = __builtin_bswap64(iv1); + #endif + } + out->len = dstlen; + out->data = dstdat; + out->ptr = dstdat; + return dstlen; +} +int64_t tea_encrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out) { + int64_t lens = src->len; + int64_t fill = 10 - (lens+1)%8; + int64_t dstlen = fill+lens+7; + uint8_t* dstdat = (uint8_t*)malloc(dstlen); + ((uint32_t*)dstdat)[0] = rand(); + ((uint32_t*)dstdat)[1] = rand(); + ((uint32_t*)dstdat)[2] = rand(); + dstdat[0] = (fill-3)|0xF8; // 存储pad长度 + memcpy(dstdat+fill, src->data, lens); + uint64_t iv1 = 0, iv2 = 0, holder; + for(int64_t i = 0; i < dstlen/8; i++) { + uint64_t block = ((uint64_t*)dstdat)[i]; + holder = block ^ iv1; + iv1 = holder; + uint32_t v1 = holder; + iv1 >>= 32; + uint32_t v0 = iv1; + for (int i = 0; i < 0x10; i++) { + v0 += (v1 + sumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); + v1 += (v0 + sumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); + } + iv1 = ((uint64_t)v0<<32) | (uint64_t)v1; iv1 = iv1 ^ iv2; iv2 = holder; ((uint64_t*)dstdat)[i] = iv1; } - - TEADAT* dst = (TEADAT*)malloc(sizeof(TEADAT)); - dst->len = dstlen; - dst->data = dstdat; - dst->ptr = dstdat; - return dst; + out->len = dstlen; + out->data = dstdat; + out->ptr = dstdat; + return dstlen; } -TEADAT* tea_decrypt_qq(const TEA t[4], const TEADAT* src) { - return tea_decrypt(t, qqsumtable, src); -} - -TEADAT* tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src) { - if (src->len < 16 || (src->len)%8 != 0) { - return NULL; - } +int64_t tea_decrypt_qq(const TEA t[4], const TEADAT* src, TEADAT* out) { + if (src->len < 16 || (src->len)%8 != 0) return 0; uint8_t* dstdat = (uint8_t*)malloc(src->len); - uint64_t iv1, iv2 = 0, holder = 0; for(int64_t i = 0; i < src->len/8; i++) { #ifdef WORDS_BIGENDIAN @@ -133,47 +153,40 @@ TEADAT* tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* #else iv1 = __builtin_bswap64(((uint64_t*)(src->data))[i]); #endif - iv2 ^= iv1; - uint32_t v1 = iv2; iv2 >>= 32; uint32_t v0 = iv2; for (int i = 0x0f; i >= 0; i--) { - v1 -= (v0 + sumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); - v0 -= (v1 + sumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); + v1 -= (v0 + qqsumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); + v0 -= (v1 + qqsumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); } iv2 = ((uint64_t)v0<<32) | (uint64_t)v1; - #ifdef WORDS_BIGENDIAN ((uint64_t*)dstdat)[i] = iv2^holder; #else ((uint64_t*)dstdat)[i] = __builtin_bswap64(iv2^holder); #endif - holder = iv1; } - - TEADAT* dst = (TEADAT*)malloc(sizeof(TEADAT)); int start = (dstdat[0]&7)+3; - dst->len = src->len-7-start; - dst->data = dstdat+start; - dst->ptr = dstdat; - return dst; + out->len = src->len-7-start; + out->data = dstdat+start; + out->ptr = dstdat; + return out->len; } -TEADAT* tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src) { - if (src->len < 16 || (src->len)%8 != 0) { - return NULL; - } +int64_t tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out) { + if (src->len < 16 || (src->len)%8 != 0) return 0; uint8_t* dstdat = (uint8_t*)malloc(src->len); - uint64_t iv1, iv2 = 0, holder = 0; for(int64_t i = 0; i < src->len/8; i++) { - iv1 = ((uint64_t*)(src->data))[i]; - + #ifdef WORDS_BIGENDIAN + iv1 = ((uint64_t*)(src->data))[i]; + #else + iv1 = __builtin_bswap64(((uint64_t*)(src->data))[i]); + #endif iv2 ^= iv1; - uint32_t v1 = iv2; iv2 >>= 32; uint32_t v0 = iv2; @@ -182,24 +195,50 @@ TEADAT* tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], v0 -= (v1 + sumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); } iv2 = ((uint64_t)v0<<32) | (uint64_t)v1; - - ((uint64_t*)dstdat)[i] = iv2^holder; - + #ifdef WORDS_BIGENDIAN + ((uint64_t*)dstdat)[i] = iv2^holder; + #else + ((uint64_t*)dstdat)[i] = __builtin_bswap64(iv2^holder); + #endif holder = iv1; } - - TEADAT* dst = (TEADAT*)malloc(sizeof(TEADAT)); int start = (dstdat[0]&7)+3; - dst->len = src->len-7-start; - dst->data = dstdat+start; - dst->ptr = dstdat; - return dst; + out->len = src->len-7-start; + out->data = dstdat+start; + out->ptr = dstdat; + return out->len; +} + +int64_t tea_decrypt_native_endian(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src, TEADAT* out) { + if (src->len < 16 || (src->len)%8 != 0) return 0; + uint8_t* dstdat = (uint8_t*)malloc(src->len); + uint64_t iv1, iv2 = 0, holder = 0; + for(int64_t i = 0; i < src->len/8; i++) { + iv1 = ((uint64_t*)(src->data))[i]; + iv2 ^= iv1; + uint32_t v1 = iv2; + iv2 >>= 32; + uint32_t v0 = iv2; + for (int i = 0x0f; i >= 0; i--) { + v1 -= (v0 + sumtable[i]) ^ ((v0 << 4) + t[2]) ^ ((v0 >> 5) + t[3]); + v0 -= (v1 + sumtable[i]) ^ ((v1 << 4) + t[0]) ^ ((v1 >> 5) + t[1]); + } + iv2 = ((uint64_t)v0<<32) | (uint64_t)v1; + ((uint64_t*)dstdat)[i] = iv2^holder; + holder = iv1; + } + int start = (dstdat[0]&7)+3; + out->len = src->len-7-start; + out->data = dstdat+start; + out->ptr = dstdat; + return out->len; } #ifdef TEST_SIMPLE_CRYPTO int main(int argc, char **argv) { TEADAT* td = (TEADAT*)malloc(sizeof(TEADAT)); TEA* t = (TEA*)"32107654BA98FEDC"; + TEADAT out; if (argc != 3) { printf("usage: %s -[e|d] 'string'\n", argv[0]); @@ -209,12 +248,11 @@ int main(int argc, char **argv) { case 'e': td->data = (uint8_t*)(argv[2]); td->len = strlen(argv[2]); - TEADAT* tde = tea_encrypt_qq(t, td); + tea_encrypt_qq(t, td, &out); // display result - for (int i = 0; i < tde->len; i++) printf("%02x", ((uint8_t*)(tde->data))[i]); + for (int i = 0; i < out.len; i++) printf("%02x", ((uint8_t*)(out.data))[i]); putchar('\n'); - free(tde->ptr); - free(tde); + free(out.ptr); break; case 'd': td->len = strlen(argv[2])/2; @@ -227,22 +265,18 @@ int main(int argc, char **argv) { td->data[i] = x; argv[2][i*2] = 0; } - TEADAT* tdd = tea_decrypt_qq(t, td); - free(td->data); - if (tdd) { - tdd->data[tdd->len] = 0; + if (tea_decrypt_qq(t, td, &out)) { + out.data[out.len] = 0; // printf("decode output len: %lld\n", tdd->len); - for (int i = 0; i < tdd->len; i++) putchar(tdd->data[i]); + for (int i = 0; i < out.len; i++) putchar(out.data[i]); putchar('\n'); - free(tdd->ptr); - free(tdd); + free(out.ptr); } else puts("decode error!"); + free(td->data); break; default: break; } - free(td); - return 0; } #endif \ No newline at end of file