From 80c7ea2afc14c74601650be89380a057d1f60c76 Mon Sep 17 00:00:00 2001 From: fumiama Date: Sat, 11 Dec 2021 17:36:08 +0800 Subject: [PATCH] add tea --- CMakeLists.txt | 13 +-- md5.c | 181 ++++++++++++++++++++++++++++++++++ simplecrypto.h | 31 ++++++ simplemd5.c | 181 ---------------------------------- simplemd5.h | 7 -- tea.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 476 insertions(+), 194 deletions(-) create mode 100644 md5.c create mode 100644 simplecrypto.h delete mode 100644 simplemd5.c delete mode 100644 simplemd5.h create mode 100644 tea.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a5347da..8ffed6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.6) -project(simple-md5-lib C) +project(simple-crypto C) SET(CMAKE_BUILD_TYPE "Release") include(TestBigEndian) @@ -10,10 +10,11 @@ endif() set(TEST 0) if(TEST) - add_definitions(-DTEST_SIMPLE_MD5_LIB) - add_executable(smd5 simplemd5.c) + add_definitions(-DTEST_SIMPLE_CRYPTO) + add_executable(smd5 md5.c) + add_executable(stea tea.c) else() - add_library(smd5 SHARED simplemd5.c) - INSTALL(TARGETS smd5 LIBRARY DESTINATION lib) - INSTALL(FILES simplemd5.h DESTINATION include) + add_library(scrypto SHARED md5.c tea.c) + INSTALL(TARGETS scrypto LIBRARY DESTINATION lib) + INSTALL(FILES simplecrypto.h DESTINATION include) endif() diff --git a/md5.c b/md5.c new file mode 100644 index 0000000..c7d9d9b --- /dev/null +++ b/md5.c @@ -0,0 +1,181 @@ +#include +#include +#if !__APPLE__ + #include +#else + #include +#endif +#include "simplecrypto.h" + +// Constants are the integer part of the sines of integers (in radians) * 2^32. +const static uint32_t k[64] = { + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee , + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 , + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be , + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 , + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa , + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 , + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed , + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a , + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c , + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 , + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 , + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 , + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 , + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 , + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 , + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; + +// r specifies the per-round shift amounts +const static uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, + 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, + 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, + 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; + +// leftrotate function definition +#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) + +static void to_bytes(uint32_t val, uint8_t *bytes) { + #ifdef WORDS_BIGENDIAN + #if __APPLE__ + val = __DARWIN_OSSwapInt32(val); + #else + val = __builtin_bswap32(val); + #endif + #endif + *(uint32_t*)bytes = val; +} + +static uint32_t to_int32(const uint8_t *bytes) { + #ifdef WORDS_BIGENDIAN + #if __APPLE__ + uint32_t val = __DARWIN_OSSwapInt32(*(uint32_t*)bytes); + #else + uint32_t val = __builtin_bswap32(*(uint32_t*)bytes); + #endif + #else + uint32_t val = *(uint32_t*)bytes; + #endif + return val; +} + +uint8_t* md5(const uint8_t *data, size_t data_len) { + + // These vars will contain the hash + uint32_t h0, h1, h2, h3; + + // Message (to prepare) + uint8_t *msg = NULL; + + size_t new_len, offset; + uint32_t w[16]; + uint32_t a, b, c, d, i, f, g, temp; + + // Initialize variables - simple count in nibbles: + h0 = 0x67452301; + h1 = 0xefcdab89; + h2 = 0x98badcfe; + h3 = 0x10325476; + + //Pre-processing: + //append "1" bit to message + //append "0" bits until message length in bits ≡ 448 (mod 512) + //append length mod (2^64) to message + + for (new_len = data_len + 1; new_len % (512/8) != 448/8; new_len++) + ; + + msg = (uint8_t*)malloc(new_len + 8); + memcpy(msg, data, data_len); + msg[data_len] = 0x80; // append the "1" bit; most significant bit is "first" + for (offset = data_len + 1; offset < new_len; offset++) + msg[offset] = 0; // append "0" bits + + // append the len in bits at the end of the buffer. + to_bytes(data_len*8, msg + new_len); + // initial_len>>29 == initial_len*8>>32, but avoids overflow. + to_bytes(data_len>>29, msg + new_len + 4); + + // Process the message in successive 512-bit chunks: + //for each 512-bit chunk of message: + for(offset=0; offset +#include + +// ---------------MD5 area--------------- + +// return 128bit(16bytes) digest +uint8_t* md5(const uint8_t *data, size_t data_len); + +// ---------------MD5 area--------------- + + +// ---------------TEA area--------------- + +typedef uint32_t TEA; +struct TEADAT { + int64_t len; + uint8_t* data; + void* ptr; // free() must use this val +}; +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_decrypt_qq(const TEA t[4], const TEADAT* src); +TEADAT* tea_decrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src); + +// ---------------TEA area--------------- + +#endif \ No newline at end of file diff --git a/simplemd5.c b/simplemd5.c deleted file mode 100644 index b40452c..0000000 --- a/simplemd5.c +++ /dev/null @@ -1,181 +0,0 @@ -#include -#include -#if !__APPLE__ - #include -#else - #include -#endif -#include "simplemd5.h" - -// Constants are the integer part of the sines of integers (in radians) * 2^32. -const static uint32_t k[64] = { - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee , - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 , - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be , - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 , - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa , - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 , - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed , - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a , - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c , - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 , - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 , - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 , - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 , - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 , - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 , - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; - -// r specifies the per-round shift amounts -const static uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; - -// leftrotate function definition -#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) - -static void to_bytes(uint32_t val, uint8_t *bytes) { - #ifdef WORDS_BIGENDIAN - #if __APPLE__ - val = __DARWIN_OSSwapInt32(val); - #else - val = __builtin_bswap32(val); - #endif - #endif - *(uint32_t*)bytes = val; -} - -static uint32_t to_int32(const uint8_t *bytes) { - #ifdef WORDS_BIGENDIAN - #if __APPLE__ - uint32_t val = __DARWIN_OSSwapInt32(*(uint32_t*)bytes); - #else - uint32_t val = __builtin_bswap32(*(uint32_t*)bytes); - #endif - #else - uint32_t val = *(uint32_t*)bytes; - #endif - return val; -} - -uint8_t* md5(const uint8_t *data, size_t data_len) { - - // These vars will contain the hash - uint32_t h0, h1, h2, h3; - - // Message (to prepare) - uint8_t *msg = NULL; - - size_t new_len, offset; - uint32_t w[16]; - uint32_t a, b, c, d, i, f, g, temp; - - // Initialize variables - simple count in nibbles: - h0 = 0x67452301; - h1 = 0xefcdab89; - h2 = 0x98badcfe; - h3 = 0x10325476; - - //Pre-processing: - //append "1" bit to message - //append "0" bits until message length in bits ≡ 448 (mod 512) - //append length mod (2^64) to message - - for (new_len = data_len + 1; new_len % (512/8) != 448/8; new_len++) - ; - - msg = (uint8_t*)malloc(new_len + 8); - memcpy(msg, data, data_len); - msg[data_len] = 0x80; // append the "1" bit; most significant bit is "first" - for (offset = data_len + 1; offset < new_len; offset++) - msg[offset] = 0; // append "0" bits - - // append the len in bits at the end of the buffer. - to_bytes(data_len*8, msg + new_len); - // initial_len>>29 == initial_len*8>>32, but avoids overflow. - to_bytes(data_len>>29, msg + new_len + 4); - - // Process the message in successive 512-bit chunks: - //for each 512-bit chunk of message: - for(offset=0; offset -#include -//return 128bit(16bytes) digest -uint8_t* md5(const uint8_t *data, size_t data_len); -#endif \ No newline at end of file diff --git a/tea.c b/tea.c new file mode 100644 index 0000000..02b78e1 --- /dev/null +++ b/tea.c @@ -0,0 +1,257 @@ +#include +#include +#include +#if !__APPLE__ + #include +#else + #include +#endif +#include "simplecrypto.h" + +const static uint32_t qqsumtable[0x10] = { + 0x9e3779b9, + 0x3c6ef372, + 0xdaa66d2b, + 0x78dde6e4, + 0x1715609d, + 0xb54cda56, + 0x5384540f, + 0xf1bbcdc8, + 0x8ff34781, + 0x2e2ac13a, + 0xcc623af3, + 0x6a99b4ac, + 0x08d12e65, + 0xa708a81e, + 0x454021d7, + 0xe3779b90, +}; + +TEADAT* tea_encrypt_qq(const TEA t[4], const TEADAT* src) { + 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); + srand(time(NULL)); + ((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++) { + #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; + uint32_t v0 = iv1; + for (int i = 0; i < 0x10; i++) { + 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 + ((uint64_t*)dstdat)[i] = iv1; + #else + ((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; +} + +TEADAT* tea_encrypt(const TEA t[4], const uint32_t sumtable[0x10], const TEADAT* src) { + 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); + srand(time(NULL)); + ((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++) { + #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; + 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; + #ifdef WORDS_BIGENDIAN + ((uint64_t*)dstdat)[i] = iv1; + #else + ((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; +} + +TEADAT* tea_decrypt_qq(const TEA t[4], const TEADAT* src) { + if (src->len < 16 || (src->len)%8 != 0) { + return NULL; + } + 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 + 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; + for (int i = 0x0f; i >= 0; i--) { + 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; +} + +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; + } + 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 + 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; + 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; + + #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; +} + +#ifdef TEST_SIMPLE_CRYPTO +int main(int argc, char **argv) { + TEADAT* td = (TEADAT*)malloc(sizeof(TEADAT)); + TEA* t = (TEA*)"32107654BA98FEDC"; + + if (argc != 3) { + printf("usage: %s -[e|d] 'string'\n", argv[0]); + return 1; + } + switch(argv[1][1]) { + case 'e': + td->data = (uint8_t*)(argv[2]); + td->len = strlen(argv[2]); + TEADAT* tde = tea_encrypt_qq(t, td); + // display result + for (int i = 0; i < tde->len; i++) printf("%02x", ((uint8_t*)(tde->data))[i]); + putchar('\n'); + free(tde->ptr); + free(tde); + break; + case 'd': + td->len = strlen(argv[2])/2; + // printf("decode input len: %lld\n", td->len); + td->data = malloc(td->len); + int i = td->len; + while (i--) { + int x; + sscanf(argv[2]+i*2, "%02x", &x); + 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; + // printf("decode output len: %lld\n", tdd->len); + for (int i = 0; i < tdd->len; i++) putchar(tdd->data[i]); + putchar('\n'); + free(tdd->ptr); + free(tdd); + } else puts("decode error!"); + break; + default: break; + } + + free(td); + + return 0; +} +#endif \ No newline at end of file